Skip to content

Commit

Permalink
fix(adapters): Make adapters to update their policies info in NP status
Browse files Browse the repository at this point in the history
Signed-off-by: Anurag Rajawat <[email protected]>
  • Loading branch information
anurag-rajawat committed Feb 16, 2024
1 parent 4246ab7 commit e47bef9
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 20 deletions.
6 changes: 2 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/5GSEC/nimbus
go 1.21

require (
github.com/go-logr/logr v1.4.1
github.com/onsi/ginkgo/v2 v2.14.0
github.com/onsi/gomega v1.30.0
k8s.io/apimachinery v0.29.1
Expand All @@ -11,11 +12,8 @@ require (
)

require (
github.com/5GSEC/nimbus/pkg/adapter/nimbus-kubearmor v0.0.0-20240208144202-ef6c819f09b3 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20240125171707-8e6641511fe3 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
Expand Down Expand Up @@ -71,7 +69,7 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.29.1 // indirect
k8s.io/api v0.29.1
k8s.io/apiextensions-apiserver v0.29.1 // indirect
k8s.io/component-base v0.29.1 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/5GSEC/nimbus/pkg/adapter/nimbus-kubearmor v0.0.0-20240208144202-ef6c819f09b3 h1:dcJ9kZy7Kn/uh36QxLdTLn0L0UtG744uFAJHwCDUDdU=
github.com/5GSEC/nimbus/pkg/adapter/nimbus-kubearmor v0.0.0-20240208144202-ef6c819f09b3/go.mod h1:TTZsB7iLwzcTzW9CjkqIUpvx8ShiQM7bSNDH7mYnV8w=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -68,8 +66,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20240125171707-8e6641511fe3 h1:xDg2EAk7rV3psrUkwC7JqY6pzOutWwh4VuUEybypcrA=
github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20240125171707-8e6641511fe3/go.mod h1:Z7ZPkMwtVcjSaDigSekvooXRxapWsLAVVmX3ltL673k=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down
2 changes: 0 additions & 2 deletions pkg/adapter/nimbus-kubearmor/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/5GSEC/nimbus v0.0.0-20240129090659-01178b5c28c7 h1:adBGcrCAKeU7PLiz6m2c+3c8uuL5UPkHN5O6FHJQm7I=
github.com/5GSEC/nimbus v0.0.0-20240129090659-01178b5c28c7/go.mod h1:VXo/w78XDmQEunuZYIsDyGDthCKealQR13X9OkY25D0=
github.com/5GSEC/nimbus v0.0.0-20240208070656-624660f34768 h1:v2fY3lWXydstfekQSHs9n0TpNnTteC7Iws3ojwGtFJk=
github.com/5GSEC/nimbus v0.0.0-20240208070656-624660f34768/go.mod h1:yw79m9f1+f3tBSZCMQKbNVKL39Q71FyGyoa8nClo1Hs=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down
22 changes: 19 additions & 3 deletions pkg/adapter/nimbus-kubearmor/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (

var (
scheme = runtime.NewScheme()
np intentv1.NimbusPolicy
k8sClient client.Client
)

Expand Down Expand Up @@ -81,6 +80,7 @@ func Run(ctx context.Context) {
func reconcileKsp(ctx context.Context, kspName, namespace string, deleted bool) {
logger := log.FromContext(ctx)
npName := adapterutil.ExtractNpName(kspName)
var np intentv1.NimbusPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: npName, Namespace: namespace}, &np)
if err != nil {
if !errors.IsNotFound(err) {
Expand All @@ -98,18 +98,22 @@ func reconcileKsp(ctx context.Context, kspName, namespace string, deleted bool)

func createOrUpdateKsp(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 {
logger.Error(err, "failed to get NimbusPolicy", "NimbusPolicy.Name", npName, "NimbusPolicy.Namespace", npNamespace)
return
}

if adapterutil.IsOrphan(np.GetOwnerReferences(), "SecurityIntentBinding") {
logger.V(4).Info("Ignoring orphan NimbusPolicy", "NimbusPolicy.Name", np.GetName(), "NimbusPolicy.Namespace", np.GetNamespace())
logger.V(4).Info("Ignoring orphan NimbusPolicy", "NimbusPolicy.Name", npName, "NimbusPolicy.Namespace", npNamespace)
return
}

ksps := processor.BuildKspsFrom(logger, &np)
deleteUnnecessaryKsps(ctx, ksps, npNamespace, logger)

// TODO: Fix loop due to unnecessary KSPs deletion
//deleteUnnecessaryKsps(ctx, ksps, npNamespace, logger)

// Iterate using a separate index variable to avoid aliasing
for idx := range ksps {
ksp := ksps[idx]
Expand Down Expand Up @@ -140,6 +144,18 @@ func createOrUpdateKsp(ctx context.Context, npName, npNamespace string) {
}
logger.Info("KubeArmorPolicy configured", "KubeArmorPolicy.Name", existingKsp.Name, "KubeArmorPolicy.Namespace", existingKsp.Namespace)
}

// Due to adapters' dependency on nimbus module, the docker image build is
// failing. The relevant code is commented out below (lines 153-155). We shall
// uncomment this code in a subsequent PR.

// Every adapter is responsible for updating the status field of the
// corresponding NimbusPolicy with the number and names of successfully created
// policies. This provides feedback to users about the translation and deployment
// of their security intent.
//if err = adapterutil.UpdateNpStatus(ctx, k8sClient, "KubeArmorPolicy/"+ksp.Name, np.Name, np.Namespace); err != nil {
// logger.Error(err, "failed to update KubeArmorPolicies status in NimbusPolicy")
//}
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/adapter/nimbus-kubearmor/processor/kspbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func unAuthorizedSaTokenAccessKsp() kubearmorv1.KubeArmorPolicy {
}
}

// TODO: Instead of downloading the KSP build it locally
func swDeploymentToolsKsp() kubearmorv1.KubeArmorPolicy {
var ksp kubearmorv1.KubeArmorPolicy
fileUrl := "https://raw.githubusercontent.com/kubearmor/policy-templates/main/nist/system/ksp-nist-si-4-execute-package-management-process-in-container.yaml"
Expand Down
1 change: 0 additions & 1 deletion pkg/adapter/nimbus-netpol/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.2 // indirect
github.com/evanphx/json-patch v5.7.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions pkg/adapter/nimbus-netpol/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
github.com/5GSEC/nimbus v0.0.0-20240129090659-01178b5c28c7 h1:adBGcrCAKeU7PLiz6m2c+3c8uuL5UPkHN5O6FHJQm7I=
github.com/5GSEC/nimbus v0.0.0-20240129090659-01178b5c28c7/go.mod h1:VXo/w78XDmQEunuZYIsDyGDthCKealQR13X9OkY25D0=
github.com/5GSEC/nimbus v0.0.0-20240208070656-624660f34768 h1:v2fY3lWXydstfekQSHs9n0TpNnTteC7Iws3ojwGtFJk=
github.com/5GSEC/nimbus v0.0.0-20240208070656-624660f34768/go.mod h1:yw79m9f1+f3tBSZCMQKbNVKL39Q71FyGyoa8nClo1Hs=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down
17 changes: 15 additions & 2 deletions pkg/adapter/nimbus-netpol/manager/netpols_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (

var (
scheme = runtime.NewScheme()
np intentv1.NimbusPolicy
k8sClient client.Client
)

Expand Down Expand Up @@ -80,6 +79,7 @@ func Run(ctx context.Context) {
func reconcileNetPol(ctx context.Context, netpolName, namespace string, deleted bool) {
logger := log.FromContext(ctx)
npName := adapterutil.ExtractNpName(netpolName)
var np intentv1.NimbusPolicy
err := k8sClient.Get(ctx, types.NamespacedName{Name: npName, Namespace: namespace}, &np)
if err != nil {
if !errors.IsNotFound(err) {
Expand All @@ -97,13 +97,14 @@ func reconcileNetPol(ctx context.Context, netpolName, namespace string, deleted

func createOrUpdateNetworkPolicy(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 {
logger.Error(err, "failed to get NimbusPolicy", "NimbusPolicy.Name", npName[0], "NimbusPolicy.Namespace", npName[1])
return
}

if adapterutil.IsOrphan(np.GetOwnerReferences(), "SecurityIntentBinding") {
logger.V(4).Info("Ignoring orphan NimbusPolicy", "NimbusPolicy.Name", np.GetName(), "NimbusPolicy.Namespace", np.GetNamespace())
logger.V(4).Info("Ignoring orphan NimbusPolicy", "NimbusPolicy.Name", npName, "NimbusPolicy.Namespace", npNamespace)
return
}

Expand Down Expand Up @@ -138,6 +139,18 @@ func createOrUpdateNetworkPolicy(ctx context.Context, npName, npNamespace string
}
logger.Info("NetworkPolicy configured", "NetworkPolicy.Name", netpol.Name, "NetworkPolicy.Namespace", netpol.Namespace)
}

// Due to adapters' dependency on nimbus module, the docker image build is
// failing. The relevant code is commented out below (lines 153-155). We shall
// uncomment this code in a subsequent PR.

// Every adapter is responsible for updating the status field of the
// corresponding NimbusPolicy with the number and names of successfully created
// policies. This provides feedback to users about the translation and deployment
// of their security intent.
//if err = adapterutil.UpdateNpStatus(ctx, k8sClient, "NetworkPolicy/"+netpol.Name, np.Name, np.Namespace); err != nil {
// logger.Error(err, "failed to update NetworkPolicies status in NimbusPolicy")
//}
}
}

Expand Down
55 changes: 53 additions & 2 deletions pkg/adapter/util/nimbuspolicy_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,61 @@
package util

import (
"context"
"strings"

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

intentv1 "github.com/5GSEC/nimbus/api/v1"
)

func ExtractNpName(kspName string) string {
words := strings.Split(kspName, "-")
// ExtractNpName extracts the actual NimbusPolicy name from a formatted policy
// name.
func ExtractNpName(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.
func UpdateNpStatus(ctx context.Context, k8sClient client.Client, currPolicyFullName, npName, namespace string) error {
// Since multiple adapters may attempt to update the NimbusPolicy 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
// issues while preventing indefinite retries in case of persistent conflicts.
if retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
latestNp := &intentv1.NimbusPolicy{}
if err := k8sClient.Get(ctx, types.NamespacedName{Name: npName, Namespace: namespace}, latestNp); err != nil {
return nil
}

updateCountAndPoliciesName(latestNp, currPolicyFullName)
if err := k8sClient.Status().Update(ctx, latestNp); err != nil {
return err
}

return nil
}); retryErr != nil {
return retryErr
}
return nil
}

func updateCountAndPoliciesName(latestNp *intentv1.NimbusPolicy, currPolicyFullName string) {
if !contains(latestNp.Status.Policies, currPolicyFullName) {
latestNp.Status.NumberOfAdapterPolicies++
latestNp.Status.Policies = append(latestNp.Status.Policies, currPolicyFullName)
}
}

func contains(existingPolicies []string, policy string) bool {
for _, existingPolicy := range existingPolicies {
if existingPolicy == policy {
return true
}
}
return false
}

0 comments on commit e47bef9

Please sign in to comment.