Repository: kubernetes-sigs/security-profiles-operator
Pull request #269 (2021-02-03 15:59:06)

Deploy default profiles via the manager
#### What type of PR is this?

/kind feature

#### What this PR does / why we need it:
We now deploy the default profiles at the same time where the daemonset
gets deployed. This allows users to use them either in the
`security-profiles-operator` namespace (default) or in the provided
namespace.
#### Which issue(s) this PR fixes:

<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.

Fixes #

or

None
-->
Fixes https://github.com/kubernetes-sigs/security-profiles-operator/issues/267
#### Does this PR have test?

<!--
If tests aren't applicable just write N/A.
-->
None
#### Special notes for your reviewer:
None
#### Does this PR introduce a user-facing change?

<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".

For more information on release notes see: https://git.k8s.io/community/contributors/guide/release-notes.md
-->

```release-note
Automatically deploy the default profiles in the correct namespace without having a need for an additional `kubectl apply` command.
```


k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/security-profiles-operator/pull/269#" title="Author self-approved">saschagrunert</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fsecurity-profiles-operator).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/security-profiles-operator/blob/master/OWNERS)~~ [saschagrunert]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 2b75f3b7f075847792febfb056d948d72988a38a | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/269/pull-security-profiles-operator-test-e2e/1356995642735464448) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=269). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: /test pull-security-profiles-operator-test-e2e
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 2b75f3b7f075847792febfb056d948d72988a38a | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/269/pull-security-profiles-operator-test-e2e/1357032880466825216) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=269). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: Alright I have to fixup the e2e tests first…
cmurphy: @saschagrunert here's a fix https://github.com/kubernetes-sigs/security-profiles-operator/pull/271 although I think the latest hello-world image tag may have fixed it anyways
k8s-ci-robot: @saschagrunert: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-security-profiles-operator-test-e2e | 0c066a7fc5ef6d0101a03819aaa584c6446f99fd | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_security-profiles-operator/269/pull-security-profiles-operator-test-e2e/1357245804275830784) | `/test pull-security-profiles-operator-test-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=security-profiles-operator&pr=269). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Asaschagrunert). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/security-profiles-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
saschagrunert: > @saschagrunert here's a fix #271 although I think the latest hello-world image tag may have fixed it anyways

Thanks! Another issue was that we still have to remove the profiles before deleting the operator. Added this hint to the docs.
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/security-profiles-operator/pull/269#pullrequestreview-583211466" title="LGTM">pjbgf</a>*, *<a href="https://github.com/kubernetes-sigs/security-profiles-operator/pull/269#" title="Author self-approved">saschagrunert</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fsecurity-profiles-operator).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes-sigs/security-profiles-operator/blob/master/OWNERS)~~ [pjbgf,saschagrunert]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/Makefile b/Makefile
index f2640bbbb..fa1ecf957 100644
--- a/Makefile
+++ b/Makefile
@@ -119,9 +119,7 @@ go-mod: ## Cleanup and verify go modules
 .PHONY: deployments
 deployments: manifests ## Generate the deployment files with kustomize
 	kustomize build --reorder=none deploy/overlays/cluster -o deploy/operator.yaml
-	kustomize build --reorder=none deploy/profiles/base -o deploy/profiles/default-profiles.yaml
 	kustomize build --reorder=none deploy/overlays/namespaced -o deploy/namespace-operator.yaml
-	kustomize build --reorder=none deploy/profiles/overlays/namespaced -o deploy/profiles/namespace-default-profiles.yaml
 	kustomize build --reorder=none deploy/base/webhook -o deploy/webhook.yaml
 
 .PHONY: image
diff --git a/deploy/profiles/base/kustomization.yaml b/deploy/profiles/base/kustomization.yaml
deleted file mode 100644
index 8e2d3bc25..000000000
--- a/deploy/profiles/base/kustomization.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
----
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-commonLabels:
-  app: security-profiles-operator
-
-resources:
-  - nginx-1.19.1.yaml
-
-generatorOptions:
-  disableNameSuffixHash: true
diff --git a/deploy/profiles/base/nginx-1.19.1.yaml b/deploy/profiles/base/nginx-1.19.1.yaml
deleted file mode 100644
index 32e02bdd6..000000000
--- a/deploy/profiles/base/nginx-1.19.1.yaml
+++ /dev/null
@@ -1,106 +0,0 @@
----
-apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
-kind: SeccompProfile
-metadata:
-  name: nginx-1.19.1
-  namespace: security-profiles-operator
-spec:
-  defaultAction: SCMP_ACT_ERRNO
-  targetWorkload: default-profiles
-  architectures:
-  - SCMP_ARCH_X86_64
-  - SCMP_ARCH_X86
-  - SCMP_ARCH_X32
-  syscalls:
-  - names:
-    - accept4
-    - access
-    - arch_prctl
-    - bind
-    - brk
-    - capget
-    - capset
-    - chdir
-    - chown
-    - clone
-    - close
-    - connect
-    - dup2
-    - epoll_create
-    - epoll_ctl
-    - epoll_pwait
-    - epoll_wait
-    - eventfd2
-    - execve
-    - exit
-    - exit_group
-    - faccessat
-    - fadvise64
-    - fchdir
-    - fchown
-    - fcntl
-    - fgetxattr
-    - fsetxattr
-    - fstat
-    - fstatfs
-    - futex
-    - getcwd
-    - getdents
-    - getdents64
-    - getegid
-    - geteuid
-    - getgid
-    - getpid
-    - getppid
-    - getrlimit
-    - getuid
-    - ioctl
-    - io_setup
-    - listen
-    - lseek
-    - mkdir
-    - mmap
-    - mprotect
-    - munmap
-    - nanosleep
-    - newfstatat
-    - open
-    - openat
-    - pipe
-    - prctl
-    - pread64
-    - prlimit64
-    - pwrite64
-    - read
-    - recvfrom
-    - recvmsg
-    - rename
-    - rt_sigaction
-    - rt_sigprocmask
-    - rt_sigreturn
-    - rt_sigsuspend
-    - sched_getaffinity
-    - seccomp
-    - sendfile
-    - sendmsg
-    - setgid
-    - setgroups
-    - setitimer
-    - set_robust_list
-    - setsockopt
-    - set_tid_address
-    - setuid
-    - sigaltstack
-    - socket
-    - socketpair
-    - stat
-    - statfs
-    - sysinfo
-    - umask
-    - uname
-    - unlink
-    - utimensat
-    - wait4
-    - write
-    - writev
-    action: SCMP_ACT_ALLOW
diff --git a/deploy/profiles/default-profiles.yaml b/deploy/profiles/default-profiles.yaml
deleted file mode 100644
index 8b03baa13..000000000
--- a/deploy/profiles/default-profiles.yaml
+++ /dev/null
@@ -1,107 +0,0 @@
-apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
-kind: SeccompProfile
-metadata:
-  labels:
-    app: security-profiles-operator
-  name: nginx-1.19.1
-  namespace: security-profiles-operator
-spec:
-  architectures:
-  - SCMP_ARCH_X86_64
-  - SCMP_ARCH_X86
-  - SCMP_ARCH_X32
-  defaultAction: SCMP_ACT_ERRNO
-  syscalls:
-  - action: SCMP_ACT_ALLOW
-    names:
-    - accept4
-    - access
-    - arch_prctl
-    - bind
-    - brk
-    - capget
-    - capset
-    - chdir
-    - chown
-    - clone
-    - close
-    - connect
-    - dup2
-    - epoll_create
-    - epoll_ctl
-    - epoll_pwait
-    - epoll_wait
-    - eventfd2
-    - execve
-    - exit
-    - exit_group
-    - faccessat
-    - fadvise64
-    - fchdir
-    - fchown
-    - fcntl
-    - fgetxattr
-    - fsetxattr
-    - fstat
-    - fstatfs
-    - futex
-    - getcwd
-    - getdents
-    - getdents64
-    - getegid
-    - geteuid
-    - getgid
-    - getpid
-    - getppid
-    - getrlimit
-    - getuid
-    - ioctl
-    - io_setup
-    - listen
-    - lseek
-    - mkdir
-    - mmap
-    - mprotect
-    - munmap
-    - nanosleep
-    - newfstatat
-    - open
-    - openat
-    - pipe
-    - prctl
-    - pread64
-    - prlimit64
-    - pwrite64
-    - read
-    - recvfrom
-    - recvmsg
-    - rename
-    - rt_sigaction
-    - rt_sigprocmask
-    - rt_sigreturn
-    - rt_sigsuspend
-    - sched_getaffinity
-    - seccomp
-    - sendfile
-    - sendmsg
-    - setgid
-    - setgroups
-    - setitimer
-    - set_robust_list
-    - setsockopt
-    - set_tid_address
-    - setuid
-    - sigaltstack
-    - socket
-    - socketpair
-    - stat
-    - statfs
-    - sysinfo
-    - umask
-    - uname
-    - unlink
-    - utimensat
-    - wait4
-    - write
-    - writev
-  targetWorkload: default-profiles
diff --git a/deploy/profiles/namespace-default-profiles.yaml b/deploy/profiles/namespace-default-profiles.yaml
deleted file mode 100644
index c8ec617da..000000000
--- a/deploy/profiles/namespace-default-profiles.yaml
+++ /dev/null
@@ -1,107 +0,0 @@
-apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
-kind: SeccompProfile
-metadata:
-  labels:
-    app: security-profiles-operator
-  name: nginx-1.19.1
-  namespace: NS_REPLACE
-spec:
-  architectures:
-  - SCMP_ARCH_X86_64
-  - SCMP_ARCH_X86
-  - SCMP_ARCH_X32
-  defaultAction: SCMP_ACT_ERRNO
-  syscalls:
-  - action: SCMP_ACT_ALLOW
-    names:
-    - accept4
-    - access
-    - arch_prctl
-    - bind
-    - brk
-    - capget
-    - capset
-    - chdir
-    - chown
-    - clone
-    - close
-    - connect
-    - dup2
-    - epoll_create
-    - epoll_ctl
-    - epoll_pwait
-    - epoll_wait
-    - eventfd2
-    - execve
-    - exit
-    - exit_group
-    - faccessat
-    - fadvise64
-    - fchdir
-    - fchown
-    - fcntl
-    - fgetxattr
-    - fsetxattr
-    - fstat
-    - fstatfs
-    - futex
-    - getcwd
-    - getdents
-    - getdents64
-    - getegid
-    - geteuid
-    - getgid
-    - getpid
-    - getppid
-    - getrlimit
-    - getuid
-    - ioctl
-    - io_setup
-    - listen
-    - lseek
-    - mkdir
-    - mmap
-    - mprotect
-    - munmap
-    - nanosleep
-    - newfstatat
-    - open
-    - openat
-    - pipe
-    - prctl
-    - pread64
-    - prlimit64
-    - pwrite64
-    - read
-    - recvfrom
-    - recvmsg
-    - rename
-    - rt_sigaction
-    - rt_sigprocmask
-    - rt_sigreturn
-    - rt_sigsuspend
-    - sched_getaffinity
-    - seccomp
-    - sendfile
-    - sendmsg
-    - setgid
-    - setgroups
-    - setitimer
-    - set_robust_list
-    - setsockopt
-    - set_tid_address
-    - setuid
-    - sigaltstack
-    - socket
-    - socketpair
-    - stat
-    - statfs
-    - sysinfo
-    - umask
-    - uname
-    - unlink
-    - utimensat
-    - wait4
-    - write
-    - writev
-  targetWorkload: default-profiles
diff --git a/deploy/profiles/overlays/namespaced/kustomization.yaml b/deploy/profiles/overlays/namespaced/kustomization.yaml
deleted file mode 100644
index a55bb3591..000000000
--- a/deploy/profiles/overlays/namespaced/kustomization.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
----
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-bases:
-  - ../../base
-
-patchesJson6902:
-  - target:
-      group: security-profiles-operator.x-k8s.io
-      version: v1alpha1
-      kind: SeccompProfile
-      name: nginx-1.19.1
-      namespace: security-profiles-operator
-    path: seccompprofile.yaml
diff --git a/deploy/profiles/overlays/namespaced/seccompprofile.yaml b/deploy/profiles/overlays/namespaced/seccompprofile.yaml
deleted file mode 100644
index 33e058ce2..000000000
--- a/deploy/profiles/overlays/namespaced/seccompprofile.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-- op: replace
-  path: /metadata/namespace
-  value: NS_REPLACE
diff --git a/installation-usage.md b/installation-usage.md
index 6d0154dc4..c691c3ab5 100644
--- a/installation-usage.md
+++ b/installation-usage.md
@@ -21,7 +21,6 @@ The feature scope of the security-profiles-operator is right now limited to:
 
 ```sh
 $ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/operator.yaml
