Skip to content

Commit

Permalink
Merge pull request jfrog#93 from robbie-demuth/artifactory-ha-enhance…
Browse files Browse the repository at this point in the history
…ments

Enhancements to stable/artifactory-ha and stable/artifactory
  • Loading branch information
jainishshah17 authored Oct 21, 2018
2 parents f8b5441 + c5ba6fe commit dda17b8
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 50 deletions.
9 changes: 9 additions & 0 deletions stable/artifactory-ha/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# JFrog Artifactory-ha Chart Changelog
All changes to this chart will be documented in this file.

## [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

Expand Down
2 changes: 1 addition & 1 deletion stable/artifactory-ha/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v1
name: artifactory-ha
home: https://www.jfrog.com/artifactory/
version: 0.6.4
version: 0.6.5
appVersion: 6.5.1
description: Universal Repository Manager supporting all major packaging formats,
build tools and CI servers.
Expand Down
72 changes: 53 additions & 19 deletions stable/artifactory-ha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,20 @@ echo ${MASTER_KEY}
# Pass the created master key to helm
helm install --name artifactory-ha --set artifactory.masterKey=${MASTER_KEY} jfrog/artifactory-ha
```
**NOTE:** Make sure to pass the same master key with `--set artifactory.masterKey=${MASTER_KEY}` on all future calls to `helm install` and `helm upgrade`!

Alternatively, you can create a secret containing the master key manually and pass it to the template at install/upgrade time.
```bash
# Create a key
export MASTER_KEY=$(openssl rand -hex 32)
echo ${MASTER_KEY}

# Create a secret containing the key. The key in the secret must be named master-key
kubectl create secret generic my-secret --from-literal=master-key=${MASTER_KEY}

# Pass the created secret to helm
helm install --name artifactory-ha --set artifactory.masterKeySecretName=my-secret jfrog/artifactory-ha
```
**NOTE:** In either case, make sure to pass the same master key on all future calls to `helm install` and `helm upgrade`! In the first case, this means always passing `--set artifactory.masterKey=${MASTER_KEY}`. In the second, this means always passing `--set artifactory.masterKeySecretName=my-secret` and ensuring the contents of the secret remain unchanged.

### Install Artifactory HA license
For activating Artifactory HA, you must install an appropriate license. There are two ways to manage the license. **Artifactory UI** or a **Kubernetes Secret**.
Expand Down Expand Up @@ -286,6 +299,19 @@ This can be done with the following parameters
```
**NOTE:** You must set `postgresql.enabled=false` in order for the chart to use the `database.*` parameters. Without it, they will be ignored!

If you store your database credentials in a pre-existing Kubernetes `Secret`, you can specify them via `database.secrets` instead of `database.user` and `database.password`:
```bash
# Create a secret containing the database credentials
kubectl create secret generic my-secret --from-literal=user=${DB_USER} --from-literal=password=${DB_PASSWORD}
...
--set postgresql.enabled=false \
--set database.secrets.user.name=my-secret \
--set database.secrets.user.key=user \
--set database.secrets.password.name=my-secret \
--set database.secrets.password.key=password \
...
```

