{{- /* The 1Password items this chart materializes. Two of them, because they have different audiences: the RPC secret belongs to this node alone, while the S3 access key is the credential the CONSUMER uses - the same item a consuming chart (stalwart's secrets.s3SecretRef) points at, which is why it carries the bucket name as a third field: endpoint, bucket, key and secret then have one source of truth instead of being kept in step by hand. WHAT THE FIELD NAMES ARE AND WHY THEY ARE NOT FREE-FORM: the operator materializes one Secret key per FIELD of the item, and this chart references those keys by name in the StatefulSet's env block. An item without the expected field leaves the container in CreateContainerConfigError. NOTES.txt lists all four fields for the installer. AND THE LIMIT THAT CANNOT BE CLOSED: a change to the CONTENT of either item restarts nothing. Helm never sees a secret the 1Password operator materializes, so there is nothing to hash. What this chart does cover is the op:// PATH, through checksum/secret-ref on the pod template. After rotating a value INSIDE an item the manual step is kubectl -n rollout restart statefulset/-garage-sfs and for the access key that is not enough on its own - see NOTES.txt, Garage refuses to adopt a changed secret for an access key it already knows. The 1Password operator's auto-restart annotation is NOT set here and must not be: verified against operator 1.12.0 it enumerates Deployments only, so on a StatefulSet it is a silent no-op advertising a guarantee it does not provide (README, guideline 9). */ -}} {{- $settings := fromYaml (include "garage.settings" .) -}} apiVersion: onepassword.com/v1 kind: OnePasswordItem metadata: name: {{ .Release.Name }}-{{ .Chart.Name }}-rpc-secret labels: app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs spec: # Must carry the field: rpc-secret # # 32 bytes of random hex - Garage rejects anything else with "Invalid RPC # secret key: expected 32 bytes of random hex". Generate it with # openssl rand -hex 32 # It is required even for a single node: Garage uses it as the network key of # its RPC layer and refuses to start without it ("rpc_secret value is # missing, not present in config file or in environment"). itemPath: {{ required "You must provide an RPC secret reference (secrets.rpcSecretRef) - the 1Password item holding this cluster's 32-byte hex 'rpc-secret' field" .Values.secrets.rpcSecretRef }} {{- $s3Needed := and $settings.singleNode (or $settings.defaultAccessKey $settings.defaultBucket) }} {{- if or .Values.secrets.s3SecretRef $s3Needed }} --- apiVersion: onepassword.com/v1 kind: OnePasswordItem metadata: name: {{ .Release.Name }}-{{ .Chart.Name }}-s3-secret labels: app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs spec: # Must carry the fields: access-key, secret-key, bucket # # THE DIRECTION IS INWARDS, and that is the part worth knowing: with # garage.singleNode plus defaultAccessKey/defaultBucket, Garage IMPORTS these # three values on start (--default-access-key / --default-bucket read them # from the environment). The vault item is the source of truth, and nothing # has to be copied out of the server afterwards. # # Garage validates all three on import and refuses to START on a malformed # one, so they are not free-form labels (src/model/key_table.rs, # src/model/bucket_alias_table.rs): # access-key at least 8 characters, ASCII alphanumeric plus - _ . # secret-key at least 16 characters, printable ASCII (U+0021-U+007E) # bucket a valid S3 bucket name (3-63 characters, lowercase) # NOTES.txt prints the generators. itemPath: {{ required "You must provide an S3 key reference (secrets.s3SecretRef) - the 1Password item holding the fields access-key, secret-key and bucket. It is required while garage.singleNode is true together with defaultAccessKey or defaultBucket, because Garage imports those values on start" .Values.secrets.s3SecretRef }} {{- end }}