Skip to content

Commit

Permalink
cdp: added resources and verbs for the cluster role
Browse files Browse the repository at this point in the history
  • Loading branch information
Yehonathan Bruchim committed Dec 24, 2024
1 parent 3b7cecc commit 58c3975
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 2 deletions.
5 changes: 5 additions & 0 deletions api/falcon/v1alpha1/falconnodesensor_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ type FalconNodeSensorConfig struct {
// For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/docs/ADVANCED.md.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="DaemonSet Advanced Settings"
Advanced FalconAdvanced `json:"advanced,omitempty"`

// Enabled the Cloud Data Protection module
// +kubebuilder:default=true
// +operator-sdk:csv:customresourcedefinitions:type=spec,order=13
CdpRolesEnabled *bool `json:"cdpRolesEnabled,omitempty"`
}

type PriorityClassConfig struct {
Expand Down
5 changes: 5 additions & 0 deletions api/falcon/v1alpha1/zz_generated.deepcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,11 @@ func (in *FalconNodeSensorConfig) DeepCopyInto(out *FalconNodeSensorConfig) {
**out = **in
}
in.Advanced.DeepCopyInto(&out.Advanced)
if in.CdpRolesEnabled != nil {
in, out := &in.CdpRolesEnabled, &out.CdpRolesEnabled
*out = new(bool)
**out = **in
}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconNodeSensorConfig.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ spec:
- kernel
- bpf
type: string
cdpRolesEnabled:
default: true
description: Enabled the Cloud Data Protection module
type: boolean
disableCleanup:
default: false
description: Disables the cleanup of the sensor through DaemonSet
Expand Down
7 changes: 7 additions & 0 deletions deploy/falcon-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3259,6 +3259,10 @@ spec:
- kernel
- bpf
type: string
cdpRolesEnabled:
default: true
description: Enabled the Cloud Data Protection module
type: boolean
disableCleanup:
default: false
description: Disables the cleanup of the sensor through DaemonSet
Expand Down Expand Up @@ -4317,6 +4321,9 @@ rules:
- securitycontextconstraints
verbs:
- use
- apiGroups: [""]
resources: ["pods", "services", "nodes", "daemonsets", "replicasets", "deployments", "jobs", "ingresses", "cronjobs", "persistentvolumes"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
Expand Down
1 change: 1 addition & 0 deletions docs/resources/node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ spec:
| node.backend | (optional) Configure the backend mode for Falcon Sensor (allowed values: kernel, bpf) |
| node.disableCleanup | (optional) Cleans up `/opt/CrowdStrike` on the nodes by deleting the files and directory. |
| node.version | (optional) Enforce particular Falcon Sensor version to be installed (example: "6.35", "6.35.0-13207") |
| node.cdpRolesEnabled | (Enable cluster roles for Cloud Data Protection module |

#### Falcon Sensor Settings
| Spec | Description |
Expand Down
58 changes: 56 additions & 2 deletions internal/controller/falcon_node/falconnodesensor_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package falcon

import (
"context"
goerr "errors"
"reflect"

falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
Expand All @@ -15,6 +16,7 @@ import (
"github.com/crowdstrike/gofalcon/falcon"
"github.com/go-logr/logr"
"github.com/operator-framework/operator-lib/proxy"
"golang.org/x/exp/slices"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
Expand All @@ -33,6 +35,16 @@ import (
clog "sigs.k8s.io/controller-runtime/pkg/log"
)

var (
cdpRoleEnabledNil = goerr.New("CdpRolesEnabled must be defined")

cdpRoles = rbacv1.PolicyRule{
APIGroups: []string{""},
Verbs: []string{"get", "watch", "list"},
Resources: []string{"pods", "services", "nodes", "daemonsets", "replicasets", "deployments", "jobs", "ingresses", "cronjobs", "persistentvolumes"},
}
)

// FalconNodeSensorReconciler reconciles a FalconNodeSensor object
type FalconNodeSensorReconciler struct {
client.Client
Expand Down Expand Up @@ -790,6 +802,11 @@ func (r *FalconNodeSensorReconciler) handlePermissions(ctx context.Context, node
return created, err
}

created, err = r.handleClusterRole(ctx, nodesensor, logger)
if created || err != nil {
return created, err
}

return r.handleClusterRoleBinding(ctx, nodesensor, logger)
}

Expand All @@ -810,7 +827,7 @@ func (r *FalconNodeSensorReconciler) handleClusterRoleBinding(ctx context.Contex
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "ClusterRole",
Name: "falcon-operator-node-sensor-role",
Name: common.NodeClusterRoleName,
},
Subjects: []rbacv1.Subject{
{
Expand All @@ -829,7 +846,7 @@ func (r *FalconNodeSensorReconciler) handleClusterRoleBinding(ctx context.Contex
logger.Info("Creating FalconNodeSensor ClusterRoleBinding")
err = r.Create(ctx, &binding)
if err != nil && !errors.IsAlreadyExists(err) {
logger.Error(err, "Failed to create new ClusterRoleBinding", "ClusteRoleBinding.Name", common.NodeClusterRoleBindingName)
logger.Error(err, "Failed to create new ClusterRoleBinding", "ClusterRoleBinding.Name", common.NodeClusterRoleBindingName)
return false, err
}

Expand Down Expand Up @@ -880,6 +897,43 @@ func (r *FalconNodeSensorReconciler) handleServiceAccount(ctx context.Context, n
return false, nil
}

// handleClusterRole updates the cluster role and grants necessary permissions to it
func (r *FalconNodeSensorReconciler) handleClusterRole(ctx context.Context, nodesensor *falconv1alpha1.FalconNodeSensor, logger logr.Logger) (bool, error) {
if nodesensor.Spec.Node.CdpRolesEnabled == nil {
return false, cdpRoleEnabledNil
}

if *nodesensor.Spec.Node.CdpRolesEnabled == false {
return false, nil
}
clusterRole := rbacv1.ClusterRole{}
err := r.Get(ctx, types.NamespacedName{Name: common.NodeClusterRoleName}, &clusterRole)
if err != nil {
logger.Error(err, "Failed to get FalconNodeSensor ClusterRole")
return false, err
}

// check if CDP cluster role was already set
for _, rule := range clusterRole.Rules {
if slices.Equal(rule.Resources, cdpRoles.Resources) &&
slices.Equal(rule.Verbs, cdpRoles.Verbs) &&
slices.Equal(rule.APIGroups, cdpRoles.APIGroups) {
return false, nil
}
}

clusterRole.Rules = append(clusterRole.Rules, cdpRoles)

err = r.Update(ctx, &clusterRole)
if err != nil {
logger.Error(err, "Failed to create new ClusterRole", "Namespace.Name", nodesensor.Spec.InstallNamespace, "ClusterRole.Name", common.NodeClusterRoleName)
return false, err
}
logger.Info("Updated FalconNodeSensor ClusterRole")
return true, nil

}

// handleServiceAccount creates and updates the service account and grants necessary permissions to it
func (r *FalconNodeSensorReconciler) handleSAAnnotations(ctx context.Context, nodesensor *falconv1alpha1.FalconNodeSensor, logger logr.Logger) error {
sa := corev1.ServiceAccount{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ var _ = Describe("FalconNodeSensor controller", func() {
})
Expect(err).To(Not(HaveOccurred()))

// ClusterRole reconcile
_, err = falconNodeReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespaceName,
})
Expect(err).To(Not(HaveOccurred()))

// TODO: clusterRoleBinding reconciliation might be removed in the future
_, err = falconNodeReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespaceName,
Expand Down
1 change: 1 addition & 0 deletions pkg/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ const (
AdmissionServiceAccountName = "falcon-operator-admission-controller"
NodeClusterRoleBindingName = "falcon-operator-node-sensor-rolebinding"
ImageServiceAccountName = "falcon-operator-image-analyzer"
NodeClusterRoleName = "falcon-operator-node-sensor-role"
)

0 comments on commit 58c3975

Please sign in to comment.