Skip to content

Commit

Permalink
KO-358: Enhance AerospikeBackupService CR with all the possible deplo…
Browse files Browse the repository at this point in the history
…yment configuration parameters (#328)

* Enhanced AerospikeBackupService CR with deployment configuration parameters.
  • Loading branch information
jwalantmodi05 authored Jan 10, 2025
1 parent 385c3d2 commit 6f8af77
Show file tree
Hide file tree
Showing 13 changed files with 5,310 additions and 123 deletions.
34 changes: 31 additions & 3 deletions api/v1beta1/aerospikebackupservice_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,13 @@ type AerospikeBackupServiceSpec struct {
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Backup Service Config"
Config runtime.RawExtension `json:"config"`

// Specify additional configuration for the AerospikeBackupService pods
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Pod Configuration"
PodSpec ServicePodSpec `json:"podSpec,omitempty"`

// Resources defines the requests and limits for the backup service container.
// Resources.Limits should be more than Resources.Requests.
// Deprecated: Resources field is now part of spec.podSpec.serviceContainer
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Resources"
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`

Expand All @@ -82,9 +87,8 @@ type AerospikeBackupServiceStatus struct {
// It includes: service, backup-policies, storage, secret-agent.
Config runtime.RawExtension `json:"config,omitempty"`

// Resources defines the requests and limits for the backup service container.
// Resources.Limits should be more than Resources.Requests.
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
// Specify additional configuration for the AerospikeBackupService pods
PodSpec ServicePodSpec `json:"podSpec,omitempty"`

// SecretMounts is the list of secret to be mounted in the backup service.
SecretMounts []SecretMount `json:"secrets,omitempty"`
Expand All @@ -103,6 +107,30 @@ type AerospikeBackupServiceStatus struct {
Port int32 `json:"port,omitempty"`
}

type ServicePodSpec struct {
// ServiceContainerSpec configures the backup service container
// created by the operator.
ServiceContainerSpec ServiceContainerSpec `json:"serviceContainer,omitempty"`

// MetaData to add to the pod.
ObjectMeta AerospikeObjectMeta `json:"metadata,omitempty"`

// SchedulingPolicy controls pods placement on Kubernetes nodes.
SchedulingPolicy `json:",inline"`

// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of
// the images used by this PodSpec.
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
}

type ServiceContainerSpec struct {
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`

// Resources defines the requests and limits for the backup service container.
// Resources.Limits should be more than Resources.Requests.
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:metadata:annotations="aerospike-kubernetes-operator/version=3.4.1"
Expand Down
63 changes: 59 additions & 4 deletions api/v1beta1/aerospikebackupservice_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package v1beta1

import (
"fmt"
"reflect"

set "github.com/deckarep/golang-set/v2"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -28,6 +29,7 @@ import (
"sigs.k8s.io/yaml"

"github.com/aerospike/aerospike-backup-service/pkg/model"
asdbv1 "github.com/aerospike/aerospike-kubernetes-operator/api/v1"
)

func (r *AerospikeBackupService) SetupWebhookWithManager(mgr ctrl.Manager) error {
Expand All @@ -36,14 +38,20 @@ func (r *AerospikeBackupService) SetupWebhookWithManager(mgr ctrl.Manager) error
Complete()
}

// Implemented Defaulter interface for future reference
//nolint:lll // for readability
//+kubebuilder:webhook:path=/mutate-asdb-aerospike-com-v1beta1-aerospikebackupservice,mutating=true,failurePolicy=fail,sideEffects=None,groups=asdb.aerospike.com,resources=aerospikebackupservices,verbs=create;update,versions=v1beta1,name=maerospikebackupservice.kb.io,admissionReviewVersions=v1

var _ webhook.Defaulter = &AerospikeBackupService{}

// Default implements webhook.Defaulter so a webhook will be registered for the type
func (r *AerospikeBackupService) Default() {
absLog := logf.Log.WithName(namespacedName(r))

absLog.Info("Setting defaults for aerospikeBackupService")

if r.Spec.Resources != nil && r.Spec.PodSpec.ServiceContainerSpec.Resources == nil {
r.Spec.PodSpec.ServiceContainerSpec.Resources = r.Spec.Resources
}
}

//nolint:lll // for readability
Expand All @@ -65,11 +73,11 @@ func (r *AerospikeBackupService) ValidateCreate() (admission.Warnings, error) {
return nil, err
}

return nil, nil
return r.validateServicePodSpec()
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (r *AerospikeBackupService) ValidateUpdate(_ runtime.Object) (admission.Warnings, error) {
func (r *AerospikeBackupService) ValidateUpdate(oldObj runtime.Object) (admission.Warnings, error) {
absLog := logf.Log.WithName(namespacedName(r))

absLog.Info("Validate update")
Expand All @@ -82,7 +90,7 @@ func (r *AerospikeBackupService) ValidateUpdate(_ runtime.Object) (admission.War
return nil, err
}

return nil, nil
return r.validateServicePodSpec()
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
Expand Down Expand Up @@ -139,3 +147,50 @@ func (r *AerospikeBackupService) validateBackupServiceSecrets() error {

return nil
}

func (r *AerospikeBackupService) validateServicePodSpec() (admission.Warnings, error) {
if err := validatePodObjectMeta(&r.Spec.PodSpec.ObjectMeta); err != nil {
return nil, err
}

return r.validateResources()
}

func (r *AerospikeBackupService) validateResources() (admission.Warnings, error) {
var warn admission.Warnings

if r.Spec.Resources != nil && r.Spec.PodSpec.ServiceContainerSpec.Resources != nil {
if !reflect.DeepEqual(r.Spec.Resources, r.Spec.PodSpec.ServiceContainerSpec.Resources) {
return nil, fmt.Errorf("resources mismatch, different resources requirements found in " +
"spec.resources and spec.podSpec.serviceContainer.resources")
}

warn = []string{"spec.resources field is deprecated, " +
"resources field is now part of spec.podSpec.serviceContainer"}
}

if r.Spec.PodSpec.ServiceContainerSpec.Resources != nil {
resources := r.Spec.PodSpec.ServiceContainerSpec.Resources
if resources.Limits != nil && resources.Requests != nil &&
((resources.Limits.Cpu().Cmp(*resources.Requests.Cpu()) < 0) ||
(resources.Limits.Memory().Cmp(*resources.Requests.Memory()) < 0)) {
return warn, fmt.Errorf("resources.Limits cannot be less than resource.Requests. Resources %v",
resources)
}
}

return warn, nil
}

func validatePodObjectMeta(objectMeta *AerospikeObjectMeta) error {
for label := range objectMeta.Labels {
if label == asdbv1.AerospikeAppLabel || label == asdbv1.AerospikeCustomResourceLabel {
return fmt.Errorf(
"label: %s is internally set by operator and shouldn't be specified by user",
label,
)
}
}

return nil
}
55 changes: 50 additions & 5 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6f8af77

Please sign in to comment.