Commit 7d41e5ec authored by 舒成's avatar 舒成

update

parent a06d036a
kind: pipeline kind: pipeline
name: docker name: docker
trigger: trigger:
branch: branch:
- release-v2.1 - release-v2.1
platform: platform:
runner: 10.11.92.34 runner: 10.11.92.34
volumes: volumes:
- name: charts - name: charts
host: host:
path: /data/downloads/k8s/charts path: /data/downloads/k8s/charts
- name: docker - name: docker
host: host:
path: /var/run/docker.sock path: /var/run/docker.sock
steps: steps:
- name: charts - name: charts
image: registry.cn-qingdao.aliyuncs.com/wod/helm:v3.6.0 image: registry.cn-qingdao.aliyuncs.com/wod/helm:v3.6.0
volumes: volumes:
- name: charts - name: charts
path: /charts path: /charts
commands: commands:
- helm package . -d /charts/ - helm package . -d /charts/
- name: ansible-amd64 - name: ansible-amd64
image: registry.cn-qingdao.aliyuncs.com/wod/ansible-image:v1.0 image: registry.cn-qingdao.aliyuncs.com/wod/ansible-image:v1.0
commands: commands:
- >- - >-
ansible-playbook /etc/ansible/linux/main.yml ansible-playbook /etc/ansible/linux/main.yml
--extra-vars --extra-vars
'{ '{
"REGISTRY_DATA_PATH": "/data/downloads/k8s/registry/{{ TARGET_ARCH }}", "REGISTRY_DATA_PATH": "/data/downloads/k8s/registry/{{ TARGET_ARCH }}",
"REGISTRY_DATA_FILE": "images-harbor-{{ TARGET_VERSION }}.tar.gz", "REGISTRY_DATA_FILE": "images-harbor-{{ TARGET_VERSION }}.tar.gz",
"TARGET_ARCH":"amd64", "TARGET_ARCH":"amd64",
"TARGET_VERSION":"v2.1.3" "TARGET_VERSION":"v2.1.3"
}' }'
--extra-vars "@ansible/images.yaml" --extra-vars "@ansible/images.yaml"
- name: ansible-arm64 - name: ansible-arm64
image: registry.cn-qingdao.aliyuncs.com/wod/ansible-image:v1.0 image: registry.cn-qingdao.aliyuncs.com/wod/ansible-image:v1.0
commands: commands:
- >- - >-
ansible-playbook /etc/ansible/linux/main.yml ansible-playbook /etc/ansible/linux/main.yml
--extra-vars --extra-vars
'{ '{
"REGISTRY_DATA_PATH": "/data/downloads/k8s/registry/{{ TARGET_ARCH }}", "REGISTRY_DATA_PATH": "/data/downloads/k8s/registry/{{ TARGET_ARCH }}",
"REGISTRY_DATA_FILE": "images-harbor-{{ TARGET_VERSION }}.tar.gz", "REGISTRY_DATA_FILE": "images-harbor-{{ TARGET_VERSION }}.tar.gz",
"TARGET_ARCH":"arm64", "TARGET_ARCH":"arm64",
"TARGET_VERSION":"v2.1.3" "TARGET_VERSION":"v2.1.3"
}' }'
--extra-vars "@ansible/images.yaml" --extra-vars "@ansible/images.yaml"
- name: ansible-ppc64le - name: ansible-ppc64le
image: registry.cn-qingdao.aliyuncs.com/wod/ansible-image:v1.0 image: registry.cn-qingdao.aliyuncs.com/wod/ansible-image:v1.0
commands: commands:
- >- - >-
ansible-playbook /etc/ansible/linux/main.yml ansible-playbook /etc/ansible/linux/main.yml
--extra-vars --extra-vars
'{ '{
"REGISTRY_DATA_PATH": "/data/downloads/k8s/registry/{{ TARGET_ARCH }}", "REGISTRY_DATA_PATH": "/data/downloads/k8s/registry/{{ TARGET_ARCH }}",
"REGISTRY_DATA_FILE": "images-harbor-{{ TARGET_VERSION }}.tar.gz", "REGISTRY_DATA_FILE": "images-harbor-{{ TARGET_VERSION }}.tar.gz",
"TARGET_ARCH":"ppc64le", "TARGET_ARCH":"ppc64le",
"TARGET_VERSION":"v2.1.3" "TARGET_VERSION":"v2.1.3"
}' }'
--extra-vars "@ansible/images.yaml" --extra-vars "@ansible/images.yaml"
--- ---
kind: secret kind: secret
name: REGISTRY_USER_ALIYUN name: REGISTRY_USER_ALIYUN
get: get:
name: USERNAME name: USERNAME
path: devops-registry-aliyun path: devops-registry-aliyun
--- ---
kind: secret kind: secret
name: REGISTRY_PASSWORD_ALIYUN name: REGISTRY_PASSWORD_ALIYUN
get: get:
name: PASSWORD name: PASSWORD
path: devops-registry-aliyun path: devops-registry-aliyun
name: Integration test name: Integration test
on: on:
pull_request: pull_request:
push: push:
jobs: jobs:
integration-test: integration-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
k8s_version: [v1.18.2, v1.17.5, v1.16.9] k8s_version: [v1.18.2, v1.17.5, v1.16.9]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Setup Docker - name: Setup Docker
uses: docker-practice/actions-setup-docker@0.0.1 uses: docker-practice/actions-setup-docker@0.0.1
with: with:
docker_version: 18.09 docker_version: 18.09
docker_channel: stable docker_channel: stable
docker_daemon_json: '{"insecure-registries":["0.0.0.0/0"]}' docker_daemon_json: '{"insecure-registries":["0.0.0.0/0"]}'
- name: Create kind cluster - name: Create kind cluster
uses: helm/kind-action@v1.0.0-rc.1 uses: helm/kind-action@v1.0.0-rc.1
with: with:
version: v0.8.1 version: v0.8.1
node_image: kindest/node:${{ matrix.k8s_version }} node_image: kindest/node:${{ matrix.k8s_version }}
cluster_name: kind-cluster-${{ matrix.k8s_version }} cluster_name: kind-cluster-${{ matrix.k8s_version }}
config: test/integration/kind-cluster.yaml config: test/integration/kind-cluster.yaml
- name: Install Nginx ingress controller - name: Install Nginx ingress controller
run: | run: |
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/ingress-nginx-2.3.0/deploy/static/provider/kind/deploy.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/ingress-nginx-2.3.0/deploy/static/provider/kind/deploy.yaml
kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s
- name: Set up Go 1.13 - name: Set up Go 1.13
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: 1.13 go-version: 1.13
- name: Cache go mod - name: Cache go mod
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ~/go/pkg/mod path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: | restore-keys: |
${{ runner.os }}-go- ${{ runner.os }}-go-
- name: Set /etc/hosts - name: Set /etc/hosts
run: | run: |
sudo -- sh -c "echo '127.0.0.1 harbor.local' >> /etc/hosts" sudo -- sh -c "echo '127.0.0.1 harbor.local' >> /etc/hosts"
sudo -- sh -c "echo '127.0.0.1 notary.harbor.local' >> /etc/hosts" sudo -- sh -c "echo '127.0.0.1 notary.harbor.local' >> /etc/hosts"
- name: Run integration tests - name: Run integration tests
working-directory: ./test working-directory: ./test
run: run:
go test -v -timeout 30m github.com/goharbor/harbor-helm/integration go test -v -timeout 30m github.com/goharbor/harbor-helm/integration
\ No newline at end of file
name: Lint name: Lint
on: on:
pull_request: pull_request:
push: push:
jobs: jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
helm_version: [3.2.3, 2.16.8] helm_version: [3.2.3, 2.16.8]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
with: with:
path: harbor path: harbor
- name: Set up Helm - name: Set up Helm
uses: azure/setup-helm@v1 uses: azure/setup-helm@v1
with: with:
version: '${{ matrix.helm_version }}' version: '${{ matrix.helm_version }}'
- name: Helm version - name: Helm version
run: run:
helm version -c helm version -c
- name: Run lint - name: Run lint
working-directory: ./harbor working-directory: ./harbor
run: run:
helm lint . helm lint .
- name: Update dependency - name: Update dependency
working-directory: ./harbor working-directory: ./harbor
run: run:
helm dependency update . helm dependency update .
- name: Run template for ingress expose - name: Run template for ingress expose
working-directory: ./harbor working-directory: ./harbor
run: run:
helm template --set "expose.type=ingress" --output-dir $(mktemp -d -t output-XXXXXXXXXX) . helm template --set "expose.type=ingress" --output-dir $(mktemp -d -t output-XXXXXXXXXX) .
- name: Run template for nodePort expose - name: Run template for nodePort expose
working-directory: ./harbor working-directory: ./harbor
run: run:
helm template --set "expose.type=nodePort,expose.tls.auto.commonName=127.0.0.1" --output-dir $(mktemp -d -t output-XXXXXXXXXX) . helm template --set "expose.type=nodePort,expose.tls.auto.commonName=127.0.0.1" --output-dir $(mktemp -d -t output-XXXXXXXXXX) .
\ No newline at end of file
name: Unit test name: Unit test
on: on:
pull_request: pull_request:
push: push:
jobs: jobs:
unit-test: unit-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Set up Helm 3.2.3 - name: Set up Helm 3.2.3
uses: azure/setup-helm@v1 uses: azure/setup-helm@v1
with: with:
version: '3.2.3' version: '3.2.3'
- name: Set up Go 1.13 - name: Set up Go 1.13
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: 1.13 go-version: 1.13
- name: Cache go mod - name: Cache go mod
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ~/go/pkg/mod path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: | restore-keys: |
${{ runner.os }}-go- ${{ runner.os }}-go-
- name: Run unit tests - name: Run unit tests
working-directory: ./test working-directory: ./test
run: run:
go test -v github.com/goharbor/harbor-helm/unittest go test -v github.com/goharbor/harbor-helm/unittest
charts/* charts/*
requirements.lock requirements.lock
\ No newline at end of file
docs/* docs/*
.git/* .git/*
.gitignore .gitignore
CONTRIBUTING.md CONTRIBUTING.md
.travis.yaml .travis.yaml
test/* test/*
raws/* raws/*
.beagle.yml .beagle.yml
CONTRIBUTING.md CONTRIBUTING.md
Deploy.md Deploy.md
.github/* .github/*
values-operator.yaml values-operator.yaml
\ No newline at end of file
# Contributing to Helm Chart for Harbor # 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. Please follow [Harbor contributing guide](https://github.com/goharbor/harbor/blob/master/CONTRIBUTING.md) to learn how to make code contribution.
## Contributers ## Contributers
Thanks very much to all contributers who submitted pull requests to Helm Chart for Harbor. Thanks very much to all contributers who submitted pull requests to Helm Chart for Harbor.
- [Paul Czarkowski @paulczar](https://github.com/paulczar) - [Paul Czarkowski @paulczar](https://github.com/paulczar)
- [Luca Innocenti Mirri @lucaim](https://github.com/lucaim) - [Luca Innocenti Mirri @lucaim](https://github.com/lucaim)
- [Steven Arnott @ArcticSnowman](https://github.com/ArcticSnowman) - [Steven Arnott @ArcticSnowman](https://github.com/ArcticSnowman)
- [Alex M @draeron](https://github.com/draeron) - [Alex M @draeron](https://github.com/draeron)
- [SangJun Yun](https://github.com/YunSangJun) - [SangJun Yun](https://github.com/YunSangJun)
apiVersion: v1 apiVersion: v1
name: beagle-harbor name: beagle-harbor
version: 2.1.3 version: 2.1.3
appVersion: 2.1.3 appVersion: 2.1.3
description: An open source trusted cloud native registry that stores, signs, and scans content description: An open source trusted cloud native registry that stores, signs, and scans content
keywords: keywords:
- docker - docker
- registry - registry
- harbor - harbor
home: https://goharbor.io home: https://goharbor.io
icon: https://raw.githubusercontent.com/goharbor/website/master/static/img/logos/harbor-icon-color.png icon: https://raw.githubusercontent.com/goharbor/website/master/static/img/logos/harbor-icon-color.png
sources: sources:
- https://github.com/goharbor/harbor - https://github.com/goharbor/harbor
- https://github.com/goharbor/harbor-helm - https://github.com/goharbor/harbor-helm
maintainers: maintainers:
- name: Wenkai Yin - name: Wenkai Yin
email: yinw@vmware.com email: yinw@vmware.com
- name: Weiwei He - name: Weiwei He
email: hweiwei@vmware.com email: hweiwei@vmware.com
- name: Qian Deng - name: Qian Deng
email: dengq@vmware.com email: dengq@vmware.com
engine: gotpl engine: gotpl
# harbor # harbor
## install ## install
```bash ```bash
# 1.install # 1.install
kubectl create ns devops kubectl create ns devops
helm install \ helm install \
--namespace=devops \ --namespace=devops \
harbor \ harbor \
/etc/kubernetes/helm/beagle-harbor \ /etc/kubernetes/helm/beagle-harbor \
-f /etc/kubernetes/helm/beagle-harbor/values-overrides.yaml -f /etc/kubernetes/helm/beagle-harbor/values-overrides.yaml
# uninstall # uninstall
helm uninstall \ helm uninstall \
--namespace=devops \ --namespace=devops \
harbor harbor
# update # update
helm upgrade \ helm upgrade \
--namespace=devops \ --namespace=devops \
harbor \ harbor \
/etc/kubernetes/helm/beagle-harbor \ /etc/kubernetes/helm/beagle-harbor \
-f /etc/kubernetes/helm/beagle-harbor/values-overrides.yaml -f /etc/kubernetes/helm/beagle-harbor/values-overrides.yaml
# template # template
helm template \ helm template \
--namespace=devops \ --namespace=devops \
harbor \ harbor \
/etc/kubernetes/helm/beagle-harbor \ /etc/kubernetes/helm/beagle-harbor \
-f /etc/kubernetes/helm/beagle-harbor/values-overrides.yaml > /etc/kubernetes/helm/beagle-harbor/dist.yaml -f /etc/kubernetes/helm/beagle-harbor/values-overrides.yaml > /etc/kubernetes/helm/beagle-harbor/dist.yaml
# package # package
helm package . -d C:/Tmp/Charts helm package . -d C:/Tmp/Charts
``` ```
## images x86_64 ## images x86_64
```bash ```bash
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor
registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v2.1.3
registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v2.1.3
registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v2.1.3
registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v2.1.3
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-db # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-db
registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v2.1.3
# registry # registry
registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1 registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1
# gitlab.wodcloud.com/cloud/chartmuseum # gitlab.wodcloud.com/cloud/chartmuseum
registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum:v2.1.3
# gitlab.wodcloud.com/cloud/clair # gitlab.wodcloud.com/cloud/clair
registry.cn-qingdao.aliyuncs.com/wod/harbor-clair:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-clair:v2.1.3
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-scanner-clair # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-scanner-clair
registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter:v2.1.3
# gitlab.wodcloud.com/cloud/harbor-scanner-trivy # gitlab.wodcloud.com/cloud/harbor-scanner-trivy
registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter:v2.1.3
# gitlab.wodcloud.com/cloud/notary # gitlab.wodcloud.com/cloud/notary
registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server:v2.1.3
registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer:v2.1.3 registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer:v2.1.3
# redis # redis
registry.cn-qingdao.aliyuncs.com/wod/redis:6.0.9 registry.cn-qingdao.aliyuncs.com/wod/redis:6.0.9
``` ```
## images arm64 ## images arm64
```bash ```bash
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor
registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-portal:v2.1.3-arm64
registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-core:v2.1.3-arm64
registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice:v2.1.3-arm64
registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl:v2.1.3-arm64
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-db # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-db
registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-db:v2.1.3-arm64
# registry # registry
registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1-arm64 registry.cn-qingdao.aliyuncs.com/wod/registry:2.7.1-arm64
# gitlab.wodcloud.com/cloud/chartmuseum # gitlab.wodcloud.com/cloud/chartmuseum
registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum:v2.1.3-arm64
# gitlab.wodcloud.com/cloud/clair # gitlab.wodcloud.com/cloud/clair
registry.cn-qingdao.aliyuncs.com/wod/harbor-clair:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-clair:v2.1.3-arm64
# gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-scanner-clair # gitlab.wodcloud.com/cloud/awecloud-goharbor-harbor-scanner-clair
registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter:v2.1.3-arm64
# gitlab.wodcloud.com/cloud/harbor-scanner-trivy # gitlab.wodcloud.com/cloud/harbor-scanner-trivy
registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter:v2.1.3-arm64
# gitlab.wodcloud.com/cloud/notary # gitlab.wodcloud.com/cloud/notary
registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server:v2.1.3-arm64
registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer:v2.1.3-arm64 registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer:v2.1.3-arm64
# redis # redis
registry.cn-qingdao.aliyuncs.com/wod/redis:6.0.9-arm64 registry.cn-qingdao.aliyuncs.com/wod/redis:6.0.9-arm64
``` ```
Apache License Apache License
Version 2.0, January 2004 Version 2.0, January 2004
http://www.apache.org/licenses/ http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions. 1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, "License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document. and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by "Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License. the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all "Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition, control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the "control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity. outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity "You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License. exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, "Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation including but not limited to software source code, documentation
source, and configuration files. source, and configuration files.
"Object" form shall mean any form resulting from mechanical "Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation, not limited to compiled object code, generated documentation,
and conversions to other media types. and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or "Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work copyright notice that is included in or attached to the work
(an example is provided in the Appendix below). (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object "Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of, separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof. the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including "Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted" the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution." designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity "Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work. subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of 2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual, this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of, copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form. Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of 3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual, this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made, (except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work, use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s) Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate granted to You under this License for that Work shall terminate
as of the date such litigation is filed. as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the 4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You modifications, and in Source or Object form, provided that You
meet the following conditions: meet the following conditions:
(a) You must give any other recipients of the Work or (a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices (b) You must cause any modified files to carry prominent notices
stating that You changed the files; and stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works (c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work, attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of excluding those notices that do not pertain to any part of
the Derivative Works; and the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its (d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or, documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed that such additional attribution notices cannot be construed
as modifying the License. as modifying the License.
You may add Your own copyright statement to Your modifications and You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use, for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License. the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, 5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions. this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions. with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade 6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor, names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file. origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or 7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS, Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License. risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, 8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise, whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill, Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages. has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing 9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer, the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity, and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify, of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability. of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work. APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]" boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright [yyyy] [name of copyright owner] Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
This source diff could not be displayed because it is too large. You can view the blob instead.
IMAGES: IMAGES:
- repo: harbor-portal - repo: harbor-portal
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-core - repo: harbor-core
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-jobservice - repo: harbor-jobservice
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-db - repo: harbor-db
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-registryctl - repo: harbor-registryctl
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-chartmuseum - repo: harbor-chartmuseum
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-clair - repo: harbor-clair
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-clair-adapter - repo: harbor-clair-adapter
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-trivy-adapter - repo: harbor-trivy-adapter
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-notary-server - repo: harbor-notary-server
tag: "v2.1.3" tag: "v2.1.3"
- repo: harbor-notary-signer - repo: harbor-notary-signer
tag: "v2.1.3" tag: "v2.1.3"
- repo: registry - repo: registry
tag: "2.7.1" tag: "2.7.1"
- repo: redis - repo: redis
tag: "6.0.9" tag: "6.0.9"
\ No newline at end of file
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIE0zCCArugAwIBAgIJAPY/OzLMeVq2MA0GCSqGSIb3DQEBCwUAMAAwHhcNMTkw MIIE0zCCArugAwIBAgIJAPY/OzLMeVq2MA0GCSqGSIb3DQEBCwUAMAAwHhcNMTkw
NDE4MDIyNzM3WhcNMjkwNDE1MDIyNzM3WjAAMIICIjANBgkqhkiG9w0BAQEFAAOC NDE4MDIyNzM3WhcNMjkwNDE1MDIyNzM3WjAAMIICIjANBgkqhkiG9w0BAQEFAAOC
Ag8AMIICCgKCAgEA3xlUJs2b/aI2NLoy4OIQ+dn/yMb/O99iKDRyZKpH8rSOmS+o Ag8AMIICCgKCAgEA3xlUJs2b/aI2NLoy4OIQ+dn/yMb/O99iKDRyZKpH8rSOmS+o
F9unmSAzL65XA/v6nY0OLI/dASDjkqkBpIdTGzogR5f8UiB6osuEY7V71XZdzWLr F9unmSAzL65XA/v6nY0OLI/dASDjkqkBpIdTGzogR5f8UiB6osuEY7V71XZdzWLr
PjnJq6ZLAaoKmwG80W5+Wd6V8PygOx52mkr1w7IWKz+1ZLI5izbppon7XVGVRaAT PjnJq6ZLAaoKmwG80W5+Wd6V8PygOx52mkr1w7IWKz+1ZLI5izbppon7XVGVRaAT
RvNZDiJ6CeJpcJ5H723lkf5RvJWatZLCYIYDbRfTiKsyQ/SlRcv5BVfHg/LJSH9Q RvNZDiJ6CeJpcJ5H723lkf5RvJWatZLCYIYDbRfTiKsyQ/SlRcv5BVfHg/LJSH9Q
LGRhPMARldl9wyZCwZZDHxheI4a+26aa8MY3u9st/l0/Oo6VCTGpMiEhiGF2LVjp LGRhPMARldl9wyZCwZZDHxheI4a+26aa8MY3u9st/l0/Oo6VCTGpMiEhiGF2LVjp
UWq/+BP4SFEvJfq/DuinI139W/5aZZ7/HwRPlmYU6pXTRLyIg7jd+19fJwR7X37q UWq/+BP4SFEvJfq/DuinI139W/5aZZ7/HwRPlmYU6pXTRLyIg7jd+19fJwR7X37q
w0o8t06FhjmrCzaYCUjoReqDmHaNmZN/ddvG7jZWBu+jNh0YavsyQyCIVmv6yqSc w0o8t06FhjmrCzaYCUjoReqDmHaNmZN/ddvG7jZWBu+jNh0YavsyQyCIVmv6yqSc
jPiD9uivxqTwjJidIBRfuUrz3aERQ7cQgf0qhqjIzflzHbFKhILocBWq7zyNl9hr jPiD9uivxqTwjJidIBRfuUrz3aERQ7cQgf0qhqjIzflzHbFKhILocBWq7zyNl9hr
vUGT/WZcw0t/OtM72SPaplmTgVbbQRxf2VHzyptGIvtydlXK8thxOMpXo4e+Sl8d vUGT/WZcw0t/OtM72SPaplmTgVbbQRxf2VHzyptGIvtydlXK8thxOMpXo4e+Sl8d
1gdQcC4oisN9F29oNs8P5yFQP//xYuv8C607nCj1DzrId5avG/NVfKB/fbDKEFgN 1gdQcC4oisN9F29oNs8P5yFQP//xYuv8C607nCj1DzrId5avG/NVfKB/fbDKEFgN
2WhHInTzPLEcjF4fErcUAEuWW0buX/6FHCG3iTtrqyD92KTVDfN1J56rrcsCAwEA 2WhHInTzPLEcjF4fErcUAEuWW0buX/6FHCG3iTtrqyD92KTVDfN1J56rrcsCAwEA
AaNQME4wHQYDVR0OBBYEFFhNhTo4UAC2PUsf8jYaWj160vGEMB8GA1UdIwQYMBaA AaNQME4wHQYDVR0OBBYEFFhNhTo4UAC2PUsf8jYaWj160vGEMB8GA1UdIwQYMBaA
FFhNhTo4UAC2PUsf8jYaWj160vGEMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL FFhNhTo4UAC2PUsf8jYaWj160vGEMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADggIBAMAsEtVlELMwdtcifHeOT0kOmf5wo9In/eFSgscCzBMDaRx2B3q36AoS BQADggIBAMAsEtVlELMwdtcifHeOT0kOmf5wo9In/eFSgscCzBMDaRx2B3q36AoS
Il7XWAZpevaR7W7yeARKaAshBLhygUqLD0zWbKlSN9Hprd1wdpM0ffyPpN5dxOYA Il7XWAZpevaR7W7yeARKaAshBLhygUqLD0zWbKlSN9Hprd1wdpM0ffyPpN5dxOYA
er04y12GRnCbMYqi4cvztP4TinXqq2yHSYhLbO9qkI5gbWVxkRuIcMKvixddllNY er04y12GRnCbMYqi4cvztP4TinXqq2yHSYhLbO9qkI5gbWVxkRuIcMKvixddllNY
Q3obJaDDHmovM3+g/G+1YFgt4qES38XnJ7BrSshHnn5EIQh286xfJriyrK2hHbLJ Q3obJaDDHmovM3+g/G+1YFgt4qES38XnJ7BrSshHnn5EIQh286xfJriyrK2hHbLJ
qz0YuF6G3DXPeWGgXvj0Hipc0f8UDZkKkk/eGEI6vEkytyvoepoZI2XbAf/ZMy5n qz0YuF6G3DXPeWGgXvj0Hipc0f8UDZkKkk/eGEI6vEkytyvoepoZI2XbAf/ZMy5n
KwuhEn4hhkFMwWaSWp/h0QdMCaxk4BVSOqmNVaLSB7+FjsIj4CasFotYiyJ2gpRB KwuhEn4hhkFMwWaSWp/h0QdMCaxk4BVSOqmNVaLSB7+FjsIj4CasFotYiyJ2gpRB
Nf8QaS4bz0Tn1eBbC8ksj+e3ZWeX2b5wVMjql9jTt2X1ICs8KKe3vEBkjqT2AUi2 Nf8QaS4bz0Tn1eBbC8ksj+e3ZWeX2b5wVMjql9jTt2X1ICs8KKe3vEBkjqT2AUi2
52TtKzm73aWrz/GPy/Q2LCor3Fh9FGVSBOBBDXGy6MJpNHJnYVH9EENFGOh85ol1 52TtKzm73aWrz/GPy/Q2LCor3Fh9FGVSBOBBDXGy6MJpNHJnYVH9EENFGOh85ol1
2pADOBB5vAU/kLB5LHPj2kue/FMiHaNnrSYIGrMlBSX2jj9EYa1uuUH+pd4MBj1F 2pADOBB5vAU/kLB5LHPj2kue/FMiHaNnrSYIGrMlBSX2jj9EYa1uuUH+pd4MBj1F
5uH8ORiaQ6ht2+WHklxic1Rj5yTYQwVlH70CBOn+qVEdo63yQwzAMJKFIwlGUQEX 5uH8ORiaQ6ht2+WHklxic1Rj5yTYQwVlH70CBOn+qVEdo63yQwzAMJKFIwlGUQEX
jiljgc86q4cZtUTFrcwMidbk+8Q6+JbDVg7HV/+pnC+wnv197kwe jiljgc86q4cZtUTFrcwMidbk+8Q6+JbDVg7HV/+pnC+wnv197kwe
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEA3xlUJs2b/aI2NLoy4OIQ+dn/yMb/O99iKDRyZKpH8rSOmS+o MIIJKQIBAAKCAgEA3xlUJs2b/aI2NLoy4OIQ+dn/yMb/O99iKDRyZKpH8rSOmS+o
F9unmSAzL65XA/v6nY0OLI/dASDjkqkBpIdTGzogR5f8UiB6osuEY7V71XZdzWLr F9unmSAzL65XA/v6nY0OLI/dASDjkqkBpIdTGzogR5f8UiB6osuEY7V71XZdzWLr
PjnJq6ZLAaoKmwG80W5+Wd6V8PygOx52mkr1w7IWKz+1ZLI5izbppon7XVGVRaAT PjnJq6ZLAaoKmwG80W5+Wd6V8PygOx52mkr1w7IWKz+1ZLI5izbppon7XVGVRaAT
RvNZDiJ6CeJpcJ5H723lkf5RvJWatZLCYIYDbRfTiKsyQ/SlRcv5BVfHg/LJSH9Q RvNZDiJ6CeJpcJ5H723lkf5RvJWatZLCYIYDbRfTiKsyQ/SlRcv5BVfHg/LJSH9Q
LGRhPMARldl9wyZCwZZDHxheI4a+26aa8MY3u9st/l0/Oo6VCTGpMiEhiGF2LVjp LGRhPMARldl9wyZCwZZDHxheI4a+26aa8MY3u9st/l0/Oo6VCTGpMiEhiGF2LVjp
UWq/+BP4SFEvJfq/DuinI139W/5aZZ7/HwRPlmYU6pXTRLyIg7jd+19fJwR7X37q UWq/+BP4SFEvJfq/DuinI139W/5aZZ7/HwRPlmYU6pXTRLyIg7jd+19fJwR7X37q
w0o8t06FhjmrCzaYCUjoReqDmHaNmZN/ddvG7jZWBu+jNh0YavsyQyCIVmv6yqSc w0o8t06FhjmrCzaYCUjoReqDmHaNmZN/ddvG7jZWBu+jNh0YavsyQyCIVmv6yqSc
jPiD9uivxqTwjJidIBRfuUrz3aERQ7cQgf0qhqjIzflzHbFKhILocBWq7zyNl9hr jPiD9uivxqTwjJidIBRfuUrz3aERQ7cQgf0qhqjIzflzHbFKhILocBWq7zyNl9hr
vUGT/WZcw0t/OtM72SPaplmTgVbbQRxf2VHzyptGIvtydlXK8thxOMpXo4e+Sl8d vUGT/WZcw0t/OtM72SPaplmTgVbbQRxf2VHzyptGIvtydlXK8thxOMpXo4e+Sl8d
1gdQcC4oisN9F29oNs8P5yFQP//xYuv8C607nCj1DzrId5avG/NVfKB/fbDKEFgN 1gdQcC4oisN9F29oNs8P5yFQP//xYuv8C607nCj1DzrId5avG/NVfKB/fbDKEFgN
2WhHInTzPLEcjF4fErcUAEuWW0buX/6FHCG3iTtrqyD92KTVDfN1J56rrcsCAwEA 2WhHInTzPLEcjF4fErcUAEuWW0buX/6FHCG3iTtrqyD92KTVDfN1J56rrcsCAwEA
AQKCAgEAk8q8s4PrvYby79UVlWJNKqceykwBkxE1fjrYORWQ2hiAirxGV5+8lDT/ AQKCAgEAk8q8s4PrvYby79UVlWJNKqceykwBkxE1fjrYORWQ2hiAirxGV5+8lDT/
k6ujm1EWwb5K0HxxRKkb+PEa1HqNNHE6JxNpJKK9exDlYAQ+x7dFBqVr/2nazmo4 k6ujm1EWwb5K0HxxRKkb+PEa1HqNNHE6JxNpJKK9exDlYAQ+x7dFBqVr/2nazmo4
MB8MLYlmIztWWoSYwe8o2mEg4q+bxYs5Imdu7AkhE7dJ63hm23gLMfeMLalRqopu MB8MLYlmIztWWoSYwe8o2mEg4q+bxYs5Imdu7AkhE7dJ63hm23gLMfeMLalRqopu
XBPwE5nXP6aGuUNHtG1K8tQJDlZY+LEbAeOfReNQhT9NdRukYSW579vfKblJrSvz XBPwE5nXP6aGuUNHtG1K8tQJDlZY+LEbAeOfReNQhT9NdRukYSW579vfKblJrSvz
ulg89sVm3cWEK5pB6rj9wJbK94voKftVqbbuBwWjd1a9pibKhwVBe2L2FWhpSZc5 ulg89sVm3cWEK5pB6rj9wJbK94voKftVqbbuBwWjd1a9pibKhwVBe2L2FWhpSZc5
F/coC7njTaYT6tr91y5VhhJhIZQCf/vv4Zl5XhFHs5VTZNbM/OfqyFQLYXVJO48K F/coC7njTaYT6tr91y5VhhJhIZQCf/vv4Zl5XhFHs5VTZNbM/OfqyFQLYXVJO48K
F7tmazAEQQBQwVZqH9C9NQdzPHWmc38Okhtc1wzaqn/rg9+1sgAMD8hWCtQJUe97 F7tmazAEQQBQwVZqH9C9NQdzPHWmc38Okhtc1wzaqn/rg9+1sgAMD8hWCtQJUe97
b9ymh5A0Z4QXKpyFT0b+pXcD1jRha07UtkX+/zLJ9HpAXcUmzkG+j5CXNpnxsIq5 b9ymh5A0Z4QXKpyFT0b+pXcD1jRha07UtkX+/zLJ9HpAXcUmzkG+j5CXNpnxsIq5
fJFeq3hBj9w6n4h+50M4W0Fse5YoEUsc3B0fz8BlQBb+YJLFLNH34MH8p1l0ZDYJ fJFeq3hBj9w6n4h+50M4W0Fse5YoEUsc3B0fz8BlQBb+YJLFLNH34MH8p1l0ZDYJ
yae0psxlBijg4OPZ+WCBa+jtFW4LiWgEcxwgz8w+hEOAQr2a1Dc7w8jd+Y4IK8Um yae0psxlBijg4OPZ+WCBa+jtFW4LiWgEcxwgz8w+hEOAQr2a1Dc7w8jd+Y4IK8Um
lTVs5dbp4mOmPMlRv/GM7kDudFqbMg3YFwXg3QbquVqLZzEzjVkCggEBAPJKZbCW lTVs5dbp4mOmPMlRv/GM7kDudFqbMg3YFwXg3QbquVqLZzEzjVkCggEBAPJKZbCW
YfLejkS/fkRyV3VIb54mKwQHoMWub88tPgGuXzjsJyd5QTQ58PpUjXrLHmn8lS2+ YfLejkS/fkRyV3VIb54mKwQHoMWub88tPgGuXzjsJyd5QTQ58PpUjXrLHmn8lS2+
viE8GJylKwN1yMlZw40+kZhpHUpCWx/2ZKjAqvqA9OOKo2fv6Hd/wOAnU4CtioC1 viE8GJylKwN1yMlZw40+kZhpHUpCWx/2ZKjAqvqA9OOKo2fv6Hd/wOAnU4CtioC1
pri7lKFYXoP8DtQVwHYvIzCRqDnhc4mwJDqzTC9xduI+svxzl4xH82fx0jrPiFY+ pri7lKFYXoP8DtQVwHYvIzCRqDnhc4mwJDqzTC9xduI+svxzl4xH82fx0jrPiFY+
/wOdXjyfIPjyhHC4jPTWbairwXS9dBjSl128aIRT580/yXE/SYAugg05jKtg5zQA /wOdXjyfIPjyhHC4jPTWbairwXS9dBjSl128aIRT580/yXE/SYAugg05jKtg5zQA
So13MTezXRHXdO0di3tEMHGREEkFpeVnnPQvCCedK0DV36iNwiWc8pwdfLMVneTt So13MTezXRHXdO0di3tEMHGREEkFpeVnnPQvCCedK0DV36iNwiWc8pwdfLMVneTt
DKwZedCx+o/7ev0CggEBAOu48DGEJJJzHxVR5mY1K2AlZyYtpTOWehK1zX74JvM3 DKwZedCx+o/7ev0CggEBAOu48DGEJJJzHxVR5mY1K2AlZyYtpTOWehK1zX74JvM3
YxN4nd+Zx5n9uSPmmKzqF3TU+44RVtdJK6ejoFE8dMDTNWaSLW/ZDmN1nT0njvOn YxN4nd+Zx5n9uSPmmKzqF3TU+44RVtdJK6ejoFE8dMDTNWaSLW/ZDmN1nT0njvOn
IWJn59ynOChWWKZgXZ/9UqGR7Pt6OxSkkex9c/fYBsMX/xusdXQigeogl0iOYVFW IWJn59ynOChWWKZgXZ/9UqGR7Pt6OxSkkex9c/fYBsMX/xusdXQigeogl0iOYVFW
gXIiiLRLHpHJsK/uNxIizj0hTYYn7uD7PRENwFRcCYf8J1eUFbd6DuCVWeQCKWgf gXIiiLRLHpHJsK/uNxIizj0hTYYn7uD7PRENwFRcCYf8J1eUFbd6DuCVWeQCKWgf
Nd2tSWoi0Vylj4uUX8Iw0tjLNMD5CREJEk4GSv4EDSmvUdv1LiBKJCL2lEcgoPeC Nd2tSWoi0Vylj4uUX8Iw0tjLNMD5CREJEk4GSv4EDSmvUdv1LiBKJCL2lEcgoPeC
oOD2iCc5KqgnmQraRilFFk8RVXA9PWZGY3C0b6TVmmcCggEANZO2AOKALlCAbTtb oOD2iCc5KqgnmQraRilFFk8RVXA9PWZGY3C0b6TVmmcCggEANZO2AOKALlCAbTtb
FI+kP08RP4t5H58AMjZsiweaGo0QiWnPDq+Fd6MIYpKn5mtcAlvUMRVovbioSJtN FI+kP08RP4t5H58AMjZsiweaGo0QiWnPDq+Fd6MIYpKn5mtcAlvUMRVovbioSJtN
c6psB/pNf8JCN82mqHEb7WlywM46AMLbZCWYFLe8VBBv+iE4GdBGPEfu4hK4vyTn c6psB/pNf8JCN82mqHEb7WlywM46AMLbZCWYFLe8VBBv+iE4GdBGPEfu4hK4vyTn
YZAvRz64HGo4Adlztbjg76V/nWtggW05uLXcpm55KJAQhv+2WULjBw9PHOGDoSwf YZAvRz64HGo4Adlztbjg76V/nWtggW05uLXcpm55KJAQhv+2WULjBw9PHOGDoSwf
Am2+U567rLht70prsQDj10laJ2QuSHS1YXGlfeFcw3eFUp9TN+JpvdoCol2lCIgl Am2+U567rLht70prsQDj10laJ2QuSHS1YXGlfeFcw3eFUp9TN+JpvdoCol2lCIgl
IHjgZj6ORWfCvpoxW7RgBuZukqCD0R60HdYtavxN3jtiepsapA83pxO0JapMgZWZ IHjgZj6ORWfCvpoxW7RgBuZukqCD0R60HdYtavxN3jtiepsapA83pxO0JapMgZWZ
rpURkQKCAQBOcEv9Liu9T/GX9pjkiezVIZ0hZy8B66DTeQvYpFrRtCyT3h8quNFi rpURkQKCAQBOcEv9Liu9T/GX9pjkiezVIZ0hZy8B66DTeQvYpFrRtCyT3h8quNFi
vLtO5v0HDR6hEf5jWAG9wet07U37ulJfl+i9KQdVoLTZA9o+71ryWTsSs+DD3CEj vLtO5v0HDR6hEf5jWAG9wet07U37ulJfl+i9KQdVoLTZA9o+71ryWTsSs+DD3CEj
yxfUxVxiULmeaiChzhq608h7GYPthUU6xlFttAWhj5oLfqzYyAg6OL76a+Nxm02g yxfUxVxiULmeaiChzhq608h7GYPthUU6xlFttAWhj5oLfqzYyAg6OL76a+Nxm02g
1ayl3m8U6eAXF23kpoUm+HNpqVnGuJmzVoUA75YKZ+NreEdhSBbfPwN9sJwtZUil 1ayl3m8U6eAXF23kpoUm+HNpqVnGuJmzVoUA75YKZ+NreEdhSBbfPwN9sJwtZUil
u7H4kHcM95Ix8eysCjKqKIqezBlITbDTnjNvLjcbJ5C+0a6lvIXT1vQR5/eGlc9M u7H4kHcM95Ix8eysCjKqKIqezBlITbDTnjNvLjcbJ5C+0a6lvIXT1vQR5/eGlc9M
BWE360pNkV/LD8mOf9Jepi2Q43oDL9EhAoIBAQDTWImfy0K9gGzA2rPy169mWYQK BWE360pNkV/LD8mOf9Jepi2Q43oDL9EhAoIBAQDTWImfy0K9gGzA2rPy169mWYQK
OlcnD3+hQq6x51Zn1e/texFeVlhHn4rrnRdCFOAp47uFkJ2m72GCVD74EwQucK9y OlcnD3+hQq6x51Zn1e/texFeVlhHn4rrnRdCFOAp47uFkJ2m72GCVD74EwQucK9y
AD5jorqgVHqCKZdkHjb2V60Mzm6g3rtL9WJXFVLvNBb/QGB2vgHVOO0zqiqGZj4e AD5jorqgVHqCKZdkHjb2V60Mzm6g3rtL9WJXFVLvNBb/QGB2vgHVOO0zqiqGZj4e
Ex7l2m//5SE4DLtn70J9CgG1HtXCS8dWrGPL1pzDnk8VXtnoXzb0LChLUFEgZRmh Ex7l2m//5SE4DLtn70J9CgG1HtXCS8dWrGPL1pzDnk8VXtnoXzb0LChLUFEgZRmh
cV6AFHEK2H8wBHviNyehsRQiDkl2AiWOcJNvkzW68ck2nJjRWyPYK1JL3NCKpB3Q cV6AFHEK2H8wBHviNyehsRQiDkl2AiWOcJNvkzW68ck2nJjRWyPYK1JL3NCKpB3Q
OohrP0fHcWAXMW97wFXZhRfnQfDxxIOlj3McYT0AlanXd0F4NGc2Nvmphx04 OohrP0fHcWAXMW97wFXZhRfnQfDxxIOlj3McYT0AlanXd0F4NGc2Nvmphx04
-----END RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
clair: clair:
database: database:
type: pgsql type: pgsql
options: options:
source: "{{ template "harbor.database.clair" . }}" source: "{{ template "harbor.database.clair" . }}"
# Number of elements kept in the cache # 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. # Values unlikely to change (e.g. namespaces) are cached in order to save prevent needless roundtrips to the database.
cachesize: 16384 cachesize: 16384
api: api:
# API server port # API server port
port: 6060 port: 6060
healthport: 6061 healthport: 6061
# Deadline before an API request will respond with a 503 # Deadline before an API request will respond with a 503
timeout: 300s timeout: 300s
updater: updater:
interval: {{ .Values.clair.updatersInterval }}h interval: {{ .Values.clair.updatersInterval }}h
{ {
"server": { "server": {
"http_addr": ":4443" "http_addr": ":4443"
}, },
"trust_service": { "trust_service": {
"type": "remote", "type": "remote",
"hostname": "{{ template "harbor.notary-signer" . }}", "hostname": "{{ template "harbor.notary-signer" . }}",
"port": "7899", "port": "7899",
"tls_ca_file": "/etc/ssl/notary/ca.crt", "tls_ca_file": "/etc/ssl/notary/ca.crt",
"key_algorithm": "ecdsa" "key_algorithm": "ecdsa"
}, },
"logging": { "logging": {
"level": "{{ .Values.logLevel }}" "level": "{{ .Values.logLevel }}"
}, },
"storage": { "storage": {
"backend": "postgres", "backend": "postgres",
"db_url": "{{ template "harbor.database.notaryServer" . }}" "db_url": "{{ template "harbor.database.notaryServer" . }}"
}, },
"auth": { "auth": {
"type": "token", "type": "token",
"options": { "options": {
"realm": "{{ .Values.externalURL }}.{{ $.Values.global.host }}/service/token", "realm": "{{ .Values.externalURL }}.{{ $.Values.global.host }}/service/token",
"service": "harbor-notary", "service": "harbor-notary",
"issuer": "harbor-token-issuer", "issuer": "harbor-token-issuer",
"rootcertbundle": "/root.crt" "rootcertbundle": "/root.crt"
} }
} }
} }
\ No newline at end of file
{ {
"server": { "server": {
"grpc_addr": ":7899", "grpc_addr": ":7899",
"tls_cert_file": "/etc/ssl/notary/tls.crt", "tls_cert_file": "/etc/ssl/notary/tls.crt",
"tls_key_file": "/etc/ssl/notary/tls.key" "tls_key_file": "/etc/ssl/notary/tls.key"
}, },
"logging": { "logging": {
"level": "{{ .Values.logLevel }}" "level": "{{ .Values.logLevel }}"
}, },
"storage": { "storage": {
"backend": "postgres", "backend": "postgres",
"db_url": "{{ template "harbor.database.notarySigner" . }}", "db_url": "{{ template "harbor.database.notarySigner" . }}",
"default_alias": "defaultalias" "default_alias": "defaultalias"
} }
} }
\ No newline at end of file
--- ---
title: Harbor High Availability Guide title: Harbor High Availability Guide
--- ---
## Goal ## Goal
Deploy Harbor on K8S via helm to make it highly available, that is, if one of node that has Harbor's container running becomes un accessible. Users does not experience interrupt of service of Harbor. Deploy Harbor on K8S via helm to make it highly available, that is, if one of node that has Harbor's container running becomes un accessible. Users does not experience interrupt of service of Harbor.
## Prerequisites ## Prerequisites
- Kubernetes cluster 1.10+ - Kubernetes cluster 1.10+
- Helm 2.10.0+ - Helm 2.10.0+
- High available ingress controller (Harbor does not manage the external endpoint) - High available ingress controller (Harbor does not manage the external endpoint)
- High available PostgreSQL database (Harbor does not handle the deployment of HA of database) - High available PostgreSQL database (Harbor does not handle the deployment of HA of database)
- High available Redis (Harbor does not handle the deployment of HA of Redis) - High available Redis (Harbor does not handle the deployment of HA of Redis)
- PVC that can be shared across nodes or external object storage - PVC that can be shared across nodes or external object storage
## Architecture ## Architecture
Most of Harbor's components are stateless now. So we can simply increase the replica of the pods to make sure the components are distributed to multiple worker nodes, and leverage the "Service" mechanism of K8S to ensure the connectivity across pods. Most of Harbor's components are stateless now. So we can simply increase the replica of the pods to make sure the components are distributed to multiple worker nodes, and leverage the "Service" mechanism of K8S to ensure the connectivity across pods.
As for storage layer, it is expected that the user provide high available PostgreSQL, Redis cluster for application data and PVCs or object storage for storing images and charts. As for storage layer, it is expected that the user provide high available PostgreSQL, Redis cluster for application data and PVCs or object storage for storing images and charts.
![HA](img/ha.png) ![HA](img/ha.png)
## Usage ## Usage
### Download Chart ### Download Chart
Download Harbor helm chart: Download Harbor helm chart:
```bash ```bash
helm repo add harbor https://helm.goharbor.io helm repo add harbor https://helm.goharbor.io
helm fetch harbor/harbor --untar helm fetch harbor/harbor --untar
``` ```
### Configuration ### Configuration
Configure the followings items in `values.yaml`, you can also set them as parameters via `--set` flag during running `helm install`: Configure the followings items in `values.yaml`, you can also set them as parameters via `--set` flag during running `helm install`:
- **Ingress rule** - **Ingress rule**
Configure the `expose.ingress.hosts.core` and `expose.ingress.hosts.notary`. Configure the `expose.ingress.hosts.core` and `expose.ingress.hosts.notary`.
- **External URL** - **External URL**
Configure the `externalURL`. Configure the `externalURL`.
- **External PostgreSQL** - **External PostgreSQL**
Set the `database.type` to `external` and fill the information in `database.external` section. Set the `database.type` to `external` and fill the information in `database.external` section.
Four empty databases should be created manually for `Harbor core`, `Clair`, `Notary server` and `Notary signer` and configure them in the section. Harbor will create tables automatically when starting up. Four empty databases should be created manually for `Harbor core`, `Clair`, `Notary server` and `Notary signer` and configure them in the section. Harbor will create tables automatically when starting up.
- **External Redis** - **External Redis**
Set the `redis.type` to `external` and fill the information in `redis.external` section. Set the `redis.type` to `external` and fill the information in `redis.external` section.
As the Redis client used by Harbor's upstream projects doesn't support `Sentinel`, Harbor can only work with a single entry point Redis. You can refer to this [guide](https://community.pivotal.io/s/article/How-to-setup-HAProxy-and-Redis-Sentinel-for-automatic-failover-between-Redis-Master-and-Slave-servers) to setup a HAProxy before the Redis to expose a single entry point. As the Redis client used by Harbor's upstream projects doesn't support `Sentinel`, Harbor can only work with a single entry point Redis. You can refer to this [guide](https://community.pivotal.io/s/article/How-to-setup-HAProxy-and-Redis-Sentinel-for-automatic-failover-between-Redis-Master-and-Slave-servers) to setup a HAProxy before the Redis to expose a single entry point.
- **Storage** - **Storage**
By default, a default `StorageClass` is needed in the K8S cluster to provision volumes to store images, charts and job logs. By default, a default `StorageClass` is needed in the K8S cluster to provision volumes to store images, charts and job logs.
If you want to specify the `StorageClass`, set `persistence.persistentVolumeClaim.registry.storageClass`, `persistence.persistentVolumeClaim.chartmuseum.storageClass` and `persistence.persistentVolumeClaim.jobservice.storageClass`. If you want to specify the `StorageClass`, set `persistence.persistentVolumeClaim.registry.storageClass`, `persistence.persistentVolumeClaim.chartmuseum.storageClass` and `persistence.persistentVolumeClaim.jobservice.storageClass`.
If you use `StorageClass`, for both default or specified one, set `persistence.persistentVolumeClaim.registry.accessMode`, `persistence.persistentVolumeClaim.chartmuseum.accessMode` and `persistence.persistentVolumeClaim.jobservice.accessMode` as `ReadWriteMany`, and make sure that the persistent volumes must can be shared cross different nodes. If you use `StorageClass`, for both default or specified one, set `persistence.persistentVolumeClaim.registry.accessMode`, `persistence.persistentVolumeClaim.chartmuseum.accessMode` and `persistence.persistentVolumeClaim.jobservice.accessMode` as `ReadWriteMany`, and make sure that the persistent volumes must can be shared cross different nodes.
You can also use the existing PVCs to store data, set `persistence.persistentVolumeClaim.registry.existingClaim`, `persistence.persistentVolumeClaim.chartmuseum.existingClaim` and `persistence.persistentVolumeClaim.jobservice.existingClaim`. You can also use the existing PVCs to store data, set `persistence.persistentVolumeClaim.registry.existingClaim`, `persistence.persistentVolumeClaim.chartmuseum.existingClaim` and `persistence.persistentVolumeClaim.jobservice.existingClaim`.
If you have no PVCs that can be shared across nodes, you can use external object storage to store images and charts and store the job logs in database. Set the `persistence.imageChartStorage.type` to the value you want to use and fill the corresponding section and set `jobservice.jobLogger` to `database`. If you have no PVCs that can be shared across nodes, you can use external object storage to store images and charts and store the job logs in database. Set the `persistence.imageChartStorage.type` to the value you want to use and fill the corresponding section and set `jobservice.jobLogger` to `database`.
- **Replica** - **Replica**
Set `portal.replicas`, `core.replicas`, `jobservice.replicas`, `registry.replicas`, `chartmuseum.replicas`, `clair.replicas`, `notary.server.replicas` and `notary.signer.replicas` to `n`(`n`>=2). Set `portal.replicas`, `core.replicas`, `jobservice.replicas`, `registry.replicas`, `chartmuseum.replicas`, `clair.replicas`, `notary.server.replicas` and `notary.signer.replicas` to `n`(`n`>=2).
### Installation ### Installation
Install the Harbor helm chart with a release name `my-release`: Install the Harbor helm chart with a release name `my-release`:
helm 2: helm 2:
```bash ```bash
helm install --name my-release . helm install --name my-release .
``` ```
helm 3: helm 3:
``` ```
helm install my-release . helm install my-release .
``` ```
--- ---
title: Upgrade Guide title: Upgrade Guide
--- ---
This guide is used to upgrade Harbor deployed by chart since version 0.3.0. This guide is used to upgrade Harbor deployed by chart since version 0.3.0.
## Notes ## Notes
- As the database schema may change between different versions of Harbor, there is a progress to migrate the schema during the upgrade and the downtime cannot be avoid - As the database schema may change between different versions of Harbor, there is a progress to migrate the schema during the upgrade and the downtime cannot be avoid
- The database schema cannot be downgraded automatically, so the `helm rollback` is not supported - The database schema cannot be downgraded automatically, so the `helm rollback` is not supported
## Upgrade ## Upgrade
### 1. Backup database ### 1. Backup database
Backup the database used by Harbor in case the upgrade process fails. Backup the database used by Harbor in case the upgrade process fails.
### 2. Download new chart ### 2. Download new chart
Download the latest version of Harbor chart. Download the latest version of Harbor chart.
### 3. Configure new chart ### 3. Configure new chart
Configure the new chart to make sure that the configuration items have the same values with the old one. Configure the new chart to make sure that the configuration items have the same values with the old one.
> Note: if TLS is enabled and the certificate is generated by chart automatically, a new certificate will be generated and overwrite the old one during the upgrade, this may cause some issues if you have distributed the certificate. You can follow the below steps to configure the new chart to use the old certificate: > Note: if TLS is enabled and the certificate is generated by chart automatically, a new certificate will be generated and overwrite the old one during the upgrade, this may cause some issues if you have distributed the certificate. You can follow the below steps to configure the new chart to use the old certificate:
1) Get the secret name which certificate is stored in: 1) Get the secret name which certificate is stored in:
```bash ```bash
kubectl get secret kubectl get secret
``` ```
Find the secret whose name ends with `-harbor-ingress` (expose service via `Ingress`) or `-harbor-nginx`(expose service via `ClusterIP` or `NodePort`) Find the secret whose name ends with `-harbor-ingress` (expose service via `Ingress`) or `-harbor-nginx`(expose service via `ClusterIP` or `NodePort`)
2) Export the secret as yaml file: 2) Export the secret as yaml file:
```bash ```bash
kubectl get secret <secret-name-from-step-1> -o yaml > secret.yaml kubectl get secret <secret-name-from-step-1> -o yaml > secret.yaml
``` ```
3) Rename the secret by setting `metadata.name` in `secret.yaml` 3) Rename the secret by setting `metadata.name` in `secret.yaml`
4) Create a new secret: 4) Create a new secret:
```bash ```bash
kubectl create -f secret.yaml kubectl create -f secret.yaml
``` ```
5) Configure the chart to use the new secret by setting `expose.tls.secretName` as the value you set in step **3** 5) Configure the chart to use the new secret by setting `expose.tls.secretName` as the value you set in step **3**
### 4. Upgrade ### 4. Upgrade
Run upgrade command: Run upgrade command:
```bash ```bash
helm upgrade release-name --force . helm upgrade release-name --force .
``` ```
> The `--force` is necessary if upgrade from version 0.3.0 due to issue [#30](https://github.com/goharbor/harbor-helm/issues/30). > The `--force` is necessary if upgrade from version 0.3.0 due to issue [#30](https://github.com/goharbor/harbor-helm/issues/30).
## Known issues ## Known issues
- The job logs will be lost if you upgrade from version 0.3.0 as the logs are store in a `emptyDir` in 0.3.0. - The job logs will be lost if you upgrade from version 0.3.0 as the logs are store in a `emptyDir` in 0.3.0.
--- ---
title: Managing Harbor with Helm title: Managing Harbor with Helm
weight: 50 weight: 50
--- ---
This documentation focuses on deploying and managing Harbor via [Helm](https://helm.sh). For general documentation for Harbor, please see the [Harbor docs](https://goharbor.io/docs). This documentation focuses on deploying and managing Harbor via [Helm](https://helm.sh). For general documentation for Harbor, please see the [Harbor docs](https://goharbor.io/docs).
\ No newline at end of file
expose: expose:
type: ingress type: ingress
tls: tls:
enabled: false enabled: false
ingress: ingress:
hosts: hosts:
core: hub.wodcloud.local core: hub.wodcloud.local
notary: notary.wodcloud.local notary: notary.wodcloud.local
annotations: annotations:
ingress.kubernetes.io/proxy-body-size: "0" ingress.kubernetes.io/proxy-body-size: "0"
externalURL: https://hub.wodcloud.local externalURL: https://hub.wodcloud.local
persistence: persistence:
enabled: true enabled: true
persistentVolumeClaim: persistentVolumeClaim:
registry: registry:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
chartmuseum: chartmuseum:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
jobservice: jobservice:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
database: database:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
redis: redis:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
trivy: trivy:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
imageChartStorage: imageChartStorage:
# s3 , filesystem # s3 , filesystem
type: filesystem type: filesystem
s3: s3:
accesskey: AKIAIOSFODNN7EXAMPLE accesskey: AKIAIOSFODNN7EXAMPLE
secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region: us-east-1 region: us-east-1
regionendpoint: http://minio.wodcloud.local regionendpoint: http://minio.wodcloud.local
bucket: registry bucket: registry
encrypt: false encrypt: false
v4auth: true v4auth: true
chunksize: '5242880' chunksize: '5242880'
rootdirectory: / rootdirectory: /
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
logLevel: info logLevel: info
harborAdminPassword: "spaceIN511" harborAdminPassword: "spaceIN511"
secretKey: "IpTIscRIgmerlare" secretKey: "IpTIscRIgmerlare"
portal: portal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal
tag: v2.1.3 tag: v2.1.3
core: core:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core
tag: v2.1.3 tag: v2.1.3
jobservice: jobservice:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice
tag: v2.1.3 tag: v2.1.3
registry: registry:
registry: registry:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/registry repository: registry.cn-qingdao.aliyuncs.com/wod/registry
tag: 2.7.1 tag: 2.7.1
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
controller: controller:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl
tag: v2.1.3 tag: v2.1.3
chartmuseum: chartmuseum:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum
tag: v2.1.3 tag: v2.1.3
nodeSelector: {} nodeSelector: {}
# nodeSelector: # nodeSelector:
# harbor: enabled # harbor: enabled
storageSpec: storageSpec:
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
clair: clair:
clair: clair:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair
tag: v2.1.3 tag: v2.1.3
adapter: adapter:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter
tag: v2.1.3 tag: v2.1.3
trivy: trivy:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter
tag: v2.1.3 tag: v2.1.3
notary: notary:
server: server:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server
tag: v2.1.3 tag: v2.1.3
signer: signer:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer
tag: v2.1.3 tag: v2.1.3
database: database:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db
tag: v2.1.3 tag: v2.1.3
password: "spaceIN511" password: "spaceIN511"
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
redis: redis:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/redis repository: registry.cn-qingdao.aliyuncs.com/wod/redis
tag: 6.0.9 tag: 6.0.9
\ No newline at end of file
expose: expose:
type: ingress type: ingress
tls: tls:
enabled: false enabled: false
ingress: ingress:
hosts: hosts:
core: hub.wodcloud.local core: hub.wodcloud.local
notary: notary.wodcloud.local notary: notary.wodcloud.local
annotations: annotations:
ingress.kubernetes.io/proxy-body-size: "0" ingress.kubernetes.io/proxy-body-size: "0"
externalURL: https://hub.wodcloud.local externalURL: https://hub.wodcloud.local
persistence: persistence:
enabled: true enabled: true
persistentVolumeClaim: persistentVolumeClaim:
registry: registry:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
chartmuseum: chartmuseum:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
jobservice: jobservice:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
database: database:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
redis: redis:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
trivy: trivy:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
imageChartStorage: imageChartStorage:
# s3 , filesystem # s3 , filesystem
type: filesystem type: filesystem
s3: s3:
accesskey: AKIAIOSFODNN7EXAMPLE accesskey: AKIAIOSFODNN7EXAMPLE
secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region: us-east-1 region: us-east-1
regionendpoint: http://minio.wodcloud.local regionendpoint: http://minio.wodcloud.local
bucket: registry bucket: registry
encrypt: false encrypt: false
v4auth: true v4auth: true
chunksize: '5242880' chunksize: '5242880'
rootdirectory: / rootdirectory: /
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
logLevel: info logLevel: info
harborAdminPassword: "spaceIN511" harborAdminPassword: "spaceIN511"
secretKey: "IpTIscRIgmerlare" secretKey: "IpTIscRIgmerlare"
portal: portal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal
tag: v2.1.3-arm64 tag: v2.1.3-arm64
core: core:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core
tag: v2.1.3-arm64 tag: v2.1.3-arm64
jobservice: jobservice:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice
tag: v2.1.3-arm64 tag: v2.1.3-arm64
registry: registry:
registry: registry:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/registry repository: registry.cn-qingdao.aliyuncs.com/wod/registry
tag: 2.7.1-arm64 tag: 2.7.1-arm64
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
controller: controller:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl
tag: v2.1.3-arm64 tag: v2.1.3-arm64
chartmuseum: chartmuseum:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum
tag: v2.1.3-arm64 tag: v2.1.3-arm64
nodeSelector: {} nodeSelector: {}
# nodeSelector: # nodeSelector:
# harbor: enabled # harbor: enabled
storageSpec: storageSpec:
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
clair: clair:
clair: clair:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair
tag: v2.1.3-arm64 tag: v2.1.3-arm64
adapter: adapter:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter
tag: v2.1.3-arm64 tag: v2.1.3-arm64
trivy: trivy:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter
tag: v2.1.3-arm64 tag: v2.1.3-arm64
notary: notary:
server: server:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server
tag: v2.1.3-arm64 tag: v2.1.3-arm64
signer: signer:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer
tag: v2.1.3-arm64 tag: v2.1.3-arm64
database: database:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db
tag: v2.1.3-arm64 tag: v2.1.3-arm64
password: "spaceIN511" password: "spaceIN511"
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
redis: redis:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/redis repository: registry.cn-qingdao.aliyuncs.com/wod/redis
tag: 6.0.9-arm64 tag: 6.0.9-arm64
\ No newline at end of file
expose: expose:
type: ingress type: ingress
tls: tls:
enabled: false enabled: false
ingress: ingress:
hosts: hosts:
core: hub.test.wodcloud.com core: hub.test.wodcloud.com
notary: notary.test.wodcloud.com notary: notary.test.wodcloud.com
annotations: annotations:
ingress.kubernetes.io/proxy-body-size: "0" ingress.kubernetes.io/proxy-body-size: "0"
externalURL: https://hub.test.wodcloud.com externalURL: https://hub.test.wodcloud.com
persistence: persistence:
enabled: true enabled: true
imageChartStorage: imageChartStorage:
# s3 , filesystem # s3 , filesystem
type: filesystem type: filesystem
filesystem: filesystem:
rootdirectory: /data rootdirectory: /data
#s3: #s3:
# accesskey: AKIAIOSFODNN7EXAMPLE # accesskey: AKIAIOSFODNN7EXAMPLE
# secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY # secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# region: us-east-1 # region: us-east-1
# regionendpoint: https://minio.sxwh.local # regionendpoint: https://minio.sxwh.local
# bucket: registry # bucket: registry
# encrypt: false # encrypt: false
# v4auth: true # v4auth: true
# chunksize: '5242880' # chunksize: '5242880'
# rootdirectory: / # rootdirectory: /
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
logLevel: info logLevel: info
harborAdminPassword: "spaceIN511" harborAdminPassword: "spaceIN511"
secretKey: "IpTIscRIgmerlare" secretKey: "IpTIscRIgmerlare"
portal: portal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
core: core:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
jobservice: jobservice:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
maxJobWorkers: 10 maxJobWorkers: 10
jobLogger: file jobLogger: file
registry: registry:
registry: registry:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/registry repository: registry.cn-qingdao.aliyuncs.com/wod/registry
tag: 2.7.1 tag: 2.7.1
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
nodeSelector: nodeSelector:
harbor: enabled harbor: enabled
storageSpec: storageSpec:
# type: emptyDir , hostPath , volumeClaimTemplate # type: emptyDir , hostPath , volumeClaimTemplate
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
volumeClaimTemplate: volumeClaimTemplate:
spec: spec:
storageClassName: rook-ceph-block storageClassName: rook-ceph-block
accessModes: ["ReadWriteOnce"] accessModes: ["ReadWriteOnce"]
resources: resources:
requests: requests:
storage: 100Gi storage: 100Gi
selector: {} selector: {}
controller: controller:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
chartmuseum: chartmuseum:
enabled: true enabled: true
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon repository: registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon
tag: v0.9.0-v1.8.2 tag: v0.9.0-v1.8.2
replicas: 1 replicas: 1
nodeSelector: nodeSelector:
harbor: enabled harbor: enabled
storageSpec: storageSpec:
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
clair: clair:
enabled: true enabled: true
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/clair-photon repository: registry.cn-qingdao.aliyuncs.com/wod/clair-photon
tag: v2.0.8-v1.8.2 tag: v2.0.8-v1.8.2
replicas: 1 replicas: 1
notary: notary:
enabled: true enabled: true
server: server:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon repository: registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon
tag: v0.6.1-v1.8.2 tag: v0.6.1-v1.8.2
replicas: 1 replicas: 1
signer: signer:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon repository: registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon
tag: v0.6.1-v1.8.2 tag: v0.6.1-v1.8.2
replicas: 1 replicas: 1
database: database:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db
tag: v1.8.2 tag: v1.8.2
password: "spaceIN511" password: "spaceIN511"
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
nodeSelector: nodeSelector:
harbor: enabled harbor: enabled
storageSpec: storageSpec:
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
volumeClaimTemplate: volumeClaimTemplate:
spec: spec:
storageClassName: rook-ceph-block storageClassName: rook-ceph-block
accessModes: ["ReadWriteOnce"] accessModes: ["ReadWriteOnce"]
resources: resources:
requests: requests:
storage: 20Gi storage: 20Gi
selector: {} selector: {}
redis: redis:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/redis repository: registry.cn-qingdao.aliyuncs.com/wod/redis
tag: 4.0.14-alpine tag: 4.0.14-alpine
\ No newline at end of file
expose: expose:
type: ingress type: ingress
tls: tls:
enabled: false enabled: false
ingress: ingress:
hosts: hosts:
core: hub.wodcloud.local core: hub.wodcloud.local
notary: notary.wodcloud.local notary: notary.wodcloud.local
annotations: annotations:
ingress.kubernetes.io/proxy-body-size: "0" ingress.kubernetes.io/proxy-body-size: "0"
externalURL: https://hub.wodcloud.local externalURL: https://hub.wodcloud.local
persistence: persistence:
enabled: true enabled: true
persistentVolumeClaim: persistentVolumeClaim:
registry: registry:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
chartmuseum: chartmuseum:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
jobservice: jobservice:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
database: database:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
redis: redis:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
trivy: trivy:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
imageChartStorage: imageChartStorage:
# s3 , filesystem # s3 , filesystem
type: filesystem type: filesystem
s3: s3:
accesskey: AKIAIOSFODNN7EXAMPLE accesskey: AKIAIOSFODNN7EXAMPLE
secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region: us-east-1 region: us-east-1
regionendpoint: http://minio.wodcloud.local regionendpoint: http://minio.wodcloud.local
bucket: registry bucket: registry
encrypt: false encrypt: false
v4auth: true v4auth: true
chunksize: '5242880' chunksize: '5242880'
rootdirectory: / rootdirectory: /
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
logLevel: info logLevel: info
harborAdminPassword: "spaceIN511" harborAdminPassword: "spaceIN511"
secretKey: "IpTIscRIgmerlare" secretKey: "IpTIscRIgmerlare"
portal: portal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal
tag: v2.1.3-ppc64le tag: v2.1.3-ppc64le
core: core:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core
tag: v2.1.3-ppc64le tag: v2.1.3-ppc64le
jobservice: jobservice:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice
tag: v2.1.3-ppc64le tag: v2.1.3-ppc64le
registry: registry:
registry: registry:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/registry repository: registry.cn-qingdao.aliyuncs.com/wod/registry
tag: 2.7.1-ppc64le tag: 2.7.1-ppc64le
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
controller: controller:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl
tag: v2.1.3-ppc64le tag: v2.1.3-ppc64le
chartmuseum: chartmuseum:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-chartmuseum
tag: v2.1.1-ppc64le tag: v2.1.1-ppc64le
nodeSelector: {} nodeSelector: {}
# nodeSelector: # nodeSelector:
# harbor: enabled # harbor: enabled
storageSpec: storageSpec:
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
clair: clair:
clair: clair:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair
tag: v2.1.1-ppc64le tag: v2.1.1-ppc64le
adapter: adapter:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-clair-adapter
tag: v2.1.1-ppc64le tag: v2.1.1-ppc64le
trivy: trivy:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-trivy-adapter
tag: v2.1.1-ppc64le tag: v2.1.1-ppc64le
notary: notary:
server: server:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-server
tag: v2.1.1-ppc64le tag: v2.1.1-ppc64le
signer: signer:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-notary-signer
tag: v2.1.1-ppc64le tag: v2.1.1-ppc64le
database: database:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-db
tag: v2.1.3-ppc64le tag: v2.1.3-ppc64le
password: "spaceIN511" password: "spaceIN511"
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
redis: redis:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/redis repository: registry.cn-qingdao.aliyuncs.com/wod/redis
tag: 6.0.9-ppc64le tag: 6.0.9-ppc64le
\ No newline at end of file
expose: expose:
type: ingress type: ingress
tls: tls:
enabled: false enabled: false
ingress: ingress:
hosts: hosts:
core: hub.test.wodcloud.com core: hub.test.wodcloud.com
notary: notary.test.wodcloud.com notary: notary.test.wodcloud.com
annotations: annotations:
ingress.kubernetes.io/proxy-body-size: "0" ingress.kubernetes.io/proxy-body-size: "0"
externalURL: https://hub.test.wodcloud.com externalURL: https://hub.test.wodcloud.com
persistence: persistence:
enabled: true enabled: true
imageChartStorage: imageChartStorage:
# s3 , filesystem # s3 , filesystem
type: filesystem type: filesystem
filesystem: filesystem:
rootdirectory: /data rootdirectory: /data
#s3: #s3:
# accesskey: AKIAIOSFODNN7EXAMPLE # accesskey: AKIAIOSFODNN7EXAMPLE
# secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY # secretkey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
# region: us-east-1 # region: us-east-1
# regionendpoint: https://minio.sxwh.local # regionendpoint: https://minio.sxwh.local
# bucket: registry # bucket: registry
# encrypt: false # encrypt: false
# v4auth: true # v4auth: true
# chunksize: '5242880' # chunksize: '5242880'
# rootdirectory: / # rootdirectory: /
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
logLevel: info logLevel: info
harborAdminPassword: "spaceIN511" harborAdminPassword: "spaceIN511"
secretKey: "IpTIscRIgmerlare" secretKey: "IpTIscRIgmerlare"
portal: portal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-portal
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
core: core:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-core
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
jobservice: jobservice:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-jobservice
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
maxJobWorkers: 10 maxJobWorkers: 10
jobLogger: file jobLogger: file
registry: registry:
registry: registry:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/registry repository: registry.cn-qingdao.aliyuncs.com/wod/registry
tag: 2.7.1 tag: 2.7.1
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
nodeSelector: nodeSelector:
harbor: enabled harbor: enabled
storageSpec: storageSpec:
# type: emptyDir , hostPath , volumeClaimTemplate # type: emptyDir , hostPath , volumeClaimTemplate
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
volumeClaimTemplate: volumeClaimTemplate:
spec: spec:
storageClassName: rook-ceph-block storageClassName: rook-ceph-block
accessModes: ["ReadWriteOnce"] accessModes: ["ReadWriteOnce"]
resources: resources:
requests: requests:
storage: 100Gi storage: 100Gi
selector: {} selector: {}
controller: controller:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl repository: registry.cn-qingdao.aliyuncs.com/wod/harbor-registryctl
tag: v1.8.2 tag: v1.8.2
replicas: 1 replicas: 1
chartmuseum: chartmuseum:
enabled: true enabled: true
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon repository: registry.cn-qingdao.aliyuncs.com/wod/chartmuseum-photon
tag: v0.9.0-v1.8.2 tag: v0.9.0-v1.8.2
replicas: 1 replicas: 1
nodeSelector: nodeSelector:
harbor: enabled harbor: enabled
storageSpec: storageSpec:
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
clair: clair:
enabled: true enabled: true
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/clair-photon repository: registry.cn-qingdao.aliyuncs.com/wod/clair-photon
tag: v2.0.8-v1.8.2 tag: v2.0.8-v1.8.2
replicas: 1 replicas: 1
notary: notary:
enabled: true enabled: true
server: server:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon repository: registry.cn-qingdao.aliyuncs.com/wod/notary-server-photon
tag: v0.6.1-v1.8.2 tag: v0.6.1-v1.8.2
replicas: 1 replicas: 1
signer: signer:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon repository: registry.cn-qingdao.aliyuncs.com/wod/notary-signer-photon
tag: v0.6.1-v1.8.2 tag: v0.6.1-v1.8.2
replicas: 1 replicas: 1
database: database:
type: external type: external
external: external:
host: "stolon-proxy.devops" host: "stolon-proxy.devops"
port: "5432" port: "5432"
username: "postgres" username: "postgres"
password: "spaceIN511" password: "spaceIN511"
coreDatabase: "hub_registry" coreDatabase: "hub_registry"
clairDatabase: "hub_clair" clairDatabase: "hub_clair"
notaryServerDatabase: "hub_notary_server" notaryServerDatabase: "hub_notary_server"
notarySignerDatabase: "hub_notary_signer" notarySignerDatabase: "hub_notary_signer"
sslmode: "disable" sslmode: "disable"
redis: redis:
type: internal type: internal
internal: internal:
image: image:
repository: registry.cn-qingdao.aliyuncs.com/wod/redis repository: registry.cn-qingdao.aliyuncs.com/wod/redis
tag: 4.0.14-alpine tag: 4.0.14-alpine
\ No newline at end of file
expose: expose:
# Set the way how to expose the service. Set the type as "ingress", # Set the way how to expose the service. Set the type as "ingress",
# "clusterIP", "nodePort" or "loadBalancer" and fill the information # "clusterIP", "nodePort" or "loadBalancer" and fill the information
# in the corresponding section # in the corresponding section
type: ingress type: ingress
tls: tls:
# Enable the tls or not. Note: if the type is "ingress" and the tls # Enable the tls or not. Note: if the type is "ingress" and the tls
# is disabled, the port must be included in the command when pull/push # is disabled, the port must be included in the command when pull/push
# images. Refer to https://github.com/goharbor/harbor/issues/5291 # images. Refer to https://github.com/goharbor/harbor/issues/5291
# for the detail. # for the detail.
enabled: true enabled: true
# The source of the tls certificate. Set it as "auto", "secret" # The source of the tls certificate. Set it as "auto", "secret"
# or "none" and fill the information in the corresponding section # or "none" and fill the information in the corresponding section
# 1) auto: generate the tls certificate automatically # 1) auto: generate the tls certificate automatically
# 2) secret: read the tls certificate from the specified secret. # 2) secret: read the tls certificate from the specified secret.
# The tls certificate can be generated manually or by cert manager # The tls certificate can be generated manually or by cert manager
# 3) none: configure no tls certificate for the ingress. If the default # 3) none: configure no tls certificate for the ingress. If the default
# tls certificate is configured in the ingress controller, choose this option # tls certificate is configured in the ingress controller, choose this option
certSource: auto certSource: auto
auto: auto:
# The common name used to generate the certificate, it's necessary # The common name used to generate the certificate, it's necessary
# when the type isn't "ingress" # when the type isn't "ingress"
commonName: "" commonName: ""
secret: secret:
# The name of secret which contains keys named: # The name of secret which contains keys named:
# "tls.crt" - the certificate # "tls.crt" - the certificate
# "tls.key" - the private key # "tls.key" - the private key
secretName: "" secretName: ""
# The name of secret which contains keys named: # The name of secret which contains keys named:
# "tls.crt" - the certificate # "tls.crt" - the certificate
# "tls.key" - the private key # "tls.key" - the private key
# Only needed when the "expose.type" is "ingress". # Only needed when the "expose.type" is "ingress".
notarySecretName: "" notarySecretName: ""
ingress: ingress:
hosts: hosts:
core: core.harbor.domain core: core.harbor.domain
notary: notary.harbor.domain notary: notary.harbor.domain
# set to the type of ingress controller if it has specific requirements. # set to the type of ingress controller if it has specific requirements.
# leave as `default` for most ingress controllers. # leave as `default` for most ingress controllers.
# set to `gce` if using the GCE ingress controller # set to `gce` if using the GCE ingress controller
# set to `ncp` if using the NCP (NSX-T Container Plugin) ingress controller # set to `ncp` if using the NCP (NSX-T Container Plugin) ingress controller
controller: default controller: default
annotations: annotations:
ingress.kubernetes.io/ssl-redirect: "true" ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-body-size: "0" ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-body-size: "0"
clusterIP: clusterIP:
# The name of ClusterIP service # The name of ClusterIP service
name: harbor name: harbor
ports: ports:
# The service port Harbor listens on when serving with HTTP # The service port Harbor listens on when serving with HTTP
httpPort: 80 httpPort: 80
# The service port Harbor listens on when serving with HTTPS # The service port Harbor listens on when serving with HTTPS
httpsPort: 443 httpsPort: 443
# The service port Notary listens on. Only needed when notary.enabled # The service port Notary listens on. Only needed when notary.enabled
# is set to true # is set to true
notaryPort: 4443 notaryPort: 4443
nodePort: nodePort:
# The name of NodePort service # The name of NodePort service
name: harbor name: harbor
ports: ports:
http: http:
# The service port Harbor listens on when serving with HTTP # The service port Harbor listens on when serving with HTTP
port: 80 port: 80
# The node port Harbor listens on when serving with HTTP # The node port Harbor listens on when serving with HTTP
nodePort: 30002 nodePort: 30002
https: https:
# The service port Harbor listens on when serving with HTTPS # The service port Harbor listens on when serving with HTTPS
port: 443 port: 443
# The node port Harbor listens on when serving with HTTPS # The node port Harbor listens on when serving with HTTPS
nodePort: 30003 nodePort: 30003
# Only needed when notary.enabled is set to true # Only needed when notary.enabled is set to true
notary: notary:
# The service port Notary listens on # The service port Notary listens on
port: 4443 port: 4443
# The node port Notary listens on # The node port Notary listens on
nodePort: 30004 nodePort: 30004
loadBalancer: loadBalancer:
# The name of LoadBalancer service # The name of LoadBalancer service
name: harbor name: harbor
# Set the IP if the LoadBalancer supports assigning IP # Set the IP if the LoadBalancer supports assigning IP
IP: "" IP: ""
ports: ports:
# The service port Harbor listens on when serving with HTTP # The service port Harbor listens on when serving with HTTP
httpPort: 80 httpPort: 80
# The service port Harbor listens on when serving with HTTPS # The service port Harbor listens on when serving with HTTPS
httpsPort: 443 httpsPort: 443
# The service port Notary listens on. Only needed when notary.enabled # The service port Notary listens on. Only needed when notary.enabled
# is set to true # is set to true
notaryPort: 4443 notaryPort: 4443
annotations: {} annotations: {}
sourceRanges: [] sourceRanges: []
# The external URL for Harbor core service. It is used to # The external URL for Harbor core service. It is used to
# 1) populate the docker/helm commands showed on portal # 1) populate the docker/helm commands showed on portal
# 2) populate the token service URL returned to docker/notary client # 2) populate the token service URL returned to docker/notary client
# #
# Format: protocol://domain[:port]. Usually: # Format: protocol://domain[:port]. Usually:
# 1) if "expose.type" is "ingress", the "domain" should be # 1) if "expose.type" is "ingress", the "domain" should be
# the value of "expose.ingress.hosts.core" # the value of "expose.ingress.hosts.core"
# 2) if "expose.type" is "clusterIP", the "domain" should be # 2) if "expose.type" is "clusterIP", the "domain" should be
# the value of "expose.clusterIP.name" # the value of "expose.clusterIP.name"
# 3) if "expose.type" is "nodePort", the "domain" should be # 3) if "expose.type" is "nodePort", the "domain" should be
# the IP address of k8s node # the IP address of k8s node
# #
# If Harbor is deployed behind the proxy, set it as the URL of proxy # If Harbor is deployed behind the proxy, set it as the URL of proxy
externalURL: https://core.harbor.domain externalURL: https://core.harbor.domain
# The internal TLS used for harbor components secure communicating. In order to enable https # The internal TLS used for harbor components secure communicating. In order to enable https
# in each components tls cert files need to provided in advance. # in each components tls cert files need to provided in advance.
internalTLS: internalTLS:
# If internal TLS enabled # If internal TLS enabled
enabled: false enabled: false
# There are three ways to provide tls # There are three ways to provide tls
# 1) "auto" will generate cert automatically # 1) "auto" will generate cert automatically
# 2) "manual" need provide cert file manually in following value # 2) "manual" need provide cert file manually in following value
# 3) "secret" internal certificates from secret # 3) "secret" internal certificates from secret
certSource: "auto" certSource: "auto"
# The content of trust ca, only available when `certSource` is "manual" # The content of trust ca, only available when `certSource` is "manual"
trustCa: "" trustCa: ""
# core related cert configuration # core related cert configuration
core: core:
# secret name for core's tls certs # secret name for core's tls certs
secretName: "" secretName: ""
# Content of core's TLS cert file, only available when `certSource` is "manual" # Content of core's TLS cert file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of core's TLS key file, only available when `certSource` is "manual" # Content of core's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# jobservice related cert configuration # jobservice related cert configuration
jobservice: jobservice:
# secret name for jobservice's tls certs # secret name for jobservice's tls certs
secretName: "" secretName: ""
# Content of jobservice's TLS key file, only available when `certSource` is "manual" # Content of jobservice's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of jobservice's TLS key file, only available when `certSource` is "manual" # Content of jobservice's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# registry related cert configuration # registry related cert configuration
registry: registry:
# secret name for registry's tls certs # secret name for registry's tls certs
secretName: "" secretName: ""
# Content of registry's TLS key file, only available when `certSource` is "manual" # Content of registry's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of registry's TLS key file, only available when `certSource` is "manual" # Content of registry's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# portal related cert configuration # portal related cert configuration
portal: portal:
# secret name for portal's tls certs # secret name for portal's tls certs
secretName: "" secretName: ""
# Content of portal's TLS key file, only available when `certSource` is "manual" # Content of portal's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of portal's TLS key file, only available when `certSource` is "manual" # Content of portal's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# chartmuseum related cert configuration # chartmuseum related cert configuration
chartmuseum: chartmuseum:
# secret name for chartmuseum's tls certs # secret name for chartmuseum's tls certs
secretName: "" secretName: ""
# Content of chartmuseum's TLS key file, only available when `certSource` is "manual" # Content of chartmuseum's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of chartmuseum's TLS key file, only available when `certSource` is "manual" # Content of chartmuseum's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# clair related cert configuration # clair related cert configuration
clair: clair:
# secret name for clair's tls certs # secret name for clair's tls certs
secretName: "" secretName: ""
# Content of clair's TLS key file, only available when `certSource` is "manual" # Content of clair's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of clair's TLS key file, only available when `certSource` is "manual" # Content of clair's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# trivy related cert configuration # trivy related cert configuration
trivy: trivy:
# secret name for trivy's tls certs # secret name for trivy's tls certs
secretName: "" secretName: ""
# Content of trivy's TLS key file, only available when `certSource` is "manual" # Content of trivy's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of trivy's TLS key file, only available when `certSource` is "manual" # Content of trivy's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# The persistence is enabled by default and a default StorageClass # The persistence is enabled by default and a default StorageClass
# is needed in the k8s cluster to provision volumes dynamicly. # is needed in the k8s cluster to provision volumes dynamicly.
# Specify another StorageClass in the "storageClass" or set "existingClaim" # Specify another StorageClass in the "storageClass" or set "existingClaim"
# if you have already existing persistent volumes to use # if you have already existing persistent volumes to use
# #
# For storing images and charts, you can also use "azure", "gcs", "s3", # For storing images and charts, you can also use "azure", "gcs", "s3",
# "swift" or "oss". Set it in the "imageChartStorage" section # "swift" or "oss". Set it in the "imageChartStorage" section
persistence: persistence:
enabled: true enabled: true
# Setting it to "keep" to avoid removing PVCs during a helm delete # Setting it to "keep" to avoid removing PVCs during a helm delete
# operation. Leaving it empty will delete PVCs after the chart deleted # operation. Leaving it empty will delete PVCs after the chart deleted
# (this does not apply for PVCs that are created for internal database # (this does not apply for PVCs that are created for internal database
# and redis components, i.e. they are never deleted automatically) # and redis components, i.e. they are never deleted automatically)
resourcePolicy: "keep" resourcePolicy: "keep"
persistentVolumeClaim: persistentVolumeClaim:
registry: registry:
# Use the existing PVC which must be created manually before bound, # Use the existing PVC which must be created manually before bound,
# and specify the "subPath" if the PVC is shared with other components # and specify the "subPath" if the PVC is shared with other components
existingClaim: "" existingClaim: ""
# Specify the "storageClass" used to provision the volume. Or the default # Specify the "storageClass" used to provision the volume. Or the default
# StorageClass will be used(the default). # StorageClass will be used(the default).
# Set it to "-" to disable dynamic provisioning # Set it to "-" to disable dynamic provisioning
storageClass: "" storageClass: ""
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
chartmuseum: chartmuseum:
existingClaim: "" existingClaim: ""
storageClass: "" storageClass: ""
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
jobservice: jobservice:
existingClaim: "" existingClaim: ""
storageClass: "" storageClass: ""
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
# If external database is used, the following settings for database will # If external database is used, the following settings for database will
# be ignored # be ignored
database: database:
existingClaim: "" existingClaim: ""
storageClass: "" storageClass: ""
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
# If external Redis is used, the following settings for Redis will # If external Redis is used, the following settings for Redis will
# be ignored # be ignored
redis: redis:
existingClaim: "" existingClaim: ""
storageClass: "" storageClass: ""
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
trivy: trivy:
existingClaim: "" existingClaim: ""
storageClass: "" storageClass: ""
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
# Define which storage backend is used for registry and chartmuseum to store # Define which storage backend is used for registry and chartmuseum to store
# images and charts. Refer to # images and charts. Refer to
# https://github.com/docker/distribution/blob/master/docs/configuration.md#storage # https://github.com/docker/distribution/blob/master/docs/configuration.md#storage
# for the detail. # for the detail.
imageChartStorage: imageChartStorage:
# Specify whether to disable `redirect` for images and chart storage, for # Specify whether to disable `redirect` for images and chart storage, for
# backends which not supported it (such as using minio for `s3` storage type), please disable # backends which not supported it (such as using minio for `s3` storage type), please disable
# it. To disable redirects, simply set `disableredirect` to `true` instead. # it. To disable redirects, simply set `disableredirect` to `true` instead.
# Refer to # Refer to
# https://github.com/docker/distribution/blob/master/docs/configuration.md#redirect # https://github.com/docker/distribution/blob/master/docs/configuration.md#redirect
# for the detail. # for the detail.
disableredirect: false disableredirect: false
# Specify the "caBundleSecretName" if the storage service uses a self-signed certificate. # Specify the "caBundleSecretName" if the storage service uses a self-signed certificate.
# The secret must contain keys named "ca.crt" which will be injected into the trust store # The secret must contain keys named "ca.crt" which will be injected into the trust store
# of registry's and chartmuseum's containers. # of registry's and chartmuseum's containers.
# caBundleSecretName: # caBundleSecretName:
# Specify the type of storage: "filesystem", "azure", "gcs", "s3", "swift", # Specify the type of storage: "filesystem", "azure", "gcs", "s3", "swift",
# "oss" and fill the information needed in the corresponding section. The type # "oss" and fill the information needed in the corresponding section. The type
# must be "filesystem" if you want to use persistent volumes for registry # must be "filesystem" if you want to use persistent volumes for registry
# and chartmuseum # and chartmuseum
type: filesystem type: filesystem
filesystem: filesystem:
rootdirectory: /storage rootdirectory: /storage
#maxthreads: 100 #maxthreads: 100
azure: azure:
accountname: accountname accountname: accountname
accountkey: base64encodedaccountkey accountkey: base64encodedaccountkey
container: containername container: containername
#realm: core.windows.net #realm: core.windows.net
gcs: gcs:
bucket: bucketname bucket: bucketname
# The base64 encoded json file which contains the key # The base64 encoded json file which contains the key
encodedkey: base64-encoded-json-key-file encodedkey: base64-encoded-json-key-file
#rootdirectory: /gcs/object/name/prefix #rootdirectory: /gcs/object/name/prefix
#chunksize: "5242880" #chunksize: "5242880"
s3: s3:
region: us-west-1 region: us-west-1
bucket: bucketname bucket: bucketname
#accesskey: awsaccesskey #accesskey: awsaccesskey
#secretkey: awssecretkey #secretkey: awssecretkey
#regionendpoint: http://myobjects.local #regionendpoint: http://myobjects.local
#encrypt: false #encrypt: false
#keyid: mykeyid #keyid: mykeyid
#secure: true #secure: true
#skipverify: false #skipverify: false
#v4auth: true #v4auth: true
#chunksize: "5242880" #chunksize: "5242880"
#rootdirectory: /s3/object/name/prefix #rootdirectory: /s3/object/name/prefix
#storageclass: STANDARD #storageclass: STANDARD
#multipartcopychunksize: "33554432" #multipartcopychunksize: "33554432"
#multipartcopymaxconcurrency: 100 #multipartcopymaxconcurrency: 100
#multipartcopythresholdsize: "33554432" #multipartcopythresholdsize: "33554432"
swift: swift:
authurl: https://storage.myprovider.com/v3/auth authurl: https://storage.myprovider.com/v3/auth
username: username username: username
password: password password: password
container: containername container: containername
#region: fr #region: fr
#tenant: tenantname #tenant: tenantname
#tenantid: tenantid #tenantid: tenantid
#domain: domainname #domain: domainname
#domainid: domainid #domainid: domainid
#trustid: trustid #trustid: trustid
#insecureskipverify: false #insecureskipverify: false
#chunksize: 5M #chunksize: 5M
#prefix: #prefix:
#secretkey: secretkey #secretkey: secretkey
#accesskey: accesskey #accesskey: accesskey
#authversion: 3 #authversion: 3
#endpointtype: public #endpointtype: public
#tempurlcontainerkey: false #tempurlcontainerkey: false
#tempurlmethods: #tempurlmethods:
oss: oss:
accesskeyid: accesskeyid accesskeyid: accesskeyid
accesskeysecret: accesskeysecret accesskeysecret: accesskeysecret
region: regionname region: regionname
bucket: bucketname bucket: bucketname
#endpoint: endpoint #endpoint: endpoint
#internal: false #internal: false
#encrypt: false #encrypt: false
#secure: true #secure: true
#chunksize: 10M #chunksize: 10M
#rootdirectory: rootdirectory #rootdirectory: rootdirectory
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
# Use this set to assign a list of default pullSecrets # Use this set to assign a list of default pullSecrets
imagePullSecrets: imagePullSecrets:
# - name: docker-registry-secret # - name: docker-registry-secret
# - name: internal-registry-secret # - name: internal-registry-secret
# The update strategy for deployments with persistent volumes(jobservice, registry # The update strategy for deployments with persistent volumes(jobservice, registry
# and chartmuseum): "RollingUpdate" or "Recreate" # and chartmuseum): "RollingUpdate" or "Recreate"
# Set it as "Recreate" when "RWM" for volumes isn't supported # Set it as "Recreate" when "RWM" for volumes isn't supported
updateStrategy: updateStrategy:
type: RollingUpdate type: RollingUpdate
# debug, info, warning, error or fatal # debug, info, warning, error or fatal
logLevel: info logLevel: info
# The initial password of Harbor admin. Change it from portal after launching Harbor # The initial password of Harbor admin. Change it from portal after launching Harbor
harborAdminPassword: "Harbor12345" harborAdminPassword: "Harbor12345"
# The name of the secret which contains key named "ca.crt". Setting this enables the # The name of the secret which contains key named "ca.crt". Setting this enables the
# download link on portal to download the certificate of CA when the certificate isn't # download link on portal to download the certificate of CA when the certificate isn't
# generated automatically # generated automatically
caSecretName: "" caSecretName: ""
# The secret key used for encryption. Must be a string of 16 chars. # The secret key used for encryption. Must be a string of 16 chars.
secretKey: "not-a-secure-key" secretKey: "not-a-secure-key"
# The proxy settings for updating clair vulnerabilities from the Internet and replicating # The proxy settings for updating clair vulnerabilities from the Internet and replicating
# artifacts from/to the registries that cannot be reached directly # artifacts from/to the registries that cannot be reached directly
proxy: proxy:
httpProxy: httpProxy:
httpsProxy: httpsProxy:
noProxy: 127.0.0.1,localhost,.local,.internal noProxy: 127.0.0.1,localhost,.local,.internal
components: components:
- core - core
- jobservice - jobservice
- clair - clair
- trivy - trivy
# The custom ca bundle secret, the secret must contain key named "ca.crt" # The custom ca bundle secret, the secret must contain key named "ca.crt"
# which will be injected into the trust store for chartmuseum, clair, core, jobservice, registry, trivy components # which will be injected into the trust store for chartmuseum, clair, core, jobservice, registry, trivy components
# caBundleSecretName: "" # caBundleSecretName: ""
## UAA Authentication Options ## UAA Authentication Options
# If you're using UAA for authentication behind a self-signed # If you're using UAA for authentication behind a self-signed
# certificate you will need to provide the CA Cert. # certificate you will need to provide the CA Cert.
# Set uaaSecretName below to provide a pre-created secret that # Set uaaSecretName below to provide a pre-created secret that
# contains a base64 encoded CA Certificate named `ca.crt`. # contains a base64 encoded CA Certificate named `ca.crt`.
# uaaSecretName: # uaaSecretName:
# If expose the service via "ingress", the Nginx will not be used # If expose the service via "ingress", the Nginx will not be used
nginx: nginx:
image: image:
repository: goharbor/nginx-photon repository: goharbor/nginx-photon
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
portal: portal:
image: image:
repository: goharbor/harbor-portal repository: goharbor/harbor-portal
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
core: core:
image: image:
repository: goharbor/harbor-core repository: goharbor/harbor-core
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
replicas: 1 replicas: 1
## Startup probe values ## Startup probe values
startupProbe: startupProbe:
enabled: true enabled: true
initialDelaySeconds: 10 initialDelaySeconds: 10
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Secret is used when core server communicates with other components. # Secret is used when core server communicates with other components.
# If a secret key is not specified, Helm will generate one. # If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars. # Must be a string of 16 chars.
secret: "" secret: ""
# Fill the name of a kubernetes secret if you want to use your own # Fill the name of a kubernetes secret if you want to use your own
# TLS certificate and private key for token encryption/decryption. # TLS certificate and private key for token encryption/decryption.
# The secret must contain keys named: # The secret must contain keys named:
# "tls.crt" - the certificate # "tls.crt" - the certificate
# "tls.key" - the private key # "tls.key" - the private key
# The default key pair will be used if it isn't set # The default key pair will be used if it isn't set
secretName: "" secretName: ""
# The XSRF key. Will be generated automatically if it isn't specified # The XSRF key. Will be generated automatically if it isn't specified
xsrfKey: "" xsrfKey: ""
jobservice: jobservice:
image: image:
repository: goharbor/harbor-jobservice repository: goharbor/harbor-jobservice
tag: v2.1.3 tag: v2.1.3
replicas: 1 replicas: 1
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
maxJobWorkers: 10 maxJobWorkers: 10
# The logger for jobs: "file", "database" or "stdout" # The logger for jobs: "file", "database" or "stdout"
jobLogger: file jobLogger: file
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Secret is used when job service communicates with other components. # Secret is used when job service communicates with other components.
# If a secret key is not specified, Helm will generate one. # If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars. # Must be a string of 16 chars.
secret: "" secret: ""
registry: registry:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
registry: registry:
image: image:
repository: goharbor/registry-photon repository: goharbor/registry-photon
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
controller: controller:
image: image:
repository: goharbor/harbor-registryctl repository: goharbor/harbor-registryctl
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
replicas: 1 replicas: 1
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Secret is used to secure the upload state from client # Secret is used to secure the upload state from client
# and registry storage backend. # and registry storage backend.
# See: https://github.com/docker/distribution/blob/master/docs/configuration.md#http # See: https://github.com/docker/distribution/blob/master/docs/configuration.md#http
# If a secret key is not specified, Helm will generate one. # If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars. # Must be a string of 16 chars.
secret: "" secret: ""
# If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. # If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL.
relativeurls: false relativeurls: false
credentials: credentials:
username: "harbor_registry_user" username: "harbor_registry_user"
password: "harbor_registry_password" password: "harbor_registry_password"
# If you update the username or password of registry, make sure use cli tool htpasswd to generate the bcrypt hash # If you update the username or password of registry, make sure use cli tool htpasswd to generate the bcrypt hash
# e.g. "htpasswd -nbBC10 $username $password" # e.g. "htpasswd -nbBC10 $username $password"
htpasswd: "harbor_registry_user:$2y$10$9L4Tc0DJbFFMB6RdSCunrOpTHdwhid4ktBJmLD00bYgqkkGOvll3m" htpasswd: "harbor_registry_user:$2y$10$9L4Tc0DJbFFMB6RdSCunrOpTHdwhid4ktBJmLD00bYgqkkGOvll3m"
middleware: middleware:
enabled: false enabled: false
type: cloudFront type: cloudFront
cloudFront: cloudFront:
baseurl: example.cloudfront.net baseurl: example.cloudfront.net
keypairid: KEYPAIRID keypairid: KEYPAIRID
duration: 3000s duration: 3000s
ipfilteredby: none ipfilteredby: none
# The secret key that should be present is CLOUDFRONT_KEY_DATA, which should be the encoded private key # The secret key that should be present is CLOUDFRONT_KEY_DATA, which should be the encoded private key
# that allows access to CloudFront # that allows access to CloudFront
privateKeySecret: "my-secret" privateKeySecret: "my-secret"
chartmuseum: chartmuseum:
enabled: true enabled: true
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
# Harbor defaults ChartMuseum to returning relative urls, if you want using absolute url you should enable it by change the following value to 'true' # Harbor defaults ChartMuseum to returning relative urls, if you want using absolute url you should enable it by change the following value to 'true'
absoluteUrl: false absoluteUrl: false
image: image:
repository: goharbor/chartmuseum-photon repository: goharbor/chartmuseum-photon
tag: v2.1.3 tag: v2.1.3
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
clair: clair:
enabled: true enabled: true
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
clair: clair:
image: image:
repository: goharbor/clair-photon repository: goharbor/clair-photon
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
adapter: adapter:
image: image:
repository: goharbor/clair-adapter-photon repository: goharbor/clair-adapter-photon
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
replicas: 1 replicas: 1
# The interval of clair updaters, the unit is hour, set to 0 to # The interval of clair updaters, the unit is hour, set to 0 to
# disable the updaters # disable the updaters
updatersInterval: 12 updatersInterval: 12
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
trivy: trivy:
# enabled the flag to enable Trivy scanner # enabled the flag to enable Trivy scanner
enabled: true enabled: true
image: image:
# repository the repository for Trivy adapter image # repository the repository for Trivy adapter image
repository: goharbor/trivy-adapter-photon repository: goharbor/trivy-adapter-photon
# tag the tag for Trivy adapter image # tag the tag for Trivy adapter image
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
# replicas the number of Pod replicas # replicas the number of Pod replicas
replicas: 1 replicas: 1
# debugMode the flag to enable Trivy debug mode with more verbose scanning log # debugMode the flag to enable Trivy debug mode with more verbose scanning log
debugMode: false debugMode: false
# vulnType a comma-separated list of vulnerability types. Possible values are `os` and `library`. # vulnType a comma-separated list of vulnerability types. Possible values are `os` and `library`.
vulnType: "os,library" vulnType: "os,library"
# severity a comma-separated list of severities to be checked # severity a comma-separated list of severities to be checked
severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"
# ignoreUnfixed the flag to display only fixed vulnerabilities # ignoreUnfixed the flag to display only fixed vulnerabilities
ignoreUnfixed: false ignoreUnfixed: false
# insecure the flag to skip verifying registry certificate # insecure the flag to skip verifying registry certificate
insecure: false insecure: false
# gitHubToken the GitHub access token to download Trivy DB # gitHubToken the GitHub access token to download Trivy DB
# #
# Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases. # Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases.
# It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached # It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached
# in the local file system (`/home/scanner/.cache/trivy/db/trivy.db`). In addition, the database contains the update # in the local file system (`/home/scanner/.cache/trivy/db/trivy.db`). In addition, the database contains the update
# timestamp so Trivy can detect whether it should download a newer version from the Internet or use the cached one. # timestamp so Trivy can detect whether it should download a newer version from the Internet or use the cached one.
# Currently, the database is updated every 12 hours and published as a new release to GitHub. # Currently, the database is updated every 12 hours and published as a new release to GitHub.
# #
# Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough # Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough
# for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000 # for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000
# requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult # requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult
# https://developer.github.com/v3/#rate-limiting # https://developer.github.com/v3/#rate-limiting
# #
# You can create a GitHub token by following the instructions in # You can create a GitHub token by following the instructions in
# https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line # https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
gitHubToken: "" gitHubToken: ""
# skipUpdate the flag to disable Trivy DB downloads from GitHub # skipUpdate the flag to disable Trivy DB downloads from GitHub
# #
# You might want to set the value of this flag to `true` in test or CI/CD environments to avoid GitHub rate limiting issues. # You might want to set the value of this flag to `true` in test or CI/CD environments to avoid GitHub rate limiting issues.
# If the value is set to `true` you have to manually download the `trivy.db` file and mount it in the # If the value is set to `true` you have to manually download the `trivy.db` file and mount it in the
# `/home/scanner/.cache/trivy/db/trivy.db` path. # `/home/scanner/.cache/trivy/db/trivy.db` path.
skipUpdate: false skipUpdate: false
resources: resources:
requests: requests:
cpu: 200m cpu: 200m
memory: 512Mi memory: 512Mi
limits: limits:
cpu: 1 cpu: 1
memory: 1Gi memory: 1Gi
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
notary: notary:
enabled: true enabled: true
server: server:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: goharbor/notary-server-photon repository: goharbor/notary-server-photon
tag: v2.1.3 tag: v2.1.3
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
signer: signer:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: goharbor/notary-signer-photon repository: goharbor/notary-signer-photon
tag: v2.1.3 tag: v2.1.3
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Fill the name of a kubernetes secret if you want to use your own # Fill the name of a kubernetes secret if you want to use your own
# TLS certificate authority, certificate and private key for notary # TLS certificate authority, certificate and private key for notary
# communications. # communications.
# The secret must contain keys named ca.crt, tls.crt and tls.key that # The secret must contain keys named ca.crt, tls.crt and tls.key that
# contain the CA, certificate and private key. # contain the CA, certificate and private key.
# They will be generated if not set. # They will be generated if not set.
secretName: "" secretName: ""
database: database:
# if external database is used, set "type" to "external" # if external database is used, set "type" to "external"
# and fill the connection informations in "external" section # and fill the connection informations in "external" section
type: internal type: internal
internal: internal:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: goharbor/harbor-db repository: goharbor/harbor-db
tag: v2.1.3 tag: v2.1.3
# The initial superuser password for internal database # The initial superuser password for internal database
password: "changeit" password: "changeit"
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
external: external:
host: "192.168.0.1" host: "192.168.0.1"
port: "5432" port: "5432"
username: "user" username: "user"
password: "password" password: "password"
coreDatabase: "registry" coreDatabase: "registry"
clairDatabase: "clair" clairDatabase: "clair"
notaryServerDatabase: "notary_server" notaryServerDatabase: "notary_server"
notarySignerDatabase: "notary_signer" notarySignerDatabase: "notary_signer"
# "disable" - No SSL # "disable" - No SSL
# "require" - Always SSL (skip verification) # "require" - Always SSL (skip verification)
# "verify-ca" - Always SSL (verify that the certificate presented by the # "verify-ca" - Always SSL (verify that the certificate presented by the
# server was signed by a trusted CA) # server was signed by a trusted CA)
# "verify-full" - Always SSL (verify that the certification presented by the # "verify-full" - Always SSL (verify that the certification presented by the
# server was signed by a trusted CA and the server host name matches the one # server was signed by a trusted CA and the server host name matches the one
# in the certificate) # in the certificate)
sslmode: "disable" sslmode: "disable"
# The maximum number of connections in the idle connection pool. # The maximum number of connections in the idle connection pool.
# If it <=0, no idle connections are retained. # If it <=0, no idle connections are retained.
maxIdleConns: 50 maxIdleConns: 50
# The maximum number of open connections to the database. # The maximum number of open connections to the database.
# If it <= 0, then there is no limit on the number of open connections. # If it <= 0, then there is no limit on the number of open connections.
# Note: the default number of connections is 1024 for postgre of harbor. # Note: the default number of connections is 1024 for postgre of harbor.
maxOpenConns: 1000 maxOpenConns: 1000
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
redis: redis:
# if external Redis is used, set "type" to "external" # if external Redis is used, set "type" to "external"
# and fill the connection informations in "external" section # and fill the connection informations in "external" section
type: internal type: internal
internal: internal:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: goharbor/redis-photon repository: goharbor/redis-photon
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
external: external:
# support redis, redis+sentinel # support redis, redis+sentinel
# addr for redis: <host_redis>:<port_redis> # addr for redis: <host_redis>:<port_redis>
# addr for redis+sentinel: <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3> # addr for redis+sentinel: <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3>
addr: "192.168.0.2:6379" addr: "192.168.0.2:6379"
# The name of the set of Redis instances to monitor, it must be set to support redis+sentinel # The name of the set of Redis instances to monitor, it must be set to support redis+sentinel
sentinelMasterSet: "" sentinelMasterSet: ""
# The "coreDatabaseIndex" must be "0" as the library Harbor # The "coreDatabaseIndex" must be "0" as the library Harbor
# used doesn't support configuring it # used doesn't support configuring it
coreDatabaseIndex: "0" coreDatabaseIndex: "0"
jobserviceDatabaseIndex: "1" jobserviceDatabaseIndex: "1"
registryDatabaseIndex: "2" registryDatabaseIndex: "2"
chartmuseumDatabaseIndex: "3" chartmuseumDatabaseIndex: "3"
clairAdapterIndex: "4" clairAdapterIndex: "4"
trivyAdapterIndex: "5" trivyAdapterIndex: "5"
password: "" password: ""
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
commonLabels: commonLabels:
app.bd-apaas.com/cluster-component: registry app.bd-apaas.com/cluster-component: registry
\ No newline at end of file
Please wait for several minutes for Harbor deployment to complete. Please wait for several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}.{{ $.Values.global.host }} Then you should be able to visit the Harbor portal at {{ .Values.externalURL }}.{{ $.Values.global.host }}
For more details, please visit https://github.com/goharbor/harbor For more details, please visit https://github.com/goharbor/harbor
{{/* {{/*
Create chart imageArch suffix. Create chart imageArch suffix.
*/}} */}}
{{- define ".beagle.imageArch" -}} {{- define ".beagle.imageArch" -}}
{{- if not (eq "amd64" .Values.global.imageArch) -}} {{- if not (eq "amd64" .Values.global.imageArch) -}}
{{- print "-" .Values.global.imageArch -}} {{- print "-" .Values.global.imageArch -}}
{{- else -}} {{- else -}}
{{- print "" -}} {{- print "" -}}
{{- end -}} {{- end -}}
{{- end }} {{- end }}
{{/* vim: set filetype=mustache: */}} {{/* vim: set filetype=mustache: */}}
{{/* {{/*
Expand the name of the chart. Expand the name of the chart.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}} */}}
{{- define "harbor.name" -}} {{- define "harbor.name" -}}
{{- default "harbor" .Values.nameOverride | trunc 63 | trimSuffix "-" -}} {{- default "harbor" .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}} {{- end -}}
{{/* {{/*
Create a default fully qualified app name. Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}} */}}
{{- define "harbor.fullname" -}} {{- define "harbor.fullname" -}}
{{- $name := default "harbor" .Values.nameOverride -}} {{- $name := default "harbor" .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}} {{- end -}}
{{/* Helm required labels */}} {{/* Helm required labels */}}
{{- define "harbor.labels" -}} {{- define "harbor.labels" -}}
heritage: {{ .Release.Service }} heritage: {{ .Release.Service }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
chart: {{ .Chart.Name }} chart: {{ .Chart.Name }}
app: "{{ template "harbor.name" . }}" app: "{{ template "harbor.name" . }}"
{{- if .Values.commonLabels}} {{- if .Values.commonLabels}}
{{ toYaml .Values.commonLabels }} {{ toYaml .Values.commonLabels }}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{/* matchLabels */}} {{/* matchLabels */}}
{{- define "harbor.matchLabels" -}} {{- define "harbor.matchLabels" -}}
release: {{ .Release.Name }} release: {{ .Release.Name }}
app: "{{ template "harbor.name" . }}" app: "{{ template "harbor.name" . }}"
{{- end -}} {{- end -}}
{{- define "harbor.autoGenCert" -}} {{- define "harbor.autoGenCert" -}}
{{- if and .Values.expose.tls.enabled (eq .Values.expose.tls.certSource "auto") -}} {{- if and .Values.expose.tls.enabled (eq .Values.expose.tls.certSource "auto") -}}
{{- printf "true" -}} {{- printf "true" -}}
{{- else -}} {{- else -}}
{{- printf "false" -}} {{- printf "false" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.autoGenCertForIngress" -}} {{- define "harbor.autoGenCertForIngress" -}}
{{- if and (eq (include "harbor.autoGenCert" .) "true") (eq .Values.expose.type "ingress") -}} {{- if and (eq (include "harbor.autoGenCert" .) "true") (eq .Values.expose.type "ingress") -}}
{{- printf "true" -}} {{- printf "true" -}}
{{- else -}} {{- else -}}
{{- printf "false" -}} {{- printf "false" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.autoGenCertForNginx" -}} {{- define "harbor.autoGenCertForNginx" -}}
{{- if and (eq (include "harbor.autoGenCert" .) "true") (ne .Values.expose.type "ingress") -}} {{- if and (eq (include "harbor.autoGenCert" .) "true") (ne .Values.expose.type "ingress") -}}
{{- printf "true" -}} {{- printf "true" -}}
{{- else -}} {{- else -}}
{{- printf "false" -}} {{- printf "false" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.host" -}} {{- define "harbor.database.host" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- template "harbor.database" . }} {{- template "harbor.database" . }}
{{- else -}} {{- else -}}
{{- .Values.database.external.host -}} {{- .Values.database.external.host -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.port" -}} {{- define "harbor.database.port" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- printf "%s" "5432" -}} {{- printf "%s" "5432" -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.port -}} {{- .Values.database.external.port -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.username" -}} {{- define "harbor.database.username" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- printf "%s" "postgres" -}} {{- printf "%s" "postgres" -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.username -}} {{- .Values.database.external.username -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.rawPassword" -}} {{- define "harbor.database.rawPassword" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- .Values.database.internal.password -}} {{- .Values.database.internal.password -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.password -}} {{- .Values.database.external.password -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.escapedRawPassword" -}} {{- define "harbor.database.escapedRawPassword" -}}
{{- include "harbor.database.rawPassword" . | urlquery | replace "+" "%20" -}} {{- include "harbor.database.rawPassword" . | urlquery | replace "+" "%20" -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.encryptedPassword" -}} {{- define "harbor.database.encryptedPassword" -}}
{{- include "harbor.database.rawPassword" . | b64enc | quote -}} {{- include "harbor.database.rawPassword" . | b64enc | quote -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.coreDatabase" -}} {{- define "harbor.database.coreDatabase" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- printf "%s" "registry" -}} {{- printf "%s" "registry" -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.coreDatabase -}} {{- .Values.database.external.coreDatabase -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.clairDatabase" -}} {{- define "harbor.database.clairDatabase" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- printf "%s" "postgres" -}} {{- printf "%s" "postgres" -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.clairDatabase -}} {{- .Values.database.external.clairDatabase -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.notaryServerDatabase" -}} {{- define "harbor.database.notaryServerDatabase" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- printf "%s" "notaryserver" -}} {{- printf "%s" "notaryserver" -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.notaryServerDatabase -}} {{- .Values.database.external.notaryServerDatabase -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.notarySignerDatabase" -}} {{- define "harbor.database.notarySignerDatabase" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- printf "%s" "notarysigner" -}} {{- printf "%s" "notarysigner" -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.notarySignerDatabase -}} {{- .Values.database.external.notarySignerDatabase -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.sslmode" -}} {{- define "harbor.database.sslmode" -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- printf "%s" "disable" -}} {{- printf "%s" "disable" -}}
{{- else -}} {{- else -}}
{{- .Values.database.external.sslmode -}} {{- .Values.database.external.sslmode -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.database.clair" -}} {{- define "harbor.database.clair" -}}
postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.clairDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }} postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.clairDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }}
{{- end -}} {{- end -}}
{{- define "harbor.database.notaryServer" -}} {{- define "harbor.database.notaryServer" -}}
postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.notaryServerDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }} postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.notaryServerDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }}
{{- end -}} {{- end -}}
{{- define "harbor.database.notarySigner" -}} {{- define "harbor.database.notarySigner" -}}
postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.notarySignerDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }} postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.database.escapedRawPassword" . }}@{{ template "harbor.database.host" . }}:{{ template "harbor.database.port" . }}/{{ template "harbor.database.notarySignerDatabase" . }}?sslmode={{ template "harbor.database.sslmode" . }}
{{- end -}} {{- end -}}
{{- define "harbor.redis.scheme" -}} {{- define "harbor.redis.scheme" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- ternary "redis+sentinel" "redis" (and (eq .type "external" ) (not (not .external.sentinelMasterSet))) }} {{- ternary "redis+sentinel" "redis" (and (eq .type "external" ) (not (not .external.sentinelMasterSet))) }}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
/*host:port*/ /*host:port*/
{{- define "harbor.redis.addr" -}} {{- define "harbor.redis.addr" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- ternary (printf "%s:6379" (include "harbor.redis" $ )) .external.addr (eq .type "internal") }} {{- ternary (printf "%s:6379" (include "harbor.redis" $ )) .external.addr (eq .type "internal") }}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{- define "harbor.redis.masterSet" -}} {{- define "harbor.redis.masterSet" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- ternary .external.sentinelMasterSet "" (eq "redis+sentinel" (include "harbor.redis.scheme" $)) }} {{- ternary .external.sentinelMasterSet "" (eq "redis+sentinel" (include "harbor.redis.scheme" $)) }}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{- define "harbor.redis.password" -}} {{- define "harbor.redis.password" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- ternary "" .external.password (eq .type "internal") }} {{- ternary "" .external.password (eq .type "internal") }}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
/*scheme://[redis:password@]host:port[/master_set]*/ /*scheme://[redis:password@]host:port[/master_set]*/
{{- define "harbor.redis.url" -}} {{- define "harbor.redis.url" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- $path := ternary "" (printf "/%s" (include "harbor.redis.masterSet" $)) (not (include "harbor.redis.masterSet" $)) }} {{- $path := ternary "" (printf "/%s" (include "harbor.redis.masterSet" $)) (not (include "harbor.redis.masterSet" $)) }}
{{- $cred := ternary (printf "redis:%s@" (.external.password | urlquery)) "" (and (eq .type "external" ) (not (not .external.password))) }} {{- $cred := ternary (printf "redis:%s@" (.external.password | urlquery)) "" (and (eq .type "external" ) (not (not .external.password))) }}
{{- printf "%s://%s%s%s" (include "harbor.redis.scheme" $) $cred (include "harbor.redis.addr" $) $path -}} {{- printf "%s://%s%s%s" (include "harbor.redis.scheme" $) $cred (include "harbor.redis.addr" $) $path -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
/*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/ /*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/
{{- define "harbor.redis.urlForCore" -}} {{- define "harbor.redis.urlForCore" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- $index := ternary "0" .external.coreDatabaseIndex (eq .type "internal") }} {{- $index := ternary "0" .external.coreDatabaseIndex (eq .type "internal") }}
{{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
/*scheme://[redis:password@]addr/db_index*/ /*scheme://[redis:password@]addr/db_index*/
{{- define "harbor.redis.urlForJobservice" -}} {{- define "harbor.redis.urlForJobservice" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- $index := ternary "1" .external.jobserviceDatabaseIndex (eq .type "internal") }} {{- $index := ternary "1" .external.jobserviceDatabaseIndex (eq .type "internal") }}
{{- printf "%s/%s" (include "harbor.redis.url" $) $index -}} {{- printf "%s/%s" (include "harbor.redis.url" $) $index -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
/*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/ /*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/
{{- define "harbor.redis.urlForRegistry" -}} {{- define "harbor.redis.urlForRegistry" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- $index := ternary "2" .external.registryDatabaseIndex (eq .type "internal") }} {{- $index := ternary "2" .external.registryDatabaseIndex (eq .type "internal") }}
{{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
/*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/ /*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/
{{- define "harbor.redis.urlForClair" -}} {{- define "harbor.redis.urlForClair" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- $index := ternary "4" .external.clairAdapterIndex (eq .type "internal") }} {{- $index := ternary "4" .external.clairAdapterIndex (eq .type "internal") }}
{{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
/*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/ /*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/
{{- define "harbor.redis.urlForTrivy" -}} {{- define "harbor.redis.urlForTrivy" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- $index := ternary "5" .external.trivyAdapterIndex (eq .type "internal") }} {{- $index := ternary "5" .external.trivyAdapterIndex (eq .type "internal") }}
{{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{- define "harbor.redis.dbForRegistry" -}} {{- define "harbor.redis.dbForRegistry" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- ternary "2" .external.registryDatabaseIndex (eq .type "internal") }} {{- ternary "2" .external.registryDatabaseIndex (eq .type "internal") }}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{- define "harbor.redis.dbForChartmuseum" -}} {{- define "harbor.redis.dbForChartmuseum" -}}
{{- with .Values.redis }} {{- with .Values.redis }}
{{- ternary "3" .external.chartmuseumDatabaseIndex (eq .type "internal") }} {{- ternary "3" .external.chartmuseumDatabaseIndex (eq .type "internal") }}
{{- end }} {{- end }}
{{- end -}} {{- end -}}
{{- define "harbor.portal" -}} {{- define "harbor.portal" -}}
{{- printf "%s-portal" (include "harbor.fullname" .) -}} {{- printf "%s-portal" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.core" -}} {{- define "harbor.core" -}}
{{- printf "%s-core" (include "harbor.fullname" .) -}} {{- printf "%s-core" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.redis" -}} {{- define "harbor.redis" -}}
{{- printf "%s-redis" (include "harbor.fullname" .) -}} {{- printf "%s-redis" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.jobservice" -}} {{- define "harbor.jobservice" -}}
{{- printf "%s-jobservice" (include "harbor.fullname" .) -}} {{- printf "%s-jobservice" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.registry" -}} {{- define "harbor.registry" -}}
{{- printf "%s-registry" (include "harbor.fullname" .) -}} {{- printf "%s-registry" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.chartmuseum" -}} {{- define "harbor.chartmuseum" -}}
{{- printf "%s-chartmuseum" (include "harbor.fullname" .) -}} {{- printf "%s-chartmuseum" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.database" -}} {{- define "harbor.database" -}}
{{- printf "%s-database" (include "harbor.fullname" .) -}} {{- printf "%s-database" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.clair" -}} {{- define "harbor.clair" -}}
{{- printf "%s-clair" (include "harbor.fullname" .) -}} {{- printf "%s-clair" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.trivy" -}} {{- define "harbor.trivy" -}}
{{- printf "%s-trivy" (include "harbor.fullname" .) -}} {{- printf "%s-trivy" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.notary-server" -}} {{- define "harbor.notary-server" -}}
{{- printf "%s-notary-server" (include "harbor.fullname" .) -}} {{- printf "%s-notary-server" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.notary-signer" -}} {{- define "harbor.notary-signer" -}}
{{- printf "%s-notary-signer" (include "harbor.fullname" .) -}} {{- printf "%s-notary-signer" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.nginx" -}} {{- define "harbor.nginx" -}}
{{- printf "%s-nginx" (include "harbor.fullname" .) -}} {{- printf "%s-nginx" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.ingress" -}} {{- define "harbor.ingress" -}}
{{- printf "%s-ingress" (include "harbor.fullname" .) -}} {{- printf "%s-ingress" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.ingress-notary" -}} {{- define "harbor.ingress-notary" -}}
{{- printf "%s-ingress-notary" (include "harbor.fullname" .) -}} {{- printf "%s-ingress-notary" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.noProxy" -}} {{- define "harbor.noProxy" -}}
{{- printf "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s" (include "harbor.core" .) (include "harbor.jobservice" .) (include "harbor.database" .) (include "harbor.chartmuseum" .) (include "harbor.clair" .) (include "harbor.notary-server" .) (include "harbor.notary-signer" .) (include "harbor.registry" .) (include "harbor.portal" .) (include "harbor.trivy" .) .Values.proxy.noProxy -}} {{- printf "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s" (include "harbor.core" .) (include "harbor.jobservice" .) (include "harbor.database" .) (include "harbor.chartmuseum" .) (include "harbor.clair" .) (include "harbor.notary-server" .) (include "harbor.notary-signer" .) (include "harbor.registry" .) (include "harbor.portal" .) (include "harbor.trivy" .) .Values.proxy.noProxy -}}
{{- end -}} {{- end -}}
{{- define "harbor.caBundleVolume" -}} {{- define "harbor.caBundleVolume" -}}
- name: ca-bundle-certs - name: ca-bundle-certs
secret: secret:
secretName: {{ .Values.caBundleSecretName }} secretName: {{ .Values.caBundleSecretName }}
{{- end -}} {{- end -}}
{{- define "harbor.caBundleVolumeMount" -}} {{- define "harbor.caBundleVolumeMount" -}}
- name: ca-bundle-certs - name: ca-bundle-certs
mountPath: /harbor_cust_cert/custom-ca.crt mountPath: /harbor_cust_cert/custom-ca.crt
subPath: ca.crt subPath: ca.crt
{{- end -}} {{- end -}}
{{/* scheme for all components except notary because it only support http mode */}} {{/* scheme for all components except notary because it only support http mode */}}
{{- define "harbor.component.scheme" -}} {{- define "harbor.component.scheme" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "https" -}} {{- printf "https" -}}
{{- else -}} {{- else -}}
{{- printf "http" -}} {{- printf "http" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* chartmuseum component container port */}} {{/* chartmuseum component container port */}}
{{- define "harbor.chartmuseum.containerPort" -}} {{- define "harbor.chartmuseum.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "9443" -}} {{- printf "9443" -}}
{{- else -}} {{- else -}}
{{- printf "9999" -}} {{- printf "9999" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* chartmuseum component service port */}} {{/* chartmuseum component service port */}}
{{- define "harbor.chartmuseum.servicePort" -}} {{- define "harbor.chartmuseum.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "443" -}} {{- printf "443" -}}
{{- else -}} {{- else -}}
{{- printf "80" -}} {{- printf "80" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* clair adapter component container port */}} {{/* clair adapter component container port */}}
{{- define "harbor.clairAdapter.containerPort" -}} {{- define "harbor.clairAdapter.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* clair adapter component service port */}} {{/* clair adapter component service port */}}
{{- define "harbor.clairAdapter.servicePort" -}} {{- define "harbor.clairAdapter.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* core component container port */}} {{/* core component container port */}}
{{- define "harbor.core.containerPort" -}} {{- define "harbor.core.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* core component service port */}} {{/* core component service port */}}
{{- define "harbor.core.servicePort" -}} {{- define "harbor.core.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "443" -}} {{- printf "443" -}}
{{- else -}} {{- else -}}
{{- printf "80" -}} {{- printf "80" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* jobservice component container port */}} {{/* jobservice component container port */}}
{{- define "harbor.jobservice.containerPort" -}} {{- define "harbor.jobservice.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* jobservice component service port */}} {{/* jobservice component service port */}}
{{- define "harbor.jobservice.servicePort" -}} {{- define "harbor.jobservice.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "443" -}} {{- printf "443" -}}
{{- else -}} {{- else -}}
{{- printf "80" -}} {{- printf "80" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* portal component container port */}} {{/* portal component container port */}}
{{- define "harbor.portal.containerPort" -}} {{- define "harbor.portal.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* portal component service port */}} {{/* portal component service port */}}
{{- define "harbor.portal.servicePort" -}} {{- define "harbor.portal.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "443" -}} {{- printf "443" -}}
{{- else -}} {{- else -}}
{{- printf "80" -}} {{- printf "80" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* registry component container port */}} {{/* registry component container port */}}
{{- define "harbor.registry.containerPort" -}} {{- define "harbor.registry.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "5443" -}} {{- printf "5443" -}}
{{- else -}} {{- else -}}
{{- printf "5000" -}} {{- printf "5000" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* registry component service port */}} {{/* registry component service port */}}
{{- define "harbor.registry.servicePort" -}} {{- define "harbor.registry.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "5443" -}} {{- printf "5443" -}}
{{- else -}} {{- else -}}
{{- printf "5000" -}} {{- printf "5000" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* registryctl component container port */}} {{/* registryctl component container port */}}
{{- define "harbor.registryctl.containerPort" -}} {{- define "harbor.registryctl.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* registryctl component service port */}} {{/* registryctl component service port */}}
{{- define "harbor.registryctl.servicePort" -}} {{- define "harbor.registryctl.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* trivy component container port */}} {{/* trivy component container port */}}
{{- define "harbor.trivy.containerPort" -}} {{- define "harbor.trivy.containerPort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* trivy component service port */}} {{/* trivy component service port */}}
{{- define "harbor.trivy.servicePort" -}} {{- define "harbor.trivy.servicePort" -}}
{{- if .Values.internalTLS.enabled -}} {{- if .Values.internalTLS.enabled -}}
{{- printf "8443" -}} {{- printf "8443" -}}
{{- else -}} {{- else -}}
{{- printf "8080" -}} {{- printf "8080" -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{/* CLAIR_ADAPTER_URL */}} {{/* CLAIR_ADAPTER_URL */}}
{{- define "harbor.clairAdapterURL" -}} {{- define "harbor.clairAdapterURL" -}}
{{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.clair" .) (include "harbor.clairAdapter.servicePort" .) -}} {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.clair" .) (include "harbor.clairAdapter.servicePort" .) -}}
{{- end -}} {{- end -}}
{{/* CORE_URL */}} {{/* CORE_URL */}}
{{/* port is included in this url as a workaround for issue https://github.com/aquasecurity/harbor-scanner-trivy/issues/108 */}} {{/* port is included in this url as a workaround for issue https://github.com/aquasecurity/harbor-scanner-trivy/issues/108 */}}
{{- define "harbor.coreURL" -}} {{- define "harbor.coreURL" -}}
{{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.core" .) (include "harbor.core.servicePort" .) -}} {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.core" .) (include "harbor.core.servicePort" .) -}}
{{- end -}} {{- end -}}
{{/* JOBSERVICE_URL */}} {{/* JOBSERVICE_URL */}}
{{- define "harbor.jobserviceURL" -}} {{- define "harbor.jobserviceURL" -}}
{{- printf "%s://%s-jobservice" (include "harbor.component.scheme" .) (include "harbor.fullname" .) -}} {{- printf "%s://%s-jobservice" (include "harbor.component.scheme" .) (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{/* PORTAL_URL */}} {{/* PORTAL_URL */}}
{{- define "harbor.portalURL" -}} {{- define "harbor.portalURL" -}}
{{- printf "%s://%s" (include "harbor.component.scheme" .) (include "harbor.portal" .) -}} {{- printf "%s://%s" (include "harbor.component.scheme" .) (include "harbor.portal" .) -}}
{{- end -}} {{- end -}}
{{/* REGISTRY_URL */}} {{/* REGISTRY_URL */}}
{{- define "harbor.registryURL" -}} {{- define "harbor.registryURL" -}}
{{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registry.servicePort" .) -}} {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registry.servicePort" .) -}}
{{- end -}} {{- end -}}
{{/* REGISTRY_CONTROLLER_URL */}} {{/* REGISTRY_CONTROLLER_URL */}}
{{- define "harbor.registryControllerURL" -}} {{- define "harbor.registryControllerURL" -}}
{{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registryctl.servicePort" .) -}} {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registryctl.servicePort" .) -}}
{{- end -}} {{- end -}}
{{/* TOKEN_SERVICE_URL */}} {{/* TOKEN_SERVICE_URL */}}
{{- define "harbor.tokenServiceURL" -}} {{- define "harbor.tokenServiceURL" -}}
{{- printf "%s/service/token" (include "harbor.coreURL" .) -}} {{- printf "%s/service/token" (include "harbor.coreURL" .) -}}
{{- end -}} {{- end -}}
{{/* TRIVY_ADAPTER_URL */}} {{/* TRIVY_ADAPTER_URL */}}
{{- define "harbor.trivyAdapterURL" -}} {{- define "harbor.trivyAdapterURL" -}}
{{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.trivy" .) (include "harbor.trivy.servicePort" .) -}} {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.trivy" .) (include "harbor.trivy.servicePort" .) -}}
{{- end -}} {{- end -}}
{{- define "harbor.internalTLS.chartmuseum.secretName" -}} {{- define "harbor.internalTLS.chartmuseum.secretName" -}}
{{- if eq .Values.internalTLS.certSource "secret" -}} {{- if eq .Values.internalTLS.certSource "secret" -}}
{{- .Values.internalTLS.chartmuseum.secretName -}} {{- .Values.internalTLS.chartmuseum.secretName -}}
{{- else -}} {{- else -}}
{{- printf "%s-chartmuseum-internal-tls" (include "harbor.fullname" .) -}} {{- printf "%s-chartmuseum-internal-tls" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.internalTLS.clair.secretName" -}} {{- define "harbor.internalTLS.clair.secretName" -}}
{{- if eq .Values.internalTLS.certSource "secret" -}} {{- if eq .Values.internalTLS.certSource "secret" -}}
{{- .Values.internalTLS.clair.secretName -}} {{- .Values.internalTLS.clair.secretName -}}
{{- else -}} {{- else -}}
{{- printf "%s-clair-internal-tls" (include "harbor.fullname" .) -}} {{- printf "%s-clair-internal-tls" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.internalTLS.core.secretName" -}} {{- define "harbor.internalTLS.core.secretName" -}}
{{- if eq .Values.internalTLS.certSource "secret" -}} {{- if eq .Values.internalTLS.certSource "secret" -}}
{{- .Values.internalTLS.core.secretName -}} {{- .Values.internalTLS.core.secretName -}}
{{- else -}} {{- else -}}
{{- printf "%s-core-internal-tls" (include "harbor.fullname" .) -}} {{- printf "%s-core-internal-tls" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.internalTLS.jobservice.secretName" -}} {{- define "harbor.internalTLS.jobservice.secretName" -}}
{{- if eq .Values.internalTLS.certSource "secret" -}} {{- if eq .Values.internalTLS.certSource "secret" -}}
{{- .Values.internalTLS.jobservice.secretName -}} {{- .Values.internalTLS.jobservice.secretName -}}
{{- else -}} {{- else -}}
{{- printf "%s-jobservice-internal-tls" (include "harbor.fullname" .) -}} {{- printf "%s-jobservice-internal-tls" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.internalTLS.portal.secretName" -}} {{- define "harbor.internalTLS.portal.secretName" -}}
{{- if eq .Values.internalTLS.certSource "secret" -}} {{- if eq .Values.internalTLS.certSource "secret" -}}
{{- .Values.internalTLS.portal.secretName -}} {{- .Values.internalTLS.portal.secretName -}}
{{- else -}} {{- else -}}
{{- printf "%s-portal-internal-tls" (include "harbor.fullname" .) -}} {{- printf "%s-portal-internal-tls" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.internalTLS.registry.secretName" -}} {{- define "harbor.internalTLS.registry.secretName" -}}
{{- if eq .Values.internalTLS.certSource "secret" -}} {{- if eq .Values.internalTLS.certSource "secret" -}}
{{- .Values.internalTLS.registry.secretName -}} {{- .Values.internalTLS.registry.secretName -}}
{{- else -}} {{- else -}}
{{- printf "%s-registry-internal-tls" (include "harbor.fullname" .) -}} {{- printf "%s-registry-internal-tls" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.internalTLS.trivy.secretName" -}} {{- define "harbor.internalTLS.trivy.secretName" -}}
{{- if eq .Values.internalTLS.certSource "secret" -}} {{- if eq .Values.internalTLS.certSource "secret" -}}
{{- .Values.internalTLS.trivy.secretName -}} {{- .Values.internalTLS.trivy.secretName -}}
{{- else -}} {{- else -}}
{{- printf "%s-trivy-internal-tls" (include "harbor.fullname" .) -}} {{- printf "%s-trivy-internal-tls" (include "harbor.fullname" .) -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.tlsCoreSecretForIngress" -}} {{- define "harbor.tlsCoreSecretForIngress" -}}
{{- if eq .Values.expose.tls.certSource "none" -}} {{- if eq .Values.expose.tls.certSource "none" -}}
{{- printf "" -}} {{- printf "" -}}
{{- else if eq .Values.expose.tls.certSource "secret" -}} {{- else if eq .Values.expose.tls.certSource "secret" -}}
{{- .Values.expose.tls.secret.secretName -}} {{- .Values.expose.tls.secret.secretName -}}
{{- else -}} {{- else -}}
{{- include "harbor.ingress" . -}} {{- include "harbor.ingress" . -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.tlsNotarySecretForIngress" -}} {{- define "harbor.tlsNotarySecretForIngress" -}}
{{- if eq .Values.expose.tls.certSource "none" -}} {{- if eq .Values.expose.tls.certSource "none" -}}
{{- printf "" -}} {{- printf "" -}}
{{- else if eq .Values.expose.tls.certSource "secret" -}} {{- else if eq .Values.expose.tls.certSource "secret" -}}
{{- .Values.expose.tls.secret.notarySecretName -}} {{- .Values.expose.tls.secret.notarySecretName -}}
{{- else -}} {{- else -}}
{{- include "harbor.ingress" . -}} {{- include "harbor.ingress" . -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- define "harbor.tlsSecretForNginx" -}} {{- define "harbor.tlsSecretForNginx" -}}
{{- if eq .Values.expose.tls.certSource "secret" -}} {{- if eq .Values.expose.tls.certSource "secret" -}}
{{- .Values.expose.tls.secret.secretName -}} {{- .Values.expose.tls.secret.secretName -}}
{{- else -}} {{- else -}}
{{- include "harbor.nginx" . -}} {{- include "harbor.nginx" . -}}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- if .Values.chartmuseum.enabled }} {{- if .Values.chartmuseum.enabled }}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
PORT: "{{ template "harbor.chartmuseum.containerPort" . }}" PORT: "{{ template "harbor.chartmuseum.containerPort" . }}"
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
TLS_CERT: "/etc/harbor/ssl/chartmuseum/tls.crt" TLS_CERT: "/etc/harbor/ssl/chartmuseum/tls.crt"
TLS_KEY: "/etc/harbor/ssl/chartmuseum/tls.key" TLS_KEY: "/etc/harbor/ssl/chartmuseum/tls.key"
{{- end }} {{- end }}
{{- if eq "redis" (include "harbor.redis.scheme" .) }} {{- if eq "redis" (include "harbor.redis.scheme" .) }}
CACHE: "redis" CACHE: "redis"
{{- else }} {{- else }}
CACHE: "redis_sentinel" CACHE: "redis_sentinel"
CACHE_REDIS_MASTERNAME: "{{ template "harbor.redis.masterSet" . }}" CACHE_REDIS_MASTERNAME: "{{ template "harbor.redis.masterSet" . }}"
{{- end }} {{- end }}
CACHE_REDIS_ADDR: "{{ template "harbor.redis.addr" . }}" CACHE_REDIS_ADDR: "{{ template "harbor.redis.addr" . }}"
CACHE_REDIS_DB: "{{ template "harbor.redis.dbForChartmuseum" . }}" CACHE_REDIS_DB: "{{ template "harbor.redis.dbForChartmuseum" . }}"
BASIC_AUTH_USER: "chart_controller" BASIC_AUTH_USER: "chart_controller"
{{- if .Values.chartmuseum.absoluteUrl }} {{- if .Values.chartmuseum.absoluteUrl }}
CHART_URL: {{ .Values.externalURL }}.{{ $.Values.global.host }}/chartrepo CHART_URL: {{ .Values.externalURL }}.{{ $.Values.global.host }}/chartrepo
{{- end }} {{- end }}
DEPTH: "1" DEPTH: "1"
{{- if eq .Values.logLevel "debug" }} {{- if eq .Values.logLevel "debug" }}
DEBUG: "true" DEBUG: "true"
{{- else }} {{- else }}
DEBUG: "false" DEBUG: "false"
{{- end }} {{- end }}
LOG_JSON: "true" LOG_JSON: "true"
DISABLE_METRICS: "false" DISABLE_METRICS: "false"
DISABLE_API: "false" DISABLE_API: "false"
DISABLE_STATEFILES: "false" DISABLE_STATEFILES: "false"
ALLOW_OVERWRITE: "true" ALLOW_OVERWRITE: "true"
AUTH_ANONYMOUS_GET: "false" AUTH_ANONYMOUS_GET: "false"
CONTEXT_PATH: "" CONTEXT_PATH: ""
INDEX_LIMIT: "0" INDEX_LIMIT: "0"
MAX_STORAGE_OBJECTS: "0" MAX_STORAGE_OBJECTS: "0"
MAX_UPLOAD_SIZE: "20971520" MAX_UPLOAD_SIZE: "20971520"
CHART_POST_FORM_FIELD_NAME: "chart" CHART_POST_FORM_FIELD_NAME: "chart"
PROV_POST_FORM_FIELD_NAME: "prov" PROV_POST_FORM_FIELD_NAME: "prov"
{{- $storage := .Values.persistence.imageChartStorage }} {{- $storage := .Values.persistence.imageChartStorage }}
{{- $storageType := $storage.type }} {{- $storageType := $storage.type }}
{{- if eq $storageType "filesystem" }} {{- if eq $storageType "filesystem" }}
STORAGE: "local" STORAGE: "local"
STORAGE_LOCAL_ROOTDIR: "/chart_storage" STORAGE_LOCAL_ROOTDIR: "/chart_storage"
{{- else if eq $storageType "azure" }} {{- else if eq $storageType "azure" }}
STORAGE: "microsoft" STORAGE: "microsoft"
STORAGE_MICROSOFT_CONTAINER: {{ $storage.azure.container }} STORAGE_MICROSOFT_CONTAINER: {{ $storage.azure.container }}
AZURE_STORAGE_ACCOUNT: {{ $storage.azure.accountname }} AZURE_STORAGE_ACCOUNT: {{ $storage.azure.accountname }}
AZURE_BASE_URL: {{ $storage.azure.realm }} AZURE_BASE_URL: {{ $storage.azure.realm }}
STORAGE_MICROSOFT_PREFIX: "/azure/harbor/charts" STORAGE_MICROSOFT_PREFIX: "/azure/harbor/charts"
{{- else if eq $storageType "gcs" }} {{- else if eq $storageType "gcs" }}
STORAGE: "google" STORAGE: "google"
STORAGE_GOOGLE_BUCKET: {{ $storage.gcs.bucket }} STORAGE_GOOGLE_BUCKET: {{ $storage.gcs.bucket }}
GOOGLE_APPLICATION_CREDENTIALS: /etc/chartmuseum/gcs-key.json GOOGLE_APPLICATION_CREDENTIALS: /etc/chartmuseum/gcs-key.json
{{- if $storage.gcs.rootdirectory }} {{- if $storage.gcs.rootdirectory }}
STORAGE_GOOGLE_PREFIX: {{ $storage.gcs.rootdirectory }} STORAGE_GOOGLE_PREFIX: {{ $storage.gcs.rootdirectory }}
{{- end }} {{- end }}
{{- else if eq $storageType "s3" }} {{- else if eq $storageType "s3" }}
STORAGE: "amazon" STORAGE: "amazon"
STORAGE_AMAZON_BUCKET: {{ $storage.s3.bucket }} STORAGE_AMAZON_BUCKET: {{ $storage.s3.bucket }}
{{- if $storage.s3.rootdirectory }} {{- if $storage.s3.rootdirectory }}
STORAGE_AMAZON_PREFIX: {{ $storage.s3.rootdirectory }} STORAGE_AMAZON_PREFIX: {{ $storage.s3.rootdirectory }}
{{- end }} {{- end }}
STORAGE_AMAZON_REGION: {{ $storage.s3.region }} STORAGE_AMAZON_REGION: {{ $storage.s3.region }}
{{- if $storage.s3.regionendpoint }} {{- if $storage.s3.regionendpoint }}
STORAGE_AMAZON_ENDPOINT: {{ $storage.s3.regionendpoint }} STORAGE_AMAZON_ENDPOINT: {{ $storage.s3.regionendpoint }}
{{- end }} {{- end }}
{{- if $storage.s3.accesskey }} {{- if $storage.s3.accesskey }}
AWS_ACCESS_KEY_ID: {{ $storage.s3.accesskey }} AWS_ACCESS_KEY_ID: {{ $storage.s3.accesskey }}
{{- end }} {{- end }}
{{- if $storage.s3.keyid }} {{- if $storage.s3.keyid }}
STORAGE_AMAZON_SSE: aws:kms STORAGE_AMAZON_SSE: aws:kms
{{- end }} {{- end }}
{{- else if eq $storageType "swift" }} {{- else if eq $storageType "swift" }}
STORAGE: "openstack" STORAGE: "openstack"
STORAGE_OPENSTACK_CONTAINER: {{ $storage.swift.container }} STORAGE_OPENSTACK_CONTAINER: {{ $storage.swift.container }}
{{- if $storage.swift.prefix }} {{- if $storage.swift.prefix }}
STORAGE_OPENSTACK_PREFIX: {{ $storage.swift.prefix }} STORAGE_OPENSTACK_PREFIX: {{ $storage.swift.prefix }}
{{- end }} {{- end }}
{{- if $storage.swift.region }} {{- if $storage.swift.region }}
STORAGE_OPENSTACK_REGION: {{ $storage.swift.region }} STORAGE_OPENSTACK_REGION: {{ $storage.swift.region }}
{{- end }} {{- end }}
OS_AUTH_URL: {{ $storage.swift.authurl }} OS_AUTH_URL: {{ $storage.swift.authurl }}
OS_USERNAME: {{ $storage.swift.username }} OS_USERNAME: {{ $storage.swift.username }}
{{- if $storage.swift.tenantid }} {{- if $storage.swift.tenantid }}
OS_PROJECT_ID: {{ $storage.swift.tenantid }} OS_PROJECT_ID: {{ $storage.swift.tenantid }}
{{- end }} {{- end }}
{{- if $storage.swift.tenant }} {{- if $storage.swift.tenant }}
OS_PROJECT_NAME: {{ $storage.swift.tenant }} OS_PROJECT_NAME: {{ $storage.swift.tenant }}
{{- end }} {{- end }}
{{- if $storage.swift.domainid }} {{- if $storage.swift.domainid }}
OS_DOMAIN_ID: {{ $storage.swift.domainid }} OS_DOMAIN_ID: {{ $storage.swift.domainid }}
{{- end }} {{- end }}
{{- if $storage.swift.domain }} {{- if $storage.swift.domain }}
OS_DOMAIN_NAME: {{ $storage.swift.domain }} OS_DOMAIN_NAME: {{ $storage.swift.domain }}
{{- end }} {{- end }}
{{- else if eq $storageType "oss" }} {{- else if eq $storageType "oss" }}
STORAGE: "alibaba" STORAGE: "alibaba"
STORAGE_ALIBABA_BUCKET: {{ $storage.oss.bucket }} STORAGE_ALIBABA_BUCKET: {{ $storage.oss.bucket }}
{{- if $storage.oss.rootdirectory }} {{- if $storage.oss.rootdirectory }}
STORAGE_ALIBABA_PREFIX: {{ $storage.oss.rootdirectory }} STORAGE_ALIBABA_PREFIX: {{ $storage.oss.rootdirectory }}
{{- end }} {{- end }}
{{- if $storage.oss.endpoint }} {{- if $storage.oss.endpoint }}
STORAGE_ALIBABA_ENDPOINT: {{ $storage.oss.endpoint }} STORAGE_ALIBABA_ENDPOINT: {{ $storage.oss.endpoint }}
{{- end }} {{- end }}
ALIBABA_CLOUD_ACCESS_KEY_ID: {{ $storage.oss.accesskeyid }} ALIBABA_CLOUD_ACCESS_KEY_ID: {{ $storage.oss.accesskeyid }}
{{- end }} {{- end }}
STORAGE_TIMESTAMP_TOLERANCE: 1s STORAGE_TIMESTAMP_TOLERANCE: 1s
{{- end }} {{- end }}
{{- if .Values.chartmuseum.enabled }} {{- if .Values.chartmuseum.enabled }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: chartmuseum component: chartmuseum
spec: spec:
replicas: {{ .Values.chartmuseum.replicas }} replicas: {{ .Values.chartmuseum.replicas }}
strategy: strategy:
type: {{ .Values.updateStrategy.type }} type: {{ .Values.updateStrategy.type }}
{{- if eq .Values.updateStrategy.type "Recreate" }} {{- if eq .Values.updateStrategy.type "Recreate" }}
rollingUpdate: null rollingUpdate: null
{{- end }} {{- end }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: chartmuseum component: chartmuseum
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: chartmuseum component: chartmuseum
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-cm.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-secret.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 }} checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
checksum/tls: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-tls.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.chartmuseum.podAnnotations }} {{- if .Values.chartmuseum.podAnnotations }}
{{ toYaml .Values.chartmuseum.podAnnotations | indent 8 }} {{ toYaml .Values.chartmuseum.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- if .Values.chartmuseum.serviceAccountName }} {{- if .Values.chartmuseum.serviceAccountName }}
serviceAccountName: {{ .Values.chartmuseum.serviceAccountName }} serviceAccountName: {{ .Values.chartmuseum.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: chartmuseum - name: chartmuseum
{{- if contains "/" .Values.chartmuseum.image.repository }} {{- if contains "/" .Values.chartmuseum.image.repository }}
image: "{{ .Values.chartmuseum.image.repository }}" image: "{{ .Values.chartmuseum.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.chartmuseum.image.hub | default .Values.global.hub }}/{{ .Values.chartmuseum.image.repository }}:{{ .Values.chartmuseum.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.chartmuseum.image.hub | default .Values.global.hub }}/{{ .Values.chartmuseum.image.repository }}:{{ .Values.chartmuseum.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /health path: /health
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.chartmuseum.containerPort" . }} port: {{ template "harbor.chartmuseum.containerPort" . }}
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /health path: /health
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.chartmuseum.containerPort" . }} port: {{ template "harbor.chartmuseum.containerPort" . }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.chartmuseum.resources }} {{- if .Values.chartmuseum.resources }}
resources: resources:
{{ toYaml .Values.chartmuseum.resources | indent 10 }} {{ toYaml .Values.chartmuseum.resources | indent 10 }}
{{- end }} {{- end }}
envFrom: envFrom:
- configMapRef: - configMapRef:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
- secretRef: - secretRef:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
env: env:
{{- if has "chartmuseum" .Values.proxy.components }} {{- if has "chartmuseum" .Values.proxy.components }}
- name: HTTP_PROXY - name: HTTP_PROXY
value: "{{ .Values.proxy.httpProxy }}" value: "{{ .Values.proxy.httpProxy }}"
- name: HTTPS_PROXY - name: HTTPS_PROXY
value: "{{ .Values.proxy.httpsProxy }}" value: "{{ .Values.proxy.httpsProxy }}"
- name: NO_PROXY - name: NO_PROXY
value: "{{ template "harbor.noProxy" . }}" value: "{{ template "harbor.noProxy" . }}"
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED - name: INTERNAL_TLS_ENABLED
value: "true" value: "true"
- name: INTERNAL_TLS_KEY_PATH - name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/chartmuseum/tls.key value: /etc/harbor/ssl/chartmuseum/tls.key
- name: INTERNAL_TLS_CERT_PATH - name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/chartmuseum/tls.crt value: /etc/harbor/ssl/chartmuseum/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH - name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/chartmuseum/ca.crt value: /etc/harbor/ssl/chartmuseum/ca.crt
{{- end }} {{- end }}
- name: BASIC_AUTH_PASS - name: BASIC_AUTH_PASS
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
key: secret key: secret
- # Needed to make AWS' client connect correctly (see https://github.com/helm/chartmuseum/issues/280) - # Needed to make AWS' client connect correctly (see https://github.com/helm/chartmuseum/issues/280)
name: AWS_SDK_LOAD_CONFIG name: AWS_SDK_LOAD_CONFIG
value: "1" value: "1"
ports: ports:
- containerPort: {{ template "harbor.chartmuseum.containerPort" . }} - containerPort: {{ template "harbor.chartmuseum.containerPort" . }}
volumeMounts: volumeMounts:
- name: chartmuseum-data - name: chartmuseum-data
mountPath: /chart_storage mountPath: /chart_storage
subPath: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.subPath }} subPath: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.subPath }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: chart-internal-certs - name: chart-internal-certs
mountPath: /etc/harbor/ssl/chartmuseum mountPath: /etc/harbor/ssl/chartmuseum
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }} {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }}
- name: gcs-key - name: gcs-key
mountPath: /etc/chartmuseum/gcs-key.json mountPath: /etc/chartmuseum/gcs-key.json
subPath: gcs-key.json subPath: gcs-key.json
{{- end }} {{- end }}
{{- if .Values.persistence.imageChartStorage.caBundleSecretName }} {{- if .Values.persistence.imageChartStorage.caBundleSecretName }}
- name: storage-service-ca - name: storage-service-ca
mountPath: /harbor_cust_cert/custom-ca-bundle.crt mountPath: /harbor_cust_cert/custom-ca-bundle.crt
subPath: ca.crt subPath: ca.crt
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }} {{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }} {{- end }}
volumes: volumes:
- name: chartmuseum-data - name: chartmuseum-data
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "filesystem") }} {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "filesystem") }}
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.existingClaim | default (include "harbor.chartmuseum" .) }} claimName: {{ .Values.persistence.persistentVolumeClaim.chartmuseum.existingClaim | default (include "harbor.chartmuseum" .) }}
{{- else }} {{- else }}
emptyDir: {} emptyDir: {}
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: chart-internal-certs - name: chart-internal-certs
secret: secret:
secretName: {{ template "harbor.internalTLS.chartmuseum.secretName" . }} secretName: {{ template "harbor.internalTLS.chartmuseum.secretName" . }}
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }} {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }}
- name: gcs-key - name: gcs-key
secret: secret:
secretName: {{ template "harbor.registry" . }} secretName: {{ template "harbor.registry" . }}
items: items:
- key: GCS_KEY_DATA - key: GCS_KEY_DATA
path: gcs-key.json path: gcs-key.json
{{- end }} {{- end }}
{{- if .Values.persistence.imageChartStorage.caBundleSecretName }} {{- if .Values.persistence.imageChartStorage.caBundleSecretName }}
- name: storage-service-ca - name: storage-service-ca
secret: secret:
secretName: {{ .Values.persistence.imageChartStorage.caBundleSecretName }} secretName: {{ .Values.persistence.imageChartStorage.caBundleSecretName }}
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }} {{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }} {{- end }}
{{- with .Values.chartmuseum.nodeSelector }} {{- with .Values.chartmuseum.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.chartmuseum.affinity }} {{- with .Values.chartmuseum.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.chartmuseum.tolerations }} {{- with .Values.chartmuseum.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .Values.chartmuseum.enabled }} {{- if .Values.chartmuseum.enabled }}
{{- $persistence := .Values.persistence -}} {{- $persistence := .Values.persistence -}}
{{- if $persistence.enabled }} {{- if $persistence.enabled }}
{{- $chartmuseum := $persistence.persistentVolumeClaim.chartmuseum -}} {{- $chartmuseum := $persistence.persistentVolumeClaim.chartmuseum -}}
{{- if and (not $chartmuseum.existingClaim) (eq $persistence.imageChartStorage.type "filesystem") }} {{- if and (not $chartmuseum.existingClaim) (eq $persistence.imageChartStorage.type "filesystem") }}
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
apiVersion: v1 apiVersion: v1
metadata: metadata:
name: {{ template "harbor.chartmuseum" . }} name: {{ template "harbor.chartmuseum" . }}
{{- if eq $persistence.resourcePolicy "keep" }} {{- if eq $persistence.resourcePolicy "keep" }}
annotations: annotations:
helm.sh/resource-policy: keep helm.sh/resource-policy: keep
{{- end }} {{- end }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: chartmuseum component: chartmuseum
spec: spec:
accessModes: accessModes:
- {{ $chartmuseum.accessMode }} - {{ $chartmuseum.accessMode }}
resources: resources:
requests: requests:
storage: {{ $chartmuseum.size }} storage: {{ $chartmuseum.size }}
{{- if $chartmuseum.storageClass }} {{- if $chartmuseum.storageClass }}
{{- if eq "-" $chartmuseum.storageClass }} {{- if eq "-" $chartmuseum.storageClass }}
storageClassName: "" storageClassName: ""
{{- else }} {{- else }}
storageClassName: {{ $chartmuseum.storageClass }} storageClassName: {{ $chartmuseum.storageClass }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if .Values.chartmuseum.enabled }} {{- if .Values.chartmuseum.enabled }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
CACHE_REDIS_PASSWORD: {{ include "harbor.redis.password" . | b64enc | quote }} CACHE_REDIS_PASSWORD: {{ include "harbor.redis.password" . | b64enc | quote }}
{{- $storage := .Values.persistence.imageChartStorage }} {{- $storage := .Values.persistence.imageChartStorage }}
{{- $storageType := $storage.type }} {{- $storageType := $storage.type }}
{{- if eq $storageType "azure" }} {{- if eq $storageType "azure" }}
AZURE_STORAGE_ACCESS_KEY: {{ $storage.azure.accountkey | b64enc | quote }} AZURE_STORAGE_ACCESS_KEY: {{ $storage.azure.accountkey | b64enc | quote }}
{{- else if eq $storageType "gcs" }} {{- else if eq $storageType "gcs" }}
# TODO support the keyfile of gcs # TODO support the keyfile of gcs
{{- else if eq $storageType "s3" }} {{- else if eq $storageType "s3" }}
{{- if $storage.s3.secretkey }} {{- if $storage.s3.secretkey }}
AWS_SECRET_ACCESS_KEY: {{ $storage.s3.secretkey | b64enc | quote }} AWS_SECRET_ACCESS_KEY: {{ $storage.s3.secretkey | b64enc | quote }}
{{- end }} {{- end }}
{{- else if eq $storageType "swift" }} {{- else if eq $storageType "swift" }}
OS_PASSWORD: {{ $storage.swift.password | b64enc | quote }} OS_PASSWORD: {{ $storage.swift.password | b64enc | quote }}
{{- else if eq $storageType "oss" }} {{- else if eq $storageType "oss" }}
ALIBABA_CLOUD_ACCESS_KEY_SECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }} ALIBABA_CLOUD_ACCESS_KEY_SECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if .Values.chartmuseum.enabled }} {{- if .Values.chartmuseum.enabled }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: "{{ template "harbor.chartmuseum" . }}" name: "{{ template "harbor.chartmuseum" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: {{ template "harbor.chartmuseum.servicePort" . }} - port: {{ template "harbor.chartmuseum.servicePort" . }}
targetPort: {{ template "harbor.chartmuseum.containerPort" . }} targetPort: {{ template "harbor.chartmuseum.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: chartmuseum component: chartmuseum
{{- end }} {{- end }}
\ No newline at end of file
{{- if and .Values.chartmuseum.enabled .Values.internalTLS.enabled }} {{- if and .Values.chartmuseum.enabled .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }} {{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.chartmuseum.secretName" . }}" name: "{{ template "harbor.internalTLS.chartmuseum.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
tls.ca: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} tls.ca: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.chartmuseum.crt\" is required!" .Values.internalTLS.chartmuseum.crt) | b64enc | quote }} tls.crt: {{ (required "The \"internalTLS.chartmuseum.crt\" is required!" .Values.internalTLS.chartmuseum.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.chartmuseum.key\" is required!" .Values.internalTLS.chartmuseum.key) | b64enc | quote }} tls.key: {{ (required "The \"internalTLS.chartmuseum.key\" is required!" .Values.internalTLS.chartmuseum.key) | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{ if .Values.clair.enabled }} {{ if .Values.clair.enabled }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ template "harbor.clair" . }} name: {{ template "harbor.clair" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: clair component: clair
spec: spec:
replicas: {{ .Values.clair.replicas }} replicas: {{ .Values.clair.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: clair component: clair
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: clair component: clair
annotations: annotations:
checksum/secret: {{ include (print $.Template.BasePath "/clair/clair-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/clair/clair-secret.yaml") . | sha256sum }}
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
checksum/tls: {{ include (print $.Template.BasePath "/clair/clair-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/clair/clair-tls.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.clair.podAnnotations }} {{- if .Values.clair.podAnnotations }}
{{ toYaml .Values.clair.podAnnotations | indent 8 }} {{ toYaml .Values.clair.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- if .Values.clair.serviceAccountName }} {{- if .Values.clair.serviceAccountName }}
serviceAccountName: {{ .Values.clair.serviceAccountName }} serviceAccountName: {{ .Values.clair.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: clair - name: clair
{{- if contains "/" .Values.clair.clair.image.repository }} {{- if contains "/" .Values.clair.clair.image.repository }}
image: "{{ .Values.clair.clair.image.repository }}" image: "{{ .Values.clair.clair.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.clair.clair.image.hub | default .Values.global.hub }}/{{ .Values.clair.clair.image.repository }}:{{ .Values.clair.clair.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.clair.clair.image.hub | default .Values.global.hub }}/{{ .Values.clair.clair.image.repository }}:{{ .Values.clair.clair.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /health path: /health
port: 6061 port: 6061
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /health path: /health
port: 6061 port: 6061
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10
args: ["-log-level", "{{ .Values.logLevel }}"] args: ["-log-level", "{{ .Values.logLevel }}"]
env: env:
{{- if has "clair" .Values.proxy.components }} {{- if has "clair" .Values.proxy.components }}
- name: HTTP_PROXY - name: HTTP_PROXY
value: "{{ .Values.proxy.httpProxy }}" value: "{{ .Values.proxy.httpProxy }}"
- name: HTTPS_PROXY - name: HTTPS_PROXY
value: "{{ .Values.proxy.httpsProxy }}" value: "{{ .Values.proxy.httpsProxy }}"
- name: NO_PROXY - name: NO_PROXY
value: "{{ template "harbor.noProxy" . }}" value: "{{ template "harbor.noProxy" . }}"
{{- end }} {{- end }}
{{- if .Values.clair.clair.resources }} {{- if .Values.clair.clair.resources }}
resources: resources:
{{ toYaml .Values.clair.clair.resources | indent 10 }} {{ toYaml .Values.clair.clair.resources | indent 10 }}
{{- end }} {{- end }}
ports: ports:
- containerPort: 6060 - containerPort: 6060
volumeMounts: volumeMounts:
- name: config - name: config
mountPath: /etc/clair/config.yaml mountPath: /etc/clair/config.yaml
subPath: config.yaml subPath: config.yaml
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: clair-internal-certs - name: clair-internal-certs
mountPath: /etc/harbor/ssl/clair mountPath: /etc/harbor/ssl/clair
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }} {{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }} {{- end }}
- name: adapter - name: adapter
{{- if contains "/" .Values.clair.adapter.image.repository }} {{- if contains "/" .Values.clair.adapter.image.repository }}
image: "{{ .Values.clair.adapter.image.repository }}" image: "{{ .Values.clair.adapter.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.clair.adapter.image.hub | default .Values.global.hub }}/{{ .Values.clair.adapter.image.repository }}:{{ .Values.clair.adapter.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.clair.adapter.image.hub | default .Values.global.hub }}/{{ .Values.clair.adapter.image.repository }}:{{ .Values.clair.adapter.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /probe/healthy path: /probe/healthy
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.clairAdapter.containerPort" . }} port: {{ template "harbor.clairAdapter.containerPort" . }}
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /probe/ready path: /probe/ready
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.clairAdapter.containerPort" . }} port: {{ template "harbor.clairAdapter.containerPort" . }}
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10
env: env:
- name: SCANNER_CLAIR_URL - name: SCANNER_CLAIR_URL
# To avoid a pod cannot reach itself via service IP when the clusters disable hairpin # To avoid a pod cannot reach itself via service IP when the clusters disable hairpin
value: "http://127.0.0.1:6060" value: "http://127.0.0.1:6060"
- name: SCANNER_STORE_REDIS_URL - name: SCANNER_STORE_REDIS_URL
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.clair" . }} name: {{ template "harbor.clair" . }}
key: redis key: redis
- name: SCANNER_CLAIR_DATABASE_URL - name: SCANNER_CLAIR_DATABASE_URL
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.clair" . }} name: {{ template "harbor.clair" . }}
key: database key: database
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED - name: INTERNAL_TLS_ENABLED
value: "true" value: "true"
- name: SCANNER_API_SERVER_ADDR - name: SCANNER_API_SERVER_ADDR
value: ":8443" value: ":8443"
- name: SCANNER_API_SERVER_TLS_KEY - name: SCANNER_API_SERVER_TLS_KEY
value: /etc/harbor/ssl/clair/tls.key value: /etc/harbor/ssl/clair/tls.key
- name: SCANNER_API_SERVER_TLS_CERTIFICATE - name: SCANNER_API_SERVER_TLS_CERTIFICATE
value: /etc/harbor/ssl/clair/tls.crt value: /etc/harbor/ssl/clair/tls.crt
{{- end }} {{- end }}
- name: SCANNER_LOG_LEVEL - name: SCANNER_LOG_LEVEL
value: "{{ .Values.logLevel }}" value: "{{ .Values.logLevel }}"
{{- if .Values.clair.adapter.resources }} {{- if .Values.clair.adapter.resources }}
resources: resources:
{{ toYaml .Values.clair.adapter.resources | indent 10 }} {{ toYaml .Values.clair.adapter.resources | indent 10 }}
{{- end }} {{- end }}
ports: ports:
- containerPort: {{ template "harbor.clairAdapter.containerPort" . }} - containerPort: {{ template "harbor.clairAdapter.containerPort" . }}
{{- if or .Values.internalTLS.enabled .Values.caBundleSecretName }} {{- if or .Values.internalTLS.enabled .Values.caBundleSecretName }}
volumeMounts: volumeMounts:
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: clair-internal-certs - name: clair-internal-certs
mountPath: /etc/harbor/ssl/clair mountPath: /etc/harbor/ssl/clair
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }} {{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }} {{- end }}
{{- end }} {{- end }}
volumes: volumes:
- name: config - name: config
secret: secret:
secretName: "{{ template "harbor.clair" . }}" secretName: "{{ template "harbor.clair" . }}"
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: clair-internal-certs - name: clair-internal-certs
secret: secret:
secretName: {{ template "harbor.internalTLS.clair.secretName" . }} secretName: {{ template "harbor.internalTLS.clair.secretName" . }}
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }} {{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }} {{- end }}
{{- with .Values.clair.nodeSelector }} {{- with .Values.clair.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.clair.affinity }} {{- with .Values.clair.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.clair.tolerations }} {{- with .Values.clair.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{ end }} {{ end }}
{{- if .Values.clair.enabled }} {{- if .Values.clair.enabled }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: {{ template "harbor.clair" . }} name: {{ template "harbor.clair" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
config.yaml: {{ tpl (.Files.Get "conf/clair.yaml") . | b64enc }} config.yaml: {{ tpl (.Files.Get "conf/clair.yaml") . | b64enc }}
redis: {{ include "harbor.redis.urlForClair" . | b64enc }} redis: {{ include "harbor.redis.urlForClair" . | b64enc }}
database: {{ include "harbor.database.clair" . | b64enc }} database: {{ include "harbor.database.clair" . | b64enc }}
{{- end }} {{- end }}
\ No newline at end of file
{{ if .Values.clair.enabled }} {{ if .Values.clair.enabled }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: "{{ template "harbor.clair" . }}" name: "{{ template "harbor.clair" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- name: adapter - name: adapter
port: {{ include "harbor.clairAdapter.servicePort" . }} port: {{ include "harbor.clairAdapter.servicePort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: clair component: clair
{{ end }} {{ end }}
{{- if and .Values.clair.enabled .Values.internalTLS.enabled }} {{- if and .Values.clair.enabled .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }} {{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.clair.secretName" . }}" name: "{{ template "harbor.internalTLS.clair.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.clair.crt\" is required!" .Values.internalTLS.clair.crt) | b64enc | quote }} tls.crt: {{ (required "The \"internalTLS.clair.crt\" is required!" .Values.internalTLS.clair.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.clair.key\" is required!" .Values.internalTLS.clair.key) | b64enc | quote }} tls.key: {{ (required "The \"internalTLS.clair.key\" is required!" .Values.internalTLS.clair.key) | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
app.conf: |+ app.conf: |+
appname = Harbor appname = Harbor
runmode = prod runmode = prod
enablegzip = true enablegzip = true
[prod] [prod]
httpport = {{ ternary "8443" "8080" .Values.internalTLS.enabled }} httpport = {{ ternary "8443" "8080" .Values.internalTLS.enabled }}
PORT: "{{ ternary "8443" "8080" .Values.internalTLS.enabled }}" PORT: "{{ ternary "8443" "8080" .Values.internalTLS.enabled }}"
DATABASE_TYPE: "postgresql" DATABASE_TYPE: "postgresql"
POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}" POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}"
POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}" POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}"
POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}" POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}"
POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}" POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}"
POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}" POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}"
POSTGRESQL_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}" POSTGRESQL_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}"
POSTGRESQL_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}" POSTGRESQL_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}"
EXT_ENDPOINT: "{{ .Values.externalURL }}.{{ $.Values.global.host }}" EXT_ENDPOINT: "{{ .Values.externalURL }}.{{ $.Values.global.host }}"
CORE_URL: "{{ template "harbor.coreURL" . }}" CORE_URL: "{{ template "harbor.coreURL" . }}"
JOBSERVICE_URL: "{{ template "harbor.jobserviceURL" . }}" JOBSERVICE_URL: "{{ template "harbor.jobserviceURL" . }}"
REGISTRY_URL: "{{ template "harbor.registryURL" . }}" REGISTRY_URL: "{{ template "harbor.registryURL" . }}"
TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}" TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}"
WITH_NOTARY: "{{ .Values.notary.enabled }}" WITH_NOTARY: "{{ .Values.notary.enabled }}"
NOTARY_URL: "http://{{ template "harbor.notary-server" . }}:4443" NOTARY_URL: "http://{{ template "harbor.notary-server" . }}:4443"
CORE_LOCAL_URL: "{{ ternary "https://127.0.0.1:8443" "http://127.0.0.1:8080" .Values.internalTLS.enabled }}" CORE_LOCAL_URL: "{{ ternary "https://127.0.0.1:8443" "http://127.0.0.1:8080" .Values.internalTLS.enabled }}"
WITH_CLAIR: "{{ .Values.clair.enabled }}" WITH_CLAIR: "{{ .Values.clair.enabled }}"
CLAIR_ADAPTER_URL: "{{ template "harbor.clairAdapterURL" . }}" CLAIR_ADAPTER_URL: "{{ template "harbor.clairAdapterURL" . }}"
WITH_TRIVY: {{ .Values.trivy.enabled | quote }} WITH_TRIVY: {{ .Values.trivy.enabled | quote }}
TRIVY_ADAPTER_URL: "{{ template "harbor.trivyAdapterURL" . }}" TRIVY_ADAPTER_URL: "{{ template "harbor.trivyAdapterURL" . }}"
REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.persistence.imageChartStorage.type }}" REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.persistence.imageChartStorage.type }}"
WITH_CHARTMUSEUM: "{{ .Values.chartmuseum.enabled }}" WITH_CHARTMUSEUM: "{{ .Values.chartmuseum.enabled }}"
CHART_REPOSITORY_URL: "{{ template "harbor.component.scheme" . }}://{{ template "harbor.chartmuseum" . }}" CHART_REPOSITORY_URL: "{{ template "harbor.component.scheme" . }}://{{ template "harbor.chartmuseum" . }}"
LOG_LEVEL: "{{ .Values.logLevel }}" LOG_LEVEL: "{{ .Values.logLevel }}"
CONFIG_PATH: "/etc/core/app.conf" CONFIG_PATH: "/etc/core/app.conf"
CHART_CACHE_DRIVER: "redis" CHART_CACHE_DRIVER: "redis"
_REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}" _REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}"
_REDIS_URL_REG: "{{ template "harbor.redis.urlForRegistry" . }}" _REDIS_URL_REG: "{{ template "harbor.redis.urlForRegistry" . }}"
PORTAL_URL: "{{ template "harbor.portalURL" . }}" PORTAL_URL: "{{ template "harbor.portalURL" . }}"
REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}" REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}"
REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}" REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}"
{{- if .Values.uaaSecretName }} {{- if .Values.uaaSecretName }}
UAA_CA_ROOT: "/etc/core/auth-ca/auth-ca.crt" UAA_CA_ROOT: "/etc/core/auth-ca/auth-ca.crt"
{{- end }} {{- end }}
{{- if has "core" .Values.proxy.components }} {{- if has "core" .Values.proxy.components }}
HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" HTTP_PROXY: "{{ .Values.proxy.httpProxy }}"
HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}"
NO_PROXY: "{{ template "harbor.noProxy" . }}" NO_PROXY: "{{ template "harbor.noProxy" . }}"
{{- end }} {{- end }}
PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE: "docker-hub,harbor" PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE: "docker-hub,harbor"
{{- if hasKey .Values.core "gcTimeWindowHours" }} {{- if hasKey .Values.core "gcTimeWindowHours" }}
#make the GC time window configurable for testing #make the GC time window configurable for testing
GC_TIME_WINDOW_HOURS: "{{ .Values.core.gcTimeWindowHours }}" GC_TIME_WINDOW_HOURS: "{{ .Values.core.gcTimeWindowHours }}"
{{- end }} {{- end }}
\ No newline at end of file
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: core component: core
spec: spec:
replicas: {{ .Values.core.replicas }} replicas: {{ .Values.core.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: core component: core
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: core component: core
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/core/core-secret.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 }} checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
checksum/tls: {{ include (print $.Template.BasePath "/core/core-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/core/core-tls.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.core.podAnnotations }} {{- if .Values.core.podAnnotations }}
{{ toYaml .Values.core.podAnnotations | indent 8 }} {{ toYaml .Values.core.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- if .Values.core.serviceAccountName }} {{- if .Values.core.serviceAccountName }}
serviceAccountName: {{ .Values.core.serviceAccountName }} serviceAccountName: {{ .Values.core.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: core - name: core
{{- if contains "/" .Values.core.image.repository }} {{- if contains "/" .Values.core.image.repository }}
image: "{{ .Values.core.image.repository }}" image: "{{ .Values.core.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.core.image.hub | default .Values.global.hub }}/{{ .Values.core.image.repository }}:{{ .Values.core.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.core.image.hub | default .Values.global.hub }}/{{ .Values.core.image.repository }}:{{ .Values.core.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
{{- if .Values.core.startupProbe.enabled }} {{- if .Values.core.startupProbe.enabled }}
startupProbe: startupProbe:
httpGet: httpGet:
path: /api/v2.0/ping path: /api/v2.0/ping
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.core.containerPort" . }} port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 360 failureThreshold: 360
initialDelaySeconds: {{ .Values.core.startupProbe.initialDelaySeconds }} initialDelaySeconds: {{ .Values.core.startupProbe.initialDelaySeconds }}
periodSeconds: 10 periodSeconds: 10
{{- end }} {{- end }}
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /api/v2.0/ping path: /api/v2.0/ping
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.core.containerPort" . }} port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 2 failureThreshold: 2
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /api/v2.0/ping path: /api/v2.0/ping
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.core.containerPort" . }} port: {{ template "harbor.core.containerPort" . }}
failureThreshold: 2 failureThreshold: 2
periodSeconds: 10 periodSeconds: 10
envFrom: envFrom:
- configMapRef: - configMapRef:
name: "{{ template "harbor.core" . }}" name: "{{ template "harbor.core" . }}"
- secretRef: - secretRef:
name: "{{ template "harbor.core" . }}" name: "{{ template "harbor.core" . }}"
env: env:
- name: CORE_SECRET - name: CORE_SECRET
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
key: secret key: secret
- name: JOBSERVICE_SECRET - name: JOBSERVICE_SECRET
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
key: JOBSERVICE_SECRET key: JOBSERVICE_SECRET
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED - name: INTERNAL_TLS_ENABLED
value: "true" value: "true"
- name: INTERNAL_TLS_KEY_PATH - name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/core/tls.key value: /etc/harbor/ssl/core/tls.key
- name: INTERNAL_TLS_CERT_PATH - name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/core/tls.crt value: /etc/harbor/ssl/core/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH - name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/core/ca.crt value: /etc/harbor/ssl/core/ca.crt
{{- end }} {{- end }}
ports: ports:
- containerPort: {{ template "harbor.core.containerPort" . }} - containerPort: {{ template "harbor.core.containerPort" . }}
volumeMounts: volumeMounts:
- name: config - name: config
mountPath: /etc/core/app.conf mountPath: /etc/core/app.conf
subPath: app.conf subPath: app.conf
- name: secret-key - name: secret-key
mountPath: /etc/core/key mountPath: /etc/core/key
subPath: key subPath: key
- name: token-service-private-key - name: token-service-private-key
mountPath: /etc/core/private_key.pem mountPath: /etc/core/private_key.pem
subPath: tls.key subPath: tls.key
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: ca-download - name: ca-download
mountPath: /etc/core/ca mountPath: /etc/core/ca
{{- end }} {{- end }}
{{- if .Values.uaaSecretName }} {{- if .Values.uaaSecretName }}
- name: auth-ca-cert - name: auth-ca-cert
mountPath: /etc/core/auth-ca/auth-ca.crt mountPath: /etc/core/auth-ca/auth-ca.crt
subPath: auth-ca.crt subPath: auth-ca.crt
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: core-internal-certs - name: core-internal-certs
mountPath: /etc/harbor/ssl/core mountPath: /etc/harbor/ssl/core
{{- end }} {{- end }}
- name: psc - name: psc
mountPath: /etc/core/token mountPath: /etc/core/token
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }} {{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }} {{- end }}
{{- if .Values.core.resources }} {{- if .Values.core.resources }}
resources: resources:
{{ toYaml .Values.core.resources | indent 10 }} {{ toYaml .Values.core.resources | indent 10 }}
{{- end }} {{- end }}
volumes: volumes:
- name: config - name: config
configMap: configMap:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
items: items:
- key: app.conf - key: app.conf
path: app.conf path: app.conf
- name: secret-key - name: secret-key
secret: secret:
secretName: {{ template "harbor.core" . }} secretName: {{ template "harbor.core" . }}
items: items:
- key: secretKey - key: secretKey
path: key path: key
- name: token-service-private-key - name: token-service-private-key
secret: secret:
{{- if .Values.core.secretName }} {{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }} secretName: {{ .Values.core.secretName }}
{{- else }} {{- else }}
secretName: {{ template "harbor.core" . }} secretName: {{ template "harbor.core" . }}
{{- end }} {{- end }}
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: ca-download - name: ca-download
secret: secret:
{{- if .Values.caSecretName }} {{- if .Values.caSecretName }}
secretName: {{ .Values.caSecretName }} secretName: {{ .Values.caSecretName }}
{{- else if eq (include "harbor.autoGenCertForIngress" .) "true" }} {{- else if eq (include "harbor.autoGenCertForIngress" .) "true" }}
secretName: "{{ template "harbor.ingress" . }}" secretName: "{{ template "harbor.ingress" . }}"
{{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }} {{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }}
secretName: {{ template "harbor.tlsSecretForNginx" . }} secretName: {{ template "harbor.tlsSecretForNginx" . }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .Values.uaaSecretName }} {{- if .Values.uaaSecretName }}
- name: auth-ca-cert - name: auth-ca-cert
secret: secret:
secretName: {{ .Values.uaaSecretName }} secretName: {{ .Values.uaaSecretName }}
items: items:
- key: ca.crt - key: ca.crt
path: auth-ca.crt path: auth-ca.crt
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: core-internal-certs - name: core-internal-certs
secret: secret:
secretName: {{ template "harbor.internalTLS.core.secretName" . }} secretName: {{ template "harbor.internalTLS.core.secretName" . }}
{{- end }} {{- end }}
- name: psc - name: psc
emptyDir: {} emptyDir: {}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }} {{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }} {{- end }}
{{- with .Values.core.nodeSelector }} {{- with .Values.core.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.core.affinity }} {{- with .Values.core.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.core.tolerations }} {{- with .Values.core.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
secretKey: {{ .Values.secretKey | b64enc | quote }} secretKey: {{ .Values.secretKey | b64enc | quote }}
secret: {{ .Values.core.secret | default (randAlphaNum 16) | b64enc | quote }} secret: {{ .Values.core.secret | default (randAlphaNum 16) | b64enc | quote }}
{{- if not .Values.core.secretName }} {{- if not .Values.core.secretName }}
tls.crt: {{ .Files.Get "cert/tls.crt" | b64enc }} tls.crt: {{ .Files.Get "cert/tls.crt" | b64enc }}
tls.key: {{ .Files.Get "cert/tls.key" | b64enc }} tls.key: {{ .Files.Get "cert/tls.key" | b64enc }}
{{- end }} {{- end }}
HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }} HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }}
POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }} REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }}
CSRF_KEY: {{ .Values.core.xsrfKey | default (randAlphaNum 32) | b64enc | quote }} CSRF_KEY: {{ .Values.core.xsrfKey | default (randAlphaNum 32) | b64enc | quote }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
{{- if (eq .Values.expose.ingress.controller "gce") }} {{- if (eq .Values.expose.ingress.controller "gce") }}
type: NodePort type: NodePort
{{- end }} {{- end }}
ports: ports:
- port: {{ template "harbor.core.servicePort" . }} - port: {{ template "harbor.core.servicePort" . }}
targetPort: {{ template "harbor.core.containerPort" . }} targetPort: {{ template "harbor.core.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: core component: core
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }} {{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.core.secretName" . }}" name: "{{ template "harbor.internalTLS.core.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.core.crt\" is required!" .Values.internalTLS.core.crt) | b64enc | quote }} tls.crt: {{ (required "The \"internalTLS.core.crt\" is required!" .Values.internalTLS.core.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.core.key\" is required!" .Values.internalTLS.core.key) | b64enc | quote }} tls.key: {{ (required "The \"internalTLS.core.key\" is required!" .Values.internalTLS.core.key) | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.database" . }}" name: "{{ template "harbor.database" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
POSTGRES_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} POSTGRES_PASSWORD: {{ template "harbor.database.encryptedPassword" . }}
{{- end -}} {{- end -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
{{- $database := .Values.persistence.persistentVolumeClaim.database -}} {{- $database := .Values.persistence.persistentVolumeClaim.database -}}
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
metadata: metadata:
name: "{{ template "harbor.database" . }}" name: "{{ template "harbor.database" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: database component: database
spec: spec:
replicas: 1 replicas: 1
serviceName: "{{ template "harbor.database" . }}" serviceName: "{{ template "harbor.database" . }}"
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: database component: database
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: database component: database
annotations: annotations:
checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }}
{{- if .Values.database.podAnnotations }} {{- if .Values.database.podAnnotations }}
{{ toYaml .Values.database.podAnnotations | indent 8 }} {{ toYaml .Values.database.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
{{- if .Values.database.internal.serviceAccountName }} {{- if .Values.database.internal.serviceAccountName }}
serviceAccountName: {{ .Values.database.internal.serviceAccountName }} serviceAccountName: {{ .Values.database.internal.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
initContainers: initContainers:
- name: "change-permission-of-directory" - name: "change-permission-of-directory"
securityContext: securityContext:
runAsUser: 0 runAsUser: 0
{{- if contains "/" .Values.database.internal.image.repository }} {{- if contains "/" .Values.database.internal.image.repository }}
image: "{{ .Values.database.internal.image.repository }}" image: "{{ .Values.database.internal.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.database.internal.image.hub | default .Values.global.hub }}/{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.database.internal.image.hub | default .Values.global.hub }}/{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
command: ["/bin/sh"] command: ["/bin/sh"]
args: ["-c", "chown -R postgres:postgres /var/lib/postgresql/data"] args: ["-c", "chown -R postgres:postgres /var/lib/postgresql/data"]
volumeMounts: volumeMounts:
- name: database-data - name: database-data
mountPath: /var/lib/postgresql/data mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }} subPath: {{ $database.subPath }}
- name: "remove-lost-found" - name: "remove-lost-found"
{{- if contains "/" .Values.database.internal.image.repository }} {{- if contains "/" .Values.database.internal.image.repository }}
image: "{{ .Values.database.internal.image.repository }}" image: "{{ .Values.database.internal.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.database.internal.image.hub | default .Values.global.hub }}/{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.database.internal.image.hub | default .Values.global.hub }}/{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
command: ["rm", "-Rf", "/var/lib/postgresql/data/lost+found"] command: ["rm", "-Rf", "/var/lib/postgresql/data/lost+found"]
volumeMounts: volumeMounts:
- name: database-data - name: database-data
mountPath: /var/lib/postgresql/data mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }} subPath: {{ $database.subPath }}
containers: containers:
- name: database - name: database
{{- if contains "/" .Values.database.internal.image.repository }} {{- if contains "/" .Values.database.internal.image.repository }}
image: "{{ .Values.database.internal.image.repository }}" image: "{{ .Values.database.internal.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.database.internal.image.hub | default .Values.global.hub }}/{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.database.internal.image.hub | default .Values.global.hub }}/{{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
exec: exec:
command: command:
- /docker-healthcheck.sh - /docker-healthcheck.sh
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
exec: exec:
command: command:
- /docker-healthcheck.sh - /docker-healthcheck.sh
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.database.internal.resources }} {{- if .Values.database.internal.resources }}
resources: resources:
{{ toYaml .Values.database.internal.resources | indent 10 }} {{ toYaml .Values.database.internal.resources | indent 10 }}
{{- end }} {{- end }}
envFrom: envFrom:
- secretRef: - secretRef:
name: "{{ template "harbor.database" . }}" name: "{{ template "harbor.database" . }}"
volumeMounts: volumeMounts:
- name: database-data - name: database-data
mountPath: /var/lib/postgresql/data mountPath: /var/lib/postgresql/data
subPath: {{ $database.subPath }} subPath: {{ $database.subPath }}
{{- if not .Values.persistence.enabled }} {{- if not .Values.persistence.enabled }}
volumes: volumes:
- name: "database-data" - name: "database-data"
emptyDir: {} emptyDir: {}
{{- else if $database.existingClaim }} {{- else if $database.existingClaim }}
volumes: volumes:
- name: "database-data" - name: "database-data"
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ $database.existingClaim }} claimName: {{ $database.existingClaim }}
{{- end -}} {{- end -}}
{{- with .Values.database.internal.nodeSelector }} {{- with .Values.database.internal.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.database.internal.affinity }} {{- with .Values.database.internal.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.database.internal.tolerations }} {{- with .Values.database.internal.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (not $database.existingClaim) }} {{- if and .Values.persistence.enabled (not $database.existingClaim) }}
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: "database-data" name: "database-data"
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
spec: spec:
accessModes: [{{ $database.accessMode | quote }}] accessModes: [{{ $database.accessMode | quote }}]
{{- if $database.storageClass }} {{- if $database.storageClass }}
{{- if (eq "-" $database.storageClass) }} {{- if (eq "-" $database.storageClass) }}
storageClassName: "" storageClassName: ""
{{- else }} {{- else }}
storageClassName: "{{ $database.storageClass }}" storageClassName: "{{ $database.storageClass }}"
{{- end }} {{- end }}
{{- end }} {{- end }}
resources: resources:
requests: requests:
storage: {{ $database.size | quote }} storage: {{ $database.size | quote }}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{- if eq .Values.database.type "internal" -}} {{- if eq .Values.database.type "internal" -}}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: "{{ template "harbor.database" . }}" name: "{{ template "harbor.database" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: 5432 - port: 5432
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: database component: database
{{- end -}} {{- end -}}
\ No newline at end of file
{{- if eq .Values.expose.type "ingress" }} {{- if eq .Values.expose.type "ingress" }}
{{- $ingress := .Values.expose.ingress -}} {{- $ingress := .Values.expose.ingress -}}
{{- $tls := .Values.expose.tls -}} {{- $tls := .Values.expose.tls -}}
{{- if eq .Values.expose.ingress.controller "gce" }} {{- if eq .Values.expose.ingress.controller "gce" }}
{{- $_ := set . "portal_path" "/*" -}} {{- $_ := set . "portal_path" "/*" -}}
{{- $_ := set . "api_path" "/api/*" -}} {{- $_ := set . "api_path" "/api/*" -}}
{{- $_ := set . "service_path" "/service/*" -}} {{- $_ := set . "service_path" "/service/*" -}}
{{- $_ := set . "v2_path" "/v2/*" -}} {{- $_ := set . "v2_path" "/v2/*" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/*" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/*" -}}
{{- $_ := set . "controller_path" "/c/*" -}} {{- $_ := set . "controller_path" "/c/*" -}}
{{- $_ := set . "notary_path" "/" -}} {{- $_ := set . "notary_path" "/" -}}
{{- else if eq .Values.expose.ingress.controller "ncp" }} {{- else if eq .Values.expose.ingress.controller "ncp" }}
{{- $_ := set . "portal_path" "/.*" -}} {{- $_ := set . "portal_path" "/.*" -}}
{{- $_ := set . "api_path" "/api/.*" -}} {{- $_ := set . "api_path" "/api/.*" -}}
{{- $_ := set . "service_path" "/service/.*" -}} {{- $_ := set . "service_path" "/service/.*" -}}
{{- $_ := set . "v2_path" "/v2/.*" -}} {{- $_ := set . "v2_path" "/v2/.*" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}} {{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}}
{{- $_ := set . "controller_path" "/c/.*" -}} {{- $_ := set . "controller_path" "/c/.*" -}}
{{- $_ := set . "notary_path" "/.*" -}} {{- $_ := set . "notary_path" "/.*" -}}
{{- else }} {{- else }}
{{- $_ := set . "portal_path" "/" -}} {{- $_ := set . "portal_path" "/" -}}
{{- $_ := set . "api_path" "/api" -}} {{- $_ := set . "api_path" "/api" -}}
{{- $_ := set . "service_path" "/service" -}} {{- $_ := set . "service_path" "/service" -}}
{{- $_ := set . "v2_path" "/v2" -}} {{- $_ := set . "v2_path" "/v2" -}}
{{- $_ := set . "chartrepo_path" "/chartrepo" -}} {{- $_ := set . "chartrepo_path" "/chartrepo" -}}
{{- $_ := set . "controller_path" "/c" -}} {{- $_ := set . "controller_path" "/c" -}}
{{- $_ := set . "notary_path" "/" -}} {{- $_ := set . "notary_path" "/" -}}
{{- end }} {{- end }}
--- ---
{{- if not (.Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1") -}} {{- if not (.Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1") -}}
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion }} {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
{{- else }} {{- else }}
apiVersion: networking.k8s.io/v1beta1 apiVersion: networking.k8s.io/v1beta1
{{- end }} {{- end }}
kind: Ingress kind: Ingress
metadata: metadata:
name: "{{ template "harbor.ingress" . }}" name: "{{ template "harbor.ingress" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
annotations: annotations:
{{ toYaml $ingress.annotations | indent 4 }} {{ toYaml $ingress.annotations | indent 4 }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
{{- end }} {{- end }}
{{- if eq .Values.expose.ingress.controller "ncp" }} {{- if eq .Values.expose.ingress.controller "ncp" }}
ncp/use-regex: "true" ncp/use-regex: "true"
{{- if $tls.enabled }} {{- if $tls.enabled }}
ncp/http-redirect: "true" ncp/http-redirect: "true"
{{- end }} {{- end }}
{{- end }} {{- end }}
spec: spec:
{{- if $tls.enabled }} {{- if $tls.enabled }}
tls: tls:
- secretName: {{ template "harbor.tlsCoreSecretForIngress" . }} - secretName: {{ template "harbor.tlsCoreSecretForIngress" . }}
{{- if $ingress.hosts.core }} {{- if $ingress.hosts.core }}
hosts: hosts:
- {{ $ingress.hosts.core }}.{{ $.Values.global.host }} - {{ $ingress.hosts.core }}.{{ $.Values.global.host }}
{{- end }} {{- end }}
{{- end }} {{- end }}
rules: rules:
- http: - http:
paths: paths:
- path: {{ .portal_path }} - path: {{ .portal_path }}
backend: backend:
serviceName: {{ template "harbor.portal" . }} serviceName: {{ template "harbor.portal" . }}
servicePort: {{ template "harbor.portal.servicePort" . }} servicePort: {{ template "harbor.portal.servicePort" . }}
- path: {{ .api_path }} - path: {{ .api_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: {{ template "harbor.core.servicePort" . }} servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .service_path }} - path: {{ .service_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: {{ template "harbor.core.servicePort" . }} servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .v2_path }} - path: {{ .v2_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: {{ template "harbor.core.servicePort" . }} servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .chartrepo_path }} - path: {{ .chartrepo_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: {{ template "harbor.core.servicePort" . }} servicePort: {{ template "harbor.core.servicePort" . }}
- path: {{ .controller_path }} - path: {{ .controller_path }}
backend: backend:
serviceName: {{ template "harbor.core" . }} serviceName: {{ template "harbor.core" . }}
servicePort: {{ template "harbor.core.servicePort" . }} servicePort: {{ template "harbor.core.servicePort" . }}
{{- if $ingress.hosts.core }} {{- if $ingress.hosts.core }}
host: {{ $ingress.hosts.core }}.{{ $.Values.global.host }} host: {{ $ingress.hosts.core }}.{{ $.Values.global.host }}
{{- end }} {{- end }}
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
--- ---
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion }} {{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion }}
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
{{- else }} {{- else }}
apiVersion: networking.k8s.io/v1beta1 apiVersion: networking.k8s.io/v1beta1
{{- end }} {{- end }}
kind: Ingress kind: Ingress
metadata: metadata:
name: "{{ template "harbor.ingress-notary" . }}" name: "{{ template "harbor.ingress-notary" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
annotations: annotations:
{{ toYaml $ingress.annotations | indent 4 }} {{ toYaml $ingress.annotations | indent 4 }}
{{- if eq .Values.expose.ingress.controller "ncp" }} {{- if eq .Values.expose.ingress.controller "ncp" }}
ncp/use-regex: "true" ncp/use-regex: "true"
{{- if $tls.enabled }} {{- if $tls.enabled }}
ncp/http-redirect: "true" ncp/http-redirect: "true"
{{- end }} {{- end }}
{{- end }} {{- end }}
spec: spec:
{{- if $tls.enabled }} {{- if $tls.enabled }}
tls: tls:
- secretName: {{ template "harbor.tlsNotarySecretForIngress" . }} - secretName: {{ template "harbor.tlsNotarySecretForIngress" . }}
{{- if $ingress.hosts.notary }} {{- if $ingress.hosts.notary }}
hosts: hosts:
- {{ $ingress.hosts.notary }}.{{ $.Values.global.host }} - {{ $ingress.hosts.notary }}.{{ $.Values.global.host }}
{{- end }} {{- end }}
{{- end }} {{- end }}
rules: rules:
- http: - http:
paths: paths:
- path: {{ .notary_path }} - path: {{ .notary_path }}
backend: backend:
serviceName: {{ template "harbor.notary-server" . }} serviceName: {{ template "harbor.notary-server" . }}
servicePort: 4443 servicePort: 4443
{{- if $ingress.hosts.notary }} {{- if $ingress.hosts.notary }}
host: {{ $ingress.hosts.notary }}.{{ $.Values.global.host }} host: {{ $ingress.hosts.notary }}.{{ $.Values.global.host }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if .Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1" -}} {{- if .Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1" -}}
--- ---
apiVersion: bcc.bd-apaas.com/v1alpha1 apiVersion: bcc.bd-apaas.com/v1alpha1
kind: IngressHost kind: IngressHost
metadata: metadata:
name: "{{ template "harbor.ingress" . }}-core" name: "{{ template "harbor.ingress" . }}-core"
annotations: annotations:
{{- with .Values.expose.ingress.annotations }} {{- with .Values.expose.ingress.annotations }}
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
labels: labels:
{{ include "harbor.labels" . | nindent 4 }} {{ include "harbor.labels" . | nindent 4 }}
spec: spec:
host: "{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}" host: "{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}"
--- ---
apiVersion: bcc.bd-apaas.com/v1alpha1 apiVersion: bcc.bd-apaas.com/v1alpha1
kind: IngressHost kind: IngressHost
metadata: metadata:
name: "{{ template "harbor.ingress" . }}-notary" name: "{{ template "harbor.ingress" . }}-notary"
annotations: annotations:
{{- with .Values.expose.ingress.annotations }} {{- with .Values.expose.ingress.annotations }}
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
labels: labels:
{{ include "harbor.labels" . | nindent 4 }} {{ include "harbor.labels" . | nindent 4 }}
spec: spec:
host: "{{ .Values.expose.ingress.hosts.notary }}.{{ $.Values.global.host }}" host: "{{ .Values.expose.ingress.hosts.notary }}.{{ $.Values.global.host }}"
{{- end -}} {{- end -}}
{{- if .Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1" -}} {{- if .Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1" -}}
--- ---
apiVersion: bcc.bd-apaas.com/v1alpha1 apiVersion: bcc.bd-apaas.com/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: "{{ template "harbor.ingress" . }}" name: "{{ template "harbor.ingress" . }}"
annotations: annotations:
{{- with .Values.expose.ingress.annotations }} {{- with .Values.expose.ingress.annotations }}
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
labels: labels:
{{ include "harbor.labels" . | nindent 4 }} {{ include "harbor.labels" . | nindent 4 }}
spec: spec:
entryPoints: entryPoints:
- websecure - websecure
routes: routes:
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.portal" . }} - name: {{ template "harbor.portal" . }}
port: {{ template "harbor.portal.servicePort" . }} port: {{ template "harbor.portal.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/api/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/api/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/service/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/service/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/v2/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/v2/`)
kind: Rule kind: Rule
middlewares: middlewares:
- name: "{{ template "harbor.ingress" . }}-https" - name: "{{ template "harbor.ingress" . }}-https"
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/chartrepo/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/chartrepo/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/c/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/c/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.notary }}.{{ $.Values.global.host }}`) && PathPrefix(`/`) - match: Host(`{{ .Values.expose.ingress.hosts.notary }}.{{ $.Values.global.host }}`) && PathPrefix(`/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.notary-server" . }} - name: {{ template "harbor.notary-server" . }}
port: 4443 port: 4443
tls: tls:
certResolver: default certResolver: default
--- ---
apiVersion: bcc.bd-apaas.com/v1alpha1 apiVersion: bcc.bd-apaas.com/v1alpha1
kind: IngressRoute kind: IngressRoute
metadata: metadata:
name: "{{ template "harbor.ingress" . }}-http" name: "{{ template "harbor.ingress" . }}-http"
annotations: annotations:
{{- with .Values.expose.ingress.annotations }} {{- with .Values.expose.ingress.annotations }}
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
labels: labels:
{{ include "harbor.labels" . | nindent 4 }} {{ include "harbor.labels" . | nindent 4 }}
spec: spec:
entryPoints: entryPoints:
- web - web
routes: routes:
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.portal" . }} - name: {{ template "harbor.portal" . }}
port: {{ template "harbor.portal.servicePort" . }} port: {{ template "harbor.portal.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/api/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/api/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/service/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/service/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/v2/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/v2/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/chartrepo/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/chartrepo/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/c/`) - match: Host(`{{ .Values.expose.ingress.hosts.core }}.{{ $.Values.global.host }}`) && PathPrefix(`/c/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.core" . }} - name: {{ template "harbor.core" . }}
port: {{ template "harbor.core.servicePort" . }} port: {{ template "harbor.core.servicePort" . }}
- match: Host(`{{ .Values.expose.ingress.hosts.notary }}.{{ $.Values.global.host }}`) && PathPrefix(`/`) - match: Host(`{{ .Values.expose.ingress.hosts.notary }}.{{ $.Values.global.host }}`) && PathPrefix(`/`)
kind: Rule kind: Rule
services: services:
- name: {{ template "harbor.notary-server" . }} - name: {{ template "harbor.notary-server" . }}
port: 4443 port: 4443
{{- end -}} {{- end -}}
{{- if .Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1" -}} {{- if .Capabilities.APIVersions.Has "bcc.bd-apaas.com/v1alpha1" -}}
apiVersion: bcc.bd-apaas.com/v1alpha1 apiVersion: bcc.bd-apaas.com/v1alpha1
kind: Middleware kind: Middleware
metadata: metadata:
name: "{{ template "harbor.ingress" . }}-https" name: "{{ template "harbor.ingress" . }}-https"
spec: spec:
headers: headers:
customRequestHeaders: customRequestHeaders:
X-Forwarded-Proto: "https" X-Forwarded-Proto: "https"
{{- end -}} {{- end -}}
\ No newline at end of file
{{- if eq (include "harbor.autoGenCertForIngress" .) "true" }} {{- if eq (include "harbor.autoGenCertForIngress" .) "true" }}
{{- $ca := genCA "harbor-ca" 365 }} {{- $ca := genCA "harbor-ca" 365 }}
{{- $cert := genSignedCert .Values.expose.ingress.hosts.core nil (list .Values.expose.ingress.hosts.core .Values.expose.ingress.hosts.notary) 365 $ca }} {{- $cert := genSignedCert .Values.expose.ingress.hosts.core nil (list .Values.expose.ingress.hosts.core .Values.expose.ingress.hosts.notary) 365 $ca }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.ingress" . }}" name: "{{ template "harbor.ingress" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
tls.crt: {{ $cert.Cert | b64enc | quote }} tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }} tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
{{- $ca := genCA "harbor-internal-ca" 365 }} {{- $ca := genCA "harbor-internal-ca" 365 }}
{{- $coreCN := (include "harbor.core" .) }} {{- $coreCN := (include "harbor.core" .) }}
{{- $coreCrt := genSignedCert $coreCN (list "127.0.0.1") (list "localhost" $coreCN) 365 $ca }} {{- $coreCrt := genSignedCert $coreCN (list "127.0.0.1") (list "localhost" $coreCN) 365 $ca }}
{{- $jsCN := (include "harbor.jobservice" .) }} {{- $jsCN := (include "harbor.jobservice" .) }}
{{- $jsCrt := genSignedCert $jsCN nil (list $jsCN) 365 $ca }} {{- $jsCrt := genSignedCert $jsCN nil (list $jsCN) 365 $ca }}
{{- $regCN := (include "harbor.registry" .) }} {{- $regCN := (include "harbor.registry" .) }}
{{- $regCrt := genSignedCert $regCN nil (list $regCN) 365 $ca }} {{- $regCrt := genSignedCert $regCN nil (list $regCN) 365 $ca }}
{{- $portalCN := (include "harbor.portal" .) }} {{- $portalCN := (include "harbor.portal" .) }}
{{- $portalCrt := genSignedCert $portalCN nil (list $portalCN) 365 $ca }} {{- $portalCrt := genSignedCert $portalCN nil (list $portalCN) 365 $ca }}
--- ---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.core.secretName" . }}" name: "{{ template "harbor.internalTLS.core.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $coreCrt.Cert | b64enc | quote }} tls.crt: {{ $coreCrt.Cert | b64enc | quote }}
tls.key: {{ $coreCrt.Key | b64enc | quote }} tls.key: {{ $coreCrt.Key | b64enc | quote }}
--- ---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}" name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $jsCrt.Cert | b64enc | quote }} tls.crt: {{ $jsCrt.Cert | b64enc | quote }}
tls.key: {{ $jsCrt.Key | b64enc | quote }} tls.key: {{ $jsCrt.Key | b64enc | quote }}
--- ---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.registry.secretName" . }}" name: "{{ template "harbor.internalTLS.registry.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $regCrt.Cert | b64enc | quote }} tls.crt: {{ $regCrt.Cert | b64enc | quote }}
tls.key: {{ $regCrt.Key | b64enc | quote }} tls.key: {{ $regCrt.Key | b64enc | quote }}
--- ---
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.portal.secretName" . }}" name: "{{ template "harbor.internalTLS.portal.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $portalCrt.Cert | b64enc | quote }} tls.crt: {{ $portalCrt.Cert | b64enc | quote }}
tls.key: {{ $portalCrt.Key | b64enc | quote }} tls.key: {{ $portalCrt.Key | b64enc | quote }}
{{- if .Values.chartmuseum.enabled }} {{- if .Values.chartmuseum.enabled }}
--- ---
{{- $chartCN := (include "harbor.chartmuseum" .) }} {{- $chartCN := (include "harbor.chartmuseum" .) }}
{{- $chartCrt := genSignedCert $chartCN nil (list $chartCN) 365 $ca }} {{- $chartCrt := genSignedCert $chartCN nil (list $chartCN) 365 $ca }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.chartmuseum.secretName" . }}" name: "{{ template "harbor.internalTLS.chartmuseum.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $chartCrt.Cert | b64enc | quote }} tls.crt: {{ $chartCrt.Cert | b64enc | quote }}
tls.key: {{ $chartCrt.Key | b64enc | quote }} tls.key: {{ $chartCrt.Key | b64enc | quote }}
{{- end }} {{- end }}
{{- if .Values.clair.enabled }} {{- if .Values.clair.enabled }}
--- ---
{{- $clairCN := (include "harbor.clair" .) }} {{- $clairCN := (include "harbor.clair" .) }}
{{- $clairCrt := genSignedCert $clairCN nil (list $clairCN) 365 $ca }} {{- $clairCrt := genSignedCert $clairCN nil (list $clairCN) 365 $ca }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.clair.secretName" . }}" name: "{{ template "harbor.internalTLS.clair.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $clairCrt.Cert | b64enc | quote }} tls.crt: {{ $clairCrt.Cert | b64enc | quote }}
tls.key: {{ $clairCrt.Key | b64enc | quote }} tls.key: {{ $clairCrt.Key | b64enc | quote }}
{{- end }} {{- end }}
{{- if and .Values.trivy.enabled}} {{- if and .Values.trivy.enabled}}
--- ---
{{- $trivyCN := (include "harbor.trivy" .) }} {{- $trivyCN := (include "harbor.trivy" .) }}
{{- $trivyCrt := genSignedCert $trivyCN nil (list $trivyCN) 365 $ca }} {{- $trivyCrt := genSignedCert $trivyCN nil (list $trivyCN) 365 $ca }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.trivy.secretName" . }}" name: "{{ template "harbor.internalTLS.trivy.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $trivyCrt.Cert | b64enc | quote }} tls.crt: {{ $trivyCrt.Cert | b64enc | quote }}
tls.key: {{ $trivyCrt.Key | b64enc | quote }} tls.key: {{ $trivyCrt.Key | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: "{{ template "harbor.jobservice" . }}-env" name: "{{ template "harbor.jobservice" . }}-env"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
CORE_URL: "{{ template "harbor.coreURL" . }}" CORE_URL: "{{ template "harbor.coreURL" . }}"
TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}" TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}"
REGISTRY_URL: "{{ template "harbor.registryURL" . }}" REGISTRY_URL: "{{ template "harbor.registryURL" . }}"
REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}" REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}"
REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}" REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}"
{{- if has "jobservice" .Values.proxy.components }} {{- if has "jobservice" .Values.proxy.components }}
HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" HTTP_PROXY: "{{ .Values.proxy.httpProxy }}"
HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}"
NO_PROXY: "{{ template "harbor.noProxy" . }}" NO_PROXY: "{{ template "harbor.noProxy" . }}"
{{- end }} {{- end }}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
config.yml: |+ config.yml: |+
#Server listening port #Server listening port
protocol: "{{ template "harbor.component.scheme" . }}" protocol: "{{ template "harbor.component.scheme" . }}"
port: {{ template "harbor.jobservice.containerPort". }} port: {{ template "harbor.jobservice.containerPort". }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
https_config: https_config:
cert: "/etc/harbor/ssl/jobservice/tls.crt" cert: "/etc/harbor/ssl/jobservice/tls.crt"
key: "/etc/harbor/ssl/jobservice/tls.key" key: "/etc/harbor/ssl/jobservice/tls.key"
{{- end }} {{- end }}
worker_pool: worker_pool:
workers: {{ .Values.jobservice.maxJobWorkers }} workers: {{ .Values.jobservice.maxJobWorkers }}
backend: "redis" backend: "redis"
redis_pool: redis_pool:
redis_url: "{{ template "harbor.redis.urlForJobservice" . }}" redis_url: "{{ template "harbor.redis.urlForJobservice" . }}"
namespace: "harbor_job_service_namespace" namespace: "harbor_job_service_namespace"
idle_timeout_second: 3600 idle_timeout_second: 3600
job_loggers: job_loggers:
{{- if eq .Values.jobservice.jobLogger "file" }} {{- if eq .Values.jobservice.jobLogger "file" }}
- name: "FILE" - name: "FILE"
level: {{ .Values.logLevel | upper }} level: {{ .Values.logLevel | upper }}
settings: # Customized settings of logger settings: # Customized settings of logger
base_dir: "/var/log/jobs" base_dir: "/var/log/jobs"
sweeper: sweeper:
duration: 14 #days duration: 14 #days
settings: # Customized settings of sweeper settings: # Customized settings of sweeper
work_dir: "/var/log/jobs" work_dir: "/var/log/jobs"
{{- else if eq .Values.jobservice.jobLogger "database" }} {{- else if eq .Values.jobservice.jobLogger "database" }}
- name: "DB" - name: "DB"
level: {{ .Values.logLevel | upper }} level: {{ .Values.logLevel | upper }}
sweeper: sweeper:
duration: 14 #days duration: 14 #days
{{- else }} {{- else }}
- name: "STD_OUTPUT" - name: "STD_OUTPUT"
level: {{ .Values.logLevel | upper }} level: {{ .Values.logLevel | upper }}
{{- end }} {{- end }}
#Loggers for the job service #Loggers for the job service
loggers: loggers:
- name: "STD_OUTPUT" - name: "STD_OUTPUT"
level: {{ .Values.logLevel | upper }} level: {{ .Values.logLevel | upper }}
\ No newline at end of file
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: jobservice component: jobservice
spec: spec:
replicas: {{ .Values.jobservice.replicas }} replicas: {{ .Values.jobservice.replicas }}
strategy: strategy:
type: {{ .Values.updateStrategy.type }} type: {{ .Values.updateStrategy.type }}
{{- if eq .Values.updateStrategy.type "Recreate" }} {{- if eq .Values.updateStrategy.type "Recreate" }}
rollingUpdate: null rollingUpdate: null
{{- end }} {{- end }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: jobservice component: jobservice
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: jobservice component: jobservice
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm.yaml") . | sha256sum }}
checksum/configmap-env: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm-env.yaml") . | sha256sum }} checksum/configmap-env: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm-env.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.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 }} checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
checksum/tls: {{ include (print $.Template.BasePath "/jobservice/jobservice-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/jobservice/jobservice-tls.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.jobservice.podAnnotations }} {{- if .Values.jobservice.podAnnotations }}
{{ toYaml .Values.jobservice.podAnnotations | indent 8 }} {{ toYaml .Values.jobservice.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- if .Values.jobservice.serviceAccountName }} {{- if .Values.jobservice.serviceAccountName }}
serviceAccountName: {{ .Values.jobservice.serviceAccountName }} serviceAccountName: {{ .Values.jobservice.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: jobservice - name: jobservice
{{- if contains "/" .Values.jobservice.image.repository }} {{- if contains "/" .Values.jobservice.image.repository }}
image: "{{ .Values.jobservice.image.repository }}" image: "{{ .Values.jobservice.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.jobservice.image.hub | default .Values.global.hub }}/{{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.jobservice.image.hub | default .Values.global.hub }}/{{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /api/v1/stats path: /api/v1/stats
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.jobservice.containerPort" . }} port: {{ template "harbor.jobservice.containerPort" . }}
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /api/v1/stats path: /api/v1/stats
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.jobservice.containerPort" . }} port: {{ template "harbor.jobservice.containerPort" . }}
initialDelaySeconds: 20 initialDelaySeconds: 20
periodSeconds: 10 periodSeconds: 10
{{- if .Values.jobservice.resources }} {{- if .Values.jobservice.resources }}
resources: resources:
{{ toYaml .Values.jobservice.resources | indent 10 }} {{ toYaml .Values.jobservice.resources | indent 10 }}
{{- end }} {{- end }}
env: env:
- name: CORE_SECRET - name: CORE_SECRET
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
key: secret key: secret
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED - name: INTERNAL_TLS_ENABLED
value: "true" value: "true"
- name: INTERNAL_TLS_KEY_PATH - name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/jobservice/tls.key value: /etc/harbor/ssl/jobservice/tls.key
- name: INTERNAL_TLS_CERT_PATH - name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/jobservice/tls.crt value: /etc/harbor/ssl/jobservice/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH - name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/jobservice/ca.crt value: /etc/harbor/ssl/jobservice/ca.crt
{{- end }} {{- end }}
envFrom: envFrom:
- configMapRef: - configMapRef:
name: "{{ template "harbor.jobservice" . }}-env" name: "{{ template "harbor.jobservice" . }}-env"
- secretRef: - secretRef:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
ports: ports:
- containerPort: {{ template "harbor.jobservice.containerPort" . }} - containerPort: {{ template "harbor.jobservice.containerPort" . }}
volumeMounts: volumeMounts:
- name: jobservice-config - name: jobservice-config
mountPath: /etc/jobservice/config.yml mountPath: /etc/jobservice/config.yml
subPath: config.yml subPath: config.yml
- name: job-logs - name: job-logs
mountPath: /var/log/jobs mountPath: /var/log/jobs
subPath: {{ .Values.persistence.persistentVolumeClaim.jobservice.subPath }} subPath: {{ .Values.persistence.persistentVolumeClaim.jobservice.subPath }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: jobservice-internal-certs - name: jobservice-internal-certs
mountPath: /etc/harbor/ssl/jobservice mountPath: /etc/harbor/ssl/jobservice
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }} {{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }} {{- end }}
volumes: volumes:
- name: jobservice-config - name: jobservice-config
configMap: configMap:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
- name: job-logs - name: job-logs
{{- if and .Values.persistence.enabled (eq .Values.jobservice.jobLogger "file") }} {{- if and .Values.persistence.enabled (eq .Values.jobservice.jobLogger "file") }}
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ .Values.persistence.persistentVolumeClaim.jobservice.existingClaim | default (include "harbor.jobservice" .) }} claimName: {{ .Values.persistence.persistentVolumeClaim.jobservice.existingClaim | default (include "harbor.jobservice" .) }}
{{- else }} {{- else }}
emptyDir: {} emptyDir: {}
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: jobservice-internal-certs - name: jobservice-internal-certs
secret: secret:
secretName: {{ template "harbor.internalTLS.jobservice.secretName" . }} secretName: {{ template "harbor.internalTLS.jobservice.secretName" . }}
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }} {{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }} {{- end }}
{{- with .Values.jobservice.nodeSelector }} {{- with .Values.jobservice.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.jobservice.affinity }} {{- with .Values.jobservice.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.jobservice.tolerations }} {{- with .Values.jobservice.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- $jobservice := .Values.persistence.persistentVolumeClaim.jobservice -}} {{- $jobservice := .Values.persistence.persistentVolumeClaim.jobservice -}}
{{- if and .Values.persistence.enabled (not $jobservice.existingClaim) }} {{- if and .Values.persistence.enabled (not $jobservice.existingClaim) }}
{{- if eq .Values.jobservice.jobLogger "file" }} {{- if eq .Values.jobservice.jobLogger "file" }}
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
apiVersion: v1 apiVersion: v1
metadata: metadata:
name: {{ template "harbor.jobservice" . }} name: {{ template "harbor.jobservice" . }}
{{- if eq .Values.persistence.resourcePolicy "keep" }} {{- if eq .Values.persistence.resourcePolicy "keep" }}
annotations: annotations:
helm.sh/resource-policy: keep helm.sh/resource-policy: keep
{{- end }} {{- end }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: jobservice component: jobservice
spec: spec:
accessModes: accessModes:
- {{ $jobservice.accessMode }} - {{ $jobservice.accessMode }}
resources: resources:
requests: requests:
storage: {{ $jobservice.size }} storage: {{ $jobservice.size }}
{{- if $jobservice.storageClass }} {{- if $jobservice.storageClass }}
{{- if eq "-" $jobservice.storageClass }} {{- if eq "-" $jobservice.storageClass }}
storageClassName: "" storageClassName: ""
{{- else }} {{- else }}
storageClassName: {{ $jobservice.storageClass }} storageClassName: {{ $jobservice.storageClass }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
JOBSERVICE_SECRET: {{ .Values.jobservice.secret | default (randAlphaNum 16) | b64enc | quote }} JOBSERVICE_SECRET: {{ .Values.jobservice.secret | default (randAlphaNum 16) | b64enc | quote }}
REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }} REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: "{{ template "harbor.jobservice" . }}" name: "{{ template "harbor.jobservice" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: {{ template "harbor.jobservice.servicePort" . }} - port: {{ template "harbor.jobservice.servicePort" . }}
targetPort: {{ template "harbor.jobservice.containerPort" . }} targetPort: {{ template "harbor.jobservice.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: jobservice component: jobservice
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }} {{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}" name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.jobservice.crt\" is required!" .Values.internalTLS.jobservice.crt) | b64enc | quote }} tls.crt: {{ (required "The \"internalTLS.jobservice.crt\" is required!" .Values.internalTLS.jobservice.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.jobservice.key\" is required!" .Values.internalTLS.jobservice.key) | b64enc | quote }} tls.key: {{ (required "The \"internalTLS.jobservice.key\" is required!" .Values.internalTLS.jobservice.key) | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if and (ne .Values.expose.type "ingress") (not .Values.expose.tls.enabled) }} {{- if and (ne .Values.expose.type "ingress") (not .Values.expose.tls.enabled) }}
{{- $scheme := (include "harbor.component.scheme" .) -}} {{- $scheme := (include "harbor.component.scheme" .) -}}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: {{ template "harbor.nginx" . }} name: {{ template "harbor.nginx" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
nginx.conf: |+ nginx.conf: |+
worker_processes auto; worker_processes auto;
pid /tmp/nginx.pid; pid /tmp/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
use epoll; use epoll;
multi_accept on; multi_accept on;
} }
http { http {
client_body_temp_path /tmp/client_body_temp; client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp; proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp; fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp; uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp; scgi_temp_path /tmp/scgi_temp;
tcp_nodelay on; tcp_nodelay on;
# this is necessary for us to be able to disable request buffering in all cases # this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1; proxy_http_version 1.1;
upstream core { upstream core {
server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}"; server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}";
} }
upstream portal { upstream portal {
server {{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}; server {{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }};
} }
log_format timed_combined '[$time_local]:$remote_addr - ' log_format timed_combined '[$time_local]:$remote_addr - '
'"$request" $status $body_bytes_sent ' '"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" ' '"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe'; '$request_time $upstream_response_time $pipe';
access_log /dev/stdout timed_combined; access_log /dev/stdout timed_combined;
server { server {
listen 8080; listen 8080;
server_tokens off; server_tokens off;
# disable any limits to avoid HTTP 413 for large image uploads # disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0; client_max_body_size 0;
# Add extra headers # Add extra headers
add_header X-Frame-Options DENY; add_header X-Frame-Options DENY;
add_header Content-Security-Policy "frame-ancestors 'none'"; add_header Content-Security-Policy "frame-ancestors 'none'";
location / { location / {
proxy_pass {{ $scheme }}://portal/; proxy_pass {{ $scheme }}://portal/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /api/ { location /api/ {
proxy_pass {{ $scheme }}://core/api/; proxy_pass {{ $scheme }}://core/api/;
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off; proxy_ssl_verify off;
proxy_ssl_session_reuse on; proxy_ssl_session_reuse on;
{{- end }} {{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /chartrepo/ { location /chartrepo/ {
proxy_pass {{ $scheme }}://core/chartrepo/; proxy_pass {{ $scheme }}://core/chartrepo/;
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off; proxy_ssl_verify off;
proxy_ssl_session_reuse on; proxy_ssl_session_reuse on;
{{- end }} {{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /c/ { location /c/ {
proxy_pass {{ $scheme }}://core/c/; proxy_pass {{ $scheme }}://core/c/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /v1/ { location /v1/ {
return 404; return 404;
} }
location /v2/ { location /v2/ {
proxy_pass {{ $scheme }}://core/v2/; proxy_pass {{ $scheme }}://core/v2/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /service/ { location /service/ {
proxy_pass {{ $scheme }}://core/service/; proxy_pass {{ $scheme }}://core/service/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /service/notifications { location /service/notifications {
return 404; return 404;
} }
} }
} }
{{- end }} {{- end }}
{{- if and (ne .Values.expose.type "ingress") .Values.expose.tls.enabled }} {{- if and (ne .Values.expose.type "ingress") .Values.expose.tls.enabled }}
{{- $scheme := (include "harbor.component.scheme" .) -}} {{- $scheme := (include "harbor.component.scheme" .) -}}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: {{ template "harbor.nginx" . }} name: {{ template "harbor.nginx" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
nginx.conf: |+ nginx.conf: |+
worker_processes auto; worker_processes auto;
pid /tmp/nginx.pid; pid /tmp/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
use epoll; use epoll;
multi_accept on; multi_accept on;
} }
http { http {
client_body_temp_path /tmp/client_body_temp; client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp; proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp; fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp; uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp; scgi_temp_path /tmp/scgi_temp;
tcp_nodelay on; tcp_nodelay on;
# this is necessary for us to be able to disable request buffering in all cases # this is necessary for us to be able to disable request buffering in all cases
proxy_http_version 1.1; proxy_http_version 1.1;
upstream core { upstream core {
server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}"; server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}";
} }
upstream portal { upstream portal {
server "{{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}"; server "{{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}";
} }
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
upstream notary-server { upstream notary-server {
server {{ template "harbor.notary-server" . }}:4443; server {{ template "harbor.notary-server" . }}:4443;
} }
{{- end }} {{- end }}
log_format timed_combined '[$time_local]:$remote_addr - ' log_format timed_combined '[$time_local]:$remote_addr - '
'"$request" $status $body_bytes_sent ' '"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" ' '"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time $pipe'; '$request_time $upstream_response_time $pipe';
access_log /dev/stdout timed_combined; access_log /dev/stdout timed_combined;
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
server { server {
listen 4443 ssl; listen 4443 ssl;
server_tokens off; server_tokens off;
# ssl # ssl
ssl_certificate /etc/nginx/cert/tls.crt; ssl_certificate /etc/nginx/cert/tls.crt;
ssl_certificate_key /etc/nginx/cert/tls.key; ssl_certificate_key /etc/nginx/cert/tls.key;
# recommendations from https://raymii.org/s/tutorials/strong_ssl_security_on_nginx.html # recommendations from https://raymii.org/s/tutorials/strong_ssl_security_on_nginx.html
ssl_protocols tlsv1.1 tlsv1.2; ssl_protocols tlsv1.1 tlsv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_session_cache shared:ssl:10m; ssl_session_cache shared:ssl:10m;
# disable any limits to avoid http 413 for large image uploads # disable any limits to avoid http 413 for large image uploads
client_max_body_size 0; client_max_body_size 0;
# required to avoid http 411: see issue #1486 (https://github.com/docker/docker/issues/1486) # required to avoid http 411: see issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on; chunked_transfer_encoding on;
location /v2/ { location /v2/ {
proxy_pass http://notary-server/v2/; proxy_pass http://notary-server/v2/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
} }
{{- end }} {{- end }}
server { server {
listen 8443 ssl; listen 8443 ssl;
# server_name harbordomain.com; # server_name harbordomain.com;
server_tokens off; server_tokens off;
# SSL # SSL
ssl_certificate /etc/nginx/cert/tls.crt; ssl_certificate /etc/nginx/cert/tls.crt;
ssl_certificate_key /etc/nginx/cert/tls.key; ssl_certificate_key /etc/nginx/cert/tls.key;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2; ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m; ssl_session_cache shared:SSL:10m;
# disable any limits to avoid HTTP 413 for large image uploads # disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0; client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on; chunked_transfer_encoding on;
# Add extra headers # Add extra headers
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
add_header X-Frame-Options DENY; add_header X-Frame-Options DENY;
add_header Content-Security-Policy "frame-ancestors 'none'"; add_header Content-Security-Policy "frame-ancestors 'none'";
location / { location / {
proxy_pass {{ $scheme }}://portal/; proxy_pass {{ $scheme }}://portal/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; HttpOnly; Secure"; proxy_cookie_path / "/; HttpOnly; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /api/ { location /api/ {
proxy_pass {{ $scheme }}://core/api/; proxy_pass {{ $scheme }}://core/api/;
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off; proxy_ssl_verify off;
proxy_ssl_session_reuse on; proxy_ssl_session_reuse on;
{{- end }} {{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure"; proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /chartrepo/ { location /chartrepo/ {
proxy_pass {{ $scheme }}://core/chartrepo/; proxy_pass {{ $scheme }}://core/chartrepo/;
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
proxy_ssl_verify off; proxy_ssl_verify off;
proxy_ssl_session_reuse on; proxy_ssl_session_reuse on;
{{- end }} {{- end }}
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure"; proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /c/ { location /c/ {
proxy_pass {{ $scheme }}://core/c/; proxy_pass {{ $scheme }}://core/c/;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure"; proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /v1/ { location /v1/ {
return 404; return 404;
} }
location /v2/ { location /v2/ {
proxy_pass {{ $scheme }}://core/v2/; proxy_pass {{ $scheme }}://core/v2/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /service/ { location /service/ {
proxy_pass {{ $scheme }}://core/service/; proxy_pass {{ $scheme }}://core/service/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 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. # 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_set_header X-Forwarded-Proto $scheme;
proxy_cookie_path / "/; Secure"; proxy_cookie_path / "/; Secure";
proxy_buffering off; proxy_buffering off;
proxy_request_buffering off; proxy_request_buffering off;
} }
location /service/notifications { location /service/notifications {
return 404; return 404;
} }
} }
server { server {
listen 8080; listen 8080;
#server_name harbordomain.com; #server_name harbordomain.com;
return 301 https://$host$request_uri; return 301 https://$host$request_uri;
} }
} }
{{- end }} {{- end }}
{{- if ne .Values.expose.type "ingress" }} {{- if ne .Values.expose.type "ingress" }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ template "harbor.nginx" . }} name: {{ template "harbor.nginx" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: nginx component: nginx
spec: spec:
replicas: {{ .Values.nginx.replicas }} replicas: {{ .Values.nginx.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: nginx component: nginx
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: nginx component: nginx
annotations: annotations:
{{- if not .Values.expose.tls.enabled }} {{- if not .Values.expose.tls.enabled }}
checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-http.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-http.yaml") . | sha256sum }}
{{- else }} {{- else }}
checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-https.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-https.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }} {{- if eq (include "harbor.autoGenCertForNginx" .) "true" }}
checksum/secret: {{ include (print $.Template.BasePath "/nginx/secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/nginx/secret.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.nginx.podAnnotations }} {{- if .Values.nginx.podAnnotations }}
{{ toYaml .Values.nginx.podAnnotations | indent 8 }} {{ toYaml .Values.nginx.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
{{- if .Values.nginx.serviceAccountName }} {{- if .Values.nginx.serviceAccountName }}
serviceAccountName: {{ .Values.nginx.serviceAccountName }} serviceAccountName: {{ .Values.nginx.serviceAccountName }}
{{- end }} {{- end }}
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: nginx - name: nginx
{{- if contains "/" .Values.nginx.image.repository }} {{- if contains "/" .Values.nginx.image.repository }}
image: "{{ .Values.nginx.image.repository }}" image: "{{ .Values.nginx.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.nginx.image.hub | default .Values.global.hub }}/{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.nginx.image.hub | default .Values.global.hub }}/{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
{{- $_ := set . "scheme" "HTTP" -}} {{- $_ := set . "scheme" "HTTP" -}}
{{- $_ := set . "port" "8080" -}} {{- $_ := set . "port" "8080" -}}
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
{{- $_ := set . "scheme" "HTTPS" -}} {{- $_ := set . "scheme" "HTTPS" -}}
{{- $_ := set . "port" "8443" -}} {{- $_ := set . "port" "8443" -}}
{{- end }} {{- end }}
livenessProbe: livenessProbe:
httpGet: httpGet:
scheme: {{ .scheme }} scheme: {{ .scheme }}
path: / path: /
port: {{ .port }} port: {{ .port }}
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
scheme: {{ .scheme }} scheme: {{ .scheme }}
path: / path: /
port: {{ .port }} port: {{ .port }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.nginx.resources }} {{- if .Values.nginx.resources }}
resources: resources:
{{ toYaml .Values.nginx.resources | indent 10 }} {{ toYaml .Values.nginx.resources | indent 10 }}
{{- end }} {{- end }}
ports: ports:
- containerPort: 8080 - containerPort: 8080
- containerPort: 8443 - containerPort: 8443
- containerPort: 4443 - containerPort: 4443
volumeMounts: volumeMounts:
- name: config - name: config
mountPath: /etc/nginx/nginx.conf mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf subPath: nginx.conf
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: certificate - name: certificate
mountPath: /etc/nginx/cert mountPath: /etc/nginx/cert
{{- end }} {{- end }}
volumes: volumes:
- name: config - name: config
configMap: configMap:
name: {{ template "harbor.nginx" . }} name: {{ template "harbor.nginx" . }}
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: certificate - name: certificate
secret: secret:
secretName: {{ template "harbor.tlsSecretForNginx" . }} secretName: {{ template "harbor.tlsSecretForNginx" . }}
{{- end }} {{- end }}
{{- with .Values.nginx.nodeSelector }} {{- with .Values.nginx.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.nginx.affinity }} {{- with .Values.nginx.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.nginx.tolerations }} {{- with .Values.nginx.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }} {{- if eq (include "harbor.autoGenCertForNginx" .) "true" }}
{{- $ca := genCA "harbor-ca" 365 }} {{- $ca := genCA "harbor-ca" 365 }}
{{- $cn := (required "The \"expose.tls.auto.commonName\" is required!" .Values.expose.tls.auto.commonName) }} {{- $cn := (required "The \"expose.tls.auto.commonName\" is required!" .Values.expose.tls.auto.commonName) }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: {{ template "harbor.nginx" . }} name: {{ template "harbor.nginx" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: 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 }} {{- 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 }} {{- $cert := genSignedCert $cn (list $cn) nil 365 $ca }}
tls.crt: {{ $cert.Cert | b64enc | quote }} tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }} tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- else }} {{- else }}
{{- $cert := genSignedCert $cn nil (list $cn) 365 $ca }} {{- $cert := genSignedCert $cn nil (list $cn) 365 $ca }}
tls.crt: {{ $cert.Cert | b64enc | quote }} tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }} tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if or (eq .Values.expose.type "clusterIP") (eq .Values.expose.type "nodePort") (eq .Values.expose.type "loadBalancer") }} {{- if or (eq .Values.expose.type "clusterIP") (eq .Values.expose.type "nodePort") (eq .Values.expose.type "loadBalancer") }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
{{- if eq .Values.expose.type "clusterIP" }} {{- if eq .Values.expose.type "clusterIP" }}
{{- $clusterIP := .Values.expose.clusterIP }} {{- $clusterIP := .Values.expose.clusterIP }}
name: {{ $clusterIP.name }} name: {{ $clusterIP.name }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
type: ClusterIP type: ClusterIP
ports: ports:
- name: http - name: http
port: {{ $clusterIP.ports.httpPort }} port: {{ $clusterIP.ports.httpPort }}
targetPort: 8080 targetPort: 8080
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: https - name: https
port: {{ $clusterIP.ports.httpsPort }} port: {{ $clusterIP.ports.httpsPort }}
targetPort: 8443 targetPort: 8443
{{- end }} {{- end }}
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
- name: notary - name: notary
port: {{ $clusterIP.ports.notaryPort }} port: {{ $clusterIP.ports.notaryPort }}
targetPort: 4443 targetPort: 4443
{{- end }} {{- end }}
{{- else if eq .Values.expose.type "nodePort" }} {{- else if eq .Values.expose.type "nodePort" }}
{{- $nodePort := .Values.expose.nodePort }} {{- $nodePort := .Values.expose.nodePort }}
name: {{ $nodePort.name }} name: {{ $nodePort.name }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
type: NodePort type: NodePort
ports: ports:
- name: http - name: http
port: {{ $nodePort.ports.http.port }} port: {{ $nodePort.ports.http.port }}
targetPort: 8080 targetPort: 8080
{{- if $nodePort.ports.http.nodePort }} {{- if $nodePort.ports.http.nodePort }}
nodePort: {{ $nodePort.ports.http.nodePort }} nodePort: {{ $nodePort.ports.http.nodePort }}
{{- end }} {{- end }}
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: https - name: https
port: {{ $nodePort.ports.https.port }} port: {{ $nodePort.ports.https.port }}
targetPort: 8443 targetPort: 8443
{{- if $nodePort.ports.https.nodePort }} {{- if $nodePort.ports.https.nodePort }}
nodePort: {{ $nodePort.ports.https.nodePort }} nodePort: {{ $nodePort.ports.https.nodePort }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
- name: notary - name: notary
port: {{ $nodePort.ports.notary.port }} port: {{ $nodePort.ports.notary.port }}
targetPort: 4443 targetPort: 4443
{{- if $nodePort.ports.notary.nodePort }} {{- if $nodePort.ports.notary.nodePort }}
nodePort: {{ $nodePort.ports.notary.nodePort }} nodePort: {{ $nodePort.ports.notary.nodePort }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- else if eq .Values.expose.type "loadBalancer" }} {{- else if eq .Values.expose.type "loadBalancer" }}
{{- $loadBalancer := .Values.expose.loadBalancer }} {{- $loadBalancer := .Values.expose.loadBalancer }}
name: {{ $loadBalancer.name }} name: {{ $loadBalancer.name }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
{{- with $loadBalancer.annotations }} {{- with $loadBalancer.annotations }}
annotations: annotations:
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
spec: spec:
type: LoadBalancer type: LoadBalancer
{{- with $loadBalancer.sourceRanges }} {{- with $loadBalancer.sourceRanges }}
loadBalancerSourceRanges: loadBalancerSourceRanges:
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
{{- if $loadBalancer.IP }} {{- if $loadBalancer.IP }}
loadBalancerIP: {{ $loadBalancer.IP }} loadBalancerIP: {{ $loadBalancer.IP }}
{{- end }} {{- end }}
ports: ports:
- name: http - name: http
port: {{ $loadBalancer.ports.httpPort }} port: {{ $loadBalancer.ports.httpPort }}
targetPort: 8080 targetPort: 8080
{{- if .Values.expose.tls.enabled }} {{- if .Values.expose.tls.enabled }}
- name: https - name: https
port: {{ $loadBalancer.ports.httpsPort }} port: {{ $loadBalancer.ports.httpsPort }}
targetPort: 8443 targetPort: 8443
{{- end }} {{- end }}
{{- if .Values.notary.enabled }} {{- if .Values.notary.enabled }}
- name: notary - name: notary
port: {{ $loadBalancer.ports.notaryPort }} port: {{ $loadBalancer.ports.notaryPort }}
targetPort: 4443 targetPort: 4443
{{- end }} {{- end }}
{{- end }} {{- end }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: nginx component: nginx
{{- end }} {{- end }}
{{- if and .Values.notary.enabled }} {{- if and .Values.notary.enabled }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: {{ template "harbor.notary-server" . }} name: {{ template "harbor.notary-server" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: notary component: notary
type: Opaque type: Opaque
data: data:
{{- if not .Values.notary.secretName }} {{- if not .Values.notary.secretName }}
{{- $ca := genCA "harbor-notary-ca" 365 }} {{- $ca := genCA "harbor-notary-ca" 365 }}
{{- $cert := genSignedCert (include "harbor.notary-signer" .) nil nil 365 $ca }} {{- $cert := genSignedCert (include "harbor.notary-signer" .) nil nil 365 $ca }}
ca.crt: {{ $ca.Cert | b64enc | quote }} ca.crt: {{ $ca.Cert | b64enc | quote }}
tls.crt: {{ $cert.Cert | b64enc | quote }} tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }} tls.key: {{ $cert.Key | b64enc | quote }}
{{- end }} {{- end }}
server.json: {{ tpl (.Files.Get "conf/notary-server.json") . | b64enc }} server.json: {{ tpl (.Files.Get "conf/notary-server.json") . | b64enc }}
signer.json: {{ tpl (.Files.Get "conf/notary-signer.json") . | b64enc }} signer.json: {{ tpl (.Files.Get "conf/notary-signer.json") . | b64enc }}
{{- end }} {{- end }}
{{ if .Values.notary.enabled }} {{ if .Values.notary.enabled }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ template "harbor.notary-server" . }} name: {{ template "harbor.notary-server" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: notary-server component: notary-server
spec: spec:
replicas: {{ .Values.notary.server.replicas }} replicas: {{ .Values.notary.server.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: notary-server component: notary-server
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: notary-server component: notary-server
annotations: annotations:
checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if .Values.notary.podAnnotations }} {{- if .Values.notary.podAnnotations }}
{{ toYaml .Values.notary.podAnnotations | indent 8 }} {{ toYaml .Values.notary.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- if .Values.notary.server.serviceAccountName }} {{- if .Values.notary.server.serviceAccountName }}
serviceAccountName: {{ .Values.notary.server.serviceAccountName }} serviceAccountName: {{ .Values.notary.server.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: notary-server - name: notary-server
{{- if contains "/" .Values.notary.server.image.repository }} {{- if contains "/" .Values.notary.server.image.repository }}
image: "{{ .Values.notary.server.image.repository }}" image: "{{ .Values.notary.server.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.notary.server.image.hub | default .Values.global.hub }}/{{ .Values.notary.server.image.repository }}:{{ .Values.notary.server.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.notary.server.image.hub | default .Values.global.hub }}/{{ .Values.notary.server.image.repository }}:{{ .Values.notary.server.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
{{- if .Values.notary.server.resources }} {{- if .Values.notary.server.resources }}
resources: resources:
{{ toYaml .Values.notary.server.resources | indent 10 }} {{ toYaml .Values.notary.server.resources | indent 10 }}
{{- end }} {{- end }}
env: env:
- name: MIGRATIONS_PATH - name: MIGRATIONS_PATH
value: migrations/server/postgresql value: migrations/server/postgresql
- name: DB_URL - name: DB_URL
value: {{ template "harbor.database.notaryServer" . }} value: {{ template "harbor.database.notaryServer" . }}
volumeMounts: volumeMounts:
- name: config - name: config
mountPath: /etc/notary/server-config.postgres.json mountPath: /etc/notary/server-config.postgres.json
subPath: server.json subPath: server.json
- name: token-service-certificate - name: token-service-certificate
mountPath: /root.crt mountPath: /root.crt
subPath: tls.crt subPath: tls.crt
- name: signer-certificate - name: signer-certificate
mountPath: /etc/ssl/notary/ca.crt mountPath: /etc/ssl/notary/ca.crt
subPath: ca.crt subPath: ca.crt
volumes: volumes:
- name: config - name: config
secret: secret:
secretName: "{{ template "harbor.notary-server" . }}" secretName: "{{ template "harbor.notary-server" . }}"
- name: token-service-certificate - name: token-service-certificate
secret: secret:
{{- if .Values.core.secretName }} {{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }} secretName: {{ .Values.core.secretName }}
{{- else }} {{- else }}
secretName: {{ template "harbor.core" . }} secretName: {{ template "harbor.core" . }}
{{- end }} {{- end }}
- name: signer-certificate - name: signer-certificate
secret: secret:
{{- if .Values.notary.secretName }} {{- if .Values.notary.secretName }}
secretName: {{ .Values.notary.secretName }} secretName: {{ .Values.notary.secretName }}
{{- else }} {{- else }}
secretName: {{ template "harbor.notary-server" . }} secretName: {{ template "harbor.notary-server" . }}
{{- end }} {{- end }}
{{- with .Values.notary.nodeSelector }} {{- with .Values.notary.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.notary.affinity }} {{- with .Values.notary.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.notary.tolerations }} {{- with .Values.notary.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{ end }} {{ end }}
{{ if .Values.notary.enabled }} {{ if .Values.notary.enabled }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: {{ template "harbor.notary-signer" . }} name: {{ template "harbor.notary-signer" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: notary-signer component: notary-signer
spec: spec:
replicas: {{ .Values.notary.signer.replicas }} replicas: {{ .Values.notary.signer.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: notary-signer component: notary-signer
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: notary-signer component: notary-signer
annotations: annotations:
checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/notary/notary-secret.yaml") . | sha256sum }}
spec: spec:
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- if .Values.notary.signer.serviceAccountName }} {{- if .Values.notary.signer.serviceAccountName }}
serviceAccountName: {{ .Values.notary.signer.serviceAccountName }} serviceAccountName: {{ .Values.notary.signer.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: notary-signer - name: notary-signer
{{- if contains "/" .Values.notary.signer.image.repository }} {{- if contains "/" .Values.notary.signer.image.repository }}
image: "{{ .Values.notary.signer.image.repository }}" image: "{{ .Values.notary.signer.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.notary.signer.image.hub | default .Values.global.hub }}/{{ .Values.notary.signer.image.repository }}:{{ .Values.notary.signer.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.notary.signer.image.hub | default .Values.global.hub }}/{{ .Values.notary.signer.image.repository }}:{{ .Values.notary.signer.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
{{- if .Values.notary.signer.resources }} {{- if .Values.notary.signer.resources }}
resources: resources:
{{ toYaml .Values.notary.signer.resources | indent 10 }} {{ toYaml .Values.notary.signer.resources | indent 10 }}
{{- end }} {{- end }}
env: env:
- name: MIGRATIONS_PATH - name: MIGRATIONS_PATH
value: migrations/signer/postgresql value: migrations/signer/postgresql
- name: DB_URL - name: DB_URL
value: {{ template "harbor.database.notarySigner" . }} value: {{ template "harbor.database.notarySigner" . }}
- name: NOTARY_SIGNER_DEFAULTALIAS - name: NOTARY_SIGNER_DEFAULTALIAS
value: defaultalias value: defaultalias
volumeMounts: volumeMounts:
- name: config - name: config
mountPath: /etc/notary/signer-config.postgres.json mountPath: /etc/notary/signer-config.postgres.json
subPath: signer.json subPath: signer.json
- name: signer-certificate - name: signer-certificate
mountPath: /etc/ssl/notary/tls.crt mountPath: /etc/ssl/notary/tls.crt
subPath: tls.crt subPath: tls.crt
- name: signer-certificate - name: signer-certificate
mountPath: /etc/ssl/notary/tls.key mountPath: /etc/ssl/notary/tls.key
subPath: tls.key subPath: tls.key
volumes: volumes:
- name: config - name: config
secret: secret:
secretName: "{{ template "harbor.notary-server" . }}" secretName: "{{ template "harbor.notary-server" . }}"
- name: signer-certificate - name: signer-certificate
secret: secret:
{{- if .Values.notary.secretName }} {{- if .Values.notary.secretName }}
secretName: {{ .Values.notary.secretName }} secretName: {{ .Values.notary.secretName }}
{{- else }} {{- else }}
secretName: {{ template "harbor.notary-server" . }} secretName: {{ template "harbor.notary-server" . }}
{{- end }} {{- end }}
{{- with .Values.notary.nodeSelector }} {{- with .Values.notary.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.notary.affinity }} {{- with .Values.notary.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.notary.tolerations }} {{- with .Values.notary.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{ end }} {{ end }}
{{ if .Values.notary.enabled }} {{ if .Values.notary.enabled }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: {{ template "harbor.notary-server" . }} name: {{ template "harbor.notary-server" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
{{- if (eq .Values.expose.ingress.controller "gce") }} {{- if (eq .Values.expose.ingress.controller "gce") }}
type: NodePort type: NodePort
{{- end }} {{- end }}
ports: ports:
- port: 4443 - port: 4443
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: notary-server component: notary-server
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: {{ template "harbor.notary-signer" . }} name: {{ template "harbor.notary-signer" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: 7899 - port: 7899
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: notary-signer component: notary-signer
{{ end }} {{ end }}
\ No newline at end of file
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: "{{ template "harbor.portal" . }}" name: "{{ template "harbor.portal" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
nginx.conf: |+ nginx.conf: |+
worker_processes auto; worker_processes auto;
pid /tmp/nginx.pid; pid /tmp/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
} }
http { http {
client_body_temp_path /tmp/client_body_temp; client_body_temp_path /tmp/client_body_temp;
proxy_temp_path /tmp/proxy_temp; proxy_temp_path /tmp/proxy_temp;
fastcgi_temp_path /tmp/fastcgi_temp; fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp; uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp; scgi_temp_path /tmp/scgi_temp;
server { server {
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
listen {{ template "harbor.portal.containerPort" . }} ssl; listen {{ template "harbor.portal.containerPort" . }} ssl;
# SSL # SSL
ssl_certificate /etc/harbor/ssl/portal/tls.crt; ssl_certificate /etc/harbor/ssl/portal/tls.crt;
ssl_certificate_key /etc/harbor/ssl/portal/tls.key; ssl_certificate_key /etc/harbor/ssl/portal/tls.key;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.2; ssl_protocols TLSv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on; ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m; ssl_session_cache shared:SSL:10m;
{{- else }} {{- else }}
listen {{ template "harbor.portal.containerPort" . }}; listen {{ template "harbor.portal.containerPort" . }};
{{- end }} {{- end }}
server_name localhost; server_name localhost;
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html index.htm; index index.html index.htm;
include /etc/nginx/mime.types; include /etc/nginx/mime.types;
gzip on; gzip on;
gzip_min_length 1000; gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth; gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
location = /index.html { location = /index.html {
add_header Cache-Control "no-store, no-cache, must-revalidate"; add_header Cache-Control "no-store, no-cache, must-revalidate";
} }
} }
} }
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: "{{ template "harbor.portal" . }}" name: "{{ template "harbor.portal" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: portal component: portal
spec: spec:
replicas: {{ .Values.portal.replicas }} replicas: {{ .Values.portal.replicas }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: portal component: portal
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: portal component: portal
annotations: annotations:
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
checksum/tls: {{ include (print $.Template.BasePath "/portal/tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/portal/tls.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.portal.podAnnotations }} {{- if .Values.portal.podAnnotations }}
{{ toYaml .Values.portal.podAnnotations | indent 8 }} {{ toYaml .Values.portal.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
{{- if .Values.portal.serviceAccountName }} {{- if .Values.portal.serviceAccountName }}
serviceAccountName: {{ .Values.portal.serviceAccountName }} serviceAccountName: {{ .Values.portal.serviceAccountName }}
{{- end }} {{- end }}
containers: containers:
- name: portal - name: portal
{{- if contains "/" .Values.portal.image.repository }} {{- if contains "/" .Values.portal.image.repository }}
image: "{{ .Values.portal.image.repository }}" image: "{{ .Values.portal.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.portal.image.hub | default .Values.global.hub }}/{{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.portal.image.hub | default .Values.global.hub }}/{{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
{{- if .Values.portal.resources }} {{- if .Values.portal.resources }}
resources: resources:
{{ toYaml .Values.portal.resources | indent 10 }} {{ toYaml .Values.portal.resources | indent 10 }}
{{- end }} {{- end }}
livenessProbe: livenessProbe:
httpGet: httpGet:
path: / path: /
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.portal.containerPort" . }} port: {{ template "harbor.portal.containerPort" . }}
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: / path: /
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.portal.containerPort" . }} port: {{ template "harbor.portal.containerPort" . }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
ports: ports:
- containerPort: {{ template "harbor.portal.containerPort" . }} - containerPort: {{ template "harbor.portal.containerPort" . }}
volumeMounts: volumeMounts:
- name: portal-config - name: portal-config
mountPath: /etc/nginx/nginx.conf mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf subPath: nginx.conf
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: portal-internal-certs - name: portal-internal-certs
mountPath: /etc/harbor/ssl/portal mountPath: /etc/harbor/ssl/portal
{{- end }} {{- end }}
volumes: volumes:
- name: portal-config - name: portal-config
configMap: configMap:
name: "{{ template "harbor.portal" . }}" name: "{{ template "harbor.portal" . }}"
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: portal-internal-certs - name: portal-internal-certs
secret: secret:
secretName: {{ template "harbor.internalTLS.portal.secretName" . }} secretName: {{ template "harbor.internalTLS.portal.secretName" . }}
{{- end }} {{- end }}
{{- with .Values.portal.nodeSelector }} {{- with .Values.portal.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.portal.affinity }} {{- with .Values.portal.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.portal.tolerations }} {{- with .Values.portal.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: "{{ template "harbor.portal" . }}" name: "{{ template "harbor.portal" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: {{ template "harbor.portal.servicePort" . }} - port: {{ template "harbor.portal.servicePort" . }}
targetPort: {{ template "harbor.portal.containerPort" . }} targetPort: {{ template "harbor.portal.containerPort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: portal component: portal
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }} {{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.portal.secretName" . }}" name: "{{ template "harbor.internalTLS.portal.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.portal.crt\" is required!" .Values.internalTLS.portal.crt) | b64enc | quote }} tls.crt: {{ (required "The \"internalTLS.portal.crt\" is required!" .Values.internalTLS.portal.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.portal.key\" is required!" .Values.internalTLS.portal.key) | b64enc | quote }} tls.key: {{ (required "The \"internalTLS.portal.key\" is required!" .Values.internalTLS.portal.key) | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if eq .Values.redis.type "internal" -}} {{- if eq .Values.redis.type "internal" -}}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: {{ template "harbor.redis" . }} name: {{ template "harbor.redis" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- port: 6379 - port: 6379
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: redis component: redis
{{- end -}} {{- end -}}
\ No newline at end of file
{{- if eq .Values.redis.type "internal" -}} {{- if eq .Values.redis.type "internal" -}}
{{- $redis := .Values.persistence.persistentVolumeClaim.redis -}} {{- $redis := .Values.persistence.persistentVolumeClaim.redis -}}
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
metadata: metadata:
name: {{ template "harbor.redis" . }} name: {{ template "harbor.redis" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: redis component: redis
spec: spec:
replicas: 1 replicas: 1
serviceName: {{ template "harbor.redis" . }} serviceName: {{ template "harbor.redis" . }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: redis component: redis
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: redis component: redis
{{- if .Values.redis.podAnnotations }} {{- if .Values.redis.podAnnotations }}
annotations: annotations:
{{ toYaml .Values.redis.podAnnotations | indent 8 }} {{ toYaml .Values.redis.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
fsGroup: 999 fsGroup: 999
{{- if .Values.redis.internal.serviceAccountName }} {{- if .Values.redis.internal.serviceAccountName }}
serviceAccountName: {{ .Values.redis.internal.serviceAccountName }} serviceAccountName: {{ .Values.redis.internal.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: redis - name: redis
{{- if contains "/" .Values.redis.internal.image.repository }} {{- if contains "/" .Values.redis.internal.image.repository }}
image: "{{ .Values.redis.internal.image.repository }}" image: "{{ .Values.redis.internal.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.redis.internal.image.hub | default .Values.global.hub }}/{{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.redis.internal.image.hub | default .Values.global.hub }}/{{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
tcpSocket: tcpSocket:
port: 6379 port: 6379
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
tcpSocket: tcpSocket:
port: 6379 port: 6379
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.redis.internal.resources }} {{- if .Values.redis.internal.resources }}
resources: resources:
{{ toYaml .Values.redis.internal.resources | indent 10 }} {{ toYaml .Values.redis.internal.resources | indent 10 }}
{{- end }} {{- end }}
volumeMounts: volumeMounts:
- name: data - name: data
mountPath: /var/lib/redis mountPath: /var/lib/redis
subPath: {{ $redis.subPath }} subPath: {{ $redis.subPath }}
{{- if not .Values.persistence.enabled }} {{- if not .Values.persistence.enabled }}
volumes: volumes:
- name: data - name: data
emptyDir: {} emptyDir: {}
{{- else if $redis.existingClaim }} {{- else if $redis.existingClaim }}
volumes: volumes:
- name: data - name: data
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ $redis.existingClaim }} claimName: {{ $redis.existingClaim }}
{{- end -}} {{- end -}}
{{- with .Values.redis.internal.nodeSelector }} {{- with .Values.redis.internal.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.redis.internal.affinity }} {{- with .Values.redis.internal.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.redis.internal.tolerations }} {{- with .Values.redis.internal.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (not $redis.existingClaim) }} {{- if and .Values.persistence.enabled (not $redis.existingClaim) }}
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: data name: data
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
spec: spec:
accessModes: [{{ $redis.accessMode | quote }}] accessModes: [{{ $redis.accessMode | quote }}]
{{- if $redis.storageClass }} {{- if $redis.storageClass }}
{{- if (eq "-" $redis.storageClass) }} {{- if (eq "-" $redis.storageClass) }}
storageClassName: "" storageClassName: ""
{{- else }} {{- else }}
storageClassName: "{{ $redis.storageClass }}" storageClassName: "{{ $redis.storageClass }}"
{{- end }} {{- end }}
{{- end }} {{- end }}
resources: resources:
requests: requests:
storage: {{ $redis.size | quote }} storage: {{ $redis.size | quote }}
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: "{{ template "harbor.registry" . }}" name: "{{ template "harbor.registry" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
data: data:
config.yml: |+ config.yml: |+
version: 0.1 version: 0.1
log: log:
{{- if eq .Values.logLevel "warning" }} {{- if eq .Values.logLevel "warning" }}
level: warn level: warn
{{- else if eq .Values.logLevel "fatal" }} {{- else if eq .Values.logLevel "fatal" }}
level: error level: error
{{- else }} {{- else }}
level: {{ .Values.logLevel }} level: {{ .Values.logLevel }}
{{- end }} {{- end }}
fields: fields:
service: registry service: registry
storage: storage:
{{- $storage := .Values.persistence.imageChartStorage }} {{- $storage := .Values.persistence.imageChartStorage }}
{{- $type := $storage.type }} {{- $type := $storage.type }}
{{- if eq $type "filesystem" }} {{- if eq $type "filesystem" }}
filesystem: filesystem:
rootdirectory: {{ $storage.filesystem.rootdirectory }} rootdirectory: {{ $storage.filesystem.rootdirectory }}
{{- if $storage.filesystem.maxthreads }} {{- if $storage.filesystem.maxthreads }}
maxthreads: {{ $storage.filesystem.maxthreads }} maxthreads: {{ $storage.filesystem.maxthreads }}
{{- end }} {{- end }}
{{- else if eq $type "azure" }} {{- else if eq $type "azure" }}
azure: azure:
accountname: {{ $storage.azure.accountname }} accountname: {{ $storage.azure.accountname }}
container: {{ $storage.azure.container }} container: {{ $storage.azure.container }}
{{- if $storage.azure.realm }} {{- if $storage.azure.realm }}
realm: {{ $storage.azure.realm }} realm: {{ $storage.azure.realm }}
{{- end }} {{- end }}
{{- else if eq $type "gcs" }} {{- else if eq $type "gcs" }}
gcs: gcs:
bucket: {{ $storage.gcs.bucket }} bucket: {{ $storage.gcs.bucket }}
keyfile: /etc/registry/gcs-key.json keyfile: /etc/registry/gcs-key.json
{{- if $storage.gcs.rootdirectory }} {{- if $storage.gcs.rootdirectory }}
rootdirectory: {{ $storage.gcs.rootdirectory }} rootdirectory: {{ $storage.gcs.rootdirectory }}
{{- end }} {{- end }}
{{- if $storage.gcs.chunksize }} {{- if $storage.gcs.chunksize }}
chunksize: {{ $storage.gcs.chunksize }} chunksize: {{ $storage.gcs.chunksize }}
{{- end }} {{- end }}
{{- else if eq $type "s3" }} {{- else if eq $type "s3" }}
s3: s3:
region: {{ $storage.s3.region }} region: {{ $storage.s3.region }}
bucket: {{ $storage.s3.bucket }} bucket: {{ $storage.s3.bucket }}
{{- if $storage.s3.regionendpoint }} {{- if $storage.s3.regionendpoint }}
regionendpoint: {{ $storage.s3.regionendpoint }} regionendpoint: {{ $storage.s3.regionendpoint }}
{{- end }} {{- end }}
{{- if $storage.s3.encrypt }} {{- if $storage.s3.encrypt }}
encrypt: {{ $storage.s3.encrypt }} encrypt: {{ $storage.s3.encrypt }}
{{- end }} {{- end }}
{{- if $storage.s3.keyid }} {{- if $storage.s3.keyid }}
keyid: {{ $storage.s3.keyid }} keyid: {{ $storage.s3.keyid }}
{{- end }} {{- end }}
{{- if $storage.s3.secure }} {{- if $storage.s3.secure }}
secure: {{ $storage.s3.secure }} secure: {{ $storage.s3.secure }}
{{- end }} {{- end }}
{{- if and $storage.s3.secure $storage.s3.skipverify }} {{- if and $storage.s3.secure $storage.s3.skipverify }}
skipverify: {{ $storage.s3.skipverify }} skipverify: {{ $storage.s3.skipverify }}
{{- end }} {{- end }}
{{- if $storage.s3.v4auth }} {{- if $storage.s3.v4auth }}
v4auth: {{ $storage.s3.v4auth }} v4auth: {{ $storage.s3.v4auth }}
{{- end }} {{- end }}
{{- if $storage.s3.chunksize }} {{- if $storage.s3.chunksize }}
chunksize: {{ $storage.s3.chunksize }} chunksize: {{ $storage.s3.chunksize }}
{{- end }} {{- end }}
{{- if $storage.s3.rootdirectory }} {{- if $storage.s3.rootdirectory }}
rootdirectory: {{ $storage.s3.rootdirectory }} rootdirectory: {{ $storage.s3.rootdirectory }}
{{- end }} {{- end }}
{{- if $storage.s3.storageclass }} {{- if $storage.s3.storageclass }}
storageclass: {{ $storage.s3.storageclass }} storageclass: {{ $storage.s3.storageclass }}
{{- end }} {{- end }}
{{- if $storage.s3.multipartcopychunksize }} {{- if $storage.s3.multipartcopychunksize }}
multipartcopychunksize: {{ $storage.s3.multipartcopychunksize }} multipartcopychunksize: {{ $storage.s3.multipartcopychunksize }}
{{- end }} {{- end }}
{{- if $storage.s3.multipartcopymaxconcurrency }} {{- if $storage.s3.multipartcopymaxconcurrency }}
multipartcopymaxconcurrency: {{ $storage.s3.multipartcopymaxconcurrency }} multipartcopymaxconcurrency: {{ $storage.s3.multipartcopymaxconcurrency }}
{{- end }} {{- end }}
{{- if $storage.s3.multipartcopythresholdsize }} {{- if $storage.s3.multipartcopythresholdsize }}
multipartcopythresholdsize: {{ $storage.s3.multipartcopythresholdsize }} multipartcopythresholdsize: {{ $storage.s3.multipartcopythresholdsize }}
{{- end }} {{- end }}
{{- else if eq $type "swift" }} {{- else if eq $type "swift" }}
swift: swift:
authurl: {{ $storage.swift.authurl }} authurl: {{ $storage.swift.authurl }}
username: {{ $storage.swift.username }} username: {{ $storage.swift.username }}
container: {{ $storage.swift.container }} container: {{ $storage.swift.container }}
{{- if $storage.swift.region }} {{- if $storage.swift.region }}
region: {{ $storage.swift.region }} region: {{ $storage.swift.region }}
{{- end }} {{- end }}
{{- if $storage.swift.tenant }} {{- if $storage.swift.tenant }}
tenant: {{ $storage.swift.tenant }} tenant: {{ $storage.swift.tenant }}
{{- end }} {{- end }}
{{- if $storage.swift.tenantid }} {{- if $storage.swift.tenantid }}
tenantid: {{ $storage.swift.tenantid }} tenantid: {{ $storage.swift.tenantid }}
{{- end }} {{- end }}
{{- if $storage.swift.domain }} {{- if $storage.swift.domain }}
domain: {{ $storage.swift.domain }} domain: {{ $storage.swift.domain }}
{{- end }} {{- end }}
{{- if $storage.swift.domainid }} {{- if $storage.swift.domainid }}
domainid: {{ $storage.swift.domainid }} domainid: {{ $storage.swift.domainid }}
{{- end }} {{- end }}
{{- if $storage.swift.trustid }} {{- if $storage.swift.trustid }}
trustid: {{ $storage.swift.trustid }} trustid: {{ $storage.swift.trustid }}
{{- end }} {{- end }}
{{- if $storage.swift.insecureskipverify }} {{- if $storage.swift.insecureskipverify }}
insecureskipverify: {{ $storage.swift.insecureskipverify }} insecureskipverify: {{ $storage.swift.insecureskipverify }}
{{- end }} {{- end }}
{{- if $storage.swift.chunksize }} {{- if $storage.swift.chunksize }}
chunksize: {{ $storage.swift.chunksize }} chunksize: {{ $storage.swift.chunksize }}
{{- end }} {{- end }}
{{- if $storage.swift.prefix }} {{- if $storage.swift.prefix }}
prefix: {{ $storage.swift.prefix }} prefix: {{ $storage.swift.prefix }}
{{- end }} {{- end }}
{{- if $storage.swift.authversion }} {{- if $storage.swift.authversion }}
authversion: {{ $storage.swift.authversion }} authversion: {{ $storage.swift.authversion }}
{{- end }} {{- end }}
{{- if $storage.swift.endpointtype }} {{- if $storage.swift.endpointtype }}
endpointtype: {{ $storage.swift.endpointtype }} endpointtype: {{ $storage.swift.endpointtype }}
{{- end }} {{- end }}
{{- if $storage.swift.tempurlcontainerkey }} {{- if $storage.swift.tempurlcontainerkey }}
tempurlcontainerkey: {{ $storage.swift.tempurlcontainerkey }} tempurlcontainerkey: {{ $storage.swift.tempurlcontainerkey }}
{{- end }} {{- end }}
{{- if $storage.swift.tempurlmethods }} {{- if $storage.swift.tempurlmethods }}
tempurlmethods: {{ $storage.swift.tempurlmethods }} tempurlmethods: {{ $storage.swift.tempurlmethods }}
{{- end }} {{- end }}
{{- else if eq $type "oss" }} {{- else if eq $type "oss" }}
oss: oss:
accesskeyid: {{ $storage.oss.accesskeyid }} accesskeyid: {{ $storage.oss.accesskeyid }}
region: {{ $storage.oss.region }} region: {{ $storage.oss.region }}
bucket: {{ $storage.oss.bucket }} bucket: {{ $storage.oss.bucket }}
{{- if $storage.oss.endpoint }} {{- if $storage.oss.endpoint }}
endpoint: {{ $storage.oss.endpoint }} endpoint: {{ $storage.oss.endpoint }}
{{- end }} {{- end }}
{{- if $storage.oss.internal }} {{- if $storage.oss.internal }}
internal: {{ $storage.oss.internal }} internal: {{ $storage.oss.internal }}
{{- end }} {{- end }}
{{- if $storage.oss.encrypt }} {{- if $storage.oss.encrypt }}
encrypt: {{ $storage.oss.encrypt }} encrypt: {{ $storage.oss.encrypt }}
{{- end }} {{- end }}
{{- if $storage.oss.secure }} {{- if $storage.oss.secure }}
secure: {{ $storage.oss.secure }} secure: {{ $storage.oss.secure }}
{{- end }} {{- end }}
{{- if $storage.oss.chunksize }} {{- if $storage.oss.chunksize }}
chunksize: {{ $storage.oss.chunksize }} chunksize: {{ $storage.oss.chunksize }}
{{- end }} {{- end }}
{{- if $storage.oss.rootdirectory }} {{- if $storage.oss.rootdirectory }}
rootdirectory: {{ $storage.oss.rootdirectory }} rootdirectory: {{ $storage.oss.rootdirectory }}
{{- end }} {{- end }}
{{- end }} {{- end }}
cache: cache:
layerinfo: redis layerinfo: redis
maintenance: maintenance:
uploadpurging: uploadpurging:
enabled: false enabled: false
delete: delete:
enabled: true enabled: true
redirect: redirect:
disable: {{ $storage.disableredirect }} disable: {{ $storage.disableredirect }}
redis: redis:
addr: {{ template "harbor.redis.addr" . }} addr: {{ template "harbor.redis.addr" . }}
{{- if eq "redis+sentinel" (include "harbor.redis.scheme" .) }} {{- if eq "redis+sentinel" (include "harbor.redis.scheme" .) }}
sentinelMasterSet: {{ template "harbor.redis.masterSet" . }} sentinelMasterSet: {{ template "harbor.redis.masterSet" . }}
{{- end }} {{- end }}
db: {{ template "harbor.redis.dbForRegistry" . }} db: {{ template "harbor.redis.dbForRegistry" . }}
password: {{ template "harbor.redis.password" . }} password: {{ template "harbor.redis.password" . }}
readtimeout: 10s readtimeout: 10s
writetimeout: 10s writetimeout: 10s
dialtimeout: 10s dialtimeout: 10s
http: http:
addr: :{{ template "harbor.registry.containerPort" . }} addr: :{{ template "harbor.registry.containerPort" . }}
relativeurls: {{ .Values.registry.relativeurls }} relativeurls: {{ .Values.registry.relativeurls }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
tls: tls:
certificate: /etc/harbor/ssl/registry/tls.crt certificate: /etc/harbor/ssl/registry/tls.crt
key: /etc/harbor/ssl/registry/tls.key key: /etc/harbor/ssl/registry/tls.key
minimumtls: tls1.2 minimumtls: tls1.2
{{- end }} {{- end }}
# set via environment variable # set via environment variable
# secret: placeholder # secret: placeholder
debug: debug:
addr: localhost:5001 addr: localhost:5001
auth: auth:
htpasswd: htpasswd:
realm: harbor-registry-basic-realm realm: harbor-registry-basic-realm
path: /etc/registry/passwd path: /etc/registry/passwd
validation: validation:
disabled: true disabled: true
compatibility: compatibility:
schema1: schema1:
enabled: true enabled: true
{{- if .Values.registry.middleware.enabled }} {{- if .Values.registry.middleware.enabled }}
{{- $middleware := .Values.registry.middleware }} {{- $middleware := .Values.registry.middleware }}
{{- $middlewareType := $middleware.type }} {{- $middlewareType := $middleware.type }}
{{- if eq $middlewareType "cloudFront" }} {{- if eq $middlewareType "cloudFront" }}
middleware: middleware:
storage: storage:
- name: cloudfront - name: cloudfront
options: options:
baseurl: {{ $middleware.cloudFront.baseurl }} baseurl: {{ $middleware.cloudFront.baseurl }}
privatekey: /etc/registry/pk.pem privatekey: /etc/registry/pk.pem
keypairid: {{ $middleware.cloudFront.keypairid }} keypairid: {{ $middleware.cloudFront.keypairid }}
duration: {{ $middleware.cloudFront.duration }} duration: {{ $middleware.cloudFront.duration }}
ipfilteredby: {{ $middleware.cloudFront.ipfilteredby }} ipfilteredby: {{ $middleware.cloudFront.ipfilteredby }}
{{- end }} {{- end }}
{{- end }} {{- end }}
ctl-config.yml: |+ ctl-config.yml: |+
--- ---
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
protocol: "https" protocol: "https"
port: 8443 port: 8443
https_config: https_config:
cert: "/etc/harbor/ssl/registry/tls.crt" cert: "/etc/harbor/ssl/registry/tls.crt"
key: "/etc/harbor/ssl/registry/tls.key" key: "/etc/harbor/ssl/registry/tls.key"
{{- else }} {{- else }}
protocol: "http" protocol: "http"
port: 8080 port: 8080
{{- end }} {{- end }}
log_level: {{ .Values.logLevel }} log_level: {{ .Values.logLevel }}
registry_config: "/etc/registry/config.yml" registry_config: "/etc/registry/config.yml"
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: "{{ template "harbor.registry" . }}" name: "{{ template "harbor.registry" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: registry component: registry
spec: spec:
replicas: {{ .Values.registry.replicas }} replicas: {{ .Values.registry.replicas }}
strategy: strategy:
type: {{ .Values.updateStrategy.type }} type: {{ .Values.updateStrategy.type }}
{{- if eq .Values.updateStrategy.type "Recreate" }} {{- if eq .Values.updateStrategy.type "Recreate" }}
rollingUpdate: null rollingUpdate: null
{{- end }} {{- end }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: registry component: registry
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: registry component: registry
annotations: annotations:
checksum/configmap: {{ include (print $.Template.BasePath "/registry/registry-cm.yaml") . | sha256sum }} checksum/configmap: {{ include (print $.Template.BasePath "/registry/registry-cm.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/registry/registry-secret.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-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
checksum/tls: {{ include (print $.Template.BasePath "/registry/registry-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/registry/registry-tls.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.registry.podAnnotations }} {{- if .Values.registry.podAnnotations }}
{{ toYaml .Values.registry.podAnnotations | indent 8 }} {{ toYaml .Values.registry.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
securityContext: securityContext:
fsGroup: 10000 fsGroup: 10000
{{- if .Values.registry.serviceAccountName }} {{- if .Values.registry.serviceAccountName }}
serviceAccountName: {{ .Values.registry.serviceAccountName }} serviceAccountName: {{ .Values.registry.serviceAccountName }}
{{- end -}} {{- end -}}
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
containers: containers:
- name: registry - name: registry
{{- if contains "/" .Values.registry.registry.image.repository }} {{- if contains "/" .Values.registry.registry.image.repository }}
image: "{{ .Values.registry.registry.image.repository }}" image: "{{ .Values.registry.registry.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.registry.registry.image.hub | default .Values.global.hub }}/{{ .Values.registry.registry.image.repository }}:{{ .Values.registry.registry.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.registry.registry.image.hub | default .Values.global.hub }}/{{ .Values.registry.registry.image.repository }}:{{ .Values.registry.registry.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: / path: /
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.registry.containerPort" . }} port: {{ template "harbor.registry.containerPort" . }}
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: / path: /
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.registry.containerPort" . }} port: {{ template "harbor.registry.containerPort" . }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.registry.registry.resources }} {{- if .Values.registry.registry.resources }}
resources: resources:
{{ toYaml .Values.registry.registry.resources | indent 10 }} {{ toYaml .Values.registry.registry.resources | indent 10 }}
{{- end }} {{- end }}
args: ["serve", "/etc/registry/config.yml"] args: ["serve", "/etc/registry/config.yml"]
envFrom: envFrom:
- secretRef: - secretRef:
name: "{{ template "harbor.registry" . }}" name: "{{ template "harbor.registry" . }}"
env: env:
{{- if has "registry" .Values.proxy.components }} {{- if has "registry" .Values.proxy.components }}
- name: HTTP_PROXY - name: HTTP_PROXY
value: "{{ .Values.proxy.httpProxy }}" value: "{{ .Values.proxy.httpProxy }}"
- name: HTTPS_PROXY - name: HTTPS_PROXY
value: "{{ .Values.proxy.httpsProxy }}" value: "{{ .Values.proxy.httpsProxy }}"
- name: NO_PROXY - name: NO_PROXY
value: "{{ template "harbor.noProxy" . }}" value: "{{ template "harbor.noProxy" . }}"
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED - name: INTERNAL_TLS_ENABLED
value: "true" value: "true"
- name: INTERNAL_TLS_KEY_PATH - name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/registry/tls.key value: /etc/harbor/ssl/registry/tls.key
- name: INTERNAL_TLS_CERT_PATH - name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/registry/tls.crt value: /etc/harbor/ssl/registry/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH - name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/registry/ca.crt value: /etc/harbor/ssl/registry/ca.crt
{{- end }} {{- end }}
ports: ports:
- containerPort: {{ template "harbor.registry.containerPort" . }} - containerPort: {{ template "harbor.registry.containerPort" . }}
- containerPort: 5001 - containerPort: 5001
volumeMounts: volumeMounts:
- name: registry-data - name: registry-data
mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }} mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }}
subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }} subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }}
- name: registry-root-certificate - name: registry-root-certificate
mountPath: /etc/registry/root.crt mountPath: /etc/registry/root.crt
subPath: tls.crt subPath: tls.crt
- name: registry-htpasswd - name: registry-htpasswd
mountPath: /etc/registry/passwd mountPath: /etc/registry/passwd
subPath: passwd subPath: passwd
- name: registry-config - name: registry-config
mountPath: /etc/registry/config.yml mountPath: /etc/registry/config.yml
subPath: config.yml subPath: config.yml
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: registry-internal-certs - name: registry-internal-certs
mountPath: /etc/harbor/ssl/registry mountPath: /etc/harbor/ssl/registry
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }} {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }}
- name: gcs-key - name: gcs-key
mountPath: /etc/registry/gcs-key.json mountPath: /etc/registry/gcs-key.json
subPath: gcs-key.json subPath: gcs-key.json
{{- end }} {{- end }}
{{- if .Values.persistence.imageChartStorage.caBundleSecretName }} {{- if .Values.persistence.imageChartStorage.caBundleSecretName }}
- name: storage-service-ca - name: storage-service-ca
mountPath: /harbor_cust_cert/custom-ca-bundle.crt mountPath: /harbor_cust_cert/custom-ca-bundle.crt
subPath: ca.crt subPath: ca.crt
{{- end }} {{- end }}
{{- if .Values.registry.middleware.enabled }} {{- if .Values.registry.middleware.enabled }}
{{- if eq .Values.registry.middleware.type "cloudFront" }} {{- if eq .Values.registry.middleware.type "cloudFront" }}
- name: cloudfront-key - name: cloudfront-key
mountPath: /etc/registry/pk.pem mountPath: /etc/registry/pk.pem
subPath: pk.pem subPath: pk.pem
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }} {{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }} {{- end }}
- name: registryctl - name: registryctl
{{- if contains "/" .Values.registry.controller.image.repository }} {{- if contains "/" .Values.registry.controller.image.repository }}
image: "{{ .Values.registry.controller.image.repository }}" image: "{{ .Values.registry.controller.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.registry.controller.image.hub | default .Values.global.hub }}/{{ .Values.registry.controller.image.repository }}:{{ .Values.registry.controller.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.registry.controller.image.hub | default .Values.global.hub }}/{{ .Values.registry.controller.image.repository }}:{{ .Values.registry.controller.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.global.imagePullPolicy }}"
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /api/health path: /api/health
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.registryctl.containerPort" . }} port: {{ template "harbor.registryctl.containerPort" . }}
initialDelaySeconds: 300 initialDelaySeconds: 300
periodSeconds: 10 periodSeconds: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /api/health path: /api/health
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
port: {{ template "harbor.registryctl.containerPort" . }} port: {{ template "harbor.registryctl.containerPort" . }}
initialDelaySeconds: 1 initialDelaySeconds: 1
periodSeconds: 10 periodSeconds: 10
{{- if .Values.registry.controller.resources }} {{- if .Values.registry.controller.resources }}
resources: resources:
{{ toYaml .Values.registry.controller.resources | indent 10 }} {{ toYaml .Values.registry.controller.resources | indent 10 }}
{{- end }} {{- end }}
envFrom: envFrom:
- secretRef: - secretRef:
name: "{{ template "harbor.registry" . }}" name: "{{ template "harbor.registry" . }}"
env: env:
- name: CORE_SECRET - name: CORE_SECRET
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.core" . }} name: {{ template "harbor.core" . }}
key: secret key: secret
- name: JOBSERVICE_SECRET - name: JOBSERVICE_SECRET
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.jobservice" . }} name: {{ template "harbor.jobservice" . }}
key: JOBSERVICE_SECRET key: JOBSERVICE_SECRET
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED - name: INTERNAL_TLS_ENABLED
value: "true" value: "true"
- name: INTERNAL_TLS_KEY_PATH - name: INTERNAL_TLS_KEY_PATH
value: /etc/harbor/ssl/registry/tls.key value: /etc/harbor/ssl/registry/tls.key
- name: INTERNAL_TLS_CERT_PATH - name: INTERNAL_TLS_CERT_PATH
value: /etc/harbor/ssl/registry/tls.crt value: /etc/harbor/ssl/registry/tls.crt
- name: INTERNAL_TLS_TRUST_CA_PATH - name: INTERNAL_TLS_TRUST_CA_PATH
value: /etc/harbor/ssl/registry/ca.crt value: /etc/harbor/ssl/registry/ca.crt
{{- end }} {{- end }}
ports: ports:
- containerPort: {{ template "harbor.registryctl.containerPort" . }} - containerPort: {{ template "harbor.registryctl.containerPort" . }}
volumeMounts: volumeMounts:
- name: registry-data - name: registry-data
mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }} mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }}
subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }} subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }}
- name: registry-config - name: registry-config
mountPath: /etc/registry/config.yml mountPath: /etc/registry/config.yml
subPath: config.yml subPath: config.yml
- name: registry-config - name: registry-config
mountPath: /etc/registryctl/config.yml mountPath: /etc/registryctl/config.yml
subPath: ctl-config.yml subPath: ctl-config.yml
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: registry-internal-certs - name: registry-internal-certs
mountPath: /etc/harbor/ssl/registry mountPath: /etc/harbor/ssl/registry
{{- end }} {{- end }}
{{- if .Values.persistence.imageChartStorage.caBundleSecretName }} {{- if .Values.persistence.imageChartStorage.caBundleSecretName }}
- name: storage-service-ca - name: storage-service-ca
mountPath: /harbor_cust_cert/custom-ca-bundle.crt mountPath: /harbor_cust_cert/custom-ca-bundle.crt
subPath: ca.crt subPath: ca.crt
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }} {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }}
- name: gcs-key - name: gcs-key
mountPath: /etc/registry/gcs-key.json mountPath: /etc/registry/gcs-key.json
subPath: gcs-key.json subPath: gcs-key.json
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 8 }} {{ include "harbor.caBundleVolumeMount" . | indent 8 }}
{{- end }} {{- end }}
volumes: volumes:
- name: registry-htpasswd - name: registry-htpasswd
secret: secret:
secretName: {{ template "harbor.registry" . }} secretName: {{ template "harbor.registry" . }}
items: items:
- key: REGISTRY_HTPASSWD - key: REGISTRY_HTPASSWD
path: passwd path: passwd
- name: registry-root-certificate - name: registry-root-certificate
secret: secret:
{{- if .Values.core.secretName }} {{- if .Values.core.secretName }}
secretName: {{ .Values.core.secretName }} secretName: {{ .Values.core.secretName }}
{{- else }} {{- else }}
secretName: {{ template "harbor.core" . }} secretName: {{ template "harbor.core" . }}
{{- end }} {{- end }}
- name: registry-config - name: registry-config
configMap: configMap:
name: "{{ template "harbor.registry" . }}" name: "{{ template "harbor.registry" . }}"
- name: registry-data - name: registry-data
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "filesystem") }} {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "filesystem") }}
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ .Values.persistence.persistentVolumeClaim.registry.existingClaim | default (include "harbor.registry" .) }} claimName: {{ .Values.persistence.persistentVolumeClaim.registry.existingClaim | default (include "harbor.registry" .) }}
{{- else }} {{- else }}
emptyDir: {} emptyDir: {}
{{- end }} {{- end }}
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: registry-internal-certs - name: registry-internal-certs
secret: secret:
secretName: {{ template "harbor.internalTLS.registry.secretName" . }} secretName: {{ template "harbor.internalTLS.registry.secretName" . }}
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }} {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs") }}
- name: gcs-key - name: gcs-key
secret: secret:
secretName: {{ template "harbor.registry" . }} secretName: {{ template "harbor.registry" . }}
items: items:
- key: GCS_KEY_DATA - key: GCS_KEY_DATA
path: gcs-key.json path: gcs-key.json
{{- end }} {{- end }}
{{- if .Values.persistence.imageChartStorage.caBundleSecretName }} {{- if .Values.persistence.imageChartStorage.caBundleSecretName }}
- name: storage-service-ca - name: storage-service-ca
secret: secret:
secretName: {{ .Values.persistence.imageChartStorage.caBundleSecretName }} secretName: {{ .Values.persistence.imageChartStorage.caBundleSecretName }}
{{- end }} {{- end }}
{{- if .Values.registry.middleware.enabled }} {{- if .Values.registry.middleware.enabled }}
{{- if eq .Values.registry.middleware.type "cloudFront" }} {{- if eq .Values.registry.middleware.type "cloudFront" }}
- name: cloudfront-key - name: cloudfront-key
secret: secret:
secretName: {{ .Values.registry.middleware.cloudFront.privateKeySecret }} secretName: {{ .Values.registry.middleware.cloudFront.privateKeySecret }}
items: items:
- key: CLOUDFRONT_KEY_DATA - key: CLOUDFRONT_KEY_DATA
path: pk.pem path: pk.pem
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }} {{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }} {{- end }}
{{- with .Values.registry.nodeSelector }} {{- with .Values.registry.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.registry.affinity }} {{- with .Values.registry.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.registry.tolerations }} {{- with .Values.registry.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- if .Values.persistence.enabled }} {{- if .Values.persistence.enabled }}
{{- $registry := .Values.persistence.persistentVolumeClaim.registry -}} {{- $registry := .Values.persistence.persistentVolumeClaim.registry -}}
{{- if and (not $registry.existingClaim) (eq .Values.persistence.imageChartStorage.type "filesystem") }} {{- if and (not $registry.existingClaim) (eq .Values.persistence.imageChartStorage.type "filesystem") }}
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
apiVersion: v1 apiVersion: v1
metadata: metadata:
name: {{ template "harbor.registry" . }} name: {{ template "harbor.registry" . }}
{{- if eq .Values.persistence.resourcePolicy "keep" }} {{- if eq .Values.persistence.resourcePolicy "keep" }}
annotations: annotations:
helm.sh/resource-policy: keep helm.sh/resource-policy: keep
{{- end }} {{- end }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: registry component: registry
spec: spec:
accessModes: accessModes:
- {{ $registry.accessMode }} - {{ $registry.accessMode }}
resources: resources:
requests: requests:
storage: {{ $registry.size }} storage: {{ $registry.size }}
{{- if $registry.storageClass }} {{- if $registry.storageClass }}
{{- if eq "-" $registry.storageClass }} {{- if eq "-" $registry.storageClass }}
storageClassName: "" storageClassName: ""
{{- else }} {{- else }}
storageClassName: {{ $registry.storageClass }} storageClassName: {{ $registry.storageClass }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.registry" . }}" name: "{{ template "harbor.registry" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
REGISTRY_HTPASSWD: {{ .Values.registry.credentials.htpasswd | b64enc | quote }} REGISTRY_HTPASSWD: {{ .Values.registry.credentials.htpasswd | b64enc | quote }}
REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (randAlphaNum 16) | b64enc | quote }} REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (randAlphaNum 16) | b64enc | quote }}
REGISTRY_REDIS_PASSWORD: {{ (include "harbor.redis.password" .) | b64enc | quote }} REGISTRY_REDIS_PASSWORD: {{ (include "harbor.redis.password" .) | b64enc | quote }}
{{- $storage := .Values.persistence.imageChartStorage }} {{- $storage := .Values.persistence.imageChartStorage }}
{{- $type := $storage.type }} {{- $type := $storage.type }}
{{- if eq $type "azure" }} {{- if eq $type "azure" }}
REGISTRY_STORAGE_AZURE_ACCOUNTKEY: {{ $storage.azure.accountkey | b64enc | quote }} REGISTRY_STORAGE_AZURE_ACCOUNTKEY: {{ $storage.azure.accountkey | b64enc | quote }}
{{- else if eq $type "gcs" }} {{- else if eq $type "gcs" }}
GCS_KEY_DATA: {{ $storage.gcs.encodedkey | quote }} GCS_KEY_DATA: {{ $storage.gcs.encodedkey | quote }}
{{- else if eq $type "s3" }} {{- else if eq $type "s3" }}
{{- if $storage.s3.accesskey }} {{- if $storage.s3.accesskey }}
REGISTRY_STORAGE_S3_ACCESSKEY: {{ $storage.s3.accesskey | b64enc | quote }} REGISTRY_STORAGE_S3_ACCESSKEY: {{ $storage.s3.accesskey | b64enc | quote }}
{{- end }} {{- end }}
{{- if $storage.s3.secretkey }} {{- if $storage.s3.secretkey }}
REGISTRY_STORAGE_S3_SECRETKEY: {{ $storage.s3.secretkey | b64enc | quote }} REGISTRY_STORAGE_S3_SECRETKEY: {{ $storage.s3.secretkey | b64enc | quote }}
{{- end }} {{- end }}
{{- else if eq $type "swift" }} {{- else if eq $type "swift" }}
REGISTRY_STORAGE_SWIFT_PASSWORD: {{ $storage.swift.password | b64enc | quote }} REGISTRY_STORAGE_SWIFT_PASSWORD: {{ $storage.swift.password | b64enc | quote }}
{{- if $storage.swift.secretkey }} {{- if $storage.swift.secretkey }}
REGISTRY_STORAGE_SWIFT_SECRETKEY: {{ $storage.swift.secretkey | b64enc | quote }} REGISTRY_STORAGE_SWIFT_SECRETKEY: {{ $storage.swift.secretkey | b64enc | quote }}
{{- end }} {{- end }}
{{- if $storage.swift.accesskey }} {{- if $storage.swift.accesskey }}
REGISTRY_STORAGE_SWIFT_ACCESSKEY: {{ $storage.swift.accesskey | b64enc | quote }} REGISTRY_STORAGE_SWIFT_ACCESSKEY: {{ $storage.swift.accesskey | b64enc | quote }}
{{- end }} {{- end }}
{{- else if eq $type "oss" }} {{- else if eq $type "oss" }}
REGISTRY_STORAGE_OSS_ACCESSKEYSECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }} REGISTRY_STORAGE_OSS_ACCESSKEYSECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }}
{{- end }} {{- end }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: "{{ template "harbor.registry" . }}" name: "{{ template "harbor.registry" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- name: registry - name: registry
port: {{ template "harbor.registry.servicePort" . }} port: {{ template "harbor.registry.servicePort" . }}
- name: controller - name: controller
port: {{ template "harbor.registryctl.servicePort" . }} port: {{ template "harbor.registryctl.servicePort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: registry component: registry
\ No newline at end of file
{{- if and .Values.internalTLS.enabled }} {{- if and .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }} {{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.registry.secretName" . }}" name: "{{ template "harbor.internalTLS.registry.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.registry.crt\" is required!" .Values.internalTLS.registry.crt) | b64enc | quote }} tls.crt: {{ (required "The \"internalTLS.registry.crt\" is required!" .Values.internalTLS.registry.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.registry.key\" is required!" .Values.internalTLS.registry.key) | b64enc | quote }} tls.key: {{ (required "The \"internalTLS.registry.key\" is required!" .Values.internalTLS.registry.key) | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
\ No newline at end of file
{{- if .Values.trivy.enabled }} {{- if .Values.trivy.enabled }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: {{ template "harbor.trivy" . }} name: {{ template "harbor.trivy" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: Opaque type: Opaque
data: data:
redisURL: {{ include "harbor.redis.urlForTrivy" . | b64enc }} redisURL: {{ include "harbor.redis.urlForTrivy" . | b64enc }}
gitHubToken: {{ .Values.trivy.gitHubToken | default "" | b64enc | quote }} gitHubToken: {{ .Values.trivy.gitHubToken | default "" | b64enc | quote }}
{{- end }} {{- end }}
{{- if .Values.trivy.enabled }} {{- if .Values.trivy.enabled }}
{{- $trivy := .Values.persistence.persistentVolumeClaim.trivy }} {{- $trivy := .Values.persistence.persistentVolumeClaim.trivy }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
metadata: metadata:
name: {{ template "harbor.trivy" . }} name: {{ template "harbor.trivy" . }}
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
component: trivy component: trivy
spec: spec:
replicas: {{ .Values.trivy.replicas }} replicas: {{ .Values.trivy.replicas }}
serviceName: {{ template "harbor.trivy" . }} serviceName: {{ template "harbor.trivy" . }}
selector: selector:
matchLabels: matchLabels:
{{ include "harbor.matchLabels" . | indent 6 }} {{ include "harbor.matchLabels" . | indent 6 }}
component: trivy component: trivy
template: template:
metadata: metadata:
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
component: trivy component: trivy
annotations: annotations:
checksum/secret: {{ include (print $.Template.BasePath "/trivy/trivy-secret.yaml") . | sha256sum }} checksum/secret: {{ include (print $.Template.BasePath "/trivy/trivy-secret.yaml") . | sha256sum }}
{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
checksum/tls: {{ include (print $.Template.BasePath "/trivy/trivy-tls.yaml") . | sha256sum }} checksum/tls: {{ include (print $.Template.BasePath "/trivy/trivy-tls.yaml") . | sha256sum }}
{{- end }} {{- end }}
{{- if .Values.trivy.podAnnotations }} {{- if .Values.trivy.podAnnotations }}
{{ toYaml .Values.trivy.podAnnotations | indent 8 }} {{ toYaml .Values.trivy.podAnnotations | indent 8 }}
{{- end }} {{- end }}
spec: spec:
{{- with .Values.imagePullSecrets }} {{- with .Values.imagePullSecrets }}
imagePullSecrets: imagePullSecrets:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
{{- if .Values.trivy.serviceAccountName }} {{- if .Values.trivy.serviceAccountName }}
serviceAccountName: {{ .Values.trivy.serviceAccountName }} serviceAccountName: {{ .Values.trivy.serviceAccountName }}
{{- end }} {{- end }}
securityContext: securityContext:
runAsNonRoot: true runAsNonRoot: true
runAsUser: 10000 runAsUser: 10000
fsGroup: 10000 fsGroup: 10000
automountServiceAccountToken: false automountServiceAccountToken: false
containers: containers:
- name: trivy - name: trivy
{{- if contains "/" .Values.trivy.image.repository }} {{- if contains "/" .Values.trivy.image.repository }}
image: "{{ .Values.trivy.image.repository }}" image: "{{ .Values.trivy.image.repository }}"
{{- else }} {{- else }}
image: "{{ .Values.trivy.image.hub | default .Values.global.hub }}/{{ .Values.trivy.image.repository }}:{{ .Values.trivy.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}" image: "{{ .Values.trivy.image.hub | default .Values.global.hub }}/{{ .Values.trivy.image.repository }}:{{ .Values.trivy.image.tag | default .Values.global.tag }}{{ template ".beagle.imageArch" . }}"
{{- end }} {{- end }}
imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}" imagePullPolicy: "{{ .Values.imagePullPolicy | default .Values.global.imagePullPolicy }}"
securityContext: securityContext:
privileged: false privileged: false
allowPrivilegeEscalation: false allowPrivilegeEscalation: false
env: env:
{{- if has "trivy" .Values.proxy.components }} {{- if has "trivy" .Values.proxy.components }}
- name: HTTP_PROXY - name: HTTP_PROXY
value: "{{ .Values.proxy.httpProxy }}" value: "{{ .Values.proxy.httpProxy }}"
- name: HTTPS_PROXY - name: HTTPS_PROXY
value: "{{ .Values.proxy.httpsProxy }}" value: "{{ .Values.proxy.httpsProxy }}"
- name: NO_PROXY - name: NO_PROXY
value: "{{ template "harbor.noProxy" . }}" value: "{{ template "harbor.noProxy" . }}"
{{- end }} {{- end }}
- name: "SCANNER_LOG_LEVEL" - name: "SCANNER_LOG_LEVEL"
value: {{ .Values.logLevel | quote }} value: {{ .Values.logLevel | quote }}
- name: "SCANNER_TRIVY_CACHE_DIR" - name: "SCANNER_TRIVY_CACHE_DIR"
value: "/home/scanner/.cache/trivy" value: "/home/scanner/.cache/trivy"
- name: "SCANNER_TRIVY_REPORTS_DIR" - name: "SCANNER_TRIVY_REPORTS_DIR"
value: "/home/scanner/.cache/reports" value: "/home/scanner/.cache/reports"
- name: "SCANNER_TRIVY_DEBUG_MODE" - name: "SCANNER_TRIVY_DEBUG_MODE"
value: {{ .Values.trivy.debugMode | quote }} value: {{ .Values.trivy.debugMode | quote }}
- name: "SCANNER_TRIVY_VULN_TYPE" - name: "SCANNER_TRIVY_VULN_TYPE"
value: {{ .Values.trivy.vulnType | quote }} value: {{ .Values.trivy.vulnType | quote }}
- name: "SCANNER_TRIVY_GITHUB_TOKEN" - name: "SCANNER_TRIVY_GITHUB_TOKEN"
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.trivy" . }} name: {{ template "harbor.trivy" . }}
key: gitHubToken key: gitHubToken
- name: "SCANNER_TRIVY_SEVERITY" - name: "SCANNER_TRIVY_SEVERITY"
value: {{ .Values.trivy.severity | quote }} value: {{ .Values.trivy.severity | quote }}
- name: "SCANNER_TRIVY_IGNORE_UNFIXED" - name: "SCANNER_TRIVY_IGNORE_UNFIXED"
value: {{ .Values.trivy.ignoreUnfixed | default false | quote }} value: {{ .Values.trivy.ignoreUnfixed | default false | quote }}
- name: "SCANNER_TRIVY_SKIP_UPDATE" - name: "SCANNER_TRIVY_SKIP_UPDATE"
value: {{ .Values.trivy.skipUpdate | default false | quote }} value: {{ .Values.trivy.skipUpdate | default false | quote }}
- name: "SCANNER_TRIVY_INSECURE" - name: "SCANNER_TRIVY_INSECURE"
value: {{ .Values.trivy.insecure | default false | quote }} value: {{ .Values.trivy.insecure | default false | quote }}
- name: SCANNER_API_SERVER_ADDR - name: SCANNER_API_SERVER_ADDR
value: ":{{ template "harbor.trivy.containerPort" . }}" value: ":{{ template "harbor.trivy.containerPort" . }}"
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: INTERNAL_TLS_ENABLED - name: INTERNAL_TLS_ENABLED
value: "true" value: "true"
- name: SCANNER_API_SERVER_TLS_KEY - name: SCANNER_API_SERVER_TLS_KEY
value: /etc/harbor/ssl/trivy/tls.key value: /etc/harbor/ssl/trivy/tls.key
- name: SCANNER_API_SERVER_TLS_CERTIFICATE - name: SCANNER_API_SERVER_TLS_CERTIFICATE
value: /etc/harbor/ssl/trivy/tls.crt value: /etc/harbor/ssl/trivy/tls.crt
{{- end }} {{- end }}
- name: "SCANNER_REDIS_URL" - name: "SCANNER_REDIS_URL"
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.trivy" . }} name: {{ template "harbor.trivy" . }}
key: redisURL key: redisURL
- name: "SCANNER_STORE_REDIS_URL" - name: "SCANNER_STORE_REDIS_URL"
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.trivy" . }} name: {{ template "harbor.trivy" . }}
key: redisURL key: redisURL
- name: "SCANNER_JOB_QUEUE_REDIS_URL" - name: "SCANNER_JOB_QUEUE_REDIS_URL"
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "harbor.trivy" . }} name: {{ template "harbor.trivy" . }}
key: redisURL key: redisURL
ports: ports:
- name: api-server - name: api-server
containerPort: {{ template "harbor.trivy.containerPort" . }} containerPort: {{ template "harbor.trivy.containerPort" . }}
volumeMounts: volumeMounts:
- name: data - name: data
mountPath: /home/scanner/.cache mountPath: /home/scanner/.cache
subPath: {{ .Values.persistence.persistentVolumeClaim.trivy.subPath }} subPath: {{ .Values.persistence.persistentVolumeClaim.trivy.subPath }}
readOnly: false readOnly: false
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: trivy-internal-certs - name: trivy-internal-certs
mountPath: /etc/harbor/ssl/trivy mountPath: /etc/harbor/ssl/trivy
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolumeMount" . | indent 10 }} {{ include "harbor.caBundleVolumeMount" . | indent 10 }}
{{- end }} {{- end }}
livenessProbe: livenessProbe:
httpGet: httpGet:
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
path: /probe/healthy path: /probe/healthy
port: api-server port: api-server
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 10 periodSeconds: 10
successThreshold: 1 successThreshold: 1
failureThreshold: 10 failureThreshold: 10
readinessProbe: readinessProbe:
httpGet: httpGet:
scheme: {{ include "harbor.component.scheme" . | upper }} scheme: {{ include "harbor.component.scheme" . | upper }}
path: /probe/ready path: /probe/ready
port: api-server port: api-server
initialDelaySeconds: 5 initialDelaySeconds: 5
periodSeconds: 10 periodSeconds: 10
successThreshold: 1 successThreshold: 1
failureThreshold: 3 failureThreshold: 3
resources: resources:
{{ toYaml .Values.trivy.resources | indent 12 }} {{ toYaml .Values.trivy.resources | indent 12 }}
{{- if or (or .Values.internalTLS.enabled .Values.caBundleSecretName) (or (not .Values.persistence.enabled) $trivy.existingClaim) }} {{- if or (or .Values.internalTLS.enabled .Values.caBundleSecretName) (or (not .Values.persistence.enabled) $trivy.existingClaim) }}
volumes: volumes:
{{- if .Values.internalTLS.enabled }} {{- if .Values.internalTLS.enabled }}
- name: trivy-internal-certs - name: trivy-internal-certs
secret: secret:
secretName: {{ template "harbor.internalTLS.trivy.secretName" . }} secretName: {{ template "harbor.internalTLS.trivy.secretName" . }}
{{- end }} {{- end }}
{{- if .Values.caBundleSecretName }} {{- if .Values.caBundleSecretName }}
{{ include "harbor.caBundleVolume" . | indent 6 }} {{ include "harbor.caBundleVolume" . | indent 6 }}
{{- end }} {{- end }}
{{- if not .Values.persistence.enabled }} {{- if not .Values.persistence.enabled }}
- name: "data" - name: "data"
emptyDir: {} emptyDir: {}
{{- else if $trivy.existingClaim }} {{- else if $trivy.existingClaim }}
- name: "data" - name: "data"
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ $trivy.existingClaim }} claimName: {{ $trivy.existingClaim }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- with .Values.trivy.nodeSelector }} {{- with .Values.trivy.nodeSelector }}
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.trivy.affinity }} {{- with .Values.trivy.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- with .Values.trivy.tolerations }} {{- with .Values.trivy.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- if and .Values.persistence.enabled (not $trivy.existingClaim) }} {{- if and .Values.persistence.enabled (not $trivy.existingClaim) }}
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: data name: data
labels: labels:
{{ include "harbor.labels" . | indent 8 }} {{ include "harbor.labels" . | indent 8 }}
spec: spec:
accessModes: [{{ $trivy.accessMode | quote }}] accessModes: [{{ $trivy.accessMode | quote }}]
{{- if $trivy.storageClass }} {{- if $trivy.storageClass }}
{{- if (eq "-" $trivy.storageClass) }} {{- if (eq "-" $trivy.storageClass) }}
storageClassName: "" storageClassName: ""
{{- else }} {{- else }}
storageClassName: "{{ $trivy.storageClass }}" storageClassName: "{{ $trivy.storageClass }}"
{{- end }} {{- end }}
{{- end }} {{- end }}
resources: resources:
requests: requests:
storage: {{ $trivy.size | quote }} storage: {{ $trivy.size | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{ if .Values.trivy.enabled }} {{ if .Values.trivy.enabled }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: "{{ template "harbor.trivy" . }}" name: "{{ template "harbor.trivy" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
spec: spec:
ports: ports:
- name: api-server - name: api-server
protocol: TCP protocol: TCP
port: {{ template "harbor.trivy.servicePort" . }} port: {{ template "harbor.trivy.servicePort" . }}
selector: selector:
{{ include "harbor.matchLabels" . | indent 4 }} {{ include "harbor.matchLabels" . | indent 4 }}
component: trivy component: trivy
{{ end }} {{ end }}
{{- if and .Values.trivy.enabled .Values.internalTLS.enabled }} {{- if and .Values.trivy.enabled .Values.internalTLS.enabled }}
{{- if eq .Values.internalTLS.certSource "manual" }} {{- if eq .Values.internalTLS.certSource "manual" }}
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: "{{ template "harbor.internalTLS.trivy.secretName" . }}" name: "{{ template "harbor.internalTLS.trivy.secretName" . }}"
labels: labels:
{{ include "harbor.labels" . | indent 4 }} {{ include "harbor.labels" . | indent 4 }}
type: kubernetes.io/tls type: kubernetes.io/tls
data: data:
ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }}
tls.crt: {{ (required "The \"internalTLS.trivy.crt\" is required!" .Values.internalTLS.trivy.crt) | b64enc | quote }} tls.crt: {{ (required "The \"internalTLS.trivy.crt\" is required!" .Values.internalTLS.trivy.crt) | b64enc | quote }}
tls.key: {{ (required "The \"internalTLS.trivy.key\" is required!" .Values.internalTLS.trivy.key) | b64enc | quote }} tls.key: {{ (required "The \"internalTLS.trivy.key\" is required!" .Values.internalTLS.trivy.key) | b64enc | quote }}
{{- end }} {{- end }}
{{- end }} {{- end }}
module github.com/goharbor/harbor-helm module github.com/goharbor/harbor-helm
go 1.13 go 1.13
require ( require (
github.com/gruntwork-io/terratest v0.28.2 github.com/gruntwork-io/terratest v0.28.2
github.com/stretchr/testify v1.6.0 github.com/stretchr/testify v1.6.0
k8s.io/api v0.18.3 k8s.io/api v0.18.3
) )
This source diff could not be displayed because it is too large. You can view the blob instead.
#/bin/bash #/bin/bash
set -e set -e
version=${HELM_VERSION} version=${HELM_VERSION}
if [ "$version" = "2" ] if [ "$version" = "2" ]
then then
dist="helm-v2.8.0-linux-amd64.tar.gz" dist="helm-v2.8.0-linux-amd64.tar.gz"
# as the helm v3 removes tiller, here appends the "-c" option # as the helm v3 removes tiller, here appends the "-c" option
# to args only when running helm v2 to display the client version # to args only when running helm v2 to display the client version
version_args="-c" version_args="-c"
elif [ "$version" = "3" ] elif [ "$version" = "3" ]
then then
# the "template" command doesn't work for helm beta3: # the "template" command doesn't work for helm beta3:
# https://github.com/helm/helm/issues/6404, use the beta2 for now # https://github.com/helm/helm/issues/6404, use the beta2 for now
dist="helm-v3.0.0-beta.2-linux-amd64.tar.gz" dist="helm-v3.0.0-beta.2-linux-amd64.tar.gz"
else else
echo "unsupported helm version: $version" echo "unsupported helm version: $version"
exit 1 exit 1
fi fi
wget -O /tmp/${dist} https://get.helm.sh/${dist} wget -O /tmp/${dist} https://get.helm.sh/${dist}
tar -zxvf /tmp/${dist} -C /tmp/ tar -zxvf /tmp/${dist} -C /tmp/
sudo mv /tmp/linux-amd64/helm /usr/local/bin/helm sudo mv /tmp/linux-amd64/helm /usr/local/bin/helm
helm version $version_args helm version $version_args
echo "Helm installed" echo "Helm installed"
\ No newline at end of file
package integration package integration
import ( import (
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
"time" "time"
"github.com/gruntwork-io/terratest/modules/helm" "github.com/gruntwork-io/terratest/modules/helm"
"github.com/gruntwork-io/terratest/modules/k8s" "github.com/gruntwork-io/terratest/modules/k8s"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
var ( var (
client = &http.Client{ client = &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, InsecureSkipVerify: true,
}, },
}, },
} }
) )
func NewBaseTestSuite(values map[string]string) BaseTestSuite { func NewBaseTestSuite(values map[string]string) BaseTestSuite {
if values == nil { if values == nil {
values = map[string]string{} values = map[string]string{}
} }
return BaseTestSuite{ return BaseTestSuite{
Options: &helm.Options{ Options: &helm.Options{
KubectlOptions: &k8s.KubectlOptions{ KubectlOptions: &k8s.KubectlOptions{
Namespace: "default", Namespace: "default",
}, },
SetValues: values, SetValues: values,
}, },
ReleaseName: "harbor", ReleaseName: "harbor",
URL: values["externalURL"], URL: values["externalURL"],
} }
} }
type BaseTestSuite struct { type BaseTestSuite struct {
suite.Suite suite.Suite
Options *helm.Options Options *helm.Options
ReleaseName string ReleaseName string
URL string // the external URL of Harbor URL string // the external URL of Harbor
} }
func (b *BaseTestSuite) SetupSuite() { func (b *BaseTestSuite) SetupSuite() {
helm.Install(b.T(), b.Options, "../..", b.ReleaseName) helm.Install(b.T(), b.Options, "../..", b.ReleaseName)
b.waitUntilHealthy(b.URL) b.waitUntilHealthy(b.URL)
} }
type overallStatus struct { type overallStatus struct {
Status string `json:"status"` Status string `json:"status"`
Components []*componentStatus `json:"components"` Components []*componentStatus `json:"components"`
} }
type componentStatus struct { type componentStatus struct {
Name string `json:"name"` Name string `json:"name"`
Status string `json:"status"` Status string `json:"status"`
Error string `json:"error,omitempty"` Error string `json:"error,omitempty"`
} }
func (b *BaseTestSuite) waitUntilHealthy(url string) { func (b *BaseTestSuite) waitUntilHealthy(url string) {
url = fmt.Sprintf("%s/api/v2.0/health", url) url = fmt.Sprintf("%s/api/v2.0/health", url)
log.Printf("wait until Harbor is healthy by calling health check API: %s ...", url) log.Printf("wait until Harbor is healthy by calling health check API: %s ...", url)
for i := 0; i < 60; i++ { for i := 0; i < 60; i++ {
time.Sleep(10 * time.Second) time.Sleep(10 * time.Second)
resp, err := client.Get(url) resp, err := client.Get(url)
if err != nil { if err != nil {
log.Printf("failed to call the health API: %v, retry 10 seconds later...", err) log.Printf("failed to call the health API: %v, retry 10 seconds later...", err)
continue continue
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
log.Printf("the response status code %d != 200, retry 10 seconds later...", resp.StatusCode) log.Printf("the response status code %d != 200, retry 10 seconds later...", resp.StatusCode)
continue continue
} }
data, err := ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
b.Require().Nil(err) b.Require().Nil(err)
resp.Body.Close() resp.Body.Close()
status := &overallStatus{} status := &overallStatus{}
err = json.Unmarshal(data, status) err = json.Unmarshal(data, status)
b.Require().Nil(err) b.Require().Nil(err)
if status.Status != "healthy" { if status.Status != "healthy" {
for _, component := range status.Components { for _, component := range status.Components {
if component.Status == "healthy" { if component.Status == "healthy" {
continue continue
} }
log.Printf("the status of component %s isn't healthy: %s , retry 10 seconds later...", log.Printf("the status of component %s isn't healthy: %s , retry 10 seconds later...",
component.Name, component.Error) component.Name, component.Error)
break break
} }
continue continue
} }
log.Printf("the status is healthy") log.Printf("the status is healthy")
return return
} }
b.FailNow("the status still isn't healthy after several retries") b.FailNow("the status still isn't healthy after several retries")
} }
func (b *BaseTestSuite) TestPush() { func (b *BaseTestSuite) TestPush() {
addr := strings.TrimPrefix(b.URL, "http://") addr := strings.TrimPrefix(b.URL, "http://")
addr = strings.TrimPrefix(addr, "https://") addr = strings.TrimPrefix(addr, "https://")
// push image // push image
b.T().Log("pushing the image...") b.T().Log("pushing the image...")
cmdStr := fmt.Sprintf("docker pull hello-world:latest;docker tag hello-world:latest %s/library/hello-world:latest; docker login %s -u admin -p Harbor12345;docker push %s/library/hello-world:latest", cmdStr := fmt.Sprintf("docker pull hello-world:latest;docker tag hello-world:latest %s/library/hello-world:latest; docker login %s -u admin -p Harbor12345;docker push %s/library/hello-world:latest",
addr, addr, addr) addr, addr, addr)
cmd := exec.Command("/bin/sh", "-c", cmdStr) cmd := exec.Command("/bin/sh", "-c", cmdStr)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err := cmd.Run() err := cmd.Run()
b.Require().Nil(err) b.Require().Nil(err)
// delete image in local // delete image in local
b.T().Log("deleting the image in local") b.T().Log("deleting the image in local")
cmdStr = fmt.Sprintf("docker rmi %s/library/hello-world:latest", addr) cmdStr = fmt.Sprintf("docker rmi %s/library/hello-world:latest", addr)
cmd = exec.Command("/bin/sh", "-c", cmdStr) cmd = exec.Command("/bin/sh", "-c", cmdStr)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err = cmd.Run() err = cmd.Run()
b.Require().Nil(err) b.Require().Nil(err)
// pull image // pull image
b.T().Log("pull the image...") b.T().Log("pull the image...")
cmdStr = fmt.Sprintf("docker pull %s/library/hello-world:latest", addr) cmdStr = fmt.Sprintf("docker pull %s/library/hello-world:latest", addr)
cmd = exec.Command("/bin/sh", "-c", cmdStr) cmd = exec.Command("/bin/sh", "-c", cmdStr)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
err = cmd.Run() err = cmd.Run()
b.Require().Nil(err) b.Require().Nil(err)
} }
func (b *BaseTestSuite) TearDownSuite() { func (b *BaseTestSuite) TearDownSuite() {
helm.Delete(b.T(), &helm.Options{}, b.ReleaseName, true) helm.Delete(b.T(), &helm.Options{}, b.ReleaseName, true)
} }
package integration package integration
import ( import (
"fmt" "fmt"
"testing" "testing"
"github.com/gruntwork-io/terratest/modules/k8s" "github.com/gruntwork-io/terratest/modules/k8s"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
type IngressTestSuite struct { type IngressTestSuite struct {
BaseTestSuite BaseTestSuite
} }
func (i *IngressTestSuite) TestIngress() { func (i *IngressTestSuite) TestIngress() {
k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-harbor-ingress", i.ReleaseName)) k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-harbor-ingress", i.ReleaseName))
k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-harbor-ingress-notary", i.ReleaseName)) k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-harbor-ingress-notary", i.ReleaseName))
} }
func TestIngressTestSuite(t *testing.T) { func TestIngressTestSuite(t *testing.T) {
suite.Run(t, &IngressTestSuite{ suite.Run(t, &IngressTestSuite{
BaseTestSuite: NewBaseTestSuite(map[string]string{ BaseTestSuite: NewBaseTestSuite(map[string]string{
"expose.ingress.hosts.core": "harbor.local", "expose.ingress.hosts.core": "harbor.local",
"expose.ingress.hosts.notary": "notary.harbor.local", "expose.ingress.hosts.notary": "notary.harbor.local",
"externalURL": "https://harbor.local", "externalURL": "https://harbor.local",
}), }),
}) })
} }
kind: Cluster kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4 apiVersion: kind.x-k8s.io/v1alpha4
nodes: nodes:
- role: control-plane - role: control-plane
kubeadmConfigPatches: kubeadmConfigPatches:
- | - |
kind: InitConfiguration kind: InitConfiguration
nodeRegistration: nodeRegistration:
kubeletExtraArgs: kubeletExtraArgs:
node-labels: "ingress-ready=true" node-labels: "ingress-ready=true"
extraPortMappings: extraPortMappings:
- containerPort: 80 - containerPort: 80
hostPort: 80 hostPort: 80
protocol: TCP protocol: TCP
- containerPort: 443 - containerPort: 443
hostPort: 443 hostPort: 443
protocol: TCP protocol: TCP
- containerPort: 30003 - containerPort: 30003
hostPort: 30003 hostPort: 30003
protocol: TCP protocol: TCP
package integration package integration
import ( import (
"testing" "testing"
"github.com/gruntwork-io/terratest/modules/k8s" "github.com/gruntwork-io/terratest/modules/k8s"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
type NodePortTestSuite struct { type NodePortTestSuite struct {
BaseTestSuite BaseTestSuite
} }
func (n *NodePortTestSuite) TestNodePort() { func (n *NodePortTestSuite) TestNodePort() {
service := k8s.GetService(n.T(), n.Options.KubectlOptions, "harbor") service := k8s.GetService(n.T(), n.Options.KubectlOptions, "harbor")
n.Equal("NodePort", string(service.Spec.Type)) n.Equal("NodePort", string(service.Spec.Type))
} }
func TestNodePortTestSuite(t *testing.T) { func TestNodePortTestSuite(t *testing.T) {
suite.Run(t, &NodePortTestSuite{ suite.Run(t, &NodePortTestSuite{
BaseTestSuite: NewBaseTestSuite(map[string]string{ BaseTestSuite: NewBaseTestSuite(map[string]string{
"expose.type": "nodePort", "expose.type": "nodePort",
"expose.tls.auto.commonName": "127.0.0.1", "expose.tls.auto.commonName": "127.0.0.1",
"expose.nodePort.ports.https.nodePort": "30003", "expose.nodePort.ports.https.nodePort": "30003",
"externalURL": "https://127.0.0.1:30003", "externalURL": "https://127.0.0.1:30003",
}), }),
}) })
} }
package test package test
package unittest package unittest
import ( import (
"os" "os"
"testing" "testing"
"github.com/gruntwork-io/terratest/modules/helm" "github.com/gruntwork-io/terratest/modules/helm"
"github.com/gruntwork-io/terratest/modules/logger" "github.com/gruntwork-io/terratest/modules/logger"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
appsV1 "k8s.io/api/apps/v1" appsV1 "k8s.io/api/apps/v1"
) )
type TrivyStatefulSetTestSuite struct { type TrivyStatefulSetTestSuite struct {
suite.Suite suite.Suite
} }
func (suite *TrivyStatefulSetTestSuite) render(values map[string]string) *appsV1.StatefulSet { func (suite *TrivyStatefulSetTestSuite) render(values map[string]string) *appsV1.StatefulSet {
helmChartPath := "../../" helmChartPath := "../../"
options := &helm.Options{ options := &helm.Options{
SetValues: values, SetValues: values,
} }
debug := os.Getenv("debug") debug := os.Getenv("debug")
if debug != "true" { if debug != "true" {
options.Logger = logger.Discard options.Logger = logger.Discard
} }
output := helm.RenderTemplate(suite.T(), options, helmChartPath, "harbor", []string{"templates/trivy/trivy-sts.yaml"}) output := helm.RenderTemplate(suite.T(), options, helmChartPath, "harbor", []string{"templates/trivy/trivy-sts.yaml"})
var ss appsV1.StatefulSet var ss appsV1.StatefulSet
helm.UnmarshalK8SYaml(suite.T(), output, &ss) helm.UnmarshalK8SYaml(suite.T(), output, &ss)
return &ss return &ss
} }
func (suite *TrivyStatefulSetTestSuite) TestPersistenceDisabled() { func (suite *TrivyStatefulSetTestSuite) TestPersistenceDisabled() {
values := map[string]string{ values := map[string]string{
"persistence.enabled": "false", "persistence.enabled": "false",
"persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 1) suite.Len(ss.Spec.Template.Spec.Volumes, 1)
suite.NotNil(ss.Spec.Template.Spec.Volumes[0].EmptyDir) suite.NotNil(ss.Spec.Template.Spec.Volumes[0].EmptyDir)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
func (suite *TrivyStatefulSetTestSuite) TestPersistenceEnabled() { func (suite *TrivyStatefulSetTestSuite) TestPersistenceEnabled() {
values := map[string]string{ values := map[string]string{
"persistence.enabled": "true", "persistence.enabled": "true",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 0) suite.Len(ss.Spec.Template.Spec.Volumes, 0)
suite.Len(ss.Spec.VolumeClaimTemplates, 1) suite.Len(ss.Spec.VolumeClaimTemplates, 1)
} }
func (suite *TrivyStatefulSetTestSuite) TestExistingClaim() { func (suite *TrivyStatefulSetTestSuite) TestExistingClaim() {
values := map[string]string{ values := map[string]string{
"persistence.enabled": "true", "persistence.enabled": "true",
"persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 1) suite.Len(ss.Spec.Template.Spec.Volumes, 1)
suite.NotNil(ss.Spec.Template.Spec.Volumes[0].PersistentVolumeClaim) suite.NotNil(ss.Spec.Template.Spec.Volumes[0].PersistentVolumeClaim)
suite.Equal("trivy-data", ss.Spec.Template.Spec.Volumes[0].PersistentVolumeClaim.ClaimName) suite.Equal("trivy-data", ss.Spec.Template.Spec.Volumes[0].PersistentVolumeClaim.ClaimName)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
func (suite *TrivyStatefulSetTestSuite) TestInternalTLSEnabled() { func (suite *TrivyStatefulSetTestSuite) TestInternalTLSEnabled() {
{ {
values := map[string]string{ values := map[string]string{
"internalTLS.enabled": "true", "internalTLS.enabled": "true",
"persistence.enabled": "false", "persistence.enabled": "false",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 2) suite.Len(ss.Spec.Template.Spec.Volumes, 2)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
{ {
values := map[string]string{ values := map[string]string{
"internalTLS.enabled": "true", "internalTLS.enabled": "true",
"persistence.enabled": "true", "persistence.enabled": "true",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 1) suite.Len(ss.Spec.Template.Spec.Volumes, 1)
suite.Len(ss.Spec.VolumeClaimTemplates, 1) suite.Len(ss.Spec.VolumeClaimTemplates, 1)
} }
{ {
values := map[string]string{ values := map[string]string{
"internalTLS.enabled": "true", "internalTLS.enabled": "true",
"persistence.enabled": "true", "persistence.enabled": "true",
"persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 2) suite.Len(ss.Spec.Template.Spec.Volumes, 2)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
} }
func (suite *TrivyStatefulSetTestSuite) TestCustomCA() { func (suite *TrivyStatefulSetTestSuite) TestCustomCA() {
{ {
values := map[string]string{ values := map[string]string{
"caBundleSecretName": "ca-bundle-secret", "caBundleSecretName": "ca-bundle-secret",
"persistence.enabled": "false", "persistence.enabled": "false",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 2) suite.Len(ss.Spec.Template.Spec.Volumes, 2)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
{ {
values := map[string]string{ values := map[string]string{
"caBundleSecretName": "ca-bundle-secret", "caBundleSecretName": "ca-bundle-secret",
"internalTLS.enabled": "true", "internalTLS.enabled": "true",
"persistence.enabled": "false", "persistence.enabled": "false",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 3) suite.Len(ss.Spec.Template.Spec.Volumes, 3)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
{ {
values := map[string]string{ values := map[string]string{
"caBundleSecretName": "ca-bundle-secret", "caBundleSecretName": "ca-bundle-secret",
"internalTLS.enabled": "true", "internalTLS.enabled": "true",
"persistence.enabled": "true", "persistence.enabled": "true",
"persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 3) suite.Len(ss.Spec.Template.Spec.Volumes, 3)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
{ {
values := map[string]string{ values := map[string]string{
"caBundleSecretName": "ca-bundle-secret", "caBundleSecretName": "ca-bundle-secret",
"persistence.enabled": "true", "persistence.enabled": "true",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 1) suite.Len(ss.Spec.Template.Spec.Volumes, 1)
suite.Len(ss.Spec.VolumeClaimTemplates, 1) suite.Len(ss.Spec.VolumeClaimTemplates, 1)
} }
{ {
values := map[string]string{ values := map[string]string{
"caBundleSecretName": "ca-bundle-secret", "caBundleSecretName": "ca-bundle-secret",
"persistence.enabled": "true", "persistence.enabled": "true",
"persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data",
} }
ss := suite.render(values) ss := suite.render(values)
suite.Len(ss.Spec.Template.Spec.Volumes, 2) suite.Len(ss.Spec.Template.Spec.Volumes, 2)
suite.Len(ss.Spec.VolumeClaimTemplates, 0) suite.Len(ss.Spec.VolumeClaimTemplates, 0)
} }
} }
func TestTrivyStatefulSetTestSuite(t *testing.T) { func TestTrivyStatefulSetTestSuite(t *testing.T) {
suite.Run(t, &TrivyStatefulSetTestSuite{}) suite.Run(t, &TrivyStatefulSetTestSuite{})
} }
#/bin/bash #/bin/bash
set -e set -e
helm lint . helm lint .
# expose the service via ingress, this disables the deployment of nginx # expose the service via ingress, this disables the deployment of nginx
helm template --set "expose.type=ingress" --output-dir /tmp/ . helm template --set "expose.type=ingress" --output-dir /tmp/ .
# expose the service via node port, this enables the deployment of nginx # expose the service via node port, this enables the deployment of nginx
helm template --set "expose.type=nodePort,expose.tls.commonName=127.0.0.1" --output-dir /tmp/ . helm template --set "expose.type=nodePort,expose.tls.commonName=127.0.0.1" --output-dir /tmp/ .
\ No newline at end of file
global: global:
hub: registry.cn-qingdao.aliyuncs.com/wod hub: registry.cn-qingdao.aliyuncs.com/wod
imagePullPolicy: "IfNotPresent" imagePullPolicy: "IfNotPresent"
imageArch: amd64 imageArch: amd64
host: wodcloud.local host: wodcloud.local
\ No newline at end of file
expose: expose:
# Set the way how to expose the service. Set the type as "ingress", # Set the way how to expose the service. Set the type as "ingress",
# "clusterIP", "nodePort" or "loadBalancer" and fill the information # "clusterIP", "nodePort" or "loadBalancer" and fill the information
# in the corresponding section # in the corresponding section
type: ingress type: ingress
tls: tls:
# Enable the tls or not. Note: if the type is "ingress" and the tls # Enable the tls or not. Note: if the type is "ingress" and the tls
# is disabled, the port must be included in the command when pull/push # is disabled, the port must be included in the command when pull/push
# images. Refer to https://github.com/goharbor/harbor/issues/5291 # images. Refer to https://github.com/goharbor/harbor/issues/5291
# for the detail. # for the detail.
enabled: false enabled: false
# The source of the tls certificate. Set it as "auto", "secret" # The source of the tls certificate. Set it as "auto", "secret"
# or "none" and fill the information in the corresponding section # or "none" and fill the information in the corresponding section
# 1) auto: generate the tls certificate automatically # 1) auto: generate the tls certificate automatically
# 2) secret: read the tls certificate from the specified secret. # 2) secret: read the tls certificate from the specified secret.
# The tls certificate can be generated manually or by cert manager # The tls certificate can be generated manually or by cert manager
# 3) none: configure no tls certificate for the ingress. If the default # 3) none: configure no tls certificate for the ingress. If the default
# tls certificate is configured in the ingress controller, choose this option # tls certificate is configured in the ingress controller, choose this option
certSource: auto certSource: auto
auto: auto:
# The common name used to generate the certificate, it's necessary # The common name used to generate the certificate, it's necessary
# when the type isn't "ingress" # when the type isn't "ingress"
commonName: "" commonName: ""
secret: secret:
# The name of secret which contains keys named: # The name of secret which contains keys named:
# "tls.crt" - the certificate # "tls.crt" - the certificate
# "tls.key" - the private key # "tls.key" - the private key
secretName: "" secretName: ""
# The name of secret which contains keys named: # The name of secret which contains keys named:
# "tls.crt" - the certificate # "tls.crt" - the certificate
# "tls.key" - the private key # "tls.key" - the private key
# Only needed when the "expose.type" is "ingress". # Only needed when the "expose.type" is "ingress".
notarySecretName: "" notarySecretName: ""
ingress: ingress:
hosts: hosts:
core: hub core: hub
notary: notary notary: notary
# set to the type of ingress controller if it has specific requirements. # set to the type of ingress controller if it has specific requirements.
# leave as `default` for most ingress controllers. # leave as `default` for most ingress controllers.
# set to `gce` if using the GCE ingress controller # set to `gce` if using the GCE ingress controller
# set to `ncp` if using the NCP (NSX-T Container Plugin) ingress controller # set to `ncp` if using the NCP (NSX-T Container Plugin) ingress controller
controller: default controller: default
annotations: annotations:
ingress.kubernetes.io/ssl-redirect: "true" ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/proxy-body-size: "0" ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/proxy-body-size: "0"
clusterIP: clusterIP:
# The name of ClusterIP service # The name of ClusterIP service
name: harbor name: harbor
ports: ports:
# The service port Harbor listens on when serving with HTTP # The service port Harbor listens on when serving with HTTP
httpPort: 80 httpPort: 80
# The service port Harbor listens on when serving with HTTPS # The service port Harbor listens on when serving with HTTPS
httpsPort: 443 httpsPort: 443
# The service port Notary listens on. Only needed when notary.enabled # The service port Notary listens on. Only needed when notary.enabled
# is set to true # is set to true
notaryPort: 4443 notaryPort: 4443
nodePort: nodePort:
# The name of NodePort service # The name of NodePort service
name: harbor name: harbor
ports: ports:
http: http:
# The service port Harbor listens on when serving with HTTP # The service port Harbor listens on when serving with HTTP
port: 80 port: 80
# The node port Harbor listens on when serving with HTTP # The node port Harbor listens on when serving with HTTP
nodePort: 30002 nodePort: 30002
https: https:
# The service port Harbor listens on when serving with HTTPS # The service port Harbor listens on when serving with HTTPS
port: 443 port: 443
# The node port Harbor listens on when serving with HTTPS # The node port Harbor listens on when serving with HTTPS
nodePort: 30003 nodePort: 30003
# Only needed when notary.enabled is set to true # Only needed when notary.enabled is set to true
notary: notary:
# The service port Notary listens on # The service port Notary listens on
port: 4443 port: 4443
# The node port Notary listens on # The node port Notary listens on
nodePort: 30004 nodePort: 30004
loadBalancer: loadBalancer:
# The name of LoadBalancer service # The name of LoadBalancer service
name: harbor name: harbor
# Set the IP if the LoadBalancer supports assigning IP # Set the IP if the LoadBalancer supports assigning IP
IP: "" IP: ""
ports: ports:
# The service port Harbor listens on when serving with HTTP # The service port Harbor listens on when serving with HTTP
httpPort: 80 httpPort: 80
# The service port Harbor listens on when serving with HTTPS # The service port Harbor listens on when serving with HTTPS
httpsPort: 443 httpsPort: 443
# The service port Notary listens on. Only needed when notary.enabled # The service port Notary listens on. Only needed when notary.enabled
# is set to true # is set to true
notaryPort: 4443 notaryPort: 4443
annotations: {} annotations: {}
sourceRanges: [] sourceRanges: []
# The external URL for Harbor core service. It is used to # The external URL for Harbor core service. It is used to
# 1) populate the docker/helm commands showed on portal # 1) populate the docker/helm commands showed on portal
# 2) populate the token service URL returned to docker/notary client # 2) populate the token service URL returned to docker/notary client
# #
# Format: protocol://domain[:port]. Usually: # Format: protocol://domain[:port]. Usually:
# 1) if "expose.type" is "ingress", the "domain" should be # 1) if "expose.type" is "ingress", the "domain" should be
# the value of "expose.ingress.hosts.core" # the value of "expose.ingress.hosts.core"
# 2) if "expose.type" is "clusterIP", the "domain" should be # 2) if "expose.type" is "clusterIP", the "domain" should be
# the value of "expose.clusterIP.name" # the value of "expose.clusterIP.name"
# 3) if "expose.type" is "nodePort", the "domain" should be # 3) if "expose.type" is "nodePort", the "domain" should be
# the IP address of k8s node # the IP address of k8s node
# #
# If Harbor is deployed behind the proxy, set it as the URL of proxy # If Harbor is deployed behind the proxy, set it as the URL of proxy
externalURL: https://hub externalURL: https://hub
# The internal TLS used for harbor components secure communicating. In order to enable https # The internal TLS used for harbor components secure communicating. In order to enable https
# in each components tls cert files need to provided in advance. # in each components tls cert files need to provided in advance.
internalTLS: internalTLS:
# If internal TLS enabled # If internal TLS enabled
enabled: false enabled: false
# There are three ways to provide tls # There are three ways to provide tls
# 1) "auto" will generate cert automatically # 1) "auto" will generate cert automatically
# 2) "manual" need provide cert file manually in following value # 2) "manual" need provide cert file manually in following value
# 3) "secret" internal certificates from secret # 3) "secret" internal certificates from secret
certSource: "auto" certSource: "auto"
# The content of trust ca, only available when `certSource` is "manual" # The content of trust ca, only available when `certSource` is "manual"
trustCa: "" trustCa: ""
# core related cert configuration # core related cert configuration
core: core:
# secret name for core's tls certs # secret name for core's tls certs
secretName: "" secretName: ""
# Content of core's TLS cert file, only available when `certSource` is "manual" # Content of core's TLS cert file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of core's TLS key file, only available when `certSource` is "manual" # Content of core's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# jobservice related cert configuration # jobservice related cert configuration
jobservice: jobservice:
# secret name for jobservice's tls certs # secret name for jobservice's tls certs
secretName: "" secretName: ""
# Content of jobservice's TLS key file, only available when `certSource` is "manual" # Content of jobservice's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of jobservice's TLS key file, only available when `certSource` is "manual" # Content of jobservice's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# registry related cert configuration # registry related cert configuration
registry: registry:
# secret name for registry's tls certs # secret name for registry's tls certs
secretName: "" secretName: ""
# Content of registry's TLS key file, only available when `certSource` is "manual" # Content of registry's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of registry's TLS key file, only available when `certSource` is "manual" # Content of registry's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# portal related cert configuration # portal related cert configuration
portal: portal:
# secret name for portal's tls certs # secret name for portal's tls certs
secretName: "" secretName: ""
# Content of portal's TLS key file, only available when `certSource` is "manual" # Content of portal's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of portal's TLS key file, only available when `certSource` is "manual" # Content of portal's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# chartmuseum related cert configuration # chartmuseum related cert configuration
chartmuseum: chartmuseum:
# secret name for chartmuseum's tls certs # secret name for chartmuseum's tls certs
secretName: "" secretName: ""
# Content of chartmuseum's TLS key file, only available when `certSource` is "manual" # Content of chartmuseum's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of chartmuseum's TLS key file, only available when `certSource` is "manual" # Content of chartmuseum's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# clair related cert configuration # clair related cert configuration
clair: clair:
# secret name for clair's tls certs # secret name for clair's tls certs
secretName: "" secretName: ""
# Content of clair's TLS key file, only available when `certSource` is "manual" # Content of clair's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of clair's TLS key file, only available when `certSource` is "manual" # Content of clair's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# trivy related cert configuration # trivy related cert configuration
trivy: trivy:
# secret name for trivy's tls certs # secret name for trivy's tls certs
secretName: "" secretName: ""
# Content of trivy's TLS key file, only available when `certSource` is "manual" # Content of trivy's TLS key file, only available when `certSource` is "manual"
crt: "" crt: ""
# Content of trivy's TLS key file, only available when `certSource` is "manual" # Content of trivy's TLS key file, only available when `certSource` is "manual"
key: "" key: ""
# The persistence is enabled by default and a default StorageClass # The persistence is enabled by default and a default StorageClass
# is needed in the k8s cluster to provision volumes dynamicly. # is needed in the k8s cluster to provision volumes dynamicly.
# Specify another StorageClass in the "storageClass" or set "existingClaim" # Specify another StorageClass in the "storageClass" or set "existingClaim"
# if you have already existing persistent volumes to use # if you have already existing persistent volumes to use
# #
# For storing images and charts, you can also use "azure", "gcs", "s3", # For storing images and charts, you can also use "azure", "gcs", "s3",
# "swift" or "oss". Set it in the "imageChartStorage" section # "swift" or "oss". Set it in the "imageChartStorage" section
persistence: persistence:
enabled: true enabled: true
# Setting it to "keep" to avoid removing PVCs during a helm delete # Setting it to "keep" to avoid removing PVCs during a helm delete
# operation. Leaving it empty will delete PVCs after the chart deleted # operation. Leaving it empty will delete PVCs after the chart deleted
# (this does not apply for PVCs that are created for internal database # (this does not apply for PVCs that are created for internal database
# and redis components, i.e. they are never deleted automatically) # and redis components, i.e. they are never deleted automatically)
resourcePolicy: "keep" resourcePolicy: "keep"
persistentVolumeClaim: persistentVolumeClaim:
registry: registry:
# Use the existing PVC which must be created manually before bound, # Use the existing PVC which must be created manually before bound,
# and specify the "subPath" if the PVC is shared with other components # and specify the "subPath" if the PVC is shared with other components
existingClaim: "" existingClaim: ""
# Specify the "storageClass" used to provision the volume. Or the default # Specify the "storageClass" used to provision the volume. Or the default
# StorageClass will be used(the default). # StorageClass will be used(the default).
# Set it to "-" to disable dynamic provisioning # Set it to "-" to disable dynamic provisioning
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
chartmuseum: chartmuseum:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
jobservice: jobservice:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
# If external database is used, the following settings for database will # If external database is used, the following settings for database will
# be ignored # be ignored
database: database:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 10Gi size: 10Gi
# If external Redis is used, the following settings for Redis will # If external Redis is used, the following settings for Redis will
# be ignored # be ignored
redis: redis:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 1Gi size: 1Gi
trivy: trivy:
existingClaim: "" existingClaim: ""
storageClass: "hostpath" storageClass: "hostpath"
subPath: "" subPath: ""
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 5Gi size: 5Gi
# Define which storage backend is used for registry and chartmuseum to store # Define which storage backend is used for registry and chartmuseum to store
# images and charts. Refer to # images and charts. Refer to
# https://github.com/docker/distribution/blob/master/docs/configuration.md#storage # https://github.com/docker/distribution/blob/master/docs/configuration.md#storage
# for the detail. # for the detail.
imageChartStorage: imageChartStorage:
# Specify whether to disable `redirect` for images and chart storage, for # Specify whether to disable `redirect` for images and chart storage, for
# backends which not supported it (such as using minio for `s3` storage type), please disable # backends which not supported it (such as using minio for `s3` storage type), please disable
# it. To disable redirects, simply set `disableredirect` to `true` instead. # it. To disable redirects, simply set `disableredirect` to `true` instead.
# Refer to # Refer to
# https://github.com/docker/distribution/blob/master/docs/configuration.md#redirect # https://github.com/docker/distribution/blob/master/docs/configuration.md#redirect
# for the detail. # for the detail.
disableredirect: false disableredirect: false
# Specify the "caBundleSecretName" if the storage service uses a self-signed certificate. # Specify the "caBundleSecretName" if the storage service uses a self-signed certificate.
# The secret must contain keys named "ca.crt" which will be injected into the trust store # The secret must contain keys named "ca.crt" which will be injected into the trust store
# of registry's and chartmuseum's containers. # of registry's and chartmuseum's containers.
# caBundleSecretName: # caBundleSecretName:
# Specify the type of storage: "filesystem", "azure", "gcs", "s3", "swift", # Specify the type of storage: "filesystem", "azure", "gcs", "s3", "swift",
# "oss" and fill the information needed in the corresponding section. The type # "oss" and fill the information needed in the corresponding section. The type
# must be "filesystem" if you want to use persistent volumes for registry # must be "filesystem" if you want to use persistent volumes for registry
# and chartmuseum # and chartmuseum
type: filesystem type: filesystem
filesystem: filesystem:
rootdirectory: /storage rootdirectory: /storage
#maxthreads: 100 #maxthreads: 100
azure: azure:
accountname: accountname accountname: accountname
accountkey: base64encodedaccountkey accountkey: base64encodedaccountkey
container: containername container: containername
#realm: core.windows.net #realm: core.windows.net
gcs: gcs:
bucket: bucketname bucket: bucketname
# The base64 encoded json file which contains the key # The base64 encoded json file which contains the key
encodedkey: base64-encoded-json-key-file encodedkey: base64-encoded-json-key-file
#rootdirectory: /gcs/object/name/prefix #rootdirectory: /gcs/object/name/prefix
#chunksize: "5242880" #chunksize: "5242880"
s3: s3:
region: us-west-1 region: us-west-1
bucket: bucketname bucket: bucketname
#accesskey: awsaccesskey #accesskey: awsaccesskey
#secretkey: awssecretkey #secretkey: awssecretkey
#regionendpoint: http://myobjects.local #regionendpoint: http://myobjects.local
#encrypt: false #encrypt: false
#keyid: mykeyid #keyid: mykeyid
#secure: true #secure: true
#skipverify: false #skipverify: false
#v4auth: true #v4auth: true
#chunksize: "5242880" #chunksize: "5242880"
#rootdirectory: /s3/object/name/prefix #rootdirectory: /s3/object/name/prefix
#storageclass: STANDARD #storageclass: STANDARD
#multipartcopychunksize: "33554432" #multipartcopychunksize: "33554432"
#multipartcopymaxconcurrency: 100 #multipartcopymaxconcurrency: 100
#multipartcopythresholdsize: "33554432" #multipartcopythresholdsize: "33554432"
swift: swift:
authurl: https://storage.myprovider.com/v3/auth authurl: https://storage.myprovider.com/v3/auth
username: username username: username
password: password password: password
container: containername container: containername
#region: fr #region: fr
#tenant: tenantname #tenant: tenantname
#tenantid: tenantid #tenantid: tenantid
#domain: domainname #domain: domainname
#domainid: domainid #domainid: domainid
#trustid: trustid #trustid: trustid
#insecureskipverify: false #insecureskipverify: false
#chunksize: 5M #chunksize: 5M
#prefix: #prefix:
#secretkey: secretkey #secretkey: secretkey
#accesskey: accesskey #accesskey: accesskey
#authversion: 3 #authversion: 3
#endpointtype: public #endpointtype: public
#tempurlcontainerkey: false #tempurlcontainerkey: false
#tempurlmethods: #tempurlmethods:
oss: oss:
accesskeyid: accesskeyid accesskeyid: accesskeyid
accesskeysecret: accesskeysecret accesskeysecret: accesskeysecret
region: regionname region: regionname
bucket: bucketname bucket: bucketname
#endpoint: endpoint #endpoint: endpoint
#internal: false #internal: false
#encrypt: false #encrypt: false
#secure: true #secure: true
#chunksize: 10M #chunksize: 10M
#rootdirectory: rootdirectory #rootdirectory: rootdirectory
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
# Use this set to assign a list of default pullSecrets # Use this set to assign a list of default pullSecrets
imagePullSecrets: imagePullSecrets:
# - name: docker-registry-secret # - name: docker-registry-secret
# - name: internal-registry-secret # - name: internal-registry-secret
# The update strategy for deployments with persistent volumes(jobservice, registry # The update strategy for deployments with persistent volumes(jobservice, registry
# and chartmuseum): "RollingUpdate" or "Recreate" # and chartmuseum): "RollingUpdate" or "Recreate"
# Set it as "Recreate" when "RWM" for volumes isn't supported # Set it as "Recreate" when "RWM" for volumes isn't supported
updateStrategy: updateStrategy:
type: RollingUpdate type: RollingUpdate
# debug, info, warning, error or fatal # debug, info, warning, error or fatal
logLevel: info logLevel: info
# The initial password of Harbor admin. Change it from portal after launching Harbor # The initial password of Harbor admin. Change it from portal after launching Harbor
harborAdminPassword: "spaceIN511" harborAdminPassword: "spaceIN511"
# The name of the secret which contains key named "ca.crt". Setting this enables the # The name of the secret which contains key named "ca.crt". Setting this enables the
# download link on portal to download the certificate of CA when the certificate isn't # download link on portal to download the certificate of CA when the certificate isn't
# generated automatically # generated automatically
caSecretName: "" caSecretName: ""
# The secret key used for encryption. Must be a string of 16 chars. # The secret key used for encryption. Must be a string of 16 chars.
secretKey: "IpTIscRIgmerlare" secretKey: "IpTIscRIgmerlare"
# The proxy settings for updating clair vulnerabilities from the Internet and replicating # The proxy settings for updating clair vulnerabilities from the Internet and replicating
# artifacts from/to the registries that cannot be reached directly # artifacts from/to the registries that cannot be reached directly
proxy: proxy:
httpProxy: httpProxy:
httpsProxy: httpsProxy:
noProxy: 127.0.0.1,localhost,.local,.internal noProxy: 127.0.0.1,localhost,.local,.internal
components: components:
- core - core
- jobservice - jobservice
- clair - clair
- trivy - trivy
# The custom ca bundle secret, the secret must contain key named "ca.crt" # The custom ca bundle secret, the secret must contain key named "ca.crt"
# which will be injected into the trust store for chartmuseum, clair, core, jobservice, registry, trivy components # which will be injected into the trust store for chartmuseum, clair, core, jobservice, registry, trivy components
# caBundleSecretName: "" # caBundleSecretName: ""
## UAA Authentication Options ## UAA Authentication Options
# If you're using UAA for authentication behind a self-signed # If you're using UAA for authentication behind a self-signed
# certificate you will need to provide the CA Cert. # certificate you will need to provide the CA Cert.
# Set uaaSecretName below to provide a pre-created secret that # Set uaaSecretName below to provide a pre-created secret that
# contains a base64 encoded CA Certificate named `ca.crt`. # contains a base64 encoded CA Certificate named `ca.crt`.
# uaaSecretName: # uaaSecretName:
# If expose the service via "ingress", the Nginx will not be used # If expose the service via "ingress", the Nginx will not be used
nginx: nginx:
image: image:
repository: nginx repository: nginx
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
portal: portal:
image: image:
repository: harbor-portal repository: harbor-portal
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
core: core:
image: image:
repository: harbor-core repository: harbor-core
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
replicas: 1 replicas: 1
## Startup probe values ## Startup probe values
startupProbe: startupProbe:
enabled: true enabled: true
initialDelaySeconds: 10 initialDelaySeconds: 10
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Secret is used when core server communicates with other components. # Secret is used when core server communicates with other components.
# If a secret key is not specified, Helm will generate one. # If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars. # Must be a string of 16 chars.
secret: "" secret: ""
# Fill the name of a kubernetes secret if you want to use your own # Fill the name of a kubernetes secret if you want to use your own
# TLS certificate and private key for token encryption/decryption. # TLS certificate and private key for token encryption/decryption.
# The secret must contain keys named: # The secret must contain keys named:
# "tls.crt" - the certificate # "tls.crt" - the certificate
# "tls.key" - the private key # "tls.key" - the private key
# The default key pair will be used if it isn't set # The default key pair will be used if it isn't set
secretName: "" secretName: ""
# The XSRF key. Will be generated automatically if it isn't specified # The XSRF key. Will be generated automatically if it isn't specified
xsrfKey: "" xsrfKey: ""
jobservice: jobservice:
image: image:
repository: harbor-jobservice repository: harbor-jobservice
tag: v2.1.3 tag: v2.1.3
replicas: 1 replicas: 1
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
maxJobWorkers: 10 maxJobWorkers: 10
# The logger for jobs: "file", "database" or "stdout" # The logger for jobs: "file", "database" or "stdout"
jobLogger: file jobLogger: file
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Secret is used when job service communicates with other components. # Secret is used when job service communicates with other components.
# If a secret key is not specified, Helm will generate one. # If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars. # Must be a string of 16 chars.
secret: "" secret: ""
registry: registry:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
registry: registry:
image: image:
repository: registry repository: registry
tag: 2.7.1 tag: 2.7.1
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
controller: controller:
image: image:
repository: harbor-registryctl repository: harbor-registryctl
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
replicas: 1 replicas: 1
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Secret is used to secure the upload state from client # Secret is used to secure the upload state from client
# and registry storage backend. # and registry storage backend.
# See: https://github.com/docker/distribution/blob/master/docs/configuration.md#http # See: https://github.com/docker/distribution/blob/master/docs/configuration.md#http
# If a secret key is not specified, Helm will generate one. # If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars. # Must be a string of 16 chars.
secret: "" secret: ""
# If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. # If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL.
relativeurls: false relativeurls: false
credentials: credentials:
username: "harbor_registry_user" username: "harbor_registry_user"
password: "harbor_registry_password" password: "harbor_registry_password"
# If you update the username or password of registry, make sure use cli tool htpasswd to generate the bcrypt hash # If you update the username or password of registry, make sure use cli tool htpasswd to generate the bcrypt hash
# e.g. "htpasswd -nbBC10 $username $password" # e.g. "htpasswd -nbBC10 $username $password"
htpasswd: "harbor_registry_user:$2y$10$9L4Tc0DJbFFMB6RdSCunrOpTHdwhid4ktBJmLD00bYgqkkGOvll3m" htpasswd: "harbor_registry_user:$2y$10$9L4Tc0DJbFFMB6RdSCunrOpTHdwhid4ktBJmLD00bYgqkkGOvll3m"
middleware: middleware:
enabled: false enabled: false
type: cloudFront type: cloudFront
cloudFront: cloudFront:
baseurl: example.cloudfront.net baseurl: example.cloudfront.net
keypairid: KEYPAIRID keypairid: KEYPAIRID
duration: 3000s duration: 3000s
ipfilteredby: none ipfilteredby: none
# The secret key that should be present is CLOUDFRONT_KEY_DATA, which should be the encoded private key # The secret key that should be present is CLOUDFRONT_KEY_DATA, which should be the encoded private key
# that allows access to CloudFront # that allows access to CloudFront
privateKeySecret: "my-secret" privateKeySecret: "my-secret"
chartmuseum: chartmuseum:
enabled: true enabled: true
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
# Harbor defaults ChartMuseum to returning relative urls, if you want using absolute url you should enable it by change the following value to 'true' # Harbor defaults ChartMuseum to returning relative urls, if you want using absolute url you should enable it by change the following value to 'true'
absoluteUrl: false absoluteUrl: false
image: image:
repository: harbor-chartmuseum repository: harbor-chartmuseum
tag: v2.1.3 tag: v2.1.3
storageSpec: storageSpec:
type: hostPath type: hostPath
emptyDir: {} emptyDir: {}
hostPath: hostPath:
root: /data root: /data
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
clair: clair:
enabled: true enabled: true
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
clair: clair:
image: image:
repository: harbor-clair repository: harbor-clair
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
adapter: adapter:
image: image:
repository: harbor-clair-adapter repository: harbor-clair-adapter
tag: v2.1.3 tag: v2.1.3
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
replicas: 1 replicas: 1
# The interval of clair updaters, the unit is hour, set to 0 to # The interval of clair updaters, the unit is hour, set to 0 to
# disable the updaters # disable the updaters
updatersInterval: 12 updatersInterval: 12
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
trivy: trivy:
# enabled the flag to enable Trivy scanner # enabled the flag to enable Trivy scanner
enabled: true enabled: true
image: image:
# repository the repository for Trivy adapter image # repository the repository for Trivy adapter image
repository: harbor-trivy-adapter repository: harbor-trivy-adapter
# tag the tag for Trivy adapter image # tag the tag for Trivy adapter image
tag: v2.1.3 tag: v2.1.3
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
# replicas the number of Pod replicas # replicas the number of Pod replicas
replicas: 1 replicas: 1
# debugMode the flag to enable Trivy debug mode with more verbose scanning log # debugMode the flag to enable Trivy debug mode with more verbose scanning log
debugMode: false debugMode: false
# vulnType a comma-separated list of vulnerability types. Possible values are `os` and `library`. # vulnType a comma-separated list of vulnerability types. Possible values are `os` and `library`.
vulnType: "os,library" vulnType: "os,library"
# severity a comma-separated list of severities to be checked # severity a comma-separated list of severities to be checked
severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"
# ignoreUnfixed the flag to display only fixed vulnerabilities # ignoreUnfixed the flag to display only fixed vulnerabilities
ignoreUnfixed: false ignoreUnfixed: false
# insecure the flag to skip verifying registry certificate # insecure the flag to skip verifying registry certificate
insecure: false insecure: false
# gitHubToken the GitHub access token to download Trivy DB # gitHubToken the GitHub access token to download Trivy DB
# #
# Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases. # Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases.
# It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached # It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached
# in the local file system (`/home/scanner/.cache/trivy/db/trivy.db`). In addition, the database contains the update # in the local file system (`/home/scanner/.cache/trivy/db/trivy.db`). In addition, the database contains the update
# timestamp so Trivy can detect whether it should download a newer version from the Internet or use the cached one. # timestamp so Trivy can detect whether it should download a newer version from the Internet or use the cached one.
# Currently, the database is updated every 12 hours and published as a new release to GitHub. # Currently, the database is updated every 12 hours and published as a new release to GitHub.
# #
# Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough # Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough
# for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000 # for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000
# requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult # requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult
# https://developer.github.com/v3/#rate-limiting # https://developer.github.com/v3/#rate-limiting
# #
# You can create a GitHub token by following the instructions in # You can create a GitHub token by following the instructions in
# https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line # https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
gitHubToken: "" gitHubToken: ""
# skipUpdate the flag to disable Trivy DB downloads from GitHub # skipUpdate the flag to disable Trivy DB downloads from GitHub
# #
# You might want to set the value of this flag to `true` in test or CI/CD environments to avoid GitHub rate limiting issues. # You might want to set the value of this flag to `true` in test or CI/CD environments to avoid GitHub rate limiting issues.
# If the value is set to `true` you have to manually download the `trivy.db` file and mount it in the # If the value is set to `true` you have to manually download the `trivy.db` file and mount it in the
# `/home/scanner/.cache/trivy/db/trivy.db` path. # `/home/scanner/.cache/trivy/db/trivy.db` path.
skipUpdate: false skipUpdate: false
resources: resources:
requests: requests:
cpu: 200m cpu: 200m
memory: 512Mi memory: 512Mi
limits: limits:
cpu: 1 cpu: 1
memory: 1Gi memory: 1Gi
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
notary: notary:
enabled: true enabled: true
server: server:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: harbor-notary-server repository: harbor-notary-server
tag: v2.1.3 tag: v2.1.3
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
signer: signer:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: harbor-notary-signer repository: harbor-notary-signer
tag: v2.1.3 tag: v2.1.3
replicas: 1 replicas: 1
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
# Fill the name of a kubernetes secret if you want to use your own # Fill the name of a kubernetes secret if you want to use your own
# TLS certificate authority, certificate and private key for notary # TLS certificate authority, certificate and private key for notary
# communications. # communications.
# The secret must contain keys named ca.crt, tls.crt and tls.key that # The secret must contain keys named ca.crt, tls.crt and tls.key that
# contain the CA, certificate and private key. # contain the CA, certificate and private key.
# They will be generated if not set. # They will be generated if not set.
secretName: "" secretName: ""
database: database:
# if external database is used, set "type" to "external" # if external database is used, set "type" to "external"
# and fill the connection informations in "external" section # and fill the connection informations in "external" section
type: internal type: internal
internal: internal:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: harbor-db repository: harbor-db
tag: v2.1.3 tag: v2.1.3
# The initial superuser password for internal database # The initial superuser password for internal database
password: "spaceIN511" password: "spaceIN511"
resources: resources:
limits: limits:
memory: 4Gi memory: 4Gi
requests: requests:
memory: 256Mi memory: 256Mi
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
external: external:
host: "192.168.0.1" host: "192.168.0.1"
port: "5432" port: "5432"
username: "user" username: "user"
password: "password" password: "password"
coreDatabase: "registry" coreDatabase: "registry"
clairDatabase: "clair" clairDatabase: "clair"
notaryServerDatabase: "notary_server" notaryServerDatabase: "notary_server"
notarySignerDatabase: "notary_signer" notarySignerDatabase: "notary_signer"
# "disable" - No SSL # "disable" - No SSL
# "require" - Always SSL (skip verification) # "require" - Always SSL (skip verification)
# "verify-ca" - Always SSL (verify that the certificate presented by the # "verify-ca" - Always SSL (verify that the certificate presented by the
# server was signed by a trusted CA) # server was signed by a trusted CA)
# "verify-full" - Always SSL (verify that the certification presented by the # "verify-full" - Always SSL (verify that the certification presented by the
# server was signed by a trusted CA and the server host name matches the one # server was signed by a trusted CA and the server host name matches the one
# in the certificate) # in the certificate)
sslmode: "disable" sslmode: "disable"
# The maximum number of connections in the idle connection pool. # The maximum number of connections in the idle connection pool.
# If it <=0, no idle connections are retained. # If it <=0, no idle connections are retained.
maxIdleConns: 50 maxIdleConns: 50
# The maximum number of open connections to the database. # The maximum number of open connections to the database.
# If it <= 0, then there is no limit on the number of open connections. # If it <= 0, then there is no limit on the number of open connections.
# Note: the default number of connections is 1024 for postgre of harbor. # Note: the default number of connections is 1024 for postgre of harbor.
maxOpenConns: 1000 maxOpenConns: 1000
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
redis: redis:
# if external Redis is used, set "type" to "external" # if external Redis is used, set "type" to "external"
# and fill the connection informations in "external" section # and fill the connection informations in "external" section
type: internal type: internal
internal: internal:
# set the service account to be used, default if left empty # set the service account to be used, default if left empty
serviceAccountName: "" serviceAccountName: ""
image: image:
repository: redis repository: redis
tag: 6.0.9 tag: 6.0.9
# resources: # resources:
# requests: # requests:
# memory: 256Mi # memory: 256Mi
# cpu: 100m # cpu: 100m
nodeSelector: {} nodeSelector: {}
tolerations: [] tolerations: []
affinity: {} affinity: {}
external: external:
# support redis, redis+sentinel # support redis, redis+sentinel
# addr for redis: <host_redis>:<port_redis> # addr for redis: <host_redis>:<port_redis>
# addr for redis+sentinel: <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3> # addr for redis+sentinel: <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3>
addr: "192.168.0.2:6379" addr: "192.168.0.2:6379"
# The name of the set of Redis instances to monitor, it must be set to support redis+sentinel # The name of the set of Redis instances to monitor, it must be set to support redis+sentinel
sentinelMasterSet: "" sentinelMasterSet: ""
# The "coreDatabaseIndex" must be "0" as the library Harbor # The "coreDatabaseIndex" must be "0" as the library Harbor
# used doesn't support configuring it # used doesn't support configuring it
coreDatabaseIndex: "0" coreDatabaseIndex: "0"
jobserviceDatabaseIndex: "1" jobserviceDatabaseIndex: "1"
registryDatabaseIndex: "2" registryDatabaseIndex: "2"
chartmuseumDatabaseIndex: "3" chartmuseumDatabaseIndex: "3"
clairAdapterIndex: "4" clairAdapterIndex: "4"
trivyAdapterIndex: "5" trivyAdapterIndex: "5"
password: "" password: ""
## Additional deployment annotations ## Additional deployment annotations
podAnnotations: {} podAnnotations: {}
commonLabels: commonLabels:
app.bd-apaas.com/cluster-component: registry app.bd-apaas.com/cluster-component: registry
\ No newline at end of file
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