Skip to content

Commit

Permalink
Merge pull request #351 from hime/native-sidecar-flag
Browse files Browse the repository at this point in the history
Add annotation to manually enable/disable native sidecar injection.
  • Loading branch information
hime authored Oct 17, 2024
2 parents df1f3e4 + 375d942 commit 880ea0c
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 15 deletions.
11 changes: 10 additions & 1 deletion pkg/webhook/injection.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,16 @@ func (si *SidecarInjector) supportsNativeSidecar() (bool, error) {
}

func injectSidecarContainer(pod *corev1.Pod, config *Config, supportsNativeSidecar bool) {
if supportsNativeSidecar {
nativeSidecarEnabled := true
if enable, ok := pod.Annotations[GcsFuseNativeSidecarEnableAnnotation]; ok {
parsedAnnotation, err := ParseBool(enable)
if err != nil {
klog.Errorf("failed to parse enableNativeSidecar annotation... ignoring annotation: %v", err)
} else {
nativeSidecarEnabled = parsedAnnotation
}
}
if supportsNativeSidecar && nativeSidecarEnabled {
pod.Spec.InitContainers = insert(pod.Spec.InitContainers, GetNativeSidecarContainerSpec(config), getInjectIndex(pod.Spec.InitContainers))
} else {
pod.Spec.Containers = insert(pod.Spec.Containers, GetSidecarContainerSpec(config), getInjectIndex(pod.Spec.Containers))
Expand Down
30 changes: 16 additions & 14 deletions pkg/webhook/mutatingwebhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"encoding/json"
"fmt"
"net/http"
"strings"

admissionv1 "k8s.io/api/admission/v1"
corev1 "k8s.io/api/core/v1"
Expand All @@ -34,13 +33,14 @@ import (
)

const (
GcsFuseVolumeEnableAnnotation = "gke-gcsfuse/volumes"
cpuLimitAnnotation = "gke-gcsfuse/cpu-limit"
cpuRequestAnnotation = "gke-gcsfuse/cpu-request"
memoryLimitAnnotation = "gke-gcsfuse/memory-limit"
memoryRequestAnnotation = "gke-gcsfuse/memory-request"
ephemeralStorageLimitAnnotation = "gke-gcsfuse/ephemeral-storage-limit"
ephemeralStorageRequestAnnotation = "gke-gcsfuse/ephemeral-storage-request"
GcsFuseVolumeEnableAnnotation = "gke-gcsfuse/volumes"
GcsFuseNativeSidecarEnableAnnotation = "gke-gcsfuse/enable-native-sidecar"
cpuLimitAnnotation = "gke-gcsfuse/cpu-limit"
cpuRequestAnnotation = "gke-gcsfuse/cpu-request"
memoryLimitAnnotation = "gke-gcsfuse/memory-limit"
memoryRequestAnnotation = "gke-gcsfuse/memory-request"
ephemeralStorageLimitAnnotation = "gke-gcsfuse/ephemeral-storage-limit"
ephemeralStorageRequestAnnotation = "gke-gcsfuse/ephemeral-storage-request"
)

type SidecarInjector struct {
Expand Down Expand Up @@ -71,15 +71,17 @@ func (si *SidecarInjector) Handle(_ context.Context, req admission.Request) admi
return admission.Allowed(fmt.Sprintf("The annotation key %q is not found, no injection required.", GcsFuseVolumeEnableAnnotation))
}

switch strings.ToLower(enableGcsfuseVolumes) {
case "false":
return admission.Allowed(fmt.Sprintf("found annotation '%v: false' for Pod: Name %q, GenerateName %q, Namespace %q, no injection required.", GcsFuseVolumeEnableAnnotation, pod.Name, pod.GenerateName, pod.Namespace))
case "true":
klog.Infof("found annotation '%v: true' for Pod: Name %q, GenerateName %q, Namespace %q, start to inject the sidecar container.", GcsFuseVolumeEnableAnnotation, pod.Name, pod.GenerateName, pod.Namespace)
default:
shouldInjectSidecar, err := ParseBool(enableGcsfuseVolumes)
if err != nil {
return admission.Errored(http.StatusBadRequest, fmt.Errorf("the acceptable values for %q are 'True', 'true', 'false' or 'False'", GcsFuseVolumeEnableAnnotation))
}

if shouldInjectSidecar {
klog.Infof("found annotation '%v: true' for Pod: Name %q, GenerateName %q, Namespace %q, start to inject the sidecar container.", GcsFuseVolumeEnableAnnotation, pod.Name, pod.GenerateName, pod.Namespace)
} else {
return admission.Allowed(fmt.Sprintf("found annotation '%v: false' for Pod: Name %q, GenerateName %q, Namespace %q, no injection required.", GcsFuseVolumeEnableAnnotation, pod.Name, pod.GenerateName, pod.Namespace))
}

sidecarInjected, _ := ValidatePodHasSidecarContainerInjected(pod)
if sidecarInjected {
return admission.Allowed("The sidecar container was injected, no injection required.")
Expand Down
42 changes: 42 additions & 0 deletions pkg/webhook/mutatingwebhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,41 @@ func TestValidateMutatingWebhookResponse(t *testing.T) {
wantResponse: wantResponse(t, false, false),
nodes: skewVersionNodes(),
},
{
name: "native container set via annotation injection successful test.",
operation: admissionv1.Create,
inputPod: validInputPodWithNativeAnnotation(false, "true"),
wantResponse: wantResponse(t, false, true),
nodes: nativeSupportNodes(),
},
{
name: "native container set via annotation injection successful with custom image test.",
operation: admissionv1.Create,
inputPod: validInputPodWithNativeAnnotation(true, "true"),
wantResponse: wantResponse(t, true, true),
nodes: nativeSupportNodes(),
},
{
name: "regular container set via annotation injection successful test.",
operation: admissionv1.Create,
inputPod: validInputPodWithNativeAnnotation(false, "false"),
wantResponse: wantResponse(t, false, false),
nodes: nativeSupportNodes(),
},
{
name: "native container set via invalid annotation injection successful test.",
operation: admissionv1.Create,
inputPod: validInputPodWithNativeAnnotation(false, "maybe"),
wantResponse: wantResponse(t, false, true),
nodes: nativeSupportNodes(),
},
{
name: "native container set via annotation injection unsupported test.",
operation: admissionv1.Create,
inputPod: validInputPodWithNativeAnnotation(false, "true"),
wantResponse: wantResponse(t, false, false),
nodes: skewVersionNodes(),
},
{
name: "Injection with custom sidecar container image successful test.",
operation: admissionv1.Create,
Expand Down Expand Up @@ -527,6 +562,13 @@ func getDuplicateDeclarationPodSpecResponse() *corev1.Pod {
return result
}

func validInputPodWithNativeAnnotation(customImage bool, enableNativeSidecarAnnotation string) *corev1.Pod {
pod := validInputPod(customImage)
pod.ObjectMeta.Annotations[GcsFuseNativeSidecarEnableAnnotation] = enableNativeSidecarAnnotation

return pod
}

func validInputPod(customImage bool) *corev1.Pod {
pod := &corev1.Pod{
Spec: corev1.PodSpec{
Expand Down
11 changes: 11 additions & 0 deletions pkg/webhook/parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ import (

var minimumSupportedVersion = version.MustParseGeneric("1.29.0")

func ParseBool(str string) (bool, error) {
switch str {
case "True", "true":
return true, nil
case "False", "false":
return false, nil
default:
return false, fmt.Errorf("could not parse string to bool: the acceptable values for %q are 'True', 'true', 'false' or 'False'", str)
}
}

// parseSidecarContainerImage supports our Privately Hosted Sidecar Image option
// by iterating the container list and finding a container named "gke-gcsfuse-sidecar"
// If we find "gke-gcsfuse-sidecar":
Expand Down

0 comments on commit 880ea0c

Please sign in to comment.