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

Add kubectl create [SUBCOMMAND] pattern #16028

Merged
merged 1 commit into from
Dec 16, 2015

Conversation

derekwaynecarr
Copy link
Member

Fixes #4822

UPDATED TO ALIGN WITH CURRENT PR STATUS

The PR now supports the following:

Create

Create a resource by filename or stdin.

JSON and YAML formats are accepted.

Usage:
  kubectl create -f FILENAME [flags]
  kubectl create [command]

Examples:
# Create a pod using the data in pod.json.
$ kubectl create -f ./pod.json

# Create a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl create -f -

Available Commands:
  namespace   Create a namespace with the specified name.
  secret      Create a secret using specified subcommand.

Create namespace

Create a namespace with the specified name.

Usage:
  kubectl create namespace NAME [--dry-run] [flags]

Aliases:
  namespace, ns


Examples:
  # Create a new namespace named my-namespace
  $ kubectl create namespace my-namespace

Create secret

Create a secret using specified subcommand.

Usage:
  kubectl create secret [flags]
  kubectl create secret [command]

Available Commands:
  docker-registry Create a secret for use with a Docker registry.
  generic         Create a secret from a local file, directory or literal value.

Create a secret that is generic

Create a secret based on a file, directory, or specified literal value

A single secret may package one or more key/value pairs.

When creating a secret based on a file, the key will default to the basename of the file, and the value will
default to the file content.  If the basename is an invalid key, you may specify an alternate key.

When creating a secret based on a directory, each file whose basename is a valid key in the directory will be
packaged into the secret.  Any directory entries except regular files are ignored (e.g. subdirectories,
symlinks, devices, pipes, etc).

Usage:
  kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run] [flags]

Examples:
  # Create a new secret named my-secret with keys for each file in folder bar
  $ kubectl create secret generic my-secret --from-file=path/to/bar

  # Create a new secret named my-secret with specified keys instead of names on disk
  $ kubectl create secret generic my-secret --from-file=ssh-privatekey=~/.ssh/id_rsa --from-file=ssh-publickey=~/.ssh/id_rsa.pub

  # Create a new secret named my-secret with key1=supersecret and key2=topsecret
  $ kubectl create secret generic my-secret --from-literal=key1=supersecret --from-literal=key2=topsecret

Create secret for use with docker registry

Create a new secret for use with Docker registries.

Dockercfg secrets are used to authenticate against Docker registries.

When using the Docker command line to push images, you can authenticate to a given registry by running
  'docker login DOCKER_REGISTRY_SERVER --username=DOCKER_USER --password=DOCKER_PASSWORD --email=DOCKER_EMAIL'.
That produces a ~/.dockercfg file that is used by subsequent 'docker push' and 'docker pull' commands to
authenticate to the registry.

When creating applications, you may have a Docker registry that requires authentication.  In order for the
nodes to pull images on your behalf, they have to have the credentials.  You can provide this information
by creating a dockercfg secret and attaching it to your service account.

Usage:
  kubectl create secret docker-registry NAME --docker-username=user --docker-password=password --docker-email=email [--docker-server=string] [--from-literal=key1=value1] [--dry-run=bool] [flags]

Examples:
  # If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
  $ kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

EDITED: To reflect latest state of commit as of 12/14/15

@k8s-github-robot k8s-github-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Oct 21, 2015
@k8s-github-robot
Copy link

Labelling this PR as size/XXL

@pmorie
Copy link
Member

pmorie commented Oct 21, 2015

So make is a top-level aggregator for macros, right? With special cases for things like run that don't sound good or make sense to group there?

@derekwaynecarr
Copy link
Member Author

@pmorie - yes, make is a macro top-level container for porcelain commands we end up needing. we could argue that expose should become make service --from but I am not making that argument in this PR. I do think this is more natural to read, and make is a sensible top-level command for other macros persistent-volume, node, daemon-set, etc in the future.

run is an obvious meet the user where they are coming from scenario when they are familiar with docker run so I am not in favor of moving that - so its an obvious special case.

@pmorie
Copy link
Member

pmorie commented Oct 21, 2015

I do think this is more natural to read, and make is a sensible top-level command for other macros persistent-volume, node, daemon-set, etc in the future.

+1 to that

@k8s-bot
Copy link

k8s-bot commented Oct 21, 2015

GCE e2e test build/test passed for commit 9e089f96593cdd3e4a3c773ef29ce60b71ddb315.

@bgrant0607
Copy link
Member

I prefer this pattern. It does read better and is more in line with our other commands. When I suggested using secret in #4822, it was as a verb, not as a concept area.

kubectl create -f ... to create from file
kubectl new resource to create from a template
kubectl make resource ... to create from resource-specific flags

