diff --git a/cmd/main.go b/cmd/main.go index 5f791ef4..2982f5fe 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -26,9 +26,8 @@ import ( // Importing custom API types and controllers intentv1 "github.com/5GSEC/nimbus/pkg/api/v1" "github.com/5GSEC/nimbus/pkg/controllers" - cleanup "github.com/5GSEC/nimbus/pkg/controllers/cleanup" - general "github.com/5GSEC/nimbus/pkg/controllers/general" - policy "github.com/5GSEC/nimbus/pkg/controllers/policy" + "github.com/5GSEC/nimbus/pkg/controllers/cleanup" + "github.com/5GSEC/nimbus/pkg/controllers/general" // Importing third-party Kubernetes resource types ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" @@ -103,8 +102,6 @@ func main() { os.Exit(1) } - policyController := policy.NewPolicyController(mgr.GetClient(), mgr.GetScheme()) - // Setting up the SecurityIntentReconciler controller with the manager. if err = (&controllers.SecurityIntentReconciler{ Client: mgr.GetClient(), @@ -119,7 +116,6 @@ func main() { 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) diff --git a/config/crd/bases/intent.security.nimbus.com_securityintentbindings.yaml b/config/crd/bases/intent.security.nimbus.com_securityintentbindings.yaml index 04f9fe56..d9cdade4 100644 --- a/config/crd/bases/intent.security.nimbus.com_securityintentbindings.yaml +++ b/config/crd/bases/intent.security.nimbus.com_securityintentbindings.yaml @@ -37,23 +37,14 @@ spec: spec: description: SecurityIntentBindingSpec defines the desired state of SecurityIntentBinding properties: - intentRequests: + intents: items: description: IntentRequest defines the request for a specific SecurityIntent properties: - description: - type: string - intentName: - type: string - mode: - type: string - type: + name: type: string required: - - description - - intentName - - mode - - type + - name type: object type: array selector: @@ -104,7 +95,7 @@ spec: type: array type: object required: - - intentRequests + - intents - selector type: object status: diff --git a/config/crd/bases/intent.security.nimbus.com_securityintents.yaml b/config/crd/bases/intent.security.nimbus.com_securityintents.yaml index 8862887f..7771e021 100644 --- a/config/crd/bases/intent.security.nimbus.com_securityintents.yaml +++ b/config/crd/bases/intent.security.nimbus.com_securityintents.yaml @@ -12,7 +12,7 @@ spec: listKind: SecurityIntentList plural: securityintents shortNames: - - sit + - si singular: securityintent scope: Namespaced versions: @@ -37,187 +37,46 @@ spec: description: SecurityIntentSpec defines the desired state of SecurityIntent properties: intent: - description: Intent defines the security policy details + description: Intent defines a security intention that can be used + to generate multiple security policies. properties: action: + description: Action defines how the security policy will be enforced. type: string description: + description: Description is human-readable explanation of the + intent's purpose. type: string - resource: + id: + description: ID is predefined in Security Intent pool. It uniquely + identifies a specific security intent. + type: string + mode: + description: Mode defines the enforcement behavior of the intent. + Defaults to best-effort. + type: string + params: + additionalProperties: + items: + type: string + type: array + description: Params are key-value pairs that allows fine-tuning + of intents to specific requirements. + type: object + severity: + description: Severity defines the potential impact of a security + violation related to the intent. Defaults to Low. + type: string + tags: + description: Tags are additional metadata for categorization and + grouping of intents. Facilitates searching, filtering, and management + of security policies. items: - description: Resource defines the resources that the security - policy applies to - properties: - capabilities: - items: - 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 - recursive: - type: boolean - 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 - fromCIDRSet: - items: - 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: - fromSource: - items: - description: FromSource defines a source path - for directory-based policies - properties: - path: - type: string - type: object - type: array - 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 - recursive: - type: boolean - 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 - type: object + type: string type: array - type: - type: string required: - action - - resource - - type + - id type: object required: - intent diff --git a/pkg/api/v1/securityintent_types.go b/pkg/api/v1/securityintent_types.go index 671198c1..12cc5d74 100644 --- a/pkg/api/v1/securityintent_types.go +++ b/pkg/api/v1/securityintent_types.go @@ -18,105 +18,31 @@ type SecurityIntentSpec struct { Intent Intent `json:"intent"` // Define the details of the security policy. } -// Intent defines the security policy details +// Intent defines a security intention that can be used to generate multiple security policies. type Intent struct { - Description string `json:"description,omitempty"` // 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"` -} + // ID is predefined in Security Intent pool. It uniquely identifies a specific security intent. + ID string `json:"id"` -// CIDRSet defines CIDR ranges for network policies -type CIDRSet struct { - CIDR string `json:"cidr,omitempty"` -} + // Description is human-readable explanation of the intent's purpose. + Description string `json:"description,omitempty"` -// ToPort defines ports and protocols for network policies -type ToPort struct { - Ports []Port `json:"ports,omitempty"` -} + // Action defines how the security policy will be enforced. + Action string `json:"action"` -// Port defines a network port and its protocol -type Port struct { - Port string `json:"port,omitempty"` - Protocol string `json:"protocol,omitempty"` -} + // Mode defines the enforcement behavior of the intent. + // Defaults to best-effort. + Mode string `json:"mode,omitempty"` -// MatchProtocol defines a protocol for network policies -type MatchProtocol struct { - Protocol string `json:"protocol,omitempty"` - FromSource []FromSource `json:"fromSource,omitempty"` -} + // Severity defines the potential impact of a security violation related to the intent. + // Defaults to Low. + Severity string `json:"severity,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"` - Recursive bool `json:"recursive,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"` -} + // Tags are additional metadata for categorization and grouping of intents. + // Facilitates searching, filtering, and management of security policies. + Tags []string `json:"tags,omitempty"` -// FromSource defines a source path for directory-based policies -type FromSource struct { - Path string `json:"path,omitempty"` + // Params are key-value pairs that allows fine-tuning of intents to specific requirements. + Params map[string][]string `json:"params,omitempty"` } // SecurityIntentStatus defines the observed state of SecurityIntent @@ -128,7 +54,7 @@ type SecurityIntentStatus struct { // SecurityIntent is the Schema for the securityintents API // +kubebuilder:object:root=true -// +kubebuilder:resource: shortName="sit" +// +kubebuilder:resource: shortName="si" // +kubebuilder:subresource:status // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/api/v1/securityintentbinding_types.go b/pkg/api/v1/securityintentbinding_types.go index d90dbc7f..b4ec0323 100644 --- a/pkg/api/v1/securityintentbinding_types.go +++ b/pkg/api/v1/securityintentbinding_types.go @@ -16,8 +16,8 @@ type SecurityIntentBindingSpec struct { // 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 Selector `json:"selector"` + Intents []IntentRequest `json:"intents"` } // Selector defines the selection criteria for resources @@ -41,10 +41,7 @@ type Resources struct { // 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"` + Name string `json:"name"` } // SecurityIntentBindingStatus defines the observed state of SecurityIntentBinding diff --git a/pkg/api/v1/zz_generated.deepcopy.go b/pkg/api/v1/zz_generated.deepcopy.go index 0c0951c5..ec45a50b 100644 --- a/pkg/api/v1/zz_generated.deepcopy.go +++ b/pkg/api/v1/zz_generated.deepcopy.go @@ -12,90 +12,27 @@ import ( ) // 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) { +func (in *Intent) DeepCopyInto(out *Intent) { *out = *in - if in.MatchPaths != nil { - in, out := &in.MatchPaths, &out.MatchPaths - *out = make([]MatchPath, len(*in)) + if in.Tags != nil { + in, out := &in.Tags, &out.Tags + *out = make([]string, 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]) + if in.Params != nil { + in, out := &in.Params, &out.Params + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal } } } @@ -125,242 +62,6 @@ func (in *IntentRequest) DeepCopy() *IntentRequest { 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 - 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 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)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// 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 @@ -489,8 +190,8 @@ func (in *SecurityIntentBindingList) DeepCopyObject() runtime.Object { func (in *SecurityIntentBindingSpec) DeepCopyInto(out *SecurityIntentBindingSpec) { *out = *in in.Selector.DeepCopyInto(&out.Selector) - if in.IntentRequests != nil { - in, out := &in.IntentRequests, &out.IntentRequests + if in.Intents != nil { + in, out := &in.Intents, &out.Intents *out = make([]IntentRequest, len(*in)) copy(*out, *in) } @@ -617,45 +318,3 @@ func (in *Selector) DeepCopy() *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/pkg/controllers/cleanup/cleanup.go b/pkg/controllers/cleanup/cleanup.go index 1d68aa62..3ec7b0b4 100644 --- a/pkg/controllers/cleanup/cleanup.go +++ b/pkg/controllers/cleanup/cleanup.go @@ -10,8 +10,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" intentv1 "github.com/5GSEC/nimbus/pkg/api/v1" - general "github.com/5GSEC/nimbus/pkg/controllers/general" - policy "github.com/5GSEC/nimbus/pkg/controllers/policy" ) // Cleanup is a function to clean up SecurityIntent resources. @@ -32,20 +30,9 @@ func Cleanup(ctx context.Context, k8sClient client.Client, logger logr.Logger) e 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 diff --git a/pkg/controllers/general/general_controller.go b/pkg/controllers/general/general_controller.go index ca28a2d1..fff21a83 100644 --- a/pkg/controllers/general/general_controller.go +++ b/pkg/controllers/general/general_controller.go @@ -58,7 +58,7 @@ func (gc *GeneralController) Reconcile(ctx context.Context, req ctrl.Request) (* intent, err := gc.WatcherIntent.Reconcile(ctx, req) if err != nil { - return nil, fmt.Errorf("Error in WatcherIntent.Reconcile: %v", err) + return nil, fmt.Errorf("error in WatcherIntent.Reconcile: %v", err) } if intent != nil { @@ -71,13 +71,13 @@ func (gc *GeneralController) Reconcile(ctx context.Context, req ctrl.Request) (* binding, err := gc.WatcherBinding.Reconcile(ctx, req) if err != nil { - return nil, fmt.Errorf("Error in WatcherBinding.Reconcile: %v", err) + 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 nil, fmt.Errorf("error in MatchIntentAndBinding: %v", err) } return bindingInfo, nil } diff --git a/pkg/controllers/general/match_intent.go b/pkg/controllers/general/match_intent.go index e2861db9..dd8d1eec 100644 --- a/pkg/controllers/general/match_intent.go +++ b/pkg/controllers/general/match_intent.go @@ -32,12 +32,12 @@ func MatchIntentAndBinding(ctx context.Context, client client.Client, binding *i } var matchedIntents []*intentv1.SecurityIntent - for _, intentReq := range binding.Spec.IntentRequests { + for _, intentReq := range binding.Spec.Intents { intent := &intentv1.SecurityIntent{} - err := client.Get(ctx, types.NamespacedName{Name: intentReq.IntentName, Namespace: binding.Namespace}, intent) + err := client.Get(ctx, types.NamespacedName{Name: intentReq.Name, 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) + log.Error(err, "Failed to get SecurityIntent", "IntentName", intentReq.Name, "Namespace", binding.Namespace) + return nil, fmt.Errorf("failed to get SecurityIntent '%s' in namespace '%s': %v", intentReq.Name, binding.Namespace, err) } matchedIntents = append(matchedIntents, intent) } diff --git a/pkg/controllers/policy/network_policy.go b/pkg/controllers/policy/network_policy.go deleted file mode 100644 index e207c804..00000000 --- a/pkg/controllers/policy/network_policy.go +++ /dev/null @@ -1,63 +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" - - ciliumv2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2" - - general "github.com/5GSEC/nimbus/pkg/controllers/general" - utils "github.com/5GSEC/nimbus/pkg/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/pkg/controllers/policy/policy_controller.go b/pkg/controllers/policy/policy_controller.go deleted file mode 100644 index 1effee67..00000000 --- a/pkg/controllers/policy/policy_controller.go +++ /dev/null @@ -1,79 +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" - - general "github.com/5GSEC/nimbus/pkg/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/pkg/controllers/policy/system_policy.go b/pkg/controllers/policy/system_policy.go deleted file mode 100644 index 3d8c1403..00000000 --- a/pkg/controllers/policy/system_policy.go +++ /dev/null @@ -1,62 +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" - - general "github.com/5GSEC/nimbus/pkg/controllers/general" - utils "github.com/5GSEC/nimbus/pkg/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/pkg/controllers/securityintentbinding_controller.go b/pkg/controllers/securityintentbinding_controller.go index 4bbaa645..3b0ed28a 100644 --- a/pkg/controllers/securityintentbinding_controller.go +++ b/pkg/controllers/securityintentbinding_controller.go @@ -14,7 +14,6 @@ import ( intentv1 "github.com/5GSEC/nimbus/pkg/api/v1" general "github.com/5GSEC/nimbus/pkg/controllers/general" - policy "github.com/5GSEC/nimbus/pkg/controllers/policy" ) // SecurityIntentBindingReconciler reconciles a SecurityIntentBinding object @@ -22,33 +21,6 @@ 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 @@ -81,21 +53,11 @@ func (r *SecurityIntentBindingReconciler) Reconcile(ctx context.Context, req ctr if binding != nil { log.Info("SecurityIntentBinding resource found", "Name", req.Name, "Namespace", req.Namespace) - bindingInfo, err := general.MatchIntentAndBinding(ctx, r.Client, binding) + _, 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) } diff --git a/pkg/controllers/utils/utils_policy.go b/pkg/controllers/utils/utils_policy.go deleted file mode 100644 index e4e918f2..00000000 --- a/pkg/controllers/utils/utils_policy.go +++ /dev/null @@ -1,425 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright 2023 Authors of Nimbus - -package utils - -import ( - "context" - "fmt" - "reflect" - "strings" - - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - - general "github.com/5GSEC/nimbus/pkg/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), - Recursive: dir.Recursive, - 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), - Recursive: dir.Recursive, - 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 { - var fromSources []kubearmorv1.MatchSourceType - for _, source := range matchProtocol.FromSource { - fromSources = append(fromSources, kubearmorv1.MatchSourceType{ - Path: kubearmorv1.MatchPathType(source.Path), - }) - } - if matchProtocol.Protocol != "" { - networkType.MatchProtocols = append(networkType.MatchProtocols, kubearmorv1.MatchNetworkProtocolType{ - Protocol: kubearmorv1.MatchNetworkProtocolStringType(matchProtocol.Protocol), - FromSource: fromSources, - }) - } - } - } - } 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 -}