Skip to content

Commit adf5cf5

Browse files
committed
feat(chart): add rustfs-operator-crds chart for Helm-managed CRDs
CRDs rendered as templates (upgradeable via helm upgrade) with values control: per-CRD toggles, keep-on-uninstall resource policy (default on), extra labels/annotations. Generated from the Rust types by scripts/generate-crds.py; the main chart keeps its crds/ directory and skips already-existing CRDs. Release workflow stamps versions in all charts. Verified on k3s: crds-chart-first install, coexistence with the main chart, upgrade ownership, keep-on-uninstall, and adoption of CRDs previously installed from crds/.
1 parent 7a10a9e commit adf5cf5

12 files changed

Lines changed: 616 additions & 6 deletions

File tree

.github/workflows/release.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ jobs:
7272
- uses: actions/checkout@v4
7373
with:
7474
fetch-depth: 0
75-
- name: Set chart version from tag
75+
- name: Set chart versions from tag
7676
run: |
7777
version="${GITHUB_REF_NAME#v}"
78-
sed -i "s/^version:.*/version: ${version}/" charts/rustfs-operator/Chart.yaml
79-
sed -i "s/^appVersion:.*/appVersion: \"${version}\"/" charts/rustfs-operator/Chart.yaml
78+
for chart in charts/*/Chart.yaml; do
79+
sed -i "s/^version:.*/version: ${version}/" "$chart"
80+
sed -i "s/^appVersion:.*/appVersion: \"${version}\"/" "$chart"
81+
done
8082
- name: Configure git
8183
run: |
8284
git config user.name "$GITHUB_ACTOR"

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustfs-operator"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
edition = "2024"
55
rust-version = "1.92"
66
license = "MIT OR Apache-2.0"

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ The chart can also bootstrap `ClusterConnection` resources (and their admin
5757
credentials Secrets) from values — see
5858
[`charts/rustfs-operator/README.md`](charts/rustfs-operator/README.md).
5959

60+
The main chart installs the CRDs from its `crds/` directory, which Helm
61+
never upgrades. For Helm-managed, value-controlled CRDs (per-CRD toggles,
62+
keep-on-uninstall policy, upgrades via `helm upgrade`), install the
63+
[`rustfs-operator-crds`](charts/rustfs-operator-crds/README.md) chart first —
64+
the main chart automatically skips CRDs that already exist. CRD manifests
65+
and the CRDs chart templates are regenerated from the Rust types with
66+
`python3 scripts/generate-crds.py`.
67+
6068
Or run from source against the current kubeconfig:
6169

