From d3f4c31e931f11ca7d7c8927f560d2662c9205cf Mon Sep 17 00:00:00 2001 From: Greg Pontejos Date: Wed, 11 Dec 2024 15:25:36 -0600 Subject: [PATCH] Update tolerations to accommodate an empty list --- api/falcon/v1alpha1/falconnodesensor_types.go | 2 +- api/falcon/v1alpha1/zz_generated.deepcopy.go | 10 +++-- deploy/falcon-operator.yaml | 2 + docs/src/resources/node.md.tmpl | 3 ++ internal/controller/assets/daemonset.go | 4 +- internal/controller/assets/daemonset_test.go | 38 ++++++++++++++++++- .../falconnodesensor_controller.go | 6 +-- 7 files changed, 54 insertions(+), 11 deletions(-) diff --git a/api/falcon/v1alpha1/falconnodesensor_types.go b/api/falcon/v1alpha1/falconnodesensor_types.go index a9902018..ee0aff4d 100644 --- a/api/falcon/v1alpha1/falconnodesensor_types.go +++ b/api/falcon/v1alpha1/falconnodesensor_types.go @@ -44,7 +44,7 @@ type FalconNodeSensorConfig struct { // Specifies tolerations for custom taints. Defaults to allowing scheduling on all nodes. // +kubebuilder:default:={{key: "node-role.kubernetes.io/master", operator: "Exists", effect: "NoSchedule"}, {key: "node-role.kubernetes.io/control-plane", operator: "Exists", effect: "NoSchedule"}, {key: "node-role.kubernetes.io/infra", operator: "Exists", effect: "NoSchedule"}} // +operator-sdk:csv:customresourcedefinitions:type=spec,order=4 - Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + Tolerations *[]corev1.Toleration `json:"tolerations"` // Specifies node affinity for scheduling the DaemonSet. Defaults to allowing scheduling on all nodes. // +operator-sdk:csv:customresourcedefinitions:type=spec,order=5 diff --git a/api/falcon/v1alpha1/zz_generated.deepcopy.go b/api/falcon/v1alpha1/zz_generated.deepcopy.go index 89f39d3a..f1490388 100644 --- a/api/falcon/v1alpha1/zz_generated.deepcopy.go +++ b/api/falcon/v1alpha1/zz_generated.deepcopy.go @@ -1057,9 +1057,13 @@ func (in *FalconNodeSensorConfig) DeepCopyInto(out *FalconNodeSensorConfig) { *out = *in if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]corev1.Toleration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) + *out = new([]corev1.Toleration) + if **in != nil { + in, out := *in, *out + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } in.NodeAffinity.DeepCopyInto(&out.NodeAffinity) diff --git a/deploy/falcon-operator.yaml b/deploy/falcon-operator.yaml index da6b3a14..feba975c 100644 --- a/deploy/falcon-operator.yaml +++ b/deploy/falcon-operator.yaml @@ -3699,6 +3699,8 @@ spec: description: Version of the sensor to be installed. The latest version will be selected when this version specifier is missing. type: string + required: + - tolerations type: object type: object status: diff --git a/docs/src/resources/node.md.tmpl b/docs/src/resources/node.md.tmpl index a79b284a..7fa9fb19 100644 --- a/docs/src/resources/node.md.tmpl +++ b/docs/src/resources/node.md.tmpl @@ -69,6 +69,9 @@ spec: | 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") | +> [!IMPORTANT] +> node.tolerations will be appended to the existing tolerations for the daemonset due to GKE Autopilot allowing users to manage Tolerations directly in the console. See documentation here: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-separation. Removing Tolerations from an existing daemonset requires a redeploy of the FalconNodeSensor manifest. + #### Falcon Sensor Settings | Spec | Description | | :---------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/internal/controller/assets/daemonset.go b/internal/controller/assets/daemonset.go index e371016a..07388fa7 100644 --- a/internal/controller/assets/daemonset.go +++ b/internal/controller/assets/daemonset.go @@ -213,7 +213,7 @@ func Daemonset(dsName, image, serviceAccount string, node *falconv1alpha1.Falcon // NodeSelector is set to linux until windows containers are supported for the Falcon sensor NodeSelector: common.NodeSelector, Affinity: nodeAffinity(node), - Tolerations: node.Spec.Node.Tolerations, + Tolerations: *node.Spec.Node.Tolerations, HostPID: hostpid, HostIPC: hostipc, HostNetwork: hostnetwork, @@ -304,7 +304,7 @@ func RemoveNodeDirDaemonset(dsName, image, serviceAccount string, node *falconv1 // NodeSelector is set to linux until windows containers are supported for the Falcon sensor NodeSelector: common.NodeSelector, Affinity: nodeAffinity(node), - Tolerations: node.Spec.Node.Tolerations, + Tolerations: *node.Spec.Node.Tolerations, HostPID: hostpid, TerminationGracePeriodSeconds: getTermGracePeriod(node), ImagePullSecrets: pullSecrets(node), diff --git a/internal/controller/assets/daemonset_test.go b/internal/controller/assets/daemonset_test.go index 58169103..3d6967f6 100644 --- a/internal/controller/assets/daemonset_test.go +++ b/internal/controller/assets/daemonset_test.go @@ -188,6 +188,23 @@ func TestDaemonset(t *testing.T) { falconNode.Name = "test" image := "testImage" dsName := "test-DaemonSet" + falconNode.Spec.Node.Tolerations = &[]corev1.Toleration{ + { + Key: "node-role.kubernetes.io/master", + Operator: "Exists", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/control-plane", + Operator: "Exists", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/infra", + Operator: "Exists", + Effect: "NoSchedule", + }, + } privileged := true escalation := true @@ -219,7 +236,7 @@ func TestDaemonset(t *testing.T) { // NodeSelector is set to linux until windows containers are supported for the Falcon sensor NodeSelector: common.NodeSelector, Affinity: nodeAffinity(&falconNode), - Tolerations: falconNode.Spec.Node.Tolerations, + Tolerations: *falconNode.Spec.Node.Tolerations, HostPID: hostpid, HostIPC: hostipc, HostNetwork: hostnetwork, @@ -298,6 +315,23 @@ func TestRemoveNodeDirDaemonset(t *testing.T) { falconNode.Name = "test" image := "testImage" dsName := "test-DaemonSet" + falconNode.Spec.Node.Tolerations = &[]corev1.Toleration{ + { + Key: "node-role.kubernetes.io/master", + Operator: "Exists", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/control-plane", + Operator: "Exists", + Effect: "NoSchedule", + }, + { + Key: "node-role.kubernetes.io/infra", + Operator: "Exists", + Effect: "NoSchedule", + }, + } privileged := true nonPrivileged := false @@ -326,7 +360,7 @@ func TestRemoveNodeDirDaemonset(t *testing.T) { // NodeSelector is set to linux until windows containers are supported for the Falcon sensor NodeSelector: common.NodeSelector, Affinity: nodeAffinity(&falconNode), - Tolerations: falconNode.Spec.Node.Tolerations, + Tolerations: *falconNode.Spec.Node.Tolerations, HostPID: hostpid, TerminationGracePeriodSeconds: getTermGracePeriod(&falconNode), ImagePullSecrets: pullSecrets(&falconNode), diff --git a/internal/controller/falcon_node/falconnodesensor_controller.go b/internal/controller/falcon_node/falconnodesensor_controller.go index 33eac247..5cc63820 100644 --- a/internal/controller/falcon_node/falconnodesensor_controller.go +++ b/internal/controller/falcon_node/falconnodesensor_controller.go @@ -639,12 +639,12 @@ func updateDaemonSetContainerProxy(ds *appsv1.DaemonSet, logger logr.Logger) boo func (r *FalconNodeSensorReconciler) updateDaemonSetTolerations(ctx context.Context, ds *appsv1.DaemonSet, nodesensor *falconv1alpha1.FalconNodeSensor, logger logr.Logger) (bool, error) { tolerations := &ds.Spec.Template.Spec.Tolerations origTolerations := nodesensor.Spec.Node.Tolerations - tolerationsUpdate := !equality.Semantic.DeepEqual(*tolerations, origTolerations) + tolerationsUpdate := !equality.Semantic.DeepEqual(*tolerations, *origTolerations) if tolerationsUpdate { logger.Info("Updating FalconNodeSensor DaemonSet Tolerations") - mergedTolerations := k8s_utils.MergeTolerations(*tolerations, origTolerations) + mergedTolerations := k8s_utils.MergeTolerations(*tolerations, *origTolerations) *tolerations = mergedTolerations - nodesensor.Spec.Node.Tolerations = mergedTolerations + nodesensor.Spec.Node.Tolerations = &mergedTolerations if err := r.Update(ctx, nodesensor); err != nil { logger.Error(err, "Failed to update FalconNodeSensor Tolerations")