From a4414711f24900dc60de8a4c5dfc5eb38b3962d6 Mon Sep 17 00:00:00 2001 From: aguyot-ensae Date: Tue, 16 Apr 2024 17:08:47 +0200 Subject: [PATCH] ajout chart catalogue perso onyxia --- charts/dokuwiki/.helmignore | 23 + charts/dokuwiki/Chart.lock | 6 + charts/dokuwiki/Chart.yaml | 38 + charts/dokuwiki/README.md | 459 ++++++ charts/dokuwiki/charts/common-2.19.1.tgz | Bin 0 -> 15699 bytes charts/dokuwiki/dokuwiki-16.0.2.tgz | Bin 0 -> 91247 bytes charts/dokuwiki/templates/NOTES.txt | 61 + charts/dokuwiki/templates/_helpers.tpl | 70 + charts/dokuwiki/templates/deployment.yaml | 422 ++++++ charts/dokuwiki/templates/dokuwiki-pvc.yaml | 30 + charts/dokuwiki/templates/extra-list.yaml | 9 + charts/dokuwiki/templates/ingress.yaml | 63 + charts/dokuwiki/templates/networkpolicy.yaml | 70 + .../templates/postinit-configmap.yaml | 20 + charts/dokuwiki/templates/secrets.yaml | 23 + charts/dokuwiki/templates/serviceaccount.yaml | 18 + charts/dokuwiki/templates/svc.yaml | 53 + charts/dokuwiki/templates/tls-secrets.yaml | 44 + charts/dokuwiki/values.schema.json | 758 ++++++++++ charts/dokuwiki/values.yaml | 794 ++++++++++ charts/harbor-helm-main/.github/release.yml | 36 + .../housekeeping-stale-issues-prs.yaml | 26 + .../.github/workflows/integration.yaml | 78 + .../.github/workflows/lint.yaml | 47 + .../.github/workflows/publish_release.yaml | 47 + .../.github/workflows/unittest.yaml | 35 + charts/harbor-helm-main/.gitignore | 2 + charts/harbor-helm-main/.helmignore | 6 + charts/harbor-helm-main/CONTRIBUTING.md | 13 + charts/harbor-helm-main/Chart.yaml | 22 + charts/harbor-helm-main/LICENSE | 201 +++ charts/harbor-helm-main/README.md | 415 ++++++ .../docs/High Availability.md | 71 + charts/harbor-helm-main/docs/Upgrade.md | 69 + charts/harbor-helm-main/docs/_index.md | 6 + charts/harbor-helm-main/docs/img/ha.png | Bin 0 -> 332250 bytes charts/harbor-helm-main/harbor-1.4.0-dev.tgz | Bin 0 -> 52398 bytes charts/harbor-helm-main/templates/NOTES.txt | 3 + .../harbor-helm-main/templates/_helpers.tpl | 574 ++++++++ .../templates/core/core-cm.yaml | 90 ++ .../templates/core/core-dpl.yaml | 253 ++++ .../templates/core/core-pre-upgrade-job.yaml | 77 + .../templates/core/core-secret.yaml | 36 + .../templates/core/core-svc.yaml | 25 + .../templates/core/core-tls.yaml | 15 + .../templates/database/database-secret.yaml | 11 + .../templates/database/database-ss.yaml | 159 ++ .../templates/database/database-svc.yaml | 14 + .../templates/exporter/exporter-cm-env.yaml | 35 + .../templates/exporter/exporter-dpl.yaml | 146 ++ .../templates/exporter/exporter-secret.yaml | 16 + .../templates/exporter/exporter-svc.yaml | 15 + .../templates/ingress/ingress.yaml | 142 ++ .../templates/ingress/secret.yaml | 15 + .../templates/internal/auto-tls.yaml | 81 ++ .../jobservice/jobservice-cm-env.yaml | 34 + .../templates/jobservice/jobservice-cm.yaml | 57 + .../templates/jobservice/jobservice-dpl.yaml | 178 +++ .../templates/jobservice/jobservice-pvc.yaml | 31 + .../jobservice/jobservice-secrets.yaml | 16 + .../templates/jobservice/jobservice-svc.yaml | 18 + .../templates/jobservice/jobservice-tls.yaml | 15 + .../templates/metrics/metrics-svcmon.yaml | 28 + .../templates/nginx/configmap-http.yaml | 150 ++ .../templates/nginx/configmap-https.yaml | 187 +++ .../templates/nginx/deployment.yaml | 132 ++ .../templates/nginx/secret.yaml | 23 + .../templates/nginx/service.yaml | 94 ++ .../templates/portal/configmap.yaml | 67 + .../templates/portal/deployment.yaml | 119 ++ .../templates/portal/service.yaml | 20 + .../templates/portal/tls.yaml | 15 + .../templates/redis/service.yaml | 14 + .../templates/redis/statefulset.yaml | 121 ++ .../templates/registry/registry-cm.yaml | 246 ++++ .../templates/registry/registry-dpl.yaml | 427 ++++++ .../templates/registry/registry-pvc.yaml | 33 + .../templates/registry/registry-secret.yaml | 55 + .../templates/registry/registry-svc.yaml | 20 + .../templates/registry/registry-tls.yaml | 15 + .../templates/registry/registryctl-cm.yaml | 8 + .../registry/registryctl-secret.yaml | 9 + .../templates/trivy/trivy-secret.yaml | 12 + .../templates/trivy/trivy-sts.yaml | 226 +++ .../templates/trivy/trivy-svc.yaml | 16 + .../templates/trivy/trivy-tls.yaml | 15 + charts/harbor-helm-main/test/e2e/Dockerfile | 7 + charts/harbor-helm-main/test/e2e/Jenkinsfile | 128 ++ charts/harbor-helm-main/test/go.mod | 9 + charts/harbor-helm-main/test/go.sum | 1282 +++++++++++++++++ .../harbor-helm-main/test/integration/base.go | 188 +++ .../test/integration/ingress_test.go | 26 + .../test/integration/kind-cluster.yaml | 20 + .../test/integration/node_port_test.go | 28 + charts/harbor-helm-main/test/test.go | 1 + .../test/unittest/trivy_stateful_set_test.go | 171 +++ charts/harbor-helm-main/values.schema.json | 758 ++++++++++ charts/harbor-helm-main/values.yaml | 1009 +++++++++++++ charts/index.yaml | 3 - .../wordpress/values.schema.json | 768 ++-------- 100 files changed, 11872 insertions(+), 669 deletions(-) create mode 100644 charts/dokuwiki/.helmignore create mode 100644 charts/dokuwiki/Chart.lock create mode 100644 charts/dokuwiki/Chart.yaml create mode 100644 charts/dokuwiki/README.md create mode 100644 charts/dokuwiki/charts/common-2.19.1.tgz create mode 100644 charts/dokuwiki/dokuwiki-16.0.2.tgz create mode 100644 charts/dokuwiki/templates/NOTES.txt create mode 100644 charts/dokuwiki/templates/_helpers.tpl create mode 100644 charts/dokuwiki/templates/deployment.yaml create mode 100644 charts/dokuwiki/templates/dokuwiki-pvc.yaml create mode 100644 charts/dokuwiki/templates/extra-list.yaml create mode 100644 charts/dokuwiki/templates/ingress.yaml create mode 100644 charts/dokuwiki/templates/networkpolicy.yaml create mode 100644 charts/dokuwiki/templates/postinit-configmap.yaml create mode 100644 charts/dokuwiki/templates/secrets.yaml create mode 100644 charts/dokuwiki/templates/serviceaccount.yaml create mode 100644 charts/dokuwiki/templates/svc.yaml create mode 100644 charts/dokuwiki/templates/tls-secrets.yaml create mode 100644 charts/dokuwiki/values.schema.json create mode 100644 charts/dokuwiki/values.yaml create mode 100644 charts/harbor-helm-main/.github/release.yml create mode 100644 charts/harbor-helm-main/.github/workflows/housekeeping-stale-issues-prs.yaml create mode 100644 charts/harbor-helm-main/.github/workflows/integration.yaml create mode 100644 charts/harbor-helm-main/.github/workflows/lint.yaml create mode 100644 charts/harbor-helm-main/.github/workflows/publish_release.yaml create mode 100644 charts/harbor-helm-main/.github/workflows/unittest.yaml create mode 100644 charts/harbor-helm-main/.gitignore create mode 100644 charts/harbor-helm-main/.helmignore create mode 100644 charts/harbor-helm-main/CONTRIBUTING.md create mode 100644 charts/harbor-helm-main/Chart.yaml create mode 100644 charts/harbor-helm-main/LICENSE create mode 100644 charts/harbor-helm-main/README.md create mode 100644 charts/harbor-helm-main/docs/High Availability.md create mode 100644 charts/harbor-helm-main/docs/Upgrade.md create mode 100644 charts/harbor-helm-main/docs/_index.md create mode 100644 charts/harbor-helm-main/docs/img/ha.png create mode 100644 charts/harbor-helm-main/harbor-1.4.0-dev.tgz create mode 100644 charts/harbor-helm-main/templates/NOTES.txt create mode 100644 charts/harbor-helm-main/templates/_helpers.tpl create mode 100644 charts/harbor-helm-main/templates/core/core-cm.yaml create mode 100644 charts/harbor-helm-main/templates/core/core-dpl.yaml create mode 100644 charts/harbor-helm-main/templates/core/core-pre-upgrade-job.yaml create mode 100644 charts/harbor-helm-main/templates/core/core-secret.yaml create mode 100644 charts/harbor-helm-main/templates/core/core-svc.yaml create mode 100644 charts/harbor-helm-main/templates/core/core-tls.yaml create mode 100644 charts/harbor-helm-main/templates/database/database-secret.yaml create mode 100644 charts/harbor-helm-main/templates/database/database-ss.yaml create mode 100644 charts/harbor-helm-main/templates/database/database-svc.yaml create mode 100644 charts/harbor-helm-main/templates/exporter/exporter-cm-env.yaml create mode 100644 charts/harbor-helm-main/templates/exporter/exporter-dpl.yaml create mode 100644 charts/harbor-helm-main/templates/exporter/exporter-secret.yaml create mode 100644 charts/harbor-helm-main/templates/exporter/exporter-svc.yaml create mode 100644 charts/harbor-helm-main/templates/ingress/ingress.yaml create mode 100644 charts/harbor-helm-main/templates/ingress/secret.yaml create mode 100644 charts/harbor-helm-main/templates/internal/auto-tls.yaml create mode 100644 charts/harbor-helm-main/templates/jobservice/jobservice-cm-env.yaml create mode 100644 charts/harbor-helm-main/templates/jobservice/jobservice-cm.yaml create mode 100644 charts/harbor-helm-main/templates/jobservice/jobservice-dpl.yaml create mode 100644 charts/harbor-helm-main/templates/jobservice/jobservice-pvc.yaml create mode 100644 charts/harbor-helm-main/templates/jobservice/jobservice-secrets.yaml create mode 100644 charts/harbor-helm-main/templates/jobservice/jobservice-svc.yaml create mode 100644 charts/harbor-helm-main/templates/jobservice/jobservice-tls.yaml create mode 100644 charts/harbor-helm-main/templates/metrics/metrics-svcmon.yaml create mode 100644 charts/harbor-helm-main/templates/nginx/configmap-http.yaml create mode 100644 charts/harbor-helm-main/templates/nginx/configmap-https.yaml create mode 100644 charts/harbor-helm-main/templates/nginx/deployment.yaml create mode 100644 charts/harbor-helm-main/templates/nginx/secret.yaml create mode 100644 charts/harbor-helm-main/templates/nginx/service.yaml create mode 100644 charts/harbor-helm-main/templates/portal/configmap.yaml create mode 100644 charts/harbor-helm-main/templates/portal/deployment.yaml create mode 100644 charts/harbor-helm-main/templates/portal/service.yaml create mode 100644 charts/harbor-helm-main/templates/portal/tls.yaml create mode 100644 charts/harbor-helm-main/templates/redis/service.yaml create mode 100644 charts/harbor-helm-main/templates/redis/statefulset.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registry-cm.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registry-dpl.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registry-pvc.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registry-secret.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registry-svc.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registry-tls.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registryctl-cm.yaml create mode 100644 charts/harbor-helm-main/templates/registry/registryctl-secret.yaml create mode 100644 charts/harbor-helm-main/templates/trivy/trivy-secret.yaml create mode 100644 charts/harbor-helm-main/templates/trivy/trivy-sts.yaml create mode 100644 charts/harbor-helm-main/templates/trivy/trivy-svc.yaml create mode 100644 charts/harbor-helm-main/templates/trivy/trivy-tls.yaml create mode 100644 charts/harbor-helm-main/test/e2e/Dockerfile create mode 100644 charts/harbor-helm-main/test/e2e/Jenkinsfile create mode 100644 charts/harbor-helm-main/test/go.mod create mode 100644 charts/harbor-helm-main/test/go.sum create mode 100644 charts/harbor-helm-main/test/integration/base.go create mode 100644 charts/harbor-helm-main/test/integration/ingress_test.go create mode 100644 charts/harbor-helm-main/test/integration/kind-cluster.yaml create mode 100644 charts/harbor-helm-main/test/integration/node_port_test.go create mode 100644 charts/harbor-helm-main/test/test.go create mode 100644 charts/harbor-helm-main/test/unittest/trivy_stateful_set_test.go create mode 100644 charts/harbor-helm-main/values.schema.json create mode 100644 charts/harbor-helm-main/values.yaml delete mode 100644 charts/index.yaml diff --git a/charts/dokuwiki/.helmignore b/charts/dokuwiki/.helmignore new file mode 100644 index 0000000..fb56657 --- /dev/null +++ b/charts/dokuwiki/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# img folder +img/ diff --git a/charts/dokuwiki/Chart.lock b/charts/dokuwiki/Chart.lock new file mode 100644 index 0000000..def42c2 --- /dev/null +++ b/charts/dokuwiki/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.19.1 +digest: sha256:c883732817d9aaa3304f7b3109262aa338959de15b432dc5a2dbde13d2e136a5 +generated: "2024-04-01T12:35:22.671196378+02:00" diff --git a/charts/dokuwiki/Chart.yaml b/charts/dokuwiki/Chart.yaml new file mode 100644 index 0000000..847e447 --- /dev/null +++ b/charts/dokuwiki/Chart.yaml @@ -0,0 +1,38 @@ +# Copyright VMware, Inc. +# SPDX-License-Identifier: APACHE-2.0 + +annotations: + category: Wiki + licenses: Apache-2.0 + images: | + - name: apache-exporter + image: docker.io/bitnami/apache-exporter:1.0.7-debian-12-r3 + - name: dokuwiki + image: docker.io/bitnami/dokuwiki:20240206.1.0-debian-12-r5 + - name: os-shell + image: docker.io/bitnami/os-shell:12-debian-12-r18 +apiVersion: v2 +appVersion: 20240206.1.0 +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: DokuWiki is a standards-compliant wiki optimized for creating documentation. Designed to be simple to use for small organizations, it stores all data in plain text files so no database is required. +home: https://bitnami.com +icon: https://bitnami.com/assets/stacks/dokuwiki/img/dokuwiki-stack-220x234.png +keywords: +- dokuwiki +- wiki +- http +- web +- application +- php +maintainers: +- name: VMware, Inc. + url: https://github.com/bitnami/charts +name: dokuwiki +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/dokuwiki +version: 16.0.2 diff --git a/charts/dokuwiki/README.md b/charts/dokuwiki/README.md new file mode 100644 index 0000000..bf35ef5 --- /dev/null +++ b/charts/dokuwiki/README.md @@ -0,0 +1,459 @@ + + +# Bitnami package for DokuWiki + +DokuWiki is a standards-compliant wiki optimized for creating documentation. Designed to be simple to use for small organizations, it stores all data in plain text files so no database is required. + +[Overview of DokuWiki](https://www.splitbrain.org/projects/dokuwiki) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/dokuwiki +``` + +Looking to use DokuWiki in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the enterprise edition of Bitnami Application Catalog. + +## Introduction + +This chart bootstraps a [DokuWiki](https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ +- PV provisioner support in the underlying infrastructure +- ReadWriteMany volumes for deployment scaling + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://REGISTRY_NAME/REPOSITORY_NAME/dokuwiki +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The command deploys DokuWiki on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Configuration and installation details + +### Resource requests and limits + +Bitnami charts allow setting resource requests and limits for all containers inside the chart deployment. These are inside the `resources` value (check parameter table). Setting requests is essential for production workloads and these should be adapted to your specific use case. + +To make this process easier, the chart contains the `resourcesPreset` values, which automatically sets the `resources` section according to different presets. Check these presets in [the bitnami/common chart](https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15). However, in production workloads using `resourcePreset` is discouraged as it may not fully adapt to your specific needs. Find more information on container resource management in the [official Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +### [Rolling VS Immutable tags](https://docs.bitnami.com/tutorials/understand-rolling-tags-containers) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Setting Pod's affinity + +This chart allows you to set your custom affinity using the `affinity` parameter. Find more information about Pod's affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `podAffinityPreset`, `podAntiAffinityPreset`, or `nodeAffinityPreset` parameters. + +### Certificates + +#### CA Certificates + +Custom CA certificates not included in the base docker image can be added with +the following configuration. The secret must exist in the same namespace as the +deployment. Will load all certificates files it finds in the secret. + +```yaml +certificates: + customCAs: + - secret: my-ca-1 + - secret: my-ca-2 +``` + +##### CA Certificates secret + +Secret can be created with: + +```console +kubectl create secret generic my-ca-1 --from-file my-ca-1.crt +``` + +#### TLS Certificate + +A web server TLS Certificate can be injected into the container with the +following configuration. The certificate will be stored at the location +specified in the certificateLocation value. + +```yaml +certificates: + customCertificate: + certificateSecret: my-secret + certificateLocation: /ssl/server.pem + keyLocation: /ssl/key.pem + chainSecret: + name: my-cert-chain-secret + key: chain.pem +``` + +##### TLS secret + +The certificate tls secret can be created with: + +```console +kubectl create secret tls my-secret --cert tls.crt --key tls.key +``` + +The certificate chain is created with: + +```console +kubectl create secret generic my-ca-1 --from-file my-ca-1.crt +``` + +## Persistence + +The [Bitnami DokuWiki](https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki) image stores the DokuWiki data and configurations at the `/bitnami/dokuwiki` path of the container. + +Persistent Volume Claims are used to keep the data across deployments. There is a [known issue](https://github.com/kubernetes/kubernetes/issues/39178) in Kubernetes Clusters with EBS in different availability zones. Ensure your cluster is configured properly to create Volumes in the same availability zone where the nodes are running. Kuberentes 1.12 solved this issue with the [Volume Binding Mode](https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode). + +See the [Parameters](#parameters) section to configure the PVC or to disable persistence. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.storageClass` | Global StorageClass for Persistent Volume(s) | `""` | +| `global.compatibility.openshift.adaptSecurityContext` | Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) | `auto` | + +### Common parameters + +| Name | Description | Value | +| ------------------- | ----------------------------------------------------------------------------------------------------- | ----- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override dokuwiki.fullname template with a string (will prepend the release name) | `""` | +| `fullnameOverride` | String to fully override dokuwiki.fullname template with a string | `""` | +| `namespaceOverride` | String to fully override common.names.namespace | `""` | +| `commonAnnotations` | Annotations to add to all deployed objects | `{}` | +| `commonLabels` | Labels to add to all deployed objects | `{}` | +| `extraDeploy` | Array of extra objects to deploy with the release (evaluated as a template). | `[]` | + +### Dokuwiki parameters + +| Name | Description | Value | +| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `image.registry` | DokuWiki image registry | `REGISTRY_NAME` | +| `image.repository` | DokuWiki image repository | `REPOSITORY_NAME/dokuwiki` | +| `image.digest` | DokuWiki image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Image pull policy | `[]` | +| `image.debug` | Enable image debugging | `false` | +| `automountServiceAccountToken` | Mount Service Account token in pod | `false` | +| `hostAliases` | Add deployment host aliases | `[]` | +| `dokuwikiUsername` | User of the application | `user` | +| `dokuwikiPassword` | Application password | `""` | +| `existingSecret` | Use an existing secret with the dokuwiki password | `""` | +| `dokuwikiEmail` | Admin email | `user@example.com` | +| `dokuwikiFullName` | User's Full Name | `User Name` | +| `dokuwikiWikiName` | Wiki name | `My Wiki` | +| `customPostInitScripts` | Custom post-init.d user scripts | `{}` | +| `updateStrategy` | Strategy to use to update Pods | `{}` | +| `topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `persistence.enabled` | Enable persistence using PVC | `true` | +| `persistence.storageClass` | PVC Storage Class for DokuWiki volume | `""` | +| `persistence.accessModes` | PVC Access Mode for DokuWiki volume | `[]` | +| `persistence.size` | PVC Storage Request for DokuWiki volume | `8Gi` | +| `persistence.existingClaim` | Name of an existing PVC to be used | `""` | +| `persistence.annotations` | Annotations to add to the PVC | `{}` | +| `podSecurityContext.enabled` | Enable securityContext on for DokuWiki deployment | `true` | +| `podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `podSecurityContext.fsGroup` | Group to configure permissions for volumes | `1001` | +| `containerSecurityContext.enabled` | Enabled Dokuwiki containers' Security Context | `true` | +| `containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `containerSecurityContext.runAsUser` | Set Dokuwiki containers' Security Context runAsUser | `1001` | +| `containerSecurityContext.runAsGroup` | Set Dokuwiki containers' Security Context runAsGroup | `1001` | +| `containerSecurityContext.runAsNonRoot` | Set Controller container's Security Context runAsNonRoot | `true` | +| `containerSecurityContext.privileged` | Set primary container's Security Context privileged | `false` | +| `containerSecurityContext.readOnlyRootFilesystem` | Set primary container's Security Context readOnlyRootFilesystem | `true` | +| `containerSecurityContext.allowPrivilegeEscalation` | Set primary container's Security Context allowPrivilegeEscalation | `false` | +| `containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `micro` | +| `resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `livenessProbe.enabled` | Enable/disable the liveness probe | `true` | +| `livenessProbe.initialDelaySeconds` | Delay before liveness probe is initiated | `120` | +| `livenessProbe.periodSeconds` | How often to perform the probe | `10` | +| `livenessProbe.timeoutSeconds` | When the probe times out | `5` | +| `livenessProbe.failureThreshold` | Minimum consecutive failures to be considered failed | `6` | +| `livenessProbe.successThreshold` | Minimum consecutive successes to be considered successful | `1` | +| `readinessProbe.enabled` | Enable/disable the readiness probe | `true` | +| `readinessProbe.initialDelaySeconds` | Delay before readinessProbe is initiated | `30` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `readinessProbe.timeoutSeconds` | When the probe times out | `5` | +| `readinessProbe.failureThreshold` | Minimum consecutive failures to be considered failed | `6` | +| `readinessProbe.successThreshold` | Minimum consecutive successes to be considered successful | `1` | +| `startupProbe.enabled` | Enable/disable the startup probe | `false` | +| `startupProbe.initialDelaySeconds` | Delay before startup probe is initiated | `120` | +| `startupProbe.periodSeconds` | How often to perform the probe | `10` | +| `startupProbe.timeoutSeconds` | When the probe times out | `5` | +| `startupProbe.failureThreshold` | Minimum consecutive failures to be considered failed | `6` | +| `startupProbe.successThreshold` | Minimum consecutive successes to be considered successful | `1` | +| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `nodeAffinityPreset.key` | Node label key to match Ignored if `affinity` is set. | `""` | +| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | +| `affinity` | Affinity for pod assignment | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Tolerations for pod assignment | `[]` | +| `command` | Override default container command (useful when using custom images) | `[]` | +| `args` | Override default container args (useful when using custom images) | `[]` | +| `extraEnvVars` | An array to add extra env vars | `[]` | +| `extraEnvVarsCM` | ConfigMap containing extra env vars | `""` | +| `extraEnvVarsSecret` | Secret containing extra env vars (in case of sensitive data) | `""` | +| `podAnnotations` | Pod annotations | `{}` | +| `customLivenessProbe` | Override default liveness probe | `{}` | +| `customReadinessProbe` | Override default readiness probe | `{}` | +| `customStartupProbe` | Override default startup probe | `{}` | +| `extraVolumes` | Array of extra volumes to be added to the deployment (evaluated as template). Requires setting `extraVolumeMounts` | `[]` | +| `extraVolumeMounts` | Array of extra volume mounts to be added to the container (evaluated as template). Normally used with `extraVolumes`. | `[]` | +| `lifecycleHooks` | LifecycleHook to set additional configuration at startup. Evaluated as a template | `{}` | +| `podLabels` | Add additional labels to the pod (evaluated as a template) | `{}` | +| `initContainers` | Attach additional init containers to the pod (evaluated as a template) | `[]` | +| `sidecars` | Attach additional containers to the pod (evaluated as a template) | `[]` | +| `priorityClassName` | Priority class assigned to the Pods | `""` | +| `schedulerName` | Alternative scheduler | `""` | +| `terminationGracePeriodSeconds` | In seconds, time the given to the pod to terminate gracefully | `""` | +| `containerPorts.http` | Container HTTP port | `8080` | +| `containerPorts.https` | Container HTTPS port | `8443` | +| `extraContainerPorts` | Optionally specify extra list of additional ports for Dokuwiki container(s) | `[]` | +| `serviceAccount.create` | Enable creation of ServiceAccount for Dokuwiki pod | `true` | +| `serviceAccount.name` | The name of the ServiceAccount to use. | `""` | +| `serviceAccount.automountServiceAccountToken` | Allows auto mount of ServiceAccountToken on the serviceAccount created | `false` | +| `serviceAccount.annotations` | Additional custom annotations for the ServiceAccount | `{}` | + +### Traffic Exposure Parameters + +| Name | Description | Value | +| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `service.type` | Kubernetes Service type | `LoadBalancer` | +| `service.loadBalancerIP` | Use serviceLoadBalancerIP to request a specific static IP, otherwise leave blank | `""` | +| `service.ports.http` | Service HTTP port | `80` | +| `service.ports.https` | Service HTTPS port | `443` | +| `service.nodePorts` | Use nodePorts to request some specific ports when using NodePort | `{}` | +| `service.clusterIP` | Kubernetes service Cluster IP | `""` | +| `service.loadBalancerSourceRanges` | Kubernetes service Load Balancer sources | `[]` | +| `service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `service.extraPorts` | Extra ports to expose in the service (normally used with the `sidecar` value) | `[]` | +| `service.annotations` | Annotations to add to the service | `{}` | +| `service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` | +| `networkPolicy.allowExternal` | Don't require server label for connections | `true` | +| `networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` | +| `networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolice | `[]` | +| `networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | +| `ingress.enabled` | Set to true to enable ingress record generation | `false` | +| `ingress.pathType` | Ingress Path type | `ImplementationSpecific` | +| `ingress.apiVersion` | Override API Version (automatically detected if not set) | `""` | +| `ingress.hostname` | When the ingress is enabled, a host pointing to this will be created | `dokuwiki.local` | +| `ingress.path` | The Path to Dokuwiki. You may need to set this to '/*' in order to use this | `/` | +| `ingress.annotations` | Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. | `{}` | +| `ingress.tls` | Enable TLS configuration for the hostname defined at ingress.hostname parameter | `false` | +| `ingress.extraHosts` | The list of additional hostnames to be covered with this ingress record. | `[]` | +| `ingress.extraPaths` | Any additional arbitrary paths that may need to be added to the ingress under the main host. | `[]` | +| `ingress.extraTls` | The tls configuration for additional hostnames to be covered with this ingress record. | `[]` | +| `ingress.secrets` | If you're providing your own certificates, please use this to add the certificates as secrets | `[]` | +| `ingress.ingressClassName` | IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) | `""` | +| `ingress.selfSigned` | Create a TLS secret for this ingress record using self-signed certificates generated by Helm | `false` | +| `ingress.extraRules` | Additional rules to be covered with this ingress record | `[]` | + +### Volume Permissions parameters + +| Name | Description | Value | +| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `volumePermissions.enabled` | Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `REGISTRY_NAME` | +| `volumePermissions.image.repository` | Init container volume-permissions image name | `REPOSITORY_NAME/os-shell` | +| `volumePermissions.image.digest` | Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `volumePermissions.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). | `nano` | +| `volumePermissions.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `volumePermissions.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `volumePermissions.containerSecurityContext.runAsUser` | User ID for the init container | `0` | + +### Metrics parameters + +| Name | Description | Value | +| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `metrics.enabled` | Start a exporter side-car | `false` | +| `metrics.image.registry` | Apache exporter image registry | `REGISTRY_NAME` | +| `metrics.image.repository` | Apache exporter image name | `REPOSITORY_NAME/apache-exporter` | +| `metrics.image.digest` | Apache exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `metrics.image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `metrics.podAnnotations` | Additional annotations for Metrics exporter pod | `{}` | +| `metrics.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). | `nano` | +| `metrics.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | + +### Certificate injection parameters + +| Name | Description | Value | +| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| `certificates.customCertificate.certificateSecret` | Secret containing the certificate and key to add | `""` | +| `certificates.customCertificate.chainSecret.name` | Name of the secret containing the certificate chain | `""` | +| `certificates.customCertificate.chainSecret.key` | Key of the certificate chain file inside the secret | `""` | +| `certificates.customCertificate.certificateLocation` | Location in the container to store the certificate | `/etc/ssl/certs/ssl-cert-snakeoil.pem` | +| `certificates.customCertificate.keyLocation` | Location in the container to store the private key | `/etc/ssl/private/ssl-cert-snakeoil.key` | +| `certificates.customCertificate.chainLocation` | Location in the container to store the certificate chain | `/etc/ssl/certs/mychain.pem` | +| `certificates.customCAs` | Defines a list of secrets to import into the container trust store | `[]` | +| `certificates.command` | Override default container command (useful when using custom images) | `[]` | +| `certificates.args` | Override default container args (useful when using custom images) | `[]` | +| `certificates.extraEnvVars` | Container sidecar extra environment variables (eg proxy) | `[]` | +| `certificates.extraEnvVarsCM` | ConfigMap containing extra env vars | `""` | +| `certificates.extraEnvVarsSecret` | Secret containing extra env vars (in case of sensitive data) | `""` | +| `certificates.image.registry` | Container sidecar registry | `REGISTRY_NAME` | +| `certificates.image.repository` | Container sidecar image | `REPOSITORY_NAME/os-shell` | +| `certificates.image.digest` | Container sidecar image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `certificates.image.pullPolicy` | Container sidecar image pull policy | `IfNotPresent` | +| `certificates.image.pullSecrets` | Container sidecar image pull secrets | `[]` | + +The above parameters map to the env variables defined in [bitnami/dokuwiki](https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki). For more information please refer to the [bitnami/dokuwiki](https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki) image documentation. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set dokuwikiUsername=admin,dokuwikiPassword=password \ + oci://REGISTRY_NAME/REPOSITORY_NAME/dokuwiki +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The above command sets the DokuWiki administrator account username and password to `admin` and `password` respectively. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://REGISTRY_NAME/REPOSITORY_NAME/dokuwiki +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. +> **Tip**: You can use the default [values.yaml](https://github.com/bitnami/charts/tree/main/bitnami/dokuwiki/values.yaml) + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### To 16.0.0 + +This major bump changes the following security defaults: + +- `runAsGroup` is changed from `0` to `1001` +- `readOnlyRootFilesystem` is set to `true` +- `resourcesPreset` is changed from `none` to the minimum size working in our test suites (NOTE: `resourcesPreset` is not meant for production usage, but `resources` adapted to your use case). +- `global.compatibility.openshift.adaptSecurityContext` is changed from `disabled` to `auto`. +- The `networkPolicy` section has been normalized amongst all Bitnami charts. Compared to the previous approach, the values section has been simplified (check the Parameters section) and now it set to `enabled=true` by default. Egress traffic is allowed by default and ingress traffic is allowed by all pods but only to the ports set in `containerPorts` and `extraContainerPorts`. + +This could potentially break any customization or init scripts used in your deployment. If this is the case, change the default values to the previous ones. + +### To 12.0.0 + +Some of the chart values were changed to adapt to the latest Bitnami standards. More specifically: + +- `containerPort` was changed to `containerPorts.http` +- `service.port` was changed to `service.ports.http` + +No issues should be expected when upgrading. + +### To 11.0.0 + +This version standardizes the way of defining Ingress rules. When configuring a single hostname for the Ingress rule, set the `ingress.hostname` value. When defining more than one, set the `ingress.extraHosts` array. Apart from this case, no issues are expected to appear when upgrading. + +### To 10.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +#### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Move dependency information from the *requirements.yaml* to the *Chart.yaml* +- After running `helm dependency update`, a *Chart.lock* file is generated containing the same structure used in the previous *requirements.lock* +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +#### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +#### Useful links + +- +- +- + +### To 7.0.0 + +This version also introduces `bitnami/common`, a [library chart](https://helm.sh/docs/topics/library_charts/#helm) as a dependency. More documentation about this new utility could be found [here](https://github.com/bitnami/charts/tree/main/bitnami/common#bitnami-common-library-chart). Please, make sure that you have updated the chart dependencies before executing any upgrade. + +The [Bitnami Dokuwiki](https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki) image was migrated to a "non-root" user approach. Previously the container ran as the `root` user and the Apache daemon was started as the `daemon` user. From now on, both the container and the Apache daemon run as user `1001`. You can revert this behavior by setting the parameters `containerSecurityContext.runAsUser` to `root`. + +Consequences: + +- The HTTP/HTTPS ports exposed by the container are now `8080/8443` instead of `80/443`. +- Backwards compatibility is not guaranteed. + +To upgrade to `7.0.0`, backup Drupal data and the previous MariaDB databases, install a new Drupal chart and import the backups and data, ensuring the `1001` user has the appropriate permissions on the migrated volume. + +### To 6.0.0 + +Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec. + +In the `apiVersion` of the deployment resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage. + +This major version signifies this change. + +### To 3.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to 3.0.0. The following example assumes that the release name is dokuwiki: + +```console +kubectl patch deployment dokuwiki-dokuwiki --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' +``` + +## License + +Copyright © 2024 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/charts/dokuwiki/charts/common-2.19.1.tgz b/charts/dokuwiki/charts/common-2.19.1.tgz new file mode 100644 index 0000000000000000000000000000000000000000..2aec1c88ed12d4638372b8677b0bd9e335975da3 GIT binary patch literal 15699 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 F0RZ?j)H?tG literal 0 HcmV?d00001 diff --git a/charts/dokuwiki/dokuwiki-16.0.2.tgz b/charts/dokuwiki/dokuwiki-16.0.2.tgz new file mode 100644 index 0000000000000000000000000000000000000000..423bfd95fd7a655555eb984aef0e4abb178eed74 GIT binary patch literal 91247 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 W=i%AV^M3;X0RR8yV(F;><^%vh@7yl{ literal 0 HcmV?d00001 diff --git a/charts/dokuwiki/templates/NOTES.txt b/charts/dokuwiki/templates/NOTES.txt new file mode 100644 index 0000000..a835320 --- /dev/null +++ b/charts/dokuwiki/templates/NOTES.txt @@ -0,0 +1,61 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.ingress.enabled }} + +1. Get the DokuWiki URL indicated on the Ingress Rule and associate it to your cluster external IP: + + export CLUSTER_IP=$(minikube ip) # On Minikube. Use: `kubectl cluster-info` on others K8s clusters + export HOSTNAME=$(kubectl get ingress --namespace {{ include "common.names.namespace" . }} {{ template "common.names.fullname" . }} -o jsonpath='{.spec.rules[0].host}') + echo "Dokuwiki URL: http://$HOSTNAME/" + echo "$CLUSTER_IP $HOSTNAME" | sudo tee -a /etc/hosts + +{{- else }} + +1. Get the DokuWiki URL by running: + +{{- if contains "NodePort" .Values.service.type }} + + export NODE_PORT=$(kubectl get --namespace {{ include "common.names.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "common.names.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ include "common.names.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo "URL: http://$NODE_IP:$NODE_PORT/" + +{{- else if contains "LoadBalancer" .Values.service.type }} + +** Please ensure an external IP is associated to the {{ template "common.names.fullname" . }} service before proceeding ** +** Watch the status using: kubectl get svc --namespace {{ include "common.names.namespace" . }} -w {{ template "common.names.fullname" . }} ** + + export SERVICE_IP=$(kubectl get svc --namespace {{ include "common.names.namespace" . }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + +{{- $port:=.Values.service.ports.http | toString }} + echo "URL: http://$SERVICE_IP{{- if ne $port "80" }}:{{ .Values.service.ports.http }}{{ end }}/" + +{{- else if contains "ClusterIP" .Values.service.type }} + + echo "URL: http://127.0.0.1:8080/" + kubectl port-forward --namespace {{ include "common.names.namespace" . }} svc/{{ template "common.names.fullname" . }} 8080:{{ .Values.service.ports.http }} + +{{- end }} +{{- end }} + +2. Login with the following credentials + + echo Username: {{ .Values.dokuwikiUsername }} + echo Password: $(kubectl get secret --namespace {{ include "common.names.namespace" . }} {{ include "dokuwiki.secretName" . }} -o jsonpath="{.data.dokuwiki-password}" | base64 -d) + +{{- include "dokuwiki.checkRollingTags" . }} + +{{- $requiredPasswords := list -}} +{{- $secretNameDockuwiki := include "dokuwiki.secretName" . -}} + +{{- if not .Values.existingSecret -}} + {{- $requiredDockuwikiPassword := dict "valueKey" "dokuwikiPassword" "secret" $secretNameDockuwiki "field" "dokuwiki-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredDockuwikiPassword -}} +{{- end -}} + +{{- $requiredDockuwikiPasswordErrors := include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" $) -}} +{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $requiredDockuwikiPasswordErrors) "context" $) -}} +{{- include "common.warnings.resources" (dict "sections" (list "metrics" "" "volumePermissions") "context" $) }} diff --git a/charts/dokuwiki/templates/_helpers.tpl b/charts/dokuwiki/templates/_helpers.tpl new file mode 100644 index 0000000..d157f83 --- /dev/null +++ b/charts/dokuwiki/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* +Return the proper certificate image name +*/}} +{{- define "certificates.image" -}} +{{- include "common.images.image" ( dict "imageRoot" .Values.certificates.image "global" .Values.global ) -}} +{{- end -}} + +{{/* +Return the proper DokuWiki image name +*/}} +{{- define "dokuwiki.image" -}} +{{- include "common.images.image" ( dict "imageRoot" .Values.image "global" .Values.global ) -}} +{{- end -}} + +{{/* +Return the proper image name (for the metrics image) +*/}} +{{- define "dokuwiki.metrics.image" -}} +{{- include "common.images.image" ( dict "imageRoot" .Values.metrics.image "global" .Values.global ) -}} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "dokuwiki.volumePermissions.image" -}} +{{- include "common.images.image" ( dict "imageRoot" .Values.volumePermissions.image "global" .Values.global ) -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "dokuwiki.imagePullSecrets" -}} +{{- include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.metrics.image .Values.volumePermissions.image .Values.certificates.image) "global" .Values.global) -}} +{{- end -}} + +{{/* + Create the name of the service account to use + */}} +{{- define "dokuwiki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Storage Class +*/}} +{{- define "dokuwiki.storageClass" -}} +{{- include "common.storage.class" ( dict "persistence" .Values.persistence "global" .Values.global ) -}} +{{- end -}} + +{{/* Dokuwiki credential secret name */}} +{{- define "dokuwiki.secretName" -}} +{{- coalesce .Values.existingSecret (include "common.names.fullname" .) -}} +{{- end -}} + +{{/* Check if there are rolling tags in the images */}} +{{- define "dokuwiki.checkRollingTags" -}} +{{- include "common.warnings.rollingTag" .Values.image -}} +{{- include "common.warnings.rollingTag" .Values.metrics.image -}} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image -}} +{{- include "common.warnings.rollingTag" .Values.certificates.image -}} +{{- end -}} diff --git a/charts/dokuwiki/templates/deployment.yaml b/charts/dokuwiki/templates/deployment.yaml new file mode 100644 index 0000000..7224998 --- /dev/null +++ b/charts/dokuwiki/templates/deployment.yaml @@ -0,0 +1,422 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: {{ template "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.updateStrategy }} + strategy: {{- toYaml .Values.updateStrategy | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + template: + metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + annotations: + {{- if .Values.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.podAnnotations "context" $) | nindent 8 }} + {{- end }} + spec: + {{- include "dokuwiki.imagePullSecrets" . | nindent 6 }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- if .Values.hostAliases }} + # yamllint disable rule:indentation + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + # yamllint enable rule:indentation + {{- end }} + serviceAccountName: {{ include "dokuwiki.serviceAccountName" .}} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName | quote }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + initContainers: + - name: prepare-base-dir + image: {{ include "dokuwiki.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + command: + - /bin/bash + args: + - -ec + - | + #!/bin/bash + + . /opt/bitnami/scripts/liblog.sh + . /opt/bitnami/scripts/libfs.sh + + info "Copying base dir to empty dir" + # In order to not break the application functionality (such as upgrades or plugins) we need + # to make the base directory writable, so we need to copy it to an empty dir volume + cp -r --preserve=mode /opt/bitnami/dokuwiki /emptydir/app-base-dir + + info "Copying symlinks to stdout/stderr" + # We copy the logs folder because it has symlinks to stdout and stderr + if ! is_dir_empty /opt/bitnami/apache/logs; then + cp -r /opt/bitnami/apache/logs /emptydir/apache-logs-dir + fi + info "Copy operation completed" + volumeMounts: + - name: empty-dir + mountPath: /emptydir + {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }} + - name: volume-permissions + image: {{ include "dokuwiki.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - sh + - -c + - | + mkdir -p /bitnami/dokuwiki + {{- if eq ( toString ( .Values.volumePermissions.containerSecurityContext.runAsUser )) "auto" }} + find /bitnami/dokuwiki -mindepth 0 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | xargs -r chown -R $(id -u):$(id -G | cut -d " " -f2) + {{- else }} + find /bitnami/dokuwiki -mindepth 0 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | xargs -r chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }} + {{- end }} + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.volumePermissions.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: dokuwiki-data + mountPath: /bitnami/dokuwiki + {{- end }} + {{- if .Values.certificates.customCAs }} + - name: certificates + image: {{ template "certificates.image" . }} + imagePullPolicy: {{ default .Values.image.pullPolicy .Values.certificates.image.pullPolicy }} + imagePullSecrets: + {{- range (default .Values.image.pullSecrets .Values.certificates.image.pullSecrets) }} + - name: {{ . }} + {{- end }} + command: + {{- if .Values.certificates.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.certificates.command "context" $) | nindent 12 }} + {{- else if .Values.certificates.customCertificate.certificateSecret }} + - sh + - -c + - install_packages ca-certificates openssl + {{- else }} + - sh + - -c + - install_packages ca-certificates openssl + && openssl req -new -x509 -days 3650 -nodes -sha256 + -subj "/CN=$(hostname)" -addext "subjectAltName = DNS:$(hostname)" + -out /etc/ssl/certs/ssl-cert-snakeoil.pem + -keyout /etc/ssl/private/ssl-cert-snakeoil.key -extensions v3_req + {{- end }} + {{- if .Values.certificates.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.certificates.args "context" $) | nindent 12 }} + {{- end }} + env: {{- include "common.tplvalues.render" (dict "value" .Values.certificates.extraEnvVars "context" $) | nindent 12 }} + envFrom: + {{- if .Values.certificates.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.certificates.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.certificates.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.certificates.extraEnvVarsSecret "context" $) }} + {{- end }} + volumeMounts: + - name: etc-ssl-certs + mountPath: /etc/ssl/certs + readOnly: false + - name: etc-ssl-private + mountPath: /etc/ssl/private + readOnly: false + - name: custom-ca-certificates + mountPath: /usr/local/share/ca-certificates + readOnly: true + {{- end }} + {{- if .Values.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: dokuwiki + image: {{ template "dokuwiki.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} + {{- end }} + env: + {{- if .Values.image.debug }} + - name: BITNAMI_DEBUG + value: "true" + {{- end }} + - name: DOKUWIKI_USERNAME + value: {{ .Values.dokuwikiUsername | quote }} + - name: DOKUWIKI_FULL_NAME + value: {{ .Values.dokuwikiFullName | quote }} + - name: DOKUWIKI_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "dokuwiki.secretName" . }} + key: dokuwiki-password + - name: DOKUWIKI_EMAIL + value: {{ .Values.dokuwikiEmail | quote }} + - name: DOKUWIKI_WIKI_NAME + value: {{ .Values.dokuwikiWikiName | quote }} + - name: APACHE_HTTP_PORT_NUMBER + value: {{ .Values.containerPorts.http | quote }} + - name: APACHE_HTTPS_PORT_NUMBER + value: {{ .Values.containerPorts.https | quote }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.containerPorts.http }} + - name: https + containerPort: {{ .Values.containerPorts.https }} + {{- if .Values.extraContainerPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraContainerPorts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /doku.php + port: http + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /doku.php + port: http + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- end }} + {{- if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.startupProbe.enabled }} + startupProbe: + httpGet: + path: /doku.php + port: http + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + {{- end }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + {{- if .Values.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + - name: empty-dir + mountPath: /opt/bitnami/apache/conf + subPath: apache-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/apache/logs + subPath: apache-logs-dir + - name: empty-dir + mountPath: /opt/bitnami/apache/var/run + subPath: apcahe-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/php/etc + subPath: php-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/php/tmp + subPath: php-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/php/var + subPath: php-var-dir + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/dokuwiki + subPath: app-base-dir + {{- if .Values.certificates.customCAs }} + - name: etc-ssl-certs + mountPath: /etc/ssl/certs/ + readOnly: false + - name: etc-ssl-private + mountPath: /etc/ssl/private/ + readOnly: false + - name: custom-ca-certificates + mountPath: /usr/local/share/ca-certificates + readOnly: true + {{- end }} + {{- if .Values.certificates.customCertificate.certificateSecret }} + - name: custom-certificate + mountPath: {{ .Values.certificates.customCertificate.certificateLocation }} + subPath: tls.crt + readOnly: true + - name: custom-certificate + mountPath: {{ .Values.certificates.customCertificate.keyLocation }} + subPath: tls.key + readOnly: true + {{- if .Values.certificates.customCertificate.chainSecret }} + - name: custom-certificate-chain + mountPath: {{ .Values.certificates.customCertificate.chainLocation }} + subPath: {{ .Values.certificates.customCertificate.chainSecret.key }} + readOnly: true + {{- end }} + {{- end }} + {{- if .Values.customPostInitScripts }} + - mountPath: /docker-entrypoint-init.d + name: custom-postinit + {{- end }} + {{- if .Values.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + - name: dokuwiki-data + mountPath: /bitnami/dokuwiki + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ template "dokuwiki.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + command: [ '/bin/apache_exporter', '--scrape_uri', 'http://status.localhost:8080/server-status/?auto'] + ports: + - name: metrics + containerPort: 9117 + livenessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 15 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 5 + timeoutSeconds: 1 + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- else if ne .Values.metrics.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.metrics.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: empty-dir + emptyDir: {} + {{- if .Values.certificates.customCAs }} + - name: etc-ssl-certs + emptyDir: + medium: "Memory" + - name: etc-ssl-private + emptyDir: + medium: "Memory" + - name: custom-ca-certificates + projected: + defaultMode: 0400 + sources: + {{- range $index, $customCA := .Values.certificates.customCAs }} + - secret: + name: {{ $customCA.secret }} + {{- end }} + {{- end }} + {{- if .Values.certificates.customCertificate.certificateSecret }} + - name: custom-certificate + secret: + secretName: {{ .Values.certificates.customCertificate.certificateSecret }} + {{- if .Values.certificates.customCertificate.chainSecret }} + - name: custom-certificate-chain + secret: + secretName: {{ .Values.certificates.customCertificate.chainSecret.name }} + {{- end }} + {{- end }} + - name: dokuwiki-data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ default (include "common.names.fullname" .) .Values.persistence.existingClaim }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.customPostInitScripts }} + - name: custom-postinit + configMap: + name: {{ printf "%s-postinit" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + defaultMode: 0755 + {{- end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} diff --git a/charts/dokuwiki/templates/dokuwiki-pvc.yaml b/charts/dokuwiki/templates/dokuwiki-pvc.yaml new file mode 100644 index 0000000..149ef4c --- /dev/null +++ b/charts/dokuwiki/templates/dokuwiki-pvc.yaml @@ -0,0 +1,30 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim ) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.commonAnnotations .Values.persistence.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.persistence.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + accessModes: + {{- if not (empty .Values.persistence.accessModes) }} + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + {{- else }} + - {{ .Values.persistence.accessMode | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{ include "dokuwiki.storageClass" . }} +{{- end -}} diff --git a/charts/dokuwiki/templates/extra-list.yaml b/charts/dokuwiki/templates/extra-list.yaml new file mode 100644 index 0000000..2d35a58 --- /dev/null +++ b/charts/dokuwiki/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/dokuwiki/templates/ingress.yaml b/charts/dokuwiki/templates/ingress.yaml new file mode 100644 index 0000000..4631527 --- /dev/null +++ b/charts/dokuwiki/templates/ingress.yaml @@ -0,0 +1,63 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.ingress.enabled }} +apiVersion: {{ template "common.capabilities.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + annotations: + {{- if .Values.ingress.certManager }} + kubernetes.io/tls-acme: "true" + {{- end }} + {{- if or .Values.commonAnnotations .Values.ingress.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.ingress.annotations .Values.commonAnnotations ) "context" . ) }} + {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.ingressClassName (include "common.ingress.supportsIngressClassname" .) }} + ingressClassName: {{ .Values.ingress.ingressClassName | quote }} + {{- end }} + rules: + {{- if .Values.ingress.hostname }} + - host: {{ .Values.ingress.hostname }} + http: + paths: + {{- if .Values.ingress.extraPaths }} + {{- toYaml .Values.ingress.extraPaths | nindent 10 }} + {{- end }} + - path: {{ .Values.ingress.path }} + {{- if eq "true" (include "common.ingress.supportsPathType" .) }} + pathType: {{ .Values.ingress.pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" .) "servicePort" "http" "context" $) | nindent 14 }} + {{- end }} + {{- range .Values.ingress.extraHosts }} + - host: {{ .name | quote }} + http: + paths: + - path: {{ default "/" .path }} + {{- if eq "true" (include "common.ingress.supportsPathType" $) }} + pathType: {{ default "ImplementationSpecific" .pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" "http" "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.ingress.extraRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraRules "context" $) | nindent 4 }} + {{- end }} + {{- if or .Values.ingress.tls .Values.ingress.extraTls }} + tls: + {{- if .Values.ingress.tls }} + - hosts: + - {{ .Values.ingress.hostname }} + secretName: {{ printf "%s-tls" .Values.ingress.hostname }} + {{- end }} + {{- if .Values.ingress.extraTls }} + {{- include "common.tplvalues.render" ( dict "value" .Values.ingress.extraTls "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/dokuwiki/templates/networkpolicy.yaml b/charts/dokuwiki/templates/networkpolicy.yaml new file mode 100644 index 0000000..2c75f53 --- /dev/null +++ b/charts/dokuwiki/templates/networkpolicy.yaml @@ -0,0 +1,70 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + policyTypes: + - Ingress + - Egress + {{- if .Values.networkPolicy.allowExternalEgress }} + egress: + - {} + {{- else }} + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + {{- if .Values.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} + ingress: + - ports: + - port: {{ .Values.containerPorts.http }} + - port: {{ .Values.containerPorts.https }} + {{- range .Values.extraContainerPorts }} + - port: {{ .containerPort }} + {{- end }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/dokuwiki/templates/postinit-configmap.yaml b/charts/dokuwiki/templates/postinit-configmap.yaml new file mode 100644 index 0000000..9e5a52c --- /dev/null +++ b/charts/dokuwiki/templates/postinit-configmap.yaml @@ -0,0 +1,20 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.customPostInitScripts }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-postinit" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + {{- if .Values.customPostInitScripts }} + {{- include "common.tplvalues.render" (dict "value" .Values.customPostInitScripts "context" $) | nindent 2 }} + {{- end }} +{{- end }} diff --git a/charts/dokuwiki/templates/secrets.yaml b/charts/dokuwiki/templates/secrets.yaml new file mode 100644 index 0000000..d77616f --- /dev/null +++ b/charts/dokuwiki/templates/secrets.yaml @@ -0,0 +1,23 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if not .Values.existingSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{ if .Values.dokuwikiPassword }} + dokuwiki-password: {{ .Values.dokuwikiPassword | b64enc | quote }} + {{ else }} + dokuwiki-password: {{ randAlphaNum 10 | b64enc | quote }} + {{ end }} +{{- end }} diff --git a/charts/dokuwiki/templates/serviceaccount.yaml b/charts/dokuwiki/templates/serviceaccount.yaml new file mode 100644 index 0000000..91895e4 --- /dev/null +++ b/charts/dokuwiki/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "dokuwiki.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end -}} diff --git a/charts/dokuwiki/templates/svc.yaml b/charts/dokuwiki/templates/svc.yaml new file mode 100644 index 0000000..69ec5d0 --- /dev/null +++ b/charts/dokuwiki/templates/svc.yaml @@ -0,0 +1,53 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.commonAnnotations .Values.service.annotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerSourceRanges)) }} + loadBalancerSourceRanges: {{ .Values.service.loadBalancerSourceRanges }} + {{- end }} + {{- if .Values.service.sessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} + {{- if .Values.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: http + port: {{ .Values.service.ports.http }} + targetPort: http + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePorts.http))) }} + nodePort: {{ .Values.service.nodePorts.http }} + {{- end }} + - name: https + port: {{ .Values.service.ports.https }} + targetPort: https + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePorts.https))) }} + nodePort: {{ .Values.service.nodePorts.https }} + {{- end }} + {{- if .Values.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} diff --git a/charts/dokuwiki/templates/tls-secrets.yaml b/charts/dokuwiki/templates/tls-secrets.yaml new file mode 100644 index 0000000..2d3d824 --- /dev/null +++ b/charts/dokuwiki/templates/tls-secrets.yaml @@ -0,0 +1,44 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.ingress.enabled }} +{{- if .Values.ingress.secrets }} +{{- range .Values.ingress.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + namespace: {{ include "common.names.namespace" $ | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $.Values.commonLabels "context" $ ) | nindent 4 }} + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate | b64enc }} + tls.key: {{ .key | b64enc }} +--- +{{- end }} +{{- end }} +{{- if and .Values.ingress.tls .Values.ingress.selfSigned }} +{{- $secretName := printf "%s-tls" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} +{{- $ca := genCA "dokuwiki-ca" 365 }} +{{- $cert := genSignedCert .Values.ingress.hostname nil (list .Values.ingress.hostname) 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.crt" "defaultValue" $cert.Cert "context" $) }} + tls.key: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.key" "defaultValue" $cert.Key "context" $) }} + ca.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" $ca.Cert "context" $) }} +{{- end }} +{{- end }} diff --git a/charts/dokuwiki/values.schema.json b/charts/dokuwiki/values.schema.json new file mode 100644 index 0000000..53992d3 --- /dev/null +++ b/charts/dokuwiki/values.schema.json @@ -0,0 +1,758 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "resources": { + "description": "Your service will have at least the requested resources and never more than its limits. No limit for a resource and you can consume everything left on the host machine.", + "type": "object", + "properties": { + "requests": { + "description": "Guaranteed resources", + "type": "object", + "properties": { + "cpu": { + "description": "The amount of cpu guaranteed", + "title": "CPU", + "type": "string", + "default": "100m", + "render": "slider", + "sliderMin": 50, + "sliderMax": 40000, + "sliderStep": 50, + "sliderUnit": "m", + "sliderExtremity": "down", + "sliderExtremitySemantic": "guaranteed", + "sliderRangeId": "cpu", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.cpuRequest", + "useRegionSliderConfig": "cpu" + } + }, + "memory": { + "description": "The amount of memory guaranteed", + "title": "memory", + "type": "string", + "default": "2Gi", + "render": "slider", + "sliderMin": 1, + "sliderMax": 200, + "sliderStep": 1, + "sliderUnit": "Gi", + "sliderExtremity": "down", + "sliderExtremitySemantic": "guaranteed", + "sliderRangeId": "memory", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.memoryRequest", + "useRegionSliderConfig": "memory" + } + } + } + }, + "limits": { + "description": "max resources", + "type": "object", + "properties": { + "cpu": { + "description": "The maximum amount of cpu", + "title": "CPU", + "type": "string", + "default": "30000m", + "render": "slider", + "sliderMin": 50, + "sliderMax": 40000, + "sliderStep": 50, + "sliderUnit": "m", + "sliderExtremity": "up", + "sliderExtremitySemantic": "Maximum", + "sliderRangeId": "cpu", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.cpuLimit", + "useRegionSliderConfig": "cpu" + } + }, + "memory": { + "description": "The maximum amount of memory", + "title": "Memory", + "type": "string", + "default": "50Gi", + "render": "slider", + "sliderMin": 1, + "sliderMax": 200, + "sliderStep": 1, + "sliderUnit": "Gi", + "sliderExtremity": "up", + "sliderExtremitySemantic": "Maximum", + "sliderRangeId": "memory", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.memoryLimit", + "useRegionSliderConfig": "memory" + } + } + } + } + } + }, + "discovery": { + "description": "configure your service to autodetect some ressources.", + "type": "object", + "properties": { + "hive": { + "type": "boolean", + "title": "Enable hive metastore discovery", + "description": "discover your hive metastore service", + "default": true + }, + "mlflow": { + "type": "boolean", + "title": "Enable mlflow discovery", + "description": "discover your mlflow service", + "default": true + }, + "metaflow": { + "type": "boolean", + "title": "Enable metaflow discovery", + "description": "discover your metaflow service", + "default": true + } + } + }, + "service": { + "description": "spark-history specific configuration", + "type": "object", + "properties": { + "image": { + "description": "image docker", + "type": "object", + "properties": { + "pullPolicy": { + "type": "string", + "description": "option when pulling the docker image", + "default": "IfNotPresent", + "enum": [ + "IfNotPresent", + "Always", + "Never" + ] + }, + "version": { + "description": "vscode supported version", + "type": "string", + "default": "inseefrlab/onyxia-vscode-python:py3.11.6", + "listEnum": [ + "inseefrlab/onyxia-vscode-python:py3.11.6", + "inseefrlab/onyxia-vscode-python:py3.10.13" + ], + "render": "list", + "hidden": { + "value": true, + "path": "service/image/custom/enabled" + } + }, + "custom": { + "description": "use a custom vscode docker image", + "type": "object", + "properties": { + "enabled": { + "title": "custom image", + "type": "boolean", + "description": "use a custom vscode docker images", + "default": false + }, + "version": { + "description": "vscode unsupported version", + "type": "string", + "default": "inseefrlab/onyxia-vscode-python:py3.11.6", + "hidden": { + "value": false, + "path": "service/image/custom/enabled" + } + } + } + } + } + } + } + }, + "persistence": { + "description": "Configuration for persistence", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Create a persistent volume", + "default": true + }, + "size": { + "type": "string", + "title": "Persistent volume size", + "description": "Size of the persistent volume", + "default": "10Gi", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderStep": 1, + "sliderUnit": "Gi", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.disk", + "useRegionSliderConfig": "disk" + }, + "hidden": { + "value": false, + "path": "persistence/enabled" + } + } + } + }, + "security": { + "description": "security specific configuration", + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "Password", + "default": "changeme", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{project.password}}" + } + }, + "allowlist": { + "type": "object", + "description": "IP protection", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable IP protection", + "description": "Only the configured set of IPs will be able to reach the service", + "default": true, + "x-onyxia": { + "overwriteDefaultWith": "region.defaultIpProtection" + } + }, + "ip": { + "type": "string", + "description": "the white list of IP is whitespace", + "title": "Whitelist of IP", + "x-onyxia": { + "overwriteDefaultWith": "{{user.ip}}" + } + } + } + }, + "networkPolicy": { + "type": "object", + "description": "Define access policy to the service", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable network policy", + "description": "Only pod from the same namespace will be allowed", + "default": true, + "x-onyxia": { + "overwriteDefaultWith": "region.defaultNetworkPolicy" + } + }, + "from": { + "type": "array", + "description": "Array of source allowed to have network access to your service", + "default": [], + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.from" + } + } + } + } + } + }, + "kubernetes": { + "description": "configuration of your kubernetes access", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "allow your service to access your namespace ressources", + "default": true + }, + "role": { + "type": "string", + "description": "bind your service account to this kubernetes default role", + "default": "view", + "hidden": { + "value": false, + "path": "kubernetes/enabled" + }, + "enum": [ + "view", + "edit", + "admin" + ] + } + } + }, + "git": { + "description": "Git user configuration", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Add git config inside your environment", + "default": true + }, + "name": { + "type": "string", + "description": "user name for git", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.name}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "email": { + "type": "string", + "description": "user email for git", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.email}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "cache": { + "type": "string", + "description": "duration in seconds of the credentials cache duration", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.credentials_cache_duration}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "token": { + "type": "string", + "description": "personal access token", + "default": "", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{git.token}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "repository": { + "type": "string", + "description": "projet", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.project}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "branch": { + "type": "string", + "description": "Branch automatically checked out", + "default": "", + "hidden": { + "value": "", + "path": "git/repository" + } + } + } + }, + "vault": { + "description": "Configuration of vault client", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Add vault temporary identity inside your environment", + "default": true + }, + "token": { + "description": "token vault", + "type": "string", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_TOKEN}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "url": { + "description": "url of vault server", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_ADDR}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "mount": { + "description": "mount of the v2 secret engine", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_MOUNT}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "directory": { + "description": "top level directory", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_TOP_DIR}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "secret": { + "description": "the path of the secret to convert into a list of environment variables", + "type": "string", + "default": "", + "hidden": { + "value": false, + "path": "vault/enabled" + } + } + } + }, + "s3": { + "description": "Configuration of temporary identity", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Add S3 temporary identity inside your environment", + "default": true + }, + "accessKeyId": { + "description": "AWS Access Key", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "s3.AWS_ACCESS_KEY_ID" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "endpoint": { + "description": "AWS S3 Endpoint", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_S3_ENDPOINT}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "defaultRegion": { + "description": "AWS S3 default region", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_DEFAULT_REGION}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "secretAccessKey": { + "description": "AWS S3 secret access key", + "type": "string", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_SECRET_ACCESS_KEY}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "sessionToken": { + "description": "AWS S3 session Token", + "type": "string", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_SESSION_TOKEN}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + } + } + }, + "ingress": { + "type": "object", + "form": true, + "title": "Ingress Details", + "properties": { + "enabled": { + "description": "Enable Ingress", + "type": "boolean", + "default": true, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.ingress" + } + }, + "hostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-0.{{k8s.domain}}" + } + }, + "userHostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-user.{{k8s.domain}}" + } + }, + "ingressClassName": { + "type": "string", + "form": true, + "title": "ingressClassName", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{k8s.ingressClassName}}" + } + }, + "useCertManager": { + "type": "boolean", + "description": "Whether CertManager should be used to generate a certificate", + "default": false, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.useCertManager" + } + }, + "certManagerClusterIssuer":{ + "type": "string", + "description": "certManager cluster issuer", + "title": "CertManager Cluster Issuer", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.certManagerClusterIssuer" + } + } + } + }, + "route": { + "type": "object", + "form": true, + "title": "Route details", + "properties": { + "enabled": { + "description": "Enable route", + "type": "boolean", + "default": false, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.route" + } + }, + "hostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-0.{{k8s.domain}}" + } + }, + "userHostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-user.{{k8s.domain}}" + } + } + } + }, + "networking": { + "type": "object", + "form": true, + "title": "Networking detail", + "properties": { + "user": { + "type": "object", + "description": "user defined port", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable a custom service port", + "description": "Enable a custom service port", + "default": false + }, + "port": { + "type": "integer", + "description": "port of the custom service", + "title": "Custom service port", + "hidden": { + "value": false, + "path": "networking/user/enabled" + }, + "default": 5000 + } + } + } + } + }, + "init": { + "description": "Init parameters", + "type": "object", + "properties": { + "regionInit": { + "type": "string", + "description": "region initialization script", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{k8s.initScriptUrl}}" + } + }, + "regionInitCheckSum": { + "type": "string", + "description": "region initialization script", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{k8s.initScriptCheckSum}}" + } + }, + "personalInit": { + "type": "string", + "description": "user initialization script", + "default": "" + }, + "personalInitArgs": { + "type": "string", + "description": "args for user initialization script", + "default": "" + } + } + }, + "repository": { + "description": "python repositories for pip and conda", + "type": "object", + "properties": { + "pipRepository": { + "type": "string", + "description": "python repository for pip", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{packageRepositoryInjection.pypiProxyUrl}}" + } + }, + "condaRepository": { + "type": "string", + "description": "python repository for pip", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{packageRepositoryInjection.condaProxyUrl}}" + } + } + } + }, + "startupProbe": { + "type": "object", + "description": "Start up probe", + "default": {}, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.startupProbe" + } + }, + "tolerations": { + "type": "array", + "description": "Array of tolerations", + "default": [], + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.tolerations" + } + }, + "nodeSelector": { + "type": "object", + "description": "NodeSelector", + "default": {}, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.nodeSelector" + } + }, + "userPreferences": { + "description": "User Preferences", + "type": "object", + "properties": { + "darkMode": { + "type": "boolean", + "description": "dark mode is or is not enabled", + "default": false, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "user.darkMode" + } + }, + "language": { + "type": "string", + "description": "Preferred language", + "default": "en", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "user.lang" + } + } + } + }, + "global": { + "description": "Suspend", + "type": "object", + "properties": { + "suspend": { + "type": "boolean", + "description": "Suspend this service", + "default": false, + "x-onyxia": { + "hidden": true + } + } + } + } + } +} \ No newline at end of file diff --git a/charts/dokuwiki/values.yaml b/charts/dokuwiki/values.yaml new file mode 100644 index 0000000..ede6cd8 --- /dev/null +++ b/charts/dokuwiki/values.yaml @@ -0,0 +1,794 @@ +# Copyright VMware, Inc. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass +## + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.storageClass Global StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + storageClass: "" + ## Compatibility adaptations for Kubernetes platforms + ## + compatibility: + ## Compatibility adaptations for Openshift + ## + openshift: + ## @param global.compatibility.openshift.adaptSecurityContext Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) + ## + adaptSecurityContext: auto +## @section Common parameters +## + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override dokuwiki.fullname template with a string (will prepend the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override dokuwiki.fullname template with a string +## +fullnameOverride: "" +## @param namespaceOverride String to fully override common.names.namespace +## +namespaceOverride: "" +## @param commonAnnotations Annotations to add to all deployed objects +## +commonAnnotations: {} +## @param commonLabels Labels to add to all deployed objects +## +commonLabels: {} +## @param extraDeploy Array of extra objects to deploy with the release (evaluated as a template). +## +extraDeploy: [] +## @section Dokuwiki parameters +## + +## Bitnami DokuWiki image version +## ref: https://hub.docker.com/r/bitnami/dokuwiki/tags/ +## @param image.registry [default: REGISTRY_NAME] DokuWiki image registry +## @param image.repository [default: REPOSITORY_NAME/dokuwiki] DokuWiki image repository +## @skip image.tag DokuWiki image tag +## @param image.digest DokuWiki image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param image.pullPolicy Image pull policy +## @param image.pullSecrets Image pull policy +## @param image.debug Enable image debugging +## +image: + registry: docker.io + repository: bitnami/dokuwiki + tag: 20240206.1.0-debian-12-r5 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Set to true if you would like to see extra information on logs + ## It turns BASH and/or NAMI debugging in the image + ## + debug: false +## @param automountServiceAccountToken Mount Service Account token in pod +## +automountServiceAccountToken: false +## @param hostAliases [array] Add deployment host aliases +## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +## +hostAliases: + ## Necessary for apache-exporter to work + ## + - ip: "127.0.0.1" + hostnames: + - "status.localhost" +## @param dokuwikiUsername User of the application +## ref: https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki#environment-variables +## +dokuwikiUsername: user +## @param dokuwikiPassword Application password +## Defaults to a random 10-character alphanumeric string if not set +## ref: https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki#environment-variables +## +dokuwikiPassword: "" +## @param existingSecret Use an existing secret with the dokuwiki password +## +existingSecret: "" +## @param dokuwikiEmail Admin email +## ref: https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki#environment-variables +## +dokuwikiEmail: user@example.com +## @param dokuwikiFullName User's Full Name +## ref: https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki#environment-variables +## +dokuwikiFullName: User Name +## @param dokuwikiWikiName Wiki name +## ref: https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki#environment-variables +## +dokuwikiWikiName: My Wiki +## @param customPostInitScripts Custom post-init.d user scripts +## ref: https://github.com/bitnami/containers/tree/main/bitnami/dokuwiki +## NOTE: supported formats are `.sh` or `.php` +## NOTE: scripts are exclusively executed during the 1st boot of the container +## e.g: +## customPostInitScripts: +## custom-post-init.sh: | +## #!/bin/bash +## echo "Hello from custom-post-init.sh" +## .htaccess: | +## RewriteEngine On +## RewriteBase / +## ... +## +customPostInitScripts: {} +## @param updateStrategy Strategy to use to update Pods +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +## +updateStrategy: {} +## @param topologySpreadConstraints Topology Spread Constraints for pod assignment +## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## The value is evaluated as a template +## +topologySpreadConstraints: [] +## Enable persistence using Persistent Volume Claims +## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ +## @param persistence.enabled Enable persistence using PVC +## @param persistence.storageClass PVC Storage Class for DokuWiki volume +## @param persistence.accessModes [array] PVC Access Mode for DokuWiki volume +## @param persistence.size PVC Storage Request for DokuWiki volume +## @param persistence.existingClaim Name of an existing PVC to be used +## @param persistence.annotations Annotations to add to the PVC +## +persistence: + enabled: true + ## Dokuwiki data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + accessModes: + - ReadWriteOnce + size: 8Gi + existingClaim: "" + annotations: {} +## @param podSecurityContext.enabled Enable securityContext on for DokuWiki deployment +## @param podSecurityContext.fsGroupChangePolicy Set filesystem group change policy +## @param podSecurityContext.sysctls Set kernel settings using the sysctl interface +## @param podSecurityContext.supplementalGroups Set filesystem extra groups +## @param podSecurityContext.fsGroup Group to configure permissions for volumes +## +podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 +## SecurityContext configuration for the container +## @param containerSecurityContext.enabled Enabled Dokuwiki containers' Security Context +## @param containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container +## @param containerSecurityContext.runAsUser Set Dokuwiki containers' Security Context runAsUser +## @param containerSecurityContext.runAsGroup Set Dokuwiki containers' Security Context runAsGroup +## @param containerSecurityContext.runAsNonRoot Set Controller container's Security Context runAsNonRoot +## @param containerSecurityContext.privileged Set primary container's Security Context privileged +## @param containerSecurityContext.readOnlyRootFilesystem Set primary container's Security Context readOnlyRootFilesystem +## @param containerSecurityContext.allowPrivilegeEscalation Set primary container's Security Context allowPrivilegeEscalation +## @param containerSecurityContext.capabilities.drop List of capabilities to be dropped +## @param containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile +## +containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + readOnlyRootFilesystem: true +## Configure resource requests and limits +## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). +## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 +## +resourcesPreset: "micro" +## @param resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) +## Example: +## resources: +## requests: +## cpu: 2 +## memory: 512Mi +## limits: +## cpu: 3 +## memory: 1024Mi +## +resources: {} +## Configure extra options for liveness and readiness probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) +## @param livenessProbe.enabled Enable/disable the liveness probe +## @param livenessProbe.initialDelaySeconds Delay before liveness probe is initiated +## @param livenessProbe.periodSeconds How often to perform the probe +## @param livenessProbe.timeoutSeconds When the probe times out +## @param livenessProbe.failureThreshold Minimum consecutive failures to be considered failed +## @param livenessProbe.successThreshold Minimum consecutive successes to be considered successful +## +livenessProbe: + enabled: true + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +## Configure extra options for liveness and readiness probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) +## @param readinessProbe.enabled Enable/disable the readiness probe +## @param readinessProbe.initialDelaySeconds Delay before readinessProbe is initiated +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds When the probe times out +## @param readinessProbe.failureThreshold Minimum consecutive failures to be considered failed +## @param readinessProbe.successThreshold Minimum consecutive successes to be considered successful +## +readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +## Configure extra options for startup and readiness probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-startup-readiness-probes/#configure-probes) +## @param startupProbe.enabled Enable/disable the startup probe +## @param startupProbe.initialDelaySeconds Delay before startup probe is initiated +## @param startupProbe.periodSeconds How often to perform the probe +## @param startupProbe.timeoutSeconds When the probe times out +## @param startupProbe.failureThreshold Minimum consecutive failures to be considered failed +## @param startupProbe.successThreshold Minimum consecutive successes to be considered successful +## +startupProbe: + enabled: false + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAffinityPreset: "" +## @param podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAntiAffinityPreset: soft +## Node affinity preset +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +## @param nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## @param nodeAffinityPreset.key Node label key to match Ignored if `affinity` is set. +## @param nodeAffinityPreset.values Node label values to match. Ignored if `affinity` is set. +## +nodeAffinityPreset: + type: "" + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] +## @param affinity Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector Node labels for pod assignment +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ +## +nodeSelector: {} +## @param tolerations Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +## @param command Override default container command (useful when using custom images) +## +command: [] +## @param args Override default container args (useful when using custom images) +## +args: [] +## @param extraEnvVars An array to add extra env vars +## +extraEnvVars: [] +## @param extraEnvVarsCM ConfigMap containing extra env vars +## +extraEnvVarsCM: "" +## @param extraEnvVarsSecret Secret containing extra env vars (in case of sensitive data) +## +extraEnvVarsSecret: "" +## @param podAnnotations Pod annotations +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param customLivenessProbe Override default liveness probe +## +customLivenessProbe: {} +## @param customReadinessProbe Override default readiness probe +## +customReadinessProbe: {} +## @param customStartupProbe Override default startup probe +## +customStartupProbe: {} +## @param extraVolumes Array of extra volumes to be added to the deployment (evaluated as template). Requires setting `extraVolumeMounts` +## +extraVolumes: [] +## @param extraVolumeMounts Array of extra volume mounts to be added to the container (evaluated as template). Normally used with `extraVolumes`. +## +extraVolumeMounts: [] +## @param lifecycleHooks LifecycleHook to set additional configuration at startup. Evaluated as a template +## +lifecycleHooks: {} +## @param podLabels Add additional labels to the pod (evaluated as a template) +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @param initContainers Attach additional init containers to the pod (evaluated as a template) +## +initContainers: [] +## @param sidecars Attach additional containers to the pod (evaluated as a template) +## +sidecars: [] +## @param priorityClassName Priority class assigned to the Pods +## +priorityClassName: "" +## @param schedulerName Alternative scheduler +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param terminationGracePeriodSeconds In seconds, time the given to the pod to terminate gracefully +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods +## +terminationGracePeriodSeconds: "" +## @param containerPorts.http Container HTTP port +## @param containerPorts.https Container HTTPS port +## +containerPorts: + http: 8080 + https: 8443 +## @param extraContainerPorts Optionally specify extra list of additional ports for Dokuwiki container(s) +## e.g: +## extraContainerPorts: +## - name: myservice +## containerPort: 9090 +## +extraContainerPorts: [] +## Service Account +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## +serviceAccount: + ## @param serviceAccount.create Enable creation of ServiceAccount for Dokuwiki pod + ## + create: true + ## @param serviceAccount.name The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the common.names.fullname template + ## + name: "" + ## @param serviceAccount.automountServiceAccountToken Allows auto mount of ServiceAccountToken on the serviceAccount created + ## Can be set to false if pods using this serviceAccount do not need to use K8s API + ## + automountServiceAccountToken: false + ## @param serviceAccount.annotations Additional custom annotations for the ServiceAccount + ## + annotations: {} +## @section Traffic Exposure Parameters +## + +## Kubernetes svc configuration +## +service: + ## @param service.type Kubernetes Service type + ## For minikube, set this to NodePort, elsewhere use LoadBalancer + ## + type: LoadBalancer + ## @param service.loadBalancerIP Use serviceLoadBalancerIP to request a specific static IP, otherwise leave blank + ## + loadBalancerIP: "" + ## @param service.ports.http Service HTTP port + ## @param service.ports.https Service HTTPS port + ## + ports: + http: 80 + https: 443 + ## + ## @param service.nodePorts [object] Use nodePorts to request some specific ports when using NodePort + ## nodePorts: + ## http: + ## https: + ## + nodePorts: + http: "" + https: "" + ## @param service.clusterIP Kubernetes service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param service.loadBalancerSourceRanges Kubernetes service Load Balancer sources + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.extraPorts Extra ports to expose in the service (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param service.annotations Annotations to add to the service + ## + annotations: {} + ## @param service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} +## Network Policy configuration +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +## +networkPolicy: + ## @param networkPolicy.enabled Specifies whether a NetworkPolicy should be created + ## + enabled: true + ## @param networkPolicy.allowExternal Don't require server label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## server label will have network access to the ports server is listening + ## on. When true, server will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.allowExternalEgress Allow the pod to access any range of port and all destinations. + ## + allowExternalEgress: true + ## @param networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolice + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + extraIngress: [] + ## @param networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} +## Configure the ingress resource that allows you to access the +## Dokuwiki installation. Set up the URL +## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/ +## +ingress: + ## @param ingress.enabled Set to true to enable ingress record generation + ## + enabled: false + ## DEPRECATED: Use ingress.annotations instead of ingress.certManager + ## certManager: false + ## + + ## @param ingress.pathType Ingress Path type + ## + pathType: ImplementationSpecific + ## @param ingress.apiVersion Override API Version (automatically detected if not set) + ## + apiVersion: "" + ## @param ingress.hostname When the ingress is enabled, a host pointing to this will be created + ## + hostname: dokuwiki.local + ## @param ingress.path The Path to Dokuwiki. You may need to set this to '/*' in order to use this + ## with ALB ingress controllers. + ## + path: / + ## @param ingress.annotations Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. + ## For a full list of possible ingress annotations, please see + ## ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md + ## Use this parameter to set the required annotations for cert-manager, see + ## ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations + ## + ## e.g: + ## annotations: + ## kubernetes.io/ingress.class: nginx + ## cert-manager.io/cluster-issuer: cluster-issuer-name + ## + annotations: {} + ## @param ingress.tls Enable TLS configuration for the hostname defined at ingress.hostname parameter + ## TLS certificates will be retrieved from a TLS secret with name: {{- printf "%s-tls" .Values.ingress.hostname }} + ## You can use the ingress.secrets parameter to create this TLS secret or relay on cert-manager to create it + ## + tls: false + ## @param ingress.extraHosts The list of additional hostnames to be covered with this ingress record. + ## Most likely the hostname above will be enough, but in the event more hosts are needed, this is an array + ## extraHosts: + ## - name: dokuwiki.local + ## path: / + ## + extraHosts: [] + ## @param ingress.extraPaths Any additional arbitrary paths that may need to be added to the ingress under the main host. + ## For example: The ALB ingress controller requires a special rule for handling SSL redirection. + ## extraPaths: + ## - path: /* + ## backend: + ## serviceName: ssl-redirect + ## servicePort: use-annotation + ## + extraPaths: [] + ## @param ingress.extraTls The tls configuration for additional hostnames to be covered with this ingress record. + ## see: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + ## extraTls: + ## - hosts: + ## - dokuwiki.local + ## secretName: dokuwiki.local-tls + ## + extraTls: [] + ## @param ingress.secrets If you're providing your own certificates, please use this to add the certificates as secrets + ## key and certificate should start with -----BEGIN CERTIFICATE----- or + ## -----BEGIN RSA PRIVATE KEY----- + ## + ## name should line up with a tlsSecret set further up + ## If you're using cert-manager, this is unneeded, as it will create the secret for you if it is not set + ## + ## It is also possible to create and manage the certificates outside of this helm chart + ## Please see README.md for more information + ## Example: + ## - name: dokuwiki.local-tls + ## key: + ## certificate: + ## + secrets: [] + ## @param ingress.ingressClassName IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) + ## + ingressClassName: "" + ## @param ingress.selfSigned Create a TLS secret for this ingress record using self-signed certificates generated by Helm + ## + selfSigned: false + ## @param ingress.extraRules Additional rules to be covered with this ingress record + ## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules + ## e.g: + ## extraRules: + ## - host: example.local + ## http: + ## path: / + ## backend: + ## service: + ## name: example-svc + ## port: + ## name: http + ## + extraRules: [] +## @section Volume Permissions parameters +## + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) + ## + enabled: false + ## @param volumePermissions.image.registry [default: REGISTRY_NAME] Init container volume-permissions image registry + ## @param volumePermissions.image.repository [default: REPOSITORY_NAME/os-shell] Init container volume-permissions image name + ## @skip volumePermissions.image.tag Init container volume-permissions image tag + ## @param volumePermissions.image.digest Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## @param volumePermissions.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 12-debian-12-r18 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + pullSecrets: [] + ## - myRegistryKeySecretName + ## Init containers' resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param volumePermissions.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param volumePermissions.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## Init container' Security Context + ## Note: the chown of the data folder is done to containerSecurityContext.runAsUser + ## and not the below volumePermissions.containerSecurityContext.runAsUser + ## @param volumePermissions.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param volumePermissions.containerSecurityContext.runAsUser User ID for the init container + ## + containerSecurityContext: + seLinuxOptions: null + runAsUser: 0 +## @section Metrics parameters +## + +## Prometheus Exporter / Metrics +## +metrics: + ## @param metrics.enabled Start a exporter side-car + ## + enabled: false + ## @param metrics.image.registry [default: REGISTRY_NAME] Apache exporter image registry + ## @param metrics.image.repository [default: REPOSITORY_NAME/apache-exporter] Apache exporter image name + ## @skip metrics.image.tag Apache exporter image tag + ## @param metrics.image.digest Apache exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param metrics.image.pullPolicy Image pull policy + ## @param metrics.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/apache-exporter + tag: 1.0.7-debian-12-r3 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param metrics.podAnnotations [object] Additional annotations for Metrics exporter pod + ## + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9117" + ## @param metrics.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param metrics.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## + resources: {} +## @section Certificate injection parameters +## + +## Add custom certificates and certificate authorities to redmine container +## +certificates: + ## @param certificates.customCertificate.certificateSecret Secret containing the certificate and key to add + ## @param certificates.customCertificate.chainSecret.name Name of the secret containing the certificate chain + ## @param certificates.customCertificate.chainSecret.key Key of the certificate chain file inside the secret + ## @param certificates.customCertificate.certificateLocation Location in the container to store the certificate + ## @param certificates.customCertificate.keyLocation Location in the container to store the private key + ## @param certificates.customCertificate.chainLocation Location in the container to store the certificate chain + ## + customCertificate: + certificateSecret: "" + chainSecret: + name: "" + key: "" + certificateLocation: /etc/ssl/certs/ssl-cert-snakeoil.pem + keyLocation: /etc/ssl/private/ssl-cert-snakeoil.key + chainLocation: /etc/ssl/certs/mychain.pem + ## @param certificates.customCAs Defines a list of secrets to import into the container trust store + ## + customCAs: [] + ## @param certificates.command Override default container command (useful when using custom images) + ## + command: [] + ## @param certificates.args Override default container args (useful when using custom images) + ## args: + ## - secret: custom-CA + ## - secret: more-custom-CAs + ## + args: [] + ## @param certificates.extraEnvVars Container sidecar extra environment variables (eg proxy) + ## + extraEnvVars: [] + ## @param certificates.extraEnvVarsCM ConfigMap containing extra env vars + ## + extraEnvVarsCM: "" + ## @param certificates.extraEnvVarsSecret Secret containing extra env vars (in case of sensitive data) + ## + extraEnvVarsSecret: "" + ## @param certificates.image.registry [default: REGISTRY_NAME] Container sidecar registry + ## @param certificates.image.repository [default: REPOSITORY_NAME/os-shell] Container sidecar image + ## @skip certificates.image.tag Container sidecar image tag + ## @param certificates.image.digest Container sidecar image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param certificates.image.pullPolicy Container sidecar image pull policy + ## @param certificates.image.pullSecrets Container sidecar image pull secrets + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 12-debian-12-r18 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images + ## + pullPolicy: IfNotPresent + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] diff --git a/charts/harbor-helm-main/.github/release.yml b/charts/harbor-helm-main/.github/release.yml new file mode 100644 index 0000000..6e85c81 --- /dev/null +++ b/charts/harbor-helm-main/.github/release.yml @@ -0,0 +1,36 @@ +# .github/release.yml + +changelog: + exclude: + labels: + - release-note/ignore-for-release + authors: + - octocat + categories: + - title: Exciting New Features 🎉 + labels: + - release-note/new-feature + - title: Enhancement 🚀 + labels: + - release-note/enhancement + - title: Component updates ⬆️ + labels: + - release-note/update + - title: Docs update 🗄️ + labels: + - release-note/docs + - title: Community update 🧑🏻‍🤝‍🧑🏾 + labels: + - release-note/community + + - title: Breaking Changes đź›  + labels: + - release-note/breaking-change + + - title: Deprecations ❌ + labels: + - release-note/deprecation + + - title: Other Changes + labels: + - "*" diff --git a/charts/harbor-helm-main/.github/workflows/housekeeping-stale-issues-prs.yaml b/charts/harbor-helm-main/.github/workflows/housekeeping-stale-issues-prs.yaml new file mode 100644 index 0000000..57a2b0d --- /dev/null +++ b/charts/harbor-helm-main/.github/workflows/housekeeping-stale-issues-prs.yaml @@ -0,0 +1,26 @@ +name: Housekeeping - Close stale issues and PRs +on: + schedule: + - cron: '0 9 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9.0.0 + with: + stale-issue-message: 'This issue is being marked stale due to a period of inactivity. If this issue is still relevant, please comment or remove the stale label. Otherwise, this issue will close in 30 days.' + stale-pr-message: 'This PR is being marked stale due to a period of inactivty. If this PR is still relevant, please comment or remove the stale label. Otherwise, this PR will close in 30 days.' + close-issue-message: 'This issue was closed because it has been stalled for 30 days with no activity. If this issue is still relevant, please re-open a new issue.' + close-pr-message: 'This PR was closed because it has been stalled for 30 days with no activity. If this PR is still relevant, please re-open a new PR against main.' + days-before-issue-stale: 60 + days-before-pr-stale: 60 + days-before-issue-close: 30 + days-before-pr-close: 30 + # Don't add stale label to PRs / issues with milestones "upcoming" attached. + exempt-milestones: "upcoming" + # Don't add stale label to PRs / issues with this label + exempt-issue-labels: 'never-stale, kind/requirement' + exempt-pr-labels: 'never-stale, kind/requirement' + # Make it 1000 to clean up a bit then wen can lower it + operations-per-run: 1000 diff --git a/charts/harbor-helm-main/.github/workflows/integration.yaml b/charts/harbor-helm-main/.github/workflows/integration.yaml new file mode 100644 index 0000000..c72b943 --- /dev/null +++ b/charts/harbor-helm-main/.github/workflows/integration.yaml @@ -0,0 +1,78 @@ +name: Integration test + +on: + pull_request: + push: + +jobs: + integration-test: + runs-on: ubuntu-latest + strategy: + matrix: + k8s_version: [v1.25.3, v1.24.7, v1.23.13] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Create kind cluster + uses: helm/kind-action@v1.1.0 + with: + version: v0.17.0 + node_image: kindest/node:${{ matrix.k8s_version }} + cluster_name: kind-cluster-${{ matrix.k8s_version }} + config: test/integration/kind-cluster.yaml + + - name: Install Nginx ingress controller + run: | + kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.0/deploy/static/provider/kind/deploy.yaml + kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s + + - name: Set up Go 1.19 + uses: actions/setup-go@v2 + with: + go-version: "1.19" + + - name: Cache go mod + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Set /etc/hosts + run: | + sudo -- sh -c "echo '127.0.0.1 harbor.local' >> /etc/hosts" + + - name: Run integration tests + working-directory: ./test + run: + go test -v -timeout 30m github.com/goharbor/harbor-helm/integration + + - name: fetch harbor logs + if: failure() + run: | + df -h + free -m + mkdir -p /tmp/harbor + for name in core jobservice registry registryctl trivy portal redis database; do \ + kubectl -n default logs -l "component=$name" --all-containers > /tmp/harbor/$name.log ; \ + done + + - uses: actions/upload-artifact@v2 + if: failure() + with: + name: harbor_${{ matrix.k8s_version }}_${{ runner.os }} + path: /tmp/harbor + + - name: fetch logs + if: failure() + run: | + mkdir -p /tmp/logs + kind export logs --name kind-cluster-${{ matrix.k8s_version }} /tmp/logs + + - uses: actions/upload-artifact@v2 + if: failure() + with: + name: kind_v${{ matrix.k8s_version }} + path: /tmp/logs diff --git a/charts/harbor-helm-main/.github/workflows/lint.yaml b/charts/harbor-helm-main/.github/workflows/lint.yaml new file mode 100644 index 0000000..83380a3 --- /dev/null +++ b/charts/harbor-helm-main/.github/workflows/lint.yaml @@ -0,0 +1,47 @@ +name: Lint + +on: + pull_request: + push: + +jobs: + lint: + runs-on: ubuntu-latest + strategy: + matrix: + helm_version: [3.11.1] + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + path: harbor + + - name: Set up Helm + uses: azure/setup-helm@v1 + with: + version: '${{ matrix.helm_version }}' + + - name: Helm version + run: + helm version -c + + - name: Run lint + continue-on-error: ${{ startsWith(matrix.helm_version, '2.') }} + working-directory: ./harbor + run: + helm lint . + + - name: Update dependency + working-directory: ./harbor + run: + helm dependency update . + + - name: Run template for ingress expose + working-directory: ./harbor + run: + helm template --set "expose.type=ingress" --output-dir $(mktemp -d -t output-XXXXXXXXXX) . + + - name: Run template for nodePort expose + working-directory: ./harbor + run: + helm template --set "expose.type=nodePort,expose.tls.auto.commonName=127.0.0.1" --output-dir $(mktemp -d -t output-XXXXXXXXXX) . diff --git a/charts/harbor-helm-main/.github/workflows/publish_release.yaml b/charts/harbor-helm-main/.github/workflows/publish_release.yaml new file mode 100644 index 0000000..604b5be --- /dev/null +++ b/charts/harbor-helm-main/.github/workflows/publish_release.yaml @@ -0,0 +1,47 @@ +name: Publish Release + +on: + push: + tags: + - 'v*.*.*' + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + ref: ${{ github.ref }} + - name: Setup Helm + uses: azure/setup-helm@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + id: install + - name: Helm Package + run: echo "PACKAGE_PATH=$(helm package . | awk '{print $NF}')" >> $GITHUB_ENV + - name: Publish Helm Chart + run: | + helm registry login registry-1.docker.io -u ${{ secrets.DOCKER_HUB_USERNAME }} -p ${{ secrets.DOCKER_HUB_PASSWORD }} + helm push ${{ env.PACKAGE_PATH }} oci://registry-1.docker.io/${{ secrets.DOCKER_HUB_USERNAME }} + helm registry login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + helm push ${{ env.PACKAGE_PATH }} oci://ghcr.io/${{ github.actor }} + - name: Upload to chart repository + run: | + git config --global user.email "${{ github.event.repository.name }}@users.noreply.github.com" + git config --global user.name "${{ github.event.repository.name }} CI" + git fetch origin chart-repository + git checkout chart-repository + mkdir -p ../helm-temp + cd ../helm-temp + cp ${{ env.PACKAGE_PATH }} . + helm repo index --merge ../harbor-helm/index.yaml . + mv ./* ../harbor-helm + cd ../harbor-helm + git add . + git commit -s -m "feat: Upload Harbor ${{ github.ref }} to chart repository" + git push origin chart-repository + - name: Release + uses: softprops/action-gh-release@v1 + with: + files: ${{ env.PACKAGE_PATH }} diff --git a/charts/harbor-helm-main/.github/workflows/unittest.yaml b/charts/harbor-helm-main/.github/workflows/unittest.yaml new file mode 100644 index 0000000..d9cf91e --- /dev/null +++ b/charts/harbor-helm-main/.github/workflows/unittest.yaml @@ -0,0 +1,35 @@ +name: Unit test + +on: + pull_request: + push: + +jobs: + unit-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up Helm 3.11.1 + uses: azure/setup-helm@v1 + with: + version: '3.11.1' + + - name: Set up Go 1.19 + uses: actions/setup-go@v2 + with: + go-version: 1.19 + + - name: Cache go mod + uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Run unit tests + working-directory: ./test + run: + go test -v github.com/goharbor/harbor-helm/unittest diff --git a/charts/harbor-helm-main/.gitignore b/charts/harbor-helm-main/.gitignore new file mode 100644 index 0000000..abc98e0 --- /dev/null +++ b/charts/harbor-helm-main/.gitignore @@ -0,0 +1,2 @@ +charts/* +requirements.lock \ No newline at end of file diff --git a/charts/harbor-helm-main/.helmignore b/charts/harbor-helm-main/.helmignore new file mode 100644 index 0000000..b4424fd --- /dev/null +++ b/charts/harbor-helm-main/.helmignore @@ -0,0 +1,6 @@ +.github/* +docs/* +.git/* +.gitignore +CONTRIBUTING.md +test/* \ No newline at end of file diff --git a/charts/harbor-helm-main/CONTRIBUTING.md b/charts/harbor-helm-main/CONTRIBUTING.md new file mode 100644 index 0000000..ac9e5a9 --- /dev/null +++ b/charts/harbor-helm-main/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contributing to Helm Chart for Harbor + +Please follow [Harbor contributing guide](https://github.com/goharbor/harbor/blob/main/CONTRIBUTING.md) to learn how to make code contribution. + +## Contributors + +Thanks very much to all contributors who submitted pull requests to Helm Chart for Harbor. + +- [Paul Czarkowski @paulczar](https://github.com/paulczar) +- [Luca Innocenti Mirri @lucaim](https://github.com/lucaim) +- [Steven Arnott @ArcticSnowman](https://github.com/ArcticSnowman) +- [Alex M @draeron](https://github.com/draeron) +- [SangJun Yun](https://github.com/YunSangJun) diff --git a/charts/harbor-helm-main/Chart.yaml b/charts/harbor-helm-main/Chart.yaml new file mode 100644 index 0000000..59edf1f --- /dev/null +++ b/charts/harbor-helm-main/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +name: harbor +version: 1.4.0-dev +appVersion: dev +description: An open source trusted cloud native registry that stores, signs, and scans content +keywords: +- docker +- registry +- harbor +home: https://goharbor.io +icon: https://raw.githubusercontent.com/goharbor/website/main/static/img/logos/harbor-icon-color.png +sources: +- https://github.com/goharbor/harbor +- https://github.com/goharbor/harbor-helm +maintainers: +- name: Wenkai Yin + email: yinw@vmware.com +- name: Weiwei He + email: hweiwei@vmware.com +- name: Shengwen Yu + email: yshengwen@vmware.com +engine: gotpl diff --git a/charts/harbor-helm-main/LICENSE b/charts/harbor-helm-main/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/charts/harbor-helm-main/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "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 + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + 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 + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + 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 stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/harbor-helm-main/README.md b/charts/harbor-helm-main/README.md new file mode 100644 index 0000000..91687dd --- /dev/null +++ b/charts/harbor-helm-main/README.md @@ -0,0 +1,415 @@ +# Helm Chart for Harbor + +**Notes:** The master branch is in heavy development, please use the other stable versions instead. A highly available solution for Harbor based on chart can be found [here](docs/High%20Availability.md). And refer to the [guide](docs/Upgrade.md) to upgrade the existing deployment. + +This repository, including the issues, focuses on deploying Harbor chart via helm. For functionality issues or Harbor questions, please open issues on [goharbor/harbor](https://github.com/goharbor/harbor) + +## Introduction + +This [Helm](https://github.com/kubernetes/helm) chart installs [Harbor](https://github.com/goharbor/harbor) in a Kubernetes cluster. Welcome to [contribute](CONTRIBUTING.md) to Helm Chart for Harbor. + +## Prerequisites + +- Kubernetes cluster 1.20+ +- Helm v3.2.0+ + +## Installation + +### Add Helm repository + +```bash +helm repo add harbor https://helm.goharbor.io +``` + +### Configure the chart + +The following items can be set via `--set` flag during installation or configured by editing the `values.yaml` directly (need to download the chart first). + +#### Configure how to expose Harbor service + +- **Ingress**: The ingress controller must be installed in the Kubernetes cluster. + **Notes:** if TLS is disabled, the port must be included in the command when pulling/pushing images. Refer to issue [#5291](https://github.com/goharbor/harbor/issues/5291) for details. +- **ClusterIP**: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. +- **NodePort**: Exposes the service on each Node’s IP at a static port (the NodePort). You’ll be able to contact the NodePort service, from outside the cluster, by requesting `NodeIP:NodePort`. +- **LoadBalancer**: Exposes the service externally using a cloud provider’s load balancer. + +#### Configure the external URL + +The external URL for Harbor core service is used to: + +1. populate the docker/helm commands showed on portal +2. populate the token service URL returned to docker client + +Format: `protocol://domain[:port]`. Usually: + +- if service exposed via `Ingress`, the `domain` should be the value of `expose.ingress.hosts.core` +- if service exposed via `ClusterIP`, the `domain` should be the value of `expose.clusterIP.name` +- if service exposed via `NodePort`, the `domain` should be the IP address of one Kubernetes node +- if service exposed via `LoadBalancer`, set the `domain` as your own domain name and add a CNAME record to map the domain name to the one you got from the cloud provider + +If Harbor is deployed behind the proxy, set it as the URL of proxy. + +#### Configure how to persist data + +- **Disable**: The data does not survive the termination of a pod. +- **Persistent Volume Claim(default)**: A default `StorageClass` is needed in the Kubernetes cluster to dynamically provision the volumes. Specify another StorageClass in the `storageClass` or set `existingClaim` if you already have existing persistent volumes to use. +- **External Storage(only for images and charts)**: For images and charts, the external storages are supported: `azure`, `gcs`, `s3` `swift` and `oss`. + +#### Configure the other items listed in [configuration](#configuration) section + +### Install the chart + +Install the Harbor helm chart with a release name `my-release`: +```bash +helm install my-release harbor/harbor +``` + +## Uninstallation + +To uninstall/delete the `my-release` deployment: +```bash +helm uninstall my-release +``` + +## Configuration + +The following table lists the configurable parameters of the Harbor chart and the default values. + +| Parameter | Description | Default | +|-----------------------------------------------------------------------| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| **Expose** | | | +| `expose.type` | How to expose the service: `ingress`, `clusterIP`, `nodePort` or `loadBalancer`, other values will be ignored and the creation of service will be skipped. | `ingress` | +| `expose.tls.enabled` | Enable TLS or not. Delete the `ssl-redirect` annotations in `expose.ingress.annotations` when TLS is disabled and `expose.type` is `ingress`. Note: if the `expose.type` is `ingress` and TLS is disabled, the port must be included in the command when pulling/pushing images. Refer to https://github.com/goharbor/harbor/issues/5291 for details. | `true` | +| `expose.tls.certSource` | The source of the TLS certificate. Set as `auto`, `secret` or `none` and fill the information in the corresponding section: 1) auto: generate the TLS certificate automatically 2) secret: read the TLS certificate from the specified secret. The TLS certificate can be generated manually or by cert manager 3) none: configure no TLS certificate for the ingress. If the default TLS certificate is configured in the ingress controller, choose this option | `auto` | +| `expose.tls.auto.commonName` | The common name used to generate the certificate, it's necessary when the type isn't `ingress` | | +| `expose.tls.secret.secretName` | The name of secret which contains keys named: `tls.crt` - the certificate; `tls.key` - the private key | | +| `expose.ingress.hosts.core` | The host of Harbor core service in ingress rule | `core.harbor.domain` | +| `expose.ingress.controller` | The ingress controller type. Currently supports `default`, `gce`, `alb`, `f5-bigip` and `ncp` | `default` | +| `expose.ingress.kubeVersionOverride` | Allows the ability to override the kubernetes version used while templating the ingress | | +| `expose.ingress.annotations` | The annotations used commonly for ingresses | | +| `expose.ingress.labels` | The labels specific to ingress | {} | +| `expose.clusterIP.name` | The name of ClusterIP service | `harbor` | +| `expose.clusterIP.annotations` | The annotations attached to the ClusterIP service | {} | +| `expose.clusterIP.ports.httpPort` | The service port Harbor listens on when serving HTTP | `80` | +| `expose.clusterIP.ports.httpsPort` | The service port Harbor listens on when serving HTTPS | `443` | +| `expose.clusterIP.annotations` | The annotations used commonly for clusterIP | | +| `expose.clusterIP.labels` | The labels specific to clusterIP | {} | +| `expose.nodePort.name` | The name of NodePort service | `harbor` | +| `expose.nodePort.ports.http.port` | The service port Harbor listens on when serving HTTP | `80` | +| `expose.nodePort.ports.http.nodePort` | The node port Harbor listens on when serving HTTP | `30002` | +| `expose.nodePort.ports.https.port` | The service port Harbor listens on when serving HTTPS | `443` | +| `expose.nodePort.ports.https.nodePort` | The node port Harbor listens on when serving HTTPS | `30003` | +| `expose.nodePort.annotations` | The annotations used commonly for nodePort | | +| `expose.nodePort.labels` | The labels specific to nodePort | {} | +| `expose.loadBalancer.name` | The name of service | `harbor` | +| `expose.loadBalancer.IP` | The IP of the loadBalancer. It only works when loadBalancer supports assigning IP | `""` | +| `expose.loadBalancer.ports.httpPort` | The service port Harbor listens on when serving HTTP | `80` | +| `expose.loadBalancer.ports.httpsPort` | The service port Harbor listens on when serving HTTPS | `30002` | +| `expose.loadBalancer.annotations` | The annotations attached to the loadBalancer service | {} | +| `expose.loadBalancer.labels` | The labels specific to loadBalancer | {} | +| `expose.loadBalancer.sourceRanges` | List of IP address ranges to assign to loadBalancerSourceRanges | [] | +| **Internal TLS** | | | +| `internalTLS.enabled` | Enable TLS for the components (core, jobservice, portal, registry, trivy) | `false` | +| `internalTLS.strong_ssl_ciphers` | Enable strong ssl ciphers for nginx and portal | `false` +| `internalTLS.certSource` | Method to provide TLS for the components, options are `auto`, `manual`, `secret`. | `auto` | +| `internalTLS.trustCa` | The content of trust CA, only available when `certSource` is `manual`. **Note**: all the internal certificates of the components must be issued by this CA | | +| `internalTLS.core.secretName` | The secret name for core component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.core.crt` | Content of core's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.core.key` | Content of core's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.jobservice.secretName` | The secret name for jobservice component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.jobservice.crt` | Content of jobservice's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.jobservice.key` | Content of jobservice's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.registry.secretName` | The secret name for registry component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.registry.crt` | Content of registry's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.registry.key` | Content of registry's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.portal.secretName` | The secret name for portal component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.portal.crt` | Content of portal's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.portal.key` | Content of portal's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.trivy.secretName` | The secret name for trivy component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.trivy.crt` | Content of trivy's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.trivy.key` | Content of trivy's TLS key file, only available when `certSource` is `manual` | | +| **IPFamily** | | | +| `ipFamily.ipv4.enabled` | if cluster is ipv4 enabled, all ipv4 related configs will set correspondingly, but currently it only affects the nginx related components | `true` | +| `ipFamily.ipv6.enabled` | if cluster is ipv6 enabled, all ipv6 related configs will set correspondingly, but currently it only affects the nginx related components | `true` | +| **Persistence** | | | +| `persistence.enabled` | Enable the data persistence or not | `true` | +| `persistence.resourcePolicy` | Setting it to `keep` to avoid removing PVCs during a helm delete operation. Leaving it empty will delete PVCs after the chart deleted. Does not affect PVCs created for internal database and redis components. | `keep` | +| `persistence.persistentVolumeClaim.registry.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components | | +| `persistence.persistentVolumeClaim.registry.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning | | +| `persistence.persistentVolumeClaim.registry.subPath` | The sub path used in the volume | | +| `persistence.persistentVolumeClaim.registry.accessMode` | The access mode of the volume | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.registry.size` | The size of the volume | `5Gi` | +| `persistence.persistentVolumeClaim.registry.annotations` | The annotations of the volume | | +| `persistence.persistentVolumeClaim.jobservice.jobLog.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components. | | +| `persistence.persistentVolumeClaim.jobservice.jobLog.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning | | +| `persistence.persistentVolumeClaim.jobservice.jobLog.subPath` | The sub path used in the volume | | +| `persistence.persistentVolumeClaim.jobservice.jobLog.accessMode` | The access mode of the volume | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.jobservice.jobLog.size` | The size of the volume | `1Gi` | +| `persistence.persistentVolumeClaim.jobservice.jobLog.annotations` | The annotations of the volume | | +| `persistence.persistentVolumeClaim.database.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components. If external database is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.database.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning. If external database is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.database.subPath` | The sub path used in the volume. If external database is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.database.accessMode` | The access mode of the volume. If external database is used, the setting will be ignored | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.database.size` | The size of the volume. If external database is used, the setting will be ignored | `1Gi` | +| `persistence.persistentVolumeClaim.database.annotations` | The annotations of the volume | | +| `persistence.persistentVolumeClaim.redis.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components. If external Redis is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.redis.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning. If external Redis is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.redis.subPath` | The sub path used in the volume. If external Redis is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.redis.accessMode` | The access mode of the volume. If external Redis is used, the setting will be ignored | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.redis.size` | The size of the volume. If external Redis is used, the setting will be ignored | `1Gi` | +| `persistence.persistentVolumeClaim.redis.annotations` | The annotations of the volume | | +| `persistence.persistentVolumeClaim.trivy.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components | | +| `persistence.persistentVolumeClaim.trivy.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning | | +| `persistence.persistentVolumeClaim.trivy.subPath` | The sub path used in the volume | | +| `persistence.persistentVolumeClaim.trivy.accessMode` | The access mode of the volume | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.trivy.size` | The size of the volume | `1Gi` | +| `persistence.persistentVolumeClaim.trivy.annotations` | The annotations of the volume | | +| `persistence.imageChartStorage.disableredirect` | The configuration for managing redirects from content backends. For backends which not supported it (such as using minio for `s3` storage type), please set it to `true` to disable redirects. Refer to the [guide](https://github.com/docker/distribution/blob/master/docs/configuration.md#redirect) for more details | `false` | +| `persistence.imageChartStorage.caBundleSecretName` | 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 of registry's and containers. | | +| `persistence.imageChartStorage.type` | The type of storage for images and charts: `filesystem`, `azure`, `gcs`, `s3`, `swift` or `oss`. The type must be `filesystem` if you want to use persistent volumes for registry. Refer to the [guide](https://github.com/docker/distribution/blob/master/docs/configuration.md#storage) for more details | `filesystem` | +| `persistence.imageChartStorage.gcs.existingSecret` | An existing secret containing the gcs service account json key. The key must be gcs-key.json. | `""` | +| `persistence.imageChartStorage.gcs.useWorkloadIdentity` | A boolean to allow the use of workloadidentity in a GKE cluster. To use it, create a kubernetes service account and set the name in the key `serviceAccountName` of each component, then allow automounting the service account. | `false` | +| **General** | | | +| `externalURL` | The external URL for Harbor core service | `https://core.harbor.domain` | +| `caBundleSecretName` | The custom CA bundle secret name, the secret must contain key named "ca.crt" which will be injected into the trust store for core, jobservice, registry, trivy components. | | +| `uaaSecretName` | If using external UAA auth which has a self signed cert, you can provide a pre-created secret containing it under the key `ca.crt`. | | +| `imagePullPolicy` | The image pull policy | | +| `imagePullSecrets` | The imagePullSecrets names for all deployments | | +| `updateStrategy.type` | The update strategy for deployments with persistent volumes(jobservice, registry): `RollingUpdate` or `Recreate`. Set it as `Recreate` when `RWM` for volumes isn't supported | `RollingUpdate` | +| `logLevel` | The log level: `debug`, `info`, `warning`, `error` or `fatal` | `info` | +| `harborAdminPassword` | The initial password of Harbor admin. Change it from portal after launching Harbor | `Harbor12345` | +| `existingSecretAdminPassword` | The name of secret where admin password can be found. | | +| `existingSecretAdminPasswordKey` | The name of the key in the secret where to find harbor admin password Harbor | `HARBOR_ADMIN_PASSWORD` | +| `caSecretName` | The name of the secret which contains key named `ca.crt`. Setting this enables the download link on portal to download the CA certificate when the certificate isn't generated automatically | | +| `secretKey` | The key used for encryption. Must be a string of 16 chars | `not-a-secure-key` | +| `existingSecretSecretKey` | An existing secret containing the encoding secretKey | `""` | +| `proxy.httpProxy` | The URL of the HTTP proxy server | | +| `proxy.httpsProxy` | The URL of the HTTPS proxy server | | +| `proxy.noProxy` | The URLs that the proxy settings not apply to | 127.0.0.1,localhost,.local,.internal | +| `proxy.components` | The component list that the proxy settings apply to | core, jobservice, trivy | +| `enableMigrateHelmHook` | Run the migration job via helm hook, if it is true, the database migration will be separated from harbor-core, run with a preupgrade job migration-job | `false` | +| **Nginx** (if service exposed via `ingress`, Nginx will not be used) | | | +| `nginx.image.repository` | Image repository | `goharbor/nginx-photon` | +| `nginx.image.tag` | Image tag | `dev` | +| `nginx.replicas` | The replica count | `1` | +| `nginx.revisionHistoryLimit` | The revision history limit | `10` | +| `nginx.resources` | The [resources] to allocate for container | undefined | +| `nginx.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `nginx.nodeSelector` | Node labels for pod assignment | `{}` | +| `nginx.tolerations` | Tolerations for pod assignment | `[]` | +| `nginx.affinity` | Node/Pod affinities | `{}` | +| `nginx.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `nginx.podAnnotations` | Annotations to add to the nginx pod | `{}` | +| `nginx.priorityClassName` | The priority class to run the pod as | | +| **Portal** | | | +| `portal.image.repository` | Repository for portal image | `goharbor/harbor-portal` | +| `portal.image.tag` | Tag for portal image | `dev` | +| `portal.replicas` | The replica count | `1` | +| `portal.revisionHistoryLimit` | The revision history limit | `10` | +| `portal.resources` | The [resources] to allocate for container | undefined | +| `portal.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `portal.nodeSelector` | Node labels for pod assignment | `{}` | +| `portal.tolerations` | Tolerations for pod assignment | `[]` | +| `portal.affinity` | Node/Pod affinities | `{}` | +| `portal.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `portal.podAnnotations` | Annotations to add to the portal pod | `{}` | +| `portal.serviceAnnotations` | Annotations to add to the portal service | `{}` | +| `portal.priorityClassName` | The priority class to run the pod as | | +| **Core** | | | +| `core.image.repository` | Repository for Harbor core image | `goharbor/harbor-core` | +| `core.image.tag` | Tag for Harbor core image | `dev` | +| `core.replicas` | The replica count | `1` | +| `core.revisionHistoryLimit` | The revision history limit | `10` | +| `core.startupProbe.initialDelaySeconds` | The initial delay in seconds for the startup probe | `10` | +| `core.resources` | The [resources] to allocate for container | undefined | +| `core.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `core.nodeSelector` | Node labels for pod assignment | `{}` | +| `core.tolerations` | Tolerations for pod assignment | `[]` | +| `core.affinity` | Node/Pod affinities | `{}` | +| `core.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `core.podAnnotations` | Annotations to add to the core pod | `{}` | +| `core.serviceAnnotations` | Annotations to add to the core service | `{}` | +| `core.configureUserSettings` | A JSON string to set in the environment variable `CONFIG_OVERWRITE_JSON` to configure user settings. See the [official docs](https://goharbor.io/docs/latest/install-config/configure-user-settings-cli/#configure-users-settings-using-an-environment-variable). | | +| `core.quotaUpdateProvider` | The provider for updating project quota(usage), there are 2 options, redis or db. By default it is implemented by db but you can configure it to redis which can improve the performance of high concurrent pushing to the same project, and reduce the database connections spike and occupies. Using redis will bring up some delay for quota usage updation for display, so only suggest switch provider to redis if you were ran into the db connections spike around the scenario of high concurrent pushing to same project, no improvment for other scenes. | `db` | +| `core.secret` | Secret is used when core server communicates with other components. If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | | +| `core.secretName` | Fill the name of a kubernetes secret if you want to use your own TLS certificate and private key for token encryption/decryption. The secret must contain keys named: `tls.crt` - the certificate and `tls.key` - the private key. The default key pair will be used if it isn't set | | +| `core.tokenKey` | PEM-formatted RSA private key used to sign service tokens. Only used if `core.secretName` is unset. If set, `core.tokenCert` MUST also be set. | | +| `core.tokenCert` | PEM-formatted certificate signed by `core.tokenKey` used to validate service tokens. Only used if `core.secretName` is unset. If set, `core.tokenKey` MUST also be set. | | +| `core.xsrfKey` | The XSRF key. Will be generated automatically if it isn't specified | | +| `core.priorityClassName` | The priority class to run the pod as | | +| `core.artifactPullAsyncFlushDuration` | The time duration for async update artifact pull_time and repository pull_count | | +| `core.gdpr.deleteUser` | Enable GDPR compliant user delete | `false` | +| `core.gdpr.auditLogsCompliant` | Enable GDPR compliant for audit logs by changing username to its CRC32 value if that user was deleted from the system | `false` | +| **Jobservice** | | | +| `jobservice.image.repository` | Repository for jobservice image | `goharbor/harbor-jobservice` | +| `jobservice.image.tag` | Tag for jobservice image | `dev` | +| `jobservice.replicas` | The replica count | `1` | +| `jobservice.revisionHistoryLimit` | The revision history limit | `10` | +| `jobservice.maxJobWorkers` | The max job workers | `10` | +| `jobservice.jobLoggers` | The loggers for jobs: `file`, `database` or `stdout` | `[file]` | +| `jobservice.loggerSweeperDuration` | The jobLogger sweeper duration in days (ignored if `jobLoggers` is set to `stdout`) | `14` | +| `jobservice.notification.webhook_job_max_retry` | The maximum retry of webhook sending notifications | `3` | +| `jobservice.notification.webhook_job_http_client_timeout` | The http client timeout value of webhook sending notifications | `3` | +| `jobservice.reaper.max_update_hours` | the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24 | `24` | +| `jobservice.reaper.max_dangling_hours` | the max time for execution in running state without new task created | `168` | +| `jobservice.resources` | The [resources] to allocate for container | undefined | +| `jobservice.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `jobservice.nodeSelector` | Node labels for pod assignment | `{}` | +| `jobservice.tolerations` | Tolerations for pod assignment | `[]` | +| `jobservice.affinity` | Node/Pod affinities | `{}` | +| `jobservice.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `jobservice.podAnnotations` | Annotations to add to the jobservice pod | `{}` | +| `jobservice.priorityClassName` | The priority class to run the pod as | | +| `jobservice.secret` | Secret is used when job service communicates with other components. If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | | +| **Registry** | | | +| `registry.registry.image.repository` | Repository for registry image | `goharbor/registry-photon` | +| `registry.registry.image.tag` | Tag for registry image | `dev` | +| `registry.registry.resources` | The [resources] to allocate for container | undefined | +| `registry.controller.image.repository` | Repository for registry controller image | `goharbor/harbor-registryctl` | +| `registry.controller.image.tag` | Tag for registry controller image | `dev` | +| `registry.controller.resources` | The [resources] to allocate for container | undefined | +| `registry.replicas` | The replica count | `1` | +| `registry.revisionHistoryLimit` | The revision history limit | `10` | +| `registry.nodeSelector` | Node labels for pod assignment | `{}` | +| `registry.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `registry.tolerations` | Tolerations for pod assignment | `[]` | +| `registry.affinity` | Node/Pod affinities | `{}` | +| `registry.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `registry.middleware` | Middleware is used to add support for a CDN between backend storage and `docker pull` recipient. See [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#middleware). | | +| `registry.podAnnotations` | Annotations to add to the registry pod | `{}` | +| `registry.priorityClassName` | The priority class to run the pod as | | +| `registry.secret` | Secret is used to secure the upload state from client and registry storage backend. See [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#http). If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | | +| `registry.credentials.username` | The username that harbor core uses internally to access the registry instance. Together with the `registry.credentials.password`, a htpasswd is created. This is an alternative to providing `registry.credentials.htpasswdString`. For more details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). | `harbor_registry_user` | +| `registry.credentials.password` | The password that harbor core uses internally to access the registry instance. Together with the `registry.credentials.username`, a htpasswd is created. This is an alternative to providing `registry.credentials.htpasswdString`. For more details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). It is suggested you update this value before installation. | `harbor_registry_password` | +| `registry.credentials.existingSecret` | An existing secret containing the password for accessing the registry instance, which is hosted by htpasswd auth mode. More details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). The key must be `REGISTRY_PASSWD` | `""` | +| `registry.credentials.htpasswdString` | Login and password in htpasswd string format. Excludes `registry.credentials.username` and `registry.credentials.password`. May come in handy when integrating with tools like argocd or flux. This allows the same line to be generated each time the template is rendered, instead of the `htpasswd` function from helm, which generates different lines each time because of the salt. | undefined | +| `registry.relativeurls` | If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. Needed if harbor is behind a reverse proxy | `false` | +| `registry.upload_purging.enabled` | If true, enable purge _upload directories | `true` | +| `registry.upload_purging.age` | Remove files in _upload directories which exist for a period of time, default is one week. | `168h` | +| `registry.upload_purging.interval` | The interval of the purge operations | `24h` | +| `registry.upload_purging.dryrun` | If true, enable dryrun for purging _upload, default false | `false` | +| **[Trivy][trivy]** | | | +| `trivy.enabled` | The flag to enable Trivy scanner | `true` | +| `trivy.image.repository` | Repository for Trivy adapter image | `goharbor/trivy-adapter-photon` | +| `trivy.image.tag` | Tag for Trivy adapter image | `dev` | +| `trivy.resources` | The [resources] to allocate for Trivy adapter container | | +| `trivy.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `trivy.replicas` | The number of Pod replicas | `1` | +| `trivy.debugMode` | The flag to enable Trivy debug mode | `false` | +| `trivy.vulnType` | Comma-separated list of vulnerability types. Possible values `os` and `library`. | `os,library` | +| `trivy.severity` | Comma-separated list of severities to be checked | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL` | +| `trivy.ignoreUnfixed` | The flag to display only fixed vulnerabilities | `false` | +| `trivy.insecure` | The flag to skip verifying registry certificate | `false` | +| `trivy.skipUpdate` | The flag to disable [Trivy DB][trivy-db] downloads from GitHub | `false` | +| `trivy.skipJavaDBUpdate` | If the flag is enabled you have to manually download the `trivy-java.db` file [Trivy Java DB][trivy-java-db] and mount it in the `/home/scanner/.cache/trivy/java-db/trivy-java.db` path | `false` | +| `trivy.offlineScan` | The flag prevents Trivy from sending API requests to identify dependencies. | `false` | +| `trivy.securityCheck` | Comma-separated list of what security issues to detect. Possible values are `vuln`, `config` and `secret`. | `vuln` | +| `trivy.timeout` | The duration to wait for scan completion | `5m0s` | +| `trivy.gitHubToken` | The GitHub access token to download [Trivy DB][trivy-db] (see [GitHub rate limiting][trivy-rate-limiting]) | | +| `trivy.priorityClassName` | The priority class to run the pod as | | +| `trivy.topologySpreadConstraints` | The priority class to run the pod as | | +| **Database** | | | +| `database.type` | If external database is used, set it to `external` | `internal` | +| `database.internal.image.repository` | Repository for database image | `goharbor/harbor-db` | +| `database.internal.image.tag` | Tag for database image | `dev` | +| `database.internal.password` | The password for database | `changeit` | +| `database.internal.shmSizeLimit` | The limit for the size of shared memory for internal PostgreSQL, conventionally it's around 50% of the memory limit of the container | `512Mi` | +| `database.internal.resources` | The [resources] to allocate for container | undefined | +| `database.internal.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `database.internal.initContainer.migrator.resources` | The [resources] to allocate for the database migrator initContainer | undefined | +| `database.internal.initContainer.permissions.resources` | The [resources] to allocate for the database permissions initContainer | undefined | +| `database.internal.nodeSelector` | Node labels for pod assignment | `{}` | +| `database.internal.tolerations` | Tolerations for pod assignment | `[]` | +| `database.internal.affinity` | Node/Pod affinities | `{}` | +| `database.internal.priorityClassName` | The priority class to run the pod as | | +| `database.internal.livenessProbe.timeoutSeconds` | The timeout used in liveness probe; 1 to 5 seconds | 1 | +| `database.internal.readinessProbe.timeoutSeconds` | The timeout used in readiness probe; 1 to 5 seconds | 1 | +| `database.external.host` | The hostname of external database | `192.168.0.1` | +| `database.external.port` | The port of external database | `5432` | +| `database.external.username` | The username of external database | `user` | +| `database.external.password` | The password of external database | `password` | +| `database.external.coreDatabase` | The database used by core service | `registry` | +| `database.external.existingSecret` | An existing password containing the database password. the key must be `password`. | `""` | +| `database.external.sslmode` | Connection method of external database (require, verify-full, verify-ca, disable) | `disable` | +| `database.maxIdleConns` | The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained. | `50` | +| `database.maxOpenConns` | The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections. | `100` | +| `database.podAnnotations` | Annotations to add to the database pod | `{}` | +| **Redis** | | | +| `redis.type` | If external redis is used, set it to `external` | `internal` | +| `redis.internal.image.repository` | Repository for redis image | `goharbor/redis-photon` | +| `redis.internal.image.tag` | Tag for redis image | `dev` | +| `redis.internal.resources` | The [resources] to allocate for container | undefined | +| `redis.internal.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `redis.internal.nodeSelector` | Node labels for pod assignment | `{}` | +| `redis.internal.tolerations` | Tolerations for pod assignment | `[]` | +| `redis.internal.affinity` | Node/Pod affinities | `{}` | +| `redis.internal.priorityClassName` | The priority class to run the pod as | | +| `redis.internal.jobserviceDatabaseIndex` | The database index for jobservice | `1` | +| `redis.internal.registryDatabaseIndex` | The database index for registry | `2` | +| `redis.internal.trivyAdapterIndex` | The database index for trivy adapter | `5` | +| `redis.internal.harborDatabaseIndex` | The database index for harbor miscellaneous business logic | `0` | +| `redis.internal.cacheLayerDatabaseIndex` | The database index for harbor cache layer | `0` | +| `redis.external.addr` | The addr of external Redis: :. When using sentinel, it should be :,:,: | `192.168.0.2:6379` | +| `redis.external.sentinelMasterSet` | The name of the set of Redis instances to monitor | | +| `redis.external.coreDatabaseIndex` | The database index for core | `0` | +| `redis.external.jobserviceDatabaseIndex` | The database index for jobservice | `1` | +| `redis.external.registryDatabaseIndex` | The database index for registry | `2` | +| `redis.external.trivyAdapterIndex` | The database index for trivy adapter | `5` | +| `redis.external.harborDatabaseIndex` | The database index for harbor miscellaneous business logic | `0` | +| `redis.external.cacheLayerDatabaseIndex` | The database index for harbor cache layer | `0` | +| `redis.external.username` | The username of external Redis | | +| `redis.external.password` | The password of external Redis | | +| `redis.external.existingSecret` | Use an existing secret to connect to redis. The key must be `REDIS_PASSWORD`. | `""` | +| `redis.podAnnotations` | Annotations to add to the redis pod | `{}` | +| **Exporter** | | | +| `exporter.replicas` | The replica count | `1` | +| `exporter.revisionHistoryLimit` | The revision history limit | `10` | +| `exporter.podAnnotations` | Annotations to add to the exporter pod | `{}` | +| `exporter.image.repository` | Repository for redis image | `goharbor/harbor-exporter` | +| `exporter.image.tag` | Tag for exporter image | `dev` | +| `exporter.nodeSelector` | Node labels for pod assignment | `{}` | +| `exporter.tolerations` | Tolerations for pod assignment | `[]` | +| `exporter.affinity` | Node/Pod affinities | `{}` | +| `exporter.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `exporter.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `exporter.cacheDuration` | the cache duration for information that exporter collected from Harbor | `30` | +| `exporter.cacheCleanInterval` | cache clean interval for information that exporter collected from Harbor | `14400` | +| `exporter.priorityClassName` | The priority class to run the pod as | | +| **Metrics** | | | +| `metrics.enabled` | if enable harbor metrics | `false` | +| `metrics.core.path` | the url path for core metrics | `/metrics` | +| `metrics.core.port` | the port for core metrics | `8001` | +| `metrics.registry.path` | the url path for registry metrics | `/metrics` | +| `metrics.registry.port` | the port for registry metrics | `8001` | +| `metrics.exporter.path` | the url path for exporter metrics | `/metrics` | +| `metrics.exporter.port` | the port for exporter metrics | `8001` | +| `metrics.serviceMonitor.enabled` | create prometheus serviceMonitor. Requires prometheus CRD's | `false` | +| `metrics.serviceMonitor.additionalLabels` | additional labels to upsert to the manifest | `""` | +| `metrics.serviceMonitor.interval` | scrape period for harbor metrics | `""` | +| `metrics.serviceMonitor.metricRelabelings` | metrics relabel to add/mod/del before ingestion | `[]` | +| `metrics.serviceMonitor.relabelings` | relabels to add/mod/del to sample before scrape | `[]` | +| **Trace** | | | +| `trace.enabled` | Enable tracing or not | `false` | +| `trace.provider` | The tracing provider: `jaeger` or `otel`. `jaeger` should be 1.26+ | `jaeger` | +| `trace.sample_rate` | Set `sample_rate` to 1 if you want sampling 100% of trace data; set 0.5 if you want sampling 50% of trace data, and so forth | `1` | +| `trace.namespace` | Namespace used to differentiate different harbor services | | +| `trace.attributes` | `attributes` is a key value dict contains user defined attributes used to initialize trace provider | | +| `trace.jaeger.endpoint` | The endpoint of jaeger | `http://hostname:14268/api/traces` | +| `trace.jaeger.username` | The username of jaeger | | +| `trace.jaeger.password` | The password of jaeger | | +| `trace.jaeger.agent_host` | The agent host of jaeger | | +| `trace.jaeger.agent_port` | The agent port of jaeger | `6831` | +| `trace.otel.endpoint` | The endpoint of otel | `hostname:4318` | +| `trace.otel.url_path` | The URL path of otel | `/v1/traces` | +| `trace.otel.compression` | Whether enable compression or not for otel | `false` | +| `trace.otel.insecure` | Whether establish insecure connection or not for otel | `true` | +| `trace.otel.timeout` | The timeout in seconds of otel | `10` | +| **Cache** | | | +| `cache.enabled` | Enable cache layer or not | `false` | +| `cache.expireHours` | The expire hours of cache layer | `24` | + +[resources]: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +[trivy]: https://github.com/aquasecurity/trivy +[trivy-db]: https://github.com/aquasecurity/trivy-db +[trivy-java-db]: https://github.com/aquasecurity/trivy-java-db +[trivy-rate-limiting]: https://github.com/aquasecurity/trivy#github-rate-limiting diff --git a/charts/harbor-helm-main/docs/High Availability.md b/charts/harbor-helm-main/docs/High Availability.md new file mode 100644 index 0000000..17a190a --- /dev/null +++ b/charts/harbor-helm-main/docs/High Availability.md @@ -0,0 +1,71 @@ +--- +title: Harbor High Availability Guide +--- + +## 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. + +## Prerequisites + +- Kubernetes cluster 1.20+ +- Helm v3.2.0+ +- 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 Redis (Harbor does not handle the deployment of HA of Redis) +- PVC that can be shared across nodes or external object storage + +## 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. + +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) + +## Usage + +### Download Chart + +Download Harbor helm chart: + +```bash +helm repo add harbor https://helm.goharbor.io +helm fetch harbor/harbor --untar +``` + +### Configuration + +Configure the following items in `values.yaml`, you can also set them as parameters via `--set` flag during running `helm install`: + +- **Ingress rule** + Configure the `expose.ingress.hosts.core`. +- **External URL** + Configure the `externalURL`. +- **External PostgreSQL** + Set the `database.type` to `external` and fill the information in `database.external` section. + + Four empty databases should be created manually for `Harbor core`, and configure them in the section. Harbor will create tables automatically when starting up. +- **External Redis** + Set the `redis.type` to `external` and fill the information in `redis.external` section. + Redis sentinel is supported after v1.9.0, configure the `redis.external.sentinelMasterSet` and `redis.external.addr` to enable it. +- **Storage** + 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` and `persistence.persistentVolumeClaim.jobservice.storageClass`. + + If you use `StorageClass`, for both default or specified one, set `persistence.persistentVolumeClaim.registry.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` 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.jobLoggers` to `database`. + +- **Replica** + Set `portal.replicas`, `core.replicas`, `jobservice.replicas`, `registry.replicas` to `n`(`n`>=2). + +### Installation + +Install the Harbor helm chart with a release name `my-release`: +``` +helm install my-release . +``` diff --git a/charts/harbor-helm-main/docs/Upgrade.md b/charts/harbor-helm-main/docs/Upgrade.md new file mode 100644 index 0000000..f7c3181 --- /dev/null +++ b/charts/harbor-helm-main/docs/Upgrade.md @@ -0,0 +1,69 @@ +--- +title: Upgrade Guide +--- + +This guide is used to upgrade Harbor deployed by chart since version 0.3.0. + +## 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 +- The database schema cannot be downgraded automatically, so the `helm rollback` is not supported + +## Upgrade + +### 1. Backup database + +Backup the database used by Harbor in case the upgrade process fails. + +### 2. Download new chart + +Download the latest version of Harbor chart. + +### 3. Configure new chart + +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: + +1) Get the secret name which certificate is stored in: + + ```bash + kubectl get secret + ``` + + Find the secret whose name ends with `-ingress` (expose service via `Ingress`) or `-harbor-nginx`(expose service via `ClusterIP` or `NodePort`) + +2) Export the secret as yaml file: + + + ```bash + kubectl get secret -o yaml > secret.yaml + ``` + + + +3) Rename the secret by setting `metadata.name` in `secret.yaml` + +4) Create a new secret: + + ```bash + kubectl create -f secret.yaml + ``` + +5) Configure the chart to use the new secret by setting `expose.tls.certSource` as `secret` and `expose.tls.secret.secretName` as the value you set in step **3** + +### 4. Upgrade + +Run upgrade command: + +```bash +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). + +## 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. +- Installing the Harbor chart(1.6-) with a release name that contains `harbor`, e.g. `my-harbor`, and trying to upgrade it to 1.7+ you will get the issue https://github.com/goharbor/harbor-helm/issues/987. + The workaround is performing the upgrade by setting the configuration `fullnameOverride` with value `release_name-harbor`, e.g. `my-harbor-harbor`, in `values.yaml` or `--set` option \ No newline at end of file diff --git a/charts/harbor-helm-main/docs/_index.md b/charts/harbor-helm-main/docs/_index.md new file mode 100644 index 0000000..16785fe --- /dev/null +++ b/charts/harbor-helm-main/docs/_index.md @@ -0,0 +1,6 @@ +--- +title: Managing Harbor with Helm +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). \ No newline at end of file diff --git a/charts/harbor-helm-main/docs/img/ha.png b/charts/harbor-helm-main/docs/img/ha.png new file mode 100644 index 0000000000000000000000000000000000000000..0f431236a8c92a97094818c237fb80a56ae21a52 GIT binary patch literal 332250 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 AHvj+t literal 0 HcmV?d00001 diff --git a/charts/harbor-helm-main/templates/NOTES.txt b/charts/harbor-helm-main/templates/NOTES.txt new file mode 100644 index 0000000..0980c08 --- /dev/null +++ b/charts/harbor-helm-main/templates/NOTES.txt @@ -0,0 +1,3 @@ +Please wait for several minutes for Harbor deployment to complete. +Then you should be able to visit the Harbor portal at {{ .Values.externalURL }} +For more details, please visit https://github.com/goharbor/harbor diff --git a/charts/harbor-helm-main/templates/_helpers.tpl b/charts/harbor-helm-main/templates/_helpers.tpl new file mode 100644 index 0000000..0914d56 --- /dev/null +++ b/charts/harbor-helm-main/templates/_helpers.tpl @@ -0,0 +1,574 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +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). +*/}} +{{- define "harbor.name" -}} +{{- default "harbor" .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +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). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "harbor.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default "harbor" .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Helm required labels */}} +{{- define "harbor.labels" -}} +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +chart: {{ .Chart.Name }} +app: "{{ template "harbor.name" . }}" +{{ include "harbor.matchLabels" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/name: {{ include "harbor.name" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: {{ include "harbor.name" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- end -}} + +{{/* matchLabels */}} +{{- define "harbor.matchLabels" -}} +release: {{ .Release.Name }} +app: "{{ template "harbor.name" . }}" +{{- end -}} + +{{/* Helper for printing values from existing secrets*/}} +{{- define "harbor.secretKeyHelper" -}} + {{- if and (not (empty .data)) (hasKey .data .key) }} + {{- index .data .key | b64dec -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.autoGenCert" -}} + {{- if and .Values.expose.tls.enabled (eq .Values.expose.tls.certSource "auto") -}} + {{- printf "true" -}} + {{- else -}} + {{- printf "false" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.autoGenCertForIngress" -}} + {{- if and (eq (include "harbor.autoGenCert" .) "true") (eq .Values.expose.type "ingress") -}} + {{- printf "true" -}} + {{- else -}} + {{- printf "false" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.autoGenCertForNginx" -}} + {{- if and (eq (include "harbor.autoGenCert" .) "true") (ne .Values.expose.type "ingress") -}} + {{- printf "true" -}} + {{- else -}} + {{- printf "false" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.host" -}} + {{- if eq .Values.database.type "internal" -}} + {{- template "harbor.database" . }} + {{- else -}} + {{- .Values.database.external.host -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.port" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "5432" -}} + {{- else -}} + {{- .Values.database.external.port -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.username" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "postgres" -}} + {{- else -}} + {{- .Values.database.external.username -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.rawPassword" -}} + {{- if eq .Values.database.type "internal" -}} + {{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (include "harbor.database" .) -}} + {{- if and (not (empty $existingSecret)) (hasKey $existingSecret.data "POSTGRES_PASSWORD") -}} + {{- .Values.database.internal.password | default (index $existingSecret.data "POSTGRES_PASSWORD" | b64dec) -}} + {{- else -}} + {{- .Values.database.internal.password -}} + {{- end -}} + {{- else -}} + {{- .Values.database.external.password -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.escapedRawPassword" -}} + {{- include "harbor.database.rawPassword" . | urlquery | replace "+" "%20" -}} +{{- end -}} + +{{- define "harbor.database.encryptedPassword" -}} + {{- include "harbor.database.rawPassword" . | b64enc | quote -}} +{{- end -}} + +{{- define "harbor.database.coreDatabase" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "registry" -}} + {{- else -}} + {{- .Values.database.external.coreDatabase -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.sslmode" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "disable" -}} + {{- else -}} + {{- .Values.database.external.sslmode -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.redis.scheme" -}} + {{- with .Values.redis }} + {{- ternary "redis+sentinel" "redis" (and (eq .type "external" ) (not (not .external.sentinelMasterSet))) }} + {{- end }} +{{- end -}} + +/*host:port*/ +{{- define "harbor.redis.addr" -}} + {{- with .Values.redis }} + {{- ternary (printf "%s:6379" (include "harbor.redis" $ )) .external.addr (eq .type "internal") }} + {{- end }} +{{- end -}} + +{{- define "harbor.redis.masterSet" -}} + {{- with .Values.redis }} + {{- ternary .external.sentinelMasterSet "" (eq "redis+sentinel" (include "harbor.redis.scheme" $)) }} + {{- end }} +{{- end -}} + +{{- define "harbor.redis.password" -}} + {{- with .Values.redis }} + {{- ternary "" .external.password (eq .type "internal") }} + {{- end }} +{{- end -}} + + +{{- define "harbor.redis.pwdfromsecret" -}} + {{- (lookup "v1" "Secret" .Release.Namespace (.Values.redis.external.existingSecret)).data.REDIS_PASSWORD | b64dec }} +{{- end -}} + +{{- define "harbor.redis.cred" -}} + {{- with .Values.redis }} + {{- if (and (eq .type "external" ) (.external.existingSecret)) }} + {{- printf ":%s@" (include "harbor.redis.pwdfromsecret" $) }} + {{- else }} + {{- ternary (printf "%s:%s@" (.external.username | urlquery) (.external.password | urlquery)) "" (and (eq .type "external" ) (not (not .external.password))) }} + {{- end }} + {{- end }} +{{- end -}} + +/*scheme://[:password@]host:port[/master_set]*/ +{{- define "harbor.redis.url" -}} + {{- with .Values.redis }} + {{- $path := ternary "" (printf "/%s" (include "harbor.redis.masterSet" $)) (not (include "harbor.redis.masterSet" $)) }} + {{- printf "%s://%s%s%s" (include "harbor.redis.scheme" $) (include "harbor.redis.cred" $) (include "harbor.redis.addr" $) $path -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForCore" -}} + {{- with .Values.redis }} + {{- $index := ternary "0" .external.coreDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index*/ +{{- define "harbor.redis.urlForJobservice" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.jobserviceDatabaseIndex .external.jobserviceDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForRegistry" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.registryDatabaseIndex .external.registryDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForTrivy" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.trivyAdapterIndex .external.trivyAdapterIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForHarbor" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.harborDatabaseIndex .external.harborDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForCache" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.cacheLayerDatabaseIndex .external.cacheLayerDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +{{- define "harbor.redis.dbForRegistry" -}} + {{- with .Values.redis }} + {{- ternary .internal.registryDatabaseIndex .external.registryDatabaseIndex (eq .type "internal") }} + {{- end }} +{{- end -}} + +{{- define "harbor.portal" -}} + {{- printf "%s-portal" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.core" -}} + {{- printf "%s-core" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.redis" -}} + {{- printf "%s-redis" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.jobservice" -}} + {{- printf "%s-jobservice" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.registry" -}} + {{- printf "%s-registry" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.registryCtl" -}} + {{- printf "%s-registryctl" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.database" -}} + {{- printf "%s-database" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.trivy" -}} + {{- printf "%s-trivy" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.nginx" -}} + {{- printf "%s-nginx" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.exporter" -}} + {{- printf "%s-exporter" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.ingress" -}} + {{- printf "%s-ingress" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.noProxy" -}} + {{- printf "%s,%s,%s,%s,%s,%s,%s,%s" (include "harbor.core" .) (include "harbor.jobservice" .) (include "harbor.database" .) (include "harbor.registry" .) (include "harbor.portal" .) (include "harbor.trivy" .) (include "harbor.exporter" .) .Values.proxy.noProxy -}} +{{- end -}} + +{{- define "harbor.caBundleVolume" -}} +- name: ca-bundle-certs + secret: + secretName: {{ .Values.caBundleSecretName }} +{{- end -}} + +{{- define "harbor.caBundleVolumeMount" -}} +- name: ca-bundle-certs + mountPath: /harbor_cust_cert/custom-ca.crt + subPath: ca.crt +{{- end -}} + +{{/* scheme for all components because it only support http mode */}} +{{- define "harbor.component.scheme" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "https" -}} + {{- else -}} + {{- printf "http" -}} + {{- end -}} +{{- end -}} + +{{/* core component container port */}} +{{- define "harbor.core.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* core component service port */}} +{{- define "harbor.core.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "443" -}} + {{- else -}} + {{- printf "80" -}} + {{- end -}} +{{- end -}} + +{{/* jobservice component container port */}} +{{- define "harbor.jobservice.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* jobservice component service port */}} +{{- define "harbor.jobservice.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "443" -}} + {{- else -}} + {{- printf "80" -}} + {{- end -}} +{{- end -}} + +{{/* portal component container port */}} +{{- define "harbor.portal.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* portal component service port */}} +{{- define "harbor.portal.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "443" -}} + {{- else -}} + {{- printf "80" -}} + {{- end -}} +{{- end -}} + +{{/* registry component container port */}} +{{- define "harbor.registry.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "5443" -}} + {{- else -}} + {{- printf "5000" -}} + {{- end -}} +{{- end -}} + +{{/* registry component service port */}} +{{- define "harbor.registry.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "5443" -}} + {{- else -}} + {{- printf "5000" -}} + {{- end -}} +{{- end -}} + +{{/* registryctl component container port */}} +{{- define "harbor.registryctl.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* registryctl component service port */}} +{{- define "harbor.registryctl.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* trivy component container port */}} +{{- define "harbor.trivy.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* trivy component service port */}} +{{- define "harbor.trivy.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* CORE_URL */}} +{{/* port is included in this url as a workaround for issue https://github.com/aquasecurity/harbor-scanner-trivy/issues/108 */}} +{{- define "harbor.coreURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.core" .) (include "harbor.core.servicePort" .) -}} +{{- end -}} + +{{/* JOBSERVICE_URL */}} +{{- define "harbor.jobserviceURL" -}} + {{- printf "%s://%s-jobservice" (include "harbor.component.scheme" .) (include "harbor.fullname" .) -}} +{{- end -}} + +{{/* PORTAL_URL */}} +{{- define "harbor.portalURL" -}} + {{- printf "%s://%s" (include "harbor.component.scheme" .) (include "harbor.portal" .) -}} +{{- end -}} + +{{/* REGISTRY_URL */}} +{{- define "harbor.registryURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registry.servicePort" .) -}} +{{- end -}} + +{{/* REGISTRY_CONTROLLER_URL */}} +{{- define "harbor.registryControllerURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registryctl.servicePort" .) -}} +{{- end -}} + +{{/* TOKEN_SERVICE_URL */}} +{{- define "harbor.tokenServiceURL" -}} + {{- printf "%s/service/token" (include "harbor.coreURL" .) -}} +{{- end -}} + +{{/* TRIVY_ADAPTER_URL */}} +{{- define "harbor.trivyAdapterURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.trivy" .) (include "harbor.trivy.servicePort" .) -}} +{{- end -}} + +{{- define "harbor.internalTLS.core.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.core.secretName -}} + {{- else -}} + {{- printf "%s-core-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.jobservice.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.jobservice.secretName -}} + {{- else -}} + {{- printf "%s-jobservice-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.portal.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.portal.secretName -}} + {{- else -}} + {{- printf "%s-portal-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.registry.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.registry.secretName -}} + {{- else -}} + {{- printf "%s-registry-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.trivy.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.trivy.secretName -}} + {{- else -}} + {{- printf "%s-trivy-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.tlsCoreSecretForIngress" -}} + {{- if eq .Values.expose.tls.certSource "none" -}} + {{- printf "" -}} + {{- else if eq .Values.expose.tls.certSource "secret" -}} + {{- .Values.expose.tls.secret.secretName -}} + {{- else -}} + {{- include "harbor.ingress" . -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.tlsSecretForNginx" -}} + {{- if eq .Values.expose.tls.certSource "secret" -}} + {{- .Values.expose.tls.secret.secretName -}} + {{- else -}} + {{- include "harbor.nginx" . -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.metricsPortName" -}} + {{- if .Values.internalTLS.enabled }} + {{- printf "https-metrics" -}} + {{- else -}} + {{- printf "http-metrics" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.traceEnvs" -}} + TRACE_ENABLED: "{{ .Values.trace.enabled }}" + TRACE_SAMPLE_RATE: "{{ .Values.trace.sample_rate }}" + TRACE_NAMESPACE: "{{ .Values.trace.namespace }}" + {{- if .Values.trace.attributes }} + TRACE_ATTRIBUTES: {{ .Values.trace.attributes | toJson | squote }} + {{- end }} + {{- if eq .Values.trace.provider "jaeger" }} + TRACE_JAEGER_ENDPOINT: "{{ .Values.trace.jaeger.endpoint }}" + TRACE_JAEGER_USERNAME: "{{ .Values.trace.jaeger.username }}" + TRACE_JAEGER_AGENT_HOSTNAME: "{{ .Values.trace.jaeger.agent_host }}" + TRACE_JAEGER_AGENT_PORT: "{{ .Values.trace.jaeger.agent_port }}" + {{- else }} + TRACE_OTEL_ENDPOINT: "{{ .Values.trace.otel.endpoint }}" + TRACE_OTEL_URL_PATH: "{{ .Values.trace.otel.url_path }}" + TRACE_OTEL_COMPRESSION: "{{ .Values.trace.otel.compression }}" + TRACE_OTEL_INSECURE: "{{ .Values.trace.otel.insecure }}" + TRACE_OTEL_TIMEOUT: "{{ .Values.trace.otel.timeout }}" + {{- end }} +{{- end -}} + +{{- define "harbor.traceEnvsForCore" -}} + {{- if .Values.trace.enabled }} + TRACE_SERVICE_NAME: "harbor-core" + {{ include "harbor.traceEnvs" . }} + {{- end }} +{{- end -}} + +{{- define "harbor.traceEnvsForJobservice" -}} + {{- if .Values.trace.enabled }} + TRACE_SERVICE_NAME: "harbor-jobservice" + {{ include "harbor.traceEnvs" . }} + {{- end }} +{{- end -}} + +{{- define "harbor.traceEnvsForRegistryCtl" -}} + {{- if .Values.trace.enabled }} + TRACE_SERVICE_NAME: "harbor-registryctl" + {{ include "harbor.traceEnvs" . }} + {{- end }} +{{- end -}} + +{{- define "harbor.traceJaegerPassword" -}} + {{- if and .Values.trace.enabled (eq .Values.trace.provider "jaeger") }} + TRACE_JAEGER_PASSWORD: "{{ .Values.trace.jaeger.password | default "" | b64enc }}" + {{- end }} +{{- end -}} + +{{/* Allow KubeVersion to be overridden. */}} +{{- define "harbor.ingress.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version .Values.expose.ingress.kubeVersionOverride -}} +{{- end -}} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/core/core-cm.yaml b/charts/harbor-helm-main/templates/core/core-cm.yaml new file mode 100644 index 0000000..93cab01 --- /dev/null +++ b/charts/harbor-helm-main/templates/core/core-cm.yaml @@ -0,0 +1,90 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + app.conf: |+ + appname = Harbor + runmode = prod + enablegzip = true + + [prod] + httpport = {{ ternary "8443" "8080" .Values.internalTLS.enabled }} + PORT: "{{ ternary "8443" "8080" .Values.internalTLS.enabled }}" + DATABASE_TYPE: "postgresql" + POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}" + POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}" + POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}" + POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}" + POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}" + POSTGRESQL_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}" + POSTGRESQL_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}" + EXT_ENDPOINT: "{{ .Values.externalURL }}" + CORE_URL: "{{ template "harbor.coreURL" . }}" + JOBSERVICE_URL: "{{ template "harbor.jobserviceURL" . }}" + REGISTRY_URL: "{{ template "harbor.registryURL" . }}" + TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}" + CORE_LOCAL_URL: "{{ ternary "https://127.0.0.1:8443" "http://127.0.0.1:8080" .Values.internalTLS.enabled }}" + WITH_TRIVY: {{ .Values.trivy.enabled | quote }} + TRIVY_ADAPTER_URL: "{{ template "harbor.trivyAdapterURL" . }}" + REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.persistence.imageChartStorage.type }}" + LOG_LEVEL: "{{ .Values.logLevel }}" + CONFIG_PATH: "/etc/core/app.conf" + CHART_CACHE_DRIVER: "redis" + _REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}" + _REDIS_URL_REG: "{{ template "harbor.redis.urlForRegistry" . }}" + {{- if or (and (eq .Values.redis.type "internal") .Values.redis.internal.harborDatabaseIndex) (and (eq .Values.redis.type "external") .Values.redis.external.harborDatabaseIndex) }} + _REDIS_URL_HARBOR: "{{ template "harbor.redis.urlForHarbor" . }}" + {{- end }} + {{- if or (and (eq .Values.redis.type "internal") .Values.redis.internal.cacheLayerDatabaseIndex) (and (eq .Values.redis.type "external") .Values.redis.external.cacheLayerDatabaseIndex) }} + _REDIS_URL_CACHE_LAYER: "{{ template "harbor.redis.urlForCache" . }}" + {{- end }} + PORTAL_URL: "{{ template "harbor.portalURL" . }}" + REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}" + REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}" + {{- if .Values.uaaSecretName }} + UAA_CA_ROOT: "/etc/core/auth-ca/auth-ca.crt" + {{- end }} + {{- if has "core" .Values.proxy.components }} + HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" + HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" + NO_PROXY: "{{ template "harbor.noProxy" . }}" + {{- end }} + PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE: "docker-hub,harbor,azure-acr,aws-ecr,google-gcr,quay,docker-registry,github-ghcr,jfrog-artifactory" + {{- if .Values.metrics.enabled}} + METRIC_ENABLE: "true" + METRIC_PATH: "{{ .Values.metrics.core.path }}" + METRIC_PORT: "{{ .Values.metrics.core.port }}" + METRIC_NAMESPACE: harbor + METRIC_SUBSYSTEM: core + {{- end }} + + {{- if hasKey .Values.core "gcTimeWindowHours" }} + #make the GC time window configurable for testing + GC_TIME_WINDOW_HOURS: "{{ .Values.core.gcTimeWindowHours }}" + {{- end }} + {{- template "harbor.traceEnvsForCore" . }} + + {{- if .Values.core.artifactPullAsyncFlushDuration }} + ARTIFACT_PULL_ASYNC_FLUSH_DURATION: {{ .Values.core.artifactPullAsyncFlushDuration | quote }} + {{- end }} + + {{- if .Values.core.gdpr}} + {{- if .Values.core.gdpr.deleteUser}} + GDPR_DELETE_USER: "true" + {{- end }} + {{- if .Values.core.gdpr.auditLogsCompliant}} + GDPR_AUDIT_LOGS: "true" + {{- end }} + {{- end }} + + {{- if .Values.cache.enabled }} + CACHE_ENABLED: "true" + CACHE_EXPIRE_HOURS: "{{ .Values.cache.expireHours }}" + {{- end }} + + {{- if .Values.core.quotaUpdateProvider }} + QUOTA_UPDATE_PROVIDER: "{{ .Values.core.quotaUpdateProvider }}" + {{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/core/core-dpl.yaml b/charts/harbor-helm-main/templates/core/core-dpl.yaml new file mode 100644 index 0000000..e52e5f7 --- /dev/null +++ b/charts/harbor-helm-main/templates/core/core-dpl.yaml @@ -0,0 +1,253 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: core + app.kubernetes.io/component: core +spec: + replicas: {{ .Values.core.replicas }} + revisionHistoryLimit: {{ .Values.core.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: core + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: core + app.kubernetes.io/component: core +{{- if .Values.core.podLabels }} +{{ toYaml .Values.core.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} + checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/core/core-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.core.podAnnotations }} +{{ toYaml .Values.core.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.core.serviceAccountName }} + serviceAccountName: {{ .Values.core.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.core.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 +{{- with .Values.core.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: core +{{- end }} +{{- end }} + containers: + - name: core + image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if .Values.core.startupProbe.enabled }} + startupProbe: + httpGet: + path: /api/v2.0/ping + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.core.containerPort" . }} + failureThreshold: 360 + initialDelaySeconds: {{ .Values.core.startupProbe.initialDelaySeconds }} + periodSeconds: 10 + {{- end }} + livenessProbe: + httpGet: + path: /api/v2.0/ping + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.core.containerPort" . }} + failureThreshold: 2 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/v2.0/ping + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.core.containerPort" . }} + failureThreshold: 2 + periodSeconds: 10 + envFrom: + - configMapRef: + name: "{{ template "harbor.core" . }}" + - secretRef: + name: "{{ template "harbor.core" . }}" + env: + - name: CORE_SECRET + valueFrom: + secretKeyRef: + name: {{ default (include "harbor.core" .) .Values.core.existingSecret }} + key: secret + - name: JOBSERVICE_SECRET + valueFrom: + secretKeyRef: + name: {{ default (include "harbor.jobservice" .) .Values.jobservice.existingSecret }} + {{- if .Values.jobservice.existingSecret }} + key: {{ .Values.jobservice.existingSecretKey }} + {{- else }} + key: JOBSERVICE_SECRET + {{- end }} + {{- if .Values.existingSecretAdminPassword }} + - name: HARBOR_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.existingSecretAdminPassword }} + key: {{ .Values.existingSecretAdminPasswordKey }} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/core/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/core/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/core/ca.crt + {{- end }} + {{- if .Values.database.external.existingSecret }} + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.external.existingSecret }} + key: password + {{- end }} + {{- if .Values.registry.credentials.existingSecret }} + - name: REGISTRY_CREDENTIAL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.registry.credentials.existingSecret }} + key: REGISTRY_PASSWD + {{- end }} + {{- if .Values.core.existingXsrfSecret }} + - name: CSRF_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.core.existingXsrfSecret }} + key: {{ .Values.core.existingXsrfSecretKey }} + {{- end }} +{{- with .Values.core.extraEnvVars }} +{{- toYaml . | nindent 10 }} +{{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + ports: + - containerPort: {{ template "harbor.core.containerPort" . }} + volumeMounts: + - name: config + mountPath: /etc/core/app.conf + subPath: app.conf + - name: secret-key + mountPath: /etc/core/key + subPath: key + - name: token-service-private-key + mountPath: /etc/core/private_key.pem + subPath: tls.key + {{- if .Values.expose.tls.enabled }} + - name: ca-download + mountPath: /etc/core/ca + {{- end }} + {{- if .Values.uaaSecretName }} + - name: auth-ca-cert + mountPath: /etc/core/auth-ca/auth-ca.crt + subPath: auth-ca.crt + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + mountPath: /etc/harbor/ssl/core + {{- end }} + - name: psc + mountPath: /etc/core/token + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} +{{- if .Values.core.resources }} + resources: +{{ toYaml .Values.core.resources | indent 10 }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ template "harbor.core" . }} + items: + - key: app.conf + path: app.conf + - name: secret-key + secret: + {{- if .Values.existingSecretSecretKey }} + secretName: {{ .Values.existingSecretSecretKey }} + {{- else }} + secretName: {{ template "harbor.core" . }} + {{- end }} + items: + - key: secretKey + path: key + - name: token-service-private-key + secret: + {{- if .Values.core.secretName }} + secretName: {{ .Values.core.secretName }} + {{- else }} + secretName: {{ template "harbor.core" . }} + {{- end }} + {{- if .Values.expose.tls.enabled }} + - name: ca-download + secret: + {{- if .Values.caSecretName }} + secretName: {{ .Values.caSecretName }} + {{- else if eq (include "harbor.autoGenCertForIngress" .) "true" }} + secretName: "{{ template "harbor.ingress" . }}" + {{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }} + secretName: {{ template "harbor.tlsSecretForNginx" . }} + {{- end }} + {{- end }} + {{- if .Values.uaaSecretName }} + - name: auth-ca-cert + secret: + secretName: {{ .Values.uaaSecretName }} + items: + - key: ca.crt + path: auth-ca.crt + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.core.secretName" . }} + {{- end }} + - name: psc + emptyDir: {} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.core.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.core.priorityClassName }} + priorityClassName: {{ .Values.core.priorityClassName }} + {{- end }} diff --git a/charts/harbor-helm-main/templates/core/core-pre-upgrade-job.yaml b/charts/harbor-helm-main/templates/core/core-pre-upgrade-job.yaml new file mode 100644 index 0000000..ce0b131 --- /dev/null +++ b/charts/harbor-helm-main/templates/core/core-pre-upgrade-job.yaml @@ -0,0 +1,77 @@ +{{- if .Values.enableMigrateHelmHook }} +apiVersion: batch/v1 +kind: Job +metadata: + name: migration-job + labels: +{{ include "harbor.labels" . | indent 4 }} + component: migrator + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-5" +spec: + template: + metadata: + labels: +{{ include "harbor.matchLabels" . | indent 8 }} + component: migrator + spec: + restartPolicy: Never + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.core.serviceAccountName }} + serviceAccountName: {{ .Values.core.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 120 + containers: + - name: core-job + image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/harbor/harbor_core", "-mode=migrate"] + envFrom: + - configMapRef: + name: "{{ template "harbor.core" . }}" + - secretRef: + name: "{{ template "harbor.core" . }}" + {{- if .Values.database.external.existingSecret }} + env: + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.external.existingSecret }} + key: password + {{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/core/app.conf + subPath: app.conf + volumes: + - name: config + configMap: + name: {{ template "harbor.core" . }} + items: + - key: app.conf + path: app.conf + {{- with .Values.core.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/core/core-secret.yaml b/charts/harbor-helm-main/templates/core/core-secret.yaml new file mode 100644 index 0000000..62a41fc --- /dev/null +++ b/charts/harbor-helm-main/templates/core/core-secret.yaml @@ -0,0 +1,36 @@ +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (include "harbor.core" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if not .Values.existingSecretSecretKey }} + secretKey: {{ .Values.secretKey | b64enc | quote }} + {{- end }} + {{- if not .Values.core.existingSecret }} + secret: {{ .Values.core.secret | default (include "harbor.secretKeyHelper" (dict "key" "secret" "data" $existingSecret.data)) | default (randAlphaNum 16) | b64enc | quote }} + {{- end }} + {{- if not .Values.core.secretName }} + {{- $ca := genCA "harbor-token-ca" 365 }} + tls.key: {{ .Values.core.tokenKey | default $ca.Key | b64enc | quote }} + tls.crt: {{ .Values.core.tokenCert | default $ca.Cert | b64enc | quote }} + {{- end }} + {{- if not .Values.existingSecretAdminPassword }} + HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }} + {{- end }} + {{- if not .Values.database.external.existingSecret }} + POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} + {{- end }} + {{- if not .Values.registry.credentials.existingSecret }} + REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }} + {{- end }} + {{- if not .Values.core.existingXsrfSecret }} + CSRF_KEY: {{ .Values.core.xsrfKey | default (include "harbor.secretKeyHelper" (dict "key" "CSRF_KEY" "data" $existingSecret.data)) | default (randAlphaNum 32) | b64enc | quote }} + {{- end }} +{{- if .Values.core.configureUserSettings }} + CONFIG_OVERWRITE_JSON: {{ .Values.core.configureUserSettings | b64enc | quote }} +{{- end }} + {{- template "harbor.traceJaegerPassword" . }} diff --git a/charts/harbor-helm-main/templates/core/core-svc.yaml b/charts/harbor-helm-main/templates/core/core-svc.yaml new file mode 100644 index 0000000..0d2cfb2 --- /dev/null +++ b/charts/harbor-helm-main/templates/core/core-svc.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- with .Values.core.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: +{{- if or (eq .Values.expose.ingress.controller "gce") (eq .Values.expose.ingress.controller "alb") (eq .Values.expose.ingress.controller "f5-bigip") }} + type: NodePort +{{- end }} + ports: + - name: {{ ternary "https-web" "http-web" .Values.internalTLS.enabled }} + port: {{ template "harbor.core.servicePort" . }} + targetPort: {{ template "harbor.core.containerPort" . }} +{{- if .Values.metrics.enabled}} + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.core.port }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: core diff --git a/charts/harbor-helm-main/templates/core/core-tls.yaml b/charts/harbor-helm-main/templates/core/core-tls.yaml new file mode 100644 index 0000000..c52148f --- /dev/null +++ b/charts/harbor-helm-main/templates/core/core-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.core.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + 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.key: {{ (required "The \"internalTLS.core.key\" is required!" .Values.internalTLS.core.key) | b64enc | quote }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/database/database-secret.yaml b/charts/harbor-helm-main/templates/database/database-secret.yaml new file mode 100644 index 0000000..864aff4 --- /dev/null +++ b/charts/harbor-helm-main/templates/database/database-secret.yaml @@ -0,0 +1,11 @@ +{{- if eq .Values.database.type "internal" -}} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.database" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + POSTGRES_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} +{{- end -}} diff --git a/charts/harbor-helm-main/templates/database/database-ss.yaml b/charts/harbor-helm-main/templates/database/database-ss.yaml new file mode 100644 index 0000000..dc6f962 --- /dev/null +++ b/charts/harbor-helm-main/templates/database/database-ss.yaml @@ -0,0 +1,159 @@ +{{- if eq .Values.database.type "internal" -}} +{{- $database := .Values.persistence.persistentVolumeClaim.database -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: "{{ template "harbor.database" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: database + app.kubernetes.io/component: database +spec: + replicas: 1 + serviceName: "{{ template "harbor.database" . }}" + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: database + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: database + app.kubernetes.io/component: database +{{- if .Values.database.podLabels }} +{{ toYaml .Values.database.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }} +{{- if .Values.database.podAnnotations }} +{{ toYaml .Values.database.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 999 + fsGroup: 999 +{{- if .Values.database.internal.serviceAccountName }} + serviceAccountName: {{ .Values.database.internal.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.database.internal.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 + initContainers: + # with "fsGroup" set, each time a volume is mounted, Kubernetes must recursively chown() and chmod() all the files and directories inside the volume + # this causes the postgresql reports the "data directory /var/lib/postgresql/data/pgdata has group or world access" issue when using some CSIs e.g. Ceph + # use this init container to correct the permission + # as "fsGroup" applied before the init container running, the container has enough permission to execute the command + - name: "data-permissions-ensurer" + image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + command: ["/bin/sh"] + args: ["-c", "chmod -R 700 /var/lib/postgresql/data/pgdata || true"] +{{- if .Values.database.internal.initContainer.permissions.resources }} + resources: +{{ toYaml .Values.database.internal.initContainer.permissions.resources | indent 10 }} +{{- end }} + volumeMounts: + - name: database-data + mountPath: /var/lib/postgresql/data + subPath: {{ $database.subPath }} + containers: + - name: database + image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + livenessProbe: + exec: + command: + - /docker-healthcheck.sh + initialDelaySeconds: 300 + periodSeconds: 10 + timeoutSeconds: {{ .Values.database.internal.livenessProbe.timeoutSeconds }} + readinessProbe: + exec: + command: + - /docker-healthcheck.sh + initialDelaySeconds: 1 + periodSeconds: 10 + timeoutSeconds: {{ .Values.database.internal.readinessProbe.timeoutSeconds }} +{{- if .Values.database.internal.resources }} + resources: +{{ toYaml .Values.database.internal.resources | indent 10 }} +{{- end }} + envFrom: + - secretRef: + name: "{{ template "harbor.database" . }}" + env: + # put the data into a sub directory to avoid the permission issue in k8s with restricted psp enabled + # more detail refer to https://github.com/goharbor/harbor-helm/issues/756 + - name: PGDATA + value: "/var/lib/postgresql/data/pgdata" +{{- with .Values.database.internal.extraEnvVars }} +{{- toYaml . | nindent 10 }} +{{- end }} + volumeMounts: + - name: database-data + mountPath: /var/lib/postgresql/data + subPath: {{ $database.subPath }} + - name: shm-volume + mountPath: /dev/shm + volumes: + - name: shm-volume + emptyDir: + medium: Memory + sizeLimit: {{ .Values.database.internal.shmSizeLimit }} + {{- if not .Values.persistence.enabled }} + - name: "database-data" + emptyDir: {} + {{- else if $database.existingClaim }} + - name: "database-data" + persistentVolumeClaim: + claimName: {{ $database.existingClaim }} + {{- end -}} + {{- with .Values.database.internal.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.database.internal.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.database.internal.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.database.internal.priorityClassName }} + priorityClassName: {{ .Values.database.internal.priorityClassName }} + {{- end }} + {{- if and .Values.persistence.enabled (not $database.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: "database-data" + labels: +{{ include "harbor.labels" . | indent 8 }} + annotations: + {{- range $key, $value := $database.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + accessModes: [{{ $database.accessMode | quote }}] + {{- if $database.storageClass }} + {{- if (eq "-" $database.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ $database.storageClass }}" + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $database.size | quote }} + {{- end -}} + {{- end -}} diff --git a/charts/harbor-helm-main/templates/database/database-svc.yaml b/charts/harbor-helm-main/templates/database/database-svc.yaml new file mode 100644 index 0000000..6475048 --- /dev/null +++ b/charts/harbor-helm-main/templates/database/database-svc.yaml @@ -0,0 +1,14 @@ +{{- if eq .Values.database.type "internal" -}} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.database" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - port: 5432 + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: database +{{- end -}} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/exporter/exporter-cm-env.yaml b/charts/harbor-helm-main/templates/exporter/exporter-cm-env.yaml new file mode 100644 index 0000000..0bf4e7d --- /dev/null +++ b/charts/harbor-helm-main/templates/exporter/exporter-cm-env.yaml @@ -0,0 +1,35 @@ +{{- if .Values.metrics.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.exporter" . }}-env" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + {{- if has "jobservice" .Values.proxy.components }} + HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" + HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" + NO_PROXY: "{{ template "harbor.noProxy" . }}" + {{- end }} + LOG_LEVEL: "{{ .Values.logLevel }}" + HARBOR_EXPORTER_PORT: "{{ .Values.metrics.exporter.port }}" + HARBOR_EXPORTER_METRICS_PATH: "{{ .Values.metrics.exporter.path }}" + HARBOR_EXPORTER_METRICS_ENABLED: "{{ .Values.metrics.enabled }}" + HARBOR_EXPORTER_CACHE_TIME: "{{ .Values.exporter.cacheDuration }}" + HARBOR_EXPORTER_CACHE_CLEAN_INTERVAL: "{{ .Values.exporter.cacheCleanInterval }}" + HARBOR_METRIC_NAMESPACE: harbor + HARBOR_METRIC_SUBSYSTEM: exporter + HARBOR_REDIS_URL: "{{ template "harbor.redis.urlForJobservice" . }}" + HARBOR_REDIS_NAMESPACE: harbor_job_service_namespace + HARBOR_REDIS_TIMEOUT: "3600" + HARBOR_SERVICE_SCHEME: "{{ template "harbor.component.scheme" . }}" + HARBOR_SERVICE_HOST: "{{ template "harbor.core" . }}" + HARBOR_SERVICE_PORT: "{{ template "harbor.core.servicePort" . }}" + HARBOR_DATABASE_HOST: "{{ template "harbor.database.host" . }}" + HARBOR_DATABASE_PORT: "{{ template "harbor.database.port" . }}" + HARBOR_DATABASE_USERNAME: "{{ template "harbor.database.username" . }}" + HARBOR_DATABASE_DBNAME: "{{ template "harbor.database.coreDatabase" . }}" + HARBOR_DATABASE_SSLMODE: "{{ template "harbor.database.sslmode" . }}" + HARBOR_DATABASE_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}" + HARBOR_DATABASE_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}" +{{- end}} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/exporter/exporter-dpl.yaml b/charts/harbor-helm-main/templates/exporter/exporter-dpl.yaml new file mode 100644 index 0000000..01e9258 --- /dev/null +++ b/charts/harbor-helm-main/templates/exporter/exporter-dpl.yaml @@ -0,0 +1,146 @@ +{{- if .Values.metrics.enabled}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "harbor.exporter" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: exporter + app.kubernetes.io/component: exporter +spec: + replicas: {{ .Values.exporter.replicas }} + revisionHistoryLimit: {{ .Values.exporter.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: exporter + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: exporter + app.kubernetes.io/component: exporter +{{- if .Values.exporter.podLabels }} +{{ toYaml .Values.exporter.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/exporter/exporter-cm-env.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/exporter/exporter-secret.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/core/core-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.exporter.podAnnotations }} +{{ toYaml .Values.exporter.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.exporter.serviceAccountName }} + serviceAccountName: {{ .Values.exporter.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.exporter.automountServiceAccountToken | default false }} +{{- with .Values.exporter.topologySpreadConstraints }} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: exporter +{{- end }} +{{- end }} + containers: + - name: exporter + image: {{ .Values.exporter.image.repository }}:{{ .Values.exporter.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: / + port: {{ .Values.metrics.exporter.port }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: {{ .Values.metrics.exporter.port }} + initialDelaySeconds: 30 + periodSeconds: 10 + args: ["-log-level", "{{ .Values.logLevel }}"] + envFrom: + - configMapRef: + name: "{{ template "harbor.exporter" . }}-env" + - secretRef: + name: "{{ template "harbor.exporter" . }}" + env: + {{- if .Values.database.external.existingSecret }} + - name: HARBOR_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.external.existingSecret }} + key: password + {{- end }} + {{- if .Values.existingSecretAdminPassword }} + - name: HARBOR_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.existingSecretAdminPassword }} + key: {{ .Values.existingSecretAdminPasswordKey }} + {{- end }} +{{- if .Values.exporter.resources }} + resources: +{{ toYaml .Values.exporter.resources | indent 10 }} +{{- end }} +{{- with .Values.exporter.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + ports: + - containerPort: {{ .Values.metrics.exporter.port }} + volumeMounts: + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + mountPath: /etc/harbor/ssl/core + # There are some metric data are collectd from harbor core. + # When internal TLS is enabled, the Exporter need the CA file to collect these data. + {{- end }} + volumes: + - name: config + secret: + secretName: "{{ template "harbor.exporter" . }}" + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.core.secretName" . }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.exporter.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.exporter.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.exporter.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.exporter.priorityClassName }} + priorityClassName: {{ .Values.exporter.priorityClassName }} + {{- end }} +{{ end }} diff --git a/charts/harbor-helm-main/templates/exporter/exporter-secret.yaml b/charts/harbor-helm-main/templates/exporter/exporter-secret.yaml new file mode 100644 index 0000000..434a1bf --- /dev/null +++ b/charts/harbor-helm-main/templates/exporter/exporter-secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.metrics.enabled}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.exporter" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: +{{- if not .Values.existingSecretAdminPassword }} + HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }} +{{- end }} +{{- if not .Values.database.external.existingSecret }} + HARBOR_DATABASE_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} +{{- end }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/exporter/exporter-svc.yaml b/charts/harbor-helm-main/templates/exporter/exporter-svc.yaml new file mode 100644 index 0000000..4a6f3fd --- /dev/null +++ b/charts/harbor-helm-main/templates/exporter/exporter-svc.yaml @@ -0,0 +1,15 @@ +{{- if .Values.metrics.enabled}} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.exporter" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.exporter.port }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: exporter +{{ end }} diff --git a/charts/harbor-helm-main/templates/ingress/ingress.yaml b/charts/harbor-helm-main/templates/ingress/ingress.yaml new file mode 100644 index 0000000..73472c6 --- /dev/null +++ b/charts/harbor-helm-main/templates/ingress/ingress.yaml @@ -0,0 +1,142 @@ +{{- if eq .Values.expose.type "ingress" }} +{{- $ingress := .Values.expose.ingress -}} +{{- $tls := .Values.expose.tls -}} +{{- if eq .Values.expose.ingress.controller "gce" }} + {{- $_ := set . "portal_path" "/*" -}} + {{- $_ := set . "api_path" "/api/*" -}} + {{- $_ := set . "service_path" "/service/*" -}} + {{- $_ := set . "v2_path" "/v2/*" -}} + {{- $_ := set . "chartrepo_path" "/chartrepo/*" -}} + {{- $_ := set . "controller_path" "/c/*" -}} +{{- else if eq .Values.expose.ingress.controller "ncp" }} + {{- $_ := set . "portal_path" "/.*" -}} + {{- $_ := set . "api_path" "/api/.*" -}} + {{- $_ := set . "service_path" "/service/.*" -}} + {{- $_ := set . "v2_path" "/v2/.*" -}} + {{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}} + {{- $_ := set . "controller_path" "/c/.*" -}} +{{- else }} + {{- $_ := set . "portal_path" "/" -}} + {{- $_ := set . "api_path" "/api/" -}} + {{- $_ := set . "service_path" "/service/" -}} + {{- $_ := set . "v2_path" "/v2/" -}} + {{- $_ := set . "chartrepo_path" "/chartrepo/" -}} + {{- $_ := set . "controller_path" "/c/" -}} +{{- end }} + +--- +{{- if semverCompare "<1.14-0" (include "harbor.ingress.kubeVersion" .) }} +apiVersion: extensions/v1beta1 +{{- else if semverCompare "<1.19-0" (include "harbor.ingress.kubeVersion" .) }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: networking.k8s.io/v1 +{{- end }} +kind: Ingress +metadata: + name: "{{ template "harbor.ingress" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- if $ingress.labels }} +{{ toYaml $ingress.labels | indent 4 }} +{{- end }} + annotations: +{{ toYaml $ingress.annotations | indent 4 }} +{{- if .Values.internalTLS.enabled }} + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" +{{- end }} +{{- if eq .Values.expose.ingress.controller "ncp" }} + ncp/use-regex: "true" + {{- if $tls.enabled }} + ncp/http-redirect: "true" + {{- end }} +{{- end }} +spec: + {{- if $ingress.className }} + ingressClassName: {{ $ingress.className }} + {{- end }} + {{- if $tls.enabled }} + tls: + - secretName: {{ template "harbor.tlsCoreSecretForIngress" . }} + {{- if $ingress.hosts.core }} + hosts: + - {{ $ingress.hosts.core }} + {{- end }} + {{- end }} + rules: + - http: + paths: +{{- if semverCompare "<1.19-0" (include "harbor.ingress.kubeVersion" .) }} + - path: {{ .api_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .service_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .v2_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .chartrepo_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .controller_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .portal_path }} + backend: + serviceName: {{ template "harbor.portal" . }} + servicePort: {{ template "harbor.portal.servicePort" . }} +{{- else }} + - path: {{ .api_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .service_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .v2_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .chartrepo_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .controller_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .portal_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.portal" . }} + port: + number: {{ template "harbor.portal.servicePort" . }} +{{- end }} + {{- if $ingress.hosts.core }} + host: {{ $ingress.hosts.core }} + {{- end }} + +{{- end }} diff --git a/charts/harbor-helm-main/templates/ingress/secret.yaml b/charts/harbor-helm-main/templates/ingress/secret.yaml new file mode 100644 index 0000000..41507b3 --- /dev/null +++ b/charts/harbor-helm-main/templates/ingress/secret.yaml @@ -0,0 +1,15 @@ +{{- if eq (include "harbor.autoGenCertForIngress" .) "true" }} +{{- $ca := genCA "harbor-ca" 365 }} +{{- $cert := genSignedCert .Values.expose.ingress.hosts.core nil (list .Values.expose.ingress.hosts.core) 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.ingress" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ $cert.Cert | b64enc | quote }} + tls.key: {{ $cert.Key | b64enc | quote }} + ca.crt: {{ $ca.Cert | b64enc | quote }} +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/internal/auto-tls.yaml b/charts/harbor-helm-main/templates/internal/auto-tls.yaml new file mode 100644 index 0000000..da5f5e2 --- /dev/null +++ b/charts/harbor-helm-main/templates/internal/auto-tls.yaml @@ -0,0 +1,81 @@ +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} +{{- $ca := genCA "harbor-internal-ca" 365 }} +{{- $coreCN := (include "harbor.core" .) }} +{{- $coreCrt := genSignedCert $coreCN (list "127.0.0.1") (list "localhost" $coreCN) 365 $ca }} +{{- $jsCN := (include "harbor.jobservice" .) }} +{{- $jsCrt := genSignedCert $jsCN nil (list $jsCN) 365 $ca }} +{{- $regCN := (include "harbor.registry" .) }} +{{- $regCrt := genSignedCert $regCN nil (list $regCN) 365 $ca }} +{{- $portalCN := (include "harbor.portal" .) }} +{{- $portalCrt := genSignedCert $portalCN nil (list $portalCN) 365 $ca }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.core.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $coreCrt.Cert | b64enc | quote }} + tls.key: {{ $coreCrt.Key | b64enc | quote }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $jsCrt.Cert | b64enc | quote }} + tls.key: {{ $jsCrt.Key | b64enc | quote }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.registry.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $regCrt.Cert | b64enc | quote }} + tls.key: {{ $regCrt.Key | b64enc | quote }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.portal.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $portalCrt.Cert | b64enc | quote }} + tls.key: {{ $portalCrt.Key | b64enc | quote }} + +{{- if and .Values.trivy.enabled}} +--- +{{- $trivyCN := (include "harbor.trivy" .) }} +{{- $trivyCrt := genSignedCert $trivyCN nil (list $trivyCN) 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.trivy.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $trivyCrt.Cert | b64enc | quote }} + tls.key: {{ $trivyCrt.Key | b64enc | quote }} +{{- end }} + +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/jobservice/jobservice-cm-env.yaml b/charts/harbor-helm-main/templates/jobservice/jobservice-cm-env.yaml new file mode 100644 index 0000000..8411c7a --- /dev/null +++ b/charts/harbor-helm-main/templates/jobservice/jobservice-cm-env.yaml @@ -0,0 +1,34 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.jobservice" . }}-env" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + CORE_URL: "{{ template "harbor.coreURL" . }}" + TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}" + REGISTRY_URL: "{{ template "harbor.registryURL" . }}" + REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}" + REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}" + + JOBSERVICE_WEBHOOK_JOB_MAX_RETRY: "{{ .Values.jobservice.notification.webhook_job_max_retry }}" + JOBSERVICE_WEBHOOK_JOB_HTTP_CLIENT_TIMEOUT: "{{ .Values.jobservice.notification.webhook_job_http_client_timeout }}" + + {{- if has "jobservice" .Values.proxy.components }} + HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" + HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" + NO_PROXY: "{{ template "harbor.noProxy" . }}" + {{- end }} + {{- if .Values.metrics.enabled}} + METRIC_NAMESPACE: harbor + METRIC_SUBSYSTEM: jobservice + {{- end }} + {{- template "harbor.traceEnvsForJobservice" . }} + {{- if .Values.cache.enabled }} + _REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}" + CACHE_ENABLED: "true" + CACHE_EXPIRE_HOURS: "{{ .Values.cache.expireHours }}" + {{- end }} + {{- if or (and (eq .Values.redis.type "internal") .Values.redis.internal.cacheLayerDatabaseIndex) (and (eq .Values.redis.type "external") .Values.redis.external.cacheLayerDatabaseIndex) }} + _REDIS_URL_CACHE_LAYER: "{{ template "harbor.redis.urlForCache" . }}" + {{- end }} diff --git a/charts/harbor-helm-main/templates/jobservice/jobservice-cm.yaml b/charts/harbor-helm-main/templates/jobservice/jobservice-cm.yaml new file mode 100644 index 0000000..8211c62 --- /dev/null +++ b/charts/harbor-helm-main/templates/jobservice/jobservice-cm.yaml @@ -0,0 +1,57 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + config.yml: |+ + #Server listening port + protocol: "{{ template "harbor.component.scheme" . }}" + port: {{ template "harbor.jobservice.containerPort". }} + {{- if .Values.internalTLS.enabled }} + https_config: + cert: "/etc/harbor/ssl/jobservice/tls.crt" + key: "/etc/harbor/ssl/jobservice/tls.key" + {{- end }} + worker_pool: + workers: {{ .Values.jobservice.maxJobWorkers }} + backend: "redis" + redis_pool: + redis_url: "{{ template "harbor.redis.urlForJobservice" . }}" + namespace: "harbor_job_service_namespace" + idle_timeout_second: 3600 + job_loggers: + {{- if has "file" .Values.jobservice.jobLoggers }} + - name: "FILE" + level: {{ .Values.logLevel | upper }} + settings: # Customized settings of logger + base_dir: "/var/log/jobs" + sweeper: + duration: {{ .Values.jobservice.loggerSweeperDuration }} #days + settings: # Customized settings of sweeper + work_dir: "/var/log/jobs" + {{- end }} + {{- if has "database" .Values.jobservice.jobLoggers }} + - name: "DB" + level: {{ .Values.logLevel | upper }} + sweeper: + duration: {{ .Values.jobservice.loggerSweeperDuration }} #days + {{- end }} + {{- if has "stdout" .Values.jobservice.jobLoggers }} + - name: "STD_OUTPUT" + level: {{ .Values.logLevel | upper }} + {{- end }} + metric: + enabled: {{ .Values.metrics.enabled }} + path: {{ .Values.metrics.jobservice.path }} + port: {{ .Values.metrics.jobservice.port }} + #Loggers for the job service + loggers: + - name: "STD_OUTPUT" + level: {{ .Values.logLevel | upper }} + reaper: + # the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24 + max_update_hours: {{ .Values.jobservice.reaper.max_update_hours }} + # the max time for execution in running state without new task created + max_dangling_hours: {{ .Values.jobservice.reaper.max_dangling_hours }} diff --git a/charts/harbor-helm-main/templates/jobservice/jobservice-dpl.yaml b/charts/harbor-helm-main/templates/jobservice/jobservice-dpl.yaml new file mode 100644 index 0000000..780d5e4 --- /dev/null +++ b/charts/harbor-helm-main/templates/jobservice/jobservice-dpl.yaml @@ -0,0 +1,178 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: jobservice + app.kubernetes.io/component: jobservice +spec: + replicas: {{ .Values.jobservice.replicas }} + revisionHistoryLimit: {{ .Values.jobservice.revisionHistoryLimit }} + strategy: + type: {{ .Values.updateStrategy.type }} + {{- if eq .Values.updateStrategy.type "Recreate" }} + rollingUpdate: null + {{- end }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: jobservice + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: jobservice + app.kubernetes.io/component: jobservice +{{- if .Values.jobservice.podLabels }} +{{ toYaml .Values.jobservice.podLabels | indent 8 }} +{{- end }} + annotations: + 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/secret: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} + checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/jobservice/jobservice-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.jobservice.podAnnotations }} +{{ toYaml .Values.jobservice.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.jobservice.serviceAccountName }} + serviceAccountName: {{ .Values.jobservice.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.jobservice.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 +{{- with .Values.jobservice.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: jobservice +{{- end }} +{{- end }} + containers: + - name: jobservice + image: {{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: /api/v1/stats + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.jobservice.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/v1/stats + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.jobservice.containerPort" . }} + initialDelaySeconds: 20 + periodSeconds: 10 +{{- if .Values.jobservice.resources }} + resources: +{{ toYaml .Values.jobservice.resources | indent 10 }} +{{- end }} + env: + - name: CORE_SECRET + valueFrom: + secretKeyRef: + name: {{ default (include "harbor.core" .) .Values.core.existingSecret }} + key: secret + {{- if .Values.jobservice.existingSecret }} + - name: JOBSERVICE_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.jobservice.existingSecret }} + key: {{ .Values.jobservice.existingSecretKey }} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/jobservice/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/jobservice/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/jobservice/ca.crt + {{- end }} + {{- if .Values.registry.credentials.existingSecret }} + - name: REGISTRY_CREDENTIAL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.registry.credentials.existingSecret }} + key: REGISTRY_PASSWD + {{- end }} +{{- with .Values.jobservice.extraEnvVars }} +{{- toYaml . | nindent 10 }} +{{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + envFrom: + - configMapRef: + name: "{{ template "harbor.jobservice" . }}-env" + - secretRef: + name: "{{ template "harbor.jobservice" . }}" + ports: + - containerPort: {{ template "harbor.jobservice.containerPort" . }} + volumeMounts: + - name: jobservice-config + mountPath: /etc/jobservice/config.yml + subPath: config.yml + - name: job-logs + mountPath: /var/log/jobs + subPath: {{ .Values.persistence.persistentVolumeClaim.jobservice.jobLog.subPath }} + {{- if .Values.internalTLS.enabled }} + - name: jobservice-internal-certs + mountPath: /etc/harbor/ssl/jobservice + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + volumes: + - name: jobservice-config + configMap: + name: "{{ template "harbor.jobservice" . }}" + - name: job-logs + {{- if and .Values.persistence.enabled (has "file" .Values.jobservice.jobLoggers) }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.persistentVolumeClaim.jobservice.jobLog.existingClaim | default (include "harbor.jobservice" .) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: jobservice-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.jobservice.secretName" . }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.jobservice.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.jobservice.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.jobservice.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.jobservice.priorityClassName }} + priorityClassName: {{ .Values.jobservice.priorityClassName }} + {{- end }} diff --git a/charts/harbor-helm-main/templates/jobservice/jobservice-pvc.yaml b/charts/harbor-helm-main/templates/jobservice/jobservice-pvc.yaml new file mode 100644 index 0000000..3f7d00b --- /dev/null +++ b/charts/harbor-helm-main/templates/jobservice/jobservice-pvc.yaml @@ -0,0 +1,31 @@ +{{- $jobLog := .Values.persistence.persistentVolumeClaim.jobservice.jobLog -}} +{{- if and .Values.persistence.enabled (not $jobLog.existingClaim) (has "file" .Values.jobservice.jobLoggers) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "harbor.jobservice" . }} + annotations: + {{- range $key, $value := $jobLog.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if eq .Values.persistence.resourcePolicy "keep" }} + helm.sh/resource-policy: keep + {{- end }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: jobservice + app.kubernetes.io/component: jobservice +spec: + accessModes: + - {{ $jobLog.accessMode }} + resources: + requests: + storage: {{ $jobLog.size }} + {{- if $jobLog.storageClass }} + {{- if eq "-" $jobLog.storageClass }} + storageClassName: "" + {{- else }} + storageClassName: {{ $jobLog.storageClass }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/jobservice/jobservice-secrets.yaml b/charts/harbor-helm-main/templates/jobservice/jobservice-secrets.yaml new file mode 100644 index 0000000..eeb00bd --- /dev/null +++ b/charts/harbor-helm-main/templates/jobservice/jobservice-secrets.yaml @@ -0,0 +1,16 @@ +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (include "harbor.jobservice" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if not .Values.jobservice.existingSecret }} + JOBSERVICE_SECRET: {{ .Values.jobservice.secret | default (include "harbor.secretKeyHelper" (dict "key" "JOBSERVICE_SECRET" "data" $existingSecret.data)) | default (randAlphaNum 16) | b64enc | quote }} + {{- end }} + {{- if not .Values.registry.credentials.existingSecret }} + REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }} + {{- end }} + {{- template "harbor.traceJaegerPassword" . }} diff --git a/charts/harbor-helm-main/templates/jobservice/jobservice-svc.yaml b/charts/harbor-helm-main/templates/jobservice/jobservice-svc.yaml new file mode 100644 index 0000000..d2b7a47 --- /dev/null +++ b/charts/harbor-helm-main/templates/jobservice/jobservice-svc.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ ternary "https-jobservice" "http-jobservice" .Values.internalTLS.enabled }} + port: {{ template "harbor.jobservice.servicePort" . }} + targetPort: {{ template "harbor.jobservice.containerPort" . }} +{{- if .Values.metrics.enabled }} + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.jobservice.port }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: jobservice diff --git a/charts/harbor-helm-main/templates/jobservice/jobservice-tls.yaml b/charts/harbor-helm-main/templates/jobservice/jobservice-tls.yaml new file mode 100644 index 0000000..234cb39 --- /dev/null +++ b/charts/harbor-helm-main/templates/jobservice/jobservice-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + 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.key: {{ (required "The \"internalTLS.jobservice.key\" is required!" .Values.internalTLS.jobservice.key) | b64enc | quote }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/metrics/metrics-svcmon.yaml b/charts/harbor-helm-main/templates/metrics/metrics-svcmon.yaml new file mode 100644 index 0000000..1122ef0 --- /dev/null +++ b/charts/harbor-helm-main/templates/metrics/metrics-svcmon.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "harbor.fullname" . }} + labels: {{ include "harbor.labels" . | nindent 4 }} +{{- if .Values.metrics.serviceMonitor.additionalLabels }} +{{ toYaml .Values.metrics.serviceMonitor.additionalLabels | indent 4 }} +{{- end }} +spec: + jobLabel: app.kubernetes.io/name + endpoints: + - port: {{ template "harbor.metricsPortName" . }} + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + honorLabels: true +{{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.metrics.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: +{{ toYaml .Values.metrics.serviceMonitor.relabelings | indent 4 }} +{{- end }} + selector: + matchLabels: {{ include "harbor.matchLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/nginx/configmap-http.yaml b/charts/harbor-helm-main/templates/nginx/configmap-http.yaml new file mode 100644 index 0000000..c4b8354 --- /dev/null +++ b/charts/harbor-helm-main/templates/nginx/configmap-http.yaml @@ -0,0 +1,150 @@ +{{- if and (ne .Values.expose.type "ingress") (not .Values.expose.tls.enabled) }} +{{- $scheme := (include "harbor.component.scheme" .) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + nginx.conf: |+ + worker_processes auto; + pid /tmp/nginx.pid; + + events { + worker_connections 3096; + use epoll; + multi_accept on; + } + + http { + client_body_temp_path /tmp/client_body_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + tcp_nodelay on; + + # this is necessary for us to be able to disable request buffering in all cases + proxy_http_version 1.1; + + upstream core { + server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}"; + } + + upstream portal { + server {{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}; + } + + log_format timed_combined '[$time_local]:$remote_addr - ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$request_time $upstream_response_time $pipe'; + + access_log /dev/stdout timed_combined; + + map $http_x_forwarded_proto $x_forwarded_proto { + default $http_x_forwarded_proto; + "" $scheme; + } + + server { + {{- if .Values.ipFamily.ipv4.enabled}} + listen 8080; + {{- end}} + {{- if .Values.ipFamily.ipv6.enabled }} + listen [::]:8080; + {{- end }} + server_tokens off; + # disable any limits to avoid HTTP 413 for large image uploads + client_max_body_size 0; + + # Add extra headers + add_header X-Frame-Options DENY; + add_header Content-Security-Policy "frame-ancestors 'none'"; + + location / { + proxy_pass {{ $scheme }}://portal/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /api/ { + proxy_pass {{ $scheme }}://core/api/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /chartrepo/ { + proxy_pass {{ $scheme }}://core/chartrepo/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /c/ { + proxy_pass {{ $scheme }}://core/c/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /v1/ { + return 404; + } + + location /v2/ { + proxy_pass {{ $scheme }}://core/v2/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + proxy_buffering off; + proxy_request_buffering off; + proxy_send_timeout 900; + proxy_read_timeout 900; + } + + location /service/ { + proxy_pass {{ $scheme }}://core/service/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /service/notifications { + return 404; + } + } + } +{{- end }} diff --git a/charts/harbor-helm-main/templates/nginx/configmap-https.yaml b/charts/harbor-helm-main/templates/nginx/configmap-https.yaml new file mode 100644 index 0000000..56c943a --- /dev/null +++ b/charts/harbor-helm-main/templates/nginx/configmap-https.yaml @@ -0,0 +1,187 @@ +{{- if and (ne .Values.expose.type "ingress") .Values.expose.tls.enabled }} +{{- $scheme := (include "harbor.component.scheme" .) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + nginx.conf: |+ + worker_processes auto; + pid /tmp/nginx.pid; + + events { + worker_connections 3096; + use epoll; + multi_accept on; + } + + http { + client_body_temp_path /tmp/client_body_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + tcp_nodelay on; + + # this is necessary for us to be able to disable request buffering in all cases + proxy_http_version 1.1; + + upstream core { + server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}"; + } + + upstream portal { + server "{{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}"; + } + + log_format timed_combined '[$time_local]:$remote_addr - ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$request_time $upstream_response_time $pipe'; + + access_log /dev/stdout timed_combined; + + map $http_x_forwarded_proto $x_forwarded_proto { + default $http_x_forwarded_proto; + "" $scheme; + } + + server { + {{- if .Values.ipFamily.ipv4.enabled }} + listen 8443 ssl; + {{- end}} + {{- if .Values.ipFamily.ipv6.enabled }} + listen [::]:8443 ssl; + {{- end }} + # server_name harbordomain.com; + server_tokens off; + # SSL + ssl_certificate /etc/nginx/cert/tls.crt; + ssl_certificate_key /etc/nginx/cert/tls.key; + + # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.2 TLSv1.3; + {{- if .Values.internalTLS.strong_ssl_ciphers }} + ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:ECDHE+RSA+SHA256:DHE+RSA+SHA256:!AES128; + {{ else }} + ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; + {{- end }} + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + + # disable any limits to avoid HTTP 413 for large image uploads + client_max_body_size 0; + + # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) + chunked_transfer_encoding on; + + # Add extra headers + add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; + add_header X-Frame-Options DENY; + add_header Content-Security-Policy "frame-ancestors 'none'"; + + location / { + proxy_pass {{ $scheme }}://portal/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; HttpOnly; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /api/ { + proxy_pass {{ $scheme }}://core/api/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /chartrepo/ { + proxy_pass {{ $scheme }}://core/chartrepo/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /c/ { + proxy_pass {{ $scheme }}://core/c/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /v1/ { + return 404; + } + + location /v2/ { + proxy_pass {{ $scheme }}://core/v2/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + proxy_buffering off; + proxy_request_buffering off; + } + + location /service/ { + proxy_pass {{ $scheme }}://core/service/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /service/notifications { + return 404; + } + } + server { + {{- if .Values.ipFamily.ipv4.enabled }} + listen 8080; + {{- end}} + {{- if .Values.ipFamily.ipv6.enabled }} + listen [::]:8080; + {{- end}} + #server_name harbordomain.com; + return 301 https://$host$request_uri; + } + } +{{- end }} diff --git a/charts/harbor-helm-main/templates/nginx/deployment.yaml b/charts/harbor-helm-main/templates/nginx/deployment.yaml new file mode 100644 index 0000000..3abc941 --- /dev/null +++ b/charts/harbor-helm-main/templates/nginx/deployment.yaml @@ -0,0 +1,132 @@ +{{- if ne .Values.expose.type "ingress" }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: nginx + app.kubernetes.io/component: nginx +spec: + replicas: {{ .Values.nginx.replicas }} + revisionHistoryLimit: {{ .Values.nginx.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: nginx + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: nginx + app.kubernetes.io/component: nginx +{{- if .Values.nginx.podLabels }} +{{ toYaml .Values.nginx.podLabels | indent 8 }} +{{- end }} + annotations: + {{- if not .Values.expose.tls.enabled }} + checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-http.yaml") . | sha256sum }} + {{- else }} + checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-https.yaml") . | sha256sum }} + {{- end }} + {{- if eq (include "harbor.autoGenCertForNginx" .) "true" }} + checksum/secret: {{ include (print $.Template.BasePath "/nginx/secret.yaml") . | sha256sum }} + {{- end }} +{{- if .Values.nginx.podAnnotations }} +{{ toYaml .Values.nginx.podAnnotations | indent 8 }} +{{- end }} + spec: +{{- if .Values.nginx.serviceAccountName }} + serviceAccountName: {{ .Values.nginx.serviceAccountName }} +{{- end }} + securityContext: + runAsUser: 10000 + fsGroup: 10000 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.nginx.automountServiceAccountToken | default false }} +{{- with .Values.nginx.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: nginx +{{- end }} +{{- end }} + containers: + - name: nginx + image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + {{- $_ := set . "scheme" "HTTP" -}} + {{- $_ := set . "port" "8080" -}} + {{- if .Values.expose.tls.enabled }} + {{- $_ := set . "scheme" "HTTPS" -}} + {{- $_ := set . "port" "8443" -}} + {{- end }} + livenessProbe: + httpGet: + scheme: {{ .scheme }} + path: / + port: {{ .port }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + scheme: {{ .scheme }} + path: / + port: {{ .port }} + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.nginx.resources }} + resources: +{{ toYaml .Values.nginx.resources | indent 10 }} +{{- end }} +{{- with .Values.nginx.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + ports: + - containerPort: 8080 + {{- if .Values.expose.tls.enabled }} + - containerPort: 8443 + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + {{- if .Values.expose.tls.enabled }} + - name: certificate + mountPath: /etc/nginx/cert + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "harbor.nginx" . }} + {{- if .Values.expose.tls.enabled }} + - name: certificate + secret: + secretName: {{ template "harbor.tlsSecretForNginx" . }} + {{- end }} + {{- with .Values.nginx.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.nginx.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.nginx.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.nginx.priorityClassName }} + priorityClassName: {{ .Values.nginx.priorityClassName }} + {{- end }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/nginx/secret.yaml b/charts/harbor-helm-main/templates/nginx/secret.yaml new file mode 100644 index 0000000..c819c55 --- /dev/null +++ b/charts/harbor-helm-main/templates/nginx/secret.yaml @@ -0,0 +1,23 @@ +{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }} +{{- $ca := genCA "harbor-ca" 365 }} +{{- $cn := (required "The \"expose.tls.auto.commonName\" is required!" .Values.expose.tls.auto.commonName) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if regexMatch `^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$` $cn }} + {{- $cert := genSignedCert $cn (list $cn) nil 365 $ca }} + tls.crt: {{ $cert.Cert | b64enc | quote }} + tls.key: {{ $cert.Key | b64enc | quote }} + ca.crt: {{ $ca.Cert | b64enc | quote }} + {{- else }} + {{- $cert := genSignedCert $cn nil (list $cn) 365 $ca }} + tls.crt: {{ $cert.Cert | b64enc | quote }} + tls.key: {{ $cert.Key | b64enc | quote }} + ca.crt: {{ $ca.Cert | b64enc | quote }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/nginx/service.yaml b/charts/harbor-helm-main/templates/nginx/service.yaml new file mode 100644 index 0000000..691584c --- /dev/null +++ b/charts/harbor-helm-main/templates/nginx/service.yaml @@ -0,0 +1,94 @@ +{{- if or (eq .Values.expose.type "clusterIP") (eq .Values.expose.type "nodePort") (eq .Values.expose.type "loadBalancer") }} +apiVersion: v1 +kind: Service +metadata: +{{- if eq .Values.expose.type "clusterIP" }} +{{- $clusterIP := .Values.expose.clusterIP }} + name: {{ $clusterIP.name }} + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- if .Values.expose.clusterIP.labels }} +{{ toYaml $clusterIP.labels | indent 4 }} +{{- end }} +{{- with $clusterIP.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: ClusterIP + {{- if .Values.expose.clusterIP.staticClusterIP }} + clusterIP: {{ .Values.expose.clusterIP.staticClusterIP }} + {{- end }} + ports: + - name: http + port: {{ $clusterIP.ports.httpPort }} + targetPort: 8080 + {{- if .Values.expose.tls.enabled }} + - name: https + port: {{ $clusterIP.ports.httpsPort }} + targetPort: 8443 + {{- end }} +{{- else if eq .Values.expose.type "nodePort" }} +{{- $nodePort := .Values.expose.nodePort }} + name: {{ $nodePort.name }} + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- if .Values.expose.nodePort.labels }} +{{ toYaml $nodePort.labels | indent 4 }} +{{- end }} +{{- with $nodePort.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: NodePort + ports: + - name: http + port: {{ $nodePort.ports.http.port }} + targetPort: 8080 + {{- if $nodePort.ports.http.nodePort }} + nodePort: {{ $nodePort.ports.http.nodePort }} + {{- end }} + {{- if .Values.expose.tls.enabled }} + - name: https + port: {{ $nodePort.ports.https.port }} + targetPort: 8443 + {{- if $nodePort.ports.https.nodePort }} + nodePort: {{ $nodePort.ports.https.nodePort }} + {{- end }} + {{- end }} +{{- else if eq .Values.expose.type "loadBalancer" }} +{{- $loadBalancer := .Values.expose.loadBalancer }} + name: {{ $loadBalancer.name }} + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- if .Values.expose.loadBalancer.labels }} +{{ toYaml $loadBalancer.labels | indent 4 }} +{{- end }} +{{- with $loadBalancer.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: LoadBalancer + {{- with $loadBalancer.sourceRanges }} + loadBalancerSourceRanges: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $loadBalancer.IP }} + loadBalancerIP: {{ $loadBalancer.IP }} + {{- end }} + ports: + - name: http + port: {{ $loadBalancer.ports.httpPort }} + targetPort: 8080 + {{- if .Values.expose.tls.enabled }} + - name: https + port: {{ $loadBalancer.ports.httpsPort }} + targetPort: 8443 + {{- end }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: nginx +{{- end }} diff --git a/charts/harbor-helm-main/templates/portal/configmap.yaml b/charts/harbor-helm-main/templates/portal/configmap.yaml new file mode 100644 index 0000000..7b2118e --- /dev/null +++ b/charts/harbor-helm-main/templates/portal/configmap.yaml @@ -0,0 +1,67 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.portal" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + nginx.conf: |+ + worker_processes auto; + pid /tmp/nginx.pid; + events { + worker_connections 1024; + } + http { + client_body_temp_path /tmp/client_body_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + server { + {{- if .Values.internalTLS.enabled }} + {{- if .Values.ipFamily.ipv4.enabled}} + listen {{ template "harbor.portal.containerPort" . }} ssl; + {{- end }} + {{- if .Values.ipFamily.ipv6.enabled}} + listen [::]:{{ template "harbor.portal.containerPort" . }} ssl; + {{- end }} + # SSL + ssl_certificate /etc/harbor/ssl/portal/tls.crt; + ssl_certificate_key /etc/harbor/ssl/portal/tls.key; + + # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.2 TLSv1.3; + {{- if .Values.internalTLS.strong_ssl_ciphers }} + ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:ECDHE+RSA+SHA256:DHE+RSA+SHA256:!AES128; + {{ else }} + ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; + {{- end }} + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + {{- else }} + {{- if .Values.ipFamily.ipv4.enabled }} + listen {{ template "harbor.portal.containerPort" . }}; + {{- end }} + {{- if .Values.ipFamily.ipv6.enabled}} + listen [::]:{{ template "harbor.portal.containerPort" . }}; + {{- end }} + {{- end }} + server_name localhost; + root /usr/share/nginx/html; + index index.html index.htm; + include /etc/nginx/mime.types; + gzip on; + gzip_min_length 1000; + 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; + location /devcenter-api-2.0 { + try_files $uri $uri/ /swagger-ui-index.html; + } + location / { + try_files $uri $uri/ /index.html; + } + location = /index.html { + add_header Cache-Control "no-store, no-cache, must-revalidate"; + } + } + } diff --git a/charts/harbor-helm-main/templates/portal/deployment.yaml b/charts/harbor-helm-main/templates/portal/deployment.yaml new file mode 100644 index 0000000..01d1e85 --- /dev/null +++ b/charts/harbor-helm-main/templates/portal/deployment.yaml @@ -0,0 +1,119 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "harbor.portal" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: portal + app.kubernetes.io/component: portal +spec: + replicas: {{ .Values.portal.replicas }} + revisionHistoryLimit: {{ .Values.portal.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: portal + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: portal + app.kubernetes.io/component: portal +{{- if .Values.portal.podLabels }} +{{ toYaml .Values.portal.podLabels | indent 8 }} +{{- end }} + annotations: +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/portal/tls.yaml") . | sha256sum }} +{{- end }} + checksum/configmap: {{ include (print $.Template.BasePath "/portal/configmap.yaml") . | sha256sum }} +{{- if .Values.portal.podAnnotations }} +{{ toYaml .Values.portal.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- if .Values.portal.serviceAccountName }} + serviceAccountName: {{ .Values.portal.serviceAccountName }} +{{- end }} + automountServiceAccountToken: {{ .Values.portal.automountServiceAccountToken | default false }} +{{- with .Values.portal.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: portal +{{- end }} +{{- end }} + containers: + - name: portal + image: {{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} +{{- if .Values.portal.resources }} + resources: +{{ toYaml .Values.portal.resources | indent 10 }} +{{- end }} +{{- with .Values.portal.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + livenessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.portal.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.portal.containerPort" . }} + initialDelaySeconds: 1 + periodSeconds: 10 + ports: + - containerPort: {{ template "harbor.portal.containerPort" . }} + volumeMounts: + - name: portal-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + {{- if .Values.internalTLS.enabled }} + - name: portal-internal-certs + mountPath: /etc/harbor/ssl/portal + {{- end }} + volumes: + - name: portal-config + configMap: + name: "{{ template "harbor.portal" . }}" + {{- if .Values.internalTLS.enabled }} + - name: portal-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.portal.secretName" . }} + {{- end }} + {{- with .Values.portal.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.portal.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.portal.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.portal.priorityClassName }} + priorityClassName: {{ .Values.portal.priorityClassName }} + {{- end }} diff --git a/charts/harbor-helm-main/templates/portal/service.yaml b/charts/harbor-helm-main/templates/portal/service.yaml new file mode 100644 index 0000000..d00026d --- /dev/null +++ b/charts/harbor-helm-main/templates/portal/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.portal" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- with .Values.portal.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: +{{- if or (eq .Values.expose.ingress.controller "gce") (eq .Values.expose.ingress.controller "alb") (eq .Values.expose.ingress.controller "f5-bigip") }} + type: NodePort +{{- end }} + ports: + - port: {{ template "harbor.portal.servicePort" . }} + targetPort: {{ template "harbor.portal.containerPort" . }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: portal diff --git a/charts/harbor-helm-main/templates/portal/tls.yaml b/charts/harbor-helm-main/templates/portal/tls.yaml new file mode 100644 index 0000000..de63f4e --- /dev/null +++ b/charts/harbor-helm-main/templates/portal/tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.portal.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + 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.key: {{ (required "The \"internalTLS.portal.key\" is required!" .Values.internalTLS.portal.key) | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/redis/service.yaml b/charts/harbor-helm-main/templates/redis/service.yaml new file mode 100644 index 0000000..79c95c3 --- /dev/null +++ b/charts/harbor-helm-main/templates/redis/service.yaml @@ -0,0 +1,14 @@ +{{- if eq .Values.redis.type "internal" -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "harbor.redis" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - port: 6379 + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: redis +{{- end -}} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/redis/statefulset.yaml b/charts/harbor-helm-main/templates/redis/statefulset.yaml new file mode 100644 index 0000000..9573f9a --- /dev/null +++ b/charts/harbor-helm-main/templates/redis/statefulset.yaml @@ -0,0 +1,121 @@ +{{- if eq .Values.redis.type "internal" -}} +{{- $redis := .Values.persistence.persistentVolumeClaim.redis -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "harbor.redis" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: redis + app.kubernetes.io/component: redis +spec: + replicas: 1 + serviceName: {{ template "harbor.redis" . }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: redis + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: redis + app.kubernetes.io/component: redis +{{- if .Values.redis.podLabels }} +{{ toYaml .Values.redis.podLabels | indent 8 }} +{{- end }} +{{- if .Values.redis.podAnnotations }} + annotations: +{{ toYaml .Values.redis.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 999 + fsGroup: 999 +{{- if .Values.redis.internal.serviceAccountName }} + serviceAccountName: {{ .Values.redis.internal.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.redis.internal.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 + containers: + - name: redis + image: {{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + livenessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.redis.internal.resources }} + resources: +{{ toYaml .Values.redis.internal.resources | indent 10 }} +{{- end }} +{{- with .Values.redis.internal.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + volumeMounts: + - name: data + mountPath: /var/lib/redis + subPath: {{ $redis.subPath }} + {{- if not .Values.persistence.enabled }} + volumes: + - name: data + emptyDir: {} + {{- else if $redis.existingClaim }} + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ $redis.existingClaim }} + {{- end -}} + {{- with .Values.redis.internal.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.redis.internal.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.redis.internal.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.redis.internal.priorityClassName }} + priorityClassName: {{ .Values.redis.internal.priorityClassName }} + {{- end }} + {{- if and .Values.persistence.enabled (not $redis.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + labels: +{{ include "harbor.labels" . | indent 8 }} + annotations: + {{- range $key, $value := $redis.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + accessModes: [{{ $redis.accessMode | quote }}] + {{- if $redis.storageClass }} + {{- if (eq "-" $redis.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ $redis.storageClass }}" + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $redis.size | quote }} + {{- end -}} + {{- end -}} diff --git a/charts/harbor-helm-main/templates/registry/registry-cm.yaml b/charts/harbor-helm-main/templates/registry/registry-cm.yaml new file mode 100644 index 0000000..4f7056c --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registry-cm.yaml @@ -0,0 +1,246 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + config.yml: |+ + version: 0.1 + log: + {{- if eq .Values.logLevel "warning" }} + level: warn + {{- else if eq .Values.logLevel "fatal" }} + level: error + {{- else }} + level: {{ .Values.logLevel }} + {{- end }} + fields: + service: registry + storage: + {{- $storage := .Values.persistence.imageChartStorage }} + {{- $type := $storage.type }} + {{- if eq $type "filesystem" }} + filesystem: + rootdirectory: {{ $storage.filesystem.rootdirectory }} + {{- if $storage.filesystem.maxthreads }} + maxthreads: {{ $storage.filesystem.maxthreads }} + {{- end }} + {{- else if eq $type "azure" }} + azure: + accountname: {{ $storage.azure.accountname }} + container: {{ $storage.azure.container }} + {{- if $storage.azure.realm }} + realm: {{ $storage.azure.realm }} + {{- end }} + {{- else if eq $type "gcs" }} + gcs: + bucket: {{ $storage.gcs.bucket }} + {{- if not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity }} + keyfile: /etc/registry/gcs-key.json + {{- end }} + {{- if $storage.gcs.rootdirectory }} + rootdirectory: {{ $storage.gcs.rootdirectory }} + {{- end }} + {{- if $storage.gcs.chunksize }} + chunksize: {{ $storage.gcs.chunksize }} + {{- end }} + {{- else if eq $type "s3" }} + s3: + region: {{ $storage.s3.region }} + bucket: {{ $storage.s3.bucket }} + {{- if $storage.s3.regionendpoint }} + regionendpoint: {{ $storage.s3.regionendpoint }} + {{- end }} + {{- if $storage.s3.encrypt }} + encrypt: {{ $storage.s3.encrypt }} + {{- end }} + {{- if $storage.s3.keyid }} + keyid: {{ $storage.s3.keyid }} + {{- end }} + {{- if $storage.s3.secure }} + secure: {{ $storage.s3.secure }} + {{- end }} + {{- if and $storage.s3.secure $storage.s3.skipverify }} + skipverify: {{ $storage.s3.skipverify }} + {{- end }} + {{- if $storage.s3.v4auth }} + v4auth: {{ $storage.s3.v4auth }} + {{- end }} + {{- if $storage.s3.chunksize }} + chunksize: {{ $storage.s3.chunksize }} + {{- end }} + {{- if $storage.s3.rootdirectory }} + rootdirectory: {{ $storage.s3.rootdirectory }} + {{- end }} + {{- if $storage.s3.storageclass }} + storageclass: {{ $storage.s3.storageclass }} + {{- end }} + {{- if $storage.s3.multipartcopychunksize }} + multipartcopychunksize: {{ $storage.s3.multipartcopychunksize }} + {{- end }} + {{- if $storage.s3.multipartcopymaxconcurrency }} + multipartcopymaxconcurrency: {{ $storage.s3.multipartcopymaxconcurrency }} + {{- end }} + {{- if $storage.s3.multipartcopythresholdsize }} + multipartcopythresholdsize: {{ $storage.s3.multipartcopythresholdsize }} + {{- end }} + {{- else if eq $type "swift" }} + swift: + authurl: {{ $storage.swift.authurl }} + username: {{ $storage.swift.username }} + container: {{ $storage.swift.container }} + {{- if $storage.swift.region }} + region: {{ $storage.swift.region }} + {{- end }} + {{- if $storage.swift.tenant }} + tenant: {{ $storage.swift.tenant }} + {{- end }} + {{- if $storage.swift.tenantid }} + tenantid: {{ $storage.swift.tenantid }} + {{- end }} + {{- if $storage.swift.domain }} + domain: {{ $storage.swift.domain }} + {{- end }} + {{- if $storage.swift.domainid }} + domainid: {{ $storage.swift.domainid }} + {{- end }} + {{- if $storage.swift.trustid }} + trustid: {{ $storage.swift.trustid }} + {{- end }} + {{- if $storage.swift.insecureskipverify }} + insecureskipverify: {{ $storage.swift.insecureskipverify }} + {{- end }} + {{- if $storage.swift.chunksize }} + chunksize: {{ $storage.swift.chunksize }} + {{- end }} + {{- if $storage.swift.prefix }} + prefix: {{ $storage.swift.prefix }} + {{- end }} + {{- if $storage.swift.authversion }} + authversion: {{ $storage.swift.authversion }} + {{- end }} + {{- if $storage.swift.endpointtype }} + endpointtype: {{ $storage.swift.endpointtype }} + {{- end }} + {{- if $storage.swift.tempurlcontainerkey }} + tempurlcontainerkey: {{ $storage.swift.tempurlcontainerkey }} + {{- end }} + {{- if $storage.swift.tempurlmethods }} + tempurlmethods: {{ $storage.swift.tempurlmethods }} + {{- end }} + {{- else if eq $type "oss" }} + oss: + accesskeyid: {{ $storage.oss.accesskeyid }} + region: {{ $storage.oss.region }} + bucket: {{ $storage.oss.bucket }} + {{- if $storage.oss.endpoint }} + endpoint: {{ $storage.oss.bucket }}.{{ $storage.oss.endpoint }} + {{- end }} + {{- if $storage.oss.internal }} + internal: {{ $storage.oss.internal }} + {{- end }} + {{- if $storage.oss.encrypt }} + encrypt: {{ $storage.oss.encrypt }} + {{- end }} + {{- if $storage.oss.secure }} + secure: {{ $storage.oss.secure }} + {{- end }} + {{- if $storage.oss.chunksize }} + chunksize: {{ $storage.oss.chunksize }} + {{- end }} + {{- if $storage.oss.rootdirectory }} + rootdirectory: {{ $storage.oss.rootdirectory }} + {{- end }} + {{- end }} + cache: + layerinfo: redis + maintenance: + uploadpurging: + {{- if .Values.registry.upload_purging.enabled }} + enabled: true + age: {{ .Values.registry.upload_purging.age }} + interval: {{ .Values.registry.upload_purging.interval }} + dryrun: {{ .Values.registry.upload_purging.dryrun }} + {{- else }} + enabled: false + {{- end }} + delete: + enabled: true + redirect: + disable: {{ $storage.disableredirect }} + redis: + addr: {{ template "harbor.redis.addr" . }} + {{- if eq "redis+sentinel" (include "harbor.redis.scheme" .) }} + sentinelMasterSet: {{ template "harbor.redis.masterSet" . }} + {{- end }} + db: {{ template "harbor.redis.dbForRegistry" . }} + {{- if not (eq (include "harbor.redis.password" .) "") }} + password: {{ template "harbor.redis.password" . }} + {{- end }} + readtimeout: 10s + writetimeout: 10s + dialtimeout: 10s + pool: + maxidle: 100 + maxactive: 500 + idletimeout: 60s + http: + addr: :{{ template "harbor.registry.containerPort" . }} + relativeurls: {{ .Values.registry.relativeurls }} + {{- if .Values.internalTLS.enabled }} + tls: + certificate: /etc/harbor/ssl/registry/tls.crt + key: /etc/harbor/ssl/registry/tls.key + minimumtls: tls1.2 + {{- end }} + # set via environment variable + # secret: placeholder + debug: + {{- if .Values.metrics.enabled}} + addr: :{{ .Values.metrics.registry.port }} + prometheus: + enabled: true + path: {{ .Values.metrics.registry.path }} + {{- else }} + addr: localhost:5001 + {{- end }} + auth: + htpasswd: + realm: harbor-registry-basic-realm + path: /etc/registry/passwd + validation: + disabled: true + compatibility: + schema1: + enabled: true + + {{- if .Values.registry.middleware.enabled }} + {{- $middleware := .Values.registry.middleware }} + {{- $middlewareType := $middleware.type }} + {{- if eq $middlewareType "cloudFront" }} + middleware: + storage: + - name: cloudfront + options: + baseurl: {{ $middleware.cloudFront.baseurl }} + privatekey: /etc/registry/pk.pem + keypairid: {{ $middleware.cloudFront.keypairid }} + duration: {{ $middleware.cloudFront.duration }} + ipfilteredby: {{ $middleware.cloudFront.ipfilteredby }} + {{- end }} + {{- end }} + ctl-config.yml: |+ + --- + {{- if .Values.internalTLS.enabled }} + protocol: "https" + port: 8443 + https_config: + cert: "/etc/harbor/ssl/registry/tls.crt" + key: "/etc/harbor/ssl/registry/tls.key" + {{- else }} + protocol: "http" + port: 8080 + {{- end }} + log_level: {{ .Values.logLevel }} + registry_config: "/etc/registry/config.yml" diff --git a/charts/harbor-helm-main/templates/registry/registry-dpl.yaml b/charts/harbor-helm-main/templates/registry/registry-dpl.yaml new file mode 100644 index 0000000..bb9cb1d --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registry-dpl.yaml @@ -0,0 +1,427 @@ +{{- $storage := .Values.persistence.imageChartStorage }} +{{- $type := $storage.type }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: registry + app.kubernetes.io/component: registry +spec: + replicas: {{ .Values.registry.replicas }} + revisionHistoryLimit: {{ .Values.registry.revisionHistoryLimit }} + strategy: + type: {{ .Values.updateStrategy.type }} + {{- if eq .Values.updateStrategy.type "Recreate" }} + rollingUpdate: null + {{- end }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: registry + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: registry + app.kubernetes.io/component: registry +{{- if .Values.registry.podLabels }} +{{ toYaml .Values.registry.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/registry/registry-cm.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/registry/registry-secret.yaml") . | sha256sum }} + checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} + checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/registry/registry-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.registry.podAnnotations }} +{{ toYaml .Values.registry.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 + fsGroupChangePolicy: OnRootMismatch +{{- if .Values.registry.serviceAccountName }} + serviceAccountName: {{ .Values.registry.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.registry.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 +{{- with .Values.registry.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: registry +{{- end }} +{{- end }} + containers: + - name: registry + image: {{ .Values.registry.registry.image.repository }}:{{ .Values.registry.registry.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registry.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registry.containerPort" . }} + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.registry.registry.resources }} + resources: +{{ toYaml .Values.registry.registry.resources | indent 10 }} +{{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + args: ["serve", "/etc/registry/config.yml"] + envFrom: + - secretRef: + name: "{{ template "harbor.registry" . }}" + {{- if .Values.persistence.imageChartStorage.s3.existingSecret }} + - secretRef: + name: {{ .Values.persistence.imageChartStorage.s3.existingSecret }} + {{- end }} + env: + {{- if .Values.registry.existingSecret }} + - name: REGISTRY_HTTP_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.registry.existingSecret }} + key: {{ .Values.registry.existingSecretKey }} + {{- end }} + {{- if has "registry" .Values.proxy.components }} + - name: HTTP_PROXY + value: "{{ .Values.proxy.httpProxy }}" + - name: HTTPS_PROXY + value: "{{ .Values.proxy.httpsProxy }}" + - name: NO_PROXY + value: "{{ template "harbor.noProxy" . }}" + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/registry/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/registry/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/registry/ca.crt + {{- end }} + {{- if .Values.redis.external.existingSecret }} + - name: REGISTRY_REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.redis.external.existingSecret }} + key: REDIS_PASSWORD + {{- end }} + {{- if .Values.persistence.imageChartStorage.azure.existingSecret }} + - name: REGISTRY_STORAGE_AZURE_ACCOUNTKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.azure.existingSecret }} + key: AZURE_STORAGE_ACCESS_KEY + {{- end }} + {{- if .Values.persistence.imageChartStorage.swift.existingSecret }} + - name: REGISTRY_STORAGE_SWIFT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.swift.existingSecret }} + key: REGISTRY_STORAGE_SWIFT_PASSWORD + - name: REGISTRY_STORAGE_SWIFT_SECRETKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.swift.existingSecret }} + key: REGISTRY_STORAGE_SWIFT_SECRETKEY + optional: true + - name: REGISTRY_STORAGE_SWIFT_ACCESSKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.swift.existingSecret }} + key: REGISTRY_STORAGE_SWIFT_ACCESSKEY + optional: true + {{- end }} + {{- if .Values.persistence.imageChartStorage.oss.existingSecret }} + - name: REGISTRY_STORAGE_OSS_ACCESSKEYSECRET + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.oss.existingSecret }} + key: REGISTRY_STORAGE_OSS_ACCESSKEYSECRET + optional: true + {{- end}} +{{- with .Values.registry.registry.extraEnvVars }} +{{- toYaml . | nindent 8 }} +{{- end }} + ports: + - containerPort: {{ template "harbor.registry.containerPort" . }} + - containerPort: {{ ternary .Values.metrics.registry.port 5001 .Values.metrics.enabled }} + volumeMounts: + - name: registry-data + mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }} + subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }} + - name: registry-htpasswd + mountPath: /etc/registry/passwd + subPath: passwd + - name: registry-config + mountPath: /etc/registry/config.yml + subPath: config.yml + {{- if .Values.internalTLS.enabled }} + - name: registry-internal-certs + mountPath: /etc/harbor/ssl/registry + {{- end }} + {{- if and (and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs")) (not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity) }} + - name: gcs-key + mountPath: /etc/registry/gcs-key.json + subPath: gcs-key.json + {{- end }} + {{- if .Values.persistence.imageChartStorage.caBundleSecretName }} + - name: storage-service-ca + mountPath: /harbor_cust_cert/custom-ca-bundle.crt + subPath: ca.crt + {{- end }} + {{- if .Values.registry.middleware.enabled }} + {{- if eq .Values.registry.middleware.type "cloudFront" }} + - name: cloudfront-key + mountPath: /etc/registry/pk.pem + subPath: pk.pem + {{- end }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + - name: registryctl + image: {{ .Values.registry.controller.image.repository }}:{{ .Values.registry.controller.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: /api/health + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registryctl.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/health + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registryctl.containerPort" . }} + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.registry.controller.resources }} + resources: +{{ toYaml .Values.registry.controller.resources | indent 10 }} +{{- end }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 10 }} + {{- end }} + envFrom: + - configMapRef: + name: "{{ template "harbor.registryCtl" . }}" + - secretRef: + name: "{{ template "harbor.registry" . }}" + - secretRef: + name: "{{ template "harbor.registryCtl" . }}" + {{- if .Values.persistence.imageChartStorage.s3.existingSecret }} + - secretRef: + name: {{ .Values.persistence.imageChartStorage.s3.existingSecret }} + {{- end }} + env: + {{- if .Values.registry.existingSecret }} + - name: REGISTRY_HTTP_SECRET + valueFrom: + secretKeyRef: + name: {{ .Values.registry.existingSecret }} + key: {{ .Values.registry.existingSecretKey }} + {{- end }} + - name: CORE_SECRET + valueFrom: + secretKeyRef: + name: {{ default (include "harbor.core" .) .Values.core.existingSecret }} + key: secret + - name: JOBSERVICE_SECRET + valueFrom: + secretKeyRef: + name: {{ default (include "harbor.jobservice" .) .Values.jobservice.existingSecret }} + {{- if .Values.jobservice.existingSecret }} + key: {{ .Values.jobservice.existingSecretKey }} + {{- else }} + key: JOBSERVICE_SECRET + {{- end }} + {{- if has "registry" .Values.proxy.components }} + - name: HTTP_PROXY + value: "{{ .Values.proxy.httpProxy }}" + - name: HTTPS_PROXY + value: "{{ .Values.proxy.httpsProxy }}" + - name: NO_PROXY + value: "{{ template "harbor.noProxy" . }}" + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/registry/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/registry/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/registry/ca.crt + {{- end }} + {{- if .Values.redis.external.existingSecret }} + - name: REGISTRY_REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.redis.external.existingSecret }} + key: REDIS_PASSWORD + {{- end }} + {{- if .Values.persistence.imageChartStorage.azure.existingSecret }} + - name: REGISTRY_STORAGE_AZURE_ACCOUNTKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.azure.existingSecret }} + key: AZURE_STORAGE_ACCESS_KEY + {{- end }} + {{- if .Values.persistence.imageChartStorage.swift.existingSecret }} + - name: REGISTRY_STORAGE_SWIFT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.swift.existingSecret }} + key: REGISTRY_STORAGE_SWIFT_PASSWORD + - name: REGISTRY_STORAGE_SWIFT_SECRETKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.swift.existingSecret }} + key: REGISTRY_STORAGE_SWIFT_SECRETKEY + optional: true + - name: REGISTRY_STORAGE_SWIFT_ACCESSKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.swift.existingSecret }} + key: REGISTRY_STORAGE_SWIFT_ACCESSKEY + optional: true + {{- end }} + {{- if .Values.persistence.imageChartStorage.oss.existingSecret }} + - name: REGISTRY_STORAGE_OSS_ACCESSKEYSECRET + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.oss.existingSecret }} + key: REGISTRY_STORAGE_OSS_ACCESSKEYSECRET + optional: true + {{- end}} +{{- with .Values.registry.controller.extraEnvVars }} +{{- toYaml . | nindent 8 }} +{{- end }} + ports: + - containerPort: {{ template "harbor.registryctl.containerPort" . }} + volumeMounts: + - name: registry-data + mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }} + subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }} + - name: registry-config + mountPath: /etc/registry/config.yml + subPath: config.yml + - name: registry-config + mountPath: /etc/registryctl/config.yml + subPath: ctl-config.yml + {{- if .Values.internalTLS.enabled }} + - name: registry-internal-certs + mountPath: /etc/harbor/ssl/registry + {{- end }} + {{- if .Values.persistence.imageChartStorage.caBundleSecretName }} + - name: storage-service-ca + mountPath: /harbor_cust_cert/custom-ca-bundle.crt + subPath: ca.crt + {{- end }} + {{- if and (and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs")) (not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity ) }} + - name: gcs-key + mountPath: /etc/registry/gcs-key.json + subPath: gcs-key.json + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + volumes: + - name: registry-htpasswd + secret: + {{- if not .Values.registry.credentials.existingSecret }} + secretName: {{ template "harbor.registry" . }}-htpasswd + {{ else }} + secretName: {{ .Values.registry.credentials.existingSecret }} + {{- end }} + items: + - key: REGISTRY_HTPASSWD + path: passwd + - name: registry-config + configMap: + name: "{{ template "harbor.registry" . }}" + - name: registry-data + {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "filesystem") }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.persistentVolumeClaim.registry.existingClaim | default (include "harbor.registry" .) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: registry-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.registry.secretName" . }} + {{- end }} + {{- if and (and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs")) (not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity ) }} + - name: gcs-key + secret: + {{- if and (eq $type "gcs") $storage.gcs.existingSecret }} + secretName: {{ $storage.gcs.existingSecret }} + {{- else }} + secretName: {{ template "harbor.registry" . }} + {{- end }} + items: + - key: GCS_KEY_DATA + path: gcs-key.json + {{- end }} + {{- if .Values.persistence.imageChartStorage.caBundleSecretName }} + - name: storage-service-ca + secret: + secretName: {{ .Values.persistence.imageChartStorage.caBundleSecretName }} + {{- end }} + {{- if .Values.registry.middleware.enabled }} + {{- if eq .Values.registry.middleware.type "cloudFront" }} + - name: cloudfront-key + secret: + secretName: {{ .Values.registry.middleware.cloudFront.privateKeySecret }} + items: + - key: CLOUDFRONT_KEY_DATA + path: pk.pem + {{- end }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.registry.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.registry.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.registry.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.registry.priorityClassName }} + priorityClassName: {{ .Values.registry.priorityClassName }} + {{- end }} diff --git a/charts/harbor-helm-main/templates/registry/registry-pvc.yaml b/charts/harbor-helm-main/templates/registry/registry-pvc.yaml new file mode 100644 index 0000000..5d6d4d3 --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registry-pvc.yaml @@ -0,0 +1,33 @@ +{{- if .Values.persistence.enabled }} +{{- $registry := .Values.persistence.persistentVolumeClaim.registry -}} +{{- if and (not $registry.existingClaim) (eq .Values.persistence.imageChartStorage.type "filesystem") }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "harbor.registry" . }} + annotations: + {{- range $key, $value := $registry.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if eq .Values.persistence.resourcePolicy "keep" }} + helm.sh/resource-policy: keep + {{- end }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: registry + app.kubernetes.io/component: registry +spec: + accessModes: + - {{ $registry.accessMode }} + resources: + requests: + storage: {{ $registry.size }} + {{- if $registry.storageClass }} + {{- if eq "-" $registry.storageClass }} + storageClassName: "" + {{- else }} + storageClassName: {{ $registry.storageClass }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/registry/registry-secret.yaml b/charts/harbor-helm-main/templates/registry/registry-secret.yaml new file mode 100644 index 0000000..e853a9c --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registry-secret.yaml @@ -0,0 +1,55 @@ +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace (include "harbor.registry" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if not .Values.registry.existingSecret }} + REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (include "harbor.secretKeyHelper" (dict "key" "REGISTRY_HTTP_SECRET" "data" $existingSecret.data)) | default (randAlphaNum 16) | b64enc | quote }} + {{- end }} + {{- if not .Values.redis.external.existingSecret }} + REGISTRY_REDIS_PASSWORD: {{ include "harbor.redis.password" . | b64enc | quote }} + {{- end }} + {{- $storage := .Values.persistence.imageChartStorage }} + {{- $type := $storage.type }} + {{- if and (eq $type "azure") (not $storage.azure.existingSecret) }} + REGISTRY_STORAGE_AZURE_ACCOUNTKEY: {{ $storage.azure.accountkey | b64enc | quote }} + {{- else if and (and (eq $type "gcs") (not $storage.gcs.existingSecret)) (not $storage.gcs.useWorkloadIdentity) }} + GCS_KEY_DATA: {{ $storage.gcs.encodedkey | quote }} + {{- else if eq $type "s3" }} + {{- if and (not $storage.s3.existingSecret) ($storage.s3.accesskey) }} + REGISTRY_STORAGE_S3_ACCESSKEY: {{ $storage.s3.accesskey | b64enc | quote }} + {{- end }} + {{- if and (not $storage.s3.existingSecret) ($storage.s3.secretkey) }} + REGISTRY_STORAGE_S3_SECRETKEY: {{ $storage.s3.secretkey | b64enc | quote }} + {{- end }} + {{- else if and (eq $type "swift") (not ($storage.swift.existingSecret)) }} + REGISTRY_STORAGE_SWIFT_PASSWORD: {{ $storage.swift.password | b64enc | quote }} + {{- if $storage.swift.secretkey }} + REGISTRY_STORAGE_SWIFT_SECRETKEY: {{ $storage.swift.secretkey | b64enc | quote }} + {{- end }} + {{- if $storage.swift.accesskey }} + REGISTRY_STORAGE_SWIFT_ACCESSKEY: {{ $storage.swift.accesskey | b64enc | quote }} + {{- end }} + {{- else if and (eq $type "oss") ((not ($storage.oss.existingSecret))) }} + REGISTRY_STORAGE_OSS_ACCESSKEYSECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }} + {{- end }} +{{- if not .Values.registry.credentials.existingSecret }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.registry" . }}-htpasswd" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if .Values.registry.credentials.htpasswdString }} + REGISTRY_HTPASSWD: {{ .Values.registry.credentials.htpasswdString | b64enc | quote }} + {{- else }} + REGISTRY_HTPASSWD: {{ htpasswd .Values.registry.credentials.username .Values.registry.credentials.password | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/registry/registry-svc.yaml b/charts/harbor-helm-main/templates/registry/registry-svc.yaml new file mode 100644 index 0000000..749690e --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registry-svc.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ ternary "https-registry" "http-registry" .Values.internalTLS.enabled }} + port: {{ template "harbor.registry.servicePort" . }} + + - name: {{ ternary "https-controller" "http-controller" .Values.internalTLS.enabled }} + port: {{ template "harbor.registryctl.servicePort" . }} +{{- if .Values.metrics.enabled}} + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.registry.port }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: registry \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/registry/registry-tls.yaml b/charts/harbor-helm-main/templates/registry/registry-tls.yaml new file mode 100644 index 0000000..9d1862c --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registry-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.registry.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + 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.key: {{ (required "The \"internalTLS.registry.key\" is required!" .Values.internalTLS.registry.key) | b64enc | quote }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/registry/registryctl-cm.yaml b/charts/harbor-helm-main/templates/registry/registryctl-cm.yaml new file mode 100644 index 0000000..87aa5ff --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registryctl-cm.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.registryCtl" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + {{- template "harbor.traceEnvsForRegistryCtl" . }} diff --git a/charts/harbor-helm-main/templates/registry/registryctl-secret.yaml b/charts/harbor-helm-main/templates/registry/registryctl-secret.yaml new file mode 100644 index 0000000..7009770 --- /dev/null +++ b/charts/harbor-helm-main/templates/registry/registryctl-secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.registryCtl" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- template "harbor.traceJaegerPassword" . }} \ No newline at end of file diff --git a/charts/harbor-helm-main/templates/trivy/trivy-secret.yaml b/charts/harbor-helm-main/templates/trivy/trivy-secret.yaml new file mode 100644 index 0000000..84652c7 --- /dev/null +++ b/charts/harbor-helm-main/templates/trivy/trivy-secret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.trivy.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.trivy" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + redisURL: {{ include "harbor.redis.urlForTrivy" . | b64enc }} + gitHubToken: {{ .Values.trivy.gitHubToken | default "" | b64enc | quote }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/trivy/trivy-sts.yaml b/charts/harbor-helm-main/templates/trivy/trivy-sts.yaml new file mode 100644 index 0000000..ddaa4c9 --- /dev/null +++ b/charts/harbor-helm-main/templates/trivy/trivy-sts.yaml @@ -0,0 +1,226 @@ +{{- if .Values.trivy.enabled }} +{{- $trivy := .Values.persistence.persistentVolumeClaim.trivy }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "harbor.trivy" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: trivy + app.kubernetes.io/component: trivy +spec: + replicas: {{ .Values.trivy.replicas }} + serviceName: {{ template "harbor.trivy" . }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: trivy + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: trivy + app.kubernetes.io/component: trivy +{{- if .Values.trivy.podLabels }} +{{ toYaml .Values.trivy.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/trivy/trivy-secret.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/trivy/trivy-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.trivy.podAnnotations }} +{{ toYaml .Values.trivy.podAnnotations | indent 8 }} +{{- end }} + spec: +{{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} +{{- end }} +{{- if .Values.trivy.serviceAccountName }} + serviceAccountName: {{ .Values.trivy.serviceAccountName }} +{{- end }} + securityContext: + runAsUser: 10000 + fsGroup: 10000 + automountServiceAccountToken: {{ .Values.trivy.automountServiceAccountToken | default false }} +{{- with .Values.trivy.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: trivy +{{- end }} +{{- end }} + containers: + - name: trivy + image: {{ .Values.trivy.image.repository }}:{{ .Values.trivy.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if not (empty .Values.containerSecurityContext) }} + securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 12 }} + {{- end }} + env: + {{- if has "trivy" .Values.proxy.components }} + - name: HTTP_PROXY + value: "{{ .Values.proxy.httpProxy }}" + - name: HTTPS_PROXY + value: "{{ .Values.proxy.httpsProxy }}" + - name: NO_PROXY + value: "{{ template "harbor.noProxy" . }}" + {{- end }} + - name: "SCANNER_LOG_LEVEL" + value: {{ .Values.logLevel | quote }} + - name: "SCANNER_TRIVY_CACHE_DIR" + value: "/home/scanner/.cache/trivy" + - name: "SCANNER_TRIVY_REPORTS_DIR" + value: "/home/scanner/.cache/reports" + - name: "SCANNER_TRIVY_DEBUG_MODE" + value: {{ .Values.trivy.debugMode | quote }} + - name: "SCANNER_TRIVY_VULN_TYPE" + value: {{ .Values.trivy.vulnType | quote }} + - name: "SCANNER_TRIVY_TIMEOUT" + value: {{ .Values.trivy.timeout | quote }} + - name: "SCANNER_TRIVY_GITHUB_TOKEN" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: gitHubToken + - name: "SCANNER_TRIVY_SEVERITY" + value: {{ .Values.trivy.severity | quote }} + - name: "SCANNER_TRIVY_IGNORE_UNFIXED" + value: {{ .Values.trivy.ignoreUnfixed | default false | quote }} + - name: "SCANNER_TRIVY_SKIP_UPDATE" + value: {{ .Values.trivy.skipUpdate | default false | quote }} + - name: "SCANNER_TRIVY_SKIP_JAVA_DB_UPDATE" + value: {{ .Values.trivy.skipJavaDBUpdate | default false | quote }} + - name: "SCANNER_TRIVY_OFFLINE_SCAN" + value: {{ .Values.trivy.offlineScan | default false | quote }} + - name: "SCANNER_TRIVY_SECURITY_CHECKS" + value: {{ .Values.trivy.securityCheck | quote }} + - name: "SCANNER_TRIVY_INSECURE" + value: {{ .Values.trivy.insecure | default false | quote }} + - name: SCANNER_API_SERVER_ADDR + value: ":{{ template "harbor.trivy.containerPort" . }}" + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: SCANNER_API_SERVER_TLS_KEY + value: /etc/harbor/ssl/trivy/tls.key + - name: SCANNER_API_SERVER_TLS_CERTIFICATE + value: /etc/harbor/ssl/trivy/tls.crt + {{- end }} + - name: "SCANNER_REDIS_URL" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: redisURL + - name: "SCANNER_STORE_REDIS_URL" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: redisURL + - name: "SCANNER_JOB_QUEUE_REDIS_URL" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: redisURL +{{- with .Values.trivy.extraEnvVars }} +{{- toYaml . | nindent 12 }} +{{- end }} + ports: + - name: api-server + containerPort: {{ template "harbor.trivy.containerPort" . }} + volumeMounts: + - name: data + mountPath: /home/scanner/.cache + subPath: {{ .Values.persistence.persistentVolumeClaim.trivy.subPath }} + readOnly: false + {{- if .Values.internalTLS.enabled }} + - name: trivy-internal-certs + mountPath: /etc/harbor/ssl/trivy + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 10 }} + {{- end }} + livenessProbe: + httpGet: + scheme: {{ include "harbor.component.scheme" . | upper }} + path: /probe/healthy + port: api-server + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 10 + readinessProbe: + httpGet: + scheme: {{ include "harbor.component.scheme" . | upper }} + path: /probe/ready + port: api-server + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + resources: +{{ toYaml .Values.trivy.resources | indent 12 }} + {{- if or (or .Values.internalTLS.enabled .Values.caBundleSecretName) (or (not .Values.persistence.enabled) $trivy.existingClaim) }} + volumes: + {{- if .Values.internalTLS.enabled }} + - name: trivy-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.trivy.secretName" . }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- if not .Values.persistence.enabled }} + - name: "data" + emptyDir: {} + {{- else if $trivy.existingClaim }} + - name: "data" + persistentVolumeClaim: + claimName: {{ $trivy.existingClaim }} + {{- end }} + {{- end }} + {{- with .Values.trivy.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.trivy.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.trivy.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.trivy.priorityClassName }} + priorityClassName: {{ .Values.trivy.priorityClassName }} + {{- end }} +{{- if and .Values.persistence.enabled (not $trivy.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + labels: +{{ include "harbor.labels" . | indent 8 }} + annotations: + {{- range $key, $value := $trivy.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + accessModes: [{{ $trivy.accessMode | quote }}] + {{- if $trivy.storageClass }} + {{- if (eq "-" $trivy.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ $trivy.storageClass }}" + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $trivy.size | quote }} +{{- end }} +{{- end }} diff --git a/charts/harbor-helm-main/templates/trivy/trivy-svc.yaml b/charts/harbor-helm-main/templates/trivy/trivy-svc.yaml new file mode 100644 index 0000000..24daf09 --- /dev/null +++ b/charts/harbor-helm-main/templates/trivy/trivy-svc.yaml @@ -0,0 +1,16 @@ +{{ if .Values.trivy.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.trivy" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ ternary "https-trivy" "http-trivy" .Values.internalTLS.enabled }} + protocol: TCP + port: {{ template "harbor.trivy.servicePort" . }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: trivy +{{ end }} diff --git a/charts/harbor-helm-main/templates/trivy/trivy-tls.yaml b/charts/harbor-helm-main/templates/trivy/trivy-tls.yaml new file mode 100644 index 0000000..a9c8330 --- /dev/null +++ b/charts/harbor-helm-main/templates/trivy/trivy-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.trivy.enabled .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.trivy.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + 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.key: {{ (required "The \"internalTLS.trivy.key\" is required!" .Values.internalTLS.trivy.key) | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/harbor-helm-main/test/e2e/Dockerfile b/charts/harbor-helm-main/test/e2e/Dockerfile new file mode 100644 index 0000000..6801396 --- /dev/null +++ b/charts/harbor-helm-main/test/e2e/Dockerfile @@ -0,0 +1,7 @@ +FROM alpine:3 + +ARG KUBECTL_VERSION="v1.27.1" +ARG HELM_VERSION="v3.13.3" +RUN apk add bash bind-tools \ + && wget https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl -P /usr/local/bin/ && chmod +x /usr/local/bin/kubectl \ + && wget -O - https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz | tar -xzO linux-amd64/helm > /usr/local/bin/helm && chmod +x /usr/local/bin/helm diff --git a/charts/harbor-helm-main/test/e2e/Jenkinsfile b/charts/harbor-helm-main/test/e2e/Jenkinsfile new file mode 100644 index 0000000..2b34f93 --- /dev/null +++ b/charts/harbor-helm-main/test/e2e/Jenkinsfile @@ -0,0 +1,128 @@ +@Library('harbor@main') _ +import io.goharbor.* + +class HarborChartFreshInstallPipelineExecutor extends FreshInstallPipelineExecutor implements Serializable { + Script script + String context + String namespace + String coreHostname + String ingressControllerServiceType + String ingressControllerIP + + HarborChartFreshInstallPipelineExecutor(Script script) { + this.script = script + this.context = script.params.cluster + this.namespace = "harbor-chart" + this.coreHostname = "harbor.chart.local" + } + + // clean up the previously installed harbor chart + void preInstall(){ + script.withCredentials([ + script.file(credentialsId: "kubeconfig", variable: "KUBE_CONFIG_FILE_PATH"), + script.usernamePassword(credentialsId: "79e9fd98-cdf5-4f55-81fa-ecba01365534", usernameVariable: "DOCKER_HUB_USERNAME", passwordVariable: "DOCKER_HUB_PASSWORD")]) { + script.sh """ + # login Docker Hub to avoid the pull limit + docker login -u \${DOCKER_HUB_USERNAME} -p \${DOCKER_HUB_PASSWORD} + # build the image + docker build -t deployer:dev -f test/e2e/Dockerfile test/e2e + # clean up the namespace + docker run -i --rm -v \${KUBE_CONFIG_FILE_PATH}:/root/.kube/config deployer:dev \ + kubectl delete namespace ${namespace} --ignore-not-found --context ${context} + docker logout + """ + } + } + + HarborInstance install(){ + // the scope of the credential is just inside the "withCredentials" block, so we need to call "withCredentials" again + script.withCredentials([script.file(credentialsId: "kubeconfig", variable: "KUBE_CONFIG_FILE_PATH")]) { + // get the service type of the ingress controller + ingressControllerServiceType = script.sh( + returnStdout: true, + script: """ + docker run -i --rm -v \${KUBE_CONFIG_FILE_PATH}:/root/.kube/config deployer:dev \ + sh -c 'kubectl get svc ingress-nginx-controller --context ${context} -n ingress-nginx -o jsonpath="{.spec.type}"' + """).trim() + // get the IP address of the ingress controller + if (ingressControllerServiceType == 'LoadBalancer') { + ingressControllerIP = script.sh( + returnStdout: true, + script: """ + docker run -i --rm -v \${KUBE_CONFIG_FILE_PATH}:/root/.kube/config deployer:dev \ + sh -c 'host \$(kubectl get svc ingress-nginx-controller --context ${context} -n ingress-nginx -o jsonpath="{.status.loadBalancer.ingress[0].hostname}") | awk "/has address/ { print \\\$4; exit }"' + """).trim() + } else if (ingressControllerServiceType == 'NodePort') { + ingressControllerIP = script.sh( + returnStdout: true, + script: """ + docker run -i --rm -v \${KUBE_CONFIG_FILE_PATH}:/root/.kube/config deployer:dev \ + sh -c 'kubectl get svc ingress-nginx-controller --context ${context} -n ingress-nginx -o jsonpath="{.spec.externalIPs[0]}"' + """).trim() + } + // install harbor chart + script.sh """ + # insert the hostAliases to run the replication test + sed -i -r "s| spec:| spec:\\n hostAliases:\\n - ip: ${ingressControllerIP}\\n hostnames:\\n - ${coreHostname}|g" ./templates/core/core-dpl.yaml + # install harbor chart + docker run -i --rm -w /workspace -v \${KUBE_CONFIG_FILE_PATH}:/root/.kube/config -v \$(pwd):/workspace deployer:dev \ + helm install harbor --kube-context ${context} -n ${namespace} --create-namespace \ + --set "expose.ingress.hosts.core=${coreHostname},externalURL=https://${coreHostname},internalTLS.enabled=true,imagePullPolicy=Always,trivy.skipUpdate=true,core.gcTimeWindowHours=0" . + """ + } + + HarborInstance instance = new HarborInstance() + instance.coreServiceURL = "https://" + coreHostname + instance.adminPassword = "Harbor12345" + instance.authMode = "database" + instance.components = "trivy" + instance.hostIPMappings = "${coreHostname}:${ingressControllerIP}" + + script.currentBuild.description = """ + Kubernetes: ${context} + Namespace: ${namespace} + Core Service: $instance.coreServiceURL + Ingress Controller IP: ${ingressControllerIP} + """ + + return instance + } + + void preTest(){ + script.withCredentials([script.file(credentialsId: "kubeconfig", variable: "KUBE_CONFIG_FILE_PATH")]) { + script.import_trivy_db(script.env.KUBE_CONFIG_FILE_PATH, context, namespace, "") + } + } +} + +def properties = { + // read context names from the kube config file + def names = [] + withCredentials([file(credentialsId: "kubeconfig", variable: "KUBE_CONFIG_FILE_PATH")]) { + def kubeConfig = readYaml file: env.KUBE_CONFIG_FILE_PATH + kubeConfig.contexts.each { + names.add(it.name) + } + } + return [ + parameters([ + string(name: 'branch', defaultValue: 'main', description: 'The branch/tag to run for'), + choice(name: "cluster", choices: names, description: 'The Kubernetes cluster that the Harbor is deployed on') + ]), + buildDiscarder(strategy: logRotator(numToKeepStr: "15")), + pipelineTriggers(triggers: [cron('TZ=Asia/Hong_Kong\n0 0 * * *')]) + ] +} + +def caseSettings = { + CaseSettings settings = new CaseSettings() + settings.cases = "gc,trivy,common,database" + return settings +} + +FreshInstallPipelineSettings settings = new FreshInstallPipelineSettings() +settings.properties = properties +settings.executor = new HarborChartFreshInstallPipelineExecutor(this) +settings.caseSettings = caseSettings + +run_fresh_install_pipeline(settings) \ No newline at end of file diff --git a/charts/harbor-helm-main/test/go.mod b/charts/harbor-helm-main/test/go.mod new file mode 100644 index 0000000..9e2bbe2 --- /dev/null +++ b/charts/harbor-helm-main/test/go.mod @@ -0,0 +1,9 @@ +module github.com/goharbor/harbor-helm + +go 1.13 + +require ( + github.com/gruntwork-io/terratest v0.38.1 + github.com/stretchr/testify v1.7.0 + k8s.io/api v0.20.6 +) diff --git a/charts/harbor-helm-main/test/go.sum b/charts/harbor-helm-main/test/go.sum new file mode 100644 index 0000000..9e495be --- /dev/null +++ b/charts/harbor-helm-main/test/go.sum @@ -0,0 +1,1282 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0 h1:bAMqZidYkmIsUqe6PtkEPT7Q+vfizScn+jfNA6jwK9c= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v50.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= +github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= +github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= +github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= +github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.40.56 h1:FM2yjR0UUYFzDTMx+mH9Vyw1k1EUUxsAFzk+BjkzANA= +github.com/aws/aws-sdk-go v1.40.56/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= +github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= +github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= +github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= +github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= +github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= +github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= +github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= +github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= +github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= +github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= +github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= +github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= +github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= +github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= +github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= +github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= +github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= +github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= +github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= +github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= +github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= +github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= +github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= +github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= +github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= +github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= +github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c h1:ZfSZ3P3BedhKGUhzj7BQlPSU4OvT6tfOKe3DVHzOA7s= +github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 h1:yY9rWGoXv1U5pl4gxqlULARMQD7x0QG85lqEXTWysik= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= +github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= +github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro= +github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= +github.com/gruntwork-io/terratest v0.38.1 h1:vymd5+mrynqre6b1GFGPMuKVE/ta38hGKssKNmVi3Kw= +github.com/gruntwork-io/terratest v0.38.1/go.mod h1:XzW8PL9pAGbLyiBdQ5OiAeWSNpZ/9ycItjYstSS2PV8= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl/v2 v2.9.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/terraform-json v0.12.0/go.mod h1:pmbq9o4EuL43db5+0ogX10Yofv1nozM+wskr/bGFJpI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 h1:ofNAzWCcyTALn2Zv40+8XitdzCgXY6e9qvXwN9W0YXg= +github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= +github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= +github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= +github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= +github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= +github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty v1.8.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= +github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.20.6 h1:bgdZrW++LqgrLikWYNruIKAtltXbSCX2l5mJu11hrVE= +k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.6 h1:R5p3SlhaABYShQSO6LpPsYHjV05Q+79eBUR0Ut/f4tk= +k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= +k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= +k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= +k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= +k8s.io/client-go v0.20.6 h1:nJZOfolnsVtDtbGJNCxzOtKUAu7zvXjB8+pMo9UNxZo= +k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= +k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= +k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= +k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3 h1:4oyYo8NREp49LBBhKxEqCulFjg26rawYKrnCmg+Sr6c= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/charts/harbor-helm-main/test/integration/base.go b/charts/harbor-helm-main/test/integration/base.go new file mode 100644 index 0000000..3f69fca --- /dev/null +++ b/charts/harbor-helm-main/test/integration/base.go @@ -0,0 +1,188 @@ +package integration + +import ( + "crypto/tls" + "encoding/json" + "fmt" + "io/ioutil" + "log" + "math/rand" + "net/http" + "os" + "os/exec" + "strings" + "sync" + "time" + + "github.com/gruntwork-io/terratest/modules/helm" + "github.com/gruntwork-io/terratest/modules/k8s" + "github.com/gruntwork-io/terratest/modules/logger" + "github.com/gruntwork-io/terratest/modules/testing" + "github.com/stretchr/testify/suite" +) + +func init() { + // override the default logger to make the log in the same style + logger.Default = logger.New(&Logger{}) +} + +var ( + client = &http.Client{ + Timeout: 30*time.Second, + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + } +) + +type Logger struct{} + +func (l *Logger) Logf(t testing.TestingT, format string, args ...interface{}) { + log.Printf(format, args...) +} + +func NewBaseTestSuite(values map[string]string) BaseTestSuite { + if values == nil { + values = map[string]string{} + } + return BaseTestSuite{ + Options: &helm.Options{ + KubectlOptions: &k8s.KubectlOptions{ + Namespace: "default", + }, + SetValues: values, + }, + ReleaseName: fmt.Sprintf("harbor-%d", rand.Int()), + URL: values["externalURL"], + } +} + +type BaseTestSuite struct { + suite.Suite + Options *helm.Options + ReleaseName string + URL string // the external URL of Harbor +} + +func (b *BaseTestSuite) SetupSuite() { + helm.Install(b.T(), b.Options, "../..", b.ReleaseName) + b.waitUntilHealthy(b.URL) +} + +type overallStatus struct { + Status string `json:"status"` + Components []*componentStatus `json:"components"` +} + +type componentStatus struct { + Name string `json:"name"` + Status string `json:"status"` + Error string `json:"error,omitempty"` +} + +func (b *BaseTestSuite) waitUntilHealthy(url string) { + var ( + timeout bool + done = make(chan struct{}) + lock = sync.RWMutex{} + ) + go func() { + log.Printf("wait until Harbor is healthy by calling the health check API ...") + stop := false + for !stop { + if err := healthy(url); err != nil { + log.Printf("the status of Harbor isn't healthy: %v, will retry 10 seconds later...", err) + time.Sleep(10 * time.Second) + lock.RLock() + stop = timeout + lock.RUnlock() + continue + } + log.Printf("the status of Harbor is healthy") + done <- struct{}{} + return + } + }() + + select { + case <-done: + return + case <-time.After(10 * time.Minute): + lock.Lock() + timeout = true + lock.Unlock() + log.Print("timeout when checking the status") + b.FailNow("timeout when checking the status") + } +} + +func healthy(url string) error { + resp, err := client.Get(fmt.Sprintf("%s/api/v2.0/health", url)) + if err != nil { + return err + } + defer resp.Body.Close() + + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("the response status code %d != 200, response body: %s", resp.StatusCode, string(data)) + } + + status := &overallStatus{} + if err = json.Unmarshal(data, status); err != nil { + return err + } + if status.Status != "healthy" { + for _, component := range status.Components { + if component.Status == "healthy" { + continue + } + return fmt.Errorf("the status of component %s isn't healthy: %s ", component.Name, component.Error) + } + return fmt.Errorf("the overall status is unhealthy, but all components are healthy") + } + return nil +} + +func (b *BaseTestSuite) TestPush() { + addr := strings.TrimPrefix(b.URL, "http://") + addr = strings.TrimPrefix(addr, "https://") + + // push image + log.Print("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", + addr, addr, addr) + cmd := exec.Command("/bin/sh", "-c", cmdStr) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + b.Require().Nil(err) + + // delete image in local + log.Print("deleting the image in local") + cmdStr = fmt.Sprintf("docker rmi %s/library/hello-world:latest", addr) + cmd = exec.Command("/bin/sh", "-c", cmdStr) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err = cmd.Run() + b.Require().Nil(err) + + // pull image + log.Print("pull the image...") + cmdStr = fmt.Sprintf("docker pull %s/library/hello-world:latest", addr) + cmd = exec.Command("/bin/sh", "-c", cmdStr) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err = cmd.Run() + b.Require().Nil(err) +} + +func (b *BaseTestSuite) TearDownSuite() { + helm.Delete(b.T(), b.Options, b.ReleaseName, true) +} diff --git a/charts/harbor-helm-main/test/integration/ingress_test.go b/charts/harbor-helm-main/test/integration/ingress_test.go new file mode 100644 index 0000000..107a4f8 --- /dev/null +++ b/charts/harbor-helm-main/test/integration/ingress_test.go @@ -0,0 +1,26 @@ +package integration + +import ( + "fmt" + "testing" + + "github.com/gruntwork-io/terratest/modules/k8s" + "github.com/stretchr/testify/suite" +) + +type IngressTestSuite struct { + BaseTestSuite +} + +func (i *IngressTestSuite) TestIngress() { + k8s.GetIngress(i.T(), i.Options.KubectlOptions, fmt.Sprintf("%s-ingress", i.ReleaseName)) +} + +func TestIngressTestSuite(t *testing.T) { + suite.Run(t, &IngressTestSuite{ + BaseTestSuite: NewBaseTestSuite(map[string]string{ + "expose.ingress.hosts.core": "harbor.local", + "externalURL": "https://harbor.local", + }), + }) +} diff --git a/charts/harbor-helm-main/test/integration/kind-cluster.yaml b/charts/harbor-helm-main/test/integration/kind-cluster.yaml new file mode 100644 index 0000000..ca9bf4a --- /dev/null +++ b/charts/harbor-helm-main/test/integration/kind-cluster.yaml @@ -0,0 +1,20 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP + - containerPort: 30003 + hostPort: 30003 + protocol: TCP diff --git a/charts/harbor-helm-main/test/integration/node_port_test.go b/charts/harbor-helm-main/test/integration/node_port_test.go new file mode 100644 index 0000000..07c2baf --- /dev/null +++ b/charts/harbor-helm-main/test/integration/node_port_test.go @@ -0,0 +1,28 @@ +package integration + +import ( + "testing" + + "github.com/gruntwork-io/terratest/modules/k8s" + "github.com/stretchr/testify/suite" +) + +type NodePortTestSuite struct { + BaseTestSuite +} + +func (n *NodePortTestSuite) TestNodePort() { + service := k8s.GetService(n.T(), n.Options.KubectlOptions, "harbor") + n.Equal("NodePort", string(service.Spec.Type)) +} + +func TestNodePortTestSuite(t *testing.T) { + suite.Run(t, &NodePortTestSuite{ + BaseTestSuite: NewBaseTestSuite(map[string]string{ + "expose.type": "nodePort", + "expose.tls.auto.commonName": "127.0.0.1", + "expose.nodePort.ports.https.nodePort": "30003", + "externalURL": "https://127.0.0.1:30003", + }), + }) +} diff --git a/charts/harbor-helm-main/test/test.go b/charts/harbor-helm-main/test/test.go new file mode 100644 index 0000000..56e5404 --- /dev/null +++ b/charts/harbor-helm-main/test/test.go @@ -0,0 +1 @@ +package test diff --git a/charts/harbor-helm-main/test/unittest/trivy_stateful_set_test.go b/charts/harbor-helm-main/test/unittest/trivy_stateful_set_test.go new file mode 100644 index 0000000..c8efa9b --- /dev/null +++ b/charts/harbor-helm-main/test/unittest/trivy_stateful_set_test.go @@ -0,0 +1,171 @@ +package unittest + +import ( + "os" + "testing" + + "github.com/gruntwork-io/terratest/modules/helm" + "github.com/gruntwork-io/terratest/modules/logger" + "github.com/stretchr/testify/suite" + appsV1 "k8s.io/api/apps/v1" +) + +type TrivyStatefulSetTestSuite struct { + suite.Suite +} + +func (suite *TrivyStatefulSetTestSuite) render(values map[string]string) *appsV1.StatefulSet { + helmChartPath := "../../" + + options := &helm.Options{ + SetValues: values, + } + + debug := os.Getenv("debug") + if debug != "true" { + options.Logger = logger.Discard + } + + output := helm.RenderTemplate(suite.T(), options, helmChartPath, "harbor", []string{"templates/trivy/trivy-sts.yaml"}) + + var ss appsV1.StatefulSet + helm.UnmarshalK8SYaml(suite.T(), output, &ss) + + return &ss +} + +func (suite *TrivyStatefulSetTestSuite) TestPersistenceDisabled() { + values := map[string]string{ + "persistence.enabled": "false", + "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 1) + suite.NotNil(ss.Spec.Template.Spec.Volumes[0].EmptyDir) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) +} + +func (suite *TrivyStatefulSetTestSuite) TestPersistenceEnabled() { + values := map[string]string{ + "persistence.enabled": "true", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 0) + suite.Len(ss.Spec.VolumeClaimTemplates, 1) +} + +func (suite *TrivyStatefulSetTestSuite) TestExistingClaim() { + values := map[string]string{ + "persistence.enabled": "true", + "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 1) + suite.NotNil(ss.Spec.Template.Spec.Volumes[0].PersistentVolumeClaim) + suite.Equal("trivy-data", ss.Spec.Template.Spec.Volumes[0].PersistentVolumeClaim.ClaimName) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) +} + +func (suite *TrivyStatefulSetTestSuite) TestInternalTLSEnabled() { + { + values := map[string]string{ + "internalTLS.enabled": "true", + "persistence.enabled": "false", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 2) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) + } + + { + values := map[string]string{ + "internalTLS.enabled": "true", + "persistence.enabled": "true", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 1) + suite.Len(ss.Spec.VolumeClaimTemplates, 1) + } + + { + values := map[string]string{ + "internalTLS.enabled": "true", + "persistence.enabled": "true", + "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 2) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) + } +} + +func (suite *TrivyStatefulSetTestSuite) TestCustomCA() { + { + values := map[string]string{ + "caBundleSecretName": "ca-bundle-secret", + "persistence.enabled": "false", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 2) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) + } + + { + values := map[string]string{ + "caBundleSecretName": "ca-bundle-secret", + "internalTLS.enabled": "true", + "persistence.enabled": "false", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 3) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) + } + + { + values := map[string]string{ + "caBundleSecretName": "ca-bundle-secret", + "internalTLS.enabled": "true", + "persistence.enabled": "true", + "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 3) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) + } + + { + values := map[string]string{ + "caBundleSecretName": "ca-bundle-secret", + "persistence.enabled": "true", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 1) + suite.Len(ss.Spec.VolumeClaimTemplates, 1) + } + + { + values := map[string]string{ + "caBundleSecretName": "ca-bundle-secret", + "persistence.enabled": "true", + "persistence.persistentVolumeClaim.trivy.existingClaim": "trivy-data", + } + + ss := suite.render(values) + suite.Len(ss.Spec.Template.Spec.Volumes, 2) + suite.Len(ss.Spec.VolumeClaimTemplates, 0) + } +} + +func TestTrivyStatefulSetTestSuite(t *testing.T) { + suite.Run(t, &TrivyStatefulSetTestSuite{}) +} diff --git a/charts/harbor-helm-main/values.schema.json b/charts/harbor-helm-main/values.schema.json new file mode 100644 index 0000000..53992d3 --- /dev/null +++ b/charts/harbor-helm-main/values.schema.json @@ -0,0 +1,758 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "resources": { + "description": "Your service will have at least the requested resources and never more than its limits. No limit for a resource and you can consume everything left on the host machine.", + "type": "object", + "properties": { + "requests": { + "description": "Guaranteed resources", + "type": "object", + "properties": { + "cpu": { + "description": "The amount of cpu guaranteed", + "title": "CPU", + "type": "string", + "default": "100m", + "render": "slider", + "sliderMin": 50, + "sliderMax": 40000, + "sliderStep": 50, + "sliderUnit": "m", + "sliderExtremity": "down", + "sliderExtremitySemantic": "guaranteed", + "sliderRangeId": "cpu", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.cpuRequest", + "useRegionSliderConfig": "cpu" + } + }, + "memory": { + "description": "The amount of memory guaranteed", + "title": "memory", + "type": "string", + "default": "2Gi", + "render": "slider", + "sliderMin": 1, + "sliderMax": 200, + "sliderStep": 1, + "sliderUnit": "Gi", + "sliderExtremity": "down", + "sliderExtremitySemantic": "guaranteed", + "sliderRangeId": "memory", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.memoryRequest", + "useRegionSliderConfig": "memory" + } + } + } + }, + "limits": { + "description": "max resources", + "type": "object", + "properties": { + "cpu": { + "description": "The maximum amount of cpu", + "title": "CPU", + "type": "string", + "default": "30000m", + "render": "slider", + "sliderMin": 50, + "sliderMax": 40000, + "sliderStep": 50, + "sliderUnit": "m", + "sliderExtremity": "up", + "sliderExtremitySemantic": "Maximum", + "sliderRangeId": "cpu", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.cpuLimit", + "useRegionSliderConfig": "cpu" + } + }, + "memory": { + "description": "The maximum amount of memory", + "title": "Memory", + "type": "string", + "default": "50Gi", + "render": "slider", + "sliderMin": 1, + "sliderMax": 200, + "sliderStep": 1, + "sliderUnit": "Gi", + "sliderExtremity": "up", + "sliderExtremitySemantic": "Maximum", + "sliderRangeId": "memory", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.memoryLimit", + "useRegionSliderConfig": "memory" + } + } + } + } + } + }, + "discovery": { + "description": "configure your service to autodetect some ressources.", + "type": "object", + "properties": { + "hive": { + "type": "boolean", + "title": "Enable hive metastore discovery", + "description": "discover your hive metastore service", + "default": true + }, + "mlflow": { + "type": "boolean", + "title": "Enable mlflow discovery", + "description": "discover your mlflow service", + "default": true + }, + "metaflow": { + "type": "boolean", + "title": "Enable metaflow discovery", + "description": "discover your metaflow service", + "default": true + } + } + }, + "service": { + "description": "spark-history specific configuration", + "type": "object", + "properties": { + "image": { + "description": "image docker", + "type": "object", + "properties": { + "pullPolicy": { + "type": "string", + "description": "option when pulling the docker image", + "default": "IfNotPresent", + "enum": [ + "IfNotPresent", + "Always", + "Never" + ] + }, + "version": { + "description": "vscode supported version", + "type": "string", + "default": "inseefrlab/onyxia-vscode-python:py3.11.6", + "listEnum": [ + "inseefrlab/onyxia-vscode-python:py3.11.6", + "inseefrlab/onyxia-vscode-python:py3.10.13" + ], + "render": "list", + "hidden": { + "value": true, + "path": "service/image/custom/enabled" + } + }, + "custom": { + "description": "use a custom vscode docker image", + "type": "object", + "properties": { + "enabled": { + "title": "custom image", + "type": "boolean", + "description": "use a custom vscode docker images", + "default": false + }, + "version": { + "description": "vscode unsupported version", + "type": "string", + "default": "inseefrlab/onyxia-vscode-python:py3.11.6", + "hidden": { + "value": false, + "path": "service/image/custom/enabled" + } + } + } + } + } + } + } + }, + "persistence": { + "description": "Configuration for persistence", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Create a persistent volume", + "default": true + }, + "size": { + "type": "string", + "title": "Persistent volume size", + "description": "Size of the persistent volume", + "default": "10Gi", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderStep": 1, + "sliderUnit": "Gi", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.disk", + "useRegionSliderConfig": "disk" + }, + "hidden": { + "value": false, + "path": "persistence/enabled" + } + } + } + }, + "security": { + "description": "security specific configuration", + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "Password", + "default": "changeme", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{project.password}}" + } + }, + "allowlist": { + "type": "object", + "description": "IP protection", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable IP protection", + "description": "Only the configured set of IPs will be able to reach the service", + "default": true, + "x-onyxia": { + "overwriteDefaultWith": "region.defaultIpProtection" + } + }, + "ip": { + "type": "string", + "description": "the white list of IP is whitespace", + "title": "Whitelist of IP", + "x-onyxia": { + "overwriteDefaultWith": "{{user.ip}}" + } + } + } + }, + "networkPolicy": { + "type": "object", + "description": "Define access policy to the service", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable network policy", + "description": "Only pod from the same namespace will be allowed", + "default": true, + "x-onyxia": { + "overwriteDefaultWith": "region.defaultNetworkPolicy" + } + }, + "from": { + "type": "array", + "description": "Array of source allowed to have network access to your service", + "default": [], + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.from" + } + } + } + } + } + }, + "kubernetes": { + "description": "configuration of your kubernetes access", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "allow your service to access your namespace ressources", + "default": true + }, + "role": { + "type": "string", + "description": "bind your service account to this kubernetes default role", + "default": "view", + "hidden": { + "value": false, + "path": "kubernetes/enabled" + }, + "enum": [ + "view", + "edit", + "admin" + ] + } + } + }, + "git": { + "description": "Git user configuration", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Add git config inside your environment", + "default": true + }, + "name": { + "type": "string", + "description": "user name for git", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.name}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "email": { + "type": "string", + "description": "user email for git", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.email}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "cache": { + "type": "string", + "description": "duration in seconds of the credentials cache duration", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.credentials_cache_duration}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "token": { + "type": "string", + "description": "personal access token", + "default": "", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{git.token}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "repository": { + "type": "string", + "description": "projet", + "default": "", + "x-onyxia": { + "overwriteDefaultWith": "{{git.project}}" + }, + "hidden": { + "value": false, + "path": "git/enabled" + } + }, + "branch": { + "type": "string", + "description": "Branch automatically checked out", + "default": "", + "hidden": { + "value": "", + "path": "git/repository" + } + } + } + }, + "vault": { + "description": "Configuration of vault client", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Add vault temporary identity inside your environment", + "default": true + }, + "token": { + "description": "token vault", + "type": "string", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_TOKEN}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "url": { + "description": "url of vault server", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_ADDR}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "mount": { + "description": "mount of the v2 secret engine", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_MOUNT}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "directory": { + "description": "top level directory", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{vault.VAULT_TOP_DIR}}" + }, + "hidden": { + "value": false, + "path": "vault/enabled" + } + }, + "secret": { + "description": "the path of the secret to convert into a list of environment variables", + "type": "string", + "default": "", + "hidden": { + "value": false, + "path": "vault/enabled" + } + } + } + }, + "s3": { + "description": "Configuration of temporary identity", + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Add S3 temporary identity inside your environment", + "default": true + }, + "accessKeyId": { + "description": "AWS Access Key", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "s3.AWS_ACCESS_KEY_ID" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "endpoint": { + "description": "AWS S3 Endpoint", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_S3_ENDPOINT}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "defaultRegion": { + "description": "AWS S3 default region", + "type": "string", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_DEFAULT_REGION}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "secretAccessKey": { + "description": "AWS S3 secret access key", + "type": "string", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_SECRET_ACCESS_KEY}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + }, + "sessionToken": { + "description": "AWS S3 session Token", + "type": "string", + "render": "password", + "x-onyxia": { + "overwriteDefaultWith": "{{s3.AWS_SESSION_TOKEN}}" + }, + "hidden": { + "value": false, + "path": "s3/enabled" + } + } + } + }, + "ingress": { + "type": "object", + "form": true, + "title": "Ingress Details", + "properties": { + "enabled": { + "description": "Enable Ingress", + "type": "boolean", + "default": true, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.ingress" + } + }, + "hostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-0.{{k8s.domain}}" + } + }, + "userHostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-user.{{k8s.domain}}" + } + }, + "ingressClassName": { + "type": "string", + "form": true, + "title": "ingressClassName", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{k8s.ingressClassName}}" + } + }, + "useCertManager": { + "type": "boolean", + "description": "Whether CertManager should be used to generate a certificate", + "default": false, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.useCertManager" + } + }, + "certManagerClusterIssuer":{ + "type": "string", + "description": "certManager cluster issuer", + "title": "CertManager Cluster Issuer", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.certManagerClusterIssuer" + } + } + } + }, + "route": { + "type": "object", + "form": true, + "title": "Route details", + "properties": { + "enabled": { + "description": "Enable route", + "type": "boolean", + "default": false, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "k8s.route" + } + }, + "hostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-0.{{k8s.domain}}" + } + }, + "userHostname": { + "type": "string", + "form": true, + "title": "Hostname", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-user.{{k8s.domain}}" + } + } + } + }, + "networking": { + "type": "object", + "form": true, + "title": "Networking detail", + "properties": { + "user": { + "type": "object", + "description": "user defined port", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable a custom service port", + "description": "Enable a custom service port", + "default": false + }, + "port": { + "type": "integer", + "description": "port of the custom service", + "title": "Custom service port", + "hidden": { + "value": false, + "path": "networking/user/enabled" + }, + "default": 5000 + } + } + } + } + }, + "init": { + "description": "Init parameters", + "type": "object", + "properties": { + "regionInit": { + "type": "string", + "description": "region initialization script", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{k8s.initScriptUrl}}" + } + }, + "regionInitCheckSum": { + "type": "string", + "description": "region initialization script", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{k8s.initScriptCheckSum}}" + } + }, + "personalInit": { + "type": "string", + "description": "user initialization script", + "default": "" + }, + "personalInitArgs": { + "type": "string", + "description": "args for user initialization script", + "default": "" + } + } + }, + "repository": { + "description": "python repositories for pip and conda", + "type": "object", + "properties": { + "pipRepository": { + "type": "string", + "description": "python repository for pip", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{packageRepositoryInjection.pypiProxyUrl}}" + } + }, + "condaRepository": { + "type": "string", + "description": "python repository for pip", + "default": "", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "{{packageRepositoryInjection.condaProxyUrl}}" + } + } + } + }, + "startupProbe": { + "type": "object", + "description": "Start up probe", + "default": {}, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.startupProbe" + } + }, + "tolerations": { + "type": "array", + "description": "Array of tolerations", + "default": [], + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.tolerations" + } + }, + "nodeSelector": { + "type": "object", + "description": "NodeSelector", + "default": {}, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "region.nodeSelector" + } + }, + "userPreferences": { + "description": "User Preferences", + "type": "object", + "properties": { + "darkMode": { + "type": "boolean", + "description": "dark mode is or is not enabled", + "default": false, + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "user.darkMode" + } + }, + "language": { + "type": "string", + "description": "Preferred language", + "default": "en", + "x-onyxia": { + "hidden": true, + "overwriteDefaultWith": "user.lang" + } + } + } + }, + "global": { + "description": "Suspend", + "type": "object", + "properties": { + "suspend": { + "type": "boolean", + "description": "Suspend this service", + "default": false, + "x-onyxia": { + "hidden": true + } + } + } + } + } +} \ No newline at end of file diff --git a/charts/harbor-helm-main/values.yaml b/charts/harbor-helm-main/values.yaml new file mode 100644 index 0000000..46a94b8 --- /dev/null +++ b/charts/harbor-helm-main/values.yaml @@ -0,0 +1,1009 @@ +expose: + # Set how to expose the service. Set the type as "ingress", "clusterIP", "nodePort" or "loadBalancer" + # and fill the information in the corresponding section + type: ingress + tls: + # Enable TLS or not. + # Delete the "ssl-redirect" annotations in "expose.ingress.annotations" when TLS is disabled and "expose.type" is "ingress" + # Note: if the "expose.type" is "ingress" and TLS is disabled, + # the port must be included in the command when pulling/pushing images. + # Refer to https://github.com/goharbor/harbor/issues/5291 for details. + enabled: true + # The source of the tls certificate. Set as "auto", "secret" + # or "none" and fill the information in the corresponding section + # 1) auto: generate the tls certificate automatically + # 2) secret: read the tls certificate from the specified secret. + # The tls certificate can be generated manually or by cert manager + # 3) none: configure no tls certificate for the ingress. If the default + # tls certificate is configured in the ingress controller, choose this option + certSource: auto + auto: + # The common name used to generate the certificate, it's necessary + # when the type isn't "ingress" + commonName: "" + secret: + # The name of secret which contains keys named: + # "tls.crt" - the certificate + # "tls.key" - the private key + secretName: "" + ingress: + hosts: + core: core.harbor.domain + # set to the type of ingress controller if it has specific requirements. + # leave as `default` for most ingress controllers. + # set to `gce` if using the GCE ingress controller + # set to `ncp` if using the NCP (NSX-T Container Plugin) ingress controller + # set to `alb` if using the ALB ingress controller + # set to `f5-bigip` if using the F5 BIG-IP ingress controller + controller: default + ## Allow .Capabilities.KubeVersion.Version to be overridden while creating ingress + kubeVersionOverride: "" + className: "" + annotations: + # note different ingress controllers may require a different ssl-redirect annotation + # for Envoy, use ingress.kubernetes.io/force-ssl-redirect: "true" and remove the nginx lines below + ingress.kubernetes.io/ssl-redirect: "true" + ingress.kubernetes.io/proxy-body-size: "0" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "0" + # ingress-specific labels + labels: {} + clusterIP: + # The name of ClusterIP service + name: harbor + # The ip address of the ClusterIP service (leave empty for acquiring dynamic ip) + staticClusterIP: "" + ports: + # The service port Harbor listens on when serving HTTP + httpPort: 80 + # The service port Harbor listens on when serving HTTPS + httpsPort: 443 + # Annotations on the ClusterIP service + annotations: {} + # ClusterIP-specific labels + labels: {} + nodePort: + # The name of NodePort service + name: harbor + ports: + http: + # The service port Harbor listens on when serving HTTP + port: 80 + # The node port Harbor listens on when serving HTTP + nodePort: 30002 + https: + # The service port Harbor listens on when serving HTTPS + port: 443 + # The node port Harbor listens on when serving HTTPS + nodePort: 30003 + # Annotations on the nodePort service + annotations: {} + # nodePort-specific labels + labels: {} + loadBalancer: + # The name of LoadBalancer service + name: harbor + # Set the IP if the LoadBalancer supports assigning IP + IP: "" + ports: + # The service port Harbor listens on when serving HTTP + httpPort: 80 + # The service port Harbor listens on when serving HTTPS + httpsPort: 443 + # Annotations on the loadBalancer service + annotations: {} + # loadBalancer-specific labels + labels: {} + sourceRanges: [] + +# The external URL for Harbor core service. It is used to +# 1) populate the docker/helm commands showed on portal +# 2) populate the token service URL returned to docker client +# +# Format: protocol://domain[:port]. Usually: +# 1) if "expose.type" is "ingress", the "domain" should be +# the value of "expose.ingress.hosts.core" +# 2) if "expose.type" is "clusterIP", the "domain" should be +# the value of "expose.clusterIP.name" +# 3) if "expose.type" is "nodePort", the "domain" should be +# the IP address of k8s node +# +# If Harbor is deployed behind the proxy, set it as the URL of proxy +externalURL: https://core.harbor.domain + +# The persistence is enabled by default and a default StorageClass +# is needed in the k8s cluster to provision volumes dynamically. +# Specify another StorageClass in the "storageClass" or set "existingClaim" +# if you already have existing persistent volumes to use +# +# For storing images and charts, you can also use "azure", "gcs", "s3", +# "swift" or "oss". Set it in the "imageChartStorage" section +persistence: + enabled: true + # Setting it to "keep" to avoid removing PVCs during a helm delete + # operation. Leaving it empty will delete PVCs after the chart deleted + # (this does not apply for PVCs that are created for internal database + # and redis components, i.e. they are never deleted automatically) + resourcePolicy: "keep" + persistentVolumeClaim: + registry: + # Use the existing PVC which must be created manually before bound, + # and specify the "subPath" if the PVC is shared with other components + existingClaim: "" + # Specify the "storageClass" used to provision the volume. Or the default + # StorageClass will be used (the default). + # Set it to "-" to disable dynamic provisioning + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 5Gi + annotations: {} + jobservice: + jobLog: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 1Gi + annotations: {} + # If external database is used, the following settings for database will + # be ignored + database: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 1Gi + annotations: {} + # If external Redis is used, the following settings for Redis will + # be ignored + redis: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 1Gi + annotations: {} + trivy: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 5Gi + annotations: {} + # Define which storage backend is used for registry to store + # images and charts. Refer to + # https://github.com/distribution/distribution/blob/main/docs/configuration.md#storage + # for the detail. + imageChartStorage: + # 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 + # it. To disable redirects, simply set `disableredirect` to `true` instead. + # Refer to + # https://github.com/distribution/distribution/blob/main/docs/configuration.md#redirect + # for the detail. + disableredirect: false + # 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 + # of registry's containers. + # caBundleSecretName: + + # Specify the type of storage: "filesystem", "azure", "gcs", "s3", "swift", + # "oss" and fill the information needed in the corresponding section. The type + # must be "filesystem" if you want to use persistent volumes for registry + type: filesystem + filesystem: + rootdirectory: /storage + #maxthreads: 100 + azure: + accountname: accountname + accountkey: base64encodedaccountkey + container: containername + #realm: core.windows.net + # To use existing secret, the key must be AZURE_STORAGE_ACCESS_KEY + existingSecret: "" + gcs: + bucket: bucketname + # The base64 encoded json file which contains the key + encodedkey: base64-encoded-json-key-file + #rootdirectory: /gcs/object/name/prefix + #chunksize: "5242880" + # To use existing secret, the key must be GCS_KEY_DATA + existingSecret: "" + useWorkloadIdentity: false + s3: + # Set an existing secret for S3 accesskey and secretkey + # keys in the secret should be REGISTRY_STORAGE_S3_ACCESSKEY and REGISTRY_STORAGE_S3_SECRETKEY for registry + #existingSecret: "" + region: us-west-1 + bucket: bucketname + #accesskey: awsaccesskey + #secretkey: awssecretkey + #regionendpoint: http://myobjects.local + #encrypt: false + #keyid: mykeyid + #secure: true + #skipverify: false + #v4auth: true + #chunksize: "5242880" + #rootdirectory: /s3/object/name/prefix + #storageclass: STANDARD + #multipartcopychunksize: "33554432" + #multipartcopymaxconcurrency: 100 + #multipartcopythresholdsize: "33554432" + swift: + authurl: https://storage.myprovider.com/v3/auth + username: username + password: password + container: containername + # keys in existing secret must be REGISTRY_STORAGE_SWIFT_PASSWORD, REGISTRY_STORAGE_SWIFT_SECRETKEY, REGISTRY_STORAGE_SWIFT_ACCESSKEY + existingSecret: "" + #region: fr + #tenant: tenantname + #tenantid: tenantid + #domain: domainname + #domainid: domainid + #trustid: trustid + #insecureskipverify: false + #chunksize: 5M + #prefix: + #secretkey: secretkey + #accesskey: accesskey + #authversion: 3 + #endpointtype: public + #tempurlcontainerkey: false + #tempurlmethods: + oss: + accesskeyid: accesskeyid + accesskeysecret: accesskeysecret + region: regionname + bucket: bucketname + # key in existingSecret must be REGISTRY_STORAGE_OSS_ACCESSKEYSECRET + existingSecret: "" + #endpoint: endpoint + #internal: false + #encrypt: false + #secure: true + #chunksize: 10M + #rootdirectory: rootdirectory + +# The initial password of Harbor admin. Change it from portal after launching Harbor +# or give an existing secret for it +# key in secret is given via (default to HARBOR_ADMIN_PASSWORD) +# existingSecretAdminPassword: +existingSecretAdminPasswordKey: HARBOR_ADMIN_PASSWORD +harborAdminPassword: "Harbor12345" + +# The internal TLS used for harbor components secure communicating. In order to enable https +# in each component tls cert files need to provided in advance. +internalTLS: + # If internal TLS enabled + enabled: false + # enable strong ssl ciphers (default: false) + strong_ssl_ciphers: false + # There are three ways to provide tls + # 1) "auto" will generate cert automatically + # 2) "manual" need provide cert file manually in following value + # 3) "secret" internal certificates from secret + certSource: "auto" + # The content of trust ca, only available when `certSource` is "manual" + trustCa: "" + # core related cert configuration + core: + # secret name for core's tls certs + secretName: "" + # Content of core's TLS cert file, only available when `certSource` is "manual" + crt: "" + # Content of core's TLS key file, only available when `certSource` is "manual" + key: "" + # jobservice related cert configuration + jobservice: + # secret name for jobservice's tls certs + secretName: "" + # Content of jobservice's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of jobservice's TLS key file, only available when `certSource` is "manual" + key: "" + # registry related cert configuration + registry: + # secret name for registry's tls certs + secretName: "" + # Content of registry's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of registry's TLS key file, only available when `certSource` is "manual" + key: "" + # portal related cert configuration + portal: + # secret name for portal's tls certs + secretName: "" + # Content of portal's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of portal's TLS key file, only available when `certSource` is "manual" + key: "" + # trivy related cert configuration + trivy: + # secret name for trivy's tls certs + secretName: "" + # Content of trivy's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of trivy's TLS key file, only available when `certSource` is "manual" + key: "" + +ipFamily: + # ipv6Enabled set to true if ipv6 is enabled in cluster, currently it affected the nginx related component + ipv6: + enabled: true + # ipv4Enabled set to true if ipv4 is enabled in cluster, currently it affected the nginx related component + ipv4: + enabled: true + +imagePullPolicy: IfNotPresent + +# Use this set to assign a list of default pullSecrets +imagePullSecrets: +# - name: docker-registry-secret +# - name: internal-registry-secret + +# The update strategy for deployments with persistent volumes(jobservice, registry): "RollingUpdate" or "Recreate" +# Set it as "Recreate" when "RWM" for volumes isn't supported +updateStrategy: + type: RollingUpdate + +# debug, info, warning, error or fatal +logLevel: info + +# The name of the secret which contains key named "ca.crt". Setting this enables the +# download link on portal to download the CA certificate when the certificate isn't +# generated automatically +caSecretName: "" + +# The secret key used for encryption. Must be a string of 16 chars. +secretKey: "not-a-secure-key" +# If using existingSecretSecretKey, the key must be secretKey +existingSecretSecretKey: "" + +# The proxy settings for updating trivy vulnerabilities from the Internet and replicating +# artifacts from/to the registries that cannot be reached directly +proxy: + httpProxy: + httpsProxy: + noProxy: 127.0.0.1,localhost,.local,.internal + components: + - core + - jobservice + - trivy + +# Run the migration job via helm hook +enableMigrateHelmHook: false + +# The custom ca bundle secret, the secret must contain key named "ca.crt" +# which will be injected into the trust store for core, jobservice, registry, trivy components +# caBundleSecretName: "" + +## UAA Authentication Options +# If you're using UAA for authentication behind a self-signed +# certificate you will need to provide the CA Cert. +# Set uaaSecretName below to provide a pre-created secret that +# contains a base64 encoded CA Certificate named `ca.crt`. +# uaaSecretName: + +metrics: + enabled: false + core: + path: /metrics + port: 8001 + registry: + path: /metrics + port: 8001 + jobservice: + path: /metrics + port: 8001 + exporter: + path: /metrics + port: 8001 + ## Create prometheus serviceMonitor to scrape harbor metrics. + ## This requires the monitoring.coreos.com/v1 CRD. Please see + ## https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md + ## + serviceMonitor: + enabled: false + additionalLabels: {} + # Scrape interval. If not set, the Prometheus default scrape interval is used. + interval: "" + # Metric relabel configs to apply to samples before ingestion. + metricRelabelings: + [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + # Relabel configs to apply to samples before ingestion. + relabelings: + [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + +trace: + enabled: false + # trace provider: jaeger or otel + # jaeger should be 1.26+ + provider: jaeger + # set sample_rate to 1 if you wanna sampling 100% of trace data; set 0.5 if you wanna sampling 50% of trace data, and so forth + sample_rate: 1 + # namespace used to differentiate different harbor services + # namespace: + # attributes is a key value dict contains user defined attributes used to initialize trace provider + # attributes: + # application: harbor + jaeger: + # jaeger supports two modes: + # collector mode(uncomment endpoint and uncomment username, password if needed) + # agent mode(uncomment agent_host and agent_port) + endpoint: http://hostname:14268/api/traces + # username: + # password: + # agent_host: hostname + # export trace data by jaeger.thrift in compact mode + # agent_port: 6831 + otel: + endpoint: hostname:4318 + url_path: /v1/traces + compression: false + insecure: true + # timeout is in seconds + timeout: 10 + +# cache layer configurations +# if this feature enabled, harbor will cache the resource +# `project/project_metadata/repository/artifact/manifest` in the redis +# which help to improve the performance of high concurrent pulling manifest. +cache: + # default is not enabled. + enabled: false + # default keep cache for one day. + expireHours: 24 + +## set Container Security Context to comply with PSP restricted policy if necessary +## each of the conatiner will apply the same security context +## containerSecurityContext:{} is initially an empty yaml that you could edit it on demand, we just filled with a common template for convenience +containerSecurityContext: + privileged: false + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + runAsNonRoot: true + capabilities: + drop: + - ALL + +# If service exposed via "ingress", the Nginx will not be used +nginx: + image: + repository: goharbor/nginx-photon + tag: dev + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + +portal: + image: + repository: goharbor/harbor-portal + tag: dev + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## Additional service annotations + serviceAnnotations: {} + ## The priority class to run the pod as + priorityClassName: + +core: + image: + repository: goharbor/harbor-core + tag: dev + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + ## Startup probe values + startupProbe: + enabled: true + initialDelaySeconds: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## Additional service annotations + serviceAnnotations: {} + ## The priority class to run the pod as + priorityClassName: + ## User settings configuration json string + configureUserSettings: + # The provider for updating project quota(usage), there are 2 options, redis or db. + # By default it is implemented by db but you can configure it to redis which + # can improve the performance of high concurrent pushing to the same project, + # and reduce the database connections spike and occupies. + # Using redis will bring up some delay for quota usage updation for display, so only + # suggest switch provider to redis if you were ran into the db connections spike around + # the scenario of high concurrent pushing to same project, no improvment for other scenes. + quotaUpdateProvider: db # Or redis + # Secret is used when core server communicates with other components. + # If a secret key is not specified, Helm will generate one. Alternatively set existingSecret to use an existing secret + # Must be a string of 16 chars. + secret: "" + # Fill in the name of a kubernetes secret if you want to use your own + # If using existingSecret, the key must be secret + existingSecret: "" + # Fill the name of a kubernetes secret if you want to use your own + # TLS certificate and private key for token encryption/decryption. + # The secret must contain keys named: + # "tls.key" - the private key + # "tls.crt" - the certificate + secretName: "" + # If not specifying a preexisting secret, a secret can be created from tokenKey and tokenCert and used instead. + # If none of secretName, tokenKey, and tokenCert are specified, an ephemeral key and certificate will be autogenerated. + # tokenKey and tokenCert must BOTH be set or BOTH unset. + # The tokenKey value is formatted as a multiline string containing a PEM-encoded RSA key, indented one more than tokenKey on the following line. + tokenKey: | + # If tokenKey is set, the value of tokenCert must be set as a PEM-encoded certificate signed by tokenKey, and supplied as a multiline string, indented one more than tokenCert on the following line. + tokenCert: | + # The XSRF key. Will be generated automatically if it isn't specified + xsrfKey: "" + # If using existingSecret, the key is defined by core.existingXsrfSecretKey + existingXsrfSecret: "" + # If using existingSecret, the key + existingXsrfSecretKey: CSRF_KEY + # The time duration for async update artifact pull_time and repository + # pull_count, the unit is second. Will be 10 seconds if it isn't set. + # eg. artifactPullAsyncFlushDuration: 10 + artifactPullAsyncFlushDuration: + gdpr: + deleteUser: false + auditLogsCompliant: false + +jobservice: + image: + repository: goharbor/harbor-jobservice + tag: dev + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + maxJobWorkers: 10 + # The logger for jobs: "file", "database" or "stdout" + jobLoggers: + - file + # - database + # - stdout + # The jobLogger sweeper duration (ignored if `jobLogger` is `stdout`) + loggerSweeperDuration: 14 #days + notification: + webhook_job_max_retry: 3 + webhook_job_http_client_timeout: 3 # in seconds + reaper: + # the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24 + max_update_hours: 24 + # the max time for execution in running state without new task created + max_dangling_hours: 168 + # Secret is used when job service communicates with other components. + # If a secret key is not specified, Helm will generate one. + # Must be a string of 16 chars. + secret: "" + # Use an existing secret resource + existingSecret: "" + # Key within the existing secret for the job service secret + existingSecretKey: JOBSERVICE_SECRET + +registry: + registry: + image: + repository: goharbor/registry-photon + tag: dev + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + controller: + image: + repository: goharbor/harbor-registryctl + tag: dev + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + # Secret is used to secure the upload state from client + # and registry storage backend. + # See: https://github.com/distribution/distribution/blob/main/docs/configuration.md#http + # If a secret key is not specified, Helm will generate one. + # Must be a string of 16 chars. + secret: "" + # Use an existing secret resource + existingSecret: "" + # Key within the existing secret for the registry service secret + existingSecretKey: REGISTRY_HTTP_SECRET + # If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. + relativeurls: false + credentials: + username: "harbor_registry_user" + password: "harbor_registry_password" + # If using existingSecret, the key must be REGISTRY_PASSWD and REGISTRY_HTPASSWD + existingSecret: "" + # Login and password in htpasswd string format. Excludes `registry.credentials.username` and `registry.credentials.password`. May come in handy when integrating with tools like argocd or flux. This allows the same line to be generated each time the template is rendered, instead of the `htpasswd` function from helm, which generates different lines each time because of the salt. + # htpasswdString: $apr1$XLefHzeG$Xl4.s00sMSCCcMyJljSZb0 # example string + htpasswdString: "" + middleware: + enabled: false + type: cloudFront + cloudFront: + baseurl: example.cloudfront.net + keypairid: KEYPAIRID + duration: 3000s + ipfilteredby: none + # The secret key that should be present is CLOUDFRONT_KEY_DATA, which should be the encoded private key + # that allows access to CloudFront + privateKeySecret: "my-secret" + # enable purge _upload directories + upload_purging: + enabled: true + # remove files in _upload directories which exist for a period of time, default is one week. + age: 168h + # the interval of the purge operations + interval: 24h + dryrun: false + +trivy: + # enabled the flag to enable Trivy scanner + enabled: true + image: + # repository the repository for Trivy adapter image + repository: goharbor/trivy-adapter-photon + # tag the tag for Trivy adapter image + tag: dev + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + # replicas the number of Pod replicas + replicas: 1 + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 1 + memory: 1Gi + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + # debugMode the flag to enable Trivy debug mode with more verbose scanning log + debugMode: false + # vulnType a comma-separated list of vulnerability types. Possible values are `os` and `library`. + vulnType: "os,library" + # severity a comma-separated list of severities to be checked + severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" + # ignoreUnfixed the flag to display only fixed vulnerabilities + ignoreUnfixed: false + # insecure the flag to skip verifying registry certificate + insecure: false + # gitHubToken the GitHub access token to download Trivy DB + # + # 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 + # 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. + # 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 + # 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 + # https://developer.github.com/v3/#rate-limiting + # + # 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 + gitHubToken: "" + # 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. + # 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. + skipUpdate: false + # skipJavaDBUpdate If the flag is enabled you have to manually download the `trivy-java.db` file and mount it in the + # `/home/scanner/.cache/trivy/java-db/trivy-java.db` path + # + skipJavaDBUpdate: false + # The offlineScan option prevents Trivy from sending API requests to identify dependencies. + # + # Scanning JAR files and pom.xml may require Internet access for better detection, but this option tries to avoid it. + # For example, the offline mode will not try to resolve transitive dependencies in pom.xml when the dependency doesn't + # exist in the local repositories. It means a number of detected vulnerabilities might be fewer in offline mode. + # It would work if all the dependencies are in local. + # This option doesn’t affect DB download. You need to specify skipUpdate as well as offlineScan in an air-gapped environment. + offlineScan: false + # Comma-separated list of what security issues to detect. Possible values are `vuln`, `config` and `secret`. Defaults to `vuln`. + securityCheck: "vuln" + # The duration to wait for scan completion + timeout: 5m0s + +database: + # if external database is used, set "type" to "external" + # and fill the connection information in "external" section + type: internal + internal: + image: + repository: goharbor/harbor-db + tag: dev + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + # The timeout used in livenessProbe; 1 to 5 seconds + livenessProbe: + timeoutSeconds: 1 + # The timeout used in readinessProbe; 1 to 5 seconds + readinessProbe: + timeoutSeconds: 1 + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + ## The priority class to run the pod as + priorityClassName: + # The initial superuser password for internal database + password: "changeit" + # The size limit for Shared memory, pgSQL use it for shared_buffer + # More details see: + # https://github.com/goharbor/harbor/issues/15034 + shmSizeLimit: 512Mi + initContainer: + migrator: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + permissions: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + external: + host: "192.168.0.1" + port: "5432" + username: "user" + password: "password" + coreDatabase: "registry" + # if using existing secret, the key must be "password" + existingSecret: "" + # "disable" - No SSL + # "require" - Always SSL (skip verification) + # "verify-ca" - Always SSL (verify that the certificate presented by the + # server was signed by a trusted CA) + # "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 + # in the certificate) + sslmode: "disable" + # The maximum number of connections in the idle connection pool per pod (core+exporter). + # If it <=0, no idle connections are retained. + maxIdleConns: 100 + # The maximum number of open connections to the database per pod (core+exporter). + # If it <= 0, then there is no limit on the number of open connections. + # Note: the default number of connections is 1024 for harbor's postgres. + maxOpenConns: 900 + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + +redis: + # if external Redis is used, set "type" to "external" + # and fill the connection information in "external" section + type: internal + internal: + image: + repository: goharbor/redis-photon + tag: dev + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + ## The priority class to run the pod as + priorityClassName: + # # jobserviceDatabaseIndex defaults to "1" + # # registryDatabaseIndex defaults to "2" + # # trivyAdapterIndex defaults to "5" + # # harborDatabaseIndex defaults to "0", but it can be configured to "6", this config is optional + # # cacheLayerDatabaseIndex defaults to "0", but it can be configured to "7", this config is optional + jobserviceDatabaseIndex: "1" + registryDatabaseIndex: "2" + trivyAdapterIndex: "5" + # harborDatabaseIndex: "6" + # cacheLayerDatabaseIndex: "7" + external: + # support redis, redis+sentinel + # addr for redis: : + # addr for redis+sentinel: :,:,: + addr: "192.168.0.2:6379" + # The name of the set of Redis instances to monitor, it must be set to support redis+sentinel + sentinelMasterSet: "" + # The "coreDatabaseIndex" must be "0" as the library Harbor + # used doesn't support configuring it + # harborDatabaseIndex defaults to "0", but it can be configured to "6", this config is optional + # cacheLayerDatabaseIndex defaults to "0", but it can be configured to "7", this config is optional + coreDatabaseIndex: "0" + jobserviceDatabaseIndex: "1" + registryDatabaseIndex: "2" + trivyAdapterIndex: "5" + # harborDatabaseIndex: "6" + # cacheLayerDatabaseIndex: "7" + # username field can be an empty string, and it will be authenticated against the default user + username: "" + password: "" + # If using existingSecret, the key must be REDIS_PASSWORD + existingSecret: "" + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + +exporter: + image: + repository: goharbor/harbor-exporter + tag: dev + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + ## The priority class to run the pod as + priorityClassName: + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + cacheDuration: 23 + cacheCleanInterval: 14400 diff --git a/charts/index.yaml b/charts/index.yaml deleted file mode 100644 index 6c82c70..0000000 --- a/charts/index.yaml +++ /dev/null @@ -1,3 +0,0 @@ -apiVersion: v1 -entries: {} -generated: "2024-04-12T14:04:42.2690925+02:00" diff --git a/charts/wordpress copie original/wordpress/values.schema.json b/charts/wordpress copie original/wordpress/values.schema.json index 7f62faa..935b417 100644 --- a/charts/wordpress copie original/wordpress/values.schema.json +++ b/charts/wordpress copie original/wordpress/values.schema.json @@ -60,7 +60,7 @@ "form": true, "hidden": { "value": false, - "path": "mariadb/primary/persistence/enabled" + "path": "mariadb/enabled" }, "render": "slider", "sliderMin": 1, @@ -82,521 +82,27 @@ "host": { "type": "string", "form": true, - "title": "Database Host", - "hidden": "mariadb/enabled" + "title": "Database Host" }, "user": { "type": "string", "form": true, - "title": "Database Username", - "hidden": "mariadb/enabled" + "title": "Database Username" }, "password": { "type": "string", "form": true, - "title": "Database Password", - "hidden": "mariadb/enabled" + "title": "Database Password" }, "database": { "type": "string", "form": true, - "title": "Database Name", - "hidden": "mariadb/enabled" + "title": "Database Name" }, "port": { "type": "integer", "form": true, - "title": "Database Port", - "hidden": "mariadb/enabled" - } - } - }, - "ingress": { - "type": "object", - "form": true, - "title": "Ingress Configuration", - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Use a custom hostname", - "description": "Enable the ingress resource that allows you to access the WordPress installation." - }, - "hostname": { - "type": "string", - "form": true, - "title": "Hostname", - "hidden": { - "value": false, - "path": "ingress/enabled" - } - }, - "tls": { - "type": "boolean", - "form": true, - "title": "Create a TLS secret", - "hidden": { - "value": false, - "path": "ingress/enabled" - } - } - } - }, - "service": { - "type": "object", - "form": true, - "title": "Service Configuration", - "properties": { - "type": { - "type": "string", - "form": true, - "title": "Service Type", - "description": "Allowed values: \"ClusterIP\", \"NodePort\" and \"LoadBalancer\"" - } - } - }, - "resources": { - "type": "object", - "title": "Required Resources", - "description": "Your service will have at least the requested resources and never more than its limits. No limit for a resource and you can consume everything left on the host machine.", - "properties": { - "requests": { - "description": "Guaranteed resources", - "type": "object", - "properties": { - "memory": { - "description": "The amount of memory guaranteed", - "title": "memory", - "type": "string", - "default": "2Gi", - "render": "slider", - "sliderMin": 1, - "sliderMax": 20, - "sliderStep": 1, - "sliderUnit": "Gi", - "sliderExtremity": "down", - "sliderExtremitySemantic": "guaranteed", - "sliderRangeId": "memory", - "x-onyxia": { - "overwriteDefaultWith": "region.resources.memoryRequest", - "useRegionSliderConfig": "memory" - } - }, - "cpu": { - "description": "The amount of cpu guaranteed", - "title": "CPU", - "type": "string", - "default": "100m", - "render": "slider", - "sliderMin": 50, - "sliderMax": 40000, - "sliderStep": 50, - "sliderUnit": "m", - "sliderExtremity": "down", - "sliderExtremitySemantic": "guaranteed", - "sliderRangeId": "cpu", - "x-onyxia": { - "overwriteDefaultWith": "region.resources.cpuRequest", - "useRegionSliderConfig": "cpu" - } - } - } - }, - "limits": { - "description": "max resources", - "type": "object", - "properties": { - "cpu": { - "description": "The maximum amount of cpu", - "title": "CPU", - "type": "string", - "default": "30000m", - "render": "slider", - "sliderMin": 50, - "sliderMax": 40000, - "sliderStep": 50, - "sliderUnit": "m", - "sliderExtremity": "up", - "sliderExtremitySemantic": "Maximum", - "sliderRangeId": "cpu", - "x-onyxia": { - "overwriteDefaultWith": "region.resources.cpuLimit", - "useRegionSliderConfig": "cpu" - } - }, - "memory": { - "description": "The maximum amount of memory", - "title": "Memory", - "type": "string", - "default": "50Gi", - "render": "slider", - "sliderMin": 1, - "sliderMax": 200, - "sliderStep": 1, - "sliderUnit": "Gi", - "sliderExtremity": "up", - "sliderExtremitySemantic": "Maximum", - "sliderRangeId": "memory", - "x-onyxia": { - "overwriteDefaultWith": "region.resources.memoryLimit", - "useRegionSliderConfig": "memory" - } - } - } - } - } - }, - "volumePermissions": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable Init Containers", - "description": "Use an init container to set required folder permissions on the data volume before mounting it in the final destination" - } - } - }, - "metrics": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "Enable Metrics", - "description": "Prometheus Exporter / Metrics", - "form": true - } - } - }, - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "security": { - "description": "security specific configuration", - "type": "object", - "properties": { - "password": { - "type": "string", - "description": "Password", - "default": "changeme", - "render": "password", - "x-onyxia": { - "overwriteDefaultWith": "{{project.password}}" - } - }, - "allowlist": { - "type": "object", - "description": "IP protection", - "properties": { - "enabled": { - "type": "boolean", - "title": "Enable IP protection", - "description": "Only the configured set of IPs will be able to reach the service", - "default": true, - "x-onyxia": { - "overwriteDefaultWith": "region.defaultIpProtection" - } - }, - "ip": { - "type": "string", - "description": "the white list of IP is whitespace", - "title": "Whitelist of IP", - "x-onyxia": { - "overwriteDefaultWith": "{{user.ip}}" - } - } - } - }, - "networkPolicy": { - "type": "object", - "description": "Define access policy to the service", - "properties": { - "enabled": { - "type": "boolean", - "title": "Enable network policy", - "description": "Only pod from the same namespace will be allowed", - "default": true, - "x-onyxia": { - "overwriteDefaultWith": "region.defaultNetworkPolicy" - } - }, - "from": { - "type": "array", - "description": "Array of source allowed to have network access to your service", - "default": [], - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "region.from" - } - } - } - } - } - }, - "kubernetes": { - "description": "configuration of your kubernetes access", - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "description": "allow your service to access your namespace ressources", - "default": true - }, - "role": { - "type": "string", - "description": "bind your service account to this kubernetes default role", - "default": "view", - "hidden": { - "value": false, - "path": "kubernetes/enabled" - }, - "enum": [ - "view", - "edit", - "admin" - ] - } - } - }, - "git": { - "description": "Git user configuration", - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "description": "Add git config inside your environment", - "default": true - }, - "name": { - "type": "string", - "description": "user name for git", - "default": "", - "x-onyxia": { - "overwriteDefaultWith": "{{git.name}}" - }, - "hidden": { - "value": false, - "path": "git/enabled" - } - }, - "email": { - "type": "string", - "description": "user email for git", - "default": "", - "x-onyxia": { - "overwriteDefaultWith": "{{git.email}}" - }, - "hidden": { - "value": false, - "path": "git/enabled" - } - }, - "cache": { - "type": "string", - "description": "duration in seconds of the credentials cache duration", - "default": "", - "x-onyxia": { - "overwriteDefaultWith": "{{git.credentials_cache_duration}}" - }, - "hidden": { - "value": false, - "path": "git/enabled" - } - }, - "token": { - "type": "string", - "description": "personal access token", - "default": "", - "render": "password", - "x-onyxia": { - "overwriteDefaultWith": "{{git.token}}" - }, - "hidden": { - "value": false, - "path": "git/enabled" - } - }, - "repository": { - "type": "string", - "description": "projet", - "default": "", - "x-onyxia": { - "overwriteDefaultWith": "{{git.project}}" - }, - "hidden": { - "value": false, - "path": "git/enabled" - } - }, - "branch": { - "type": "string", - "description": "Branch automatically checked out", - "default": "", - "hidden": { - "value": "", - "path": "git/repository" - } - } - } - }, - "vault": { - "description": "Configuration of vault client", - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "description": "Add vault temporary identity inside your environment", - "default": true - }, - "token": { - "description": "token vault", - "type": "string", - "render": "password", - "x-onyxia": { - "overwriteDefaultWith": "{{vault.VAULT_TOKEN}}" - }, - "hidden": { - "value": false, - "path": "vault/enabled" - } - }, - "url": { - "description": "url of vault server", - "type": "string", - "x-onyxia": { - "overwriteDefaultWith": "{{vault.VAULT_ADDR}}" - }, - "hidden": { - "value": false, - "path": "vault/enabled" - } - }, - "mount": { - "description": "mount of the v2 secret engine", - "type": "string", - "x-onyxia": { - "overwriteDefaultWith": "{{vault.VAULT_MOUNT}}" - }, - "hidden": { - "value": false, - "path": "vault/enabled" - } - }, - "directory": { - "description": "top level directory", - "type": "string", - "x-onyxia": { - "overwriteDefaultWith": "{{vault.VAULT_TOP_DIR}}" - }, - "hidden": { - "value": false, - "path": "vault/enabled" - } - }, - "secret": { - "description": "the path of the secret to convert into a list of environment variables", - "type": "string", - "default": "", - "hidden": { - "value": false, - "path": "vault/enabled" - } - } - } - }, - "s3": { - "description": "Configuration of temporary identity", - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "description": "Add S3 temporary identity inside your environment", - "default": true - }, - "accessKeyId": { - "description": "AWS Access Key", - "type": "string", - "x-onyxia": { - "overwriteDefaultWith": "s3.AWS_ACCESS_KEY_ID" - }, - "hidden": { - "value": false, - "path": "s3/enabled" - } - }, - "endpoint": { - "description": "AWS S3 Endpoint", - "type": "string", - "x-onyxia": { - "overwriteDefaultWith": "{{s3.AWS_S3_ENDPOINT}}" - }, - "hidden": { - "value": false, - "path": "s3/enabled" - } - }, - "defaultRegion": { - "description": "AWS S3 default region", - "type": "string", - "x-onyxia": { - "overwriteDefaultWith": "{{s3.AWS_DEFAULT_REGION}}" - }, - "hidden": { - "value": false, - "path": "s3/enabled" - } - }, - "secretAccessKey": { - "description": "AWS S3 secret access key", - "type": "string", - "render": "password", - "x-onyxia": { - "overwriteDefaultWith": "{{s3.AWS_SECRET_ACCESS_KEY}}" - }, - "hidden": { - "value": false, - "path": "s3/enabled" - } - }, - "sessionToken": { - "description": "AWS S3 session Token", - "type": "string", - "render": "password", - "x-onyxia": { - "overwriteDefaultWith": "{{s3.AWS_SESSION_TOKEN}}" - }, - "hidden": { - "value": false, - "path": "s3/enabled" - } + "title": "Database Port" } } }, @@ -663,200 +169,130 @@ } } }, - "route": { + "service": { "type": "object", "form": true, - "title": "Route details", + "title": "Service Configuration", "properties": { - "enabled": { - "description": "Enable route", - "type": "boolean", - "default": false, - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "k8s.route" - } - }, - "hostname": { + "type": { "type": "string", "form": true, - "title": "Hostname", - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-0.{{k8s.domain}}" - } - }, - "userHostname": { - "type": "string", - "form": true, - "title": "Hostname", - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "{{project.id}}-{{k8s.randomSubdomain}}-user.{{k8s.domain}}" - } + "title": "Service Type", + "description": "Allowed values: \"ClusterIP\", \"NodePort\" and \"LoadBalancer\"" } } }, - "networking": { + "resources": { + "description": "Your service will have at least the requested resources and never more than its limits. No limit for a resource and you can consume everything left on the host machine.", "type": "object", - "form": true, - "title": "Networking detail", "properties": { - "user": { + "requests": { + "description": "Guaranteed resources", "type": "object", - "description": "user defined port", "properties": { - "enabled": { - "type": "boolean", - "title": "Enable a custom service port", - "description": "Enable a custom service port", - "default": false + "cpu": { + "description": "The amount of cpu guaranteed", + "title": "CPU", + "type": "string", + "default": "100m", + "render": "slider", + "sliderMin": 50, + "sliderMax": 40000, + "sliderStep": 50, + "sliderUnit": "m", + "sliderExtremity": "down", + "sliderExtremitySemantic": "guaranteed", + "sliderRangeId": "cpu", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.cpuRequest", + "useRegionSliderConfig": "cpu" + } }, - "port": { - "type": "integer", - "description": "port of the custom service", - "title": "Custom service port", - "hidden": { - "value": false, - "path": "networking/user/enabled" - }, - "default": 5000 + "memory": { + "description": "The amount of memory guaranteed", + "title": "memory", + "type": "string", + "default": "2Gi", + "render": "slider", + "sliderMin": 1, + "sliderMax": 200, + "sliderStep": 1, + "sliderUnit": "Gi", + "sliderExtremity": "down", + "sliderExtremitySemantic": "guaranteed", + "sliderRangeId": "memory", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.memoryRequest", + "useRegionSliderConfig": "memory" + } + } + } + }, + "limits": { + "description": "max resources", + "type": "object", + "properties": { + "cpu": { + "description": "The maximum amount of cpu", + "title": "CPU", + "type": "string", + "default": "30000m", + "render": "slider", + "sliderMin": 50, + "sliderMax": 40000, + "sliderStep": 50, + "sliderUnit": "m", + "sliderExtremity": "up", + "sliderExtremitySemantic": "Maximum", + "sliderRangeId": "cpu", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.cpuLimit", + "useRegionSliderConfig": "cpu" + } + }, + "memory": { + "description": "The maximum amount of memory", + "title": "Memory", + "type": "string", + "default": "50Gi", + "render": "slider", + "sliderMin": 1, + "sliderMax": 200, + "sliderStep": 1, + "sliderUnit": "Gi", + "sliderExtremity": "up", + "sliderExtremitySemantic": "Maximum", + "sliderRangeId": "memory", + "x-onyxia": { + "overwriteDefaultWith": "region.resources.memoryLimit", + "useRegionSliderConfig": "memory" + } } } } } }, - "init": { - "description": "Init parameters", + "volumePermissions": { "type": "object", "properties": { - "regionInit": { - "type": "string", - "description": "region initialization script", - "default": "", - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "{{k8s.initScriptUrl}}" - } - }, - "regionInitCheckSum": { - "type": "string", - "description": "region initialization script", - "default": "", - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "{{k8s.initScriptCheckSum}}" - } - }, - "personalInit": { - "type": "string", - "description": "user initialization script", - "default": "" - }, - "personalInitArgs": { - "type": "string", - "description": "args for user initialization script", - "default": "" - } - } - }, - "repository": { - "description": "python repositories for pip and conda", - "type": "object", - "properties": { - "pipRepository": { - "type": "string", - "description": "python repository for pip", - "default": "", - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "{{packageRepositoryInjection.pypiProxyUrl}}" - } - }, - "condaRepository": { - "type": "string", - "description": "python repository for pip", - "default": "", - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "{{packageRepositoryInjection.condaProxyUrl}}" - } - } - } - }, - "startupProbe": { - "type": "object", - "description": "Start up probe", - "default": {}, - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "region.startupProbe" - } - }, - "tolerations": { - "type": "array", - "description": "Array of tolerations", - "default": [], - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "region.tolerations" - } - }, - "nodeSelector": { - "type": "object", - "description": "NodeSelector", - "default": {}, - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "region.nodeSelector" - } - }, - "userPreferences": { - "description": "User Preferences", - "type": "object", - "properties": { - "darkMode": { + "enabled": { "type": "boolean", - "description": "dark mode is or is not enabled", - "default": false, - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "user.darkMode" - } - }, - "language": { - "type": "string", - "description": "Preferred language", - "default": "en", - "x-onyxia": { - "hidden": true, - "overwriteDefaultWith": "user.lang" - } + "form": true, + "title": "Enable Init Containers", + "description": "Use an init container to set required folder permissions on the data volume before mounting it in the final destination" } } }, - "global": { - "description": "Suspend", + "metrics": { "type": "object", "properties": { - "suspend": { + "enabled": { "type": "boolean", - "description": "Suspend this service", - "default": false, - "x-onyxia": { - "hidden": true - } + "title": "Enable Metrics", + "description": "Prometheus Exporter / Metrics", + "form": true } } } } -} - - - - - - - - - +}