From bb3e7fee7f3cbebe042b2e157a46a6777c50a5b0 Mon Sep 17 00:00:00 2001 From: jlandowner Date: Mon, 31 Jul 2023 21:29:03 +0900 Subject: [PATCH 1/7] Add --required-useraddons on comoctl tmpl gen --- api/v1alpha1/template_types.go | 2 + .../templates/dev-code-server/Makefile | 3 +- .../dev-code-server/cosmo-template.yaml | 2 +- .../dev-code-server/team-a-template.yaml | 5 ++- .../dev-code-server/team-a/kustomization.yaml | 10 +++++ .../dev-code-server/team-shared-template.yaml | 2 +- .../templates/iamserviceaccount/Makefile | 10 +++++ .../templates/iamserviceaccount/addon.yaml | 37 +++++++++++++++++++ .../kubernetes/clusterrolebinding.yaml | 12 ++++++ .../kubernetes/kustomization.yaml | 3 ++ .../kubernetes/serviceaccount.yaml | 5 +++ internal/cmd/__snapshots__/template_test.snap | 7 ++-- internal/cmd/template/generate.go | 33 +++++++++-------- 13 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 hack/local-run-test/templates/dev-code-server/team-a/kustomization.yaml create mode 100644 hack/local-run-test/templates/iamserviceaccount/Makefile create mode 100644 hack/local-run-test/templates/iamserviceaccount/addon.yaml create mode 100644 hack/local-run-test/templates/iamserviceaccount/kubernetes/clusterrolebinding.yaml create mode 100644 hack/local-run-test/templates/iamserviceaccount/kubernetes/kustomization.yaml create mode 100644 hack/local-run-test/templates/iamserviceaccount/kubernetes/serviceaccount.yaml diff --git a/api/v1alpha1/template_types.go b/api/v1alpha1/template_types.go index 209d7c17..011010aa 100644 --- a/api/v1alpha1/template_types.go +++ b/api/v1alpha1/template_types.go @@ -20,6 +20,8 @@ const ( TemplateAnnKeyUserRoles = "cosmo-workspace.github.io/userroles" // TemplateAnnKeyForbiddenUserRoles is an annotation key on Template which is not for specific UserRoles TemplateAnnKeyForbiddenUserRoles = "cosmo-workspace.github.io/forbidden-userroles" + // TemplateAnnKeyRequiredAddons is a annotation key for Template which requires useraddons + TemplateAnnKeyRequiredAddons = "cosmo-workspace.github.io/required-useraddons" ) func init() { diff --git a/hack/local-run-test/templates/dev-code-server/Makefile b/hack/local-run-test/templates/dev-code-server/Makefile index 6d4964b6..9f22e32d 100644 --- a/hack/local-run-test/templates/dev-code-server/Makefile +++ b/hack/local-run-test/templates/dev-code-server/Makefile @@ -8,10 +8,11 @@ template: ## Create template cd kubernetes/ && kustomize edit set image $(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_TAG) kustomize build kubernetes/ | cosmoctl tmpl generate -o cosmo-template.yaml --workspace \ --required-vars CODE-SERVER_STORAGE_GB:20,DOCKER_STORAGE:20 - kustomize build kubernetes/ | cosmoctl tmpl generate -o team-a-template.yaml --workspace \ + kustomize build team-a | cosmoctl tmpl generate -o team-a-template.yaml --workspace \ --name team-a-codeserver \ --desc 'only for team A' \ --userroles 'team-a-*' \ + --required-useraddons team-a-serviceaccount \ --required-vars CODE-SERVER_STORAGE_GB:20,DOCKER_STORAGE:20 kustomize build kubernetes/ | cosmoctl tmpl generate -o team-shared-template.yaml --workspace \ --name team-shared-codeserver \ diff --git a/hack/local-run-test/templates/dev-code-server/cosmo-template.yaml b/hack/local-run-test/templates/dev-code-server/cosmo-template.yaml index 568f61d4..080805dd 100644 --- a/hack/local-run-test/templates/dev-code-server/cosmo-template.yaml +++ b/hack/local-run-test/templates/dev-code-server/cosmo-template.yaml @@ -1,4 +1,4 @@ -# Generated by cosmoctl - cosmo v0.10.0 cosmo-workspace 2023 +# Generated by cosmoctl - cosmo v1.0.0-rc2 cosmo-workspace 2023 apiVersion: cosmo-workspace.github.io/v1alpha1 kind: Template metadata: diff --git a/hack/local-run-test/templates/dev-code-server/team-a-template.yaml b/hack/local-run-test/templates/dev-code-server/team-a-template.yaml index 88e1abd1..4a24333c 100644 --- a/hack/local-run-test/templates/dev-code-server/team-a-template.yaml +++ b/hack/local-run-test/templates/dev-code-server/team-a-template.yaml @@ -1,8 +1,9 @@ -# Generated by cosmoctl - cosmo v0.10.0 cosmo-workspace 2023 +# Generated by cosmoctl - cosmo v1.0.0-rc2 cosmo-workspace 2023 apiVersion: cosmo-workspace.github.io/v1alpha1 kind: Template metadata: annotations: + cosmo-workspace.github.io/required-useraddons: team-a-serviceaccount cosmo-workspace.github.io/userroles: team-a-* workspace.cosmo-workspace.github.io/deployment: workspace workspace.cosmo-workspace.github.io/service: workspace @@ -84,7 +85,7 @@ spec: runAsUser: 1000 securityContext: fsGroup: 1000 - serviceAccountName: default + serviceAccountName: iamserviceaccount requiredVars: - default: "20" var: CODE-SERVER_STORAGE_GB diff --git a/hack/local-run-test/templates/dev-code-server/team-a/kustomization.yaml b/hack/local-run-test/templates/dev-code-server/team-a/kustomization.yaml new file mode 100644 index 00000000..b0645cde --- /dev/null +++ b/hack/local-run-test/templates/dev-code-server/team-a/kustomization.yaml @@ -0,0 +1,10 @@ +resources: +- ../kubernetes + +patches: +- target: + kind: Deployment + patch: | + - op: replace + path: /spec/template/spec/serviceAccountName + value: iamserviceaccount \ No newline at end of file diff --git a/hack/local-run-test/templates/dev-code-server/team-shared-template.yaml b/hack/local-run-test/templates/dev-code-server/team-shared-template.yaml index 37c5b2e8..c47bc01d 100644 --- a/hack/local-run-test/templates/dev-code-server/team-shared-template.yaml +++ b/hack/local-run-test/templates/dev-code-server/team-shared-template.yaml @@ -1,4 +1,4 @@ -# Generated by cosmoctl - cosmo v0.10.0 cosmo-workspace 2023 +# Generated by cosmoctl - cosmo v1.0.0-rc2 cosmo-workspace 2023 apiVersion: cosmo-workspace.github.io/v1alpha1 kind: Template metadata: diff --git a/hack/local-run-test/templates/iamserviceaccount/Makefile b/hack/local-run-test/templates/iamserviceaccount/Makefile new file mode 100644 index 00000000..6c00d2a7 --- /dev/null +++ b/hack/local-run-test/templates/iamserviceaccount/Makefile @@ -0,0 +1,10 @@ +all: template + +.PHONY: template +template: + kustomize build kubernetes | cosmoctl tmpl gen --useraddon \ + --name team-a-serviceaccount \ + --userroles=team-a-* \ + --disable-nameprefix \ + --cluster-scope \ + -o addon.yaml diff --git a/hack/local-run-test/templates/iamserviceaccount/addon.yaml b/hack/local-run-test/templates/iamserviceaccount/addon.yaml new file mode 100644 index 00000000..5607a3b8 --- /dev/null +++ b/hack/local-run-test/templates/iamserviceaccount/addon.yaml @@ -0,0 +1,37 @@ +# Generated by cosmoctl - cosmo v1.0.0-rc2 cosmo-workspace 2023 +apiVersion: cosmo-workspace.github.io/v1alpha1 +kind: ClusterTemplate +metadata: + annotations: + cosmo-workspace.github.io/disable-nameprefix: "true" + cosmo-workspace.github.io/userroles: team-a-* + creationTimestamp: null + labels: + cosmo-workspace.github.io/type: useraddon + name: team-a-serviceaccount +spec: + rawYaml: | + apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + cosmo-workspace.github.io/instance: '{{INSTANCE}}' + cosmo-workspace.github.io/template: '{{TEMPLATE}}' + name: iamserviceaccount + namespace: '{{NAMESPACE}}' + --- + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + labels: + cosmo-workspace.github.io/instance: '{{INSTANCE}}' + cosmo-workspace.github.io/template: '{{TEMPLATE}}' + name: '{{USER}}-view' + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: view + subjects: + - kind: ServiceAccount + name: iamserviceaccount + namespace: '{{NAMESPACE}}' diff --git a/hack/local-run-test/templates/iamserviceaccount/kubernetes/clusterrolebinding.yaml b/hack/local-run-test/templates/iamserviceaccount/kubernetes/clusterrolebinding.yaml new file mode 100644 index 00000000..4f73aeba --- /dev/null +++ b/hack/local-run-test/templates/iamserviceaccount/kubernetes/clusterrolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: "{{USER}}-view" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: view +subjects: +- kind: ServiceAccount + name: iamserviceaccount + namespace: "{{NAMESPACE}}" diff --git a/hack/local-run-test/templates/iamserviceaccount/kubernetes/kustomization.yaml b/hack/local-run-test/templates/iamserviceaccount/kubernetes/kustomization.yaml new file mode 100644 index 00000000..a16f3c19 --- /dev/null +++ b/hack/local-run-test/templates/iamserviceaccount/kubernetes/kustomization.yaml @@ -0,0 +1,3 @@ +resources: +- clusterrolebinding.yaml +- serviceaccount.yaml \ No newline at end of file diff --git a/hack/local-run-test/templates/iamserviceaccount/kubernetes/serviceaccount.yaml b/hack/local-run-test/templates/iamserviceaccount/kubernetes/serviceaccount.yaml new file mode 100644 index 00000000..01f0e77f --- /dev/null +++ b/hack/local-run-test/templates/iamserviceaccount/kubernetes/serviceaccount.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: iamserviceaccount + namespace: "{{NAMESPACE}}" diff --git a/internal/cmd/__snapshots__/template_test.snap b/internal/cmd/__snapshots__/template_test.snap index 9d576cab..e817bbc2 100644 --- a/internal/cmd/__snapshots__/template_test.snap +++ b/internal/cmd/__snapshots__/template_test.snap @@ -466,15 +466,16 @@ Flags: --cluster-scope generate ClusterTemplate (default generate namespaced Template) --desc string template description --disable-nameprefix disable adding instance name prefix on child resource name - --forbidden-userroles string user roles NOT to show this template (e.g. 'teama-*', 'teamb-admin', etc.) + --forbidden-userroles strings user roles NOT to show this template (e.g. 'teama-*', 'teamb-admin', etc.) -h, --help help for generate -n, --name string template name (use directory name if not specified) -o, --output string write output into file (default: Stdout) - --required-vars string template custom vars to be replaced by instance. format --required-vars VAR1,VAR2:default-value + --required-useraddons strings required user addons + --required-vars strings template custom vars to be replaced by instance. format --required-vars VAR1,VAR2:default-value --set-default-user-addon set default user addon --user-addon template as type useraddon --useraddon template as type useraddon - --userroles string user roles to show this template (e.g. 'teama-*', 'teamb-admin', etc.) + --userroles strings user roles to show this template (e.g. 'teama-*', 'teamb-admin', etc.) --workspace template as type workspace --workspace-deployment-name string Deployment name for Workspace. use with --workspace (auto detected if not specified) --workspace-main-service-port-name string ServicePort name for Workspace main container port. use with --workspace (auto detected if not specified) diff --git a/internal/cmd/template/generate.go b/internal/cmd/template/generate.go index a7149849..fda89990 100644 --- a/internal/cmd/template/generate.go +++ b/internal/cmd/template/generate.go @@ -32,7 +32,7 @@ type generateOption struct { Name string OutputFile string - RequiredVars string + RequiredVars []string Desc string TypeWorkspace bool @@ -41,8 +41,9 @@ type generateOption struct { SetDefaultUserAddon bool DisableNamePrefix bool ClusterScope bool - UserRoles string - ForbiddenUserRoles string + UserRoles []string + ForbiddenUserRoles []string + RequiredUserAddons []string tmpl cosmov1alpha1.TemplateObject } @@ -54,7 +55,7 @@ func generateCmd(cmd *cobra.Command, cliOpt *cmdutil.CliOptions) *cobra.Command cmd.Flags().StringVarP(&o.Name, "name", "n", "", "template name (use directory name if not specified)") cmd.Flags().StringVarP(&o.OutputFile, "output", "o", "", "write output into file (default: Stdout)") - cmd.Flags().StringVar(&o.RequiredVars, "required-vars", "", "template custom vars to be replaced by instance. format --required-vars VAR1,VAR2:default-value") + cmd.Flags().StringSliceVar(&o.RequiredVars, "required-vars", []string{}, "template custom vars to be replaced by instance. format --required-vars VAR1,VAR2:default-value") cmd.Flags().StringVar(&o.Desc, "desc", "", "template description") cmd.Flags().BoolVar(&o.TypeWorkspace, "workspace", false, "template as type workspace") @@ -68,8 +69,9 @@ func generateCmd(cmd *cobra.Command, cliOpt *cmdutil.CliOptions) *cobra.Command cmd.Flags().BoolVar(&o.DisableNamePrefix, "disable-nameprefix", false, "disable adding instance name prefix on child resource name") cmd.Flags().BoolVar(&o.ClusterScope, "cluster-scope", false, "generate ClusterTemplate (default generate namespaced Template)") - cmd.Flags().StringVar(&o.UserRoles, "userroles", "", "user roles to show this template (e.g. 'teama-*', 'teamb-admin', etc.)") - cmd.Flags().StringVar(&o.ForbiddenUserRoles, "forbidden-userroles", "", "user roles NOT to show this template (e.g. 'teama-*', 'teamb-admin', etc.)") + cmd.Flags().StringSliceVar(&o.UserRoles, "userroles", []string{}, "user roles to show this template (e.g. 'teama-*', 'teamb-admin', etc.)") + cmd.Flags().StringSliceVar(&o.ForbiddenUserRoles, "forbidden-userroles", []string{}, "user roles NOT to show this template (e.g. 'teama-*', 'teamb-admin', etc.)") + cmd.Flags().StringSliceVar(&o.RequiredUserAddons, "required-useraddons", []string{}, "required user addons") return cmd } @@ -127,11 +129,9 @@ func (o *generateOption) Complete(cmd *cobra.Command, args []string) error { } } - if o.RequiredVars != "" { - varsList := strings.Split(o.RequiredVars, ",") - - vars := make([]cosmov1alpha1.RequiredVarSpec, 0, len(varsList)) - for _, v := range varsList { + if len(o.RequiredVars) > 0 { + vars := make([]cosmov1alpha1.RequiredVarSpec, 0, len(o.RequiredVars)) + for _, v := range o.RequiredVars { vcol := strings.Split(v, ":") varSpec := cosmov1alpha1.RequiredVarSpec{Var: vcol[0]} if len(vcol) > 1 { @@ -170,11 +170,14 @@ func (o *generateOption) Complete(cmd *cobra.Command, args []string) error { } } - if o.UserRoles != "" { - ann[cosmov1alpha1.TemplateAnnKeyUserRoles] = o.UserRoles + if len(o.UserRoles) > 0 { + ann[cosmov1alpha1.TemplateAnnKeyUserRoles] = strings.Join(o.UserRoles, ",") + } + if len(o.ForbiddenUserRoles) > 0 { + ann[cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles] = strings.Join(o.ForbiddenUserRoles, ",") } - if o.ForbiddenUserRoles != "" { - ann[cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles] = o.ForbiddenUserRoles + if len(o.RequiredUserAddons) > 0 { + ann[cosmov1alpha1.TemplateAnnKeyRequiredAddons] = strings.Join(o.RequiredUserAddons, ",") } o.tmpl.SetAnnotations(ann) From 4b40f798d70af08873e57f8c8c04472715610aeb Mon Sep 17 00:00:00 2001 From: jlandowner Date: Tue, 1 Aug 2023 21:44:32 +0900 Subject: [PATCH 2/7] remove forbidden-roles --- api/v1alpha1/template_types.go | 2 - internal/cmd/__snapshots__/template_test.snap | 46 ++++++------ internal/cmd/template/generate.go | 6 +- internal/cmd/template/get.go | 49 +++++++++---- internal/cmd/template_test.go | 2 +- pkg/kosmo/template.go | 19 +---- pkg/kosmo/template_test.go | 72 ------------------- 7 files changed, 64 insertions(+), 132 deletions(-) diff --git a/api/v1alpha1/template_types.go b/api/v1alpha1/template_types.go index 011010aa..f8928b99 100644 --- a/api/v1alpha1/template_types.go +++ b/api/v1alpha1/template_types.go @@ -18,8 +18,6 @@ const ( // TemplateAnnKeyUserRoles is an annotation key on Template for specific UserRoles TemplateAnnKeyUserRoles = "cosmo-workspace.github.io/userroles" - // TemplateAnnKeyForbiddenUserRoles is an annotation key on Template which is not for specific UserRoles - TemplateAnnKeyForbiddenUserRoles = "cosmo-workspace.github.io/forbidden-userroles" // TemplateAnnKeyRequiredAddons is a annotation key for Template which requires useraddons TemplateAnnKeyRequiredAddons = "cosmo-workspace.github.io/required-useraddons" ) diff --git a/internal/cmd/__snapshots__/template_test.snap b/internal/cmd/__snapshots__/template_test.snap index e817bbc2..9414a37e 100644 --- a/internal/cmd/__snapshots__/template_test.snap +++ b/internal/cmd/__snapshots__/template_test.snap @@ -218,14 +218,13 @@ spec: ['cosmoctl [template] [generate] ✅ success in normal context: template generate --user-addon --set-default-user-addon --disable-nameprefix 2'] SnapShot = 'success' -['cosmoctl [template] [generate] ✅ success in normal context: template generate --workspace --userroles teama-* --forbidden-userroles teama-operator,teama-testuser 1'] +['cosmoctl [template] [generate] ✅ success in normal context: template generate --workspace --userroles teama-* 1'] SnapShot = """ # Generated by cosmoctl - cosmo vX.X.X cosmo-workspace 2023 apiVersion: cosmo-workspace.github.io/v1alpha1 kind: Template metadata: annotations: - cosmo-workspace.github.io/forbidden-userroles: teama-operator,teama-testuser cosmo-workspace.github.io/userroles: teama-* workspace.cosmo-workspace.github.io/deployment: workspace workspace.cosmo-workspace.github.io/service: workspace @@ -328,7 +327,7 @@ spec: """ -['cosmoctl [template] [generate] ✅ success in normal context: template generate --workspace --userroles teama-* --forbidden-userroles teama-operator,teama-testuser 2'] +['cosmoctl [template] [generate] ✅ success in normal context: template generate --workspace --userroles teama-* 2'] SnapShot = 'success' ['cosmoctl [template] [generate] ✅ success in normal context: template generate --workspace --workspace-main-service-port-name main --required-vars HOGE:HOGEHOGE,FUGA:FUGAFUGA 1'] @@ -466,7 +465,6 @@ Flags: --cluster-scope generate ClusterTemplate (default generate namespaced Template) --desc string template description --disable-nameprefix disable adding instance name prefix on child resource name - --forbidden-userroles strings user roles NOT to show this template (e.g. 'teama-*', 'teamb-admin', etc.) -h, --help help for generate -n, --name string template name (use directory name if not specified) -o, --output string write output into file (default: Stdout) @@ -493,9 +491,9 @@ SnapShot = 'validation error: --workspace and --user-addon cannot be specified c ['cosmoctl [template] [get] ✅ success in normal context: template get --workspace 1'] SnapShot = """ -NAME REQUIRED-VARS DEPLOYMENT/SERVICE -template1 {{HOGE}},{{FUGA}} /workspace -template2 {{HOGE}},{{FUGA}} /workspace +NAME REQUIRED_VARS USERROLE REQUIRED_ADDONS +template1 {{HOGE}},{{FUGA}} +template2 {{HOGE}},{{FUGA}} """ ['cosmoctl [template] [get] ✅ success in normal context: template get --workspace 2'] @@ -503,11 +501,11 @@ SnapShot = 'success' ['cosmoctl [template] [get] ✅ success in normal context: template get 1'] SnapShot = """ -NAME REQUIREDVARS TYPE ISCLUSTERSCOPE FORROLE FORBIDDENROLE -template1 {{HOGE}},{{FUGA}} workspace false -template2 {{HOGE}},{{FUGA}} workspace false -template3 {{HOGE}},{{FUGA}} useraddon false -cluster-template1 {{HOGE}},{{FUGA}} useraddon true +TYPE NAME CLUSTERSCOPE REQUIRED_VARS DEFAULT USERROLE REQUIRED_ADDONS +workspace template1 false {{HOGE}},{{FUGA}} true +workspace template2 false {{HOGE}},{{FUGA}} true +useraddon template3 false {{HOGE}},{{FUGA}} true +useraddon cluster-template1 true {{HOGE}},{{FUGA}} """ ['cosmoctl [template] [get] ✅ success in normal context: template get 2'] @@ -515,7 +513,7 @@ SnapShot = 'success' ['cosmoctl [template] [get] ✅ success in normal context: template get notfound 1'] SnapShot = """ -NAME REQUIREDVARS TYPE ISCLUSTERSCOPE FORROLE FORBIDDENROLE +TYPE NAME CLUSTERSCOPE REQUIRED_VARS DEFAULT USERROLE REQUIRED_ADDONS """ ['cosmoctl [template] [get] ✅ success in normal context: template get notfound 2'] @@ -523,8 +521,8 @@ SnapShot = 'success' ['cosmoctl [template] [get] ✅ success in normal context: template get template2 --workspace 1'] SnapShot = """ -NAME REQUIRED-VARS DEPLOYMENT/SERVICE -template2 {{HOGE}},{{FUGA}} /workspace +NAME REQUIRED_VARS USERROLE REQUIRED_ADDONS +template2 {{HOGE}},{{FUGA}} """ ['cosmoctl [template] [get] ✅ success in normal context: template get template2 --workspace 2'] @@ -532,8 +530,8 @@ SnapShot = 'success' ['cosmoctl [template] [get] ✅ success in normal context: template get template2 1'] SnapShot = """ -NAME REQUIREDVARS TYPE ISCLUSTERSCOPE FORROLE FORBIDDENROLE -template2 {{HOGE}},{{FUGA}} workspace false +TYPE NAME CLUSTERSCOPE REQUIRED_VARS DEFAULT USERROLE REQUIRED_ADDONS +workspace template2 false {{HOGE}},{{FUGA}} true """ ['cosmoctl [template] [get] ✅ success in normal context: template get template2 2'] @@ -541,9 +539,9 @@ SnapShot = 'success' ['cosmoctl [template] [get] ✅ success in normal context: template get template2 cluster-template1 notfound 1'] SnapShot = """ -NAME REQUIREDVARS TYPE ISCLUSTERSCOPE FORROLE FORBIDDENROLE -template2 {{HOGE}},{{FUGA}} workspace false -cluster-template1 {{HOGE}},{{FUGA}} useraddon true +TYPE NAME CLUSTERSCOPE REQUIRED_VARS DEFAULT USERROLE REQUIRED_ADDONS +workspace template2 false {{HOGE}},{{FUGA}} true +useraddon cluster-template1 true {{HOGE}},{{FUGA}} """ ['cosmoctl [template] [get] ✅ success in normal context: template get template2 cluster-template1 notfound 2'] @@ -551,9 +549,9 @@ SnapShot = 'success' ['cosmoctl [template] [get] ✅ success in normal context: template get template2 template3 1'] SnapShot = """ -NAME REQUIREDVARS TYPE ISCLUSTERSCOPE FORROLE FORBIDDENROLE -template2 {{HOGE}},{{FUGA}} workspace false -template3 {{HOGE}},{{FUGA}} useraddon false +TYPE NAME CLUSTERSCOPE REQUIRED_VARS DEFAULT USERROLE REQUIRED_ADDONS +workspace template2 false {{HOGE}},{{FUGA}} true +useraddon template3 false {{HOGE}},{{FUGA}} true """ ['cosmoctl [template] [get] ✅ success in normal context: template get template2 template3 2'] @@ -567,6 +565,7 @@ Usage: Flags: -h, --help help for get + --useraddon show type useraddon template --workspace show type workspace template Global Flags: @@ -587,6 +586,7 @@ Usage: Flags: -h, --help help for get + --useraddon show type useraddon template --workspace show type workspace template Global Flags: diff --git a/internal/cmd/template/generate.go b/internal/cmd/template/generate.go index fda89990..178a93b4 100644 --- a/internal/cmd/template/generate.go +++ b/internal/cmd/template/generate.go @@ -42,7 +42,6 @@ type generateOption struct { DisableNamePrefix bool ClusterScope bool UserRoles []string - ForbiddenUserRoles []string RequiredUserAddons []string tmpl cosmov1alpha1.TemplateObject @@ -70,7 +69,7 @@ func generateCmd(cmd *cobra.Command, cliOpt *cmdutil.CliOptions) *cobra.Command cmd.Flags().BoolVar(&o.ClusterScope, "cluster-scope", false, "generate ClusterTemplate (default generate namespaced Template)") cmd.Flags().StringSliceVar(&o.UserRoles, "userroles", []string{}, "user roles to show this template (e.g. 'teama-*', 'teamb-admin', etc.)") - cmd.Flags().StringSliceVar(&o.ForbiddenUserRoles, "forbidden-userroles", []string{}, "user roles NOT to show this template (e.g. 'teama-*', 'teamb-admin', etc.)") + cmd.Flags().StringSliceVar(&o.RequiredUserAddons, "required-useraddons", []string{}, "required user addons") return cmd @@ -173,9 +172,6 @@ func (o *generateOption) Complete(cmd *cobra.Command, args []string) error { if len(o.UserRoles) > 0 { ann[cosmov1alpha1.TemplateAnnKeyUserRoles] = strings.Join(o.UserRoles, ",") } - if len(o.ForbiddenUserRoles) > 0 { - ann[cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles] = strings.Join(o.ForbiddenUserRoles, ",") - } if len(o.RequiredUserAddons) > 0 { ann[cosmov1alpha1.TemplateAnnKeyRequiredAddons] = strings.Join(o.RequiredUserAddons, ",") } diff --git a/internal/cmd/template/get.go b/internal/cmd/template/get.go index 51f89ba3..cd05a4aa 100644 --- a/internal/cmd/template/get.go +++ b/internal/cmd/template/get.go @@ -14,13 +14,13 @@ import ( cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/cmdutil" "github.com/cosmo-workspace/cosmo/pkg/kubeutil" - "github.com/cosmo-workspace/cosmo/pkg/workspace" ) type GetOption struct { *cmdutil.CliOptions TemplateNames []string TypeWorkspace bool + TypeUserAddon bool tmpltype string } @@ -30,6 +30,7 @@ func GetCmd(cmd *cobra.Command, cliOpt *cmdutil.CliOptions) *cobra.Command { cmd.PersistentPreRunE = o.PreRunE cmd.RunE = cmdutil.RunEHandler(o.RunE) cmd.PersistentFlags().BoolVar(&o.TypeWorkspace, "workspace", false, "show type workspace template") + cmd.PersistentFlags().BoolVar(&o.TypeUserAddon, "useraddon", false, "show type useraddon template") return cmd } @@ -49,6 +50,8 @@ func (o *GetOption) Validate(cmd *cobra.Command, args []string) error { } if o.TypeWorkspace { o.tmpltype = cosmov1alpha1.TemplateLabelEnumTypeWorkspace + } else if o.TypeUserAddon { + o.tmpltype = cosmov1alpha1.TemplateLabelEnumTypeUserAddon } return nil } @@ -104,29 +107,50 @@ func (o *GetOption) RunE(cmd *cobra.Command, args []string) error { switch o.tmpltype { case cosmov1alpha1.TemplateLabelEnumTypeWorkspace: - columnNames := []string{"NAME", "REQUIRED-VARS", "DEPLOYMENT/SERVICE"} + columnNames := []string{"NAME", "REQUIRED_VARS", "USERROLE", "REQUIRED_ADDONS"} fmt.Fprintf(w, "%s\n", strings.Join(columnNames, "\t")) for _, v := range tmpls { - cfg, err := workspace.ConfigFromTemplateAnnotations(v.(*cosmov1alpha1.Template)) - if err != nil { - o.Logr.Error(err, "failed to get workspace config", "template", v.GetName()) - continue + vars := make([]string, 0, len(v.GetSpec().RequiredVars)) + for _, t := range v.GetSpec().RequiredVars { + vars = append(vars, t.Var) + } + rawTmplVars := strings.Join(vars, ",") + + var forRoles, requiredAddons string + ann := v.GetAnnotations() + if ann != nil { + forRoles = ann[cosmov1alpha1.TemplateAnnKeyUserRoles] + requiredAddons = ann[cosmov1alpha1.TemplateAnnKeyRequiredAddons] } + rowdata := []string{v.GetName(), rawTmplVars, forRoles, requiredAddons} + fmt.Fprintf(w, "%s\n", strings.Join(rowdata, "\t")) + } + + case cosmov1alpha1.TemplateLabelEnumTypeUserAddon: + columnNames := []string{"NAME", "REQUIRED_VARS", "CLUSTERSCOPE", "DEFAULT", "USERROLE"} + fmt.Fprintf(w, "%s\n", strings.Join(columnNames, "\t")) + + for _, v := range tmpls { vars := make([]string, 0, len(v.GetSpec().RequiredVars)) for _, t := range v.GetSpec().RequiredVars { vars = append(vars, t.Var) } rawTmplVars := strings.Join(vars, ",") - resources := fmt.Sprintf("%s/%s", cfg.DeploymentName, cfg.ServiceName) - rowdata := []string{v.GetName(), rawTmplVars, resources} + var isDefault, forRoles string + ann := v.GetAnnotations() + if ann != nil { + isDefault = ann[cosmov1alpha1.UserAddonTemplateAnnKeyDefaultUserAddon] + forRoles = ann[cosmov1alpha1.TemplateAnnKeyUserRoles] + } + rowdata := []string{v.GetName(), rawTmplVars, strconv.FormatBool(v.GetScope() == meta.RESTScopeRoot), isDefault, forRoles} fmt.Fprintf(w, "%s\n", strings.Join(rowdata, "\t")) } default: - columnNames := []string{"NAME", "REQUIREDVARS", "TYPE", "ISCLUSTERSCOPE", "FORROLE", "FORBIDDENROLE"} + columnNames := []string{"TYPE", "NAME", "CLUSTERSCOPE", "REQUIRED_VARS", "DEFAULT", "USERROLE", "REQUIRED_ADDONS"} fmt.Fprintf(w, "%s\n", strings.Join(columnNames, "\t")) for _, v := range tmpls { @@ -136,15 +160,16 @@ func (o *GetOption) RunE(cmd *cobra.Command, args []string) error { } rawTmplVars := strings.Join(vars, ",") - var forRoles, forbiddenRoles string + var isDefault, forRoles, requiredAddons string ann := v.GetAnnotations() if ann != nil { + isDefault = ann[cosmov1alpha1.UserAddonTemplateAnnKeyDefaultUserAddon] forRoles = ann[cosmov1alpha1.TemplateAnnKeyUserRoles] - forbiddenRoles = ann[cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles] + requiredAddons = ann[cosmov1alpha1.TemplateAnnKeyRequiredAddons] } tmplType := v.GetLabels()[cosmov1alpha1.TemplateLabelKeyType] - rowdata := []string{v.GetName(), rawTmplVars, tmplType, strconv.FormatBool(v.GetScope() == meta.RESTScopeRoot), forRoles, forbiddenRoles} + rowdata := []string{tmplType, v.GetName(), strconv.FormatBool(v.GetScope() == meta.RESTScopeRoot), rawTmplVars, isDefault, forRoles, requiredAddons} fmt.Fprintf(w, "%s\n", strings.Join(rowdata, "\t")) } } diff --git a/internal/cmd/template_test.go b/internal/cmd/template_test.go index 52a88a22..43f8d61f 100644 --- a/internal/cmd/template_test.go +++ b/internal/cmd/template_test.go @@ -101,7 +101,7 @@ var _ = Describe("cosmoctl [template]", func() { Entry(desc, "template", "generate", "--workspace", "--workspace-main-service-port-name", "main", "-o", "/tmp/test-cosmo-template"), Entry(desc, "template", "generate", "--user-addon", "--set-default-user-addon", "--disable-nameprefix"), Entry(desc, "template", "generate", "--user-addon", "--set-default-user-addon", "--cluster-scope", "--disable-nameprefix"), - Entry(desc, "template", "generate", "--workspace", "--userroles", "teama-*", "--forbidden-userroles", "teama-operator,teama-testuser"), + Entry(desc, "template", "generate", "--workspace", "--userroles", "teama-*"), ) DescribeTable("❌ fail with invalid args:", diff --git a/pkg/kosmo/template.go b/pkg/kosmo/template.go index 0248f875..9dabdb89 100644 --- a/pkg/kosmo/template.go +++ b/pkg/kosmo/template.go @@ -33,24 +33,9 @@ func isAllowedToUseTemplate(ctx context.Context, tmpl cosmov1alpha1.TemplateObje } forRoles := ann[cosmov1alpha1.TemplateAnnKeyUserRoles] - forbiddenRoles := ann[cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles] - - if forbiddenRoles != "" { - for _, forbiddenRole := range strings.Split(forbiddenRoles, ",") { - for _, role := range roles { - debugAll.Info("matching to forbiddenRole...", "forbiddenRole", forbiddenRole, "role", role.Name, "tmpl", tmpl.GetName()) - if matched, err := filepath.Match(forbiddenRole, role.Name); err == nil && matched { - // the role is forbidden - debugAll.Info("forbidden: roles matched to forbiddenRole", "forbiddenRole", forbiddenRole, "role", role.Name, "tmpl", tmpl.GetName()) - return false - } - } - } - } - if forRoles == "" { // all allowed - debugAll.Info("allowed: roles does not matched all forbiddenRoles and NO forRoles", "forbiddenRoles", forbiddenRoles, "forRoles", forRoles, "tmpl", tmpl.GetName()) + debugAll.Info("allowed: roles does not matched all forbiddenRoles and NO forRoles", "forRoles", forRoles, "tmpl", tmpl.GetName()) return true } for _, forRole := range strings.Split(forRoles, ",") { @@ -63,7 +48,7 @@ func isAllowedToUseTemplate(ctx context.Context, tmpl cosmov1alpha1.TemplateObje } } // the role does not match the specified roles - debugAll.Info("forbidden: roles does not match forRoles", forbiddenRoles, forRoles) + debugAll.Info("forbidden: roles does not match forRoles", forRoles) return false } diff --git a/pkg/kosmo/template_test.go b/pkg/kosmo/template_test.go index 7eeb8976..b24a710d 100644 --- a/pkg/kosmo/template_test.go +++ b/pkg/kosmo/template_test.go @@ -101,23 +101,6 @@ func Test_isAllowedToUseTemplate(t *testing.T) { }, want: true, }, - { - name: "forbidden if role is matched to forbidden role", - args: args{ - tmpl: &cosmov1alpha1.Template{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sword-of-gryffindor", - Annotations: map[string]string{ - cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles: "slytherin", - }, - }, - }, - roles: []cosmov1alpha1.UserRole{ - {Name: "slytherin"}, - }, - }, - want: false, - }, { name: "forbidden if role is not matched to allowed role", args: args{ @@ -135,25 +118,6 @@ func Test_isAllowedToUseTemplate(t *testing.T) { }, want: false, }, - { - name: "forbidden if role is matched to allowed role but also matched to forbidden role", - args: args{ - tmpl: &cosmov1alpha1.Template{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sword-of-gryffindor", - Annotations: map[string]string{ - cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles: "slytherin", - cosmov1alpha1.TemplateAnnKeyUserRoles: "gryffindor", - }, - }, - }, - roles: []cosmov1alpha1.UserRole{ - {Name: "slytherin"}, - {Name: "gryffindor"}, - }, - }, - want: false, - }, { name: "allowed if wildcard match for allowed role", args: args{ @@ -205,42 +169,6 @@ func Test_isAllowedToUseTemplate(t *testing.T) { }, want: false, }, - { - name: "forbidden if both allowed role wildcard and forbidden role matches", - args: args{ - tmpl: &cosmov1alpha1.Template{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sword-of-gryffindor", - Annotations: map[string]string{ - cosmov1alpha1.TemplateAnnKeyUserRoles: "gryffindor-*", - cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles: "gryffindor-faker", - }, - }, - }, - roles: []cosmov1alpha1.UserRole{ - {Name: "gryffindor-faker"}, - }, - }, - want: false, - }, - { - name: "forbidden if both allowed role wildcard and forbidden wildcard matches", - args: args{ - tmpl: &cosmov1alpha1.Template{ - ObjectMeta: metav1.ObjectMeta{ - Name: "sword-of-gryffindor", - Annotations: map[string]string{ - cosmov1alpha1.TemplateAnnKeyUserRoles: "gryffindor-*", - cosmov1alpha1.TemplateAnnKeyForbiddenUserRoles: "gryffindor-f*", - }, - }, - }, - roles: []cosmov1alpha1.UserRole{ - {Name: "gryffindor-faker"}, - }, - }, - want: false, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From b248e4e01330cadaf34037c8a02dced103d08c1d Mon Sep 17 00:00:00 2001 From: jlandowner Date: Wed, 2 Aug 2023 10:33:15 +0900 Subject: [PATCH 3/7] Add required addon on protobuf and filter template in UI --- hack/local-run-test/Makefile | 1 + .../templates/dev-code-server/Makefile | 8 +- .../dev-code-server/team-shared-template.yaml | 92 ------------------- .../templates/iamserviceaccount/Makefile | 1 + internal/dashboard/template_handler.go | 9 ++ pkg/kubeutil/utils.go | 13 +++ proto/gen/dashboard/v1alpha1/template.pb.go | 47 ++++++---- proto/gen/index.md | 1 + .../dashboard/v1alpha1/template.proto | 2 + .../gen/dashboard/v1alpha1/template_pb.ts | 6 ++ .../views/organisms/WorkspaceActionDialog.tsx | 19 +++- 11 files changed, 79 insertions(+), 120 deletions(-) delete mode 100644 hack/local-run-test/templates/dev-code-server/team-shared-template.yaml diff --git a/hack/local-run-test/Makefile b/hack/local-run-test/Makefile index ed3cdf9c..66f101c4 100644 --- a/hack/local-run-test/Makefile +++ b/hack/local-run-test/Makefile @@ -309,6 +309,7 @@ apply-template: kubectl cosmoctl ## Apply template. for i in `ls ../../example/useraddons/*/*.yaml`; do until (kubectl apply -f $$i) do sleep 1; done; done for i in `ls ../../example/workspaces/*.yaml`; do until (kubectl apply -f $$i) do sleep 1; done; done $(MAKE) -C templates/dev-code-server apply + kubectl apply -f templates/iamserviceaccount/addon.yaml add-user: kubectl cosmoctl ## add user diff --git a/hack/local-run-test/templates/dev-code-server/Makefile b/hack/local-run-test/templates/dev-code-server/Makefile index 9f22e32d..264f97dc 100644 --- a/hack/local-run-test/templates/dev-code-server/Makefile +++ b/hack/local-run-test/templates/dev-code-server/Makefile @@ -14,14 +14,8 @@ template: ## Create template --userroles 'team-a-*' \ --required-useraddons team-a-serviceaccount \ --required-vars CODE-SERVER_STORAGE_GB:20,DOCKER_STORAGE:20 - kustomize build kubernetes/ | cosmoctl tmpl generate -o team-shared-template.yaml --workspace \ - --name team-shared-codeserver \ - --desc 'shared template excluding team-a-dev' \ - --forbidden-userroles team-a-dev \ - --required-vars CODE-SERVER_STORAGE_GB:20,DOCKER_STORAGE:20 .PHONY: apply apply: template ## Apply template kubectl apply -f cosmo-template.yaml - kubectl apply -f team-a-template.yaml - kubectl apply -f team-shared-template.yaml + kubectl apply -f team-a-template.yaml \ No newline at end of file diff --git a/hack/local-run-test/templates/dev-code-server/team-shared-template.yaml b/hack/local-run-test/templates/dev-code-server/team-shared-template.yaml deleted file mode 100644 index c47bc01d..00000000 --- a/hack/local-run-test/templates/dev-code-server/team-shared-template.yaml +++ /dev/null @@ -1,92 +0,0 @@ -# Generated by cosmoctl - cosmo v1.0.0-rc2 cosmo-workspace 2023 -apiVersion: cosmo-workspace.github.io/v1alpha1 -kind: Template -metadata: - annotations: - cosmo-workspace.github.io/forbidden-userroles: team-a-dev - workspace.cosmo-workspace.github.io/deployment: workspace - workspace.cosmo-workspace.github.io/service: workspace - workspace.cosmo-workspace.github.io/service-main-port: main - creationTimestamp: null - labels: - cosmo-workspace.github.io/type: workspace - name: team-shared-codeserver -spec: - description: shared template excluding team-a-dev - rawYaml: | - apiVersion: v1 - kind: Service - metadata: - labels: - cosmo-workspace.github.io/instance: '{{INSTANCE}}' - cosmo-workspace.github.io/template: '{{TEMPLATE}}' - name: '{{INSTANCE}}-workspace' - namespace: '{{NAMESPACE}}' - spec: - ports: - - name: main - port: 18080 - protocol: TCP - selector: - cosmo-workspace.github.io/instance: '{{INSTANCE}}' - cosmo-workspace.github.io/template: '{{TEMPLATE}}' - type: ClusterIP - --- - apiVersion: apps/v1 - kind: Deployment - metadata: - labels: - cosmo-workspace.github.io/instance: '{{INSTANCE}}' - cosmo-workspace.github.io/template: '{{TEMPLATE}}' - name: '{{INSTANCE}}-workspace' - namespace: '{{NAMESPACE}}' - spec: - replicas: 1 - selector: - matchLabels: - cosmo-workspace.github.io/instance: '{{INSTANCE}}' - cosmo-workspace.github.io/template: '{{TEMPLATE}}' - strategy: - type: Recreate - template: - metadata: - labels: - cosmo-workspace.github.io/instance: '{{INSTANCE}}' - cosmo-workspace.github.io/template: '{{TEMPLATE}}' - spec: - containers: - - command: - - sh - - -c - - | - /usr/bin/entrypoint.sh --log debug --auth=none --bind-addr 0.0.0.0:18080 --app-name=cosmo . - image: ghcr.io/cosmo-workspace/dev-code-server:v0.0.2-4.13.0 - imagePullPolicy: Always - livenessProbe: - httpGet: - path: / - port: 18080 - name: code-server - ports: - - containerPort: 18080 - name: main - protocol: TCP - readinessProbe: - httpGet: - path: / - port: 18080 - resources: - limits: - memory: 6Gi - requests: - memory: 100Mi - securityContext: - runAsUser: 1000 - securityContext: - fsGroup: 1000 - serviceAccountName: default - requiredVars: - - default: "20" - var: CODE-SERVER_STORAGE_GB - - default: "20" - var: DOCKER_STORAGE diff --git a/hack/local-run-test/templates/iamserviceaccount/Makefile b/hack/local-run-test/templates/iamserviceaccount/Makefile index 6c00d2a7..8d98092e 100644 --- a/hack/local-run-test/templates/iamserviceaccount/Makefile +++ b/hack/local-run-test/templates/iamserviceaccount/Makefile @@ -7,4 +7,5 @@ template: --userroles=team-a-* \ --disable-nameprefix \ --cluster-scope \ + --required-useraddons resource-limitter \ -o addon.yaml diff --git a/internal/dashboard/template_handler.go b/internal/dashboard/template_handler.go index f6cc3fb8..3478c7e3 100644 --- a/internal/dashboard/template_handler.go +++ b/internal/dashboard/template_handler.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "strconv" + "strings" connect_go "github.com/bufbuild/connect-go" "google.golang.org/protobuf/types/known/emptypb" @@ -12,6 +13,7 @@ import ( cosmov1alpha1 "github.com/cosmo-workspace/cosmo/api/v1alpha1" "github.com/cosmo-workspace/cosmo/pkg/clog" + "github.com/cosmo-workspace/cosmo/pkg/kubeutil" dashv1alpha1 "github.com/cosmo-workspace/cosmo/proto/gen/dashboard/v1alpha1" "github.com/cosmo-workspace/cosmo/proto/gen/dashboard/v1alpha1/dashboardv1alpha1connect" ) @@ -100,5 +102,12 @@ func convertTemplateToDashv1alpha1Template(tmpl cosmov1alpha1.TemplateObject) *d Description: tmpl.GetSpec().Description, RequiredVars: requiredVars, IsClusterScope: tmpl.GetScope() == meta.RESTScopeRoot, + RequiredUseraddons: func() []string { + requiredAddons := kubeutil.GetAnnotation(tmpl, cosmov1alpha1.TemplateAnnKeyRequiredAddons) + if requiredAddons != "" { + return strings.Split(requiredAddons, ",") + } + return nil + }(), } } diff --git a/pkg/kubeutil/utils.go b/pkg/kubeutil/utils.go index 6e861dbc..e7bdb28b 100644 --- a/pkg/kubeutil/utils.go +++ b/pkg/kubeutil/utils.go @@ -94,3 +94,16 @@ func PodStatusReason(pod corev1.Pod) string { return reason } + +type AnnotationHolder interface { + GetAnnotations() map[string]string + SetAnnotations(map[string]string) +} + +func GetAnnotation(obj AnnotationHolder, key string) string { + ann := obj.GetAnnotations() + if ann == nil { + return "" + } + return ann[key] +} diff --git a/proto/gen/dashboard/v1alpha1/template.pb.go b/proto/gen/dashboard/v1alpha1/template.pb.go index f91e28b2..d4b1d2e1 100644 --- a/proto/gen/dashboard/v1alpha1/template.pb.go +++ b/proto/gen/dashboard/v1alpha1/template.pb.go @@ -89,6 +89,7 @@ type Template struct { RequiredVars []*TemplateRequiredVars `protobuf:"bytes,3,rep,name=required_vars,json=requiredVars,proto3" json:"required_vars,omitempty"` IsDefaultUserAddon *bool `protobuf:"varint,4,opt,name=is_default_user_addon,json=isDefaultUserAddon,proto3,oneof" json:"is_default_user_addon,omitempty"` IsClusterScope bool `protobuf:"varint,5,opt,name=is_cluster_scope,json=isClusterScope,proto3" json:"is_cluster_scope,omitempty"` + RequiredUseraddons []string `protobuf:"bytes,6,rep,name=required_useraddons,json=requiredUseraddons,proto3" json:"required_useraddons,omitempty"` } func (x *Template) Reset() { @@ -158,6 +159,13 @@ func (x *Template) GetIsClusterScope() bool { return false } +func (x *Template) GetRequiredUseraddons() []string { + if x != nil { + return x.RequiredUseraddons + } + return nil +} + var File_dashboard_v1alpha1_template_proto protoreflect.FileDescriptor var file_dashboard_v1alpha1_template_proto_rawDesc = []byte{ @@ -170,7 +178,7 @@ var file_dashboard_v1alpha1_template_proto_rawDesc = []byte{ 0x09, 0x52, 0x07, 0x76, 0x61, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x8b, 0x02, 0x0a, 0x08, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0xbc, 0x02, 0x0a, 0x08, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, @@ -185,23 +193,26 @@ var file_dashboard_v1alpha1_template_proto_rawDesc = []byte{ 0x72, 0x41, 0x64, 0x64, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x73, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x73, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x63, - 0x6f, 0x70, 0x65, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x69, 0x73, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x42, 0xe1, 0x01, - 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0d, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, - 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2f, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, 0x58, - 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x56, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, 0x44, 0x61, 0x73, - 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x44, 0x61, - 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x12, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x61, 0x64, + 0x64, 0x6f, 0x6e, 0x73, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x69, 0x73, 0x5f, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x42, 0xe1, + 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0d, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2d, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, + 0x61, 0x72, 0x64, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x44, 0x58, + 0x58, 0xaa, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2e, 0x56, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x12, 0x44, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, + 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x1e, 0x44, 0x61, + 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x44, + 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/gen/index.md b/proto/gen/index.md index 5dd21036..7a645755 100644 --- a/proto/gen/index.md +++ b/proto/gen/index.md @@ -172,6 +172,7 @@ | required_vars | [TemplateRequiredVars](#dashboard-v1alpha1-TemplateRequiredVars) | repeated | | | is_default_user_addon | [bool](#bool) | optional | | | is_cluster_scope | [bool](#bool) | | | +| required_useraddons | [string](#string) | repeated | | diff --git a/proto/proto/dashboard-apis/dashboard/v1alpha1/template.proto b/proto/proto/dashboard-apis/dashboard/v1alpha1/template.proto index 215b36d8..9fe6e6e4 100644 --- a/proto/proto/dashboard-apis/dashboard/v1alpha1/template.proto +++ b/proto/proto/dashboard-apis/dashboard/v1alpha1/template.proto @@ -22,4 +22,6 @@ message Template { optional bool is_default_user_addon = 4; bool is_cluster_scope = 5; + + repeated string required_useraddons = 6; } diff --git a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/template_pb.ts b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/template_pb.ts index 476841a7..40a9eeb1 100644 --- a/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/template_pb.ts +++ b/web/dashboard-ui/src/proto/gen/dashboard/v1alpha1/template_pb.ts @@ -82,6 +82,11 @@ export class Template extends Message