diff --git a/doi/README.md b/doi/README.md index 0c41726..d965a47 100644 --- a/doi/README.md +++ b/doi/README.md @@ -114,6 +114,32 @@ docker run --rm -it doi:latest /bin/bash docker run --rm --user tomcat:tomcat --volume=/path/to/external/config:/config:ro --name doi doi:latest ``` +## Kubernetes deployment + +A Helm chart for deploying the DOI service is provided in `doi/helm` from the +repository root. Start with `doi/helm/examples/values.example.yaml`, provide +the environment-specific registry, service, VOSpace, and DataCite settings, +and create the referenced credential and certificate Secrets out of band. + +Validate the chart before installation: + +``` +helm lint doi/helm \ + --set application.config.accountPrefix=10.5072 +helm template doi doi/helm \ + --namespace doi \ + --set application.config.accountPrefix=10.5072 +``` + +Install it with environment-specific values: + +``` +helm upgrade --install doi doi/helm \ + --namespace doi \ + --create-namespace \ + --values +``` + ## running it with alternative settings ``` docker run --rm --user tomcat:tomcat --volume=/path/to/external/config:/config:ro --name doi-alt doi:latest diff --git a/doi/helm/.helmignore b/doi/helm/.helmignore new file mode 100644 index 0000000..9288868 --- /dev/null +++ b/doi/helm/.helmignore @@ -0,0 +1,7 @@ +# Patterns to ignore when building packages. +.DS_Store +.git/ +.gitignore +.helmignore +*.swp +*.tmp diff --git a/doi/helm/Chart.yaml b/doi/helm/Chart.yaml new file mode 100644 index 0000000..9b9898b --- /dev/null +++ b/doi/helm/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +name: doi +description: "A Helm chart to install the Digital Object Identifier service" + +maintainers: + - name: Canadian Astronomy Data Centre + email: cadc@nrc-cnrc.gc.ca + +type: application + +version: 0.1.0 + +appVersion: "1.2.0" diff --git a/doi/helm/README.md b/doi/helm/README.md new file mode 100644 index 0000000..6f678f8 --- /dev/null +++ b/doi/helm/README.md @@ -0,0 +1,94 @@ +# doi + +Digital Object Identifier service Helm chart. + +This chart deploys the CADC DOI Tomcat service. Non-secret configuration is rendered into a ConfigMap under `/config`; DataCite credentials and the required `doiadmin.pem` and `cadcproxy.pem` files are read from Kubernetes Secrets and merged into the runtime config by an init container. An optional `RsaSignaturePub.key` can also be projected from a Secret for browser cookie validation. + +## Required Secrets + +Create a Secret for DataCite credentials: + +```shell +kubectl create secret generic doi-datacite \ + --from-literal=username='' \ + --from-literal=password='' +``` + +Create a Secret for service certificates: + +```shell +kubectl create secret generic doi-certs \ + --from-file=doiadmin.pem=./doiadmin.pem \ + --from-file=cadcproxy.pem=./cadcproxy.pem +``` + +Create the optional Secret containing the cookie-signature public key: + +```shell +kubectl create secret generic doi-cookie-signature-public-key \ + --from-file=RsaSignaturePub.key=./RsaSignaturePub.key +``` + +Set: + +```yaml +application: + datacite: + auth: + existingSecret: doi-datacite + certificates: + existingSecret: doi-certs + cookieSignaturePublicKey: + existingSecret: + name: doi-cookie-signature-public-key + path: RsaSignaturePub.key +``` + +## Example Values + +Start from `examples/values.example.yaml` and replace the example hostnames, registry IDs, VOSpace URI, DataCite account prefix, and Secret names. + +## Test the Chart + +Render and lint the chart with non-secret placeholder Secret names: + +```shell +helm lint doi/helm \ + --set application.datacite.auth.existingSecret=doi-datacite \ + --set application.certificates.existingSecret=doi-certs \ + --set application.config.accountPrefix=10.5072 + +helm template doi doi/helm \ + --namespace doi \ + --set application.datacite.auth.existingSecret=doi-datacite \ + --set application.certificates.existingSecret=doi-certs \ + --set application.config.accountPrefix=10.5072 +``` + +Dry-run against a cluster: + +```shell +helm upgrade --install doi doi/helm \ + --namespace doi \ + --create-namespace \ + --values doi/helm/examples/values.example.yaml \ + --dry-run +``` + +Install after replacing the example values and creating the required Secrets: + +```shell +helm upgrade --install doi doi/helm \ + --namespace doi \ + --create-namespace \ + --values +``` + +Check the workload: + +```shell +kubectl -n doi get pods +kubectl -n doi logs deploy/doi-tomcat +kubectl -n doi port-forward svc/doi-tomcat-svc 18080:8080 +curl http://localhost:18080/doi/availability +``` diff --git a/doi/helm/config/cadc-log.properties b/doi/helm/config/cadc-log.properties new file mode 100644 index 0000000..8432ebc --- /dev/null +++ b/doi/helm/config/cadc-log.properties @@ -0,0 +1,3 @@ +{{- range $val := .Values.application.loggingGroups }} +group = {{ $val }} +{{- end }} diff --git a/doi/helm/config/cadc-registry.properties b/doi/helm/config/cadc-registry.properties new file mode 100644 index 0000000..378fc6e --- /dev/null +++ b/doi/helm/config/cadc-registry.properties @@ -0,0 +1,21 @@ +# +# local authority map +# +{{- with .Values.application.gmsID }} +ivo://ivoa.net/std/GMS#search-1.0 = {{ . }} +ivo://ivoa.net/std/GMS#search-0.1 = {{ . }} +ivo://ivoa.net/std/GMS#users-1.0 = {{ . }} +ivo://ivoa.net/std/UMS#users-0.1 = {{ . }} +ivo://ivoa.net/std/UMS#users-1.0 = {{ . }} +ivo://ivoa.net/sso#tls-with-password = {{ . }} +{{- end }} +{{- with .Values.application.oidcURI }} +ivo://ivoa.net/sso#OAuth = {{ . }} +ivo://ivoa.net/sso#OpenID = {{ . }} +{{- end }} + +{{- $raw := .Values.application.registryURL -}} +{{- $urls := ternary (list $raw) $raw (kindIs "string" $raw) -}} +{{- range $urls }} +ca.nrc.cadc.reg.client.RegistryClient.baseURL = {{ . }} +{{- end }} diff --git a/doi/helm/config/catalina.properties b/doi/helm/config/catalina.properties new file mode 100644 index 0000000..b949552 --- /dev/null +++ b/doi/helm/config/catalina.properties @@ -0,0 +1,10 @@ +tomcat.connector.connectionTimeout=180000 +tomcat.connector.keepAliveTimeout=180000 +tomcat.connector.secure=true +tomcat.connector.scheme=https +tomcat.connector.proxyName={{ include "doi.hostname" . }} +tomcat.connector.proxyPort=443 +ca.nrc.cadc.auth.PrincipalExtractor.enableClientCertHeader=true +ca.nrc.cadc.util.Log4jInit.messageOnly=true +# (default: ca.nrc.cadc.auth.NoOpIdentityManager) +ca.nrc.cadc.auth.IdentityManager={{ .Values.application.identityManagerClass }} diff --git a/doi/helm/config/doi.properties b/doi/helm/config/doi.properties new file mode 100644 index 0000000..9e80fa8 --- /dev/null +++ b/doi/helm/config/doi.properties @@ -0,0 +1,19 @@ +ca.nrc.cadc.doi.vospaceParentUri = {{ .Values.application.config.vospaceParentUri | required ".Values.application.config.vospaceParentUri is required" }} +ca.nrc.cadc.doi.metaDataPrefix = {{ .Values.application.config.metaDataPrefix | required ".Values.application.config.metaDataPrefix is required" }} +ca.nrc.cadc.doi.groupPrefix = {{ .Values.application.config.groupPrefix | required ".Values.application.config.groupPrefix is required" }} +ca.nrc.cadc.doi.landingUrl = {{ .Values.application.config.landingUrl | required ".Values.application.config.landingUrl is required" }} +ca.nrc.cadc.doi.datacite.mdsUrl = {{ .Values.application.config.mdsUrl | required ".Values.application.config.mdsUrl is required" }} +ca.nrc.cadc.doi.datacite.accountPrefix = {{ .Values.application.config.accountPrefix | required ".Values.application.config.accountPrefix is required" }} +{{- with .Values.application.config.doiIdentifierPrefix }} +ca.nrc.cadc.doi.doiIdentifierPrefix = {{ . }} +{{- end }} +{{- with .Values.application.config.publisherGroupURI }} +ca.nrc.cadc.doi.publisherGroupURI = {{ . }} +{{- end }} +{{- with .Values.application.config.selfPublish }} +ca.nrc.cadc.doi.selfPublish = {{ . }} +{{- end }} +{{- if .Values.application.config.randomTestID }} +ca.nrc.cadc.doi.randomTestID = true +{{- end }} +# ca.nrc.cadc.doi.datacite.username and ca.nrc.cadc.doi.datacite.password are appended at pod startup from Secret {{ include "doi.dataciteAuthSecretName" . }}. diff --git a/doi/helm/config/war-rename.conf b/doi/helm/config/war-rename.conf new file mode 100644 index 0000000..ce2fe27 --- /dev/null +++ b/doi/helm/config/war-rename.conf @@ -0,0 +1,3 @@ +{{- if and .Values.application.applicationName (ne .Values.application.applicationName "doi") }} +mv doi.war {{ .Values.application.applicationName }}.war +{{- end }} diff --git a/doi/helm/examples/values.example.yaml b/doi/helm/examples/values.example.yaml new file mode 100644 index 0000000..4deb5e5 --- /dev/null +++ b/doi/helm/examples/values.example.yaml @@ -0,0 +1,58 @@ +# Example values for deploying the DOI service. +# +# Copy this file and replace the example values with your environment-specific +# hostnames, registry IDs, VOSpace URI, DataCite account, and Secret names. + +image: + repository: bucket.canfar.net/doi + tag: "1.2.0" + +imagePullSecrets: + - name: bucket-registry-auth + +application: + registryURL: https://doi.example.org/reg + gmsID: ivo://example.org/gms + oidcURI: https://iam.example.org/ + + config: + vospaceParentUri: vos://example.org~arc/doi + metaDataPrefix: doi + groupPrefix: doi + landingUrl: https://doi.example.org/doi + mdsUrl: https://mds.datacite.org + accountPrefix: "10.5072" + + datacite: + auth: + existingSecret: doi-datacite + + certificates: + existingSecret: doi-certs + + cookieSignaturePublicKey: + existingSecret: + name: doi-cookie-signature-public-key + path: RsaSignaturePub.key + +ingress: + enabled: true + className: traefik + hosts: + - host: doi.example.org + paths: + - path: /doi + pathType: Prefix + +httpRoute: + enabled: false + parentRefs: + - name: gateway + sectionName: http + hostnames: + - doi.example.org + rules: + - matches: + - path: + type: PathPrefix + value: /doi diff --git a/doi/helm/templates/NOTES.txt b/doi/helm/templates/NOTES.txt new file mode 100644 index 0000000..b3c90f0 --- /dev/null +++ b/doi/helm/templates/NOTES.txt @@ -0,0 +1,13 @@ +'{{ .Chart.Name }}' installed successfully. You can monitor it in the {{ .Release.Namespace }} Namespace: + +kubectl -n {{ .Release.Namespace }} get pods + +Your release is named {{ .Release.Name }}. + +The DOI service expects DataCite credentials from Secret {{ include "doi.dataciteAuthSecretName" . }} +and PEM certificates from Secret {{ include "doi.certificateSecretName" . }}. + +To learn more about the release, try: + + $ helm -n {{ .Release.Namespace }} status {{ .Release.Name }} + $ helm -n {{ .Release.Namespace }} get all {{ .Release.Name }} diff --git a/doi/helm/templates/_helpers.tpl b/doi/helm/templates/_helpers.tpl new file mode 100644 index 0000000..6583829 --- /dev/null +++ b/doi/helm/templates/_helpers.tpl @@ -0,0 +1,78 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "doi.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "doi.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "doi.selectorLabels" -}} +app.kubernetes.io/name: {{ include "doi.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "doi.labels" -}} +helm.sh/chart: {{ include "doi.chart" . }} +{{ include "doi.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Use the Gateway API hostname when HTTPRoute is enabled; otherwise use the +first configured Ingress hostname. DOI needs this to construct external URLs. +*/}} +{{- define "doi.hostname" -}} +{{- if .Values.httpRoute.enabled -}} +{{- $hostnames := .Values.httpRoute.hostnames | default (list) -}} +{{- if eq (len $hostnames) 0 -}} +{{- fail "httpRoute.hostnames must contain at least one hostname when httpRoute.enabled is true" -}} +{{- end -}} +{{- index $hostnames 0 -}} +{{- else -}} +{{- $hosts := .Values.ingress.hosts | default (list) -}} +{{- if eq (len $hosts) 0 -}} +{{- fail "ingress.hosts must contain at least one hostname when httpRoute is disabled" -}} +{{- end -}} +{{- index (index $hosts 0) "host" -}} +{{- end -}} +{{- end }} + +{{/* +Create the name of the service account to use. +*/}} +{{- define "doi.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (printf "%s-service-account" .Release.Name) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +DataCite credential Secret name. +*/}} +{{- define "doi.dataciteAuthSecretName" -}} +{{- required "application.datacite.auth.existingSecret is required" .Values.application.datacite.auth.existingSecret -}} +{{- end -}} + +{{/* +PEM certificate Secret name. +*/}} +{{- define "doi.certificateSecretName" -}} +{{- required "application.certificates.existingSecret is required" .Values.application.certificates.existingSecret -}} +{{- end -}} diff --git a/doi/helm/templates/configmap.yaml b/doi/helm/templates/configmap.yaml new file mode 100644 index 0000000..d24c04b --- /dev/null +++ b/doi/helm/templates/configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "doi.labels" . | nindent 4 }} +data: +{{ tpl (.Files.Glob "config/*").AsConfig . | indent 2 }} diff --git a/doi/helm/templates/deployment.yaml b/doi/helm/templates/deployment.yaml new file mode 100644 index 0000000..d420d6d --- /dev/null +++ b/doi/helm/templates/deployment.yaml @@ -0,0 +1,173 @@ +{{- $containerPort := .Values.service.port -}} +{{- $auth := .Values.application.datacite.auth | default dict -}} +{{- $authKeys := $auth.secretKeys | default dict -}} +{{- $usernameKey := $authKeys.username | default "username" -}} +{{- $passwordKey := $authKeys.password | default "password" -}} +{{- $certs := .Values.application.certificates | default dict -}} +{{- $certKeys := $certs.secretKeys | default dict -}} +{{- $doiadminKey := $certKeys.doiadmin | default "doiadmin.pem" -}} +{{- $cadcproxyKey := $certKeys.cadcproxy | default "cadcproxy.pem" -}} +{{- $cookieKey := .Values.application.cookieSignaturePublicKey | default dict -}} +{{- $cookieKeySecret := $cookieKey.existingSecret | default dict -}} +{{- $cookieKeySecretName := trim (($cookieKeySecret.name | default "") | toString) -}} +{{- $cookieKeyPath := trim (($cookieKeySecret.path | default "RsaSignaturePub.key") | toString) -}} +{{- if empty $cookieKeyPath -}} +{{- $cookieKeyPath = "RsaSignaturePub.key" -}} +{{- end -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + run: {{ .Release.Name }}-tomcat + {{- include "doi.labels" . | nindent 4 }} + name: {{ .Release.Name }}-tomcat + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ default 1 .Values.replicaCount }} + selector: + matchLabels: + run: {{ .Release.Name }}-tomcat + template: + metadata: + labels: + run: {{ .Release.Name }}-tomcat + {{- include "doi.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "doi.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automount }} + {{- with .Values.application.nodeAffinity }} + affinity: + nodeAffinity: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- $podSC := merge (.Values.volumeInit.podSecurityContext | default dict) (.Values.podSecurityContext | default dict) }} + {{- if not (empty $podSC) }} + securityContext: + {{- toYaml $podSC | nindent 8 }} + {{- end }} + initContainers: + - name: merge-doi-config + image: {{ .Values.volumeInit.image | quote }} + imagePullPolicy: {{ .Values.volumeInit.imagePullPolicy }} + command: ['sh', '-c'] + args: + - | + set -e + cp -R /config-src/. /config-dst/ + cp "/certs/${DOIADMIN_KEY}" /config-dst/doiadmin.pem + cp "/certs/${CADCPROXY_KEY}" /config-dst/cadcproxy.pem + USER=$(tr -d '\n' < "/datacite/${USERNAME_KEY}") + PASS=$(tr -d '\n' < "/datacite/${PASSWORD_KEY}") + printf '\nca.nrc.cadc.doi.datacite.username = %s\n' "$USER" >> /config-dst/doi.properties + printf 'ca.nrc.cadc.doi.datacite.password = %s\n' "$PASS" >> /config-dst/doi.properties + env: + - name: USERNAME_KEY + value: {{ $usernameKey | quote }} + - name: PASSWORD_KEY + value: {{ $passwordKey | quote }} + - name: DOIADMIN_KEY + value: {{ $doiadminKey | quote }} + - name: CADCPROXY_KEY + value: {{ $cadcproxyKey | quote }} + volumeMounts: + - name: config-source + mountPath: /config-src + readOnly: true + - name: datacite-secret + mountPath: /datacite + readOnly: true + - name: certificate-secret + mountPath: /certs + readOnly: true + - name: config-merged + mountPath: /config-dst + {{- with .Values.volumeInit.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + containers: + - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + name: {{ .Release.Name }}-tomcat + resources: + requests: + memory: {{ .Values.application.resources.requests.memory }} + cpu: {{ .Values.application.resources.requests.cpu }} + limits: + memory: {{ .Values.application.resources.limits.memory }} + cpu: {{ .Values.application.resources.limits.cpu }} + securityContext: + {{- $tomcatSC := merge (dict "allowPrivilegeEscalation" false) (.Values.securityContext | default dict) }} + {{- toYaml $tomcatSC | nindent 12 }} + {{- with .Values.application.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ $containerPort }} + protocol: TCP + {{- with .Values.application.extraPorts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: "/config" + name: config-merged + {{- with .Values.application.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.startupProbe }} + startupProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.application.extraHosts }} + hostAliases: + {{- range $extraHost := . }} + - ip: {{ $extraHost.ip }} + hostnames: + - {{ $extraHost.hostname }} + {{- end }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config-source + {{- if $cookieKeySecretName }} + projected: + sources: + - configMap: + name: {{ .Release.Name }}-config + - secret: + name: {{ $cookieKeySecretName }} + items: + - key: RsaSignaturePub.key + path: {{ $cookieKeyPath | quote }} + {{- else }} + configMap: + name: {{ .Release.Name }}-config + {{- end }} + - name: datacite-secret + secret: + secretName: {{ include "doi.dataciteAuthSecretName" . }} + - name: certificate-secret + secret: + secretName: {{ include "doi.certificateSecretName" . }} + - name: config-merged + emptyDir: {} + {{- with .Values.application.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/doi/helm/templates/httproute.yaml b/doi/helm/templates/httproute.yaml new file mode 100644 index 0000000..0bc79dd --- /dev/null +++ b/doi/helm/templates/httproute.yaml @@ -0,0 +1,39 @@ +{{- if .Values.httpRoute.enabled -}} +{{- $serviceName := printf "%s-tomcat-svc" .Release.Name -}} +{{- $servicePort := .Values.service.port -}} +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ .Release.Name }}-httproute + namespace: {{ .Release.Namespace }} + labels: + {{- include "doi.labels" . | nindent 4 }} + {{- with .Values.httpRoute.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- with .Values.httpRoute.parentRefs }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.httpRoute.hostnames }} + hostnames: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- range .Values.httpRoute.rules }} + {{- with .matches }} + - matches: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .filters }} + filters: + {{- toYaml . | nindent 8 }} + {{- end }} + backendRefs: + - name: {{ $serviceName }} + port: {{ $servicePort }} + weight: 1 + {{- end }} +{{- end }} diff --git a/doi/helm/templates/ingress.yaml b/doi/helm/templates/ingress.yaml new file mode 100644 index 0000000..31fbc3e --- /dev/null +++ b/doi/helm/templates/ingress.yaml @@ -0,0 +1,32 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Release.Name }}-ingress + namespace: {{ .Release.Namespace }} + labels: + {{- include "doi.labels" . | nindent 4 }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- with .Values.ingress.tls }} + tls: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $.Release.Name }}-tomcat-svc + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/doi/helm/templates/service.yaml b/doi/helm/templates/service.yaml new file mode 100644 index 0000000..7774861 --- /dev/null +++ b/doi/helm/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-tomcat-svc + namespace: {{ .Release.Namespace }} + labels: + run: {{ .Release.Name }}-tomcat-svc + {{- include "doi.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.port }} + name: http + protocol: TCP + selector: + run: {{ .Release.Name }}-tomcat diff --git a/doi/helm/templates/serviceaccount.yaml b/doi/helm/templates/serviceaccount.yaml new file mode 100644 index 0000000..7416370 --- /dev/null +++ b/doi/helm/templates/serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "doi.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "doi.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/doi/helm/templates/tests/test-connection.yaml b/doi/helm/templates/tests/test-connection.yaml new file mode 100644 index 0000000..71a9e22 --- /dev/null +++ b/doi/helm/templates/tests/test-connection.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-test-connection" + namespace: {{ .Release.Namespace }} + labels: + {{- include "doi.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox:1.36 + command: ['wget'] + args: ['{{ .Release.Name }}-tomcat-svc:{{ .Values.service.port }}{{ .Values.application.availabilityPath }}'] + restartPolicy: Never diff --git a/doi/helm/values.yaml b/doi/helm/values.yaml new file mode 100644 index 0000000..4b0a835 --- /dev/null +++ b/doi/helm/values.yaml @@ -0,0 +1,197 @@ +kubernetesClusterDomain: cluster.local + +replicaCount: 1 + +image: + repository: bucket.canfar.net/doi + pullPolicy: IfNotPresent + tag: "1.2.0" + +imagePullSecrets: [] + +nameOverride: "" +fullnameOverride: "" + +podSecurityContext: {} + +securityContext: {} + +application: + # Optional rename of the application from the default "doi". + applicationName: "doi" + + # The endpoint to serve this from. If applicationName is changed, this should match. + endpoint: "/doi" + + # VOSI endpoint used by Kubernetes health probes and the Helm test. + availabilityPath: "/doi/availability" + + # Set the Registry URL pointing to the desired registry (https:// URL). + # registryURL: https://example.org/reg + + # ID (URI) of the GMS Service. Required for auth-related registry lookups. + # gmsID: ivo://example.org/gms + + # URI or URL of the OIDC (IAM) server. Used to validate incoming tokens. + # oidcURI: https://example.org/oidc + + # The IdentityManager class handling authentication. + identityManagerClass: org.opencadc.auth.StandardIdentityManager + + config: + # VOSpace URI to the parent DOI folder. + vospaceParentUri: "vos://example.org~arc/doi" + + # Prefix prepended to the DOI name for metadata stored in VOSpace. + metaDataPrefix: "doi" + + # Prefix prepended to the DOI name to create the backing GMS group name. + groupPrefix: "doi" + + # DOI landing page URL. + landingUrl: "https://example.org/doi" + + # DataCite MDS REST endpoint. + mdsUrl: "https://mds.datacite.org" + + # Registered prefix for the DataCite account. + accountPrefix: "" + + # Optional DOI identifier prefix. + doiIdentifierPrefix: "" + + # Optional publisher group URI for alternative DOI settings. + publisherGroupURI: "" + + # Optional self-publish flag for alternative DOI settings. + selfPublish: "" + + # Developer testing only. + randomTestID: false + + datacite: + auth: + # Existing Secret containing DataCite credentials. + existingSecret: "doi-datacite" + secretKeys: + username: username + password: password + + certificates: + # Existing Secret containing doiadmin.pem and cadcproxy.pem. + existingSecret: "doi-certs" + secretKeys: + doiadmin: doiadmin.pem + cadcproxy: cadcproxy.pem + + # Mount an RSA public key for browser cookie validation from a Secret. + # The Secret data key must be RsaSignaturePub.key. Leave the Secret name + # empty when cookie validation is not required. + cookieSignaturePublicKey: + existingSecret: + name: "" + # Filename under /config. Defaults to RsaSignaturePub.key when empty. + path: "" + + # Optionally set the DEBUG port. + # extraEnv: + # - name: CATALINA_OPTS + # value: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5555" + # extraPorts: + # - containerPort: 5555 + # protocol: TCP + + # This applies to the DOI service pod. + # nodeAffinity: {} + + # Optionally mount additional config or certificates. + # extraVolumeMounts: + # - mountPath: "/config/cacerts" + # name: cacert-volume + # extraVolumes: + # - name: cacert-volume + # secret: + # defaultMode: 420 + # secretName: doi-cacert-secret + + # Groups that can alter logging. Empty array means nobody can alter it. + loggingGroups: [] + + resources: + requests: + memory: "500Mi" + cpu: "500m" + limits: + memory: "1Gi" + cpu: "750m" + + # Specify extra hostnames that will be added to the Pod's /etc/hosts file. + # extraHosts: + # - ip: 127.3.34.5 + # hostname: myhost.example.org + # extraHosts: [] + +tolerations: [] + +service: + type: ClusterIP + port: 8080 + +ingress: + enabled: false + className: "" + hosts: + - host: chart-example.local + paths: + - path: /doi + pathType: Prefix + tls: [] + +# Expose the service with a Kubernetes Gateway API HTTPRoute. +httpRoute: + enabled: false + annotations: {} + parentRefs: + - name: gateway + sectionName: http + # namespace: default + hostnames: + - chart-example.local + rules: + - matches: + - path: + type: PathPrefix + value: /doi + +volumeInit: + image: busybox:1.36 + imagePullPolicy: IfNotPresent + securityContext: {} + podSecurityContext: {} + +serviceAccount: + create: false + automount: false + annotations: {} + name: "" + +livenessProbe: + httpGet: + path: /doi/availability + port: http + periodSeconds: 30 + +readinessProbe: + httpGet: + path: /doi/availability + port: http + periodSeconds: 15 + +startupProbe: + httpGet: + path: /doi/availability + port: http + initialDelaySeconds: 10 + timeoutSeconds: 30 + periodSeconds: 10 + failureThreshold: 30