Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Helm chart #79

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/publish-helm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Publish Helm Chart

# Trigger on release events for main and helm-chart branches
on:
release:
types: [published]
branches:
- main
- helm-chart
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Let's not forget to remove this 😃

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

absolutely


env:
REGISTRY: ghcr.io
CHART_DIR: chart
HELM_VERSION: v3.12.3

jobs:
build:
name: Build and Validate Chart
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Helm
uses: azure/setup-helm@v3
with:
version: ${{ env.HELM_VERSION }}

- name: Update chart version
run: |
# Extract version from release tag
VERSION=${GITHUB_REF#refs/tags/}
echo "Setting chart version to: ${VERSION}"
yq e -i '.version = "'${VERSION}'"' ${{ env.CHART_DIR }}/Chart.yaml

- name: Lint chart
run: helm lint ${{ env.CHART_DIR }}

- name: Validate chart template
run: helm template ${{ env.CHART_DIR }}

- name: Package chart
run: helm package ${{ env.CHART_DIR }}

- name: Upload chart artifact
uses: actions/upload-artifact@v3
with:
name: helm-chart
path: ./*.tgz
retention-days: 1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there are no daily releases, this should probably be changed.


publish:
name: Publish to Registry
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Download chart artifact
uses: actions/download-artifact@v3
with:
name: helm-chart

- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Push chart to registry
run: |
echo "Publishing Helm chart to ${{ env.REGISTRY }}/${{ github.repository_owner }}"
helm push *.tgz oci://${{ env.REGISTRY }}/${{ github.repository_owner }}
5 changes: 5 additions & 0 deletions chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v2
name: harbor-day2-operator
description: A Helm chart for Harbor Day 2 Operator that manages existing Harbor instances
version: 0.1.0
type: application
100 changes: 100 additions & 0 deletions chart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Harbor Day 2 Operator Helm Chart

This Helm chart deploys the Harbor Day 2 Operator, which is designed for automated management of existing Harbor instances using the Harbor API.

## Prerequisites

- Kubernetes 1.16+
- Helm 3.0+
- An existing Harbor instance
- OIDC provider configuration

## Installing the Chart

1. Create a values file with your configuration:

```yaml
image:
tag: "your-version-tag"

harbor:
apiUrl: "https://your-harbor-instance/api/v2.0/"
adminPasswordNew: "your-new-admin-password"
adminPasswordOld: "your-old-admin-password" # Optional
robotSecrets: {} # Add your robot account secrets

oidc:
endpoint: "https://your-oidc-provider"
staticClientToken: "your-oidc-client-token"

configFiles:
enabled: true
# Add your configuration files here
"config.json": |
{
"your": "configuration"
}
```

2. Install the chart:

```bash
helm install harbor-day2-operator ./harbor-day2-operator -f values.yaml
```

## Configuration

The following table lists the configurable parameters of the Harbor Day 2 Operator chart and their default values.

| Parameter | Description | Default |
|-----------|-------------|---------|
| `replicaCount` | Number of replicas | `1` |
| `image.repository` | Image repository | `ghcr.io/steadforce/steadops/workbenches/harbor-day2-operator` |
| `image.tag` | Image tag | `""` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `harbor.apiUrl` | Harbor API URL | `""` |
| `harbor.adminUsername` | Harbor admin username | `"admin"` |
| `harbor.adminPasswordNew` | New admin password | `""` |
| `harbor.adminPasswordOld` | Old admin password | `""` |
| `harbor.robotNamePrefix` | Prefix for robot accounts | `"robot$"` |
| `oidc.endpoint` | OIDC provider endpoint | `""` |
| `oidc.staticClientToken` | OIDC static client token | `""` |
| `configFolder` | Path to configuration files | `/usr/local/scripts` |
| `configFiles.enabled` | Enable configuration files | `true` |

## Configuration Files

The operator uses configuration files in JSON format to define the desired state of the Harbor instance. These files should be provided through the `configFiles` section in the values.yaml.

Example configuration:

```yaml
configFiles:
enabled: true
"projects.json": |
{
"projects": [
{
"name": "example-project",
"public": false
}
]
}
"robots.json": |
[
{
"name": "example-robot",
"duration": "-1",
"description": "Example robot"
}
]
```

## Security

The chart creates several Kubernetes secrets to store sensitive information:
- Admin password (new and old)
- Robot account credentials
- OIDC static client token

Make sure to handle these secrets securely and never commit them to version control.
51 changes: 51 additions & 0 deletions chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "harbor-day2-operator.name" -}}
{{- default .Chart.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 "harbor-day2-operator.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 chart name and version as used by the chart label.
*/}}
{{- define "harbor-day2-operator.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "harbor-day2-operator.labels" -}}
helm.sh/chart: {{ include "harbor-day2-operator.chart" . }}
{{ include "harbor-day2-operator.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "harbor-day2-operator.selectorLabels" -}}
app.kubernetes.io/name: {{ include "harbor-day2-operator.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
15 changes: 15 additions & 0 deletions chart/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- if .Values.configFiles.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "harbor-day2-operator.fullname" . }}-config
labels:
{{- include "harbor-day2-operator.labels" . | nindent 4 }}
data:
{{- range $filename, $content := .Values.configFiles }}
{{- if ne $filename "enabled" }}
{{ $filename }}: |
{{- $content | nindent 4 }}
{{- end }}
{{- end }}
{{- end }}
68 changes: 68 additions & 0 deletions chart/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "harbor-day2-operator.fullname" . }}
labels:
{{- include "harbor-day2-operator.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "harbor-day2-operator.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "harbor-day2-operator.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: ADMIN_PASSWORD_NEW
valueFrom:
secretKeyRef:
name: {{ include "harbor-day2-operator.fullname" . }}-admin
key: password-new
- name: ADMIN_PASSWORD_OLD
valueFrom:
secretKeyRef:
name: {{ include "harbor-day2-operator.fullname" . }}-admin
key: password-old
- name: HARBOR_API_URL
value: {{ .Values.harbor.apiUrl }}
- name: ADMIN_USERNAME
value: {{ .Values.harbor.adminUsername }}
- name: OIDC_ENDPOINT
value: {{ .Values.oidc.endpoint }}
- name: CONFIG_FOLDER_PATH
value: {{ .Values.configFolder }}
- name: ROBOT_NAME_PREFIX
value: {{ .Values.harbor.robotNamePrefix }}
envFrom:
- secretRef:
name: {{ include "harbor-day2-operator.fullname" . }}-robot
- secretRef:
name: {{ include "harbor-day2-operator.fullname" . }}-oidc
command: ["watch", "-n", "60", "/bin/ash", "-ec", "/usr/local/harbor"]
volumeMounts:
- name: config-volume
mountPath: {{ .Values.configFolder }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: config-volume
configMap:
name: {{ include "harbor-day2-operator.fullname" . }}-config
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
34 changes: 34 additions & 0 deletions chart/templates/secrets.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "harbor-day2-operator.fullname" . }}-admin
labels:
{{- include "harbor-day2-operator.labels" . | nindent 4 }}
type: Opaque
data:
password-new: {{ required "A new admin password is required" .Values.harbor.adminPasswordNew | b64enc }}
{{- if .Values.harbor.adminPasswordOld }}
password-old: {{ .Values.harbor.adminPasswordOld | b64enc }}
{{- end }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "harbor-day2-operator.fullname" . }}-robot
labels:
{{- include "harbor-day2-operator.labels" . | nindent 4 }}
type: Opaque
data:
{{- range $key, $value := .Values.harbor.robotSecrets }}
{{ $key }}: {{ $value | b64enc }}
{{- end }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "harbor-day2-operator.fullname" . }}-oidc
labels:
{{- include "harbor-day2-operator.labels" . | nindent 4 }}
type: Opaque
data:
OIDC_STATIC_CLIENT_TOKEN: {{ required "An OIDC static client token is required" .Values.oidc.staticClientToken | b64enc }}
35 changes: 35 additions & 0 deletions chart/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
replicaCount: 1

image:
repository: ghcr.io/steadforce/steadops/workbenches/harbor-day2-operator
tag: "" # Set your specific version
pullPolicy: IfNotPresent

harbor:
apiUrl: "" # The Harbor API URL to manage
adminUsername: "admin"
robotNamePrefix: "robot$"

oidc:
endpoint: "" # OIDC provider endpoint

configFolder: /usr/local/scripts

resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi

nodeSelector: {}
tolerations: []
affinity: {}

# Configuration files to be mounted
configFiles:
enabled: true
# Add your configuration files here in the format:
# filename: |
# content
Loading