Skip to content

Commit

Permalink
Added Printer columns
Browse files Browse the repository at this point in the history
  • Loading branch information
abhishekdwivedi3060 committed Jul 9, 2024
1 parent c567b49 commit 0cc297b
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 20 deletions.
5 changes: 5 additions & 0 deletions api/v1beta1/aerospikebackup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,15 @@ type OnDemandSpec struct {
// AerospikeBackupStatus defines the observed state of AerospikeBackup
type AerospikeBackupStatus struct {
OnDemand []OnDemandSpec `json:"onDemand,omitempty"`

// TODO: finalize the status and phase
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Backup Service Name",type=string,JSONPath=`.spec.backupService.name`
// +kubebuilder:printcolumn:name="Backup Service Namespace",type=string,JSONPath=`.spec.backupService.namespace`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"

// AerospikeBackup is the Schema for the aerospikebackup API
type AerospikeBackup struct {
Expand Down
18 changes: 16 additions & 2 deletions api/v1beta1/aerospikebackupservice_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// +kubebuilder:validation:Enum=InProgress;Completed;Failed
type AerospikeBackupServicePhase string

// These are the valid phases of Aerospike Backup Service reconcile flow.
const (
AerospikeBackupServiceInProgress AerospikeBackupServicePhase = "InProgress"
AerospikeBackupServiceCompleted AerospikeBackupServicePhase = "Completed"
AerospikeBackupServiceFailed AerospikeBackupServicePhase = "Failed"
)

// AerospikeBackupServiceSpec defines the desired state of AerospikeBackupService
//
Expand Down Expand Up @@ -58,12 +65,19 @@ type AerospikeBackupServiceStatus struct {
// Backup service config hash
ConfigHash string `json:"configHash"`

// Backup service phase
Phase AerospikeBackupServicePhase `json:"phase,omitempty"`

// Backup service listening port
Port int32 `json:"port"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Image",type=string,JSONPath=`.spec.image`
// +kubebuilder:printcolumn:name="Service Type",type=string,JSONPath=`.spec.service.type`
//+kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"

// AerospikeBackupService is the Schema for the aerospikebackupservices API
type AerospikeBackupService struct {
Expand Down
3 changes: 3 additions & 0 deletions api/v1beta1/aerospikerestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ type AerospikeRestoreStatus struct {

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Backup Service Name",type=string,JSONPath=`.spec.backupService.name`
// +kubebuilder:printcolumn:name="Backup Service Namespace",type=string,JSONPath=`.spec.backupService.namespace`
//+kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.restoreResult.status`
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"

// AerospikeRestore is the Schema for the aerospikerestores API
//
Expand Down
12 changes: 11 additions & 1 deletion config/crd/bases/asdb.aerospike.com_aerospikebackups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,17 @@ spec:
singular: aerospikebackup
scope: Namespaced
versions:
- name: v1beta1
- additionalPrinterColumns:
- jsonPath: .spec.backupService.name
name: Backup Service Name
type: string
- jsonPath: .spec.backupService.namespace
name: Backup Service Namespace
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: AerospikeBackup is the Schema for the aerospikebackup API
Expand Down
22 changes: 21 additions & 1 deletion config/crd/bases/asdb.aerospike.com_aerospikebackupservices.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,20 @@ spec:
singular: aerospikebackupservice
scope: Namespaced
versions:
- name: v1beta1
- additionalPrinterColumns:
- jsonPath: .spec.image
name: Image
type: string
- jsonPath: .spec.service.type
name: Service Type
type: string
- jsonPath: .status.phase
name: Status
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: AerospikeBackupService is the Schema for the aerospikebackupservices
Expand Down Expand Up @@ -163,6 +176,13 @@ spec:
contextPath:
description: Backup Service API context path
type: string
phase:
description: Backup service phase
enum:
- InProgress
- Completed
- Failed
type: string
port:
description: Backup service listening port
format: int32
Expand Down
9 changes: 9 additions & 0 deletions config/crd/bases/asdb.aerospike.com_aerospikerestores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,18 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.backupService.name
name: Backup Service Name
type: string
- jsonPath: .spec.backupService.namespace
name: Backup Service Namespace
type: string
- jsonPath: .status.restoreResult.status
name: Status
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
Expand Down
4 changes: 2 additions & 2 deletions config/samples/asdb_v1beta1_aerospikebackup.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ spec:
name: aerospikebackupservice-sample
namespace: aerospike
onDemand:
id: first-ad-hoc-backup
routineName: test-routine
- id: first-ad-hoc-backup
routineName: test-routine
config:
aerospike-cluster:
test-cluster:
Expand Down
125 changes: 114 additions & 11 deletions controllers/backup-service/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package backupservice
import (
"context"
"fmt"
"time"

"github.com/go-logr/logr"
app "k8s.io/api/apps/v1"
Expand All @@ -12,11 +13,13 @@ import (
"k8s.io/apimachinery/pkg/labels"
k8sRuntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/record"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/yaml"

asdbv1beta1 "github.com/aerospike/aerospike-kubernetes-operator/api/v1beta1"
Expand Down Expand Up @@ -49,15 +52,35 @@ type SingleBackupServiceReconciler struct {
}

func (r *SingleBackupServiceReconciler) Reconcile() (result ctrl.Result, recErr error) {
// Set the status phase to Error if the recErr is not nil
// recErr is only set when reconcile failure should result in Error phase of the Backup service operation
defer func() {
if recErr != nil {
r.Log.Error(recErr, "Reconcile failed")

if err := r.setStatusPhase(asdbv1beta1.AerospikeBackupServiceFailed); err != nil {
recErr = err
}
}
}()

// Set the status to AerospikeClusterInProgress before starting any operations
if err := r.setStatusPhase(asdbv1beta1.AerospikeBackupServiceInProgress); err != nil {
return reconcile.Result{}, err
}

if err := r.reconcileConfigMap(); err != nil {
recErr = err
return ctrl.Result{}, err
}

if err := r.reconcileDeployment(); err != nil {
recErr = err
return ctrl.Result{}, err
}

if err := r.reconcileService(); err != nil {
recErr = err
return ctrl.Result{}, err
}

Expand Down Expand Up @@ -202,7 +225,7 @@ func (r *SingleBackupServiceReconciler) reconcileDeployment() error {
return fmt.Errorf("failed to deploy Backup service deployment: %v", err)
}

return nil
return r.waitForDeploymentToBeReady()
}

r.Log.Info(
Expand All @@ -225,7 +248,7 @@ func (r *SingleBackupServiceReconciler) reconcileDeployment() error {

if oldResourceVersion != deploy.ResourceVersion {
r.Log.Info("Deployment spec is updated, will result in rolling restart")
return nil
return r.waitForDeploymentToBeReady()
}

hash, err := utils.GetHash(string(r.aeroBackupService.Spec.Config.Raw))
Expand All @@ -237,14 +260,7 @@ func (r *SingleBackupServiceReconciler) reconcileDeployment() error {
if r.aeroBackupService.Status.ConfigHash != "" && hash != r.aeroBackupService.Status.ConfigHash {
r.Log.Info("Config hash is updated, will result in rolling restart")

var podList corev1.PodList

labelSelector := labels.SelectorFromSet(utils.LabelsForAerospikeBackupService(r.aeroBackupService.Name))
listOps := &client.ListOptions{
Namespace: r.aeroBackupService.Namespace, LabelSelector: labelSelector,
}

err = r.Client.List(context.TODO(), &podList, listOps)
podList, err := r.getBackupServicePodList()
if err != nil {
return err
}
Expand All @@ -258,7 +274,7 @@ func (r *SingleBackupServiceReconciler) reconcileDeployment() error {
}
}

return nil
return r.waitForDeploymentToBeReady()
}

return nil
Expand All @@ -268,6 +284,21 @@ func getBackupServiceName(aeroBackupService *asdbv1beta1.AerospikeBackupService)
return types.NamespacedName{Name: aeroBackupService.Name, Namespace: aeroBackupService.Namespace}
}

func (r *SingleBackupServiceReconciler) getBackupServicePodList() (*corev1.PodList, error) {
var podList corev1.PodList

labelSelector := labels.SelectorFromSet(utils.LabelsForAerospikeBackupService(r.aeroBackupService.Name))
listOps := &client.ListOptions{
Namespace: r.aeroBackupService.Namespace, LabelSelector: labelSelector,
}

if err := r.Client.List(context.TODO(), &podList, listOps); err != nil {
return nil, err
}

return &podList, nil
}

func (r *SingleBackupServiceReconciler) getDeploymentObject() (*app.Deployment, error) {
svcLabels := utils.LabelsForAerospikeBackupService(r.aeroBackupService.Name)
volumeMounts, volumes := r.getVolumeAndMounts()
Expand Down Expand Up @@ -534,6 +565,77 @@ func (r *SingleBackupServiceReconciler) getBackupServiceConfig() (*serviceConfig
return &svcConfig, nil
}

func (r *SingleBackupServiceReconciler) waitForDeploymentToBeReady() error {
const (
podStatusTimeout = 2 * time.Minute
podStatusRetryInterval = time.Second * 5
)

r.Log.Info(
"Waiting for deployment to be ready", "WaitTimePerPod", podStatusTimeout,
)

if err := wait.PollUntilContextTimeout(context.TODO(),
podStatusRetryInterval, podStatusTimeout, true, func(ctx context.Context) (done bool, err error) {
podList, err := r.getBackupServicePodList()
if err != nil {
return false, err
}

if len(podList.Items) == 0 {
return false, fmt.Errorf("no pod found for deployment")
}

for idx := range podList.Items {
pod := &podList.Items[idx]

if err := utils.CheckPodFailed(pod); err != nil {
return false, fmt.Errorf("pod %s failed: %v", pod.Name, err)
}

if !utils.IsPodRunningAndReady(pod) {
r.Log.Info("Pod is not ready", "pod", pod.Name)
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 {
return false, fmt.Errorf("deployment status is not updated")
}

return true, nil
},
); err != nil {
return err
}

r.Log.Info("Deployment is ready")

return nil
}

func (r *SingleBackupServiceReconciler) setStatusPhase(phase asdbv1beta1.AerospikeBackupServicePhase) error {
if r.aeroBackupService.Status.Phase != phase {
r.aeroBackupService.Status.Phase = phase

if err := r.Client.Status().Update(context.Background(), r.aeroBackupService); err != nil {
r.Log.Error(err, fmt.Sprintf("Failed to set restore status to %s", phase))
return err
}
}

return nil
}

func (r *SingleBackupServiceReconciler) updateStatus() error {
svcConfig, err := r.getBackupServiceConfig()
if err != nil {
Expand All @@ -548,6 +650,7 @@ func (r *SingleBackupServiceReconciler) updateStatus() error {
r.aeroBackupService.Status.ContextPath = svcConfig.contextPath
r.aeroBackupService.Status.Port = svcConfig.portInfo[common.HTTPKey]
r.aeroBackupService.Status.ConfigHash = hash
r.aeroBackupService.Status.Phase = asdbv1beta1.AerospikeBackupServiceCompleted

r.Log.Info(fmt.Sprintf("Updating status: %+v", r.aeroBackupService.Status))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,17 @@ spec:
singular: aerospikebackup
scope: Namespaced
versions:
- name: v1beta1
- additionalPrinterColumns:
- jsonPath: .spec.backupService.name
name: Backup Service Name
type: string
- jsonPath: .spec.backupService.namespace
name: Backup Service Namespace
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1beta1
schema:
openAPIV3Schema:
description: AerospikeBackup is the Schema for the aerospikebackup API
Expand Down
Loading

0 comments on commit 0cc297b

Please sign in to comment.