From 7f7ce117a44dee5d222ea19f772f686ea9b4fc1f Mon Sep 17 00:00:00 2001 From: grzegorz-ciezkowski Date: Tue, 10 Dec 2024 12:19:32 +0100 Subject: [PATCH 1/6] feat(teams) Add members to team status (#723) --- cmd/greenhouse/controllers.go | 1 + pkg/apis/greenhouse/v1alpha1/team_types.go | 1 + pkg/controllers/team/team_controller.go | 78 ++++++++++++++++++++++ test/e2e/controllers.go | 1 + 4 files changed, 81 insertions(+) create mode 100644 pkg/controllers/team/team_controller.go diff --git a/cmd/greenhouse/controllers.go b/cmd/greenhouse/controllers.go index 9803b9ee7..c714c03e7 100644 --- a/cmd/greenhouse/controllers.go +++ b/cmd/greenhouse/controllers.go @@ -23,6 +23,7 @@ var knownControllers = map[string]func(controllerName string, mgr ctrl.Manager) "organizationController": startOrganizationReconciler, // Team controllers. + "teamController": (&teamcontrollers.TeamReconciler{}).SetupWithManager, "teamPropagation": (&teamcontrollers.TeamPropagationReconciler{}).SetupWithManager, // TeamMembership controllers. diff --git a/pkg/apis/greenhouse/v1alpha1/team_types.go b/pkg/apis/greenhouse/v1alpha1/team_types.go index 89182cbc6..2614d5ece 100644 --- a/pkg/apis/greenhouse/v1alpha1/team_types.go +++ b/pkg/apis/greenhouse/v1alpha1/team_types.go @@ -20,6 +20,7 @@ type TeamSpec struct { // TeamStatus defines the observed state of Team type TeamStatus struct { StatusConditions StatusConditions `json:"statusConditions"` + Members []User `json:"members"` } //+kubebuilder:object:root=true diff --git a/pkg/controllers/team/team_controller.go b/pkg/controllers/team/team_controller.go new file mode 100644 index 000000000..ab84d72fb --- /dev/null +++ b/pkg/controllers/team/team_controller.go @@ -0,0 +1,78 @@ +package team + +import ( + "context" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/record" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + greenhouseapisv1alpha1 "github.com/cloudoperators/greenhouse/pkg/apis/greenhouse/v1alpha1" + "github.com/cloudoperators/greenhouse/pkg/lifecycle" +) + +type TeamReconciler struct { + client.Client + recorder record.EventRecorder +} + +// SetupWithManager sets up the controller with the Manager. +func (r *TeamReconciler) SetupWithManager(name string, mgr ctrl.Manager) error { + r.Client = mgr.GetClient() + r.recorder = mgr.GetEventRecorderFor(name) + return ctrl.NewControllerManagedBy(mgr). + Named(name). + For(&greenhouseapisv1alpha1.Team{}). + Complete(r) +} + +func (r *TeamReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + return lifecycle.Reconcile(ctx, r.Client, req.NamespacedName, &greenhouseapisv1alpha1.Team{}, r, r.setStatus()) +} + +func (r *TeamReconciler) EnsureDeleted(_ context.Context, _ lifecycle.RuntimeObject) (ctrl.Result, lifecycle.ReconcileResult, error) { + return ctrl.Result{}, lifecycle.Success, nil +} + +func (r *TeamReconciler) EnsureCreated(ctx context.Context, object lifecycle.RuntimeObject) (ctrl.Result, lifecycle.ReconcileResult, error) { + return ctrl.Result{}, lifecycle.Success, nil +} + +func (r *TeamReconciler) setStatus() lifecycle.Conditioner { + return func(ctx context.Context, object lifecycle.RuntimeObject) { + team, ok := object.(*greenhouseapisv1alpha1.Team) + if !ok { + return + } + + var members []greenhouseapisv1alpha1.User + teamMembershipList := new(greenhouseapisv1alpha1.TeamMembershipList) + + err := r.List(ctx, teamMembershipList) + if err != nil { + ctrl.Log.Error(err, "Failed to list team memberships") + return + } + + for _, member := range teamMembershipList.Items { + if !hasOwnerReference(member.OwnerReferences, team.Kind, team.Name) { + continue + } + + members = append(members, member.Spec.Members...) + } + + team.Status.Members = members + } +} + +func hasOwnerReference(ownerReferences []v1.OwnerReference, kind, name string) bool { + for _, ownerReference := range ownerReferences { + if ownerReference.Kind == kind && ownerReference.Name == name { + return true + } + } + + return false +} diff --git a/test/e2e/controllers.go b/test/e2e/controllers.go index d7f9ec8c9..ab441099e 100644 --- a/test/e2e/controllers.go +++ b/test/e2e/controllers.go @@ -36,6 +36,7 @@ var knownControllers = map[string]func(controllerName string, mgr ctrl.Manager) "organizationTeamRoleSeeder": (&organizationcontrollers.TeamRoleSeederReconciler{}).SetupWithManager, // Team controllers. + "teamController": (&teamcontrollers.TeamReconciler{}).SetupWithManager, "teamPropagation": (&teamcontrollers.TeamPropagationReconciler{}).SetupWithManager, // TeamMembership controllers. From a6add012658a695e2a4226a2e647e91f2ae031e0 Mon Sep 17 00:00:00 2001 From: Cloud Operator <169066274+cloud-operator@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:28:20 +0000 Subject: [PATCH 2/6] Automatic generation of CRD API Docs --- docs/reference/api/index.html | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/reference/api/index.html b/docs/reference/api/index.html index 49d59b738..209c39422 100644 --- a/docs/reference/api/index.html +++ b/docs/reference/api/index.html @@ -3404,6 +3404,18 @@

TeamStatus + + +members
+ + +[]User + + + + + + @@ -3468,7 +3480,8 @@

User

(Appears on: -TeamMembershipSpec) +TeamMembershipSpec, +TeamStatus)

