Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

Commit

Permalink
Merge pull request #95 from font/olm
Browse files Browse the repository at this point in the history
Fix installing Gatekeeper when operator is deployed via OLM
  • Loading branch information
font authored Dec 19, 2020
2 parents af4e906 + efea7fe commit 0d05b51
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 69 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ manifests: controller-gen
.PHONY: import-manifests
import-manifests: kustomize
$(KUSTOMIZE) build github.com/open-policy-agent/gatekeeper/config/default/?ref=$(GATEKEEPER_VERSION) -o $(GATEKEEPER_MANIFEST_DIR)
rm -f ./$(GATEKEEPER_MANIFEST_DIR)/v1_namespace_gatekeeper-system.yaml

# Run go fmt against code
.PHONY: fmt
Expand Down
15 changes: 4 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,11 @@ Then proceed to the installation method you prefer below.

### Outside the Cluster

If you would like to run the Operator outside the cluster, you'll have to set the
`WATCH_NAMESPACE` environment variable to the namespace you want the
Operator to monitor:
If you would like to run the Operator outside the cluster you just execute:

1. Set the WATCH_NAMESPACE environment variable:
```shell
export WATCH_NAMESPACE=gatekeeper-system
```
1. You then run the Operator with:
```shell
make run
```
```shell
make run
```

### Inside the Cluster

Expand Down
17 changes: 12 additions & 5 deletions bundle/manifests/gatekeeper-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,18 @@ spec:
- get
- patch
- update
- apiGroups:
- ""
resources:
- namespaces
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- security.openshift.io
resourceNames:
Expand Down Expand Up @@ -256,11 +268,6 @@ spec:
- --enable-leader-election
command:
- /manager
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.annotations['olm.targetNamespaces']
image: quay.io/gatekeeper/gatekeeper-operator:latest
imagePullPolicy: Always
name: manager
Expand Down
8 changes: 8 additions & 0 deletions config/gatekeeper/v1_namespace_gatekeeper-system.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: Namespace
metadata:
labels:
admission.gatekeeper.sh/ignore: no-self-managing
control-plane: controller-manager
gatekeeper.sh/system: "yes"
name: gatekeeper-system
5 changes: 0 additions & 5 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,4 @@ spec:
requests:
cpu: 100m
memory: 20Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
terminationGracePeriodSeconds: 10
15 changes: 15 additions & 0 deletions config/rbac/overlays/openshift/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ patchesJSON6902:
kind: ClusterRole
name: manager-role
patch: |-
- op: add
path: /rules/-
value:
apiGroups:
- ""
resources:
- namespaces
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- op: add
path: /rules/-
value:
Expand Down
52 changes: 30 additions & 22 deletions controllers/gatekeeper_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"strconv"
"time"

