Skip to content

Commit

Permalink
updated adapter for namespaced policy
Browse files Browse the repository at this point in the history
Signed-off-by: Ved Ratan <[email protected]>
  • Loading branch information
VedRatan committed Mar 13, 2024
1 parent c695d2c commit 826a7c8
Show file tree
Hide file tree
Showing 9 changed files with 343 additions and 289 deletions.
73 changes: 0 additions & 73 deletions cpol.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion examples/namespaced/escape-to-host-si-sib.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ spec:
kind: Pod
namespace: default
matchLabels:
app: nginx
app: nginx
5 changes: 2 additions & 3 deletions pkg/adapter/nimbus-kyverno/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import (
"os/signal"
"syscall"

"github.com/5GSEC/nimbus/pkg/adapter/nimbus-kyverno/manager"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/5GSEC/nimbus/pkg/adapter/nimbus-kyverno/manager"
)

func main() {
ctrl.SetLogger(zap.New(zap.UseDevMode(true)))
ctrl.SetLogger(zap.New())
logger := ctrl.Log

ctx, cancelFunc := context.WithCancel(context.Background())
Expand Down
155 changes: 82 additions & 73 deletions pkg/adapter/nimbus-kyverno/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@ package manager

import (
"context"
// "fmt"
"strings"

intentv1 "github.com/5GSEC/nimbus/api/v1"
"github.com/5GSEC/nimbus/pkg/adapter/common"
"github.com/5GSEC/nimbus/pkg/adapter/k8s"
// kcpwatcher "github.com/5GSEC/nimbus/pkg/adapter/nimbus-kyverno/watcher"
watcher "github.com/5GSEC/nimbus/pkg/adapter/nimbus-kyverno/watcher"
processor "github.com/5GSEC/nimbus/pkg/adapter/nimbus-kyverno/processor"
adapterutil "github.com/5GSEC/nimbus/pkg/adapter/util"
globalwatcher "github.com/5GSEC/nimbus/pkg/adapter/watcher"
"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/api/errors"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
Expand All @@ -40,43 +39,54 @@ func Run(ctx context.Context) {
deletedNpCh := make(chan common.Request)
go globalwatcher.WatchNimbusPolicies(ctx, npCh, deletedNpCh)

// clusterNpChan := make(chan string)
// deletedClusterNpChan := make(chan string)
// go globalwatcher.WatchClusterNimbusPolicies(ctx, clusterNpChan, deletedClusterNpChan)
clusterNpChan := make(chan string)
deletedClusterNpChan := make(chan string)
go globalwatcher.WatchClusterNimbusPolicies(ctx, clusterNpChan, deletedClusterNpChan)

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

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

// updatedKcpCh := make(chan common.Request)
// deletedKcpCh := make(chan common.Request)
go watcher.WatchKps(ctx, updatedKpCh, deletedKpCh)

// go kcpwatcher.WatchKcps(ctx, updatedKcpCh, deletedKcpCh)

for {
select {
case <-ctx.Done():
close(npCh)
close(deletedNpCh)
// close(clusterNpChan)
// close(deletedClusterNpChan)
// close(updatedKcpCh)
// close(deletedKcpCh)
close(clusterNpChan)
close(deletedClusterNpChan)
close(updatedKcpCh)
close(deletedKcpCh)
close(updatedKpCh)
close(deletedKpCh)
return
case createdNp := <-npCh:
createOrUpdateKcp(ctx, createdNp.Name, createdNp.Namespace)
createOrUpdateKp(ctx, createdNp.Name, createdNp.Namespace)
case _ = <-clusterNpChan: // Fixme: CreateKCP based on ClusterNP
// createOrUpdateKcp(ctx, createdCnp)
case deletedNp := <-deletedNpCh:
deleteKcp(ctx, deletedNp.Name, deletedNp.Namespace)
// case updatedKcp := <-updatedKcpCh:
// reconcileKcp(ctx, updatedKcp.Name, updatedKcp.Namespace, false)
// case deletedKsp := <-deletedKcpCh:
// reconcileKcp(ctx, deletedKsp.Name, deletedKsp.Namespace, true)
// case _ = <-clusterNpChan: // Fixme: CreateKCP based on ClusterNP
// fmt.Println("No-op for ClusterNimbusPolicy")
// case _ = <-deletedClusterNpChan: // Fixme: DeleteKCP based on ClusterNP
// fmt.Println("No-op for ClusterNimbusPolicy")
deleteKp(ctx, deletedNp.Name, deletedNp.Namespace)
case _ = <-deletedClusterNpChan: // Fixme: DeleteKCP based on ClusterNP
// deleteKcp(ctx, deletedCnp)
case updatedKp := <-updatedKpCh:
reconcileKp(ctx, updatedKp.Name, updatedKp.Namespace, true)
case _ = <-updatedKcpCh:
// reconcileKcp(ctx, updatedKcp.Name, false)
case _ = <-deletedKcpCh:
// reconcileKcp(ctx, deletedKcp.Name, true)
case deletedKp := <-deletedKpCh:
reconcileKp(ctx, deletedKp.Name, deletedKp.Namespace, true)
}

}
}


func reconcileKcp(ctx context.Context, kcpName, namespace string, deleted bool) {
func reconcileKp(ctx context.Context, kcpName, namespace string, deleted bool) {
logger := log.FromContext(ctx)
npName := adapterutil.ExtractNpName(kcpName)
var np intentv1.NimbusPolicy
Expand All @@ -92,10 +102,10 @@ func reconcileKcp(ctx context.Context, kcpName, namespace string, deleted bool)
} else {
logger.V(2).Info("Reconciling modified KyvernoClusterPolicy", "KyvernoClusterPolicy.Name", kcpName, "KyvernoClusterPolicy.Namespace", namespace)
}
createOrUpdateKcp(ctx, npName, namespace)
createOrUpdateKp(ctx, npName, namespace)
}

func createOrUpdateKcp(ctx context.Context, npName, npNamespace string) {
func createOrUpdateKp(ctx context.Context, npName, npNamespace string) {
logger := log.FromContext(ctx)
var np intentv1.NimbusPolicy
if err := k8sClient.Get(ctx, types.NamespacedName{Name: npName, Namespace: npNamespace}, &np); err != nil {
Expand All @@ -108,40 +118,40 @@ func createOrUpdateKcp(ctx context.Context, npName, npNamespace string) {
return
}

// deleteDanglingKcps(ctx, np, logger)
kcps := processor.BuildKcpsFrom(logger, &np)
// deleteDanglingkps(ctx, np, logger)
kps := processor.BuildKpsFrom(logger, &np)

// Iterate using a separate index variable to avoid aliasing
for idx := range kcps {
kcp := kcps[idx]
for idx := range kps {
kp := kps[idx]

// Set NimbusPolicy as the owner of the KSP
if err := ctrl.SetControllerReference(&np, &kcp, scheme); err != nil {
logger.Error(err, "failed to set OwnerReference on KyvernoClusterPolicy", "Name", kcp.Name)
if err := ctrl.SetControllerReference(&np, &kp, scheme); err != nil {
logger.Error(err, "failed to set OwnerReference on KyvernoPolicy", "Name", kp.Name)
return
}

var existingKcp kyvernov1.ClusterPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: kcp.Name, Namespace: kcp.Namespace}, &existingKcp)
var existingKp kyvernov1.Policy
err := k8sClient.Get(ctx, types.NamespacedName{Name: kp.Name, Namespace: kp.Namespace}, &existingKp)
if err != nil && !errors.IsNotFound(err) {
logger.Error(err, "failed to get existing KyvernoClusterPolicy", "KyvernoClusterPolicy.Name", kcp.Name, "KyvernoClusterPolicy.Namespace", kcp.Namespace)
logger.Error(err, "failed to get existing KyvernoPolicy", "KyvernoPolicy.Name", kp.Name, "KyvernoPolicy.Namespace", kp.Namespace)
return
}
if err != nil {
if errors.IsNotFound(err) {
if err = k8sClient.Create(ctx, &kcp); err != nil {
logger.Error(err, "failed to create KyvernoClusterPolicy", "KyvernoClusterPolicy.Name", kcp.Name, "KyvernoClusterPolicy.Namespace", kcp.Namespace)
if err = k8sClient.Create(ctx, &kp); err != nil {
logger.Error(err, "failed to create KyvernoPolicy", "KyvernoPolicy.Name", kp.Name, "KyvernoPolicy.Namespace", kp.Namespace)
return
}
logger.Info("KyvernoClusterPolicy created", "KyvernoClusterPolicy.Name", kcp.Name, "KyvernoClusterPolicy.Namespace", kcp.Namespace)
logger.Info("KyvernoPolicy created", "KyvernoPolicy.Name", kp.Name, "KyvernoPolicy.Namespace", kp.Namespace)
}
} else {
kcp.ObjectMeta.ResourceVersion = existingKcp.ObjectMeta.ResourceVersion
if err = k8sClient.Update(ctx, &kcp); err != nil {
logger.Error(err, "failed to configure existing KyvernoClusterPolicy", "KyvernoClusterPolicy.Name", existingKcp.Name, "KyvernoClusterPolicy.Namespace", existingKcp.Namespace)
kp.ObjectMeta.ResourceVersion = existingKp.ObjectMeta.ResourceVersion
if err = k8sClient.Update(ctx, &kp); err != nil {
logger.Error(err, "failed to configure existing KyvernoPolicy", "KyvernoPolicy.Name", existingKp.Name, "KyvernoPolicy.Namespace", existingKp.Namespace)
return
}
logger.Info("KyvernoClusterPolicy configured", "KyvernoClusterPolicy.Name", existingKcp.Name, "KyvernoClusterPolicy.Namespace", existingKcp.Namespace)
logger.Info("KyvernoPolicy configured", "KyvernoPolicy.Name", existingKp.Name, "KyvernoPolicy.Namespace", existingKp.Namespace)
}

//TODO: Due to adapters' dependency on nimbus module, the docker image build is
Expand All @@ -153,69 +163,68 @@ func createOrUpdateKcp(ctx context.Context, npName, npNamespace string) {
}
}

func deleteKcp(ctx context.Context, npName, npNamespace string) {
func deleteKp(ctx context.Context, npName, npNamespace string) {
logger := log.FromContext(ctx)
var kcps kyvernov1.ClusterPolicyList
var kps kyvernov1.PolicyList

if err := k8sClient.List(ctx, &kcps, &client.ListOptions{Namespace: npNamespace}); err != nil {
logger.Error(err, "failed to list KyvernoClusterPolicies")
if err := k8sClient.List(ctx, &kps, &client.ListOptions{Namespace: npNamespace}); 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 KCPs will be automatically
// the owner and when it gets deleted corresponding kps will be automatically
// deleted.
for _, kcp := range kcps.Items {
err := k8sClient.Delete(ctx, &kcp )
if err !=nil {
logger.Error(err, "Deleting KyvernoClusterPolicy")
}
logger.Info("KyvernoClusterPolicy already deleted due to NimbusPolicy deletion",
"KyvernoClusterPolicy.Name", kcp.Name, "KyvernoClusterPolicy.Namespace", kcp.Namespace,
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,
)
}
}

func deleteDanglingKcps(ctx context.Context, np intentv1.NimbusPolicy, logger logr.Logger) {
var existingKcps kyvernov1.ClusterPolicyList
if err := k8sClient.List(ctx, &existingKcps, client.InNamespace(np.Namespace)); err != nil {



func deleteDanglingkps(ctx context.Context, np intentv1.NimbusPolicy, logger logr.Logger) {
var existingkps kyvernov1.PolicyList
if err := k8sClient.List(ctx, &existingkps, client.InNamespace(np.Namespace)); err != nil {
logger.Error(err, "failed to list KyvernoClusterPolicies for cleanup")
return
}

var kcpsOwnedByNp []kyvernov1.ClusterPolicy
for _, kcp := range existingKcps.Items {
ownerRef := kcp.OwnerReferences[0]
var kpsOwnedByNp []kyvernov1.Policy
for _, kp := range existingkps.Items {
ownerRef := kp.OwnerReferences[0]
if ownerRef.Name == np.Name && ownerRef.UID == np.UID {
kcpsOwnedByNp = append(kcpsOwnedByNp, kcp)
kpsOwnedByNp = append(kpsOwnedByNp, kp)
}
}
if len(kcpsOwnedByNp) == 0 {
if len(kpsOwnedByNp) == 0 {
return
}

kcpsToDelete := make(map[string]kyvernov1.ClusterPolicy)
kpsToDelete := make(map[string]kyvernov1.Policy)

// Populate owned KCPs
for _, kcpOwnedByNp := range kcpsOwnedByNp {
kcpsToDelete[kcpOwnedByNp.Name] = kcpOwnedByNp
// Populate owned kps
for _, kpOwnedByNp := range kpsOwnedByNp {
kpsToDelete[kpOwnedByNp.Name] = kpOwnedByNp
}

for _, nimbusRule := range np.Spec.NimbusRules {
kcpName := np.Name + "-" + strings.ToLower(nimbusRule.ID)
delete(kcpsToDelete, kcpName)
kpName := np.Name + "-" + strings.ToLower(nimbusRule.ID)
delete(kpsToDelete, kpName)
}

for kcpName := range kcpsToDelete {
kcp := kcpsToDelete[kcpName]
if err := k8sClient.Delete(ctx, &kcp); err != nil {
logger.Error(err, "failed to delete dangling KyvernoClusterPolicy", "KyvernoClusterPolicy.Name", kcp.Namespace, "KyvernoClusterPolicy.Namespace", kcp.Namespace)
for kpName := range kpsToDelete {
kp := kpsToDelete[kpName]
if err := k8sClient.Delete(ctx, &kp); err != nil {
logger.Error(err, "failed to delete dangling KyvernoPolicy", "KyvernoPolicy.Name", kp.Namespace, "KyvernoPolicy.Namespace", kp.Namespace)
continue
}

logger.Info("Dangling KyvernoClusterPolicy deleted", "KyvernoClusterPolicy.Name", kcp.Name, "KyvernoClusterPolicy.Namespace", kcp.Namespace)
logger.Info("Dangling KyvernoPolicy deleted", "KyvernoPolicy.Name", kp.Name, "KyvernoPolicy.Namespace", kp.Namespace)
}
}

Loading

0 comments on commit 826a7c8

Please sign in to comment.