Skip to content

Commit

Permalink
Remove operator roles (#2530)
Browse files Browse the repository at this point in the history
* remove the concept of operator roles as flags
* remove the global operator manifests 
* keep/modify the namespace operator manifests to allow deployments restricted to one or more namespaces
* allow the parameterization of the operator name to allow multiple (namespaced) operators to be deployed in a single namespace
* make the operator logs target work for both variants
* run the e2e tests with a all-in-one operator
* add a dedicated webhook toggle flag
* disable the webhook by default in the namespaced variant, enable it in the all-in-one variant
* Remove duplicated word

Co-authored-by: Michael Morello <michael.morello@gmail.com>
  • Loading branch information
pebrc and barkbay authored Feb 13, 2020
1 parent 96cd36f commit 3819530
Show file tree
Hide file tree
Showing 35 changed files with 223 additions and 889 deletions.
43 changes: 19 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ SKIP_DOCKER_COMMAND ?= false

## -- Namespaces

# namespace in which the global operator is deployed (see config/global-operator)
GLOBAL_OPERATOR_NAMESPACE ?= elastic-system
# namespace in which the namespace operator is deployed (see config/namespace-operator)
NAMESPACE_OPERATOR_NAMESPACE ?= elastic-namespace-operators
# comma separated list of namespaces in which the namespace operator should watch resources
# namespace in which the operator is deployed (see config/operator)
OPERATOR_NAMESPACE ?= elastic-system
# name of the operator statefulset and related resources
OPERATOR_NAME ?= elastic-operator
# comma separated list of namespaces in which the operator should watch resources
MANAGED_NAMESPACES ?=

## -- Security
Expand Down Expand Up @@ -150,13 +150,13 @@ install-crds: generate-crds
run: install-crds go-run

go-run:
# Run the operator locally with role All, with debug logs, operator image set to latest and operator namespace for a global operator
# Run the operator locally with debug logs and operator image set to latest
AUTO_PORT_FORWARD=true \
go run \
-ldflags "$(GO_LDFLAGS)" \
-tags "$(GO_TAGS)" \
./cmd/main.go manager \
--development --operator-roles=global,namespace \
--development \
--log-verbosity=$(LOG_VERBOSITY) \
--ca-cert-validity=10h --ca-cert-rotate-before=1h \
--operator-namespace=default \
Expand All @@ -169,7 +169,6 @@ go-debug:
-- \
manager \
--development \
--operator-roles=global,namespace \
--log-verbosity=$(LOG_VERBOSITY) \
--ca-cert-validity=10h \
--ca-cert-rotate-before=1h \
Expand All @@ -190,16 +189,14 @@ ifndef GCLOUD_PROJECT
endif
endif

# Deploy both the global and namespace operators against the current k8s cluster
deploy: check-gke install-crds build-operator-image apply-operators
# Deploy the operator against the current k8s cluster
deploy: check-gke install-crds build-operator-image apply-operator

apply-operators:
apply-operator:
OPERATOR_IMAGE=$(OPERATOR_IMAGE) \
NAMESPACE=$(GLOBAL_OPERATOR_NAMESPACE) \
$(MAKE) --no-print-directory -sC config/operator generate-global | kubectl apply -f -
OPERATOR_IMAGE=$(OPERATOR_IMAGE) \
NAMESPACE=$(NAMESPACE_OPERATOR_NAMESPACE) \
MANAGED_NAMESPACE=$(MANAGED_NAMESPACE) \
OPERATOR_NAME=$(OPERATOR_NAME) \
NAMESPACE=$(OPERATOR_NAMESPACE) \
MANAGED_NAMESPACES=$(MANAGED_NAMESPACES) \
$(MAKE) --no-print-directory -sC config/operator generate-namespace | kubectl apply -f -

apply-psp:
Expand All @@ -211,19 +208,17 @@ ALL_IN_ONE_OUTPUT_FILE=config/all-in-one.yaml
generate-all-in-one:
cp -f $(ALL_CRDS) $(ALL_IN_ONE_OUTPUT_FILE)
OPERATOR_IMAGE=$(OPERATOR_IMAGE) \
NAMESPACE=$(GLOBAL_OPERATOR_NAMESPACE) \
OPERATOR_NAME=$(OPERATOR_NAME) \
NAMESPACE=$(OPERATOR_NAMESPACE) \
$(MAKE) --no-print-directory -sC config/operator generate-all-in-one >> $(ALL_IN_ONE_OUTPUT_FILE)

# Deploy an all in one operator against the current k8s cluster
deploy-all-in-one: GO_TAGS ?= release
deploy-all-in-one: docker-build docker-push
kubectl apply -f $(ALL_IN_ONE_OUTPUT_FILE)

logs-namespace-operator:
@ kubectl --namespace=$(NAMESPACE_OPERATOR_NAMESPACE) logs -f statefulset.apps/elastic-namespace-operator

logs-global-operator:
@ kubectl --namespace=$(GLOBAL_OPERATOR_NAMESPACE) logs -f statefulset.apps/elastic-global-operator
logs-operator:
@ kubectl --namespace=$(OPERATOR_NAMESPACE) logs -f statefulset.apps/$(OPERATOR_NAME)

samples:
@ echo "-> Pushing samples to Kubernetes cluster..."
Expand All @@ -242,7 +237,7 @@ cluster-bootstrap: install-crds

clean-k8s-cluster:
kubectl delete --ignore-not-found=true ValidatingWebhookConfiguration validating-webhook-configuration
for ns in $(NAMESPACE_OPERATOR_NAMESPACE) $(GLOBAL_OPERATOR_NAMESPACE) $(MANAGED_NAMESPACE); do \
for ns in $(OPERATOR_NAMESPACE) $(MANAGED_NAMESPACES); do \
echo "Deleting resources in $$ns"; \
kubectl delete statefulsets -n $$ns --all; \
kubectl delete deployments -n $$ns --all; \
Expand Down Expand Up @@ -474,7 +469,7 @@ kind-with-operator-%: kind-node-variable-check docker-build
./hack/kind/kind.sh \
--load-images $(OPERATOR_IMAGE) \
--nodes "${*}" \
make install-crds apply-operators
make install-crds apply-operator

## Run all the e2e tests in a Kind cluster
set-kind-e2e-image:
Expand Down
100 changes: 45 additions & 55 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ func init() {
operator.EnableTracingFlag,
false,
"Enable APM tracing in the operator. Endpoint, token etc are to be configured via environment variables. See https://www.elastic.co/guide/en/apm/agent/go/1.x/configuration.html")
Cmd.Flags().Bool(
operator.EnableWebhookFlag,
false,
"Enables a validating webhook server in the operator process.",
)
Cmd.Flags().Bool(
operator.ManageWebhookCertsFlag,
true,
Expand All @@ -142,11 +147,6 @@ func init() {
"",
"K8s namespace the operator runs in",
)
Cmd.Flags().StringSlice(
operator.OperatorRolesFlag,
[]string{operator.All},
"Roles this operator should assume (either namespace, global, webhook or all)",
)
Cmd.Flags().String(
operator.WebhookCertDirFlag,
// this is controller-runtime's own default, copied here for making the default explicit when using `--help`
Expand Down Expand Up @@ -268,27 +268,19 @@ func execute() {
caCertValidity, caCertRotateBefore := ValidateCertExpirationFlags(operator.CACertValidityFlag, operator.CACertRotateBeforeFlag)
certValidity, certRotateBefore := ValidateCertExpirationFlags(operator.CertValidityFlag, operator.CertRotateBeforeFlag)

// Setup all Controllers
roles := viper.GetStringSlice(operator.OperatorRolesFlag)
err = operator.ValidateRoles(roles)
if err != nil {
log.Error(err, "invalid roles specified")
os.Exit(1)
}

// Setup a client to set the operator uuid config map
clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
log.Error(err, "unable to create k8s clientset")
os.Exit(1)
}

operatorInfo, err := about.GetOperatorInfo(clientset, operatorNamespace, roles)
operatorInfo, err := about.GetOperatorInfo(clientset, operatorNamespace)
if err != nil {
log.Error(err, "unable to get operator info")
os.Exit(1)
}
log.Info("Setting up controllers", "roles", roles)
log.Info("Setting up controllers")
var tracer *apm.Tracer
if viper.GetBool(operator.EnableTracingFlag) {
tracer = tracing.NewTracer("elastic-operator")
Expand All @@ -308,7 +300,7 @@ func execute() {
Tracer: tracer,
}

if operator.HasRole(operator.WebhookServer, roles) {
if viper.GetBool(operator.EnableWebhookFlag) {
setupWebhook(mgr, params.CertRotation, clientset)
}

Expand All @@ -321,48 +313,46 @@ func execute() {
accessReviewer = rbac.NewPermissiveAccessReviewer()
}

if operator.HasRole(operator.NamespaceOperator, roles) {
if err = apmserver.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "ApmServer")
os.Exit(1)
}
if err = elasticsearch.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "Elasticsearch")
os.Exit(1)
}
if err = kibana.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "Kibana")
os.Exit(1)
}
if err = asesassn.Add(mgr, accessReviewer, params); err != nil {
log.Error(err, "unable to create controller", "controller", "ApmServerElasticsearchAssociation")
os.Exit(1)
}
if err = kbassn.Add(mgr, accessReviewer, params); err != nil {
log.Error(err, "unable to create controller", "controller", "KibanaAssociation")
os.Exit(1)
}