6270
```sh
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v2
2+
name: rustfs-operator-crds
3+
description: CustomResourceDefinitions for the rustfs-operator, managed as Helm templates (upgradeable, value-controlled)
4+
type: application
5+
home: https://github.com/OpenProjectX/rustfs-operator
6+
sources:
7+
- https://github.com/OpenProjectX/rustfs-operator
8+
keywords:
9+
- rustfs
10+
- s3
11+
- operator
12+
- crds
13+
# version and appVersion are overwritten from the git tag by the release workflow
14+
version: 0.4.0
15+
appVersion: "0.4.0"
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# rustfs-operator-crds Helm chart
2+
3+
The [rustfs-operator](https://github.com/OpenProjectX/rustfs-operator) CRDs
4+
(`Bucket`, `User`, `Policy`, `ClusterConnection`) as **Helm templates**, so
5+
they are upgradeable via `helm upgrade` and controllable through values —
6+
unlike the copy shipped in the main chart's `crds/` directory, which Helm
7+
only ever installs once.
8+
9+
```sh
10+
helm repo add rustfs-operator https://openprojectx.github.io/rustfs-operator
11+
12+
# install CRDs first, then the operator (it skips already-existing CRDs)
13+
helm install rustfs-operator-crds rustfs-operator/rustfs-operator-crds
14+
helm install rustfs-operator rustfs-operator/rustfs-operator \
15+
--namespace rustfs-operator --create-namespace
16+
```
17+
18+
## Values
19+
20+
| Key | Default | Description |
21+
|-----|---------|-------------|
22+
| `keep` | `true` | add `helm.sh/resource-policy: keep` so `helm uninstall` leaves the CRDs (deleting a CRD cascades to **all** CRs of that kind) |
23+
| `annotations` | `{}` | extra annotations on every CRD |
24+
| `labels` | `{}` | extra labels on every CRD |
25+
| `crds.bucket` | `true` | install `buckets.rustfs.com` |
26+
| `crds.user` | `true` | install `users.rustfs.com` |
27+
| `crds.policy` | `true` | install `policies.rustfs.com` |
28+
| `crds.clusterConnection` | `true` | install `clusterconnections.rustfs.com` |
29+
30+
## Adopting CRDs installed by the main chart
31+
32+
If the CRDs already exist on the cluster (installed from the main chart's
33+
`crds/` directory), Helm refuses to manage them until they carry release
34+
ownership metadata. Adopt them once, then install this chart:
35+
36+
```sh
37+
for crd in buckets users policies clusterconnections; do
38+
kubectl annotate crd ${crd}.rustfs.com \
39+
meta.helm.sh/release-name=rustfs-operator-crds \
40+
meta.helm.sh/release-namespace=default --overwrite
41+
kubectl label crd ${crd}.rustfs.com \
42+
app.kubernetes.io/managed-by=Helm --overwrite
43+
done
44+
helm install rustfs-operator-crds rustfs-operator/rustfs-operator-crds
45+
```
46+
47+
(Adjust the release name/namespace to whatever you install with.)
48+
49+
## Development
50+
51+
Templates are generated from the Rust CRD types — do not edit them by hand.
52+
Regenerate after changing `src/crd.rs`:
53+
54+
```sh
55+
python3 scripts/generate-crds.py
56+
```
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
{{- if .Values.crds.bucket }}
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
name: buckets.rustfs.com
6+
{{- if or .Values.keep .Values.annotations }}
7+
annotations:
8+
{{- if .Values.keep }}
9+
helm.sh/resource-policy: keep
10+
{{- end }}
11+
{{- with .Values.annotations }}
12+
{{- toYaml . | nindent 4 }}
13+
{{- end }}
14+
{{- end }}
15+
labels:
16+
app.kubernetes.io/name: rustfs-operator-crds
17+
app.kubernetes.io/managed-by: {{ .Release.Service }}
18+
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version }}
19+
{{- with .Values.labels }}
20+
{{- toYaml . | nindent 4 }}
21+
{{- end }}
22+
spec:
23+
group: rustfs.com
24+
names:
25+
categories: []
26+
kind: Bucket
27+
plural: buckets
28+
shortNames:
29+
- rfb
30+
singular: bucket
31+
scope: Namespaced
32+
versions:
33+
- additionalPrinterColumns:
34+
- jsonPath: .status.ready
35+
name: Ready
36+
type: boolean
37+
- jsonPath: .status.message
38+
name: Message
39+
type: string
40+
name: v1alpha1
41+
schema:
42+
openAPIV3Schema:
43+
description: Auto-generated derived type for BucketSpec via `CustomResource`
44+
properties:
45+
spec:
46+
description: An S3 bucket in RustFS.
47+
properties:
48+
bucketName:
49+
description: Bucket name in RustFS; defaults to the CR name.
50+
nullable: true
51+
type: string
52+
connection:
53+
description: |-
54+
Reference to a RustFS server. Exactly one of `secretRef` / `clusterRef`
55+
must be set (validated at reconcile time).
56+
properties:
57+
clusterRef:
58+
description: Name of a cluster-scoped ClusterConnection.
59+
nullable: true
60+
type: string
61+
secretRef:
62+
description: |-
63+
Name of a Secret in the resource's namespace holding `endpoint`,
64+
`accessKey` and `secretKey` (optional: `region`, `insecure`).
65+
nullable: true
66+
type: string
67+
type: object
68+
deletionPolicy:
69+
default: Delete
70+
description: What happens to the remote resource when the CR is deleted.
71+
enum:
72+
- Delete
73+
- Retain
74+
type: string
75+
quotaBytes:
76+
description: Hard quota in bytes; unset means unmanaged.
77+
format: uint64
78+
minimum: 0.0
79+
nullable: true
80+
type: integer
81+
versioning:
82+
description: Desired versioning state; unset means unmanaged.
83+
nullable: true
84+
type: boolean
85+
required:
86+
- connection
87+
type: object
88+
status:
89+
description: Shared status for all RustFS resources.
90+
nullable: true
91+
properties:
92+
message:
93+
description: Human-readable state or last error.
94+
nullable: true
95+
type: string
96+
observedGeneration:
97+
description: Generation last acted upon.
98+
format: int64
99+
nullable: true
100+
type: integer
101+
ready:
102+
default: false
103+
description: True once the remote resource matches the spec.
104+
type: boolean
105+
type: object
106+
required:
107+
- spec
108+
title: Bucket
109+
type: object
110+
served: true
111+
storage: true
112+
subresources:
113+
status: {}
114+
{{- end }}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
{{- if .Values.crds.clusterConnection }}
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
name: clusterconnections.rustfs.com
6+
{{- if or .Values.keep .Values.annotations }}
7+
annotations:
8+
{{- if .Values.keep }}
9+
helm.sh/resource-policy: keep
10+
{{- end }}
11+
{{- with .Values.annotations }}
12+
{{- toYaml . | nindent 4 }}
13+
{{- end }}
14+
{{- end }}
15+
labels:
16+
app.kubernetes.io/name: rustfs-operator-crds
17+
app.kubernetes.io/managed-by: {{ .Release.Service }}
18+
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version }}
19+
{{- with .Values.labels }}
20+
{{- toYaml . | nindent 4 }}
21+
{{- end }}
22+
spec:
23+
group: rustfs.com
24+
names:
25+
categories: []
26+
kind: ClusterConnection
27+
plural: clusterconnections
28+
shortNames:
29+
- rfcc
30+
singular: clusterconnection
31+
scope: Cluster
32+
versions:
33+
- additionalPrinterColumns:
34+
- jsonPath: .spec.endpoint
35+
name: Endpoint
36+
type: string
37+
name: v1alpha1
38+
schema:
39+
openAPIV3Schema:
40+
description: Auto-generated derived type for ClusterConnectionSpec via `CustomResource`
41+
properties:
42+
spec:
43+
description: |-
44+
A centrally managed connection to a RustFS server. Cluster-scoped; the
45+
referenced credentials Secret lives in the operator's own namespace, so
46+
application namespaces never see admin credentials.
47+
properties:
48+
allowedNamespaces:
49+
description: |-
50+
Namespaces whose resources may use this connection.
51+
Absent means all namespaces are allowed.
52+
items:
53+
type: string
54+
nullable: true
55+
type: array
56+
credentialsSecretRef:
57+
description: |-
58+
Name of the Secret in the operator's namespace holding `accessKey`
59+
and `secretKey`.
60+
type: string
61+
endpoint:
62+
description: RustFS endpoint URL, e.g. `http://rustfs.storage.svc:9000`.
63+
type: string
64+
insecure:
65+
default: false
66+
description: Skip TLS verification.
67+
type: boolean
68+
region:
69+
description: AWS region; defaults to `us-east-1`.
70+
nullable: true
71+
type: string
72+
required:
73+
- credentialsSecretRef
74+
- endpoint
75+
type: object
76+
required:
77+
- spec
78+
title: ClusterConnection
79+
type: object
80+
served: true
81+
storage: true
82+
subresources: {}
83+
{{- end }}

0 commit comments

Comments
 (0)