github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/acl_auth_method_create.go (about) 1 package command 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "strings" 8 "time" 9 10 "github.com/hashicorp/nomad/api" 11 "github.com/mitchellh/cli" 12 "github.com/posener/complete" 13 "golang.org/x/exp/slices" 14 ) 15 16 // Ensure ACLAuthMethodCreateCommand satisfies the cli.Command interface. 17 var _ cli.Command = &ACLAuthMethodCreateCommand{} 18 19 // ACLAuthMethodCreateCommand implements cli.Command. 20 type ACLAuthMethodCreateCommand struct { 21 Meta 22 23 name string 24 methodType string 25 tokenLocality string 26 maxTokenTTL time.Duration 27 isDefault bool 28 config string 29 json bool 30 tmpl string 31 32 testStdin io.Reader 33 } 34 35 // Help satisfies the cli.Command Help function. 36 func (a *ACLAuthMethodCreateCommand) Help() string { 37 helpText := ` 38 Usage: nomad acl auth-method create [options] 39 40 Create is used to create new ACL auth methods. Use requires a management token. 41 42 General Options: 43 44 ` + generalOptionsUsage(usageOptsDefault|usageOptsNoNamespace) + ` 45 46 ACL Auth Method Create Options: 47 48 -name 49 Sets the human readable name for the ACL auth method. The name must be 50 between 1-128 characters and is a required parameter. 51 52 -type 53 Sets the type of the auth method. Currently the only supported type is 54 'OIDC'. 55 56 -max-token-ttl 57 Sets the duration of time all tokens created by this auth method should be 58 valid for. 59 60 -token-locality 61 Defines the kind of token that this auth method should produce. This can be 62 either 'local' or 'global'. 63 64 -default 65 Specifies whether this auth method should be treated as a default one in 66 case no auth method is explicitly specified for a login command. 67 68 -config 69 Auth method configuration in JSON format. May be prefixed with '@' to 70 indicate that the value is a file path to load the config from. '-' may also 71 be given to indicate that the config is available on stdin. 72 73 -json 74 Output the ACL auth-method in a JSON format. 75 76 -t 77 Format and display the ACL auth-method using a Go template. 78 ` 79 return strings.TrimSpace(helpText) 80 } 81 82 func (a *ACLAuthMethodCreateCommand) AutocompleteFlags() complete.Flags { 83 return mergeAutocompleteFlags(a.Meta.AutocompleteFlags(FlagSetClient), 84 complete.Flags{ 85 "-name": complete.PredictAnything, 86 "-type": complete.PredictSet("OIDC"), 87 "-max-token-ttl": complete.PredictAnything, 88 "-token-locality": complete.PredictSet("local", "global"), 89 "-default": complete.PredictSet("true", "false"), 90 "-config": complete.PredictNothing, 91 "-json": complete.PredictNothing, 92 "-t": complete.PredictAnything, 93 }) 94 } 95 96 func (a *ACLAuthMethodCreateCommand) AutocompleteArgs() complete.Predictor { 97 return complete.PredictNothing 98 } 99 100 // Synopsis satisfies the cli.Command Synopsis function. 101 func (a *ACLAuthMethodCreateCommand) Synopsis() string { return "Create a new ACL auth method" } 102 103 // Name returns the name of this command. 104 func (a *ACLAuthMethodCreateCommand) Name() string { return "acl auth-method create" } 105 106 // Run satisfies the cli.Command Run function. 107 func (a *ACLAuthMethodCreateCommand) Run(args []string) int { 108 109 flags := a.Meta.FlagSet(a.Name(), FlagSetClient) 110 flags.Usage = func() { a.Ui.Output(a.Help()) } 111 flags.StringVar(&a.name, "name", "", "") 112 flags.StringVar(&a.methodType, "type", "", "") 113 flags.StringVar(&a.tokenLocality, "token-locality", "", "") 114 flags.DurationVar(&a.maxTokenTTL, "max-token-ttl", 0, "") 115 flags.BoolVar(&a.isDefault, "default", false, "") 116 flags.StringVar(&a.config, "config", "", "") 117 flags.BoolVar(&a.json, "json", false, "") 118 flags.StringVar(&a.tmpl, "t", "", "") 119 if err := flags.Parse(args); err != nil { 120 return 1 121 } 122 123 // Check that we got no arguments. 124 if len(flags.Args()) != 0 { 125 a.Ui.Error("This command takes no arguments") 126 a.Ui.Error(commandErrorText(a)) 127 return 1 128 } 129 130 // Perform some basic validation 131 if a.name == "" { 132 a.Ui.Error("ACL auth method name must be specified using the -name flag") 133 return 1 134 } 135 if !slices.Contains([]string{"global", "local"}, a.tokenLocality) { 136 a.Ui.Error("Token locality must be set to either 'local' or 'global'") 137 return 1 138 } 139 if a.maxTokenTTL < 1 { 140 a.Ui.Error("Max token TTL must be set to a value between min and max TTL configured for the server.") 141 return 1 142 } 143 if strings.ToUpper(a.methodType) != "OIDC" { 144 a.Ui.Error("ACL auth method type must be set to 'OIDC'") 145 return 1 146 } 147 if len(a.config) == 0 { 148 a.Ui.Error("Must provide ACL auth method config in JSON format") 149 return 1 150 } 151 152 config, err := loadDataSource(a.config, a.testStdin) 153 if err != nil { 154 a.Ui.Error(fmt.Sprintf("Error loading configuration: %v", err)) 155 return 1 156 } 157 158 configJSON := api.ACLAuthMethodConfig{} 159 err = json.Unmarshal([]byte(config), &configJSON) 160 if err != nil { 161 a.Ui.Error(fmt.Sprintf("Unable to parse config: %v", err)) 162 return 1 163 } 164 165 // Set up the auth method with the passed parameters. 166 authMethod := api.ACLAuthMethod{ 167 Name: a.name, 168 Type: strings.ToUpper(a.methodType), 169 TokenLocality: a.tokenLocality, 170 MaxTokenTTL: a.maxTokenTTL, 171 Default: a.isDefault, 172 Config: &configJSON, 173 } 174 175 // Get the HTTP client. 176 client, err := a.Meta.Client() 177 if err != nil { 178 a.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 179 return 1 180 } 181 182 // Create the auth method via the API. 183 method, _, err := client.ACLAuthMethods().Create(&authMethod, nil) 184 if err != nil { 185 a.Ui.Error(fmt.Sprintf("Error creating ACL auth method: %v", err)) 186 return 1 187 } 188 189 if a.json || len(a.tmpl) > 0 { 190 out, err := Format(a.json, a.tmpl, method) 191 if err != nil { 192 a.Ui.Error(err.Error()) 193 return 1 194 } 195 196 a.Ui.Output(out) 197 return 0 198 } 199 200 a.Ui.Output(fmt.Sprintf("Created ACL auth method:\n%s", formatAuthMethod(method))) 201 return 0 202 }