Commit a447bcdc by Denise Schannon Committed by Craig Jellick

remove harbor

parent 12e82e39
docs/*
.git/*
.gitignore
CONTRIBUTING.md
# Contributing to Helm Chart for Harbor
Please follow [Harbor contributing guide](https://github.com/goharbor/harbor/blob/master/CONTRIBUTING.md) to learn how to make code contribution.
# Contributers
Thanks very much to all contributers who submitted pull requests to Helm Chart for Harbor.
- [Paul Czarkowski @paulczar](https://github.com/paulczar)
- [Luca Innocenti Mirri @lucaim](https://github.com/lucaim)
- [Steven Arnott @ArcticSnowman](https://github.com/ArcticSnowman)
- [Alex M @draeron](https://github.com/draeron)
- [SangJun Yun](https://github.com/YunSangJun)
name: harbor
version: 1.7.5-rancher1
appVersion: 1.7.5
description: An open source trusted cloud native registry that stores, signs, and scans content
keywords:
- docker
- registry
- harbor
home: https://goharbor.io
icon: https://raw.githubusercontent.com/goharbor/harbor/master/docs/img/harbor_logo.png
sources:
- https://github.com/goharbor/harbor
- https://github.com/goharbor/harbor-helm
maintainers:
- name: Rancher
email: support@rancher.com
engine: gotpl
Please wait for several minutes for Harbor deployment to complete.
{{- if .Values.globalRegistryMode -}}
Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}.
{{- else -}}
Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}/registry.
{{- end -}}
For more details, please visit https://github.com/goharbor/harbor.
\ No newline at end of file
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.adminserver" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: adminserver
data:
DATABASE_TYPE: "postgresql"
POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}"
POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}"
POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}"
POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}"
POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}"
EXT_ENDPOINT: "{{ template "harbor.externalURL" . }}"
CORE_URL: "http://{{ template "harbor.core" . }}"
JOBSERVICE_URL: "http://{{ template "harbor.fullname" . }}-jobservice"
REGISTRY_URL: "http://{{ template "harbor.registry" . }}:5000"
TOKEN_SERVICE_URL: "http://{{ template "harbor.core" . }}/service/token"
WITH_NOTARY: "{{ .Values.notary.enabled }}"
NOTARY_URL: "http://{{ template "harbor.notary-server" . }}:4443"
LOG_LEVEL: "{{ .Values.logLevel }}"
IMAGE_STORE_PATH: "/" # This is a temporary hack.
CFG_EXPIRATION: "5"
ADMIRAL_URL: "NA"
RESET: "false"
WITH_CLAIR: "{{ .Values.clair.enabled }}"
CLAIR_DB_HOST: "{{ template "harbor.database.host" . }}"
CLAIR_DB_PORT: "{{ template "harbor.database.port" . }}"
CLAIR_DB_USERNAME: "{{ template "harbor.database.username" . }}"
CLAIR_DB: "{{ template "harbor.database.clairDatabase" . }}"
CLAIR_URL: "http://{{ template "harbor.fullname" . }}-clair:6060"
CLAIR_DB_SSLMODE: "{{ template "harbor.database.sslmode" . }}"
REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.imageChartStorage.type }}"
WITH_CHARTMUSEUM: "{{ .Values.chartmuseum.enabled }}"
CHART_REPOSITORY_URL: "http://{{ template "harbor.chartmuseum" . }}"
# The following properties are for Harbor configurations
AUTH_MODE: "db_auth"
SELF_REGISTRATION: "on"
PROJECT_CREATION_RESTRICTION: "everyone"
TOKEN_EXPIRATION: "30"
EMAIL_HOST: "smtp.mydomain.com"
EMAIL_FROM: "admin <sample_admin@mydomain.com>"
EMAIL_PORT: "25"
\ No newline at end of file
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ template "harbor.adminserver" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: adminserver
spec:
replicas: {{ .Values.adminserver.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: adminserver
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: adminserver
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/adminserver/adminserver-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/adminserver/adminserver-secrets.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
{{- if .Values.adminserver.podAnnotations }}
{{ toYaml .Values.adminserver.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: adminserver
image: {{ template "system_default_registry" . }}{{ .Values.adminserver.image.repository }}:{{ .Values.adminserver.image.tag }}
imagePullPolicy: "{{ .Values.imagePullPolicy }}"
livenessProbe:
httpGet:
path: /api/ping
port: 8080
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/ping
port: 8080
initialDelaySeconds: 1
periodSeconds: 10
resources:
{{ toYaml .Values.adminserver.resources | indent 10 }}
envFrom:
- configMapRef:
name: "{{ template "harbor.adminserver" . }}"
- secretRef:
name: "{{ template "harbor.adminserver" . }}"
env:
- name: PORT
value: "8080"
- name: JSON_CFG_STORE_PATH
value: /etc/adminserver/config/config.json
- name: KEY_PATH
value: /etc/adminserver/key
- name: CORE_SECRET
valueFrom:
secretKeyRef:
name: "{{ template "harbor.core" . }}"
key: secret
- name: JOBSERVICE_SECRET
valueFrom:
secretKeyRef:
name: "{{ template "harbor.jobservice" . }}"
key: secret
ports:
- containerPort: 8080
volumeMounts:
- name: adminserver-key
mountPath: /etc/adminserver/key
subPath: key
volumes:
- name: adminserver-key
secret:
secretName: "{{ template "harbor.adminserver" . }}"
items:
- key: secretKey
path: key
{{- with .Values.adminserver.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.adminserver.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.adminserver.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.adminserver" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: adminserver
type: Opaque
data:
secretKey: {{ .Values.secretKey | b64enc | quote }}
HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }}
POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{ if .Values.clair.enabled }}
CLAIR_DB_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{ end }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "harbor.adminserver" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 8080
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: adminserver
{{- if .Values.chartmuseum.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.chartmuseum" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
data:
PORT: "9999"
CACHE: "redis"
CACHE_REDIS_ADDR: "{{ template "harbor.redis.host" . }}:{{ template "harbor.redis.port" . }}"
CACHE_REDIS_DB: "{{ template "harbor.redis.chartmuseumDatabaseIndex" . }}"
BASIC_AUTH_USER: "chart_controller"
DEPTH: "1"
{{- if eq .Values.logLevel "debug" }}
DEBUG: "true"
{{- else }}
DEBUG: "false"
{{- end }}
LOG_JSON: "true"
DISABLE_METRICS: "false"
DISABLE_API: "false"
DISABLE_STATEFILES: "false"
ALLOW_OVERWRITE: "true"
#CHART_URL: {{ template "harbor.externalURL" . }}/chartrepo
AUTH_ANONYMOUS_GET: "false"
TLS_CERT:
TLS_KEY:
CONTEXT_PATH:
INDEX_LIMIT: "0"
MAX_STORAGE_OBJECTS: "0"
MAX_UPLOAD_SIZE: "20971520"
CHART_POST_FORM_FIELD_NAME: "chart"
PROV_POST_FORM_FIELD_NAME: "prov"
{{- $storage := .Values.imageChartStorage }}
{{- $storageType := $storage.type }}
{{- if eq $storageType "filesystem" }}
STORAGE: "local"
STORAGE_LOCAL_ROOTDIR: "/chart_storage"
{{- else if eq $storageType "azure" }}
STORAGE: "microsoft"
STORAGE_MICROSOFT_CONTAINER: {{ $storage.azure.container }}
AZURE_STORAGE_ACCOUNT: {{ $storage.azure.accountname }}
STORAGE_MICROSOFT_PREFIX: "/azure/harbor/charts"
{{- else if eq $storageType "gcs" }}
STORAGE: "google"
STORAGE_GOOGLE_BUCKET: {{ $storage.gcs.bucket }}
GOOGLE_APPLICATION_CREDENTIALS: /etc/chartmuseum/gcs-key.json
{{- if $storage.gcs.rootdirectory }}
STORAGE_GOOGLE_PREFIX: {{ $storage.gcs.rootdirectory }}
{{- end }}
{{- else if eq $storageType "s3" }}
STORAGE: "amazon"
STORAGE_AMAZON_BUCKET: {{ $storage.s3.bucket }}
{{- if $storage.s3.rootdirectory }}
STORAGE_AMAZON_PREFIX: {{ $storage.s3.rootdirectory }}
{{- end }}
STORAGE_AMAZON_REGION: {{ $storage.s3.region }}
{{- if $storage.s3.regionendpoint }}
STORAGE_AMAZON_ENDPOINT: {{ $storage.s3.regionendpoint }}
{{- end }}
{{- if $storage.s3.accesskey }}
AWS_ACCESS_KEY_ID: {{ $storage.s3.accesskey }}
{{- end }}
{{- else if eq $storageType "swift" }}
STORAGE: "openstack"
STORAGE_OPENSTACK_CONTAINER: {{ $storage.swift.container }}
{{- if $storage.swift.secretkey }}
STORAGE_OPENSTACK_PREFIX: {{ $storage.swift.prefix }}
{{- end }}
{{- if $storage.swift.secretkey }}
STORAGE_OPENSTACK_REGION: {{ $storage.swift.region }}
{{- end }}
OS_AUTH_URL: {{ $storage.swift.authurl }}
OS_USERNAME: {{ $storage.swift.username }}
{{- if $storage.swift.secretkey }}
OS_PROJECT_ID: {{ $storage.swift.tenantid }}
{{- end }}
{{- if $storage.swift.secretkey }}
OS_PROJECT_NAME: {{ $storage.swift.tenant }}
{{- end }}
{{- if $storage.swift.secretkey }}
OS_DOMAIN_ID: {{ $storage.swift.domainid }}
{{- end }}
{{- if $storage.swift.secretkey }}
OS_DOMAIN_NAME: {{ $storage.swift.domain }}
{{- end }}
{{- else if eq $storageType "oss" }}
STORAGE: "alibaba"
STORAGE_ALIBABA_BUCKET: {{ $storage.oss.bucket }}
{{- if $storage.oss.secretkey }}
STORAGE_ALIBABA_PREFIX: {{ $storage.oss.rootdirectory }}
{{- end }}
{{- if $storage.oss.secretkey }}
STORAGE_ALIBABA_ENDPOINT: {{ $storage.oss.endpoint }}
{{- end }}
ALIBABA_CLOUD_ACCESS_KEY_ID: {{ $storage.oss.accesskeyid }}
{{- end }}
{{- end }}
\ No newline at end of file
{{- if .Values.chartmuseum.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ template "harbor.chartmuseum" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: chartmuseum
spec:
replicas: {{ .Values.chartmuseum.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: chartmuseum
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: chartmuseum
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-secret.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if .Values.chartmuseum.podAnnotations }}
{{ toYaml .Values.chartmuseum.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: chartmuseum
image: {{ template "system_default_registry" . }}{{ .Values.chartmuseum.image.repository }}:{{ .Values.chartmuseum.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
httpGet:
path: /health
port: 9999
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 9999
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.chartmuseum.resources }}
resources:
{{ toYaml .Values.chartmuseum.resources | indent 10 }}
{{- end }}
envFrom:
- configMapRef:
name: "{{ template "harbor.chartmuseum" . }}"
- secretRef:
name: "{{ template "harbor.chartmuseum" . }}"
env:
- name: BASIC_AUTH_PASS
valueFrom:
secretKeyRef:
name: {{ template "harbor.core" . }}
key: secret
ports:
- containerPort: 9999
volumeMounts:
- name: chartmuseum-data
mountPath: /chart_storage
subPath: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.subPath }}
{{- if and .Values.persistence.enabled (eq .Values.imageChartStorage.type "gcs") }}
- name: gcs-key
mountPath: /etc/chartmuseum/gcs-key.json
subPath: gcs-key.json
{{- end }}
volumes:
- name: chartmuseum-data
{{- if and .Values.persistence.enabled (eq .Values.imageChartStorage.type "filesystem") }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.existingClaim | default (include "harbor.chartmuseum" .) }}
{{- else }}
emptyDir: {}
{{- end }}
{{- if and .Values.persistence.enabled (eq .Values.imageChartStorage.type "gcs") }}
- name: gcs-key
secret:
secretName: {{ template "harbor.registry" . }}
items:
- key: GCS_KEY_DATA
path: gcs-key.json
{{- end }}
{{- with .Values.chartmuseum.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.chartmuseum.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.chartmuseum.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- end }}
{{- $persistence := .Values.persistence -}}
{{- if and .Values.chartmuseum.enabled $persistence.enabled }}
{{- $chartmuseum := $persistence.persistentVolumeClaim.chartmuseum -}}
{{- if and (not $chartmuseum.existingClaim) (eq $persistence.imageChartStorage.type "filesystem") }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "harbor.chartmuseum" . }}
{{- if eq $persistence.resourcePolicy "keep" }}
annotations:
helm.sh/resource-policy: keep
{{- end }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: chartmuseum
spec:
accessModes:
- {{ $chartmuseum.accessMode }}
resources:
requests:
storage: {{ $chartmuseum.size }}
{{- if $chartmuseum.storageClass }}
{{- if eq "-" $chartmuseum.storageClass }}
storageClassName: ""
{{- else }}
storageClassName: {{ $chartmuseum.storageClass }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.chartmuseum.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.chartmuseum" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
CACHE_REDIS_PASSWORD: {{ include "harbor.redis.rawPassword" . | b64enc | quote }}
{{- $storage := .Values.imageChartStorage }}
{{- $storageType := $storage.type }}
{{- if eq $storageType "azure" }}
AZURE_STORAGE_ACCESS_KEY: {{ $storage.azure.accountkey | b64enc | quote }}
{{- else if eq $storageType "gcs" }}
# TODO support the keyfile of gcs
{{- else if eq $storageType "s3" }}
{{- if $storage.s3.secretkey }}
AWS_SECRET_ACCESS_KEY: {{ $storage.s3.secretkey | b64enc | quote }}
{{- end }}
{{- else if eq $storageType "swift" }}
OS_PASSWORD: {{ $storage.swift.password | b64enc | quote }}
{{- else if eq $storageType "oss" }}
ALIBABA_CLOUD_ACCESS_KEY_SECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }}
{{- end }}
{{- end }}
\ No newline at end of file
{{- if .Values.chartmuseum.enabled }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.chartmuseum" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 9999
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: chartmuseum
{{- end }}
\ No newline at end of file
{{ if .Values.clair.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.clair" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: clair
data:
config.yaml: |
clair:
database:
type: pgsql
options:
source: "{{ template "harbor.database.clair" . }}"
# Number of elements kept in the cache
# Values unlikely to change (e.g. namespaces) are cached in order to save prevent needless roundtrips to the database.
cachesize: 16384
api:
# API server port
port: 6060
healthport: 6061
# Deadline before an API request will respond with a 503
timeout: 300s
updater:
interval: {{ .Values.clair.updatersInterval }}h
notifier:
attempts: 3
renotifyinterval: 2h
http:
endpoint: "http://{{ template "harbor.core" . }}/service/notifications/clair"
{{ end }}
{{ if .Values.clair.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "harbor.clair" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: clair
spec:
replicas: {{ .Values.clair.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: clair
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: clair
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/clair/clair-cm.yaml") . | sha256sum }}
{{- if .Values.clair.podAnnotations }}
{{ toYaml .Values.clair.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: clair
image: {{ template "system_default_registry" . }}{{ .Values.clair.image.repository }}:{{ .Values.clair.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
httpGet:
path: /health
port: 6061
initialDelaySeconds: 50
periodSeconds: 20
readinessProbe:
httpGet:
path: /health
port: 6061
initialDelaySeconds: 30
periodSeconds: 10
args: ["-log-level", "{{ .Values.logLevel }}"]
env:
{{- if .Values.clair.httpProxy }}
- name: HTTP_PROXY
value: {{ .Values.clair.httpProxy }}
{{- end }}
{{- if .Values.clair.httpsProxy }}
- name: HTTPS_PROXY
value: {{ .Values.clair.httpsProxy }}
{{- end }}
- name: NO_PROXY
value: "{{ template "harbor.registry" . }},{{ template "harbor.core" . }}"
{{- if .Values.clair.resources }}
resources:
{{ toYaml .Values.clair.resources | indent 10 }}
{{- end }}
ports:
- containerPort: 6060
volumeMounts:
- name: clair-config
mountPath: /etc/clair/config.yaml
subPath: config.yaml
volumes:
- name: clair-config
configMap:
name: "{{ template "harbor.clair" . }}"
items:
- key: config.yaml
path: config.yaml
{{- with .Values.clair.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.clair.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.clair.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{ end }}
{{ if .Values.clair.enabled }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.clair" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- name: clair
port: 6060
- name: health
port: 6061
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: clair
{{ end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.core" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
data:
app.conf: |+
appname = Harbor
runmode = prod
enablegzip = true
[prod]
httpport = 8080
_REDIS_URL: "{{ template "harbor.redisForCore" . }}"
_REDIS_URL_REG: "{{ template "harbor.redisForGC" . }}"
LOG_LEVEL: "{{ .Values.logLevel }}"
CONFIG_PATH: "/etc/core/app.conf"
SYNC_REGISTRY: "false"
ADMINSERVER_URL: "http://{{ template "harbor.adminserver" . }}"
CHART_CACHE_DRIVER: "redis"
CORE_URL: "http://{{ template "harbor.core" . }}"
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "harbor.core" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: core
spec:
replicas: {{ .Values.core.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: core
template:
metadata:
labels:
{{ include "harbor.matchLabels" . | indent 8 }}
component: core
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
{{- if .Values.core.podAnnotations }}
{{ toYaml .Values.core.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: core
image: {{ template "system_default_registry" . }}{{ .Values.core.image.repository }}:{{ .Values.core.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
httpGet:
path: /api/ping
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/ping
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
envFrom:
- configMapRef:
name: "{{ template "harbor.core" . }}"
- secretRef:
name: "{{ template "harbor.core" . }}"
env:
- name: CORE_SECRET
valueFrom:
secretKeyRef:
name: {{ template "harbor.core" . }}
key: secret
- name: JOBSERVICE_SECRET
valueFrom:
secretKeyRef:
name: "{{ template "harbor.jobservice" . }}"
key: secret
ports:
- containerPort: 8080
volumeMounts:
- name: config
mountPath: /etc/core/app.conf
subPath: app.conf
- name: secret-key
mountPath: /etc/core/key
subPath: key
- name: token-service-private-key
mountPath: /etc/core/private_key.pem
subPath: tokenServicePrivateKey
{{- if eq (include "harbor.autoGenCert" .) "true" }}
- name: ca-download
mountPath: /etc/core/ca/ca.crt
subPath: ca.crt
{{- end }}
- name: psc
mountPath: /etc/core/token
{{- if .Values.core.resources }}
resources:
{{ toYaml .Values.core.resources | indent 10 }}
{{- end }}
volumes:
- name: config
configMap:
name: {{ template "harbor.core" . }}
- name: secret-key
secret:
secretName: {{ template "harbor.core" . }}
items:
- key: secretKey
path: key
- name: token-service-private-key
secret:
{{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }}
{{- else }}
secretName: {{ template "harbor.core" . }}
{{- end }}
- name: ca-download
secret:
{{- if .Values.globalRegistryMode }}
secretName: "tls-rancher"
items:
- key: tls.crt
path: ca.crt
{{- else if eq (include "harbor.autoGenCert" .) "true" }}
secretName: {{ template "harbor.ingress.core" . }}
items:
- key: ca.crt
path: ca.crt
{{- else }}
secretName: {{ template "harbor.nginx" . }}
items:
- key: ca.crt
path: ca.crt
{{- end }}
- name: psc
emptyDir: {}
{{- with .Values.core.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.core.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.core.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- $cert := genSelfSignedCert "harbor" nil nil 365 }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "harbor.core" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
secretKey: {{ .Values.secretKey | b64enc | quote }}
secret: {{ .Values.core.secret | default (randAlphaNum 16) | b64enc | quote }}
{{- if not .Values.core.secretName }}
tokenServiceRootCertBundle: {{ $cert.Cert | b64enc | quote }}
tokenServicePrivateKey: {{ $cert.Key | b64enc | quote }}
{{- end }}
HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }}
POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{ if .Values.clair.enabled }}
CLAIR_DB_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{ end }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "harbor.core" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
{{- if (eq .Values.expose.ingress.controller "gce") }}
type: NodePort
{{- end }}
ports:
- port: 80
targetPort: 8080
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: core
{{- if eq .Values.database.type "internal" -}}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.database" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
POSTGRES_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{- end -}}
{{- if eq .Values.database.type "internal" -}}
{{- $database := .Values.persistence.persistentVolumeClaim.database -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: "{{ template "harbor.database" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: database
spec:
replicas: 1
serviceName: "{{ template "harbor.database" . }}"
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: database
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: database
annotations:
checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }}
{{- if .Values.database.podAnnotations }}
{{ toYaml .Values.database.podAnnotations | indent 8 }}
{{- end }}
spec:
initContainers:
- name: "remove-lost-found"
image: {{ template "system_default_registry" . }}{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
command: ["rm", "-Rf", "/var/lib/postgresql/data/lost+found"]
volumeMounts:
- name: database-data
mountPath: /var/lib/postgresql/data
containers:
- name: database
image: {{ template "system_default_registry" . }}{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
exec:
command:
- /docker-healthcheck.sh
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
exec:
command:
- /docker-healthcheck.sh
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.database.internal.resources }}
resources:
{{ toYaml .Values.database.internal.resources | indent 10 }}
{{- end }}
envFrom:
- secretRef:
name: "{{ template "harbor.database" . }}"
volumeMounts:
- name: database-data
mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }}
{{- if not .Values.persistence.enabled }}
volumes:
- name: "database-data"
emptyDir: {}
{{- else if $database.existingClaim }}
volumes:
- name: "database-data"
persistentVolumeClaim:
claimName: {{ $database.existingClaim }}
{{- end -}}
{{- with .Values.database.internal.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.database.internal.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.database.internal.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if and .Values.persistence.enabled (not $database.existingClaim) }}
volumeClaimTemplates:
- metadata:
name: "database-data"
labels:
{{ include "harbor.labels" . | indent 8 }}
spec:
accessModes: [{{ $database.accessMode | quote }}]
{{- if $database.storageClass }}
{{- if (eq "-" $database.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ $database.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ $database.size | quote }}
{{- end -}}
{{- end -}}
{{- if eq .Values.database.type "internal" -}}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.database" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 5432
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: database
{{- end -}}
\ No newline at end of file
{{- if eq .Values.expose.type "ingress" }}
{{- $ingress := .Values.expose.ingress -}}
{{- $tls := .Values.expose.tls -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "{{ template "harbor.ingress.core" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
annotations:
{{ toYaml $ingress.annotations | indent 4 }}
spec:
tls:
- hosts:
- {{ $ingress.host }}
{{- if .Values.globalRegistryMode }}
secretName: "tls-rancher-ingress"
{{- else if $tls.secretName }}
secretName: {{ $tls.secretName }}
{{- else }}
secretName: "{{ template "harbor.ingress.core" . }}"
{{- end }}
{{- if .Values.globalRegistryMode }}
rules:
- http:
paths:
- path: /v2/
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /api/projects
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /registry/
backend:
serviceName: {{ template "harbor.proxy" . }}
servicePort: 80
{{- if $ingress.host }}
host: {{ $ingress.host }}
{{- end }}
{{- else if eq .Values.expose.ingress.controller "gce" }}
rules:
- http:
paths:
- path: /*
backend:
serviceName: {{ template "harbor.portal" . }}
servicePort: 80
- path: /api/*
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /service/*
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /v2/*
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /chartrepo/*
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /c/*
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
{{- if $ingress.host }}
host: {{ $ingress.host }}
{{- end }}
{{- else }}
rules:
- http:
paths:
- path: /
backend:
serviceName: {{ template "harbor.portal" . }}
servicePort: 80
- path: /api/
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /service/
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /v2/
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /chartrepo/
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
- path: /c/
backend:
serviceName: {{ template "harbor.core" . }}
servicePort: 80
{{- if $ingress.host }}
host: {{ $ingress.host }}
{{- end }}
{{- end }}
{{- end }}
{{- if not .Values.globalRegistryMode }}
{{- if .Values.notary.enabled }}
{{- if eq .Values.expose.type "ingress" }}
{{- $ingress := .Values.expose.ingress -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "{{ template "harbor.ingress.notary" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
annotations:
{{ toYaml $ingress.annotations | indent 4 }}
{{ printf "%s: /" $ingress.rewriteAnnotation }}
spec:
{{- if .Values.expose.tls.enabled }}
tls:
- secretName: {{ .Values.expose.tls.secretName }}
{{- if $ingress.host }}
hosts:
- {{ $ingress.host }}
{{- end }}
{{- end }}
rules:
- http:
paths:
- path: /notary/
backend:
serviceName: {{ template "harbor.notary-server" . }}
servicePort: 4443
{{- if $ingress.host }}
host: {{ $ingress.host }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
{{- if eq (include "harbor.autoGenCertForIngress" .) "true" -}}
{{- $cn := (required "The \"expose.ingress.host\" is required!" (include "harbor.tlsCommonName" .)) }}
{{- $ca := genCA "harbor-ca" 3650 }}
{{- $cert := genSignedCert .Values.expose.ingress.host nil (list .Values.expose.ingress.host) 3650 $ca }}
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.ingress.core" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls
data:
{{- if regexMatch `^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$` $cn }}
{{- $cert := genSignedCert $cn (list $cn) nil 365 $ca }}
tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- else }}
{{- $cert := genSignedCert $cn nil (list $cn) 365 $ca }}
tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- end }}
{{- end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.jobservice" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
data:
config.yml: |+
protocol: "http"
port: 8080
worker_pool:
workers: {{ .Values.jobservice.maxJobWorkers }}
backend: "redis"
redis_pool:
redis_url: "{{ template "harbor.redisForJobservice" . }}"
namespace: "harbor_job_service_namespace"
job_loggers:
{{- if eq .Values.jobservice.jobLogger "file" }}
- name: "FILE"
level: {{ .Values.logLevel | upper }}
settings: # Customized settings of logger
base_dir: "/var/log/jobs"
sweeper:
duration: 14 #days
settings: # Customized settings of sweeper
work_dir: "/var/log/jobs"
{{- else if eq .Values.jobservice.jobLogger "database" }}
- name: "DB"
level: {{ .Values.logLevel | upper }}
sweeper:
duration: 14 #days
{{- else }}
- name: "STD_OUTPUT"
level: {{ .Values.logLevel | upper }}
{{- end }}
#Loggers for the job service
loggers:
- name: "STD_OUTPUT"
level: {{ .Values.logLevel | upper }}
admin_server: "http://{{ template "harbor.adminserver" . }}"
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ template "harbor.jobservice" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: jobservice
spec:
replicas: {{ .Values.jobservice.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: jobservice
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: jobservice
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if .Values.jobservice.podAnnotations }}
{{ toYaml .Values.jobservice.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: jobservice
image: {{ template "system_default_registry" . }}{{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
httpGet:
path: /api/v1/stats
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/v1/stats
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
{{- if .Values.jobservice.resources }}
resources:
{{ toYaml .Values.jobservice.resources | indent 10 }}
{{- end }}
env:
- name: CORE_SECRET
valueFrom:
secretKeyRef:
name: {{ template "harbor.core" . }}
key: secret
- name: JOBSERVICE_SECRET
valueFrom:
secretKeyRef:
name: "{{ template "harbor.jobservice" . }}"
key: secret
- name: ADMINSERVER_URL
value: "http://{{ template "harbor.adminserver" . }}"
- name: REGISTRY_CONTROLLER_URL
value: "http://{{ template "harbor.registry" . }}:8080"
- name: LOG_LEVEL
value: debug
ports:
- containerPort: 8080
volumeMounts:
- name: jobservice-config
mountPath: /etc/jobservice/config.yml
subPath: config.yml
- name: job-logs
mountPath: /var/log/jobs
subPath: {{ .Values.persistence.persistentVolumeClaim.jobservice.subPath }}
volumes:
- name: jobservice-config
configMap:
name: "{{ template "harbor.jobservice" . }}"
- name: job-logs
{{- if and .Values.persistence.enabled (eq .Values.jobservice.jobLogger "file") }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.persistentVolumeClaim.jobservice.existingClaim | default (include "harbor.jobservice" .) }}
{{- else }}
emptyDir: {}
{{- end }}
{{- with .Values.jobservice.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.jobservice.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.jobservice.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- $jobservice := .Values.persistence.persistentVolumeClaim.jobservice -}}
{{- if and .Values.persistence.enabled (not $jobservice.existingClaim) }}
{{- if eq .Values.jobservice.jobLogger "file" }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "harbor.jobservice" . }}
{{- if eq .Values.persistence.resourcePolicy "keep" }}
annotations:
helm.sh/resource-policy: keep
{{- end }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: jobservice
spec:
accessModes:
- {{ $jobservice.accessMode }}
resources:
requests:
storage: {{ $jobservice.size }}
{{- if $jobservice.storageClass }}
{{- if eq "-" $jobservice.storageClass }}
storageClassName: ""
{{- else }}
storageClassName: {{ $jobservice.storageClass }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.jobservice" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
secret: {{ .Values.jobservice.secret | default (randAlphaNum 16) | b64enc | quote }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.jobservice" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 80
targetPort: 8080
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: jobservice
{{- if and (ne .Values.expose.type "ingress") }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.nginx" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
data:
nginx.conf: |+
worker_processes auto;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
tcp_nodelay on;
# this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1;
upstream core {
server {{ template "harbor.core" . }};
}
upstream portal {
server {{ template "harbor.portal" . }};
}
{{- if .Values.notary.enabled }}
upstream notary-server {
server {{ template "harbor.notary-server" . }}:4443;
}
{{- end }}
log_format timed_combined 'remote_addr - '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe';
access_log /dev/stdout timed_combined;
server {
listen 443 ssl;
# server_name harbordomain.com;
server_tokens off;
# SSL
ssl_certificate /etc/nginx/cert/tls.crt;
ssl_certificate_key /etc/nginx/cert/tls.key;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on;
location / {
proxy_pass http://portal/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
# Add Secure flag when serving HTTPS
proxy_cookie_path / "/; secure";
proxy_buffering off;
proxy_request_buffering off;
}
location /api/ {
proxy_pass http://core/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /chartrepo/ {
proxy_pass http://core/chartrepo/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /c/ {
proxy_pass http://core/c/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /v1/ {
return 404;
}
location /v2/ {
proxy_pass http://core/v2/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /service/ {
proxy_pass http://core/service/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
location /service/notifications {
return 404;
}
{{- if .Values.notary.enabled }}
location /notary/ {
proxy_pass http://notary-server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
rewrite /notary/(.*) /$1 break;
}
{{- end }}
}
server {
listen 80;
#server_name harbordomain.com;
return 301 https://$host$request_uri;
}
}
{{- end }}
{{- if ne .Values.expose.type "ingress" }}
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ template "harbor.nginx" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: nginx
spec:
replicas: 1
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: nginx
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: nginx
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-https.yaml") . | sha256sum }}
{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }}
checksum/secret: {{ include (print $.Template.BasePath "/nginx/secret.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.nginx.podAnnotations }}
{{ toYaml .Values.nginx.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: nginx
image: {{ template "system_default_registry" . }}{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}
imagePullPolicy: "{{ .Values.imagePullPolicy }}"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.nginx.resources }}
resources:
{{ toYaml .Values.nginx.resources | indent 10 }}
{{- end }}
ports:
- containerPort: 80
- containerPort: 443
volumeMounts:
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: certificate
mountPath: /etc/nginx/cert
volumes:
- name: config
configMap:
name: {{ template "harbor.nginx" . }}
- name: certificate
secret:
{{- if .Values.expose.tls.secretName }}
secretName: {{ .Values.expose.tls.secretName }}
{{- else }}
secretName: {{ template "harbor.nginx" . }}
{{- end }}
{{- with .Values.nginx.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.nginx.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.nginx.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- end }}
\ No newline at end of file
{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }}
{{- $ca := genCA "harbor-ca" 3650 }}
{{- $cn := (include "harbor.tlsCommonName" .) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "harbor.nginx" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
{{- if regexMatch `^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$` $cn }}
{{- $cert := genSignedCert $cn (list $cn) nil 3650 $ca }}
tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- else }}
{{- $cert := genSignedCert $cn nil (list $cn) 3650 $ca }}
tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- end }}
{{- end }}
{{- if ne .Values.expose.type "ingress" }}
apiVersion: v1
kind: Service
metadata:
{{- if eq .Values.expose.type "clusterIP" }}
{{- $clusterIP := .Values.expose.clusterIP }}
name: {{ $clusterIP.name }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
type: ClusterIP
ports:
- name: https
port: {{ $clusterIP.ports.https }}
targetPort: 443
{{- else if eq .Values.expose.type "nodePort" }}
{{- $nodePort := .Values.expose.nodePort }}
name: {{ $nodePort.name }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
type: NodePort
ports:
- name: https
port: {{ $nodePort.ports.https.port }}
targetPort: 443
{{- if $nodePort.ports.https.nodePort }}
nodePort: {{ $nodePort.ports.https.nodePort }}
{{- end }}
{{- else if eq .Values.expose.type "loadBalancer" }}
{{- $loadBalancer := .Values.expose.loadBalancer }}
name: {{ $loadBalancer.name }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
type: LoadBalancer
ports:
- name: https
port: {{ $loadBalancer.ports.https }}
targetPort: 443
{{- end }}
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: nginx
{{- end }}
{{ if .Values.notary.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.notary-server" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: notary
data:
{{ $ca := genCA "harbor-notary-ca" 365 }}
{{ $cert := genSignedCert (include "harbor.notary-signer" .) nil nil 365 $ca }}
{{- if not .Values.notary.secretName }}
notary-signer-ca.crt: |
{{ $ca.Cert | indent 4 }}
notary-signer.crt: |
{{ $cert.Cert | indent 4 }}
notary-signer.key: |
{{ $cert.Key | indent 4 }}
{{- end }}
server-config.postgres.json: |
{
"server": {
"http_addr": ":4443"
},
"trust_service": {
"type": "remote",
"hostname": "{{ template "harbor.notary-signer" . }}",
"port": "7899",
{{- if not .Values.notary.secretName }}
"tls_ca_file": "./notary-signer-ca.crt",
{{- else }}
"tls_ca_file": "/etc/ssl/notary/cert/notary-signer-ca.crt",
{{- end }}
"key_algorithm": "ecdsa"
},
"logging": {
"level": "{{ .Values.logLevel }}"
},
"storage": {
"backend": "postgres",
"db_url": "{{ template "harbor.database.notaryServer" . }}"
},
"auth": {
"type": "token",
"options": {
{{- if .Values.globalRegistryMode }}
"realm": "{{ template "harbor.externalURL" . }}/registry/service/token",
{{- else }}
"realm": "{{ template "harbor.externalURL" . }}/service/token",
{{- end }}
"service": "harbor-notary",
"issuer": "harbor-token-issuer",
"rootcertbundle": "/root.crt"
}
}
}
signer-config.postgres.json: |
{
"server": {
"grpc_addr": ":7899",
{{- if not .Values.notary.secretName }}
"tls_cert_file": "./notary-signer.crt",
"tls_key_file": "./notary-signer.key"
{{- else }}
"tls_cert_file": "/etc/ssl/notary/cert/notary-signer.crt",
"tls_key_file": "/etc/ssl/notary/cert/notary-signer.key"
{{- end }}
},
"logging": {
"level": "{{ .Values.logLevel }}"
},
"storage": {
"backend": "postgres",
"db_url": "{{ template "harbor.database.notarySigner" . }}",
"default_alias": "defaultalias"
}
}
{{ end }}
{{ if .Values.notary.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "harbor.notary-server" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: notary-server
spec:
replicas: {{ .Values.notary.server.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: notary-server
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: notary-server
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/notary/notary-cm.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if .Values.notary.podAnnotations }}
{{ toYaml .Values.notary.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: notary-server
image: {{ template "system_default_registry" . }}{{ .Values.notary.server.image.repository }}:{{ .Values.notary.server.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
{{- if .Values.notary.server.resources }}
resources:
{{ toYaml .Values.notary.server.resources | indent 10 }}
{{- end }}
env:
- name: MIGRATIONS_PATH
value: migrations/server/postgresql
- name: DB_URL
value: {{ template "harbor.database.notaryServer" . }}
volumeMounts:
- name: notary-config
mountPath: /etc/notary
- name: root-certificate
mountPath: /root.crt
subPath: tokenServiceRootCertBundle
{{- if .Values.notary.secretName }}
- name: notary-ca
mountPath: /etc/ssl/notary/cert/notary-signer-ca.crt
subPath: ca
{{- end }}
volumes:
- name: notary-config
configMap:
name: "{{ template "harbor.notary-server" . }}"
- name: root-certificate
secret:
{{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }}
{{- else }}
secretName: {{ template "harbor.core" . }}
{{- end }}
{{- if .Values.notary.secretName }}
- name: notary-ca
secret:
secretName: {{ .Values.notary.secretName }}
{{- end }}
{{- with .Values.notary.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.notary.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.notary.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{ end }}
{{ if .Values.notary.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "harbor.notary-signer" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: notary-signer
spec:
replicas: {{ .Values.notary.signer.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: notary-signer
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: notary-signer
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/notary/notary-cm.yaml") . | sha256sum }}
spec:
containers:
- name: notary-signer
image: {{ template "system_default_registry" . }}{{ .Values.notary.signer.image.repository }}:{{ .Values.notary.signer.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
{{- if .Values.notary.signer.resources }}
resources:
{{ toYaml .Values.notary.signer.resources | indent 10 }}
{{- end }}
env:
- name: MIGRATIONS_PATH
value: migrations/signer/postgresql
- name: DB_URL
value: {{ template "harbor.database.notarySigner" . }}
- name: NOTARY_SIGNER_DEFAULTALIAS
value: defaultalias
volumeMounts:
- name: notary-config
mountPath: /etc/notary
{{- if .Values.notary.secretName }}
- name: notary-cert
mountPath: /etc/ssl/notary/cert/notary-signer-ca.crt
subPath: ca
- name: notary-cert
mountPath: /etc/ssl/notary/cert/notary-signer.crt
subPath: crt
- name: notary-cert
mountPath: /etc/ssl/notary/cert/notary-signer.key
subPath: key
{{- end }}
volumes:
- name: notary-config
configMap:
name: "{{ template "harbor.notary-server" . }}"
{{- if .Values.notary.secretName }}
- name: notary-cert
secret:
secretName: {{ .Values.notary.secretName }}
{{- end }}
{{- with .Values.notary.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.notary.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.notary.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{ end }}
{{ if .Values.notary.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "harbor.notary-server" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
{{- if (eq .Values.expose.ingress.controller "gce") }}
type: NodePort
{{- end }}
ports:
- port: 4443
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: notary-server
---
apiVersion: v1
kind: Service
metadata:
name: {{ template "harbor.notary-signer" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 7899
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: notary-signer
{{ end }}
\ No newline at end of file
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ template "harbor.portal" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: portal
spec:
replicas: {{ .Values.portal.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: portal
template:
metadata:
labels:
{{ include "harbor.matchLabels" . | indent 8 }}
component: portal
annotations:
{{- if .Values.portal.podAnnotations }}
{{ toYaml .Values.portal.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: portal
image: {{ template "system_default_registry" . }}{{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
{{- if .Values.portal.resources }}
resources:
{{ toYaml .Values.portal.resources | indent 10 }}
{{- end }}
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 1
periodSeconds: 10
ports:
- containerPort: 80
{{- with .Values.portal.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.portal.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.portal.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.portal" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
{{- if (eq .Values.expose.ingress.controller "gce") }}
type: NodePort
{{- end }}
ports:
- port: 80
targetPort: 80
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: portal
{{ if .Values.globalRegistryMode }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "harbor.proxy" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: proxy
data:
default.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location = /registry {
return 302 /registry/;
}
location /registry/service/ {
proxy_pass http://{{ template "harbor.core" . }}/service/;
}
location /registry/api/ {
proxy_pass http://{{ template "harbor.core" . }}/api/;
}
{{ if .Values.chartmuseum.enabled }}
location /registry/chartrepo/ {
proxy_pass http://{{ template "harbor.core" . }}/chartrepo/;
}
{{ end }}
location /registry/c/ {
proxy_pass http://{{ template "harbor.core" . }}/c/;
}
{{ if .Values.notary.enabled }}
location /registry/notary/ {
proxy_pass http://{{ template "harbor.notary-server" . }}:4443/;
}
{{ end }}
location /registry/ {
proxy_pass http://{{ template "harbor.portal" . }}/;
include filters.conf;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
filters.conf: |
sub_filter_types application/javascript;
sub_filter 'src="main' 'src="/registry/main';
sub_filter 'src="runtime' 'src="/registry/runtime';
sub_filter 'src="scripts' 'src="/registry/scripts';
sub_filter '"/c/login"' '"/registry/c/login"';
sub_filter '"/c/log_out"' '"/registry/c/log_out"';
sub_filter '"/c/userExists"' '"/registry/c/userExists"';
sub_filter '"/c/reset"' '"/registry/c/reset"';
sub_filter '"/c/sendEmail' '"/registry/c/sendEmail';
sub_filter '"/c/oidc_login"' '"/registry/c/oidc_login"';
sub_filter '"/api/' '"/registry/api/';
sub_filter '"/service/' '"/registry/service/';
sub_filter '"/chartrepo/' '"/registry/chartrepo/';
sub_filter '<base href="/">' '<base href="/registry">';
sub_filter 'href="favicon.ico' 'href="/registry/favicon.ico';
sub_filter 'href="styles' 'href="/registry/styles';
sub_filter '"images/harbor-logo.svg"' '"/registry/images/harbor-logo.svg"';
sub_filter '"/images/helm-gray.svg"' '"/registry/images/helm-gray.svg"';
sub_filter '"images/harbor-black-logo.png' '"/registry/images/harbor-black-logo.png';
#sub_filter '"static/images' '"registry/static/images';
sub_filter '"../../../images' '"/registry/images';
sub_filter '"/swagger.json"' '"/registry/swagger.json"';
sub_filter '"i18n/lang/"' '"/registry/i18n/lang/"';
sub_filter '"/language' '"/registry/language';
sub_filter 'http.get("setting.json"' 'http.get("/registry/setting.json"';
sub_filter_once off;
proxy_set_header Accept-Encoding "";
{{ end }}
{{ if .Values.globalRegistryMode }}
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ template "harbor.proxy" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: proxy
spec:
replicas: 1
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: proxy
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: proxy
spec:
containers:
- name: nginx
image: {{ template "system_default_registry" . }}{{ .Values.proxy.image.repository }}:{{ .Values.proxy.image.tag }}
imagePullPolicy: {{ .Values.proxy.image.pullPolicy }}
resources:
{{ toYaml .Values.proxy.resources | indent 10 }}
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
readOnly: true
- mountPath: /etc/nginx/filters.conf
name: filter-config
subPath: filters.conf
readOnly: true
volumes:
- name: nginx-config
configMap:
name: "{{ template "harbor.proxy" . }}"
items:
- key: default.conf
path: default.conf
- name: filter-config
configMap:
name: "{{ template "harbor.proxy" . }}"
items:
- key: filters.conf
path: filters.conf
{{- with .Values.proxy.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.proxy.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.proxy.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{ end }}
\ No newline at end of file
{{ if .Values.globalRegistryMode }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.proxy" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 80
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: proxy
{{ end }}
\ No newline at end of file
{{- if eq .Values.redis.type "internal" -}}
apiVersion: v1
kind: Service
metadata:
name: {{ template "harbor.redis" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- port: 6379
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: redis
{{- end -}}
\ No newline at end of file
{{- if eq .Values.redis.type "internal" -}}
{{- $redis := .Values.persistence.persistentVolumeClaim.redis -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "harbor.redis" . }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: redis
spec:
replicas: 1
serviceName: {{ template "harbor.redis" . }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: redis
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: redis
{{- if .Values.redis.podAnnotations }}
annotations:
{{ toYaml .Values.redis.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: redis
image: {{ template "system_default_registry" . }}{{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.redis.internal.resources }}
resources:
{{ toYaml .Values.redis.internal.resources | indent 10 }}
{{- end }}
volumeMounts:
- name: data
mountPath: /var/lib/redis
subPath: {{ $redis.subPath }}
{{- if not .Values.persistence.enabled }}
volumes:
- name: data
emptyDir: {}
{{- else if $redis.existingClaim }}
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ $redis.existingClaim }}
{{- end -}}
{{- with .Values.redis.internal.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.redis.internal.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.redis.internal.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if and .Values.persistence.enabled (not $redis.existingClaim) }}
volumeClaimTemplates:
- metadata:
name: data
labels:
{{ include "harbor.labels" . | indent 8 }}
spec:
accessModes: [{{ $redis.accessMode | quote }}]
{{- if $redis.storageClass }}
{{- if (eq "-" $redis.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ $redis.storageClass }}"
{{- end }}
{{- end }}
resources:
requests:
storage: {{ $redis.size | quote }}
{{- end -}}
{{- end -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ template "harbor.registry" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
data:
config.yml: |+
version: 0.1
log:
level: {{ .Values.logLevel }}
fields:
service: registry
storage:
{{- $storage := .Values.imageChartStorage }}
{{- $type := $storage.type }}
{{- if eq $type "filesystem" }}
filesystem:
rootdirectory: {{ $storage.filesystem.rootdirectory }}
{{- if $storage.filesystem.maxthreads }}
maxthreads: {{ $storage.filesystem.maxthreads }}
{{- end }}
{{- else if eq $type "azure" }}
azure:
accountname: {{ $storage.azure.accountname }}
container: {{ $storage.azure.container }}
{{- if $storage.azure.realm }}
realm: {{ $storage.azure.realm }}
{{- end }}
{{- else if eq $type "gcs" }}
gcs:
bucket: {{ $storage.gcs.bucket }}
keyfile: /etc/registry/gcs-key.json
{{- if $storage.gcs.rootdirectory }}
rootdirectory: {{ $storage.gcs.rootdirectory }}
{{- end }}
{{- if $storage.gcs.chunksize }}
chunksize: {{ $storage.gcs.chunksize }}
{{- end }}
{{- else if eq $type "s3" }}
s3:
region: {{ $storage.s3.region }}
bucket: {{ $storage.s3.bucket }}
{{- if $storage.s3.regionendpoint }}
regionendpoint: {{ $storage.s3.regionendpoint }}
{{- end }}
{{- if $storage.s3.encrypt }}
encrypt: {{ $storage.s3.encrypt }}
{{- end }}
{{- if $storage.s3.insecure }}
secure: false
{{- end }}
{{- if $storage.s3.v4auth }}
v4auth: {{ $storage.s3.v4auth }}
{{- end }}
{{- if $storage.s3.chunksize }}
chunksize: {{ $storage.s3.chunksize }}
{{- end }}
{{- if $storage.s3.rootdirectory }}
rootdirectory: {{ $storage.s3.rootdirectory }}
{{- end }}
{{- if $storage.s3.storageclass }}
storageclass: {{ $storage.s3.storageclass }}
{{- end }}
{{- else if eq $type "swift" }}
swift:
authurl: {{ $storage.swift.authurl }}
username: {{ $storage.swift.username }}
container: {{ $storage.swift.container }}
{{- if $storage.swift.region }}
region: {{ $storage.swift.region }}
{{- end }}
{{- if $storage.swift.tenant }}
tenant: {{ $storage.swift.tenant }}
{{- end }}
{{- if $storage.swift.tenantid }}
tenantid: {{ $storage.swift.tenantid }}
{{- end }}
{{- if $storage.swift.domain }}
domain: {{ $storage.swift.domain }}
{{- end }}
{{- if $storage.swift.domainid }}
domainid: {{ $storage.swift.domainid }}
{{- end }}
{{- if $storage.swift.trustid }}
trustid: {{ $storage.swift.trustid }}
{{- end }}
{{- if $storage.swift.insecureskipverify }}
insecureskipverify: {{ $storage.swift.insecureskipverify }}
{{- end }}
{{- if $storage.swift.chunksize }}
chunksize: {{ $storage.swift.chunksize }}
{{- end }}
{{- if $storage.swift.prefix }}
prefix: {{ $storage.swift.prefix }}
{{- end }}
{{- if $storage.swift.authversion }}
authversion: {{ $storage.swift.authversion }}
{{- end }}
{{- if $storage.swift.endpointtype }}
endpointtype: {{ $storage.swift.endpointtype }}
{{- end }}
{{- if $storage.swift.tempurlcontainerkey }}
tempurlcontainerkey: {{ $storage.swift.tempurlcontainerkey }}
{{- end }}
{{- if $storage.swift.tempurlmethods }}
tempurlmethods: {{ $storage.swift.tempurlmethods }}
{{- end }}
{{- else if eq $type "oss" }}
oss:
accesskeyid: {{ $storage.oss.accesskeyid }}
region: {{ $storage.oss.region }}
bucket: {{ $storage.oss.bucket }}
{{- if $storage.oss.endpoint }}
endpoint: {{ $storage.oss.endpoint }}
{{- end }}
{{- if $storage.oss.internal }}
internal: {{ $storage.oss.internal }}
{{- end }}
{{- if $storage.oss.encrypt }}
encrypt: {{ $storage.oss.encrypt }}
{{- end }}
{{- if $storage.oss.insecure }}
secure: false
{{- end }}
{{- if $storage.oss.chunksize }}
chunksize: {{ $storage.oss.chunksize }}
{{- end }}
{{- if $storage.oss.rootdirectory }}
rootdirectory: {{ $storage.oss.rootdirectory }}
{{- end }}
{{- end }}
cache:
layerinfo: redis
maintenance:
uploadpurging:
enabled: false
delete:
enabled: true
redirect:
disable: {{ $storage.disableredirect }}
redis:
addr: "{{ template "harbor.redis.host" . }}:{{ template "harbor.redis.port" . }}"
password: {{ template "harbor.redis.rawPassword" . }}
db: {{ template "harbor.redis.registryDatabaseIndex" . }}
http:
addr: :5000
# set via environment variable
# secret: placeholder
debug:
addr: localhost:5001
auth:
token:
issuer: harbor-token-issuer
{{- if .Values.globalRegistryMode }}
realm: "{{ template "harbor.externalURL" . }}/registry/service/token"
{{- else }}
realm: "{{ template "harbor.externalURL" . }}/service/token"
{{- end }}
rootcertbundle: /etc/registry/root.crt
service: harbor-registry
validation:
disabled: true
notifications:
endpoints:
- name: harbor
disabled: false
url: http://{{ template "harbor.core" . }}/service/notifications
timeout: 3000ms
threshold: 5
backoff: 1s
ctl-config.yml: |+
---
protocol: "http"
port: 8080
log_level: {{ .Values.logLevel }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ template "harbor.registry" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
component: registry
spec:
replicas: {{ .Values.registry.replicas }}
selector:
matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }}
component: registry
strategy:
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
{{ include "harbor.labels" . | indent 8 }}
component: registry
annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/registry/registry-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/registry/registry-secret.yaml") . | sha256sum }}
checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if .Values.registry.podAnnotations }}
{{ toYaml .Values.registry.podAnnotations | indent 8 }}
{{- end }}
spec:
containers:
- name: registry
image: {{ template "system_default_registry" . }}{{ .Values.registry.registry.image.repository }}:{{ .Values.registry.registry.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
httpGet:
path: /
port: 5000
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 5000
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.registry.registry.resources }}
resources:
{{ toYaml .Values.registry.registry.resources | indent 10 }}
{{- end }}
args: ["serve", "/etc/registry/config.yml"]
envFrom:
- secretRef:
name: "{{ template "harbor.registry" . }}"
ports:
- containerPort: 5000
- containerPort: 5001
volumeMounts:
- name: registry-data
mountPath: {{ .Values.imageChartStorage.filesystem.rootdirectory }}
subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }}
- name: registry-root-certificate
mountPath: /etc/registry/root.crt
subPath: tokenServiceRootCertBundle
- name: registry-config
mountPath: /etc/registry/config.yml
subPath: config.yml
{{- if and .Values.persistence.enabled (eq .Values.imageChartStorage.type "gcs") }}
- name: gcs-key
mountPath: /etc/registry/gcs-key.json
subPath: gcs-key.json
{{- end }}
- name: registryctl
image: {{ template "system_default_registry" . }}{{ .Values.registry.controller.image.repository }}:{{ .Values.registry.controller.image.tag }}
imagePullPolicy: {{ .Values.imagePullPolicy }}
livenessProbe:
httpGet:
path: /api/health
port: 8080
initialDelaySeconds: 1
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: 8080
initialDelaySeconds: 1
periodSeconds: 10
{{- if .Values.registry.controller.resources }}
resources:
{{ toYaml .Values.registry.controller.resources | indent 10 }}
{{- end }}
args: ["serve", "/etc/registry/config.yml"]
envFrom:
- secretRef:
name: "{{ template "harbor.registry" . }}"
env:
- name: CORE_SECRET
valueFrom:
secretKeyRef:
name: {{ template "harbor.core" . }}
key: secret
- name: JOBSERVICE_SECRET
valueFrom:
secretKeyRef:
name: {{ template "harbor.jobservice" . }}
key: secret
ports:
- containerPort: 8080
volumeMounts:
- name: registry-data
mountPath: {{ .Values.imageChartStorage.filesystem.rootdirectory }}
subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }}
- name: registry-config
mountPath: /etc/registry/config.yml
subPath: config.yml
- name: registry-config
mountPath: /etc/registryctl/config.yml
subPath: ctl-config.yml
volumes:
- name: registry-root-certificate
secret:
{{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }}
{{- else }}
secretName: {{ template "harbor.core" . }}
{{- end }}
- name: registry-config
configMap:
name: "{{ template "harbor.registry" . }}"
- name: registry-data
{{- if and .Values.persistence.enabled (eq .Values.imageChartStorage.type "filesystem") }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.persistentVolumeClaim.registry.existingClaim | default (include "harbor.registry" .) }}
{{- else }}
emptyDir: {}
{{- end }}
{{- if and .Values.persistence.enabled (eq .Values.imageChartStorage.type "gcs") }}
- name: gcs-key
secret:
secretName: {{ template "harbor.registry" . }}
items:
- key: GCS_KEY_DATA
path: gcs-key.json
{{- end }}
{{- with .Values.registry.nodeSelector }}
nodeSelector:
beta.kubernetes.io/os: linux
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.registry.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.registry.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if .Values.persistence.enabled }}
{{- $registry := .Values.persistence.persistentVolumeClaim.registry -}}
{{- if and (not $registry.existingClaim) (eq .Values.imageChartStorage.type "filesystem") }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "harbor.registry" . }}
{{- if eq .Values.persistence.resourcePolicy "keep" }}
annotations:
helm.sh/resource-policy: keep
{{- end }}
labels:
{{ include "harbor.labels" . | indent 4 }}
component: registry
spec:
accessModes:
- {{ $registry.accessMode }}
resources:
requests:
storage: {{ $registry.size }}
{{- if $registry.storageClass }}
{{- if eq "-" $registry.storageClass }}
storageClassName: ""
{{- else }}
storageClassName: {{ $registry.storageClass }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
apiVersion: v1
kind: Secret
metadata:
name: "{{ template "harbor.registry" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
type: Opaque
data:
REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (randAlphaNum 16) | b64enc | quote }}
{{- $storage := .Values.imageChartStorage }}
{{- $type := $storage.type }}
{{- if eq $type "azure" }}
REGISTRY_STORAGE_AZURE_ACCOUNTKEY: {{ $storage.azure.accountkey | b64enc | quote }}
{{- else if eq $type "gcs" }}
GCS_KEY_DATA: {{ $storage.gcs.encodedkey | quote }}
{{- else if eq $type "s3" }}
{{- if $storage.s3.accesskey }}
REGISTRY_STORAGE_S3_ACCESSKEY: {{ $storage.s3.accesskey | b64enc | quote }}
{{- end }}
{{- if $storage.s3.secretkey }}
REGISTRY_STORAGE_S3_SECRETKEY: {{ $storage.s3.secretkey | b64enc | quote }}
{{- end }}
{{- else if eq $type "swift" }}
REGISTRY_STORAGE_SWIFT_PASSWORD: {{ $storage.swift.password | b64enc | quote }}
{{- if $storage.swift.secretkey }}
REGISTRY_STORAGE_SWIFT_SECRETKEY: {{ $storage.swift.secretkey | b64enc | quote }}
{{- end }}
{{- if $storage.swift.accesskey }}
REGISTRY_STORAGE_SWIFT_ACCESSKEY: {{ $storage.swift.accesskey | b64enc | quote }}
{{- end }}
{{- else if eq $type "oss" }}
REGISTRY_STORAGE_OSS_ACCESSKEYSECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: "{{ template "harbor.registry" . }}"
labels:
{{ include "harbor.labels" . | indent 4 }}
spec:
ports:
- name: registry
port: 5000
- name: controller
port: 8080
selector:
{{ include "harbor.matchLabels" . | indent 4 }}
component: registry
\ No newline at end of file
suite: Test Enable/Disable Addons
templates:
- clair-cm.yaml
- clair-dpl.yaml
- clair-svc.yaml
- notary-cm.yaml
- notary-server.yaml
- notary-signer.yaml
- notary-svc.yaml
- core-secret.yaml
tests:
- it: should enable clair and notary by default
asserts:
- template: clair/clair-cm.yaml
hasDocuments:
count: 1
- template: clair/clair-dpl.yaml
hasDocuments:
count: 1
- template: clair/clair-svc.yaml
hasDocuments:
count: 1
- template: notary/notary-cm.yaml
hasDocuments:
count: 1
- template: notary/notary-server.yaml
hasDocuments:
count: 1
- template: notary/notary-signer.yaml
hasDocuments:
count: 1
- template: notary/notary-svc.yaml
hasDocuments:
count: 2
- it: should disable clair
set:
clair:
enabled: false
asserts:
- template: clair/clair-cm.yaml
hasDocuments:
count: 0
- template: clair/clair-dpl.yaml
hasDocuments:
count: 0
- template: clair/clair-svc.yaml
hasDocuments:
count: 0
- it: should disable notary
set:
notary:
enabled: false
asserts:
- template: notary/notary-cm.yaml
hasDocuments:
count: 0
- template: notary/notary-server.yaml
hasDocuments:
count: 0
- template: notary/notary-signer.yaml
hasDocuments:
count: 0
- template: notary/notary-svc.yaml
hasDocuments:
count: 0
suite: Test Global Options
templates:
- registry-cm.yaml
- registry-dpl.yaml
- registry-secret.yaml
- jobservice-secrets.yaml
- core-secret.yaml
tests:
- it: has no system default registry set
set:
registry:
registry:
image:
repository: test/registry-photon
tag: mytag
asserts:
- template: registry/registry-dpl.yaml
equal:
path: spec.template.spec.containers[0].image
value: test/registry-photon:mytag
- it: should use system default registry
set:
global:
systemDefaultRegistry: reg.myorg.com
registry:
registry:
image:
repository: test/registry-photon
tag: mytag
asserts:
- template: registry/registry-dpl.yaml
equal:
path: spec.template.spec.containers[0].image
value: reg.myorg.com/test/registry-photon:mytag
suite: Test Ingress
templates:
- ingress.yaml
tests:
- it: should set ingress host
set:
expose:
ingress:
host: test.myorg.com
asserts:
- template: ingress/ingress.yaml
equal:
path: spec.tls[0].hosts[0]
value: test.myorg.com
- template: ingress/ingress.yaml
equal:
path: spec.rules[0].host
value: test.myorg.com
- it: should use tls-rancher-ingress secret
set:
expose:
ingress:
host: test.myorg.com
globalRegistryMode: true
asserts:
- template: ingress/ingress.yaml
equal:
path: spec.tls[0].secretName
value: tls-rancher-ingress
suite: Test Registry Configmap
templates:
- registry-cm.yaml
- registry-dpl.yaml
- registry-secret.yaml
- jobservice-secrets.yaml
- core-secret.yaml
tests:
- it: should use filesystem storage backend by default
asserts:
- template: registry/registry-cm.yaml
matchRegex:
path: data.config\.yml
pattern: "filesystem:"
- it: should use s3 storage backend
set:
imageChartStorage:
type: s3
s3:
region: us-west-2
bucket: mybucket
accesskey: myaccesskey
secretkey: mysecretkey
asserts:
- template: registry/registry-cm.yaml
matchRegex:
path: data.config\.yml
pattern: "(?s)s3:.*region: us-west-2.*bucket: mybucket"
- template: registry/registry-secret.yaml
equal:
path: data.REGISTRY_STORAGE_S3_ACCESSKEY
value: bXlhY2Nlc3NrZXk=
- template: registry/registry-secret.yaml
equal:
path: data.REGISTRY_STORAGE_S3_SECRETKEY
value: bXlzZWNyZXRrZXk=
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment