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