Skip to content

Commit

Permalink
Merge pull request #434 from redhatrises/kac_asset_up
Browse files Browse the repository at this point in the history
feat: add admission controller deployment
  • Loading branch information
redhatrises authored Oct 16, 2023
2 parents 45c8b32 + ef804c2 commit be05118
Show file tree
Hide file tree
Showing 12 changed files with 1,014 additions and 13 deletions.
2 changes: 1 addition & 1 deletion controllers/falcon_container/falconcontainer_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ func (r *FalconContainerReconciler) Reconcile(ctx context.Context, req ctrl.Requ
}

pod, err := k8sutils.GetReadyPod(r.Client, ctx, r.Namespace(), map[string]string{common.FalconComponentKey: common.FalconSidecarSensor})
if err != nil && err.Error() != "No Injector pod found in a Ready state" {
if err != nil && err.Error() != "No webhook service pod found in a Ready state" {
err = r.StatusUpdate(ctx, req, log, falconContainer, falconv1alpha1.ConditionFailed, metav1.ConditionFalse, "Reconciling", fmt.Sprintf("failed to find Ready injector pod: %v", err))
if err != nil {
return ctrl.Result{}, err
Expand Down
3 changes: 2 additions & 1 deletion controllers/falcon_container/image_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
"github.com/crowdstrike/falcon-operator/internal/controller/assets"
"github.com/crowdstrike/falcon-operator/pkg/common"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/api/errors"
types "k8s.io/apimachinery/pkg/types"
Expand All @@ -20,7 +21,7 @@ const (
)

func (r *FalconContainerReconciler) reconcileImageStream(ctx context.Context, log logr.Logger, falconContainer *falconv1alpha1.FalconContainer) (*imagev1.ImageStream, error) {
imageStream := assets.ImageStream(imageStreamName, r.imageNamespace(falconContainer))
imageStream := assets.ImageStream(imageStreamName, r.imageNamespace(falconContainer), common.FalconSidecarSensor)
existingImageStream := &imagev1.ImageStream{}

err := r.Client.Get(ctx, types.NamespacedName{Name: imageStreamName, Namespace: r.imageNamespace(falconContainer)}, existingImageStream)
Expand Down
4 changes: 3 additions & 1 deletion controllers/falcon_node/falconnodesensor_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,8 @@ func (r *FalconNodeSensorReconciler) handleClusterRoleBinding(ctx context.Contex
Kind: "ClusterRoleBinding",
},
ObjectMeta: metav1.ObjectMeta{
Name: common.NodeClusterRoleBindingName,
Name: common.NodeClusterRoleBindingName,
Labels: common.CRLabels("clusterrolebinding", common.NodeClusterRoleBindingName, common.FalconKernelSensor),
},
RoleRef: rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Expand Down Expand Up @@ -637,6 +638,7 @@ func (r *FalconNodeSensorReconciler) handleServiceAccount(ctx context.Context, n
ObjectMeta: metav1.ObjectMeta{
Namespace: nodesensor.TargetNs(),
Name: common.NodeServiceAccountName,
Labels: common.CRLabels("serviceaccount", common.NodeServiceAccountName, common.FalconKernelSensor),
},
}
err = ctrl.SetControllerReference(nodesensor, &sa, r.Scheme)
Expand Down
334 changes: 327 additions & 7 deletions internal/controller/assets/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/crowdstrike/falcon-operator/pkg/common"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)
Expand Down Expand Up @@ -176,15 +177,16 @@ func SideCarDeployment(name string, namespace string, component string, imageUri
},
},
},
TopologySpreadConstraints: []corev1.TopologySpreadConstraint{{
MaxSkew: 1,
TopologyKey: "kubernetes.io/hostname",
WhenUnsatisfiable: corev1.ScheduleAnyway,
LabelSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{common.FalconInstanceNameKey: name},
TopologySpreadConstraints: []corev1.TopologySpreadConstraint{
{
MaxSkew: 1,
TopologyKey: "kubernetes.io/hostname",
WhenUnsatisfiable: corev1.ScheduleAnyway,
LabelSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{common.FalconInstanceNameKey: name},
},
},
},
},
ImagePullSecrets: imagePullSecrets,
SecurityContext: &corev1.PodSecurityContext{
RunAsNonRoot: &runNonRoot,
Expand Down Expand Up @@ -251,3 +253,321 @@ func SideCarDeployment(name string, namespace string, component string, imageUri
},
}
}

// 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
readOnlyRootFilesystem := true
allowPrivilegeEscalation := false
shareProcessNamespace := true
resourcesClient := &corev1.ResourceRequirements{}
resourcesAC := &corev1.ResourceRequirements{}
sizeLimitTmp := resource.MustParse("256Mi")
sizeLimitPrivate := resource.MustParse("4Ki")
labels := common.CRLabels("deployment", name, component)

if falconAdmission.Spec.AdmissionConfig.ResourcesClient != nil {

Check failure on line 269 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 269 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
resourcesClient = falconAdmission.Spec.AdmissionConfig.ResourcesClient

Check failure on line 270 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 270 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
}

if falconAdmission.Spec.AdmissionConfig.ResourcesAC != nil {

Check failure on line 273 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 273 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
resourcesAC = falconAdmission.Spec.AdmissionConfig.ResourcesAC

Check failure on line 274 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 274 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
}

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: falconAdmission.Spec.AdmissionConfig.Replicas,

Check failure on line 288 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 288 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
Selector: &metav1.LabelSelector{
MatchLabels: labels,
},
Strategy: admissionDepUpdateStrategy(falconAdmission),
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: "node-role.kubernetes.io/master",
Operator: corev1.NodeSelectorOpDoesNotExist,
},
},
},
},
},
},
},
TopologySpreadConstraints: []corev1.TopologySpreadConstraint{
{
MaxSkew: 1,
TopologyKey: "kubernetes.io/hostname",
WhenUnsatisfiable: corev1.ScheduleAnyway,
LabelSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{common.FalconInstanceNameKey: name},
},
},
},
ImagePullSecrets: pullSecretsAdmission(falconAdmission),
ShareProcessNamespace: &shareProcessNamespace,
SecurityContext: &corev1.PodSecurityContext{
RunAsNonRoot: &runNonRoot,
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
},
ServiceAccountName: common.AdmissionServiceAccountName,
NodeSelector: common.NodeSelector,
PriorityClassName: common.FalconPriorityClassName,
Containers: []corev1.Container{
{
Name: "falcon-client",
Image: imageUri,
ImagePullPolicy: falconAdmission.Spec.AdmissionConfig.ImagePullPolicy,

Check failure on line 347 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 347 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
Args: []string{"client"},
SecurityContext: &corev1.SecurityContext{
ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
RunAsNonRoot: &runNonRoot,
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{
"ALL",
},
},
},
Env: []corev1.EnvVar{
{
Name: "__CS_POD_NAMESPACE",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.namespace",
},
},
},
{
Name: "__CS_POD_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "metadata.name",
},
},
},
{
Name: "__CS_POD_NODENAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
APIVersion: "v1",
FieldPath: "spec.nodeName",
},
},
},
},
EnvFrom: []corev1.EnvFromSource{
{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: name + "-config",
},
},
},
},
Ports: []corev1.ContainerPort{
{
ContainerPort: *falconAdmission.Spec.AdmissionConfig.ContainerPort,

Check failure on line 399 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 399 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
Name: common.FalconAdmissionServiceHTTPSName,
Protocol: corev1.ProtocolTCP,
},
},
VolumeMounts: []corev1.VolumeMount{
{
Name: name + "-tls-certs",
MountPath: "/run/secrets/tls",
ReadOnly: true,
},
{
Name: "crowdstrike-falcon-vol0",
MountPath: "/tmp",
},
{
Name: "crowdstrike-falcon-vol1",
MountPath: "/var/private",
},
},
StartupProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: common.FalconAdmissionClientStartupProbePath,
Port: intstr.IntOrString{IntVal: *falconAdmission.Spec.AdmissionConfig.ContainerPort},

