# Secret Generate and Regenerate
# Table of Contents
1. [Problem statement](#Problem-statement)
* [Proposed Commands](#Proposed-Command
)
2. [Proposal](#Proposal)
* [Passphrase Command](#Passphrase-Command)
1. [Intro](#Introduction)
2. [Sequenece Diagram](#Sequence-Diagram)
3. [Output Secrets](#Output-Secrets)
4. [Phase run Sequence Diagram](#Phase-run-Sequence-Diagram)
* [Certificate Command](#Certificate-Command)
1. [Intro](#Introduction1)
2. [Sequenece Diagram](#Sequence-Diagram1)
3. [Output Secrets](#Output-Secrets1)
4. [Phase run Sequence Diagram](#Phase-run-Sequence-Diagram1)
3. [Usecases](#Usecases)
## Problem statement
`airshipctl secret encrypt` and `airsipctl secret decrypt` commands are used to encrypt/decrypt the secrets already available. Adding `airshipctl secret generate` helps in generating passphrases and certificates as kuberenetes secrets. It would also encrypt the secrets. With `--regenerate-all` the secrets which are marked as regenerate true can be regenerated again. The operator can then use `airshipctl phase run` to apply the newly generated secrets.
The passphrase based secrets that are generated would be imported to another existing CRD object using Replacementtransformer. In this case the operator would define a replacement transformer object to replace the generated passphrase secret in the targetted CRD object.
### Proposed Commands
This below command would allow operators to generate all passphrases for a new site, or to generate only newly added passphrase catalogue entries for that site without regenerating existing passphrases.
`airshipctl secret generate passphrase`
To regenerate passphrases for a site the operator can use the below command. The passphrases which are flagged `disable_regenerate: true` will not be recreated again using the below comamnd.
`airshipctl secret generate passphrase --regenerate-all`
The below command would allow operators to generate the CA certificates for a new site, or to generate only newly added CA certificate catalogue entries for that site without regenerating existing certificates.
`airshipctl secret generate certificate`
To regenerate CA certificates for a site the operator can use the below command. Certificates which are flagged as `disable_regenerate: true` in the catalogue document will not be recreated again.
`airshipctl secret generate certificate --regenerate-all`
## Proposal
To generate the required secret passphrases/certificates we would propose a secretGenerator catalog yaml file which contains the details about what secret passphrases/certificates needs to be created. This catalog file also holds the information about the regeneration, encryption flags and other details.
### Passphrase Command
#### Introduction
The command will generate kubernetes secrets with passwords/uuids as data. These kubernetes `kind: Secrets` yaml files data will be used by the operator to define a replacement transformer which would replace the data in the desired kubernetes object. Please note that these secrets are used for replacement purpose and will not be created on the kubernetes cluster itself.
To generate the passphrases we would use the existing `airshipctl secret generate masterpassphrase` command. The command will be enhanced to take `regex` parameter as input so that the generated passphrase matches the `regex`.
By default the `disable_encrypt: false` flag is set to false, so the kubernetes secrets generated will be encrypted by default. Under the hood we would use the `airshipctl secret encrypt` command to encrypt the secrets. So the pre-requisite would be to set the `gpg` keys in the `$HOME/.airship/config` file using `airshipctl config set-encryption` command.
Whenever `airshipctl secret generate passphrase` or `airshipctl secret generate passphrase --regenerate-all` command is triggered, the current context's metadata yaml file is read for catalog yaml file details.
Example of metadata.yaml file
```
phase: # this exists today in metadata.yaml
path: manifests/phase
passphrases:
- path: airshipctl/manifests/site/test-site/generation-source/openstack.yaml # Catalogue file location
secrets_path: airshipctl/manifests/site/test-site/generation-secrets # Generated secrets and kustomization.yaml file will be placed here
- path: airshipctl/manifests/site/test-site/generation-source/bmc.yaml # Another example
secrets_path: airshipctl/manifests/site/test-site/generation-passphrases
```
Here is an example of the catalog yaml and the expected kubernetes secret outputs once the command has executed successfully.
<details>
<summary> Catalog File with passphrase details </summary>
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-source/openstack.yaml`
Contents:
```yaml
apiVersion: secrets.airshipit.org/v1alpha1
kind: secretGenerator
metadata:
name: secret-catalog
data:
passphrases:
# This will generate a Secret named "helm-release-password" in:
# <secrets_path>/
- name: 'helm-release-password'
# disable_encrypt: false # by default
disable_regenerate: true # default is false
data:
- key: password
- key: username
- name: 'helm-release-test-password'
disable_encrypt: false
data:
- key: password
regex: "^Xy[a-f][6-9][@#$%&]*$" # This regex will be used when creating the passphrase
- name: 'helm-release-testing-password'
disable_encrypt: false
data:
- key: password
value: "airship" # This value would be base64 encoded in the secret
- name: 'helm-release-example-password'
stringData:
- key: password
value: "testing" # This value will not be encoded will just be encrypted directly
```
</details>
#### Sequence Diagram
<details>
<summary> Generate and Regenerate command</summary>
![](https://i.imgur.com/i7rVHdm.png)
</details>
#### Output Secrets
Once the command gets executed it would generates the secret yaml files in the `secrets_path` specified and also a kustomization file invoking the generated secrets will be created.
The expectation is that the kustomization file in the corresponding phase will be edited by the operator to add this `secrets_path` as the resource in the kustomization file. The transformer section also needs to be changed by operator to call replacement folder if not present. And the replacement rules should also be created by the operator in the replacement folder.
If the secrets are encrypted then the `sops` plugin should be invoked before the replacement transformer which would decrypt the secrets. Please note the same `gpg` keys should be used for decryption which were set in the `$HOME/.airship/config` when the generate command was triggered.
The ReplacementTransformer will be enhanced to decode the secrets before they get replaced. The decoding feature will remove the base64 encoding applied on the secrets.
The required secret yaml files will be created in the `secrets_path` defined.
Please note that the `airshipit.org/deploy-k8s: "false"` annotation will be specified for all the secrets which means the secret will just be used to replace some fields in the target reference object (here HelmRelease) and will not be actually created in the kubernetes cluster itself.
<details>
<summary> Kustomization File </summary>
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-secrets/kustomization.yaml`
Contents:
```yaml
resources:
- helm-release-password.yaml
- helm-release-test-password.yaml
```
</details>
<details>
<summary markdown="span"> Secret YAML files </summary>
Sample secret yaml files that would be generated using the command.
* helm-release-password
Location: `$HOME/airshipctl/manifests/site/test-site/generation-secrets/helm-release-password.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: helm-release-password
annotations:
airshipit.org/encrypt: "true"
airshipit.org/regenerate: "false"
labels:
airshipit.org/deploy-k8s: "false"
data:
username: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
password: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
* helm-release-test-password
Location: `$HOME/airshipctl/manifests/site/test-site/generation-secrets/helm-release-test-password.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: helm-release-test-password
annotations:
airshipit.org/encrypt: "false"
labels:
airshipit.org/deploy-k8s: "false"
data:
password: "Xyb8z#df"
```
* helm-release-testing-password
Location: `$HOME/airshipctl/manifests/site/test-site/generation-secrets/helm-release-testing-password.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: helm-release-testing-password
annotations:
airshipit.org/encrypt: "false"
labels:
airshipit.org/deploy-k8s: "false"
data:
password: "YWlyc2hpcA=="
```
* helm-release-example-password
Location: `$HOME/airshipctl/manifests/site/test-site/generation-secrets/helm-release-example-password.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: helm-release-example-password
annotations:
airshipit.org/encrypt: "true"
labels:
airshipit.org/deploy-k8s: "false"
stringData:
password: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
</details>
Example changes that are expected by the user/operator:
For example:
Replacement rules should be created in a file like `<function>/replacements/secrets.yaml` in the `replacements` folder.
Kustomization file for a phase after editing would be as follows:
```
# kustomization.yaml for `workload` phase
resources:
- ../../../../type/airship-core/target/workload
- ../catalogues
- ../generated-secrets # New line of config
transformers:
- sops.yaml # New line of config, decrypt the generated Secrets first
# Note: this line will exist already, and will pull in the new replacements
- ../../../../type/airship-core/target/workload/replacements
```
#### Phase run Sequence Diagram
After secrets are generated below is the sequence of flows showing how the secrets would be applied.
Or once the secrets are generated the operator can store them in github/document manifest repository which can be pulled by other user and run the `airshipctl phase run` command directly.
<details>
<summary> Phase run command sequence</summary>
The below is flow of execution once the operator updates the kustomization.yaml file, add replacements and sops.yaml(for decryption).
![](https://i.imgur.com/GQ29mYd.png)
</details>
### Certificate Command
#### Introduction
The command will generate kubernetes tls secrets. These kubernetes `kind: Secrets` yaml files can be directly applied on the kubernetes cluster. Using this command the CA certificates for CAPI components(capi, capo, capd, capz, capm3, capg), kubernetes components and service account keypairs can be created.
Whenever `airshipctl secret generate certificate` or `airshipctl secret generate certificate --regenerate-all` command is triggered, the current context's `metadata.yaml` is searched for the catalogue information for certificate details.
By default the `disable_encrypt: false` flag is set to false, so the kubernetes secrets generated will be encrypted by default. Under the hood we would use the `airshipctl secret encrypt` command to encrypt the secrets. So the pre-requisite would be to set the `gpg` generated keys in the `$HOME/.airship/config` file using `airshipctl config set-encryption` command.
Here is an example of the catalog yaml and the expected kubernetes secret outputs once the certificate command has executed successfully.
Example of metadata.yaml file
```
phase: # this exists today in metadata.yaml
path: manifests/phase
certificates:
- path: airshipctl/manifests/site/test-site/generation-source/certificate.yaml # Catalogue file location
certificate_path: airshipctl/manifests/site/test-site/generation-certificate # Generated certificates and kustomization.yaml file will be placed here
- path: airshipctl/manifests/site/test-site/generation-source/test.yaml
certificate_path: airshipctl/manifests/site/test-site/generation-certificate-secrets # Another example
```
<details>
<summary>
Catalog File with certificate details </summary>
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-source/certificate.yaml`
Contents:
```yaml
apiVersion: secrets.airshipit.org/v1alpha1
kind: secretGenerator
metadata:
name: secret-certitificate-catalog
data:
certificates:
cluster_certificate_authorities:
- description: 'capi ca certificate' # Certs generated using openssl commands
document_name: capi_ca
days: 365
disable_encrypt: false #defaults to false
common_name: capi_system
- description: 'capd ca certificate' # Certs generated using openssl commands
document_name: capd_ca
days: 365
disable_encrypt: true
common_name: capd_system
- description: 'capm3 ca certificate'
document_name: capm3_ca
disable_regenerate: true # defaults to false
tls.key: $HOME/tls.key
tls.crt: $HOME/tls.crt
kubernetes_certificate_authorities:
- workloadCluster: dtc #Target cluster name
days: 365 # Days of validity - default 365
description: 'kubernetes ETCd, CA , Proxy certificates'
common_name: kubernetescerts
type: k8s_certs
disable_encrypt : false # default false
- workloadCluster: dtc
days: 365
description: 'kubernetes SA certificates'
type: key_pairs
tls.key: $HOME/tls.key
tls.crt: $HOME/tls.crt
```
</details>
#### Sequence Diagram
Please note: airshipctl secret certificate --regenerate-all regenerates the CA certificate, and it is expected that if the regenerated CA certificates are applied to the existing cluster the certificates using the CA has also to be regenerated.
<details>
<summary> Generate and Regenerate command</summary>
![](https://i.imgur.com/vnejpKU.png)
</details>
#### Output Secrets
The expectation is that the command generates the secret yaml files in the `certificate_path` specified and a corresponding kustomization file created. It would be the responsiblity of the user to invoke this kustomization file from the corresponding phase run's kustomization file (like `initinfra` or `workload` or `controlplane`) that is of interest. And if the secrets are encrypted then the user should also invoke the `sops` plugin in kustomization file to perform the decrpytion of certificates before they get applied on the cluster. Please note the same `gpg` keys should be used for decryption which were set in the `$HOME/.airship/config` when the generate command was triggered.
It will be the operator responsibility to invoke the certificates kustomization as resource in the corresponding phase kustomization file.
<details>
<summary> Kustomization File </summary>
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/kustomization.yaml`
Contents:
```yaml
resources:
- capi-ca.yaml
- capd-ca.yaml
- capm3-ca.yaml
- test-site-ca.yaml
- test-site-proxy.yaml
- test-site-etcd.yaml
- test-site-sa.yaml
```
</details>
<details>
<summary> CAPI CA Secret </summary>
Certificate secret generated with both key and cert details encrypted.
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/capi-ca.yaml
`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
annotations:
airshipit.org/encrypt: "true"
name: capi-ca
type: kubernetes.io/tls
data:
tls.crt: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
tls.key: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
</details>
<details>
<summary> CAPD CA Secret </summary>
Certificate secret generated with both key and cert details without any encryption, as encrypt is set to false in the certificate.yaml file.
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/capd-ca.yaml
`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: capd-ca
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURWRENDQWp5Z0F3SUJBZ0lVTUNwc09vRXhyRzdnRTVMOVJSamdnT01UOG53d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0dURVhNQlVHQTFVRUF3d09TM1ZpWlhKdVpYUmxjeUJCVUVrd0hoY05NakF3T1RFMU1ERXdORE0zV2hjTgpNekF3T1RFek1ERXdORE0zV2pBWk1SY3dGUVlEVlFRRERBNUxkV0psY201bGRHVnpJRUZRU1RDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUtBZFo0UWJHZmlLTExpTXNHcFJKS3d5ZkRGWVI5U0MKbGtVb3hlTU1BZVBkeVNNU0paTTlFMFBOaDM5TUtTVjNSZDRIZWt1eGdHK3J4em83WmcrZU1aY1hyNFk3ektQMwo1SW0vaERkMm1TYThsMEkxZTRwV3B0Z25vZjdvRWJpSXVIU2YxQmRhMU4wWm1EUUdtckxyQnFOZFE3c1BVenNWCllPejZVUFZlamNIeEFjMXBvMWZsQXYrWVNZejVXa28wRVRnTXZYRGtxT0hrWFc1WnhPcHBVbiszOVpvWTZMK3gKVmUwUHFQdHlmSVZ1M3dtcnZFNGd4SmxtWEk3dUxmdzZONHpwS2RuK0k0K1RJRWF5aE1EMWRRenNwQzRMM0IrcApYcHFPMWNWM2ZKMlBycS9mNU14SnIxWTVHUTZlQlZyTGVod1ZWTEhEMzF3ZWFpZ3UzeStyM3RVQ0F3RUFBYU9CCmt6Q0JrREFkQmdOVkhRNEVGZ1FVT1d5YTNFd2J5c25UUy9ZajFWTEtjMGh4aDRvd1ZBWURWUjBqQkUwd1M0QVUKT1d5YTNFd2J5c25UUy9ZajFWTEtjMGh4aDRxaEhhUWJNQmt4RnpBVkJnTlZCQU1NRGt0MVltVnlibVYwWlhNZwpRVkJKZ2hRd0ttdzZnVEdzYnVBVGt2MUZHT0NBNHhQeWZEQU1CZ05WSFJNRUJUQURBUUgvTUFzR0ExVWREd1FFCkF3SUJCakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBTVp1U2tJbTdQdlA4MW5HSjlYOVZFOFVZTVdDSU5GMEEKYit1UURFaHRGc0dxdnZFZHhQcURUWUpwdlF1SUJlOVd0cmlWRzh0MENIL1NnZ0g2TlJod0wyYkJwMm5WaEFVVwphK3hZL1RpTmMzUEl5RHNFeEY3VHVENGJzaW1BQUJTZ2ZtbXRxV1dqajRyOStodS9vZ09jLzQyYk9JT0JWbHNkCi9VNzBiR3dZQjU5QXgvL2dIWVJmVDl3L3p0VHBvY2tzdEhhSjZsVDd5SFlqYUkzaU5EWnZNSnFRSWNxME4vTEMKcVBjWjBWQXBMUTZRUHRpMWpVSzBGM1VlZEF6TVc3ZFF4NkV3Qjd5UHo4NWdZS3ZJdWdyaStrc2YwbGMyeHVDRwpXTGg2YjFNWk9Cc1NZNkppVHpSUUpYdXNCRUdaTGN5VkRJSEU3Y0Q4NWhOQmZpdDAvejFmZlE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktZd2dnU2lBZ0VBQW9JQkFRQ2dIV2VFR3huNGlpeTQKakxCcVVTU3NNbnd4V0VmVWdwWkZLTVhqREFIajNja2pFaVdUUFJORHpZZC9UQ2tsZDBYZUIzcExzWUJ2cThjNgpPMllQbmpHWEY2K0dPOHlqOStTSnY0UTNkcGttdkpkQ05YdUtWcWJZSjZIKzZCRzRpTGgwbjlRWFd0VGRHWmcwCkJwcXk2d2FqWFVPN0QxTTdGV0RzK2xEMVhvM0I4UUhOYWFOWDVRTC9tRW1NK1ZwS05CRTRETDF3NUtqaDVGMXUKV2NUcWFWSi90L1dhR09pL3NWWHRENmo3Y255RmJ0OEpxN3hPSU1TWlpseU83aTM4T2plTTZTblovaU9Qa3lCRwpzb1RBOVhVTTdLUXVDOXdmcVY2YWp0WEZkM3lkajY2djMrVE1TYTlXT1JrT25nVmF5M29jRlZTeHc5OWNIbW9vCkx0OHZxOTdWQWdNQkFBRUNnZ0VBWjNRNFUySlRlSVNHK3NOa3BYMUNiY1M4L0FFbmdFYlVJMkdCNHY3NkphcEMKOE5jajBpdnZTNnI3OXFOV0hyQWZRNk9mUUZNelFuUkNhUHpDS0NzMXJZT1BWUE5FZVZtTm4vZFB6YXBpc0dYQQpjZll1bWFiOWJNTEc1L1k0cFB3cCtxamVtQ3lIUjBqblVBNUlYSHlCTUlMdFpXczBnd09BT2Y1TzJ3dTZHbW5CCnlDbk5FaFFjbmZUdnN0MVBINUlTeEZ0TjFtODlnQ2orNEhsdHkybUdOdUNEczZ2QnZyWmEyeEJRZUtTcTl1eXEKY1dsdDkrRzI2ZmZFRmw0UEwwWit2Y0wrVDZLd0I4NFl2ampUd25pNEMzb1BmV3lZeEpkSjF0U3NFK1lSM3NIOApEdmlobmMwak00c0Fxb3hrMk5UV2kvNHpUUkppdytRcGhyRnNJWFNvUVFLQmdRRFNRaU44djFEUFk4VzdJUkFXClp6MTN5SWdrRTJHZXUzc2tFMkhweDN6ZFdMZWdmazF6SW42eUtpN0RzVTZhV2xjQURpMm5mU3BVSCtZQ2M0dVkKcmlnZ0xFMG9iZHJLVEFGdm1YYjA1WFRhR3FtcFE4TGxiWmxMTXVycXp0aG5BWmN3M2NySmxMb25kNkZISW9icAp3QU50K2p5a3pTaGs1T3MwSi9XajZiL3prUUtCZ1FEQzhxTkdndWVIbGw5QVNKeHJmM2hTeGJXWFhhTnJqMTJGCkEwNHlnNTFkbHg1QksweUVsZ3VZQ3RtZW5mZWgySWw5U1E3Yng4Z0Z5OWdWeDI5d1Z4eFp2b0xMaU16WU16RGMKWU5UTW9ETEtITjA3dHZ6ZDVza3piWFA3cFUwc25SMDV2RkJ2SHZtTHhWVlkvVHd6ZTdpZDVlNGtISTRWRmUxWQpnUDBYV0ZITkJRS0JnQTRXWGxoU1hUQzRCNXlGRjVYWXJ2YWltZlNJMCthVnV5ZHNvUWZQMU43anZkSGtCSDV0ClZqM0xzN3hxMmRCZnN5cU95S0pMTVpYWFdVcmF3UVNtem90eFRHNGtCaCs5dmU3alFtUWdKNWNoYURLdUZwWFcKcFFtenpLZVUya3owZjFQSDJIbHZISlhlWHhEc0VFd0RFSGZDNTJOSFY2aUM2ZnRobmdTd2VhcnhBb0dBRVd0Ywo2NUFHNERhdmpDN3d5eW80dGl5MGJUSVF5Q3VuVDV0Y0FXZUJTRHVZbUhvbC9ETHNGa25oNkNwMVZpRGpLQzYvCkJTUjAydys3M3paUzN0YnAwWnNVVk51RWNrMGdzSkIyYzFKZE4zSWMwcGtuUHl6QURiaGFCTUpnZ3Z3SEFJR3oKTGpxMlVhYndXV05IWGRKUVRNdWUyOXN4VnZEK3BFbmlVNU93dTRFQ2dZQmptRkRMZEZuT0VtOGlOZEFNVFM0SQpXM0VnckgvQVhsZ0dIOTVJVElKZCtuTmM3QUJQcktYUGEzTTlPRytCTUlpVlJZZ2JMVitXWU1hbHUvZWFJeWFXClR3TGpxaW5nak8rQXhKWFJkT1M3NGpOamFSWGtmM0RWQ1F3WUd0T0xqdE1qRVhmTWdORnViQXZ4TFVOUmZFblIKa09nR0pWQkgwSyttcVVaNVFiVWUwZz09Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
```
</details>
<details>
<summary> CAPM3 CA Secret</summary>
Certificate secret generated based on the tls.key and tls.crt files specified in the secretGenerate catalog yaml and also encrypted.
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/capm3-ca.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
annotations:
airshipit.org/encrypt: "true"
name: capm3-ca
type: kubernetes.io/tls
data:
tls.crt: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
tls.key: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
</details>
<details>
<summary> k8s Certificate Secret </summary>
Certificate secret generated with both key and cert details encrypted. There are 3 secrets created for the workload cluster these are the ca, proxy and etcd secrets. The names of the secrets are preffixed by the target workload cluster name.
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate`
1. CA File:
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/test-site-ca.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: test-site-ca
annotations:
airshipit.org/encrypt: "true"
type: kubernetes.io/tls
data:
tls.crt: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
tls.key: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
2. Proxy File:
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/test-site-proxy.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: test-site-proxy
annotations:
airshipit.org/encrypt: "true"
type: kubernetes.io/tls
data:
tls.crt: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
tls.key: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
3. Etcd File
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/test-site-etcd.yaml`
Contents:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: test-site-etcd
annotations:
airshipit.org/encrypt: "true"
type: kubernetes.io/tls
data:
tls.crt: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
tls.key: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
</details>
<details>
<summary> SA CA Secret</summary>
Certificate secret generated with both public and private keys encrypted. This service account with public and private keys is used by the kubernetes controller manager.
Location:
`$HOME/airshipctl/manifests/site/test-site/generation-certificate/test-site-sa.yaml`
Contents:
```
apiVersion: v1
kind: Secret
metadata:
name: test-site-sa
annotations:
airshipit.org/encrypt: "true"
type: kubernetes.io/tls
data:
tls.crt: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
tls.key: ENC[AES256_GCM,data:UA9BH2/Lhqsuekfe2VEFsw==,iv:pA1LkhM9O1WUfyB6f4MqW+ywDQrVeZOUmD8DNsK9gq0=,tag:9DVSISNEgibN3qs3STTN4w==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
lastmodified: '2020-09-09T09:08:15Z'
mac: ENC[AES256_GCM,data:pYzWql1bZWQ6s1hBub3XhChA5OpQzK5r+yYO6glsl5fhgdO6Ck/gveoSP2utFNWXS786M3gcR6F1DjWqMZp6kJ5Qm3yO1oyx9Inxsd2DxqP8CFXhqo0xape9c1SIpRnc/TdMfsu+iyyK4smtak2mibHzc6mfOKt/FJ03lONis2I=,iv:YrNZ6qp1hyLKMQXHHSstOqKro2EAKwSPWKsuH1Hyshg=,tag:VFwddodT5UmsDoZ1qgnN3Q==,type:str]
pgp:
- created_at: '2020-09-09T09:08:15Z'
enc: |
-----BEGIN PGP MESSAGE-----
hQEMA0Xswh95z+O7AQf/QrfvLfWtAitMmJULsaHPoETrDXpOQ4dK6CHntONguVVx
JxO91dUhGtNd88OQAOEIvU7Ycag3+bEKDjQxadRY/ig0FgWIbv5OeH5mFkvNDooh
ysH5KSJ5mQfFyIKwxk4kxbWWLfTEuX+MyxSBPW7jESJ8534nOhB2/znWe984rASX
+Edg6J85oJhWhqg3/yTSSGyrpgcdF0CEpUhPYBl9FLRJQI23x+jqgFB2AQ40xNRu
wUTNwumTk2hI9zJpwOhoY/XqJhGMplm5IgwTiY1rwzDOgbPK2WtKgfbm91kifEi0
O7I3G9qOUNNnFkc1VBBRrXRnqW5QbktntIxDnpH51tJeAb2d4DLk/CuhvBWmTtLb
/GsxhEt8IJvu9JHEbQKJLUG9oHwzRZewTyAYtKTJDzXLXZUYvozZ0j3aAyfW48O9
XgyYuGjz9TPWFdYvNO8dntL2Kdq+xZfobflFgBiZmg==
=ZELQ
-----END PGP MESSAGE-----
fp: 681E3A89EB1DAFD36EB883120A73BB48E26694D8
encrypted_regex: ^data
version: 3.6.0
```
</details>
#### Phase run Sequence Diagram
After certificate secrets are generated below is the sequence of flows showing how the certificate secrets would be applied to the cluster.
Please note: If the CA is regenrated and applied on the cluster, it would be the responsiblity of the operator to rotate the certificates as well.
1. For Management: Forcebily rotate certificates
2. For Workload: Rotate Machine templates and KCP
<details>
<summary> Phase run sequence</summary>
The below is flow of execution once the operator updates the kustomization.yaml file. And executes `airshipctl phase run` command.
![](https://i.imgur.com/OvT2ihg.png)
</details>
### Usecases
1. Secret Generate Certificate Usecase: This can be used to generate external certificates for capi, capck, capbk and capz/capd/capo/capm3/capg components. It also facilitates creation of certificate secrets for the kubernetes components in the target workload cluster.
2. Secret Generate Passphrases Usecase: This command can be used to generate generic secrets in the kubernetes manifest files, these can be secrets related to the applications that would be deployed on the kubernetes cluster.
### Changes to existing code
1. Enchance `airshipctl secret generate masterpassphrase` command to accept regex, to generate passphrases based on regex specified.
2. Add decoding functionality to the `ReplacementTransformer` plugin so that the secretes would be decoded before they get replaced.
### Some Known conflicts
1. If the secrets are manually created by the operator or if already exists in the `secrets_path` or `certificate_path` location when the corresponding command is triggered, those secrets will not be overridden. If the commands are executed will `--regenerate-all` flag and has `regenerate: true` only then the secrets will be over-written.
2. In case of certificates if the command is triggered with `--regenerate-all` flag and the secret source certificates are not present `tls.key` and `tls.crt` then previously generated certificates will be retained.
3. If the same certificate secret is created in some other location in the mainfest file by the operator manually, the phase run will fail with conflicts.