Skip to content

Commit

Permalink
Merge pull request #536 from redhatrises/admission_ns_exclusions
Browse files Browse the repository at this point in the history
feat(admission): automate ocp & falcon ns exclusions
  • Loading branch information
redhatrises authored May 2, 2024
2 parents 946e0cf + e0d40fb commit d77d059
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 26 deletions.
4 changes: 0 additions & 4 deletions api/falcon/v1alpha1/falconadmission_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@ type FalconAdmissionNamespace struct {
// Configure a list of namespaces to ignore admission control.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Ignore Namespace List",order=1
Namespaces []string `json:"namespaces,omitempty"`

// For OpenShift clusters, ignore openshift-specific namespaces for admission control.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Ignore OpenShift Namespaces",order=2,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"}
IgnoreOpenShiftNamespaces bool `json:"ignoreOpenShiftNamespaces,omitempty"`
}

// FalconAdmissionStatus defines the observed state of FalconAdmission
Expand Down
5 changes: 3 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ func main() {
os.Exit(1)
}
if err = (&admissioncontroller.FalconAdmissionReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
OpenShift: openShift,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "FalconAdmission")
os.Exit(1)
Expand Down
4 changes: 0 additions & 4 deletions config/crd/bases/falcon.crowdstrike.com_falconadmissions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 0 additions & 4 deletions deploy/falcon-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,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.
Expand Down
1 change: 0 additions & 1 deletion docs/deployment/openshift/resources/admission/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ spec:
| admissionConfig.tls.validity | (optional) Configure the validity of the TLS certificate used by the Falcon Admission Controller |
| admissionConfig.failurePolicy | (optional) Configure the failure policy of the Falcon Admission Controller |
| admissionConfig.disabledNamespaces.namespaces | (optional) Configure the list of namespaces the Falcon Admission Controller validating webhook should ignore |
| admissionConfig.disabledNamespaces.ignoreOpenShiftNamespaces | (optional) Configure whether the Falcon Admission Controller validating webhook should ignore OpenShift-specific namespaces |
| admissionConfig.replicas | (optional) Configure the number of replicas of the Falcon Admission Controller |
| admissionConfig.imagePullPolicy | (optional) Configure the image pull policy of the Falcon Admission Controller |
| admissionConfig.imagePullSecrets | (optional) Configure the image pull secrets of the Falcon Admission Controller |
Expand Down
1 change: 0 additions & 1 deletion docs/resources/admission/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ spec:
| admissionConfig.tls.validity | (optional) Configure the validity of the TLS certificate used by the Falcon Admission Controller |
| admissionConfig.failurePolicy | (optional) Configure the failure policy of the Falcon Admission Controller |
| admissionConfig.disabledNamespaces.namespaces | (optional) Configure the list of namespaces the Falcon Admission Controller validating webhook should ignore |
| admissionConfig.disabledNamespaces.ignoreOpenShiftNamespaces | (optional) Configure whether the Falcon Admission Controller validating webhook should ignore OpenShift-specific namespaces |
| admissionConfig.replicas | (optional) Configure the number of replicas of the Falcon Admission Controller |
| admissionConfig.imagePullPolicy | (optional) Configure the image pull policy of the Falcon Admission Controller |
| admissionConfig.imagePullSecrets | (optional) Configure the image pull secrets of the Falcon Admission Controller |
Expand Down
1 change: 0 additions & 1 deletion docs/src/resources/admission.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ spec:
| admissionConfig.tls.validity | (optional) Configure the validity of the TLS certificate used by the Falcon Admission Controller |
| admissionConfig.failurePolicy | (optional) Configure the failure policy of the Falcon Admission Controller |
| admissionConfig.disabledNamespaces.namespaces | (optional) Configure the list of namespaces the Falcon Admission Controller validating webhook should ignore |
| admissionConfig.disabledNamespaces.ignoreOpenShiftNamespaces | (optional) Configure whether the Falcon Admission Controller validating webhook should ignore OpenShift-specific namespaces |
| admissionConfig.replicas | (optional) Configure the number of replicas of the Falcon Admission Controller |
| admissionConfig.imagePullPolicy | (optional) Configure the image pull policy of the Falcon Admission Controller |
| admissionConfig.imagePullSecrets | (optional) Configure the image pull secrets of the Falcon Admission Controller |
Expand Down
17 changes: 13 additions & 4 deletions internal/controller/admission/falconadmission_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ import (
// FalconAdmissionReconciler reconciles a FalconAdmission object
type FalconAdmissionReconciler struct {
client.Client
Scheme *runtime.Scheme
Scheme *runtime.Scheme
OpenShift bool
}

// SetupWithManager sets up the controller with the Manager.
func (r *FalconAdmissionReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&falconv1alpha1.FalconAdmission{}).
Owns(&corev1.Namespace{}).
Owns(&corev1.ConfigMap{}).
Owns(&corev1.ResourceQuota{}).
Owns(&corev1.Secret{}).
Expand Down Expand Up @@ -412,14 +414,21 @@ func (r *FalconAdmissionReconciler) reconcileAdmissionValidatingWebHook(ctx cont
failPolicy := arv1.Ignore
port := int32(443)

if falconAdmission.Spec.AdmissionConfig.DisabledNamespaces.IgnoreOpenShiftNamespaces {
ocpNS, err := k8sutils.GetNamespaceNamesSort(ctx, r.Client)
if r.OpenShift {
ocpNS, err := k8sutils.GetOpenShiftNamespaceNamesSort(ctx, r.Client)
if err != nil {
return false, err
}
disabledNamespaces = append(disabledNamespaces, ocpNS...)
}

falconNS, err := k8sutils.GetRunningFalconNS(r.Client, ctx)
if err != nil {
return false, err
}

disabledNamespaces = append(disabledNamespaces, falconNS...)

if falconAdmission.Spec.AdmissionConfig.FailurePolicy != "" {
failPolicy = falconAdmission.Spec.AdmissionConfig.FailurePolicy
}
Expand All @@ -431,7 +440,7 @@ func (r *FalconAdmissionReconciler) reconcileAdmissionValidatingWebHook(ctx cont
webhook := assets.ValidatingWebhook(falconAdmission.Name, falconAdmission.Spec.InstallNamespace, webhookName, cabundle, port, failPolicy, disabledNamespaces)
updated := false

err := r.Get(ctx, types.NamespacedName{Name: webhookName}, existingWebhook)
err = r.Get(ctx, types.NamespacedName{Name: webhookName}, existingWebhook)
if err != nil && apierrors.IsNotFound(err) {
err = k8sutils.Create(r.Client, r.Scheme, ctx, req, log, falconAdmission, &falconAdmission.Status, webhook)
if err != nil {
Expand Down
25 changes: 23 additions & 2 deletions internal/controller/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
falconv1alpha1 "github.com/crowdstrike/falcon-operator/api/falcon/v1alpha1"
"github.com/go-logr/logr"
"golang.org/x/exp/slices"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
Expand Down Expand Up @@ -249,7 +250,27 @@ func GetDeployment(r client.Client, ctx context.Context, namespace string, match
return &depList.Items[0], nil
}

func GetNamespaceNamesSort(ctx context.Context, cli client.Client) ([]string, error) {
func GetRunningFalconNS(r client.Client, ctx context.Context) ([]string, error) {
podList := &corev1.PodList{}
falconNamespaces := []string{}
listOpts := []client.ListOption{
client.MatchingLabels{"crowdstrike.com/provider": "crowdstrike"},
}

if err := r.List(ctx, podList, listOpts...); err != nil {
return []string{}, fmt.Errorf("unable to list pods: %v", err)
}

for _, pod := range podList.Items {
if !slices.Contains(falconNamespaces, pod.GetNamespace()) {
falconNamespaces = append(falconNamespaces, pod.GetNamespace())
}
}

return falconNamespaces, nil
}

func GetOpenShiftNamespaceNamesSort(ctx context.Context, cli client.Client) ([]string, error) {
nsList := []string{}
ns := &corev1.NamespaceList{}
err := cli.List(ctx, ns)
Expand All @@ -258,7 +279,7 @@ func GetNamespaceNamesSort(ctx context.Context, cli client.Client) ([]string, er
}

for _, i := range ns.Items {
if strings.Contains(i.Name, "openshift") || strings.Contains(i.Name, "falcon") {
if strings.Contains(i.Name, "openshift") && !slices.Contains(nsList, i.Name) {
nsList = append(nsList, i.Name)
}
}
Expand Down
35 changes: 32 additions & 3 deletions internal/controller/common/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,36 @@ func TestGetDeployment(t *testing.T) {
}
}

func TestGetNamespaceNamesSort(t *testing.T) {
func TestGetRunningFalconNS(t *testing.T) {
ctx := context.Background()

fakeClient, err := getFakeClient()
if err != nil {
t.Errorf("TestGetRunningFalconNS getFakeClient() error = %v", err)
}

err = fakeClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "test-namespace"}})
if err != nil {
t.Errorf("TestGetRunningFalconNS Create() error = %v", err)
}

err = fakeClient.Create(ctx, &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-pod", Namespace: "test-namespace", Labels: map[string]string{"crowdstrike.com/provider": "crowdstrike"}}})
if err != nil {
t.Errorf("TestGetRunningFalconNS Create() error = %v", err)
}

want := []string{"test-namespace"}
got, err := GetRunningFalconNS(fakeClient, ctx)
if err != nil {
t.Errorf("GetRunningFalconNS() error = %v", err)
}

if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("GetRunningFalconNS() mismatch (-want +got):\n%s", diff)
}
}

func TestGetOpenShiftNamespaceNamesSort(t *testing.T) {
ctx := context.Background()

fakeClient, err := getFakeClient()
Expand All @@ -153,8 +182,8 @@ func TestGetNamespaceNamesSort(t *testing.T) {
}
}

want := []string{"falcon-system", "openshift"}
got, err := GetNamespaceNamesSort(ctx, fakeClient)
want := []string{"openshift"}
got, err := GetOpenShiftNamespaceNamesSort(ctx, fakeClient)
if err != nil {
t.Errorf("GetNamespaceNamesSort() error = %v", err)
}
Expand Down

0 comments on commit d77d059

Please sign in to comment.