Where there are more familiar verbs (run, expose, autoscale), we should keep them, especially where, as with run, they don't create resources of just a single type.

@bgrant0607
Copy link
Member

This is also similar to what I proposed here:
#4822 (comment)

@derekwaynecarr
Copy link
Member Author

@bgrant0607 - ack, will pursue completing this PR, add tests, etc.

@smarterclayton
Copy link
Contributor

Wow, 3 verbs just to create something. That won't confuse users at all

@smarterclayton
Copy link
Contributor

How do I create something that is an aggregate of multiple types of things? I.e. a generator that creates several things?

@smarterclayton
Copy link
Contributor

I must be missing the distinction between new and make. Is it about input or output? I'm going to want to look at the output of new and make as YAML (without creating on the server a lot), so I don't think the fact that new is about an editor makes sense. I'd rather have -o editor. And what sort of templates are new?

@derekwaynecarr
Copy link
Member Author

@smarterclayton - I am going to abstain from noun-verb / verb-verb discussions.

In OpenShift alone, we have 4 different commands to create a secret depending upon the type of secret as a result of wanting to scope flag proliferation. Trying to do it all in new seems like the worst possible scenario for flag proliferation issues. So it seems at a given, there are some resource types that have common enough usage scenarios for 4 different variations of porcelain commands where new alone will not help solve all possible scenarios.

If you want to blend new and make, then the challenge is cobra I think, or I could just be ignorant here. arg[0] has completely different semantics between TYPE and subcommand. I also don't think you would advocate for each new to take the same set of global flags.

kubectl new replication-controller --name=foo --capacity=... makes no sense.
kubectl make persistent-volume foo --capacity=... does.

I agree that kubectl make [SUBCOMMAND] --editor=true is a nice semantic to take the output of the porcelain command as input to the editor is a nice to do in the future.

I think describing make as macro based and new as template based is sensible enough to me.

I am tired of going back and forth.

/cc @DirectXMan12

@derekwaynecarr
Copy link
Member Author

As alternative based on in-person discussions with @smarterclayton , I am fine with:

kubectl create -f foo.yaml
kubectl create namespace foo
kubectl create secret foo --from-literal=key1=value1
kubectl create secret-dockercfg foo --docker-server=foo
kubectl create quota my-quota --hard=cpu=4,memory=4Mi,pods=10
kubectl create config foo --from-literal=key1=value1
kubectl create persistent-volume foo --capacity=size=X,iops=y
kubectl create limits my-limit --min=cpu=100m --max=cpu=1

So basically, macros become sub-commands of create which would work since create takes no args.

Wait for closure before proceeding.

UPDATED with macro examples for many other objects

@smarterclayton
Copy link
Contributor

Some discussions with Derek. There are several ways to create things

  • Generators (complex input, specialized use case with help, or output that varies based on input significantly)
    • run

      kubectl run <name> <image> [ ... lots of args ] -- <command>
      
    • expose

    • podex

    • openshift new-app (create apps from source)

      oc new-app php https://github.com/somerepo/myapp.git
      
    • openshift new-build (create builds based on source)

    • create from template (parameterize with arguments and then send)

  • Complex use case driven
    • Add a persistent volume to a deployment by creating or binding a PVC, identifying the volume name, and identifying where to mount in the container

      oc volume deployment/foo --add --claim-size=10G --mount-path=/var/lib/mysql
      
  • Creating API objects from simple inputs
    • secrets, config (from files or args, many different types)

      kubectl make|create dockercfg-secret <file>
      
    • volumes, nodes, limits, quotas, networks, pvcs, possibly services in the future

  • Totally generic
    • Create

      kubectl create -f <JSON>
      
    • Apply

    • The proposed new command straddles this category and the one above

A new user, coming to Kube or OpenShift, opens the CLI and tries to find the familiar command that begins their path. If they haven't gotten a hint ahead of time (run or new-app), they'll probably likely gravitate to something like create. Create is not a novice end-user concept. It is a high skill concept. New is not much better. The ideal case for most new Kube users is "run", and for OpenShift is "new-app". We'll probably need to change "new-app" to something in the future, but it represents our introduction verb (go from source to production).

I'd rather not have both "create" and "make", because the distinction between them is arbitrary and will distract users. Create is the lowest verb, but Make is only slightly above it.

@smarterclayton
Copy link
Contributor

Edited comment

@thockin
Copy link
Member

thockin commented Oct 22, 2015

I am eager to use this, whether we go with 'create' or 'make' or 'new' (I don't know what new does).

I think new users or relative novices will often think "what was that command again..." and run kubectl -?. If that spits out 3 lines (create, make, new) the user will want to blow their brains out. That makes me agree with the latest proposal - create as the one true way.

Can we fold new into this? kubectl create --edit namespace = take all the defaults for flags and pop open $EDITOR.

@ghodss because of historical interest :)

