diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 7a8e6de3..55dfce3b 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -85,6 +85,7 @@ rules: - delete - get - list + - update - watch - apiGroups: - "" diff --git a/config/samples/all_flash_cluster_cr.yaml b/config/samples/all_flash_cluster_cr.yaml index 52bf312e..b6ed64c3 100644 --- a/config/samples/all_flash_cluster_cr.yaml +++ b/config/samples/all_flash_cluster_cr.yaml @@ -12,7 +12,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/dim_nostorage_cluster_cr.yaml b/config/samples/dim_nostorage_cluster_cr.yaml index f33510ea..13c27efb 100644 --- a/config/samples/dim_nostorage_cluster_cr.yaml +++ b/config/samples/dim_nostorage_cluster_cr.yaml @@ -5,7 +5,7 @@ metadata: namespace: aerospike spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 podSpec: multiPodPerHost: true diff --git a/config/samples/dim_nostorage_cluster_skip_validation_cr.yaml b/config/samples/dim_nostorage_cluster_skip_validation_cr.yaml index 13e74d1a..8dbd797a 100644 --- a/config/samples/dim_nostorage_cluster_skip_validation_cr.yaml +++ b/config/samples/dim_nostorage_cluster_skip_validation_cr.yaml @@ -20,7 +20,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 podSpec: multiPodPerHost: true diff --git a/config/samples/hdd_dim_storage_cluster_cr.yaml b/config/samples/hdd_dim_storage_cluster_cr.yaml index b5b52666..1ad579fc 100644 --- a/config/samples/hdd_dim_storage_cluster_cr.yaml +++ b/config/samples/hdd_dim_storage_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/host_network_cluster_cr.yaml b/config/samples/host_network_cluster_cr.yaml index e4b63b2e..99bc0017 100644 --- a/config/samples/host_network_cluster_cr.yaml +++ b/config/samples/host_network_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/ldap_cluster_cr.yaml b/config/samples/ldap_cluster_cr.yaml index 96c19214..dc779946 100644 --- a/config/samples/ldap_cluster_cr.yaml +++ b/config/samples/ldap_cluster_cr.yaml @@ -14,7 +14,7 @@ metadata: namespace: aerospike spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 podSpec: multiPodPerHost: true diff --git a/config/samples/pmem_cluster_cr.yaml b/config/samples/pmem_cluster_cr.yaml index 44497705..c6439b06 100644 --- a/config/samples/pmem_cluster_cr.yaml +++ b/config/samples/pmem_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/podspec_cr.yaml b/config/samples/podspec_cr.yaml index d9642d2b..fa19fa2f 100644 --- a/config/samples/podspec_cr.yaml +++ b/config/samples/podspec_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/rack_enabled_cluster_cr.yaml b/config/samples/rack_enabled_cluster_cr.yaml index 7319e82f..dfbde112 100644 --- a/config/samples/rack_enabled_cluster_cr.yaml +++ b/config/samples/rack_enabled_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 rackConfig: namespaces: - test diff --git a/config/samples/sc_mode_cluster_cr.yaml b/config/samples/sc_mode_cluster_cr.yaml index 845f3442..e9975eef 100644 --- a/config/samples/sc_mode_cluster_cr.yaml +++ b/config/samples/sc_mode_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 4 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 rosterNodeBlockList: - 1A0 diff --git a/config/samples/shadow_device_cluster_cr.yaml b/config/samples/shadow_device_cluster_cr.yaml index 42656dae..a6b74f1e 100644 --- a/config/samples/shadow_device_cluster_cr.yaml +++ b/config/samples/shadow_device_cluster_cr.yaml @@ -7,7 +7,7 @@ metadata: spec: # Add fields here size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/shadow_file_cluster_cr.yaml b/config/samples/shadow_file_cluster_cr.yaml index 5d1a0e71..38a952af 100644 --- a/config/samples/shadow_file_cluster_cr.yaml +++ b/config/samples/shadow_file_cluster_cr.yaml @@ -7,7 +7,7 @@ metadata: spec: # Add fields here size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/ssd_storage_cluster_cr.yaml b/config/samples/ssd_storage_cluster_cr.yaml index 6cb15893..c21d7c3e 100644 --- a/config/samples/ssd_storage_cluster_cr.yaml +++ b/config/samples/ssd_storage_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/tls_cluster_cr.yaml b/config/samples/tls_cluster_cr.yaml index 97f5ddb1..7158ac70 100644 --- a/config/samples/tls_cluster_cr.yaml +++ b/config/samples/tls_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 4 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/xdr_dst_cluster_cr.yaml b/config/samples/xdr_dst_cluster_cr.yaml index 01196be8..9d2f7482 100644 --- a/config/samples/xdr_dst_cluster_cr.yaml +++ b/config/samples/xdr_dst_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/config/samples/xdr_src_cluster_cr.yaml b/config/samples/xdr_src_cluster_cr.yaml index 43cd5ecb..df68b652 100644 --- a/config/samples/xdr_src_cluster_cr.yaml +++ b/config/samples/xdr_src_cluster_cr.yaml @@ -6,7 +6,7 @@ metadata: spec: size: 2 - image: aerospike/aerospike-server-enterprise:7.2.0.1 + image: aerospike/aerospike-server-enterprise:8.0.0.2 storage: filesystemVolumePolicy: diff --git a/helm-charts/aerospike-backup-service/README.md b/helm-charts/aerospike-backup-service/README.md index 13f768a8..0b77d5db 100644 --- a/helm-charts/aerospike-backup-service/README.md +++ b/helm-charts/aerospike-backup-service/README.md @@ -1,6 +1,6 @@ # Aerospike Backup Service (Custom Resource) Helm Chart -A Helm chart for `AerospikeBackupService` custom resource to be used with the Aerospike Kubernetes Operator. +A Helm chart for `AerospikeBackupService` (ABS) custom resource to be used with the Aerospike Kubernetes Operator. ## Pre Requisites @@ -18,9 +18,21 @@ helm repo update ### Deploy Aerospike Backup Service +#### Prepare the namespace + +We recommend using one ABS deployment per Aerospike cluster. + +Create the service account for the ABS in the namespace where ABS is deployed + +```sh +kubectl create serviceaccount aerospike-backup-service -n +``` + +> Note: ServiceAccount name can be configured. Update the configured ServiceAccount in a ABS CR file to use a different service account name. + #### Install the chart -`` used to install Aerospike backup service chart must be included in `watchNamespaces` value of +`` used to install ABS chart must be included in `watchNamespaces` value of aerospike-kubernetes-operator's `values.yaml` ```sh @@ -38,22 +50,18 @@ helm install aerospike-backup-service aerospike/aerospike-backup-service \ ## Configurations -| Name | Description | Default | -|------------------------------|-------------------------------------------------------------------------------|--------------------------------------| -| `image.repository` | Aerospike backup service container image repository | `aerospike/aerospike-backup-service` | -| `image.tag` | Aerospike backup service container image tag | `3.0.0` | -| `customLabels` | Custom labels to add on the AerospikeBackupService resource | `{}` (nil) | -| `serviceAccount.create` | Enable ServiceAccount creation for Aerospike backup service. | true | -| `serviceAccount.annotations` | ServiceAccount annotations | `{}` (nil) | -| `backupServiceConfig` | Aerospike backup service configuration | `{}` (nil) | -| `secrets` | Secrets to be mounted in the Aerospike Backup Service pod like aws creds etc. | `[]` (nil) | -| `resources` | Aerospike backup service pod resource requirements | `{}` (nil) | -| `service` | Kubernetes service configuration for Aerospike backup service | `{}` (nil) | - +| Name | Description | Default | +|-----------------------|-------------------------------------------------------------------------------|--------------------------------------| +| `image.repository` | Aerospike backup service container image repository | `aerospike/aerospike-backup-service` | +| `image.tag` | Aerospike backup service container image tag | `3.0.0` | +| `customLabels` | Custom labels to add on the Aerospike backup service resource | `{}` (nil) | +| `backupServiceConfig` | Aerospike backup service configuration | `{}` (nil) | +| `secrets` | Secrets to be mounted in the Aerospike backup service pod like aws creds etc. | `[]` (nil) | +| `resources` | Aerospike backup service pod resource requirements | `{}` (nil) | +| `service` | Kubernetes service configuration for Aerospike backup service | `{}` (nil) | +| `podSpec` | Aerospike backup service pod configuration | `{}` (nil) | ### Configurations Explained - -[//]: # (TODO: Update below link when the documentation is available.) Refer -to [AerospikeBackupService Customer Resource Spec](https://docs.aerospike.com/cloud/kubernetes/operator/cluster-configuration-settings#spec) +to [AerospikeBackupService Customer Resource Spec](https://aerospike.com/docs/cloud/kubernetes/operator/backup-and-restore/backup-service-configuration#spec) for details on above [configuration fields](#Configurations) diff --git a/helm-charts/aerospike-backup-service/values.yaml b/helm-charts/aerospike-backup-service/values.yaml index 73e0b897..d487ec3e 100644 --- a/helm-charts/aerospike-backup-service/values.yaml +++ b/helm-charts/aerospike-backup-service/values.yaml @@ -25,7 +25,6 @@ backupServiceConfig: {} # backup-policies: # test-policy: # parallel: 3 -# remove-files: KeepAll # storage: # local: # local-storage: diff --git a/helm-charts/aerospike-backup/README.md b/helm-charts/aerospike-backup/README.md index fbc268aa..73e5c233 100644 --- a/helm-charts/aerospike-backup/README.md +++ b/helm-charts/aerospike-backup/README.md @@ -49,8 +49,6 @@ helm install aerospike-backup aerospike/aerospike-backup \ | `onDemandBackups[*].delay` | Delay interval before starting the on-demand backup | | ### Configurations Explained - -[//]: # (TODO: Update below link when the documentation is available.) Refer -to [AerospikeBackup Customer Resource Spec](https://docs.aerospike.com/cloud/kubernetes/operator/cluster-configuration-settings#spec) +to [AerospikeBackup Customer Resource Spec](https://aerospike.com/docs/cloud/kubernetes/operator/backup-and-restore/backup-configuration#spec) for details on above [configuration fields](#Configurations) diff --git a/helm-charts/aerospike-cluster/README.md b/helm-charts/aerospike-cluster/README.md index 4c297a8c..76f4d702 100644 --- a/helm-charts/aerospike-cluster/README.md +++ b/helm-charts/aerospike-cluster/README.md @@ -48,7 +48,7 @@ helm install aerospike ./aerospike-cluster/ \ | -- |---------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------| | `replicas` | Aerospike cluster size | `3` | | `image.repository` | Aerospike server container image repository | `aerospike/aerospike-server-enterprise` | -| `image.tag` | Aerospike server container image tag | `7.2.0.1` | +| `image.tag` | Aerospike server container image tag | `8.0.0.2` | | `imagePullSecrets` | Secrets containing credentials to pull Aerospike container image from a private registry | `{}` (nil) | | `customLabels` | Custom labels to add on the aerospikecluster resource | `{}` (nil) | | `aerospikeAccessControl` | Aerospike access control configuration. Define users and roles to be created on the cluster. | `{}` (nil) | @@ -116,4 +116,4 @@ validationPolicy: ### Configurations Explained -Refer to [AerospikeCluster Customer Resource Spec](https://docs.aerospike.com/cloud/kubernetes/operator/cluster-configuration-settings#spec) for details on above [configuration fields](#Configurations) +Refer to [AerospikeCluster Customer Resource Spec](https://aerospike.com/docs/cloud/kubernetes/operator/configuration/Cluster-configuration-settings#spec) for details on above [configuration fields](#Configurations) diff --git a/helm-charts/aerospike-cluster/templates/aerospike-cluster-cr.yaml b/helm-charts/aerospike-cluster/templates/aerospike-cluster-cr.yaml index c4a9c856..def7ded0 100644 --- a/helm-charts/aerospike-cluster/templates/aerospike-cluster-cr.yaml +++ b/helm-charts/aerospike-cluster/templates/aerospike-cluster-cr.yaml @@ -16,7 +16,7 @@ spec: size: {{ .Values.replicas }} # Aerospike server docker image - image: {{ .Values.image.repository | default "aerospike/aerospike-server-enterprise" }}:{{ .Values.image.tag | default "7.2.0.1" }} + image: {{ .Values.image.repository | default "aerospike/aerospike-server-enterprise" }}:{{ .Values.image.tag | default "8.0.0.2" }} ## maxUnavailable defines percentage/number of pods that can be allowed to go down or unavailable ## before application disruption. diff --git a/helm-charts/aerospike-cluster/values.yaml b/helm-charts/aerospike-cluster/values.yaml index 1112b1b6..d01d2ee4 100644 --- a/helm-charts/aerospike-cluster/values.yaml +++ b/helm-charts/aerospike-cluster/values.yaml @@ -8,7 +8,7 @@ replicas: 3 ## Aerospike server docker image image: repository: aerospike/aerospike-server-enterprise - tag: 7.2.0.1 + tag: 8.0.0.2 ## In case the above image is pulled from a registry that requires ## authentication, a secret containing credentials can be added diff --git a/helm-charts/aerospike-kubernetes-operator/templates/aerospike-operator-manager-clusterrole.yaml b/helm-charts/aerospike-kubernetes-operator/templates/aerospike-operator-manager-clusterrole.yaml index 5afb86ad..b34795d1 100644 --- a/helm-charts/aerospike-kubernetes-operator/templates/aerospike-operator-manager-clusterrole.yaml +++ b/helm-charts/aerospike-kubernetes-operator/templates/aerospike-operator-manager-clusterrole.yaml @@ -91,6 +91,7 @@ rules: - get - list - watch + - update - apiGroups: - "" resources: diff --git a/helm-charts/aerospike-restore/README.md b/helm-charts/aerospike-restore/README.md index 06966f8c..51ed2282 100644 --- a/helm-charts/aerospike-restore/README.md +++ b/helm-charts/aerospike-restore/README.md @@ -48,8 +48,6 @@ helm install aerospike-restore aerospike/aerospike-restore \ | `pollingPeriod` | Polling period for restore operation status | `60s` | ### Configurations Explained - -[//]: # (TODO: Update below link when the documentation is available.) Refer -to [AerospikeRestore Customer Resource Spec](https://docs.aerospike.com/cloud/kubernetes/operator/cluster-configuration-settings#spec) +to [AerospikeRestore Customer Resource Spec](https://aerospike.com/docs/cloud/kubernetes/operator/backup-and-restore/restore-configuration#spec) for details on above [configuration fields](#Configurations) diff --git a/internal/controller/backup-service/reconciler.go b/internal/controller/backup-service/reconciler.go index f1873e32..517586d1 100644 --- a/internal/controller/backup-service/reconciler.go +++ b/internal/controller/backup-service/reconciler.go @@ -25,6 +25,7 @@ import ( "github.com/aerospike/aerospike-backup-service/v3/pkg/validation" asdbv1beta1 "github.com/aerospike/aerospike-kubernetes-operator/api/v1beta1" "github.com/aerospike/aerospike-kubernetes-operator/internal/controller/common" + backup_service "github.com/aerospike/aerospike-kubernetes-operator/pkg/backup-service" "github.com/aerospike/aerospike-kubernetes-operator/pkg/utils" lib "github.com/aerospike/aerospike-management-lib" ) @@ -90,7 +91,8 @@ func (r *SingleBackupServiceReconciler) Reconcile() (result ctrl.Result, recErr } if err := r.reconcileConfigMap(); err != nil { - r.Log.Error(err, "Failed to reconcile config map") + r.Log.Error(err, "Failed to reconcile config map", + "configmap", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeWarning, "ConfigMapReconcileFailed", "Failed to reconcile config map %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -101,7 +103,8 @@ func (r *SingleBackupServiceReconciler) Reconcile() (result ctrl.Result, recErr } if err := r.reconcileDeployment(); err != nil { - r.Log.Error(err, "Failed to reconcile deployment") + r.Log.Error(err, "Failed to reconcile deployment", + "deployment", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeWarning, "DeploymentReconcileFailed", "Failed to reconcile deployment %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -112,7 +115,8 @@ func (r *SingleBackupServiceReconciler) Reconcile() (result ctrl.Result, recErr } if err := r.reconcileService(); err != nil { - r.Log.Error(err, "Failed to reconcile service") + r.Log.Error(err, "Failed to reconcile service", + "service", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeWarning, "ServiceReconcileFailed", "Failed to reconcile service %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -131,6 +135,8 @@ func (r *SingleBackupServiceReconciler) Reconcile() (result ctrl.Result, recErr return ctrl.Result{}, err } + r.Log.Info("Reconcile completed successfully") + return ctrl.Result{}, nil } @@ -148,7 +154,7 @@ func (r *SingleBackupServiceReconciler) reconcileConfigMap() error { } r.Log.Info("Creating Backup Service ConfigMap", - "name", getBackupServiceName(r.aeroBackupService)) + "configmap", getBackupServiceName(r.aeroBackupService)) cm = &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -177,7 +183,7 @@ func (r *SingleBackupServiceReconciler) reconcileConfigMap() error { } r.Log.Info("Created Backup Service ConfigMap", - "name", getBackupServiceName(r.aeroBackupService)) + "configmap", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeNormal, "ConfigMapCreated", "Created Backup Service ConfigMap %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -186,7 +192,7 @@ func (r *SingleBackupServiceReconciler) reconcileConfigMap() error { r.Log.Info( "Backup Service ConfigMap already exist. Updating existing ConfigMap if required", - "name", getBackupServiceName(r.aeroBackupService), + "configmap", getBackupServiceName(r.aeroBackupService), ) desiredDataMap := make(map[string]interface{}) @@ -239,7 +245,7 @@ func (r *SingleBackupServiceReconciler) reconcileConfigMap() error { } r.Log.Info("Updated Backup Service ConfigMap", - "name", getBackupServiceName(r.aeroBackupService)) + "configmap", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeNormal, "ConfigMapUpdated", "Updated Backup Service ConfigMap %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -254,22 +260,16 @@ func (r *SingleBackupServiceReconciler) getConfigMapData() map[string]string { } func (r *SingleBackupServiceReconciler) reconcileDeployment() error { - var deploy app.Deployment - - if err := r.Client.Get(context.TODO(), - types.NamespacedName{ - Namespace: r.aeroBackupService.Namespace, - Name: r.aeroBackupService.Name, - }, &deploy, - ); err != nil { + deployment, err := r.getBackupSvcDeployment() + if err != nil { if !errors.IsNotFound(err) { return err } r.Log.Info("Creating Backup Service deployment", - "name", getBackupServiceName(r.aeroBackupService)) + "deployment", getBackupServiceName(r.aeroBackupService)) - deployment, err := r.getDeploymentObject() + deployment, err = r.getDeploymentObject() if err != nil { return err } @@ -288,7 +288,7 @@ func (r *SingleBackupServiceReconciler) reconcileDeployment() error { } r.Log.Info("Created Backup Service deployment", - "name", getBackupServiceName(r.aeroBackupService)) + "deployment", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeNormal, "DeploymentCreated", "Created Backup Service Deployment %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -297,83 +297,111 @@ func (r *SingleBackupServiceReconciler) reconcileDeployment() error { r.Log.Info( "Backup Service deployment already exist. Updating existing deployment if required", - "name", getBackupServiceName(r.aeroBackupService), + "deployment", getBackupServiceName(r.aeroBackupService), ) - oldResourceVersion := deploy.ResourceVersion + oldResourceVersion := deployment.ResourceVersion desiredDeployObj, err := r.getDeploymentObject() if err != nil { return err } - deploy.Spec = desiredDeployObj.Spec + deployment.Spec = desiredDeployObj.Spec - if err = r.Client.Update(context.TODO(), &deploy, common.UpdateOption); err != nil { + if err = r.Client.Update(context.TODO(), deployment, common.UpdateOption); err != nil { return fmt.Errorf("failed to update Backup service deployment: %v", err) } r.Log.Info("Updated Backup Service deployment", - "name", getBackupServiceName(r.aeroBackupService)) + "deployment", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeNormal, "DeploymentUpdated", "Updated Backup Service Deployment %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) - if oldResourceVersion != deploy.ResourceVersion { - r.Log.Info("Deployment spec is updated, will result in rolling restart") + if oldResourceVersion != deployment.ResourceVersion { + r.Log.Info("Deployment spec is updated, will result in rolling restart of Backup service pod", + "deployment", getBackupServiceName(r.aeroBackupService)) return r.waitForDeploymentToBeReady() } - // If status is empty then no need for config Hash comparison - if len(r.aeroBackupService.Status.Config.Raw) == 0 { - return r.waitForDeploymentToBeReady() + // Wait for deployment pods to be ready before doing any operation related to the backup service + if err := r.waitForDeploymentToBeReady(); err != nil { + return err + } + + return r.updateBackupSvcConfig() +} + +func (r *SingleBackupServiceReconciler) getBackupSvcDeployment() (*app.Deployment, error) { + var deployment app.Deployment + + if err := r.Client.Get(context.TODO(), + types.NamespacedName{ + Namespace: r.aeroBackupService.Namespace, + Name: r.aeroBackupService.Name, + }, &deployment, + ); err != nil { + return nil, err + } + + return &deployment, nil +} + +func (r *SingleBackupServiceReconciler) updateBackupSvcConfig() error { + var currentConfig, desiredConfig dto.Config + + backupSvc := &asdbv1beta1.BackupService{ + Name: r.aeroBackupService.Name, + Namespace: r.aeroBackupService.Namespace, } - desiredHash, err := utils.GetHash(string(r.aeroBackupService.Spec.Config.Raw)) + backupServiceClient, err := backup_service.GetBackupServiceClient(r.Client, backupSvc) if err != nil { return err } - currentHash, err := utils.GetHash(string(r.aeroBackupService.Status.Config.Raw)) + apiBackupSvcConfig, err := backupServiceClient.GetBackupServiceConfig() if err != nil { return err } - // If there is a change in config hash, then reload the config or restart the deployment pod - if desiredHash != currentHash { - r.Log.Info("BackupService config mismatch, will reload the config") + desiredData, err := common.GetBackupSvcConfigFromCM(r.Client, backupSvc) + if err != nil { + return err + } - if err := r.updateBackupSvcConfig(); err != nil { - return err - } + synced, err := common.IsBackupSvcFullConfigSynced(apiBackupSvcConfig, desiredData, r.Log) + if err != nil { + return err + } - r.Log.Info("Reloaded backup service") + if synced { + r.Log.Info("Backup service config already latest, skipping update") + return nil } - return nil -} + r.Log.Info("Backup service config mismatch, will reload the config") -func (r *SingleBackupServiceReconciler) updateBackupSvcConfig() error { - var currentConfig, desiredConfig dto.Config + apiBackupSvcConfigData, err := yaml.Marshal(apiBackupSvcConfig) + if err != nil { + return err + } - if err := yaml.Unmarshal(r.aeroBackupService.Status.Config.Raw, ¤tConfig); err != nil { + if err := yaml.Unmarshal(apiBackupSvcConfigData, ¤tConfig); err != nil { return err } - if err := yaml.Unmarshal(r.aeroBackupService.Spec.Config.Raw, &desiredConfig); err != nil { + if err := yaml.Unmarshal([]byte(desiredData), &desiredConfig); err != nil { return err } if err := validation.ValidateStaticFieldChanges(¤tConfig, &desiredConfig); err != nil { - r.Log.Info("Static config change detected, will result in rolling restart") + r.Log.Info("Static config change detected, will result in rolling restart of Backup service pod") // In case of static config change restart the backup service pod return r.restartBackupSvcPod() } - return common.ReloadBackupServiceConfigInPods(r.Client, r.Log, - &asdbv1beta1.BackupService{ - Name: r.aeroBackupService.Name, - Namespace: r.aeroBackupService.Namespace}, - ) + return common.ReloadBackupServiceConfigInPods(r.Client, backupServiceClient, r.Log, backupSvc) } func (r *SingleBackupServiceReconciler) restartBackupSvcPod() error { @@ -547,7 +575,7 @@ func (r *SingleBackupServiceReconciler) reconcileService() error { } r.Log.Info("Creating Backup Service", - "name", getBackupServiceName(r.aeroBackupService)) + "service", getBackupServiceName(r.aeroBackupService)) svc, err := r.getServiceObject() if err != nil { @@ -568,7 +596,7 @@ func (r *SingleBackupServiceReconciler) reconcileService() error { } r.Log.Info("Created Backup Service", - "name", getBackupServiceName(r.aeroBackupService)) + "service", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeNormal, "ServiceCreated", "Created Backup Service %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -577,7 +605,7 @@ func (r *SingleBackupServiceReconciler) reconcileService() error { r.Log.Info( "Backup Service already exist. Updating existing service if required", - "name", getBackupServiceName(r.aeroBackupService), + "service", getBackupServiceName(r.aeroBackupService), ) svc, err := r.getServiceObject() @@ -591,7 +619,7 @@ func (r *SingleBackupServiceReconciler) reconcileService() error { return fmt.Errorf("failed to update Backup service: %v", err) } - r.Log.Info("Updated Backup Service", "name", getBackupServiceName(r.aeroBackupService)) + r.Log.Info("Updated Backup Service", "service", getBackupServiceName(r.aeroBackupService)) r.Recorder.Eventf(r.aeroBackupService, corev1.EventTypeNormal, "ServiceUpdated", "Updated Backup Service %s/%s", r.aeroBackupService.Namespace, r.aeroBackupService.Name) @@ -685,18 +713,33 @@ func (r *SingleBackupServiceReconciler) waitForDeploymentToBeReady() error { ) r.Log.Info( - "Waiting for deployment to be ready", "WaitTimePerPod", podStatusTimeout, + "Waiting for deployment to be ready", "deployment", getBackupServiceName(r.aeroBackupService), + "WaitTimePerPod", podStatusTimeout, ) if err := wait.PollUntilContextTimeout(context.TODO(), podStatusRetryInterval, podStatusTimeout, true, func(ctx context.Context) (done bool, err error) { + deployment, err := r.getBackupSvcDeployment() + if err != nil { + return false, err + } + + // This check is for the condition when deployment rollout is yet to begin, and + // pods with new spec are yet to be created. + if deployment.Generation > deployment.Status.ObservedGeneration { + r.Log.Info("Waiting for deployment to be ready", + "deployment", getBackupServiceName(r.aeroBackupService)) + return false, nil + } + podList, err := common.GetBackupServicePodList(r.Client, r.aeroBackupService.Name, r.aeroBackupService.Namespace) if err != nil { return false, err } if len(podList.Items) == 0 { - r.Log.Info("No pod found for deployment") + r.Log.Info("No pod found for deployment", + "deployment", getBackupServiceName(r.aeroBackupService)) return false, nil } @@ -708,21 +751,12 @@ func (r *SingleBackupServiceReconciler) waitForDeploymentToBeReady() error { } if !utils.IsPodRunningAndReady(pod) { - r.Log.Info("Pod is not ready", "pod", pod.Name) + r.Log.Info("Pod is not ready", "pod", utils.GetNamespacedName(pod)) return false, nil } } - var deploy app.Deployment - if err := r.Client.Get( - ctx, - types.NamespacedName{Name: r.aeroBackupService.Name, Namespace: r.aeroBackupService.Namespace}, - &deploy, - ); err != nil { - return false, err - } - - if deploy.Status.Replicas != *deploy.Spec.Replicas { + if deployment.Status.Replicas != *deployment.Spec.Replicas { return false, nil } @@ -732,7 +766,7 @@ func (r *SingleBackupServiceReconciler) waitForDeploymentToBeReady() error { return err } - r.Log.Info("Deployment is ready") + r.Log.Info("Deployment is ready", "deployment", getBackupServiceName(r.aeroBackupService)) return nil } diff --git a/internal/controller/backup/reconciler.go b/internal/controller/backup/reconciler.go index 8e443747..25fc0c9d 100644 --- a/internal/controller/backup/reconciler.go +++ b/internal/controller/backup/reconciler.go @@ -96,6 +96,8 @@ func (r *SingleBackupReconciler) Reconcile() (result ctrl.Result, recErr error) return reconcile.Result{}, err } + r.Log.Info("Reconcile completed successfully") + return ctrl.Result{}, nil } @@ -124,7 +126,13 @@ func (r *SingleBackupReconciler) cleanUpAndRemoveFinalizer(finalizerName string) return err } - if err := common.ReloadBackupServiceConfigInPods(r.Client, r.Log, &r.aeroBackup.Spec.BackupService); err != nil { + backupServiceClient, err := backup_service.GetBackupServiceClient(r.Client, &r.aeroBackup.Spec.BackupService) + if err != nil { + return err + } + + if err := common.ReloadBackupServiceConfigInPods(r.Client, backupServiceClient, + r.Log, &r.aeroBackup.Spec.BackupService); err != nil { return err } @@ -151,7 +159,7 @@ func (r *SingleBackupReconciler) reconcileConfigMap() error { } r.Log.Info("Updating existing ConfigMap for Backup", - "name", r.aeroBackup.Spec.BackupService.String(), + "configmap", r.aeroBackup.Spec.BackupService.String(), ) specBackupConfig, err := r.getBackupConfigInMap() @@ -226,7 +234,7 @@ func (r *SingleBackupReconciler) reconcileConfigMap() error { } r.Log.Info("Updated Backup Service ConfigMap for Backup", - "name", r.aeroBackup.Spec.BackupService.String(), + "configmap", r.aeroBackup.Spec.BackupService.String(), ) r.Recorder.Eventf(r.aeroBackup, corev1.EventTypeNormal, "ConfigMapUpdated", "Updated Backup Service ConfigMap %s for Backup %s/%s", r.aeroBackup.Spec.BackupService.String(), @@ -240,7 +248,7 @@ func (r *SingleBackupReconciler) removeBackupInfoFromConfigMap() error { if err != nil { if errors.IsNotFound(err) { r.Log.Info("Backup Service ConfigMap not found, skip updating", - "name", r.aeroBackup.Spec.BackupService.String()) + "configmap", r.aeroBackup.Spec.BackupService.String()) return nil } @@ -248,7 +256,7 @@ func (r *SingleBackupReconciler) removeBackupInfoFromConfigMap() error { } r.Log.Info("Removing Backup info from existing ConfigMap", - "name", r.aeroBackup.Spec.BackupService.String(), + "configmap", r.aeroBackup.Spec.BackupService.String(), ) specBackupConfig, err := r.getBackupConfigInMap() @@ -316,7 +324,7 @@ func (r *SingleBackupReconciler) removeBackupInfoFromConfigMap() error { } r.Log.Info("Removed Backup info from existing ConfigMap", - "name", r.aeroBackup.Spec.BackupService.String(), + "configmap", r.aeroBackup.Spec.BackupService.String(), ) return nil @@ -418,7 +426,7 @@ func (r *SingleBackupReconciler) reconcileScheduledBackup() error { } if hotReloadRequired { - err = common.ReloadBackupServiceConfigInPods(r.Client, r.Log, &r.aeroBackup.Spec.BackupService) + err = common.ReloadBackupServiceConfigInPods(r.Client, serviceClient, r.Log, &r.aeroBackup.Spec.BackupService) if err != nil { return err } diff --git a/internal/controller/cluster/aerospikecluster_controller.go b/internal/controller/cluster/aerospikecluster_controller.go index 07563e3a..c1ebb669 100644 --- a/internal/controller/cluster/aerospikecluster_controller.go +++ b/internal/controller/cluster/aerospikecluster_controller.go @@ -66,7 +66,7 @@ type RackState struct { Size int } -// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;delete +// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;delete;update // +kubebuilder:rbac:groups=core,resources=pods/exec,verbs=create // +kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch;create;update;patch;delete diff --git a/internal/controller/common/backup_config_util.go b/internal/controller/common/backup_config_util.go index 1ebe2ecb..17ac2a8e 100644 --- a/internal/controller/common/backup_config_util.go +++ b/internal/controller/common/backup_config_util.go @@ -51,6 +51,7 @@ func GetBackupServicePodList(k8sClient client.Client, name, namespace string) (* func ReloadBackupServiceConfigInPods( k8sClient client.Client, + backupServiceClient *backup_service.Client, log logr.Logger, backupSvc *v1beta1.BackupService, ) error { @@ -90,13 +91,7 @@ func ReloadBackupServiceConfigInPods( // Waiting for 1 second so that pods get the latest configMap update. time.Sleep(1 * time.Second) - backupServiceClient, err := backup_service.GetBackupServiceClient(k8sClient, backupSvc) - if err != nil { - return err - } - - err = backupServiceClient.ApplyConfig() - if err != nil { + if err := backupServiceClient.ApplyConfig(); err != nil { return err } @@ -113,27 +108,17 @@ func validateBackupSvcConfigReload(k8sClient client.Client, return err } - var cm corev1.ConfigMap - - if err := k8sClient.Get(context.TODO(), types.NamespacedName{ - Namespace: backupSvc.Namespace, - Name: backupSvc.Name, - }, &cm); err != nil { + desiredData, err := GetBackupSvcConfigFromCM(k8sClient, backupSvc) + if err != nil { return err } - configMapBackupSvcConfig := make(map[string]interface{}) - - data := cm.Data[v1beta1.BackupServiceConfigYAML] - - if err := yaml.Unmarshal([]byte(data), &configMapBackupSvcConfig); err != nil { + synced, err := IsBackupSvcFullConfigSynced(apiBackupSvcConfig, desiredData, log) + if err != nil { return err } - log.Info(fmt.Sprintf("Backup Service config fetched from Backup Service via API: %v", apiBackupSvcConfig)) - log.Info(fmt.Sprintf("Backup Service config found in ConfigMap: %v", configMapBackupSvcConfig)) - - if !reflect.DeepEqual(apiBackupSvcConfig, configMapBackupSvcConfig) { + if !synced { log.Info("Backup service config not yet updated in pods, requeue") return fmt.Errorf("backup service config not yet updated in pods") } @@ -142,3 +127,31 @@ func validateBackupSvcConfigReload(k8sClient client.Client, return nil } + +func IsBackupSvcFullConfigSynced(currentBackupSvcConfig map[string]interface{}, desired string, + log logr.Logger, +) (bool, error) { + desiredBackupSvcConfig := make(map[string]interface{}) + + if err := yaml.Unmarshal([]byte(desired), &desiredBackupSvcConfig); err != nil { + return false, err + } + + log.Info(fmt.Sprintf("Backup Service config fetched from Backup Service via API: %v", currentBackupSvcConfig)) + log.Info(fmt.Sprintf("Backup Service config found in ConfigMap: %v", desiredBackupSvcConfig)) + + return reflect.DeepEqual(currentBackupSvcConfig, desiredBackupSvcConfig), nil +} + +func GetBackupSvcConfigFromCM(k8sClient client.Client, backupSvc *v1beta1.BackupService) (string, error) { + var cm corev1.ConfigMap + + if err := k8sClient.Get(context.TODO(), types.NamespacedName{ + Namespace: backupSvc.Namespace, + Name: backupSvc.Name, + }, &cm); err != nil { + return "", err + } + + return cm.Data[v1beta1.BackupServiceConfigYAML], nil +} diff --git a/internal/controller/restore/reconciler.go b/internal/controller/restore/reconciler.go index d529cb0d..8c84b390 100644 --- a/internal/controller/restore/reconciler.go +++ b/internal/controller/restore/reconciler.go @@ -93,6 +93,8 @@ func (r *SingleRestoreReconciler) Reconcile() (result ctrl.Result, recErr error) r.Recorder.Eventf(r.aeroRestore, corev1.EventTypeNormal, "RestoreCompleted", "Restore completed successfully %s/%s", r.aeroRestore.Namespace, r.aeroRestore.Name) + r.Log.Info("Reconcile completed successfully") + return ctrl.Result{}, nil } diff --git a/pkg/configschema/schemas b/pkg/configschema/schemas index 50ca067d..87bc637c 160000 --- a/pkg/configschema/schemas +++ b/pkg/configschema/schemas @@ -1 +1 @@ -Subproject commit 50ca067d6b9d248bf9dea2d78060e6f42a9c2c0e +Subproject commit 87bc637c2c2edecd63194cee03c445c83ac60ddc diff --git a/test/cluster/cluster_helper.go b/test/cluster/cluster_helper.go index db63394e..10ab36af 100644 --- a/test/cluster/cluster_helper.go +++ b/test/cluster/cluster_helper.go @@ -32,14 +32,14 @@ import ( const ( baseImage = "aerospike/aerospike-server-enterprise" - nextServerVersion = "7.2.0.1_1" - latestServerVersion = "7.2.0.1" + nextServerVersion = "8.0.0.2_1" + latestServerVersion = "8.0.0.2" invalidVersion = "3.0.0.4" post6Version = "7.0.0.0" version6 = "6.0.0.5" - latestSchemaVersion = "7.2.0" + latestSchemaVersion = "8.0.0" ) var (