Skip to content

Commit

Permalink
feat(serviceaccount): add interactive mode for the reset credentials …
Browse files Browse the repository at this point in the history
…command (#248)
  • Loading branch information
Enda authored Jan 21, 2021
1 parent ffbb807 commit 16699e5
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 166 deletions.
2 changes: 1 addition & 1 deletion docs/commands/rhoas_serviceaccount_create.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ $ rhoas serviceaccount create -o env --force
--file-location string Sets a custom file location to save the credentials
-h, --help help for create
--name string Name of the service account
-o, --output string Format of the config [env, kafka, properties, json, kube]
-o, --output string Format of the credentials file: ["env" "json" "properties" "kube"]
--overwrite Force overwrite a file if it already exists
....

Expand Down
4 changes: 2 additions & 2 deletions docs/commands/rhoas_serviceaccount_reset-credentials.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ rhoas serviceaccount reset-credentials [flags]
=== Examples

....
$ rhoas serviceaccount reset-credentials
$ rhoas serviceaccount reset-credentials --id 173c1ad9-932d-4007-ae0f-4da74f4d2ccd -o json
....

=== Options

....
--file-location string Sets a custom file location to save the credentials
-f, --force Forcefully reset credentials for the service account
-h, --help help for reset-credentials
--id string The unique ID of the service account to delete
-o, --output string Format of the config [env, kafka, properties, json, kube] (default "env")
-o, --output string Format of the credentials file: ["env" "json" "properties" "kube"]
--overwrite Force overwrite a file if it already exists
....

Expand Down
137 changes: 23 additions & 114 deletions pkg/cmd/serviceaccount/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func NewCreateCommand(f *factory.Factory) *cobra.Command {
},
}

