From e7b58063bae0f8f8aa5d6215e106a3fac31d9773 Mon Sep 17 00:00:00 2001 From: Jeremy Ary Date: Sat, 1 May 2021 09:33:59 -0500 Subject: [PATCH] DBAAS-21/24/25: allow DBaaSConn to bind to apps --- Makefile | 9 + api/v1/dbaasconnection_types.go | 9 +- bundle.Dockerfile | 2 +- .../dbaas-operator.clusterserviceversion.yaml | 70 ++++---- .../dbaas.redhat.com_dbaasconnections.yaml | 17 ++ bundle/metadata/annotations.yaml | 2 +- .../dbaas.redhat.com_dbaasconnections.yaml | 12 ++ config/crd/kustomization.yaml | 1 + .../patches/service_binding_annotations.yaml | 12 ++ .../dbaas-operator.clusterserviceversion.yaml | 12 +- config/rbac/role.yaml | 23 +++ config/samples/busybox-runner.yaml | 23 +++ config/samples/dbaas_v1_dbaasservice.yaml | 44 ++--- controllers/dbaasconnection_controller.go | 117 +++++++++++-- controllers/dbaasservice_controller.go | 86 ++++------ .../models/dbaasconnection_resources.go | 161 ++++++++++++++++++ controllers/models/dbaasservice_resources.go | 63 +++++++ go.mod | 1 + 18 files changed, 527 insertions(+), 137 deletions(-) create mode 100644 config/crd/patches/service_binding_annotations.yaml create mode 100644 config/samples/busybox-runner.yaml create mode 100644 controllers/models/dbaasconnection_resources.go create mode 100644 controllers/models/dbaasservice_resources.go diff --git a/Makefile b/Makefile index 05f668f0..396e52e1 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,7 @@ endif all: build +.PHONY: release release: build generate bundle docker-build docker-push bundle-build bundle-push catalog-build catalog-push ##@ General @@ -116,6 +117,14 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. $(KUSTOMIZE) build config/default | kubectl delete -f - +.PHONY: catalog-update +catalog-update: catalog-remove catalog-apply + +catalog-remove: ## remove the sample catalog source from the dbaas-olm namespace + oc delete catalogsource dbaas-operator -n dbaas-olm + +catalog-apply: ## apply the sample catalog source to dbaas-olm namespace + oc apply -f config/samples/catalog-source.yaml CONTROLLER_GEN = $(shell pwd)/bin/controller-gen controller-gen: ## Download controller-gen locally if necessary. diff --git a/api/v1/dbaasconnection_types.go b/api/v1/dbaasconnection_types.go index 9abc7223..0bbfcfd9 100644 --- a/api/v1/dbaasconnection_types.go +++ b/api/v1/dbaasconnection_types.go @@ -34,8 +34,13 @@ type DBaaSConnectionSpec struct { // DBaaSConnectionStatus defines the observed state of DBaaSConnection type DBaaSConnectionStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file + + // DBConfigMap is the name of the ConfigMap containing the connection info + DBConfigMap string `json:"dbConfigMap"` + + //+kubebuilder:validation:Required + // DBCredentials is the name of the Secret containing the database credentials + DBCredentials string `json:"dbCredentials"` } //+kubebuilder:object:root=true diff --git a/bundle.Dockerfile b/bundle.Dockerfile index cbfd8823..879307f1 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -6,9 +6,9 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=dbaas-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha +LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.6.1+git -LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 # Labels for testing. LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 diff --git a/bundle/manifests/dbaas-operator.clusterserviceversion.yaml b/bundle/manifests/dbaas-operator.clusterserviceversion.yaml index 44ee48c3..d9d5c5ae 100644 --- a/bundle/manifests/dbaas-operator.clusterserviceversion.yaml +++ b/bundle/manifests/dbaas-operator.clusterserviceversion.yaml @@ -27,45 +27,12 @@ metadata: "provider": { "name": "MongoDB Atlas" } - }, - "status": { - "projects": [ - { - "clusters": [ - { - "cloudProvider": "TENANT", - "cloudRegion": "US_EAST_1", - "id": "6086aa1528fd4b5704aed738", - "instanceSizeName": "M0", - "name": "Cluster0" - } - ], - "id": "6086aa084e995e38dfd1dd7e", - "name": "different project" - }, - { - "clusters": [ - { - "cloudProvider": "TENANT", - "cloudRegion": "US_EAST_1", - "id": "608484560795100e26a40caa", - "instanceSizeName": "M0", - "name": "Cluster0" - } - ], - "id": "6084842759a7bd6d9b0ea0e8", - "name": "example project", - "users": [ - { - "name": "dbExampleUser" - } - ] - } - ] } } ] capabilities: Basic Install + categories: Database + description: Import provider cloud instances for easy coupling with developer applications. operators.operatorframework.io/builder: operator-sdk-v1.6.1+git operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 name: dbaas-operator.v0.0.1 @@ -80,15 +47,38 @@ spec: - kind: DBaaSService name: dbaasservices.dbaas.redhat.com version: v1 - description: DBaaS Operator - displayName: DBaaS Operator + description: Import provider cloud instances for easy coupling with developer applications. + displayName: Database-as-a-Service Operator icon: - - base64data: "" - mediatype: "" + - base64data: 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 + mediatype: image/png install: spec: clusterPermissions: - rules: + - apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - create + - delete + - get + - list + - update + - watch + - apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - update + - watch - apiGroups: - atlas.mongodb.com resources: @@ -272,7 +262,7 @@ spec: keywords: - dbaas links: - - name: Dbaas Operator + - name: Database-as-a-Service Operator url: https://dbaas-operator.domain maturity: alpha provider: diff --git a/bundle/manifests/dbaas.redhat.com_dbaasconnections.yaml b/bundle/manifests/dbaas.redhat.com_dbaasconnections.yaml index c8f80873..22a14b6f 100644 --- a/bundle/manifests/dbaas.redhat.com_dbaasconnections.yaml +++ b/bundle/manifests/dbaas.redhat.com_dbaasconnections.yaml @@ -3,6 +3,13 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.4.1 + service.binding/db.host: path={.status.dbConfigMap},objectType=ConfigMap + service.binding/db.name: path={.status.dbConfigMap},objectType=ConfigMap + service.binding/db.password: path={.status.dbCredentials},objectType=Secret + service.binding/db.port: path={.status.dbConfigMap},objectType=ConfigMap + service.binding/db.user: path={.status.dbCredentials},objectType=Secret + service.binding/provider: path={.spec.provider} + service.binding/type: path={.spec.type} creationTimestamp: null name: dbaasconnections.dbaas.redhat.com spec: @@ -38,6 +45,16 @@ spec: type: object status: description: DBaaSConnectionStatus defines the observed state of DBaaSConnection + properties: + dbConfigMap: + description: DBConfigMap is the name of the ConfigMap containing the connection info + type: string + dbCredentials: + description: DBCredentials is the name of the Secret containing the database credentials + type: string + required: + - dbConfigMap + - dbCredentials type: object type: object served: true diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index e6f52204..94f13322 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -5,9 +5,9 @@ annotations: operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: dbaas-operator operators.operatorframework.io.bundle.channels.v1: alpha + operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.builder: operator-sdk-v1.6.1+git - operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 # Annotations for testing. operators.operatorframework.io.test.mediatype.v1: scorecard+v1 diff --git a/config/crd/bases/dbaas.redhat.com_dbaasconnections.yaml b/config/crd/bases/dbaas.redhat.com_dbaasconnections.yaml index fcaeba31..473a29f3 100644 --- a/config/crd/bases/dbaas.redhat.com_dbaasconnections.yaml +++ b/config/crd/bases/dbaas.redhat.com_dbaasconnections.yaml @@ -45,6 +45,18 @@ spec: type: object status: description: DBaaSConnectionStatus defines the observed state of DBaaSConnection + properties: + dbConfigMap: + description: DBConfigMap is the name of the ConfigMap containing the + connection info + type: string + dbCredentials: + description: DBCredentials is the name of the Secret containing the + database credentials + type: string + required: + - dbConfigMap + - dbCredentials type: object type: object served: true diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 9ab7e9de..a9951c20 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -7,6 +7,7 @@ resources: #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: +- patches/service_binding_annotations.yaml # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD #- patches/webhook_in_dbaasservices.yaml diff --git a/config/crd/patches/service_binding_annotations.yaml b/config/crd/patches/service_binding_annotations.yaml new file mode 100644 index 00000000..529fd4b0 --- /dev/null +++ b/config/crd/patches/service_binding_annotations.yaml @@ -0,0 +1,12 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: dbaasconnections.dbaas.redhat.com + annotations: + service.binding/type: 'path={.spec.type}' + service.binding/provider: 'path={.spec.provider}' + service.binding/db.name: 'path={.status.dbConfigMap},objectType=ConfigMap' + service.binding/db.host: 'path={.status.dbConfigMap},objectType=ConfigMap' + service.binding/db.port: 'path={.status.dbConfigMap},objectType=ConfigMap' + service.binding/db.user: 'path={.status.dbCredentials},objectType=Secret' + service.binding/db.password: 'path={.status.dbCredentials},objectType=Secret' \ No newline at end of file diff --git a/config/manifests/bases/dbaas-operator.clusterserviceversion.yaml b/config/manifests/bases/dbaas-operator.clusterserviceversion.yaml index 55527b8e..37a48cc6 100644 --- a/config/manifests/bases/dbaas-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/dbaas-operator.clusterserviceversion.yaml @@ -4,16 +4,18 @@ metadata: annotations: alm-examples: '[]' capabilities: Basic Install + categories: Database + description: Import provider cloud instances for easy coupling with developer applications. name: dbaas-operator.v0.0.0 namespace: placeholder spec: apiservicedefinitions: {} customresourcedefinitions: {} - description: DBaaS Operator - displayName: DBaaS Operator + description: Import provider cloud instances for easy coupling with developer applications. + displayName: Database-as-a-Service Operator icon: - - base64data: "" - mediatype: "" + - base64data: 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 + mediatype: image/png install: spec: deployments: null @@ -30,7 +32,7 @@ spec: keywords: - dbaas links: - - name: Dbaas Operator + - name: Database-as-a-Service Operator url: https://dbaas-operator.domain maturity: alpha provider: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index c5afc114..5e7fcc3b 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -6,6 +6,29 @@ metadata: creationTimestamp: null name: manager-role rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - update + - watch - apiGroups: - atlas.mongodb.com resources: diff --git a/config/samples/busybox-runner.yaml b/config/samples/busybox-runner.yaml new file mode 100644 index 00000000..742ae76c --- /dev/null +++ b/config/samples/busybox-runner.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dbaas-busybox-example +spec: + replicas: 1 + selector: + matchLabels: + name: dbaas-busybox-example + template: + metadata: + labels: + name: dbaas-busybox-example + spec: + containers: + - name: dbaas-busybox-example + # Replace this with the built image name + image: quay.io/bmozaffa/busybox + imagePullPolicy: IfNotPresent + command: ['sh', '-c', 'echo The app is running! && sleep 3600'] + ports: + - containerPort: 8080 + protocol: TCP \ No newline at end of file diff --git a/config/samples/dbaas_v1_dbaasservice.yaml b/config/samples/dbaas_v1_dbaasservice.yaml index eb11980e..b0f042ea 100644 --- a/config/samples/dbaas_v1_dbaasservice.yaml +++ b/config/samples/dbaas_v1_dbaasservice.yaml @@ -8,25 +8,25 @@ spec: credentialsSecretNamespace: dbaas-operator provider: name: MongoDB Atlas -# Once Atlas has been queried based on the credential secret auth info provided, results will populate status -# example after query result: -status: - projects: - - clusters: - - cloudProvider: TENANT - cloudRegion: US_EAST_1 - id: 6086aa1528fd4b5704aed738 - instanceSizeName: M0 - name: Cluster0 - id: 6086aa084e995e38dfd1dd7e - name: different project - - clusters: - - cloudProvider: TENANT - cloudRegion: US_EAST_1 - id: 608484560795100e26a40caa - instanceSizeName: M0 - name: Cluster0 - id: 6084842759a7bd6d9b0ea0e8 - name: example project - users: - - name: dbExampleUser +# Once Atlas has been queried based on the credential secret auth info provided, results will populate status - +# Here's an example status after query result is appended: +# status: +# projects: +# - clusters: +# - cloudProvider: TENANT +# cloudRegion: US_EAST_1 +# id: 6086aa1528fd4b5704aed738 +# instanceSizeName: M0 +# name: Cluster0 +# id: 6086aa084e995e38dfd1dd7e +# name: different project +# - clusters: +# - cloudProvider: TENANT +# cloudRegion: US_EAST_1 +# id: 608484560795100e26a40caa +# instanceSizeName: M0 +# name: Cluster0 +# id: 6084842759a7bd6d9b0ea0e8 +# name: example project +# users: +# - name: dbExampleUser \ No newline at end of file diff --git a/controllers/dbaasconnection_controller.go b/controllers/dbaasconnection_controller.go index 3237ec46..3c1dd09d 100644 --- a/controllers/dbaasconnection_controller.go +++ b/controllers/dbaasconnection_controller.go @@ -18,6 +18,11 @@ package controllers import ( "context" + "github.com/RHEcosystemAppEng/dbaas-operator/controllers/models" + v12 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" @@ -37,21 +42,108 @@ type DBaaSConnectionReconciler struct { //+kubebuilder:rbac:groups=dbaas.redhat.com,resources=dbaasconnections,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=dbaas.redhat.com,resources=dbaasconnections/status,verbs=get;update;patch //+kubebuilder:rbac:groups=dbaas.redhat.com,resources=dbaasconnections/finalizers,verbs=update +//+kubebuilder:rbac:groups=atlas.mongodb.com,resources=atlasservices,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=atlas.mongodb.com,resources=atlasservices/status,verbs=get +// +kubebuilder:rbac:groups="",resources=secrets;configmaps,verbs=get;list;create;update;delete;watch +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;create;update;delete;watch -// Reconcile is part of the main kubernetes reconciliation loop which aims to -// move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the DBaaSConnection object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.7.2/pkg/reconcile func (r *DBaaSConnectionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = r.Log.WithValues("dbaasconnection", req.NamespacedName) + log := r.Log.WithValues("dbaasconnection", req.NamespacedName) - // your logic here + // fetch DBaaSConnection object initiating reconcile + log.Info("reconcile initiated", "object", req.String()) + var dbaasConnection dbaasv1.DBaaSConnection + err := r.Get(ctx, req.NamespacedName, &dbaasConnection) + if err != nil { + if apierrors.IsNotFound(err) { + // CR deleted since request queued, child objects getting GC'd, no requeue + log.Info("DBaaSConnection resource not found, has been deleted") + return ctrl.Result{}, nil + } else { + // error fetching resource instance, requeue and try again + r.Log.Error(err, "error fetching DBaaSConnection for reconcile") + return ctrl.Result{}, err + } + } + // DBaaSConnection resource found, try and find matching bindable deployment + existingDeployment := models.Deployment(&dbaasConnection) + err = r.Get(ctx, client.ObjectKeyFromObject(existingDeployment), existingDeployment) + if err != nil { + if apierrors.IsNotFound(err) { + // matching Deployment has not yet been created, make one with ownerReference + newDeployment := models.OwnedDeployment(&dbaasConnection) + _, err = controllerutil.CreateOrUpdate(ctx, r.Client, newDeployment, func() error { + newDeployment.Spec = models.MutateDeploymentSpec() + return nil + }) + if err != nil { + r.Log.Error(err, "error creating new connection ConfigMap") + return ctrl.Result{}, err + } + } else { + // error fetching resource instance, requeue and try again + r.Log.Error(err, "error fetching matching Deployment, requeuing") + return ctrl.Result{}, err + } + } + + // try and find matching ConfigMap + existingConfigMap := models.ConfigMap(&dbaasConnection) + err = r.Get(ctx, client.ObjectKeyFromObject(existingConfigMap), existingConfigMap) + if err != nil { + if apierrors.IsNotFound(err) { + // matching ConfigMap has not yet been created, make one with ownerReference + connectionConfigMap := models.OwnedConfigMap(&dbaasConnection) + _, err = controllerutil.CreateOrUpdate(ctx, r.Client, connectionConfigMap, func() error { + connectionConfigMap.Data = models.MutateConfigMapData(&dbaasConnection) + return nil + }) + if err != nil { + r.Log.Error(err, "error creating new connection ConfigMap") + return ctrl.Result{}, err + } + } else { + // error fetching resource instance, requeue and try again + r.Log.Error(err, "error fetching matching ConfigMap, requeuing") + return ctrl.Result{}, err + } + } + + // try and find matching Secret + existingSecret := models.Secret(&dbaasConnection) + err = r.Get(ctx, client.ObjectKeyFromObject(existingSecret), existingSecret) + if err != nil { + if apierrors.IsNotFound(err) { + // matching Secret has not yet been created, make one with ownerReference + connectionSecret := models.OwnedSecret(&dbaasConnection) + _, err = controllerutil.CreateOrUpdate(ctx, r.Client, connectionSecret, func() error { + connectionSecret.Data = models.MutateSecretData() + return nil + }) + if err != nil { + r.Log.Error(err, "error creating new connection ConfigMap") + return ctrl.Result{}, err + } + } else { + // error fetching resource instance, requeue and try again + r.Log.Error(err, "error fetching matching Secret, requeuing") + return ctrl.Result{}, err + } + } + + // now that the ConfigMap and Secret exist, add them to status on our dbaasConnection + log.Info("new connection ConfigMap & Secret created") + newStatus := models.UpdatedConnectionStatus(&dbaasConnection) + + newStatus.DeepCopyInto(&dbaasConnection.Status) + if err = r.Status().Update(ctx, &dbaasConnection); err != nil { + r.Log.Error(err, "error saving modified DBaaSConnection status") + return ctrl.Result{}, err + } + + // corresponding ConfigMap & Secret have been made available for binding via status, reconciliations can continue + log.Info("all DBaaSConnection dependencies created successfully") return ctrl.Result{}, nil } @@ -59,5 +151,8 @@ func (r *DBaaSConnectionReconciler) Reconcile(ctx context.Context, req ctrl.Requ func (r *DBaaSConnectionReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&dbaasv1.DBaaSConnection{}). + Owns(&v1.Secret{}). + Owns(&v1.ConfigMap{}). + Owns(&v12.Deployment{}). Complete(r) } diff --git a/controllers/dbaasservice_controller.go b/controllers/dbaasservice_controller.go index ef4ec036..8acef7b4 100644 --- a/controllers/dbaasservice_controller.go +++ b/controllers/dbaasservice_controller.go @@ -18,12 +18,10 @@ package controllers import ( "context" - "fmt" + "github.com/RHEcosystemAppEng/dbaas-operator/controllers/models" "github.com/go-logr/logr" atlas "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - ptr "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -65,48 +63,15 @@ func (r *DBaaSServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request } // DBaaSService resource found, try and find matching AtlasService - found := atlas.AtlasService{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "atlas.mongodb.com/v1", - Kind: "AtlasService", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("atlas-service-%s", dbaasService.UID), - Namespace: dbaasService.Namespace, - }, - } - err = r.Get(ctx, client.ObjectKeyFromObject(&found), &found) + found := models.AtlasService(&dbaasService) + err = r.Get(ctx, client.ObjectKeyFromObject(found), found) if err != nil { if apierrors.IsNotFound(err) { // matching AtlasService has not yet been created, make one with ownerReference to our resource - atlasInstance := atlas.AtlasService{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("atlas-service-%s", dbaasService.UID), - Namespace: dbaasService.Namespace, - Labels: map[string]string{ - "owner-resource": dbaasService.Name, - }, - OwnerReferences: []metav1.OwnerReference{ - { - UID: dbaasService.GetUID(), - APIVersion: "dbaas.redhat.com/v1", - BlockOwnerDeletion: ptr.BoolPtr(false), - Controller: ptr.BoolPtr(true), - Kind: "DBaaSService", - Name: dbaasService.Name, - }, - }, - }, - } - _, err = controllerutil.CreateOrUpdate(ctx, r.Client, &atlasInstance, func() error { - // modifier callback, mutate spec to match expectation - atlasInstance.Spec = atlas.AtlasServiceSpec{ - Name: "dbaas-operator-test", - ConnectionSecret: &atlas.ResourceRef{ - Name: dbaasService.Spec.CredentialsSecretName, - }, - } + atlasInstance := models.OwnedAtlasService(&dbaasService) + _, err = controllerutil.CreateOrUpdate(ctx, r.Client, atlasInstance, func() error { + atlasInstance.Spec = models.MutateAtlasServiceSpec(&dbaasService) return nil }) if err != nil { @@ -123,41 +88,52 @@ func (r *DBaaSServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request return ctrl.Result{}, err } + // refetch object prior to status update in case modifications have occurred + err = r.Get(ctx, req.NamespacedName, &dbaasService) + if err != nil { + if apierrors.IsNotFound(err) { + // CR deleted since request queued, child objects getting GC'd, no requeue + log.Info("DBaasService resource not found, has been deleted") + return ctrl.Result{}, nil + } + // error fetching resource instance, requeue and try again + r.Log.Error(err, "error fetching DBaasService prior to status update") + return ctrl.Result{}, err + } + // matching AtlasService with ownerReference to our resource found, so it's been touched - update our status log.Info("AtlasService altered, syncing DBaaSService status") - err = r.syncServiceStatuses(&dbaasService, &found) + err = r.syncServiceStatuses(&dbaasService, found) if err != nil { r.Log.Error(err, "error syncing service status") return ctrl.Result{}, err } - if err = r.Status().Update(ctx, &dbaasService); err != nil { - r.Log.Error(err, "error saving modified DBaaSService status") - return ctrl.Result{}, err + if apierrors.IsConflict(err) { + r.Log.Info("conflict at status update, requeue to sort it out") + return ctrl.Result{}, nil + } else { + r.Log.Error(err, "error saving modified DBaaSService status") + return ctrl.Result{}, err + } } + // instances have been selected for import & added to our Spec, so we need to create DBaasConnection for each if dbaasService.Spec.Imports != nil { for _, id := range dbaasService.Spec.Imports { - dbaasConnection := dbaasv1.DBaaSConnection{ - ObjectMeta: metav1.ObjectMeta{ - Name: fmt.Sprintf("atlas-connection-%s", id), - Namespace: dbaasService.Namespace, - }, - } - _, err = controllerutil.CreateOrUpdate(ctx, r.Client, &dbaasConnection, func() error { - // modifier callback, mutate spec to match expectation + dbaasConnection := models.DBaaSConnection(&dbaasService) + _, err = controllerutil.CreateOrUpdate(ctx, r.Client, dbaasConnection, func() error { dbaasConnection.Spec = dbaasv1.DBaaSConnectionSpec{ Imports: []string{id}, } return nil }) if err != nil { - r.Log.Error(err, "error creating new matching AtlasService") + r.Log.Error(err, "error creating new DBaaSConnection for import selection") return ctrl.Result{}, err } } } - // reconcile cycle complete return ctrl.Result{}, nil } diff --git a/controllers/models/dbaasconnection_resources.go b/controllers/models/dbaasconnection_resources.go new file mode 100644 index 00000000..62e9880d --- /dev/null +++ b/controllers/models/dbaasconnection_resources.go @@ -0,0 +1,161 @@ +package models + +import ( + "encoding/base64" + "fmt" + dbaasv1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1" + v12 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + ptr "k8s.io/utils/pointer" +) + +func Deployment(dbaasConnection *dbaasv1.DBaaSConnection) *v12.Deployment { + return &v12.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dbaas-deploy", + Namespace: dbaasConnection.Namespace, + Labels: map[string]string{ + "managed-by": "dbaas-operator", + }, + }, + } +} + +func OwnedDeployment(dbaasConnection *dbaasv1.DBaaSConnection) *v12.Deployment { + return &v12.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "dbaas-deploy", + Namespace: dbaasConnection.Namespace, + Labels: map[string]string{ + "managed-by": "dbaas-operator", + }, + OwnerReferences: []metav1.OwnerReference{ + { + UID: dbaasConnection.GetUID(), + APIVersion: "dbaas.redhat.com/v1", + BlockOwnerDeletion: ptr.BoolPtr(false), + Controller: ptr.BoolPtr(true), + Kind: "DBaaSConnection", + Name: dbaasConnection.Name, + }, + }, + }, + } +} + +func MutateDeploymentSpec() v12.DeploymentSpec { + return v12.DeploymentSpec{ + Replicas: ptr.Int32Ptr(0), + Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": "bind-deploy"}}, + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"name": "bind-deploy"}, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "bind-deploy", + Image: "quay.io/bmozaffa/busybox", + ImagePullPolicy: v1.PullIfNotPresent, + Command: []string{"sh", "-c", "echo The app is running! && sleep 3600"}, + Ports: []v1.ContainerPort{{ContainerPort: int32(8080), Protocol: v1.ProtocolTCP}}, + }, + }, + }, + }, + } +} + +func ConfigMap(dbaasConnection *dbaasv1.DBaaSConnection) *v1.ConfigMap { + return &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("dbaas-atlas-connection-%s", dbaasConnection.Spec.Imports[0]), + Namespace: dbaasConnection.Namespace, + Labels: map[string]string{ + "managed-by": "dbaas-operator", + }, + }, + } +} + +func OwnedConfigMap(dbaasConnection *dbaasv1.DBaaSConnection) *v1.ConfigMap { + return &v1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("dbaas-atlas-connection-%s", dbaasConnection.Spec.Imports[0]), + Namespace: dbaasConnection.Namespace, + Labels: map[string]string{ + "managed-by": "dbaas-operator", + }, + OwnerReferences: []metav1.OwnerReference{ + { + UID: dbaasConnection.GetUID(), + APIVersion: "dbaas.redhat.com/v1", + BlockOwnerDeletion: ptr.BoolPtr(false), + Controller: ptr.BoolPtr(true), + Kind: "DBaaSConnection", + Name: dbaasConnection.Name, + }, + }, + }, + } +} + +func MutateConfigMapData(dbaasConnection *dbaasv1.DBaaSConnection) map[string]string { + return map[string]string{ + "db.host": "example.mongodb.net", + "db.name": fmt.Sprintf("db-%s", dbaasConnection.Spec.Imports[0]), + "db.port": "27017", + } +} + +func Secret(dbaasConnection *dbaasv1.DBaaSConnection) *v1.Secret { + return &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("dbaas-atlas-connection-%s", dbaasConnection.Spec.Imports[0]), + Namespace: dbaasConnection.Namespace, + Labels: map[string]string{ + "managed-by": "dbaas-operator", + }, + }, + } +} + +func OwnedSecret(dbaasConnection *dbaasv1.DBaaSConnection) *v1.Secret { + return &v1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Opaque", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("dbaas-atlas-connection-%s", dbaasConnection.Spec.Imports[0]), + Namespace: dbaasConnection.Namespace, + Labels: map[string]string{ + "managed-by": "dbaas-operator", + }, + OwnerReferences: []metav1.OwnerReference{ + { + UID: dbaasConnection.GetUID(), + APIVersion: "dbaas.redhat.com/v1", + BlockOwnerDeletion: ptr.BoolPtr(false), + Controller: ptr.BoolPtr(true), + Kind: "DBaaSConnection", + Name: dbaasConnection.Name, + }, + }, + }, + } +} + +func MutateSecretData() map[string][]byte { + return map[string][]byte{ + "db.password": []byte(base64.StdEncoding.EncodeToString([]byte("foo-user"))), + "db.user": []byte(base64.StdEncoding.EncodeToString([]byte("bar-pw"))), + } +} + +func UpdatedConnectionStatus(dbaasConnection *dbaasv1.DBaaSConnection) dbaasv1.DBaaSConnectionStatus { + return dbaasv1.DBaaSConnectionStatus{ + DBConfigMap: fmt.Sprintf("dbaas-atlas-connection-%s", dbaasConnection.Spec.Imports[0]), + DBCredentials: fmt.Sprintf("dbaas-atlas-connection-%s", dbaasConnection.Spec.Imports[0]), + } +} diff --git a/controllers/models/dbaasservice_resources.go b/controllers/models/dbaasservice_resources.go new file mode 100644 index 00000000..da680827 --- /dev/null +++ b/controllers/models/dbaasservice_resources.go @@ -0,0 +1,63 @@ +package models + +import ( + "fmt" + dbaasv1 "github.com/RHEcosystemAppEng/dbaas-operator/api/v1" + atlas "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + v1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + ptr "k8s.io/utils/pointer" +) + +func AtlasService(dbaasService *dbaasv1.DBaaSService) *v1.AtlasService { + return &v1.AtlasService{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "atlas.mongodb.com/v1", + Kind: "AtlasService", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("atlas-service-%s", dbaasService.UID), + Namespace: dbaasService.Namespace, + }, + } +} + +func OwnedAtlasService(dbaasService *dbaasv1.DBaaSService) *v1.AtlasService { + return &v1.AtlasService{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("atlas-service-%s", dbaasService.UID), + Namespace: dbaasService.Namespace, + Labels: map[string]string{ + "owner-resource": dbaasService.Name, + }, + OwnerReferences: []metav1.OwnerReference{ + { + UID: dbaasService.GetUID(), + APIVersion: "dbaas.redhat.com/v1", + BlockOwnerDeletion: ptr.BoolPtr(false), + Controller: ptr.BoolPtr(true), + Kind: "DBaaSService", + Name: dbaasService.Name, + }, + }, + }, + } +} + +func MutateAtlasServiceSpec(dbaasService *dbaasv1.DBaaSService) atlas.AtlasServiceSpec { + return atlas.AtlasServiceSpec{ + Name: "dbaas-operator-test", + ConnectionSecret: &atlas.ResourceRef{ + Name: dbaasService.Spec.CredentialsSecretName, + }, + } +} + +func DBaaSConnection(dbaasService *dbaasv1.DBaaSService) *dbaasv1.DBaaSConnection { + return &dbaasv1.DBaaSConnection{ + ObjectMeta: metav1.ObjectMeta{ + Name: "atlas-connection", + Namespace: dbaasService.Namespace, + }, + } +} diff --git a/go.mod b/go.mod index 4472447a..af1c2738 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/mongodb/mongodb-atlas-kubernetes v0.5.0 github.com/onsi/ginkgo v1.15.2 github.com/onsi/gomega v1.11.0 + k8s.io/api v0.19.2 k8s.io/apimachinery v0.19.2 k8s.io/client-go v0.19.2 k8s.io/utils v0.0.0-20200912215256-4140de9c8800