From d0412d9a0d8529a445f95237469b2c6eb2614f12 Mon Sep 17 00:00:00 2001 From: Mihai Turdean <6640685+mihai-turdean@users.noreply.github.com> Date: Thu, 28 Aug 2025 11:38:47 -0600 Subject: [PATCH] Simplify local development config for iam-app-operator (#110164) --- apps/iam/.gitignore | 2 + apps/iam/Makefile | 30 +-------------- apps/iam/Tiltfile | 16 ++++++++ apps/iam/cmd/operator/config.go | 6 +-- apps/iam/local/Tiltfile | 57 ---------------------------- apps/iam/local/k3d-config.json | 16 -------- apps/iam/local/scripts/cluster.sh | 43 --------------------- apps/iam/local/scripts/push_image.sh | 12 ------ apps/iam/local/yamls/operator.yaml | 25 +++++++++--- apps/iam/local/yamls/zanzana.yaml | 44 +++++++++++++-------- apps/iam/pkg/app/app.go | 14 ++++--- 11 files changed, 79 insertions(+), 186 deletions(-) create mode 100644 apps/iam/.gitignore create mode 100644 apps/iam/Tiltfile delete mode 100644 apps/iam/local/Tiltfile delete mode 100644 apps/iam/local/k3d-config.json delete mode 100755 apps/iam/local/scripts/cluster.sh delete mode 100755 apps/iam/local/scripts/push_image.sh diff --git a/apps/iam/.gitignore b/apps/iam/.gitignore new file mode 100644 index 00000000000..b7ebb479073 --- /dev/null +++ b/apps/iam/.gitignore @@ -0,0 +1,2 @@ +# Local development overrides +local/yamls/iam-secrets.yaml diff --git a/apps/iam/Makefile b/apps/iam/Makefile index 04746e30a31..71b00aca821 100644 --- a/apps/iam/Makefile +++ b/apps/iam/Makefile @@ -1,7 +1,5 @@ include ../sdk.mk -OPERATOR_DOCKERIMAGE := "github.com/grafana/grafana/apps/iam/operator" - .PHONY: generate generate: install-app-sdk update-app-sdk ## Run Grafana App SDK code generation @$(APP_SDK_BIN) generate \ @@ -17,17 +15,9 @@ deps: @go mod tidy @GOWORK=off go mod vendor -.PHONY: build -build: build/operator - -.PHONY: build/operator -build/operator: - docker build -t $(OPERATOR_DOCKERIMAGE) -f cmd/operator/Dockerfile . - .PHONY: local/up local/up: - @./local/scripts/cluster.sh create "local/k3d-config.json" - @cd local && tilt up + @tilt up .PHONY: local/generate local/generate: @@ -35,20 +25,4 @@ local/generate: .PHONY: local/down local/down: - @cd local && tilt down - -.PHONY: local/deploy_plugin -local/deploy_plugin: - -tilt disable grafana - cp -R plugin/dist local/mounted-files/plugin/dist - -tilt enable grafana - -.PHONY: local/push_operator -local/push_operator: build/operator - # Tag the docker image as part of localhost, which is what the generated k8s uses to avoid confusion with the real operator image - @docker tag "$(OPERATOR_DOCKERIMAGE):latest" "localhost/$(OPERATOR_DOCKERIMAGE):latest" - @./local/scripts/push_image.sh "localhost/$(OPERATOR_DOCKERIMAGE):latest" - -.PHONY: local/clean -local/clean: local/down - @./local/scripts/cluster.sh delete + @tilt down diff --git a/apps/iam/Tiltfile b/apps/iam/Tiltfile new file mode 100644 index 00000000000..f72dd50552a --- /dev/null +++ b/apps/iam/Tiltfile @@ -0,0 +1,16 @@ + +# version_settings() enforces a minimum Tilt version +# https://docs.tilt.dev/api.html#api.version_settings +version_settings(constraint='>=0.22.2') + +custom_build( + 'grafana-iam-operator', + command='docker build -t $EXPECTED_REF -f cmd/operator/Dockerfile .', + deps=[ + 'cmd/operator', + 'pkg', + ], + disable_push=True, +) + +k8s_yaml([filename for filename in listdir('local/yamls') if filename.lower().endswith(('.yaml', '.yml'))]) diff --git a/apps/iam/cmd/operator/config.go b/apps/iam/cmd/operator/config.go index 939399699c5..0794b3fd496 100644 --- a/apps/iam/cmd/operator/config.go +++ b/apps/iam/cmd/operator/config.go @@ -89,11 +89,11 @@ func LoadConfigFromEnv() (*Config, error) { } cfg.KubeConfig = kubeConfig } else if folderAppURL := os.Getenv("FOLDER_APP_URL"); folderAppURL != "" { - exchangeUrl := os.Getenv("AUTH_TOKEN_EXCHANGE_URL") + exchangeUrl := os.Getenv("TOKEN_EXCHANGE_URL") authToken := os.Getenv("AUTH_TOKEN") namespace := os.Getenv("FOLDER_APP_NAMESPACE") if exchangeUrl == "" || authToken == "" { - return nil, fmt.Errorf("AUTH_TOKEN_EXCHANGE_URL and AUTH_TOKEN must be set when FOLDER_APP_URL is set") + return nil, fmt.Errorf("TOKEN_EXCHANGE_URL and AUTH_TOKEN must be set when FOLDER_APP_URL is set") } kubeConfig, err := LoadKubeConfigFromFolderAppURL(folderAppURL, exchangeUrl, authToken, namespace) @@ -111,7 +111,7 @@ func LoadConfigFromEnv() (*Config, error) { cfg.ZanzanaClient.Address = os.Getenv("ZANZANA_ADDR") cfg.ZanzanaClient.Token = os.Getenv("ZANZANA_TOKEN") - cfg.ZanzanaClient.TokenExchangeURL = os.Getenv("ZANZANA_TOKEN_EXCHANGE_URL") + cfg.ZanzanaClient.TokenExchangeURL = os.Getenv("TOKEN_EXCHANGE_URL") cfg.ZanzanaClient.ServerCertFile = os.Getenv("ZANZANA_SERVER_CERT_FILE") cfg.FolderReconciler.Namespace = os.Getenv("FOLDER_RECONCILER_NAMESPACE") diff --git a/apps/iam/local/Tiltfile b/apps/iam/local/Tiltfile deleted file mode 100644 index 6c53501d811..00000000000 --- a/apps/iam/local/Tiltfile +++ /dev/null @@ -1,57 +0,0 @@ - -# version_settings() enforces a minimum Tilt version -# https://docs.tilt.dev/api.html#api.version_settings -version_settings(constraint='>=0.22.2') - -def name(c): - return c['metadata']['name'] - -def namespace(c): - if 'namespace' in c['metadata']: - return c['metadata']['namespace'] - return '' - -def decode(yaml): - resources = decode_yaml_stream(yaml) - - # workaround a bug in decode_yaml_stream where it returns duplicates - # This bug has been fixed in Tilt v0.17.3+ - filtered = [] - names = {} - for r in resources: - if r == None: - continue - - n = '%s:%s:%s' % (name(r), r['kind'], namespace(r)) - if n in names: - continue - - names[n] = True - filtered.append(r) - - return filtered - -def find_overlapping(o, yamls): - for elem in yamls: - if name(o) == name(elem) and o['kind'] == elem['kind'] and namespace(o) == namespace(elem): - return elem - return None - -yaml_objects = [] -# Parse all YAML files in our "yamls" directory -for filename in listdir('yamls'): - if filename.lower().endswith(('.yaml', '.yml')): - decoded = decode(read_file(filename)) - for o in decoded: - present = find_overlapping(o, yaml_objects) - if present != None: - print("Overlapping resource found: %s", filename) - exit(1) - yaml_objects += decoded - -bundle = encode_yaml_stream(yaml_objects) - -# k8s_yaml automatically creates resources in Tilt for the entities -# and will inject any images referenced in the Tiltfile when deploying -# https://docs.tilt.dev/api.html#api.k8s_yaml -k8s_yaml(bundle) diff --git a/apps/iam/local/k3d-config.json b/apps/iam/local/k3d-config.json deleted file mode 100644 index 224d6026fc7..00000000000 --- a/apps/iam/local/k3d-config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "apiVersion": "k3d.io/v1alpha3", - "kind": "Simple", - "kubeAPI": { - "hostPort": "8556" - }, - "options": { - "k3d": { - "wait": true - }, - "kubeconfig": { - "switchCurrentContext": true, - "updateDefaultKubeconfig": true - } - } -} diff --git a/apps/iam/local/scripts/cluster.sh b/apps/iam/local/scripts/cluster.sh deleted file mode 100755 index 1edf4502d9c..00000000000 --- a/apps/iam/local/scripts/cluster.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -set -eufo pipefail - -CLUSTER_NAME="grafana-iam-operator" - -create_cluster() { - K3D_CONFIG="${1:-k3d-config.json}" - - if ! k3d cluster list "${CLUSTER_NAME}" >/dev/null 2>&1; then - # Array of extra options to add to the k3d cluster create command - EXTRA_K3D_OPTS=() - - # Bug in k3d for btrfs filesystems workaround, see https://k3d.io/v5.2.2/faq/faq/#issues-with-btrfs - # Apple is APFS/HFS and stat has a different API, so we might as well skip that - if [[ "${OSTYPE}" != "darwin*" ]]; then - ROOTFS="$(stat -f --format="%T" "/")" - if [[ "${ROOTFS}" == "btrfs" ]]; then - EXTRA_K3D_OPTS+=("-v" "/dev/mapper:/dev/mapper") - fi - fi - - k3d cluster create "${CLUSTER_NAME}" --config "${K3D_CONFIG}" ${EXTRA_K3D_OPTS[@]+"${EXTRA_K3D_OPTS[@]}"} - else - echo "Cluster already exists" - fi -} - -delete_cluster() { - k3d cluster delete "${CLUSTER_NAME}" -} - -if [ $# -lt 1 ]; then - echo "Usage: ./cluster.sh [create|delete]" - exit 1 -fi - -if [ $1 == "create" ]; then - create_cluster $2 -elif [ $1 == "delete" ]; then - delete_cluster -else - echo "Unknown argument ${1}" -fi diff --git a/apps/iam/local/scripts/push_image.sh b/apps/iam/local/scripts/push_image.sh deleted file mode 100755 index 33257688764..00000000000 --- a/apps/iam/local/scripts/push_image.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash -set -eufo pipefail - -CLUSTER_NAME="grafana-iam-operator" -IMAGE="$1" - -if [[ "$IMAGE" == "" ]]; then - echo "usage: push_image.sh " - exit 1 -fi - -k3d image import "${IMAGE}" -c "${CLUSTER_NAME}" \ No newline at end of file diff --git a/apps/iam/local/yamls/operator.yaml b/apps/iam/local/yamls/operator.yaml index 58fb79c68a5..4ef08bc7d19 100644 --- a/apps/iam/local/yamls/operator.yaml +++ b/apps/iam/local/yamls/operator.yaml @@ -23,7 +23,7 @@ spec: spec: serviceAccount: operator containers: - - image: localhost/github.com/grafana/grafana/apps/iam/operator:latest + - image: grafana-iam-operator imagePullPolicy: IfNotPresent name: iam-app-operator command: ["/bin/sh"] @@ -31,15 +31,28 @@ spec: - -c - exec /usr/bin/operator env: + - name: KUBE_FEATURE_WatchListClient + value: "false" - name: ZANZANA_ADDR value: zanzana.default.svc.cluster.local:50051 - name: FOLDER_APP_URL value: https://host.docker.internal:6446 - - name: AUTH_TOKEN_EXCHANGE_URL + - name: FOLDER_APP_NAMESPACE + value: grafana-folder + - name: TOKEN_EXCHANGE_URL value: http://host.docker.internal:8080/v1/sign-access-token - name: AUTH_TOKEN - value: "" - - name: FOLDER_APP_NAMESPACE - value: "grafana-folder" + valueFrom: + secretKeyRef: + name: iam-app-operator-secrets + key: auth-token + - name: ZANZANA_TOKEN + valueFrom: + secretKeyRef: + name: iam-app-operator-secrets + key: zanzana-token - name: FOLDER_RECONCILER_NAMESPACE - value: "default" + valueFrom: + secretKeyRef: + name: iam-app-operator-secrets + key: folder-reconciler-namespace diff --git a/apps/iam/local/yamls/zanzana.yaml b/apps/iam/local/yamls/zanzana.yaml index 37095eb05b2..5a306717468 100644 --- a/apps/iam/local/yamls/zanzana.yaml +++ b/apps/iam/local/yamls/zanzana.yaml @@ -88,12 +88,8 @@ metadata: name: zanzana data: grafana.ini: | - app_mode = development target = zanzana-server - [log] - level = info - [database] type = postgres host = postgres.default.svc:5432 @@ -103,17 +99,27 @@ data: [feature_toggles] zanzana = true - authZGRPCServer = true - - [zanzana.server] - allow_insecure = true - check_query_cache = true - http_addr = 0.0.0.0:8080 [grpc_server] enabled = true address = 0.0.0.0:50051 enable_logging = true + use_tls = false + + [log] + level = debug + + [server] + http_port = 8080 + + [zanzana.server] + check_query_cache = true + check_query_cache_enabled = true + check_query_cache_ttl = 10s + list_objects_deadline = 3s + list_objects_max_results = 1000 + signing_keys_url = http://host.docker.internal:8080/v1/keys + use_streamed_list_objects = false --- apiVersion: v1 kind: Service @@ -124,10 +130,10 @@ metadata: name: zanzana spec: ports: - - name: http + - name: zanzana-http-metrics port: 8080 targetPort: 8080 - - name: grpc + - name: zanzana-grpc port: 50051 targetPort: 50051 selector: @@ -162,17 +168,23 @@ spec: image: grafana/grafana-dev:12.2.0-257970 imagePullPolicy: IfNotPresent name: zanzana + ports: + - containerPort: 50051 + name: grpc + - containerPort: 8080 + name: http-metrics + readinessProbe: + grpc: + port: 50051 + initialDelaySeconds: 10 + timeoutSeconds: 5 volumeMounts: - mountPath: /etc/grafana-config name: zanzana-config - - mountPath: /var/lib/grafana - name: zanzana-storage serviceAccount: zanzana volumes: - configMap: name: zanzana-config name: zanzana-config - - emptyDir: {} - name: zanzana-storage --- diff --git a/apps/iam/pkg/app/app.go b/apps/iam/pkg/app/app.go index 2da47c45575..ac63c7fb001 100644 --- a/apps/iam/pkg/app/app.go +++ b/apps/iam/pkg/app/app.go @@ -43,6 +43,12 @@ func New(cfg app.Config) (app.App, error) { logging.DefaultLogger.Info("FolderReconciler created") + reconcilerOptions := simple.BasicReconcileOptions{} + + if cfg.SpecificConfig.(AppConfig).FolderReconcilerNamespace != "" { + reconcilerOptions.Namespace = cfg.SpecificConfig.(AppConfig).FolderReconcilerNamespace + } + config := simple.AppConfig{ Name: cfg.ManifestData.AppName, KubeConfig: cfg.KubeConfig, @@ -54,11 +60,9 @@ func New(cfg app.Config) (app.App, error) { }, UnmanagedKinds: []simple.AppUnmanagedKind{ { - Kind: foldersKind.FolderKind(), - Reconciler: folderReconciler, - ReconcileOptions: simple.BasicReconcileOptions{ - Namespace: cfg.SpecificConfig.(AppConfig).FolderReconcilerNamespace, - }, + Kind: foldersKind.FolderKind(), + Reconciler: folderReconciler, + ReconcileOptions: reconcilerOptions, }, }, }