buildpacks-community / kpack-cli

A command line interface for interacting with kpack.
Other
33 stars 14 forks source link

Add `--dry-run` to kp commands so that they produce yaml that can be `kubectl` applied #37

Closed djoyahoy closed 4 years ago

djoyahoy commented 4 years ago

kp create and patch commands should be able to produce yaml output with a --dry-run flag.

Context: this helps to enable a Gitops workflow so that the yaml can be reused in the git repo that triggers the pipeline

mgibson1121 commented 4 years ago

Direct feature request

 Is is possible to output the Kubernetes resources created by kp in YAML instead of applying them (like a dry-run) ? That could be useful to manage TBS in a Gitops way.
tylerphelan commented 4 years ago

We're going to look into the kubectl --dry-run interface

sukhil-suresh commented 4 years ago

example of running kubectl --dry-run -o yaml

$ k create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --dry-run -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: kubernetes-bootcamp
  name: kubernetes-bootcamp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kubernetes-bootcamp
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: kubernetes-bootcamp
    spec:
      containers:
      - image: gcr.io/google-samples/kubernetes-bootcamp:v1
        name: kubernetes-bootcamp
        resources: {}
status: {}
tylerphelan commented 4 years ago

Updates: --dry-run does not run command but outputs yaml by default -o gives output

sukhil-suresh commented 4 years ago

The dry-run branch contains the implementation as sketched out originally in the issue.

kp create and patch commands should be able to produce yaml output with a --dry-run flag.

resource output is shown with the --dry-run flag and output format specified by --output yaml or --output json

BUT on inspecting the kubectl behaviour, turns out...

For kp, with the --dry-run, for some of the commands, there are side effects.. Eg: image creation from a local source. The source code has to be uploaded to a registry. It's not possible to generate the output yaml/json without these side effects. There are similar side effects for clusterstore and clusterstack create/patch/save commands - Images are relocated so that the image references can be part of the output yaml

These side effect inducing steps can take a while and by default emit status updates such as Uploading.... Skipping these updates when --output flag is used, would make the command seem unresposive/hanging. And at the same time, we need to allow for output text to be input for other commands. Example.

p clusterstack update --dry-run --output yaml > new-stack.yaml && kubectl apply -f new-stack.yaml

And so, we are opting to emit these side effect updates to stderr when --output command is enabled. Only the resource output will be written to stdout.

The dry-run-output branch has the reworked code (in progress).

sukhil-suresh commented 3 years ago

Info for acceptance

--dry-run and --output flags are supported for the kp subcommands:

--dry-run is helpful for client side validation of a given command and will not result in the creation/update/deletion of kpack custom K8s resources. The output of the command will be printed with a (dry run) suffixed. Example:

$ kp builder create test-builder --tag sukhilsuresh/test-image --order order.yaml --store test-store --stack test-stack --dry-run
Builder "test-builder" created (dry run)

--output will allow you to view the resource (output in yaml or json format) sent to the server. This can be used with the --dry-run flag to get the resource output wihout actually creating the resource. Example:

$ DOCKER_PASSWORD=password kp secret create my-dockerhub-creds --dockerhub sukhilsuresh --dry-run --output yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRL...zdWtoaWxzdXJlc2giLfQ==
kind: Secret
...
type: kubernetes.io/dockerconfigjson
---
apiVersion: v1
imagePullSecrets:
- name: my-dockerhub-creds
kind: ServiceAccount
...
secrets:
- name: default-token-4w24f
- name: my-dockerhub-creds

You can kubectl apply the resource output generated (for commands that support the --outputflag)

$ kp image create timg6 -t sukhilsuresh/timg6 --local-path /Users/ssuresh/workspace/spring-petclinic --output yaml --dry-run | k apply -f -
Uploading to 'index.docker.io/sukhilsuresh/timg6-source'... (dry run)
image.kpack.io/timg6 created

You can also pipe the output for a resource along with it's creation

$ kp image create timg6 -t sukhilsuresh/timg6 --local-path /Users/ssuresh/workspace/spring-petclinic --output json > timg6.json
Uploading to 'index.docker.io/sukhilsuresh/timg6-source'...
    Uploading 'index.docker.io/sukhilsuresh/timg6-source@sha256:f535e85e5946bfde7b2951a5dab43b1bf9a35f7e25dc0499937169abf6cfaa15'

$ cat timg6.json
{
    "kind": "Image",
    "apiVersion": "kpack.io/v1alpha1",
    ...

}
mgibson1121 commented 3 years ago

Just took a look and this works according to the conversation discussed here. @sukhil-suresh One thing to consider is providing a bit more context in the help output for the --dry-run flag. It currently reads only print the object that would be sent, without sending it. I can see some users being confused running the command without the dry run flag and not seeing output. Maybe something like print the object that would be sent without sending it, use --output flag to specify format

sukhil-suresh commented 3 years ago

Pulled the story back into done for now, since it waiting on this PR to merge

The help text now reads like below. wondering if it is ok? or do we need more changes?

$ kp cbldr save -h
...
Flags:
  -b, --buildpack strings   buildpack id and optional version in the form of either '<buildpack>@<version>' or '<buildpack>'
                              repeat for each buildpack in order, or supply once with comma-separated list
      --dry-run             perform validation with no side-effects; no objects are sent to the server.
                              The --dry-run flag can be used in combination with the --output flag to
                              view the Kubernetes resource(s) without sending anything to the server.
  -h, --help                help for save
  -o, --order string        path to buildpack order yaml
      --output string       print Kubernetes resources in the specified format; supported formats are: yaml, json.
                              The output can be used with the "kubectl apply -f" command. To allow this, the command
                              updates are redirected to stderr and only the Kubernetes resource(s) are written to stdout.
  -s, --stack string        stack resource to use (default "default" for a create)
      --store string        buildpack store to use (default "default" for a create)
  -t, --tag string          registry location where the builder will be created
sukhil-suresh commented 3 years ago

@mgibson1121 marked story for acceptance

mgibson1121 commented 3 years ago

@sukhil-suresh Not seeing the help text you link in your PR show up using the latest kp binary I can find (Darwin 34).

mgibson1121 commented 3 years ago

This story passes acceptance