### Deleting Artifactory
To delete the Artifactory HA cluster
```bash
Expand Down Expand Up @@ -325,7 +351,8 @@ The following table lists the configurable parameters of the artifactory chart a
| `artifactory.image.pullPolicy` | Container pull policy | `IfNotPresent` |
| `artifactory.image.repository` | Container image | `docker.bintray.io/jfrog/artifactory-pro` |
| `artifactory.image.version` | Container image tag | `.Chart.AppVersion` |
| `artifactory.masterKey` | Artifactory Master Key. Can be generated with `openssl rand -hex 32` |`FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`|
| `artifactory.masterKey` | Artifactory Master Key. Can be generated with `openssl rand -hex 32` |`FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF`|
| `artifactory.masterKeySecretName` | Artifactory Master Key secret name | |
| `artifactory.license.secret` | Artifactory license secret name | |
| `artifactory.license.dataKey`| Artifactory license secret data key | |
| `artifactory.service.name` | Artifactory service name to be set in Nginx configuration | `artifactory` |
Expand All @@ -347,12 +374,13 @@ The following table lists the configurable parameters of the artifactory chart a
| `artifactory.readinessProbe.timeoutSeconds` | When the probe times out | 10 |
| `artifactory.readinessProbe.successThreshold` | Minimum consecutive successes for the probe to be considered successful after having failed. | 1 |
| `artifactory.readinessProbe.failureThreshold` | Minimum consecutive failures for the probe to be considered failed after having succeeded. | 10 |
| `artifactory.persistence.mountPath` | Artifactory persistence volume mount path | `"/var/opt/jfrog/artifactory"` |
| `artifactory.persistence.enabled` | Artifactory persistence volume enabled | `true` |
| `artifactory.persistence.accessMode` | Artifactory persistence volume access mode | `ReadWriteOnce` |
| `artifactory.persistence.size` | Artifactory persistence volume size | `200Gi` |
| `artifactory.persistence.type` | Artifactory HA storage type | `file-system` |
| `artifactory.persistence.redundancy` | Artifactory HA storage redundancy | `3` |
| `artifactory.persistence.mountPath` | Artifactory persistence volume mount path | `"/var/opt/jfrog/artifactory"` |
| `artifactory.persistence.enabled` | Artifactory persistence volume enabled | `true` |
| `artifactory.persistence.accessMode` | Artifactory persistence volume access mode | `ReadWriteOnce` |
| `artifactory.persistence.size` | Artifactory persistence or local volume size | `200Gi` |
| `artifactory.persistence.maxCacheSize` | Artifactory cache-fs provider maxCacheSize in bytes | `50000000000` |
| `artifactory.persistence.type` | Artifactory HA storage type | `file-system` |
| `artifactory.persistence.redundancy` | Artifactory HA storage redundancy | `3` |
| `artifactory.persistence.nfs.ip` | NFS server IP | |
| `artifactory.persistence.nfs.haDataMount` | NFS data directory | `/data` |
| `artifactory.persistence.nfs.haBackupMount` | NFS backup directory | `/backup` |
Expand All @@ -363,12 +391,14 @@ The following table lists the configurable parameters of the artifactory chart a
| `artifactory.persistence.googleStorage.identity` | Google Storage service account id | |
| `artifactory.persistence.googleStorage.credential` | Google Storage service account key | |
| `artifactory.persistence.googleStorage.path` | Google Storage path in bucket | `artifactory-ha/filestore` |
| `artifactory.persistence.awsS3.bucketName` | AWS S3 bucket name | `artifactory-ha` |
| `artifactory.persistence.awsS3.endpoint` | AWS S3 bucket endpoint | See https://docs.aws.amazon.com/general/latest/gr/rande.html |
| `artifactory.persistence.awsS3.region` | AWS S3 bucket region | |
| `artifactory.persistence.awsS3.identity` | AWS S3 AWS_ACCESS_KEY_ID | |
| `artifactory.persistence.awsS3.credential` | AWS S3 AWS_SECRET_ACCESS_KEY | |
| `artifactory.persistence.awsS3.path` | AWS S3 path in bucket | `artifactory-ha/filestore` |
| `artifactory.persistence.awsS3.bucketName` | AWS S3 bucket name | `artifactory-ha` |
| `artifactory.persistence.awsS3.endpoint` | AWS S3 bucket endpoint | See https://docs.aws.amazon.com/general/latest/gr/rande.html |
| `artifactory.persistence.awsS3.region` | AWS S3 bucket region | |
| `artifactory.persistence.awsS3.identity` | AWS S3 AWS_ACCESS_KEY_ID | |
| `artifactory.persistence.awsS3.credential` | AWS S3 AWS_SECRET_ACCESS_KEY | |
| `artifactory.persistence.awsS3.path` | AWS S3 path in bucket | `artifactory-ha/filestore` |
| `artifactory.persistence.awsS3.refreshCredentials` | AWS S3 renew credentials on expiration | `true` |
| `artifactory.persistence.awsS3.testConnection` | AWS S3 test connection on start up | `false` |
| `artifactory.javaOpts.other` | Artifactory extra java options (for all nodes) | `-Dartifactory.locking.provider.type=db` |
| `artifactory.replicator.enabled` | Enable Artifactory Replicator | `false` |
| `artifactory.distributionCerts` | Name of ConfigMap for Artifactory Distribution Certificate | |
Expand Down Expand Up @@ -443,11 +473,15 @@ The following table lists the configurable parameters of the artifactory chart a
| `postgresql.resources.requests.cpu` | PostgreSQL initial cpu request | |
| `postgresql.resources.limits.memory` | PostgreSQL memory limit | |
| `postgresql.resources.limits.cpu` | PostgreSQL cpu limit | |
| `database.type` | External database type (`postgresql`, `mysql`, `oracle` or `mssql`) | |
| `database.host` | External database hostname | |
| `database.port` | External database port | |
| `database.user` | External database username | |
| `database.password` | External database password | |
| `database.type` | External database type (`postgresql`, `mysql`, `oracle` or `mssql`) | |
| `database.host` | External database hostname | |
| `database.port` | External database port | |
| `database.user` | External database username | |
| `database.password` | External database password | |
| `database.secrets.user.name` | External database username `Secret` name | |
| `database.secrets.user.key` | External database username `Secret` key | |
| `database.secrets.password.name` | External database password `Secret` name | |
| `database.secrets.password.key` | External database password `Secret` key | |


Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`.
Expand Down
5 changes: 4 additions & 1 deletion stable/artifactory-ha/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
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 ******************************************
Expand All @@ -12,6 +12,9 @@ Congratulations. You have just deployed JFrog Artifactory HA!
* $ echo ${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 }}

