1package command 2 3import ( 4 "flag" 5 "fmt" 6 "strconv" 7 "strings" 8 "time" 9 10 "github.com/hashicorp/vault/api" 11 "github.com/mitchellh/cli" 12 "github.com/posener/complete" 13) 14 15var _ cli.Command = (*AuthTuneCommand)(nil) 16var _ cli.CommandAutocomplete = (*AuthTuneCommand)(nil) 17 18type AuthTuneCommand struct { 19 *BaseCommand 20 21 flagAuditNonHMACRequestKeys []string 22 flagAuditNonHMACResponseKeys []string 23 flagDefaultLeaseTTL time.Duration 24 flagDescription string 25 flagListingVisibility string 26 flagMaxLeaseTTL time.Duration 27 flagOptions map[string]string 28 flagTokenType string 29 flagVersion int 30} 31 32func (c *AuthTuneCommand) Synopsis() string { 33 return "Tunes an auth method configuration" 34} 35 36func (c *AuthTuneCommand) Help() string { 37 helpText := ` 38Usage: vault auth tune [options] PATH 39 40 Tunes the configuration options for the auth method at the given PATH. The 41 argument corresponds to the PATH where the auth method is enabled, not the 42 TYPE! 43 44 Tune the default lease for the github auth method: 45 46 $ vault auth tune -default-lease-ttl=72h github/ 47 48` + c.Flags().Help() 49 50 return strings.TrimSpace(helpText) 51} 52 53func (c *AuthTuneCommand) Flags() *FlagSets { 54 set := c.flagSet(FlagSetHTTP) 55 56 f := set.NewFlagSet("Command Options") 57 58 f.StringSliceVar(&StringSliceVar{ 59 Name: flagNameAuditNonHMACRequestKeys, 60 Target: &c.flagAuditNonHMACRequestKeys, 61 Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit" + 62 "devices in the request data object.", 63 }) 64 65 f.StringSliceVar(&StringSliceVar{ 66 Name: flagNameAuditNonHMACResponseKeys, 67 Target: &c.flagAuditNonHMACResponseKeys, 68 Usage: "Comma-separated string or list of keys that will not be HMAC'd by audit" + 69 "devices in the response data object.", 70 }) 71 72 f.DurationVar(&DurationVar{ 73 Name: "default-lease-ttl", 74 Target: &c.flagDefaultLeaseTTL, 75 Default: 0, 76 EnvVar: "", 77 Completion: complete.PredictAnything, 78 Usage: "The default lease TTL for this auth method. If unspecified, this " + 79 "defaults to the Vault server's globally configured default lease TTL, " + 80 "or a previously configured value for the auth method.", 81 }) 82 83 f.StringVar(&StringVar{ 84 Name: flagNameDescription, 85 Target: &c.flagDescription, 86 Usage: "Human-friendly description of the this auth method. This overrides" + 87 "the current stored value, if any.", 88 }) 89 90 f.StringVar(&StringVar{ 91 Name: flagNameListingVisibility, 92 Target: &c.flagListingVisibility, 93 Usage: "Determines the visibility of the mount in the UI-specific listing" + 94 "endpoint.", 95 }) 96 97 f.DurationVar(&DurationVar{ 98 Name: "max-lease-ttl", 99 Target: &c.flagMaxLeaseTTL, 100 Default: 0, 101 EnvVar: "", 102 Completion: complete.PredictAnything, 103 Usage: "The maximum lease TTL for this auth method. If unspecified, this " + 104 "defaults to the Vault server's globally configured maximum lease TTL, " + 105 "or a previously configured value for the auth method.", 106 }) 107 108 f.StringMapVar(&StringMapVar{ 109 Name: "options", 110 Target: &c.flagOptions, 111 Completion: complete.PredictAnything, 112 Usage: "Key-value pair provided as key=value for the mount options. " + 113 "This can be specified multiple times.", 114 }) 115 116 f.StringVar(&StringVar{ 117 Name: flagNameTokenType, 118 Target: &c.flagTokenType, 119 Usage: "Sets a forced token type for the mount.", 120 }) 121 122 f.IntVar(&IntVar{ 123 Name: "version", 124 Target: &c.flagVersion, 125 Default: 0, 126 Usage: "Select the version of the auth method to run. Not supported by all auth methods.", 127 }) 128 129 return set 130} 131 132func (c *AuthTuneCommand) AutocompleteArgs() complete.Predictor { 133 return c.PredictVaultAuths() 134} 135 136func (c *AuthTuneCommand) AutocompleteFlags() complete.Flags { 137 return c.Flags().Completions() 138} 139 140func (c *AuthTuneCommand) Run(args []string) int { 141 f := c.Flags() 142 143 if err := f.Parse(args); err != nil { 144 c.UI.Error(err.Error()) 145 return 1 146 } 147 148 args = f.Args() 149 switch { 150 case len(args) < 1: 151 c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1, got %d)", len(args))) 152 return 1 153 case len(args) > 1: 154 c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args))) 155 return 1 156 } 157 158 client, err := c.Client() 159 if err != nil { 160 c.UI.Error(err.Error()) 161 return 2 162 } 163 164 if c.flagVersion > 0 { 165 if c.flagOptions == nil { 166 c.flagOptions = make(map[string]string) 167 } 168 c.flagOptions["version"] = strconv.Itoa(c.flagVersion) 169 } 170 171 mountConfigInput := api.MountConfigInput{ 172 DefaultLeaseTTL: ttlToAPI(c.flagDefaultLeaseTTL), 173 MaxLeaseTTL: ttlToAPI(c.flagMaxLeaseTTL), 174 Options: c.flagOptions, 175 } 176 177 // Set these values only if they are provided in the CLI 178 f.Visit(func(fl *flag.Flag) { 179 if fl.Name == flagNameAuditNonHMACRequestKeys { 180 mountConfigInput.AuditNonHMACRequestKeys = c.flagAuditNonHMACRequestKeys 181 } 182 183 if fl.Name == flagNameAuditNonHMACResponseKeys { 184 mountConfigInput.AuditNonHMACResponseKeys = c.flagAuditNonHMACResponseKeys 185 } 186 187 if fl.Name == flagNameDescription { 188 mountConfigInput.Description = &c.flagDescription 189 } 190 191 if fl.Name == flagNameListingVisibility { 192 mountConfigInput.ListingVisibility = c.flagListingVisibility 193 } 194 195 if fl.Name == flagNameTokenType { 196 mountConfigInput.TokenType = c.flagTokenType 197 } 198 }) 199 200 // Append /auth (since that's where auths live) and a trailing slash to 201 // indicate it's a path in output 202 mountPath := ensureTrailingSlash(sanitizePath(args[0])) 203 204 if err := client.Sys().TuneMount("/auth/"+mountPath, mountConfigInput); err != nil { 205 c.UI.Error(fmt.Sprintf("Error tuning auth method %s: %s", mountPath, err)) 206 return 2 207 } 208 209 c.UI.Output(fmt.Sprintf("Success! Tuned the auth method at: %s", mountPath)) 210 return 0 211} 212