Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions ct.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ chart-repos:
- opentelemetry=https://open-telemetry.github.io/opentelemetry-helm-charts
- grafana=https://grafana.github.io/helm-charts
- prometheus-community=https://prometheus-community.github.io/helm-charts
- external-secrets=https://charts.external-secrets.io/
helm-dependency-extra-args: "--skip-refresh"
4 changes: 4 additions & 0 deletions deploy-templates/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ dependencies:
version: 10.5.15
repository: https://grafana.github.io/helm-charts
condition: grafana.enabled
- name: external-secrets
version: 2.7.0
repository: https://charts.external-secrets.io/
condition: external-secrets.enabled
44 changes: 42 additions & 2 deletions deploy-templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ and `config/grafana/dashboards/`). See the repository root `README.md` for the f

| Repository | Name | Version |
|------------|------|---------|
| https://charts.external-secrets.io/ | external-secrets | 2.7.0 |
| https://grafana.github.io/helm-charts | grafana | 10.5.15 |
| https://grafana.github.io/helm-charts | loki | 7.0.0 |
| https://open-telemetry.github.io/opentelemetry-helm-charts | opentelemetry-collector | 0.164.1 |
Expand All @@ -101,7 +102,36 @@ and `config/grafana/dashboards/`). See the repository root `README.md` for the f
| dashboards.folders.operational | string | `"Operational"` | |
| dashboards.label | string | `"grafana_dashboard"` | |
| dashboards.labelValue | string | `"1"` | |
| eso.aws | object | `{"region":"eu-central-1","roleArn":"arn:aws:iam::012345678910:role/AWSIRSA_Shared_ExternalSecretOperatorAccess"}` | AWS configuration (if provider is `aws`). |
| eso.aws.region | string | `"eu-central-1"` | AWS region. |
| eso.aws.roleArn | string | `"arn:aws:iam::012345678910:role/AWSIRSA_Shared_ExternalSecretOperatorAccess"` | AWS role ARN for the ExternalSecretOperator to assume. |
| eso.enabled | bool | `false` | Render the SecretStore/ExternalSecret resources. |
| eso.generic.secretStore.providerConfig | object | `{}` | Defines SecretStore provider configuration. |
| eso.provider | string | `"generic"` | Defines provider type. One of `aws`, `generic`, or `vault`. |
| eso.secretPath | string | `"/infra/claude-code-telemetry"` | Defines the path to the secret in the provider. If provider is `vault`, the path must be prefixed with `secret/`. |
| eso.vault | object | `{"mountPath":"core","role":"claude-code-telemetry","server":"http://vault.vault:8200"}` | Vault configuration (if provider is `vault`). |
| eso.vault.mountPath | string | `"core"` | Mount path for the Kubernetes authentication method. |
| eso.vault.role | string | `"claude-code-telemetry"` | Vault role for the Kubernetes authentication method. |
| eso.vault.server | string | `"http://vault.vault:8200"` | Vault server URL. |
| external-secrets.enabled | bool | `false` | |
| external-secrets.installCRDs | bool | `true` | |
| external-secrets.scopedNamespace | string | `"claude-code-telemetry"` | |
| external-secrets.scopedRBAC | bool | `true` | |
| fullnameOverride | string | `"claude-code-telemetry"` | |
| grafana."grafana.ini"."auth.generic_oauth".allow_sign_up | bool | `true` | |
| grafana."grafana.ini"."auth.generic_oauth".api_url | string | `"https://keycloak.example.com/realms/main/protocol/openid-connect/userinfo"` | |
| grafana."grafana.ini"."auth.generic_oauth".auth_url | string | `"https://keycloak.example.com/realms/main/protocol/openid-connect/auth"` | |
| grafana."grafana.ini"."auth.generic_oauth".auto_login | bool | `false` | |
| grafana."grafana.ini"."auth.generic_oauth".client_id | string | `"grafana-claude-code-telemetry"` | |
| grafana."grafana.ini"."auth.generic_oauth".email_attribute_path | string | `"email"` | |
| grafana."grafana.ini"."auth.generic_oauth".enabled | bool | `false` | |
| grafana."grafana.ini"."auth.generic_oauth".groups_attribute_path | string | `"groups"` | |
| grafana."grafana.ini"."auth.generic_oauth".name | string | `"SSO"` | |
| grafana."grafana.ini"."auth.generic_oauth".role_attribute_path | string | `"contains(roles[*], 'administrator') && 'Admin' || contains(roles[*], 'developer') && 'Editor' || 'Viewer'"` | |
| grafana."grafana.ini"."auth.generic_oauth".scopes | string | `"openid profile email roles groups"` | |
| grafana."grafana.ini"."auth.generic_oauth".token_url | string | `"https://keycloak.example.com/realms/main/protocol/openid-connect/token"` | |
| grafana."grafana.ini".analytics.check_for_updates | bool | `false` | |
| grafana."grafana.ini".server.root_url | string | `"https://grafana.example.com"` | |
| grafana.datasources."datasources.yaml".apiVersion | int | `1` | |
| grafana.datasources."datasources.yaml".datasources[0].access | string | `"proxy"` | |
| grafana.datasources."datasources.yaml".datasources[0].isDefault | bool | `true` | |
Expand All @@ -116,6 +146,12 @@ and `config/grafana/dashboards/`). See the repository root `README.md` for the f
| grafana.datasources."datasources.yaml".datasources[1].url | string | `"http://loki:3100"` | |
| grafana.enabled | bool | `true` | |
| grafana.fullnameOverride | string | `"grafana"` | |
| grafana.ingress.annotations | object | `{}` | |
| grafana.ingress.enabled | bool | `false` | |
| grafana.ingress.hosts[0] | string | `"grafana.example.com"` | |
| grafana.ingress.path | string | `"/"` | |
| grafana.ingress.pathType | string | `"Prefix"` | |
| grafana.ingress.tls | list | `[]` | |
| grafana.rbac.namespaced | bool | `true` | |
| grafana.sidecar.dashboards.enabled | bool | `true` | |
| grafana.sidecar.dashboards.folderAnnotation | string | `"grafana_folder"` | |
Expand All @@ -131,6 +167,10 @@ and `config/grafana/dashboards/`). See the repository root `README.md` for the f
| ingress.http.enabled | bool | `false` | |
| ingress.http.host | string | `"otel-http.example.com"` | |
| ingress.http.tls | list | `[]` | |
| keycloakClient.clientId | string | `"grafana"` | OAuth client ID; keep in sync with grafana.grafana\.ini.auth\.generic_oauth.client_id. |
| keycloakClient.create | bool | `false` | Render a KeycloakClient CR for Grafana SSO via the KubeRocketCI keycloak-operator. |
| keycloakClient.grafanaUrl | string | `"https://grafana.example.com"` | Grafana external URL (OAuth redirect base); keep in sync with grafana ingress host and server.root_url. |
| keycloakClient.realmRef | object | `{"kind":"ClusterKeycloakRealm","name":"main"}` | Keycloak realm the client is created in. |
| loki.backend.replicas | int | `0` | |
| loki.chunksCache.enabled | bool | `false` | |
| loki.deploymentMode | string | `"SingleBinary"` | |
Expand Down Expand Up @@ -231,5 +271,5 @@ and `config/grafana/dashboards/`). See the repository root `README.md` for the f
| prometheus.scrapeConfigs.prometheus.enabled | bool | `false` | |
| prometheus.server.fullnameOverride | string | `"prometheus-server"` | |
| prometheus.server.persistentVolume.enabled | bool | `true` | |
| prometheus.server.persistentVolume.size | string | `"10Gi"` | |
| prometheus.server.retention | string | `"30d"` | |
| prometheus.server.persistentVolume.size | string | `"20Gi"` | |
| prometheus.server.retention | string | `"365d"` | |
41 changes: 41 additions & 0 deletions deploy-templates/templates/external-secrets/grafana-sso.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{{- /*
The single SSO secret for this bundle: Grafana admin credentials + OAuth client secret.
Grafana consumes `username`/`password` (admin.existingSecret) and `clientSecret`
(envValueFrom -> GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET); the KeycloakClient CR references
`$grafana-sso:clientSecret`. Without ESO, create the same Secret manually:
kubectl create secret generic grafana-sso \
--from-literal=username=<admin> --from-literal=password=<pass> \
--from-literal=clientSecret=<oauth-client-secret>
*/ -}}
{{- if .Values.eso.enabled }}
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: grafana-sso
labels:
{{- include "claude-code-telemetry.labels" . | nindent 4 }}
spec:
refreshInterval: 1h
secretStoreRef:
kind: SecretStore
name: {{ .Release.Name }}
data:
- secretKey: username
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: {{ .Values.eso.secretPath }}
property: username
- secretKey: password
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: {{ .Values.eso.secretPath }}
property: password
- secretKey: clientSecret
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: {{ .Values.eso.secretPath }}
property: clientSecret
{{- end }}
17 changes: 17 additions & 0 deletions deploy-templates/templates/external-secrets/secretstore-aws.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{{- if and .Values.eso.enabled (eq .Values.eso.provider "aws") }}
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: {{ .Release.Name }}
labels:
{{- include "claude-code-telemetry.labels" . | nindent 4 }}
spec:
provider:
aws:
service: ParameterStore
region: {{ .Values.eso.aws.region }}
auth:
jwt:
serviceAccountRef:
name: externalsecrets-{{ .Release.Name }}-{{ .Values.eso.provider }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if and .Values.eso.enabled (eq .Values.eso.provider "generic") }}
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: {{ .Release.Name }}
labels:
{{- include "claude-code-telemetry.labels" . | nindent 4 }}
spec:
provider:
{{- with .Values.eso.generic.secretStore.providerConfig }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
20 changes: 20 additions & 0 deletions deploy-templates/templates/external-secrets/secretstore-vault.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{{- if and .Values.eso.enabled (eq .Values.eso.provider "vault") }}
apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
name: {{ .Release.Name }}
labels:
{{- include "claude-code-telemetry.labels" . | nindent 4 }}
spec:
provider:
vault:
auth:
kubernetes:
mountPath: {{ .Values.eso.vault.mountPath }}
role: {{ .Values.eso.vault.role }}
serviceAccountRef:
name: externalsecrets-{{ .Release.Name }}-{{ .Values.eso.provider }}
path: secret
server: {{ .Values.eso.vault.server }}
version: v2
{{- end }}
12 changes: 12 additions & 0 deletions deploy-templates/templates/external-secrets/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{{- if and .Values.eso.enabled (ne .Values.eso.provider "generic") }}
apiVersion: v1
kind: ServiceAccount
metadata:
{{- if eq .Values.eso.provider "aws" }}
annotations:
eks.amazonaws.com/role-arn: {{ .Values.eso.aws.roleArn }}
{{- end }}
name: externalsecrets-{{ .Release.Name }}-{{ .Values.eso.provider }}
labels:
{{- include "claude-code-telemetry.labels" . | nindent 4 }}
{{- end }}
42 changes: 42 additions & 0 deletions deploy-templates/templates/keycloak/keycloakclient-grafana.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{{- if .Values.keycloakClient.create }}
apiVersion: v1.edp.epam.com/v1
kind: KeycloakClient
metadata:
name: {{ .Values.keycloakClient.clientId }}
labels:
{{- include "claude-code-telemetry.labels" . | nindent 4 }}
spec:
advancedProtocolMappers: true
clientId: {{ .Values.keycloakClient.clientId }}
directAccess: true
# Client secret consumed from the grafana-sso Secret (kubectl- or ESO-created; see values.yaml).
secret: $grafana-sso:clientSecret
defaultClientScopes:
- profile
- email
- roles
realmRef:
kind: {{ .Values.keycloakClient.realmRef.kind }}
name: {{ .Values.keycloakClient.realmRef.name }}
webUrl: {{ .Values.keycloakClient.grafanaUrl | quote }}
protocolMappers:
- name: roles
protocol: openid-connect
protocolMapper: "oidc-usermodel-realm-role-mapper"
config:
"access.token.claim": "true"
"claim.name": "roles"
"id.token.claim": "true"
"userinfo.token.claim": "true"
"multivalued": "true"
# Expose group membership so Grafana can gate access (allowed_groups) and map org roles.
- name: groups
protocol: openid-connect
protocolMapper: "oidc-group-membership-mapper"
config:
"access.token.claim": "true"
"claim.name": "groups"
"id.token.claim": "true"
"userinfo.token.claim": "true"
"full.path": "false"
{{- end }}
Loading
Loading