"github.com/RHsyseng/operator-utils/pkg/utils/openshift"
"github.com/go-logr/logr"
"github.com/openshift/library-go/pkg/manifest"
"github.com/pkg/errors"
Expand All @@ -35,7 +34,6 @@ import (
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate"

Expand All @@ -47,6 +45,7 @@ import (
var (
defaultGatekeeperCrName = "gatekeeper"
openshiftAssetsDir = "openshift/"
NamespaceFile = "v1_namespace_gatekeeper-system.yaml"
RoleFile = "rbac.authorization.k8s.io_v1_role_gatekeeper-manager-role.yaml"
AuditFile = "apps_v1_deployment_gatekeeper-audit.yaml"
WebhookFile = "apps_v1_deployment_gatekeeper-controller-manager.yaml"
Expand All @@ -55,6 +54,7 @@ var (
ServerCertFile = "v1_secret_gatekeeper-webhook-server-cert.yaml"
ValidatingWebhookConfiguration = "admissionregistration.k8s.io_v1beta1_validatingwebhookconfiguration_gatekeeper-validating-webhook-configuration.yaml"
orderedStaticAssets = []string{
NamespaceFile,
"apiextensions.k8s.io_v1beta1_customresourcedefinition_configs.config.gatekeeper.sh.yaml",
"apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplates.templates.gatekeeper.sh.yaml",
"apiextensions.k8s.io_v1beta1_customresourcedefinition_constrainttemplatepodstatuses.status.gatekeeper.sh.yaml",
Expand Down Expand Up @@ -89,9 +89,10 @@ const (
// GatekeeperReconciler reconciles a Gatekeeper object
type GatekeeperReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
Namespace string
Log logr.Logger
Scheme *runtime.Scheme
Namespace string
PlatformName util.PlatformType
}

// Gatekeeper Operator RBAC permissions to manager Gatekeeper custom resource
Expand Down Expand Up @@ -127,15 +128,6 @@ func (r *GatekeeperReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error)
logger := r.Log.WithValues("gatekeeper", req.NamespacedName)
logger.Info("Reconciling Gatekeeper")

cfg, err := config.GetConfig()
if err != nil {
return ctrl.Result{}, err
}
platformName, err := openshift.GetPlatformName(cfg)
if err != nil {
return ctrl.Result{}, err
}

if req.Name != defaultGatekeeperCrName {
err := fmt.Errorf("Gatekeeper resource name must be '%s'", defaultGatekeeperCrName)
logger.Error(err, "Invalid Gatekeeper resource name")
Expand All @@ -144,7 +136,7 @@ func (r *GatekeeperReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error)
}

gatekeeper := &operatorv1alpha1.Gatekeeper{}
err = r.Get(ctx, req.NamespacedName, gatekeeper)
err := r.Get(ctx, req.NamespacedName, gatekeeper)
if err != nil {
if apierrors.IsNotFound(err) {

Expand All @@ -154,7 +146,7 @@ func (r *GatekeeperReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error)
return ctrl.Result{}, err
}

err = r.deployGatekeeperResources(gatekeeper, platformName)
err = r.deployGatekeeperResources(gatekeeper)
if err != nil {
return ctrl.Result{}, errors.Wrap(err, "Unable to deploy Gatekeeper resources")
}
Expand All @@ -180,16 +172,24 @@ func (r *GatekeeperReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}

func (r *GatekeeperReconciler) deployGatekeeperResources(gatekeeper *operatorv1alpha1.Gatekeeper, platformName string) error {
func (r *GatekeeperReconciler) deployGatekeeperResources(gatekeeper *operatorv1alpha1.Gatekeeper) error {
for _, a := range getStaticAssets(gatekeeper) {
if a == RoleFile && platformName == "OpenShift" {
// Handle special cases in switch below.
switch {
case a == NamespaceFile && !r.isOpenShift():
// Ignore the namespace resource on Kubernetes as we default to use
// the same namespace as the operator, which by definition is
// already created as a result of executing this code.
continue
case a == RoleFile && r.isOpenShift():
a = openshiftAssetsDir + a
}

manifest, err := util.GetManifest(a)
if err != nil {
return err
}
if err = crOverrides(gatekeeper, a, manifest, r.Namespace, (platformName == "OpenShift")); err != nil {
if err = crOverrides(gatekeeper, a, manifest, r.Namespace, r.isOpenShift()); err != nil {
return err
}

Expand Down Expand Up @@ -262,6 +262,10 @@ func (r *GatekeeperReconciler) updateOrCreateResource(manifest *manifest.Manifes
return err
}

func (r *GatekeeperReconciler) isOpenShift() bool {
return util.IsOpenShift(r.PlatformName)
}

var commonSpecOverridesFn = []func(*unstructured.Unstructured, operatorv1alpha1.GatekeeperSpec) error{
setAffinity,
setNodeSelector,
Expand All @@ -275,8 +279,12 @@ var commonContainerOverridesFn = []func(map[string]interface{}, operatorv1alpha1

// crOverrides
func crOverrides(gatekeeper *operatorv1alpha1.Gatekeeper, asset string, manifest *manifest.Manifest, namespace string, isOpenshift bool) error {
// set current namespace
if err := setCurrentNamespace(manifest.Obj, asset, namespace); err != nil {
if asset == NamespaceFile {
manifest.Obj.SetName(namespace)
return nil
}
// set resource's namespace
if err := setNamespace(manifest.Obj, asset, namespace); err != nil {
return err
}
// audit overrides
Expand Down Expand Up @@ -597,7 +605,7 @@ func setContainerArg(obj *unstructured.Unstructured, containerName, argName stri
})
}

func setCurrentNamespace(obj *unstructured.Unstructured, asset, namespace string) error {
func setNamespace(obj *unstructured.Unstructured, asset, namespace string) error {
if obj.GetNamespace() != "" {
obj.SetNamespace(namespace)
}
Expand Down
60 changes: 35 additions & 25 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package main

import (
"flag"
"fmt"
"os"

"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -28,8 +27,11 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/RHsyseng/operator-utils/pkg/utils/openshift"
operatorv1alpha1 "github.com/gatekeeper/gatekeeper-operator/api/v1alpha1"
"github.com/gatekeeper/gatekeeper-operator/controllers"
"github.com/gatekeeper/gatekeeper-operator/pkg/util"
"github.com/pkg/errors"
// +kubebuilder:scaffold:imports
)

Expand All @@ -56,30 +58,37 @@ func main() {

ctrl.SetLogger(zap.New(zap.UseDevMode(true)))

watchNamespace, err := getWatchNamespace()
if err != nil {
setupLog.Error(err, "unable to get WatchNamespace, ")
os.Exit(1)
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
cfg := ctrl.GetConfigOrDie()
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443,
LeaderElection: enableLeaderElection,
LeaderElectionID: "6ccdc528.gatekeeper.sh",
Namespace: watchNamespace, // namespaced-scope when the value is not an empty string
})
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}

platformName, err := openshift.GetPlatformName(cfg)
if err != nil {
setupLog.Error(err, "unable to get platform name")
os.Exit(1)
}

namespace, err := gatekeeperNamespace(platformName)
if err != nil {
setupLog.Error(err, "unable to get Gatekeeper namespace")
os.Exit(1)
}

if err = (&controllers.GatekeeperReconciler{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("Gatekeeper"),
Scheme: mgr.GetScheme(),
Namespace: watchNamespace,
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("Gatekeeper"),
Scheme: mgr.GetScheme(),
Namespace: namespace,
PlatformName: util.PlatformType(platformName),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Gatekeeper")
os.Exit(1)
Expand All @@ -93,17 +102,18 @@ func main() {
}
}

// getWatchNamespace returns the Namespace the operator should be watching for
// changes.
func getWatchNamespace() (string, error) {
// WatchNamespaceEnvVar is the constant for env variable WATCH_NAMESPACE
// which specifies the Namespace to watch. An empty value means the
// operator is running with cluster scope.
var watchNamespaceEnvVar = "WATCH_NAMESPACE"

ns, found := os.LookupEnv(watchNamespaceEnvVar)
if !found {
return "", fmt.Errorf("%s must be set", watchNamespaceEnvVar)
func gatekeeperNamespace(platformName string) (string, error) {
ns, err := util.GetOperatorNamespace()
if err != nil {
return "", errors.Wrapf(err, "Failed to get operator namespace")
}

switch util.PlatformType(platformName) {
case util.OpenShift:
return util.GetPlatformNamespace(platformName), nil
case util.Kubernetes:
fallthrough
default:
return ns, nil
}
return ns, nil
}
Loading

0 comments on commit 0d05b51

Please sign in to comment.