Skip to content

Commit

Permalink
add run as user flag knative#678
Browse files Browse the repository at this point in the history
  • Loading branch information
itsmurugappan committed Feb 19, 2020
1 parent c2dcb6b commit f2b70de
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/cmd/kn_service_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ kn service create NAME --image IMAGE [flags]
--requests-cpu string The requested CPU (e.g., 250m).
--requests-memory string 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}}")
--run-as-user int The user to run the container (e.g., 1001).
--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.
--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-timeout int Seconds to wait before giving up on waiting for service to be ready. (default 600)
Expand Down
1 change: 1 addition & 0 deletions docs/cmd/kn_service_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ kn service update NAME [flags]
--requests-cpu string The requested CPU (e.g., 250m).
--requests-memory string 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}}")
--run-as-user int The user to run the container (e.g., 1001).
--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%.
Expand Down
7 changes: 7 additions & 0 deletions pkg/kn/commands/service/configuration_edit_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type ConfigurationEditFlags struct {
ServiceAccountName string
ImagePullSecrets string
Annotations []string
RunAsUser int64

// Preferences about how to do the action.
LockToDigest bool
Expand Down Expand Up @@ -189,6 +190,8 @@ func (p *ConfigurationEditFlags) addSharedFlags(command *cobra.Command) {
"",
"Image pull secret to set. An empty argument (\"\") clears the pull secret. The referenced secret must exist in the service's namespace.")
p.markFlagMakesRevision("pull-secret")
command.Flags().Int64VarP(&p.RunAsUser, "run-as-user", "", 0, "The user to run the container (e.g., 1001).")
p.markFlagMakesRevision("run-as-user")
}

// AddUpdateFlags adds the flags specific to update.
Expand Down Expand Up @@ -396,6 +399,10 @@ func (p *ConfigurationEditFlags) Apply(
servinglib.UpdateImagePullSecrets(template, p.ImagePullSecrets)
}

if cmd.Flags().Changed("run-as-user") {
servinglib.UpdateRunAsUser(template, p.RunAsUser)
}

return nil
}

Expand Down
24 changes: 24 additions & 0 deletions pkg/kn/commands/service/create_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"knative.dev/client/pkg/wait"

"knative.dev/client/pkg/util"
"knative.dev/pkg/ptr"
)

func TestServiceCreateImageMock(t *testing.T) {
Expand Down Expand Up @@ -385,6 +386,29 @@ func TestServiceCreateWithMountSecret(t *testing.T) {
r.Validate()
}

func TestServiceCreateWithUser(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].SecurityContext = &corev1.SecurityContext{
RunAsUser: ptr.Int64(int64(1001)),
}
template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
template.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", "--run-as-user", "1001", "--no-wait", "--revision-name=")
assert.NilError(t, err)
assert.Assert(t, util.ContainsAll(output, "created", "foo", "default"))

r.Validate()
}

func getService(name string) *servingv1.Service {
service := &servingv1.Service{
ObjectMeta: metav1.ObjectMeta{
Expand Down
46 changes: 46 additions & 0 deletions pkg/kn/commands/service/service_update_mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
clientserving "knative.dev/client/pkg/serving"
clientservingv1 "knative.dev/client/pkg/serving/v1"
"knative.dev/client/pkg/util"
"knative.dev/pkg/ptr"
)

func TestServiceUpdateEnvMock(t *testing.T) {
Expand Down Expand Up @@ -1427,3 +1428,48 @@ func TestServiceUpdateWithRemovingMount(t *testing.T) {

r.Validate()
}

func TestServiceUpdateUser(t *testing.T) {
client := clientservingv1.NewMockKnServiceClient(t)
svcName := "svc1"
newService := getService(svcName)
template := &newService.Spec.Template
template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{
RunAsUser: ptr.Int64(int64(1001)),
}
template.ObjectMeta.Annotations = map[string]string{
clientserving.UserImageAnnotationKey: "gcr.io/foo/bar:baz",
}

updatedService := getService(svcName)
template = &updatedService.Spec.Template
template.Spec.Containers[0].Image = "gcr.io/foo/bar:baz"
template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{
RunAsUser: ptr.Int64(int64(1002)),
}
template.ObjectMeta.Annotations = map[string]string{
clientserving.UserImageAnnotationKey: "gcr.io/foo/bar:baz",
}

r := client.Recorder()
recordServiceUpdateWithSuccess(r, svcName, newService, updatedService)

output, err := executeServiceCommand(client,
"create", svcName, "--image", "gcr.io/foo/bar:baz",
"--run-as-user", "1001",
"--no-wait", "--revision-name=",
)
assert.NilError(t, err)
assert.Assert(t, util.ContainsAll(output, "created", svcName, "default"))

output, err = executeServiceCommand(client,
"update", svcName,
"--run-as-user", "1002",
"--no-wait", "--revision-name=",
)
assert.NilError(t, err)
assert.Assert(t, util.ContainsAll(output, "updated", svcName, "default"))

r.Validate()
}
12 changes: 12 additions & 0 deletions pkg/serving/config_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,18 @@ func UpdateContainerPort(template *servingv1.RevisionTemplateSpec, port int32) e
return nil
}

// UpdateRunAsUser updates container with a given RunAsUser
func UpdateRunAsUser(template *servingv1.RevisionTemplateSpec, runAsUser int64) error {
container, err := ContainerOfRevisionTemplate(template)
if err != nil {
return err
}
container.SecurityContext = &corev1.SecurityContext{
RunAsUser: &runAsUser,
}
return nil
}

// UpdateResources updates resources as requested
func UpdateResources(template *servingv1.RevisionTemplateSpec, requestsResourceList corev1.ResourceList, limitsResourceList corev1.ResourceList) error {
container, err := ContainerOfRevisionTemplate(template)
Expand Down

0 comments on commit f2b70de

Please sign in to comment.