Skip to content
Open
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
22 changes: 21 additions & 1 deletion charts/scalar-manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,28 @@ Current chart version is `3.0.0-SNAPSHOT`
| scalarManager.securityContext.runAsNonRoot | bool | `true` | |
| scalarManager.serviceAccount.automountServiceAccountToken | bool | `true` | |
| scalarManager.serviceAccount.serviceAccountName | string | `""` | |
| scalarManager.tls | object | `{"certManager":{"dnsNames":["localhost","scalar-manager"],"duration":"8760h0m0s","enabled":false,"issuerRef":{},"privateKey":{"algorithm":"RSA","encoding":"PKCS8","size":2048},"renewBefore":"360h0m0s","selfSigned":{"enabled":false},"usages":["server auth","key encipherment","signing"]},"downstream":{"caRootCertSecret":"","certChainSecret":"","enabled":false,"privateKeySecret":""},"upstream":{"grafana":[],"prometheus":[],"scalardb":[],"scalardl":[]}}` | Unified TLS configuration for both API and Web components. |
| scalarManager.tls.certManager | object | `{"dnsNames":["localhost","scalar-manager"],"duration":"8760h0m0s","enabled":false,"issuerRef":{},"privateKey":{"algorithm":"RSA","encoding":"PKCS8","size":2048},"renewBefore":"360h0m0s","selfSigned":{"enabled":false},"usages":["server auth","key encipherment","signing"]}` | Cert-manager integration for automatic certificate management. |
| scalarManager.tls.certManager.dnsNames | list | `["localhost","scalar-manager"]` | DNS names for the certificate. |
| scalarManager.tls.certManager.duration | string | `"8760h0m0s"` | Duration of the certificate. |
| scalarManager.tls.certManager.enabled | bool | `false` | Enable cert-manager integration. |
| scalarManager.tls.certManager.issuerRef | object | `{}` | Reference to the issuer for the certificate. |
| scalarManager.tls.certManager.privateKey | object | `{"algorithm":"RSA","encoding":"PKCS8","size":2048}` | Private key configurations. |
| scalarManager.tls.certManager.renewBefore | string | `"360h0m0s"` | How long before expiry the certificate should be renewed. |
| scalarManager.tls.certManager.selfSigned | object | `{"enabled":false}` | Use a self-signed certificate. |
| scalarManager.tls.certManager.usages | list | `["server auth","key encipherment","signing"]` | Usages for the certificate. |
| scalarManager.tls.downstream | object | `{"caRootCertSecret":"","certChainSecret":"","enabled":false,"privateKeySecret":""}` | Enable downstream TLS for Scalar Manager (applies to both API and Web components). |
| scalarManager.tls.downstream.caRootCertSecret | string | `""` | Secret containing the CA root certificate for web-to-API communication (Web needs to validate API's TLS certificate). |
| scalarManager.tls.downstream.certChainSecret | string | `""` | Secret containing the certificate for downstream TLS. |
| scalarManager.tls.downstream.enabled | bool | `false` | Enable downstream TLS (Web and API share the same certificate). |
| scalarManager.tls.downstream.privateKeySecret | string | `""` | Secret containing the private key for downstream TLS. |
| scalarManager.tls.upstream | object | `{"grafana":[],"prometheus":[],"scalardb":[],"scalardl":[]}` | Upstream TLS configuration for external service connections. |
| scalarManager.tls.upstream.grafana | list | `[]` | Grafana TLS configuration (array to support multiple namespaces). |
| scalarManager.tls.upstream.prometheus | list | `[]` | Prometheus TLS configuration (array to support multiple namespaces). |
| scalarManager.tls.upstream.scalardb | list | `[]` | ScalarDB TLS configuration (array to support multiple namespaces). |
| scalarManager.tls.upstream.scalardl | list | `[]` | ScalarDL TLS configuration (array to support multiple namespaces). |
| scalarManager.tolerations | list | `[]` | |
| scalarManager.web.env | list | `[{"name":"GRAFANA_SERVER_URL","value":"http://scalardb-cluster-monitoring-grafana:3000"}]` | The environment variables for Scalar Manager web container. If you want to customize environment variables, you can override this value with your environment variables. |
| scalarManager.web.env | list | `[{"name":"GRAFANA_SERVICE_INFO_CACHE_TTL","value":"180000"}]` | The environment variables for Scalar Manager web container. If you want to customize environment variables, you can override this value with your environment variables. |
| scalarManager.web.image.pullPolicy | string | `"IfNotPresent"` | |
| scalarManager.web.image.repository | string | `"ghcr.io/scalar-labs/scalar-manager-web"` | |
| scalarManager.web.image.tag | string | `""` | |
Expand Down
80 changes: 80 additions & 0 deletions charts/scalar-manager/templates/scalar-manager/certmanager.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{{- if and .Values.scalarManager.tls.downstream.enabled .Values.scalarManager.tls.certManager.enabled }}
{{- if .Values.scalarManager.tls.certManager.selfSigned.enabled }}
---
# This issuer is for creating the self-signed CA certificate.
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: {{ include "scalar-manager.fullname" . }}-bootstrap-selfsigned-issuer
namespace: {{ .Release.Namespace }}
spec:
selfSigned: {}
---
# This is the CA certificate.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ include "scalar-manager.fullname" . }}-ca-cert
namespace: {{ .Release.Namespace }}
spec:
isCA: true
commonName: {{ include "scalar-manager.fullname" . }}-ca
secretName: {{ include "scalar-manager.fullname" . }}-ca-cert
duration: {{ .Values.scalarManager.tls.certManager.duration }}
renewBefore: {{ .Values.scalarManager.tls.certManager.renewBefore }}
privateKey:
algorithm: {{ .Values.scalarManager.tls.certManager.privateKey.algorithm }}
encoding: {{ .Values.scalarManager.tls.certManager.privateKey.encoding }}
size: {{ .Values.scalarManager.tls.certManager.privateKey.size }}
issuerRef:
name: {{ include "scalar-manager.fullname" . }}-bootstrap-selfsigned-issuer
kind: Issuer
---
# This issuer uses the CA certificate to sign other certificates.
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: {{ include "scalar-manager.fullname" . }}-ca-issuer
namespace: {{ .Release.Namespace }}
spec:
ca:
secretName: {{ include "scalar-manager.fullname" . }}-ca-cert
{{- end }}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ include "scalar-manager.fullname" . }}-tls-cert
namespace: {{ .Release.Namespace }}
spec:
secretName: {{ include "scalar-manager.fullname" . }}-tls-cert
commonName: {{ include "scalar-manager.fullname" . }}
{{- with .Values.scalarManager.tls.certManager.dnsNames }}
dnsNames:
{{- range . }}
- {{ . | quote }}
{{- end }}
{{- end }}
duration: {{ .Values.scalarManager.tls.certManager.duration }}
renewBefore: {{ .Values.scalarManager.tls.certManager.renewBefore }}
{{- with .Values.scalarManager.tls.certManager.usages }}
usages:
{{- range . }}
- {{ . | quote }}
{{- end }}
{{- end }}
privateKey:
algorithm: {{ .Values.scalarManager.tls.certManager.privateKey.algorithm }}
encoding: {{ .Values.scalarManager.tls.certManager.privateKey.encoding }}
size: {{ .Values.scalarManager.tls.certManager.privateKey.size }}
issuerRef:
{{- if .Values.scalarManager.tls.certManager.selfSigned.enabled }}
name: {{ include "scalar-manager.fullname" . }}-ca-issuer
kind: Issuer
{{- else }}
{{- if not (len .Values.scalarManager.tls.certManager.issuerRef) }}
{{- fail "When using cert-manager with an external issuer, scalarManager.tls.certManager.issuerRef must be configured." -}}
{{- end }}
{{- toYaml .Values.scalarManager.tls.certManager.issuerRef | nindent 4 }}
{{- end }}
{{- end }}
209 changes: 208 additions & 1 deletion charts/scalar-manager/templates/scalar-manager/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,85 @@ spec:
imagePullPolicy: {{ .Values.scalarManager.api.image.pullPolicy }}
securityContext:
{{- toYaml .Values.scalarManager.securityContext | nindent 12 }}
env:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to configure Scalar Manager Web via environment variables because there is no configuration files like application.properties.

