From e8ae0e15370617c312def50e4a92c0253d702c61 Mon Sep 17 00:00:00 2001 From: Arghya Sadhu Date: Wed, 30 Sep 2020 20:18:29 +0530 Subject: [PATCH] adding annotation-service and annotation-revision to kn create/update (#1029) --- CHANGELOG.adoc | 4 + docs/cmd/kn_service_create.md | 86 +++++++-------- docs/cmd/kn_service_update.md | 88 +++++++-------- .../service/configuration_edit_flags.go | 62 ++++++++--- pkg/kn/commands/service/create_mock_test.go | 100 ++++++++++++++++++ test/e2e/service_options_test.go | 35 ++++++ 6 files changed, 278 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index b91c885a25..f8446029b2 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -26,6 +26,10 @@ | Add support for service initialScale via `--scale-init` flag | https://github.com/knative/client/pull/990[#990] +| 🎁 +| Add "--annotation-service" and "--annotation-revision" to kn service create/update +| https://github.com/knative/client/pull/1029[#1029] + |=== ## v0.17.0 (2020-08-26) diff --git a/docs/cmd/kn_service_create.md b/docs/cmd/kn_service_create.md index 0ffb240b2e..8441f158ae 100644 --- a/docs/cmd/kn_service_create.md +++ b/docs/cmd/kn_service_create.md @@ -53,48 +53,50 @@ kn service create NAME --image IMAGE ### Options ``` - -a, --annotation stringArray Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). - --arg stringArray Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times. - --async DEPRECATED: please use --no-wait instead. Do not wait for 'service create' operation to be completed. - --autoscale-window string Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s) - --cluster-local Specify that the service be private. (--no-cluster-local will make the service publicly available) - --cmd string Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments. - --concurrency-limit int Hard Limit of concurrent requests to be processed by a single replica. - --concurrency-target int Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given. - --concurrency-utilization int Percentage of concurrent requests utilization before scaling up. (default 70) - -e, --env stringArray Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-). - --env-from stringArray Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-. - -f, --filename string Create a service from file. The created service can be further modified by combining with other options. For example, -f /path/to/file --env NAME=value adds also an environment variable. - --force Create service forcefully, replaces existing service if any. - -h, --help help for create - --image string Image to run. - -l, --label stringArray Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). - --label-revision stringArray Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag. - --label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag. - --limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'. - --limits-cpu string DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m). - --limits-memory string DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi). - --lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true) - --mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume. - -n, --namespace string Specify the namespace to operate in. - --no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true) - --no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) - --no-wait Do not wait for 'service create' operation to be completed. - -p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'. - --pull-secret string Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace. - --request strings The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'. - --requests-cpu string DEPRECATED: please use --request instead. The requested CPU (e.g., 250m). - --requests-memory string DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi). - --revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}") - --scale int Minimum and maximum number of replicas. - --scale-init int Initial number of replicas with which a service starts. Can be 0 or a positive integer. - --scale-max int Maximum number of replicas. - --scale-min int Minimum number of replicas. - --service-account string Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace. - --user int The user ID to run the container (e.g., 1001). - --volume stringArray Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-. - --wait Wait for 'service create' operation to be completed. (default true) - --wait-timeout int Seconds to wait before giving up on waiting for service to be ready. (default 600) + -a, --annotation stringArray Annotations to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). + --annotation-revision stringArray Revision annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag. + --annotation-service stringArray Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag. + --arg stringArray Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times. + --async DEPRECATED: please use --no-wait instead. Do not wait for 'service create' operation to be completed. + --autoscale-window string Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s) + --cluster-local Specify that the service be private. (--no-cluster-local will make the service publicly available) + --cmd string Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments. + --concurrency-limit int Hard Limit of concurrent requests to be processed by a single replica. + --concurrency-target int Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given. + --concurrency-utilization int Percentage of concurrent requests utilization before scaling up. (default 70) + -e, --env stringArray Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-). + --env-from stringArray Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-. + -f, --filename string Create a service from file. The created service can be further modified by combining with other options. For example, -f /path/to/file --env NAME=value adds also an environment variable. + --force Create service forcefully, replaces existing service if any. + -h, --help help for create + --image string Image to run. + -l, --label stringArray Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). + --label-revision stringArray Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag. + --label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag. + --limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'. + --limits-cpu string DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m). + --limits-memory string DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi). + --lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true) + --mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume. + -n, --namespace string Specify the namespace to operate in. + --no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true) + --no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) + --no-wait Do not wait for 'service create' operation to be completed. + -p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'. + --pull-secret string Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace. + --request strings The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'. + --requests-cpu string DEPRECATED: please use --request instead. The requested CPU (e.g., 250m). + --requests-memory string DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi). + --revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}") + --scale int Minimum and maximum number of replicas. + --scale-init int Initial number of replicas with which a service starts. Can be 0 or a positive integer. + --scale-max int Maximum number of replicas. + --scale-min int Minimum number of replicas. + --service-account string Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace. + --user int The user ID to run the container (e.g., 1001). + --volume stringArray Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-. + --wait Wait for 'service create' operation to be completed. (default true) + --wait-timeout int Seconds to wait before giving up on waiting for service to be ready. (default 600) ``` ### Options inherited from parent commands diff --git a/docs/cmd/kn_service_update.md b/docs/cmd/kn_service_update.md index 007a029233..0633a4e391 100644 --- a/docs/cmd/kn_service_update.md +++ b/docs/cmd/kn_service_update.md @@ -38,49 +38,51 @@ kn service update NAME ### Options ``` - -a, --annotation stringArray Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). - --arg stringArray Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times. - --async DEPRECATED: please use --no-wait instead. Do not wait for 'service update' operation to be completed. - --autoscale-window string Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s) - --cluster-local Specify that the service be private. (--no-cluster-local will make the service publicly available) - --cmd string Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments. - --concurrency-limit int Hard Limit of concurrent requests to be processed by a single replica. - --concurrency-target int Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given. - --concurrency-utilization int Percentage of concurrent requests utilization before scaling up. (default 70) - -e, --env stringArray Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-). - --env-from stringArray Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-. - -h, --help help for update - --image string Image to run. - -l, --label stringArray Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). - --label-revision stringArray Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag. - --label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over "label" flag. - --limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'. - --limits-cpu string DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m). - --limits-memory string DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi). - --lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true) - --mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume. - -n, --namespace string Specify the namespace to operate in. - --no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true) - --no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) - --no-wait Do not wait for 'service update' operation to be completed. - -p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'. - --pull-secret string Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace. - --request strings The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'. - --requests-cpu string DEPRECATED: please use --request instead. The requested CPU (e.g., 250m). - --requests-memory string DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi). - --revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}") - --scale int Minimum and maximum number of replicas. - --scale-init int Initial number of replicas with which a service starts. Can be 0 or a positive integer. - --scale-max int Maximum number of replicas. - --scale-min int Minimum number of replicas. - --service-account string Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace. - --tag strings Set tag (format: --tag revisionRef=tagName) where revisionRef can be a revision or '@latest' string representing latest ready revision. This flag can be specified multiple times. - --traffic strings Set traffic distribution (format: --traffic revisionRef=percent) where revisionRef can be a revision or a tag or '@latest' string representing latest ready revision. This flag can be given multiple times with percent summing up to 100%. - --untag strings Untag revision (format: --untag tagName). This flag can be specified multiple times. - --user int The user ID to run the container (e.g., 1001). - --volume stringArray Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-. - --wait Wait for 'service update' operation to be completed. (default true) - --wait-timeout int Seconds to wait before giving up on waiting for service to be ready. (default 600) + -a, --annotation stringArray Annotations to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). + --annotation-revision stringArray Revision annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag. + --annotation-service stringArray Service annotation to set. name=value; you may provide this flag any number of times to set multiple annotations. To unset, specify the annotation name followed by a "-" (e.g., name-). This flag takes precedence over the "annotation" flag. + --arg stringArray Add argument to the container command. Example: --arg myArg1 --arg --myArg2 --arg myArg3=3. You can use this flag multiple times. + --async DEPRECATED: please use --no-wait instead. Do not wait for 'service update' operation to be completed. + --autoscale-window string Duration to look back for making auto-scaling decisions. The service is scaled to zero if no request was received in during that time. (eg: 10s) + --cluster-local Specify that the service be private. (--no-cluster-local will make the service publicly available) + --cmd string Specify command to be used as entrypoint instead of default one. Example: --cmd /app/start or --cmd /app/start --arg myArg to pass aditional arguments. + --concurrency-limit int Hard Limit of concurrent requests to be processed by a single replica. + --concurrency-target int Recommendation for when to scale up based on the concurrent number of incoming request. Defaults to --concurrency-limit when given. + --concurrency-utilization int Percentage of concurrent requests utilization before scaling up. (default 70) + -e, --env stringArray Environment variable to set. NAME=value; you may provide this flag any number of times to set multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-). + --env-from stringArray Add environment variables from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret:). Example: --env-from cm:myconfigmap or --env-from secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --env-from cm:myconfigmap-. + -h, --help help for update + --image string Image to run. + -l, --label stringArray Labels to set for both Service and Revision. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). + --label-revision stringArray Revision label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag. + --label-service stringArray Service label to set. name=value; you may provide this flag any number of times to set multiple labels. To unset, specify the label name followed by a "-" (e.g., name-). This flag takes precedence over the "label" flag. + --limit strings The resource requirement limits for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource limit, append "-" to the resource name, e.g. '--limit memory-'. + --limits-cpu string DEPRECATED: please use --limit instead. The limits on the requested CPU (e.g., 1000m). + --limits-memory string DEPRECATED: please use --limit instead. The limits on the requested memory (e.g., 1024Mi). + --lock-to-digest Keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) (default true) + --mount stringArray Mount a ConfigMap (prefix cm: or config-map:), a Secret (prefix secret: or sc:), or an existing Volume (without any prefix) on the specified directory. Example: --mount /mydir=cm:myconfigmap, --mount /mydir=secret:mysecret, or --mount /mydir=myvolume. When a configmap or a secret is specified, a corresponding volume is automatically generated. You can use this flag multiple times. For unmounting a directory, append "-", e.g. --mount /mydir-, which also removes any auto-generated volume. + -n, --namespace string Specify the namespace to operate in. + --no-cluster-local Do not specify that the service be private. (--no-cluster-local will make the service publicly available) (default true) + --no-lock-to-digest Do not keep the running image for the service constant when not explicitly specifying the image. (--no-lock-to-digest pulls the image tag afresh with each new revision) + --no-wait Do not wait for 'service update' operation to be completed. + -p, --port string The port where application listens on, in the format 'NAME:PORT', where 'NAME' is optional. Examples: '--port h2c:8080' , '--port 8080'. + --pull-secret string Image pull secret to set. An empty argument ("") clears the pull secret. The referenced secret must exist in the service's namespace. + --request strings The resource requirement requests for this Service. For example, 'cpu=100m,memory=256Mi'. You can use this flag multiple times. To unset a resource request, append "-" to the resource name, e.g. '--request cpu-'. + --requests-cpu string DEPRECATED: please use --request instead. The requested CPU (e.g., 250m). + --requests-memory string DEPRECATED: please use --request instead. The requested memory (e.g., 64Mi). + --revision-name string The revision name to set. Must start with the service name and a dash as a prefix. Empty revision name will result in the server generating a name for the revision. Accepts golang templates, allowing {{.Service}} for the service name, {{.Generation}} for the generation, and {{.Random [n]}} for n random consonants. (default "{{.Service}}-{{.Random 5}}-{{.Generation}}") + --scale int Minimum and maximum number of replicas. + --scale-init int Initial number of replicas with which a service starts. Can be 0 or a positive integer. + --scale-max int Maximum number of replicas. + --scale-min int Minimum number of replicas. + --service-account string Service account name to set. An empty argument ("") clears the service account. The referenced service account must exist in the service's namespace. + --tag strings Set tag (format: --tag revisionRef=tagName) where revisionRef can be a revision or '@latest' string representing latest ready revision. This flag can be specified multiple times. + --traffic strings Set traffic distribution (format: --traffic revisionRef=percent) where revisionRef can be a revision or a tag or '@latest' string representing latest ready revision. This flag can be given multiple times with percent summing up to 100%. + --untag strings Untag revision (format: --untag tagName). This flag can be specified multiple times. + --user int The user ID to run the container (e.g., 1001). + --volume stringArray Add a volume from a ConfigMap (prefix cm: or config-map:) or a Secret (prefix secret: or sc:). Example: --volume myvolume=cm:myconfigmap or --volume myvolume=secret:mysecret. You can use this flag multiple times. To unset a ConfigMap/Secret reference, append "-" to the name, e.g. --volume myvolume-. + --wait Wait for 'service update' operation to be completed. (default true) + --wait-timeout int Seconds to wait before giving up on waiting for service to be ready. (default 600) ``` ### Options inherited from parent commands diff --git a/pkg/kn/commands/service/configuration_edit_flags.go b/pkg/kn/commands/service/configuration_edit_flags.go index 791586258c..f3241ba387 100644 --- a/pkg/kn/commands/service/configuration_edit_flags.go +++ b/pkg/kn/commands/service/configuration_edit_flags.go @@ -51,6 +51,8 @@ type ConfigurationEditFlags struct { LabelsRevision []string RevisionName string Annotations []string + AnnotationsService []string + AnnotationsRevision []string ClusterLocal bool ScaleInit int @@ -127,13 +129,13 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) { "Service label to set. name=value; you may provide this flag "+ "any number of times to set multiple labels. "+ "To unset, specify the label name followed by a \"-\" (e.g., name-). This flag takes "+ - "precedence over \"label\" flag.") + "precedence over the \"label\" flag.") p.markFlagMakesRevision("label-service") command.Flags().StringArrayVarP(&p.LabelsRevision, "label-revision", "", []string{}, "Revision label to set. name=value; you may provide this flag "+ "any number of times to set multiple labels. "+ "To unset, specify the label name followed by a \"-\" (e.g., name-). This flag takes "+ - "precedence over \"label\" flag.") + "precedence over the \"label\" flag.") p.markFlagMakesRevision("label-revision") command.Flags().StringVar(&p.RevisionName, "revision-name", "{{.Service}}-{{.Random 5}}-{{.Generation}}", @@ -149,11 +151,25 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) { // Don't mark as changing the revision. command.Flags().StringArrayVarP(&p.Annotations, "annotation", "a", []string{}, - "Service annotation to set. name=value; you may provide this flag "+ + "Annotations to set for both Service and Revision. name=value; you may provide this flag "+ "any number of times to set multiple annotations. "+ "To unset, specify the annotation name followed by a \"-\" (e.g., name-).") p.markFlagMakesRevision("annotation") + command.Flags().StringArrayVarP(&p.AnnotationsService, "annotation-service", "", []string{}, + "Service annotation to set. name=value; you may provide this flag "+ + "any number of times to set multiple annotations. "+ + "To unset, specify the annotation name followed by a \"-\" (e.g., name-). This flag takes "+ + "precedence over the \"annotation\" flag.") + p.markFlagMakesRevision("annotation-service") + + command.Flags().StringArrayVarP(&p.AnnotationsRevision, "annotation-revision", "", []string{}, + "Revision annotation to set. name=value; you may provide this flag "+ + "any number of times to set multiple annotations. "+ + "To unset, specify the annotation name followed by a \"-\" (e.g., name-). This flag takes "+ + "precedence over the \"annotation\" flag.") + p.markFlagMakesRevision("annotation-revision") + command.Flags().IntVar(&p.ScaleInit, "scale-init", 0, "Initial number of replicas with which a service starts. Can be 0 or a positive integer.") p.markFlagMakesRevision("scale-init") } @@ -406,25 +422,47 @@ func (p *ConfigurationEditFlags) Apply( } } - if cmd.Flags().Changed("annotation") { - annotationsMap, err := util.MapFromArrayAllowingSingles(p.Annotations, "=") + if cmd.Flags().Changed("annotation") || cmd.Flags().Changed("annotation-service") || cmd.Flags().Changed("annotation-revision") { + annotationsAllMap, err := util.MapFromArrayAllowingSingles(p.Annotations, "=") if err != nil { return fmt.Errorf("Invalid --annotation: %w", err) } + annotationRevisionFlagMap, err := util.MapFromArrayAllowingSingles(p.AnnotationsRevision, "=") + if err != nil { + return fmt.Errorf("Invalid --annotation-revision: %w", err) + } + annotationServiceFlagMap, err := util.MapFromArrayAllowingSingles(p.AnnotationsService, "=") + if err != nil { + return fmt.Errorf("Invalid --annotation-service: %w", err) + } + + annotationsToRemove := util.ParseMinusSuffix(annotationsAllMap) + + revisionAnnotations := make(util.StringMap) + revisionAnnotations.Merge(annotationsAllMap) + revisionAnnotations.Merge(annotationRevisionFlagMap) + err = servinglib.UpdateRevisionTemplateAnnotations(template, revisionAnnotations, annotationsToRemove) + if err != nil { + return err + } + + serviceAnnotations := make(util.StringMap) - annotationsToRemove := util.ParseMinusSuffix(annotationsMap) // Service Annotations can't contain Autoscaling ones - serviceAnnotations := make(map[string]string) - for key, value := range annotationsMap { + + for key, value := range annotationsAllMap { if !strings.HasPrefix(key, autoscaling.GroupName) { serviceAnnotations[key] = value } } - // Add all user provided annotations to RevisionTemplate - err = servinglib.UpdateRevisionTemplateAnnotations(template, annotationsMap, annotationsToRemove) - if err != nil { - return err + + for key, value := range annotationServiceFlagMap { + if strings.HasPrefix(key, autoscaling.GroupName) { + return fmt.Errorf("Service cannot have annotation: %s", key) + } + serviceAnnotations[key] = value } + err = servinglib.UpdateServiceAnnotations(service, serviceAnnotations, annotationsToRemove) if err != nil { return err diff --git a/pkg/kn/commands/service/create_mock_test.go b/pkg/kn/commands/service/create_mock_test.go index 0c919ee76b..6e95ac8dbd 100644 --- a/pkg/kn/commands/service/create_mock_test.go +++ b/pkg/kn/commands/service/create_mock_test.go @@ -579,6 +579,106 @@ func TestServiceCreateWithAnnotations(t *testing.T) { r.Validate() } +func TestServiceCreateWithRevisionAndServiceAnnotations(t *testing.T) { + client := knclient.NewMockKnServiceClient(t) + + r := client.Recorder() + r.GetService("foo", nil, errors.NewNotFound(servingv1.Resource("service"), "foo")) + + service := getService("foo") + template := &service.Spec.Template + + service.ObjectMeta.Annotations = map[string]string{ + "foo": "bar", + } + + template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz" + template.ObjectMeta.Annotations = map[string]string{ + autoscaling.InitialScaleAnnotationKey: "1", // autoscaling in only added Revision Template + servinglib.UserImageAnnotationKey: "gcr.io/foo/bar:baz", + } + + r.CreateService(service, nil) + + output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz", + "--annotation-service", "foo=bar", + "--annotation-revision", autoscaling.InitialScaleAnnotationKey+"=1", + "--no-wait", "--revision-name=") + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(output, "created", "foo", "default")) + + r.Validate() +} + +func TestServiceCreateWithRevisionAnnotations(t *testing.T) { + client := knclient.NewMockKnServiceClient(t) + + r := client.Recorder() + r.GetService("foo", nil, errors.NewNotFound(servingv1.Resource("service"), "foo")) + + service := getService("foo") + template := &service.Spec.Template + + template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz" + template.ObjectMeta.Annotations = map[string]string{ + autoscaling.InitialScaleAnnotationKey: "1", // autoscaling in only added Revision Template + servinglib.UserImageAnnotationKey: "gcr.io/foo/bar:baz", + } + + r.CreateService(service, nil) + + output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz", + "--annotation-revision", autoscaling.InitialScaleAnnotationKey+"=1", + "--no-wait", "--revision-name=") + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(output, "created", "foo", "default")) + + r.Validate() +} + +func TestServiceCreateWithServiceAnnotations(t *testing.T) { + client := knclient.NewMockKnServiceClient(t) + + r := client.Recorder() + r.GetService("foo", nil, errors.NewNotFound(servingv1.Resource("service"), "foo")) + + service := getService("foo") + template := &service.Spec.Template + + service.ObjectMeta.Annotations = map[string]string{ + "foo": "bar", + } + + template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz" + template.ObjectMeta.Annotations = map[string]string{ + servinglib.UserImageAnnotationKey: "gcr.io/foo/bar:baz", + } + + r.CreateService(service, nil) + + output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz", + "--annotation-service", "foo=bar", + "--no-wait", "--revision-name=") + assert.NilError(t, err) + assert.Assert(t, util.ContainsAll(output, "created", "foo", "default")) + + r.Validate() +} + +func TestServiceCreateWithAutoScaleServiceAnnotationsError(t *testing.T) { + client := knclient.NewMockKnServiceClient(t) + + r := client.Recorder() + + output, err := executeServiceCommand(client, "create", "foo", "--image", "gcr.io/foo/bar:baz", + "--annotation-service", autoscaling.InitialScaleAnnotationKey+"=1", + "--no-wait", "--revision-name=") + assert.Assert(t, err != nil) + assert.Assert(t, util.ContainsAll(output, "Service cannot have annotation: autoscaling.knative.dev/initialScale")) + + r.Validate() +} + func getServiceWithUrl(name string, urlName string) *servingv1.Service { service := servingv1.Service{} url, _ := apis.ParseURL(urlName) diff --git a/test/e2e/service_options_test.go b/test/e2e/service_options_test.go index c0f5ffdb43..617314e679 100644 --- a/test/e2e/service_options_test.go +++ b/test/e2e/service_options_test.go @@ -163,6 +163,21 @@ func TestServiceOptions(t *testing.T) { validateServiceInitScale(r, "svc11", "2") t.Log("delete service") test.ServiceDelete(r, "svc11") + + t.Log("create and validate service and revision annotations") + serviceCreateWithOptions(r, "svc12", "--annotation-service", "svc=helloworld-svc", "--annotation-revision", "rev=helloworld-rev") + validateServiceAndRevisionAnnotations(r, "svc12", map[string]string{"svc": "helloworld-svc"}, map[string]string{"rev": "helloworld-rev"}) + test.ServiceDelete(r, "svc12") + + t.Log("create and validate service annotations") + serviceCreateWithOptions(r, "svc13", "--annotation-service", "svc=helloworld-svc") + validateServiceAndRevisionAnnotations(r, "svc13", map[string]string{"svc": "helloworld-svc"}, nil) + test.ServiceDelete(r, "svc13") + + t.Log("create and validate revision annotations") + serviceCreateWithOptions(r, "svc14", "--annotation-revision", "rev=helloworld-rev") + validateServiceAndRevisionAnnotations(r, "svc14", nil, map[string]string{"rev": "helloworld-rev"}) + test.ServiceDelete(r, "svc14") } func serviceCreateWithOptions(r *test.KnRunResultCollector, serviceName string, options ...string) { @@ -249,6 +264,26 @@ func validateServiceAnnotations(r *test.KnRunResultCollector, serviceName string } } +func validateServiceAndRevisionAnnotations(r *test.KnRunResultCollector, serviceName string, expectedServiceAnnotations, expectedRevisionAnnotations map[string]string) { + + metadataAnnotationsJsonpathFormat := "jsonpath={.metadata.annotations.%s}" + templateAnnotationsJsonpathFormat := "jsonpath={.spec.template.metadata.annotations.%s}" + + for k, v := range expectedServiceAnnotations { + + out := r.KnTest().Kn().Run("service", "describe", serviceName, "-o", fmt.Sprintf(metadataAnnotationsJsonpathFormat, k)) + assert.Equal(r.T(), v, out.Stdout) + r.AssertNoError(out) + } + + for k, v := range expectedRevisionAnnotations { + + out := r.KnTest().Kn().Run("service", "describe", serviceName, "-o", fmt.Sprintf(templateAnnotationsJsonpathFormat, k)) + assert.Equal(r.T(), v, out.Stdout) + r.AssertNoError(out) + } +} + func validateLabels(r *test.KnRunResultCollector, serviceName string, expectedServiceLabels, expectedRevisionLabels map[string]string) { out := r.KnTest().Kn().Run("service", "describe", serviceName, "-ojson") data := json.NewDecoder(strings.NewReader(out.Stdout))