cmd.Flags().StringVarP(&opts.output, "output", "o", "", "Format of the config [env, kafka, properties, json, kube]")
cmd.Flags().StringVarP(&opts.output, "output", "o", "", fmt.Sprintf("Format of the credentials file: %q", flagutil.CredentialsOutputFormats))
cmd.Flags().StringVar(&opts.name, "name", "", "Name of the service account")
cmd.Flags().StringVar(&opts.description, "description", "", "Description for the service account")
cmd.Flags().BoolVar(&opts.overwrite, "overwrite", false, "Force overwrite a file if it already exists")
Expand All @@ -114,25 +114,25 @@ func runCreate(opts *Options) error {

if opts.interactive {
// run the create command interactively
serviceAccountPayload, err = promptRequestPayload(opts)
if err != nil {
err = runInteractivePrompt(opts)
if err = cmdutil.CheckSurveyError(err); err != nil {
return err
}
} else {
// obtain the absolute path to where credentials will be saved
opts.filename = credentials.AbsolutePath(opts.output, opts.filename)
}

// If the credentials file already exists, and the --overwrite flag is not set then return an error
// indicating that the user should explicitly request overwriting of the file
_, err = os.Stat(opts.filename)
if err == nil && !opts.overwrite {
return fmt.Errorf("file '%v' already exists. Use --overwrite to overwrite the file, or --file-location flag to choose a custom location", opts.filename)
}

// create the service account
serviceAccountPayload = &managedservices.ServiceAccountRequest{Name: opts.name, Description: &opts.description}
// If the credentials file already exists, and the --overwrite flag is not set then return an error
// indicating that the user should explicitly request overwriting of the file
_, err = os.Stat(opts.filename)
if err == nil && !opts.overwrite {
return fmt.Errorf("file '%v' already exists. Use --overwrite to overwrite the file, or --file-location flag to choose a custom location", opts.filename)
}

// create the service account
serviceAccountPayload = &managedservices.ServiceAccountRequest{Name: opts.name, Description: &opts.description}

a := client.DefaultApi.CreateServiceAccount(context.Background())
a = a.ServiceAccountRequest(*serviceAccountPayload)
serviceacct, _, apiErr := a.Execute()
Expand Down Expand Up @@ -164,24 +164,24 @@ func runCreate(opts *Options) error {
return nil
}

func promptRequestPayload(opts *Options) (payload *managedservices.ServiceAccountRequest, err error) {
func runInteractivePrompt(opts *Options) (err error) {
_, err = opts.Connection()
if err != nil {
return nil, err
return err
}

logger, err := opts.Logger()
if err != nil {
return nil, err
return err
}

logger.Debug("Beginning interactive prompt")

promptName := &survey.Input{Message: "Name:", Help: "Give your service account an easily identifiable name"}

err = survey.AskOne(promptName, &opts.name, survey.WithValidator(survey.Required))
if err = cmdutil.CheckSurveyError(err); err != nil {
return nil, err
if err != nil {
return err
}

// if the --output flag was not used, ask in the prompt
Expand All @@ -196,113 +196,22 @@ func promptRequestPayload(opts *Options) (payload *managedservices.ServiceAccoun
}

err = survey.AskOne(outputPrompt, &opts.output)
if err = cmdutil.CheckSurveyError(err); err != nil {
return nil, err
if err != nil {
return err
}
}

opts.filename, err = chooseFileLocation(opts)
opts.filename, opts.overwrite, err = credentials.ChooseFileLocation(opts.output, opts.filename, opts.overwrite)
if err != nil {
return nil, err
return err
}

promptDescription := &survey.Multiline{Message: "Description (optional):"}

err = survey.AskOne(promptDescription, &opts.description)
if err = cmdutil.CheckSurveyError(err); err != nil {
return nil, err
}

serviceacct := &managedservices.ServiceAccountRequest{
Name: opts.name,
Description: &opts.description,
}

if opts.overwrite {
return serviceacct, nil
}

return serviceacct, err
}

// start an interactive prompt to get the path to the credentials file
// a while loop will be entered as it can take multiple attempts to find a suitable location
// if the file already exists
func chooseFileLocation(opts *Options) (filePath string, err error) {
chooseFileLocation := true
filePath = opts.filename

defaultPath := credentials.AbsolutePath(opts.output, filePath)

logger, err := opts.Logger()
if err != nil {
return "", err
}

var attempts = 0
for chooseFileLocation {
attempts++
logger.Debug("Choosing location to save service account credentials")
logger.Debug("Attempt number", attempts)

// choose location
fileNamePrompt := &survey.Input{
Message: "Credentials file location:",
Help: "Enter the path to the file where the service account credentials will be saved to",
Default: defaultPath,
}
if filePath == "" {
err = survey.AskOne(fileNamePrompt, &filePath, survey.WithValidator(survey.Required))
if err = cmdutil.CheckSurveyError(err); err != nil {
return "", err
}
}

// check if the file selected already exists
// if so ask the user to confirm if they would like to have it overwritten
_, err = os.Stat(filePath)
// file does not exist, we will create it
if os.IsNotExist(err) {
return filePath, nil
}
// another error occurred
if err != nil {
return "", err
}

if opts.overwrite {
return filePath, nil
}

overwriteFilePrompt := &survey.Confirm{
Message: fmt.Sprintf("The file '%v' already exists. Do you want to overwrite it?", filePath),
}

err = survey.AskOne(overwriteFilePrompt, &opts.overwrite)

if err = cmdutil.CheckSurveyError(err); err != nil {
return "", err
}

if opts.overwrite {
return filePath, nil
}

filePath = ""

diffLocationPrompt := &survey.Confirm{
Message: "Would you like to specify a different file location?",
}
err = survey.AskOne(diffLocationPrompt, &chooseFileLocation)
if err = cmdutil.CheckSurveyError(err); err != nil {
return "", err
}
defaultPath = ""
}

if filePath == "" {
return "", fmt.Errorf("You must specify a file to save the service account credentials")
return err
}

return "", nil
return nil
}
2 changes: 1 addition & 1 deletion pkg/cmd/serviceaccount/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func runDelete(opts *Options) (err error) {

var confirmDelete bool
promptConfirmDelete := &survey.Confirm{
Message: "Are you sure you want to delete this service account?",
Message: fmt.Sprintf("Are you sure you want to delete the service account with ID '%v'?", opts.id),
}

err = survey.AskOne(promptConfirmDelete, &confirmDelete)
Expand Down
Loading

0 comments on commit 16699e5

Please sign in to comment.