@thockin
Copy link
Member

thockin commented Oct 22, 2015

Also, do we have precedent for --foo=key=value vs --foo=key:value - I find the latter more readable (and is closer to docker FWIW).

@derekwaynecarr
Copy link
Member Author

@thockin we have precedent for key=value syntax for kubectl run

@derekwaynecarr
Copy link
Member Author

If @bgrant0607 acks with an ok that resource macros become subcommand of create , I will finish this up tomorrow and do the initial implement of secret and namespace and move on :-)

@smarterclayton
Copy link
Contributor

Or "-o editor"

On Oct 21, 2015, at 8:22 PM, Tim Hockin notifications@github.com wrote:

I am eager to use this, whether we go with 'create' or 'make' or 'new' (I
don't know what new does).

I think new users or relative novices will often think "what was that
command again..." and run kubectl -?. If that spits out 3 lines (create,
make, new) the user will want to blow their brains out. That makes me agree
with the latest proposal - create as the one true way.

Can we fold new into this? kubectl create --edit namespace = take all the
defaults for flags and pop open $EDITOR.

@ghodss https://github.com/ghodss because of historical interest :)


Reply to this email directly or view it on GitHub
#16028 (comment)
.

@pmorie
Copy link
Member

pmorie commented Oct 22, 2015

I think new users or relative novices will often think "what was that command again..." and run kubectl -?. If that spits out 3 lines (create, make, new) the user will want to blow their brains out.

I literally lol'd reading this. +1

@bgrant0607
Copy link
Member

cc @janetkuo

@bgrant0607
Copy link
Member

Regardless what we do, we're going to need good documentation, with examples.

I'm fine with adding sub-behaviors to create.

I'd rather use --edit than -o editor.

The main difference, though, for new was the input. So, we'd need something like --from-template or --from-example.

Still catching up on the other comments.

@bgrant0607
Copy link
Member

Aggregate of multiple things, like run: custom command. Don't use resource-specific commands like create/make/new/whatever.

@bgrant0607
Copy link
Member

We should try to make all variants of currently accepted resource names (e.g., svc) work as subcommands, and not introduce new ones (e.g., persistent-volume) if we follow that approach.

@derekwaynecarr
Copy link
Member Author

@deads2k - still wrapping up the test-cmd.sh changes, but take a look.

return f.PrintObject(cmd, obj, out)
}

useShortOutput := options.OutputFormat == "name"
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 always false because you checked for "" above, right?

@k8s-bot
Copy link

k8s-bot commented Dec 14, 2015

GCE e2e test build/test passed for commit cab6a17f2acbbffe275b7263fadc67247175920b.

@derekwaynecarr
Copy link
Member Author

@deads2k - here is the issue for evaluating support of a --confirm flag: #18663

Updates made to hack/test-cmd.sh, I had to fall back to grep (similar to pod templates test) because my go-template-fu was not working nicely with the secret data map with multiple keys; PTAL

# Pre-condition: only the "default" namespace exists
kube::test::get_object_assert 'namespaces' "{{range.items}}{{$id_field}}:{{end}}" 'default:'
# Command
kubectl create namespace other
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd choose a different name, since the next test is expecting that namespace "other" doesn't exist.

@deads2k
Copy link
Contributor

deads2k commented Dec 14, 2015

a couple comments on test-cmd, then this #16028 (comment) and I think its good.

@k8s-bot
Copy link

k8s-bot commented Dec 14, 2015

GCE e2e test build/test passed for commit 2bc3a5e0414db3531971780dba3ecc7cc7ada2a1.

@k8s-bot
Copy link

k8s-bot commented Dec 14, 2015

GCE e2e test build/test passed for commit c438594a3e593907f1ae896639e483004e6e0a1a.

@derekwaynecarr
Copy link
Member Author

@deads2k - last two updates addressed, PTAL

@deads2k
Copy link
Contributor

deads2k commented Dec 14, 2015

lgtm

@deads2k deads2k added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Dec 14, 2015
@k8s-bot
Copy link

k8s-bot commented Dec 14, 2015

GCE e2e test build/test passed for commit 5e09485.

@derekwaynecarr
Copy link
Member Author

@k8s-bot - test this

@ncdc
Copy link
Member

ncdc commented Dec 16, 2015

@k8s-bot unit test this

@k8s-github-robot
Copy link

@k8s-bot test this [submit-queue is verifying that this PR is safe to merge]

@k8s-bot
Copy link

k8s-bot commented Dec 16, 2015

GCE e2e test build/test passed for commit 5e09485.

@k8s-github-robot
Copy link

Automatic merge from submit-queue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/kubectl lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.