From e6c7d2859dae9c68c0f6eeeca5ca746bad813912 Mon Sep 17 00:00:00 2001 From: Ying Chun Guo Date: Wed, 4 Mar 2020 16:51:53 +0800 Subject: [PATCH] Add serviceaccount & resources config to cronjob source (#665) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Roland Huß --- CHANGELOG.adoc | 4 +++ docs/cmd/kn_source_cronjob_create.md | 21 +++++++++++---- docs/cmd/kn_source_cronjob_update.md | 15 +++++++---- .../legacysources/v1alpha1/cronjob_client.go | 25 +++++++++++++++++ pkg/kn/commands/source/cronjob/create.go | 13 ++++++++- pkg/kn/commands/source/cronjob/create_test.go | 5 ++-- .../commands/source/cronjob/cronjob_test.go | 13 +++++++-- pkg/kn/commands/source/cronjob/describe.go | 8 ++++++ .../commands/source/cronjob/describe_test.go | 12 +++++++++ pkg/kn/commands/source/cronjob/flags.go | 15 +++++++++-- pkg/kn/commands/source/cronjob/list_test.go | 2 +- pkg/kn/commands/source/cronjob/update.go | 15 +++++++++++ pkg/kn/commands/source/cronjob/update_test.go | 5 ++-- test/e2e/cronjob_test.go | 27 +++++++++++++++++++ 14 files changed, 160 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 1d5429731..e801f8e79 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -18,6 +18,10 @@ |=== | | Description | PR +| ✨ +| Add serviceaccount and resources config to cronjob source handling +| https://github.com/knative/client/issues/564[#564] + | ✨ | Allow configuration sink prefixes | https://github.com/knative/client/pull/571[#571] diff --git a/docs/cmd/kn_source_cronjob_create.md b/docs/cmd/kn_source_cronjob_create.md index 161eddc7e..2fda38fea 100644 --- a/docs/cmd/kn_source_cronjob_create.md +++ b/docs/cmd/kn_source_cronjob_create.md @@ -16,16 +16,27 @@ kn source cronjob create NAME --schedule SCHEDULE --sink SINK --data DATA [flags # Create a crontab scheduler 'my-cron-trigger' which fires every minute and sends 'ping' to service 'mysvc' as a cloudevent kn source cronjob create my-cron-trigger --schedule "* * * * */1" --data "ping" --sink svc:mysvc + + # Create a crontab scheduler 'my-cron-trigger' with ServiceAccount name + kn source cronjob create my-cron-trigger1 --schedule "* * * * */1" --data "ping" --sink svc:event-display --service-account myaccount + + # Create a crontab scheduler 'my-cron-trigger' with requested resources + kn source cronjob create my-cron-trigger1 --schedule "* * * * */1" --data "ping" --sink svc:event-display --requests-cpu 100m --requests-memory 128Mi ``` ### Options ``` - -d, --data string String data to send - -h, --help help for create - -n, --namespace string Specify the namespace to operate in. - --schedule string Schedule specification in crontab format (e.g. '* * * * */2' for every two minutes - -s, --sink string Addressable sink for events + -d, --data string String data to send + -h, --help help for create + --limits-cpu string The limits on the requested CPU (e.g., 1000m). + --limits-memory string The limits on the requested memory (e.g., 1024Mi). + -n, --namespace string Specify the namespace to operate in. + --requests-cpu string The requested CPU (e.g., 250m). + --requests-memory string The requested memory (e.g., 64Mi). + --schedule string Schedule specification in crontab format (e.g. '* * * * */2' for every two minutes + --service-account string Name of the service account to use to run this source + -s, --sink string Addressable sink for events ``` ### Options inherited from parent commands diff --git a/docs/cmd/kn_source_cronjob_update.md b/docs/cmd/kn_source_cronjob_update.md index caa9767ab..ef7d93314 100644 --- a/docs/cmd/kn_source_cronjob_update.md +++ b/docs/cmd/kn_source_cronjob_update.md @@ -21,11 +21,16 @@ kn source cronjob update NAME --schedule SCHEDULE --sink SERVICE --data DATA [fl ### Options ``` - -d, --data string String data to send - -h, --help help for update - -n, --namespace string Specify the namespace to operate in. - --schedule string Schedule specification in crontab format (e.g. '* * * * */2' for every two minutes - -s, --sink string Addressable sink for events + -d, --data string String data to send + -h, --help help for update + --limits-cpu string The limits on the requested CPU (e.g., 1000m). + --limits-memory string The limits on the requested memory (e.g., 1024Mi). + -n, --namespace string Specify the namespace to operate in. + --requests-cpu string The requested CPU (e.g., 250m). + --requests-memory string The requested memory (e.g., 64Mi). + --schedule string Schedule specification in crontab format (e.g. '* * * * */2' for every two minutes + --service-account string Name of the service account to use to run this source + -s, --sink string Addressable sink for events ``` ### Options inherited from parent commands diff --git a/pkg/eventing/legacysources/v1alpha1/cronjob_client.go b/pkg/eventing/legacysources/v1alpha1/cronjob_client.go index 7069cc80f..ec3ed1701 100644 --- a/pkg/eventing/legacysources/v1alpha1/cronjob_client.go +++ b/pkg/eventing/legacysources/v1alpha1/cronjob_client.go @@ -158,6 +158,31 @@ func (b *CronJobSourceBuilder) Sink(sink *duckv1beta1.Destination) *CronJobSourc return b } +func (b *CronJobSourceBuilder) ServiceAccount(sa string) *CronJobSourceBuilder { + b.cronjobSource.Spec.ServiceAccountName = sa + return b +} + +func (b *CronJobSourceBuilder) ResourceRequestsCPU(cpu string) *CronJobSourceBuilder { + b.cronjobSource.Spec.Resources.Requests.ResourceCPU = cpu + return b +} + +func (b *CronJobSourceBuilder) ResourceRequestsMemory(memory string) *CronJobSourceBuilder { + b.cronjobSource.Spec.Resources.Requests.ResourceMemory = memory + return b +} + +func (b *CronJobSourceBuilder) ResourceLimitsCPU(cpu string) *CronJobSourceBuilder { + b.cronjobSource.Spec.Resources.Limits.ResourceCPU = cpu + return b +} + +func (b *CronJobSourceBuilder) ResourceLimitsMemory(memory string) *CronJobSourceBuilder { + b.cronjobSource.Spec.Resources.Limits.ResourceMemory = memory + return b +} + func (b *CronJobSourceBuilder) Build() *v1alpha1.CronJobSource { return b.cronjobSource } diff --git a/pkg/kn/commands/source/cronjob/create.go b/pkg/kn/commands/source/cronjob/create.go index 1142f4d60..52bbdcedd 100644 --- a/pkg/kn/commands/source/cronjob/create.go +++ b/pkg/kn/commands/source/cronjob/create.go @@ -35,7 +35,13 @@ func NewCronJobCreateCommand(p *commands.KnParams) *cobra.Command { Short: "Create a CronJob source.", Example: ` # Create a crontab scheduler 'my-cron-trigger' which fires every minute and sends 'ping' to service 'mysvc' as a cloudevent - kn source cronjob create my-cron-trigger --schedule "* * * * */1" --data "ping" --sink svc:mysvc`, + kn source cronjob create my-cron-trigger --schedule "* * * * */1" --data "ping" --sink svc:mysvc + + # Create a crontab scheduler 'my-cron-trigger' with ServiceAccount name + kn source cronjob create my-cron-trigger1 --schedule "* * * * */1" --data "ping" --sink svc:event-display --service-account myaccount + + # Create a crontab scheduler 'my-cron-trigger' with requested resources + kn source cronjob create my-cron-trigger1 --schedule "* * * * */1" --data "ping" --sink svc:event-display --requests-cpu 100m --requests-memory 128Mi`, RunE: func(cmd *cobra.Command, args []string) (err error) { if len(args) != 1 { @@ -68,6 +74,11 @@ func NewCronJobCreateCommand(p *commands.KnParams) *cobra.Command { Schedule(cronUpdateFlags.schedule). Data(cronUpdateFlags.data). Sink(toDuckV1Beta1(destination)). + ResourceRequestsCPU(cronUpdateFlags.resourceRequestsCPU). + ResourceRequestsMemory(cronUpdateFlags.resourceRequestsMemory). + ResourceLimitsCPU(cronUpdateFlags.resourceLimitsCPU). + ResourceLimitsMemory(cronUpdateFlags.resourceLimitsMemory). + ServiceAccount(cronUpdateFlags.serviceAccountName). Build()) if err == nil { fmt.Fprintf(cmd.OutOrStdout(), "CronJob source '%s' created in namespace '%s'.\n", args[0], cronSourceClient.Namespace()) diff --git a/pkg/kn/commands/source/cronjob/create_test.go b/pkg/kn/commands/source/cronjob/create_test.go index 9c8431388..ae99a82e4 100644 --- a/pkg/kn/commands/source/cronjob/create_test.go +++ b/pkg/kn/commands/source/cronjob/create_test.go @@ -37,9 +37,10 @@ func TestSimpleCreateCronJobSource(t *testing.T) { cronjobClient := clientsourcesv1alpha1.NewMockKnCronJobSourceClient(t) cronJobRecorder := cronjobClient.Recorder() - cronJobRecorder.CreateCronJobSource(createCronJobSource("testsource", "* * * * */2", "maxwell", "mysvc"), nil) + cronJobRecorder.CreateCronJobSource(createCronJobSource("testsource", "* * * * */2", "maxwell", "mysvc", "mysa", "100m", "128Mi", "200m", "256Mi"), nil) - out, err := executeCronJobSourceCommand(cronjobClient, dynamicClient, "create", "--sink", "svc:mysvc", "--schedule", "* * * * */2", "--data", "maxwell", "testsource") + out, err := executeCronJobSourceCommand(cronjobClient, dynamicClient, "create", "--sink", "svc:mysvc", "--schedule", "* * * * */2", "--data", "maxwell", + "--service-account", "mysa", "--requests-cpu", "100m", "--requests-memory", "128Mi", "--limits-cpu", "200m", "--limits-memory", "256Mi", "testsource") assert.NilError(t, err, "Source should have been created") util.ContainsAll(out, "created", "default", "testsource") diff --git a/pkg/kn/commands/source/cronjob/cronjob_test.go b/pkg/kn/commands/source/cronjob/cronjob_test.go index 49546a19a..443454f66 100644 --- a/pkg/kn/commands/source/cronjob/cronjob_test.go +++ b/pkg/kn/commands/source/cronjob/cronjob_test.go @@ -82,9 +82,18 @@ func cleanupCronJobMockClient() { cronJobSourceClientFactory = nil } -func createCronJobSource(name, schedule, data, service string) *v1alpha1.CronJobSource { +func createCronJobSource(name, schedule, data, service string, sa string, requestcpu string, requestmm string, limitcpu string, limitmm string) *v1alpha1.CronJobSource { sink := &v1beta1.Destination{ Ref: &corev1.ObjectReference{Name: service, Kind: "Service", APIVersion: "serving.knative.dev/v1", Namespace: "default"}, } - return source_client_v1alpha1.NewCronJobSourceBuilder(name).Schedule(schedule).Data(data).Sink(sink).Build() + return source_client_v1alpha1.NewCronJobSourceBuilder(name). + Schedule(schedule). + Data(data). + Sink(sink). + ResourceRequestsCPU(requestcpu). + ResourceRequestsMemory(requestmm). + ResourceLimitsCPU(limitcpu). + ResourceLimitsMemory(limitmm). + ServiceAccount(sa). + Build() } diff --git a/pkg/kn/commands/source/cronjob/describe.go b/pkg/kn/commands/source/cronjob/describe.go index 86e48acd5..da941b811 100644 --- a/pkg/kn/commands/source/cronjob/describe.go +++ b/pkg/kn/commands/source/cronjob/describe.go @@ -106,4 +106,12 @@ func writeCronJobSource(dw printers.PrefixWriter, source *v1alpha1.CronJobSource commands.WriteMetadata(dw, &source.ObjectMeta, printDetails) dw.WriteAttribute("Schedule", source.Spec.Schedule) dw.WriteAttribute("Data", source.Spec.Data) + dw.WriteAttribute("ServiceAccountName", source.Spec.ServiceAccountName) + subWriter1 := dw.WriteAttribute("Resources", "") + subWriter2 := subWriter1.WriteAttribute("Requests", "") + subWriter2.WriteAttribute("CPU", source.Spec.Resources.Requests.ResourceCPU) + subWriter2.WriteAttribute("Memory", source.Spec.Resources.Requests.ResourceMemory) + subWriter2 = subWriter1.WriteAttribute("Limits", "") + subWriter2.WriteAttribute("CPU", source.Spec.Resources.Limits.ResourceCPU) + subWriter2.WriteAttribute("Memory", source.Spec.Resources.Limits.ResourceMemory) } diff --git a/pkg/kn/commands/source/cronjob/describe_test.go b/pkg/kn/commands/source/cronjob/describe_test.go index e54f6c701..e90bf4ee1 100644 --- a/pkg/kn/commands/source/cronjob/describe_test.go +++ b/pkg/kn/commands/source/cronjob/describe_test.go @@ -37,6 +37,7 @@ func TestSimpleDescribe(t *testing.T) { out, err := executeCronJobSourceCommand(cronjobClient, nil, "describe", "testsource") assert.NilError(t, err) util.ContainsAll(out, "1 2 3 4 5", "honeymoon", "myservicenamespace", "mysvc", "Service", "testsource") + util.ContainsAll(out, "myaccount", "100m", "128Mi", "200m", "256Mi") cronJobRecorder.Validate() @@ -72,6 +73,17 @@ func getCronJobSource() *v1alpha1.CronJobSource { Name: "mysvc", }, }, + ServiceAccountName: "myaccount", + Resources: v1alpha1.CronJobResourceSpec{ + Requests: v1alpha1.CronJobRequestsSpec{ + ResourceCPU: "100m", + ResourceMemory: "128Mi", + }, + Limits: v1alpha1.CronJobLimitsSpec{ + ResourceCPU: "200m", + ResourceMemory: "256Mi", + }, + }, }, Status: v1alpha1.CronJobSourceStatus{}, } diff --git a/pkg/kn/commands/source/cronjob/flags.go b/pkg/kn/commands/source/cronjob/flags.go index cb100fb0b..b8cb96d8e 100644 --- a/pkg/kn/commands/source/cronjob/flags.go +++ b/pkg/kn/commands/source/cronjob/flags.go @@ -29,13 +29,24 @@ import ( ) type cronJobUpdateFlags struct { - schedule string - data string + schedule string + data string + resourceRequestsCPU string + resourceRequestsMemory string + resourceLimitsCPU string + resourceLimitsMemory string + serviceAccountName string } func (c *cronJobUpdateFlags) addCronJobFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&c.schedule, "schedule", "", "Schedule specification in crontab format (e.g. '* * * * */2' for every two minutes") cmd.Flags().StringVarP(&c.data, "data", "d", "", "String data to send") + cmd.Flags().StringVar(&c.resourceRequestsCPU, "requests-cpu", "", "The requested CPU (e.g., 250m).") + cmd.Flags().StringVar(&c.resourceRequestsMemory, "requests-memory", "", "The requested memory (e.g., 64Mi).") + cmd.Flags().StringVar(&c.resourceLimitsCPU, "limits-cpu", "", "The limits on the requested CPU (e.g., 1000m).") + cmd.Flags().StringVar(&c.resourceLimitsMemory, "limits-memory", "", + "The limits on the requested memory (e.g., 1024Mi).") + cmd.Flags().StringVar(&c.serviceAccountName, "service-account", "", "Name of the service account to use to run this source") } // CronJobListHandlers handles printing human readable table for `kn source cronjob list` command's output diff --git a/pkg/kn/commands/source/cronjob/list_test.go b/pkg/kn/commands/source/cronjob/list_test.go index a99a3ec74..ccf150598 100644 --- a/pkg/kn/commands/source/cronjob/list_test.go +++ b/pkg/kn/commands/source/cronjob/list_test.go @@ -28,7 +28,7 @@ func TestListCronJobSource(t *testing.T) { cronjobClient := knsource_v1alpha1.NewMockKnCronJobSourceClient(t) cronJobRecorder := cronjobClient.Recorder() - cJSource := createCronJobSource("testsource", "* * * * */2", "maxwell", "mysvc") + cJSource := createCronJobSource("testsource", "* * * * */2", "maxwell", "mysvc", "mysa", "100m", "128Mi", "200m", "256Mi") cJSourceList := v1alpha1.CronJobSourceList{} cJSourceList.Items = []v1alpha1.CronJobSource{*cJSource} diff --git a/pkg/kn/commands/source/cronjob/update.go b/pkg/kn/commands/source/cronjob/update.go index b2c22e3ec..e67248df5 100644 --- a/pkg/kn/commands/source/cronjob/update.go +++ b/pkg/kn/commands/source/cronjob/update.go @@ -76,6 +76,21 @@ func NewCronJobUpdateCommand(p *commands.KnParams) *cobra.Command { } b.Sink(toDuckV1Beta1(destination)) } + if cmd.Flags().Changed("requests-cpu") { + b.ResourceRequestsCPU(cronUpdateFlags.resourceRequestsCPU) + } + if cmd.Flags().Changed("requests-memory") { + b.ResourceRequestsMemory(cronUpdateFlags.resourceRequestsMemory) + } + if cmd.Flags().Changed("limits-cpu") { + b.ResourceLimitsCPU(cronUpdateFlags.resourceLimitsCPU) + } + if cmd.Flags().Changed("limits-memory") { + b.ResourceLimitsMemory(cronUpdateFlags.resourceLimitsMemory) + } + if cmd.Flags().Changed("service-account") { + b.ServiceAccount(cronUpdateFlags.serviceAccountName) + } err = cronSourceClient.UpdateCronJobSource(b.Build()) if err == nil { fmt.Fprintf(cmd.OutOrStdout(), "CronJob source '%s' updated in namespace '%s'.\n", name, cronSourceClient.Namespace()) diff --git a/pkg/kn/commands/source/cronjob/update_test.go b/pkg/kn/commands/source/cronjob/update_test.go index 1d96da2da..5f5590909 100644 --- a/pkg/kn/commands/source/cronjob/update_test.go +++ b/pkg/kn/commands/source/cronjob/update_test.go @@ -52,9 +52,10 @@ func TestSimpleUpdate(t *testing.T) { }, Status: v1alpha1.CronJobSourceStatus{}, }, nil) - cronJobRecorder.UpdateCronJobSource(createCronJobSource("testsource", "* * * * */3", "maxwell", "mysvc"), nil) + cronJobRecorder.UpdateCronJobSource(createCronJobSource("testsource", "* * * * */3", "maxwell", "mysvc", "mysa", "100m", "128Mi", "200m", "256Mi"), nil) - out, err := executeCronJobSourceCommand(cronjobClient, nil, "update", "--schedule", "* * * * */3", "testsource") + out, err := executeCronJobSourceCommand(cronjobClient, nil, "update", "--schedule", "* * * * */3", "--service-account", + "mysa", "--requests-cpu", "100m", "--requests-memory", "128Mi", "--limits-cpu", "200m", "--limits-memory", "256Mi", "testsource") assert.NilError(t, err) util.ContainsAll(out, "updated", "default", "testsource") diff --git a/test/e2e/cronjob_test.go b/test/e2e/cronjob_test.go index 94d04cf92..fd533e12a 100644 --- a/test/e2e/cronjob_test.go +++ b/test/e2e/cronjob_test.go @@ -57,6 +57,12 @@ func TestSourceCronJob(t *testing.T) { out, err := test.getResourceFieldsWithJSONPath("cronjobsource", "testcronjobsource2", jpSinkRefNameInSpec) assert.NilError(t, err) assert.Equal(t, out, "testsvc1") + + t.Log("create cronJob source with service account and resources") + test.cronJobSourceCreateWithResources(t, r, "testcronjobsource3", "* * * * */1", "ping", "svc:testsvc0", "default", "100m", "128Mi", "200m", "256Mi") + test.verifyCronJobSourceDescribe(t, r, "testcronjobsource3", "* * * * */1", "ping", "testsvc0", "default", "100m", "128Mi", "200m", "256Mi") + test.cronJobSourceUpdateResources(t, r, "testcronjobsource3", "101m", "129Mi", "201m", "257Mi") + test.verifyCronJobSourceDescribe(t, r, "testcronjobsource3", "* * * * */1", "ping", "testsvc0", "default", "101m", "129Mi", "201m", "257Mi") } func (test *e2eTest) cronJobSourceCreate(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string) { @@ -85,3 +91,24 @@ func (test *e2eTest) cronJobSourceUpdateSink(t *testing.T, r *KnRunResultCollect assert.Check(t, util.ContainsAll(out.Stdout, sourceName, "updated", "namespace", test.kn.namespace)) r.AssertNoError(out) } + +func (test *e2eTest) cronJobSourceCreateWithResources(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string, sa string, requestcpu string, requestmm string, limitcpu string, limitmm string) { + out := test.kn.Run("source", "cronjob", "create", sourceName, + "--schedule", schedule, "--data", data, "--sink", sink, "--service-account", sa, + "--requests-cpu", requestcpu, "--requests-memory", requestmm, "--limits-cpu", limitcpu, "--limits-memory", limitmm) + assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, "cronjob", "source", sourceName, "created", "namespace", test.kn.namespace)) + r.AssertNoError(out) +} + +func (test *e2eTest) cronJobSourceUpdateResources(t *testing.T, r *KnRunResultCollector, sourceName string, requestcpu string, requestmm string, limitcpu string, limitmm string) { + out := test.kn.Run("source", "cronjob", "update", sourceName, + "--requests-cpu", requestcpu, "--requests-memory", requestmm, "--limits-cpu", limitcpu, "--limits-memory", limitmm) + assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, sourceName, "updated", "namespace", test.kn.namespace)) + r.AssertNoError(out) +} + +func (test *e2eTest) verifyCronJobSourceDescribe(t *testing.T, r *KnRunResultCollector, sourceName string, schedule string, data string, sink string, sa string, requestcpu string, requestmm string, limitcpu string, limitmm string) { + out := test.kn.Run("source", "cronjob", "describe", sourceName) + assert.Check(t, util.ContainsAllIgnoreCase(out.Stdout, sourceName, schedule, data, sink, sa, requestcpu, requestmm, limitcpu, limitmm)) + r.AssertNoError(out) +}