From e5e4bfccfefa18fc146e718a05a104c604b39f5a Mon Sep 17 00:00:00 2001 From: Michael Maximilien Date: Fri, 31 Jan 2020 16:18:40 -0800 Subject: [PATCH] fixes(#606): adds --cluster-local / --no-cluster-local flags When specified on 'service create' the '--cluster-local' flag will make the created service 'private' by setting its config visibility to 'cluster-local'. This is done with label: serving.knative.dev/visibility: cluster-local The --no-cluster-local will remove the label. --- CHANGELOG.adoc | 9 ++++++++ docs/cmd/kn_service_create.md | 5 +++++ docs/cmd/kn_service_update.md | 2 ++ .../service/configuration_edit_flags.go | 12 +++++++++++ pkg/kn/commands/service/create.go | 5 ++++- pkg/kn/commands/service/create_test.go | 21 +++++++++++++++++++ pkg/serving/config_changes.go | 10 +++++++++ 7 files changed, 63 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index cde488d9e0..c044e45c39 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -13,6 +13,15 @@ |=== //// +## v0.13.0 (2020-02-14) + +[cols="1,10,3", options="header", width="100%"] +|=== +| | Description | PR + +| 🎁 +| adds --cluster-local / --no-cluster-local flags +| https://github.com/knative/client/pull/629[#629] ## v0.12.0 (2020-01-29) diff --git a/docs/cmd/kn_service_create.md b/docs/cmd/kn_service_create.md index ed8502d4d7..e322cff8ae 100644 --- a/docs/cmd/kn_service_create.md +++ b/docs/cmd/kn_service_create.md @@ -37,6 +37,9 @@ kn service create NAME --image IMAGE [flags] # Create a service with annotation kn service create s1 --image dev.local/ns/image:v3 --annotation sidecar.istio.io/inject=false + + # Create a private service (that is a service with no external endpoint) + kn service create s1 --image dev.local/ns/image:v3 --cluster-local ``` ### Options @@ -45,6 +48,7 @@ kn service create NAME --image IMAGE [flags] --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-). --async Create service and don't wait for it to become ready. --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; sets service's route visibility to 'cluster-local'.(--no-cluster-local will remove any 'cluster-local' route visibility) --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. -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-). @@ -60,6 +64,7 @@ kn service create NAME --image IMAGE [flags] --min-scale int Minimal number of replicas. --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; sets service's route visibility to 'cluster-local'.(--no-cluster-local will remove any 'cluster-local' route visibility) (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) -p, --port int32 The port where application listens on. --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. diff --git a/docs/cmd/kn_service_update.md b/docs/cmd/kn_service_update.md index 154d2dfc40..fccc04a2f0 100644 --- a/docs/cmd/kn_service_update.md +++ b/docs/cmd/kn_service_update.md @@ -41,6 +41,7 @@ kn service update NAME [flags] --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-). --async Update service and don't wait for it to become ready. --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; sets service's route visibility to 'cluster-local'.(--no-cluster-local will remove any 'cluster-local' route visibility) --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. -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-). @@ -55,6 +56,7 @@ kn service update NAME [flags] --min-scale int Minimal number of replicas. --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; sets service's route visibility to 'cluster-local'.(--no-cluster-local will remove any 'cluster-local' route visibility) (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) -p, --port int32 The port where application listens on. --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. diff --git a/pkg/kn/commands/service/configuration_edit_flags.go b/pkg/kn/commands/service/configuration_edit_flags.go index d3aa169d85..fa096b5b55 100644 --- a/pkg/kn/commands/service/configuration_edit_flags.go +++ b/pkg/kn/commands/service/configuration_edit_flags.go @@ -49,6 +49,7 @@ type ConfigurationEditFlags struct { ServiceAccountName string ImagePullSecrets string Annotations []string + ClusterLocal bool // Preferences about how to do the action. LockToDigest bool @@ -117,6 +118,10 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) { p.markFlagMakesRevision("max-scale") command.Flags().StringVar(&p.AutoscaleWindow, "autoscale-window", "", "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)") p.markFlagMakesRevision("autoscale-window") + flags.AddBothBoolFlagsUnhidden(command.Flags(), &p.ClusterLocal, "cluster-local", "", false, + "specify that the service be private; sets service's route visibility to 'cluster-local'."+ + "(--no-cluster-local will remove any 'cluster-local' route visibility)") + p.markFlagMakesRevision("cluster-local") command.Flags().IntVar(&p.ConcurrencyTarget, "concurrency-target", 0, "Recommendation for when to scale up based on the concurrent number of incoming request. "+ "Defaults to --concurrency-limit when given.") @@ -309,6 +314,13 @@ func (p *ConfigurationEditFlags) Apply( } } + if cmd.Flags().Changed("cluster-local") || cmd.Flags().Changed("no-cluster-local") { + err = servinglib.UpdateClusterLocal(service, template, p.ClusterLocal) + if err != nil { + return err + } + } + if cmd.Flags().Changed("concurrency-target") { err = servinglib.UpdateConcurrencyTarget(template, p.ConcurrencyTarget) if err != nil { diff --git a/pkg/kn/commands/service/create.go b/pkg/kn/commands/service/create.go index 46bbbaaf7f..1da642b9e7 100644 --- a/pkg/kn/commands/service/create.go +++ b/pkg/kn/commands/service/create.go @@ -56,7 +56,10 @@ var create_example = ` kn service create --force s1 --image dev.local/ns/image:v1 # Create a service with annotation - kn service create s1 --image dev.local/ns/image:v3 --annotation sidecar.istio.io/inject=false` + kn service create s1 --image dev.local/ns/image:v3 --annotation sidecar.istio.io/inject=false + + # Create a private service (that is a service with no external endpoint) + kn service create s1 --image dev.local/ns/image:v3 --cluster-local` func NewServiceCreateCommand(p *commands.KnParams) *cobra.Command { var editFlags ConfigurationEditFlags diff --git a/pkg/kn/commands/service/create_test.go b/pkg/kn/commands/service/create_test.go index e9ad155716..874ba4fcef 100644 --- a/pkg/kn/commands/service/create_test.go +++ b/pkg/kn/commands/service/create_test.go @@ -21,6 +21,7 @@ import ( "strings" "testing" + "gotest.tools/assert" api_errors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" @@ -493,3 +494,23 @@ func TestServiceCreateWithServiceAccountName(t *testing.T) { t.Fatalf("wrong service account name:%v", template.Spec.ServiceAccountName) } } + +func TestServiceCreateWithClusterLocal(t *testing.T) { + action, created, _, err := fakeServiceCreate([]string{ + "service", "create", "foo", "--image", "gcr.io/foo/bar:baz", + "--cluster-local"}, false, false) + + if err != nil { + t.Fatal(err) + } else if !action.Matches("create", "services") { + t.Fatalf("Bad action %v", action) + } + + template, err := servinglib.RevisionTemplateOfService(created) + if err != nil { + t.Fatal(err) + } + + _, present := template.Labels[config.VisibilityLabelKey] + assert.Assert(t, !present) +} diff --git a/pkg/serving/config_changes.go b/pkg/serving/config_changes.go index 86b9a3a8d5..607d00c597 100644 --- a/pkg/serving/config_changes.go +++ b/pkg/serving/config_changes.go @@ -31,6 +31,7 @@ import ( "knative.dev/serving/pkg/apis/autoscaling" "knative.dev/serving/pkg/apis/serving" servingv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1" + "knative.dev/serving/pkg/reconciler/route/config" ) // VolumeSourceType is a type standing for enumeration of ConfigMap and Secret @@ -193,6 +194,15 @@ func UpdateAutoscaleWindow(template *servingv1alpha1.RevisionTemplateSpec, windo return UpdateRevisionTemplateAnnotation(template, autoscaling.WindowAnnotationKey, window) } +// UpdateClusterLocal updates container serving.knative.dev/visibility annotation +func UpdateClusterLocal(service *servingv1alpha1.Service, template *servingv1alpha1.RevisionTemplateSpec, clusterLocal bool) error { + if clusterLocal { + return UpdateLabels(service, template, map[string]string{config.VisibilityLabelKey: config.VisibilityClusterLocal}, []string{}) + } else { + return UpdateLabels(service, template, map[string]string{}, []string{config.VisibilityLabelKey}) + } +} + // UpdateConcurrencyTarget updates container concurrency annotation func UpdateConcurrencyTarget(template *servingv1alpha1.RevisionTemplateSpec, target int) error { return UpdateRevisionTemplateAnnotation(template, autoscaling.TargetAnnotationKey, strconv.Itoa(target))