User specifies a human person.

From 1affb211d987b6529b3f1776973d1cda4ecb9dcd Mon Sep 17 00:00:00 2001 From: License Bot Date: Tue, 10 Dec 2024 11:29:24 +0000 Subject: [PATCH 3/6] Automatic application of license header --- pkg/controllers/team/team_controller.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/controllers/team/team_controller.go b/pkg/controllers/team/team_controller.go index ab84d72fb..0fa6c1f82 100644 --- a/pkg/controllers/team/team_controller.go +++ b/pkg/controllers/team/team_controller.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +// SPDX-License-Identifier: Apache-2.0 + package team import ( From bcc6a00481f15a4d471ae5510f59df9d3c1283ab Mon Sep 17 00:00:00 2001 From: grzegorz-ciezkowski Date: Wed, 11 Dec 2024 16:14:52 +0100 Subject: [PATCH 4/6] feat(teams) Unit tests for members in team (#723) --- charts/manager/crds/greenhouse.sap_teams.yaml | 27 +- charts/manager/templates/role.yaml | 157 ++++ charts/manager/templates/webhooks.yaml | 754 +++++++++--------- .../v1alpha1/zz_generated.deepcopy.go | 5 + pkg/controllers/team/suite_test.go | 30 + pkg/controllers/team/team_controller.go | 9 + pkg/controllers/team/team_controller_test.go | 68 ++ 7 files changed, 664 insertions(+), 386 deletions(-) create mode 100644 charts/manager/templates/role.yaml create mode 100644 pkg/controllers/team/suite_test.go create mode 100644 pkg/controllers/team/team_controller_test.go diff --git a/charts/manager/crds/greenhouse.sap_teams.yaml b/charts/manager/crds/greenhouse.sap_teams.yaml index dc749ae56..23d71264b 100644 --- a/charts/manager/crds/greenhouse.sap_teams.yaml +++ b/charts/manager/crds/greenhouse.sap_teams.yaml @@ -1,6 +1,3 @@ -# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors -# SPDX-License-Identifier: Apache-2.0 - --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -65,6 +62,29 @@ spec: status: description: TeamStatus defines the observed state of Team properties: + members: + items: + description: User specifies a human person. + properties: + email: + description: Email of the user. + type: string + firstName: + description: FirstName of the user. + type: string + id: + description: ID is the unique identifier of the user. + type: string + lastName: + description: LastName of the user. + type: string + required: + - email + - firstName + - id + - lastName + type: object + type: array statusConditions: description: |- A StatusConditions contains a list of conditions. @@ -105,6 +125,7 @@ spec: x-kubernetes-list-type: map type: object required: + - members - statusConditions type: object type: object diff --git a/charts/manager/templates/role.yaml b/charts/manager/templates/role.yaml new file mode 100644 index 000000000..d0508edcd --- /dev/null +++ b/charts/manager/templates/role.yaml @@ -0,0 +1,157 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: manager-role +rules: +- apiGroups: + - "" + resources: + - events + - secrets + - serviceaccounts + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' +- apiGroups: + - dex.coreos.com + resources: + - connectors + - oauth2clients + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - greenhouse.sap + resources: + - cluster-kubeconfigs + - teamroles + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - greenhouse.sap + resources: + - clusters + - organizations + - plugindefinitions + - plugins + - teammemberships + - teamrolebindings + - teams + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - greenhouse.sap + resources: + - clusters/finalizers + - organizations/finalizers + - plugindefinitions/finalizers + - pluginpresets/finalizers + - plugins/finalizers + - teammemberships/finalizers + - teamrolebindings/finalizers + - teams/finalizers + verbs: + - update +- apiGroups: + - greenhouse.sap + resources: + - clusters/status + - organizations/status + - plugindefinitions/status + - pluginpresets/status + - teammemberships/status + - teamrolebindings/status + - teams/status + verbs: + - get + - patch + - update +- apiGroups: + - greenhouse.sap + resources: + - pluginpresets + verbs: + - get + - list + - update + - watch +- apiGroups: + - greenhouse.sap + resources: + - plugins/status + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - greenhouse.sap + resources: + - teammemberships= + verbs: + - get + - list +- apiGroups: + - rbac + resources: + - clusterrolebindings + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - create + - get + - list + - patch + - update + - watch diff --git a/charts/manager/templates/webhooks.yaml b/charts/manager/templates/webhooks.yaml index 9191734e2..ef01c86b1 100644 --- a/charts/manager/templates/webhooks.yaml +++ b/charts/manager/templates/webhooks.yaml @@ -4,392 +4,380 @@ kind: MutatingWebhookConfiguration metadata: name: greenhouse-mutating-webhook-configuration webhooks: - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-cluster - failurePolicy: Fail - name: mcluster.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - clusters - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-organization - failurePolicy: Fail - name: morganization.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - organizations - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-plugin - failurePolicy: Fail - name: mplugin.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - plugins - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-plugindefinition - failurePolicy: Fail - name: mplugindefinition.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - plugindefinitions - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-pluginpreset - failurePolicy: Fail - name: mpluginpreset.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - pluginpresets - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-teamrole - failurePolicy: Fail - name: mrole.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - teamroles - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-teamrolebinding - failurePolicy: Fail - name: mrolebinding.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - teamrolebindings - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate--v1-secret - failurePolicy: Ignore - matchPolicy: Exact - name: msecret.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - secrets - sideEffects: None - namespaceSelector: - matchExpressions: - - key: kubernetes.io/metadata.name - operator: NotIn - values: - - kube-system - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /mutate-greenhouse-sap-v1alpha1-team - failurePolicy: Fail - name: mteam.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - resources: - - teams - sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-cluster + failurePolicy: Fail + name: mcluster.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - clusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-organization + failurePolicy: Fail + name: morganization.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - organizations + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-plugin + failurePolicy: Fail + name: mplugin.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - plugins + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-plugindefinition + failurePolicy: Fail + name: mplugindefinition.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - plugindefinitions + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-pluginpreset + failurePolicy: Fail + name: mpluginpreset.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - pluginpresets + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-teamrole + failurePolicy: Fail + name: mrole.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - teamroles + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-teamrolebinding + failurePolicy: Fail + name: mrolebinding.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - teamrolebindings + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate--v1-secret + failurePolicy: Ignore + matchPolicy: Exact + name: msecret.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - secrets + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /mutate-greenhouse-sap-v1alpha1-team + failurePolicy: Fail + name: mteam.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - teams + sideEffects: None --- apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: greenhouse-validating-webhook-configuration webhooks: - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-cluster - failurePolicy: Fail - name: vcluster.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - clusters - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-organization - failurePolicy: Fail - name: vorganization.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - organizations - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-plugin - failurePolicy: Fail - name: vplugin.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - plugins - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-plugindefinition - failurePolicy: Fail - name: vplugindefinition.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - plugindefinitions - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-pluginpreset - failurePolicy: Fail - name: vpluginpreset.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - pluginpresets - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-teamrole - failurePolicy: Fail - name: vrole.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - teamroles - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-teamrolebinding - failurePolicy: Fail - name: vrolebinding.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - teamrolebindings - sideEffects: None - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate--v1-secret - failurePolicy: Ignore - matchPolicy: Exact - name: vsecret.kb.io - rules: - - apiGroups: - - "" - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - secrets - sideEffects: None - namespaceSelector: - matchExpressions: - - key: kubernetes.io/metadata.name - operator: NotIn - values: - - kube-system - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: greenhouse-webhook-service - namespace: greenhouse - path: /validate-greenhouse-sap-v1alpha1-team - failurePolicy: Fail - name: vteam.kb.io - rules: - - apiGroups: - - greenhouse.sap - apiVersions: - - v1alpha1 - operations: - - CREATE - - UPDATE - - DELETE - resources: - - teams - sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-cluster + failurePolicy: Fail + name: vcluster.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - clusters + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-organization + failurePolicy: Fail + name: vorganization.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - organizations + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-plugin + failurePolicy: Fail + name: vplugin.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - plugins + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-plugindefinition + failurePolicy: Fail + name: vplugindefinition.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - plugindefinitions + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-pluginpreset + failurePolicy: Fail + name: vpluginpreset.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - pluginpresets + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-teamrole + failurePolicy: Fail + name: vrole.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - teamroles + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-teamrolebinding + failurePolicy: Fail + name: vrolebinding.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - teamrolebindings + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate--v1-secret + failurePolicy: Ignore + matchPolicy: Exact + name: vsecret.kb.io + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - secrets + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: greenhouse-webhook-service + namespace: greenhouse + path: /validate-greenhouse-sap-v1alpha1-team + failurePolicy: Fail + name: vteam.kb.io + rules: + - apiGroups: + - greenhouse.sap + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + - DELETE + resources: + - teams + sideEffects: None diff --git a/pkg/apis/greenhouse/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/greenhouse/v1alpha1/zz_generated.deepcopy.go index 613021e25..ad8c165a4 100644 --- a/pkg/apis/greenhouse/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/greenhouse/v1alpha1/zz_generated.deepcopy.go @@ -1461,6 +1461,11 @@ func (in *TeamSpec) DeepCopy() *TeamSpec { func (in *TeamStatus) DeepCopyInto(out *TeamStatus) { *out = *in in.StatusConditions.DeepCopyInto(&out.StatusConditions) + if in.Members != nil { + in, out := &in.Members, &out.Members + *out = make([]User, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TeamStatus. diff --git a/pkg/controllers/team/suite_test.go b/pkg/controllers/team/suite_test.go new file mode 100644 index 000000000..34a56f8f3 --- /dev/null +++ b/pkg/controllers/team/suite_test.go @@ -0,0 +1,30 @@ +package team + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + greenhousecluster "github.com/cloudoperators/greenhouse/pkg/controllers/cluster" + "github.com/cloudoperators/greenhouse/pkg/test" +) + +//+kubebuilder:rbac:groups=greenhouse.sap,resources=team,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=greenhouse.sap,resources=teammembership,verbs=get,list + +func TestTeamController(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "TeamControllerSuite") +} + +var _ = BeforeSuite(func() { + test.RegisterController("teamController", (&TeamReconciler{}).SetupWithManager) + test.RegisterController("cluster", (&greenhousecluster.RemoteClusterReconciler{}).SetupWithManager) + + test.TestBeforeSuite() +}) + +var _ = AfterSuite(func() { + test.TestAfterSuite() +}) diff --git a/pkg/controllers/team/team_controller.go b/pkg/controllers/team/team_controller.go index 0fa6c1f82..7c6a91ea0 100644 --- a/pkg/controllers/team/team_controller.go +++ b/pkg/controllers/team/team_controller.go @@ -20,6 +20,10 @@ type TeamReconciler struct { recorder record.EventRecorder } +//+kubebuilder:rbac:groups=greenhouse.sap,resources=teams,verbs=get;list;watch;update +//+kubebuilder:rbac:groups=greenhouse.sap,resources=teams/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=greenhouse.sap,resources=teammemberships=,verbs=get;list + // SetupWithManager sets up the controller with the Manager. func (r *TeamReconciler) SetupWithManager(name string, mgr ctrl.Manager) error { r.Client = mgr.GetClient() @@ -67,6 +71,11 @@ func (r *TeamReconciler) setStatus() lifecycle.Conditioner { } team.Status.Members = members + team.Status.StatusConditions.SetConditions(greenhouseapisv1alpha1.TrueCondition( + greenhouseapisv1alpha1.StatusUpToDateCondition, "", "Members is up to date")) + if team.Status.StatusConditions.Conditions == nil { + team.Status.StatusConditions.Conditions = []greenhouseapisv1alpha1.Condition{} + } } } diff --git a/pkg/controllers/team/team_controller_test.go b/pkg/controllers/team/team_controller_test.go new file mode 100644 index 000000000..d56a544ac --- /dev/null +++ b/pkg/controllers/team/team_controller_test.go @@ -0,0 +1,68 @@ +package team + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + greenhouseapisv1alpha1 "github.com/cloudoperators/greenhouse/pkg/apis/greenhouse/v1alpha1" + "github.com/cloudoperators/greenhouse/pkg/test" +) + +var _ = Describe("TeamControllerTest", Ordered, func() { + It("Should update status of team with members", func() { + err := test.K8sClient.Create(test.Ctx, &greenhouseapisv1alpha1.Team{ + TypeMeta: metav1.TypeMeta{ + Kind: "Team", + APIVersion: greenhouseapisv1alpha1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-team", + Namespace: test.TestNamespace, + }, + Spec: greenhouseapisv1alpha1.TeamSpec{ + Description: "", + MappedIDPGroup: "MAP_IDP_GROUP", + }, + }) + Expect(err).ToNot(HaveOccurred()) + + err = test.K8sClient.Create(test.Ctx, &greenhouseapisv1alpha1.TeamMembership{ + TypeMeta: metav1.TypeMeta{ + Kind: "TeamMembership", + APIVersion: greenhouseapisv1alpha1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test-membership", + Namespace: test.TestNamespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: greenhouseapisv1alpha1.GroupVersion.String(), + Kind: "Team", + Name: "test-team", + UID: "uhuihiuh", + }, + }, + }, + Spec: greenhouseapisv1alpha1.TeamMembershipSpec{ + Members: []greenhouseapisv1alpha1.User{ + { + ID: "d2a72c04-42d2-426a-942d-af9609c4cd00", + FirstName: "John", + LastName: "Doe", + Email: "john.doe@example.com", + }, + }, + }, + }) + Expect(err).ToNot(HaveOccurred()) + + Eventually(func(g Gomega) { + team := &greenhouseapisv1alpha1.Team{} + err := test.K8sClient.Get(test.Ctx, client.ObjectKey{Name: "test-team", Namespace: test.TestNamespace}, team) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(team.Status.Members).To(HaveLen(1)) + }).Should(Succeed()) + }) +}) From 67955265a1c482727f90647d139f2401b10f93fd Mon Sep 17 00:00:00 2001 From: Cloud Operator <169066274+cloud-operator@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:15:52 +0000 Subject: [PATCH 5/6] Automatic generation of CRD API Docs --- docs/reference/api/openapi.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/reference/api/openapi.yaml b/docs/reference/api/openapi.yaml index 73354b6e8..a7e19bad4 100755 --- a/docs/reference/api/openapi.yaml +++ b/docs/reference/api/openapi.yaml @@ -1107,6 +1107,29 @@ components: status: description: TeamStatus defines the observed state of Team properties: + members: + items: + description: User specifies a human person. + properties: + email: + description: Email of the user. + type: string + firstName: + description: FirstName of the user. + type: string + id: + description: ID is the unique identifier of the user. + type: string + lastName: + description: LastName of the user. + type: string + required: + - email + - firstName + - id + - lastName + type: object + type: array statusConditions: description: A StatusConditions contains a list of conditions.\nOnly one condition of a given type may exist in the list. properties: @@ -1141,6 +1164,7 @@ components: x-kubernetes-list-type: map type: object required: + - members - statusConditions type: object type: object From b61caaf986c0627171a16c782bbacd734f57c619 Mon Sep 17 00:00:00 2001 From: License Bot Date: Wed, 11 Dec 2024 15:16:47 +0000 Subject: [PATCH 6/6] Automatic application of license header --- charts/manager/crds/greenhouse.sap_teams.yaml | 3 +++ pkg/controllers/team/suite_test.go | 3 +++ pkg/controllers/team/team_controller_test.go | 3 +++ 3 files changed, 9 insertions(+) diff --git a/charts/manager/crds/greenhouse.sap_teams.yaml b/charts/manager/crds/greenhouse.sap_teams.yaml index 23d71264b..2ed83cd96 100644 --- a/charts/manager/crds/greenhouse.sap_teams.yaml +++ b/charts/manager/crds/greenhouse.sap_teams.yaml @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +# SPDX-License-Identifier: Apache-2.0 + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition diff --git a/pkg/controllers/team/suite_test.go b/pkg/controllers/team/suite_test.go index 34a56f8f3..f8fc53d48 100644 --- a/pkg/controllers/team/suite_test.go +++ b/pkg/controllers/team/suite_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +// SPDX-License-Identifier: Apache-2.0 + package team import ( diff --git a/pkg/controllers/team/team_controller_test.go b/pkg/controllers/team/team_controller_test.go index d56a544ac..741e6f77a 100644 --- a/pkg/controllers/team/team_controller_test.go +++ b/pkg/controllers/team/team_controller_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors +// SPDX-License-Identifier: Apache-2.0 + package team import (