diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 02929b26..6603a695 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -117,4 +117,4 @@ jobs:
- name: Run Gosec Security Scanner
uses: securego/gosec@master
with:
- args: "-exclude=G307 ./..."
+ args: "-exclude=G307 -exclude-dir=docs ./..."
diff --git a/PROJECT b/PROJECT
index c3e7a743..1e3527bd 100644
--- a/PROJECT
+++ b/PROJECT
@@ -44,7 +44,7 @@ resources:
controller: true
domain: crowdstrike.com
group: falcon
- kind: FalconImage
+ kind: FalconImageAnalyzer
path: github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1
version: v1alpha1
version: "3"
diff --git a/README.md b/README.md
index 1493cbd8..c7a687e9 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,11 @@ The CrowdStrike Falcon Operator deploys CrowdStrike Falcon to the cluster. The o
| Custom Resource | Description |
| :-------- | :------------ |
| [FalconAdmission](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/admission/README.md) | Manages installation of Falcon Admission Controller on the cluster |
+| [FalconImageAnalyzer](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/imageanalyzer/README.md) | Manages installation of Falcon Image Assessment at Runtime on the cluster |
| [FalconContainer](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/container/README.md) | Manages installation of Falcon Container Sensor on the cluster |
| [FalconNodeSensor](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/node/README.md) | Manages installation of Falcon Linux Sensor on the cluster nodes |
+
## Installation and Deployment
For installation and deployment of the CrowdStrike Falcon Operator and its Custom Resources, please read the [Installation and Deployment Guide](docs/install_guide.md) and choose the deployment method that is right for your target environment.
diff --git a/api/falcon/v1alpha1/falconimage_types.go b/api/falcon/v1alpha1/falconimage_types.go
deleted file mode 100644
index 9b8a4b93..00000000
--- a/api/falcon/v1alpha1/falconimage_types.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package v1alpha1
-
-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.
-
-// FalconImageSpec defines the desired state of FalconImage
-type FalconImageSpec 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 FalconImage. Edit falconimage_types.go to remove/update
- Foo string `json:"foo,omitempty"`
-}
-
-// FalconImageStatus defines the observed state of FalconImage
-type FalconImageStatus 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
-
-// FalconImage is the Schema for the falconimages API
-type FalconImage struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ObjectMeta `json:"metadata,omitempty"`
-
- Spec FalconImageSpec `json:"spec,omitempty"`
- Status FalconImageStatus `json:"status,omitempty"`
-}
-
-//+kubebuilder:object:root=true
-
-// FalconImageList contains a list of FalconImage
-type FalconImageList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
- Items []FalconImage `json:"items"`
-}
-
-func init() {
- SchemeBuilder.Register(&FalconImage{}, &FalconImageList{})
-}
diff --git a/api/falcon/v1alpha1/falconimageanalyzer_types.go b/api/falcon/v1alpha1/falconimageanalyzer_types.go
new file mode 100644
index 00000000..c0839edf
--- /dev/null
+++ b/api/falcon/v1alpha1/falconimageanalyzer_types.go
@@ -0,0 +1,191 @@
+package v1alpha1
+
+import (
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ 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.
+
+// FalconImageAnalyzerSpec defines the desired state of FalconImageAnalyzer
+type FalconImageAnalyzerSpec struct {
+ // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Namespace where the Falcon Image Analyzer should be installed.
+ // For best security practices, this should be a dedicated namespace that is not used for any other purpose.
+ // It also should not be the same namespace where the Falcon Operator or the Falcon Sensor is installed.
+ // +kubebuilder:default:=falcon-iar
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,order=1,xDescriptors={"urn:alm:descriptor:io.kubernetes:Namespace"}
+ InstallNamespace string `json:"installNamespace,omitempty"`
+
+ // FalconAPI configures connection from your local Falcon operator to CrowdStrike Falcon platform.
+ //
+ // When configured, it will pull the sensor from registry.crowdstrike.com and deploy the appropriate sensor to the cluster.
+ //
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Platform API Configuration",order=2
+ FalconAPI *FalconAPI `json:"falcon_api,omitempty"`
+
+ // Registry configures container image registry to which the Image Analyzer image will be pushed.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Registry Configuration",order=6
+ Registry RegistrySpec `json:"registry,omitempty"`
+
+ // Additional configuration for Falcon Image Analyzer deployment.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Configuration",order=5
+ ImageAnalyzerConfig FalconImageAnalyzerConfigSpec `json:"imageAnalyzerConfig,omitempty"`
+
+ // Location of the Image Analyzer image. Use only in cases when you mirror the original image to your repository/name:tag
+ // +kubebuilder:validation:Pattern="^.*:.*$"
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Image URI",order=7
+ Image string `json:"image,omitempty"`
+
+ // Falcon Image Analyzer 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 Image Analyzer Version",order=8
+ Version *string `json:"version,omitempty"`
+}
+
+type FalconImageAnalyzerConfigSpec struct {
+ // Define annotations that will be passed down to Image Analyzer service account. This is useful for passing along AWS IAM Role or GCP Workload Identity.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Service Account Configuration",order=1
+ ServiceAccount FalconImageAnalyzerServiceAccount `json:"serviceAccount,omitempty"`
+
+ // +kubebuilder:default:=Always
+ // +kubebuilder:validation:Enum=Always;IfNotPresent;Never
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Image Pull Policy",order=2,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:imagePullPolicy"}
+ ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`
+
+ // ImagePullSecrets is an optional list of references to secrets to use for pulling image from the image location.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,order=3,displayName="Falcon Image Analyzer Image Pull Secrets",xDescriptors={"urn:alm:descriptor:io.kubernetes:Secret"}
+ ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
+
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Resources",order=4,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:resourceRequirements"}
+ Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
+
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Azure Config file path",order=5
+ AzureConfigPath string `json:"azureConfigPath,omitempty"`
+
+ // Enable priority class for the Falcon Image Analyzer deployment.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Priority Class",order=6
+ PriorityClass FalconImageAnalyzerPriorityClass `json:"priorityClass,omitempty"`
+
+ // Type of Deployment update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.
+ // +kubebuilder:default:={"rollingUpdate":{"maxUnavailable":0,"maxSurge":1}}
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Deployment Update Strategy",order=7
+ DepUpdateStrategy FalconImageAnalyzerUpdateStrategy `json:"updateStrategy,omitempty"`
+
+ // Set the falcon image analyzer volume size limit.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Volume Size Limit",order=8
+ // +kubebuilder:default:="20Gi"
+ VolumeSizeLimit string `json:"sizeLimit,omitempty"`
+
+ // Set the falcon image analyzer volume mount path.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Volume Mount Path",order=9
+ // +kubebuilder:default:="/tmp"
+ VolumeMountPath string `json:"mountPath,omitempty"`
+
+ // Name of the Kubernetes Cluster.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Cluster Name",order=10
+ ClusterName string `json:"clusterName,omitempty"`
+
+ // Exclusions for the Falcon Image Analyzer.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Exclusions",order=11
+ Exclusions Exclusions `json:"exclusions,omitempty"`
+
+ // RegistryConfig for the Falcon Image Analyzer.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Registry Configuration Options",order=12
+ RegistryConfig RegistryConfig `json:"registryConfig,omitempty"`
+
+ // Enable debugging for the Falcon Image Analyzer.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Image Analyzer Enable Debugging",order=13
+ // +kubebuilder:default:=false
+ EnableDebug bool `json:"debug,omitempty"`
+}
+
+type FalconImageAnalyzerPriorityClass struct {
+ // Name of the priority class to use.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Name of the Priority Class to use",order=1
+ Name string `json:"name,omitempty"`
+}
+
+type FalconImageAnalyzerServiceAccount struct {
+ // Define annotations that will be passed down to the Service Account. This is useful for passing along AWS IAM Role or GCP Workload Identity.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Service Account Annotations",order=1
+ Annotations map[string]string `json:"annotations,omitempty"`
+}
+
+type FalconImageAnalyzerUpdateStrategy struct {
+ // RollingUpdate is used to specify the strategy used to roll out a deployment
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Falcon Admisison Controller deployment update configuration",order=1,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:updateStrategy"}
+ RollingUpdate appsv1.RollingUpdateDeployment `json:"rollingUpdate,omitempty"`
+}
+
+type Exclusions struct {
+ // Configure a list of registries for the Falcon Image Analyzer to ignore.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Exclusions List",order=1
+ Registries []string `json:"registries,omitempty"`
+
+ // Configure a list of namespaces for Image Analyzer to ignore.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Ignore Namespace List",order=2
+ Namespaces []string `json:"namespaces,omitempty"`
+}
+
+type RegistryConfig struct {
+ // If neceeary, configure the registry credentials for the Falcon Image Analyzer.
+ // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Registry Credentials",order=1
+ Credentials []RegistryCreds `json:"credentials,omitempty"`
+}
+
+type RegistryCreds struct {
+ // Namespace where the registry container secret is located.
+ Namespace string `json:"namespace,omitempty"`
+ // Name of the registry container secret.
+ SecretName string `json:"secretName,omitempty"`
+}
+
+// FalconImageAnalyzerStatus defines the observed state of FalconImageAnalyzer
+type FalconImageAnalyzerStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Version of the CrowdStrike Falcon Sensor
+ // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Falcon Sensor Version",xDescriptors={"urn:alm:descriptor:text"}
+ Sensor *string `json:"sensor,omitempty"`
+
+ // Version of the CrowdStrike Falcon Operator
+ // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Falcon Operator Version",xDescriptors={"urn:alm:descriptor:text"}
+ Version string `json:"version,omitempty"`
+
+ // +optional
+ // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Falcon Image Analyzer Conditions",xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
+ Conditions []metav1.Condition `json:"conditions,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+//+kubebuilder:resource:scope=Cluster
+//+kubebuilder:printcolumn:name="Operator Version",type="string",JSONPath=".status.version",description="Version of the Operator"
+//+kubebuilder:printcolumn:name="Falcon Sensor",type="string",JSONPath=".status.sensor",description="Version of the Falcon Image Analyzer"
+
+// FalconImageAnalyzer is the Schema for the falconImageAnalyzers API
+type FalconImageAnalyzer struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec FalconImageAnalyzerSpec `json:"spec,omitempty"`
+ Status FalconCRStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// FalconImageAnalyzerList contains a list of FalconImageAnalyzer
+type FalconImageAnalyzerList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []FalconImageAnalyzer `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&FalconImageAnalyzer{}, &FalconImageAnalyzerList{})
+}
diff --git a/api/falcon/v1alpha1/zz_generated.deepcopy.go b/api/falcon/v1alpha1/zz_generated.deepcopy.go
index 8308c098..8375a772 100644
--- a/api/falcon/v1alpha1/zz_generated.deepcopy.go
+++ b/api/falcon/v1alpha1/zz_generated.deepcopy.go
@@ -235,6 +235,31 @@ func (in *AutoPilot) DeepCopy() *AutoPilot {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Exclusions) DeepCopyInto(out *Exclusions) {
+ *out = *in
+ if in.Registries != nil {
+ in, out := &in.Registries, &out.Registries
+ *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)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Exclusions.
+func (in *Exclusions) DeepCopy() *Exclusions {
+ if in == nil {
+ return nil
+ }
+ out := new(Exclusions)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FalconAPI) DeepCopyInto(out *FalconAPI) {
*out = *in
@@ -754,26 +779,26 @@ func (in *FalconContainerStatus) DeepCopy() *FalconContainerStatus {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *FalconImage) DeepCopyInto(out *FalconImage) {
+func (in *FalconImageAnalyzer) DeepCopyInto(out *FalconImageAnalyzer) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
- out.Status = in.Status
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImage.
-func (in *FalconImage) DeepCopy() *FalconImage {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageAnalyzer.
+func (in *FalconImageAnalyzer) DeepCopy() *FalconImageAnalyzer {
if in == nil {
return nil
}
- out := new(FalconImage)
+ out := new(FalconImageAnalyzer)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *FalconImage) DeepCopyObject() runtime.Object {
+func (in *FalconImageAnalyzer) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@@ -781,31 +806,61 @@ func (in *FalconImage) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *FalconImageList) DeepCopyInto(out *FalconImageList) {
+func (in *FalconImageAnalyzerConfigSpec) DeepCopyInto(out *FalconImageAnalyzerConfigSpec) {
+ *out = *in
+ in.ServiceAccount.DeepCopyInto(&out.ServiceAccount)
+ if in.ImagePullSecrets != nil {
+ in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
+ *out = make([]corev1.LocalObjectReference, len(*in))
+ copy(*out, *in)
+ }
+ if in.Resources != nil {
+ in, out := &in.Resources, &out.Resources
+ *out = new(corev1.ResourceRequirements)
+ (*in).DeepCopyInto(*out)
+ }
+ out.PriorityClass = in.PriorityClass
+ in.DepUpdateStrategy.DeepCopyInto(&out.DepUpdateStrategy)
+ in.Exclusions.DeepCopyInto(&out.Exclusions)
+ in.RegistryConfig.DeepCopyInto(&out.RegistryConfig)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageAnalyzerConfigSpec.
+func (in *FalconImageAnalyzerConfigSpec) DeepCopy() *FalconImageAnalyzerConfigSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(FalconImageAnalyzerConfigSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FalconImageAnalyzerList) DeepCopyInto(out *FalconImageAnalyzerList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
- *out = make([]FalconImage, len(*in))
+ *out = make([]FalconImageAnalyzer, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageList.
-func (in *FalconImageList) DeepCopy() *FalconImageList {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageAnalyzerList.
+func (in *FalconImageAnalyzerList) DeepCopy() *FalconImageAnalyzerList {
if in == nil {
return nil
}
- out := new(FalconImageList)
+ out := new(FalconImageAnalyzerList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *FalconImageList) DeepCopyObject() runtime.Object {
+func (in *FalconImageAnalyzerList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@@ -813,31 +868,108 @@ func (in *FalconImageList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *FalconImageSpec) DeepCopyInto(out *FalconImageSpec) {
+func (in *FalconImageAnalyzerPriorityClass) DeepCopyInto(out *FalconImageAnalyzerPriorityClass) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageAnalyzerPriorityClass.
+func (in *FalconImageAnalyzerPriorityClass) DeepCopy() *FalconImageAnalyzerPriorityClass {
+ if in == nil {
+ return nil
+ }
+ out := new(FalconImageAnalyzerPriorityClass)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FalconImageAnalyzerServiceAccount) DeepCopyInto(out *FalconImageAnalyzerServiceAccount) {
+ *out = *in
+ if in.Annotations != nil {
+ in, out := &in.Annotations, &out.Annotations
+ *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 FalconImageAnalyzerServiceAccount.
+func (in *FalconImageAnalyzerServiceAccount) DeepCopy() *FalconImageAnalyzerServiceAccount {
+ if in == nil {
+ return nil
+ }
+ out := new(FalconImageAnalyzerServiceAccount)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FalconImageAnalyzerSpec) DeepCopyInto(out *FalconImageAnalyzerSpec) {
*out = *in
+ if in.FalconAPI != nil {
+ in, out := &in.FalconAPI, &out.FalconAPI
+ *out = new(FalconAPI)
+ (*in).DeepCopyInto(*out)
+ }
+ in.Registry.DeepCopyInto(&out.Registry)
+ in.ImageAnalyzerConfig.DeepCopyInto(&out.ImageAnalyzerConfig)
+ if in.Version != nil {
+ in, out := &in.Version, &out.Version
+ *out = new(string)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageAnalyzerSpec.
+func (in *FalconImageAnalyzerSpec) DeepCopy() *FalconImageAnalyzerSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(FalconImageAnalyzerSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FalconImageAnalyzerStatus) DeepCopyInto(out *FalconImageAnalyzerStatus) {
+ *out = *in
+ if in.Sensor != nil {
+ in, out := &in.Sensor, &out.Sensor
+ *out = new(string)
+ **out = **in
+ }
+ if in.Conditions != nil {
+ in, out := &in.Conditions, &out.Conditions
+ *out = make([]v1.Condition, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageSpec.
-func (in *FalconImageSpec) DeepCopy() *FalconImageSpec {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageAnalyzerStatus.
+func (in *FalconImageAnalyzerStatus) DeepCopy() *FalconImageAnalyzerStatus {
if in == nil {
return nil
}
- out := new(FalconImageSpec)
+ out := new(FalconImageAnalyzerStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *FalconImageStatus) DeepCopyInto(out *FalconImageStatus) {
+func (in *FalconImageAnalyzerUpdateStrategy) DeepCopyInto(out *FalconImageAnalyzerUpdateStrategy) {
*out = *in
+ in.RollingUpdate.DeepCopyInto(&out.RollingUpdate)
}
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageStatus.
-func (in *FalconImageStatus) DeepCopy() *FalconImageStatus {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FalconImageAnalyzerUpdateStrategy.
+func (in *FalconImageAnalyzerUpdateStrategy) DeepCopy() *FalconImageAnalyzerUpdateStrategy {
if in == nil {
return nil
}
- out := new(FalconImageStatus)
+ out := new(FalconImageAnalyzerUpdateStrategy)
in.DeepCopyInto(out)
return out
}
@@ -1091,6 +1223,41 @@ func (in *PriorityClassConfig) DeepCopy() *PriorityClassConfig {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) {
+ *out = *in
+ if in.Credentials != nil {
+ in, out := &in.Credentials, &out.Credentials
+ *out = make([]RegistryCreds, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryConfig.
+func (in *RegistryConfig) DeepCopy() *RegistryConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(RegistryConfig)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RegistryCreds) DeepCopyInto(out *RegistryCreds) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryCreds.
+func (in *RegistryCreds) DeepCopy() *RegistryCreds {
+ if in == nil {
+ return nil
+ }
+ out := new(RegistryCreds)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RegistrySpec) DeepCopyInto(out *RegistrySpec) {
*out = *in
diff --git a/bundle.Dockerfile b/bundle.Dockerfile
index f8362984..fb641fcc 100644
--- a/bundle.Dockerfile
+++ b/bundle.Dockerfile
@@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/
LABEL operators.operatorframework.io.bundle.package.v1=falcon-operator
LABEL operators.operatorframework.io.bundle.channels.v1=alpha
-LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.33.0
+LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.34.1
LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1
LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4
diff --git a/bundle/manifests/falcon-operator-admission-controller-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/falcon-operator-admission-controller-role_rbac.authorization.k8s.io_v1_clusterrole.yaml
index 00a760d7..0e6d1b3d 100644
--- a/bundle/manifests/falcon-operator-admission-controller-role_rbac.authorization.k8s.io_v1_clusterrole.yaml
+++ b/bundle/manifests/falcon-operator-admission-controller-role_rbac.authorization.k8s.io_v1_clusterrole.yaml
@@ -17,6 +17,9 @@ rules:
resources:
- namespaces
- nodes
+ - pods
+ - replicationcontrollers
+ - services
verbs:
- get
- list
@@ -26,6 +29,25 @@ rules:
resources:
- daemonsets
- deployments
+ - replicasets
+ - statefulsets
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - batch
+ resources:
+ - cronjobs
+ - jobs
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - admissionregistration.k8s.io
+ resources:
+ - validatingwebhookconfigurations
verbs:
- get
- list
diff --git a/bundle/manifests/falcon-operator-image-controller-role_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/manifests/falcon-operator-image-controller-role_rbac.authorization.k8s.io_v1_clusterrole.yaml
new file mode 100644
index 00000000..c1dcd7ca
--- /dev/null
+++ b/bundle/manifests/falcon-operator-image-controller-role_rbac.authorization.k8s.io_v1_clusterrole.yaml
@@ -0,0 +1,32 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ creationTimestamp: null
+ labels:
+ crowdstrike.com/component: rbac
+ crowdstrike.com/created-by: falcon-operator
+ crowdstrike.com/instance: image-controller-role
+ crowdstrike.com/managed-by: kustomize
+ crowdstrike.com/name: clusterrole
+ crowdstrike.com/part-of: Falcon
+ crowdstrike.com/provider: crowdstrike
+ name: falcon-operator-image-controller-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - pods
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - security.openshift.io
+ resourceNames:
+ - privileged
+ resources:
+ - securitycontextconstraints
+ verbs:
+ - use
diff --git a/bundle/manifests/falcon-operator.clusterserviceversion.yaml b/bundle/manifests/falcon-operator.clusterserviceversion.yaml
index dd5cf9d4..ef112afa 100644
--- a/bundle/manifests/falcon-operator.clusterserviceversion.yaml
+++ b/bundle/manifests/falcon-operator.clusterserviceversion.yaml
@@ -68,6 +68,30 @@ metadata:
}
}
},
+ {
+ "apiVersion": "falcon.crowdstrike.com/v1alpha1",
+ "kind": "FalconImageAnalyzer",
+ "metadata": {
+ "labels": {
+ "app.kubernetes.io/created-by": "falcon-operator",
+ "app.kubernetes.io/instance": "falconimageanalyzer-sample",
+ "app.kubernetes.io/managed-by": "kustomize",
+ "app.kubernetes.io/name": "falconimageanalyzer",
+ "app.kubernetes.io/part-of": "falcon-operator"
+ },
+ "name": "falconimageanalyzer-sample"
+ },
+ "spec": {
+ "falcon_api": {
+ "client_id": "PLEASE_FILL_IN",
+ "client_secret": "PLEASE_FILL_IN",
+ "cloud_region": "autodiscover"
+ },
+ "registry": {
+ "type": "crowdstrike"
+ }
+ }
+ },
{
"apiVersion": "falcon.crowdstrike.com/v1alpha1",
"kind": "FalconNodeSensor",
@@ -98,13 +122,23 @@ metadata:
}
}
]
- capabilities: Basic Install
+ capabilities: Seamless Upgrades
categories: Security,Monitoring
containerImage: quay.io/crowdstrike/falcon-operator
- createdAt: "2023-12-21T21:26:46Z"
+ createdAt: "2024-05-16T19:53:46Z"
description: Falcon Operator installs CrowdStrike Falcon Sensors on the cluster
+ features.operators.openshift.io/cnf: "false"
+ features.operators.openshift.io/cni: "false"
+ features.operators.openshift.io/csi: "false"
+ features.operators.openshift.io/disconnected: "false"
+ features.operators.openshift.io/fips-compliant: "false"
+ features.operators.openshift.io/proxy-aware: "true"
+ features.operators.openshift.io/tls-profiles: "false"
+ features.operators.openshift.io/token-auth-aws: "false"
+ features.operators.openshift.io/token-auth-azure: "false"
+ features.operators.openshift.io/token-auth-gcp: "false"
operatorframework.io/suggested-namespace: falcon-operator
- operators.operatorframework.io/builder: operator-sdk-v1.33.0
+ operators.operatorframework.io/builder: operator-sdk-v1.34.1
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
repository: https://github.com/CrowdStrike/falcon-operator
support: Community Only
@@ -174,12 +208,6 @@ spec:
path: resourcequota.pods
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:podCount
- - description: For OpenShift clusters, ignore openshift-specific namespaces
- for admission control.
- displayName: Ignore OpenShift Namespaces
- path: admissionConfig.disabledNamespaces.ignoreOpenShiftNamespaces
- x-descriptors:
- - urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- displayName: Falcon Admission Controller Image Pull Policy
path: admissionConfig.imagePullPolicy
x-descriptors:
@@ -243,7 +271,7 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:number
- description: The application proxy host to use for Falcon sensor proxy configuration.
- displayName: Disable Falcon Proxy Host
+ displayName: Falcon Proxy Host
path: falcon.aph
- description: Falcon Customer ID (CID) Override (optional, default is derived
from the API Key pair)
@@ -340,6 +368,14 @@ spec:
path: injector.serviceAccount
- displayName: Falcon Container Injector TLS Validity Length (days)
path: injector.tls.validity
+ - description: Namespace where the Falcon Sensor should be installed. For best
+ security practices, this should be a dedicated namespace that is not used
+ for any other purpose. It also should not be the same namespace where the
+ Falcon Operator, or other Falcon resources are deployed.
+ displayName: Install Namespace
+ path: installNamespace
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Namespace
- description: Allow pushing to docker registries over HTTPS with failed TLS
verification. Note that this does not affect other TLS connections.
displayName: Skip Registry TLS Verification
@@ -398,7 +434,7 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap
- description: The application proxy host to use for Falcon sensor proxy configuration.
- displayName: Disable Falcon Proxy Host
+ displayName: Falcon Proxy Host
path: falcon.aph
- description: Falcon Customer ID (CID) Override (optional, default is derived
from the API Key pair)
@@ -453,6 +489,156 @@ spec:
displayName: Annotations
path: injector.serviceAccount.annotations
version: v1alpha1
+ - description: FalconImageAnalyzer is the Schema for the falconImageAnalyzers
+ API
+ displayName: Falcon Image Analyzer
+ kind: FalconImageAnalyzer
+ name: falconimageanalyzers.falcon.crowdstrike.com
+ specDescriptors:
+ - description: Falcon OAuth2 API Client ID
+ displayName: Client ID
+ path: falcon_api.client_id
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:password
+ - description: Configure a list of registries for the Falcon Image Analyzer
+ to ignore.
+ displayName: Exclusions List
+ path: imageAnalyzerConfig.exclusions.registries
+ - description: Name of the priority class to use.
+ displayName: Name of the Priority Class to use
+ path: imageAnalyzerConfig.priorityClass.name
+ - description: If neceeary, configure the registry credentials for the Falcon
+ Image Analyzer.
+ displayName: Registry Credentials
+ path: imageAnalyzerConfig.registryConfig.credentials
+ - description: Define annotations that will be passed down to Image Analyzer
+ service account. This is useful for passing along AWS IAM Role or GCP Workload
+ Identity.
+ displayName: Service Account Configuration
+ path: imageAnalyzerConfig.serviceAccount
+ - description: Define annotations that will be passed down to the Service Account.
+ This is useful for passing along AWS IAM Role or GCP Workload Identity.
+ displayName: Service Account Annotations
+ path: imageAnalyzerConfig.serviceAccount.annotations
+ - description: RollingUpdate is used to specify the strategy used to roll out
+ a deployment
+ displayName: Falcon Admisison Controller deployment update configuration
+ path: imageAnalyzerConfig.updateStrategy.rollingUpdate
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:updateStrategy
+ - description: Namespace where the Falcon Image Analyzer should be installed.
+ For best security practices, this should be a dedicated namespace that is
+ not used for any other purpose. It also should not be the same namespace
+ where the Falcon Operator or the Falcon Sensor is installed.
+ displayName: Install Namespace
+ path: installNamespace
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Namespace
+ - description: Allow pushing to docker registries over HTTPS with failed TLS
+ verification. Note that this does not affect other TLS connections.
+ displayName: Skip Registry TLS Verification
+ path: registry.tls.insecure_skip_verify
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:booleanSwitch
+ - description: Type of container registry to be used
+ displayName: Registry Type
+ path: registry.type
+ - description: "FalconAPI configures connection from your local Falcon operator
+ to CrowdStrike Falcon platform. \n When configured, it will pull the sensor
+ from registry.crowdstrike.com and deploy the appropriate sensor to the cluster."
+ displayName: Falcon Platform API Configuration
+ path: falcon_api
+ - description: Falcon OAuth2 API Client Secret
+ displayName: Client Secret
+ path: falcon_api.client_secret
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:password
+ - description: Configure a list of namespaces for Image Analyzer to ignore.
+ displayName: Ignore Namespace List
+ path: imageAnalyzerConfig.exclusions.namespaces
+ - displayName: Falcon Image Analyzer Image Pull Policy
+ path: imageAnalyzerConfig.imagePullPolicy
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:imagePullPolicy
+ - description: TLS configures TLS connection for push of Falcon Container image
+ to the registry
+ displayName: Registry TLS Configuration
+ path: registry.tls
+ - description: Allow for users to provide a CA Cert Bundle, as either a string
+ or base64 encoded string
+ displayName: Registry CA Certificate Bundle; optionally (double) base64 encoded
+ path: registry.tls.caCertificate
+ - description: Cloud Region defines CrowdStrike Falcon Cloud Region to which
+ the operator will connect and register.
+ displayName: CrowdStrike Falcon Cloud Region
+ path: falcon_api.cloud_region
+ - description: ImagePullSecrets is an optional list of references to secrets
+ to use for pulling image from the image location.
+ displayName: Falcon Image Analyzer Image Pull Secrets
+ path: imageAnalyzerConfig.imagePullSecrets
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Secret
+ - description: Azure Container Registry Name represents the name of the ACR
+ for the Falcon Container push. Only applicable to Azure cloud.
+ displayName: Azure Container Registry Name
+ path: registry.acr_name
+ - description: Allow for users to provide a ConfigMap containing a CA Cert Bundle
+ under a key ending in .crt
+ displayName: ConfigMap containing Registry CA Certificate Bundle
+ path: registry.tls.caCertificateConfigMap
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap
+ - description: Falcon Customer ID (CID) Override (optional, default is derived
+ from the API Key pair)
+ displayName: Falcon Customer ID (CID)
+ path: falcon_api.cid
+ - displayName: Falcon Image Analyzer Resources
+ path: imageAnalyzerConfig.resources
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:resourceRequirements
+ - description: Additional configuration for Falcon Image Analyzer deployment.
+ displayName: Falcon Image Analyzer Configuration
+ path: imageAnalyzerConfig
+ - displayName: Azure Config file path
+ path: imageAnalyzerConfig.azureConfigPath
+ - description: Enable priority class for the Falcon Image Analyzer deployment.
+ displayName: Priority Class
+ path: imageAnalyzerConfig.priorityClass
+ - description: Registry configures container image registry to which the Image
+ Analyzer image will be pushed.
+ displayName: Falcon Image Analyzer Registry Configuration
+ path: registry
+ - description: Location of the Image Analyzer image. Use only in cases when
+ you mirror the original image to your repository/name:tag
+ displayName: Falcon Image Analyzer Image URI
+ path: image
+ - description: Type of Deployment update. Can be "RollingUpdate" or "OnDelete".
+ Default is RollingUpdate.
+ displayName: Deployment Update Strategy
+ path: imageAnalyzerConfig.updateStrategy
+ - description: Set the falcon image analyzer volume size limit.
+ displayName: Falcon Image Analyzer Volume Size Limit
+ path: imageAnalyzerConfig.sizeLimit
+ - description: 'Falcon Image Analyzer Version. The latest version will be selected
+ when version specifier is missing. Example: 6.31, 6.31.0, 6.31.0-1409, etc.'
+ displayName: Falcon Image Analyzer Version
+ path: version
+ - description: Set the falcon image analyzer volume mount path.
+ displayName: Falcon Image Analyzer Volume Mount Path
+ path: imageAnalyzerConfig.mountPath
+ - description: Name of the Kubernetes Cluster.
+ displayName: Falcon Image Analyzer Cluster Name
+ path: imageAnalyzerConfig.clusterName
+ - description: Exclusions for the Falcon Image Analyzer.
+ displayName: Falcon Image Analyzer Exclusions
+ path: imageAnalyzerConfig.exclusions
+ - description: RegistryConfig for the Falcon Image Analyzer.
+ displayName: Falcon Image Analyzer Registry Configuration Options
+ path: imageAnalyzerConfig.registryConfig
+ - description: Enable debugging for the Falcon Image Analyzer.
+ displayName: Falcon Image Analyzer Enable Debugging
+ path: imageAnalyzerConfig.debug
+ version: v1alpha1
- description: FalconNodeSensor is the Schema for the falconnodesensors API
displayName: Falcon Node Sensor
kind: FalconNodeSensor
@@ -472,6 +658,14 @@ spec:
path: falcon_api.client_id
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:password
+ - description: Namespace where the Falcon Sensor should be installed. For best
+ security practices, this should be a dedicated namespace that is not used
+ for any other purpose. It also should not be the same namespace where the
+ Falcon Operator, or other Falcon resources are deployed.
+ displayName: Install Namespace
+ path: installNamespace
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Namespace
- description: ImagePullSecrets is an optional list of references to secrets
in the falcon-system namespace to use for pulling image from image_override
location.
@@ -518,7 +712,7 @@ spec:
displayName: Priority Class Value
path: node.priorityClass.value
- description: The application proxy host to use for Falcon sensor proxy configuration.
- displayName: Disable Falcon Proxy Host
+ displayName: Falcon Proxy Host
path: falcon.aph
- description: Falcon Customer ID (CID) Override (optional, default is derived
from the API Key pair)
@@ -620,6 +814,7 @@ spec:
| Custom Resource | Description |
| :-------- | :------------ |
| [FalconAdmission](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/admission/README.md) | Manages installation of Falcon Admission Controller on the cluster |
+ | [FalconImageAnalyzer](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/imageanalyzer/README.md) | Manages installation of Falcon Image Assessment at Runtime on the cluster |
| [FalconContainer](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/container/README.md) | Manages installation of Falcon Container Sensor on the cluster |
| [FalconNodeSensor](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/node/README.md) | Manages installation of Falcon Linux Sensor on the cluster nodes |
@@ -707,6 +902,14 @@ spec:
- list
- update
- watch
+ - apiGroups:
+ - ""
+ resources:
+ - replicationcontrollers
+ verbs:
+ - get
+ - list
+ - watch
- apiGroups:
- ""
resources:
@@ -796,6 +999,31 @@ spec:
- list
- update
- watch
+ - apiGroups:
+ - apps
+ resources:
+ - replicasets
+ verbs:
+ - get
+ - list
+ - watch
+ - apiGroups:
+ - apps
+ resources:
+ - statefulsets
+ verbs:
+ - get
+ - list
+ - watch
+ - apiGroups:
+ - batch
+ resources:
+ - cronjobs
+ - jobs
+ verbs:
+ - get
+ - list
+ - watch
- apiGroups:
- coordination.k8s.io
resources:
@@ -873,6 +1101,32 @@ spec:
- get
- patch
- update
+ - apiGroups:
+ - falcon.crowdstrike.com
+ resources:
+ - falconimageanalyzers
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+ - apiGroups:
+ - falcon.crowdstrike.com
+ resources:
+ - falconimageanalyzers/finalizers
+ verbs:
+ - update
+ - apiGroups:
+ - falcon.crowdstrike.com
+ resources:
+ - falconimageanalyzers/status
+ verbs:
+ - get
+ - patch
+ - update
- apiGroups:
- falcon.crowdstrike.com
resources:
@@ -921,6 +1175,17 @@ spec:
- list
- update
- watch
+ - apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - update
+ - watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
@@ -1007,7 +1272,32 @@ spec:
- linux
containers:
- args:
- - --config=controller_manager_config.yaml
+ - --secure-listen-address=0.0.0.0:8443
+ - --upstream=http://127.0.0.1:8080/
+ - --logtostderr=true
+ - --v=0
+ image: gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0
+ name: kube-rbac-proxy
+ ports:
+ - containerPort: 8443
+ name: https
+ protocol: TCP
+ resources:
+ limits:
+ cpu: 500m
+ memory: 128Mi
+ requests:
+ cpu: 5m
+ memory: 64Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ - args:
+ - --health-probe-bind-address=:8081
+ - --metrics-bind-address=127.0.0.1:8080
+ - --leader-elect
command:
- /manager
env:
@@ -1017,7 +1307,7 @@ spec:
fieldPath: metadata.annotations['olm.targetNamespaces']
- name: OPERATOR_NAME
value: falcon-operator
- image: quay.io/crowdstrike/falcon-operator:0.9.1
+ image: controller:latest
livenessProbe:
httpGet:
path: /healthz
@@ -1044,41 +1334,12 @@ spec:
drop:
- ALL
privileged: false
- volumeMounts:
- - mountPath: /controller_manager_config.yaml
- name: manager-config
- subPath: controller_manager_config.yaml
- - args:
- - --secure-listen-address=0.0.0.0:8443
- - --upstream=http://127.0.0.1:8080/
- - --logtostderr=true
- - --v=0
- image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1
- name: kube-rbac-proxy
- ports:
- - containerPort: 8443
- name: https
- protocol: TCP
- resources:
- limits:
- cpu: 500m
- memory: 128Mi
- requests:
- cpu: 5m
- memory: 64Mi
- securityContext:
- allowPrivilegeEscalation: false
- capabilities:
- drop:
- - ALL
securityContext:
runAsNonRoot: true
+ seccompProfile:
+ type: RuntimeDefault
serviceAccountName: falcon-operator-controller-manager
terminationGracePeriodSeconds: 10
- volumes:
- - configMap:
- name: falcon-operator-manager-config
- name: manager-config
permissions:
- rules:
- apiGroups:
@@ -1115,9 +1376,9 @@ spec:
serviceAccountName: falcon-operator-controller-manager
strategy: deployment
installModes:
- - supported: true
+ - supported: false
type: OwnNamespace
- - supported: true
+ - supported: false
type: SingleNamespace
- supported: false
type: MultiNamespace
@@ -1136,7 +1397,7 @@ spec:
- email: integrations@crowdstrike.com
name: CrowdStrike Solutions Architecture
maturity: alpha
- minKubeVersion: 1.17.0
+ minKubeVersion: 1.22.0
provider:
name: CrowdStrike
url: https://crowdStrike.com
diff --git a/bundle/manifests/falcon.crowdstrike.com_falconadmissions.yaml b/bundle/manifests/falcon.crowdstrike.com_falconadmissions.yaml
index 64540a4d..bc7c05c2 100644
--- a/bundle/manifests/falcon.crowdstrike.com_falconadmissions.yaml
+++ b/bundle/manifests/falcon.crowdstrike.com_falconadmissions.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.12.0
+ controller-gen.kubebuilder.io/version: v0.13.0
creationTimestamp: null
name: falconadmissions.falcon.crowdstrike.com
spec:
@@ -59,10 +59,6 @@ spec:
disabledNamespaces:
description: Ignore admission control for a specific set of namespaces.
properties:
- ignoreOpenShiftNamespaces:
- description: For OpenShift clusters, ignore openshift-specific
- namespaces for admission control.
- type: boolean
namespaces:
description: Configure a list of namespaces to ignore admission
control.
@@ -125,7 +121,8 @@ spec:
description: "Claims lists the names of resources, defined
in spec.resourceClaims, that are used by this container.
\n This is an alpha field and requires enabling the DynamicResourceAllocation
- feature gate. \n This field is immutable."
+ feature gate. \n This field is immutable. It can only be
+ set for containers."
items:
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
properties:
@@ -162,7 +159,8 @@ spec:
description: 'Requests describes the minimum amount of compute
resources required. If Requests is omitted for a container,
it defaults to Limits if that is explicitly specified, otherwise
- to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ to an implementation-defined value. Requests cannot exceed
+ Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
type: object
type: object
resourcesClient:
@@ -180,7 +178,8 @@ spec:
description: "Claims lists the names of resources, defined
in spec.resourceClaims, that are used by this container.
\n This is an alpha field and requires enabling the DynamicResourceAllocation
- feature gate. \n This field is immutable."
+ feature gate. \n This field is immutable. It can only be
+ set for containers."
items:
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
properties:
@@ -217,7 +216,8 @@ spec:
description: 'Requests describes the minimum amount of compute
resources required. If Requests is omitted for a container,
it defaults to Limits if that is explicitly specified, otherwise
- to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ to an implementation-defined value. Requests cannot exceed
+ Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
type: object
type: object
serviceAccount:
diff --git a/bundle/manifests/falcon.crowdstrike.com_falconcontainers.yaml b/bundle/manifests/falcon.crowdstrike.com_falconcontainers.yaml
index 557da71e..9cd3ebc5 100644
--- a/bundle/manifests/falcon.crowdstrike.com_falconcontainers.yaml
+++ b/bundle/manifests/falcon.crowdstrike.com_falconcontainers.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.12.0
+ controller-gen.kubebuilder.io/version: v0.13.0
creationTimestamp: null
name: falconcontainers.falcon.crowdstrike.com
spec:
@@ -557,7 +557,7 @@ spec:
between the SizeLimit specified here and the sum of
memory limits of all containers in a pod. The default
is nil which means that the limit is undefined. More
- info: http://kubernetes.io/docs/user-guide/volumes#emptydir'
+ info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir'
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
type: object
@@ -735,7 +735,8 @@ spec:
defined in spec.resourceClaims, that are
used by this container. \n This is an alpha
field and requires enabling the DynamicResourceAllocation
- feature gate. \n This field is immutable."
+ feature gate. \n This field is immutable.
+ It can only be set for containers."
items:
description: ResourceClaim references one
entry in PodSpec.ResourceClaims.
@@ -777,7 +778,8 @@ spec:
Requests is omitted for a container, it
defaults to Limits if that is explicitly
specified, otherwise to an implementation-defined
- value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ value. Requests cannot exceed Limits. More
+ info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
type: object
type: object
selector:
@@ -1762,7 +1764,8 @@ spec:
description: "Claims lists the names of resources, defined
in spec.resourceClaims, that are used by this container.
\n This is an alpha field and requires enabling the DynamicResourceAllocation
- feature gate. \n This field is immutable."
+ feature gate. \n This field is immutable. It can only be
+ set for containers."
items:
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
properties:
@@ -1799,7 +1802,8 @@ spec:
description: 'Requests describes the minimum amount of compute
resources required. If Requests is omitted for a container,
it defaults to Limits if that is explicitly specified, otherwise
- to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ to an implementation-defined value. Requests cannot exceed
+ Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
type: object
type: object
sensorResources:
@@ -1810,7 +1814,8 @@ spec:
description: "Claims lists the names of resources, defined
in spec.resourceClaims, that are used by this container.
\n This is an alpha field and requires enabling the DynamicResourceAllocation
- feature gate. \n This field is immutable."
+ feature gate. \n This field is immutable. It can only be
+ set for containers."
items:
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
properties:
@@ -1847,7 +1852,8 @@ spec:
description: 'Requests describes the minimum amount of compute
resources required. If Requests is omitted for a container,
it defaults to Limits if that is explicitly specified, otherwise
- to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ to an implementation-defined value. Requests cannot exceed
+ Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
type: object
type: object
serviceAccount:
@@ -1871,6 +1877,14 @@ spec:
x-kubernetes-int-or-string: true
type: object
type: object
+ installNamespace:
+ default: falcon-system
+ description: Namespace where the Falcon Sensor should be installed.
+ For best security practices, this should be a dedicated namespace
+ that is not used for any other purpose. It also should not be the
+ same namespace where the Falcon Operator, or other Falcon resources
+ are deployed.
+ type: string
registry:
description: Registry configures container image registry to which
the Falcon Container image will be pushed
diff --git a/bundle/manifests/falcon.crowdstrike.com_falconimageanalyzers.yaml b/bundle/manifests/falcon.crowdstrike.com_falconimageanalyzers.yaml
new file mode 100644
index 00000000..8aed50a3
--- /dev/null
+++ b/bundle/manifests/falcon.crowdstrike.com_falconimageanalyzers.yaml
@@ -0,0 +1,423 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.13.0
+ creationTimestamp: null
+ name: falconimageanalyzers.falcon.crowdstrike.com
+spec:
+ group: falcon.crowdstrike.com
+ names:
+ kind: FalconImageAnalyzer
+ listKind: FalconImageAnalyzerList
+ plural: falconimageanalyzers
+ singular: falconimageanalyzer
+ scope: Cluster
+ versions:
+ - additionalPrinterColumns:
+ - description: Version of the Operator
+ jsonPath: .status.version
+ name: Operator Version
+ type: string
+ - description: Version of the Falcon Image Analyzer
+ jsonPath: .status.sensor
+ name: Falcon Sensor
+ type: string
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: FalconImageAnalyzer is the Schema for the falconImageAnalyzers
+ 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: FalconImageAnalyzerSpec defines the desired state of FalconImageAnalyzer
+ properties:
+ falcon_api:
+ description: "FalconAPI configures connection from your local Falcon
+ operator to CrowdStrike Falcon platform. \n When configured, it
+ will pull the sensor from registry.crowdstrike.com and deploy the
+ appropriate sensor to the cluster."
+ properties:
+ cid:
+ description: Falcon Customer ID (CID) Override (optional, default
+ is derived from the API Key pair)
+ pattern: ^[0-9a-fA-F]{32}-[0-9a-fA-F]{2}$
+ type: string
+ client_id:
+ description: Falcon OAuth2 API Client ID
+ type: string
+ client_secret:
+ description: Falcon OAuth2 API Client Secret
+ type: string
+ cloud_region:
+ description: Cloud Region defines CrowdStrike Falcon Cloud Region
+ to which the operator will connect and register.
+ enum:
+ - autodiscover
+ - us-1
+ - us-2
+ - eu-1
+ - us-gov-1
+ type: string
+ required:
+ - client_id
+ - client_secret
+ - cloud_region
+ type: object
+ image:
+ description: Location of the Image Analyzer image. Use only in cases
+ when you mirror the original image to your repository/name:tag
+ pattern: ^.*:.*$
+ type: string
+ imageAnalyzerConfig:
+ description: Additional configuration for Falcon Image Analyzer deployment.
+ properties:
+ azureConfigPath:
+ type: string
+ clusterName:
+ description: Name of the Kubernetes Cluster.
+ type: string
+ debug:
+ default: false
+ description: Enable debugging for the Falcon Image Analyzer.
+ type: boolean
+ exclusions:
+ description: Exclusions for the Falcon Image Analyzer.
+ properties:
+ namespaces:
+ description: Configure a list of namespaces for Image Analyzer
+ to ignore.
+ items:
+ type: string
+ type: array
+ registries:
+ description: Configure a list of registries for the Falcon
+ Image Analyzer to ignore.
+ items:
+ type: string
+ type: array
+ type: object
+ imagePullPolicy:
+ default: Always
+ description: PullPolicy describes a policy for if/when to pull
+ a container image
+ enum:
+ - Always
+ - IfNotPresent
+ - Never
+ type: string
+ imagePullSecrets:
+ description: ImagePullSecrets is an optional list of references
+ to secrets to use for pulling image from the image location.
+ items:
+ description: LocalObjectReference contains enough information
+ to let you locate the referenced object inside the same namespace.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ type: array
+ mountPath:
+ default: /tmp
+ description: Set the falcon image analyzer volume mount path.
+ type: string
+ priorityClass:
+ description: Enable priority class for the Falcon Image Analyzer
+ deployment.
+ properties:
+ name:
+ description: Name of the priority class to use.
+ type: string
+ type: object
+ registryConfig:
+ description: RegistryConfig for the Falcon Image Analyzer.
+ properties:
+ credentials:
+ description: If neceeary, configure the registry credentials
+ for the Falcon Image Analyzer.
+ items:
+ properties:
+ namespace:
+ description: Namespace where the registry container
+ secret is located.
+ type: string
+ secretName:
+ description: Name of the registry container secret.
+ type: string
+ type: object
+ type: array
+ type: object
+ resources:
+ description: ResourceRequirements describes the compute resource
+ requirements.
+ properties:
+ claims:
+ description: "Claims lists the names of resources, defined
+ in spec.resourceClaims, that are used by this container.
+ \n This is an alpha field and requires enabling the DynamicResourceAllocation
+ feature gate. \n This field is immutable. It can only be
+ set for containers."
+ items:
+ description: ResourceClaim references one entry in PodSpec.ResourceClaims.
+ properties:
+ name:
+ description: Name must match the name of one entry in
+ pod.spec.resourceClaims of the Pod where this field
+ is used. It makes that resource available inside a
+ container.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. Requests cannot exceed
+ Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ serviceAccount:
+ description: Define annotations that will be passed down to Image
+ Analyzer service account. This is useful for passing along AWS
+ IAM Role or GCP Workload Identity.
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Define annotations that will be passed down to
+ the Service Account. This is useful for passing along AWS
+ IAM Role or GCP Workload Identity.
+ type: object
+ type: object
+ sizeLimit:
+ default: 20Gi
+ description: Set the falcon image analyzer volume size limit.
+ type: string
+ updateStrategy:
+ default:
+ rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 0
+ description: Type of Deployment update. Can be "RollingUpdate"
+ or "OnDelete". Default is RollingUpdate.
+ properties:
+ rollingUpdate:
+ description: RollingUpdate is used to specify the strategy
+ used to roll out a deployment
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'The maximum number of pods that can be scheduled
+ above the desired number of pods. Value can be an absolute
+ number (ex: 5) or a percentage of desired pods (ex:
+ 10%). This can not be 0 if MaxUnavailable is 0. Absolute
+ number is calculated from percentage by rounding up.
+ Defaults to 25%. Example: when this is set to 30%, the
+ new ReplicaSet can be scaled up immediately when the
+ rolling update starts, such that the total number of
+ old and new pods do not exceed 130% of desired pods.
+ Once old pods have been killed, new ReplicaSet can be
+ scaled up further, ensuring that total number of pods
+ running at any time during the update is at most 130%
+ of desired pods.'
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'The maximum number of pods that can be unavailable
+ during the update. Value can be an absolute number (ex:
+ 5) or a percentage of desired pods (ex: 10%). Absolute
+ number is calculated from percentage by rounding down.
+ This can not be 0 if MaxSurge is 0. Defaults to 25%.
+ Example: when this is set to 30%, the old ReplicaSet
+ can be scaled down to 70% of desired pods immediately
+ when the rolling update starts. Once new pods are ready,
+ old ReplicaSet can be scaled down further, followed
+ by scaling up the new ReplicaSet, ensuring that the
+ total number of pods available at all times during the
+ update is at least 70% of desired pods.'
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ installNamespace:
+ default: falcon-iar
+ description: Namespace where the Falcon Image Analyzer should be installed.
+ For best security practices, this should be a dedicated namespace
+ that is not used for any other purpose. It also should not be the
+ same namespace where the Falcon Operator or the Falcon Sensor is
+ installed.
+ type: string
+ registry:
+ description: Registry configures container image registry to which
+ the Image Analyzer image will be pushed.
+ properties:
+ acr_name:
+ description: Azure Container Registry Name represents the name
+ of the ACR for the Falcon Container push. Only applicable to
+ Azure cloud.
+ type: string
+ tls:
+ description: TLS configures TLS connection for push of Falcon
+ Container image to the registry
+ properties:
+ caCertificate:
+ description: Allow for users to provide a CA Cert Bundle,
+ as either a string or base64 encoded string
+ type: string
+ caCertificateConfigMap:
+ description: Allow for users to provide a ConfigMap containing
+ a CA Cert Bundle under a key ending in .crt
+ type: string
+ insecure_skip_verify:
+ description: Allow pushing to docker registries over HTTPS
+ with failed TLS verification. Note that this does not affect
+ other TLS connections.
+ type: boolean
+ type: object
+ type:
+ description: Type of container registry to be used
+ enum:
+ - acr
+ - ecr
+ - gcr
+ - crowdstrike
+ - openshift
+ type: string
+ required:
+ - type
+ type: object
+ version:
+ description: 'Falcon Image Analyzer Version. The latest version will
+ be selected when version specifier is missing. Example: 6.31, 6.31.0,
+ 6.31.0-1409, etc.'
+ type: string
+ type: object
+ status:
+ description: FalconAdmissionStatus defines the observed state of FalconAdmission
+ properties:
+ conditions:
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource. --- This struct is intended for direct
+ use as an array at the field path .status.conditions. For example,
+ \n type FooStatus struct{ // Represents the observations of a
+ foo's current state. // Known .status.conditions.type are: \"Available\",
+ \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
+ // +listType=map // +listMapKey=type Conditions []metav1.Condition
+ `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
+ protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
+ properties:
+ lastTransitionTime:
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another. This should be when
+ the underlying condition changed. If that is not known, then
+ using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: message is a human readable message indicating
+ details about the transition. This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon. For instance, if .metadata.generation
+ is currently 12, but the .status.conditions[x].observedGeneration
+ is 9, the condition is out of date with respect to the current
+ state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition. Producers
+ of specific condition types may define expected values and
+ meanings for this field, and whether the values are considered
+ a guaranteed API. The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ --- Many .condition.type values are consistent across resources
+ like Available, but because arbitrary conditions can be useful
+ (see .node.status.conditions), the ability to deconflict is
+ important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ sensor:
+ description: Version of the CrowdStrike Falcon Sensor
+ type: string
+ version:
+ description: Version of the CrowdStrike Falcon Operator
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: null
+ storedVersions: null
diff --git a/bundle/manifests/falcon.crowdstrike.com_falconnodesensors.yaml b/bundle/manifests/falcon.crowdstrike.com_falconnodesensors.yaml
index f9c57190..a5654368 100644
--- a/bundle/manifests/falcon.crowdstrike.com_falconnodesensors.yaml
+++ b/bundle/manifests/falcon.crowdstrike.com_falconnodesensors.yaml
@@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
- controller-gen.kubebuilder.io/version: v0.12.0
+ controller-gen.kubebuilder.io/version: v0.13.0
creationTimestamp: null
name: falconnodesensors.falcon.crowdstrike.com
spec:
@@ -127,6 +127,14 @@ spec:
- client_secret
- cloud_region
type: object
+ installNamespace:
+ default: falcon-system
+ description: Namespace where the Falcon Sensor should be installed.
+ For best security practices, this should be a dedicated namespace
+ that is not used for any other purpose. It also should not be the
+ same namespace where the Falcon Operator, or other Falcon resources
+ are deployed.
+ type: string
node:
description: Various configuration for DaemonSet Deployment
properties:
diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml
index 76f016f2..7d7c59b7 100644
--- a/bundle/metadata/annotations.yaml
+++ b/bundle/metadata/annotations.yaml
@@ -5,7 +5,7 @@ annotations:
operators.operatorframework.io.bundle.metadata.v1: metadata/
operators.operatorframework.io.bundle.package.v1: falcon-operator
operators.operatorframework.io.bundle.channels.v1: alpha
- operators.operatorframework.io.metrics.builder: operator-sdk-v1.33.0
+ operators.operatorframework.io.metrics.builder: operator-sdk-v1.34.1
operators.operatorframework.io.metrics.mediatype.v1: metrics+v1
operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4
diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml
index d5b4b3e4..fa911673 100644
--- a/bundle/tests/scorecard/config.yaml
+++ b/bundle/tests/scorecard/config.yaml
@@ -8,7 +8,7 @@ stages:
- entrypoint:
- scorecard-test
- basic-check-spec
- image: quay.io/operator-framework/scorecard-test:v1.33.0
+ image: quay.io/operator-framework/scorecard-test:v1.34.1
labels:
suite: basic
test: basic-check-spec-test
@@ -18,7 +18,7 @@ stages:
- entrypoint:
- scorecard-test
- olm-bundle-validation
- image: quay.io/operator-framework/scorecard-test:v1.33.0
+ image: quay.io/operator-framework/scorecard-test:v1.34.1
labels:
suite: olm
test: olm-bundle-validation-test
@@ -28,7 +28,7 @@ stages:
- entrypoint:
- scorecard-test
- olm-crds-have-validation
- image: quay.io/operator-framework/scorecard-test:v1.33.0
+ image: quay.io/operator-framework/scorecard-test:v1.34.1
labels:
suite: olm
test: olm-crds-have-validation-test
@@ -38,7 +38,7 @@ stages:
- entrypoint:
- scorecard-test
- olm-crds-have-resources
- image: quay.io/operator-framework/scorecard-test:v1.33.0
+ image: quay.io/operator-framework/scorecard-test:v1.34.1
labels:
suite: olm
test: olm-crds-have-resources-test
@@ -48,7 +48,7 @@ stages:
- entrypoint:
- scorecard-test
- olm-spec-descriptors
- image: quay.io/operator-framework/scorecard-test:v1.33.0
+ image: quay.io/operator-framework/scorecard-test:v1.34.1
labels:
suite: olm
test: olm-spec-descriptors-test
@@ -58,7 +58,7 @@ stages:
- entrypoint:
- scorecard-test
- olm-status-descriptors
- image: quay.io/operator-framework/scorecard-test:v1.33.0
+ image: quay.io/operator-framework/scorecard-test:v1.34.1
labels:
suite: olm
test: olm-status-descriptors-test
diff --git a/cmd/main.go b/cmd/main.go
index 3b808768..ad118040 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -41,7 +41,7 @@ import (
falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
admissioncontroller "github.com/crowdstrike/falcon-operator/internal/controller/admission"
containercontroller "github.com/crowdstrike/falcon-operator/internal/controller/falcon_container"
- imagecontroller "github.com/crowdstrike/falcon-operator/internal/controller/falcon_image"
+ imageanalyzercontroller "github.com/crowdstrike/falcon-operator/internal/controller/falcon_image_analyzer"
nodecontroller "github.com/crowdstrike/falcon-operator/internal/controller/falcon_node"
"github.com/crowdstrike/falcon-operator/pkg/common"
"github.com/crowdstrike/falcon-operator/version"
@@ -205,11 +205,11 @@ func main() {
setupLog.Error(err, "unable to create controller", "controller", "FalconAdmission")
os.Exit(1)
}
- if err = (&imagecontroller.FalconImageReconciler{
+ if err = (&imageanalyzercontroller.FalconImageAnalyzerReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create controller", "controller", "FalconImage")
+ setupLog.Error(err, "unable to create controller", "controller", "FalconImageAnalyzer")
os.Exit(1)
}
// +kubebuilder:scaffold:builder
diff --git a/config/crd/bases/falcon.crowdstrike.com_falconimageanalyzers.yaml b/config/crd/bases/falcon.crowdstrike.com_falconimageanalyzers.yaml
new file mode 100644
index 00000000..26aca01a
--- /dev/null
+++ b/config/crd/bases/falcon.crowdstrike.com_falconimageanalyzers.yaml
@@ -0,0 +1,417 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.13.0
+ name: falconimageanalyzers.falcon.crowdstrike.com
+spec:
+ group: falcon.crowdstrike.com
+ names:
+ kind: FalconImageAnalyzer
+ listKind: FalconImageAnalyzerList
+ plural: falconimageanalyzers
+ singular: falconimageanalyzer
+ scope: Cluster
+ versions:
+ - additionalPrinterColumns:
+ - description: Version of the Operator
+ jsonPath: .status.version
+ name: Operator Version
+ type: string
+ - description: Version of the Falcon Image Analyzer
+ jsonPath: .status.sensor
+ name: Falcon Sensor
+ type: string
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: FalconImageAnalyzer is the Schema for the falconImageAnalyzers
+ 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: FalconImageAnalyzerSpec defines the desired state of FalconImageAnalyzer
+ properties:
+ falcon_api:
+ description: "FalconAPI configures connection from your local Falcon
+ operator to CrowdStrike Falcon platform. \n When configured, it
+ will pull the sensor from registry.crowdstrike.com and deploy the
+ appropriate sensor to the cluster."
+ properties:
+ cid:
+ description: Falcon Customer ID (CID) Override (optional, default
+ is derived from the API Key pair)
+ pattern: ^[0-9a-fA-F]{32}-[0-9a-fA-F]{2}$
+ type: string
+ client_id:
+ description: Falcon OAuth2 API Client ID
+ type: string
+ client_secret:
+ description: Falcon OAuth2 API Client Secret
+ type: string
+ cloud_region:
+ description: Cloud Region defines CrowdStrike Falcon Cloud Region
+ to which the operator will connect and register.
+ enum:
+ - autodiscover
+ - us-1
+ - us-2
+ - eu-1
+ - us-gov-1
+ type: string
+ required:
+ - client_id
+ - client_secret
+ - cloud_region
+ type: object
+ image:
+ description: Location of the Image Analyzer image. Use only in cases
+ when you mirror the original image to your repository/name:tag
+ pattern: ^.*:.*$
+ type: string
+ imageAnalyzerConfig:
+ description: Additional configuration for Falcon Image Analyzer deployment.
+ properties:
+ azureConfigPath:
+ type: string
+ clusterName:
+ description: Name of the Kubernetes Cluster.
+ type: string
+ debug:
+ default: false
+ description: Enable debugging for the Falcon Image Analyzer.
+ type: boolean
+ exclusions:
+ description: Exclusions for the Falcon Image Analyzer.
+ properties:
+ namespaces:
+ description: Configure a list of namespaces for Image Analyzer
+ to ignore.
+ items:
+ type: string
+ type: array
+ registries:
+ description: Configure a list of registries for the Falcon
+ Image Analyzer to ignore.
+ items:
+ type: string
+ type: array
+ type: object
+ imagePullPolicy:
+ default: Always
+ description: PullPolicy describes a policy for if/when to pull
+ a container image
+ enum:
+ - Always
+ - IfNotPresent
+ - Never
+ type: string
+ imagePullSecrets:
+ description: ImagePullSecrets is an optional list of references
+ to secrets to use for pulling image from the image location.
+ items:
+ description: LocalObjectReference contains enough information
+ to let you locate the referenced object inside the same namespace.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ type: array
+ mountPath:
+ default: /tmp
+ description: Set the falcon image analyzer volume mount path.
+ type: string
+ priorityClass:
+ description: Enable priority class for the Falcon Image Analyzer
+ deployment.
+ properties:
+ name:
+ description: Name of the priority class to use.
+ type: string
+ type: object
+ registryConfig:
+ description: RegistryConfig for the Falcon Image Analyzer.
+ properties:
+ credentials:
+ description: If neceeary, configure the registry credentials
+ for the Falcon Image Analyzer.
+ items:
+ properties:
+ namespace:
+ description: Namespace where the registry container
+ secret is located.
+ type: string
+ secretName:
+ description: Name of the registry container secret.
+ type: string
+ type: object
+ type: array
+ type: object
+ resources:
+ description: ResourceRequirements describes the compute resource
+ requirements.
+ properties:
+ claims:
+ description: "Claims lists the names of resources, defined
+ in spec.resourceClaims, that are used by this container.
+ \n This is an alpha field and requires enabling the DynamicResourceAllocation
+ feature gate. \n This field is immutable. It can only be
+ set for containers."
+ items:
+ description: ResourceClaim references one entry in PodSpec.ResourceClaims.
+ properties:
+ name:
+ description: Name must match the name of one entry in
+ pod.spec.resourceClaims of the Pod where this field
+ is used. It makes that resource available inside a
+ container.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. Requests cannot exceed
+ Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ serviceAccount:
+ description: Define annotations that will be passed down to Image
+ Analyzer service account. This is useful for passing along AWS
+ IAM Role or GCP Workload Identity.
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Define annotations that will be passed down to
+ the Service Account. This is useful for passing along AWS
+ IAM Role or GCP Workload Identity.
+ type: object
+ type: object
+ sizeLimit:
+ default: 20Gi
+ description: Set the falcon image analyzer volume size limit.
+ type: string
+ updateStrategy:
+ default:
+ rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 0
+ description: Type of Deployment update. Can be "RollingUpdate"
+ or "OnDelete". Default is RollingUpdate.
+ properties:
+ rollingUpdate:
+ description: RollingUpdate is used to specify the strategy
+ used to roll out a deployment
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'The maximum number of pods that can be scheduled
+ above the desired number of pods. Value can be an absolute
+ number (ex: 5) or a percentage of desired pods (ex:
+ 10%). This can not be 0 if MaxUnavailable is 0. Absolute
+ number is calculated from percentage by rounding up.
+ Defaults to 25%. Example: when this is set to 30%, the
+ new ReplicaSet can be scaled up immediately when the
+ rolling update starts, such that the total number of
+ old and new pods do not exceed 130% of desired pods.
+ Once old pods have been killed, new ReplicaSet can be
+ scaled up further, ensuring that total number of pods
+ running at any time during the update is at most 130%
+ of desired pods.'
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'The maximum number of pods that can be unavailable
+ during the update. Value can be an absolute number (ex:
+ 5) or a percentage of desired pods (ex: 10%). Absolute
+ number is calculated from percentage by rounding down.
+ This can not be 0 if MaxSurge is 0. Defaults to 25%.
+ Example: when this is set to 30%, the old ReplicaSet
+ can be scaled down to 70% of desired pods immediately
+ when the rolling update starts. Once new pods are ready,
+ old ReplicaSet can be scaled down further, followed
+ by scaling up the new ReplicaSet, ensuring that the
+ total number of pods available at all times during the
+ update is at least 70% of desired pods.'
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ installNamespace:
+ default: falcon-iar
+ description: Namespace where the Falcon Image Analyzer should be installed.
+ For best security practices, this should be a dedicated namespace
+ that is not used for any other purpose. It also should not be the
+ same namespace where the Falcon Operator or the Falcon Sensor is
+ installed.
+ type: string
+ registry:
+ description: Registry configures container image registry to which
+ the Image Analyzer image will be pushed.
+ properties:
+ acr_name:
+ description: Azure Container Registry Name represents the name
+ of the ACR for the Falcon Container push. Only applicable to
+ Azure cloud.
+ type: string
+ tls:
+ description: TLS configures TLS connection for push of Falcon
+ Container image to the registry
+ properties:
+ caCertificate:
+ description: Allow for users to provide a CA Cert Bundle,
+ as either a string or base64 encoded string
+ type: string
+ caCertificateConfigMap:
+ description: Allow for users to provide a ConfigMap containing
+ a CA Cert Bundle under a key ending in .crt
+ type: string
+ insecure_skip_verify:
+ description: Allow pushing to docker registries over HTTPS
+ with failed TLS verification. Note that this does not affect
+ other TLS connections.
+ type: boolean
+ type: object
+ type:
+ description: Type of container registry to be used
+ enum:
+ - acr
+ - ecr
+ - gcr
+ - crowdstrike
+ - openshift
+ type: string
+ required:
+ - type
+ type: object
+ version:
+ description: 'Falcon Image Analyzer Version. The latest version will
+ be selected when version specifier is missing. Example: 6.31, 6.31.0,
+ 6.31.0-1409, etc.'
+ type: string
+ type: object
+ status:
+ description: FalconAdmissionStatus defines the observed state of FalconAdmission
+ properties:
+ conditions:
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource. --- This struct is intended for direct
+ use as an array at the field path .status.conditions. For example,
+ \n type FooStatus struct{ // Represents the observations of a
+ foo's current state. // Known .status.conditions.type are: \"Available\",
+ \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
+ // +listType=map // +listMapKey=type Conditions []metav1.Condition
+ `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
+ protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
+ properties:
+ lastTransitionTime:
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another. This should be when
+ the underlying condition changed. If that is not known, then
+ using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: message is a human readable message indicating
+ details about the transition. This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon. For instance, if .metadata.generation
+ is currently 12, but the .status.conditions[x].observedGeneration
+ is 9, the condition is out of date with respect to the current
+ state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition. Producers
+ of specific condition types may define expected values and
+ meanings for this field, and whether the values are considered
+ a guaranteed API. The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ --- Many .condition.type values are consistent across resources
+ like Available, but because arbitrary conditions can be useful
+ (see .node.status.conditions), the ability to deconflict is
+ important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ sensor:
+ description: Version of the CrowdStrike Falcon Sensor
+ type: string
+ version:
+ description: Version of the CrowdStrike Falcon Operator
+ type: string
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/config/crd/bases/falcon.crowdstrike.com_falconimages.yaml b/config/crd/bases/falcon.crowdstrike.com_falconimages.yaml
deleted file mode 100644
index e23986a1..00000000
--- a/config/crd/bases/falcon.crowdstrike.com_falconimages.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.13.0
- name: falconimages.falcon.crowdstrike.com
-spec:
- group: falcon.crowdstrike.com
- names:
- kind: FalconImage
- listKind: FalconImageList
- plural: falconimages
- singular: falconimage
- scope: Namespaced
- versions:
- - name: v1alpha1
- schema:
- openAPIV3Schema:
- description: FalconImage is the Schema for the falconimages 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: FalconImageSpec defines the desired state of FalconImage
- properties:
- foo:
- description: Foo is an example field of FalconImage. Edit falconimage_types.go
- to remove/update
- type: string
- type: object
- status:
- description: FalconImageStatus defines the observed state of FalconImage
- type: object
- type: object
- served: true
- storage: true
- subresources:
- status: {}
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index d79dd3d8..a811b831 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -5,7 +5,7 @@ resources:
- bases/falcon.crowdstrike.com_falconadmissions.yaml
- bases/falcon.crowdstrike.com_falconcontainers.yaml
- bases/falcon.crowdstrike.com_falconnodesensors.yaml
-- bases/falcon.crowdstrike.com_falconimages.yaml
+- bases/falcon.crowdstrike.com_falconimageanalyzers.yaml
#+kubebuilder:scaffold:crdkustomizeresource
patches:
@@ -15,6 +15,7 @@ patches:
#- path: patches/webhook_in_falconcontainers.yaml
#- path: patches/webhook_in_falconnodesensors.yaml
#- path: patches/webhook_in_falconimages.yaml
+#- path: patches/webhook_in_falconimageanalyzers.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
@@ -23,6 +24,7 @@ patches:
#- path: patches/cainjection_in_falconcontainers.yaml
#- path: patches/cainjection_in_falconnodesensors.yaml
#- path: patches/cainjection_in_falconimages.yaml
+#- path: patches/cainjection_in_falconimageanalyzers.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
# [WEBHOOK] To enable webhook, uncomment the following section
diff --git a/config/crd/patches/cainjection_in_falcon_falconimages.yaml b/config/crd/patches/cainjection_in_falcon_falconimageanalyzers.yaml
similarity index 82%
rename from config/crd/patches/cainjection_in_falcon_falconimages.yaml
rename to config/crd/patches/cainjection_in_falcon_falconimageanalyzers.yaml
index 398a45ab..53b6919c 100644
--- a/config/crd/patches/cainjection_in_falcon_falconimages.yaml
+++ b/config/crd/patches/cainjection_in_falcon_falconimageanalyzers.yaml
@@ -4,4 +4,4 @@ kind: CustomResourceDefinition
metadata:
annotations:
cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME
- name: falconimages.falcon.crowdstrike.com
+ name: falconimageanalyzers.falcon.crowdstrike.com
diff --git a/config/crd/patches/webhook_in_falcon_falconimages.yaml b/config/crd/patches/webhook_in_falcon_falconimageanalyzers.yaml
similarity index 87%
rename from config/crd/patches/webhook_in_falcon_falconimages.yaml
rename to config/crd/patches/webhook_in_falcon_falconimageanalyzers.yaml
index b62ab3e8..11d0a20b 100644
--- a/config/crd/patches/webhook_in_falcon_falconimages.yaml
+++ b/config/crd/patches/webhook_in_falcon_falconimageanalyzers.yaml
@@ -2,7 +2,7 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
- name: falconimages.falcon.crowdstrike.com
+ name: falconimageanalyzers.falcon.crowdstrike.com
spec:
conversion:
strategy: Webhook
diff --git a/config/manifests/bases/falcon-operator.clusterserviceversion.yaml b/config/manifests/bases/falcon-operator.clusterserviceversion.yaml
index 88066993..7570b4bb 100644
--- a/config/manifests/bases/falcon-operator.clusterserviceversion.yaml
+++ b/config/manifests/bases/falcon-operator.clusterserviceversion.yaml
@@ -87,12 +87,6 @@ spec:
path: resourcequota.pods
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:podCount
- - description: For OpenShift clusters, ignore openshift-specific namespaces
- for admission control.
- displayName: Ignore OpenShift Namespaces
- path: admissionConfig.disabledNamespaces.ignoreOpenShiftNamespaces
- x-descriptors:
- - urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- displayName: Falcon Admission Controller Image Pull Policy
path: admissionConfig.imagePullPolicy
x-descriptors:
@@ -156,7 +150,7 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:number
- description: The application proxy host to use for Falcon sensor proxy configuration.
- displayName: Disable Falcon Proxy Host
+ displayName: Falcon Proxy Host
path: falcon.aph
- description: Falcon Customer ID (CID) Override (optional, default is derived
from the API Key pair)
@@ -253,6 +247,14 @@ spec:
path: injector.serviceAccount
- displayName: Falcon Container Injector TLS Validity Length (days)
path: injector.tls.validity
+ - description: Namespace where the Falcon Sensor should be installed. For best
+ security practices, this should be a dedicated namespace that is not used
+ for any other purpose. It also should not be the same namespace where the
+ Falcon Operator, or other Falcon resources are deployed.
+ displayName: Install Namespace
+ path: installNamespace
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Namespace
- description: Allow pushing to docker registries over HTTPS with failed TLS
verification. Note that this does not affect other TLS connections.
displayName: Skip Registry TLS Verification
@@ -311,7 +313,7 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap
- description: The application proxy host to use for Falcon sensor proxy configuration.
- displayName: Disable Falcon Proxy Host
+ displayName: Falcon Proxy Host
path: falcon.aph
- description: Falcon Customer ID (CID) Override (optional, default is derived
from the API Key pair)
@@ -366,6 +368,156 @@ spec:
displayName: Annotations
path: injector.serviceAccount.annotations
version: v1alpha1
+ - description: FalconImageAnalyzer is the Schema for the falconImageAnalyzers
+ API
+ displayName: Falcon Image Analyzer
+ kind: FalconImageAnalyzer
+ name: falconimageanalyzers.falcon.crowdstrike.com
+ specDescriptors:
+ - description: Falcon OAuth2 API Client ID
+ displayName: Client ID
+ path: falcon_api.client_id
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:password
+ - description: Configure a list of registries for the Falcon Image Analyzer
+ to ignore.
+ displayName: Exclusions List
+ path: imageAnalyzerConfig.exclusions.registries
+ - description: Name of the priority class to use.
+ displayName: Name of the Priority Class to use
+ path: imageAnalyzerConfig.priorityClass.name
+ - description: If neceeary, configure the registry credentials for the Falcon
+ Image Analyzer.
+ displayName: Registry Credentials
+ path: imageAnalyzerConfig.registryConfig.credentials
+ - description: Define annotations that will be passed down to Image Analyzer
+ service account. This is useful for passing along AWS IAM Role or GCP Workload
+ Identity.
+ displayName: Service Account Configuration
+ path: imageAnalyzerConfig.serviceAccount
+ - description: Define annotations that will be passed down to the Service Account.
+ This is useful for passing along AWS IAM Role or GCP Workload Identity.
+ displayName: Service Account Annotations
+ path: imageAnalyzerConfig.serviceAccount.annotations
+ - description: RollingUpdate is used to specify the strategy used to roll out
+ a deployment
+ displayName: Falcon Admisison Controller deployment update configuration
+ path: imageAnalyzerConfig.updateStrategy.rollingUpdate
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:updateStrategy
+ - description: Namespace where the Falcon Image Analyzer should be installed.
+ For best security practices, this should be a dedicated namespace that is
+ not used for any other purpose. It also should not be the same namespace
+ where the Falcon Operator or the Falcon Sensor is installed.
+ displayName: Install Namespace
+ path: installNamespace
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Namespace
+ - description: Allow pushing to docker registries over HTTPS with failed TLS
+ verification. Note that this does not affect other TLS connections.
+ displayName: Skip Registry TLS Verification
+ path: registry.tls.insecure_skip_verify
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:booleanSwitch
+ - description: Type of container registry to be used
+ displayName: Registry Type
+ path: registry.type
+ - description: "FalconAPI configures connection from your local Falcon operator
+ to CrowdStrike Falcon platform. \n When configured, it will pull the sensor
+ from registry.crowdstrike.com and deploy the appropriate sensor to the cluster."
+ displayName: Falcon Platform API Configuration
+ path: falcon_api
+ - description: Falcon OAuth2 API Client Secret
+ displayName: Client Secret
+ path: falcon_api.client_secret
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:password
+ - description: Configure a list of namespaces for Image Analyzer to ignore.
+ displayName: Ignore Namespace List
+ path: imageAnalyzerConfig.exclusions.namespaces
+ - displayName: Falcon Image Analyzer Image Pull Policy
+ path: imageAnalyzerConfig.imagePullPolicy
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:imagePullPolicy
+ - description: TLS configures TLS connection for push of Falcon Container image
+ to the registry
+ displayName: Registry TLS Configuration
+ path: registry.tls
+ - description: Allow for users to provide a CA Cert Bundle, as either a string
+ or base64 encoded string
+ displayName: Registry CA Certificate Bundle; optionally (double) base64 encoded
+ path: registry.tls.caCertificate
+ - description: Cloud Region defines CrowdStrike Falcon Cloud Region to which
+ the operator will connect and register.
+ displayName: CrowdStrike Falcon Cloud Region
+ path: falcon_api.cloud_region
+ - description: ImagePullSecrets is an optional list of references to secrets
+ to use for pulling image from the image location.
+ displayName: Falcon Image Analyzer Image Pull Secrets
+ path: imageAnalyzerConfig.imagePullSecrets
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Secret
+ - description: Azure Container Registry Name represents the name of the ACR
+ for the Falcon Container push. Only applicable to Azure cloud.
+ displayName: Azure Container Registry Name
+ path: registry.acr_name
+ - description: Allow for users to provide a ConfigMap containing a CA Cert Bundle
+ under a key ending in .crt
+ displayName: ConfigMap containing Registry CA Certificate Bundle
+ path: registry.tls.caCertificateConfigMap
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap
+ - description: Falcon Customer ID (CID) Override (optional, default is derived
+ from the API Key pair)
+ displayName: Falcon Customer ID (CID)
+ path: falcon_api.cid
+ - displayName: Falcon Image Analyzer Resources
+ path: imageAnalyzerConfig.resources
+ x-descriptors:
+ - urn:alm:descriptor:com.tectonic.ui:resourceRequirements
+ - description: Additional configuration for Falcon Image Analyzer deployment.
+ displayName: Falcon Image Analyzer Configuration
+ path: imageAnalyzerConfig
+ - displayName: Azure Config file path
+ path: imageAnalyzerConfig.azureConfigPath
+ - description: Enable priority class for the Falcon Image Analyzer deployment.
+ displayName: Priority Class
+ path: imageAnalyzerConfig.priorityClass
+ - description: Registry configures container image registry to which the Image
+ Analyzer image will be pushed.
+ displayName: Falcon Image Analyzer Registry Configuration
+ path: registry
+ - description: Location of the Image Analyzer image. Use only in cases when
+ you mirror the original image to your repository/name:tag
+ displayName: Falcon Image Analyzer Image URI
+ path: image
+ - description: Type of Deployment update. Can be "RollingUpdate" or "OnDelete".
+ Default is RollingUpdate.
+ displayName: Deployment Update Strategy
+ path: imageAnalyzerConfig.updateStrategy
+ - description: Set the falcon image analyzer volume size limit.
+ displayName: Falcon Image Analyzer Volume Size Limit
+ path: imageAnalyzerConfig.sizeLimit
+ - description: 'Falcon Image Analyzer Version. The latest version will be selected
+ when version specifier is missing. Example: 6.31, 6.31.0, 6.31.0-1409, etc.'
+ displayName: Falcon Image Analyzer Version
+ path: version
+ - description: Set the falcon image analyzer volume mount path.
+ displayName: Falcon Image Analyzer Volume Mount Path
+ path: imageAnalyzerConfig.mountPath
+ - description: Name of the Kubernetes Cluster.
+ displayName: Falcon Image Analyzer Cluster Name
+ path: imageAnalyzerConfig.clusterName
+ - description: Exclusions for the Falcon Image Analyzer.
+ displayName: Falcon Image Analyzer Exclusions
+ path: imageAnalyzerConfig.exclusions
+ - description: RegistryConfig for the Falcon Image Analyzer.
+ displayName: Falcon Image Analyzer Registry Configuration Options
+ path: imageAnalyzerConfig.registryConfig
+ - description: Enable debugging for the Falcon Image Analyzer.
+ displayName: Falcon Image Analyzer Enable Debugging
+ path: imageAnalyzerConfig.debug
+ version: v1alpha1
- description: FalconNodeSensor is the Schema for the falconnodesensors API
displayName: Falcon Node Sensor
kind: FalconNodeSensor
@@ -385,6 +537,14 @@ spec:
path: falcon_api.client_id
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:password
+ - description: Namespace where the Falcon Sensor should be installed. For best
+ security practices, this should be a dedicated namespace that is not used
+ for any other purpose. It also should not be the same namespace where the
+ Falcon Operator, or other Falcon resources are deployed.
+ displayName: Install Namespace
+ path: installNamespace
+ x-descriptors:
+ - urn:alm:descriptor:io.kubernetes:Namespace
- description: ImagePullSecrets is an optional list of references to secrets
in the falcon-system namespace to use for pulling image from image_override
location.
@@ -431,7 +591,7 @@ spec:
displayName: Priority Class Value
path: node.priorityClass.value
- description: The application proxy host to use for Falcon sensor proxy configuration.
- displayName: Disable Falcon Proxy Host
+ displayName: Falcon Proxy Host
path: falcon.aph
- description: Falcon Customer ID (CID) Override (optional, default is derived
from the API Key pair)
@@ -533,6 +693,7 @@ spec:
| Custom Resource | Description |
| :-------- | :------------ |
| [FalconAdmission](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/admission/README.md) | Manages installation of Falcon Admission Controller on the cluster |
+ | [FalconImageAnalyzer](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/imageanalyzer/README.md) | Manages installation of Falcon Image Assessment at Runtime on the cluster |
| [FalconContainer](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/container/README.md) | Manages installation of Falcon Container Sensor on the cluster |
| [FalconNodeSensor](https://github.com/CrowdStrike/falcon-operator/tree/main/docs/resources/node/README.md) | Manages installation of Falcon Linux Sensor on the cluster nodes |
diff --git a/config/non-olm/kustomization.yaml b/config/non-olm/kustomization.yaml
index 7cdb14ca..72efb190 100644
--- a/config/non-olm/kustomization.yaml
+++ b/config/non-olm/kustomization.yaml
@@ -34,3 +34,4 @@ patches:
- path: patches/manager_patch.yaml
- path: patches/namespace_patch.yaml
- path: patches/falconnodesensor_role.yaml
+- path: patches/falcon_falconimageanalyzer_role.yaml
diff --git a/config/non-olm/patches/falcon_falconimageanalyzer_role.yaml b/config/non-olm/patches/falcon_falconimageanalyzer_role.yaml
new file mode 100644
index 00000000..53ab8a3f
--- /dev/null
+++ b/config/non-olm/patches/falcon_falconimageanalyzer_role.yaml
@@ -0,0 +1,23 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ crowdstrike.com/component: rbac
+ crowdstrike.com/created-by: falcon-operator
+ crowdstrike.com/instance: image-controller-role
+ crowdstrike.com/managed-by: kustomize
+ crowdstrike.com/name: clusterrole
+ crowdstrike.com/part-of: Falcon
+ crowdstrike.com/provider: crowdstrike
+ name: image-controller-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - pods
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
diff --git a/config/rbac/falcon_falconimage_editor_role.yaml b/config/rbac/falcon_falconimageanalyzer_editor_role.yaml
similarity index 69%
rename from config/rbac/falcon_falconimage_editor_role.yaml
rename to config/rbac/falcon_falconimageanalyzer_editor_role.yaml
index cd8e65e1..74e2f83a 100644
--- a/config/rbac/falcon_falconimage_editor_role.yaml
+++ b/config/rbac/falcon_falconimageanalyzer_editor_role.yaml
@@ -1,20 +1,20 @@
-# permissions for end users to edit falconimages.
+# permissions for end users to edit falconimageanalyzers.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
- app.kubernetes.io/instance: falconimage-editor-role
+ app.kubernetes.io/instance: falconimageanalyzer-editor-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: falcon-operator
app.kubernetes.io/part-of: falcon-operator
app.kubernetes.io/managed-by: kustomize
- name: falconimage-editor-role
+ name: falconimageanalyzer-editor-role
rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages
+ - falconimageanalyzers
verbs:
- create
- delete
@@ -26,6 +26,6 @@ rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages/status
+ - falconimageanalyzers/status
verbs:
- get
diff --git a/config/rbac/falcon_falconimageanalyzer_role.yaml b/config/rbac/falcon_falconimageanalyzer_role.yaml
new file mode 100644
index 00000000..c374e396
--- /dev/null
+++ b/config/rbac/falcon_falconimageanalyzer_role.yaml
@@ -0,0 +1,31 @@
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ crowdstrike.com/component: rbac
+ crowdstrike.com/created-by: falcon-operator
+ crowdstrike.com/instance: image-controller-role
+ crowdstrike.com/managed-by: kustomize
+ crowdstrike.com/name: clusterrole
+ crowdstrike.com/part-of: Falcon
+ crowdstrike.com/provider: crowdstrike
+ name: image-controller-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - pods
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - security.openshift.io
+ resourceNames:
+ - privileged
+ resources:
+ - securitycontextconstraints
+ verbs:
+ - use
diff --git a/config/rbac/falcon_falconimage_viewer_role.yaml b/config/rbac/falcon_falconimageanalyzer_viewer_role.yaml
similarity index 67%
rename from config/rbac/falcon_falconimage_viewer_role.yaml
rename to config/rbac/falcon_falconimageanalyzer_viewer_role.yaml
index b7e02989..b0e2641c 100644
--- a/config/rbac/falcon_falconimage_viewer_role.yaml
+++ b/config/rbac/falcon_falconimageanalyzer_viewer_role.yaml
@@ -1,20 +1,20 @@
-# permissions for end users to view falconimages.
+# permissions for end users to view falconimageanalyzers.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
- app.kubernetes.io/instance: falconimage-viewer-role
+ app.kubernetes.io/instance: falconimageanalyzer-viewer-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: falcon-operator
app.kubernetes.io/part-of: falcon-operator
app.kubernetes.io/managed-by: kustomize
- name: falconimage-viewer-role
+ name: falconimageanalyzer-viewer-role
rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages
+ - falconimageanalyzers
verbs:
- get
- list
@@ -22,6 +22,6 @@ rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages/status
+ - falconimageanalyzers/status
verbs:
- get
diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml
index 98daede3..09b4558d 100644
--- a/config/rbac/kustomization.yaml
+++ b/config/rbac/kustomization.yaml
@@ -25,3 +25,6 @@ resources:
# AdmissionController RBAC
- falconadmission_role.yaml
+
+# ImageAnalyzer RBAC
+- falcon_falconimageanalyzer_role.yaml
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index b7e87b39..432a8e02 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -258,7 +258,7 @@ rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages
+ - falconimageanalyzers
verbs:
- create
- delete
@@ -270,13 +270,13 @@ rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages/finalizers
+ - falconimageanalyzers/finalizers
verbs:
- update
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages/status
+ - falconimageanalyzers/status
verbs:
- get
- patch
@@ -329,6 +329,17 @@ rules:
- list
- update
- watch
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - update
+ - watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
diff --git a/config/samples/falcon_v1alpha1_falconimage.yaml b/config/samples/falcon_v1alpha1_falconimage.yaml
deleted file mode 100644
index da59166f..00000000
--- a/config/samples/falcon_v1alpha1_falconimage.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: falcon.crowdstrike.com/v1alpha1
-kind: FalconImage
-metadata:
- labels:
- app.kubernetes.io/name: falconimage
- app.kubernetes.io/instance: falconimage-sample
- app.kubernetes.io/part-of: falcon-operator
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/created-by: falcon-operator
- name: falconimage-sample
-spec:
- # TODO(user): Add fields here
diff --git a/config/samples/falcon_v1alpha1_falconimageanalyzer-all-options.yaml b/config/samples/falcon_v1alpha1_falconimageanalyzer-all-options.yaml
new file mode 100644
index 00000000..0f96484f
--- /dev/null
+++ b/config/samples/falcon_v1alpha1_falconimageanalyzer-all-options.yaml
@@ -0,0 +1,51 @@
+apiVersion: falcon.crowdstrike.com/v1alpha1
+kind: FalconImageAnalyzer
+metadata:
+ labels:
+ app.kubernetes.io/name: falconimageanalyzer
+ app.kubernetes.io/instance: falconimageanalyzer-sample
+ app.kubernetes.io/part-of: falcon-operator
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/created-by: falcon-operator
+ name: falconimageanalyzer-sample
+spec:
+ falcon_api:
+ client_id: PLEASE_FILL_IN
+ client_secret: PLEASE_FILL_IN
+ cloud_region: autodiscover
+ cid: 00001111222233334444555566667777-12
+ imageAnalyzerConfig:
+ serviceAccount:
+ annotations:
+ # These are just examples, you wouldn't combine AWS & GKE roles at once
+ eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/iam-role-name
+ iam.gke.io/gcp-service-account: $GCP_SERVICE_ACCOUNT@$GCP_PROJECT_ID.iam.gserviceaccount.com
+ imagePullPolicy: Always
+ imagePullSecret:
+ - name: your-pre-created-secret
+ azureConfigPath: "/etc/azure.json"
+ sizeLimit: "20Gi"
+ mountPath: "/tmp"
+ clusterName: my-cluster
+ debug: true
+ priorityClass:
+ name: my_pc_name
+ exclusions:
+ registries:
+ - myreg
+ - myreg2
+ namespaces:
+ - n1
+ - n2
+ registryConfig:
+ credentials:
+ - namespace: test
+ secretName: secret
+ - namespace: test2
+ secretName: secret2
+ registry:
+ type: acr
+ acr_name: falcon-sensor-repo
+ tls:
+ insecure_skip_verify: false
+ version: 1.2.3.tagname
diff --git a/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml b/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml
new file mode 100644
index 00000000..22263fbe
--- /dev/null
+++ b/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml
@@ -0,0 +1,17 @@
+apiVersion: falcon.crowdstrike.com/v1alpha1
+kind: FalconImageAnalyzer
+metadata:
+ labels:
+ app.kubernetes.io/name: falconimageanalyzer
+ app.kubernetes.io/instance: falconimageanalyzer-sample
+ app.kubernetes.io/part-of: falcon-operator
+ app.kubernetes.io/managed-by: kustomize
+ app.kubernetes.io/created-by: falcon-operator
+ name: falconimageanalyzer-sample
+spec:
+ falcon_api:
+ client_id: PLEASE_FILL_IN
+ client_secret: PLEASE_FILL_IN
+ cloud_region: autodiscover
+ registry:
+ type: crowdstrike
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index 8d0d6bb6..a7c5f656 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -3,5 +3,5 @@ resources:
- falcon_v1alpha1_falconadmission.yaml
- falcon_v1alpha1_falconcontainer.yaml
- falcon_v1alpha1_falconnodesensor.yaml
-- falcon_v1alpha1_falconimage.yaml
+- falcon_v1alpha1_falconimageanalyzer.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
diff --git a/deploy/falcon-operator.yaml b/deploy/falcon-operator.yaml
index af30c4bb..ad7424ae 100644
--- a/deploy/falcon-operator.yaml
+++ b/deploy/falcon-operator.yaml
@@ -2575,20 +2575,30 @@ kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.13.0
- name: falconimages.falcon.crowdstrike.com
+ name: falconimageanalyzers.falcon.crowdstrike.com
spec:
group: falcon.crowdstrike.com
names:
- kind: FalconImage
- listKind: FalconImageList
- plural: falconimages
- singular: falconimage
- scope: Namespaced
+ kind: FalconImageAnalyzer
+ listKind: FalconImageAnalyzerList
+ plural: falconimageanalyzers
+ singular: falconimageanalyzer
+ scope: Cluster
versions:
- - name: v1alpha1
+ - additionalPrinterColumns:
+ - description: Version of the Operator
+ jsonPath: .status.version
+ name: Operator Version
+ type: string
+ - description: Version of the Falcon Image Analyzer
+ jsonPath: .status.sensor
+ name: Falcon Sensor
+ type: string
+ name: v1alpha1
schema:
openAPIV3Schema:
- description: FalconImage is the Schema for the falconimages API
+ description: FalconImageAnalyzer is the Schema for the falconImageAnalyzers
+ API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
@@ -2603,15 +2613,373 @@ spec:
metadata:
type: object
spec:
- description: FalconImageSpec defines the desired state of FalconImage
+ description: FalconImageAnalyzerSpec defines the desired state of FalconImageAnalyzer
properties:
- foo:
- description: Foo is an example field of FalconImage. Edit falconimage_types.go
- to remove/update
+ falcon_api:
+ description: "FalconAPI configures connection from your local Falcon
+ operator to CrowdStrike Falcon platform. \n When configured, it
+ will pull the sensor from registry.crowdstrike.com and deploy the
+ appropriate sensor to the cluster."
+ properties:
+ cid:
+ description: Falcon Customer ID (CID) Override (optional, default
+ is derived from the API Key pair)
+ pattern: ^[0-9a-fA-F]{32}-[0-9a-fA-F]{2}$
+ type: string
+ client_id:
+ description: Falcon OAuth2 API Client ID
+ type: string
+ client_secret:
+ description: Falcon OAuth2 API Client Secret
+ type: string
+ cloud_region:
+ description: Cloud Region defines CrowdStrike Falcon Cloud Region
+ to which the operator will connect and register.
+ enum:
+ - autodiscover
+ - us-1
+ - us-2
+ - eu-1
+ - us-gov-1
+ type: string
+ required:
+ - client_id
+ - client_secret
+ - cloud_region
+ type: object
+ image:
+ description: Location of the Image Analyzer image. Use only in cases
+ when you mirror the original image to your repository/name:tag
+ pattern: ^.*:.*$
+ type: string
+ imageAnalyzerConfig:
+ description: Additional configuration for Falcon Image Analyzer deployment.
+ properties:
+ azureConfigPath:
+ type: string
+ clusterName:
+ description: Name of the Kubernetes Cluster.
+ type: string
+ debug:
+ default: false
+ description: Enable debugging for the Falcon Image Analyzer.
+ type: boolean
+ exclusions:
+ description: Exclusions for the Falcon Image Analyzer.
+ properties:
+ namespaces:
+ description: Configure a list of namespaces for Image Analyzer
+ to ignore.
+ items:
+ type: string
+ type: array
+ registries:
+ description: Configure a list of registries for the Falcon
+ Image Analyzer to ignore.
+ items:
+ type: string
+ type: array
+ type: object
+ imagePullPolicy:
+ default: Always
+ description: PullPolicy describes a policy for if/when to pull
+ a container image
+ enum:
+ - Always
+ - IfNotPresent
+ - Never
+ type: string
+ imagePullSecrets:
+ description: ImagePullSecrets is an optional list of references
+ to secrets to use for pulling image from the image location.
+ items:
+ description: LocalObjectReference contains enough information
+ to let you locate the referenced object inside the same namespace.
+ properties:
+ name:
+ description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ TODO: Add other useful fields. apiVersion, kind, uid?'
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ type: array
+ mountPath:
+ default: /tmp
+ description: Set the falcon image analyzer volume mount path.
+ type: string
+ priorityClass:
+ description: Enable priority class for the Falcon Image Analyzer
+ deployment.
+ properties:
+ name:
+ description: Name of the priority class to use.
+ type: string
+ type: object
+ registryConfig:
+ description: RegistryConfig for the Falcon Image Analyzer.
+ properties:
+ credentials:
+ description: If neceeary, configure the registry credentials
+ for the Falcon Image Analyzer.
+ items:
+ properties:
+ namespace:
+ description: Namespace where the registry container
+ secret is located.
+ type: string
+ secretName:
+ description: Name of the registry container secret.
+ type: string
+ type: object
+ type: array
+ type: object
+ resources:
+ description: ResourceRequirements describes the compute resource
+ requirements.
+ properties:
+ claims:
+ description: "Claims lists the names of resources, defined
+ in spec.resourceClaims, that are used by this container.
+ \n This is an alpha field and requires enabling the DynamicResourceAllocation
+ feature gate. \n This field is immutable. It can only be
+ set for containers."
+ items:
+ description: ResourceClaim references one entry in PodSpec.ResourceClaims.
+ properties:
+ name:
+ description: Name must match the name of one entry in
+ pod.spec.resourceClaims of the Pod where this field
+ is used. It makes that resource available inside a
+ container.
+ type: string
+ required:
+ - name
+ type: object
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. Requests cannot exceed
+ Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
+ type: object
+ type: object
+ serviceAccount:
+ description: Define annotations that will be passed down to Image
+ Analyzer service account. This is useful for passing along AWS
+ IAM Role or GCP Workload Identity.
+ properties:
+ annotations:
+ additionalProperties:
+ type: string
+ description: Define annotations that will be passed down to
+ the Service Account. This is useful for passing along AWS
+ IAM Role or GCP Workload Identity.
+ type: object
+ type: object
+ sizeLimit:
+ default: 20Gi
+ description: Set the falcon image analyzer volume size limit.
+ type: string
+ updateStrategy:
+ default:
+ rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 0
+ description: Type of Deployment update. Can be "RollingUpdate"
+ or "OnDelete". Default is RollingUpdate.
+ properties:
+ rollingUpdate:
+ description: RollingUpdate is used to specify the strategy
+ used to roll out a deployment
+ properties:
+ maxSurge:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'The maximum number of pods that can be scheduled
+ above the desired number of pods. Value can be an absolute
+ number (ex: 5) or a percentage of desired pods (ex:
+ 10%). This can not be 0 if MaxUnavailable is 0. Absolute
+ number is calculated from percentage by rounding up.
+ Defaults to 25%. Example: when this is set to 30%, the
+ new ReplicaSet can be scaled up immediately when the
+ rolling update starts, such that the total number of
+ old and new pods do not exceed 130% of desired pods.
+ Once old pods have been killed, new ReplicaSet can be
+ scaled up further, ensuring that total number of pods
+ running at any time during the update is at most 130%
+ of desired pods.'
+ x-kubernetes-int-or-string: true
+ maxUnavailable:
+ anyOf:
+ - type: integer
+ - type: string
+ description: 'The maximum number of pods that can be unavailable
+ during the update. Value can be an absolute number (ex:
+ 5) or a percentage of desired pods (ex: 10%). Absolute
+ number is calculated from percentage by rounding down.
+ This can not be 0 if MaxSurge is 0. Defaults to 25%.
+ Example: when this is set to 30%, the old ReplicaSet
+ can be scaled down to 70% of desired pods immediately
+ when the rolling update starts. Once new pods are ready,
+ old ReplicaSet can be scaled down further, followed
+ by scaling up the new ReplicaSet, ensuring that the
+ total number of pods available at all times during the
+ update is at least 70% of desired pods.'
+ x-kubernetes-int-or-string: true
+ type: object
+ type: object
+ type: object
+ installNamespace:
+ default: falcon-iar
+ description: Namespace where the Falcon Image Analyzer should be installed.
+ For best security practices, this should be a dedicated namespace
+ that is not used for any other purpose. It also should not be the
+ same namespace where the Falcon Operator or the Falcon Sensor is
+ installed.
+ type: string
+ registry:
+ description: Registry configures container image registry to which
+ the Image Analyzer image will be pushed.
+ properties:
+ acr_name:
+ description: Azure Container Registry Name represents the name
+ of the ACR for the Falcon Container push. Only applicable to
+ Azure cloud.
+ type: string
+ tls:
+ description: TLS configures TLS connection for push of Falcon
+ Container image to the registry
+ properties:
+ caCertificate:
+ description: Allow for users to provide a CA Cert Bundle,
+ as either a string or base64 encoded string
+ type: string
+ caCertificateConfigMap:
+ description: Allow for users to provide a ConfigMap containing
+ a CA Cert Bundle under a key ending in .crt
+ type: string
+ insecure_skip_verify:
+ description: Allow pushing to docker registries over HTTPS
+ with failed TLS verification. Note that this does not affect
+ other TLS connections.
+ type: boolean
+ type: object
+ type:
+ description: Type of container registry to be used
+ enum:
+ - acr
+ - ecr
+ - gcr
+ - crowdstrike
+ - openshift
+ type: string
+ required:
+ - type
+ type: object
+ version:
+ description: 'Falcon Image Analyzer Version. The latest version will
+ be selected when version specifier is missing. Example: 6.31, 6.31.0,
+ 6.31.0-1409, etc.'
type: string
type: object
status:
- description: FalconImageStatus defines the observed state of FalconImage
+ description: FalconAdmissionStatus defines the observed state of FalconAdmission
+ properties:
+ conditions:
+ items:
+ description: "Condition contains details for one aspect of the current
+ state of this API Resource. --- This struct is intended for direct
+ use as an array at the field path .status.conditions. For example,
+ \n type FooStatus struct{ // Represents the observations of a
+ foo's current state. // Known .status.conditions.type are: \"Available\",
+ \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge
+ // +listType=map // +listMapKey=type Conditions []metav1.Condition
+ `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\"
+ protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }"
+ properties:
+ lastTransitionTime:
+ description: lastTransitionTime is the last time the condition
+ transitioned from one status to another. This should be when
+ the underlying condition changed. If that is not known, then
+ using the time when the API field changed is acceptable.
+ format: date-time
+ type: string
+ message:
+ description: message is a human readable message indicating
+ details about the transition. This may be an empty string.
+ maxLength: 32768
+ type: string
+ observedGeneration:
+ description: observedGeneration represents the .metadata.generation
+ that the condition was set based upon. For instance, if .metadata.generation
+ is currently 12, but the .status.conditions[x].observedGeneration
+ is 9, the condition is out of date with respect to the current
+ state of the instance.
+ format: int64
+ minimum: 0
+ type: integer
+ reason:
+ description: reason contains a programmatic identifier indicating
+ the reason for the condition's last transition. Producers
+ of specific condition types may define expected values and
+ meanings for this field, and whether the values are considered
+ a guaranteed API. The value should be a CamelCase string.
+ This field may not be empty.
+ maxLength: 1024
+ minLength: 1
+ pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+ type: string
+ status:
+ description: status of the condition, one of True, False, Unknown.
+ enum:
+ - "True"
+ - "False"
+ - Unknown
+ type: string
+ type:
+ description: type of condition in CamelCase or in foo.example.com/CamelCase.
+ --- Many .condition.type values are consistent across resources
+ like Available, but because arbitrary conditions can be useful
+ (see .node.status.conditions), the ability to deconflict is
+ important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
+ maxLength: 316
+ pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+ type: string
+ required:
+ - lastTransitionTime
+ - message
+ - reason
+ - status
+ - type
+ type: object
+ type: array
+ sensor:
+ description: Version of the CrowdStrike Falcon Sensor
+ type: string
+ version:
+ description: Version of the CrowdStrike Falcon Operator
+ type: string
type: object
type: object
served: true
@@ -3429,6 +3797,30 @@ rules:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
+metadata:
+ labels:
+ crowdstrike.com/component: rbac
+ crowdstrike.com/created-by: falcon-operator
+ crowdstrike.com/instance: image-controller-role
+ crowdstrike.com/managed-by: kustomize
+ crowdstrike.com/name: clusterrole
+ crowdstrike.com/part-of: Falcon
+ crowdstrike.com/provider: crowdstrike
+ name: falcon-operator-image-controller-role
+rules:
+- apiGroups:
+ - ""
+ resources:
+ - namespaces
+ - pods
+ - secrets
+ verbs:
+ - get
+ - list
+ - watch
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
metadata:
name: falcon-operator-manager-role
rules:
@@ -3686,7 +4078,7 @@ rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages
+ - falconimageanalyzers
verbs:
- create
- delete
@@ -3698,13 +4090,13 @@ rules:
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages/finalizers
+ - falconimageanalyzers/finalizers
verbs:
- update
- apiGroups:
- falcon.crowdstrike.com
resources:
- - falconimages/status
+ - falconimageanalyzers/status
verbs:
- get
- patch
@@ -3757,6 +4149,17 @@ rules:
- list
- update
- watch
+- apiGroups:
+ - rbac.authorization.k8s.io
+ resources:
+ - clusterroles
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - update
+ - watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
diff --git a/docs/deployment/azure/README.md b/docs/deployment/azure/README.md
index 05e92f47..cc23a2a2 100644
--- a/docs/deployment/azure/README.md
+++ b/docs/deployment/azure/README.md
@@ -3,6 +3,7 @@
This document will guide you through the installation of the Falcon Operator and deployment of the following custom resources provided by the Falcon Operator:
- [FalconAdmission](../../resources/admission/README.md) with the Falcon Admission Controller image being mirrored from CrowdStrike container registry to ACR (Azure Container Registry).
- [FalconContainer](../../resources/container/README.md) with the Falcon Container image being mirrored from CrowdStrike container registry to ACR (Azure Container Registry).
+- [FalconImageAnalyzer](../../resources/imageanalyzer/README.md) with the Falcon Image Analyzer image being mirrored from CrowdStrike container registry.
- [FalconNodeSensor](../../resources/node/README.md) custom resource to the cluster.
## Prerequisites
@@ -118,6 +119,20 @@ The Image push secret is used by the operator to mirror the Falcon Container sen
+### Deploying the Falcon Image Analyzer
+
+
+ Click to expand
+
+After the Falcon Operator has deployed, you can now deploy the Image Analyzer:
+
+- Deploy FalconImageAnalyzer through the cli using the `kubectl` command:
+ ```sh
+ kubectl create -n falcon-operator -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+ ```
+
+
+
## Upgrading
@@ -182,6 +197,19 @@ kubectl delete falconadmission --all
+### Uninstalling the Falcon Image Analyzer
+
+
+ Click to expand
+
+Remove the FalconImageAnalyzer resource. The operator will then uninstall the Falcon Image Analyzer from the cluster:
+
+```sh
+kubectl delete falconimageanalyzer --all
+```
+
+
+
### Uninstalling the Falcon Operator
diff --git a/docs/deployment/eks-fargate/README.md b/docs/deployment/eks-fargate/README.md
index a2c90518..02849f33 100644
--- a/docs/deployment/eks-fargate/README.md
+++ b/docs/deployment/eks-fargate/README.md
@@ -3,6 +3,7 @@
This document will guide you through the installation of the Falcon Operator and deployment of the following custom resources provided by the Falcon Operator:
- [FalconAdmission](../../resources/admission/README.md) with the Falcon Admission Controller image being mirrored from CrowdStrike container registry to ECR (Elastic Container Registry). A new AWS IAM Policy will be created to allow the operator to push to ECR registry.
- [FalconContainer](../../resources/container/README.md) with the Falcon Container image being mirrored from CrowdStrike container registry to ECR (Elastic Container Registry). A new AWS IAM Policy will be created to allow the operator to push to ECR registry.
+- [FalconImageAnalyzer](../../resources/imageanalyzer/README.md) with the Falcon Image Analyzer image being mirrored from CrowdStrike container registry.
## Prerequisites
@@ -86,6 +87,30 @@ This document will guide you through the installation of the Falcon Operator and
+### Deploying the Falcon Image Analyzer
+
+
+ Click to expand
+
+- Create an EKS Fargate profile for the FalconImageAnalyzer resource deployment:
+ ```sh
+ eksctl create fargateprofile \
+ --region "$AWS_REGION" \
+ --cluster eks-fargate-cluster \
+ --name fp-falcon-iar \
+ --namespace falcon-iar
+ ```
+
+
+After the Falcon Operator has deployed, you can now deploy the Image Analyzer:
+
+- Deploy FalconImageAnalyzer through the cli using the `kubectl` command:
+ ```sh
+ kubectl create -n falcon-operator -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+ ```
+
+
+
## Upgrading
@@ -139,6 +164,19 @@ kubectl delete falconadmission --all
+### Uninstalling the Falcon Image Analyzer
+
+
+ Click to expand
+
+Remove the FalconImageAnalyzer resource. The operator will then uninstall the Falcon Image Analyzer from the cluster:
+
+```sh
+kubectl delete falconimageanalyzer --all
+```
+
+
+
### Uninstalling the Falcon Operator
diff --git a/docs/deployment/eks/README.md b/docs/deployment/eks/README.md
index 564c03df..cfea07e0 100644
--- a/docs/deployment/eks/README.md
+++ b/docs/deployment/eks/README.md
@@ -3,6 +3,7 @@
This document will guide you through the installation of the Falcon Operator and deployment of the following custom resources provided by the Falcon Operator:
- [FalconAdmission](../../resources/admission/README.md) with the Falcon Admission Controller image being mirrored from CrowdStrike container registry to ECR (Elastic Container Registry). A new AWS IAM Policy will be created to allow the operator to push to ECR registry.
- [FalconContainer](../../resources/container/README.md) with the Falcon Container image being mirrored from CrowdStrike container registry to ECR (Elastic Container Registry). A new AWS IAM Policy will be created to allow the operator to push to ECR registry.
+- [FalconImageAnalyzer](../../resources/imageanalyzer/README.md) with the Falcon Image Analyzer image being mirrored from CrowdStrike container registry.
- [FalconNodeSensor](../../resources/node/README.md) custom resource to the cluster.
## Prerequisites
@@ -94,6 +95,20 @@ After the Falcon Operator has deployed, you can now deploy the Falcon Node Senso
+### Deploying the Falcon Image Analyzer
+
+
+ Click to expand
+
+After the Falcon Operator has deployed, you can now deploy the Image Analyzer:
+
+- Deploy FalconImageAnalyzer through the cli using the `kubectl` command:
+ ```sh
+ kubectl create -n falcon-operator -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+ ```
+
+
+
## Upgrading
@@ -158,6 +173,19 @@ kubectl delete falconadmission --all
+### Uninstalling the Falcon Image Analyzer
+
+
+ Click to expand
+
+Remove the FalconImageAnalyzer resource. The operator will then uninstall the Falcon Image Analyzer from the cluster:
+
+```sh
+kubectl delete falconimageanalyzer --all
+```
+
+
+
### Uninstalling the Falcon Operator
diff --git a/docs/deployment/generic/README.md b/docs/deployment/generic/README.md
index 42360ace..efe02634 100644
--- a/docs/deployment/generic/README.md
+++ b/docs/deployment/generic/README.md
@@ -3,6 +3,7 @@
This document will guide you through the installation of the Falcon Operator and deployment of the following custom resources provided by the Falcon Operator:
- [FalconAdmission](../../resources/admission/README.md) with the Falcon Admission Controller image being mirrored from CrowdStrike container registry to .
- [FalconContainer](../../resources/container/README.md) with the Falcon Container image being mirrored from CrowdStrike container registry to .
+- [FalconImageAnalyzer](../../resources/imageanalyzer/README.md) with the Falcon Image Analyzer image being mirrored from CrowdStrike container registry.
- [FalconNodeSensor](../../resources/node/README.md) custom resource to the cluster.
## Prerequisites
@@ -72,6 +73,20 @@ After the Falcon Operator has deployed, you can now deploy the Falcon Node Senso
+### Deploying the Falcon Image Analyzer
+
+
+ Click to expand
+
+After the Falcon Operator has deployed, you can now deploy the Image Analyzer:
+
+- Deploy FalconImageAnalyzer through the cli using the `kubectl` command:
+ ```sh
+ kubectl create -n falcon-operator -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+ ```
+
+
+
## Upgrading
@@ -136,6 +151,19 @@ kubectl delete falconadmission --all
+### Uninstalling the Falcon Image Analyzer
+
+
+ Click to expand
+
+Remove the FalconImageAnalyzer resource. The operator will then uninstall the Falcon Image Analyzer from the cluster:
+
+```sh
+kubectl delete falconimageanalyzer --all
+```
+
+
+
### Uninstalling the Falcon Operator
diff --git a/docs/deployment/gke/README.md b/docs/deployment/gke/README.md
index 14743f66..a28e7a1b 100644
--- a/docs/deployment/gke/README.md
+++ b/docs/deployment/gke/README.md
@@ -3,6 +3,7 @@
This document will guide you through the installation of the Falcon Operator and deployment of the following custom resources provided by the Falcon Operator:
- [FalconAdmission](../../resources/admission/README.md) with the Falcon Admission Controller image being mirrored from CrowdStrike container registry to GCR (Google Container Registry). A new GCP service account for pushing to GCR registry will be created.
- [FalconContainer](../../resources/container/README.md) with the Falcon Container image being mirrored from CrowdStrike container registry to GCR (Google Container Registry). A new GCP service account for pushing to GCR registry will be created.
+- [FalconImageAnalyzer](../../resources/imageanalyzer/README.md) with the Falcon Image Analyzer image being mirrored from CrowdStrike container registry.
- [FalconNodeSensor](../../resources/node/README.md) custom resource to the cluster.
## Prerequisites
@@ -118,6 +119,20 @@ An image push secret is used by the operator to mirror Falcon Container image fr
+### Deploying the Falcon Image Analyzer
+
+
+ Click to expand
+
+After the Falcon Operator has deployed, you can now deploy the Image Analyzer:
+
+- Deploy FalconImageAnalyzer through the cli using the `kubectl` command:
+ ```sh
+ kubectl create -n falcon-operator -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+ ```
+
+
+
## Upgrading
@@ -182,6 +197,19 @@ kubectl delete falconadmission --all
+### Uninstalling the Falcon Image Analyzer
+
+
+ Click to expand
+
+Remove the FalconImageAnalyzer resource. The operator will then uninstall the Falcon Image Analyzer from the cluster:
+
+```sh
+kubectl delete falconimageanalyzer --all
+```
+
+
+
### Uninstalling the Falcon Operator
@@ -197,6 +225,9 @@ kubectl delete -f https://github.com/crowdstrike/falcon-operator/releases/latest
## GKE Autopilot configuration
+
+ Click to expand
+
### Setting the PriorityClass
When you enable GKE Autopilot deployment in the Falcon Operator, this creates a new PriorityClass to ensure that the sensor DaemonSet has priority over other application pods. This means that it’s possible that some application pods are evicted or pushed back in the scheduling queue depending on cluster resources availability to accommodate sensor Pods. You can either allow the operator to deploy its own PriorityClass or specify an existing PriorityClass.
@@ -299,6 +330,8 @@ node:
+
+
## GKE Node Upgrades
If the sidecar sensor has been deployed to your GKE cluster, you will want to explicitly disable CrowdStrike Falcon from monitoring using labels for the kube-public, kube-system, falcon-operator, and falcon-system namespaces.
diff --git a/docs/deployment/openshift/resources/imageanalyzer/README.md b/docs/deployment/openshift/resources/imageanalyzer/README.md
new file mode 100644
index 00000000..3a7c8383
--- /dev/null
+++ b/docs/deployment/openshift/resources/imageanalyzer/README.md
@@ -0,0 +1,184 @@
+# Falcon Image Analyzer
+
+## About FalconImageAnalyzer Custom Resource (CR)
+Falcon Operator introduces the FalconImageAnalyzer Custom Resource (CR) to the cluster. The resource is meant to install, configure, and uninstall the Falcon Image Analyzer on the cluster.
+
+### FalconImageAnalyzer CR Configuration using CrowdStrike API Keys
+To start the FalconImageAnalyzer installation using CrowdStrike API Keys to allow the operator to determine your Falcon Customer ID (CID) as well as pull down the CrowdStrike Falcon Image Analyzer image, please create the following FalconImageAnalyzer resource to your cluster.
+
+> [!IMPORTANT]
+> You will need to provide CrowdStrike API Keys and CrowdStrike cloud region for the installation. It is recommended to establish new API credentials for the installation at https://falcon.crowdstrike.com/support/api-clients-and-keys, required permissions are:
+> * Falcon Images Download: **Read**
+> * Sensor Download: **Read**
+
+Example:
+
+```yaml
+apiVersion: falcon.crowdstrike.com/v1alpha1
+kind: FalconImageAnalyzer
+metadata:
+ name: falcon-image-analyzer
+spec:
+ falcon_api:
+ client_id: PLEASE_FILL_IN
+ client_secret: PLEASE_FILL_IN
+ cloud_region: us-1
+ registry:
+ type: crowdstrike
+```
+
+### FalconImageAnalyzer Reference Manual
+
+#### Falcon API Settings
+| Spec | Description |
+| :------------------------- | :------------------------------------------------------------------------------------------------------- |
+| falcon_api.client_id | CrowdStrike API Client ID |
+| falcon_api.client_secret | CrowdStrike API Client Secret |
+| falcon_api.cloud_region | CrowdStrike cloud region (allowed values: us-1, us-2, eu-1, us-gov-1) |
+| falcon_api.cid | CrowdStrike Falcon CID |
+
+#### Falcon Image Analyzer Configuration Settings
+| Spec | Description |
+| :---------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
+| installNamespace | (optional) Override the default namespace of falcon-iar |
+| image | (optional) Leverage a Falcon Image Analyzer Sensor image that is not managed by the operator; typically used with custom repositories; overrides all registry settings; might require imageAnalyzerConfig.imagePullSecrets to be set |
+| version | (optional) Enforce particular Falcon Image Analyzer version to be installed (example: "6.31", "6.31.0", "6.31.0-1409") |
+| registry.type | Registry to mirror Falcon Image Analyzer (allowed values: acr, ecr, crowdstrike, gcr, openshift) |
+| registry.tls.insecure_skip_verify | (optional) Skip TLS check when pushing Falcon Image Analyzer to target registry (only for demoing purposes on self-signed openshift clusters) |
+| registry.tls.caCertificate | (optional) A string containing an optionally base64-encoded Certificate Authority Chain for self-signed TLS Registry Certificates |
+| registry.tls.caCertificateConfigMap | (optional) The name of a ConfigMap containing CA Certificate Authority Chains under keys ending in ".tls" for self-signed TLS Registry Certificates (ignored when registry.tls.caCertificate is set) |
+| registry.acr_name | (optional) Name of ACR for the Falcon Falcon Image Analyzer push. Only applicable to Azure cloud. (`registry.type="acr"`) |
+| imageAnalyzerConfig.serviceAccount.annotations | (optional) Configure annotations for the falcon-iar service account (e.g. for IAM role association) |
+| imageAnalyzerConfig.azureConfigPath | (optional) Azure config file path |
+| imageAnalyzerConfig.sizeLimit | (optional) Configure the size limit of the temp storage space for scanning. By Default, this is set to `20Gi`. |
+| imageAnalyzerConfig.mountPath | (optional) Configure the location of the temp storage space for scanning. By Default, this is set to `/tmp`. |
+| imageAnalyzerConfig.clusterName | (required) K8s cluster name |
+| imageAnalyzerConfig.debug | (optional) Set to `true` for debug level log |
+| imageAnalyzerConfig.priorityClass.name | (optional) Set to avoid pod evictions due to resource limits. |
+| imageAnalyzerConfig.exclusions.registries | (optional) Set the value as a list of registries to be excluded. All images in that registry(s) will be excluded |
+| imageAnalyzerConfig.exclusions.namespaces | (optional) Set the value as a list of namespaces to be excluded. All pods in that namespace(s) will be excluded |
+| imageAnalyzerConfig.imagePullPolicy | (optional) Configure the image pull policy of the Falcon Image Analyzer |
+| imageAnalyzerConfig.imagePullSecrets | (optional) Configure the image pull secrets of the Falcon Image Analyzer |
+| imageAnalyzerConfig.registryConfig.credentials | (optional) Use this to provide registry secrets in the form of a list of maps. e.g.
- namespace: ns1
secretName: mysecretname |
+| imageAnalyzerConfig.resources | (optional) Configure the resources of the Falcon Image Analyzer |
+| imageAnalyzerConfig.updateStrategy | (optional) Configure the deployment update strategy of the Falcon Image Analyzer |
+
+
+> [!IMPORTANT]
+> All arguments are optional, but successful deployment requires either **client_id and client_secret or the Falcon cid and image**. When deploying using the CrowdStrike Falcon API, the container image and CID will be fetched from CrowdStrike Falcon API. While in the latter case, the CID and image location is explicitly specified by the user.
+
+### Auto Proxy Configuration
+
+The operator will automatically configure the sensor's proxy configuration when the cluster proxy is configured on OpenShift via OLM. See the following documentation for more information:
+* [Configuring cluster-wide proxy](https://docs.openshift.com/container-platform/latest/networking/enable-cluster-wide-proxy.html)
+* [Overriding proxy settings of an Operator](https://docs.openshift.com/container-platform/4.13/operators/admin/olm-configuring-proxy-support.html#olm-overriding-proxy-settings_olm-configuring-proxy-support)
+
+When not running on OpenShift, adding the proxy configuration via environment variables will also configure the sensor's proxy information.
+```yaml
+- args:
+ - --leader-elect
+ command:
+ - /manager
+ env:
+ - name: OPERATOR_NAME
+ value: falcon-operator
+ - name: HTTP_PROXY
+ value: http://proxy.example.com:8080
+ - name: HTTPS_PROXY
+ value: http://proxy.example.com:8080
+ image: quay.io/crowdstrike/falcon-operator:latest
+```
+These settings can be overridden by configuring the [sensor's proxy settings](#falcon-sensor-settings) which will only change the sensor's proxy settings **not** the operator's proxy settings.
+
+>[!IMPORTANT]
+> 1. If using the CrowdStrike API with the **client_id and client_secret** authentication method, the operator must be able to reach the CrowdStrike API through the proxy via the Kubernetes cluster networking configuration.
+> If the proxy is not configured correctly, the operator will not be able to authenticate with the CrowdStrike API and will not be able to create the sensor.
+> 2. If the CrowdStrike API is not used, configure the [sensor's proxy settings](#falcon-sensor-settings).
+> 3. Ensure that the host node can reach the CrowdStrike Falcon Cloud through the proxy.
+
+
+### Image Registry considerations
+
+The Falcon Image Analyzer Image is distributed by CrowdStrike through CrowdStrike Falcon registry. Operator supports two modes of deployment:
+
+#### (Option 1) Use CrowdStrike registry directly
+
+Does not require any advanced setup. Users are advised to use the following except in their FalconImageAnalyzer custom resource definition.
+
+```yaml
+registry:
+ type: crowdstrike
+```
+
+The Falcon Image Analyzer product will then be installed directly from CrowdStrike registry. Any new deployment to the cluster may contact CrowdStrike registry for the image download.
+
+#### (Option 2) Let operator mirror Falcon Image Analyzer image to your local registry
+
+Requires advanced setup to grant the operator push access to your local registry. The operator will then mirror the Falcon Image Analyzer image from CrowdStrike registry to your local registry of choice.
+Supported registries are: acr, ecr, gcr, and openshift. Each registry type requires advanced setup enable image push.
+
+#### (Option 3) Use a custom Image URI
+
+Image must be available at the specified URI; setting the image attribute will cause registry settings to be ignored. No image mirroring will be leveraged.
+
+Example:
+```yaml
+image: myprivateregistry.internal.lan/falcon-image-analyzer/falcon-imageanalyzer:1.0.9
+```
+
+### Install Steps
+To install Falcon Image Analyzer, run the following command to install the FalconImageAnalyzer CR:
+```sh
+oc create -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+```
+
+### Uninstall Steps
+To uninstall Falcon Image Analyzer simply remove the FalconImageAnalyzer resource. The operator will uninstall the Falcon Image Analyzer from the cluster.
+
+```sh
+oc delete falconimageanalyzer --all
+```
+
+### Sensor upgrades
+
+To upgrade the sensor version, simply add and/or update the `version` field in the FalconImageAnalyzer resource and apply the change. Alternatively if the `image` field was used instead of using the Falcon API credentials, add and/or update the `image` field in the FalconImageAnalyzer resource and apply the change. The operator will detect the change and perform the upgrade.
+
+### Troubleshooting
+
+- Falcon Operator modifies the FalconImageAnalyzer CR based on what is happening in the cluster. You can get list the CR, Operator Version, and Sensor version by running the following:
+
+ ```sh
+ $ oc get falconimageanalyzer
+ NAME OPERATOR VERSION FALCON SENSOR
+ falcon-image-analyzer 0.8.0 1.0.9
+ ```
+
+ This is helpful information to use as a starting point for troubleshooting.
+ You can get more insight by viewing the FalconImageAnalyzer CRD in full detail by running the following command:
+
+ ```sh
+ oc get falconimageanalyzer -o yaml
+ ```
+
+- To review the logs of Falcon Operator:
+ ```sh
+ oc -n falcon-operator logs -f deploy/falcon-operator-controller-manager -c manager
+ ```
+
+- To review the logs of Falcon Image Analyzer service:
+ ```sh
+ oc logs -n falcon-iar -l "crowdstrike.com/provider=crowdstrike"
+ ```
+
+- To review the currently deployed version of the operator:
+ ```sh
+ oc get falconimageanalyzer -A -o=jsonpath='{.items[].status.version}'
+ ```
+
+
+### Additional Documentation
+End-to-end guide(s) to install Falcon-operator together with FalconImageAnalyzer resource.
+ - [Deployment Guide for OpenShift](../../README.md)
+
+
+
diff --git a/docs/resources/imageanalyzer/README.md b/docs/resources/imageanalyzer/README.md
new file mode 100644
index 00000000..32b568cf
--- /dev/null
+++ b/docs/resources/imageanalyzer/README.md
@@ -0,0 +1,188 @@
+# Falcon Image Analyzer
+
+## About FalconImageAnalyzer Custom Resource (CR)
+Falcon Operator introduces the FalconImageAnalyzer Custom Resource (CR) to the cluster. The resource is meant to install, configure, and uninstall the Falcon Image Analyzer on the cluster.
+
+### FalconImageAnalyzer CR Configuration using CrowdStrike API Keys
+To start the FalconImageAnalyzer installation using CrowdStrike API Keys to allow the operator to determine your Falcon Customer ID (CID) as well as pull down the CrowdStrike Falcon Image Analyzer image, please create the following FalconImageAnalyzer resource to your cluster.
+
+> [!IMPORTANT]
+> You will need to provide CrowdStrike API Keys and CrowdStrike cloud region for the installation. It is recommended to establish new API credentials for the installation at https://falcon.crowdstrike.com/support/api-clients-and-keys, required permissions are:
+> * Falcon Images Download: **Read**
+> * Sensor Download: **Read**
+
+Example:
+
+```yaml
+apiVersion: falcon.crowdstrike.com/v1alpha1
+kind: FalconImageAnalyzer
+metadata:
+ name: falcon-image-analyzer
+spec:
+ falcon_api:
+ client_id: PLEASE_FILL_IN
+ client_secret: PLEASE_FILL_IN
+ cloud_region: us-1
+ registry:
+ type: crowdstrike
+```
+
+### FalconImageAnalyzer Reference Manual
+
+#### Falcon API Settings
+| Spec | Description |
+| :------------------------- | :------------------------------------------------------------------------------------------------------- |
+| falcon_api.client_id | CrowdStrike API Client ID |
+| falcon_api.client_secret | CrowdStrike API Client Secret |
+| falcon_api.cloud_region | CrowdStrike cloud region (allowed values: us-1, us-2, eu-1, us-gov-1) |
+| falcon_api.cid | CrowdStrike Falcon CID |
+
+#### Falcon Image Analyzer Configuration Settings
+| Spec | Description |
+| :---------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
+| installNamespace | (optional) Override the default namespace of falcon-iar |
+| image | (optional) Leverage a Falcon Image Analyzer Sensor image that is not managed by the operator; typically used with custom repositories; overrides all registry settings; might require imageAnalyzerConfig.imagePullSecrets to be set |
+| version | (optional) Enforce particular Falcon Image Analyzer version to be installed (example: "6.31", "6.31.0", "6.31.0-1409") |
+| registry.type | Registry to mirror Falcon Image Analyzer (allowed values: acr, ecr, crowdstrike, gcr, openshift) |
+| registry.tls.insecure_skip_verify | (optional) Skip TLS check when pushing Falcon Image Analyzer to target registry (only for demoing purposes on self-signed openshift clusters) |
+| registry.tls.caCertificate | (optional) A string containing an optionally base64-encoded Certificate Authority Chain for self-signed TLS Registry Certificates |
+| registry.tls.caCertificateConfigMap | (optional) The name of a ConfigMap containing CA Certificate Authority Chains under keys ending in ".tls" for self-signed TLS Registry Certificates (ignored when registry.tls.caCertificate is set) |
+| registry.acr_name | (optional) Name of ACR for the Falcon Falcon Image Analyzer push. Only applicable to Azure cloud. (`registry.type="acr"`) |
+| imageAnalyzerConfig.serviceAccount.annotations | (optional) Configure annotations for the falcon-iar service account (e.g. for IAM role association) |
+| imageAnalyzerConfig.azureConfigPath | (optional) Azure config file path |
+| imageAnalyzerConfig.sizeLimit | (optional) Configure the size limit of the temp storage space for scanning. By Default, this is set to `20Gi`. |
+| imageAnalyzerConfig.mountPath | (optional) Configure the location of the temp storage space for scanning. By Default, this is set to `/tmp`. |
+| imageAnalyzerConfig.clusterName | (required) K8s cluster name |
+| imageAnalyzerConfig.debug | (optional) Set to `true` for debug level log |
+| imageAnalyzerConfig.priorityClass.name | (optional) Set to avoid pod evictions due to resource limits. |
+| imageAnalyzerConfig.exclusions.registries | (optional) Set the value as a list of registries to be excluded. All images in that registry(s) will be excluded |
+| imageAnalyzerConfig.exclusions.namespaces | (optional) Set the value as a list of namespaces to be excluded. All pods in that namespace(s) will be excluded |
+| imageAnalyzerConfig.imagePullPolicy | (optional) Configure the image pull policy of the Falcon Image Analyzer |
+| imageAnalyzerConfig.imagePullSecrets | (optional) Configure the image pull secrets of the Falcon Image Analyzer |
+| imageAnalyzerConfig.registryConfig.credentials | (optional) Use this to provide registry secrets in the form of a list of maps. e.g.
- namespace: ns1
secretName: mysecretname |
+| imageAnalyzerConfig.resources | (optional) Configure the resources of the Falcon Image Analyzer |
+| imageAnalyzerConfig.updateStrategy | (optional) Configure the deployment update strategy of the Falcon Image Analyzer |
+
+
+> [!IMPORTANT]
+> All arguments are optional, but successful deployment requires either **client_id and client_secret or the Falcon cid and image**. When deploying using the CrowdStrike Falcon API, the container image and CID will be fetched from CrowdStrike Falcon API. While in the latter case, the CID and image location is explicitly specified by the user.
+
+### Auto Proxy Configuration
+
+The operator will automatically configure the sensor's proxy configuration when the cluster proxy is configured on OpenShift via OLM. See the following documentation for more information:
+* [Configuring cluster-wide proxy](https://docs.openshift.com/container-platform/latest/networking/enable-cluster-wide-proxy.html)
+* [Overriding proxy settings of an Operator](https://docs.openshift.com/container-platform/4.13/operators/admin/olm-configuring-proxy-support.html#olm-overriding-proxy-settings_olm-configuring-proxy-support)
+
+When not running on OpenShift, adding the proxy configuration via environment variables will also configure the sensor's proxy information.
+```yaml
+- args:
+ - --leader-elect
+ command:
+ - /manager
+ env:
+ - name: OPERATOR_NAME
+ value: falcon-operator
+ - name: HTTP_PROXY
+ value: http://proxy.example.com:8080
+ - name: HTTPS_PROXY
+ value: http://proxy.example.com:8080
+ image: quay.io/crowdstrike/falcon-operator:latest
+```
+These settings can be overridden by configuring the [sensor's proxy settings](#falcon-sensor-settings) which will only change the sensor's proxy settings **not** the operator's proxy settings.
+
+>[!IMPORTANT]
+> 1. If using the CrowdStrike API with the **client_id and client_secret** authentication method, the operator must be able to reach the CrowdStrike API through the proxy via the Kubernetes cluster networking configuration.
+> If the proxy is not configured correctly, the operator will not be able to authenticate with the CrowdStrike API and will not be able to create the sensor.
+> 2. If the CrowdStrike API is not used, configure the [sensor's proxy settings](#falcon-sensor-settings).
+> 3. Ensure that the host node can reach the CrowdStrike Falcon Cloud through the proxy.
+
+
+### Image Registry considerations
+
+The Falcon Image Analyzer Image is distributed by CrowdStrike through CrowdStrike Falcon registry. Operator supports two modes of deployment:
+
+#### (Option 1) Use CrowdStrike registry directly
+
+Does not require any advanced setup. Users are advised to use the following except in their FalconImageAnalyzer custom resource definition.
+
+```yaml
+registry:
+ type: crowdstrike
+```
+
+The Falcon Image Analyzer product will then be installed directly from CrowdStrike registry. Any new deployment to the cluster may contact CrowdStrike registry for the image download.
+
+#### (Option 2) Let operator mirror Falcon Image Analyzer image to your local registry
+
+Requires advanced setup to grant the operator push access to your local registry. The operator will then mirror the Falcon Image Analyzer image from CrowdStrike registry to your local registry of choice.
+Supported registries are: acr, ecr, gcr, and openshift. Each registry type requires advanced setup enable image push.
+
+#### (Option 3) Use a custom Image URI
+
+Image must be available at the specified URI; setting the image attribute will cause registry settings to be ignored. No image mirroring will be leveraged.
+
+Example:
+```yaml
+image: myprivateregistry.internal.lan/falcon-image-analyzer/falcon-imageanalyzer:1.0.9
+```
+
+### Install Steps
+To install Falcon Image Analyzer, run the following command to install the FalconImageAnalyzer CR:
+```sh
+kubectl create -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+```
+
+### Uninstall Steps
+To uninstall Falcon Image Analyzer simply remove the FalconImageAnalyzer resource. The operator will uninstall the Falcon Image Analyzer from the cluster.
+
+```sh
+kubectl delete falconimageanalyzer --all
+```
+
+### Sensor upgrades
+
+To upgrade the sensor version, simply add and/or update the `version` field in the FalconImageAnalyzer resource and apply the change. Alternatively if the `image` field was used instead of using the Falcon API credentials, add and/or update the `image` field in the FalconImageAnalyzer resource and apply the change. The operator will detect the change and perform the upgrade.
+
+### Troubleshooting
+
+- Falcon Operator modifies the FalconImageAnalyzer CR based on what is happening in the cluster. You can get list the CR, Operator Version, and Sensor version by running the following:
+
+ ```sh
+ $ kubectl get falconimageanalyzer
+ NAME OPERATOR VERSION FALCON SENSOR
+ falcon-image-analyzer 0.8.0 1.0.9
+ ```
+
+ This is helpful information to use as a starting point for troubleshooting.
+ You can get more insight by viewing the FalconImageAnalyzer CRD in full detail by running the following command:
+
+ ```sh
+ kubectl get falconimageanalyzer -o yaml
+ ```
+
+- To review the logs of Falcon Operator:
+ ```sh
+ kubectl -n falcon-operator logs -f deploy/falcon-operator-controller-manager -c manager
+ ```
+
+- To review the logs of Falcon Image Analyzer service:
+ ```sh
+ kubectl logs -n falcon-iar -l "crowdstrike.com/provider=crowdstrike"
+ ```
+
+- To review the currently deployed version of the operator:
+ ```sh
+ kubectl get falconimageanalyzer -A -o=jsonpath='{.items[].status.version}'
+ ```
+
+
+### Additional Documentation
+End-to-end guide(s) to install Falcon-operator together with FalconImageAnalyzer resource.
+ - [Deployment Guide for AKS/ACR](../../deployment/azure/README.md)
+ - [Deployment Guide for EKS/ECR](../../deployment/eks/README.md)
+ - [Deployment Guide for EKS Fargate](../../deployment/eks-fargate/README.md)
+ - [Deployment Guide for GKE/GCR](../../deployment/gke/README.md)
+ - [Deployment Guide for OpenShift](../../deployment/openshift/README.md)
+
+
+
diff --git a/docs/src/deployment/README.md.tmpl b/docs/src/deployment/README.md.tmpl
index 44fa42a8..920dc2c0 100644
--- a/docs/src/deployment/README.md.tmpl
+++ b/docs/src/deployment/README.md.tmpl
@@ -6,6 +6,7 @@
This document will guide you through the installation of the Falcon Operator and deployment of the following custom resources provided by the Falcon Operator:
- [FalconAdmission](../../resources/admission/README.md) with the Falcon Admission Controller image being mirrored from CrowdStrike container registry to {{ get $registry .Distro }}.
- [FalconContainer](../../resources/container/README.md) with the Falcon Container image being mirrored from CrowdStrike container registry to {{ get $registry .Distro }}.
+- [FalconImageAnalyzer](../../resources/imageanalyzer/README.md) with the Falcon Image Analyzer image being mirrored from CrowdStrike container registry.
{{- if ne .Distro "eks-fargate" }}
- [FalconNodeSensor](../../resources/node/README.md) custom resource to the cluster.
{{- end }}
@@ -118,6 +119,32 @@ After the Falcon Operator has deployed, you can now deploy the Falcon Node Senso
+### Deploying the Falcon Image Analyzer
+
+
+ Click to expand
+
+{{- if eq .Distro "eks-fargate" }}
+
+- Create an EKS Fargate profile for the FalconImageAnalyzer resource deployment:
+ ```sh
+ eksctl create fargateprofile \
+ --region "$AWS_REGION" \
+ --cluster eks-fargate-cluster \
+ --name fp-falcon-iar \
+ --namespace falcon-iar
+ ```
+{{ end }}
+
+After the Falcon Operator has deployed, you can now deploy the Image Analyzer:
+
+- Deploy FalconImageAnalyzer through the cli using the `{{ .KubeCmd }}` command:
+ ```sh
+ {{ .KubeCmd }} create -n falcon-operator -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+ ```
+
+
+
## Upgrading
@@ -185,6 +212,19 @@ Remove the FalconAdmission resource. The operator will then uninstall the Falcon
+### Uninstalling the Falcon Image Analyzer
+
+
+ Click to expand
+
+Remove the FalconImageAnalyzer resource. The operator will then uninstall the Falcon Image Analyzer from the cluster:
+
+```sh
+{{ .KubeCmd }} delete falconimageanalyzer --all
+```
+
+
+
### Uninstalling the Falcon Operator
diff --git a/docs/src/resources/imageanalyzer.md.tmpl b/docs/src/resources/imageanalyzer.md.tmpl
new file mode 100644
index 00000000..ee28b745
--- /dev/null
+++ b/docs/src/resources/imageanalyzer.md.tmpl
@@ -0,0 +1,167 @@
+# Falcon Image Analyzer
+
+## About FalconImageAnalyzer Custom Resource (CR)
+Falcon Operator introduces the FalconImageAnalyzer Custom Resource (CR) to the cluster. The resource is meant to install, configure, and uninstall the Falcon Image Analyzer on the cluster.
+
+### FalconImageAnalyzer CR Configuration using CrowdStrike API Keys
+To start the FalconImageAnalyzer installation using CrowdStrike API Keys to allow the operator to determine your Falcon Customer ID (CID) as well as pull down the CrowdStrike Falcon Image Analyzer image, please create the following FalconImageAnalyzer resource to your cluster.
+
+> [!IMPORTANT]
+> You will need to provide CrowdStrike API Keys and CrowdStrike cloud region for the installation. It is recommended to establish new API credentials for the installation at https://falcon.crowdstrike.com/support/api-clients-and-keys, required permissions are:
+> * Falcon Images Download: **Read**
+> * Sensor Download: **Read**
+
+Example:
+
+```yaml
+apiVersion: falcon.crowdstrike.com/v1alpha1
+kind: FalconImageAnalyzer
+metadata:
+ name: falcon-image-analyzer
+spec:
+ falcon_api:
+ client_id: PLEASE_FILL_IN
+ client_secret: PLEASE_FILL_IN
+ cloud_region: us-1
+ registry:
+ type: crowdstrike
+```
+
+### FalconImageAnalyzer Reference Manual
+
+#### Falcon API Settings
+| Spec | Description |
+| :------------------------- | :------------------------------------------------------------------------------------------------------- |
+| falcon_api.client_id | CrowdStrike API Client ID |
+| falcon_api.client_secret | CrowdStrike API Client Secret |
+| falcon_api.cloud_region | CrowdStrike cloud region (allowed values: us-1, us-2, eu-1, us-gov-1) |
+| falcon_api.cid | CrowdStrike Falcon CID |
+
+#### Falcon Image Analyzer Configuration Settings
+| Spec | Description |
+| :---------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- |
+| installNamespace | (optional) Override the default namespace of falcon-iar |
+| image | (optional) Leverage a Falcon Image Analyzer Sensor image that is not managed by the operator; typically used with custom repositories; overrides all registry settings; might require imageAnalyzerConfig.imagePullSecrets to be set |
+| version | (optional) Enforce particular Falcon Image Analyzer version to be installed (example: "6.31", "6.31.0", "6.31.0-1409") |
+| registry.type | Registry to mirror Falcon Image Analyzer (allowed values: acr, ecr, crowdstrike, gcr, openshift) |
+| registry.tls.insecure_skip_verify | (optional) Skip TLS check when pushing Falcon Image Analyzer to target registry (only for demoing purposes on self-signed openshift clusters) |
+| registry.tls.caCertificate | (optional) A string containing an optionally base64-encoded Certificate Authority Chain for self-signed TLS Registry Certificates |
+| registry.tls.caCertificateConfigMap | (optional) The name of a ConfigMap containing CA Certificate Authority Chains under keys ending in ".tls" for self-signed TLS Registry Certificates (ignored when registry.tls.caCertificate is set) |
+| registry.acr_name | (optional) Name of ACR for the Falcon Falcon Image Analyzer push. Only applicable to Azure cloud. (`registry.type="acr"`) |
+| imageAnalyzerConfig.serviceAccount.annotations | (optional) Configure annotations for the falcon-iar service account (e.g. for IAM role association) |
+| imageAnalyzerConfig.azureConfigPath | (optional) Azure config file path |
+| imageAnalyzerConfig.sizeLimit | (optional) Configure the size limit of the temp storage space for scanning. By Default, this is set to `20Gi`. |
+| imageAnalyzerConfig.mountPath | (optional) Configure the location of the temp storage space for scanning. By Default, this is set to `/tmp`. |
+| imageAnalyzerConfig.clusterName | (required) K8s cluster name |
+| imageAnalyzerConfig.debug | (optional) Set to `true` for debug level log |
+| imageAnalyzerConfig.priorityClass.name | (optional) Set to avoid pod evictions due to resource limits. |
+| imageAnalyzerConfig.exclusions.registries | (optional) Set the value as a list of registries to be excluded. All images in that registry(s) will be excluded |
+| imageAnalyzerConfig.exclusions.namespaces | (optional) Set the value as a list of namespaces to be excluded. All pods in that namespace(s) will be excluded |
+| imageAnalyzerConfig.imagePullPolicy | (optional) Configure the image pull policy of the Falcon Image Analyzer |
+| imageAnalyzerConfig.imagePullSecrets | (optional) Configure the image pull secrets of the Falcon Image Analyzer |
+| imageAnalyzerConfig.registryConfig.credentials | (optional) Use this to provide registry secrets in the form of a list of maps. e.g.
- namespace: ns1
secretName: mysecretname |
+| imageAnalyzerConfig.resources | (optional) Configure the resources of the Falcon Image Analyzer |
+| imageAnalyzerConfig.updateStrategy | (optional) Configure the deployment update strategy of the Falcon Image Analyzer |
+
+
+> [!IMPORTANT]
+> All arguments are optional, but successful deployment requires either **client_id and client_secret or the Falcon cid and image**. When deploying using the CrowdStrike Falcon API, the container image and CID will be fetched from CrowdStrike Falcon API. While in the latter case, the CID and image location is explicitly specified by the user.
+
+### Auto Proxy Configuration
+
+{{ template "proxy.tmpl" . }}
+
+### Image Registry considerations
+
+The Falcon Image Analyzer Image is distributed by CrowdStrike through CrowdStrike Falcon registry. Operator supports two modes of deployment:
+
+#### (Option 1) Use CrowdStrike registry directly
+
+Does not require any advanced setup. Users are advised to use the following except in their FalconImageAnalyzer custom resource definition.
+
+```yaml
+registry:
+ type: crowdstrike
+```
+
+The Falcon Image Analyzer product will then be installed directly from CrowdStrike registry. Any new deployment to the cluster may contact CrowdStrike registry for the image download.
+
+#### (Option 2) Let operator mirror Falcon Image Analyzer image to your local registry
+
+Requires advanced setup to grant the operator push access to your local registry. The operator will then mirror the Falcon Image Analyzer image from CrowdStrike registry to your local registry of choice.
+Supported registries are: acr, ecr, gcr, and openshift. Each registry type requires advanced setup enable image push.
+
+#### (Option 3) Use a custom Image URI
+
+Image must be available at the specified URI; setting the image attribute will cause registry settings to be ignored. No image mirroring will be leveraged.
+
+Example:
+```yaml
+image: myprivateregistry.internal.lan/falcon-image-analyzer/falcon-imageanalyzer:1.0.9
+```
+
+### Install Steps
+To install Falcon Image Analyzer, run the following command to install the FalconImageAnalyzer CR:
+```sh
+{{ .KubeCmd }} create -f https://raw.githubusercontent.com/crowdstrike/falcon-operator/main/config/samples/falcon_v1alpha1_falconimageanalyzer.yaml --edit=true
+```
+
+### Uninstall Steps
+To uninstall Falcon Image Analyzer simply remove the FalconImageAnalyzer resource. The operator will uninstall the Falcon Image Analyzer from the cluster.
+
+```sh
+{{ .KubeCmd }} delete falconimageanalyzer --all
+```
+
+### Sensor upgrades
+
+To upgrade the sensor version, simply add and/or update the `version` field in the FalconImageAnalyzer resource and apply the change. Alternatively if the `image` field was used instead of using the Falcon API credentials, add and/or update the `image` field in the FalconImageAnalyzer resource and apply the change. The operator will detect the change and perform the upgrade.
+
+### Troubleshooting
+
+- Falcon Operator modifies the FalconImageAnalyzer CR based on what is happening in the cluster. You can get list the CR, Operator Version, and Sensor version by running the following:
+
+ ```sh
+ $ {{ .KubeCmd }} get falconimageanalyzer
+ NAME OPERATOR VERSION FALCON SENSOR
+ falcon-image-analyzer 0.8.0 1.0.9
+ ```
+
+ This is helpful information to use as a starting point for troubleshooting.
+ You can get more insight by viewing the FalconImageAnalyzer CRD in full detail by running the following command:
+
+ ```sh
+ {{ .KubeCmd }} get falconimageanalyzer -o yaml
+ ```
+
+- To review the logs of Falcon Operator:
+ ```sh
+ {{ .KubeCmd }} -n falcon-operator logs -f deploy/falcon-operator-controller-manager -c manager
+ ```
+
+- To review the logs of Falcon Image Analyzer service:
+ ```sh
+ {{ .KubeCmd }} logs -n falcon-iar -l "crowdstrike.com/provider=crowdstrike"
+ ```
+
+- To review the currently deployed version of the operator:
+ ```sh
+ {{ .KubeCmd }} get falconimageanalyzer -A -o=jsonpath='{.items[].status.version}'
+ ```
+
+
+### Additional Documentation
+End-to-end guide(s) to install Falcon-operator together with FalconImageAnalyzer resource.
+
+{{- if ne .Distro "openshift" }}
+ - [Deployment Guide for AKS/ACR](../../deployment/azure/README.md)
+ - [Deployment Guide for EKS/ECR](../../deployment/eks/README.md)
+ - [Deployment Guide for EKS Fargate](../../deployment/eks-fargate/README.md)
+ - [Deployment Guide for GKE/GCR](../../deployment/gke/README.md)
+ - [Deployment Guide for OpenShift](../../deployment/openshift/README.md)
+{{- else if eq .Distro "openshift" }}
+ - [Deployment Guide for OpenShift](../../README.md)
+{{- end }}
+
+
+
diff --git a/docs/src/templates/gkeautopilot.tmpl b/docs/src/templates/gkeautopilot.tmpl
index b98c3179..64490fe1 100644
--- a/docs/src/templates/gkeautopilot.tmpl
+++ b/docs/src/templates/gkeautopilot.tmpl
@@ -2,6 +2,9 @@
## GKE Autopilot configuration
+
+ Click to expand
+
### Setting the PriorityClass
When you enable GKE Autopilot deployment in the Falcon Operator, this creates a new PriorityClass to ensure that the sensor DaemonSet has priority over other application pods. This means that it’s possible that some application pods are evicted or pushed back in the scheduling queue depending on cluster resources availability to accommodate sensor Pods. You can either allow the operator to deploy its own PriorityClass or specify an existing PriorityClass.
@@ -104,4 +107,6 @@ node:
+
+
{{- end -}}
diff --git a/internal/controller/admission/falconadmission_controller.go b/internal/controller/admission/falconadmission_controller.go
index 42e232e5..1cd3a1dd 100644
--- a/internal/controller/admission/falconadmission_controller.go
+++ b/internal/controller/admission/falconadmission_controller.go
@@ -139,13 +139,12 @@ func (r *FalconAdmissionReconciler) Reconcile(ctx context.Context, req ctrl.Requ
}
if falconAdmission.Status.Version != version.Get() {
- falconAdmission.Status.Version = version.Get()
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
err := r.Get(ctx, req.NamespacedName, falconAdmission)
if err != nil {
return err
}
-
+ falconAdmission.Status.Version = version.Get()
return r.Status().Update(ctx, falconAdmission)
})
if err != nil {
diff --git a/internal/controller/assets/deployment.go b/internal/controller/assets/deployment.go
index dae5e68f..ba190c24 100644
--- a/internal/controller/assets/deployment.go
+++ b/internal/controller/assets/deployment.go
@@ -248,6 +248,152 @@ func SideCarDeployment(name string, namespace string, component string, imageUri
}
}
+// ImageAnalyzerDeployment returns a Deployment object for the CrowdStrike Falcon IAR Controller
+func ImageAnalyzerDeployment(name string, namespace string, component string, imageUri string, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) *appsv1.Deployment {
+ labels := common.CRLabels("deployment", name, component)
+ var replicaCount int32 = 1
+ hostPathFile := corev1.HostPathFile
+ var rootUid int64 = 0
+ privileged := false
+ allowPrivilegeEscalation := false
+ resources := &corev1.ResourceRequirements{}
+ if falconImageAnalyzer.Spec.ImageAnalyzerConfig.Resources != nil {
+ resources = falconImageAnalyzer.Spec.ImageAnalyzerConfig.Resources
+ }
+
+ if falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeSizeLimit == "" {
+ falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeSizeLimit = "20Gi"
+ }
+
+ if falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeMountPath == "" {
+ falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeMountPath = "/tmp"
+ }
+
+ sizeLimit := resource.MustParse(falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeSizeLimit)
+
+ volumes := []corev1.Volume{
+ {
+ Name: "tmp-volume",
+ VolumeSource: corev1.VolumeSource{
+ EmptyDir: &corev1.EmptyDirVolumeSource{
+ SizeLimit: &sizeLimit,
+ },
+ },
+ },
+ }
+
+ volumeMounts := []corev1.VolumeMount{
+ {
+ Name: "tmp-volume",
+ MountPath: falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeMountPath,
+ },
+ }
+
+ if falconImageAnalyzer.Spec.ImageAnalyzerConfig.AzureConfigPath != "" {
+ volumes = append(volumes, corev1.Volume{
+ Name: "azure-config",
+ VolumeSource: corev1.VolumeSource{
+ HostPath: &corev1.HostPathVolumeSource{
+ Path: falconImageAnalyzer.Spec.ImageAnalyzerConfig.AzureConfigPath,
+ Type: &hostPathFile,
+ },
+ },
+ },
+ )
+
+ volumeMounts = append(volumeMounts, corev1.VolumeMount{
+ Name: "azure-config",
+ MountPath: "/etc/kubernetes/azure.json",
+ })
+ }
+
+ return &appsv1.Deployment{
+ TypeMeta: metav1.TypeMeta{
+ APIVersion: appsv1.SchemeGroupVersion.String(),
+ Kind: "Deployment",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ Labels: labels,
+ },
+ Spec: appsv1.DeploymentSpec{
+ Replicas: &replicaCount,
+ Selector: &metav1.LabelSelector{
+ MatchLabels: labels,
+ },
+ Template: corev1.PodTemplateSpec{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: labels,
+ Annotations: map[string]string{
+ common.FalconContainerInjection: "disabled",
+ },
+ },
+ Spec: corev1.PodSpec{
+ Affinity: &corev1.Affinity{
+ NodeAffinity: &corev1.NodeAffinity{
+ RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
+ NodeSelectorTerms: []corev1.NodeSelectorTerm{
+ {
+ MatchExpressions: []corev1.NodeSelectorRequirement{
+ {
+ Key: "kubernetes.io/os",
+ Operator: corev1.NodeSelectorOpIn,
+ Values: []string{"linux"},
+ },
+ {
+ Key: "kubernetes.io/arch",
+ Operator: corev1.NodeSelectorOpIn,
+ Values: []string{"amd64"},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Containers: []corev1.Container{
+ {
+ Name: "falcon-image-analyzer",
+ SecurityContext: &corev1.SecurityContext{
+ RunAsUser: &rootUid,
+ Privileged: &privileged,
+ AllowPrivilegeEscalation: &allowPrivilegeEscalation,
+ Capabilities: &corev1.Capabilities{
+ Drop: []corev1.Capability{
+ "ALL",
+ },
+ },
+ SeccompProfile: &corev1.SeccompProfile{
+ Type: corev1.SeccompProfileTypeRuntimeDefault,
+ },
+ },
+ Resources: *resources,
+ Image: imageUri,
+ ImagePullPolicy: falconImageAnalyzer.Spec.ImageAnalyzerConfig.ImagePullPolicy,
+ Args: []string{"-runmode", "watcher"},
+ EnvFrom: []corev1.EnvFromSource{
+ {
+ ConfigMapRef: &corev1.ConfigMapEnvSource{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: name + "-config",
+ },
+ },
+ },
+ },
+ VolumeMounts: volumeMounts,
+ },
+ },
+ ServiceAccountName: common.ImageServiceAccountName,
+ NodeSelector: common.NodeSelector,
+ Volumes: volumes,
+ PriorityClassName: falconImageAnalyzer.Spec.ImageAnalyzerConfig.PriorityClass.Name,
+ },
+ },
+ },
+ }
+}
+
// AdmissionDeployment returns a Deployment object for the CrowdStrike Falcon Admission Controller
func AdmissionDeployment(name string, namespace string, component string, imageUri string, falconAdmission *falconv1alpha1.FalconAdmission) *appsv1.Deployment {
runNonRoot := true
diff --git a/internal/controller/falcon_container/falconcontainer_controller.go b/internal/controller/falcon_container/falconcontainer_controller.go
index 197e337c..8b4417dd 100644
--- a/internal/controller/falcon_container/falconcontainer_controller.go
+++ b/internal/controller/falcon_container/falconcontainer_controller.go
@@ -115,13 +115,13 @@ func (r *FalconContainerReconciler) Reconcile(ctx context.Context, req ctrl.Requ
}
if falconContainer.Status.Version != version.Get() {
- falconContainer.Status.Version = version.Get()
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
err := r.Get(ctx, req.NamespacedName, falconContainer)
if err != nil {
return err
}
+ falconContainer.Status.Version = version.Get()
return r.Status().Update(ctx, falconContainer)
})
if err != nil {
diff --git a/internal/controller/falcon_image/falconimage_controller.go b/internal/controller/falcon_image/falconimage_controller.go
deleted file mode 100644
index e72cc824..00000000
--- a/internal/controller/falcon_image/falconimage_controller.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package falcon
-
-import (
- "context"
-
- "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"
-
- falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
-)
-
-// FalconImageReconciler reconciles a FalconImage object
-type FalconImageReconciler struct {
- client.Client
- Scheme *runtime.Scheme
-}
-
-//+kubebuilder:rbac:groups=falcon.crowdstrike.com,resources=falconimages,verbs=get;list;watch;create;update;patch;delete
-//+kubebuilder:rbac:groups=falcon.crowdstrike.com,resources=falconimages/status,verbs=get;update;patch
-//+kubebuilder:rbac:groups=falcon.crowdstrike.com,resources=falconimages/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 FalconImage 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.15.0/pkg/reconcile
-func (r *FalconImageReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
- _ = log.FromContext(ctx)
-
- // TODO(user): your logic here
-
- return ctrl.Result{}, nil
-}
-
-// SetupWithManager sets up the controller with the Manager.
-func (r *FalconImageReconciler) SetupWithManager(mgr ctrl.Manager) error {
- return ctrl.NewControllerManagedBy(mgr).
- For(&falconv1alpha1.FalconImage{}).
- Complete(r)
-}
diff --git a/internal/controller/falcon_image_analyzer/configmap.go b/internal/controller/falcon_image_analyzer/configmap.go
new file mode 100644
index 00000000..70db4e0b
--- /dev/null
+++ b/internal/controller/falcon_image_analyzer/configmap.go
@@ -0,0 +1,118 @@
+package falcon
+
+import (
+ "context"
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+
+ falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
+ "github.com/crowdstrike/falcon-operator/internal/controller/assets"
+ k8sutils "github.com/crowdstrike/falcon-operator/internal/controller/common"
+ "github.com/crowdstrike/falcon-operator/pkg/common"
+ "github.com/crowdstrike/falcon-operator/pkg/falcon_api"
+ "github.com/go-logr/logr"
+ corev1 "k8s.io/api/core/v1"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
+ types "k8s.io/apimachinery/pkg/types"
+ ctrl "sigs.k8s.io/controller-runtime"
+)
+
+const (
+ isKubernetes = "true"
+ agentRunmode = "watcher"
+ agentMaxConsumerThreads = "1"
+)
+
+func (r *FalconImageAnalyzerReconciler) reconcileConfigMap(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (bool, error) {
+ return r.reconcileGenericConfigMap(falconImageAnalyzer.Name+"-config", r.newConfigMap, ctx, req, log, falconImageAnalyzer)
+}
+
+func (r *FalconImageAnalyzerReconciler) reconcileGenericConfigMap(name string, genFunc func(context.Context, string, *falconv1alpha1.FalconImageAnalyzer) (*corev1.ConfigMap, error), ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (bool, error) {
+ cm, err := genFunc(ctx, name, falconImageAnalyzer)
+ if err != nil {
+ return false, err
+ }
+
+ existingCM := &corev1.ConfigMap{}
+ err = r.Get(ctx, types.NamespacedName{Name: name, Namespace: falconImageAnalyzer.Spec.InstallNamespace}, existingCM)
+ if err != nil && apierrors.IsNotFound(err) {
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, cm)
+ if err != nil {
+ return false, err
+ }
+
+ return false, nil
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer ConfigMap")
+ return false, err
+ }
+
+ if !reflect.DeepEqual(cm.Data, existingCM.Data) {
+ existingCM.Data = cm.Data
+ if err := k8sutils.Update(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingCM); err != nil {
+ return false, err
+ }
+ return true, nil
+ }
+
+ return false, nil
+
+}
+
+func (r *FalconImageAnalyzerReconciler) newConfigMap(ctx context.Context, name string, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (*corev1.ConfigMap, error) {
+ var err error
+ data := map[string]string{}
+ cid := ""
+
+ if cid == "" && falconImageAnalyzer.Spec.FalconAPI != nil {
+ cid, err = falcon_api.FalconCID(ctx, falconImageAnalyzer.Spec.FalconAPI.CID, falconImageAnalyzer.Spec.FalconAPI.ApiConfig())
+ if err != nil {
+ return &corev1.ConfigMap{}, err
+ }
+ }
+
+ if falconImageAnalyzer.Spec.FalconAPI.ClientId != "" {
+ data["AGENT_CLIENT_ID"] = falconImageAnalyzer.Spec.FalconAPI.ClientId
+ }
+
+ if falconImageAnalyzer.Spec.FalconAPI.ClientId != "" {
+ data["AGENT_CLIENT_SECRET"] = falconImageAnalyzer.Spec.FalconAPI.ClientSecret
+ }
+
+ if falconImageAnalyzer.Spec.FalconAPI.CloudRegion != "" {
+ data["AGENT_REGION"] = falconImageAnalyzer.Spec.FalconAPI.CloudRegion
+ }
+
+ if falconImageAnalyzer.Spec.ImageAnalyzerConfig.ClusterName != "" {
+ data["AGENT_CLUSTER_NAME"] = falconImageAnalyzer.Spec.ImageAnalyzerConfig.ClusterName
+ }
+
+ if len(falconImageAnalyzer.Spec.ImageAnalyzerConfig.RegistryConfig.Credentials) > 0 {
+ for _, v := range falconImageAnalyzer.Spec.ImageAnalyzerConfig.RegistryConfig.Credentials {
+ data["AGENT_REGISTRY_CREDENTIALS"] = fmt.Sprintf("%s:%s", v.Namespace, v.SecretName)
+ }
+ }
+
+ if len(falconImageAnalyzer.Spec.ImageAnalyzerConfig.Exclusions.Namespaces) > 0 {
+ data["AGENT_NAMESPACE_EXCLUSIONS"] = strings.Join(falconImageAnalyzer.Spec.ImageAnalyzerConfig.Exclusions.Namespaces, ",")
+ }
+
+ if len(falconImageAnalyzer.Spec.ImageAnalyzerConfig.Exclusions.Registries) > 0 {
+ data["AGENT_REGISTRY_EXCLUSIONS"] = strings.Join(falconImageAnalyzer.Spec.ImageAnalyzerConfig.Exclusions.Registries, ",")
+ }
+
+ data["AGENT_DEBUG"] = strconv.FormatBool(falconImageAnalyzer.Spec.ImageAnalyzerConfig.EnableDebug)
+
+ data["IS_KUBERNETES"] = isKubernetes
+ data["AGENT_CID"] = cid
+ data["AGENT_RUNMODE"] = agentRunmode
+ data["AGENT_MAX_CONSUMER_THREADS"] = agentMaxConsumerThreads
+ data["AGENT_TEMP_MOUNT_SIZE"] = "20Gi"
+ if falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeSizeLimit != "" {
+ data["AGENT_TEMP_MOUNT_SIZE"] = falconImageAnalyzer.Spec.ImageAnalyzerConfig.VolumeSizeLimit
+ }
+
+ return assets.SensorConfigMap(name, falconImageAnalyzer.Spec.InstallNamespace, common.FalconImageAnalyzer, data), nil
+}
diff --git a/internal/controller/falcon_image_analyzer/falconimage_controller.go b/internal/controller/falcon_image_analyzer/falconimage_controller.go
new file mode 100644
index 00000000..93bedfaf
--- /dev/null
+++ b/internal/controller/falcon_image_analyzer/falconimage_controller.go
@@ -0,0 +1,437 @@
+package falcon
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "reflect"
+ "strconv"
+ "time"
+
+ falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
+ "github.com/crowdstrike/falcon-operator/internal/controller/assets"
+ k8sutils "github.com/crowdstrike/falcon-operator/internal/controller/common"
+ "github.com/crowdstrike/falcon-operator/pkg/aws"
+ "github.com/crowdstrike/falcon-operator/pkg/common"
+ "github.com/crowdstrike/falcon-operator/pkg/registry/pulltoken"
+ "github.com/crowdstrike/falcon-operator/version"
+ "github.com/go-logr/logr"
+ imagev1 "github.com/openshift/api/image/v1"
+ "github.com/operator-framework/operator-lib/proxy"
+ appsv1 "k8s.io/api/apps/v1"
+ corev1 "k8s.io/api/core/v1"
+ rbacv1 "k8s.io/api/rbac/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"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
+ "k8s.io/client-go/util/retry"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+)
+
+// FalconImageAnalyzerReconciler reconciles a FalconImageAnalyzer object
+type FalconImageAnalyzerReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *FalconImageAnalyzerReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&falconv1alpha1.FalconImageAnalyzer{}).
+ Owns(&corev1.Namespace{}).
+ Owns(&corev1.ConfigMap{}).
+ Owns(&corev1.Secret{}).
+ Owns(&appsv1.Deployment{}).
+ Owns(&corev1.ServiceAccount{}).
+ Owns(&rbacv1.ClusterRoleBinding{}).
+ Complete(r)
+}
+
+//+kubebuilder:rbac:groups=falcon.crowdstrike.com,resources=falconimageanalyzers,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=falcon.crowdstrike.com,resources=falconimageanalyzers/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=falcon.crowdstrike.com,resources=falconimageanalyzers/finalizers,verbs=update
+//+kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch;create;update;delete
+//+kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete
+//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete
+//+kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;delete
+//+kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;update
+//+kubebuilder:rbac:groups="apps",resources=deployments,verbs=get;list;watch;create;update;delete
+//+kubebuilder:rbac:groups="security.openshift.io",resources=securitycontextconstraints,resourceNames=privileged,verbs=use
+//+kubebuilder:rbac:groups="image.openshift.io",resources=imagestreams,verbs=get;list;watch;create;update;delete
+//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles,verbs=create;get;list;update;watch;delete
+//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=create;get;list;update;watch;delete
+
+// 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 FalconImageAnalyzer 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.14.1/pkg/reconcile
+func (r *FalconImageAnalyzerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ updated := false
+ log := log.FromContext(ctx)
+
+ // Fetch the FalconImageAnalyzer instance
+ falconImageAnalyzer := &falconv1alpha1.FalconImageAnalyzer{}
+ err := r.Get(ctx, req.NamespacedName, falconImageAnalyzer)
+ if err != nil {
+ if errors.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("FalconImageAnalyzer resource not found. Ignoring since object must be deleted")
+ return ctrl.Result{}, nil
+ }
+
+ log.Error(err, "Failed to get FalconImageAnalyzer resource")
+ return ctrl.Result{}, err
+ }
+
+ validate, err := k8sutils.CheckRunningPodLabels(r.Client, ctx, falconImageAnalyzer.Spec.InstallNamespace, common.CRLabels("deployment", falconImageAnalyzer.Name, common.FalconImageAnalyzer))
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ if !validate {
+ err = k8sutils.ConditionsUpdate(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, metav1.Condition{
+ Status: metav1.ConditionFalse,
+ Reason: falconv1alpha1.ReasonReqNotMet,
+ Type: falconv1alpha1.ConditionFailed,
+ Message: "falconImageAnalyzer must not be installed in a namespace with other workloads running. Please change the namespace in the CR configuration.",
+ ObservedGeneration: falconImageAnalyzer.GetGeneration(),
+ })
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+ log.Error(nil, "falconImageAnalyzer 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
+ }
+
+ // Let's just set the status as Unknown when no status is available
+ if falconImageAnalyzer.Status.Conditions == nil || len(falconImageAnalyzer.Status.Conditions) == 0 {
+ meta.SetStatusCondition(&falconImageAnalyzer.Status.Conditions, metav1.Condition{Type: falconv1alpha1.ConditionPending, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"})
+ if err = r.Status().Update(ctx, falconImageAnalyzer); err != nil {
+ log.Error(err, "Failed to update FalconImageAnalyzer status")
+ return ctrl.Result{}, err
+ }
+
+ // Let's re-fetch the Custom Resource after update the status
+ // so that we have the latest state of the resource on the cluster and we will avoid
+ // raise the issue "the object has been modified, please apply
+ // your changes to the latest version and try again" which would re-trigger the reconciliation
+ // if we try to update it again in the following operations
+ if err := r.Get(ctx, req.NamespacedName, falconImageAnalyzer); err != nil {
+ log.Error(err, "Failed to re-fetch FalconImageAnalyzer")
+ return ctrl.Result{}, err
+ }
+ }
+
+ if falconImageAnalyzer.Status.Version != version.Get() {
+ err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
+ err = r.Get(ctx, req.NamespacedName, falconImageAnalyzer)
+ if err != nil {
+ log.Error(err, "Failed to re-fetch FalconImageAnalyzer for status update")
+ return err
+ }
+
+ falconImageAnalyzer.Status.Version = version.Get()
+ return r.Status().Update(ctx, falconImageAnalyzer)
+ })
+ if err != nil {
+ log.Error(err, "Failed to update FalconImageAnalyzer status for falconImageAnalyzer.Status.Version")
+ return ctrl.Result{}, err
+ }
+
+ }
+
+ if err := r.reconcileNamespace(ctx, req, log, falconImageAnalyzer); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ // Image being set will override other image based settings
+ if falconImageAnalyzer.Spec.Image != "" {
+ if _, err := r.setImageTag(ctx, falconImageAnalyzer); err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to set Falcon Image Analyzer version: %v", err)
+ }
+ } else if os.Getenv("RELATED_IMAGE_IMAGE_ANALYZER") != "" && falconImageAnalyzer.Spec.FalconAPI == nil {
+ if _, err := r.setImageTag(ctx, falconImageAnalyzer); err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to set Falcon Image Analyzer version: %v", err)
+ }
+ } else {
+ switch falconImageAnalyzer.Spec.Registry.Type {
+ case falconv1alpha1.RegistryTypeECR:
+ if _, err := aws.UpsertECRRepo(ctx, "falcon-image-analyzer"); err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to reconcile ECR repository: %v", err)
+ }
+ case falconv1alpha1.RegistryTypeOpenshift:
+ stream, err := r.reconcileImageStream(ctx, req, log, falconImageAnalyzer)
+ if err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to reconcile Image Stream")
+ }
+ if stream == nil {
+ return ctrl.Result{}, nil
+ }
+ }
+
+ if r.imageMirroringEnabled(falconImageAnalyzer) {
+ if err := r.PushImage(ctx, log, falconImageAnalyzer); err != nil {
+ return ctrl.Result{}, fmt.Errorf("cannot refresh Falcon Image image: %v", err)
+ }
+ } else {
+ updated, err = r.verifyCrowdStrike(ctx, log, falconImageAnalyzer)
+ if updated {
+ return ctrl.Result{}, nil
+ }
+ if err != nil {
+ log.Error(err, "Failed to verify CrowdStrike Image Image Registry access")
+ time.Sleep(time.Second * 5)
+ return ctrl.Result{RequeueAfter: 5 * time.Second}, err
+ }
+
+ if err := r.reconcileRegistrySecret(ctx, req, log, falconImageAnalyzer); err != nil {
+ return ctrl.Result{}, err
+ }
+ }
+ }
+
+ if err := r.reconcileServiceAccount(ctx, req, log, falconImageAnalyzer); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if err := r.reconcileClusterRoleBinding(ctx, req, log, falconImageAnalyzer); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ configUpdated, err := r.reconcileConfigMap(ctx, req, log, falconImageAnalyzer)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ err = r.reconcileImageAnalyzerDeployment(ctx, req, log, falconImageAnalyzer)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ if configUpdated {
+ err = r.imageAnalyzerDeploymentUpdate(ctx, req, log, falconImageAnalyzer)
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ return ctrl.Result{}, nil
+ }
+
+ if err := k8sutils.ConditionsUpdate(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, metav1.Condition{
+ Status: metav1.ConditionTrue,
+ Reason: falconv1alpha1.ReasonInstallSucceeded,
+ Type: falconv1alpha1.ConditionSuccess,
+ Message: "FalconImageAnalyzer installation completed",
+ ObservedGeneration: falconImageAnalyzer.GetGeneration(),
+ }); err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to update FalconImageAnalyzer installation completion condition: %v", err)
+ }
+
+ return ctrl.Result{}, nil
+}
+
+func (r *FalconImageAnalyzerReconciler) reconcileImageAnalyzerDeployment(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) error {
+ imageUri, err := r.imageUri(ctx, falconImageAnalyzer)
+ if err != nil {
+ return fmt.Errorf("unable to determine falcon container image URI: %v", err)
+ }
+
+ existingDeployment := &appsv1.Deployment{}
+ dep := assets.ImageAnalyzerDeployment(falconImageAnalyzer.Name, falconImageAnalyzer.Spec.InstallNamespace, common.FalconImageAnalyzer, imageUri, falconImageAnalyzer)
+ updated := false
+
+ if len(proxy.ReadProxyVarsFromEnv()) > 0 {
+ for i, container := range dep.Spec.Template.Spec.Containers {
+ dep.Spec.Template.Spec.Containers[i].Env = append(container.Env, proxy.ReadProxyVarsFromEnv()...)
+ }
+ }
+
+ err = r.Get(ctx, types.NamespacedName{Name: falconImageAnalyzer.Name, Namespace: falconImageAnalyzer.Spec.InstallNamespace}, existingDeployment)
+ if err != nil && apierrors.IsNotFound(err) {
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, dep)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer Deployment")
+ return err
+ }
+
+ if len(proxy.ReadProxyVarsFromEnv()) > 0 {
+ for i, container := range existingDeployment.Spec.Template.Spec.Containers {
+ newContainerEnv := common.AppendUniqueEnvVars(container.Env, proxy.ReadProxyVarsFromEnv())
+ updatedContainerEnv := common.UpdateEnvVars(container.Env, proxy.ReadProxyVarsFromEnv())
+ if !equality.Semantic.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[i].Env, newContainerEnv) {
+ existingDeployment.Spec.Template.Spec.Containers[i].Env = newContainerEnv
+ updated = true
+ }
+ if !equality.Semantic.DeepEqual(existingDeployment.Spec.Template.Spec.Containers[i].Env, updatedContainerEnv) {
+ existingDeployment.Spec.Template.Spec.Containers[i].Env = updatedContainerEnv
+ updated = true
+ }
+ if updated {
+ log.Info("Updating FalconNodeSensor Deployment Proxy Settings")
+ }
+ }
+ }
+
+ if !reflect.DeepEqual(dep.Spec.Template.Spec.Containers[0].Image, existingDeployment.Spec.Template.Spec.Containers[0].Image) {
+ existingDeployment.Spec.Template.Spec.Containers[0].Image = dep.Spec.Template.Spec.Containers[0].Image
+ updated = true
+ }
+
+ if !reflect.DeepEqual(dep.Spec.Template.Spec.Containers[0].ImagePullPolicy, existingDeployment.Spec.Template.Spec.Containers[0].ImagePullPolicy) {
+ existingDeployment.Spec.Template.Spec.Containers[0].ImagePullPolicy = dep.Spec.Template.Spec.Containers[0].ImagePullPolicy
+ updated = true
+ }
+
+ if !reflect.DeepEqual(dep.Spec.Template.Spec.ImagePullSecrets, existingDeployment.Spec.Template.Spec.ImagePullSecrets) {
+ existingDeployment.Spec.Template.Spec.ImagePullSecrets = dep.Spec.Template.Spec.ImagePullSecrets
+ updated = true
+ }
+
+ if !reflect.DeepEqual(dep.Spec.Template.Spec.Containers[0].Ports, existingDeployment.Spec.Template.Spec.Containers[0].Ports) {
+ existingDeployment.Spec.Template.Spec.Containers[0].Ports = dep.Spec.Template.Spec.Containers[0].Ports
+ updated = true
+ }
+
+ if !reflect.DeepEqual(existingDeployment.Spec.Strategy.RollingUpdate, dep.Spec.Strategy.RollingUpdate) {
+ existingDeployment.Spec.Strategy.RollingUpdate = dep.Spec.Strategy.RollingUpdate
+ updated = true
+ }
+
+ if updated {
+ if err := k8sutils.Update(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingDeployment); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (r *FalconImageAnalyzerReconciler) reconcileRegistrySecret(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) error {
+ pulltoken, err := pulltoken.CrowdStrike(ctx, r.falconApiConfig(ctx, falconImageAnalyzer))
+ if err != nil {
+ return fmt.Errorf("unable to get registry pull token: %v", err)
+ }
+
+ secretData := map[string][]byte{corev1.DockerConfigJsonKey: common.CleanDecodedBase64(pulltoken)}
+ secret := assets.Secret(common.FalconPullSecretName, falconImageAnalyzer.Spec.InstallNamespace, "falcon-operator", secretData, corev1.SecretTypeDockerConfigJson)
+ existingSecret := &corev1.Secret{}
+
+ err = r.Get(ctx, types.NamespacedName{Name: common.FalconPullSecretName, Namespace: falconImageAnalyzer.Spec.InstallNamespace}, existingSecret)
+ if err != nil && apierrors.IsNotFound(err) {
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, secret)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer Registry Pull Secret")
+ return err
+ }
+
+ if !reflect.DeepEqual(secret.Data, existingSecret.Data) {
+ err = k8sutils.Update(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingSecret)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (r *FalconImageAnalyzerReconciler) reconcileImageStream(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (*imagev1.ImageStream, error) {
+ const imageStreamName = "falcon-image-analyzer"
+ namespace := r.imageNamespace(falconImageAnalyzer)
+ imageStream := assets.ImageStream(imageStreamName, namespace, common.FalconImageAnalyzer)
+ existingImageStream := &imagev1.ImageStream{}
+
+ err := r.Get(ctx, types.NamespacedName{Name: imageStreamName, Namespace: namespace}, existingImageStream)
+ if err != nil && apierrors.IsNotFound(err) {
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, imageStream)
+ if err != nil {
+ return imageStream, err
+ }
+
+ return imageStream, nil
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer ImageStream")
+ return existingImageStream, err
+ }
+
+ if !reflect.DeepEqual(imageStream.Spec, existingImageStream.Spec) {
+ existingImageStream.Spec = imageStream.Spec
+ err = k8sutils.Update(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingImageStream)
+ if err != nil {
+ return existingImageStream, err
+ }
+ }
+
+ return existingImageStream, nil
+}
+
+func (r *FalconImageAnalyzerReconciler) reconcileNamespace(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) error {
+ namespace := assets.Namespace(falconImageAnalyzer.Spec.InstallNamespace)
+ existingNamespace := &corev1.Namespace{}
+
+ err := r.Get(ctx, types.NamespacedName{Name: falconImageAnalyzer.Spec.InstallNamespace}, existingNamespace)
+ if err != nil && apierrors.IsNotFound(err) {
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, namespace)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer Namespace")
+ return err
+ }
+
+ return nil
+}
+
+func (r *FalconImageAnalyzerReconciler) imageAnalyzerDeploymentUpdate(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) error {
+ existingDeployment := &appsv1.Deployment{}
+ configVersion := "falcon.config.version"
+ err := r.Get(ctx, types.NamespacedName{Name: falconImageAnalyzer.Name, Namespace: falconImageAnalyzer.Spec.InstallNamespace}, existingDeployment)
+ if err != nil && apierrors.IsNotFound(err) {
+ return err
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer Deployment")
+ return err
+ }
+
+ _, ok := existingDeployment.Spec.Template.Annotations[configVersion]
+ if ok {
+ i, err := strconv.Atoi(existingDeployment.Spec.Template.Annotations[configVersion])
+ if err != nil {
+ return err
+ }
+
+ existingDeployment.Spec.Template.Annotations[configVersion] = strconv.Itoa(i + 1)
+ } else {
+ existingDeployment.Spec.Template.Annotations[configVersion] = "1"
+ }
+
+ log.Info("Rolling FalconImageAnalyzer Deployment due to non-deployment configuration change")
+ if err := k8sutils.Update(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingDeployment); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/internal/controller/falcon_image_analyzer/image_push.go b/internal/controller/falcon_image_analyzer/image_push.go
new file mode 100644
index 00000000..a6a8c452
--- /dev/null
+++ b/internal/controller/falcon_image_analyzer/image_push.go
@@ -0,0 +1,238 @@
+package falcon
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "strings"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/types"
+
+ falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
+ "github.com/crowdstrike/falcon-operator/internal/controller/image"
+ "github.com/crowdstrike/falcon-operator/pkg/aws"
+ "github.com/crowdstrike/falcon-operator/pkg/common"
+ "github.com/crowdstrike/falcon-operator/pkg/gcp"
+ "github.com/crowdstrike/falcon-operator/pkg/k8s_utils"
+ "github.com/crowdstrike/falcon-operator/pkg/registry/auth"
+ "github.com/crowdstrike/falcon-operator/pkg/registry/falcon_registry"
+ "github.com/crowdstrike/falcon-operator/pkg/registry/pushtoken"
+ "github.com/crowdstrike/gofalcon/falcon"
+ "github.com/go-logr/logr"
+ imagev1 "github.com/openshift/api/image/v1"
+ "k8s.io/apimachinery/pkg/api/meta"
+)
+
+func (r *FalconImageAnalyzerReconciler) PushImage(ctx context.Context, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) error {
+ registryUri, err := r.registryUri(ctx, falconImageAnalyzer)
+ if err != nil {
+ return err
+ }
+
+ // If we have version locking enabled (as it is by default), use the already configured version if present
+ if r.versionLock(falconImageAnalyzer) {
+ return nil
+ }
+
+ pushAuth, err := r.pushAuth(ctx, falconImageAnalyzer)
+ if err != nil {
+ return err
+ }
+
+ log.Info("Found secret for image push", "Secret.Name", pushAuth.Name())
+ image := image.NewImageRefresher(ctx, log, r.falconApiConfig(ctx, falconImageAnalyzer), pushAuth, falconImageAnalyzer.Spec.Registry.TLS.InsecureSkipVerify)
+ version := falconImageAnalyzer.Spec.Version
+
+ tag, err := image.Refresh(registryUri, falcon.ImageSensor, version)
+ if err != nil {
+ return fmt.Errorf("Cannot push Falcon Image Analyzer Image: %v", err)
+ }
+
+ log.Info("Falcon Image Analyzer Controller Image pushed successfully", "Image.Tag", tag)
+ falconImageAnalyzer.Status.Sensor = &tag
+
+ imageUri, err := r.imageUri(ctx, falconImageAnalyzer)
+ if err != nil {
+ return fmt.Errorf("Cannot identify Falcon Image Analyzer Image: %v", err)
+ }
+
+ meta.SetStatusCondition(&falconImageAnalyzer.Status.Conditions, metav1.Condition{
+ Type: "ImageReady",
+ Status: metav1.ConditionTrue,
+ Message: imageUri,
+ Reason: "Pushed",
+ })
+
+ return r.Client.Status().Update(ctx, falconImageAnalyzer)
+}
+
+func (r *FalconImageAnalyzerReconciler) verifyCrowdStrike(ctx context.Context, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (bool, error) {
+ if _, err := r.setImageTag(ctx, falconImageAnalyzer); err != nil {
+ return false, fmt.Errorf("Cannot set Falcon Registry Tag: %s", err)
+ }
+
+ imageUri, err := r.imageUri(ctx, falconImageAnalyzer)
+ if err != nil {
+ return false, fmt.Errorf("Cannot find Falcon Registry URI: %s", err)
+ }
+
+ condition := meta.IsStatusConditionPresentAndEqual(falconImageAnalyzer.Status.Conditions, falconv1alpha1.ConditionImageReady, metav1.ConditionTrue)
+ if condition {
+ return false, nil
+ }
+
+ log.Info("Skipping push of Falcon Image Analyzer image to local registry. Remote CrowdStrike registry will be used.")
+ meta.SetStatusCondition(&falconImageAnalyzer.Status.Conditions, metav1.Condition{
+ Status: metav1.ConditionTrue,
+ Reason: falconv1alpha1.ReasonDiscovered,
+ Message: imageUri,
+ Type: falconv1alpha1.ConditionImageReady,
+ ObservedGeneration: falconImageAnalyzer.GetGeneration(),
+ })
+
+ return true, r.Status().Update(ctx, falconImageAnalyzer)
+}
+
+func (r *FalconImageAnalyzerReconciler) registryUri(ctx context.Context, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (string, error) {
+ switch falconImageAnalyzer.Spec.Registry.Type {
+ case falconv1alpha1.RegistryTypeOpenshift:
+ imageStream := &imagev1.ImageStream{}
+ err := r.Get(ctx, types.NamespacedName{Name: "falcon-image-analyzer", Namespace: r.imageNamespace(falconImageAnalyzer)}, imageStream)
+ if err != nil {
+ return "", err
+ }
+
+ if imageStream.Status.DockerImageRepository == "" {
+ return "", fmt.Errorf("Unable to find route to OpenShift on-cluster registry. Please verify that OpenShift on-cluster registry is up and running.")
+ }
+
+ return imageStream.Status.DockerImageRepository, nil
+ case falconv1alpha1.RegistryTypeGCR:
+ projectId, err := gcp.GetProjectID()
+ if err != nil {
+ return "", fmt.Errorf("Cannot get GCP Project ID: %v", err)
+ }
+
+ return "gcr.io/" + projectId + "/falcon-imageanalyzer", nil
+ case falconv1alpha1.RegistryTypeECR:
+ repo, err := aws.UpsertECRRepo(ctx, "falcon-image-analyzer")
+ if err != nil {
+ return "", fmt.Errorf("Cannot get target docker URI for ECR repository: %v", err)
+ }
+
+ return *repo.RepositoryUri, nil
+ case falconv1alpha1.RegistryTypeACR:
+ if falconImageAnalyzer.Spec.Registry.AcrName == nil {
+ return "", fmt.Errorf("Cannot push Falcon Image locally to ACR. acr_name was not specified")
+ }
+
+ return fmt.Sprintf("%s.azurecr.io/falcon-imageanalyzer", *falconImageAnalyzer.Spec.Registry.AcrName), nil
+ case falconv1alpha1.RegistryTypeCrowdStrike:
+ cloud, err := falconImageAnalyzer.Spec.FalconAPI.FalconCloud(ctx)
+ if err != nil {
+ return "", err
+ }
+
+ return falcon.FalconContainerSensorImageURI(cloud, falcon.ImageSensor), nil
+ default:
+ return "", fmt.Errorf("Unrecognized registry type: %s", falconImageAnalyzer.Spec.Registry.Type)
+ }
+}
+
+func (r *FalconImageAnalyzerReconciler) imageUri(ctx context.Context, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (string, error) {
+ if falconImageAnalyzer.Spec.Image != "" {
+ return falconImageAnalyzer.Spec.Image, nil
+ }
+
+ imageAnalyzerImage := os.Getenv("RELATED_IMAGE_IMAGE_ANALYZER")
+ if imageAnalyzerImage != "" && falconImageAnalyzer.Spec.FalconAPI == nil {
+ return imageAnalyzerImage, nil
+ }
+
+ registryUri, err := r.registryUri(ctx, falconImageAnalyzer)
+ if err != nil {
+ return "", err
+ }
+
+ imageTag, err := r.setImageTag(ctx, falconImageAnalyzer)
+ if err != nil {
+ return "", fmt.Errorf("failed to set Falcon Image Analyzer Image version: %v", err)
+ }
+
+ return fmt.Sprintf("%s:%s", registryUri, imageTag), nil
+}
+
+func (r *FalconImageAnalyzerReconciler) getImageTag(falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (string, error) {
+ if falconImageAnalyzer.Status.Sensor != nil && *falconImageAnalyzer.Status.Sensor != "" {
+ return *falconImageAnalyzer.Status.Sensor, nil
+ }
+
+ return "", fmt.Errorf("Unable to get falcon image analyzer container image version")
+}
+
+func (r *FalconImageAnalyzerReconciler) setImageTag(ctx context.Context, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (string, error) {
+ // If version locking is enabled and a version is already set in status, return the current version
+ if r.versionLock(falconImageAnalyzer) {
+ if tag, err := r.getImageTag(falconImageAnalyzer); err == nil {
+ return tag, err
+ }
+ }
+
+ // If an Image URI is set, use it for our version
+ if falconImageAnalyzer.Spec.Image != "" {
+ falconImageAnalyzer.Status.Sensor = common.ImageVersion(falconImageAnalyzer.Spec.Image)
+
+ return *falconImageAnalyzer.Status.Sensor, r.Client.Status().Update(ctx, falconImageAnalyzer)
+ }
+
+ if os.Getenv("RELATED_IMAGE_IMAGE_ANALYZER") != "" && falconImageAnalyzer.Spec.FalconAPI == nil {
+ image := os.Getenv("RELATED_IMAGE_IMAGE_ANALYZER")
+ falconImageAnalyzer.Status.Sensor = common.ImageVersion(image)
+
+ return *falconImageAnalyzer.Status.Sensor, r.Client.Status().Update(ctx, falconImageAnalyzer)
+ }
+
+ // Otherwise, get the newest version matching the requested version string
+ registry, err := falcon_registry.NewFalconRegistry(ctx, r.falconApiConfig(ctx, falconImageAnalyzer))
+ if err != nil {
+ return "", err
+ }
+
+ tag, err := registry.LastContainerTag(ctx, falcon.ImageSensor, falconImageAnalyzer.Spec.Version)
+ if err == nil {
+ falconImageAnalyzer.Status.Sensor = common.ImageVersion(tag)
+ }
+
+ return tag, err
+}
+
+func (r *FalconImageAnalyzerReconciler) pushAuth(ctx context.Context, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) (auth.Credentials, error) {
+ return pushtoken.GetCredentials(ctx, falconImageAnalyzer.Spec.Registry.Type,
+ k8s_utils.QuerySecretsInNamespace(r.Client, r.imageNamespace(falconImageAnalyzer)),
+ )
+}
+
+func (r *FalconImageAnalyzerReconciler) imageNamespace(falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) string {
+ if falconImageAnalyzer.Spec.Registry.Type == falconv1alpha1.RegistryTypeOpenshift {
+ // Within OpenShift, ImageStreams are separated by namespaces. The "openshift" namespace
+ // is shared and images pushed there can be referenced by deployments in other namespaces
+ return "openshift"
+ }
+ return falconImageAnalyzer.Spec.InstallNamespace
+}
+
+func (r *FalconImageAnalyzerReconciler) falconApiConfig(ctx context.Context, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) *falcon.ApiConfig {
+ cfg := falconImageAnalyzer.Spec.FalconAPI.ApiConfig()
+ cfg.Context = ctx
+
+ return cfg
+}
+
+func (r *FalconImageAnalyzerReconciler) imageMirroringEnabled(falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) bool {
+ return falconImageAnalyzer.Spec.Registry.Type != falconv1alpha1.RegistryTypeCrowdStrike
+}
+
+func (r *FalconImageAnalyzerReconciler) versionLock(falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) bool {
+ return (falconImageAnalyzer.Spec.Version != nil && falconImageAnalyzer.Status.Sensor != nil && strings.Contains(*falconImageAnalyzer.Status.Sensor, *falconImageAnalyzer.Spec.Version)) || (falconImageAnalyzer.Spec.Version == nil && falconImageAnalyzer.Status.Sensor != nil)
+}
diff --git a/internal/controller/falcon_image_analyzer/rbac.go b/internal/controller/falcon_image_analyzer/rbac.go
new file mode 100644
index 00000000..8475a3e7
--- /dev/null
+++ b/internal/controller/falcon_image_analyzer/rbac.go
@@ -0,0 +1,116 @@
+package falcon
+
+import (
+ "context"
+ "reflect"
+
+ falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
+ "github.com/crowdstrike/falcon-operator/internal/controller/assets"
+ k8sutils "github.com/crowdstrike/falcon-operator/internal/controller/common"
+ "github.com/crowdstrike/falcon-operator/pkg/common"
+ "github.com/go-logr/logr"
+ corev1 "k8s.io/api/core/v1"
+ rbacv1 "k8s.io/api/rbac/v1"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
+ types "k8s.io/apimachinery/pkg/types"
+ ctrl "sigs.k8s.io/controller-runtime"
+)
+
+const (
+ imageClusterRoleName = "falcon-operator-image-controller-role"
+ imageClusterRoleBindingName = "falcon-operator-image-controller-rolebinding"
+)
+
+func (r *FalconImageAnalyzerReconciler) reconcileServiceAccount(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) error {
+ update := false
+ existingServiceAccount := &corev1.ServiceAccount{}
+
+ imagePullSecrets := []corev1.LocalObjectReference{{Name: common.FalconPullSecretName}}
+ for _, secret := range falconImageAnalyzer.Spec.ImageAnalyzerConfig.ImagePullSecrets {
+ if secret.Name != common.FalconPullSecretName {
+ imagePullSecrets = append(imagePullSecrets, corev1.LocalObjectReference{Name: secret.Name})
+ }
+ }
+
+ serviceAccount := assets.ServiceAccount(common.ImageServiceAccountName,
+ falconImageAnalyzer.Spec.InstallNamespace,
+ common.FalconImageAnalyzer,
+ falconImageAnalyzer.Spec.ImageAnalyzerConfig.ServiceAccount.Annotations,
+ imagePullSecrets)
+
+ err := r.Get(ctx, types.NamespacedName{Name: common.ImageServiceAccountName, Namespace: falconImageAnalyzer.Spec.InstallNamespace}, existingServiceAccount)
+ if err != nil && apierrors.IsNotFound(err) {
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, serviceAccount)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer ServiceAccount")
+ return err
+ }
+
+ if !reflect.DeepEqual(serviceAccount.ObjectMeta.Annotations, existingServiceAccount.ObjectMeta.Annotations) {
+ existingServiceAccount.ObjectMeta.Annotations = serviceAccount.ObjectMeta.Annotations
+ update = true
+ }
+ if !reflect.DeepEqual(serviceAccount.ObjectMeta.Labels, existingServiceAccount.ObjectMeta.Labels) {
+ existingServiceAccount.ObjectMeta.Labels = serviceAccount.ObjectMeta.Labels
+ update = true
+ }
+
+ if update {
+ err = k8sutils.Update(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingServiceAccount)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+
+}
+
+func (r *FalconImageAnalyzerReconciler) reconcileClusterRoleBinding(ctx context.Context, req ctrl.Request, log logr.Logger, falconImageAnalyzer *falconv1alpha1.FalconImageAnalyzer) error {
+ clusterRoleBinding := assets.ClusterRoleBinding(imageClusterRoleBindingName,
+ falconImageAnalyzer.Spec.InstallNamespace,
+ imageClusterRoleName,
+ common.ImageServiceAccountName,
+ common.FalconImageAnalyzer,
+ []rbacv1.Subject{})
+ existingClusterRoleBinding := &rbacv1.ClusterRoleBinding{}
+
+ err := r.Client.Get(ctx, types.NamespacedName{Name: imageClusterRoleBindingName}, existingClusterRoleBinding)
+ if err != nil && apierrors.IsNotFound(err) {
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, clusterRoleBinding)
+ if err != nil {
+ return err
+ }
+
+ return nil
+ } else if err != nil {
+ log.Error(err, "Failed to get FalconImageAnalyzer ClusterRoleBinding")
+ return err
+ }
+
+ // If the RoleRef changes, we need to re-create it
+ if !reflect.DeepEqual(clusterRoleBinding.RoleRef, existingClusterRoleBinding.RoleRef) {
+ if err = k8sutils.Delete(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingClusterRoleBinding); err != nil {
+ return err
+ }
+
+ err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, clusterRoleBinding)
+ if err != nil {
+ return err
+ }
+ // If RoleRef is the same but Subjects have changed, update the object and post to k8s api
+ } else if !reflect.DeepEqual(clusterRoleBinding.Subjects, existingClusterRoleBinding.Subjects) {
+ existingClusterRoleBinding.Subjects = clusterRoleBinding.Subjects
+ err = k8sutils.Update(r.Client, ctx, req, log, falconImageAnalyzer, &falconImageAnalyzer.Status, existingClusterRoleBinding)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/internal/controller/falcon_image/suite_test.go b/internal/controller/falcon_image_analyzer/suite_test.go
similarity index 100%
rename from internal/controller/falcon_image/suite_test.go
rename to internal/controller/falcon_image_analyzer/suite_test.go
diff --git a/internal/controller/falcon_node/falconnodesensor_controller.go b/internal/controller/falcon_node/falconnodesensor_controller.go
index 2c029f31..2b3d3cce 100644
--- a/internal/controller/falcon_node/falconnodesensor_controller.go
+++ b/internal/controller/falcon_node/falconnodesensor_controller.go
@@ -119,13 +119,13 @@ func (r *FalconNodeSensorReconciler) Reconcile(ctx context.Context, req ctrl.Req
}
if nodesensor.Status.Version != version.Get() {
- nodesensor.Status.Version = version.Get()
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
err := r.Get(ctx, req.NamespacedName, nodesensor)
if err != nil {
return err
}
+ nodesensor.Status.Version = version.Get()
return r.Status().Update(ctx, nodesensor)
})
if err != nil {
@@ -325,13 +325,13 @@ func (r *FalconNodeSensorReconciler) Reconcile(ctx context.Context, req ctrl.Req
imgVer := common.ImageVersion(image)
if nodesensor.Status.Sensor != imgVer {
- nodesensor.Status.Sensor = imgVer
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
err := r.Get(ctx, req.NamespacedName, nodesensor)
if err != nil {
return err
}
+ nodesensor.Status.Sensor = imgVer
return r.Status().Update(ctx, nodesensor)
})
if err != nil {
diff --git a/pkg/common/constants.go b/pkg/common/constants.go
index d25bcd6e..7926df89 100644
--- a/pkg/common/constants.go
+++ b/pkg/common/constants.go
@@ -32,6 +32,7 @@ const (
FalconKernelSensor = "kernel_sensor"
FalconSidecarSensor = "container_sensor"
FalconAdmissionController = "admission_controller"
+ FalconImageAnalyzer = "falcon-imageanalyzer"
FalconFinalizer = "falcon.crowdstrike.com/finalizer"
FalconProviderValue = "crowdstrike"
FalconPartOfValue = "Falcon"
@@ -44,4 +45,5 @@ const (
NodeServiceAccountName = "falcon-operator-node-sensor"
AdmissionServiceAccountName = "falcon-operator-admission-controller"
NodeClusterRoleBindingName = "falcon-operator-node-sensor-rolebinding"
+ ImageServiceAccountName = "falcon-operator-image-analyzer"
)