However, I think we can configure Scalar Manager API by using application.properties. And, it seems that there are two ways to configure Scalar Manager API in this update. One is using the application.properties file. Another is via environment variables.

My concern is that mixing two configuration ways might cause confusion for users. Is it possible to use only one of application.properties or environment variables?

Also, we already provide the way to configure Scalar Manager API by using application.properties. Therefore, to keep backward compatibility and consistency of How to configure Scalar Manager API, I think it would be better to use only application.properties instead of mixing both application.properties and environment variables.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the main config for the API is still application.properties. For the API we add several properties for the TLS in the application.properties, and those configs will get the TLS configs from the env by default. If user overrides these configs, then the API will accept the values user enters.

This env part of the API is for the TLS only as I aimed for one TLS config block in the values file, and the certs is the same for Scalar Manager API and Web. If we dont do the env mapping here, then users have to configure the TLS separately in the application.properties. Also, we still dont expose any env config for the API in values. WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have one question.

If we don't set app.tls.inbound.enabled=${APP_TLS_INBOUND_ENABLED} in the application.properties file explicitly as follows, and we set scalarManager.tls.downstream.enabled=true, does Scalar Manager API start with TLS enabled configuration?

scalarManager:
  api:
    applicationProperties: |
      spring.datasource.url=jdbc:postgresql://user.postgresql.example.com:5432/postgres
      spring.datasource.username=postgres
      spring.datasource.password=postgres
      spring.datasource.driver-class-name=org.postgresql.Driver
  tls:
    downstream:
      enabled: true

