Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(brig): Interactive prompt for creating projects #534

Merged
merged 5 commits into from
Jul 24, 2018

Conversation

technosophos
Copy link
Contributor

This adds brig project create to create projects from interactive
prompts or from an existing secret.

See #504

"os"
"strings"

"github.com/AlecAivazis/survey"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@radu-matei radu-matei Jul 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@technosophos - what revision of this package did you use?
It's not in Gopkg.toml, and building off its latest revision currently fails

# github.com/Azure/brigade/vendor/github.com/AlecAivazis/survey
vendor/github.com/AlecAivazis/survey/survey.go:57:8: undefined: terminal.Stdio

The user will be prompted to answer questions to build the configuration. If -f
is specified in conjunction with -x/--no-prompts, then the values in the file will
be used without prompting the user for any changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What am I deleting here?

`

var (
projectCreateConfig = ""
Copy link
Contributor

@bacongobbler bacongobbler Jul 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to set these to their default values since .StringVarP and .BoolVarP already do that after .ParseFlags() is called. Should be just projectCreateConfig string, right?


if globalVerbose {
out.Write(data)
fmt.Println()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this could be simplified to

fmt.Fprintf(out, "%v\n", data)

}

// Only prompt for key if clone URL requires it
if strings.HasPrefix(p.Repo.CloneURL, "ssh") || strings.HasPrefix(p.Repo.CloneURL, "git+ssh") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we accept ssh-style clone URLs, such as git@github.com:Azure/brigade? If so should we add a check for that, or should we punt it and document that? Or, perhaps a yes/no prompt for whether we need to attach an SSH key?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to invert the selection, and not ask if the URL is http or https, since those are really the two forms that cannot take an SSH key

}

// loadFileValidator validates that a file exists and can be read.
func loadFileValidator(val interface{}) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see why we have to do this, but do you have any ideas on if there are any cleaner ways to this approach? it feels a little awkward to accept an interface{} then immediately cast it into a string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that to satisfy the Validator interface, we have to do func (interface{}) error as the signature.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I tried brainstorming if there were any Go hacks we could do to make this cleaner, but this looks as good as it gets. :)

@technosophos technosophos force-pushed the feat/project-create branch from 40197e9 to 966fc1a Compare July 9, 2018 21:05
@technosophos
Copy link
Contributor Author

@bacongobbler Okay, this is ready for a re-review

return err
}

store := kube.New(c, globalNamespace)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configuring globalNamespace which is default means the namespace configured through the survey is not used - so all projects are created in the default namespace, regardless of the value passed.

Prompt: &survey.Input{
Message: "Kubernetes Namespace",
Help: "The namespace in which this project applies",
Default: p.Kubernetes.Namespace,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used, see comment above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you're right... the value here should just be set to globalNamespace.

@technosophos technosophos force-pushed the feat/project-create branch from 82212a8 to c81a859 Compare July 17, 2018 18:53
@technosophos
Copy link
Contributor Author

@radu-matei The namespace thing was fixed. Now --namespace is the only way to set all the namespace-related stuff. This appears to be the best way to impose consistency.

@radu-matei
Copy link
Contributor

Should the --dry-run flag output the secret the command would create?
As I see, right now it only outputs the project ID

Copy link
Contributor

@radu-matei radu-matei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the experience introduced by this command - there are a few comments I left, but this looks really good!

? Configure Advanced Brigade Settings? No
```

You can use `--dry-run --debug` to see the answers to the question without creating
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a --debug flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops... it was --verbose. Will fix that.

@@ -184,6 +214,9 @@ You can use SSH keys and a `git+ssh` URL to secure a private repository.
In this case, your project's `cloneURL` should be of the form `git@github.com:Azure/brigade.git`
and you will need to add the SSH _private key_ to the `values.yaml` file.

When doing `brig project create`, if you choose a URL that looks like it supports
an SSH key, you will be prompted to enter the path to the SSH private key file.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a little confusing - could you explain what looks like it supports an SSH key mean, and how to ensure that I can add an SSH key for my repo?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewriting that to make 'use' unambiguous

{
Name: "buildStorageSize",
Prompt: &survey.Input{
Message: "Build storage size",
Copy link
Contributor

@radu-matei radu-matei Jul 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it help here to get more information about the storage size (unit of measure and the format) without asking for more help?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Prompt: &survey.Input{
Message: "Build Storage Class",
Help: "Kubernetes provides named storage classes. If you want to use a custom storage class, set the class name here.",
Default: p.Kubernetes.BuildStorageClass,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's surely not needed for this PR, but would it be nice to get pre-populated values for the storage classes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good idea. I will file an issue to add this in a subsequent PR.

can save a local copy of that secret using `brigade project create --out=myproject.json`.

If you have already created the secret, you can fetch it from Kubernetes by running
`brig project get my/project` where `my/project` is the project name you assigned.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed for this PR, but if the create command can generate a JSON file, and it can also accept a JSON file as input, would it make sense to have an option on the get command to output as JSON?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a branch that does this. I will open it as a PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #560

return nil
}

if !projectCreateReplace {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense that instead of a --replace flag to have a brig project edit command / shell out directly to kubectl edit secret ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would opt for doing that as a separate PR. The --replace will walk you through the questions again, but with the old value s pre-populated. I figured this would be useful for people who needed help text and stuff like that.

…er command is set

Along the way, I also added a convenience setter to the brig project
create interface.
@technosophos technosophos force-pushed the feat/project-create branch from 527a2d4 to 78242e8 Compare July 23, 2018 23:29
projectCreateReplace bool
)

var defaultProject = &brigade.Project{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be safer to make this a non-pointer. Force a copy of the object so the default stays default.


configureWorker := false
if err := survey.AskOne(&survey.Confirm{
Message: "Configure Brigade worker?",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be part of the Advanced Brigade Settings?

@technosophos technosophos force-pushed the feat/project-create branch from d134c2d to fb19f07 Compare July 24, 2018 16:23
Also, grammar fixes, reorganizing questions into more logical units, and
generally doing whatever Adam says to do.
@technosophos technosophos force-pushed the feat/project-create branch from fb19f07 to 1f193f3 Compare July 24, 2018 19:50
@technosophos technosophos merged commit c2e31f6 into brigadecore:master Jul 24, 2018
@technosophos technosophos deleted the feat/project-create branch July 24, 2018 20:05
@technosophos
Copy link
Contributor Author

🔥

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants