From 993d13c4755b440ff8abb77e0f5fd49b61ab1b4a Mon Sep 17 00:00:00 2001 From: SirishaGopigiri Date: Wed, 27 Jan 2021 13:50:43 +0000 Subject: [PATCH] Reverting secret-generation template and adding examples This reverts commit bfe88fda569043eadfa2a4143ca40520d2b98aaa. We are also adding some README.md files and some example yaml for easy facilitation of secret generation. Reason for revert: Taking a different approach to implement secret generation https://review.opendev.org/c/airship/airshipctl/+/771736 Change-Id: Idea4271f99b4bc9f0f88440fc19b6ca44686cf2a --- .../generate-secrets-example/README.md | 118 ++++++++++++++++++ .../SecretGenerateExamples.md | 36 ++++++ .../kustomization.yaml | 2 + .../secret-generation.yaml | 39 ++++++ .../generate-certificates-template.yaml | 41 ------ .../generate-passphrases-template.yaml | 53 -------- .../generate-secrets/kustomization.yaml | 5 - .../replacements/kustomization.yaml | 4 - .../replacements/secrets.yaml | 27 ---- .../generatesecrets-example/README.md | 28 ----- .../generatesecrets-example/certificates.yaml | 20 --- .../kustomization.yaml | 5 - .../generatesecrets-example/passphrases.yaml | 40 ------ .../replacements/kustomization.yaml | 4 - .../replacements/secrets-replace.yaml | 33 ----- 15 files changed, 195 insertions(+), 260 deletions(-) create mode 100644 manifests/function/generate-secrets-example/README.md create mode 100644 manifests/function/generate-secrets-example/SecretGenerateExamples.md create mode 100644 manifests/function/generate-secrets-example/kustomization.yaml create mode 100644 manifests/function/generate-secrets-example/secret-generation.yaml delete mode 100644 manifests/function/generate-secrets/generate-certificates-template.yaml delete mode 100644 manifests/function/generate-secrets/generate-passphrases-template.yaml delete mode 100644 manifests/function/generate-secrets/kustomization.yaml delete mode 100644 manifests/function/generate-secrets/replacements/kustomization.yaml delete mode 100644 manifests/function/generate-secrets/replacements/secrets.yaml delete mode 100644 manifests/function/generatesecrets-example/README.md delete mode 100644 manifests/function/generatesecrets-example/certificates.yaml delete mode 100644 manifests/function/generatesecrets-example/kustomization.yaml delete mode 100644 manifests/function/generatesecrets-example/passphrases.yaml delete mode 100644 manifests/function/generatesecrets-example/replacements/kustomization.yaml delete mode 100644 manifests/function/generatesecrets-example/replacements/secrets-replace.yaml diff --git a/manifests/function/generate-secrets-example/README.md b/manifests/function/generate-secrets-example/README.md new file mode 100644 index 000000000..98312274f --- /dev/null +++ b/manifests/function/generate-secrets-example/README.md @@ -0,0 +1,118 @@ +Function: generate-secrets-example +================================= + +This function provide an example on how to generate secrets using templator +and variable catalogue. The generated secrets are usually of +`kind: VariableCatalogue`. These generated secrets then be used in +conjuction with `kind: ReplacementTransformer` to subsitute accordingly +in the site manifests. If the generated secrets needs to be deployed +on the cluster then define the secret as `kind: Secret` and appropriately +mark it with `deploy-k8s: true` annotation. + +## Generating & Encrypting Secrets + +Make a copy of this folder to the appropraite site for which secrets has to +be generated and then edit the [secret-generation.yaml](secret-generation.yaml) +with the required secret generation details. +For example refer to [generator](../../site/test-site/target/generator/) folder. + +Once the secret definitions are in place in the site manifests, we can +add a new phase to generate secrets pointing to the folder in site manifests. +Below is an example of how to add phase to the [phases.yaml](../../phases/phases.yaml). + +``` +apiVersion: airshipit.org/v1alpha1 +kind: Phase +metadata: + name: secret-generate +config: + executorRef: + apiVersion: airshipit.org/v1alpha1 + kind: GenericContainer + name: encrypter + documentEntryPoint: target/generator +``` + +The executorRef is of `kind: GenericContainer` and should also have the +following definition in [executor.yaml](../../phases/executor.yaml) + +``` +--- +apiVersion: airshipit.org/v1alpha1 +kind: GenericContainer +metadata: + name: encrypter + labels: + airshipit.org/deploy-k8s: "false" +kustomizeSinkOutputDir: "target/generator/results/generated" +spec: + container: + image: quay.io/aodinokov/sops:v0.0.3 + envs: + - SOPS_IMPORT_PGP + - SOPS_PGP_FP +config: | + apiVersion: v1 + kind: ConfigMap + data: + cmd: encrypt + unencrypted-regex: '^(kind|apiVersion|group|metadata)$' +``` + +The container spec in the `kind: GenericContainer` is specified with +sops spec so that the generated secrets would be encrypted and +then stored in the `kustomizeSinkOutputDir` directory. Sops uses pgp keys +and sops fingerprint key environment variable from the terminal to +perform encryption on the generated secrets. + +## Steps to execute using airshipctl command + +1. Sops environment variable has to be exported which will be +used for encryption. Download the sops key file. If you want to use +custom sops key copy it to the current location with filename as `key.asc`. + +`curl -fsSL -o key.asc https://raw.githubusercontent.com/mozilla/sops/master/pgp/sops_functional_tests_key.asc` + +2. Export key file and set corresponding fingerprint which will be +used for encryption. + +`export SOPS_IMPORT_PGP="$(cat key.asc)" && export SOPS_PGP_FP="FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4"` + +3. Then run the airshipctl command + +`airshipctl phase run ` + +Once the command executes successfully, we can see the generated and +encrypted secrets will be placed in `kustomizeSinkOutputDir`. + +## Generate Secrets without encryption(Not recommended) + +In case if no encryption is required for the secrets then use the below +`kind: GenericContainer` definition in the [executor.yaml](../../phases/executor.yaml) + +``` +--- +apiVersion: airshipit.org/v1alpha1 +kind: GenericContainer +metadata: + name: encrypter + labels: + airshipit.org/deploy-k8s: "false" +kustomizeSinkOutputDir: "target/generator/results/generated" +spec: + container: + image: quay.io/airshipit/templater:latest +config: | + foo: bar +``` + +## Decrypt to read the secrets + +To decrypt the secrets for readability purposes run the kustomize build +command on the generated secrets folder with the [kustomization.yaml](../../site/test-site/target/generator/results/kustomization.yaml) and [decrypt-secrets.yaml](../../site/test-site/target/generator/results/decrypt-secrets.yaml) +files in place in the same folder. + +Kustomize command to decrypt: + +`KUSTOMIZE_PLUGIN_HOME=$(pwd)/manifests SOPS_IMPORT_PGP=$(cat key.asc) kustomize build \ --enable_alpha_plugins \ +manifests/site/test-site/target/generator/results` \ No newline at end of file diff --git a/manifests/function/generate-secrets-example/SecretGenerateExamples.md b/manifests/function/generate-secrets-example/SecretGenerateExamples.md new file mode 100644 index 000000000..d9a2044ed --- /dev/null +++ b/manifests/function/generate-secrets-example/SecretGenerateExamples.md @@ -0,0 +1,36 @@ +## Secret Generation Examples + +Below examples show different function calls in templater that can be used for creation of secrets. + +1. derivePassword function to generate password +``` +password: {{ derivePassword 1 "long" (randAscii 10) "user" "example.com" }} +``` + +2. To generate randonm Ascii or AlphaNum or Numeric or Alpha keys +``` +test1: {{ randAlphaNum }} +test2: {{ randAlpha 5 }} +test3: {{ randNumeric 12 }} +test4: {{ randAscii 10 }} +``` + +3. Generate keys matching regex +``` +regexkey: {{ regexGen "abc[x-z]+" 6 }} +``` + +4. To generate certificate authorities +``` +{{- $ca := genCA }} +{{- $ca := genCA "foo-ca" 365 }} +{{- $ca := genCAWithKey "foo-ca" 365 (genPrivateKey "rsa") }} +``` + +5. Certificate generation(selfsigned and signed) +``` +{{- $cert := genSelfSignedCert }} +{{- $cert := genSelfSignedCertWithKey "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 (genPrivateKey "ecdsa") }} +{{- $cert := genSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 $ca }} +{{- $cert := genSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 $ca (genPrivateKey "ed25519")}} +``` \ No newline at end of file diff --git a/manifests/function/generate-secrets-example/kustomization.yaml b/manifests/function/generate-secrets-example/kustomization.yaml new file mode 100644 index 000000000..635c1de83 --- /dev/null +++ b/manifests/function/generate-secrets-example/kustomization.yaml @@ -0,0 +1,2 @@ +generators: + - secret-generation.yaml diff --git a/manifests/function/generate-secrets-example/secret-generation.yaml b/manifests/function/generate-secrets-example/secret-generation.yaml new file mode 100644 index 000000000..5c176f2bf --- /dev/null +++ b/manifests/function/generate-secrets-example/secret-generation.yaml @@ -0,0 +1,39 @@ +apiVersion: airshipit.org/v1alpha1 +kind: Templater +metadata: + name: secret-template + annotations: + config.kubernetes.io/function: | + container: + image: quay.io/airshipit/templater:latest +values: + clusterCa: + cn: "Kubernetes API" + validity: 3650 + password: + len: 1 + cap: "long" + masterKey: "test" + siteKey: "user" + sitePassword: "example.org" +template: | + apiVersion: airshipit.org/v1alpha1 + kind: VariableCatalogue + metadata: + labels: + airshipit.org/deploy-k8s: "false" + name: password-secret + annotations: + config.kubernetes.io/path: secrets.yaml + passkey: {{ derivePassword (.password.len|toUint32) .password.cap .password.masterKey .password.siteKey .password.sitePassword }} + rand1: {{ randAlphaNum 4 }} + rand2: {{ randAlpha 5 }} + rand3: {{ randNumeric 12 }} + rand4: {{ randAscii 10 }} + regexkey: {{ regexGen "ed[0-9]*[xY]{3,7}" 7 }} + {{- $ca := genCA .clusterCa.cn .clusterCa.validity }} + {{- $cert := genSignedCert "foo.com" (list "10.0.0.1" "10.0.0.2") (list "bar.com" "bat.com") 365 $ca }} + tls.key: {{ $ca.Key|b64enc|quote }} + tls.crt: {{ $ca.Cert|b64enc|quote }} + tlsCert.key: {{ $cert.Cert|b64enc|quote }} + tlsCert.crt: {{ $cert.Key|b64enc|quote }} \ No newline at end of file diff --git a/manifests/function/generate-secrets/generate-certificates-template.yaml b/manifests/function/generate-secrets/generate-certificates-template.yaml deleted file mode 100644 index d98a69525..000000000 --- a/manifests/function/generate-secrets/generate-certificates-template.yaml +++ /dev/null @@ -1,41 +0,0 @@ -apiVersion: airshipit.org/v1alpha1 -kind: Templater -metadata: - name: generate-certificates-template - annotations: - config.kubernetes.io/function: |- - container: - image: quay.io/airshipit/templater:latest -values: - certificates: -template: | - {{- range $key, $val := .certificates }} - {{- $secretName := $key }} - {{- $secret := $val }} - {{- $ca := "" }} - {{- if not .validity }} - {{- $_ := set . "validity" 365 }} - {{- end }} - {{- if not .cn }} - {{- $_ := set . "cn" "kubernetes" }} - {{- end }} - {{- if .keyEncoding }} - {{- $ca = genCAWithKey .cn .validity (genPrivateKey .keyEncoding)}} - {{- else}} - {{- $ca = genCA .cn .validity }} - {{end -}} - --- - apiVersion: v1 - kind: Secret - metadata: - name: {{ $secretName }} - {{- if $secret.deployk8s }} - namespace: {{ $secret.namespace | default "default" }} - {{- end }} - labels: - airshipit.org/deploy-k8s: {{ $secret.deployk8s | default "false" }} - data: - tls.crt: {{ $ca.Cert|b64enc|quote }} - tls.key: {{ $ca.Key|b64enc|quote }} - type: kubernetes.io/tls - {{ end -}} \ No newline at end of file diff --git a/manifests/function/generate-secrets/generate-passphrases-template.yaml b/manifests/function/generate-secrets/generate-passphrases-template.yaml deleted file mode 100644 index 456839986..000000000 --- a/manifests/function/generate-secrets/generate-passphrases-template.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: airshipit.org/v1alpha1 -kind: Templater -metadata: - name: generate-passphrases-template - annotations: - config.kubernetes.io/function: |- - container: - image: quay.io/airshipit/templater:latest -values: - passphrases: -template: | - {{- range $key, $val := .passphrases }} - {{- $secretName := $key }} - {{- $secret := $val }} - --- - apiVersion: v1 - kind: Secret - type: Opaque - metadata: - name: {{ $secretName }} - {{- if $secret.deployk8s }} - namespace: {{ $secret.namespace | default "default" }} - {{- end }} - labels: - airshipit.org/deploy-k8s: {{ $secret.deployk8s | default "false" }} - data: - {{range $secret.values -}} - {{- if not .keyName }} - {{- $_ := set . "keyName" "password" }} - {{- end }} - {{ if not .generationType -}} - {{- fail "no valid generationType specified!" }} - {{ end -}} - {{if eq .generationType "static" -}} - {{ .keyName }}: {{ .value | b64enc }} - {{else if eq .generationType "randAscii" -}} - {{ .keyName }}: {{ randAscii .length | b64enc }} - {{else if eq .generationType "randAlpha" -}} - {{ .keyName }}: {{ randAlpha .length | b64enc }} - {{else if eq .generationType "randAlphaNum" -}} - {{ .keyName }}: {{ randAlphaNum .length | b64enc }} - {{else if eq .generationType "randNumeric" -}} - {{ .keyName }}: {{ randNumeric .length | b64enc }} - {{else if eq .generationType "regexGen" -}} - {{ .keyName }}: {{ regexGen .regex (.limit | int) | b64enc }} - {{else if eq .generationType "derivePassword" -}} - {{ .keyName }}: {{ derivePassword (.length | toUint32) .passwordType .masterPassword .user .site | b64enc }} - {{else -}} - {{ $error := printf "%s is not a valid generationType!" .generationType }} - {{- fail $error }} - {{end}} - {{end -}} - {{end -}} diff --git a/manifests/function/generate-secrets/kustomization.yaml b/manifests/function/generate-secrets/kustomization.yaml deleted file mode 100644 index f938b4334..000000000 --- a/manifests/function/generate-secrets/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - generate-passphrases-template.yaml - - generate-certificates-template.yaml diff --git a/manifests/function/generate-secrets/replacements/kustomization.yaml b/manifests/function/generate-secrets/replacements/kustomization.yaml deleted file mode 100644 index e2740c9c9..000000000 --- a/manifests/function/generate-secrets/replacements/kustomization.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - secrets.yaml diff --git a/manifests/function/generate-secrets/replacements/secrets.yaml b/manifests/function/generate-secrets/replacements/secrets.yaml deleted file mode 100644 index 76444ce05..000000000 --- a/manifests/function/generate-secrets/replacements/secrets.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: airshipit.org/v1alpha1 -kind: ReplacementTransformer -metadata: - name: generate-secret-replacements - annotations: - config.kubernetes.io/function: |- - container: - image: quay.io/airshipit/replacement-transformer:latest -replacements: -- source: - objref: - name: generate-secret-catalogue - fieldref: "{.generate.passphrases}" - target: - objref: - kind: Templater - name: generate-passphrases-template - fieldrefs: ["{.values.passphrases}"] -- source: - objref: - name: generate-secret-catalogue - fieldref: "{.generate.certificates}" - target: - objref: - kind: Templater - name: generate-certificates-template - fieldrefs: ["{.values.certificates}"] diff --git a/manifests/function/generatesecrets-example/README.md b/manifests/function/generatesecrets-example/README.md deleted file mode 100644 index 373455499..000000000 --- a/manifests/function/generatesecrets-example/README.md +++ /dev/null @@ -1,28 +0,0 @@ -Function: generatesecrets-example -================================= - -This function defines a secrets variable catalogue profile that -can be consumed by the generate-secrets function to generate secrets. -Using this example we can build other catalogues to generate passphrases -and certificates. - -In the `example` defined passphrases and certificates fields are defined. -Sprig library templater functions and other custom defined functions -will be called to generate the respective passphrases and certificates. - -In passphrases catalogue the `generationType` field has to be specified, so that the -passphrase generation happens based on the function. Here is the list of valid -`generationType` functions supported as of now: `randAscii`, `randAlpha`, -`randAlphaNum`, `randNumeric`, `derivePassword`, `regexGen`. Along with the -`generationType` the corresponding fields for that function has to be specified. -Refer to the `example` for the required fields for specific `generationType`. -If no `generationType` or inavlid type is specified an appropriate -error will be thrown and execution fails. - -For certificate generation, commonName(`cn`), `validity`, `keyEncoding` are -the valid fields that are to be specified. If `cn` and `validity` are not -specified they take "kubernetes" and "365" days as default values. - -The `/replacements` kustomization contains a substitution rule that injects -the variables specified into the generate-secrets function template, which will be -used to generate the respective passphrases and certificates based on the variables. diff --git a/manifests/function/generatesecrets-example/certificates.yaml b/manifests/function/generatesecrets-example/certificates.yaml deleted file mode 100644 index d6a6da195..000000000 --- a/manifests/function/generatesecrets-example/certificates.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: airshipit.org/v1alpha1 -kind: VariableCatalogue -metadata: - # NOTE: change this when copying this example - name: certificates-example - labels: - airshipit.org/deploy-k8s: "false" -generate: - certificates: - ca-cert: - namespace: dummy - cn: kubernetes - validity: 20 - ca-cert-key: - deployk8s: true - keyEncoding: "rsa" - namespace: test - cn: k8 - validity: 365 - diff --git a/manifests/function/generatesecrets-example/kustomization.yaml b/manifests/function/generatesecrets-example/kustomization.yaml deleted file mode 100644 index c3fc341b0..000000000 --- a/manifests/function/generatesecrets-example/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - passphrases.yaml - - certificates.yaml diff --git a/manifests/function/generatesecrets-example/passphrases.yaml b/manifests/function/generatesecrets-example/passphrases.yaml deleted file mode 100644 index cae802c70..000000000 --- a/manifests/function/generatesecrets-example/passphrases.yaml +++ /dev/null @@ -1,40 +0,0 @@ -apiVersion: airshipit.org/v1alpha1 -kind: VariableCatalogue -metadata: - # NOTE: change this when copying this example - name: passphrases-example - labels: - airshipit.org/deploy-k8s: "false" -generate: - passphrases: - secret1: - namespace: ns1 - deployk8s: true - values: - - keyName: key1 - generationType: derivePassword - passwordType: long - user: test - site: example.com - masterPassword: master - length: 2 - - generationType: randAlpha - length: 3 - - keyName: key3 - generationType: static - value: mypass - - keyName: key4 - generationType: randAlphaNum - length: 4 - - keyName: key5 - generationType: randNumeric - length: 5 - secret2: - namespace: test - values: - - generationType: randAscii - length: 3 - - keyName: key2 - generationType: regexGen - regex: "[efghul][a-z]{2,3}[0-9]{2,8}" - limit: 10 diff --git a/manifests/function/generatesecrets-example/replacements/kustomization.yaml b/manifests/function/generatesecrets-example/replacements/kustomization.yaml deleted file mode 100644 index cdaa6406c..000000000 --- a/manifests/function/generatesecrets-example/replacements/kustomization.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - secrets-replace.yaml diff --git a/manifests/function/generatesecrets-example/replacements/secrets-replace.yaml b/manifests/function/generatesecrets-example/replacements/secrets-replace.yaml deleted file mode 100644 index d70e7fcff..000000000 --- a/manifests/function/generatesecrets-example/replacements/secrets-replace.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# These rules inject passphrases and certificate variable values -# from the `generate-secret-catalogue` into the `generate-passphrases-template` -# and `generate-certificates-template` function's Template plugin configs respectively. -apiVersion: airshipit.org/v1alpha1 -kind: ReplacementTransformer -metadata: - # NOTE: change this when copying this example - name: generatesecrets-example-replacements - annotations: - config.kubernetes.io/function: |- - container: - image: quay.io/airshipit/replacement-transformer:latest -replacements: -- source: - objref: - # NOTE: change this to match your passphrases's metadata.name - name: passphrases-example - fieldref: "{.generate.passphrases}" - target: - objref: - kind: Templater - name: generate-passphrases-template - fieldrefs: ["{.values.passphrases}"] -- source: - objref: - # NOTE: change this to match your certificates's metadata.name - name: certificates-example - fieldref: "{.generate.certificates}" - target: - objref: - kind: Templater - name: generate-certificates-template - fieldrefs: ["{.values.certificates}"]