Skip to content

Commit

Permalink
Merge pull request #570 from CrowdStrike/mhyson/sensor-update-policy
Browse files Browse the repository at this point in the history
feat: add support for sensor version selection by update policy
  • Loading branch information
mhyson-cs authored Aug 16, 2024
2 parents d8b487f + ae9c8fb commit c41b187
Show file tree
Hide file tree
Showing 29 changed files with 632 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# To re-generate a bundle for another specific version without changing the standard setup, you can:
# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
VERSION ?= 1.0.0
VERSION ?= 1.1.0

# CHANNELS define the bundle channels used in the bundle.
# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable")
Expand Down
3 changes: 3 additions & 0 deletions UNSAFE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Unsafe Settings

To be written ...
6 changes: 6 additions & 0 deletions api/falcon/v1alpha1/falconadmission_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ type FalconAdmissionSpec struct {
// Falcon Admission Controller Version. The latest version will be selected when version specifier is missing. Example: 6.31, 6.31.0, 6.31.0-1409, etc.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Admission Controller Version",order=8
Version *string `json:"version,omitempty"`

// FalconUnsafe configures various options that go against industry practices or are otherwise not recommended for use.
// Adjusting these settings may result in incorrect or undesirable behavior. Proceed at your own risk.
// For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Admission Controller Unsafe Settings"
Unsafe FalconUnsafe `json:"unsafe,omitempty"`
}

