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

fix(): offboard ns when invalid labels are applied to ns #409

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a1f77d7
fix(): initial changes for offboarding replicated ns
gourishkb Oct 3, 2024
6973574
fix(): expose offBoardPod function
gourishkb Oct 4, 2024
10ebd09
fix(): offboard objects, while cleaning up ns
gourishkb Oct 9, 2024
acea6a8
select the slice gateway services only
mridulgain Oct 22, 2024
242a323
fix(): offboardRequired function
gourishkb Oct 23, 2024
81f2f58
fix(): Add ignore_critical parameter to pipeline config
KRANTHI0918 Oct 29, 2024
a693a2e
fix(): Set ignore_critical to false in pipeline configuration
KRANTHI0918 Oct 29, 2024
91094ac
fix(): Add update_trivy flag with default 'false'
KRANTHI0918 Oct 29, 2024
07d43aa
fix(): vulnerabilities
gourishkb Oct 30, 2024
210435b
fix(): code cleanup
gourishkb Nov 4, 2024
5db5228
fix(): Update Jenkinsfile
KRANTHI0918 Nov 5, 2024
01e1136
Update README.md
uma-kt Oct 29, 2024
247409d
Update README.md
uma-kt Oct 29, 2024
fbf2dec
fix(): configurable ns exclusion list (#408)
priyank-upadhyay Oct 30, 2024
f3eb9a5
fix(): Fixed tunnel status reporting in the slicegw CR (#406)
bharath-avesha Nov 4, 2024
63cb4aa
fix(): update gw deploy if gateway sidecar image has been changed in …
mridulgain Nov 5, 2024
ffb8b62
add empty string check for sidecar image name
mridulgain Nov 5, 2024
3e5301d
fix(): test build
mridulgain Nov 5, 2024
71628a8
fix(): update gw deploy if gateway sidecar image pull policy is chang…
mridulgain Nov 6, 2024
46a48e9
fix: getNodeIp logic for no-network mode
mridulgain Nov 13, 2024
403decd
address review comments
mridulgain Nov 13, 2024
d54ebc5
Set custom Trivy DB repository in GitHub Action env
KRANTHI0918 Nov 13, 2024
5c889b8
fix(): Dockerfile golang 1.23.2
gourishkb Nov 19, 2024
b23a7f7
Merge branch 'master' into feature-nsreplication
gourishkb Nov 20, 2024
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
13 changes: 13 additions & 0 deletions pkg/namespace/controllers/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (

"github.com/kubeslice/worker-operator/controllers"

cntrl "github.com/kubeslice/worker-operator/controllers"
hub "github.com/kubeslice/worker-operator/pkg/hub/hubclient"
"github.com/kubeslice/worker-operator/pkg/logger"
"github.com/kubeslice/worker-operator/pkg/utils"
Expand Down Expand Up @@ -103,6 +104,18 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
log.Error(err, "error while retrieving labels from namespace")
return ctrl.Result{}, err
}
if sliceName != "" {
isNsConfigured, err := cntrl.SliceAppNamespaceConfigured(ctx, sliceName, namespace.Name)
if err != nil {
log.Error(err, "Failed to get app namespace info for slice",
"slice", sliceName, "namespace", namespace.Name)
return ctrl.Result{}, nil
}
if !isNsConfigured {
log.Info("Namespace not part of slice", "namespace", namespace.Name, "slice", sliceName)
return ctrl.Result{}, nil
}
}
*r.EventRecorder = (*r.EventRecorder).WithSlice(sliceName)
err = hub.UpdateNamespaceInfoToHub(ctx, r.Hubclient, namespace.Name, sliceName)
if err != nil {
Expand Down
147 changes: 123 additions & 24 deletions pkg/webhook/pod/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,18 @@ const (
)

var (
log = logger.NewWrappedLogger().WithName("Webhook").V(1)
log = logger.NewWrappedLogger().WithName("Webhook").V(1)
LabelsToRemove = []string{
"kubeslice.io/nsmIP",
"kubeslice.io/pod-type",
"kubeslice.io/slice",
}

AnnotationsToRemove = []string{
"kubeslice.io/status",
"ns.networkservicemesh.io",
"networkservicemesh.io",
}
)

type SliceInfoProvider interface {
Expand Down Expand Up @@ -80,6 +91,10 @@ func (wh *WebhookServer) Handle(ctx context.Context, req admission.Request) admi

if mutate, sliceName := wh.MutationRequired(pod.ObjectMeta, ctx, req.Kind.Kind); !mutate {
log.Info("mutation not required for pod", "pod metadata", pod.ObjectMeta.Name)
if offBoard := wh.OffboardRequired(pod.ObjectMeta, ctx, req.Kind.Kind, sliceName); offBoard {
log.Info("mutation to offboard required for pod", "pod metadata", pod.ObjectMeta.Name)
pod.ObjectMeta = wh.OffBoardObject(pod.ObjectMeta, ctx)
}
} else {
log.Info("mutating pod", "pod metadata", pod.ObjectMeta.Name)
pod = MutatePod(pod, sliceName)
Expand All @@ -100,9 +115,13 @@ func (wh *WebhookServer) Handle(ctx context.Context, req admission.Request) admi

if mutate, sliceName := wh.MutationRequired(deploy.ObjectMeta, ctx, req.Kind.Kind); !mutate {
log.Info("mutation not required for deployment", "pod metadata", deploy.Spec.Template.ObjectMeta)
if offBoard := wh.OffboardRequired(deploy.ObjectMeta, ctx, req.Kind.Kind, sliceName); offBoard {
log.Info("mutation to offboard required for deploy", "deploy metadata", deploy.ObjectMeta.Name)
deploy.ObjectMeta = wh.OffBoardObject(deploy.ObjectMeta, ctx)
}
} else {
deploy = MutateDeployment(deploy, sliceName)
log.Info("mutated deploy", "pod metadata", deploy.Spec.Template.ObjectMeta)
log.Info("mutated deploy", "deploy metadata", deploy.Spec.Template.ObjectMeta)
}

marshaled, err := json.Marshal(deploy)
Expand All @@ -119,10 +138,14 @@ func (wh *WebhookServer) Handle(ctx context.Context, req admission.Request) admi
log := logger.FromContext(ctx)

if mutate, sliceName := wh.MutationRequired(statefulset.ObjectMeta, ctx, req.Kind.Kind); !mutate {
log.Info("mutation not required for statefulsets", "pod metadata", statefulset.Spec.Template.ObjectMeta)
log.Info("mutation not required for statefulsets", "statefulset metadata", statefulset.Spec.Template.ObjectMeta)
if offBoard := wh.OffboardRequired(statefulset.ObjectMeta, ctx, req.Kind.Kind, sliceName); offBoard {
log.Info("mutation to offboard required for statefulset", "statefulset metadata", statefulset.ObjectMeta.Name)
statefulset.ObjectMeta = wh.OffBoardObject(statefulset.ObjectMeta, ctx)
}
} else {
statefulset = MutateStatefulset(statefulset, sliceName)
log.Info("mutated statefulset", "pod metadata", statefulset.Spec.Template.ObjectMeta)
log.Info("mutated statefulset", "statefulset metadata", statefulset.Spec.Template.ObjectMeta)
}

marshaled, err := json.Marshal(statefulset)
Expand All @@ -139,10 +162,14 @@ func (wh *WebhookServer) Handle(ctx context.Context, req admission.Request) admi
log := logger.FromContext(ctx)

if mutate, sliceName := wh.MutationRequired(daemonset.ObjectMeta, ctx, req.Kind.Kind); !mutate {
log.Info("mutation not required for daemonset", "pod metadata", daemonset.Spec.Template.ObjectMeta)
log.Info("mutation not required for daemonset", "daemonset metadata", daemonset.Spec.Template.ObjectMeta)
if offBoard := wh.OffboardRequired(daemonset.ObjectMeta, ctx, req.Kind.Kind, sliceName); offBoard {
log.Info("mutation to offboard required for daemonset", "daemonset metadata", daemonset.ObjectMeta.Name)
daemonset.ObjectMeta = wh.OffBoardObject(daemonset.ObjectMeta, ctx)
}
} else {
daemonset = MutateDaemonSet(daemonset, sliceName)
log.Info("mutated daemonset", "pod metadata", daemonset.Spec.Template.ObjectMeta)
log.Info("mutated daemonset", "daemonset metadata", daemonset.Spec.Template.ObjectMeta)
}

marshaled, err := json.Marshal(daemonset)
Expand Down Expand Up @@ -177,6 +204,34 @@ func (wh *WebhookServer) Handle(ctx context.Context, req admission.Request) admi
}}
}

func (wh *WebhookServer) OffBoardObject(metadata metav1.ObjectMeta, ctx context.Context) metav1.ObjectMeta {
log := logger.FromContext(ctx).WithName("Webhook")

annotations := metadata.GetAnnotations()
labels := metadata.GetLabels()

// Remove kubeslice and nsm labels if present
LabelsToRemove := []string{"kubeslice.io/nsmIP", "kubeslice.io/pod-type", "kubeslice.io/slice"}
for _, labelKey := range LabelsToRemove {
if _, exists := labels[labelKey]; exists {
log.Info("Removing label", "labelKey", labelKey)
delete(labels, labelKey)
}
}
metadata.SetLabels(labels)

// Remove annotations if necessary
AnnotationsToRemove := []string{"kubeslice.io/status", "ns.networkservicemesh.io", "networkservicemesh.io"}
for _, annotationKey := range AnnotationsToRemove {
if _, exists := annotations[annotationKey]; exists {
log.Info("Removing annotation", "annotationKey", annotationKey)
delete(annotations, annotationKey)
}
}
metadata.SetAnnotations(annotations)
return metadata
}

func MutatePod(pod *corev1.Pod, sliceName string) *corev1.Pod {
// Add injection status to pod annotations
if pod.ObjectMeta.Annotations == nil {
Expand Down Expand Up @@ -317,9 +372,53 @@ func (wh *WebhookServer) ValidateServiceExport(svcex *v1beta1.ServiceExport, ctx
return true, "", nil
}

func (wh *WebhookServer) OffboardRequired(metadata metav1.ObjectMeta, ctx context.Context, kind, sliceName string) bool {
log := logger.FromContext(ctx).WithName("Webhook")
annotations := metadata.GetAnnotations()
labels := metadata.GetLabels()

// Remove kubeslice and nsm labels if present
if sliceNameInNs, exists := labels[admissionWebhookSliceNamespaceSelectorKey]; exists {
log.Info("slice name in namespace exists", "sliceNameInNs", sliceNameInNs)
if sliceNameInNs != sliceName {
log.Info("slice name in namespace does not match sliceName", "sliceNameInNs", sliceNameInNs, "sliceName", sliceName)
nsConfigured, err := wh.SliceInfoClient.SliceAppNamespaceConfigured(context.Background(), sliceName, metadata.Namespace)
if err != nil {
log.Error(err, "Failed to get app namespace info for slice",
"slice", sliceName, "namespace", metadata.Namespace)
return false
}
if !nsConfigured {
log.Info("Namespace not part of slice", "namespace", metadata.Namespace, "slice", sliceName)
return true
}
return false
}
return false
}

LabelsToRemove := []string{"kubeslice.io/nsmIP", "kubeslice.io/pod-type", "kubeslice.io/slice"}
for _, labelKey := range LabelsToRemove {
if _, exists := labels[labelKey]; exists {
log.Info("Found label", "labelKey", labelKey)
return true
}
}

// Remove annotations if necessary
AnnotationsToRemove := []string{"kubeslice.io/status", "ns.networkservicemesh.io", "networkservicemesh.io"}
for _, annotationKey := range AnnotationsToRemove {
if _, exists := annotations[annotationKey]; exists {
log.Info("Found annotation", "annotationKey", annotationKey)
return true
}
}
return false
}

// returns mutationRequired bool, sliceName string
func (wh *WebhookServer) MutationRequired(metadata metav1.ObjectMeta, ctx context.Context, kind string) (bool, string) {
log := logger.FromContext(ctx)
log := logger.FromContext(ctx).WithName("Webhook")
annotations := metadata.GetAnnotations()

labels := metadata.GetLabels()
Expand All @@ -338,19 +437,6 @@ func (wh *WebhookServer) MutationRequired(metadata metav1.ObjectMeta, ctx contex
return false, ""
}

// do not inject if it is already injected
//TODO(rahulsawra): need better way to define injected status
if annotations[AdmissionWebhookAnnotationStatusKey] == "injected" {
log.Info("obj is already injected", "kind", kind)
return false, ""
}

// Do not auto onboard control plane namespace. Ideally, we should not have any deployment/pod in the control plane ns connect to a slice
if metadata.Namespace == controlPlaneNamespace {
log.Info("namespace is same as controle plane")
return false, ""
}

nsLabels, err := wh.SliceInfoClient.GetNamespaceLabels(context.Background(), wh.Client, metadata.Namespace)
if err != nil {
log.Error(err, "Error getting namespace labels")
Expand All @@ -367,25 +453,38 @@ func (wh *WebhookServer) MutationRequired(metadata metav1.ObjectMeta, ctx contex
return false, ""
}

// do not inject if it is already injected
//TODO(rahulsawra): need better way to define injected status
if annotations[AdmissionWebhookAnnotationStatusKey] == "injected" {
log.Info("obj is already injected", "kind", kind)
return false, sliceNameInNs
}

// Do not auto onboard control plane namespace. Ideally, we should not have any deployment/pod in the control plane ns connect to a slice
if metadata.Namespace == controlPlaneNamespace {
log.Info("namespace is same as controle plane")
return false, sliceNameInNs
}

sliceNetworkType, err := wh.SliceInfoClient.GetSliceOverlayNetworkType(context.Background(), wh.Client, sliceNameInNs)
if err != nil {
log.Error(err, "Error getting slice overlay network type")
return false, ""
return false, sliceNameInNs
}
if sliceNetworkType != "" && sliceNetworkType != v1alpha1.SINGLENET {
log.Info("Slice overlay type is not single-network. Skip pod mutation...")
return false, ""
return false, sliceNameInNs
}

nsConfigured, err := wh.SliceInfoClient.SliceAppNamespaceConfigured(context.Background(), sliceNameInNs, metadata.Namespace)
if err != nil {
log.Error(err, "Failed to get app namespace info for slice",
"slice", sliceNameInNs, "namespace", metadata.Namespace)
return false, ""
return false, sliceNameInNs
}
if !nsConfigured {
log.Info("Namespace not part of slice", "namespace", metadata.Namespace, "slice", sliceNameInNs)
return false, ""
return false, sliceNameInNs
}
// The annotation kubeslice.io/slice:SLICENAME is present, enable mutation
return true, sliceNameInNs
Expand Down
Loading