In this case, I think some default configurations like app.tls.inbound.enabled=${APP_TLS_INBOUND_ENABLED} are not applied because the default application.properties is overwritten by the above user-specified application.properties. Is my understanding correct?

If my understanding is correct, Scalar Manager API does not start with TLS configuration even if we set scalarManager.tls.downstream.enabled=true because there is no configuration about TLS on the overwritten (user-specified) application.properties side.

That's why I want to ask this question. I'd like to know the behavior of the Scalar Manager API in the above configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is expected behavior.
But based on this situation, I made some updates to simplify the default config. With these updates, the TLS config will automatically be bound to the API via environment variables directly from the TLS config block in the values.yml. So users dont have to set the values in the properties for TLS, except custom values if they want to.
PTAL again when have time and let me know your thoughts

# Spring Boot SSL configuration (inbound TLS)
- name: SERVER_SSL_ENABLED
value: "{{ .Values.scalarManager.tls.downstream.enabled }}"
{{- if .Values.scalarManager.tls.downstream.enabled }}
- name: SERVER_SSL_CERTIFICATE
value: "/tls/scalar-manager/certs/tls.crt"
- name: SERVER_SSL_CERTIFICATE_PRIVATE_KEY
value: "/tls/scalar-manager/certs/tls.key"
{{- end }}
# Upstream TLS configuration
{{- range $index, $prometheus := .Values.scalarManager.tls.upstream.prometheus }}
- name: APP_TLS_OUTBOUND_PROMETHEUS_{{ $index }}_ENABLED
value: "{{ $prometheus.enabled }}"
{{- if $prometheus.enabled }}
- name: APP_TLS_OUTBOUND_PROMETHEUS_{{ $index }}_NAMESPACE
value: "{{ $prometheus.namespace }}"
- name: APP_TLS_OUTBOUND_PROMETHEUS_{{ $index }}_CA_ROOT_CERT_PATH
value: "/tls/upstream/prometheus-{{ $index }}/certs/ca.crt"
{{- if $prometheus.overrideAuthority }}
- name: APP_TLS_OUTBOUND_PROMETHEUS_{{ $index }}_OVERRIDE_AUTHORITY
value: "{{ $prometheus.overrideAuthority }}"
{{- end }}
{{- end }}
{{- end }}
{{- range $index, $scalardb := .Values.scalarManager.tls.upstream.scalardb }}
- name: APP_TLS_OUTBOUND_SCALARDB_{{ $index }}_ENABLED
value: "{{ $scalardb.enabled }}"
{{- if $scalardb.enabled }}
- name: APP_TLS_OUTBOUND_SCALARDB_{{ $index }}_NAMESPACE
value: "{{ $scalardb.namespace }}"
- name: APP_TLS_OUTBOUND_SCALARDB_{{ $index }}_CA_ROOT_CERT_PATH
value: "/tls/upstream/scalardb-{{ $index }}/certs/ca.crt"
{{- if $scalardb.overrideAuthority }}
- name: APP_TLS_OUTBOUND_SCALARDB_{{ $index }}_OVERRIDE_AUTHORITY
value: "{{ $scalardb.overrideAuthority }}"
{{- end }}
{{- end }}
{{- end }}
{{- range $index, $scalardl := .Values.scalarManager.tls.upstream.scalardl }}
- name: APP_TLS_OUTBOUND_SCALARDL_{{ $index }}_ENABLED
value: "{{ $scalardl.enabled }}"
{{- if $scalardl.enabled }}
- name: APP_TLS_OUTBOUND_SCALARDL_{{ $index }}_NAMESPACE
value: "{{ $scalardl.namespace }}"
- name: APP_TLS_OUTBOUND_SCALARDL_{{ $index }}_CA_ROOT_CERT_PATH
value: "/tls/upstream/scalardl-{{ $index }}/certs/ca.crt"
{{- if $scalardl.overrideAuthority }}
- name: APP_TLS_OUTBOUND_SCALARDL_{{ $index }}_OVERRIDE_AUTHORITY
value: "{{ $scalardl.overrideAuthority }}"
{{- end }}
{{- end }}
{{- end }}
volumeMounts:
- name: api-application-properties-volume
mountPath: /app/application.properties
subPath: scalar-manager-api-application.properties
{{- if .Values.scalarManager.tls.downstream.enabled }}
- name: scalar-manager-tls-volume
mountPath: /tls/scalar-manager/certs
{{- end }}
{{- range $index, $prometheus := .Values.scalarManager.tls.upstream.prometheus }}
{{- if and $prometheus.enabled $prometheus.caRootCertSecret }}
- name: scalar-manager-tls-upstream-prometheus-{{ $index }}-volume
mountPath: /tls/upstream/prometheus-{{ $index }}/certs
{{- end }}
{{- end }}
{{- range $index, $scalardb := .Values.scalarManager.tls.upstream.scalardb }}
{{- if and $scalardb.enabled $scalardb.caRootCertSecret }}
- name: scalar-manager-tls-upstream-scalardb-{{ $index }}-volume
mountPath: /tls/upstream/scalardb-{{ $index }}/certs
{{- end }}
{{- end }}
{{- range $index, $scalardl := .Values.scalarManager.tls.upstream.scalardl }}
{{- if and $scalardl.enabled $scalardl.caRootCertSecret }}
- name: scalar-manager-tls-upstream-scalardl-{{ $index }}-volume
mountPath: /tls/upstream/scalardl-{{ $index }}/certs
{{- end }}
{{- end }}
- name: {{ .Chart.Name }}-web
{{- if eq .Values.global.platform "azure" }}
image: "{{ .Values.global.azure.images.scalarManagerWeb.registry }}/{{ .Values.global.azure.images.scalarManagerWeb.image }}:{{ .Values.global.azure.images.scalarManagerWeb.tag | default .Chart.AppVersion }}"
Expand All @@ -54,15 +129,147 @@ spec:
{{- toYaml .Values.scalarManager.web.resources | nindent 12 }}
env:
{{- toYaml .Values.scalarManager.web.env | nindent 12 }}
# Downstream TLS configuration
- name: TLS_INBOUND_ENABLED
value: "{{ .Values.scalarManager.tls.downstream.enabled }}"
{{- if .Values.scalarManager.tls.downstream.enabled }}
- name: TLS_INBOUND_KEY_PATH
value: "/tls/scalar-manager/certs/tls.key"
- name: TLS_INBOUND_CERT_PATH
value: "/tls/scalar-manager/certs/tls.crt"
{{- end }}
# Upstream TLS configuration
# Auto-enable API communication when downstream TLS is enabled (same pod)
- name: TLS_OUTBOUND_API_ENABLED
value: "{{ .Values.scalarManager.tls.downstream.enabled }}"
{{- if .Values.scalarManager.tls.downstream.enabled }}
- name: TLS_OUTBOUND_API_CA_ROOT_CERT_PATH
{{- if .Values.scalarManager.tls.downstream.caRootCertSecret }}
value: "/tls/ca/certs/ca.crt"
{{- else if .Values.scalarManager.tls.certManager.enabled }}
# For cert-manager issuers (self-signed or external), we assume ca.crt is present in the secret.
value: "/tls/scalar-manager/certs/ca.crt"
{{- else }}
# Manual mode without a caRootCertSecret, assume the server cert is the trust anchor.
value: "/tls/scalar-manager/certs/tls.crt"
{{- end }}
{{- end }}
{{- range $index, $grafana := .Values.scalarManager.tls.upstream.grafana }}
{{- if $grafana.enabled }}
- name: TLS_OUTBOUND_GRAFANA_{{ $index }}_ENABLED
value: "{{ $grafana.enabled }}"
- name: TLS_OUTBOUND_GRAFANA_{{ $index }}_NAMESPACE
value: "{{ $grafana.namespace }}"
- name: TLS_OUTBOUND_GRAFANA_{{ $index }}_CA_ROOT_CERT_PATH
value: "/tls/upstream/grafana-{{ $index }}/certs/ca.crt"
{{- if $grafana.overrideAuthority }}
- name: TLS_OUTBOUND_GRAFANA_{{ $index }}_OVERRIDE_AUTHORITY
value: "{{ $grafana.overrideAuthority }}"
{{- end }}
{{- end }}
{{- end }}
ports:
- containerPort: 3000
- containerPort: {{ .Values.scalarManager.web.service.ports.web.targetPort }}
imagePullPolicy: {{ .Values.scalarManager.web.image.pullPolicy }}
volumeMounts:
{{- if .Values.scalarManager.tls.downstream.enabled }}
- name: scalar-manager-tls-volume
mountPath: /tls/scalar-manager/certs
{{- end }}
{{- if .Values.scalarManager.tls.downstream.caRootCertSecret }}
- name: scalar-manager-tls-downstream-ca-volume
mountPath: /tls/ca/certs
{{- end }}
{{- range $index, $grafana := .Values.scalarManager.tls.upstream.grafana }}
{{- if and $grafana.enabled $grafana.caRootCertSecret }}
- name: scalar-manager-tls-upstream-grafana-{{ $index }}-volume
mountPath: /tls/upstream/grafana-{{ $index }}/certs
{{- end }}
{{- end }}
securityContext:
{{- toYaml .Values.scalarManager.securityContext | nindent 12 }}
volumes:
- name: api-application-properties-volume
configMap:
name: {{ include "scalar-manager.fullname" . }}-api-application-properties
{{- if and .Values.scalarManager.tls.downstream.enabled (not .Values.scalarManager.tls.certManager.enabled) }}
{{- if or (not .Values.scalarManager.tls.downstream.certChainSecret) (not .Values.scalarManager.tls.downstream.privateKeySecret) }}
{{- fail "When using manual downstream TLS, both scalarManager.tls.downstream.certChainSecret and scalarManager.tls.downstream.privateKeySecret must be set." -}}
{{- end }}
- name: scalar-manager-tls-volume
projected:
sources:
- secret:
name: {{ .Values.scalarManager.tls.downstream.certChainSecret }}
items:
- key: tls.crt
path: tls.crt
- secret:
name: {{ .Values.scalarManager.tls.downstream.privateKeySecret }}
items:
- key: tls.key
path: tls.key
{{- end }}
{{- if and .Values.scalarManager.tls.downstream.enabled .Values.scalarManager.tls.certManager.enabled }}
- name: scalar-manager-tls-volume
secret:
secretName: {{ include "scalar-manager.fullname" . }}-tls-cert
items:
- key: tls.crt
path: tls.crt
- key: tls.key
path: tls.key
- key: ca.crt
path: ca.crt
{{- end }}
{{- if .Values.scalarManager.tls.downstream.caRootCertSecret }}
- name: scalar-manager-tls-downstream-ca-volume
secret:
secretName: {{ .Values.scalarManager.tls.downstream.caRootCertSecret }}
items:
- key: ca.crt
path: ca.crt
{{- end }}
{{- range $index, $grafana := .Values.scalarManager.tls.upstream.grafana }}
{{- if and $grafana.enabled $grafana.caRootCertSecret }}
- name: scalar-manager-tls-upstream-grafana-{{ $index }}-volume
secret:
secretName: {{ $grafana.caRootCertSecret }}
items:
- key: ca.crt
path: ca.crt
{{- end }}
{{- end }}
{{- range $index, $prometheus := .Values.scalarManager.tls.upstream.prometheus }}
{{- if and $prometheus.enabled $prometheus.caRootCertSecret }}
- name: scalar-manager-tls-upstream-prometheus-{{ $index }}-volume
secret:
secretName: {{ $prometheus.caRootCertSecret }}
items:
- key: ca.crt
path: ca.crt
{{- end }}
{{- end }}
{{- range $index, $scalardb := .Values.scalarManager.tls.upstream.scalardb }}
{{- if and $scalardb.enabled $scalardb.caRootCertSecret }}
- name: scalar-manager-tls-upstream-scalardb-{{ $index }}-volume
secret:
secretName: {{ $scalardb.caRootCertSecret }}
items:
- key: ca.crt
path: ca.crt
{{- end }}
{{- end }}
{{- range $index, $scalardl := .Values.scalarManager.tls.upstream.scalardl }}
{{- if and $scalardl.enabled $scalardl.caRootCertSecret }}
- name: scalar-manager-tls-upstream-scalardl-{{ $index }}-volume
secret:
secretName: {{ $scalardl.caRootCertSecret }}
items:
- key: ca.crt
path: ca.crt
{{- end }}
{{- end }}
securityContext:
{{- toYaml .Values.scalarManager.podSecurityContext | nindent 8 }}
{{- with .Values.scalarManager.imagePullSecrets }}
Expand Down
Loading