// Garbage collect any orphaned user Secrets leftover from deleted resources while the operator was not running.
garbageCollectUsers(cfg, managedNamespaces)
if err = apmserver.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "ApmServer")
os.Exit(1)
}
if err = elasticsearch.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "Elasticsearch")
os.Exit(1)
}
if err = kibana.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "Kibana")
os.Exit(1)
}
if err = asesassn.Add(mgr, accessReviewer, params); err != nil {
log.Error(err, "unable to create controller", "controller", "ApmServerElasticsearchAssociation")
os.Exit(1)
}
if err = kbassn.Add(mgr, accessReviewer, params); err != nil {
log.Error(err, "unable to create controller", "controller", "KibanaAssociation")
os.Exit(1)
}
if operator.HasRole(operator.GlobalOperator, roles) {
if err = license.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "License")
os.Exit(1)
}
if err = licensetrial.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "LicenseTrial")
os.Exit(1)
}

go func() {
time.Sleep(10 * time.Second) // wait some arbitrary time for the manager to start
mgr.GetCache().WaitForCacheSync(nil) // wait until k8s client cache is initialized
r := licensing.NewResourceReporter(mgr.GetClient())
r.Start(operatorNamespace, licensing.ResourceReporterFrequency)
}()
if err = license.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "License")
os.Exit(1)
}
if err = licensetrial.Add(mgr, params); err != nil {
log.Error(err, "unable to create controller", "controller", "LicenseTrial")
os.Exit(1)
}

// Garbage collect any orphaned user Secrets leftover from deleted resources while the operator was not running.
garbageCollectUsers(cfg, managedNamespaces)

go func() {
time.Sleep(10 * time.Second) // wait some arbitrary time for the manager to start
mgr.GetCache().WaitForCacheSync(nil) // wait until k8s client cache is initialized
r := licensing.NewResourceReporter(mgr.GetClient())
r.Start(operatorNamespace, licensing.ResourceReporterFrequency)
}()

log.Info("Starting the manager", "uuid", operatorInfo.OperatorUUID,
"namespace", operatorNamespace, "version", operatorInfo.BuildInfo.Version,
"build_hash", operatorInfo.BuildInfo.Hash, "build_date", operatorInfo.BuildInfo.Date,
Expand Down
2 changes: 1 addition & 1 deletion config/e2e/managed_namespaces.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{- $testRun := .TestRun -}}
{{- range .NamespaceOperator.ManagedNamespaces }}
{{- range .Operator.ManagedNamespaces }}
---
apiVersion: v1
kind: Namespace
Expand Down
Loading

0 comments on commit 3819530

Please sign in to comment.