From 315d6d674c0b8a6850e5c721e7c77af8633a7dfb Mon Sep 17 00:00:00 2001 From: zoetrope Date: Fri, 17 May 2024 10:07:31 +0000 Subject: [PATCH] Support extra parameters in the templates --- api/v1beta1/tenant_types.go | 4 ++ api/v1beta1/zz_generated.deepcopy.go | 7 +++ charts/cattage/crds/tenant.yaml | 5 ++ .../crd/bases/cattage.cybozu.io_tenants.yaml | 6 +++ config/manager/configmap.yaml | 8 ++-- config/samples/tenant.yaml | 4 ++ controllers/tenant_controller.go | 48 +++++++++++++++---- docs/crd_tenant.md | 1 + 8 files changed, 69 insertions(+), 14 deletions(-) diff --git a/api/v1beta1/tenant_types.go b/api/v1beta1/tenant_types.go index 8c28ff6..ab3d83e 100644 --- a/api/v1beta1/tenant_types.go +++ b/api/v1beta1/tenant_types.go @@ -23,6 +23,10 @@ type TenantSpec struct { // If not specified, the default controller is used. // +optional ControllerName string `json:"controllerName,omitempty"` + + // ExtraParams is a map of extra parameters that can be used in the templates. + // +optional + ExtraParams map[string]string `json:"extraParams,omitempty"` } // RootNamespaceSpec defines the desired state of Namespace. diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 88da99c..645dbe5 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -155,6 +155,13 @@ func (in *TenantSpec) DeepCopyInto(out *TenantSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.ExtraParams != nil { + in, out := &in.ExtraParams, &out.ExtraParams + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TenantSpec. diff --git a/charts/cattage/crds/tenant.yaml b/charts/cattage/crds/tenant.yaml index ce094e8..f4bd0b4 100644 --- a/charts/cattage/crds/tenant.yaml +++ b/charts/cattage/crds/tenant.yaml @@ -77,6 +77,11 @@ spec: - roles type: object type: array + extraParams: + additionalProperties: + type: string + description: ExtraParams is a map of extra parameters that can be used in the templates. + type: object rootNamespaces: description: RootNamespaces are the list of root namespaces that belong to this tenant. items: diff --git a/config/crd/bases/cattage.cybozu.io_tenants.yaml b/config/crd/bases/cattage.cybozu.io_tenants.yaml index 6c9dc30..8760070 100644 --- a/config/crd/bases/cattage.cybozu.io_tenants.yaml +++ b/config/crd/bases/cattage.cybozu.io_tenants.yaml @@ -79,6 +79,12 @@ spec: - roles type: object type: array + extraParams: + additionalProperties: + type: string + description: ExtraParams is a map of extra parameters that can be + used in the templates. + type: object rootNamespaces: description: RootNamespaces are the list of root namespaces that belong to this tenant. diff --git a/config/manager/configmap.yaml b/config/manager/configmap.yaml index 63f7b59..48094da 100644 --- a/config/manager/configmap.yaml +++ b/config/manager/configmap.yaml @@ -25,9 +25,9 @@ data: {{- range .Roles.admin }} - apiGroup: rbac.authorization.k8s.io kind: Group - name: {{ . }} + name: {{ .Name }} - kind: ServiceAccount - name: node-{{ . }} + name: node-{{ .Name }} namespace: teleport {{- end }} argocd: @@ -48,9 +48,9 @@ data: kind: LimitRange roles: - groups: - - cybozu-go:{{ .Name }} + - cybozu-go:{{with .Extras.GitHubTeam}}{{ . }}{{else}}{{ .Name }}{{end}} {{- range .Roles.admin }} - - cybozu-go:{{ . }} + - cybozu-go:{{with .Extras.GitHubTeam}}{{ . }}{{else}}{{ .Name }}{{end}} {{- end }} name: admin policies: diff --git a/config/samples/tenant.yaml b/config/samples/tenant.yaml index bb85a3f..397deef 100644 --- a/config/samples/tenant.yaml +++ b/config/samples/tenant.yaml @@ -6,6 +6,8 @@ spec: rootNamespaces: - name: app-a controllerName: second + extraParams: + GitHubTeam: a-team-gh --- apiVersion: cattage.cybozu.io/v1beta1 kind: Tenant @@ -21,3 +23,5 @@ spec: - name: a-team roles: - admin + extraParams: + GitHubTeam: b-team-gh diff --git a/controllers/tenant_controller.go b/controllers/tenant_controller.go index 22d26d2..c48ead9 100644 --- a/controllers/tenant_controller.go +++ b/controllers/tenant_controller.go @@ -354,15 +354,23 @@ func (r *TenantReconciler) patchRoleBinding(ctx context.Context, rb *acrbacv1.Ro }) } -func rolesMap(delegates []cattagev1beta1.DelegateSpec) map[string][]string { - result := make(map[string][]string) +func (r *TenantReconciler) rolesMap(ctx context.Context, delegates []cattagev1beta1.DelegateSpec) (map[string][]Role, error) { + result := make(map[string][]Role) for _, d := range delegates { for _, role := range d.Roles { - result[role] = append(result[role], d.Name) + delegatedTenant := &cattagev1beta1.Tenant{} + err := r.client.Get(ctx, client.ObjectKey{Name: d.Name}, delegatedTenant) + if err != nil { + return nil, err + } + result[role] = append(result[role], Role{ + Name: delegatedTenant.Name, + Extras: delegatedTenant.Spec.ExtraParams, + }) } } - return result + return result, nil } func (r *TenantReconciler) reconcileNamespaces(ctx context.Context, tenant *cattagev1beta1.Tenant) error { @@ -395,13 +403,20 @@ func (r *TenantReconciler) reconcileNamespaces(ctx context.Context, tenant *catt if err != nil { return err } + roles, err := r.rolesMap(ctx, tenant.Spec.Delegates) + if err != nil { + return err + } + var buf bytes.Buffer err = tpl.Execute(&buf, struct { - Name string - Roles map[string][]string + Name string + Roles map[string][]Role + Extras map[string]string }{ - Name: tenant.Name, - Roles: rolesMap(tenant.Spec.Delegates), + Name: tenant.Name, + Roles: roles, + Extras: tenant.Spec.ExtraParams, }) if err != nil { return err @@ -445,6 +460,11 @@ func (r *TenantReconciler) reconcileNamespaces(ctx context.Context, tenant *catt return nil } +type Role struct { + Name string + Extras map[string]string +} + func (r *TenantReconciler) reconcileArgoCD(ctx context.Context, tenant *cattagev1beta1.Tenant) error { logger := log.FromContext(ctx) @@ -469,17 +489,24 @@ func (r *TenantReconciler) reconcileArgoCD(ctx context.Context, tenant *cattagev return err } + roles, err := r.rolesMap(ctx, tenant.Spec.Delegates) + if err != nil { + return err + } + var buf bytes.Buffer err = tpl.Execute(&buf, struct { Name string Namespaces []string - Roles map[string][]string + Roles map[string][]Role Repositories []string + Extras map[string]string }{ Name: tenant.Name, Namespaces: namespaces, - Roles: rolesMap(tenant.Spec.Delegates), + Roles: roles, Repositories: tenant.Spec.ArgoCD.Repositories, + Extras: tenant.Spec.ExtraParams, }) if err != nil { return err @@ -489,6 +516,7 @@ func (r *TenantReconciler) reconcileArgoCD(ctx context.Context, tenant *cattagev dec := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) _, _, err = dec.Decode(buf.Bytes(), nil, proj) if err != nil { + logger.Error(err, "failed to decode", "yaml", buf.String()) return err } diff --git a/docs/crd_tenant.md b/docs/crd_tenant.md index 2705dcb..1475845 100644 --- a/docs/crd_tenant.md +++ b/docs/crd_tenant.md @@ -78,6 +78,7 @@ TenantSpec defines the desired state of Tenant. | argocd | ArgoCD is the settings of Argo CD for this tenant. | [ArgoCDSpec](#argocdspec) | false | | delegates | Delegates is a list of other tenants that are delegated access to this tenant. | [][DelegateSpec](#delegatespec) | false | | controllerName | ControllerName is the name of the application-controller that manages this tenant's applications. If not specified, the default controller is used. | string | false | +| extraParams | ExtraParams is a map of extra parameters that can be used in the templates. | map[string]string | false | [Back to Custom Resources](#custom-resources)