Skip to content

Commit

Permalink
Use StrategicMergePatch to apply overrides (#175)
Browse files Browse the repository at this point in the history
  • Loading branch information
lllamnyp committed Apr 18, 2024
2 parents f7a5298 + 9f3f24c commit bee8012
Show file tree
Hide file tree
Showing 11 changed files with 640 additions and 9,568 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ help: ## Display this help.
##@ Development

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
manifests: controller-gen yq ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
$(YQ) -i '.spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.podTemplate.properties.spec.properties |= {}' config/crd/bases/etcd.aenix.io_etcdclusters.yaml

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
Expand Down
60 changes: 5 additions & 55 deletions api/v1alpha1/etcdcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)

const defaultEtcdImage = "quay.io/coreos/etcd:v3.5.12"
const DefaultEtcdImage = "quay.io/coreos/etcd:v3.5.12"

// EtcdClusterSpec defines the desired state of EtcdCluster
type EtcdClusterSpec struct {
Expand Down Expand Up @@ -128,66 +128,16 @@ type EmbeddedObjectMetadata struct {
Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`
}

// PodTemplate allows overrides, such as sidecars, init containers, changes to the security context, etc to the pod template generated by the operator.
type PodTemplate struct {
// EmbeddedObjectMetadata contains metadata relevant to an EmbeddedResource
// +optional
EmbeddedObjectMetadata `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`

// Spec defines the desired state of spec for etcd members. If not specified, default values will be used.
// Spec follows the structure of a regular Pod spec. Overrides defined here will be strategically merged with the default pod spec, generated by the operator.
// +optional
Spec PodSpec `json:"spec,omitempty"`
}

// PodSpec defines the desired state of PodSpec for etcd members.
// +k8s:openapi-gen=true
type PodSpec struct {
// Containers allows the user to add containers to the pod and change "etcd" container if such options are not
// available in the EtcdCluster custom resource.
// +optional
Containers []corev1.Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,2,rep,name=containers"`

// ImagePullSecrets An optional list of references to secrets in the same namespace
// to use for pulling images from registries
// see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod
// +optional
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
// ServiceAccountName is the name of the ServiceAccount to use to run the etcd pods.
// +optional
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// ReadinessGates is an optional list of conditions that must be true for the pod to be considered ready for
// traffic. A pod is considered ready when all of its containers are ready.
// +optional
ReadinessGates []corev1.PodReadinessGate `json:"readinessGates,omitempty"`
// Affinity sets the scheduling constraints for the pod.
// +optional
Affinity *corev1.Affinity `json:"affinity,omitempty"`
// NodeSelector is a selector which must be true for the pod to fit on a node.
// +optional
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// TopologySpreadConstraints describes how a group of pods ought to spread across topology domains.
// +optional
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
// Tolerations is a list of tolerations.
// +optional
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
// SecurityContext holds pod-level security attributes and common container settings.
// +optional
SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"`
// PriorityClassName is the name of the PriorityClass for this pod.
// +optional
PriorityClassName string `json:"priorityClassName,omitempty"`
// TerminationGracePeriodSeconds is the time to wait before forceful pod shutdown.
// +optional
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
// SchedulerName is the name of the scheduler to be used for scheduling the pod.
// +optional
SchedulerName string `json:"schedulerName,omitempty"`
// RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod.
// +optional
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
// Volumes are volumes for being used by the pods. Cannot collide with "data" volume used by etcd.
// +optional
Volumes []corev1.Volume `json:"volumes,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name" protobuf:"bytes,1,rep,name=volumes"`
// +kubebuilder:pruning:PreserveUnknownFields
Spec corev1.PodSpec `json:"spec,omitempty"`
}

// StorageSpec defines the configured storage for a etcd members.
Expand Down
15 changes: 0 additions & 15 deletions api/v1alpha1/etcdcluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package v1alpha1
import (
"fmt"
"math"
"slices"
"strings"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -64,20 +63,6 @@ func (r *EtcdCluster) Default() {
}
}
}
etcdContainerIdx := slices.IndexFunc(r.Spec.PodTemplate.Spec.Containers, func(c corev1.Container) bool {
return c.Name == "etcd"
})
if etcdContainerIdx == -1 {
r.Spec.PodTemplate.Spec.Containers = append(r.Spec.PodTemplate.Spec.Containers, corev1.Container{
Name: "etcd",
Image: defaultEtcdImage,
})
} else {
c := &r.Spec.PodTemplate.Spec.Containers[etcdContainerIdx]
if c.Image == "" {
c.Image = defaultEtcdImage
}
}
}

// +kubebuilder:webhook:path=/validate-etcd-aenix-io-v1alpha1-etcdcluster,mutating=false,failurePolicy=fail,sideEffects=None,groups=etcd.aenix.io,resources=etcdclusters,verbs=create;update,versions=v1alpha1,name=vetcdcluster.kb.io,admissionReviewVersions=v1
Expand Down
1 change: 0 additions & 1 deletion api/v1alpha1/etcdcluster_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ var _ = Describe("EtcdCluster Webhook", func() {
It("Should fill in the default value if a required field is empty", func() {
etcdCluster := &EtcdCluster{}
etcdCluster.Default()
Expect(etcdCluster.Spec.PodTemplate.Spec.Containers[0].Image).To(Equal(defaultEtcdImage))
Expect(etcdCluster.Spec.Replicas).To(BeNil(), "User should have an opportunity to create cluster with 0 replicas")
Expect(etcdCluster.Spec.Storage.EmptyDir).To(BeNil())
storage := etcdCluster.Spec.Storage.VolumeClaimTemplate.Spec.Resources.Requests.Storage()
Expand Down
80 changes: 0 additions & 80 deletions api/v1alpha1/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 bee8012

Please sign in to comment.