Skip to content

Commit

Permalink
(chore): Mutate logic update (#198)
Browse files Browse the repository at this point in the history
* updated mutate logic for namespaced policy

---------

Signed-off-by: Ved Ratan <[email protected]>
  • Loading branch information
VedRatan authored Jun 27, 2024
1 parent 7f047bd commit 4a700b4
Show file tree
Hide file tree
Showing 8 changed files with 383 additions and 101 deletions.
2 changes: 1 addition & 1 deletion examples/clusterscoped/coco-workload-si-sib.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ spec:
- "*"
workloadSelector:
matchLabels:
app: nginx
app: nginx
2 changes: 2 additions & 0 deletions examples/clusterscoped/csib-3-exclude-names.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ spec:
- name: escape-to-host
selector:
nsSelector:
matchNames:
- "*"
excludeNames:
- ns-2
- ns-3
22 changes: 22 additions & 0 deletions examples/namespaced/coco-workload-si-sib.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: intent.security.nimbus.com/v1alpha1
kind: SecurityIntent
metadata:
name: coco-workload
spec:
intent:
id: cocoWorkload
description: "Ensure workload is encryted by running the specified workload in a Confidential VM"
action: Block
---
apiVersion: intent.security.nimbus.com/v1alpha1
kind: SecurityIntentBinding
metadata:
name: coco-workload-binding
spec:
intents:
- name: coco-workload
selector:
workloadSelector:
matchLabels:
app: nginx
app1: test
63 changes: 62 additions & 1 deletion pkg/adapter/nimbus-kyverno/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ package manager

import (
"context"
"fmt"
"strings"

"github.com/go-logr/logr"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
Expand All @@ -35,6 +38,7 @@ var (
func init() {
utilruntime.Must(v1alpha1.AddToScheme(scheme))
utilruntime.Must(kyvernov1.AddToScheme(scheme))
utilruntime.Must(corev1.AddToScheme(scheme))
k8sClient = k8s.NewOrDie(scheme)
}

Expand All @@ -51,9 +55,10 @@ func Run(ctx context.Context) {
deletedKcpCh := make(chan string)
go watcher.WatchKcps(ctx, updatedKcpCh, deletedKcpCh)

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

for {
select {
Expand All @@ -67,6 +72,7 @@ func Run(ctx context.Context) {
close(updatedKcpCh)
close(deletedKcpCh)

close(addKpCh)
close(updatedKpCh)
close(deletedKpCh)
return
Expand All @@ -78,6 +84,8 @@ func Run(ctx context.Context) {
logKpToDelete(ctx, deletedNp)
case deletedCnp := <-deletedClusterNpChan:
logKcpToDelete(ctx, deletedCnp)
case addedKp := <-addKpCh:
createTriggerForKp(ctx, addedKp)
case updatedKp := <-updatedKpCh:
reconcileKp(ctx, updatedKp.Name, updatedKp.Namespace, true)
case updatedKcp := <-updatedKcpCh:
Expand Down Expand Up @@ -259,6 +267,23 @@ func logKpToDelete(ctx context.Context, deletedNp *unstructured.Unstructured) {
)
}
}
if strings.Contains(deletedNp.GetName(), "coco-workload") {
var cms corev1.ConfigMapList
if err := k8sClient.List(ctx, &cms, &client.ListOptions{Namespace: deletedNp.GetNamespace()}); err != nil {
logger.Error(err, "failed to list ConfigMaps")
return
}
for _, cm := range cms.Items {
for _, cmOwnerRef := range cm.OwnerReferences {
if cmOwnerRef.Name == kp.GetName() && cmOwnerRef.UID == kp.GetUID() {
logger.Info("ConfigMap deleted due to KyvernoPolicy deletion",
"ConfigMap.Name", cm.GetName(), "ConfigMap.Namespace", cm.GetNamespace(),
"KyvernoPolicy.Name", kp.Name, "KyvernoPolicy.Namespace", kp.Namespace,
)
}
}
}
}
}
}

Expand Down Expand Up @@ -382,3 +407,39 @@ func deleteDanglingkcps(ctx context.Context, cnp v1alpha1.ClusterNimbusPolicy, l

}
}

func createTriggerForKp(ctx context.Context, nameNamespace common.Request) {
logger := log.FromContext(ctx)
configMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: nameNamespace.Name + "-trigger-configmap",
Namespace: nameNamespace.Namespace,
},
Data: map[string]string{
"data": "dummy",
},
}

var existingKp kyvernov1.Policy
err := k8sClient.Get(ctx, types.NamespacedName{Name: nameNamespace.Name, Namespace: nameNamespace.Namespace}, &existingKp)
if err != nil && !errors.IsNotFound(err) {
logger.Error(err, "failed to get existing KyvernoPolicy", "KyvernoPolicy.Name", existingKp.Name, "KyvernoPolicy.Namespace", nameNamespace.Namespace)
return
}

// Set MutateExistingKyvernoPolicy as the owner of the zConfigMap
if err := ctrl.SetControllerReference(&existingKp, &configMap.ObjectMeta, scheme); err != nil {
logger.Error(err, "failed to set OwnerReference on ConfigMap", "Name", configMap.Name)
return
}

// Create the ConfigMap
err = k8sClient.Create(context.TODO(), configMap)

if err != nil {
logger.Error(err, "failed to create trigger ConfigMap in namespace", nameNamespace.Namespace)
} else {
fmt.Println(nameNamespace)
logger.Info("Created trigger ConfigMap in namespace ", nameNamespace.Namespace)
}
}
141 changes: 98 additions & 43 deletions pkg/adapter/nimbus-kyverno/processor/kcpbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,44 +57,79 @@ var nsBlackList = []string{"kube-system"}

func clusterCocoRuntimeAddition(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1.Rule) kyvernov1.ClusterPolicy {
var matchFilters, excludeFilters []kyvernov1.ResourceFilter
var resourceFilter kyvernov1.ResourceFilter

labels := cnp.Spec.WorkloadSelector.MatchLabels
excludeNamespaces := cnp.Spec.NsSelector.ExcludeNames
namespaces := cnp.Spec.NsSelector.MatchNames
// exclude kube-system
resourceFilter = kyvernov1.ResourceFilter{
resourceFilter := kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Namespaces: nsBlackList,
},
}
excludeFilters = append(excludeFilters, resourceFilter)

if len(cnp.Spec.NsSelector.MatchNames) > 0 {
if len(cnp.Spec.WorkloadSelector.MatchLabels) > 0 {
if namespaces[0] != "*" && len(labels) > 0 {
for key, value := range labels {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
"apps/v1/Deployment",
},
Namespaces: cnp.Spec.NsSelector.MatchNames,
Namespaces: namespaces,
Selector: &metav1.LabelSelector{
MatchLabels: cnp.Spec.WorkloadSelector.MatchLabels,
MatchLabels: map[string]string{
key: value,
},
},
},
}
matchFilters = append(matchFilters, resourceFilter)
}
} else if namespaces[0] != "*" && len(labels) == 0 {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
"apps/v1/Deployment",
},
Namespaces: cnp.Spec.NsSelector.MatchNames,
},
}
matchFilters = append(matchFilters, resourceFilter)
} else if namespaces[0] == "*" && len(labels) > 0 {

if len(excludeNamespaces) > 0 {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Namespaces: excludeNamespaces,
},
}
excludeFilters = append(excludeFilters, resourceFilter)
}

} else {
for key, value := range labels {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
"apps/v1/Deployment",
},
Namespaces: cnp.Spec.NsSelector.MatchNames,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
key: value,
},
},
},
}
matchFilters = append(matchFilters, resourceFilter)
}
} else if namespaces[0] == "*" && len(labels) == 0 {
if len(excludeNamespaces) > 0 {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Namespaces: excludeNamespaces,
},
}
excludeFilters = append(excludeFilters, resourceFilter)
}
matchFilters = append(matchFilters, resourceFilter)

} else if len(cnp.Spec.NsSelector.ExcludeNames) > 0 {

resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
Expand All @@ -103,14 +138,8 @@ func clusterCocoRuntimeAddition(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1
},
}
matchFilters = append(matchFilters, resourceFilter)

resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Namespaces: cnp.Spec.NsSelector.ExcludeNames,
},
}
excludeFilters = append(excludeFilters, resourceFilter)
}

patchStrategicMerge := map[string]interface{}{
"spec": map[string]interface{}{
"template": map[string]interface{}{
Expand Down Expand Up @@ -141,13 +170,13 @@ func clusterCocoRuntimeAddition(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1
kyvernov1.TargetResourceSpec{
ResourceSpec: kyvernov1.ResourceSpec{
APIVersion: "apps/v1",
Kind: "Deployment",
Kind: "Deployment",
},
},
},
RawPatchStrategicMerge: &v1.JSON{
Raw: patchBytes,
} ,
},
},
},
},
Expand All @@ -171,44 +200,78 @@ func clusterEscapeToHost(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1.Rule)
}

var matchFilters, excludeFilters []kyvernov1.ResourceFilter
var resourceFilter kyvernov1.ResourceFilter

labels := cnp.Spec.WorkloadSelector.MatchLabels
excludeNamespaces := cnp.Spec.NsSelector.ExcludeNames
namespaces := cnp.Spec.NsSelector.MatchNames
// exclude kube-system
resourceFilter = kyvernov1.ResourceFilter{
resourceFilter := kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Namespaces: nsBlackList,
},
}
excludeFilters = append(excludeFilters, resourceFilter)

