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  }