-$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/profiles/default-profiles.yaml
 ```
 
 ### 2. Create Profile
@@ -305,7 +304,6 @@ operator deployment to run in a single namespace, use the
 NAMESPACE=<your-namespace>
 
 curl https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/namespace-operator.yaml | sed "s/NS_REPLACE/$NAMESPACE/g" | kubectl apply -f -
-curl https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/profiles/namespace-default-profiles.yaml | sed "s/NS_REPLACE/$NAMESPACE/g" | kubectl apply -f -
 ```
 
 ## Troubleshooting
@@ -344,6 +342,6 @@ Please note corrupted seccomp profiles can disrupt your workloads. Therefore, en
 To uninstall, remove the profiles before removing the rest of the operator:
 
 ```sh
-$ kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/profiles/default-profiles.yaml
+$ kubectl delete seccompprofiles --all --all-namespaces
 $ kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/security-profiles-operator/master/deploy/operator.yaml
 ```
diff --git a/internal/pkg/controllers/spod/bindata/default_profiles.go b/internal/pkg/controllers/spod/bindata/default_profiles.go
new file mode 100644
index 000000000..f6809bac8
--- /dev/null
+++ b/internal/pkg/controllers/spod/bindata/default_profiles.go
@@ -0,0 +1,148 @@
+/*
+Copyright 2021 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package bindata
+
+import (
+	"github.com/containers/common/pkg/seccomp"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	"sigs.k8s.io/security-profiles-operator/api/seccompprofile/v1alpha1"
+	"sigs.k8s.io/security-profiles-operator/internal/pkg/config"
+)
+
+var (
+	archX8664 = v1alpha1.Arch(seccomp.ArchX86_64)
+	archX86   = v1alpha1.Arch(seccomp.ArchX86)
+	archX32   = v1alpha1.Arch(seccomp.ArchX32)
+)
+
+// DefaultProfiles returns the default profiles deployed by the operator.
+func DefaultProfiles() []*v1alpha1.SeccompProfile {
+	return []*v1alpha1.SeccompProfile{
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "nginx-1.19.1",
+				Namespace: config.GetOperatorNamespace(),
+				Labels: map[string]string{
+					"app": config.OperatorName,
+				},
+			},
+			Spec: v1alpha1.SeccompProfileSpec{
+				TargetWorkload: "default-profiles",
+				DefaultAction:  seccomp.ActErrno,
+				Architectures:  []*v1alpha1.Arch{&archX8664, &archX86, &archX32},
+				Syscalls: []*v1alpha1.Syscall{
+					{
+						Action: seccomp.ActAllow,
+						Names: []string{
+							"accept4",
+							"access",
+							"arch_prctl",
+							"bind",
+							"brk",
+							"capget",
+							"capset",
+							"chdir",
+							"chown",
+							"clone",
+							"close",
+							"connect",
+							"dup2",
+							"epoll_create",
+							"epoll_ctl",
+							"epoll_pwait",
+							"epoll_wait",
+							"eventfd2",
+							"execve",
+							"exit",
+							"exit_group",
+							"faccessat",
+							"fadvise64",
+							"fchdir",
+							"fchown",
+							"fcntl",
+							"fgetxattr",
+							"fsetxattr",
+							"fstat",
+							"fstatfs",
+							"futex",
+							"getcwd",
+							"getdents",
+							"getdents64",
+							"getegid",
+							"geteuid",
+							"getgid",
+							"getpid",
+							"getppid",
+							"getrlimit",
+							"getuid",
+							"ioctl",
+							"io_setup",
+							"listen",
+							"lseek",
+							"mkdir",
+							"mmap",
+							"mprotect",
+							"munmap",
+							"nanosleep",
+							"newfstatat",
+							"open",
+							"openat",
+							"pipe",
+							"prctl",
+							"pread64",
+							"prlimit64",
+							"pwrite64",
+							"read",
+							"recvfrom",
+							"recvmsg",
+							"rename",
+							"rt_sigaction",
+							"rt_sigprocmask",
+							"rt_sigreturn",
+							"rt_sigsuspend",
+							"sched_getaffinity",
+							"seccomp",
+							"sendfile",
+							"sendmsg",
+							"setgid",
+							"setgroups",
+							"setitimer",
+							"set_robust_list",
+							"setsockopt",
+							"set_tid_address",
+							"setuid",
+							"sigaltstack",
+							"socket",
+							"socketpair",
+							"stat",
+							"statfs",
+							"sysinfo",
+							"umask",
+							"uname",
+							"unlink",
+							"utimensat",
+							"wait4",
+							"write",
+							"writev",
+						},
+					},
+				},
+			},
+		},
+	}
+}
diff --git a/internal/pkg/controllers/spod/configmap_controller.go b/internal/pkg/controllers/spod/configmap_controller.go
index 34fbd97be..c1bdc8e78 100644
--- a/internal/pkg/controllers/spod/configmap_controller.go
+++ b/internal/pkg/controllers/spod/configmap_controller.go
@@ -34,6 +34,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
 	"sigs.k8s.io/security-profiles-operator/internal/pkg/config"
+	"sigs.k8s.io/security-profiles-operator/internal/pkg/controllers/spod/bindata"
 )
 
 // blank assignment to verify that ReconcileConfigMap implements `reconcile.Reconciler`.
@@ -43,11 +44,12 @@ var _ reconcile.Reconciler = &ReconcileSPOd{}
 type ReconcileSPOd struct {
 	// This client, initialized using mgr.Client() above, is a split client
 	// that reads objects from the cache and writes to the apiserver
-	client   client.Client
-	scheme   *runtime.Scheme
-	baseSPOd *appsv1.DaemonSet
-	record   event.Recorder
-	log      logr.Logger
+	client         client.Client
+	scheme         *runtime.Scheme
+	baseSPOd       *appsv1.DaemonSet
+	record         event.Recorder
+	log            logr.Logger
+	watchNamespace string
 }
 
 // Reconcile reads that state of the cluster for a ConfigMap object and makes changes based on the state read
@@ -98,21 +100,40 @@ func (r *ReconcileSPOd) handleCreate(
 	ctx context.Context,
 	cfg *corev1.ConfigMap,
 	image string,
-) (reconcile.Result, error) {
-	r.log.Info("Creating SPOd")
+) (res reconcile.Result, err error) {
+	r.log.Info("Creating operator resources")
 	newSPOd := r.getConfiguredSPOd(cfg, image)
 
 	if err := controllerutil.SetControllerReference(cfg, newSPOd, r.scheme); err != nil {
-		return reconcile.Result{}, errors.Wrap(err, "setting spod controller reference")
+		return res, errors.Wrap(err, "setting spod controller reference")
 	}
 
+	r.log.Info("Deploying operator daemonset")
 	if err := r.client.Create(ctx, newSPOd); err != nil {
 		if kerrors.IsAlreadyExists(err) {
-			return reconcile.Result{}, nil
+			return res, nil
 		}
-		return reconcile.Result{}, errors.Wrap(err, "error creating spod DaemonSet")
+		return res, errors.Wrap(err, "creating operator DaemonSet")
 	}
-	return reconcile.Result{}, nil
+
+	r.log.Info("Deploying operator default profiles")
+	for _, profile := range bindata.DefaultProfiles() {
+		// Adapt the namespace if we watch only a single one
+		if r.watchNamespace != "" {
+			profile.Namespace = r.watchNamespace
+		}
+
+		if err := r.client.Create(ctx, profile); err != nil {
+			if kerrors.IsAlreadyExists(err) {
+				return res, nil
+			}
+			return res, errors.Wrapf(
+				err, "creating operator default profile %s", profile.Name,
+			)
+		}
+	}
+
+	return res, nil
 }
 
 func (r *ReconcileSPOd) getConfiguredSPOd(cfg *corev1.ConfigMap, image string) *appsv1.DaemonSet {
diff --git a/internal/pkg/controllers/spod/setup.go b/internal/pkg/controllers/spod/setup.go
index e9a4e9604..3694b850f 100644
--- a/internal/pkg/controllers/spod/setup.go
+++ b/internal/pkg/controllers/spod/setup.go
@@ -50,11 +50,12 @@ func Setup(ctx context.Context, mgr ctrl.Manager, dt *DaemonTunables, l logr.Log
 		WithEventFilter(resource.NewPredicates(isSPOdConfig)).
 		Owns(&appsv1.DaemonSet{}).
 		Complete(&ReconcileSPOd{
-			baseSPOd: getEffectiveSPOd(dt),
-			client:   mgr.GetClient(),
-			log:      l,
-			record:   event.NewAPIRecorder(mgr.GetEventRecorderFor("spod-config")),
-			scheme:   mgr.GetScheme(),
+			baseSPOd:       getEffectiveSPOd(dt),
+			client:         mgr.GetClient(),
+			log:            l,
+			record:         event.NewAPIRecorder(mgr.GetEventRecorderFor("spod-config")),
+			scheme:         mgr.GetScheme(),
+			watchNamespace: dt.WatchNamespace,
 		})
 }
 


Test patch:
diff --git a/test/e2e_test.go b/test/e2e_test.go
index 046028277..c3b29ffc6 100644
--- a/test/e2e_test.go
+++ b/test/e2e_test.go
@@ -28,13 +28,11 @@ import (
 )
 
 const (
-	certmanager              = "https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager.yaml"
-	manifest                 = "deploy/operator.yaml"
-	namespaceManifest        = "deploy/namespace-operator.yaml"
-	defaultProfiles          = "deploy/profiles/default-profiles.yaml"
-	namespaceDefaultProfiles = "deploy/profiles/namespace-default-profiles.yaml"
-	testNamespace            = "test-ns"
-	defaultNamespace         = "default"
+	certmanager       = "https://github.com/jetstack/cert-manager/releases/download/v1.1.0/cert-manager.yaml"
+	manifest          = "deploy/operator.yaml"
+	namespaceManifest = "deploy/namespace-operator.yaml"
+	testNamespace     = "test-ns"
+	defaultNamespace  = "default"
 	// NOTE(jaosorior): We should be able to decrease this once we
 	// migrate to a single daemonset-based implementation for the
 	// SELinux pieces.
@@ -44,7 +42,7 @@ const (
 
 func (e *e2e) TestSecurityProfilesOperator() {
 	// Deploy the operator
-	e.deployOperator(manifest, defaultProfiles)
+	e.deployOperator(manifest)
 	defer e.run("git", "checkout", manifest)
 
 	// Retrieve the inputs for the test cases
@@ -100,7 +98,7 @@ func (e *e2e) TestSecurityProfilesOperator() {
 	})
 
 	// Clean up cluster-wide deployment to prepare for namespace deployment
-	e.cleanupOperator(manifest, defaultProfiles)
+	e.cleanupOperator(manifest)
 
 	e.logf("testing namespace operator")
 
@@ -113,15 +111,10 @@ func (e *e2e) TestSecurityProfilesOperator() {
 		"sed", "-i", fmt.Sprintf("s/NS_REPLACE/%s/", testNamespace),
 		namespaceManifest,
 	)
-	e.run(
-		"sed", "-i", fmt.Sprintf("s/NS_REPLACE/%s/", testNamespace),
-		namespaceDefaultProfiles,
-	)
 	defer e.run("git", "checkout", namespaceManifest)
-	defer e.run("git", "checkout", namespaceDefaultProfiles)
 	// All following operations such as create pod will be in the test namespace
 	e.kubectl("config", "set-context", "--current", "--namespace", testNamespace)
-	e.deployOperator(namespaceManifest, namespaceDefaultProfiles)
+	e.deployOperator(namespaceManifest)
 
 	for _, testCase := range testCases {
 		tc := testCase
@@ -131,7 +124,7 @@ func (e *e2e) TestSecurityProfilesOperator() {
 	}
 }
 
-func (e *e2e) deployOperator(manifest, profiles string) {
+func (e *e2e) deployOperator(manifest string) {
 	// Ensure that we do not accidentally pull the image and use the pre-loaded
 	// ones from the nodes
 	e.logf("Setting imagePullPolicy to '%s' in manifest: %s", e.pullPolicy, manifest)
@@ -166,10 +159,6 @@ func (e *e2e) deployOperator(manifest, profiles string) {
 	e.logf("Deploying operator")
 	e.kubectl("create", "-f", manifest)
 
-	// Deploy the default profiles
-	e.logf("Deploying default profiles")
-	e.kubectl("create", "-f", profiles)
-
 	// Wait for the operator to be ready
 	e.logf("Waiting for operator to be ready")
 	// Wait for deployment
@@ -181,10 +170,10 @@ func (e *e2e) deployOperator(manifest, profiles string) {
 	e.kubectlOperatorNS("wait", "--for", "condition=ready", "pod", "-l", "app=spod")
 }
 
-func (e *e2e) cleanupOperator(manifest, profiles string) {
+func (e *e2e) cleanupOperator(manifest string) {
 	// Clean up the operator
 	e.logf("Cleaning up operator")
-	e.kubectl("delete", "-f", profiles)
+	e.kubectl("delete", "seccompprofiles", "--all", "--all-namespaces")
 	e.kubectl("delete", "-f", manifest)
 }
 
diff --git a/test/tc_redeploy_operator_test.go b/test/tc_redeploy_operator_test.go
index e7bcc7455..48f383752 100644
--- a/test/tc_redeploy_operator_test.go
+++ b/test/tc_redeploy_operator_test.go
@@ -18,16 +18,16 @@ package e2e_test
 
 func (e *e2e) testCaseReDeployOperator([]string) {
 	// Clean up the operator
-	e.cleanupOperator(manifest, defaultProfiles)
+	e.cleanupOperator(manifest)
 
 	// Deploy the operator again
-	e.deployOperator(manifest, defaultProfiles)
+	e.deployOperator(manifest)
 }
 
 func (e *e2e) testCaseReDeployNamespaceOperator([]string) {
 	// Clean up the operator
-	e.cleanupOperator(namespaceManifest, namespaceDefaultProfiles)
+	e.cleanupOperator(namespaceManifest)
 
 	// Deploy the operator again
-	e.deployOperator(namespaceManifest, namespaceDefaultProfiles)
+	e.deployOperator(namespaceManifest)
 }