Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

Make default operator configuration configurable not hardcoded #49

Merged
merged 8 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
./scripts

# Binaries for programs and plugins
*.exe
*.exe~
Expand Down Expand Up @@ -27,4 +25,5 @@ Dockerfile.cross
*.swo
*~
.vscode/
.scripts/
.DS_Store
16 changes: 12 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ IMG ?= $(IMAGE_TAG_BASE):v$(VERSION)
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.25.0

# Default Backstage config directory to use
# it has to be defined as a set of YAML files inside ./config/manager/${CONF_DIR} directory
# to use other config - add a directory with config and run 'CONF_DIR=<dir-name> make ...'
# TODO find better place than ./config/manager (but not ./config/overlays) ?
# TODO it works only for make run, needs supporting make deploy as well https://github.com/janus-idp/operator/issues/47
CONF_DIR ?= default-config

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
Expand Down Expand Up @@ -124,8 +131,9 @@ vet: ## Run go vet against code.
go vet ./...

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out
test: manifests generate fmt vet envtest ## Run tests. We need LOCALBIN=$(LOCALBIN) to get correct default-config path
mkdir -p $(LOCALBIN)/default-config && cp config/manager/${CONF_DIR}/* $(LOCALBIN)/default-config
LOCALBIN=$(LOCALBIN) KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out

##@ Build

Expand All @@ -134,8 +142,8 @@ build: generate fmt vet ## Build manager binary.
go build -o bin/manager main.go

.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go
run: manifests generate fmt vet build ## Run a controller from your host.
cd $(LOCALBIN) && mkdir -p default-config && cp ../config/manager/${CONF_DIR}/* default-config && ./manager

PLATFORM ?= linux/amd64
# If you wish built the manager image targeting other platforms you can use the --platform flag.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ spec:
app.kubernetes.io/created-by: backstage-operator
app.kubernetes.io/instance: controller-manager
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: deployment
app.kubernetes.io/name: deployment.yaml
app.kubernetes.io/part-of: backstage-operator
control-plane: controller-manager
name: backstage-operator-controller-manager
Expand Down Expand Up @@ -240,7 +240,7 @@ spec:
- create
- patch
serviceAccountName: backstage-operator-controller-manager
strategy: deployment
strategy: deployment.yaml
gazarenkov marked this conversation as resolved.
Show resolved Hide resolved
installModes:
- supported: false
type: OwnNamespace
Expand Down
4 changes: 2 additions & 2 deletions config/default/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Adds namespace to all resources.
namespace: backstage-operator-system
namespace: backstage-system

# Value of this field is prepended to the
# names of all resources, e.g. a deployment named
# "wordpress" becomes "alices-wordpress".
# Note that it should also match with the prefix (text before '-') of the namespace
# field above.
namePrefix: backstage-operator-
namePrefix: backstage-

# Labels to add to all resources and selectors.
#commonLabels:
Expand Down
30 changes: 30 additions & 0 deletions config/manager/default-config/db-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
backstage.io/app: # placeholder for 'backstage-db-<cr-name>'
template:
metadata:
labels:
backstage.io/app: # placeholder for 'backstage-db-<cr-name>'
spec:
containers:
- name: postgres
image: postgres:13.2-alpine
imagePullPolicy: 'IfNotPresent'
ports:
- containerPort: 5432
envFrom:
- secretRef:
name: postgres-secrets
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgresdb
volumes:
- name: postgresdb
persistentVolumeClaim:
claimName: postgres-storage-claim
16 changes: 16 additions & 0 deletions config/manager/default-config/db-pv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-storage
namespace: backstage
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 2G
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: '/mnt/data'
11 changes: 11 additions & 0 deletions config/manager/default-config/db-pvc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-storage-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2G
9 changes: 9 additions & 0 deletions config/manager/default-config/db-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
selector:
backstage.io/app: # placeholder for 'backstage-db-<cr-name>'
ports:
- port: 5432
28 changes: 28 additions & 0 deletions config/manager/default-config/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: backstage
spec:
replicas: 1
selector:
matchLabels:
backstage.io/app: # placeholder for 'backstage-<cr-name>'
template:
metadata:
labels:
backstage.io/app: # placeholder for 'backstage-<cr-name>'
spec:
containers:
- name: backstage
image: ghcr.io/backstage/backstage
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 7007
envFrom:
- secretRef:
name: postgres-secrets
# - secretRef:
# name: backstage-secrets


12 changes: 12 additions & 0 deletions config/manager/default-config/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: backstage
spec:
type: NodePort
selector:
backstage.io/app: # placeholder for 'backstage-<cr-name>'
ports:
- name: http
port: 80
targetPort: http
16 changes: 14 additions & 2 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,17 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: controller
newName: quay.io/rhdh/backstage-operator
newTag: v0.0.1
newName: gazarenkov/backstage
gazarenkov marked this conversation as resolved.
Show resolved Hide resolved

generatorOptions:
disableNameSuffixHash: true

configMapGenerator:
- files:
- default-config/deployment.yaml
- default-config/service.yaml
- default-config/db-deployment.yaml
gazarenkov marked this conversation as resolved.
Show resolved Hide resolved
- default-config/db-service.yaml
- default-config/db-pv.yaml
- default-config/db-pvc.yaml
name: default-config
8 changes: 8 additions & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,13 @@ spec:
requests:
cpu: 10m
memory: 64Mi
volumeMounts:
- mountPath: /default-config
name: default-config
serviceAccountName: controller-manager
terminationGracePeriodSeconds: 10
volumes:
- name: default-config
configMap:
name: default-config

2 changes: 1 addition & 1 deletion config/rbac/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
resources:
# All RBAC will be applied under this service account in
# the deployment namespace. You may comment out this resource
# the deployment.yaml namespace. You may comment out this resource
gazarenkov marked this conversation as resolved.
Show resolved Hide resolved
# if your manager will use a service account that exists at
# runtime. Be sure to update RoleBinding and ClusterRoleBinding
# subjects if changing service account names.
Expand Down
62 changes: 35 additions & 27 deletions controllers/backstage_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"bytes"
"context"
"fmt"
"os"
"path/filepath"

bs "backstage.io/backstage-operator/api/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
Expand All @@ -42,7 +44,7 @@ type BackstageReconciler struct {
client.Client
Scheme *runtime.Scheme
// If true, Backstage Controller always sync the state of runtime objects created
// otherwise, the can be re-configured independently
// otherwise, runtime objects can be re-configured independently
OwnsRuntime bool

// Namespace allows to restrict the reconciliation to this particular namespace,
Expand Down Expand Up @@ -90,63 +92,55 @@ func (r *BackstageReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
if !backstage.Spec.SkipLocalDb {
// log Debug
if err := r.applyPV(ctx, backstage, req.Namespace); err != nil {
//backstage.Status.LocalDb.PersistentVolume.Status = err.Error()
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("failed to apply Database PV: %w", err)
}

if err := r.applyPVC(ctx, backstage, req.Namespace); err != nil {
//backstage.Status.PostgreState = err.Error()
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("failed to apply Database PVC: %w", err)
}

err := r.applyLocalDbDeployment(ctx, backstage, req.Namespace)
if err != nil {
//backstage.Status.PostgreState = err.Error()
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("failed to apply Database Deployment: %w", err)
}

err = r.applyLocalDbService(ctx, backstage, req.Namespace)
if err != nil {
//backstage.Status.PostgreState = err.Error()
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("failed to apply Database Service: %w", err)
}

}

err := r.applyBackstageDeployment(ctx, backstage, req.Namespace)
if err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("failed to apply Backstage Deployment: %w", err)
}

if err := r.applyBackstageService(ctx, backstage, req.Namespace); err != nil {
// TODO BackstageDepState state
//backstage.Status.BackstageState = err.Error()
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("failed to apply Backstage Service: %w", err)
}

//TODO: it is just a placeholder for the time
r.setRunningStatus(ctx, &backstage, req.Namespace)
r.setSyncStatus(&backstage)
err = r.Status().Update(ctx, &backstage)
if err != nil {
return ctrl.Result{}, err
return ctrl.Result{}, fmt.Errorf("failed to set status: %w", err)
//log.FromContext(ctx).Error(err, "unable to update backstage.status")
}

return ctrl.Result{}, nil
}

func (r *BackstageReconciler) readConfigMapOrDefault(ctx context.Context, name string, key string, ns string, def string, object v1.Object) error {
func (r *BackstageReconciler) readConfigMapOrDefault(ctx context.Context, name string, key string, ns string, object v1.Object) error {

// ConfigMap name not set, default
//lg := log.FromContext(ctx)

//lg.V(1).Info("readConfigMapOrDefault CM: ", "name", name)

if name == "" {
err := readYaml(def, object)
err := readYamlFile(defFile(key), object)
gazarenkov marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
return fmt.Errorf("failed to read YAML file: %w", err)
}
object.SetNamespace(ns)
return nil
Expand All @@ -156,34 +150,48 @@ func (r *BackstageReconciler) readConfigMapOrDefault(ctx context.Context, name s
if err := r.Get(ctx, types.NamespacedName{Name: name, Namespace: ns}, &cm); err != nil {
return err
}
//lg.V(1).Info("readConfigMapOrDefault CM name found: ", "ConfigMap:", cm)

val, ok := cm.Data[key]
if !ok {
// key not found, default
err := readYaml(def, object)
err := readYamlFile(defFile(key), object)
if err != nil {
return err
return fmt.Errorf("failed to read YAML file: %w", err)
}
} else {
err := readYaml(val, object)
err := readYaml([]byte(val), object)
if err != nil {
return err
return fmt.Errorf("failed to read YAML: %w", err)
}
}
object.SetNamespace(ns)
return nil
}

func readYaml(manifest string, object interface{}) error {
dec := yaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(manifest)), 1000)
func readYaml(manifest []byte, object interface{}) error {
dec := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(manifest), 1000)
if err := dec.Decode(object); err != nil {
return err
return fmt.Errorf("failed to decode YAML: %w", err)
}
return nil
}

func readYamlFile(path string, object interface{}) error {

b, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read YAML file: %w", err)
}
return readYaml(b, object)
}

func defFile(key string) string {
return filepath.Join(os.Getenv("LOCALBIN"), "default-config", key)
gazarenkov marked this conversation as resolved.
Show resolved Hide resolved
}

// sets the RuntimeRunning condition
func (r *BackstageReconciler) setRunningStatus(ctx context.Context, backstage *bs.Backstage, ns string) {

meta.SetStatusCondition(&backstage.Status.Conditions, v1.Condition{
Type: bs.RuntimeConditionRunning,
Status: "Unknown",
Expand Down
Loading