forked from hashicorp/consul
-
Notifications
You must be signed in to change notification settings - Fork 0
/
translate.go
139 lines (107 loc) · 3.22 KB
/
translate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package rules
import (
"flag"
"fmt"
"io"
"strings"
"github.com/hashicorp/consul/acl"
aclhelpers "github.com/hashicorp/consul/command/acl"
"github.com/hashicorp/consul/command/flags"
"github.com/hashicorp/consul/command/helpers"
"github.com/mitchellh/cli"
)
func New(ui cli.Ui) *cmd {
c := &cmd{UI: ui}
c.init()
return c
}
type cmd struct {
UI cli.Ui
flags *flag.FlagSet
http *flags.HTTPFlags
help string
tokenAccessor bool
tokenSecret bool
// testStdin is the input for testing
testStdin io.Reader
}
func (c *cmd) init() {
c.flags = flag.NewFlagSet("", flag.ContinueOnError)
c.flags.BoolVar(&c.tokenAccessor, "token-accessor", false, "Specifies that "+
"the TRANSLATE argument refers to a ACL token AccessorID. "+
"The rules to translate will then be read from the retrieved token")
c.flags.BoolVar(&c.tokenSecret, "token-secret", false,
"Specifies that the TRANSLATE argument refers to a ACL token SecretID. "+
"The rules to translate will then be read from the retrieved token")
c.http = &flags.HTTPFlags{}
flags.Merge(c.flags, c.http.ClientFlags())
flags.Merge(c.flags, c.http.ServerFlags())
c.help = flags.Usage(help, c.flags)
}
func (c *cmd) Run(args []string) int {
if err := c.flags.Parse(args); err != nil {
return 1
}
data, err := c.dataFromArgs(c.flags.Args())
if err != nil {
c.UI.Error(fmt.Sprintf("Error! %v", err))
return 1
}
if c.tokenSecret || c.tokenAccessor {
client, err := c.http.APIClient()
if err != nil {
c.UI.Error(fmt.Sprintf("Error connecting to Consul Agent: %s", err))
return 1
}
// Trim whitespace and newlines (e.g. from echo without -n)
data = strings.TrimSpace(data)
if rules, err := aclhelpers.GetRulesFromLegacyToken(client, data, c.tokenSecret); err != nil {
c.UI.Error(err.Error())
return 1
} else {
data = rules
}
}
translated, err := acl.TranslateLegacyRules([]byte(data))
if err != nil {
c.UI.Error(fmt.Sprintf("Error translating rules: %s", err))
return 1
}
c.UI.Info(string(translated))
return 0
}
func (c *cmd) dataFromArgs(args []string) (string, error) {
switch len(args) {
case 0:
return "", fmt.Errorf("Missing TRANSLATE argument")
case 1:
data, err := helpers.LoadDataSource(args[0], c.testStdin)
if err != nil {
return "", err
}
return data, nil
default:
return "", fmt.Errorf("Too many arguments: expected 1 got %d", len(args))
}
}
func (c *cmd) Synopsis() string {
return synopsis
}
func (c *cmd) Help() string {
return flags.Usage(c.help, nil)
}
const synopsis = "Translate the legacy rule syntax into the current syntax"
const help = `
Usage: consul acl translate-rules [options] TRANSLATE
Translates the legacy ACL rule syntax into the current syntax.
Translate rules within a file:
$ consul acl translate-rules @rules.hcl
Translate rules from stdin:
$ consul acl translate-rules -
Translate rules from a string argument:
$ consul acl translate-rules 'key "" { policy = "write"}'
Translate rules for a legacy ACL token using its SecretID passed from stdin:
$ consul acl translate-rules -token-secret -
Translate rules for a legacy ACL token using its AccessorID:
$ consul acl translate-rules -token-accessor 429cd746-03d5-4bbb-a83a-18b164171c89
`