type FalconAdmissionRQSpec struct {
Expand Down
6 changes: 6 additions & 0 deletions api/falcon/v1alpha1/falconcontainer_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ type FalconContainerSpec struct {
// Falcon Container Version. The latest version will be selected when version specifier is missing; ignored when Image is set.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Container Image Version",order=6
Version *string `json:"version,omitempty"`

// FalconUnsafe configures various options that go against industry practices or are otherwise not recommended for use.
// Adjusting these settings may result in incorrect or undesirable behavior. Proceed at your own risk.
// For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Container Unsafe Settings"
Unsafe FalconUnsafe `json:"unsafe,omitempty"`
}

type FalconContainerInjectorSpec struct {
Expand Down
6 changes: 6 additions & 0 deletions api/falcon/v1alpha1/falconnodesensor_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ type FalconNodeSensorConfig struct {

// Version of the sensor to be installed. The latest version will be selected when this version specifier is missing.
Version *string `json:"version,omitempty"`

// FalconUnsafe configures various options that go against industry practices or are otherwise not recommended for use.
// Adjusting these settings may result in incorrect or undesirable behavior. Proceed at your own risk.
// For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="DaemonSet Unsafe Settings"
Unsafe FalconUnsafe `json:"unsafe,omitempty"`
}

type PriorityClassConfig struct {
Expand Down
10 changes: 10 additions & 0 deletions api/falcon/v1alpha1/unsafe.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package v1alpha1

// FalconUnsafe configures various options that go against industry practices or are otherwise not recommended for use.
// Adjusting these settings may result in incorrect or undesirable behavior. Proceed at your own risk.
// For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
type FalconUnsafe struct {
// UpdatePolicy is the name of a sensor update policy configured and enabled in Falcon UI. It is ignored when Image and/or Version are set.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Sensor Update Policy",order=1
UpdatePolicy *string `json:"updatePolicy,omitempty"`
}
23 changes: 23 additions & 0 deletions api/falcon/v1alpha1/zz_generated.deepcopy.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ func (in *FalconAdmissionSpec) DeepCopyInto(out *FalconAdmissionSpec) {
*out = new(string)
**out = **in
}
in.Unsafe.DeepCopyInto(&out.Unsafe)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconAdmissionSpec.
Expand Down Expand Up @@ -739,6 +740,7 @@ func (in *FalconContainerSpec) DeepCopyInto(out *FalconContainerSpec) {
*out = new(string)
**out = **in
}
in.Unsafe.DeepCopyInto(&out.Unsafe)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconContainerSpec.
Expand Down Expand Up @@ -1032,6 +1034,7 @@ func (in *FalconNodeSensorConfig) DeepCopyInto(out *FalconNodeSensorConfig) {
*out = new(string)
**out = **in
}
in.Unsafe.DeepCopyInto(&out.Unsafe)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconNodeSensorConfig.
Expand Down Expand Up @@ -1198,6 +1201,26 @@ func (in *FalconSensor) DeepCopy() *FalconSensor {
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FalconUnsafe) DeepCopyInto(out *FalconUnsafe) {
*out = *in
if in.UpdatePolicy != nil {
in, out := &in.UpdatePolicy, &out.UpdatePolicy
*out = new(string)
**out = **in
}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconUnsafe.
func (in *FalconUnsafe) DeepCopy() *FalconUnsafe {
if in == nil {
return nil
}
out := new(FalconUnsafe)
in.DeepCopyInto(out)
return out
}

// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PriorityClassConfig) DeepCopyInto(out *PriorityClassConfig) {
*out = *in
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/falcon.crowdstrike.com_falconadmissions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,18 @@ spec:
can be created in the namespace.
type: string
type: object
unsafe:
description: FalconUnsafe configures various options that go against
industry practices or are otherwise not recommended for use. Adjusting
these settings may result in incorrect or undesirable behavior.
Proceed at your own risk. For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
properties:
updatePolicy:
description: UpdatePolicy is the name of a sensor update policy
configured and enabled in Falcon UI. It is ignored when Image
and/or Version are set.
type: string
type: object
version:
description: 'Falcon Admission Controller Version. The latest version
will be selected when version specifier is missing. Example: 6.31,
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/falcon.crowdstrike.com_falconcontainers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,18 @@ spec:
required:
- type
type: object
unsafe:
description: FalconUnsafe configures various options that go against
industry practices or are otherwise not recommended for use. Adjusting
these settings may result in incorrect or undesirable behavior.
Proceed at your own risk. For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
properties:
updatePolicy:
description: UpdatePolicy is the name of a sensor update policy
configured and enabled in Falcon UI. It is ignored when Image
and/or Version are set.
type: string
type: object
version:
description: Falcon Container Version. The latest version will be
selected when version specifier is missing; ignored when Image is
Expand Down
13 changes: 13 additions & 0 deletions config/crd/bases/falcon.crowdstrike.com_falconnodesensors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,19 @@ spec:
type: string
type: object
type: array
unsafe:
description: FalconUnsafe configures various options that go against
industry practices or are otherwise not recommended for use.
Adjusting these settings may result in incorrect or undesirable
behavior. Proceed at your own risk. For more information, please
see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
properties:
updatePolicy:
description: UpdatePolicy is the name of a sensor update policy
configured and enabled in Falcon UI. It is ignored when
Image and/or Version are set.
type: string
type: object
updateStrategy:
description: Type of DaemonSet update. Can be "RollingUpdate"
or "OnDelete". Default is RollingUpdate.
Expand Down
37 changes: 37 additions & 0 deletions deploy/falcon-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,18 @@ spec:
can be created in the namespace.
type: string
type: object
unsafe:
description: FalconUnsafe configures various options that go against
industry practices or are otherwise not recommended for use. Adjusting
these settings may result in incorrect or undesirable behavior.
Proceed at your own risk. For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
properties:
updatePolicy:
description: UpdatePolicy is the name of a sensor update policy
configured and enabled in Falcon UI. It is ignored when Image
and/or Version are set.
type: string
type: object
version:
description: 'Falcon Admission Controller Version. The latest version
will be selected when version specifier is missing. Example: 6.31,
Expand Down Expand Up @@ -2479,6 +2491,18 @@ spec:
required:
- type
type: object
unsafe:
description: FalconUnsafe configures various options that go against
industry practices or are otherwise not recommended for use. Adjusting
these settings may result in incorrect or undesirable behavior.
Proceed at your own risk. For more information, please see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
properties:
updatePolicy:
description: UpdatePolicy is the name of a sensor update policy
configured and enabled in Falcon UI. It is ignored when Image
and/or Version are set.
type: string
type: object
version:
description: Falcon Container Version. The latest version will be
selected when version specifier is missing; ignored when Image is
Expand Down Expand Up @@ -3503,6 +3527,19 @@ spec:
type: string
type: object
type: array
unsafe:
description: FalconUnsafe configures various options that go against
industry practices or are otherwise not recommended for use.
Adjusting these settings may result in incorrect or undesirable
behavior. Proceed at your own risk. For more information, please
see https://github.com/CrowdStrike/falcon-operator/blob/main/UNSAFE.md.
properties:
updatePolicy:
description: UpdatePolicy is the name of a sensor update policy
configured and enabled in Falcon UI. It is ignored when
Image and/or Version are set.
type: string
type: object
updateStrategy:
description: Type of DaemonSet update. Can be "RollingUpdate"
or "OnDelete". Default is RollingUpdate.
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ require (
github.com/containers/image/v5 v5.31.1
github.com/crowdstrike/gofalcon v0.6.0
github.com/go-logr/logr v1.4.1
github.com/go-openapi/swag v0.23.0
github.com/google/go-cmp v0.6.0
github.com/onsi/ginkgo/v2 v2.9.5
github.com/onsi/gomega v1.27.7
github.com/openshift/api v0.0.0-20220630121623-32f1d77b9f50
github.com/operator-framework/operator-lib v0.11.0
github.com/stretchr/testify v1.9.0
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
k8s.io/api v0.27.2
k8s.io/apimachinery v0.27.2
Expand Down Expand Up @@ -78,7 +80,6 @@ require (
github.com/go-openapi/runtime v0.28.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/strfmt v0.23.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand Down Expand Up @@ -123,6 +124,7 @@ require (
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/proglottis/gpgme v0.1.3 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
Expand All @@ -138,6 +140,7 @@ require (
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/sylabs/sif/v2 v2.16.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
Expand Down
73 changes: 73 additions & 0 deletions internal/apitest/apitest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package apitest

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

type Test struct {
expectedOutputs []any
goTest *testing.T
inputs []any
m *mock.Mock
mockCalls []*mock.Call
name string
}

func NewTest(name string) *Test {
test := Test{
name: name,
}
return &test
}

func (test Test) AssertExpectations(outputs ...any) {
test.m.AssertExpectations(test.goTest)

for i, expectedValue := range test.expectedOutputs {
assert.Equal(test.goTest, expectedValue, outputs[i], fmt.Sprintf("wrong value in output %d", i))
}
}

func (test *Test) ExpectOutputs(outputs ...any) *Test {
test.expectedOutputs = outputs
return test
}

func (test Test) GetInput(index int) any {
return test.inputs[index]
}

func (test Test) GetStringPointerInput(index int) *string {
return test.GetInput(index).(*string)
}

func (test Test) GetMock() *mock.Mock {
return test.m
}

func (test Test) Run(goTest *testing.T, runner func(Test)) {
test.m = &mock.Mock{}
for _, call := range test.mockCalls {
call.Parent = test.m
}
test.m.ExpectedCalls = test.mockCalls

goTest.Run(test.name, func(goTest *testing.T) {
test.goTest = goTest
runner(test)
})
}

func (test *Test) WithMockCall(call *mock.Mock) *Test {
test.mockCalls = append(test.mockCalls, call.ExpectedCalls...)
return test
}

func (test *Test) WithInputs(inputs ...any) *Test {
test.inputs = inputs
return test
}
9 changes: 4 additions & 5 deletions internal/controller/admission/falconadmission_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -96,7 +95,7 @@ func (r *FalconAdmissionReconciler) Reconcile(ctx context.Context, req ctrl.Requ
falconAdmission := &falconv1alpha1.FalconAdmission{}
err := r.Get(ctx, req.NamespacedName, falconAdmission)
if err != nil {
if errors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
// If the custom resource is not found then, it usually means that it was deleted or not created
// In this way, we will stop the reconciliation
log.Info("FalconAdmission resource not found. Ignoring since object must be deleted")
Expand All @@ -123,11 +122,11 @@ func (r *FalconAdmissionReconciler) Reconcile(ctx context.Context, req ctrl.Requ
return ctrl.Result{}, err
}
log.Error(nil, "FalconAdmission is attempting to install in a namespace with existing pods. Please update the CR configuration to a namespace that does not have workoads already running.")
return ctrl.Result{}, err
return ctrl.Result{}, nil
}

// Let's just set the status as Unknown when no status is available
if falconAdmission.Status.Conditions == nil || len(falconAdmission.Status.Conditions) == 0 {
if len(falconAdmission.Status.Conditions) == 0 {
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
meta.SetStatusCondition(&falconAdmission.Status.Conditions, metav1.Condition{Type: falconv1alpha1.ConditionPending, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"})
return r.Status().Update(ctx, falconAdmission)
Expand Down Expand Up @@ -256,7 +255,7 @@ func (r *FalconAdmissionReconciler) Reconcile(ctx context.Context, req ctrl.Requ
}

pod, err := k8sutils.GetReadyPod(r.Client, ctx, falconAdmission.Spec.InstallNamespace, map[string]string{common.FalconComponentKey: common.FalconAdmissionController})
if err != nil && err.Error() != "No webhook service pod found in a Ready state" {
if err != nil && err != k8sutils.ErrNoWebhookServicePodReady {
log.Error(err, "Failed to find Ready admission controller pod")
return ctrl.Result{}, err
}
Expand Down
Loading

0 comments on commit c41b187

Please sign in to comment.