Skip to content

Commit

Permalink
refactor(adapter): Refactor adapter utils
Browse files Browse the repository at this point in the history
Signed-off-by: Anurag Rajawat <[email protected]>
  • Loading branch information
anurag-rajawat committed Jun 10, 2024
1 parent ac704d7 commit d7124cf
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 149 deletions.
4 changes: 2 additions & 2 deletions pkg/adapter/nimbus-k8tls/manager/cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func createOrUpdateCj(ctx context.Context, logger logr.Logger, cwnp v1alpha1.Clu
logger.Info("configured Kubernetes CronJob", "CronJob.Name", cronJob.Name, "CronJob.Namespace", cronJob.Namespace)
}

if err = adapterutil.UpdateCnpStatus(ctx, k8sClient, "CronJob/"+cronJob.Name, cwnp.Name, false); err != nil {
if err = adapterutil.UpdateCwnpStatus(ctx, k8sClient, "CronJob/"+cronJob.Name, cwnp.Name, false); err != nil {
logger.Error(err, "failed to update ClusterNimbusPolicy status")
}
}
Expand All @@ -68,7 +68,7 @@ func deleteCronJobs(ctx context.Context, logger logr.Logger, cwnpName string, cr
continue
}

if err := adapterutil.UpdateCnpStatus(ctx, k8sClient, "CronJob/"+cronJob.Name, cwnpName, true); err != nil {
if err := adapterutil.UpdateCwnpStatus(ctx, k8sClient, "CronJob/"+cronJob.Name, cwnpName, true); err != nil {
logger.Error(err, "failed to update ClusterNimbusPolicy status")
}
logger.Info("Dangling Kubernetes CronJob deleted", "CronJobJob.Name", cronJob.Name, "CronJob.Namespace", cronJob.Namespace)
Expand Down
2 changes: 1 addition & 1 deletion pkg/adapter/nimbus-k8tls/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func Run(ctx context.Context) {

func reconcileCronJob(ctx context.Context, name string) {
logger := log.FromContext(ctx)
cwnpName := adapterutil.ExtractClusterNpName(name)
cwnpName := adapterutil.ExtractAnyNimbusPolicyName(name)
var cwnp v1alpha1.ClusterNimbusPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: cwnpName}, &cwnp)
if err != nil {
Expand Down
19 changes: 10 additions & 9 deletions pkg/adapter/nimbus-kubearmor/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/go-logr/logr"
kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
Expand Down Expand Up @@ -40,7 +41,7 @@ func init() {

func Run(ctx context.Context) {
npCh := make(chan common.Request)
deletedNpCh := make(chan common.Request)
deletedNpCh := make(chan *unstructured.Unstructured)
go globalwatcher.WatchNimbusPolicies(ctx, npCh, deletedNpCh, "SecurityIntentBinding", "ClusterSecurityIntentBinding")

updatedKspCh := make(chan common.Request)
Expand All @@ -58,7 +59,7 @@ func Run(ctx context.Context) {
case createdNp := <-npCh:
createOrUpdateKsp(ctx, createdNp.Name, createdNp.Namespace)
case deletedNp := <-deletedNpCh:
deleteKsp(ctx, deletedNp.Name, deletedNp.Namespace)
logKspToDelete(ctx, deletedNp)
case updatedKsp := <-updatedKspCh:
reconcileKsp(ctx, updatedKsp.Name, updatedKsp.Namespace, false)
case deletedKsp := <-deletedKspCh:
Expand All @@ -69,7 +70,7 @@ func Run(ctx context.Context) {

func reconcileKsp(ctx context.Context, kspName, namespace string, deleted bool) {
logger := log.FromContext(ctx)
npName := adapterutil.ExtractNpName(kspName)
npName := adapterutil.ExtractAnyNimbusPolicyName(kspName)
var np v1alpha1.NimbusPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: npName, Namespace: namespace}, &np)
if err != nil {
Expand Down Expand Up @@ -141,23 +142,23 @@ func createOrUpdateKsp(ctx context.Context, npName, npNamespace string) {
}
}

func deleteKsp(ctx context.Context, npName, npNamespace string) {
func logKspToDelete(ctx context.Context, deletedNp *unstructured.Unstructured) {
logger := log.FromContext(ctx)
var ksps kubearmorv1.KubeArmorPolicyList

if err := k8sClient.List(ctx, &ksps, &client.ListOptions{Namespace: npNamespace}); err != nil {
if err := k8sClient.List(ctx, &ksps, &client.ListOptions{Namespace: deletedNp.GetNamespace()}); err != nil {
logger.Error(err, "failed to list KubeArmorPolicies")
return
}

// Kubernetes GC automatically deletes the child when the parent/owner is
// deleted. So, we don't need to do anything in this case since NimbusPolicy is
// the owner and when it gets deleted corresponding KSPs will be automatically
// deleted.
// deleted. So, we don't need to delete the policy because NimbusPolicy is the
// owner and when it gets deleted all the corresponding policies will be
// automatically deleted.
for _, ksp := range ksps.Items {
logger.Info("KubeArmorPolicy already deleted due to NimbusPolicy deletion",
"KubeArmorPolicy.Name", ksp.Name, "KubeArmorPolicy.Namespace", ksp.Namespace,
"NimbusPolicy.Name", npName, "NimbusPolicy.Namespace", npNamespace,
"NimbusPolicy.Name", deletedNp.GetName(), "NimbusPolicy.Namespace", deletedNp.GetNamespace(),
)
}
}
Expand Down
43 changes: 23 additions & 20 deletions pkg/adapter/nimbus-kyverno/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ func init() {
}

func Run(ctx context.Context) {

npCh := make(chan common.Request)
deletedNpCh := make(chan common.Request)
deletedNpCh := make(chan *unstructured.Unstructured)
go globalwatcher.WatchNimbusPolicies(ctx, npCh, deletedNpCh, "SecurityIntentBinding")

clusterNpChan := make(chan string)
Expand All @@ -50,23 +49,24 @@ func Run(ctx context.Context) {

updatedKcpCh := make(chan string)
deletedKcpCh := make(chan string)

go watcher.WatchKcps(ctx, updatedKcpCh, deletedKcpCh)

updatedKpCh := make(chan common.Request)
deletedKpCh := make(chan common.Request)

go watcher.WatchKps(ctx, updatedKpCh, deletedKpCh)

for {
select {
case <-ctx.Done():
close(npCh)
close(deletedNpCh)

close(clusterNpChan)
close(deletedClusterNpChan)

close(updatedKcpCh)
close(deletedKcpCh)

close(updatedKpCh)
close(deletedKpCh)
return
Expand All @@ -75,7 +75,7 @@ func Run(ctx context.Context) {
case createdCnp := <-clusterNpChan:
createOrUpdateKcp(ctx, createdCnp)
case deletedNp := <-deletedNpCh:
deleteKp(ctx, deletedNp.Name, deletedNp.Namespace)
logKpToDelete(ctx, deletedNp)
case deletedCnp := <-deletedClusterNpChan:
logKcpToDelete(ctx, deletedCnp)
case updatedKp := <-updatedKpCh:
Expand All @@ -87,13 +87,12 @@ func Run(ctx context.Context) {
case deletedKp := <-deletedKpCh:
reconcileKp(ctx, deletedKp.Name, deletedKp.Namespace, true)
}

}
}

func reconcileKp(ctx context.Context, kpName, namespace string, deleted bool) {
logger := log.FromContext(ctx)
npName := adapterutil.ExtractNpName(kpName)
npName := adapterutil.ExtractAnyNimbusPolicyName(kpName)
var np v1alpha1.NimbusPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: npName, Namespace: namespace}, &np)
if err != nil {
Expand All @@ -112,7 +111,7 @@ func reconcileKp(ctx context.Context, kpName, namespace string, deleted bool) {

func reconcileKcp(ctx context.Context, kcpName string, deleted bool) {
logger := log.FromContext(ctx)
cnpName := adapterutil.ExtractClusterNpName(kcpName)
cnpName := adapterutil.ExtractAnyNimbusPolicyName(kcpName)
var cnp v1alpha1.ClusterNimbusPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: cnpName}, &cnp)
if err != nil {
Expand Down Expand Up @@ -232,30 +231,34 @@ func createOrUpdateKcp(ctx context.Context, cnpName string) {
logger.Info("KyvernoClusterPolicy configured", "KyvernoClusterPolicy.Name", existingKcp.Name)
}

if err = adapterutil.UpdateCnpStatus(ctx, k8sClient, "KyvernoClusterPolicy/"+kcp.Name, cnp.Name, false); err != nil {
if err = adapterutil.UpdateCwnpStatus(ctx, k8sClient, "KyvernoClusterPolicy/"+kcp.Name, cnp.Name, false); err != nil {
logger.Error(err, "failed to update KyvernoClusterPolicies status in NimbusPolicy")
}
}
}

func deleteKp(ctx context.Context, npName, npNamespace string) {
func logKpToDelete(ctx context.Context, deletedNp *unstructured.Unstructured) {
logger := log.FromContext(ctx)
var kps kyvernov1.PolicyList

if err := k8sClient.List(ctx, &kps, &client.ListOptions{Namespace: npNamespace}); err != nil {
var kps kyvernov1.PolicyList
if err := k8sClient.List(ctx, &kps, &client.ListOptions{Namespace: deletedNp.GetNamespace()}); err != nil {
logger.Error(err, "failed to list KyvernoPolicies")
return
}

// Kubernetes GC automatically deletes the child when the parent/owner is
// deleted. So, we don't need to do anything in this case since NimbusPolicy is
// the owner and when it gets deleted corresponding kps will be automatically
// deleted.
// deleted. So, we don't need to delete the policy because NimbusPolicy is the
// owner and when it gets deleted all the corresponding policies will be
// automatically deleted.
for _, kp := range kps.Items {
logger.Info("KyvernoPolicy already deleted due to NimbusPolicy deletion",
"KyvernoPolicy.Name", kp.Name, "KyvernoPolicy.Namespace", kp.Namespace,
"NimbusPolicy.Name", npName, "NimbusPolicy.Namespace", npNamespace,
)
for _, ownerRef := range kp.OwnerReferences {
if ownerRef.Name == deletedNp.GetName() && ownerRef.UID == deletedNp.GetUID() {
logger.Info("KyvernoPolicy deleted due to NimbusPolicy deletion",
"KyvernoPolicy.Name", kp.Name, "KyvernoPolicy.Namespace", kp.Namespace,
"NimbusPolicy.Name", deletedNp.GetName(), "NimbusPolicy.Namespace", deletedNp.GetNamespace(),
)
}
}
}
}

Expand Down Expand Up @@ -373,7 +376,7 @@ func deleteDanglingkcps(ctx context.Context, cnp v1alpha1.ClusterNimbusPolicy, l

logger.Info("Dangling KyvernoClusterPolicy deleted", "KyvernoClusterPolicy.Name", kcp.Name)

if err := adapterutil.UpdateCnpStatus(ctx, k8sClient, "KyvernoClusterPolicy/"+kcp.Name, cnp.Name, true); err != nil {
if err := adapterutil.UpdateCwnpStatus(ctx, k8sClient, "KyvernoClusterPolicy/"+kcp.Name, cnp.Name, true); err != nil {
logger.Error(err, "failed to update KyvernoClusterPolicy statis in ClusterNimbusPolicy")
}

Expand Down
34 changes: 20 additions & 14 deletions pkg/adapter/nimbus-netpol/manager/netpols_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import (
"github.com/go-logr/logr"
netv1 "k8s.io/api/networking/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

v1alpha1 "github.com/5GSEC/nimbus/api/v1alpha1"
"github.com/5GSEC/nimbus/api/v1alpha1"
"github.com/5GSEC/nimbus/pkg/adapter/common"
"github.com/5GSEC/nimbus/pkg/adapter/k8s"
adapterutil "github.com/5GSEC/nimbus/pkg/adapter/util"
Expand All @@ -43,7 +44,7 @@ func Run(ctx context.Context) {
// Watch NimbusPolicies only, and not ClusterNimbusPolicies as NetworkPolicy is
// namespaced scoped
npCh := make(chan common.Request)
deletedNpCh := make(chan common.Request)
deletedNpCh := make(chan *unstructured.Unstructured)
go globalwatcher.WatchNimbusPolicies(ctx, npCh, deletedNpCh, "SecurityIntentBinding", "ClusterSecurityIntentBinding")

updatedNetpolCh := make(chan common.Request)
Expand All @@ -61,7 +62,7 @@ func Run(ctx context.Context) {
case createdNp := <-npCh:
createOrUpdateNetworkPolicy(ctx, createdNp.Name, createdNp.Namespace)
case deletedNp := <-deletedNpCh:
deleteNetworkPolicy(ctx, deletedNp.Name, deletedNp.Namespace)
logNetworkPolicyToDelete(ctx, deletedNp)
case updatedNetpol := <-updatedNetpolCh:
reconcileNetPol(ctx, updatedNetpol.Name, updatedNetpol.Namespace, false)
case deletedNetpol := <-deletedNetpolCh:
Expand All @@ -72,7 +73,7 @@ func Run(ctx context.Context) {

func reconcileNetPol(ctx context.Context, netpolName, namespace string, deleted bool) {
logger := log.FromContext(ctx)
npName := adapterutil.ExtractNpName(netpolName)
npName := adapterutil.ExtractAnyNimbusPolicyName(netpolName)
var np v1alpha1.NimbusPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: npName, Namespace: namespace}, &np)
if err != nil {
Expand Down Expand Up @@ -143,24 +144,29 @@ func createOrUpdateNetworkPolicy(ctx context.Context, npName, npNamespace string
}
}

func deleteNetworkPolicy(ctx context.Context, npName, npNamespace string) {
func logNetworkPolicyToDelete(ctx context.Context, deletedNp *unstructured.Unstructured) {
logger := log.FromContext(ctx)
var netpols netv1.NetworkPolicyList

if err := k8sClient.List(ctx, &netpols, &client.ListOptions{Namespace: npNamespace}); err != nil {
var netpols netv1.NetworkPolicyList
if err := k8sClient.List(ctx, &netpols, &client.ListOptions{Namespace: deletedNp.GetNamespace()}); err != nil {
logger.Error(err, "failed to list NetworkPolicies")
return
}

// Kubernetes GC automatically deletes the child when the parent/owner is
// deleted. So, we don't need to do anything in this case since NimbusPolicy is
// the owner and when it gets deleted corresponding NetworkPolicies will be automatically
// deleted.
// deleted. So, we don't need to delete the policy because NimbusPolicy is the
// owner and when it gets deleted all the corresponding policies will be
// automatically deleted.
for _, netpol := range netpols.Items {
logger.Info("NetworkPolicy already deleted due to NimbusPolicy deletion",
"NetworkPolicy.Name", netpol.Name, "NetworkPolicy.Namespace", netpol.Namespace,
"NetworkPolicy.Name", npName, "NetworkPolicy.Namespace", npNamespace,
)
for _, ownerRef := range netpol.OwnerReferences {
if ownerRef.Name == deletedNp.GetName() && ownerRef.UID == deletedNp.GetUID() {
logger.Info("NetworkPolicy already deleted due to NimbusPolicy deletion",
"NetworkPolicy.Name", netpol.Name, "NetworkPolicy.Namespace", netpol.Namespace,
"NetworkPolicy.Name", deletedNp.GetName(), "NetworkPolicy.Namespace", deletedNp.GetNamespace(),
)
break
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,23 @@ package util

import (
"context"
"strings"
"slices"

"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/controller-runtime/pkg/client"

v1alpha1 "github.com/5GSEC/nimbus/api/v1alpha1"
"github.com/5GSEC/nimbus/api/v1alpha1"
)

// ExtractNpName extracts the actual NimbusPolicy name from a formatted policy
// name.
func ExtractClusterNpName(policyName string) string {
words := strings.Split(policyName, "-")
return strings.Join(words[:len(words)-1], "-")
}

// UpdateNpStatus updates the provided NimbusPolicy status with the number and
// names of its descendant policies that were created. Every adapter is
// responsible for updating the status field of the corresponding NimbusPolicy
// with the number and names of successfully created policies by calling this
// API. This provides feedback to users about the translation and deployment of
// their security intent
func UpdateCnpStatus(ctx context.Context, k8sClient client.Client, currPolicyFullName, cnpName string, decrement bool) error {
// Since multiple adapters may attempt to update the NimbusPolicy status
// UpdateCwnpStatus updates provided ClusterNimbusPolicy status subresource with
// the number and names of its descendant policies that were created. Every
// adapter is responsible for updating the status field of the corresponding
// ClusterNimbusPolicy with the number and names of successfully created policies
// by calling this API. This provides feedback to users about the translation and
// deployment of their security intent.
func UpdateCwnpStatus(ctx context.Context, k8sClient client.Client, currPolicyFullName, cnpName string, decrement bool) error {
// Since multiple adapters may attempt to update the ClusterNimbusPolicy status
// concurrently, potentially leading to conflicts. To ensure data consistency,
// retry on write failures. On conflict, the update is retried with an
// exponential backoff strategy. This provides resilience against potential
Expand All @@ -52,7 +45,7 @@ func UpdateCnpStatus(ctx context.Context, k8sClient client.Client, currPolicyFul
}

func updateCountAndClusterPoliciesName(latestCnp *v1alpha1.ClusterNimbusPolicy, currPolicyFullName string, decrement bool) {
if !contains(latestCnp.Status.Policies, currPolicyFullName) {
if !slices.Contains(latestCnp.Status.Policies, currPolicyFullName) {
latestCnp.Status.NumberOfAdapterPolicies++
latestCnp.Status.Policies = append(latestCnp.Status.Policies, currPolicyFullName)
}
Expand Down
Loading

0 comments on commit d7124cf

Please sign in to comment.