Commit 33a050fa by Jainish Shah Committed by Guangbo

Updating artifactory-ha chart to v0.7.0 (#61)

parent cc069322
# JFrog Artifactory-ha Chart Changelog # JFrog Artifactory-ha Chart Changelog
All notable changes to this chart will be documented in this file. All changes to this chart will be documented in this file.
## [0.7.0] - Oct 28, 2018
* Update postgresql chart to version 0.9.5 to be able and use `postgresConfig` options
## [0.6.9] - Oct 23, 2018
* Fix providing external secret for database credentials
## [0.6.8] - Oct 22, 2018
* Allow user to configure externalTrafficPolicy for Loadbalancer
## [0.6.7] - Oct 22, 2018
* Updated ingress annotation support (with examples) to support docker registry v2
## [0.6.6] - Oct 21, 2018
* Updated Artifactory version to 6.5.2
## [0.6.5] - Oct 19, 2018
* Allow providing pre-existing secret containing master key
* Allow arbitrary annotations on primary and member node pods
* Enforce size limits when using local storage with `emptyDir`
* Allow `soft` or `hard` specification of member node anti-affinity
* Allow providing pre-existing secrets containing external database credentials
* Fix `s3` binary store provider to properly use the `cache-fs` provider
* Allow arbitrary properties when using the `s3` binary store provider
## [0.6.4] - Oct 18, 2018
* Updated Artifactory version to 6.5.1
## [0.6.3] - Oct 17, 2018
* Add Apache 2.0 license
## [0.6.2] - Oct 14, 2018
* Make S3 endpoint configurable (was hardcoded with `s3.amazonaws.com`)
## [0.6.1] - Oct 11, 2018
* Allows ingress default `backend` to be enabled or disabled (defaults to enabled)
## [0.6.0] - Oct 11, 2018
* Updated Artifactory version to 6.5.0
## [0.5.3] - Oct 9, 2018
* Quote ingress hosts to support wildcard names
## [0.5.2] - Oct 2, 2018
* Add `helm repo add jfrog https://charts.jfrog.io` to README
## [0.5.1] - Oct 2, 2018
* Set Artifactory to 6.4.1
## [0.5.0] - Sep 27, 2018
* Set Artifactory to 6.4.0
## [0.4.7] - Sep 26, 2018
* Add ci/test-values.yaml
## [0.4.6] - Sep 25, 2018
* Add PodDisruptionBudget for member nodes, defaulting to minAvailable of 1
## [0.4.4] - Sep 2, 2018 ## [0.4.4] - Sep 2, 2018
* Updated Artifactory version to 6.3.2 * Updated Artifactory version to 6.3.2
......
apiVersion: v1 apiVersion: v1
name: artifactory-ha name: artifactory-ha
home: https://www.jfrog.com/artifactory/ home: https://www.jfrog.com/artifactory/
version: 0.4.4 version: 0.7.0
appVersion: 6.3.2 appVersion: 6.5.2
description: Universal Repository Manager supporting all major packaging formats, description: Universal Repository Manager supporting all major packaging formats,
build tools and CI servers. build tools and CI servers.
keywords: keywords:
- artifactory - artifactory
- jfrog - jfrog
- devops
sources: sources:
- https://bintray.com/jfrog/product/JFrog-Artifactory-Pro/view - https://bintray.com/jfrog/product/JFrog-Artifactory-Pro/view
- https://github.com/jfrog/charts - https://github.com/jfrog/charts
......
...@@ -22,7 +22,7 @@ questions: ...@@ -22,7 +22,7 @@ questions:
type: string type: string
label: Artifactory Image Name label: Artifactory Image Name
- variable: artifactory.image.version - variable: artifactory.image.version
default: "6.3.2" default: "6.5.2"
description: "Artifactory image tag" description: "Artifactory image tag"
type: string type: string
label: Artifactory Image Tag label: Artifactory Image Tag
...@@ -32,7 +32,7 @@ questions: ...@@ -32,7 +32,7 @@ questions:
type: string type: string
label: Nginx Image Name label: Nginx Image Name
- variable: nginx.image.version - variable: nginx.image.version
default: "6.3.2" default: "6.5.2"
description: "Nginx image tag" description: "Nginx image tag"
type: string type: string
label: Nginx Image Tag label: Nginx Image Tag
...@@ -213,6 +213,13 @@ questions: ...@@ -213,6 +213,13 @@ questions:
label: Config Nginx LoadBalancer IP label: Config Nginx LoadBalancer IP
show_if: "nginx.enabled=true&&nginx.service.type=LoadBalancer&&ingress.enabled=false" show_if: "nginx.enabled=true&&nginx.service.type=LoadBalancer&&ingress.enabled=false"
group: "Services and Load Balancing" group: "Services and Load Balancing"
- variable: nginx.tlsSecretName
default: ""
description: "Provide SSL Secret name to configure with Nginx"
type: string
label: Config Nginx SSL Secret
show_if: "nginx.enabled=true&&ingress.enabled=false"
group: "Services and Load Balancing"
- variable: nginx.persistence.enabled - variable: nginx.persistence.enabled
default: false default: false
description: "enable persistence storage for nginx server" description: "enable persistence storage for nginx server"
......
dependencies: dependencies:
- name: postgresql - name: postgresql
repository: https://kubernetes-charts.storage.googleapis.com/ repository: https://kubernetes-charts.storage.googleapis.com/
version: 0.8.7 version: 0.9.5
digest: sha256:02e9e88b9a147c956d857fb8874f16257b90fc980522b329f3257979811af7f7 digest: sha256:7e07fb616d953e518e3373e2c5183290b4b6e94292a233528c0d52ffd42afc77
generated: 2018-01-17T15:55:26.174758+02:00 generated: 2018-10-28T06:26:39.466565306+02:00
dependencies: dependencies:
- name: postgresql - name: postgresql
version: 0.8.7 version: 0.9.5
repository: https://kubernetes-charts.storage.googleapis.com/ repository: https://kubernetes-charts.storage.googleapis.com/
condition: postgresql.enabled condition: postgresql.enabled
Congratulations. You have just deployed JFrog Artifactory HA! Congratulations. You have just deployed JFrog Artifactory HA!
{{- if eq .Values.artifactory.masterKey "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" }} {{- if (not .Values.artifactory.masterKeySecretName) and eq .Values.artifactory.masterKey "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" }}
***************************************** WARNING ****************************************** ***************************************** WARNING ******************************************
...@@ -12,6 +12,9 @@ Congratulations. You have just deployed JFrog Artifactory HA! ...@@ -12,6 +12,9 @@ Congratulations. You have just deployed JFrog Artifactory HA!
* $ echo ${MASTER_KEY} * * $ echo ${MASTER_KEY} *
* * * *
* Pass the created master key to helm with '--set artifactory.masterKey=${MASTER_KEY}' * * Pass the created master key to helm with '--set artifactory.masterKey=${MASTER_KEY}' *
* *
* Alternatively, you can use a pre-existing secret with a key called master-key with *
* '--set artifactory.masterKeySecretName=${SECRET_NAME}' *
******************************************************************************************** ********************************************************************************************
{{- end }} {{- end }}
......
...@@ -65,7 +65,7 @@ data: ...@@ -65,7 +65,7 @@ data:
<!-- Set max cache-fs size --> <!-- Set max cache-fs size -->
<provider id="cache-fs" type="cache-fs"> <provider id="cache-fs" type="cache-fs">
<maxCacheSize>50000000000</maxCacheSize> <maxCacheSize>{{ .Values.artifactory.persistence.maxCacheSize }}</maxCacheSize>
</provider> </provider>
<provider id="eventual-cluster" type="eventual-cluster"> <provider id="eventual-cluster" type="eventual-cluster">
...@@ -98,25 +98,22 @@ data: ...@@ -98,25 +98,22 @@ data:
{{- if eq .Values.artifactory.persistence.type "aws-s3" }} {{- if eq .Values.artifactory.persistence.type "aws-s3" }}
<!-- AWS S3 --> <!-- AWS S3 -->
<config version="2"> <config version="2">
<chain> <chain> <!--template="cluster-s3"-->
<provider id="cache-fs" type="cache-fs">
<provider id="sharding-cluster" type="sharding-cluster"> <provider id="sharding-cluster" type="sharding-cluster">
<readBehavior>crossNetworkStrategy</readBehavior>
<writeBehavior>crossNetworkStrategy</writeBehavior>
<redundancy>{{ .Values.artifactory.persistence.redundancy }}</redundancy>
<minSpareUploaderExecutor>2</minSpareUploaderExecutor>
<sub-provider id="eventual-cluster" type="eventual-cluster"> <sub-provider id="eventual-cluster" type="eventual-cluster">
<provider id="retry" type="retry"> <provider id="retry-s3" type="retry">
<provider id="s3" type="s3"/> <provider id="s3" type="s3"/>
</provider> </provider>
</sub-provider> </sub-provider>
<dynamic-provider id="remote" type="remote"/> <dynamic-provider id="remote" type="remote"/>
<property name="zones" value="local,remote"/> </provider>
</provider> </provider>
</chain> </chain>
<!-- Set max cache-fs size --> <!-- Set max cache-fs size -->
<provider id="cache-fs" type="cache-fs"> <provider id="cache-fs" type="cache-fs">
<maxCacheSize>50000000000</maxCacheSize> <maxCacheSize>{{ .Values.artifactory.persistence.maxCacheSize }}</maxCacheSize>
</provider> </provider>
<provider id="eventual-cluster" type="eventual-cluster"> <provider id="eventual-cluster" type="eventual-cluster">
...@@ -129,21 +126,26 @@ data: ...@@ -129,21 +126,26 @@ data:
<zone>remote</zone> <zone>remote</zone>
</provider> </provider>
<provider id="file-system" type="file-system"> <provider id="sharding-cluster" type="sharding-cluster">
<fileStoreDir>{{ .Values.artifactory.persistence.mountPath }}/data/filestore</fileStoreDir> <readBehavior>crossNetworkStrategy</readBehavior>
<tempDir>/tmp</tempDir> <writeBehavior>crossNetworkStrategy</writeBehavior>
<redundancy>{{ .Values.artifactory.persistence.redundancy }}</redundancy>
<property name="zones" value="local,remote"/>
</provider> </provider>
<provider id="s3" type="s3"> <provider id="s3" type="s3">
<endpoint>s3.amazonaws.com</endpoint> <endpoint>{{ .Values.artifactory.persistence.awsS3.endpoint }}</endpoint>
<refreshCredentials>true</refreshCredentials> <refreshCredentials>{{ .Values.artifactory.persistence.awsS3.refreshCredentials }}</refreshCredentials>
<testConnection>false</testConnection> <testConnection>{{ .Values.artifactory.persistence.awsS3.testConnection }}</testConnection>
<httpsOnly>true</httpsOnly> <httpsOnly>true</httpsOnly>
<region>{{ .Values.artifactory.persistence.awsS3.region }}</region> <region>{{ .Values.artifactory.persistence.awsS3.region }}</region>
<bucketName>{{ .Values.artifactory.persistence.awsS3.bucketName }}</bucketName> <bucketName>{{ .Values.artifactory.persistence.awsS3.bucketName }}</bucketName>
<identity>{{ .Values.artifactory.persistence.awsS3.identity }}</identity> <identity>{{ .Values.artifactory.persistence.awsS3.identity }}</identity>
<credential>{{ .Values.artifactory.persistence.awsS3.credential }}</credential> <credential>{{ .Values.artifactory.persistence.awsS3.credential }}</credential>
<path>{{ .Values.artifactory.persistence.awsS3.path }}</path> <path>{{ .Values.artifactory.persistence.awsS3.path }}</path>
{{- range $key, $value := .Values.artifactory.persistence.awsS3.properties }}
<property name="{{ $key }}" value="{{ $value }}"/>
{{- end }}
</provider> </provider>
</config> </config>
{{- end }} {{- end }}
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: {{ template "artifactory-ha.fullname" . }}-node
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
component: {{ .Values.artifactory.name }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
selector:
matchLabels:
app: {{ template "artifactory-ha.name" . }}
role: {{ template "artifactory-ha.node.name" . }}
release: {{ .Release.Name }}
minAvailable: {{ .Values.artifactory.node.minAvailable }}
...@@ -25,6 +25,11 @@ spec: ...@@ -25,6 +25,11 @@ spec:
role: {{ template "artifactory-ha.node.name" . }} role: {{ template "artifactory-ha.node.name" . }}
component: {{ .Values.artifactory.name }} component: {{ .Values.artifactory.name }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
annotations:
checksum/binarystore: {{ include (print $.Template.BasePath "/artifactory-binarystore.yaml") . | sha256sum }}
{{- range $key, $value := .Values.artifactory.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec: spec:
serviceAccountName: {{ template "artifactory-ha.serviceAccountName" . }} serviceAccountName: {{ template "artifactory-ha.serviceAccountName" . }}
{{- if .Values.imagePullSecrets }} {{- if .Values.imagePullSecrets }}
...@@ -108,6 +113,18 @@ spec: ...@@ -108,6 +113,18 @@ spec:
value: '{{ .Values.database.host }}' value: '{{ .Values.database.host }}'
- name: DB_PORT - name: DB_PORT
value: '{{ .Values.database.port }}' value: '{{ .Values.database.port }}'
{{- if .Values.database.secrets }}
- name: DB_USER
valueFrom:
secretKeyRef:
name: {{ .Values.database.secrets.user.name }}
key: {{ .Values.database.secrets.user.key }}
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.database.secrets.password.name }}
key: {{ .Values.database.secrets.password.key }}
{{- else }}
- name: DB_USER - name: DB_USER
value: '{{ .Values.database.user }}' value: '{{ .Values.database.user }}'
- name: DB_PASSWORD - name: DB_PASSWORD
...@@ -116,6 +133,7 @@ spec: ...@@ -116,6 +133,7 @@ spec:
name: {{ template "artifactory-ha.fullname" . }} name: {{ template "artifactory-ha.fullname" . }}
key: db-password key: db-password
{{- end }} {{- end }}
{{- end }}
- name: EXTRA_JAVA_OPTIONS - name: EXTRA_JAVA_OPTIONS
value: " value: "
{{- if .Values.artifactory.javaOpts.other }} {{- if .Values.artifactory.javaOpts.other }}
...@@ -141,7 +159,7 @@ spec: ...@@ -141,7 +159,7 @@ spec:
- name: ARTIFACTORY_MASTER_KEY - name: ARTIFACTORY_MASTER_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "artifactory-ha.fullname" . }} name: "{{ .Values.artifactory.masterKeySecretName | default (include "artifactory-ha.fullname" .) }}"
key: master-key key: master-key
- name: HA_IS_PRIMARY - name: HA_IS_PRIMARY
value: "false" value: "false"
...@@ -210,10 +228,34 @@ spec: ...@@ -210,10 +228,34 @@ spec:
nodeSelector: nodeSelector:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- if .Values.artifactory.node.affinity }}
{{- with .Values.artifactory.node.affinity }} {{- with .Values.artifactory.node.affinity }}
affinity: affinity:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
{{- end }} {{- end }}
{{- else if eq .Values.artifactory.node.podAntiAffinity.type "soft" }}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: {{ .Values.artifactory.node.podAntiAffinity.topologyKey }}
labelSelector:
matchLabels:
app: {{ template "artifactory-ha.name" . }}
release: {{ .Release.Name }}
role: {{ template "artifactory-ha.node.name" . }}
{{- else if eq .Values.artifactory.node.podAntiAffinity.type "hard" }}
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: {{ .Values.artifactory.node.podAntiAffinity.topologyKey }}
labelSelector:
matchLabels:
app: {{ template "artifactory-ha.name" . }}
release: {{ .Release.Name }}
role: {{ template "artifactory-ha.node.name" . }}
{{- end }}
{{- with .Values.artifactory.node.tolerations }} {{- with .Values.artifactory.node.tolerations }}
tolerations: tolerations:
{{ toYaml . | indent 8 }} {{ toYaml . | indent 8 }}
...@@ -240,11 +282,11 @@ spec: ...@@ -240,11 +282,11 @@ spec:
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ template "artifactory-ha.fullname" . }}-backup-pvc claimName: {{ template "artifactory-ha.fullname" . }}-backup-pvc
{{- end }} {{- end }}
{{- if not .Values.artifactory.persistence.enabled }} {{- if .Values.artifactory.persistence.local }}
- name: volume - name: volume
emptyDir: {} emptyDir:
sizeLimit: {{ .Values.artifactory.persistence.size }}
{{- else }} {{- else }}
{{- if .Values.artifactory.persistence.enabled }}
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: volume name: volume
...@@ -267,4 +309,3 @@ spec: ...@@ -267,4 +309,3 @@ spec:
storage: {{ .Values.artifactory.persistence.size }} storage: {{ .Values.artifactory.persistence.size }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }}
...@@ -25,6 +25,11 @@ spec: ...@@ -25,6 +25,11 @@ spec:
role: {{ template "artifactory-ha.primary.name" . }} role: {{ template "artifactory-ha.primary.name" . }}
component: {{ .Values.artifactory.name }} component: {{ .Values.artifactory.name }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
annotations:
checksum/binarystore: {{ include (print $.Template.BasePath "/artifactory-binarystore.yaml") . | sha256sum }}
{{- range $key, $value := .Values.artifactory.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec: spec:
serviceAccountName: {{ template "artifactory-ha.serviceAccountName" . }} serviceAccountName: {{ template "artifactory-ha.serviceAccountName" . }}
{{- if .Values.imagePullSecrets }} {{- if .Values.imagePullSecrets }}
...@@ -111,6 +116,18 @@ spec: ...@@ -111,6 +116,18 @@ spec:
value: '{{ .Values.database.host }}' value: '{{ .Values.database.host }}'
- name: DB_PORT - name: DB_PORT
value: '{{ .Values.database.port }}' value: '{{ .Values.database.port }}'
{{- if .Values.database.secrets }}
- name: DB_USER
valueFrom:
secretKeyRef:
name: {{ .Values.database.secrets.user.name }}
key: {{ .Values.database.secrets.user.key }}
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.database.secrets.password.name }}
key: {{ .Values.database.secrets.password.key }}
{{- else }}
- name: DB_USER - name: DB_USER
value: '{{ .Values.database.user }}' value: '{{ .Values.database.user }}'
- name: DB_PASSWORD - name: DB_PASSWORD
...@@ -119,6 +136,7 @@ spec: ...@@ -119,6 +136,7 @@ spec:
name: {{ template "artifactory-ha.fullname" . }} name: {{ template "artifactory-ha.fullname" . }}
key: db-password key: db-password
{{- end }} {{- end }}
{{- end }}
- name: EXTRA_JAVA_OPTIONS - name: EXTRA_JAVA_OPTIONS
value: " value: "
{{- if .Values.artifactory.javaOpts.other }} {{- if .Values.artifactory.javaOpts.other }}
...@@ -144,7 +162,7 @@ spec: ...@@ -144,7 +162,7 @@ spec:
- name: ARTIFACTORY_MASTER_KEY - name: ARTIFACTORY_MASTER_KEY
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: {{ template "artifactory-ha.fullname" . }} name: "{{ .Values.artifactory.masterKeySecretName | default (include "artifactory-ha.fullname" .) }}"
key: master-key key: master-key
- name: HA_IS_PRIMARY - name: HA_IS_PRIMARY
value: "true" value: "true"
...@@ -269,11 +287,11 @@ spec: ...@@ -269,11 +287,11 @@ spec:
persistentVolumeClaim: persistentVolumeClaim:
claimName: {{ template "artifactory-ha.fullname" . }}-backup-pvc claimName: {{ template "artifactory-ha.fullname" . }}-backup-pvc
{{- end }} {{- end }}
{{- if not .Values.artifactory.persistence.enabled }} {{- if .Values.artifactory.persistence.local }}
- name: volume - name: volume
emptyDir: {} emptyDir:
sizeLimit: {{ .Values.artifactory.persistence.size }}
{{- else }} {{- else }}
{{- if .Values.artifactory.persistence.enabled }}
volumeClaimTemplates: volumeClaimTemplates:
- metadata: - metadata:
name: volume name: volume
...@@ -296,4 +314,3 @@ spec: ...@@ -296,4 +314,3 @@ spec:
storage: {{ .Values.artifactory.persistence.size }} storage: {{ .Values.artifactory.persistence.size }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }}
...@@ -9,7 +9,9 @@ metadata: ...@@ -9,7 +9,9 @@ metadata:
release: {{ .Release.Name }} release: {{ .Release.Name }}
type: Opaque type: Opaque
data: data:
{{- if not .Values.artifactory.masterKeySecretName }}
master-key: {{ .Values.artifactory.masterKey | b64enc | quote }} master-key: {{ .Values.artifactory.masterKey | b64enc | quote }}
{{- end }}
{{- if .Values.database.password }} {{- if .Values.database.password }}
db-password: {{ .Values.database.password | b64enc | quote }} db-password: {{ .Values.database.password | b64enc | quote }}
{{- end }} {{- end }}
...@@ -10,18 +10,23 @@ metadata: ...@@ -10,18 +10,23 @@ metadata:
chart: {{ template "artifactory-ha.chart" . }} chart: {{ template "artifactory-ha.chart" . }}
release: {{ .Release.Name }} release: {{ .Release.Name }}
heritage: {{ .Release.Service }} heritage: {{ .Release.Service }}
{{- if .Values.ingress.annotations }}
annotations: annotations:
{{- range $key, $value := .Values.ingress.annotations }} {{ .Values.ingress.annotations | toYaml | trimSuffix "\n" | indent 4 -}}
{{ $key }}: {{ $value | quote }} {{- end }}
{{- end }}
spec: spec:
{{- if .Values.ingress.defaultBackend.enabled }}
backend:
serviceName: {{ $serviceName }}
servicePort: {{ $servicePort }}
{{- end -}}
{{- if .Values.ingress.hosts }} {{- if .Values.ingress.hosts }}
rules: rules:
{{- range $host := .Values.ingress.hosts }} {{- range $host := .Values.ingress.hosts }}
- host: {{ $host }} - host: {{ $host | quote }}
http: http:
paths: paths:
- path: - path: /
backend: backend:
serviceName: {{ $serviceName }} serviceName: {{ $serviceName }}
servicePort: {{ $servicePort }} servicePort: {{ $servicePort }}
......
...@@ -19,7 +19,9 @@ spec: ...@@ -19,7 +19,9 @@ spec:
{{ if .Values.nginx.service.loadBalancerIP -}} {{ if .Values.nginx.service.loadBalancerIP -}}
loadBalancerIP: {{ .Values.nginx.service.loadBalancerIP }} loadBalancerIP: {{ .Values.nginx.service.loadBalancerIP }}
{{ end -}} {{ end -}}
externalTrafficPolicy: Local {{- if .Values.nginx.service.externalTrafficPolicy }}
externalTrafficPolicy: {{ .Values.nginx.service.externalTrafficPolicy }}
{{- end }}
{{- end }} {{- end }}
{{- if .Values.nginx.service.loadBalancerSourceRanges }} {{- if .Values.nginx.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges: loadBalancerSourceRanges:
......
...@@ -38,6 +38,8 @@ serviceAccount: ...@@ -38,6 +38,8 @@ serviceAccount:
ingress: ingress:
enabled: false enabled: false
defaultBackend:
enabled: true
# Used to create an Ingress record. # Used to create an Ingress record.
hosts: hosts:
# - artifactory.domain.example # - artifactory.domain.example
...@@ -80,8 +82,19 @@ database: ...@@ -80,8 +82,19 @@ database:
type: type:
host: host:
port: port:
## If you would like this chart to create the secret containing the db
## password, use these values
user: user:
password: password:
## If you have existing Kubernetes secrets containing db credentials, use
## these values
secrets: {}
# user:
# name: "rds-artifactory"
# key: "db-user"
# password:
# name: "rds-artifactory"
# key: "db-password"
# Artifactory # Artifactory
artifactory: artifactory:
...@@ -89,14 +102,17 @@ artifactory: ...@@ -89,14 +102,17 @@ artifactory:
image: image:
repository: "docker.bintray.io/jfrog/artifactory-pro" repository: "docker.bintray.io/jfrog/artifactory-pro"
# Note that by default we use appVersion to get image tag # Note that by default we use appVersion to get image tag
# version: 6.3.2 # version:
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
## Artifactory requires a unique master key ## Artifactory requires a unique master key
## You can generate one with the command: ## You can generate one with the command:
## 'openssl rand -hex 32' ## 'openssl rand -hex 32'
## Pass it to helm with '--set artifactory.masterKey=${MASTER_KEY}' ## Pass it to helm with '--set artifactory.masterKey=${MASTER_KEY}'
## Alternatively, you can use a pre-existing secret with a key called master-key by specifying masterKeySecretName
## IMPORTANT: You should NOT use the example masterKey for a production deployment! ## IMPORTANT: You should NOT use the example masterKey for a production deployment!
masterKey: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF masterKey: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
# masterKeySecretName:
## Artifactory license secret. ## Artifactory license secret.
## If artifactory.license.secret is passed, it will be mounted as ## If artifactory.license.secret is passed, it will be mounted as
...@@ -135,11 +151,12 @@ artifactory: ...@@ -135,11 +151,12 @@ artifactory:
successThreshold: 1 successThreshold: 1
persistence: persistence:
enabled: true enabled: true
# local: false local: false
redundancy: 3 redundancy: 3
mountPath: "/var/opt/jfrog/artifactory" mountPath: "/var/opt/jfrog/artifactory"
accessMode: ReadWriteOnce accessMode: ReadWriteOnce
size: 200Gi size: 200Gi
maxCacheSize: 50000000000
## artifactory data Persistent Volume Storage Class ## artifactory data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass> ## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning ## If set to "-", storageClassName: "", which disables dynamic provisioning
...@@ -177,13 +194,20 @@ artifactory: ...@@ -177,13 +194,20 @@ artifactory:
credential: credential:
path: "artifactory-ha/filestore" path: "artifactory-ha/filestore"
## For artifactory.persistence.type aws-s3 ## For artifactory.persistence.type aws-s3
## IMPORTANT: Make sure S3 `endpoint` and `region` match! See https://docs.aws.amazon.com/general/latest/gr/rande.html
awsS3: awsS3:
# Set a unique bucket name # Set a unique bucket name
bucketName: "artifactory-ha-aws" bucketName: "artifactory-ha-aws"
endpoint:
region: region:
identity: identity:
credential: credential:
path: "artifactory-ha/filestore" path: "artifactory-ha/filestore"
refreshCredentials: true
testConnection: false
## Additional properties to set on the s3 provider
properties: {}
# httpclient.max-connections: 100
service: service:
name: artifactory name: artifactory
type: ClusterIP type: ClusterIP
...@@ -204,6 +228,8 @@ artifactory: ...@@ -204,6 +228,8 @@ artifactory:
# Name of ConfigMap for Distribution Cert # Name of ConfigMap for Distribution Cert
distributionCerts: distributionCerts:
annotations: {}
## Type specific configurations. ## Type specific configurations.
## There is a difference between the primary and the member nodes. ## There is a difference between the primary and the member nodes.
## Customising their resources and java parameters is done here. ## Customising their resources and java parameters is done here.
...@@ -239,6 +265,7 @@ artifactory: ...@@ -239,6 +265,7 @@ artifactory:
## If true, you must prepare a PVC with the name e.g `artifactory-ha-member` ## If true, you must prepare a PVC with the name e.g `artifactory-ha-member`
existingClaim: false existingClaim: false
replicaCount: 2 replicaCount: 2
minAvailable: 1
## Resources for the member nodes ## Resources for the member nodes
resources: {} resources: {}
# requests: # requests:
...@@ -257,8 +284,16 @@ artifactory: ...@@ -257,8 +284,16 @@ artifactory:
tolerations: [] tolerations: []
## Complete specification of the "affinity" of the member nodes; if this is non-empty,
## "podAntiAffinity" values are not used.
affinity: {} affinity: {}
## Only used if "affinity" is empty
podAntiAffinity:
## Valid values are "soft" or "hard"; any other value indicates no anti-affinity
type: ""
topologyKey: "kubernetes.io/hostname"
# Nginx # Nginx
nginx: nginx:
enabled: true enabled: true
...@@ -269,7 +304,7 @@ nginx: ...@@ -269,7 +304,7 @@ nginx:
image: image:
repository: "docker.bintray.io/jfrog/nginx-artifactory-pro" repository: "docker.bintray.io/jfrog/nginx-artifactory-pro"
# Note that by default we use appVersion to get image tag # Note that by default we use appVersion to get image tag
# version: 6.3.2 # version:
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
service: service:
## For minikube, set this to NodePort, elsewhere use LoadBalancer ## For minikube, set this to NodePort, elsewhere use LoadBalancer
...@@ -282,6 +317,8 @@ nginx: ...@@ -282,6 +317,8 @@ nginx:
loadBalancerSourceRanges: [] loadBalancerSourceRanges: []
## Provide static ip address ## Provide static ip address
loadBalancerIP: loadBalancerIP:
## There are two available options: “Cluster” (default) and “Local”.
externalTrafficPolicy: Cluster
externalPortHttp: 80 externalPortHttp: 80
internalPortHttp: 80 internalPortHttp: 80
externalPortHttps: 443 externalPortHttps: 443
......
# 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
OWNERS
\ No newline at end of file
# JFrog Artifactory-ha Chart Changelog
All notable changes to this chart will be documented in this file.
## [0.4.4] - Sep 2, 2018
* Updated Artifactory version to 6.3.2
## [0.4.0] - Aug 22, 2018
* Added support to run as non root
* Updated Artifactory version to 6.2.0
## [0.3.0] - Aug 22, 2018
* Enabled RBAC Support
* Added support for PostStartCommand (To download Database JDBC connector)
* Increased postgresql max_connections
* Added support for `nginx.conf` ConfigMap
* Updated Artifactory version to 6.1.0
\ No newline at end of file
apiVersion: v1
name: artifactory-ha
home: https://www.jfrog.com/artifactory/
version: 0.4.4
appVersion: 6.3.2
description: Universal Repository Manager supporting all major packaging formats,
build tools and CI servers.
keywords:
- artifactory
- jfrog
sources:
- https://bintray.com/jfrog/product/JFrog-Artifactory-Pro/view
- https://github.com/jfrog/charts
maintainers:
- name: jainishshah17
email: jainishs@jfrog.com
- name: eldada
email: eldada@jfrog.com
- name: rimusz
email: rimasm@jfrog.com
icon: https://raw.githubusercontent.com/jfrog/artifactory-dcos/master/images/jfrog_med.png
approvers:
- jainishshah17
- eldada
- rimusz
reviewers:
- jainishshah17
- eldada
- rimusz
\ No newline at end of file
dependencies:
- name: postgresql
repository: https://kubernetes-charts.storage.googleapis.com/
version: 0.8.7
digest: sha256:02e9e88b9a147c956d857fb8874f16257b90fc980522b329f3257979811af7f7
generated: 2018-01-17T15:55:26.174758+02:00
dependencies:
- name: postgresql
version: 0.8.7
repository: https://kubernetes-charts.storage.googleapis.com/
condition: postgresql.enabled
Congratulations. You have just deployed JFrog Artifactory HA!
{{- if eq .Values.artifactory.masterKey "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" }}
***************************************** WARNING ******************************************
* Your Artifactory master key is still set to the provided example: *
* artifactory.masterKey=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF *
* *
* You should change this to your own generated key: *
* $ export MASTER_KEY=$(openssl rand -hex 32) *
* $ echo ${MASTER_KEY} *
* *
* Pass the created master key to helm with '--set artifactory.masterKey=${MASTER_KEY}' *
********************************************************************************************
{{- end }}
{{- if .Values.postgresql.enabled }}
DATABASE:
To extract the database password, run the following
export DB_PASSWORD=$(kubectl get --namespace {{ .Release.Namespace }} $(kubectl get secret --namespace {{ .Release.Namespace }} -o name | grep postgresql) -o jsonpath="{.data.postgres-password}" | base64 --decode)
echo ${DB_PASSWORD}
{{- end }}
SETUP:
1. Get the Artifactory IP and URL
{{- if contains "NodePort" .Values.nginx.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "artifactory-ha.nginx.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT/
{{- else if contains "LoadBalancer" .Values.nginx.service.type }}
NOTE: It may take a few minutes for the LoadBalancer public IP to be available!
You can watch the status of the service by running 'kubectl get svc -w {{ template "artifactory-ha.nginx.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "artifactory-ha.nginx.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP/
{{- else if contains "ClusterIP" .Values.nginx.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "component={{ .Values.nginx.name }}" -o jsonpath="{.items[0].metadata.name}")
kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME 8080:80
echo http://127.0.0.1:8080
{{- end }}
2. Open Artifactory in your browser
Default credential for Artifactory:
user: admin
password: password
{{- if .Values.artifactory.license.secret }}
3. Manage Artifactory license through the {{ .Values.artifactory.license.secret }} secret ONLY!
Since the artifactory license(s) is managed with a secret ({{ .Values.artifactory.license.secret }}), any change through the Artifactory UI might not be saved!
{{- else }}
3. Add HA licenses to activate Artifactory HA through the Artifactory UI
NOTE: Each Artifactory node requires a valid license. See https://www.jfrog.com/confluence/display/RTF/HA+Installation+and+Setup for more details.
{{- end }}
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "artifactory-ha.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
The primary node name
*/}}
{{- define "artifactory-ha.primary.name" -}}
{{- $name := .Release.Name | trunc 29 -}}
{{- printf "%s-%s-primary" $name .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
The member node name
*/}}
{{- define "artifactory-ha.node.name" -}}
{{- $name := .Release.Name | trunc 29 -}}
{{- printf "%s-%s-member" $name .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Expand the name nginx service.
*/}}
{{- define "artifactory-ha.nginx.name" -}}
{{- default .Values.nginx.name .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 "artifactory-ha.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .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 -}}
{{/*
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 "artifactory-ha.nginx.fullname" -}}
{{- if .Values.nginx.fullnameOverride -}}
{{- .Values.nginx.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nginx.name -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "artifactory-ha.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "artifactory-ha.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "artifactory-ha.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
\ No newline at end of file
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ template "artifactory-ha.fullname" . }}-bs
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
binarystore.xml: |-
{{- if eq .Values.artifactory.persistence.type "file-system" }}
<!-- File system replication -->
<config version="2">
<chain>
<provider id="cache-fs" type="cache-fs">
<provider id="sharding-cluster" type="sharding-cluster">
<readBehavior>crossNetworkStrategy</readBehavior>
<writeBehavior>crossNetworkStrategy</writeBehavior>
<redundancy>{{ .Values.artifactory.persistence.redundancy }}</redundancy>
<lenientLimit>2</lenientLimit>
<minSpareUploaderExecutor>2</minSpareUploaderExecutor>
<sub-provider id="state-aware" type="state-aware"/>
<dynamic-provider id="remote" type="remote"/>
<property name="zones" value="local,remote"/>
</provider>
</provider>
</chain>
<!-- Shards add local file-system provider configuration -->
<provider id="state-aware" type="state-aware">
<fileStoreDir>shard-fs-1</fileStoreDir>
<zone>local</zone>
</provider>
<!-- Shards dynamic remote provider configuration -->
<provider id="remote" type="remote">
<checkPeriod>30</checkPeriod>
<serviceId>tester-remote1</serviceId>
<timeout>10000</timeout>
<zone>remote</zone>
<property name="header.remote.block" value="true"/>
</provider>
</config>
{{- end }}
{{- if eq .Values.artifactory.persistence.type "google-storage" }}
<!-- Google storage -->
<config version="2">
<chain>
<provider id="sharding-cluster" type="sharding-cluster">
<readBehavior>crossNetworkStrategy</readBehavior>
<writeBehavior>crossNetworkStrategy</writeBehavior>
<redundancy>{{ .Values.artifactory.persistence.redundancy }}</redundancy>
<minSpareUploaderExecutor>2</minSpareUploaderExecutor>
<sub-provider id="eventual-cluster" type="eventual-cluster">
<provider id="retry" type="retry">
<provider id="google-storage" type="google-storage"/>
</provider>
</sub-provider>
<dynamic-provider id="remote" type="remote"/>
<property name="zones" value="local,remote"/>
</provider>
</chain>
<!-- Set max cache-fs size -->
<provider id="cache-fs" type="cache-fs">
<maxCacheSize>50000000000</maxCacheSize>
</provider>
<provider id="eventual-cluster" type="eventual-cluster">
<zone>local</zone>
</provider>
<provider id="remote" type="remote">
<checkPeriod>30</checkPeriod>
<timeout>10000</timeout>
<zone>remote</zone>
</provider>
<provider id="file-system" type="file-system">
<fileStoreDir>{{ .Values.artifactory.persistence.mountPath }}/data/filestore</fileStoreDir>
<tempDir>/tmp</tempDir>
</provider>
<provider id="google-storage" type="google-storage">
<providerId>google-cloud-storage</providerId>
<endpoint>commondatastorage.googleapis.com</endpoint>
<httpsOnly>false</httpsOnly>
<bucketName>{{ .Values.artifactory.persistence.googleStorage.bucketName }}</bucketName>
<identity>{{ .Values.artifactory.persistence.googleStorage.identity }}</identity>
<credential>{{ .Values.artifactory.persistence.googleStorage.credential }}</credential>
<path>{{ .Values.artifactory.persistence.googleStorage.path }}</path>
</provider>
</config>
{{- end }}
{{- if eq .Values.artifactory.persistence.type "aws-s3" }}
<!-- AWS S3 -->
<config version="2">
<chain>
<provider id="sharding-cluster" type="sharding-cluster">
<readBehavior>crossNetworkStrategy</readBehavior>
<writeBehavior>crossNetworkStrategy</writeBehavior>
<redundancy>{{ .Values.artifactory.persistence.redundancy }}</redundancy>
<minSpareUploaderExecutor>2</minSpareUploaderExecutor>
<sub-provider id="eventual-cluster" type="eventual-cluster">
<provider id="retry" type="retry">
<provider id="s3" type="s3"/>
</provider>
</sub-provider>
<dynamic-provider id="remote" type="remote"/>
<property name="zones" value="local,remote"/>
</provider>
</chain>
<!-- Set max cache-fs size -->
<provider id="cache-fs" type="cache-fs">
<maxCacheSize>50000000000</maxCacheSize>
</provider>
<provider id="eventual-cluster" type="eventual-cluster">
<zone>local</zone>
</provider>
<provider id="remote" type="remote">
<checkPeriod>30</checkPeriod>
<timeout>10000</timeout>
<zone>remote</zone>
</provider>
<provider id="file-system" type="file-system">
<fileStoreDir>{{ .Values.artifactory.persistence.mountPath }}/data/filestore</fileStoreDir>
<tempDir>/tmp</tempDir>
</provider>
<provider id="s3" type="s3">
<endpoint>s3.amazonaws.com</endpoint>
<refreshCredentials>true</refreshCredentials>
<testConnection>false</testConnection>
<httpsOnly>true</httpsOnly>
<region>{{ .Values.artifactory.persistence.awsS3.region }}</region>
<bucketName>{{ .Values.artifactory.persistence.awsS3.bucketName }}</bucketName>
<identity>{{ .Values.artifactory.persistence.awsS3.identity }}</identity>
<credential>{{ .Values.artifactory.persistence.awsS3.credential }}</credential>
<path>{{ .Values.artifactory.persistence.awsS3.path }}</path>
</provider>
</config>
{{- end }}
{{- if eq .Values.artifactory.persistence.type "nfs" }}
### Artifactory HA data
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ template "artifactory-ha.fullname" . }}-data-pv
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
id: {{ template "artifactory-ha.name" . }}-data-pv
type: nfs-volume
spec:
capacity:
storage: {{ .Values.artifactory.persistence.nfs.capacity }}
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
server: {{ .Values.artifactory.persistence.nfs.ip }}
path: "{{ .Values.artifactory.persistence.nfs.haDataMount }}"
readOnly: false
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "artifactory-ha.fullname" . }}-data-pvc
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: nfs-volume
spec:
accessModes:
- ReadWriteOnce
storageClassName: ""
resources:
requests:
storage: {{ .Values.artifactory.persistence.nfs.capacity }}
selector:
matchLabels:
id: {{ template "artifactory-ha.name" . }}-data-pv
app: {{ template "artifactory-ha.name" . }}
release: {{ .Release.Name }}
---
### Artifactory HA backup
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ template "artifactory-ha.fullname" . }}-backup-pv
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
id: {{ template "artifactory-ha.name" . }}-backup-pv
type: nfs-volume
spec:
capacity:
storage: {{ .Values.artifactory.persistence.nfs.capacity }}
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
server: {{ .Values.artifactory.persistence.nfs.ip }}
path: "{{ .Values.artifactory.persistence.nfs.haBackupMount }}"
readOnly: false
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "artifactory-ha.fullname" . }}-backup-pvc
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: nfs-volume
spec:
accessModes:
- ReadWriteOnce
storageClassName: ""
resources:
requests:
storage: {{ .Values.artifactory.persistence.nfs.capacity }}
selector:
matchLabels:
id: {{ template "artifactory-ha.name" . }}-backup-pv
app: {{ template "artifactory-ha.name" . }}
release: {{ .Release.Name }}
{{- end }}
\ No newline at end of file
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ template "artifactory-ha.fullname" . }}-isc
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
inactiveServerCleaner.groovy: |-
import org.artifactory.state.ArtifactoryServerState
import org.artifactory.storage.db.servers.service.ArtifactoryServersCommonService
import org.artifactory.common.ConstantValues
import org.slf4j.Logger
import java.util.concurrent.TimeUnit
jobs {
clean(interval: 90000, delay: 900000) {
runCleanupHAInactiveServers()
}
}
executions {
cleanHAInactiveServers() { params ->
runCleanupHAInactiveServers()
}
}
def runCleanupHAInactiveServers() {
def artifactoryServersCommonService = ctx.beanForType(ArtifactoryServersCommonService)
def artifactoryInactiveServerCleaner = new ArtifactoryInactiveServersCleaner(artifactoryServersCommonService, log)
artifactoryInactiveServerCleaner.cleanInactiveArtifactoryServers()
}
public class ArtifactoryInactiveServersCleaner {
private ArtifactoryServersCommonService artifactoryServersCommonService
private Logger log
ArtifactoryInactiveServersCleaner(ArtifactoryServersCommonService artifactoryServersCommonService, Logger log) {
this.artifactoryServersCommonService = artifactoryServersCommonService
this.log = log
}
def cleanInactiveArtifactoryServers() {
log.info "Executing inactive artifactory servers cleaner plugin"
List<String> allMembers = artifactoryServersCommonService.getAllArtifactoryServers()
for (member in allMembers) {
def heartbeat = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - member.getLastHeartbeat())
def noHeartbeat = heartbeat > ConstantValues.haHeartbeatStaleIntervalSecs.getInt()
if (member.getServerState() == ArtifactoryServerState.UNAVAILABLE || ( noHeartbeat && member.getServerState() != ArtifactoryServerState.CONVERTING && member.getServerState() != ArtifactoryServerState.STARTING )) {
try {
log.info "Inactive artifactory servers cleaning task found server ${member.serverId} to remove"
artifactoryServersCommonService.removeServer(member.serverId)
}catch (Exception e){
log.error "Error: Not able to remove ${member.serverId}, ${e.message}"
}
}
}
log.info "No inactive servers found"
}
}
\ No newline at end of file
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
component: {{ .Values.artifactory.name }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "artifactory-ha.fullname" . }}
rules:
{{ toYaml .Values.rbac.role.rules }}
{{- end }}
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
component: {{ .Values.artifactory.name }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "artifactory-ha.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ template "artifactory-ha.serviceAccountName" . }}
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: {{ template "artifactory-ha.fullname" . }}
{{- end }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "artifactory-ha.fullname" . }}
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: Opaque
data:
master-key: {{ .Values.artifactory.masterKey | b64enc | quote }}
{{- if .Values.database.password }}
db-password: {{ .Values.database.password | b64enc | quote }}
{{- end }}
# Service for all Artifactory cluster nodes.
apiVersion: v1
kind: Service
metadata:
name: {{ template "artifactory-ha.fullname" . }}
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
component: {{ .Values.artifactory.name }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
type: {{ .Values.artifactory.service.type }}
ports:
- port: {{ .Values.artifactory.externalPort }}
targetPort: {{ .Values.artifactory.internalPort }}
protocol: TCP
name: http
selector:
{{- if eq .Values.artifactory.service.pool "members" }}
role: {{ template "artifactory-ha.node.name" . }}
{{- end }}
app: {{ template "artifactory-ha.name" . }}
component: "{{ .Values.artifactory.name }}"
release: {{ .Release.Name }}
---
# Internal service for Artifactory primary node only!
# Used by member nodes to check readiness of primary node before starting up
apiVersion: v1
kind: Service
metadata:
name: {{ template "artifactory-ha.primary.name" . }}
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
component: {{ .Values.artifactory.name }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
spec:
type: {{ .Values.artifactory.service.type }}
ports:
- port: {{ .Values.artifactory.externalPort }}
targetPort: {{ .Values.artifactory.internalPort }}
protocol: TCP
name: http
{{- if .Values.artifactory.replicator.enabled }}
- port: {{ .Values.artifactory.externalPortReplicator }}
targetPort: {{ .Values.artifactory.internalPortReplicator }}
protocol: TCP
name: replicator
{{- end}}
selector:
role: {{ template "artifactory-ha.primary.name" . }}
app: {{ template "artifactory-ha.name" . }}
component: "{{ .Values.artifactory.name }}"
release: {{ .Release.Name }}
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
component: {{ .Values.artifactory.name }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "artifactory-ha.serviceAccountName" . }}
{{- end }}
{{- if .Values.ingress.enabled -}}
{{- $serviceName := include "artifactory-ha.fullname" . -}}
{{- $servicePort := .Values.artifactory.externalPort -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ template "artifactory-ha.fullname" . }}
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
annotations:
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- if .Values.ingress.hosts }}
rules:
{{- range $host := .Values.ingress.hosts }}
- host: {{ $host }}
http:
paths:
- path:
backend:
serviceName: {{ $serviceName }}
servicePort: {{ $servicePort }}
{{- end -}}
{{- end -}}
{{- if .Values.ingress.tls }}
tls:
{{ toYaml .Values.ingress.tls | indent 4 }}
{{- end -}}
{{- end -}}
{{- if .Values.nginx.enabled -}}
{{- $serviceName := include "artifactory-ha.fullname" . -}}
{{- $servicePort := .Values.artifactory.externalPort -}}
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ template "artifactory-ha.nginx.fullname" . }}
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: {{ .Values.nginx.name }}
spec:
replicas: {{ .Values.nginx.replicaCount }}
selector:
matchLabels:
app: {{ template "artifactory-ha.name" . }}
release: {{ .Release.Name }}
component: {{ .Values.nginx.name }}
template:
metadata:
labels:
app: {{ template "artifactory-ha.name" . }}
component: {{ .Values.nginx.name }}
release: {{ .Release.Name }}
spec:
serviceAccountName: {{ template "artifactory-ha.serviceAccountName" . }}
{{- if .Values.imagePullSecrets }}
imagePullSecrets:
- name: {{ .Values.imagePullSecrets }}
{{- end }}
initContainers:
{{- if .Values.nginx.persistence.enabled }}
- name: "remove-lost-found"
image: "{{ .Values.initContainerImage }}"
imagePullPolicy: {{ .Values.nginx.image.pullPolicy }}
command:
- '/bin/sh'
- '-c'
- 'rm -rfv {{ .Values.nginx.persistence.mountPath }}/lost+found'
volumeMounts:
- mountPath: {{ .Values.nginx.persistence.mountPath | quote }}
name: nginx-volume
{{- end }}
- name: "wait-for-artifactory"
image: "{{ .Values.initContainerImage }}"
command:
- 'sh'
- '-c'
- >
until nc -z -w 2 {{ $serviceName }} {{ $servicePort }} && echo artifactory ok; do
sleep 2;
done;
securityContext:
runAsUser: {{ .Values.nginx.uid }}
fsGroup: {{ .Values.nginx.gid }}
containers:
- name: {{ .Values.nginx.name }}
image: '{{ .Values.nginx.image.repository }}:{{ default .Chart.AppVersion .Values.nginx.image.version }}'
imagePullPolicy: {{ .Values.nginx.image.pullPolicy }}
lifecycle:
postStart:
exec:
command:
- '/bin/sh'
- '-c'
- >
{{- if .Values.nginx.customConfigMap }}
cp -Lrf /tmp/nginx.conf /etc/nginx/nginx.conf;
{{- end }}
if [ -f /tmp/replicator-nginx.conf ]; then
cp -fv /tmp/replicator-nginx.conf /etc/nginx/conf.d/replicator-nginx.conf;
fi;
if [ -f /tmp/ssl/*.crt ]; then
rm -rf /var/opt/jfrog/nginx/ssl/example.*;
cp -fv /tmp/ssl/* /var/opt/jfrog/nginx/ssl;
fi;
until [ -f /etc/nginx/conf.d/artifactory.conf ]; do sleep 1; done;
if ! grep -q 'upstream' /etc/nginx/conf.d/artifactory.conf; then
sed -i -e 's,proxy_pass .*,proxy_pass http://{{ $serviceName }}:{{ $servicePort }}/artifactory/;,g' \
-e 's,server_name .*,server_name ~(?<repo>.+)\\.{{ $serviceName }} {{ $serviceName }};,g' \
/etc/nginx/conf.d/artifactory.conf;
fi;
if ! grep -q 'proxy_http_version' /etc/nginx/conf.d/artifactory.conf; then
sed -i 's,\(proxy_next_upstream .*\),proxy_http_version 1.1;\n \1,g' /etc/nginx/conf.d/artifactory.conf;
fi;
sleep 5; nginx -s reload; touch /var/log/nginx/conf.done
env:
- name: ART_BASE_URL
{{- if .Values.nginx.env.artUrl }}
value: {{ .Values.nginx.env.artUrl }}
{{- else }}
value: 'http://{{ $serviceName }}:{{ $servicePort }}/artifactory'
{{- end }}
- name: SSL
value: "{{ .Values.nginx.env.ssl }}"
- name: SKIP_AUTO_UPDATE_CONFIG
value: "{{ .Values.nginx.env.skipAutoConfigUpdate }}"
ports:
- containerPort: {{ .Values.nginx.internalPortHttp }}
- containerPort: {{ .Values.nginx.internalPortHttps }}
{{- if .Values.artifactory.replicator.enabled }}
- containerPort: {{ .Values.nginx.internalPortReplicator }}
{{- end }}
volumeMounts:
- name: nginx-volume
mountPath: {{ .Values.nginx.persistence.mountPath | quote }}
{{- if .Values.artifactory.replicator.enabled }}
- name: replicator-nginx-config
mountPath: "/tmp/replicator-nginx.conf"
subPath: replicator-nginx.conf
{{- end }}
{{- if .Values.nginx.tlsSecretName }}
- name: ssl-secret-volume
mountPath: "/tmp/ssl"
{{- end }}
{{- if .Values.nginx.customConfigMap }}
- name: nginx-config
mountPath: "/tmp/"
{{- end }}
resources:
{{ toYaml .Values.nginx.resources | indent 10 }}
{{- if .Values.nginx.readinessProbe.enabled }}
readinessProbe:
httpGet:
path: '/artifactory/webapp/#/login'
port: 80
initialDelaySeconds: {{ .Values.nginx.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.nginx.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.nginx.readinessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.nginx.readinessProbe.failureThreshold }}
successThreshold: {{ .Values.nginx.readinessProbe.successThreshold }}
{{- end }}
{{- if .Values.nginx.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: '/artifactory/webapp/#/login'
port: 80
initialDelaySeconds: {{ .Values.nginx.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.nginx.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.nginx.livenessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.nginx.livenessProbe.failureThreshold }}
successThreshold: {{ .Values.nginx.livenessProbe.successThreshold }}
{{- 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 }}
volumes:
{{- if .Values.artifactory.replicator.enabled }}
- name: replicator-nginx-config
configMap:
name: {{ template "artifactory-ha.fullname" . }}-replicator-nginx-config
{{- end}}
{{- if .Values.nginx.customConfigMap }}
- name: nginx-config
configMap:
name: {{ .Values.nginx.customConfigMap }}
{{- end }}
- name: nginx-volume
{{- if .Values.nginx.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ .Values.nginx.persistence.existingClaim | default (include "artifactory-ha.nginx.fullname" .) }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- if .Values.nginx.tlsSecretName }}
- name: ssl-secret-volume
secret:
secretName: {{ .Values.nginx.tlsSecretName }}
{{- end }}
{{- end }}
{{- if and .Values.nginx.persistence.enabled (.Values.nginx.enabled ) }}
{{- if (not .Values.nginx.persistence.existingClaim) }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "artifactory-ha.nginx.fullname" . }}
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
accessModes:
- {{ .Values.nginx.persistence.accessMode | quote }}
resources:
requests:
storage: {{ .Values.nginx.persistence.size | quote }}
{{- if .Values.nginx.persistence.storageClass }}
{{- if (eq "-" .Values.nginx.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.nginx.persistence.storageClass }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.artifactory.replicator.enabled -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "artifactory-ha.fullname" . }}-replicator-nginx-config
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
replicator-nginx.conf: |
## Artifactory replicator
server {
listen {{ .Values.nginx.externalPortReplicator }};
server_name {{ include "artifactory-ha.fullname" . }};
client_max_body_size 0;
location / {
proxy_read_timeout 900;
proxy_pass_header Server;
proxy_pass http://{{ include "artifactory-ha.primary.name" . }}:{{ .Values.nginx.internalPortReplicator }};
proxy_http_version 1.1;
}
}
{{- end -}}
\ No newline at end of file
{{- if .Values.nginx.enabled -}}
apiVersion: v1
kind: Service
metadata:
name: {{ template "artifactory-ha.nginx.fullname" . }}
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
component: {{ .Values.nginx.name }}
{{- if .Values.nginx.service.annotations }}
annotations:
{{ toYaml .Values.nginx.service.annotations | indent 4 }}
{{- end }}
spec:
type: {{ .Values.nginx.service.type }}
{{- if eq .Values.nginx.service.type "LoadBalancer" }}
{{ if .Values.nginx.service.loadBalancerIP -}}
loadBalancerIP: {{ .Values.nginx.service.loadBalancerIP }}
{{ end -}}
externalTrafficPolicy: Local
{{- end }}
{{- if .Values.nginx.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{ toYaml .Values.nginx.service.loadBalancerSourceRanges | indent 4 }}
{{- end }}
ports:
{{- if .Values.artifactory.replicator.enabled }}
- port: {{ .Values.nginx.externalPortReplicator }}
targetPort: {{ .Values.nginx.internalPortReplicator }}
protocol: TCP
name: replicator
{{- end }}
- port: {{ .Values.nginx.externalPortHttp }}
targetPort: {{ .Values.nginx.internalPortHttp }}
protocol: TCP
name: http
- port: {{ .Values.nginx.externalPortHttps }}
targetPort: {{ .Values.nginx.internalPortHttps }}
protocol: TCP
name: https
selector:
app: {{ template "artifactory-ha.name" . }}
component: {{ .Values.nginx.name }}
release: {{ .Release.Name }}
{{- end }}
{{- if .Values.artifactory.replicator.enabled -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "artifactory-ha.fullname" . }}-replicator-config
labels:
app: {{ template "artifactory-ha.name" . }}
chart: {{ template "artifactory-ha.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
data:
replicator.yaml: |-
externalUrl: {{ .Values.artifactory.replicator.publicUrl }}
internalUrl: http://localhost:6061
listenPort: 6061
{{- end -}}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment