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