if len(cnp.Spec.NsSelector.MatchNames) > 0 {
if len(cnp.Spec.WorkloadSelector.MatchLabels) > 0 {
if namespaces[0] != "*" && len(labels) > 0 {
for key, value := range labels {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
"v1/Pod",
},
Namespaces: cnp.Spec.NsSelector.MatchNames,
Namespaces: namespaces,
Selector: &metav1.LabelSelector{
MatchLabels: cnp.Spec.WorkloadSelector.MatchLabels,
MatchLabels: map[string]string{
key: value,
},
},
},
}

} else {
matchFilters = append(matchFilters, resourceFilter)
}
} else if namespaces[0] != "*" && len(labels) == 0 {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
"v1/Pod",
},
Namespaces: cnp.Spec.NsSelector.MatchNames,
},
}
matchFilters = append(matchFilters, resourceFilter)
} else if namespaces[0] == "*" && len(labels) > 0 {
if len(excludeNamespaces) > 0 {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription {
Namespaces: excludeNamespaces,
},
}
excludeFilters = append(excludeFilters, resourceFilter)
}
for key, value := range labels {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
"v1/Pod",
},
Namespaces: cnp.Spec.NsSelector.MatchNames,
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
key: value,
},
},
},
}
matchFilters = append(matchFilters, resourceFilter)
}
matchFilters = append(matchFilters, resourceFilter)

} else if len(cnp.Spec.NsSelector.ExcludeNames) > 0 {
} else if namespaces[0] == "*" && len(labels) == 0 {

if len(excludeNamespaces) > 0 {
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Namespaces: excludeNamespaces,
},
}
excludeFilters = append(excludeFilters, resourceFilter)
}
resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Kinds: []string{
Expand All @@ -217,15 +280,7 @@ func clusterEscapeToHost(cnp *v1alpha1.ClusterNimbusPolicy, rule v1alpha1.Rule)
},
}
matchFilters = append(matchFilters, resourceFilter)

resourceFilter = kyvernov1.ResourceFilter{
ResourceDescription: kyvernov1.ResourceDescription{
Namespaces: cnp.Spec.NsSelector.ExcludeNames,
},
}
excludeFilters = append(excludeFilters, resourceFilter)
}

background := true
return kyvernov1.ClusterPolicy{
Spec: kyvernov1.Spec{
Expand Down
Loading

0 comments on commit 4a700b4

Please sign in to comment.