Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KO-358: Enhance AerospikeBackupService CR with all the possible deployment configuration params #328

Merged
merged 4 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: check spacing

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.0"
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

abhishekdwivedi3060 marked this conversation as resolved.
Show resolved Hide resolved
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
Loading