mirror of
https://github.com/netbirdio/kubernetes-operator.git
synced 2026-05-22 17:11:40 -07:00
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:
@@ -107,4 +107,12 @@ resources:
|
||||
kind: NetworkResource
|
||||
path: github.com/netbirdio/kubernetes-operator/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: netbird.io
|
||||
kind: SidecarProfile
|
||||
path: github.com/netbirdio/kubernetes-operator/api/v1alpha1
|
||||
version: v1alpha1
|
||||
version: "3"
|
||||
|
||||
@@ -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{})
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
apiVersion: netbird.io/v1alpha1
|
||||
kind: SetupKey
|
||||
metadata:
|
||||
name: sidecar
|
||||
namespace: default
|
||||
spec:
|
||||
name: sidecar
|
||||
ephemeral: true
|
||||
---
|
||||
apiVersion: netbird.io/v1alpha1
|
||||
kind: SidecarProfile
|
||||
metadata:
|
||||
name: test
|
||||
namespace: default
|
||||
spec:
|
||||
setupKeyRef:
|
||||
name: sidecar
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app: ubuntu
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: ubuntu
|
||||
namespace: default
|
||||
labels:
|
||||
app: ubuntu
|
||||
spec:
|
||||
containers:
|
||||
- name: ubuntu
|
||||
image: ubuntu:latest
|
||||
command: ["sleep", "infinity"]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,6 @@ rules:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
{{- if or .Values.netbirdAPI.key .Values.netbirdAPI.keyFromSecret }}
|
||||
- apiGroups:
|
||||
- netbird.io
|
||||
resources:
|
||||
@@ -35,6 +34,11 @@ rules:
|
||||
- nbresources
|
||||
- nbroutingpeers
|
||||
- nbpolicies
|
||||
- setupkeys
|
||||
- groups
|
||||
- networkrouters
|
||||
- networkresources
|
||||
- sidecarprofiles
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
@@ -50,6 +54,11 @@ rules:
|
||||
- nbresources/status
|
||||
- nbroutingpeers/status
|
||||
- nbpolicies/status
|
||||
- setupkeys/status
|
||||
- groups/status
|
||||
- networkrouters/status
|
||||
- networkresources/status
|
||||
- sidecarprofiles/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
@@ -61,6 +70,11 @@ rules:
|
||||
- nbresources/finalizers
|
||||
- nbroutingpeers/finalizers
|
||||
- nbpolicies/finalizers
|
||||
- setupkeys/finalizers
|
||||
- groups/finalizers
|
||||
- networkrouters/finalizers
|
||||
- networkresources/finalizers
|
||||
- sidecarprofiles/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
@@ -99,7 +113,6 @@ rules:
|
||||
- watch
|
||||
- create
|
||||
- delete
|
||||
{{- end }}
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
||||
@@ -17,20 +17,31 @@ limitations under the License.
|
||||
package v1
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
||||
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||
"github.com/netbirdio/kubernetes-operator/internal/controller"
|
||||
)
|
||||
|
||||
const (
|
||||
SidecarProfileAnnotation = "netbird.io/sidecar-profile"
|
||||
|
||||
setupKeyAnnotation = "netbird.io/setup-key"
|
||||
sidecarAnnotation = "netbird.io/init-sidecar"
|
||||
)
|
||||
@@ -60,14 +71,128 @@ type PodNetbirdInjector struct {
|
||||
|
||||
var _ admission.Defaulter[*corev1.Pod] = &PodNetbirdInjector{}
|
||||
|
||||
// Default implements webhook.CustomDefaulter so a webhook will be registered for the Kind Pod.
|
||||
func (d *PodNetbirdInjector) Default(ctx context.Context, pod *corev1.Pod) error {
|
||||
podlog.Info("Defaulting for Pod", "name", pod.GetName())
|
||||
// If setup key annotations are set we do the legacy injection.
|
||||
if pod.Annotations != nil && pod.Annotations[setupKeyAnnotation] != "" {
|
||||
return d.legacyInjector(ctx, pod)
|
||||
}
|
||||
|
||||
// if the setup key annotation is missing, do nothing.
|
||||
if pod.Annotations == nil || pod.Annotations[setupKeyAnnotation] == "" {
|
||||
// Find sidecar profiles matching pods labels.
|
||||
sidecarProfileList := &nbv1alpha1.SidecarProfileList{}
|
||||
err := d.client.List(ctx, sidecarProfileList, client.InNamespace(pod.Namespace))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sidecarProfiles := []nbv1alpha1.SidecarProfile{}
|
||||
for _, sidecarProfile := range sidecarProfileList.Items {
|
||||
if sidecarProfile.Spec.PodSelector == nil || sidecarProfile.Spec.PodSelector.Size() == 0 {
|
||||
sidecarProfiles = append(sidecarProfiles, sidecarProfile)
|
||||
continue
|
||||
}
|
||||
selector, err := metav1.LabelSelectorAsSelector(sidecarProfile.Spec.PodSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if selector.Matches(labels.Set(pod.Labels)) {
|
||||
sidecarProfiles = append(sidecarProfiles, sidecarProfile)
|
||||
}
|
||||
}
|
||||
// Do nothing if no profile matches.
|
||||
if len(sidecarProfiles) == 0 {
|
||||
return nil
|
||||
}
|
||||
// If two match we chose the first in alphabetical order.
|
||||
if len(sidecarProfiles) > 1 {
|
||||
slices.SortFunc(sidecarProfiles, func(a, b nbv1alpha1.SidecarProfile) int {
|
||||
return cmp.Compare(a.Name, b.Name)
|
||||
})
|
||||
}
|
||||
sidecarProfile := sidecarProfiles[0]
|
||||
|
||||
// Get setup key referenced by sidecar profile.
|
||||
setupKey := &nbv1alpha1.SetupKey{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: sidecarProfile.Spec.SetupKeyRef.Name,
|
||||
Namespace: pod.Namespace,
|
||||
},
|
||||
}
|
||||
err = d.client.Get(ctx, client.ObjectKeyFromObject(setupKey), setupKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add sidecar container.
|
||||
envVars := []corev1.EnvVar{
|
||||
{
|
||||
Name: "NB_SETUP_KEY",
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: &corev1.SecretKeySelector{
|
||||
LocalObjectReference: corev1.LocalObjectReference{
|
||||
Name: setupKey.SecretName(),
|
||||
},
|
||||
Key: controller.SetupKeySecretKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "NB_MANAGEMENT_URL",
|
||||
Value: d.managementURL,
|
||||
},
|
||||
}
|
||||
if len(sidecarProfile.Spec.ExtraDNSLabels) > 0 {
|
||||
envVars = append(envVars, corev1.EnvVar{
|
||||
Name: "NB_EXTRA_DNS_LABELS",
|
||||
Value: strings.Join(sidecarProfile.Spec.ExtraDNSLabels, ","),
|
||||
})
|
||||
}
|
||||
|
||||
container := corev1.Container{
|
||||
Name: "netbird",
|
||||
Image: d.clientImage,
|
||||
Env: envVars,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Capabilities: &corev1.Capabilities{
|
||||
Add: []corev1.Capability{"NET_ADMIN"},
|
||||
},
|
||||
},
|
||||
}
|
||||
if sidecarProfile.Spec.ContainerOverride != nil {
|
||||
baseJSON, err := json.Marshal(&container)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
overrideJSON, err := json.Marshal(sidecarProfile.Spec.ContainerOverride)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mergedJSON, err := strategicpatch.StrategicMergePatch(baseJSON, overrideJSON, corev1.Container{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(mergedJSON, &container)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch sidecarProfile.Spec.InjectionMode {
|
||||
case nbv1alpha1.InjectionModeSidecar:
|
||||
restartPolicy := corev1.ContainerRestartPolicyAlways
|
||||
container.RestartPolicy = &restartPolicy
|
||||
pod.Spec.InitContainers = append(pod.Spec.InitContainers, container)
|
||||
case nbv1alpha1.InjectionModeContainer:
|
||||
pod.Spec.Containers = append(pod.Spec.Containers, container)
|
||||
default:
|
||||
return fmt.Errorf("unknown injection mode %s", sidecarProfile.Spec.InjectionMode)
|
||||
}
|
||||
|
||||
pod.Annotations[SidecarProfileAnnotation] = sidecarProfile.Name
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *PodNetbirdInjector) legacyInjector(ctx context.Context, pod *corev1.Pod) error {
|
||||
podlog.Info("Defaulting for Pod", "name", pod.GetName())
|
||||
|
||||
// retrieve the NBSetupKey resource
|
||||
var nbSetupKey netbirdiov1.NBSetupKey
|
||||
@@ -118,7 +243,17 @@ func (d *PodNetbirdInjector) Default(ctx context.Context, pod *corev1.Pod) error
|
||||
}
|
||||
|
||||
// Build the netbird container spec.
|
||||
nbContainer := d.buildNetbirdContainer(envVars, nbSetupKey.Spec.VolumeMounts)
|
||||
nbContainer := corev1.Container{
|
||||
Name: "netbird",
|
||||
Image: d.clientImage,
|
||||
Env: envVars,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Capabilities: &corev1.Capabilities{
|
||||
Add: []corev1.Capability{"NET_ADMIN"},
|
||||
},
|
||||
},
|
||||
VolumeMounts: nbSetupKey.Spec.VolumeMounts,
|
||||
}
|
||||
|
||||
// If sidecar mode is requested, inject as a sidecar (init container with restartPolicy: Always).
|
||||
if pod.Annotations[sidecarAnnotation] == "true" {
|
||||
@@ -130,22 +265,5 @@ func (d *PodNetbirdInjector) Default(ctx context.Context, pod *corev1.Pod) error
|
||||
}
|
||||
|
||||
pod.Spec.Volumes = append(pod.Spec.Volumes, nbSetupKey.Spec.Volumes...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildNetbirdContainer constructs the NetBird container spec with the given
|
||||
// environment variables and volume mounts.
|
||||
func (d *PodNetbirdInjector) buildNetbirdContainer(envVars []corev1.EnvVar, volumeMounts []corev1.VolumeMount) corev1.Container {
|
||||
return corev1.Container{
|
||||
Name: "netbird",
|
||||
Image: d.clientImage,
|
||||
Env: envVars,
|
||||
SecurityContext: &corev1.SecurityContext{
|
||||
Capabilities: &corev1.Capabilities{
|
||||
Add: []corev1.Capability{"NET_ADMIN"},
|
||||
},
|
||||
},
|
||||
VolumeMounts: volumeMounts,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@ import (
|
||||
"context"
|
||||
|
||||
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
||||
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var _ = Describe("Pod Webhook", func() {
|
||||
@@ -35,7 +35,7 @@ var _ = Describe("Pod Webhook", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
obj = &corev1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "test",
|
||||
Annotations: make(map[string]string),
|
||||
@@ -83,7 +83,7 @@ var _ = Describe("Pod Webhook", func() {
|
||||
When("NBSetupKey exists", Ordered, func() {
|
||||
BeforeAll(func() {
|
||||
sk := netbirdiov1.NBSetupKey{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "test",
|
||||
},
|
||||
@@ -98,7 +98,7 @@ var _ = Describe("Pod Webhook", func() {
|
||||
}
|
||||
|
||||
err := k8sClient.Create(context.Background(), &corev1.Namespace{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
},
|
||||
})
|
||||
@@ -154,4 +154,59 @@ var _ = Describe("Pod Webhook", func() {
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
Context("When creating Pod with SidecarProfile", func() {
|
||||
BeforeEach(func() {
|
||||
sidecarProfile := &nbv1alpha1.SidecarProfile{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "test",
|
||||
},
|
||||
Spec: nbv1alpha1.SidecarProfileSpec{
|
||||
SetupKeyRef: corev1.LocalObjectReference{
|
||||
Name: "test",
|
||||
},
|
||||
InjectionMode: nbv1alpha1.InjectionModeContainer,
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.Background(), sidecarProfile)).To(Succeed())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
sidecarProfile := &nbv1alpha1.SidecarProfile{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "test",
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Delete(ctx, sidecarProfile)).To(Succeed())
|
||||
})
|
||||
|
||||
When("SetupKey doesn't exist", func() {
|
||||
It("Should fail", func() {
|
||||
Expect(defaulter.Default(context.Background(), obj)).To(HaveOccurred())
|
||||
Expect(obj.Spec.Containers).To(HaveLen(1))
|
||||
})
|
||||
})
|
||||
|
||||
When("SetupKey exists", func() {
|
||||
It("Should succeed", func() {
|
||||
setupKey := &nbv1alpha1.SetupKey{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "test",
|
||||
},
|
||||
Spec: nbv1alpha1.SetupKeySpec{
|
||||
Name: "test",
|
||||
Ephemeral: true,
|
||||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.Background(), setupKey)).To(Succeed())
|
||||
|
||||
Expect(defaulter.Default(context.Background(), obj)).NotTo(HaveOccurred())
|
||||
Expect(obj.Spec.Containers).To(HaveLen(2))
|
||||
Expect(obj.Spec.Containers[1].Name).To(Equal("netbird"))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
|
||||
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
||||
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
@@ -78,6 +79,9 @@ var _ = BeforeSuite(func() {
|
||||
err = netbirdiov1.AddToScheme(scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = nbv1alpha1.AddToScheme(scheme)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// +kubebuilder:scaffold:scheme
|
||||
|
||||
By("bootstrapping test environment")
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// ContainerOverrideApplyConfiguration represents a declarative configuration of the ContainerOverride type for use
|
||||
// with apply.
|
||||
type ContainerOverrideApplyConfiguration struct {
|
||||
// Image overrides the image used by the client.
|
||||
Image *string `json:"image,omitempty"`
|
||||
Env []v1.EnvVar `json:"env,omitempty"`
|
||||
SecurityContext *v1.SecurityContext `json:"securityContext,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerOverrideApplyConfiguration constructs a declarative configuration of the ContainerOverride type for use with
|
||||
// apply.
|
||||
func ContainerOverride() *ContainerOverrideApplyConfiguration {
|
||||
return &ContainerOverrideApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithImage sets the Image field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Image field is set to the value of the last call.
|
||||
func (b *ContainerOverrideApplyConfiguration) WithImage(value string) *ContainerOverrideApplyConfiguration {
|
||||
b.Image = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithEnv adds the given value to the Env field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the Env field.
|
||||
func (b *ContainerOverrideApplyConfiguration) WithEnv(values ...v1.EnvVar) *ContainerOverrideApplyConfiguration {
|
||||
for i := range values {
|
||||
b.Env = append(b.Env, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithSecurityContext sets the SecurityContext field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the SecurityContext field is set to the value of the last call.
|
||||
func (b *ContainerOverrideApplyConfiguration) WithSecurityContext(value v1.SecurityContext) *ContainerOverrideApplyConfiguration {
|
||||
b.SecurityContext = &value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// SidecarProfileApplyConfiguration represents a declarative configuration of the SidecarProfile type for use
|
||||
// with apply.
|
||||
//
|
||||
// SidecarProfile is the Schema for the sidecarprofiles API.
|
||||
type SidecarProfileApplyConfiguration struct {
|
||||
v1.TypeMetaApplyConfiguration `json:",inline"`
|
||||
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||
Spec *SidecarProfileSpecApplyConfiguration `json:"spec,omitempty"`
|
||||
Status *SidecarProfileStatusApplyConfiguration `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// SidecarProfile constructs a declarative configuration of the SidecarProfile type for use with
|
||||
// apply.
|
||||
func SidecarProfile(name, namespace string) *SidecarProfileApplyConfiguration {
|
||||
b := &SidecarProfileApplyConfiguration{}
|
||||
b.WithName(name)
|
||||
b.WithNamespace(namespace)
|
||||
b.WithKind("SidecarProfile")
|
||||
b.WithAPIVersion("netbird.io/v1alpha1")
|
||||
return b
|
||||
}
|
||||
|
||||
func (b SidecarProfileApplyConfiguration) IsApplyConfiguration() {}
|
||||
|
||||
// WithKind sets the Kind field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Kind field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithKind(value string) *SidecarProfileApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.Kind = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the APIVersion field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithAPIVersion(value string) *SidecarProfileApplyConfiguration {
|
||||
b.TypeMetaApplyConfiguration.APIVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithName sets the Name field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Name field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithName(value string) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Name = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGenerateName sets the GenerateName field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the GenerateName field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithGenerateName(value string) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.GenerateName = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithNamespace sets the Namespace field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Namespace field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithNamespace(value string) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Namespace = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUID sets the UID field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the UID field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithUID(value types.UID) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.UID = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the ResourceVersion field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithResourceVersion(value string) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.ResourceVersion = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGeneration sets the Generation field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Generation field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithGeneration(value int64) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.Generation = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the CreationTimestamp field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithCreationTimestamp(value metav1.Time) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionTimestamp field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||
// overwriting an existing map entries in Labels field with the same key.
|
||||
func (b *SidecarProfileApplyConfiguration) WithLabels(entries map[string]string) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Labels[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||
// overwriting an existing map entries in Annotations field with the same key.
|
||||
func (b *SidecarProfileApplyConfiguration) WithAnnotations(entries map[string]string) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
|
||||
b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
|
||||
}
|
||||
for k, v := range entries {
|
||||
b.ObjectMetaApplyConfiguration.Annotations[k] = v
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the OwnerReferences field.
|
||||
func (b *SidecarProfileApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithOwnerReferences")
|
||||
}
|
||||
b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithFinalizers adds the given value to the Finalizers field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the Finalizers field.
|
||||
func (b *SidecarProfileApplyConfiguration) WithFinalizers(values ...string) *SidecarProfileApplyConfiguration {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
for i := range values {
|
||||
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *SidecarProfileApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||
if b.ObjectMetaApplyConfiguration == nil {
|
||||
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||
}
|
||||
}
|
||||
|
||||
// WithSpec sets the Spec field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Spec field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithSpec(value *SidecarProfileSpecApplyConfiguration) *SidecarProfileApplyConfiguration {
|
||||
b.Spec = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithStatus sets the Status field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Status field is set to the value of the last call.
|
||||
func (b *SidecarProfileApplyConfiguration) WithStatus(value *SidecarProfileStatusApplyConfiguration) *SidecarProfileApplyConfiguration {
|
||||
b.Status = value
|
||||
return b
|
||||
}
|
||||
|
||||
// GetKind retrieves the value of the Kind field in the declarative configuration.
|
||||
func (b *SidecarProfileApplyConfiguration) GetKind() *string {
|
||||
return b.TypeMetaApplyConfiguration.Kind
|
||||
}
|
||||
|
||||
// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
|
||||
func (b *SidecarProfileApplyConfiguration) GetAPIVersion() *string {
|
||||
return b.TypeMetaApplyConfiguration.APIVersion
|
||||
}
|
||||
|
||||
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||
func (b *SidecarProfileApplyConfiguration) GetName() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Name
|
||||
}
|
||||
|
||||
// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
|
||||
func (b *SidecarProfileApplyConfiguration) GetNamespace() *string {
|
||||
b.ensureObjectMetaApplyConfigurationExists()
|
||||
return b.ObjectMetaApplyConfiguration.Namespace
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
apiv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// SidecarProfileSpecApplyConfiguration represents a declarative configuration of the SidecarProfileSpec type for use
|
||||
// with apply.
|
||||
//
|
||||
// SidecarProfileSpec defines the desired state of SidecarProfile.
|
||||
type SidecarProfileSpecApplyConfiguration struct {
|
||||
// SetupKeyRef is the reference to the setup key used in the client.
|
||||
SetupKeyRef *v1.LocalObjectReference `json:"setupKeyRef,omitempty"`
|
||||
// PodSelector determines which pods the profile should apply to.
|
||||
// An empty slector means the profile will apply to all pods in the namespace.
|
||||
PodSelector *metav1.LabelSelectorApplyConfiguration `json:"podSelector,omitempty"`
|
||||
// InjectionMode defines whether the sidecar is injected as a native Kubernetes sidecar container or as a regular container.
|
||||
InjectionMode *apiv1alpha1.InjectionMode `json:"injectionMode,omitempty"`
|
||||
// ExtraDNSLabels assigns additional DNS names to peers beyond their default hostname.
|
||||
ExtraDNSLabels []string `json:"extraDNSLabels,omitempty"`
|
||||
ContainerOverride *ContainerOverrideApplyConfiguration `json:"containerOverride,omitempty"`
|
||||
}
|
||||
|
||||
// SidecarProfileSpecApplyConfiguration constructs a declarative configuration of the SidecarProfileSpec type for use with
|
||||
// apply.
|
||||
func SidecarProfileSpec() *SidecarProfileSpecApplyConfiguration {
|
||||
return &SidecarProfileSpecApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithSetupKeyRef sets the SetupKeyRef field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the SetupKeyRef field is set to the value of the last call.
|
||||
func (b *SidecarProfileSpecApplyConfiguration) WithSetupKeyRef(value v1.LocalObjectReference) *SidecarProfileSpecApplyConfiguration {
|
||||
b.SetupKeyRef = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithPodSelector sets the PodSelector field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the PodSelector field is set to the value of the last call.
|
||||
func (b *SidecarProfileSpecApplyConfiguration) WithPodSelector(value *metav1.LabelSelectorApplyConfiguration) *SidecarProfileSpecApplyConfiguration {
|
||||
b.PodSelector = value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithInjectionMode sets the InjectionMode field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the InjectionMode field is set to the value of the last call.
|
||||
func (b *SidecarProfileSpecApplyConfiguration) WithInjectionMode(value apiv1alpha1.InjectionMode) *SidecarProfileSpecApplyConfiguration {
|
||||
b.InjectionMode = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithExtraDNSLabels adds the given value to the ExtraDNSLabels field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the ExtraDNSLabels field.
|
||||
func (b *SidecarProfileSpecApplyConfiguration) WithExtraDNSLabels(values ...string) *SidecarProfileSpecApplyConfiguration {
|
||||
for i := range values {
|
||||
b.ExtraDNSLabels = append(b.ExtraDNSLabels, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithContainerOverride sets the ContainerOverride field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the ContainerOverride field is set to the value of the last call.
|
||||
func (b *SidecarProfileSpecApplyConfiguration) WithContainerOverride(value *ContainerOverrideApplyConfiguration) *SidecarProfileSpecApplyConfiguration {
|
||||
b.ContainerOverride = value
|
||||
return b
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||
)
|
||||
|
||||
// SidecarProfileStatusApplyConfiguration represents a declarative configuration of the SidecarProfileStatus type for use
|
||||
// with apply.
|
||||
//
|
||||
// SidecarProfileStatus defines the observed state of SidecarProfile.
|
||||
type SidecarProfileStatusApplyConfiguration struct {
|
||||
// Conditions holds the conditions for the SidecarProfile.
|
||||
Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// SidecarProfileStatusApplyConfiguration constructs a declarative configuration of the SidecarProfileStatus type for use with
|
||||
// apply.
|
||||
func SidecarProfileStatus() *SidecarProfileStatusApplyConfiguration {
|
||||
return &SidecarProfileStatusApplyConfiguration{}
|
||||
}
|
||||
|
||||
// WithConditions adds the given value to the Conditions field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the Conditions field.
|
||||
func (b *SidecarProfileStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *SidecarProfileStatusApplyConfiguration {
|
||||
for i := range values {
|
||||
if values[i] == nil {
|
||||
panic("nil value passed to WithConditions")
|
||||
}
|
||||
b.Conditions = append(b.Conditions, *values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
@@ -16,6 +16,8 @@ import (
|
||||
func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||
switch kind {
|
||||
// Group=netbird.io, Version=v1alpha1
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("ContainerOverride"):
|
||||
return &apiv1alpha1.ContainerOverrideApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("CrossNamespaceReference"):
|
||||
return &apiv1alpha1.CrossNamespaceReferenceApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("DNSZoneReference"):
|
||||
@@ -46,6 +48,12 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||
return &apiv1alpha1.SetupKeySpecApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("SetupKeyStatus"):
|
||||
return &apiv1alpha1.SetupKeyStatusApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("SidecarProfile"):
|
||||
return &apiv1alpha1.SidecarProfileApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("SidecarProfileSpec"):
|
||||
return &apiv1alpha1.SidecarProfileSpecApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("SidecarProfileStatus"):
|
||||
return &apiv1alpha1.SidecarProfileStatusApplyConfiguration{}
|
||||
case v1alpha1.SchemeGroupVersion.WithKind("WorkloadOverride"):
|
||||
return &apiv1alpha1.WorkloadOverrideApplyConfiguration{}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user