Expand Down
42 changes: 22 additions & 20 deletions stable/artifactory-ha/templates/artifactory-binarystore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ data:

<!-- Set max cache-fs size -->
<provider id="cache-fs" type="cache-fs">
<maxCacheSize>50000000000</maxCacheSize>
<maxCacheSize>{{ .Values.artifactory.persistence.maxCacheSize }}</maxCacheSize>
</provider>

<provider id="eventual-cluster" type="eventual-cluster">
Expand Down Expand Up @@ -98,25 +98,22 @@ data:
{{- 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"/>
<chain> <!--template="cluster-s3"-->
<provider id="cache-fs" type="cache-fs">
<provider id="sharding-cluster" type="sharding-cluster">
<sub-provider id="eventual-cluster" type="eventual-cluster">
<provider id="retry-s3" type="retry">
<provider id="s3" type="s3"/>
</provider>
</sub-provider>
<dynamic-provider id="remote" type="remote"/>
</provider>
</provider>
</chain>

<!-- Set max cache-fs size -->
<provider id="cache-fs" type="cache-fs">
<maxCacheSize>50000000000</maxCacheSize>
<maxCacheSize>{{ .Values.artifactory.persistence.maxCacheSize }}</maxCacheSize>
</provider>

<provider id="eventual-cluster" type="eventual-cluster">
Expand All @@ -129,21 +126,26 @@ data:
<zone>remote</zone>
</provider>

<provider id="file-system" type="file-system">
<fileStoreDir>{{ .Values.artifactory.persistence.mountPath }}/data/filestore</fileStoreDir>
<tempDir>/tmp</tempDir>
<provider id="sharding-cluster" type="sharding-cluster">
<readBehavior>crossNetworkStrategy</readBehavior>
<writeBehavior>crossNetworkStrategy</writeBehavior>
<redundancy>{{ .Values.artifactory.persistence.redundancy }}</redundancy>
<property name="zones" value="local,remote"/>
</provider>

<provider id="s3" type="s3">
<endpoint>{{ .Values.artifactory.persistence.awsS3.endpoint }}</endpoint>
<refreshCredentials>true</refreshCredentials>
<testConnection>false</testConnection>
<refreshCredentials>{{ .Values.artifactory.persistence.awsS3.refreshCredentials }}</refreshCredentials>
<testConnection>{{ .Values.artifactory.persistence.awsS3.testConnection }}</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>
{{- range $key, $value := .Values.artifactory.persistence.awsS3.properties }}
<property name="{{ $key }}" value="{{ $value }}"/>
{{- end }}
</provider>
</config>
{{- end }}
32 changes: 30 additions & 2 deletions stable/artifactory-ha/templates/artifactory-node-statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ spec:
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:
serviceAccountName: {{ template "artifactory-ha.serviceAccountName" . }}
{{- if .Values.imagePullSecrets }}
Expand Down Expand Up @@ -143,7 +146,7 @@ spec:
- name: ARTIFACTORY_MASTER_KEY
valueFrom:
secretKeyRef:
name: {{ template "artifactory-ha.fullname" . }}
name: "{{ .Values.artifactory.masterKeySecretName | default (include "artifactory-ha.fullname" .) }}"
key: master-key
- name: HA_IS_PRIMARY
value: "false"
Expand Down Expand Up @@ -212,10 +215,34 @@ spec:
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- if .Values.artifactory.node.affinity }}
{{- with .Values.artifactory.node.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- 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 }}
tolerations:
{{ toYaml . | indent 8 }}
Expand Down Expand Up @@ -244,7 +271,8 @@ spec:
{{- end }}
{{- if .Values.artifactory.persistence.local }}
- name: volume
emptyDir: {}
emptyDir:
sizeLimit: {{ .Values.artifactory.persistence.size }}
{{- else }}
volumeClaimTemplates:
- metadata:
Expand Down
Loading

0 comments on commit dda17b8

Please sign in to comment.