diff --git a/Dockerfile b/Dockerfile index 7ec52042..e9f55bb8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,9 +15,9 @@ COPY go.sum go.sum RUN go mod download # Copy the go source -COPY main.go main.go -COPY api/ api/ -COPY controllers/ controllers/ +COPY Nimbus/cmd/main.go Nimbus/cmd/main.go +COPY Nimbus/api/ Nimbus/api/ +COPY Nimbus/ontrollers/ Nimbus/controllers/ # Build # the GOARCH has not a default value to allow the binary be built according to the host where the command diff --git a/Makefile b/Makefile index ea881017..26a655b8 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and Cust .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." + $(CONTROLLER_GEN) object:headerFile="Nimbus/hack/boilerplate.go.txt" paths="./Nimbus/..." .PHONY: fmt fmt: ## Run go fmt against code. @@ -68,7 +68,7 @@ vet: ## Run go vet against code. test: manifests generate fmt vet envtest ## Run tests. KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out -GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint +GOLANGCI_LINT = $(shell pwd)/Nimbus/bin/golangci-lint GOLANGCI_LINT_VERSION ?= v1.54.2 golangci-lint: @[ -f $(GOLANGCI_LINT) ] || { \ @@ -88,11 +88,11 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes .PHONY: build build: manifests generate fmt vet ## Build manager binary. - go build -o bin/manager main.go + go build -o Nimbus/bin/manager Nimbus/cmd/main.go .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. - go run ./main.go + go run Nimbus/cmd/main.go # If you wish to build the manager image targeting other platforms you can use the --platform flag. # (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it. @@ -149,7 +149,7 @@ undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/confi ##@ Build Dependencies ## Location to install dependencies to -LOCALBIN ?= $(shell pwd)/bin +LOCALBIN ?= $(shell pwd)/Nimbus/bin $(LOCALBIN): mkdir -p $(LOCALBIN) diff --git a/api/v1/groupversion_info.go b/Nimbus/api/v1/groupversion_info.go similarity index 100% rename from api/v1/groupversion_info.go rename to Nimbus/api/v1/groupversion_info.go diff --git a/Nimbus/api/v1/securityintent_types.go b/Nimbus/api/v1/securityintent_types.go new file mode 100644 index 00000000..cbd58274 --- /dev/null +++ b/Nimbus/api/v1/securityintent_types.go @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// SecurityIntentSpec defines the desired state of SecurityIntent +type SecurityIntentSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + Intent Intent `json:"intent"` // Define the details of the security policy. +} + +// Intent defines the security policy details +type Intent struct { + Description string `json:"description"` // Define the description + Action string `json:"action"` // Define the action of the policy + Type string `json:"type"` // Defines the type of the policy + Resource []Resource `json:"resource"` // Define the resources to which the security policy applies +} + +// Resource defines the resources that the security policy applies to +type Resource struct { + Network []Network `json:"network,omitempty"` + Process []Process `json:"process,omitempty"` + File []File `json:"file,omitempty"` + Capabilities []Capabilities `json:"capabilities,omitempty"` + Syscalls []Syscalls `json:"syscalls,omitempty"` + FromCIDRSet []CIDRSet `json:"fromCIDRSet,omitempty"` + ToPorts []ToPort `json:"toPorts,omitempty"` +} + +// Network defines the network-related policies +type Network struct { + MatchProtocols []MatchProtocol `json:"matchProtocols,omitempty"` +} + +// Process defines the process-related policies +type Process struct { + MatchPaths []MatchPath `json:"matchPaths,omitempty"` + MatchDirectories []MatchDirectory `json:"matchDirectories,omitempty"` + MatchPatterns []MatchPattern `json:"matchPatterns,omitempty"` +} + +// File defines the file-related policies +type File struct { + MatchPaths []MatchPath `json:"matchPaths,omitempty"` + MatchDirectories []MatchDirectory `json:"matchDirectories,omitempty"` +} + +// Capabilities defines the capabilities-related policies +type Capabilities struct { + MatchCapabilities []MatchCapability `json:"matchCapabilities,omitempty"` +} + +// Syscalls defines the syscalls-related policies +type Syscalls struct { + MatchSyscalls []MatchSyscall `json:"matchSyscalls,omitempty"` +} + +// CIDRSet defines CIDR ranges for network policies +type CIDRSet struct { + CIDR string `json:"cidr,omitempty"` +} + +// ToPort defines ports and protocols for network policies +type ToPort struct { + Ports []Port `json:"ports,omitempty"` +} + +// Port defines a network port and its protocol +type Port struct { + Port string `json:"port,omitempty"` + Protocol string `json:"protocol,omitempty"` +} + +// MatchProtocol defines a protocol for network policies +type MatchProtocol struct { + Protocol string `json:"protocol,omitempty"` +} + +// MatchPath defines a path for process or file policies +type MatchPath struct { + Path string `json:"path,omitempty"` +} + +// MatchDirectory defines a directory for process or file policies +type MatchDirectory struct { + Directory string `json:"dir,omitempty"` + FromSource []FromSource `json:"fromSource,omitempty"` +} + +// MatchPattern defines a pattern for process policies +type MatchPattern struct { + Pattern string `json:"pattern,omitempty"` +} + +// MatchSyscall defines a syscall for syscall policies +type MatchSyscall struct { + Syscalls []string `json:"syscalls,omitempty"` +} + +// MatchCapability defines a capability for capabilities policies +type MatchCapability struct { + Capability string `json:"capability,omitempty"` +} + +// FromSource defines a source path for directory-based policies +type FromSource struct { + Path string `json:"path,omitempty"` +} + +// SecurityIntentStatus defines the observed state of SecurityIntent +type SecurityIntentStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + // This field can be updated to reflect the actual status of the application of the security intents +} + +// SecurityIntent is the Schema for the securityintents API +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SecurityIntent is the Schema for the securityintents API +type SecurityIntent struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec SecurityIntentSpec `json:"spec,omitempty"` + Status SecurityIntentStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// SecurityIntentList contains a list of SecurityIntent +type SecurityIntentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []SecurityIntent `json:"items"` +} + +func init() { + SchemeBuilder.Register(&SecurityIntent{}, &SecurityIntentList{}) +} diff --git a/Nimbus/api/v1/securityintentbinding_types.go b/Nimbus/api/v1/securityintentbinding_types.go new file mode 100644 index 00000000..7d3e8e46 --- /dev/null +++ b/Nimbus/api/v1/securityintentbinding_types.go @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// SecurityIntentBindingSpec defines the desired state of SecurityIntentBinding +type SecurityIntentBindingSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Foo is an example field of SecurityIntentBinding. Edit securityintentbinding_types.go to remove/update + Selector Selector `json:"selector"` + IntentRequests []IntentRequest `json:"intentRequests"` +} + +// Selector defines the selection criteria for resources +type Selector struct { + Any []ResourceFilter `json:"any,omitempty"` + All []ResourceFilter `json:"all,omitempty"` + CEL []string `json:"cel,omitempty"` +} + +// ResourceFilter is used for filtering resources +type ResourceFilter struct { + Resources Resources `json:"resources,omitempty"` +} + +// Resources defines the properties for selecting Kubernetes resources +type Resources struct { + Kind string `json:"kind,omitempty"` + Namespace string `json:"namespace,omitempty"` + MatchLabels map[string]string `json:"matchLabels,omitempty"` +} + +// IntentRequest defines the request for a specific SecurityIntent +type IntentRequest struct { + Type string `json:"type"` + IntentName string `json:"intentName"` + Description string `json:"description"` + Mode string `json:"mode"` +} + +// SecurityIntentBindingStatus defines the observed state of SecurityIntentBinding +type SecurityIntentBindingStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// SecurityIntentBinding is the Schema for the securityintentbindings API +type SecurityIntentBinding struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SecurityIntentBindingSpec `json:"spec,omitempty"` + Status SecurityIntentBindingStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// SecurityIntentBindingList contains a list of SecurityIntentBinding +type SecurityIntentBindingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []SecurityIntentBinding `json:"items"` +} + +func init() { + SchemeBuilder.Register(&SecurityIntentBinding{}, &SecurityIntentBindingList{}) +} diff --git a/Nimbus/api/v1/zz_generated.deepcopy.go b/Nimbus/api/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000..69431e40 --- /dev/null +++ b/Nimbus/api/v1/zz_generated.deepcopy.go @@ -0,0 +1,654 @@ +//go:build !ignore_autogenerated + +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CIDRSet) DeepCopyInto(out *CIDRSet) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CIDRSet. +func (in *CIDRSet) DeepCopy() *CIDRSet { + if in == nil { + return nil + } + out := new(CIDRSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Capabilities) DeepCopyInto(out *Capabilities) { + *out = *in + if in.MatchCapabilities != nil { + in, out := &in.MatchCapabilities, &out.MatchCapabilities + *out = make([]MatchCapability, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Capabilities. +func (in *Capabilities) DeepCopy() *Capabilities { + if in == nil { + return nil + } + out := new(Capabilities) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *File) DeepCopyInto(out *File) { + *out = *in + if in.MatchPaths != nil { + in, out := &in.MatchPaths, &out.MatchPaths + *out = make([]MatchPath, len(*in)) + copy(*out, *in) + } + if in.MatchDirectories != nil { + in, out := &in.MatchDirectories, &out.MatchDirectories + *out = make([]MatchDirectory, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new File. +func (in *File) DeepCopy() *File { + if in == nil { + return nil + } + out := new(File) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FromSource) DeepCopyInto(out *FromSource) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FromSource. +func (in *FromSource) DeepCopy() *FromSource { + if in == nil { + return nil + } + out := new(FromSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Intent) DeepCopyInto(out *Intent) { + *out = *in + if in.Resource != nil { + in, out := &in.Resource, &out.Resource + *out = make([]Resource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Intent. +func (in *Intent) DeepCopy() *Intent { + if in == nil { + return nil + } + out := new(Intent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntentRequest) DeepCopyInto(out *IntentRequest) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntentRequest. +func (in *IntentRequest) DeepCopy() *IntentRequest { + if in == nil { + return nil + } + out := new(IntentRequest) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchCapability) DeepCopyInto(out *MatchCapability) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchCapability. +func (in *MatchCapability) DeepCopy() *MatchCapability { + if in == nil { + return nil + } + out := new(MatchCapability) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchDirectory) DeepCopyInto(out *MatchDirectory) { + *out = *in + if in.FromSource != nil { + in, out := &in.FromSource, &out.FromSource + *out = make([]FromSource, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchDirectory. +func (in *MatchDirectory) DeepCopy() *MatchDirectory { + if in == nil { + return nil + } + out := new(MatchDirectory) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchPath) DeepCopyInto(out *MatchPath) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchPath. +func (in *MatchPath) DeepCopy() *MatchPath { + if in == nil { + return nil + } + out := new(MatchPath) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchPattern) DeepCopyInto(out *MatchPattern) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchPattern. +func (in *MatchPattern) DeepCopy() *MatchPattern { + if in == nil { + return nil + } + out := new(MatchPattern) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchProtocol) DeepCopyInto(out *MatchProtocol) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchProtocol. +func (in *MatchProtocol) DeepCopy() *MatchProtocol { + if in == nil { + return nil + } + out := new(MatchProtocol) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MatchSyscall) DeepCopyInto(out *MatchSyscall) { + *out = *in + if in.Syscalls != nil { + in, out := &in.Syscalls, &out.Syscalls + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MatchSyscall. +func (in *MatchSyscall) DeepCopy() *MatchSyscall { + if in == nil { + return nil + } + out := new(MatchSyscall) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Network) DeepCopyInto(out *Network) { + *out = *in + if in.MatchProtocols != nil { + in, out := &in.MatchProtocols, &out.MatchProtocols + *out = make([]MatchProtocol, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Network. +func (in *Network) DeepCopy() *Network { + if in == nil { + return nil + } + out := new(Network) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Port) DeepCopyInto(out *Port) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Port. +func (in *Port) DeepCopy() *Port { + if in == nil { + return nil + } + out := new(Port) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Process) DeepCopyInto(out *Process) { + *out = *in + if in.MatchPaths != nil { + in, out := &in.MatchPaths, &out.MatchPaths + *out = make([]MatchPath, len(*in)) + copy(*out, *in) + } + if in.MatchDirectories != nil { + in, out := &in.MatchDirectories, &out.MatchDirectories + *out = make([]MatchDirectory, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MatchPatterns != nil { + in, out := &in.MatchPatterns, &out.MatchPatterns + *out = make([]MatchPattern, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Process. +func (in *Process) DeepCopy() *Process { + if in == nil { + return nil + } + out := new(Process) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Resource) DeepCopyInto(out *Resource) { + *out = *in + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = make([]Network, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Process != nil { + in, out := &in.Process, &out.Process + *out = make([]Process, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.File != nil { + in, out := &in.File, &out.File + *out = make([]File, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Capabilities != nil { + in, out := &in.Capabilities, &out.Capabilities + *out = make([]Capabilities, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Syscalls != nil { + in, out := &in.Syscalls, &out.Syscalls + *out = make([]Syscalls, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.FromCIDRSet != nil { + in, out := &in.FromCIDRSet, &out.FromCIDRSet + *out = make([]CIDRSet, len(*in)) + copy(*out, *in) + } + if in.ToPorts != nil { + in, out := &in.ToPorts, &out.ToPorts + *out = make([]ToPort, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resource. +func (in *Resource) DeepCopy() *Resource { + if in == nil { + return nil + } + out := new(Resource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceFilter) DeepCopyInto(out *ResourceFilter) { + *out = *in + in.Resources.DeepCopyInto(&out.Resources) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilter. +func (in *ResourceFilter) DeepCopy() *ResourceFilter { + if in == nil { + return nil + } + out := new(ResourceFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Resources) DeepCopyInto(out *Resources) { + *out = *in + if in.MatchLabels != nil { + in, out := &in.MatchLabels, &out.MatchLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources. +func (in *Resources) DeepCopy() *Resources { + if in == nil { + return nil + } + out := new(Resources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntent) DeepCopyInto(out *SecurityIntent) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntent. +func (in *SecurityIntent) DeepCopy() *SecurityIntent { + if in == nil { + return nil + } + out := new(SecurityIntent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SecurityIntent) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntentBinding) DeepCopyInto(out *SecurityIntentBinding) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentBinding. +func (in *SecurityIntentBinding) DeepCopy() *SecurityIntentBinding { + if in == nil { + return nil + } + out := new(SecurityIntentBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SecurityIntentBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntentBindingList) DeepCopyInto(out *SecurityIntentBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SecurityIntentBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentBindingList. +func (in *SecurityIntentBindingList) DeepCopy() *SecurityIntentBindingList { + if in == nil { + return nil + } + out := new(SecurityIntentBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SecurityIntentBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntentBindingSpec) DeepCopyInto(out *SecurityIntentBindingSpec) { + *out = *in + in.Selector.DeepCopyInto(&out.Selector) + if in.IntentRequests != nil { + in, out := &in.IntentRequests, &out.IntentRequests + *out = make([]IntentRequest, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentBindingSpec. +func (in *SecurityIntentBindingSpec) DeepCopy() *SecurityIntentBindingSpec { + if in == nil { + return nil + } + out := new(SecurityIntentBindingSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntentBindingStatus) DeepCopyInto(out *SecurityIntentBindingStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentBindingStatus. +func (in *SecurityIntentBindingStatus) DeepCopy() *SecurityIntentBindingStatus { + if in == nil { + return nil + } + out := new(SecurityIntentBindingStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntentList) DeepCopyInto(out *SecurityIntentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SecurityIntent, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentList. +func (in *SecurityIntentList) DeepCopy() *SecurityIntentList { + if in == nil { + return nil + } + out := new(SecurityIntentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SecurityIntentList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntentSpec) DeepCopyInto(out *SecurityIntentSpec) { + *out = *in + in.Intent.DeepCopyInto(&out.Intent) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentSpec. +func (in *SecurityIntentSpec) DeepCopy() *SecurityIntentSpec { + if in == nil { + return nil + } + out := new(SecurityIntentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecurityIntentStatus) DeepCopyInto(out *SecurityIntentStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentStatus. +func (in *SecurityIntentStatus) DeepCopy() *SecurityIntentStatus { + if in == nil { + return nil + } + out := new(SecurityIntentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Selector) DeepCopyInto(out *Selector) { + *out = *in + if in.Any != nil { + in, out := &in.Any, &out.Any + *out = make([]ResourceFilter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.All != nil { + in, out := &in.All, &out.All + *out = make([]ResourceFilter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CEL != nil { + in, out := &in.CEL, &out.CEL + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Selector. +func (in *Selector) DeepCopy() *Selector { + if in == nil { + return nil + } + out := new(Selector) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Syscalls) DeepCopyInto(out *Syscalls) { + *out = *in + if in.MatchSyscalls != nil { + in, out := &in.MatchSyscalls, &out.MatchSyscalls + *out = make([]MatchSyscall, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Syscalls. +func (in *Syscalls) DeepCopy() *Syscalls { + if in == nil { + return nil + } + out := new(Syscalls) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ToPort) DeepCopyInto(out *ToPort) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]Port, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ToPort. +func (in *ToPort) DeepCopy() *ToPort { + if in == nil { + return nil + } + out := new(ToPort) + in.DeepCopyInto(out) + return out +} diff --git a/Nimbus/bin/controller-gen b/Nimbus/bin/controller-gen new file mode 100755 index 00000000..bc357ab8 Binary files /dev/null and b/Nimbus/bin/controller-gen differ diff --git a/Nimbus/bin/kustomize b/Nimbus/bin/kustomize new file mode 100755 index 00000000..5b49fa5d Binary files /dev/null and b/Nimbus/bin/kustomize differ diff --git a/main.go b/Nimbus/cmd/main.go similarity index 64% rename from main.go rename to Nimbus/cmd/main.go index 2db3cd46..146e30e6 100644 --- a/main.go +++ b/Nimbus/cmd/main.go @@ -4,11 +4,15 @@ package main import ( + "context" "flag" "os" + "os/signal" + "syscall" + "time" - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. + // Importing all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can utilize them. _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/apimachinery/pkg/runtime" @@ -19,11 +23,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" - intentv1 "github.com/5GSEC/nimbus/api/v1" - "github.com/5GSEC/nimbus/controllers" - general "github.com/5GSEC/nimbus/controllers/general" - policy "github.com/5GSEC/nimbus/controllers/policy" + // Importing custom API types and controllers + intentv1 "github.com/5GSEC/nimbus/Nimbus/api/v1" + "github.com/5GSEC/nimbus/Nimbus/controllers" + cleanup "github.com/5GSEC/nimbus/Nimbus/controllers/cleanup" + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" + policy "github.com/5GSEC/nimbus/Nimbus/controllers/policy" + // Importing third-party Kubernetes resource types ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" //+kubebuilder:scaffold:imports @@ -40,14 +47,13 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(intentv1.AddToScheme(scheme)) - utilruntime.Must(kubearmorv1.AddToScheme(scheme)) utilruntime.Must(ciliumv2.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } func main() { - // Flags for the command line parameters like metrics address, leader election, etc. + // Flags for command line parameters such as metrics address, leader election, etc. var metricsAddr string var enableLeaderElection bool var probeAddr string @@ -86,14 +92,14 @@ func main() { // LeaderElectionReleaseOnCancel: true, }) if err != nil { - setupLog.Error(err, "unable to start manager") + setupLog.Error(err, "Unable to start manager") os.Exit(1) } // Setting up the GeneralController and PolicyController. generalController, err := general.NewGeneralController(mgr.GetClient()) if err != nil { - setupLog.Error(err, "unable to create GeneralController") + setupLog.Error(err, "Unable to create GeneralController") os.Exit(1) } @@ -104,27 +110,61 @@ func main() { Client: mgr.GetClient(), Scheme: mgr.GetScheme(), GeneralController: generalController, - PolicyController: policyController, }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "SecurityIntent") + setupLog.Error(err, "Unable to create controller", "controller", "SecurityIntent") os.Exit(1) } + if err = (&controllers.SecurityIntentBindingReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + GeneralController: generalController, + PolicyController: policyController, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "Unable to create controller", "controller", "SecurityIntentBinding") + os.Exit(1) + } //+kubebuilder:scaffold:builder + // Setting up health checks for the manager. if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up health check") + setupLog.Error(err, "Unable to set up health check") os.Exit(1) } if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - setupLog.Error(err, "unable to set up ready check") + setupLog.Error(err, "Unable to set up ready check") os.Exit(1) } - // Starting the manager. - setupLog.Info("starting manager") + // Creating channels for handling termination signals. + sigs := make(chan os.Signal, 1) + cleanupDone := make(chan bool) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + + // Separate goroutine to wait for termination signal. + go func() { + <-sigs // Waiting for termination signal + setupLog.Info("Received termination signal, performing cleanup...") + + // Calling the Cleanup function + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + err := cleanup.Cleanup(ctx, mgr.GetClient(), setupLog) + + if err != nil { + setupLog.Error(err, "Cleanup failed") + } + + cleanupDone <- true // Signaling cleanup completion + }() + + // Starting the manager + setupLog.Info("Starting manager") if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { - setupLog.Error(err, "problem running manager") + setupLog.Error(err, "Problem running manager") os.Exit(1) } + + <-cleanupDone // Waiting for cleanup completion + setupLog.Info("Cleanup completed") } diff --git a/Nimbus/controllers/cleanup/cleanup.go b/Nimbus/controllers/cleanup/cleanup.go new file mode 100644 index 00000000..501dd604 --- /dev/null +++ b/Nimbus/controllers/cleanup/cleanup.go @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package cleanup + +import ( + "context" + + "github.com/go-logr/logr" + "sigs.k8s.io/controller-runtime/pkg/client" + + intentv1 "github.com/5GSEC/nimbus/Nimbus/api/v1" + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" + policy "github.com/5GSEC/nimbus/Nimbus/controllers/policy" +) + +// Cleanup is a function to clean up SecurityIntent resources. +// It removes all policies associated with each SecurityIntent before deleting the SecurityIntent itself. +func Cleanup(ctx context.Context, k8sClient client.Client, logger logr.Logger) error { + + // Logging the start of the cleanup process. + logger.Info("Performing cleanup") + + var securityIntentBindings intentv1.SecurityIntentBindingList + if err := k8sClient.List(ctx, &securityIntentBindings); err != nil { + logger.Error(err, "Unable to list SecurityIntentBinding resources for cleanup") + return err + } + + if len(securityIntentBindings.Items) == 0 { + logger.Info("No SecurityIntentBinding resources found for cleanup") + return nil + } + + npc := policy.NewNetworkPolicyController(k8sClient, nil) + + // Iterating over each SecurityIntent to delete associated policies. + for _, binding := range securityIntentBindings.Items { + bindingCopy := binding + bindingInfo := &general.BindingInfo{ + Binding: &bindingCopy, + } + + // Deleting network policies associated with the current SecurityIntent. + if err := npc.DeletePolicy(ctx, bindingInfo); err != nil { + logger.Error(err, "Failed to delete network policy for SecurityIntentBinding", "Name", bindingCopy.Name) + return err + } + if err := k8sClient.Delete(ctx, &bindingCopy); err != nil { + logger.Error(err, "Failed to delete SecurityIntentBinding", "Name", bindingCopy.Name) + continue + } + } + return nil +} diff --git a/controllers/general/general_controller.go b/Nimbus/controllers/general/general_controller.go similarity index 52% rename from controllers/general/general_controller.go rename to Nimbus/controllers/general/general_controller.go index a188c2d4..ca28a2d1 100644 --- a/controllers/general/general_controller.go +++ b/Nimbus/controllers/general/general_controller.go @@ -9,14 +9,13 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - - intentv1 "github.com/5GSEC/nimbus/api/v1" ) // GeneralController is a struct that holds a Kubernetes client and a WatcherIntent. type GeneralController struct { - Client client.Client // Client is used to interact with the Kubernetes API. - WatcherIntent *WatcherIntent // WatcherIntent is a custom struct to manage specific operations. + Client client.Client // Client is used to interact with the Kubernetes API. + WatcherIntent *WatcherIntent // WatcherIntent is a custom struct to manage specific operations. + WatcherBinding *WatcherBinding // WatcherBinding is a custom struct to manage SecurityIntentBinding operations. } // NewGeneralController creates a new instance of GeneralController. @@ -33,31 +32,55 @@ func NewGeneralController(client client.Client) (*GeneralController, error) { return nil, fmt.Errorf("GeneralController: Error creating WatcherIntent: %v", err) } + // Create a new WatcherBinding. + watcherBinding, err := NewWatcherBinding(client) + if err != nil { + // If there is an error in creating WatcherBinding, return an error. + return nil, fmt.Errorf("GeneralController: Error creating WatcherBinding: %v", err) + } + // Return a new GeneralController instance with initialized fields. return &GeneralController{ - Client: client, - WatcherIntent: watcherIntent, + Client: client, + WatcherIntent: watcherIntent, + WatcherBinding: watcherBinding, }, nil } -// Reconcile is the method that will be called when there is an update to the resources being watched. -func (gc *GeneralController) Reconcile(ctx context.Context, req ctrl.Request) (*intentv1.SecurityIntent, error) { +func (gc *GeneralController) Reconcile(ctx context.Context, req ctrl.Request) (*BindingInfo, error) { if gc == nil { - // If the GeneralController instance is nil, return an error. return nil, fmt.Errorf("GeneralController is nil") } + if gc.WatcherIntent == nil { - // If the WatcherIntent is not set, return an error. return nil, fmt.Errorf("WatcherIntent is nil") } - // Call the Reconcile method of WatcherIntent to handle the specific logic. intent, err := gc.WatcherIntent.Reconcile(ctx, req) if err != nil { - // If there is an error in reconciliation, return the error. return nil, fmt.Errorf("Error in WatcherIntent.Reconcile: %v", err) } - // Return the intent and nil as error if reconciliation is successful. - return intent, nil + if intent != nil { + return nil, nil + } + + if gc.WatcherBinding == nil { + return nil, fmt.Errorf("WatcherBinding is nil") + } + + binding, err := gc.WatcherBinding.Reconcile(ctx, req) + if err != nil { + return nil, fmt.Errorf("Error in WatcherBinding.Reconcile: %v", err) + } + + if binding != nil { + bindingInfo, err := MatchIntentAndBinding(ctx, gc.Client, binding) + if err != nil { + return nil, fmt.Errorf("Error in MatchIntentAndBinding: %v", err) + } + return bindingInfo, nil + } + + return nil, nil } diff --git a/Nimbus/controllers/general/match_intent.go b/Nimbus/controllers/general/match_intent.go new file mode 100644 index 00000000..b2e1c899 --- /dev/null +++ b/Nimbus/controllers/general/match_intent.go @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package general + +import ( + "context" + "fmt" + + "sigs.k8s.io/controller-runtime/pkg/log" + + intentv1 "github.com/5GSEC/nimbus/Nimbus/api/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// BindingInfo holds the matching information between SecurityIntent and SecurityIntentBinding. +type BindingInfo struct { + Intent []*intentv1.SecurityIntent + Binding *intentv1.SecurityIntentBinding +} + +// MatchIntentAndBinding finds matching SecurityIntent for a given SecurityIntentBinding. +func MatchIntentAndBinding(ctx context.Context, client client.Client, binding *intentv1.SecurityIntentBinding) (*BindingInfo, error) { + log := log.FromContext(ctx) + + if client == nil { + return nil, fmt.Errorf("client is nil") + } + if binding == nil { + return nil, fmt.Errorf("SecurityIntentBinding is nil") + } + + var matchedIntents []*intentv1.SecurityIntent + for _, intentReq := range binding.Spec.IntentRequests { + intent := &intentv1.SecurityIntent{} + err := client.Get(ctx, types.NamespacedName{Name: intentReq.IntentName, Namespace: binding.Namespace}, intent) + if err != nil { + log.Error(err, "Failed to get SecurityIntent", "IntentName", intentReq.IntentName, "Namespace", binding.Namespace) + return nil, fmt.Errorf("Failed to get SecurityIntent '%s' in namespace '%s': %v", intentReq.IntentName, binding.Namespace, err) + } + matchedIntents = append(matchedIntents, intent) + } + + if len(matchedIntents) > 0 { + log.Info("Matched SecurityIntents for Binding", "BindingName", binding.Name) + } + return &BindingInfo{ + Intent: matchedIntents, + Binding: binding, + }, nil +} diff --git a/Nimbus/controllers/general/watch_binding.go b/Nimbus/controllers/general/watch_binding.go new file mode 100644 index 00000000..7e82a9e2 --- /dev/null +++ b/Nimbus/controllers/general/watch_binding.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package general + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + intentv1 "github.com/5GSEC/nimbus/Nimbus/api/v1" + "k8s.io/apimachinery/pkg/api/errors" +) + +// WatcherBinding is a struct that holds a Kubernetes client. +type WatcherBinding struct { + Client client.Client // Client to interact with Kubernetes resources. +} + +// NewWatcherBinding creates a new instance of WatcherBinding. +func NewWatcherBinding(client client.Client) (*WatcherBinding, error) { + if client == nil { + // Return an error if the client is not provided. + return nil, fmt.Errorf("WatcherBinding: Client is nil") + } + + // Return a new WatcherBinding instance with the provided client. + return &WatcherBinding{ + Client: client, + }, nil +} + +// Reconcile handles the reconciliation of the SecurityIntentBinding resources. +func (wb *WatcherBinding) Reconcile(ctx context.Context, req ctrl.Request) (*intentv1.SecurityIntentBinding, error) { + log := log.FromContext(ctx) + + if wb == nil || wb.Client == nil { + log.Info("WatcherBinding is nil or Client is nil in Reconcile") + return nil, fmt.Errorf("WatcherBinding or Client is not initialized") + } + + binding := &intentv1.SecurityIntentBinding{} + err := wb.Client.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, binding) + + if err != nil { + if errors.IsNotFound(err) { + log.Info("SecurityIntentBinding resource not found. Ignoring since object must be deleted", "Name", req.Name, "Namespace", req.Namespace) + return nil, nil + } + log.Error(err, "Failed to get SecurityIntentBinding", "Name", req.Name, "Namespace", req.Namespace) + return nil, err + } + return binding, nil +} diff --git a/controllers/general/watch_intent.go b/Nimbus/controllers/general/watch_intent.go similarity index 61% rename from controllers/general/watch_intent.go rename to Nimbus/controllers/general/watch_intent.go index ab6a207b..c5c302e9 100644 --- a/controllers/general/watch_intent.go +++ b/Nimbus/controllers/general/watch_intent.go @@ -12,7 +12,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - intentv1 "github.com/5GSEC/nimbus/api/v1" + intentv1 "github.com/5GSEC/nimbus/Nimbus/api/v1" "k8s.io/apimachinery/pkg/api/errors" ) @@ -36,32 +36,24 @@ func NewWatcherIntent(client client.Client) (*WatcherIntent, error) { // Reconcile is the method that handles the reconciliation of the Kubernetes resources. func (wi *WatcherIntent) Reconcile(ctx context.Context, req ctrl.Request) (*intentv1.SecurityIntent, error) { - log := log.FromContext(ctx) // Get the logger from the context. + log := log.FromContext(ctx) - // Check if WatcherIntent or its client is not initialized. if wi == nil || wi.Client == nil { - fmt.Println("WatcherIntent is nil or Client is nil in Reconcile") + log.Info("WatcherIntent is nil or Client is nil in Reconcile") return nil, fmt.Errorf("WatcherIntent or Client is not initialized") } - intent := &intentv1.SecurityIntent{} // Create an instance of SecurityIntent. - // Attempt to get the SecurityIntent resource from Kubernetes. - err := wi.Client.Get(ctx, types.NamespacedName{ - Name: req.Name, - Namespace: req.Namespace, - }, intent) + intent := &intentv1.SecurityIntent{} + err := wi.Client.Get(ctx, types.NamespacedName{Name: req.Name, Namespace: req.Namespace}, intent) - if err != nil { - // Handle the case where the SecurityIntent resource is not found. + if err == nil { + return intent, nil + } else { if errors.IsNotFound(err) { - log.Info("SecurityIntent resource not found. Ignoring since object must be deleted") + log.Info("SecurityIntent resource not found. Ignoring since object must be deleted", "Name", req.Name, "Namespace", req.Namespace) return nil, nil } - // Log and return an error if there is a problem getting the SecurityIntent. - log.Error(err, "Failed to get SecurityIntent") + log.Error(err, "Failed to get SecurityIntent", "Name", req.Name, "Namespace", req.Namespace) return nil, err } - - // Return the SecurityIntent instance if found successfully. - return intent, nil } diff --git a/Nimbus/controllers/policy/network_policy.go b/Nimbus/controllers/policy/network_policy.go new file mode 100644 index 00000000..391b5815 --- /dev/null +++ b/Nimbus/controllers/policy/network_policy.go @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package policy + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" + + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" + utils "github.com/5GSEC/nimbus/Nimbus/controllers/utils" +) + +// NetworkPolicyController struct to handle network policies. +type NetworkPolicyController struct { + Client client.Client // Client to interact with Kubernetes API. + Scheme *runtime.Scheme // Scheme defines the runtime scheme of the Kubernetes objects. +} + +// NewNetworkPolicyController creates a new instance of NetworkPolicyController. +func NewNetworkPolicyController(client client.Client, scheme *runtime.Scheme) *NetworkPolicyController { + return &NetworkPolicyController{ + Client: client, + Scheme: scheme, + } +} + +// HandlePolicy processes the network policies defined in the SecurityIntent resource. +func (npc *NetworkPolicyController) HandlePolicy(ctx context.Context, bindingInfo *general.BindingInfo) error { + log := log.FromContext(ctx) + log.Info("Handling Network Policy", "BindingName", bindingInfo.Binding.Name) + + // Build and apply/update Cilium Network Policy based on BindingInfo. + ciliumPolicySpec := utils.BuildCiliumNetworkPolicySpec(ctx, bindingInfo).(*ciliumv2.CiliumNetworkPolicy) + err := utils.ApplyOrUpdatePolicy(ctx, npc.Client, ciliumPolicySpec, bindingInfo.Binding.Name) + if err != nil { + log.Error(err, "Failed to apply Cilium Network Policy", "Name", bindingInfo.Binding.Name) + return err + } + + log.Info("Applied Network Policy", "PolicyName", bindingInfo.Binding.Name) + return nil +} + +// DeletePolicy removes the network policy associated with the SecurityIntent resource. +func (npc *NetworkPolicyController) DeletePolicy(ctx context.Context, bindingInfo *general.BindingInfo) error { + log := log.FromContext(ctx) + + // Modified line: Merged variable declaration with assignment + err := utils.DeletePolicy(ctx, npc.Client, "CiliumNetworkPolicy", bindingInfo.Binding.Name, bindingInfo.Binding.Namespace) + if err != nil { + log.Error(err, "Failed to delete Cilium Network Policy", "Name", bindingInfo.Binding.Name) + return err + } + + log.Info("Deleted Network Policy", "PolicyName", bindingInfo.Binding.Name) + return nil +} diff --git a/Nimbus/controllers/policy/policy_controller.go b/Nimbus/controllers/policy/policy_controller.go new file mode 100644 index 00000000..38c00183 --- /dev/null +++ b/Nimbus/controllers/policy/policy_controller.go @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package policy + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" +) + +// Constant for the finalizer name used in the SecurityIntent resource. +// const securityIntentFinalizer = "finalizer.securityintent.intent.security.nimbus.com" + +// PolicyController struct handles different types of policies. +type PolicyController struct { + Client client.Client // Client for interacting with Kubernetes API. + Scheme *runtime.Scheme // Scheme defines the runtime scheme of the Kubernetes objects. + NetworkPolicyController *NetworkPolicyController // Controller for handling network policies. + SystemPolicyController *SystemPolicyController // Controller for handling system policies. +} + +// NewPolicyController creates a new instance of PolicyController. +func NewPolicyController(client client.Client, scheme *runtime.Scheme) *PolicyController { + if client == nil || scheme == nil { + fmt.Println("PolicyController: Client or Scheme is nil") + return nil + } + + return &PolicyController{ + Client: client, + Scheme: scheme, + NetworkPolicyController: NewNetworkPolicyController(client, scheme), + SystemPolicyController: NewSystemPolicyController(client, scheme), + } +} + +// Reconcile handles the reconciliation logic for the SecurityIntent and SecurityIntentBinding resources. +func (pc *PolicyController) Reconcile(ctx context.Context, bindingInfo *general.BindingInfo) error { + log := log.FromContext(ctx) + + var intentRequestType string + if len(bindingInfo.Binding.Spec.IntentRequests) > 0 { + intentRequestType = bindingInfo.Binding.Spec.IntentRequests[0].Type + } + + log.Info("Processing policy", "BindingName", bindingInfo.Binding.Name, "IntentType", intentRequestType) + + var err error + switch intentRequestType { + case "network": + err = pc.NetworkPolicyController.HandlePolicy(ctx, bindingInfo) + if err != nil { + log.Error(err, "Failed to apply network policy", "BindingName", bindingInfo.Binding.Name) + return err + } + case "system": + err = pc.SystemPolicyController.HandlePolicy(ctx, bindingInfo) + if err != nil { + log.Error(err, "Failed to apply system policy", "BindingName", bindingInfo.Binding.Name) + return err + } + default: + err = fmt.Errorf("unknown policy type: %s", intentRequestType) + log.Error(err, "Unknown policy type", "Type", intentRequestType) + return err + } + if err != nil { + log.Error(err, "Failed to apply policy", "BindingName", bindingInfo.Binding.Name) + return err + } + + return nil +} diff --git a/Nimbus/controllers/policy/system_policy.go b/Nimbus/controllers/policy/system_policy.go new file mode 100644 index 00000000..d98cdc76 --- /dev/null +++ b/Nimbus/controllers/policy/system_policy.go @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package policy + +import ( + "context" + + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" + utils "github.com/5GSEC/nimbus/Nimbus/controllers/utils" +) + +// SystemPolicyController is a struct to handle system policies. +type SystemPolicyController struct { + Client client.Client // Client for interacting with Kubernetes API. + Scheme *runtime.Scheme // Scheme defines the runtime scheme of the Kubernetes objects. +} + +// NewSystemPolicyController creates a new instance of SystemPolicyController. +func NewSystemPolicyController(client client.Client, scheme *runtime.Scheme) *SystemPolicyController { + return &SystemPolicyController{ + Client: client, + Scheme: scheme, + } +} + +// HandlePolicy processes the system policy as defined in SecurityIntent. +func (spc *SystemPolicyController) HandlePolicy(ctx context.Context, bindingInfo *general.BindingInfo) error { + log := log.FromContext(ctx) // Logger with context. + log.Info("Handling System Policy", "BindingName", bindingInfo.Binding.Name) + + // Build KubeArmorPolicy based on BindingInfo + kubearmorPolicy := utils.BuildKubeArmorPolicySpec(ctx, bindingInfo) + + err := utils.ApplyOrUpdatePolicy(ctx, spc.Client, kubearmorPolicy, bindingInfo.Binding.Name) + if err != nil { + log.Error(err, "Failed to apply KubeArmorPolicy", "Name", bindingInfo.Binding.Name) + return err + } + + log.Info("Applied KubeArmorPolicy", "PolicyName", bindingInfo.Binding.Name) + return nil +} + +// DeletePolicy removes the system policy associated with the SecurityIntent resource. +func (spc *SystemPolicyController) DeletePolicy(ctx context.Context, bindingInfo *general.BindingInfo) error { + log := log.FromContext(ctx) + + // Delete KubeArmor Policy + err := utils.DeletePolicy(ctx, spc.Client, "KubeArmorPolicy", bindingInfo.Binding.Name, bindingInfo.Binding.Namespace) + if err != nil { + log.Error(err, "Failed to delete KubeArmor Policy", "Name", bindingInfo.Binding.Name) + return err + } + + log.Info("Deleted System Policy", "PolicyName", bindingInfo.Binding.Name) + return nil +} diff --git a/controllers/securityintent_controller.go b/Nimbus/controllers/securityintent_controller.go similarity index 60% rename from controllers/securityintent_controller.go rename to Nimbus/controllers/securityintent_controller.go index c6008ee1..e87cb8cd 100644 --- a/controllers/securityintent_controller.go +++ b/Nimbus/controllers/securityintent_controller.go @@ -10,48 +10,35 @@ import ( "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/5GSEC/nimbus/api/v1" - general "github.com/5GSEC/nimbus/controllers/general" - policy "github.com/5GSEC/nimbus/controllers/policy" + "github.com/5GSEC/nimbus/Nimbus/api/v1" + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" ) -// SecurityIntentReconciler reconciles a SecurityIntent object. type SecurityIntentReconciler struct { client.Client - Scheme *runtime.Scheme // Scheme defines the runtime scheme of the Kubernetes objects. - GeneralController *general.GeneralController // GeneralController is a custom controller for general operations. - PolicyController *policy.PolicyController // PolicyController is a custom controller for policy operations. + Scheme *runtime.Scheme + GeneralController *general.GeneralController } // NewSecurityIntentReconciler creates a new SecurityIntentReconciler. func NewSecurityIntentReconciler(client client.Client, scheme *runtime.Scheme) *SecurityIntentReconciler { - // Check if the client is nil. if client == nil { fmt.Println("SecurityIntentReconciler: Client is nil") return nil } - // Initialize GeneralController; if failed, return nil. generalController, err := general.NewGeneralController(client) - if err != nil || generalController == nil { // Check if generalController is nil. + if err != nil { fmt.Println("SecurityIntentReconciler: Failed to initialize GeneralController:", err) return nil } - // Initialize PolicyController; if failed, return nil. - policyController := policy.NewPolicyController(client, scheme) - if policyController == nil { - fmt.Println("SecurityIntentReconciler: Failed to initialize PolicyController") - return nil - } - - // Return a new instance of SecurityIntentReconciler. return &SecurityIntentReconciler{ Client: client, Scheme: scheme, GeneralController: generalController, - PolicyController: policyController, } } @@ -71,30 +58,23 @@ func NewSecurityIntentReconciler(client client.Client, scheme *runtime.Scheme) * // Reconcile handles the reconciliation of the SecurityIntent resources. func (r *SecurityIntentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - // Check if GeneralController or its components are properly initialized. + log := log.FromContext(ctx) + if r.GeneralController == nil { fmt.Println("SecurityIntentReconciler: GeneralController is nil") return ctrl.Result{}, fmt.Errorf("GeneralController is not properly initialized") } - if r.GeneralController.WatcherIntent == nil { - fmt.Println("SecurityIntentReconciler: WatcherIntent is nil") - return ctrl.Result{}, fmt.Errorf("WatcherIntent is not properly initialized") - } - // Perform Reconcile logic regardless of the state of GeneralController and WatcherIntent. - intent, err := r.GeneralController.Reconcile(ctx, req) + intent, err := r.GeneralController.WatcherIntent.Reconcile(ctx, req) if err != nil { + log.Error(err, "Error in WatcherIntent.Reconcile", "Request", req.NamespacedName) return ctrl.Result{}, err } - if intent == nil { - return ctrl.Result{}, nil - } - - // Invoke the PolicyController's Reconcile method with the intent. - err = r.PolicyController.Reconcile(ctx, intent) - if err != nil { - return ctrl.Result{}, err + if intent != nil { + log.Info("SecurityIntent resource found", "Name", req.Name, "Namespace", req.Namespace) + } else { + log.Info("SecurityIntent resource not found", "Name", req.Name, "Namespace", req.Namespace) } return ctrl.Result{}, nil diff --git a/Nimbus/controllers/securityintentbinding_controller.go b/Nimbus/controllers/securityintentbinding_controller.go new file mode 100644 index 00000000..8e6ccc5e --- /dev/null +++ b/Nimbus/controllers/securityintentbinding_controller.go @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package controllers + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + intentv1 "github.com/5GSEC/nimbus/Nimbus/api/v1" + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" + policy "github.com/5GSEC/nimbus/Nimbus/controllers/policy" +) + +// SecurityIntentBindingReconciler reconciles a SecurityIntentBinding object +type SecurityIntentBindingReconciler struct { + client.Client + Scheme *runtime.Scheme + GeneralController *general.GeneralController + PolicyController *policy.PolicyController +} + +func NewSecurityIntentBindingReconciler(client client.Client, scheme *runtime.Scheme) *SecurityIntentBindingReconciler { + if client == nil { + fmt.Println("SecurityIntentBindingReconciler: Client is nil") + return nil + } + + generalController, err := general.NewGeneralController(client) + if err != nil { + fmt.Println("SecurityIntentBindingReconciler: Failed to initialize GeneralController:", err) + return nil + } + + policyController := policy.NewPolicyController(client, scheme) + if policyController == nil { + fmt.Println("SecurityIntentBindingReconciler: Failed to initialize PolicyController") + return nil + } + + return &SecurityIntentBindingReconciler{ + Client: client, + Scheme: scheme, + GeneralController: generalController, + PolicyController: policyController, + } +} + +//+kubebuilder:rbac:groups=intent.security.nimbus.com,resources=securityintentbindings,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=intent.security.nimbus.com,resources=securityintentbindings/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=intent.security.nimbus.com,resources=securityintentbindings/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the SecurityIntentBinding object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.3/pkg/reconcile + +func (r *SecurityIntentBindingReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + log := log.FromContext(ctx) + + if r.GeneralController == nil || r.GeneralController.WatcherBinding == nil { + fmt.Println("SecurityIntentBindingReconciler: GeneralController or WatcherBinding is not initialized") + return ctrl.Result{}, fmt.Errorf("GeneralController or WatcherBinding is not initialized") + } + + binding, err := r.GeneralController.WatcherBinding.Reconcile(ctx, req) + if err != nil { + return ctrl.Result{}, fmt.Errorf("Error in WatcherBinding.Reconcile: %v", err) + } + + if binding != nil { + log.Info("SecurityIntentBinding resource found", "Name", req.Name, "Namespace", req.Namespace) + + bindingInfo, err := general.MatchIntentAndBinding(ctx, r.Client, binding) + if err != nil { + log.Error(err, "Failed to match SecurityIntent with SecurityIntentBinding", "BindingName", binding.Name) + return ctrl.Result{}, err + } + + if bindingInfo != nil { + err = r.PolicyController.Reconcile(ctx, bindingInfo) + if err != nil { + log.Error(err, "Failed to apply policy for SecurityIntentBinding", "BindingName", binding.Name) + return ctrl.Result{}, err + } + } else { + log.Info("No matching SecurityIntent found for SecurityIntentBinding", "BindingName", binding.Name) + } + } else { + log.Info("SecurityIntentBinding resource not found", "Name", req.Name, "Namespace", req.Namespace) + } + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *SecurityIntentBindingReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&intentv1.SecurityIntentBinding{}). + Complete(r) +} diff --git a/controllers/suite_test.go b/Nimbus/controllers/suite_test.go similarity index 98% rename from controllers/suite_test.go rename to Nimbus/controllers/suite_test.go index 846d176e..9a0874a7 100644 --- a/controllers/suite_test.go +++ b/Nimbus/controllers/suite_test.go @@ -19,7 +19,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - intentv1 "github.com/5GSEC/nimbus/api/v1" + intentv1 "github.com/5GSEC/nimbus/Nimbus/api/v1" //+kubebuilder:scaffold:imports ) diff --git a/Nimbus/controllers/utils/utils_policy.go b/Nimbus/controllers/utils/utils_policy.go new file mode 100644 index 00000000..7ecdbac7 --- /dev/null +++ b/Nimbus/controllers/utils/utils_policy.go @@ -0,0 +1,415 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Authors of Nimbus + +package utils + +import ( + "context" + "fmt" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" + "reflect" + "strings" + + general "github.com/5GSEC/nimbus/Nimbus/controllers/general" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + client "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" + "github.com/cilium/cilium/pkg/policy/api" + kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" +) + +// --------------------------------------------------- +// -------- Creation of Policy Specifications -------- +// --------------------------------------------------- + +// BuildKubeArmorPolicySpec creates a policy specification (either KubeArmorPolicy or KubeArmorHostPolicy) +// based on the provided SecurityIntent and the type of policy. +// BuildKubeArmorPolicySpec creates a KubeArmor policy specification based on the provided SecurityIntentBinding. +func BuildKubeArmorPolicySpec(ctx context.Context, bindingInfo *general.BindingInfo) *kubearmorv1.KubeArmorPolicy { + log := log.FromContext(ctx) + log.Info("Creating KubeArmorPolicy", "BindingName", bindingInfo.Binding.Name) + + intent := bindingInfo.Intent[0] + + return &kubearmorv1.KubeArmorPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: bindingInfo.Binding.Name, + Namespace: bindingInfo.Binding.Namespace, + }, + Spec: kubearmorv1.KubeArmorPolicySpec{ + Selector: kubearmorv1.SelectorType{ + MatchLabels: extractMatchLabels(bindingInfo), + }, + Process: extractToKubeArmorPolicyProcessType(bindingInfo), + File: extractToKubeArmorPolicyFileType(bindingInfo), + Capabilities: extractToKubeArmorPolicyCapabilitiesType(bindingInfo), + Network: extractToKubeArmorPolicyNetworkType(bindingInfo), + // TODO: To discuss + //Network: convertToKubeArmorHostPolicyNetworkType(extractNetworkPolicy(intent)), + Action: kubearmorv1.ActionType(intent.Spec.Intent.Action), + }, + } +} + +// BuildCiliumNetworkPolicySpec creates a Cilium network policy specification based on the provided BindingInfo. +func BuildCiliumNetworkPolicySpec(ctx context.Context, bindingInfo *general.BindingInfo) interface{} { + log := log.FromContext(ctx) + log.Info("Creating CiliumNetworkPolicy", "Name", bindingInfo.Binding.Name) + + endpointSelector := getEndpointSelector(ctx, bindingInfo) + ingressDenyRules := getIngressDenyRules(bindingInfo) + + policy := &ciliumv2.CiliumNetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: bindingInfo.Binding.Name, + Namespace: bindingInfo.Binding.Namespace, + }, + Spec: &api.Rule{ + EndpointSelector: endpointSelector, + IngressDeny: ingressDenyRules, + }, + } + return policy +} + +// TODO: To discuss +//func convertToKubeArmorHostPolicyNetworkType(slice []interface{}) kubearmorv1.MatchHostNetworkProtocolType { +// var result kubearmorv1.MatchHostNetworkProtocolType +// for _, item := range slice { +// str, ok := item.(string) +// if !ok { +// continue // or appropriate error handling +// } +// // Requires explicit type conversion to MatchNetworkProtocolStringType +// protocol := kubearmorv1.MatchNetworkProtocolStringType(str) +// result.MatchProtocols = append(result.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{ +// Protocol: protocol, +// }) +// } +// return result +//} + +// -------------------------------------- +// -------- Utility Functions ---------- +// -------------------------------------- + +// extractMatchLabelsFromBinding extracts matchLabels from the SecurityIntentBinding. +func extractMatchLabels(bindingInfo *general.BindingInfo) map[string]string { + matchLabels := make(map[string]string) + for _, filter := range bindingInfo.Binding.Spec.Selector.Any { + for key, val := range filter.Resources.MatchLabels { + matchLabels[key] = val + } + } + + for _, filter := range bindingInfo.Binding.Spec.Selector.All { + for key, val := range filter.Resources.MatchLabels { + matchLabels[key] = val + } + } + + // Remove 'any:', 'all:', 'cel:' prefixes from the keys + processedLabels := make(map[string]string) + for key, val := range matchLabels { + processedKey := removeReservedPrefixes(key) + processedLabels[processedKey] = val + } + + return processedLabels +} + +func extractToKubeArmorPolicyProcessType(bindingInfo *general.BindingInfo) kubearmorv1.ProcessType { + intent := bindingInfo.Intent[0] + + var processType kubearmorv1.ProcessType + for _, resource := range intent.Spec.Intent.Resource { + for _, process := range resource.Process { + for _, match := range process.MatchPaths { + if path := match.Path; path != "" && strings.HasPrefix(path, "/") { + processType.MatchPaths = append(processType.MatchPaths, kubearmorv1.ProcessPathType{ + Path: kubearmorv1.MatchPathType(path), + }) + } + } + for _, dir := range process.MatchDirectories { + var fromSources []kubearmorv1.MatchSourceType + for _, source := range dir.FromSource { + fromSources = append(fromSources, kubearmorv1.MatchSourceType{ + Path: kubearmorv1.MatchPathType(source.Path), + }) + } + if dir.Directory != "" || len(fromSources) > 0 { + processType.MatchDirectories = append(processType.MatchDirectories, kubearmorv1.ProcessDirectoryType{ // Adjusted type here + Directory: kubearmorv1.MatchDirectoryType(dir.Directory), + FromSource: fromSources, + }) + } + } + for _, pattern := range process.MatchPatterns { + if pattern.Pattern != "" { + processType.MatchPatterns = append(processType.MatchPatterns, kubearmorv1.ProcessPatternType{ + Pattern: pattern.Pattern, + }) + } + } + } + } + return processType +} + +func extractToKubeArmorPolicyFileType(bindingInfo *general.BindingInfo) kubearmorv1.FileType { + intent := bindingInfo.Intent[0] + + var fileType kubearmorv1.FileType + + for _, resource := range intent.Spec.Intent.Resource { + for _, file := range resource.File { + for _, path := range file.MatchPaths { + if path.Path != "" { + fileType.MatchPaths = append(fileType.MatchPaths, kubearmorv1.FilePathType{ + Path: kubearmorv1.MatchPathType(path.Path), + }) + } + } + + for _, dir := range file.MatchDirectories { + var fromSources []kubearmorv1.MatchSourceType + for _, source := range dir.FromSource { + fromSources = append(fromSources, kubearmorv1.MatchSourceType{ + Path: kubearmorv1.MatchPathType(source.Path), + }) + } + if dir.Directory != "" || len(fromSources) > 0 { + fileType.MatchDirectories = append(fileType.MatchDirectories, kubearmorv1.FileDirectoryType{ + Directory: kubearmorv1.MatchDirectoryType(dir.Directory), + FromSource: fromSources, + }) + } + } + } + } + + return fileType +} + +func extractToKubeArmorPolicyCapabilitiesType(bindingInfo *general.BindingInfo) kubearmorv1.CapabilitiesType { + var capabilitiesType kubearmorv1.CapabilitiesType + intent := bindingInfo.Intent[0] + + if len(intent.Spec.Intent.Resource) > 0 && len(intent.Spec.Intent.Resource[0].Capabilities) > 0 { + for _, capability := range intent.Spec.Intent.Resource[0].Capabilities { + for _, matchCapability := range capability.MatchCapabilities { + if matchCapability.Capability != "" { + capabilitiesType.MatchCapabilities = append(capabilitiesType.MatchCapabilities, kubearmorv1.MatchCapabilitiesType{ + Capability: kubearmorv1.MatchCapabilitiesStringType(matchCapability.Capability), + }) + } + } + } + } else { + capabilitiesType.MatchCapabilities = append(capabilitiesType.MatchCapabilities, kubearmorv1.MatchCapabilitiesType{ + Capability: "lease", + }) + } + return capabilitiesType +} + +func extractToKubeArmorPolicyNetworkType(bindingInfo *general.BindingInfo) kubearmorv1.NetworkType { + var networkType kubearmorv1.NetworkType + intent := bindingInfo.Intent[0] + + if len(intent.Spec.Intent.Resource) > 0 && len(intent.Spec.Intent.Resource[0].Network) > 0 { + for _, network := range intent.Spec.Intent.Resource[0].Network { + for _, matchProtocol := range network.MatchProtocols { + if matchProtocol.Protocol != "" { + networkType.MatchProtocols = append(networkType.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{ + Protocol: kubearmorv1.MatchNetworkProtocolStringType(matchProtocol.Protocol), + }) + } + } + } + } else { + networkType.MatchProtocols = append(networkType.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{ + Protocol: "raw", + }) + } + return networkType +} + +// getEndpointSelector creates an endpoint selector from the SecurityIntent. +func getEndpointSelector(ctx context.Context, bindingInfo *general.BindingInfo) api.EndpointSelector { + + matchLabels := make(map[string]string) + /// Extract matched labels from BindingInfo + for _, filter := range bindingInfo.Binding.Spec.Selector.Any { + for key, val := range filter.Resources.MatchLabels { + matchLabels[key] = val + } + } + + for _, filter := range bindingInfo.Binding.Spec.Selector.All { + for key, val := range filter.Resources.MatchLabels { + matchLabels[key] = val + } + } + + processedLabels := make(map[string]string) + for key, val := range matchLabels { + processedKey := removeReservedPrefixes(key) + processedLabels[processedKey] = val + } + + // Create an Endpoint Selector based on processed labels + return api.NewESFromMatchRequirements(processedLabels, nil) +} + +func removeReservedPrefixes(key string) string { + for _, prefix := range []string{"any:", "all:", "cel:"} { + for strings.HasPrefix(key, prefix) { + key = strings.TrimPrefix(key, prefix) + } + } + return strings.TrimSpace(key) +} + +// getIngressDenyRules generates ingress deny rules from SecurityIntent specified in BindingInfo. +func getIngressDenyRules(bindingInfo *general.BindingInfo) []api.IngressDenyRule { + intent := bindingInfo.Intent[0] + + var ingressDenyRules []api.IngressDenyRule + + for _, resource := range intent.Spec.Intent.Resource { + ingressRule := api.IngressDenyRule{} + + for _, cidrSet := range resource.FromCIDRSet { + ingressRule.FromCIDRSet = append(ingressRule.FromCIDRSet, api.CIDRRule{ + Cidr: api.CIDR(cidrSet.CIDR), + }) + } + + for _, toPort := range resource.ToPorts { + var ports []api.PortProtocol + for _, port := range toPort.Ports { + ports = append(ports, api.PortProtocol{ + Port: port.Port, + Protocol: parseProtocol(port.Protocol), + }) + } + ingressRule.ToPorts = api.PortDenyRules{ + { + Ports: ports, + }, + } + } + + ingressDenyRules = append(ingressDenyRules, ingressRule) + } + + return ingressDenyRules +} + +func parseProtocol(protocol string) api.L4Proto { + // Convert protocol string to L4Proto type. + switch strings.ToUpper(protocol) { + case "TCP": + return api.ProtoTCP + case "UDP": + return api.ProtoUDP + case "ICMP": + return api.ProtoICMP + default: + return api.ProtoTCP + } +} + +// ---------------------------------------- +// -------- Apply & Update Policy -------- +// ---------------------------------------- + +// ApplyOrUpdatePolicy applies or updates the given policy. +func ApplyOrUpdatePolicy(ctx context.Context, c client.Client, policy client.Object, policyName string) error { + // Update the policy if it already exists, otherwise create a new one. + log := log.FromContext(ctx) + + var existingPolicy client.Object + var policySpec interface{} + + switch p := policy.(type) { + case *kubearmorv1.KubeArmorPolicy: + existingPolicy = &kubearmorv1.KubeArmorPolicy{} + policySpec = p.Spec + case *kubearmorv1.KubeArmorHostPolicy: + existingPolicy = &kubearmorv1.KubeArmorHostPolicy{} + policySpec = p.Spec + case *ciliumv2.CiliumNetworkPolicy: + existingPolicy = &ciliumv2.CiliumNetworkPolicy{} + policySpec = p.Spec + default: + return fmt.Errorf("unsupported policy type") + } + + err := c.Get(ctx, types.NamespacedName{Name: policyName, Namespace: policy.GetNamespace()}, existingPolicy) + if err != nil && !errors.IsNotFound(err) { + // Other error handling + log.Error(err, "Failed to get existing policy", "policy", policyName) + return err + } + + if errors.IsNotFound(err) { + // Create a policy if it doesn't exist + if err := c.Create(ctx, policy); err != nil { + log.Error(err, "Failed to apply policy", "policy", policyName) + return err + } + log.Info("Policy created", "Name", policyName) + } else { + // Update if policy already exists (compares specs only) + existingSpec := reflect.ValueOf(existingPolicy).Elem().FieldByName("Spec").Interface() + if !reflect.DeepEqual(policySpec, existingSpec) { + reflect.ValueOf(existingPolicy).Elem().FieldByName("Spec").Set(reflect.ValueOf(policySpec)) + if err := c.Update(ctx, existingPolicy); err != nil { + log.Error(err, "Failed to update policy", "policy", policyName) + return err + } + log.Info("Policy updated", "Name", policyName) + } else { + log.Info("Policy unchanged", "Name", policyName) + } + } + return nil +} + +// ---------------------------------------- +// ----------- Delete Policy ------------- +// ---------------------------------------- + +// DeletePolicy deletes a policy based on type, name, and namespace. +func DeletePolicy(ctx context.Context, c client.Client, policyType, name, namespace string) error { + // Process the deletion request based on policy type. + + var policy client.Object + log := log.FromContext(ctx) + + switch policyType { + case "KubeArmorPolicy": + policy = &kubearmorv1.KubeArmorPolicy{} + case "KubeArmorHostPolicy": + policy = &kubearmorv1.KubeArmorHostPolicy{} + case "CiliumNetworkPolicy": + policy = &ciliumv2.CiliumNetworkPolicy{} + default: + return fmt.Errorf("Unknown policy type: %s", policyType) + } + + policy.SetName(name) + policy.SetNamespace(namespace) + + if err := c.Delete(ctx, policy); client.IgnoreNotFound(err) != nil { + log.Error(err, "Failed to delete policy", "Type", policyType, "Name", name, "Namespace", namespace) + return err + } + return nil +} diff --git a/hack/boilerplate.go.txt b/Nimbus/hack/boilerplate.go.txt similarity index 100% rename from hack/boilerplate.go.txt rename to Nimbus/hack/boilerplate.go.txt diff --git a/api/v1/securityintent_types.go b/api/v1/securityintent_types.go deleted file mode 100644 index 7938246f..00000000 --- a/api/v1/securityintent_types.go +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2023 Authors of Nimbus - -package v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -// SecurityIntentSpec defines the desired state of SecurityIntent -type SecurityIntentSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - Selector Selector `json:"selector"` // Define criteria for selecting resources - Intent Intent `json:"intent"` // Define the details of the security policy. -} - -// Selector defines the selection criteria for resources -type Selector struct { - Match Match `json:"match,omitempty"` // Define the resource filter to be used - CEL []string `json:"cel"` // Define filter conditions as CEL expressions -} - -// Match defines the resource filters to be used -type Match struct { - Any []ResourceFilter `json:"any,omitempty"` // Apply when one or more conditions match - All []ResourceFilter `json:"all,omitempty"` //Apply when all conditions must match -} - -// ResourceFilter is used for filtering resources, subjects, roles, and cluster roles -type ResourceFilter struct { - Resources Resources `json:"resources,omitempty"` // Define properties to select k8s resources - Subjects []Subject `json:"subjects,omitempty"` // Define the subjects to filter - Roles []string `json:"roles,omitempty"` // Define the roles to filter. -} - -// Resources defines the properties for selecting Kubernetes resources -type Resources struct { - Names []string `json:"names,omitempty"` // Define the resource name - Namespaces []string `json:"namespaces,omitempty"` // Define the namespaces to which the resource belongs - Kinds []string `json:"kinds"` // Define resource kinds - Operations []string `json:"operations,omitempty"` // Define operations for the resource - - MatchLabels map[string]string `json:"matchLabels,omitempty"` // Define labels to apply to the resource -} - -// Subject defines the subject for filtering -type Subject struct { - Kind string `json:"kind"` // Define the kind of policy - Name string `json:"name,omitempty"` // Define the name of the policy -} - -// Intent defines the security policy details -type Intent struct { - Action string `json:"action"` // Define the action of the policy - Mode string `json:"mode"` // Defines the mode of the policy - Type string `json:"type"` // Defines the type of the policy - Resource []Resource `json:"resource"` // Define the resource to which the security policy applies -} - -// Resource defines the resources that the security policy applies to -type Resource struct { - Key string `json:"key,omitempty"` // Define a resource key - Val []string `json:"val,omitempty"` // Define a resource value list - Valcel string `json:"valcel,omitempty"` // Define a CEL expression - Attrs []string `json:"attrs,omitempty"` // Define additional attributes -} - -// SecurityIntentStatus defines the observed state of SecurityIntent -type SecurityIntentStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file - // This field can be updated to reflect the actual status of the application of the security intents -} - -// SecurityIntent is the Schema for the securityintents API -// +kubebuilder:object:root=true -// +kubebuilder:subresource:status -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// SecurityIntent is the Schema for the securityintents API -type SecurityIntent struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - Spec SecurityIntentSpec `json:"spec,omitempty"` - Status SecurityIntentStatus `json:"status,omitempty"` -} - -//+kubebuilder:object:root=true - -// SecurityIntentList contains a list of SecurityIntent -type SecurityIntentList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []SecurityIntent `json:"items"` -} - -func init() { - SchemeBuilder.Register(&SecurityIntent{}, &SecurityIntentList{}) -} diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go deleted file mode 100644 index 875d649d..00000000 --- a/api/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,283 +0,0 @@ -//go:build !ignore_autogenerated - -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2023 Authors of Nimbus - -// Code generated by controller-gen. DO NOT EDIT. - -package v1 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Intent) DeepCopyInto(out *Intent) { - *out = *in - if in.Resource != nil { - in, out := &in.Resource, &out.Resource - *out = make([]Resource, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Intent. -func (in *Intent) DeepCopy() *Intent { - if in == nil { - return nil - } - out := new(Intent) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Match) DeepCopyInto(out *Match) { - *out = *in - if in.Any != nil { - in, out := &in.Any, &out.Any - *out = make([]ResourceFilter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.All != nil { - in, out := &in.All, &out.All - *out = make([]ResourceFilter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Match. -func (in *Match) DeepCopy() *Match { - if in == nil { - return nil - } - out := new(Match) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Resource) DeepCopyInto(out *Resource) { - *out = *in - if in.Val != nil { - in, out := &in.Val, &out.Val - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Attrs != nil { - in, out := &in.Attrs, &out.Attrs - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resource. -func (in *Resource) DeepCopy() *Resource { - if in == nil { - return nil - } - out := new(Resource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceFilter) DeepCopyInto(out *ResourceFilter) { - *out = *in - in.Resources.DeepCopyInto(&out.Resources) - if in.Subjects != nil { - in, out := &in.Subjects, &out.Subjects - *out = make([]Subject, len(*in)) - copy(*out, *in) - } - if in.Roles != nil { - in, out := &in.Roles, &out.Roles - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceFilter. -func (in *ResourceFilter) DeepCopy() *ResourceFilter { - if in == nil { - return nil - } - out := new(ResourceFilter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Resources) DeepCopyInto(out *Resources) { - *out = *in - if in.Names != nil { - in, out := &in.Names, &out.Names - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Namespaces != nil { - in, out := &in.Namespaces, &out.Namespaces - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Kinds != nil { - in, out := &in.Kinds, &out.Kinds - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Operations != nil { - in, out := &in.Operations, &out.Operations - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.MatchLabels != nil { - in, out := &in.MatchLabels, &out.MatchLabels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources. -func (in *Resources) DeepCopy() *Resources { - if in == nil { - return nil - } - out := new(Resources) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecurityIntent) DeepCopyInto(out *SecurityIntent) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntent. -func (in *SecurityIntent) DeepCopy() *SecurityIntent { - if in == nil { - return nil - } - out := new(SecurityIntent) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *SecurityIntent) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecurityIntentList) DeepCopyInto(out *SecurityIntentList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]SecurityIntent, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentList. -func (in *SecurityIntentList) DeepCopy() *SecurityIntentList { - if in == nil { - return nil - } - out := new(SecurityIntentList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *SecurityIntentList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecurityIntentSpec) DeepCopyInto(out *SecurityIntentSpec) { - *out = *in - in.Selector.DeepCopyInto(&out.Selector) - in.Intent.DeepCopyInto(&out.Intent) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentSpec. -func (in *SecurityIntentSpec) DeepCopy() *SecurityIntentSpec { - if in == nil { - return nil - } - out := new(SecurityIntentSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecurityIntentStatus) DeepCopyInto(out *SecurityIntentStatus) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityIntentStatus. -func (in *SecurityIntentStatus) DeepCopy() *SecurityIntentStatus { - if in == nil { - return nil - } - out := new(SecurityIntentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Selector) DeepCopyInto(out *Selector) { - *out = *in - in.Match.DeepCopyInto(&out.Match) - if in.CEL != nil { - in, out := &in.CEL, &out.CEL - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Selector. -func (in *Selector) DeepCopy() *Selector { - if in == nil { - return nil - } - out := new(Selector) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Subject) DeepCopyInto(out *Subject) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Subject. -func (in *Subject) DeepCopy() *Subject { - if in == nil { - return nil - } - out := new(Subject) - in.DeepCopyInto(out) - return out -} diff --git a/config/crd/bases/intent.security.nimbus.com_securityintentbindings.yaml b/config/crd/bases/intent.security.nimbus.com_securityintentbindings.yaml new file mode 100644 index 00000000..8d31ce03 --- /dev/null +++ b/config/crd/bases/intent.security.nimbus.com_securityintentbindings.yaml @@ -0,0 +1,116 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: securityintentbindings.intent.security.nimbus.com +spec: + group: intent.security.nimbus.com + names: + kind: SecurityIntentBinding + listKind: SecurityIntentBindingList + plural: securityintentbindings + singular: securityintentbinding + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: SecurityIntentBinding is the Schema for the securityintentbindings + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: SecurityIntentBindingSpec defines the desired state of SecurityIntentBinding + properties: + intentRequests: + items: + description: IntentRequest defines the request for a specific SecurityIntent + properties: + description: + type: string + intentName: + type: string + mode: + type: string + type: + type: string + required: + - description + - intentName + - mode + - type + type: object + type: array + selector: + description: Foo is an example field of SecurityIntentBinding. Edit + securityintentbinding_types.go to remove/update + properties: + all: + items: + description: ResourceFilter is used for filtering resources + properties: + resources: + description: Resources defines the properties for selecting + Kubernetes resources + properties: + kind: + type: string + matchLabels: + additionalProperties: + type: string + type: object + namespace: + type: string + type: object + type: object + type: array + any: + items: + description: ResourceFilter is used for filtering resources + properties: + resources: + description: Resources defines the properties for selecting + Kubernetes resources + properties: + kind: + type: string + matchLabels: + additionalProperties: + type: string + type: object + namespace: + type: string + type: object + type: object + type: array + cel: + items: + type: string + type: array + type: object + required: + - intentRequests + - selector + type: object + status: + description: SecurityIntentBindingStatus defines the observed state of + SecurityIntentBinding + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/intent.security.nimbus.com_securityintents.yaml b/config/crd/bases/intent.security.nimbus.com_securityintents.yaml index 0eb4c348..a40e688d 100644 --- a/config/crd/bases/intent.security.nimbus.com_securityintents.yaml +++ b/config/crd/bases/intent.security.nimbus.com_securityintents.yaml @@ -39,152 +39,174 @@ spec: properties: action: type: string - mode: + description: type: string resource: items: description: Resource defines the resources that the security policy applies to properties: - attrs: + capabilities: items: - type: string + description: Capabilities defines the capabilities-related + policies + properties: + matchCapabilities: + items: + description: MatchCapability defines a capability + for capabilities policies + properties: + capability: + type: string + type: object + type: array + type: object + type: array + file: + items: + description: File defines the file-related policies + properties: + matchDirectories: + items: + description: MatchDirectory defines a directory + for process or file policies + properties: + dir: + type: string + fromSource: + items: + description: FromSource defines a source path + for directory-based policies + properties: + path: + type: string + type: object + type: array + type: object + type: array + matchPaths: + items: + description: MatchPath defines a path for process + or file policies + properties: + path: + type: string + type: object + type: array + type: object type: array - key: - type: string - val: + fromCIDRSet: items: - type: string + description: CIDRSet defines CIDR ranges for network policies + properties: + cidr: + type: string + type: object + type: array + network: + items: + description: Network defines the network-related policies + properties: + matchProtocols: + items: + description: MatchProtocol defines a protocol for + network policies + properties: + protocol: + type: string + type: object + type: array + type: object + type: array + process: + items: + description: Process defines the process-related policies + properties: + matchDirectories: + items: + description: MatchDirectory defines a directory + for process or file policies + properties: + dir: + type: string + fromSource: + items: + description: FromSource defines a source path + for directory-based policies + properties: + path: + type: string + type: object + type: array + type: object + type: array + matchPaths: + items: + description: MatchPath defines a path for process + or file policies + properties: + path: + type: string + type: object + type: array + matchPatterns: + items: + description: MatchPattern defines a pattern for + process policies + properties: + pattern: + type: string + type: object + type: array + type: object + type: array + syscalls: + items: + description: Syscalls defines the syscalls-related policies + properties: + matchSyscalls: + items: + description: MatchSyscall defines a syscall for + syscall policies + properties: + syscalls: + items: + type: string + type: array + type: object + type: array + type: object + type: array + toPorts: + items: + description: ToPort defines ports and protocols for network + policies + properties: + ports: + items: + description: Port defines a network port and its + protocol + properties: + port: + type: string + protocol: + type: string + type: object + type: array + type: object type: array - valcel: - type: string type: object type: array type: type: string required: - action - - mode + - description - resource - type type: object - selector: - description: Selector defines the selection criteria for resources - properties: - cel: - items: - type: string - type: array - match: - description: Match defines the resource filters to be used - properties: - all: - items: - description: ResourceFilter is used for filtering resources, - subjects, roles, and cluster roles - properties: - resources: - description: Resources defines the properties for selecting - Kubernetes resources - properties: - kinds: - items: - type: string - type: array - matchLabels: - additionalProperties: - type: string - type: object - names: - items: - type: string - type: array - namespaces: - items: - type: string - type: array - operations: - items: - type: string - type: array - required: - - kinds - type: object - roles: - items: - type: string - type: array - subjects: - items: - description: Subject defines the subject for filtering - properties: - kind: - type: string - name: - type: string - required: - - kind - type: object - type: array - type: object - type: array - any: - items: - description: ResourceFilter is used for filtering resources, - subjects, roles, and cluster roles - properties: - resources: - description: Resources defines the properties for selecting - Kubernetes resources - properties: - kinds: - items: - type: string - type: array - matchLabels: - additionalProperties: - type: string - type: object - names: - items: - type: string - type: array - namespaces: - items: - type: string - type: array - operations: - items: - type: string - type: array - required: - - kinds - type: object - roles: - items: - type: string - type: array - subjects: - items: - description: Subject defines the subject for filtering - properties: - kind: - type: string - name: - type: string - required: - - kind - type: object - type: array - type: object - type: array - type: object - required: - - cel - type: object required: - intent - - selector type: object status: description: SecurityIntentStatus defines the observed state of SecurityIntent diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 09ca7a1f..399c070e 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -3,17 +3,20 @@ # It should be run by config/default resources: - bases/intent.security.nimbus.com_securityintents.yaml +- bases/intent.security.nimbus.com_securityintentbindings.yaml #+kubebuilder:scaffold:crdkustomizeresource patches: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD #- path: patches/webhook_in_securityintents.yaml +#- path: patches/webhook_in_securityintentbindings.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD #- path: patches/cainjection_in_securityintents.yaml +#- path: patches/cainjection_in_securityintentbindings.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # [WEBHOOK] To enable webhook, uncomment the following section diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 529251e7..63cf0e18 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -4,6 +4,32 @@ kind: ClusterRole metadata: name: manager-role rules: +- apiGroups: + - intent.security.nimbus.com + resources: + - securityintentbindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - intent.security.nimbus.com + resources: + - securityintentbindings/finalizers + verbs: + - update +- apiGroups: + - intent.security.nimbus.com + resources: + - securityintentbindings/status + verbs: + - get + - patch + - update - apiGroups: - intent.security.nimbus.com resources: diff --git a/config/rbac/securityintentbinding_editor_role.yaml b/config/rbac/securityintentbinding_editor_role.yaml new file mode 100644 index 00000000..dcd147e5 --- /dev/null +++ b/config/rbac/securityintentbinding_editor_role.yaml @@ -0,0 +1,31 @@ +# permissions for end users to edit securityintentbindings. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: securityintentbinding-editor-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: nimbus + app.kubernetes.io/part-of: nimbus + app.kubernetes.io/managed-by: kustomize + name: securityintentbinding-editor-role +rules: +- apiGroups: + - intent.security.nimbus.com + resources: + - securityintentbindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - intent.security.nimbus.com + resources: + - securityintentbindings/status + verbs: + - get diff --git a/config/rbac/securityintentbinding_viewer_role.yaml b/config/rbac/securityintentbinding_viewer_role.yaml new file mode 100644 index 00000000..e2bc7408 --- /dev/null +++ b/config/rbac/securityintentbinding_viewer_role.yaml @@ -0,0 +1,27 @@ +# permissions for end users to view securityintentbindings. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: clusterrole + app.kubernetes.io/instance: securityintentbinding-viewer-role + app.kubernetes.io/component: rbac + app.kubernetes.io/created-by: nimbus + app.kubernetes.io/part-of: nimbus + app.kubernetes.io/managed-by: kustomize + name: securityintentbinding-viewer-role +rules: +- apiGroups: + - intent.security.nimbus.com + resources: + - securityintentbindings + verbs: + - get + - list + - watch +- apiGroups: + - intent.security.nimbus.com + resources: + - securityintentbindings/status + verbs: + - get diff --git a/config/samples/intent_v1_securityintentbinding.yaml b/config/samples/intent_v1_securityintentbinding.yaml new file mode 100644 index 00000000..8dd7ac7e --- /dev/null +++ b/config/samples/intent_v1_securityintentbinding.yaml @@ -0,0 +1,12 @@ +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntentBinding +metadata: + labels: + app.kubernetes.io/name: securityintentbinding + app.kubernetes.io/instance: securityintentbinding-sample + app.kubernetes.io/part-of: nimbus + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: nimbus + name: securityintentbinding-sample +spec: + # TODO(user): Add fields here diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index d9aaf765..c5f98a58 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -1,4 +1,5 @@ ## Append samples of your project ## resources: - intent_v1_securityintent.yaml +- intent_v1_securityintentbinding.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/controllers/policy/network_policy.go b/controllers/policy/network_policy.go deleted file mode 100644 index fd5ffc29..00000000 --- a/controllers/policy/network_policy.go +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2023 Authors of Nimbus - -package policy - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - intentv1 "github.com/5GSEC/nimbus/api/v1" - ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" - kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" - - utils "github.com/5GSEC/nimbus/controllers/utils" -) - -// NetworkPolicyController struct to handle network policies. -type NetworkPolicyController struct { - Client client.Client // Client to interact with Kubernetes API. - Scheme *runtime.Scheme // Scheme defines the runtime scheme of the Kubernetes objects. -} - -// NewNetworkPolicyController creates a new instance of NetworkPolicyController. -func NewNetworkPolicyController(client client.Client, scheme *runtime.Scheme) *NetworkPolicyController { - return &NetworkPolicyController{ - Client: client, - Scheme: scheme, - } -} - -// HandlePolicy processes the network policies defined in the SecurityIntent resource. -func (npc *NetworkPolicyController) HandlePolicy(ctx context.Context, intent *intentv1.SecurityIntent) error { - log := log.FromContext(ctx) // Logger with context. - - // Build and apply/update Cilium Network Policy based on SecurityIntent. - ciliumPolicy := utils.BuildCiliumNetworkPolicySpec(ctx, intent).(*ciliumv2.CiliumNetworkPolicy) - err := utils.ApplyOrUpdatePolicy(ctx, npc.Client, ciliumPolicy, ciliumPolicy.Name) - if err != nil { - log.Error(err, "Failed to apply Cilium Network Policy", "Name", ciliumPolicy.Name) - return err - } - - // If SecurityIntent contains protocol resources, build and apply/update KubeArmor Network Policy. - if containsProtocolResource(intent) { - armorNetPolicy := utils.BuildKubeArmorPolicySpec(ctx, intent, utils.GetPolicyType(utils.IsHostPolicy(intent))).(*kubearmorv1.KubeArmorPolicy) - err = utils.ApplyOrUpdatePolicy(ctx, npc.Client, armorNetPolicy, armorNetPolicy.Name) - if err != nil { - log.Error(err, "Failed to apply KubeArmor Network Policy", "Name", armorNetPolicy.Name) - return err - } - } - - log.Info("Applied Network Policy", "PolicyName", intent.Name) - return nil -} - -// DeletePolicy removes the network policy associated with the SecurityIntent resource. -func (npc *NetworkPolicyController) DeletePolicy(ctx context.Context, intent *intentv1.SecurityIntent) error { - log := log.FromContext(ctx) - var err error - - // Delete KubeArmor or Cilium Network Policy based on the contents of SecurityIntent. - - if containsProtocolResource(intent) { - err = deleteNetworkPolicy(ctx, npc.Client, "KubeArmorPolicy", intent.Name, intent.Namespace) - if err != nil { - log.Error(err, "Failed to delete KubeArmor Network Policy", "Name", intent.Name) - return err - } - } else { - // Delete Cilium Network Policy by default - err = deleteNetworkPolicy(ctx, npc.Client, "CiliumNetworkPolicy", intent.Name, intent.Namespace) - if err != nil { - log.Error(err, "Failed to delete Cilium Network Policy", "Name", intent.Name) - return err - } - } - - log.Info("Deleted Network Policy", "PolicyName", intent.Name) - return nil -} - -// containsProtocolResource checks for the presence of protocol resources in SecurityIntent. -func containsProtocolResource(intent *intentv1.SecurityIntent) bool { - // Iterates through the intent resources to find if 'protocols' key is present. - for _, resource := range intent.Spec.Intent.Resource { - if resource.Key == "protocols" { - return true - } - } - return false -} - -// deleteNetworkPolicy helps in deleting a specified network policy. -func deleteNetworkPolicy(ctx context.Context, c client.Client, policyType, name, namespace string) error { - // Utilizes utility function to delete the specified network policy. - return utils.DeletePolicy(ctx, c, policyType, name, namespace) -} diff --git a/controllers/policy/policy_controller.go b/controllers/policy/policy_controller.go deleted file mode 100644 index 36642fb6..00000000 --- a/controllers/policy/policy_controller.go +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2023 Authors of Nimbus - -package policy - -import ( - "context" - "fmt" - - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - intentv1 "github.com/5GSEC/nimbus/api/v1" - utils "github.com/5GSEC/nimbus/controllers/utils" -) - -// Constant for the finalizer name used in the SecurityIntent resource. -const securityIntentFinalizer = "finalizer.securityintent.intent.security.nimbus.com" - -// PolicyController struct handles different types of policies. -type PolicyController struct { - Client client.Client // Client for interacting with Kubernetes API. - Scheme *runtime.Scheme // Scheme defines the runtime scheme of the Kubernetes objects. - SystemPolicyController *SystemPolicyController // Controller for handling system policies. - NetworkPolicyController *NetworkPolicyController // Controller for handling network policies. -} - -// NewPolicyController creates a new instance of PolicyController. -func NewPolicyController(client client.Client, scheme *runtime.Scheme) *PolicyController { - if client == nil || scheme == nil { - // Print an error and return nil if the client or scheme is not provided. - fmt.Println("PolicyController: Client or Scheme is nil") - return nil - } - - // Initialize and return a new PolicyController with system and network policy controllers. - return &PolicyController{ - Client: client, - Scheme: scheme, - SystemPolicyController: NewSystemPolicyController(client, scheme), - NetworkPolicyController: NewNetworkPolicyController(client, scheme), - } -} - -// Reconcile handles the reconciliation logic for the SecurityIntent resource. -func (pc *PolicyController) Reconcile(ctx context.Context, intent *intentv1.SecurityIntent) error { - log := log.FromContext(ctx) // Logger with context. - log.Info("Processing policy", "Name", intent.Name, "Type", intent.Spec.Intent.Type) - - var err error - - // Switch-case to handle different types of policies based on the intent type. - switch intent.Spec.Intent.Type { - case "system": - log.Info("Handling system policy") - err = pc.SystemPolicyController.HandlePolicy(ctx, intent) - case "network": - log.Info("Handling network policy") - err = pc.NetworkPolicyController.HandlePolicy(ctx, intent) - default: - log.Info("Unknown policy type", "Type", intent.Spec.Intent.Type) - } - - // Handling finalizer logic for clean up during delete operations. - if intent.ObjectMeta.DeletionTimestamp.IsZero() { - // If the resource is not being deleted, add the finalizer if it's not present. - if !utils.ContainsString(intent.ObjectMeta.Finalizers, securityIntentFinalizer) { - intent.ObjectMeta.Finalizers = append(intent.ObjectMeta.Finalizers, securityIntentFinalizer) - err = pc.Client.Update(ctx, intent) - } - } else { - // If the resource is being deleted, process deletion based on policy type and remove finalizer. - if utils.ContainsString(intent.ObjectMeta.Finalizers, securityIntentFinalizer) { - switch intent.Spec.Intent.Type { - case "system": - err = pc.SystemPolicyController.DeletePolicy(ctx, intent) - case "network": - err = pc.NetworkPolicyController.DeletePolicy(ctx, intent) - default: - err = fmt.Errorf("unknown policy type: %s", intent.Spec.Intent.Type) - } - - // Removing the finalizer after handling deletion. - intent.ObjectMeta.Finalizers = utils.RemoveString(intent.ObjectMeta.Finalizers, securityIntentFinalizer) - if updateErr := pc.Client.Update(ctx, intent); updateErr != nil { - return updateErr - } - } - } - - return err -} diff --git a/controllers/policy/system_policy.go b/controllers/policy/system_policy.go deleted file mode 100644 index 9a814616..00000000 --- a/controllers/policy/system_policy.go +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2023 Authors of Nimbus - -package policy - -import ( - "context" - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - utils "github.com/5GSEC/nimbus/controllers/utils" - - intentv1 "github.com/5GSEC/nimbus/api/v1" - kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" -) - -// SystemPolicyController is a struct to handle system policies. -type SystemPolicyController struct { - Client client.Client // Client for interacting with Kubernetes API. - Scheme *runtime.Scheme // Scheme defines the runtime scheme of the Kubernetes objects. -} - -// NewSystemPolicyController creates a new instance of SystemPolicyController. -func NewSystemPolicyController(client client.Client, scheme *runtime.Scheme) *SystemPolicyController { - return &SystemPolicyController{ - Client: client, - Scheme: scheme, - } -} - -// HandlePolicy processes the system policy as defined in SecurityIntent. -func (spc *SystemPolicyController) HandlePolicy(ctx context.Context, intent *intentv1.SecurityIntent) error { - log := log.FromContext(ctx) // Logger with context. - - // Determine if the policy is a HostPolicy. - isHost := utils.IsHostPolicy(intent) - - var err error - if isHost { - // Create and apply a KubeArmorHostPolicy if it's a host policy. - hostPolicy := createKubeArmorHostPolicy(ctx, intent) - err = applyKubeArmorHostPolicy(ctx, spc.Client, hostPolicy) - } else { - // Create and apply a KubeArmorPolicy otherwise. - armorPolicy := createKubeArmorPolicy(ctx, intent) - err = applyKubeArmorPolicy(ctx, spc.Client, armorPolicy) - } - - if err != nil { - log.Error(err, "Failed to apply policy") - return err - } - - log.Info("Applied System Policy", "PolicyType", utils.GetPolicyType(isHost), "PolicyName", intent.Name) - return nil -} - -// DeletePolicy removes the system policy associated with the SecurityIntent resource. -func (spc *SystemPolicyController) DeletePolicy(ctx context.Context, intent *intentv1.SecurityIntent) error { - log := log.FromContext(ctx) - - isHost := utils.IsHostPolicy(intent) - policyType := utils.GetPolicyType(isHost) - - // Delete the system policy. - err := deleteSystemPolicy(ctx, spc.Client, policyType, intent.Name, intent.Namespace) - if err != nil { - log.Error(err, "Failed to delete policy") - return err - } - - log.Info("Deleted System Policy", "PolicyType", policyType, "PolicyName", intent.Name) - return nil -} - -// createKubeArmorHostPolicy(): Creates a KubeArmorHostPolicy object based on the given SecurityIntent -func createKubeArmorHostPolicy(ctx context.Context, intent *intentv1.SecurityIntent) *kubearmorv1.KubeArmorHostPolicy { - return utils.BuildKubeArmorPolicySpec(ctx, intent, "host").(*kubearmorv1.KubeArmorHostPolicy) -} - -// createKubeArmorPolicy creates a KubeArmorPolicy object based on the given SecurityIntent -func createKubeArmorPolicy(ctx context.Context, intent *intentv1.SecurityIntent) *kubearmorv1.KubeArmorPolicy { - return utils.BuildKubeArmorPolicySpec(ctx, intent, "policy").(*kubearmorv1.KubeArmorPolicy) -} - -// applyKubeArmorPolicy applies a KubeArmorPolicy to the Kubernetes cluster -func applyKubeArmorPolicy(ctx context.Context, c client.Client, policy *kubearmorv1.KubeArmorPolicy) error { - return utils.ApplyOrUpdatePolicy(ctx, c, policy, policy.Name) -} - -// applyKubeArmorHostPolicy applies a KubeArmorHostPolicy to the Kubernetes cluster -func applyKubeArmorHostPolicy(ctx context.Context, c client.Client, policy *kubearmorv1.KubeArmorHostPolicy) error { - return utils.ApplyOrUpdatePolicy(ctx, c, policy, policy.Name) -} - -func deleteSystemPolicy(ctx context.Context, c client.Client, policyType, name, namespace string) error { - // Utilizes utility function to delete the specified system policy. - return utils.DeletePolicy(ctx, c, policyType, name, namespace) -} diff --git a/controllers/utils/utils_policy.go b/controllers/utils/utils_policy.go deleted file mode 100644 index 9cdd9209..00000000 --- a/controllers/utils/utils_policy.go +++ /dev/null @@ -1,627 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2023 Authors of Nimbus - -package utils - -import ( - "context" - "fmt" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "reflect" - "strings" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - client "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" - - intentv1 "github.com/5GSEC/nimbus/api/v1" - ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" - "github.com/cilium/cilium/pkg/policy/api" - kubearmorv1 "github.com/kubearmor/KubeArmor/pkg/KubeArmorController/api/security.kubearmor.com/v1" -) - -// --------------------------------------------------- -// -------- Creation of Policy Specifications -------- -// --------------------------------------------------- - -// BuildKubeArmorPolicySpec creates a policy specification (either KubeArmorPolicy or KubeArmorHostPolicy) -// based on the provided SecurityIntent and the type of policy. -func BuildKubeArmorPolicySpec(ctx context.Context, intent *intentv1.SecurityIntent, policyType string) interface{} { - log := log.FromContext(ctx) - // Logging the creation of a KubeArmor policy. - log.Info("Creating KubeArmorPolicy", "Name", intent.Name) - - matchLabels := convertToMapString(extractLabels(intent)) - - // Convert extracted information into specific KubeArmor policy types. - if policyType == "host" { - - return &kubearmorv1.KubeArmorHostPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: intent.Name, - Namespace: intent.Namespace, - }, - Spec: kubearmorv1.KubeArmorHostPolicySpec{ - NodeSelector: kubearmorv1.NodeSelectorType{ - MatchLabels: matchLabels, - }, - Process: convertToKubeArmorHostPolicyProcessType(extractProcessPolicy(intent)), - File: convertToKubeArmorHostPolicyFileType(extractFilePolicy(intent)), - Capabilities: convertToKubeArmorHostPolicyCapabilitiesType(extractCapabilitiesPolicy(intent)), - // TODO: To discuss - //Network: convertToKubeArmorHostPolicyNetworkType(extractNetworkPolicy(intent)), - Action: kubearmorv1.ActionType(formatAction(intent.Spec.Intent.Action)), - }, - } - } else { - return &kubearmorv1.KubeArmorPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: intent.Name, - Namespace: intent.Namespace, - }, - Spec: kubearmorv1.KubeArmorPolicySpec{ - Selector: kubearmorv1.SelectorType{ - MatchLabels: matchLabels, - }, - Process: convertToKubeArmorPolicyProcessType(extractProcessPolicy(intent)), - File: convertToKubeArmorPolicyFileType(extractFilePolicy(intent)), - Capabilities: convertToKubeArmorPolicyCapabilitiesType(extractCapabilitiesPolicy(intent)), - Network: convertToKubeArmorPolicyNetworkType(extractNetworkPolicy(intent)), - Action: kubearmorv1.ActionType(formatAction(intent.Spec.Intent.Action)), - }, - } - } -} - -// BuildCiliumNetworkPolicySpec creates a Cilium network policy specification based on the provided SecurityIntent. -func BuildCiliumNetworkPolicySpec(ctx context.Context, intent *intentv1.SecurityIntent) interface{} { - // Logging the creation of a Cilium Network Policy. - log := log.FromContext(ctx) - log.Info("Creating CiliumNetworkPolicy", "Name", intent.Name) - - // Utilize utility functions to construct a Cilium network policy from the intent. - endpointSelector := getEndpointSelector(intent) - ingressDenyRules := getIngressDenyRules(intent) - - // Build and return a Cilium Network Policy based on the intent. - return &ciliumv2.CiliumNetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: intent.Name, - Namespace: intent.Namespace, - }, - Spec: &api.Rule{ - EndpointSelector: endpointSelector, - IngressDeny: ingressDenyRules, - }, - } -} - -// ---------------------------------------- -// -------- Conversion Functions ---------- -// ---------------------------------------- - -// Various conversion functions to transform data from the SecurityIntent into specific policy types. -// These functions handle different aspects like processing types, file types, network types, etc., -// and convert them into the format required by KubeArmor and Cilium policies. - -// convertToMapString converts a slice of interfaces to a map of string key-value pairs. -func convertToMapString(slice []interface{}) map[string]string { - // Iterate through the slice, converting each item into a map and merging them into a single map. - result := make(map[string]string) - for _, item := range slice { - for key, value := range item.(map[string]string) { - result[key] = value - } - } - return result -} - -func convertToKubeArmorHostPolicyProcessType(slice []interface{}) kubearmorv1.ProcessType { - var result kubearmorv1.ProcessType - for _, item := range slice { - str, ok := item.(string) - if !ok { - continue // or appropriate error handling - } - // The 'Pattern' field is of type string, so it can be assigned directly - result.MatchPatterns = append(result.MatchPatterns, kubearmorv1.ProcessPatternType{ - Pattern: str, - }) - } - return result -} - -func convertToKubeArmorHostPolicyFileType(slice []interface{}) kubearmorv1.FileType { - var result kubearmorv1.FileType - for _, item := range slice { - result.MatchPaths = append(result.MatchPaths, kubearmorv1.FilePathType{ - Path: kubearmorv1.MatchPathType(item.(string)), - }) - } - return result -} - -// TODO: To discuss -//func convertToKubeArmorHostPolicyNetworkType(slice []interface{}) kubearmorv1.MatchHostNetworkProtocolType { -// var result kubearmorv1.MatchHostNetworkProtocolType -// for _, item := range slice { -// str, ok := item.(string) -// if !ok { -// continue // or appropriate error handling -// } -// // Requires explicit type conversion to MatchNetworkProtocolStringType -// protocol := kubearmorv1.MatchNetworkProtocolStringType(str) -// result.MatchProtocols = append(result.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{ -// Protocol: protocol, -// }) -// } -// return result -//} - -func convertToKubeArmorHostPolicyCapabilitiesType(slice []interface{}) kubearmorv1.HostCapabilitiesType { - var result kubearmorv1.HostCapabilitiesType - for _, item := range slice { - str, ok := item.(string) - if !ok { - continue // or appropriate error handling - } - // Convert to MatchCapabilitiesStringType - capability := kubearmorv1.MatchCapabilitiesStringType(str) - result.MatchCapabilities = append(result.MatchCapabilities, kubearmorv1.MatchHostCapabilitiesType{ - Capability: capability, - }) - } - return result -} - -func convertToKubeArmorPolicyProcessType(slice []interface{}) kubearmorv1.ProcessType { - var result kubearmorv1.ProcessType - for _, item := range slice { - if str, ok := item.(string); ok { - result.MatchPatterns = append(result.MatchPatterns, kubearmorv1.ProcessPatternType{ - Pattern: str, - }) - } - } - return result -} - -func convertToKubeArmorPolicyFileType(slice []interface{}) kubearmorv1.FileType { - var result kubearmorv1.FileType - for _, item := range slice { - path, ok := item.(map[string]string)["Path"] - if !ok { - continue // or appropriate error handling - } - result.MatchPaths = append(result.MatchPaths, kubearmorv1.FilePathType{ - Path: kubearmorv1.MatchPathType(path), - }) - } - return result -} - -func convertToKubeArmorPolicyCapabilitiesType(slice []interface{}) kubearmorv1.CapabilitiesType { - var result kubearmorv1.CapabilitiesType - //var types []kubearmorv1.MatchCapabilitiesType - //var spec *kubearmorv1.KubeArmorPolicySpec - for _, item := range slice { - str, ok := item.(map[string]string)["Capability"] - if !ok { - continue // or appropriate error handling - } - result.MatchCapabilities = append(result.MatchCapabilities, kubearmorv1.MatchCapabilitiesType{ - Capability: kubearmorv1.MatchCapabilitiesStringType(str), - }) - } - if len(result.MatchCapabilities) == 0 { - return kubearmorv1.CapabilitiesType{ - MatchCapabilities: []kubearmorv1.MatchCapabilitiesType{}, - } - } - return result -} - -func convertToKubeArmorPolicyNetworkType(slice []interface{}) kubearmorv1.NetworkType { - var result kubearmorv1.NetworkType - for _, item := range slice { - str, ok := item.(map[string]string)["Protocol"] - if !ok { - continue // or appropriate error handling - } - result.MatchProtocols = append(result.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{ - Protocol: kubearmorv1.MatchNetworkProtocolStringType(str), - }) - } - return result -} - -// -------------------------------------- -// -------- Utility Functions ---------- -// -------------------------------------- - -// GetPolicyType returns the type of policy as a string based on whether it's a host policy. -func GetPolicyType(isHost bool) string { - if isHost { - return "KubeArmorHostPolicy" - } - return "KubeArmorPolicy" -} - -// IsHostPolicy determines if the given SecurityIntent is a Host Policy. -func IsHostPolicy(intent *intentv1.SecurityIntent) bool { - // Check for specific labels in the CEL field of the intent to determine if it's a host policy. - for _, cel := range intent.Spec.Selector.CEL { - if strings.Contains(cel, "kubernetes.io") { - return true - } - } - return false -} - -// cleanLabelKey cleans up the label key to remove unnecessary prefixes. -func cleanLabelKey(key string) string { - // Remove specific prefixes from the label key, if present. - if strings.HasPrefix(key, "object.metadata.labels.") { - return strings.TrimPrefix(key, "object.metadata.labels.") - } - return key -} - -// parseCELExpression parses a CEL expression and extracts labels as key-value pairs. -func parseCELExpression(expression string) map[string]string { - // Process the CEL expression and convert it into a map of labels. - parsedLabels := make(map[string]string) - - expression = strings.TrimSpace(expression) - expressions := strings.Split(expression, " && ") - - for _, expr := range expressions { - parts := strings.Split(expr, " == ") - if len(parts) == 2 { - key := strings.TrimSpace(parts[0]) - value := strings.TrimSpace(parts[1]) - - key = strings.TrimPrefix(key, "object.metadata.labels['") - key = strings.TrimSuffix(key, "']") - value = strings.Trim(value, "'") - - parsedLabels[key] = value - } - } - - return parsedLabels -} - -// extractLabels(): Extracts and returns labels from a CEL expression and Match fields -func extractLabels(intent *intentv1.SecurityIntent) []interface{} { - labels := make([]interface{}, 0) - - isHost := IsHostPolicy(intent) - - // Extract labels from Match.Any - for _, filter := range intent.Spec.Selector.Match.Any { - for key, val := range filter.Resources.MatchLabels { - if strings.HasPrefix(key, "object.metadata.labels.") { - cleanKey := cleanLabelKey(key) - labels = append(labels, map[string]string{cleanKey: val}) - } - } - } - - // Extract labels from Match.All - for _, filter := range intent.Spec.Selector.Match.All { - for key, val := range filter.Resources.MatchLabels { - if strings.HasPrefix(key, "object.metadata.labels.") { - cleanKey := cleanLabelKey(key) - labels = append(labels, map[string]string{cleanKey: val}) - } - } - } - - // Extract labels from CEL expressions - if isHost { - // Special handling for KubeArmorHostPolicy - for _, cel := range intent.Spec.Selector.CEL { - if strings.Contains(cel, "kubernetes.io/") { - parts := strings.Split(cel, " == ") - if len(parts) == 2 { - key := strings.TrimSpace(parts[0]) - key = strings.TrimPrefix(key, "object.metadata.labels['") - key = strings.TrimSuffix(key, "']") - value := strings.Trim(parts[1], "'") - cleanKey := cleanLabelKey(key) - labels = append(labels, map[string]string{cleanKey: value}) - } - } - } - } else { - // General handling for other policies - for _, cel := range intent.Spec.Selector.CEL { - if strings.HasPrefix(cel, "object.metadata.labels.") { - parsedLabels := parseCELExpression(cel) - for key, val := range parsedLabels { - cleanKey := cleanLabelKey(key) - labels = append(labels, map[string]string{cleanKey: val}) - } - } - } - } - - return labels -} - -func extractProcessPolicy(intent *intentv1.SecurityIntent) []interface{} { - var matchPatterns []interface{} - for _, resource := range intent.Spec.Intent.Resource { - if resource.Key == "commands" { - for _, cmd := range resource.Val { - matchPatterns = append(matchPatterns, map[string]string{"Pattern": cmd}) - } - } - } - return matchPatterns -} - -func extractFilePolicy(intent *intentv1.SecurityIntent) []interface{} { - var matchPaths []interface{} - for _, resource := range intent.Spec.Intent.Resource { - if resource.Key == "paths" { - for _, path := range resource.Val { - matchPaths = append(matchPaths, map[string]string{"Path": path}) - } - } - } - return matchPaths -} - -func extractCapabilitiesPolicy(intent *intentv1.SecurityIntent) []interface{} { - var matchCapabilities []interface{} - for _, resource := range intent.Spec.Intent.Resource { - if resource.Key == "capabilities" { - for _, capability := range resource.Val { - matchCapabilities = append(matchCapabilities, map[string]string{"Capability": capability}) - } - } - } - return matchCapabilities -} - -// extractNetworkPolicy() - Extracts network policy from SecurityIntent and returns it as a slice of interface{} -func extractNetworkPolicy(intent *intentv1.SecurityIntent) []interface{} { - var matchNetworkProtocols []interface{} - - for _, resource := range intent.Spec.Intent.Resource { - if resource.Key == "protocols" { - for _, protocol := range resource.Val { - protocolMap := map[string]string{"Protocol": protocol} - matchNetworkProtocols = append(matchNetworkProtocols, protocolMap) - } - } - } - - return matchNetworkProtocols -} - -// getEndpointSelector creates an endpoint selector from the SecurityIntent. -func getEndpointSelector(intent *intentv1.SecurityIntent) api.EndpointSelector { - // Create an Endpoint Selector based on matched labels extracted from the intent. - matchLabels := make(map[string]string) - - // Matching labels to a "Match Any" filter - for _, filter := range intent.Spec.Selector.Match.Any { - for key, val := range filter.Resources.MatchLabels { - matchLabels[key] = val - } - } - - // Matching labels that fit the "Match All" filter - for _, filter := range intent.Spec.Selector.Match.All { - for key, val := range filter.Resources.MatchLabels { - matchLabels[key] = val - } - } - - // Create an Endpoint Selector based on matched labels - return api.NewESFromMatchRequirements(matchLabels, nil) -} - -// getIngressDenyRules generates ingress deny rules from SecurityIntent. -func getIngressDenyRules(intent *intentv1.SecurityIntent) []api.IngressDenyRule { - // Process the intent to create ingress deny rules. - var ingressDenyRules []api.IngressDenyRule - - for _, resource := range intent.Spec.Intent.Resource { - if resource.Key == "ingress" { - for _, val := range resource.Val { - cidr, port, protocol := splitCIDRAndPort(val) - - ingressRule := api.IngressDenyRule{ - ToPorts: api.PortDenyRules{ - { - Ports: []api.PortProtocol{ - { - Port: port, - Protocol: parseProtocol(protocol), - }, - }, - }, - }, - } - - if cidr != "" { - ingressRule.FromCIDRSet = []api.CIDRRule{{Cidr: api.CIDR(cidr)}} - } - - ingressDenyRules = append(ingressDenyRules, ingressRule) - } - } - } - - return ingressDenyRules -} - -// splitCIDRAndPort separates CIDR, port, and protocol information from a combined string. -func splitCIDRAndPort(cidrAndPort string) (string, string, string) { - // Split the string into CIDR, port, and protocol components, with handling for different formats. - - // Default protocol is TCP - defaultProtocol := "TCP" - - // Separate strings based on '-' - split := strings.Split(cidrAndPort, "-") - - // If there are three separate elements, return the CIDR, port, and protocol separately - if len(split) == 3 { - return split[0], split[1], split[2] - } - - // If there are two separate elements, return the CIDR, port, and default protocol - if len(split) == 2 { - return split[0], split[1], defaultProtocol - } - - // If there is only one element, return the CIDR, empty port, and default protocol - return cidrAndPort, "", defaultProtocol -} - -func parseProtocol(protocol string) api.L4Proto { - // Convert protocol string to L4Proto type. - switch strings.ToUpper(protocol) { - case "TCP": - return api.ProtoTCP - case "UDP": - return api.ProtoUDP - case "ICMP": - return api.ProtoICMP - default: - return api.ProtoTCP - } -} - -func formatAction(action string) string { - // Convert action string to a specific format. - switch strings.ToLower(action) { - case "block": - return "Block" - case "audit": - return "Audit" - case "allow": - return "Allow" - default: - return action - } -} - -// ---------------------------------------- -// -------- Apply & Update Policy -------- -// ---------------------------------------- - -// ApplyOrUpdatePolicy applies or updates the given policy. -func ApplyOrUpdatePolicy(ctx context.Context, c client.Client, policy client.Object, policyName string) error { - // Update the policy if it already exists, otherwise create a new one. - log := log.FromContext(ctx) - - var existingPolicy client.Object - var policySpec interface{} - - switch p := policy.(type) { - case *kubearmorv1.KubeArmorPolicy: - existingPolicy = &kubearmorv1.KubeArmorPolicy{} - policySpec = p.Spec - case *kubearmorv1.KubeArmorHostPolicy: - existingPolicy = &kubearmorv1.KubeArmorHostPolicy{} - policySpec = p.Spec - case *ciliumv2.CiliumNetworkPolicy: - existingPolicy = &ciliumv2.CiliumNetworkPolicy{} - policySpec = p.Spec - default: - return fmt.Errorf("unsupported policy type") - } - - err := c.Get(ctx, types.NamespacedName{Name: policyName, Namespace: policy.GetNamespace()}, existingPolicy) - if err != nil && !errors.IsNotFound(err) { - // Other error handling - log.Error(err, "Failed to get existing policy", "policy", policyName) - return err - } - - if errors.IsNotFound(err) { - // Create a policy if it doesn't exist - if err := c.Create(ctx, policy); err != nil { - log.Error(err, "Failed to apply policy", "policy", policyName) - return err - } - log.Info("Policy created", "Name", policyName) - } else { - // Update if policy already exists (compares specs only) - existingSpec := reflect.ValueOf(existingPolicy).Elem().FieldByName("Spec").Interface() - if !reflect.DeepEqual(policySpec, existingSpec) { - reflect.ValueOf(existingPolicy).Elem().FieldByName("Spec").Set(reflect.ValueOf(policySpec)) - if err := c.Update(ctx, existingPolicy); err != nil { - log.Error(err, "Failed to update policy", "policy", policyName) - return err - } - log.Info("Policy updated", "Name", policyName) - } else { - log.Info("Policy unchanged", "Name", policyName) - } - } - return nil -} - -// ---------------------------------------- -// ----------- Delete Policy ------------- -// ---------------------------------------- - -// DeletePolicy deletes a policy based on type, name, and namespace. -func DeletePolicy(ctx context.Context, c client.Client, policyType, name, namespace string) error { - // Process the deletion request based on policy type. - - var policy client.Object - log := log.FromContext(ctx) - - switch policyType { - case "KubeArmorPolicy": - policy = &kubearmorv1.KubeArmorPolicy{} - case "KubeArmorHostPolicy": - policy = &kubearmorv1.KubeArmorHostPolicy{} - case "CiliumNetworkPolicy": - policy = &ciliumv2.CiliumNetworkPolicy{} - default: - return fmt.Errorf("unknown policy type: %s", policyType) - } - - policy.SetName(name) - policy.SetNamespace(namespace) - - if err := c.Delete(ctx, policy); client.IgnoreNotFound(err) != nil { - log.Error(err, "Failed to delete policy", "Type", policyType, "Name", name, "Namespace", namespace) - return err - } - return nil -} - -// containsString checks if a string is included in a slice. -func ContainsString(slice []string, s string) bool { - // Iterate through the slice to check if the string exists. - - for _, item := range slice { - if item == s { - return true - } - } - return false -} - -// removeString removes a specific string from a slice. -func RemoveString(slice []string, s string) []string { - // Create a new slice excluding the specified string. - result := []string{} - for _, item := range slice { - if item != s { - result = append(result, item) - } - } - return result -} diff --git a/docs/Quick-tutorials.md b/docs/Quick-tutorials.md index f9a2b919..6a55dc8f 100644 --- a/docs/Quick-tutorials.md +++ b/docs/Quick-tutorials.md @@ -5,7 +5,7 @@ busybox-pod ``` -$ kubectl apply -f ./test-yaml/env/busybox-pod.yaml +$ kubectl apply -f ./test/env/busybox-pod.yaml ``` ```yaml @@ -25,7 +25,7 @@ spec: redis-pod ``` -$ kubectl apply -f ./test-yaml/env/redis-pod.yaml +$ kubectl apply -f ./test/env/redis-pod.yaml ``` ```yaml apiVersion: v1 @@ -63,9 +63,9 @@ You want to enforce a policy that blocks all external traffic from accessing por $ make run ``` -### Create and apply intent file +### Create and apply Securityintent and SecurityintentBinding file ``` -$ kubectl apply -f ./test-yaml/intents/network/intent-redis.yaml +$ kubectl apply -f ./test/v2/intents/network/intent-redis.yaml ``` ```yaml apiVersion: intent.security.nimbus.com/v1 @@ -73,79 +73,77 @@ kind: SecurityIntent metadata: name: redis-ingress-deny-traffic namespace: default +spec: + intent: + description: "Block port 6379" + action: Block + type: network + resource: + - fromCIDRSet: + - cidr: 0.0.0.0/0 + toPorts: + - ports: + - port: "6379" + protocol: tcp + +``` + +``` +$ kubectl apply -f ./test/v2/bindings/network/binding-redis.yaml +``` +```yaml +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntentBinding +metadata: + name: net-redis-ingress-deny + namespace: default spec: selector: - match: any: - resources: - names: ["redis-pod"] - namespaces: ["default"] - kinds: ["Pod"] + kind: Pod + namespace: default matchLabels: app: "redis" - cel: - - "object.spec.template.spec.containers.all(container, container.ports.any(port, port.number == 6379))" - intent: - action: block - mode: strict - type: network - resource: - - key: "ingress" - val: ["0.0.0.0/0-6379"] - -``` -
- make run - cclab@kubearmor:~/nimbus$ make run -make: go: Permission denied -test -s /home/cclab/nimbus/bin/controller-gen && /home/cclab/nimbus/bin/controller-gen --version | grep -q v0.13.0 || \ -GOBIN=/home/cclab/nimbus/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.13.0 -/home/cclab/nimbus/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases -/home/cclab/nimbus/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." -go fmt ./... -go vet ./... -go: downloading github.com/onsi/ginkgo/v2 v2.11.0 -go: downloading github.com/onsi/gomega v1.27.10 -go run ./main.go -2023-11-14T15:56:47Z INFO setup starting manager -2023-11-14T15:56:47Z INFO controller-runtime.metrics Starting metrics server -2023-11-14T15:56:47Z INFO starting server {"kind": "health probe", "addr": "[::]:8081"} -2023-11-14T15:56:47Z INFO controller-runtime.metrics Serving metrics server {"bindAddress": ":8080", "secure": false} -2023-11-14T15:56:47Z INFO Starting EventSource {"controller": "securityintent", "controllerGroup": "intent.security.nimbus.com", "controllerKind": "SecurityIntent", "source": "kind source: *v1.SecurityIntent"} -2023-11-14T15:56:47Z INFO Starting Controller {"controller": "securityintent", "controllerGroup": "intent.security.nimbus.com", "controllerKind": "SecurityIntent"} -2023-11-14T15:56:47Z INFO Starting workers {"controller": "securityintent", "controllerGroup": "intent.security.nimbus.com", "controllerKind": "SecurityIntent", "worker count": 1} -2023-11-14T16:00:00Z INFO SecurityIntent object fetched {"controller": "securityintent", "controllerGroup": "intent.security.nimbus.com", "controllerKind": "SecurityIntent", "SecurityIntent": {"name":"redis-ingress-deny-traffic","namespace":"default"}, "namespace": "default", "name": "redis-ingress-deny-traffic", "reconcileID": "f1f990e8-35d2-4dfb-8107-164a916cfb2f", "intent": "redis-ingress-deny-traffic"} -2023-11-14T16:00:00Z INFO Applied CiliumNetworkPolicy {"controller": "securityintent", "controllerGroup": "intent.security.nimbus.com", "controllerKind": "SecurityIntent", "SecurityIntent": {"name":"redis-ingress-deny-traffic","namespace":"default"}, "namespace": "default", "name": "redis-ingress-deny-traffic", "reconcileID": "f1f990e8-35d2-4dfb-8107-164a916cfb2f", "policy": {"namespace": "default", "name": "redis-ingress-deny-traffic"}} -2023-11-14T16:00:00Z INFO Successfully reconciled SecurityIntent {"controller": "securityintent", "controllerGroup": "intent.security.nimbus.com", "controllerKind": "SecurityIntent", "SecurityIntent": {"name":"redis-ingress-deny-traffic","namespace":"default"}, "namespace": "default", "name": "redis-ingress-deny-traffic", "reconcileID": "f1f990e8-35d2-4dfb-8107-164a916cfb2f", "intent": "redis-ingress-deny-traffic"} -
- - - -### Verify SecurityIntent creation + intentRequests: + - type: network + intentName: redis-ingress-deny-traffic + description: "Don’t allow any outside traffic to the Redis port" + mode: strict + +``` + +### Verify SecurityIntent and SecurityIntentBinding ``` $ kubectl get SecurityIntent NAME AGE -redis-ingress-deny-traffic 2m +redis-ingress-deny-traffic 26s + +``` +``` +$ kubectl get SecurityIntentBinding +NAME AGE +net-redis-ingress-deny 25s ``` ### Verify Cilium Network Policy Creation ``` -$ kubectl get CiliumNetworkPolicies -NAME AGE -redis-ingress-deny-traffic 2m19s +$ kubectl get cnp +NAME AGE +net-redis-ingress-deny 38s ``` ``` -$ kubectl get CiliumNetworkPolicies redis-ingress-deny-traffic -o yaml +$ kubectl get cnp net-redis-ingress-deny -o yaml apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: - creationTimestamp: "2023-11-14T16:00:00Z" + creationTimestamp: "2023-12-12T18:11:36Z" generation: 1 - name: redis-ingress-deny-traffic + name: net-redis-ingress-deny namespace: default - resourceVersion: "89051" - uid: 1c3e4e7e-697f-4fbc-a3a8-3a91af6380e6 + resourceVersion: "3415520" + uid: 0b1d9071-16e8-405f-bd92-b3774c41a9df spec: endpointSelector: matchLabels: diff --git a/go.mod b/go.mod index 8616ce7a..53e7242e 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,12 @@ go 1.20 require ( github.com/cilium/cilium v1.14.3 - github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20231213111259-085100ae8f3d - github.com/onsi/ginkgo/v2 v2.13.0 - github.com/onsi/gomega v1.29.0 - k8s.io/apimachinery v0.29.0 - k8s.io/client-go v0.29.0 + github.com/go-logr/logr v1.3.0 + github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20231215052929-bc6c2f17fe38 + github.com/onsi/ginkgo/v2 v2.11.0 + github.com/onsi/gomega v1.27.10 + k8s.io/apimachinery v0.28.3 + k8s.io/client-go v0.28.3 sigs.k8s.io/controller-runtime v0.16.3 ) @@ -21,9 +22,8 @@ require ( github.com/cilium/proxy v0.0.0-20230623092907-8fddead4e52c // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.7.0 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect @@ -95,15 +95,15 @@ require ( go.uber.org/dig v1.17.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.16.0 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.12.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.31.0 // indirect @@ -111,12 +111,12 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.29.0 // indirect - k8s.io/apiextensions-apiserver v0.29.0 // indirect - k8s.io/component-base v0.29.0 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8 // indirect - k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect + k8s.io/api v0.28.3 // indirect + k8s.io/apiextensions-apiserver v0.28.3 // indirect + k8s.io/component-base v0.28.3 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 1b850def..fd334e94 100644 --- a/go.sum +++ b/go.sum @@ -83,14 +83,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= -github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -255,6 +256,7 @@ github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+h github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -278,8 +280,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 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-20231213111259-085100ae8f3d h1:jjXTvtV+Iaq1vg7BO8mgqXAzVY+kRiKYSKdCainJQXc= -github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20231213111259-085100ae8f3d/go.mod h1:LtrnsoV9isTrXx0ClJgKxSJ/gbYmDj9m3pXIjG1yxBg= +github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20231215052929-bc6c2f17fe38 h1:nlgCW1NsV9AGk0ghzanS92b91wv18QHOEnEx8PI8MSQ= +github.com/kubearmor/KubeArmor/pkg/KubeArmorController v0.0.0-20231215052929-bc6c2f17fe38/go.mod h1:LtrnsoV9isTrXx0ClJgKxSJ/gbYmDj9m3pXIjG1yxBg= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -308,10 +310,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= @@ -426,7 +428,7 @@ go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= +go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI= @@ -458,8 +460,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8= -golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -484,7 +486,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -519,8 +521,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -530,8 +532,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -545,8 +547,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -594,15 +596,16 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.1-0.20230616193735-e0c3b6e6ae3b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -613,13 +616,13 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -674,8 +677,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -746,9 +749,9 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= -google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e h1:AZX1ra8YbFMSb7+1pI8S9v4rrgRR7jU1FmuFSSjTVcQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -806,22 +809,22 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= -k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8 h1:vzKzxN5uyJZLY8HL1/OovW7BJefnsBIWt8T7Gjh2boQ= -k8s.io/kube-openapi v0.0.0-20231206194836-bf4651e18aa8/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= -k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM= +k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc= +k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08= +k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc= +k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A= +k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8= +k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4= +k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo= +k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI= +k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= +k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/test-yaml/env/busybox-pod.yaml b/test/env/busybox-pod.yaml similarity index 100% rename from test-yaml/env/busybox-pod.yaml rename to test/env/busybox-pod.yaml diff --git a/test-yaml/env/multiubuntu.yaml b/test/env/multiubuntu.yaml similarity index 100% rename from test-yaml/env/multiubuntu.yaml rename to test/env/multiubuntu.yaml diff --git a/test-yaml/env/redis-pod.yaml b/test/env/redis-pod.yaml similarity index 100% rename from test-yaml/env/redis-pod.yaml rename to test/env/redis-pod.yaml diff --git a/test-yaml/intents/network/intent-net-icmp-audit.yaml b/test/v1/intents/network/intent-net-icmp-audit.yaml similarity index 100% rename from test-yaml/intents/network/intent-net-icmp-audit.yaml rename to test/v1/intents/network/intent-net-icmp-audit.yaml diff --git a/test-yaml/intents/network/intent-network-sample.yaml b/test/v1/intents/network/intent-network-sample.yaml similarity index 100% rename from test-yaml/intents/network/intent-network-sample.yaml rename to test/v1/intents/network/intent-network-sample.yaml diff --git a/test-yaml/intents/network/intent-redis.yaml b/test/v1/intents/network/intent-redis.yaml similarity index 100% rename from test-yaml/intents/network/intent-redis.yaml rename to test/v1/intents/network/intent-redis.yaml diff --git a/test-yaml/intents/network/intent-risky-network-access.yaml b/test/v1/intents/network/intent-risky-network-access.yaml similarity index 100% rename from test-yaml/intents/network/intent-risky-network-access.yaml rename to test/v1/intents/network/intent-risky-network-access.yaml diff --git a/test-yaml/intents/system/intent-accessd-shadow-file.yaml b/test/v1/intents/system/intent-accessd-shadow-file.yaml similarity index 100% rename from test-yaml/intents/system/intent-accessd-shadow-file.yaml rename to test/v1/intents/system/intent-accessd-shadow-file.yaml diff --git a/test-yaml/intents/system/intent-allow-access-to-credentials-dir.yaml b/test/v1/intents/system/intent-allow-access-to-credentials-dir.yaml similarity index 100% rename from test-yaml/intents/system/intent-allow-access-to-credentials-dir.yaml rename to test/v1/intents/system/intent-allow-access-to-credentials-dir.yaml diff --git a/test-yaml/intents/system/intent-bug-block.yaml b/test/v1/intents/system/intent-bug-block.yaml similarity index 100% rename from test-yaml/intents/system/intent-bug-block.yaml rename to test/v1/intents/system/intent-bug-block.yaml diff --git a/test-yaml/intents/system/intent-cap-net-raw-block.yaml b/test/v1/intents/system/intent-cap-net-raw-block.yaml similarity index 100% rename from test-yaml/intents/system/intent-cap-net-raw-block.yaml rename to test/v1/intents/system/intent-cap-net-raw-block.yaml diff --git a/test-yaml/intents/system/intent-do-not-allow-priv-escalation.yaml b/test/v1/intents/system/intent-do-not-allow-priv-escalation.yaml similarity index 100% rename from test-yaml/intents/system/intent-do-not-allow-priv-escalation.yaml rename to test/v1/intents/system/intent-do-not-allow-priv-escalation.yaml diff --git a/test-yaml/intents/system/intent-path-block.yaml b/test/v1/intents/system/intent-path-block.yaml similarity index 100% rename from test-yaml/intents/system/intent-path-block.yaml rename to test/v1/intents/system/intent-path-block.yaml diff --git a/test-yaml/intents/system/intent-restrict-write-access-to-sys-folders.yaml b/test/v1/intents/system/intent-restrict-write-access-to-sys-folders.yaml similarity index 100% rename from test-yaml/intents/system/intent-restrict-write-access-to-sys-folders.yaml rename to test/v1/intents/system/intent-restrict-write-access-to-sys-folders.yaml diff --git a/test-yaml/intents/template-intent.yaml b/test/v1/intents/template-intent.yaml similarity index 100% rename from test-yaml/intents/template-intent.yaml rename to test/v1/intents/template-intent.yaml diff --git a/test-yaml/policy/cnp/policy-redis.yaml b/test/v1/policy/cnp/policy-redis.yaml similarity index 100% rename from test-yaml/policy/cnp/policy-redis.yaml rename to test/v1/policy/cnp/policy-redis.yaml diff --git a/test-yaml/policy/cnp/policy-risky.yaml b/test/v1/policy/cnp/policy-risky.yaml similarity index 100% rename from test-yaml/policy/cnp/policy-risky.yaml rename to test/v1/policy/cnp/policy-risky.yaml diff --git a/test-yaml/policy/hsp/policy-accessed-shadow-file.yaml b/test/v1/policy/hsp/policy-accessed-shadow-file.yaml similarity index 100% rename from test-yaml/policy/hsp/policy-accessed-shadow-file.yaml rename to test/v1/policy/hsp/policy-accessed-shadow-file.yaml diff --git a/test-yaml/policy/hsp/policy-bug-block.yaml b/test/v1/policy/hsp/policy-bug-block.yaml similarity index 100% rename from test-yaml/policy/hsp/policy-bug-block.yaml rename to test/v1/policy/hsp/policy-bug-block.yaml diff --git a/test-yaml/policy/ksp/policy-audit-all-unlink.yaml b/test/v1/policy/ksp/policy-audit-all-unlink.yaml similarity index 100% rename from test-yaml/policy/ksp/policy-audit-all-unlink.yaml rename to test/v1/policy/ksp/policy-audit-all-unlink.yaml diff --git a/test-yaml/policy/ksp/policy-cap-net-raw-block.yaml b/test/v1/policy/ksp/policy-cap-net-raw-block.yaml similarity index 100% rename from test-yaml/policy/ksp/policy-cap-net-raw-block.yaml rename to test/v1/policy/ksp/policy-cap-net-raw-block.yaml diff --git a/test-yaml/policy/ksp/policy-file-dir-allow-from-source-path.yaml b/test/v1/policy/ksp/policy-file-dir-allow-from-source-path.yaml similarity index 100% rename from test-yaml/policy/ksp/policy-file-dir-allow-from-source-path.yaml rename to test/v1/policy/ksp/policy-file-dir-allow-from-source-path.yaml diff --git a/test-yaml/policy/ksp/policy-net-icmp-audit.yaml b/test/v1/policy/ksp/policy-net-icmp-audit.yaml similarity index 100% rename from test-yaml/policy/ksp/policy-net-icmp-audit.yaml rename to test/v1/policy/ksp/policy-net-icmp-audit.yaml diff --git a/test-yaml/policy/ksp/policy-path-block.yaml b/test/v1/policy/ksp/policy-path-block.yaml similarity index 100% rename from test-yaml/policy/ksp/policy-path-block.yaml rename to test/v1/policy/ksp/policy-path-block.yaml diff --git a/test-yaml/policy/ksp/policy-proc-dir-block.yaml b/test/v1/policy/ksp/policy-proc-dir-block.yaml similarity index 100% rename from test-yaml/policy/ksp/policy-proc-dir-block.yaml rename to test/v1/policy/ksp/policy-proc-dir-block.yaml diff --git a/test/v2/bindings/network/binding-redis.yaml b/test/v2/bindings/network/binding-redis.yaml new file mode 100644 index 00000000..0c7420df --- /dev/null +++ b/test/v2/bindings/network/binding-redis.yaml @@ -0,0 +1,18 @@ +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntentBinding +metadata: + name: net-redis-ingress-deny + namespace: default +spec: + selector: + any: + - resources: + kind: Pod + namespace: default + matchLabels: + app: "redis" + intentRequests: + - type: network + intentName: redis-ingress-deny-traffic + description: "Don’t allow any outside traffic to the Redis port" + mode: strict \ No newline at end of file diff --git a/test/v2/bindings/system/binding-path-block.yaml b/test/v2/bindings/system/binding-path-block.yaml new file mode 100644 index 00000000..755ff69b --- /dev/null +++ b/test/v2/bindings/system/binding-path-block.yaml @@ -0,0 +1,18 @@ +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntentBinding +metadata: + name: sys-proc-path-sleep-block + namespace: multiubuntu +spec: + selector: + any: + - resources: + kind: Pod + namespace: multiubuntu + matchLabels: + group: group-1 + intentRequests: + - type: system + intentName: group-1-proc-path-sleep-block + description: "Block a specific executable /bin/sleep" + mode: strict \ No newline at end of file diff --git a/test/v2/intents/network/intent-redis.yaml b/test/v2/intents/network/intent-redis.yaml new file mode 100644 index 00000000..aac9eb5b --- /dev/null +++ b/test/v2/intents/network/intent-redis.yaml @@ -0,0 +1,17 @@ +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntent +metadata: + name: redis-ingress-deny-traffic + namespace: default +spec: + intent: + description: "Block port 6379" + action: Block + type: network + resource: + - fromCIDRSet: + - cidr: 0.0.0.0/0 + toPorts: + - ports: + - port: "6379" + protocol: tcp diff --git a/test/v2/intents/system/intent-path-block.yaml b/test/v2/intents/system/intent-path-block.yaml new file mode 100644 index 00000000..af15253c --- /dev/null +++ b/test/v2/intents/system/intent-path-block.yaml @@ -0,0 +1,14 @@ +apiVersion: intent.security.nimbus.com/v1 +kind: SecurityIntent +metadata: + name: group-1-proc-path-sleep-block + namespace: multiubuntu +spec: + intent: + description: "block the execution of '/bin/sleep'" + action: Block + type: system + resource: + - process: + - matchPaths: + - path: "/bin/sleep" \ No newline at end of file