Check failure on line 423 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 423 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
Scheme: corev1.URISchemeHTTPS,
},
},
InitialDelaySeconds: 5,
TimeoutSeconds: 1,
PeriodSeconds: 2,
SuccessThreshold: 1,
FailureThreshold: 30,
},
LivenessProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: common.FalconAdmissionClientLivenessProbePath,
Port: intstr.IntOrString{IntVal: *falconAdmission.Spec.AdmissionConfig.ContainerPort},

Check failure on line 437 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

Check failure on line 437 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)
Scheme: corev1.URISchemeHTTPS,
},
},
InitialDelaySeconds: 5,
TimeoutSeconds: 1,
PeriodSeconds: 10,
SuccessThreshold: 1,
FailureThreshold: 3,
},
Resources: *resourcesClient,
},
{
Name: "falcon-kac",
Image: imageUri,
ImagePullPolicy: falconAdmission.Spec.AdmissionConfig.ImagePullPolicy,

Check failure on line 452 in internal/controller/assets/deployment.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.19.x)

falconAdmission.Spec.AdmissionConfig undefined (type v1alpha1.FalconAdmissionSpec has no field or method AdmissionConfig)

SecurityContext: &corev1.SecurityContext{
ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
RunAsNonRoot: &runNonRoot,
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{
"ALL",
},
},
},
EnvFrom: []corev1.EnvFromSource{
{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: name + "-config",
},
},
},
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "crowdstrike-falcon-vol0",
MountPath: "/tmp",
},
{
Name: "crowdstrike-falcon-vol1",
MountPath: "/var/private",
},
},
StartupProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: common.FalconAdmissionStartupProbePath,
Port: intstr.IntOrString{IntVal: *falconAdmission.Spec.AdmissionConfig.ContainerPort},
Scheme: corev1.URISchemeHTTPS,
},
},
InitialDelaySeconds: 5,
TimeoutSeconds: 1,
PeriodSeconds: 2,
SuccessThreshold: 1,
FailureThreshold: 30,
},
LivenessProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: common.FalconAdmissionLivenessProbePath,
Port: intstr.IntOrString{IntVal: *falconAdmission.Spec.AdmissionConfig.ContainerPort},
Scheme: corev1.URISchemeHTTPS,
},
},
InitialDelaySeconds: 5,
TimeoutSeconds: 1,
PeriodSeconds: 10,
SuccessThreshold: 1,
FailureThreshold: 3,
},
Resources: *resourcesAC,
},
},
Volumes: []corev1.Volume{
{
Name: name + "-tls-certs",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: name + "-tls",
},
},
},
{
Name: "crowdstrike-falcon-vol0",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
SizeLimit: &sizeLimitTmp,
},
},
},
{
Name: "crowdstrike-falcon-vol1",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
SizeLimit: &sizeLimitPrivate,
},
},
},
},
},
},
},
}
}

func pullSecretsAdmission(admission *falconv1alpha1.FalconAdmission) []corev1.LocalObjectReference {
if admission.Spec.Image == "" {
return []corev1.LocalObjectReference{
{
Name: common.FalconPullSecretName,
},
}
} else {
return admission.Spec.AdmissionConfig.ImagePullSecrets
}
}

func admissionDepUpdateStrategy(admission *falconv1alpha1.FalconAdmission) appsv1.DeploymentStrategy {
rollingUpdateSettings := appsv1.RollingUpdateDeployment{}

if admission.Spec.AdmissionConfig.DepUpdateStrategy.RollingUpdate.MaxSurge != nil {
rollingUpdateSettings.MaxSurge = admission.Spec.AdmissionConfig.DepUpdateStrategy.RollingUpdate.MaxSurge
}

if admission.Spec.AdmissionConfig.DepUpdateStrategy.RollingUpdate.MaxUnavailable != nil {
rollingUpdateSettings.MaxUnavailable = admission.Spec.AdmissionConfig.DepUpdateStrategy.RollingUpdate.MaxUnavailable
}

return appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
RollingUpdate: &rollingUpdateSettings,
}
}
Loading

0 comments on commit be05118

Please sign in to comment.