Add sidecar profile (#192)

This change adds a new SidecarProfile resource which allows configuring
client sidecar injection into pods. It replaces the older annotation
based solution. This removes any pod specific configuration from the
setup key and puts it all in this side car configuration.

Fixes #188

Signed-off-by: Philip Laine <philip.laine@gmail.com>
This commit is contained in:
Philip Laine
2026-04-23 19:17:53 +02:00
committed by GitHub
parent 876a0e1eb3
commit 9838f0dccc
14 changed files with 1447 additions and 29 deletions
+102
View File
@@ -0,0 +1,102 @@
package v1alpha1
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// InjectionMode defines how the sidecar is injected into the pod.
// +kubebuilder:validation:Enum=Sidecar;Container
type InjectionMode string
const (
// InjectionModeSidecar injects the client as a sidecar container.
InjectionModeSidecar InjectionMode = "Sidecar"
// InjectionModeContainer injects the client as a regular container.
InjectionModeContainer InjectionMode = "Container"
)
// SidecarProfileSpec defines the desired state of SidecarProfile.
type SidecarProfileSpec struct {
// SetupKeyRef is the reference to the setup key used in the client.
// +required
SetupKeyRef corev1.LocalObjectReference `json:"setupKeyRef"`
// PodSelector determines which pods the profile should apply to.
// An empty slector means the profile will apply to all pods in the namespace.
// +optional
PodSelector *metav1.LabelSelector `json:"podSelector,omitempty"`
// InjectionMode defines whether the sidecar is injected as a native Kubernetes sidecar container or as a regular container.
// +kubebuilder:default=Sidecar
// +optional
InjectionMode InjectionMode `json:"injectionMode,omitempty"`
// ExtraDNSLabels assigns additional DNS names to peers beyond their default hostname.
// +optional
ExtraDNSLabels []string `json:"extraDNSLabels,omitempty"`
// +optional
ContainerOverride *ContainerOverride `json:"containerOverride,omitempty"`
}
type ContainerOverride struct {
// Image overrides the image used by the client.
// +optional
Image string `json:"image,omitempty"`
// +optional
Env []corev1.EnvVar `json:"env,omitempty"`
// +optional
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
}
// SidecarProfileStatus defines the observed state of SidecarProfile.
type SidecarProfileStatus struct {
// Conditions holds the conditions for the SidecarProfile.
// +listType=map
// +listMapKey=type
// +optional
Conditions []metav1.Condition `json:"conditions,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource
// SidecarProfile is the Schema for the sidecarprofiles API.
type SidecarProfile struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// +required
Spec SidecarProfileSpec `json:"spec"`
// +kubebuilder:default={}
Status SidecarProfileStatus `json:"status,omitempty"`
}
// GetConditions returns the status conditions of the object.
func (s *SidecarProfile) GetConditions() []metav1.Condition {
return s.Status.Conditions
}
// SetConditions sets the status conditions on the object.
func (s *SidecarProfile) SetConditions(conditions []metav1.Condition) {
s.Status.Conditions = conditions
}
// +kubebuilder:object:root=true
// SidecarProfileList contains a list of SidecarProfile
type SidecarProfileList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitzero"`
Items []SidecarProfile `json:"items"`
}
func init() {
SchemeBuilder.Register(&SidecarProfile{}, &SidecarProfileList{})
}
+139
View File
@@ -10,6 +10,33 @@ import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ContainerOverride) DeepCopyInto(out *ContainerOverride) {
*out = *in
if in.Env != nil {
in, out := &in.Env, &out.Env
*out = make([]v1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.SecurityContext != nil {
in, out := &in.SecurityContext, &out.SecurityContext
*out = new(v1.SecurityContext)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerOverride.
func (in *ContainerOverride) DeepCopy() *ContainerOverride {
if in == nil {
return nil
}
out := new(ContainerOverride)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CrossNamespaceReference) DeepCopyInto(out *CrossNamespaceReference) {
*out = *in
@@ -481,6 +508,118 @@ func (in *SetupKeyStatus) DeepCopy() *SetupKeyStatus {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SidecarProfile) DeepCopyInto(out *SidecarProfile) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SidecarProfile.
func (in *SidecarProfile) DeepCopy() *SidecarProfile {
if in == nil {
return nil
}
out := new(SidecarProfile)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *SidecarProfile) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SidecarProfileList) DeepCopyInto(out *SidecarProfileList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]SidecarProfile, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SidecarProfileList.
func (in *SidecarProfileList) DeepCopy() *SidecarProfileList {
if in == nil {
return nil
}
out := new(SidecarProfileList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *SidecarProfileList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SidecarProfileSpec) DeepCopyInto(out *SidecarProfileSpec) {
*out = *in
out.SetupKeyRef = in.SetupKeyRef
if in.PodSelector != nil {
in, out := &in.PodSelector, &out.PodSelector
*out = new(metav1.LabelSelector)
(*in).DeepCopyInto(*out)
}
if in.ExtraDNSLabels != nil {
in, out := &in.ExtraDNSLabels, &out.ExtraDNSLabels
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ContainerOverride != nil {
in, out := &in.ContainerOverride, &out.ContainerOverride
*out = new(ContainerOverride)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SidecarProfileSpec.
func (in *SidecarProfileSpec) DeepCopy() *SidecarProfileSpec {
if in == nil {
return nil
}
out := new(SidecarProfileSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SidecarProfileStatus) DeepCopyInto(out *SidecarProfileStatus) {
*out = *in
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]metav1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SidecarProfileStatus.
func (in *SidecarProfileStatus) DeepCopy() *SidecarProfileStatus {
if in == nil {
return nil
}
out := new(SidecarProfileStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkloadOverride) DeepCopyInto(out *WorkloadOverride) {
*out = *in