diff --git a/templates/_utils.tpl b/templates/_utils.tpl index 29aa9f0..dfd245b 100644 --- a/templates/_utils.tpl +++ b/templates/_utils.tpl @@ -81,3 +81,24 @@ helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | quote }} {{ include "opal.pgsqlSelectorLabels" . }} {{- end -}} +{{/* +Create the name of the server service account to use +*/}} +{{- define "opal.serverServiceAccountName" -}} +{{- if .Values.server.serviceAccount.create }} +{{- default (include "opal.serverName" .) .Values.server.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.server.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the client service account to use +*/}} +{{- define "opal.clientServiceAccountName" -}} +{{- if .Values.client.serviceAccount.create }} +{{- default (include "opal.clientName" .) .Values.client.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.client.serviceAccount.name }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/deployment-client.yaml b/templates/deployment-client.yaml index 45a982a..ecdbbca 100644 --- a/templates/deployment-client.yaml +++ b/templates/deployment-client.yaml @@ -21,6 +21,11 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + serviceAccountName: {{ include "opal.clientServiceAccountName" . }} + {{- with .Values.client.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} {{- if .Values.client.opaStartupData }} volumes: - name: opa-startup-data @@ -30,6 +35,10 @@ spec: {{- end }} containers: - name: opal-client + {{- with .Values.client.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} image: {{ include "opal.clientImage" . | quote }} imagePullPolicy: {{ .Values.client.imagePullPolicy | default "IfNotPresent" | quote }} ports: diff --git a/templates/deployment-pgsql.yaml b/templates/deployment-pgsql.yaml index bded5c6..b732320 100644 --- a/templates/deployment-pgsql.yaml +++ b/templates/deployment-pgsql.yaml @@ -20,10 +20,18 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.pgsql.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} containers: - name: pgsql image: {{ include "opal.pgsqlImage" . | quote }} imagePullPolicy: IfNotPresent + {{- with .Values.pgsql.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} ports: - name: pgsql containerPort: 5432 diff --git a/templates/deployment-server.yaml b/templates/deployment-server.yaml index b159ad1..7392ec3 100644 --- a/templates/deployment-server.yaml +++ b/templates/deployment-server.yaml @@ -21,6 +21,11 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} + serviceAccountName: {{ include "opal.serverServiceAccountName" . }} + {{- with .Values.server.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} {{- if .Values.e2e }} volumes: - name: e2e @@ -34,6 +39,10 @@ spec: - name: git-init image: {{ include "opal.serverImage" . | quote }} imagePullPolicy: IfNotPresent + {{- with .Values.server.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} volumeMounts: - mountPath: /opt/e2e name: e2e @@ -63,6 +72,10 @@ spec: - name: opal-server image: {{ include "opal.serverImage" . | quote }} imagePullPolicy: {{ .Values.server.imagePullPolicy | default "IfNotPresent" | quote }} + {{- with .Values.server.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} {{- if .Values.e2e }} volumeMounts: - mountPath: /opt/e2e/policy-repo-data diff --git a/templates/ingress-client.yaml b/templates/ingress-client.yaml new file mode 100644 index 0000000..8025364 --- /dev/null +++ b/templates/ingress-client.yaml @@ -0,0 +1,43 @@ +{{- if .Values.client.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "opal.clientName" . }} + labels: + {{- include "opal.clientLabels" . | nindent 4 }} + {{- with .Values.client.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.client.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- if .Values.client.ingress.tls }} + tls: + {{- range .Values.client.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.client.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- with .pathType }} + pathType: {{ . }} + {{- end }} + backend: + service: + name: {{ include "opal.clientName" $ }} + port: + number: {{ .port }} + {{- end }} + {{- end }} +{{- end }} diff --git a/templates/serviceaccount-client.yaml b/templates/serviceaccount-client.yaml new file mode 100644 index 0000000..f473c5e --- /dev/null +++ b/templates/serviceaccount-client.yaml @@ -0,0 +1,13 @@ +{{- if .Values.client.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "opal.clientServiceAccountName" . }} + labels: + {{- include "opal.clientLabels" . | nindent 4 }} + {{- with .Values.client.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.client.serviceAccount.automount }} +{{- end }} diff --git a/templates/serviceaccount-server.yaml b/templates/serviceaccount-server.yaml new file mode 100644 index 0000000..2256bc8 --- /dev/null +++ b/templates/serviceaccount-server.yaml @@ -0,0 +1,13 @@ +{{- if .Values.server.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "opal.serverServiceAccountName" . }} + labels: + {{- include "opal.serverLabels" . | nindent 4 }} + {{- with .Values.server.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.server.serviceAccount.automount }} +{{- end }} diff --git a/values.schema.json b/values.schema.json index f138b52..d8ada56 100644 --- a/values.schema.json +++ b/values.schema.json @@ -5,7 +5,9 @@ "definitions": { "DataSourceEntry": { - "type": "object", "title": "DataSourceEntry", "additionalProperties": true, + "type": "object", + "title": "DataSourceEntry", + "additionalProperties": true, "properties": { "url": {"type": "string", "title": "url source to query for data"}, "topics": {"type": "array", "title": "topics the data applies to", "items": { "type": "string" }}, @@ -15,13 +17,19 @@ } }, "ServerDataSourceConfig": { - "type": "object", "title": "ServerDataSourceConfig", "additionalProperties": false, + "type": "object", + "title": "ServerDataSourceConfig", + "additionalProperties": false, "properties": { "config": { - "type": ["object", "null"], "title": "DataSourceConfig", "additionalProperties": false, + "type": ["object", "null"], + "title": "DataSourceConfig", + "additionalProperties": false, "properties": { "entries": { - "type": "array", "title": "list of data sources", "default": [], + "type": "array", + "title": "list of data sources", + "default": [], "items": { "$ref": "#/definitions/DataSourceEntry" } } } @@ -31,58 +39,35 @@ } }, - "type": "object", "required": ["image"], + "type": "object", + "required": ["image"], "properties": { "image": { - "type": "object", "title": "image", "additionalProperties": false, + "type": "object", + "title": "image", + "additionalProperties": false, "required": ["server", "client", "pgsql"], "properties": { "server": { - "type": "object", "title": "server", "additionalProperties": false, + "type": "object", + "title": "server", + "additionalProperties": false, "properties": { - "registry": { - "type": "string", - "default": "docker.io", - "title": "server docker image registry" - }, - "repository": { - "type": "string", - "default": "permitio/opal-server", - "title": "server docker image repository" - }, - "tag": { - "type": "string", - "title": "server docker image tag. defaults to chart appVersion" - }, - "pullSecrets": { - "type": "array", - "default": [], - "title": "server docker image pull secrets" - } + "registry": {"type": "string", "default": "docker.io", "title": "server docker image registry"}, + "repository": {"type": "string", "default": "permitio/opal-server", "title": "server docker image repository"}, + "tag": {"type": "string", "title": "server docker image tag. defaults to chart appVersion"}, + "pullSecrets": {"type": "array", "default": [], "title": "server docker image pull secrets"} } }, "client": { - "type": "object", "title": "client", "additionalProperties": false, + "type": "object", + "title": "client", + "additionalProperties": false, "properties": { - "registry": { - "type": "string", - "default": "docker.io", - "title": "client docker image registry" - }, - "repository": { - "type": "string", - "default": "permitio/opal-client", - "title": "client docker image repository" - }, - "tag": { - "type": "string", - "title": "client docker image tag. defaults to chart appVersion" - }, - "pullSecrets": { - "type": "array", - "default": [], - "title": "client docker image pull secrets" - } + "registry": {"type": "string", "default": "docker.io", "title": "client docker image registry"}, + "repository": {"type": "string", "default": "permitio/opal-client", "title": "client docker image repository"}, + "tag": {"type": "string", "title": "client docker image tag. defaults to chart appVersion"}, + "pullSecrets": {"type": "array", "default": [], "title": "client docker image pull secrets"} } }, "pgsql": { @@ -90,136 +75,101 @@ "title": "pgsql", "additionalProperties": false, "properties": { - "registry": { - "type": "string", - "default": "docker.io", - "title": "pgsql docker image registry" - }, - "repository": { - "type": "string", - "default": "postgres", - "title": "pgsql docker image repository" - }, - "tag": { - "type": "string", - "default": "alpine", - "title": "pgsql docker image tag" - }, - "pullSecrets": { - "type": "array", - "default": [], - "title": "pgsql docker image pull secrets" - } + "registry": {"type": "string", "default": "docker.io", "title": "pgsql docker image registry"}, + "repository": {"type": "string", "default": "postgres", "title": "pgsql docker image repository"}, + "tag": {"type": "string", "default": "alpine", "title": "pgsql docker image tag"}, + "pullSecrets": {"type": "array", "default": [], "title": "pgsql docker image pull secrets"} } } } }, "server": { - "type": ["null", "object"], "additionalProperties": false, "title": "opal server settings", + "type": ["null", "object"], + "additionalProperties": false, + "title": "opal server settings", "required": ["port", "policyRepoUrl", "pollingInterval", "dataConfigSources", "broadcastPgsql", "uvicornWorkers", "replicas"], "properties": { - "enabled": { - "type": "boolean", "title": "enable server", "default": true - }, - "port": { - "type": "integer", "title": "server listening port", "default": 7002 - }, - "policyRepoUrl": { - "type": "string", "title": "policy repo url", - "default":"https://github.com/permitio/opal-example-policy-repo" - }, - "policyRepoSshKey": { - "type": ["null", "string"], "title": "policy SSH key","default": null - }, - "policyRepoClonePath": { - "type": ["null", "string"], "title": "policy clone path","default": null - }, - "policyRepoMainBranch": { - "type": ["null", "string"], "title": "policy main branch","default": null - }, - "pollingInterval": { - "type": "integer", "title": "polling interval (sec)", "default": 30 - }, + "enabled": {"type": "boolean", "title": "enable server", "default": true}, + "port": {"type": "integer", "title": "server listening port", "default": 7002}, + "policyRepoUrl": {"type": "string", "title": "policy repo url", "default": "https://github.com/permitio/opal-example-policy-repo"}, + "policyRepoSshKey": {"type": ["null", "string"], "title": "policy SSH key", "default": null}, + "policyRepoClonePath": {"type": ["null", "string"], "title": "policy clone path", "default": null}, + "policyRepoMainBranch": {"type": ["null", "string"], "title": "policy main branch", "default": null}, + "pollingInterval": {"type": "integer", "title": "polling interval (sec)", "default": 30}, "dataConfigSources": {"$ref": "#/definitions/ServerDataSourceConfig"}, - "broadcastUri": { - "type": ["null", "string"], "title": "broadcast url", "default": null - }, - "broadcastPgsql": { - "type": "boolean", "title": "install broadcast pgsql", "default": true - }, - "broadcastReplicas": { - "type": "integer", "title": "replicas for broadcast pgsql", "default": 1 - }, - "uvicornWorkers": { - "type": "integer", "title": "num of uvicorn workers per pod", "default": 4 - }, - "replicas": { - "type": "integer", "title": "num of replicas", "default": 1 - }, - "extraEnv": { - "type": "object", "title": "extra environment variables list", "default": null - }, - "secrets": { - "type": "array", - "title": "name of a kubernetes secret from where to fetch secret environment variables.", - "default": null, - "items": { "type": "string" } - }, - "resources": { - "type": "object", - "title": "resources", - "default": null - }, - "imagePullPolicy": { - "type": "string", - "default": "IfNotPresent", - "title": "when kubelet should pull specified image" - } + "broadcastUri": {"type": ["null", "string"], "title": "broadcast url", "default": null}, + "broadcastPgsql": {"type": "boolean", "title": "install broadcast pgsql", "default": true}, + "broadcastReplicas": {"type": "integer", "title": "replicas for broadcast pgsql", "default": 1}, + "uvicornWorkers": {"type": "integer", "title": "num of uvicorn workers per pod", "default": 4}, + "replicas": {"type": "integer", "title": "num of replicas", "default": 1}, + "extraEnv": {"type": "object", "title": "extra environment variables list", "default": null}, + "secrets": {"type": "array", "title": "name of a kubernetes secret from where to fetch secret environment variables.", "default": null, "items": {"type": "string"}}, + "resources": {"type": "object", "title": "resources", "default": null}, + "imagePullPolicy": {"type": "string", "default": "IfNotPresent", "title": "when kubelet should pull specified image"}, + "podSecurityContext": {"type": "object", "title": "pod security context", "default": {}}, + "securityContext": {"type": "object", "title": "container security context", "default": {}}, + "serviceAccount": {"type": "object", "title": "service account configuration", "default": {}} } }, "client": { - "type": ["null", "object"], "additionalProperties": false, "title": "opal client settings", + "type": ["null", "object"], + "additionalProperties": false, + "title": "opal client settings", "required": ["port", "opaPort", "replicas"], "properties": { - "enabled": { - "type": "boolean", "title": "enable client", "default": true - }, - "port": { - "type": "integer", "title": "client rest port", "default": 7000 - }, - "opaPort": { - "type": "integer", "title": "client embedded opa port", "default": 8181 - }, - "replicas": { - "type": "integer", "title": "num of replicas", "default": 1 - }, - "extraEnv": { - "type": "object", "title": "extra environment variables list", "default": null - }, - "opaStartupData": { - "type": "object", "title": "client startup data for embedded opa", "default": null - }, - "serverUrl": { - "type": "string", - "title": "opal server url for client to connect to" - }, - "secrets": { - "type": "array", - "title": "name of a kubernetes secret from where to fetch secret environment variables.", - "default": null, - "items": { "type": "string" } - }, - "resources": { + "enabled": {"type": "boolean", "title": "enable client", "default": true}, + "port": {"type": "integer", "title": "client rest port", "default": 7000}, + "opaPort": {"type": "integer", "title": "client embedded opa port", "default": 8181}, + "replicas": {"type": "integer", "title": "num of replicas", "default": 1}, + "extraEnv": {"type": "object", "title": "extra environment variables list", "default": null}, + "opaStartupData": {"type": "object", "title": "client startup data for embedded opa", "default": null}, + "serverUrl": {"type": "string", "title": "opal server url for client to connect to"}, + "secrets": {"type": "array", "title": "name of a kubernetes secret from where to fetch secret environment variables.", "default": null, "items": {"type": "string"}}, + "resources": {"type": "object", "title": "resources", "default": null}, + "imagePullPolicy": {"type": "string", "default": "IfNotPresent", "title": "when kubelet should pull specified image"}, + "podSecurityContext": {"type": "object", "title": "pod security context", "default": {}}, + "securityContext": {"type": "object", "title": "container security context", "default": {}}, + "serviceAccount": {"type": "object", "title": "service account configuration", "default": {}}, + "ingress": { "type": "object", - "title": "resources", - "default": null - }, - "imagePullPolicy": { - "type": "string", - "default": "IfNotPresent", - "title": "when kubelet should pull specified image" + "title": "Ingress configuration", + "properties": { + "enabled": {"type": "boolean", "default": false}, + "annotations": {"type": "object", "additionalProperties": {"type": "string"}}, + "hosts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": {"type": "string"}, + "paths": { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": {"type": "string"}, + "pathType": {"type": "string", "default": "ImplementationSpecific"} + }, + "required": ["path"] + } + } + }, + "required": ["host"] + } + } + } } } + }, + "pgsql": { + "type": ["null", "object"], + "additionalProperties": false, + "title": "opal pgsql settings", + "required": [], + "properties": { + "podSecurityContext": {"type": "object", "title": "pod security context", "default": {}}, + "securityContext": {"type": "object", "title": "container security context", "default": {}} + } } } } diff --git a/values.yaml b/values.yaml index dd6b9ff..a600e78 100644 --- a/values.yaml +++ b/values.yaml @@ -43,6 +43,29 @@ server: # "CUSTOM_ENV_VAR": "VALUE" } + # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ + serviceAccount: + # Specifies whether a service account should be created + create: false + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + + podSecurityContext: {} + # fsGroup: 2000 + + securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + client: port: 7000 opaPort: 8181 @@ -50,3 +73,60 @@ client: # If you need to specify a custom hostname for the opal-sever, configure the serverUrl property # serverUrl: http://custom-hostname-for-opal:opal-port extraEnv: {} + + # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ + ingress: + enabled: false + className: "" + annotations: + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 + hosts: + - host: opal-example.local + paths: + - path: /opa(/|$)(.*) + pathType: ImplementationSpecific + port: 8181 + - path: /client(/|$)(.*) + pathType: ImplementationSpecific + port: 7002 + tls: [] + # - secretName: opal-example-tls + # hosts: + # - opal-example.local + + # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ + serviceAccount: + # Specifies whether a service account should be created + create: false + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + + podSecurityContext: {} + # fsGroup: 2000 + + securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +pgsql: + podSecurityContext: {} + # fsGroup: 2000 + + securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 \ No newline at end of file