feat: add amphora jumpbox on k8s (#883)

Co-authored-by: okozachenko1203 <okozachenko1203@users.noreply.github.com>
Co-authored-by: Mohammed Naser <mnaser@vexxhost.com>
diff --git a/roles/defaults/vars/main.yml b/roles/defaults/vars/main.yml
index dc34073..be719d5 100644
--- a/roles/defaults/vars/main.yml
+++ b/roles/defaults/vars/main.yml
@@ -147,12 +147,12 @@
   nova_service_cleaner: ghcr.io/vexxhost/atmosphere/heat:2023.2@sha256:c5118e27245b53db06e5098e980816d5f2a8f2615dde49d5e0c5b3172ee69bf6
   nova_spiceproxy_assets: ghcr.io/vexxhost/atmosphere/nova:zed@sha256:584c9e0a1c503110c95ff511610993e9b41d99091579291c7726db155b6fa0ca
   nova_spiceproxy: ghcr.io/vexxhost/atmosphere/nova:zed@sha256:584c9e0a1c503110c95ff511610993e9b41d99091579291c7726db155b6fa0ca
-  octavia_api: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:7b865b938379bcd75eeb90a457a2a19a6a70c0cf28fea250777ca75974ea1389
-  octavia_db_sync: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:7b865b938379bcd75eeb90a457a2a19a6a70c0cf28fea250777ca75974ea1389
+  octavia_api: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:52d00cb9b4a42a915a52956e4fad09e71f43e79d1a5a55bf538879a6602f7348
+  octavia_db_sync: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:52d00cb9b4a42a915a52956e4fad09e71f43e79d1a5a55bf538879a6602f7348
   octavia_health_manager_init: ghcr.io/vexxhost/atmosphere/heat:2023.2@sha256:c5118e27245b53db06e5098e980816d5f2a8f2615dde49d5e0c5b3172ee69bf6
-  octavia_health_manager: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:7b865b938379bcd75eeb90a457a2a19a6a70c0cf28fea250777ca75974ea1389
-  octavia_housekeeping: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:7b865b938379bcd75eeb90a457a2a19a6a70c0cf28fea250777ca75974ea1389
-  octavia_worker: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:7b865b938379bcd75eeb90a457a2a19a6a70c0cf28fea250777ca75974ea1389
+  octavia_health_manager: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:52d00cb9b4a42a915a52956e4fad09e71f43e79d1a5a55bf538879a6602f7348
+  octavia_housekeeping: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:52d00cb9b4a42a915a52956e4fad09e71f43e79d1a5a55bf538879a6602f7348
+  octavia_worker: ghcr.io/vexxhost/atmosphere/octavia:2023.2@sha256:52d00cb9b4a42a915a52956e4fad09e71f43e79d1a5a55bf538879a6602f7348
   openvswitch_db_server: ghcr.io/vexxhost/atmosphere/openvswitch:3.1.0-65@sha256:c68347b6b1479fda5ccf3165492b989ebe49985fa30661ed4f1ea208fa2a110e
   openvswitch_vswitchd: ghcr.io/vexxhost/atmosphere/openvswitch:3.1.0-65@sha256:c68347b6b1479fda5ccf3165492b989ebe49985fa30661ed4f1ea208fa2a110e
   ovn_controller: ghcr.io/vexxhost/atmosphere/ovn-host:23.03.0-69@sha256:03b4174e347d14e370aff7399a34f5fcbab1176dcf72c22ffbb0e8c1f66628a6
@@ -182,6 +182,7 @@
   rabbitmq_server: docker.io/library/rabbitmq:3.10.2-management@sha256:350ab6d773e3af45183466488fe3259df36cd6ade437b4366a59e8052458cc3a
   rabbitmq_topology_operator: docker.io/rabbitmqoperator/messaging-topology-operator:1.6.0@sha256:5052e8bdb26996c62315f0707c6fb291fd84492e360cca7351e2c3fdf659be43
   rook_ceph: docker.io/rook/ceph:v1.10.10@sha256:9ae0eca578ef6e38492e5f90073050491382d8772914ddb8ffe4fca8d365b850
+  secretgen_controller: ghcr.io/carvel-dev/secretgen-controller@sha256:59ec05ce5847bfd70c8e04f08b5195e918c8f6fbb947ffc91b456494a2958fd5
   senlin_api: ghcr.io/vexxhost/atmosphere/senlin:2023.2@sha256:f718174547f3f66e5af758a10c87f7a75e9cbe1fe277cef27130fd512f727401
   senlin_conductor: ghcr.io/vexxhost/atmosphere/senlin:2023.2@sha256:f718174547f3f66e5af758a10c87f7a75e9cbe1fe277cef27130fd512f727401
   senlin_db_sync: ghcr.io/vexxhost/atmosphere/senlin:2023.2@sha256:f718174547f3f66e5af758a10c87f7a75e9cbe1fe277cef27130fd512f727401
diff --git a/roles/octavia/meta/main.yml b/roles/octavia/meta/main.yml
index b049eb4..e022886 100644
--- a/roles/octavia/meta/main.yml
+++ b/roles/octavia/meta/main.yml
@@ -33,3 +33,4 @@
     vars:
       upload_helm_chart_src: "{{ octavia_helm_chart_path }}"
       upload_helm_chart_dest: "{{ octavia_helm_chart_ref }}"
+  - role: secretgen_controller
diff --git a/roles/octavia/tasks/generate_resources.yml b/roles/octavia/tasks/generate_resources.yml
index be003ab..1c4c87e 100644
--- a/roles/octavia/tasks/generate_resources.yml
+++ b/roles/octavia/tasks/generate_resources.yml
@@ -152,3 +152,43 @@
     cloud: atmosphere
     image: "{{ octavia_amphora_image_name }}"
   register: _octavia_amphora_image
+
+- name: Create Amphora SSH key
+  run_once: true
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: secretgen.k14s.io/v1alpha1
+      kind: SSHKey
+      metadata:
+        name: "{{ octavia_helm_release_name }}-amphora-ssh-key"
+        namespace: "{{ octavia_helm_release_namespace }}"
+      spec:
+        secretTemplate:
+          type: Opaque
+          stringData:
+            id_rsa: $(privateKey)
+            id_rsa.pub: $(authorizedKey)
+    wait: true
+    wait_timeout: 60
+    wait_condition:
+      type: ReconcileSucceeded
+      status: true
+
+- name: Grab generated Amphora public key
+  run_once: true
+  kubernetes.core.k8s_info:
+    api_version: v1
+    kind: Secret
+    name: "{{ octavia_helm_release_name }}-amphora-ssh-key"
+    namespace: "{{ octavia_helm_release_namespace }}"
+  register: octavia_ssh_key_secret
+
+- name: Import Amphora SSH key-pair in OpenStack
+  run_once: true
+  openstack.cloud.keypair:
+    cloud: atmosphere
+    state: present
+    name: "{{ octavia_helm_release_name }}-amphora-ssh-key"
+    public_key: "{{ octavia_ssh_key_secret.resources[0]['data']['id_rsa.pub'] | b64decode }}"
+  register: octavia_amphora_ssh_keypair
diff --git a/roles/octavia/vars/main.yml b/roles/octavia/vars/main.yml
index a137ae5..2a69cd9 100644
--- a/roles/octavia/vars/main.yml
+++ b/roles/octavia/vars/main.yml
@@ -39,6 +39,16 @@
               mountPath: /etc/octavia/certs/server
             - name: octavia-client-certs
               mountPath: /etc/octavia/certs/client
+            - name: octavia-amphora-ssh-key-dir
+              mountPath: /var/lib/octavia/.ssh
+            - name: octavia-amphora-ssh-key
+              mountPath: /var/lib/octavia/.ssh/id_rsa
+              subPath: id_rsa
+              readOnly: true
+            - name: octavia-amphora-ssh-key
+              mountPath: /var/lib/octavia/.ssh/id_rsa.pub
+              subPath: id_rsa.pub
+              readOnly: true
           volumes:
             - name: octavia-server-ca
               secret:
@@ -46,6 +56,14 @@
             - name: octavia-client-certs
               secret:
                 secretName: octavia-client-certs
+            - name: octavia-amphora-ssh-key-dir
+              emptyDir: {}
+            - name: octavia-amphora-ssh-key
+              secret:
+                secretName: "{{ octavia_ssh_key_secret.resources[0]['metadata']['name'] }}"
+                defaultMode: 0444 # noqa: yaml[octal-values]
+            - name: octavia-amphora-ssh-key-dir
+              emptyDir: {}
       octavia_housekeeping:
         octavia_housekeeping:
           volumeMounts:
@@ -94,7 +112,7 @@
         amp_flavor_id: "{{ _octavia_amphora_flavor.id }}"
         amp_image_owner_id: "{{ _octavia_amphora_image.openstack_image.owner }}"
         amp_secgroup_list: "{{ _octavia_amphora_sg.id }}"
-        amp_ssh_key_name: null
+        amp_ssh_key_name: "{{ octavia_amphora_ssh_keypair.key.name }}"
         client_ca: /etc/octavia/certs/client/ca.crt
         volume_driver: volume_cinder_driver
         workers: 4
diff --git a/roles/secretgen_controller/README.md b/roles/secretgen_controller/README.md
new file mode 100644
index 0000000..aef2b92
--- /dev/null
+++ b/roles/secretgen_controller/README.md
@@ -0,0 +1 @@
+# `secretgen_controller`
diff --git a/roles/secretgen_controller/meta/main.yml b/roles/secretgen_controller/meta/main.yml
new file mode 100644
index 0000000..dce41d4
--- /dev/null
+++ b/roles/secretgen_controller/meta/main.yml
@@ -0,0 +1,27 @@
+# Copyright (c) 2022 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+galaxy_info:
+  author: VEXXHOST, Inc.
+  description: Ansible role for secret-gen controller
+  license: Apache-2.0
+  min_ansible_version: 5.5.0
+  standalone: false
+  platforms:
+    - name: Ubuntu
+      versions:
+        - focal
+
+dependencies:
+  - role: defaults
diff --git a/roles/secretgen_controller/tasks/main.yml b/roles/secretgen_controller/tasks/main.yml
new file mode 100644
index 0000000..de7827b
--- /dev/null
+++ b/roles/secretgen_controller/tasks/main.yml
@@ -0,0 +1,18 @@
+# Copyright (c) 2022 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+- name: Deploy secretgen-controller
+  kubernetes.core.k8s:
+    state: present
+    template: release.yml.tpl
diff --git a/roles/secretgen_controller/templates/release.yml.tpl b/roles/secretgen_controller/templates/release.yml.tpl
new file mode 100644
index 0000000..a976db2
--- /dev/null
+++ b/roles/secretgen_controller/templates/release.yml.tpl
@@ -0,0 +1,902 @@
+# https://github.com/carvel-dev/secretgen-controller/releases/download/v0.16.0/release.yml

+---

+apiVersion: v1

+kind: Namespace

+metadata:

+  name: secretgen-controller

+---

+apiVersion: apiextensions.k8s.io/v1

+kind: CustomResourceDefinition

+metadata:

+  name: secretexports.secretgen.carvel.dev

+spec:

+  group: secretgen.carvel.dev

+  names:

+    kind: SecretExport

+    listKind: SecretExportList

+    plural: secretexports

+    singular: secretexport

+  scope: Namespaced

+  versions:

+  - additionalPrinterColumns:

+    - description: Friendly description

+      jsonPath: .status.friendlyDescription

+      name: Description

+      type: string

+    - description: Time since creation

+      jsonPath: .metadata.creationTimestamp

+      name: Age

+      type: date

+    name: v1alpha1

+    schema:

+      openAPIV3Schema:

+        properties:

+          apiVersion:

+            description: 'APIVersion defines the versioned schema of this representation

+              of an object. Servers should convert recognized schemas to the latest

+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'

+            type: string

+          kind:

+            description: 'Kind is a string value representing the REST resource this

+              object represents. Servers may infer this from the endpoint the client

+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'

+            type: string

+          metadata:

+            type: object

+          spec:

+            properties:

+              dangerousToNamespacesSelector:

+                items:

+                  properties:

+                    key:

+                      description: Property to target the resource for the match.

+                        It supports dot notation.

+                      type: string

+                    operator:

+                      description: Type of comparison.

+                      enum:

+                      - In

+                      - NotIn

+                      - Exists

+                      - DoesNotExist

+                      type: string

+                    values:

+                      description: Values to match on the resource key using the comparison

+                        operator.

+                      items:

+                        type: string

+                      type: array

+                  required:

+                  - key

+                  - operator

+                  type: object

+                type: array

+              toNamespace:

+                type: string

+              toNamespaces:

+                items:

+                  type: string

+                type: array

+            type: object

+          status:

+            properties:

+              conditions:

+                items:

+                  properties:

+                    message:

+                      description: Human-readable message indicating details about

+                        last transition.

+                      type: string

+                    reason:

+                      description: Unique, this should be a short, machine understandable

+                        string that gives the reason for condition's last transition.

+                        If it reports "ResizeStarted" that means the underlying persistent

+                        volume is being resized.

+                      type: string

+                    status:

+                      type: string

+                    type:

+                      type: string

+                  type: object

+                type: array

+              friendlyDescription:

+                type: string

+              observedGeneration:

+                format: int64

+                type: integer

+              observedSecretResourceVersion:

+                type: string

+            type: object

+        required:

+        - spec

+        type: object

+    served: true

+    storage: true

+    subresources:

+      status: {}

+---

+apiVersion: apiextensions.k8s.io/v1

+kind: CustomResourceDefinition

+metadata:

+  name: secretimports.secretgen.carvel.dev

+spec:

+  group: secretgen.carvel.dev

+  names:

+    kind: SecretImport

+    listKind: SecretImportList

+    plural: secretimports

+    singular: secretimport

+  scope: Namespaced

+  versions:

+  - additionalPrinterColumns:

+    - description: Friendly description

+      jsonPath: .status.friendlyDescription

+      name: Description

+      type: string

+    - description: Time since creation

+      jsonPath: .metadata.creationTimestamp

+      name: Age

+      type: date

+    name: v1alpha1

+    schema:

+      openAPIV3Schema:

+        properties:

+          apiVersion:

+            description: 'APIVersion defines the versioned schema of this representation

+              of an object. Servers should convert recognized schemas to the latest

+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'

+            type: string

+          kind:

+            description: 'Kind is a string value representing the REST resource this

+              object represents. Servers may infer this from the endpoint the client

+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'

+            type: string

+          metadata:

+            type: object

+          spec:

+            properties:

+              fromNamespace:

+                type: string

+            type: object

+          status:

+            properties:

+              conditions:

+                items:

+                  properties:

+                    message:

+                      description: Human-readable message indicating details about

+                        last transition.

+                      type: string

+                    reason:

+                      description: Unique, this should be a short, machine understandable

+                        string that gives the reason for condition's last transition.

+                        If it reports "ResizeStarted" that means the underlying persistent

+                        volume is being resized.

+                      type: string

+                    status:

+                      type: string

+                    type:

+                      type: string

+                  type: object

+                type: array

+              friendlyDescription:

+                type: string

+              observedGeneration:

+                format: int64

+                type: integer

+            type: object

+        required:

+        - spec

+        type: object

+    served: true

+    storage: true

+    subresources:

+      status: {}

+---

+apiVersion: apiextensions.k8s.io/v1

+kind: CustomResourceDefinition

+metadata:

+  name: secrettemplates.secretgen.carvel.dev

+spec:

+  group: secretgen.carvel.dev

+  names:

+    kind: SecretTemplate

+    listKind: SecretTemplateList

+    plural: secrettemplates

+    singular: secrettemplate

+  scope: Namespaced

+  versions:

+  - additionalPrinterColumns:

+    - description: Friendly description

+      jsonPath: .status.friendlyDescription

+      name: Description

+      type: string

+    - description: Time since creation

+      jsonPath: .metadata.creationTimestamp

+      name: Age

+      type: date

+    name: v1alpha1

+    schema:

+      openAPIV3Schema:

+        description: SecretTemplate allows the construction of secrets using data

+          that reside in other Kubernetes resources

+        properties:

+          apiVersion:

+            description: 'APIVersion defines the versioned schema of this representation

+              of an object. Servers should convert recognized schemas to the latest

+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'

+            type: string

+          kind:

+            description: 'Kind is a string value representing the REST resource this

+              object represents. Servers may infer this from the endpoint the client

+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'

+            type: string

+          metadata:

+            type: object

+          spec:

+            description: SecretTemplateSpec contains spec information

+            properties:

+              inputResources:

+                description: A list of input resources that are used to construct

+                  a new secret. Input Resources can refer to ANY Kubernetes API. If

+                  loading more than Secrets types ensure that `.spec.ServiceAccountName`

+                  is set to an appropriate value. Input resources are read in the

+                  order they are defined. An Input resource's name can be evaluated

+                  dynamically from data in a previously evaluated input resource.

+                items:

+                  description: InputResource is references a single Kubernetes resource

+                    along with a identifying name

+                  properties:

+                    name:

+                      description: The name of InputResource. This is used as the

+                        identifying name in templating to refer to this Input Resource.

+                      type: string

+                    ref:

+                      description: The reference to the Input Resource

+                      properties:

+                        apiVersion:

+                          type: string

+                        kind:

+                          type: string

+                        name:

+                          description: The name of the input resource. This field

+                            can itself contain JSONPATH syntax to load the name dynamically

+                            from other input resources. For example this field could

+                            be set to a static value of "my-secret" or a dynamic valid

+                            of "$(.anotherinputresource.spec.name)".

+                          type: string

+                      required:

+                      - apiVersion

+                      - kind

+                      - name

+                      type: object

+                  required:

+                  - name

+                  - ref

+                  type: object

+                type: array

+              serviceAccountName:

+                description: The Service Account used to read InputResources. If not

+                  specified, only Secrets can be read as InputResources.

+                type: string

+              template:

+                description: A JSONPath based template that can be used to create

+                  Secrets.

+                properties:

+                  data:

+                    additionalProperties:

+                      type: string

+                    description: 'Data key and value. Where key is the Secret Key

+                      and the value is a jsonpath surrounded by $( ). The fetched

+                      data MUST be base64 encoded. All InputResources are available

+                      via their identifying name. For example: key1: $(.secretinput1.data.value1)

+                      key2: $(.secretinput2.data.value2)'

+                    type: object

+                  metadata:

+                    description: Metadata contains metadata for the Secret

+                    properties:

+                      annotations:

+                        additionalProperties:

+                          type: string

+                        description: Annotations to be placed on the generated secret

+                        type: object

+                      labels:

+                        additionalProperties:

+                          type: string

+                        description: Labels to be placed on the generated secret

+                        type: object

+                    type: object

+                  stringData:

+                    additionalProperties:

+                      type: string

+                    description: 'StringData key and value. Where key is the Secret

+                      Key and the value can contain a JSONPATH syntax surrounded by

+                      $( ). All InputResources are available via their identifying

+                      name. For example: key1: static-text key2: $(.input1.spec.value1)

+                      key3: combined-$(.input2.status.value2)-$(.input2.status.value3)'

+                    type: object

+                  type:

+                    description: Type is the type of Kubernetes Secret

+                    type: string

+                type: object

+            required:

+            - inputResources

+            type: object

+          status:

+            description: SecretTemplateStatus contains status information

+            properties:

+              conditions:

+                items:

+                  properties:

+                    message:

+                      description: Human-readable message indicating details about

+                        last transition.

+                      type: string

+                    reason:

+                      description: Unique, this should be a short, machine understandable

+                        string that gives the reason for condition's last transition.

+                        If it reports "ResizeStarted" that means the underlying persistent

+                        volume is being resized.

+                      type: string

+                    status:

+                      type: string

+                    type:

+                      type: string

+                  type: object

+                type: array

+              friendlyDescription:

+                type: string

+              observedGeneration:

+                format: int64

+                type: integer

+              observedSecretResourceVersion:

+                type: string

+              secret:

+                description: LocalObjectReference contains enough information to let

+                  you locate the referenced object inside the same namespace.

+                properties:

+                  name:

+                    description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

+                      TODO: Add other useful fields. apiVersion, kind, uid?'

+                    type: string

+                type: object

+                x-kubernetes-map-type: atomic

+            type: object

+        required:

+        - spec

+        type: object

+    served: true

+    storage: true

+    subresources:

+      status: {}

+---

+apiVersion: apiextensions.k8s.io/v1

+kind: CustomResourceDefinition

+metadata:

+  name: certificates.secretgen.k14s.io

+spec:

+  group: secretgen.k14s.io

+  names:

+    kind: Certificate

+    listKind: CertificateList

+    plural: certificates

+    singular: certificate

+  scope: Namespaced

+  versions:

+  - additionalPrinterColumns:

+    - description: Friendly description

+      jsonPath: .status.friendlyDescription

+      name: Description

+      type: string

+    - description: Time since creation

+      jsonPath: .metadata.creationTimestamp

+      name: Age

+      type: date

+    name: v1alpha1

+    schema:

+      openAPIV3Schema:

+        properties:

+          apiVersion:

+            description: 'APIVersion defines the versioned schema of this representation

+              of an object. Servers should convert recognized schemas to the latest

+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'

+            type: string

+          kind:

+            description: 'Kind is a string value representing the REST resource this

+              object represents. Servers may infer this from the endpoint the client

+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'

+            type: string

+          metadata:

+            type: object

+          spec:

+            properties:

+              alternativeNames:

+                items:

+                  type: string

+                type: array

+              caRef:

+                description: LocalObjectReference contains enough information to let

+                  you locate the referenced object inside the same namespace.

+                properties:

+                  name:

+                    description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

+                      TODO: Add other useful fields. apiVersion, kind, uid?'

+                    type: string

+                type: object

+                x-kubernetes-map-type: atomic

+              commonName:

+                type: string

+              duration:

+                format: int64

+                type: integer

+              extendedKeyUsage:

+                items:

+                  type: string

+                type: array

+              isCA:

+                type: boolean

+              organization:

+                type: string

+              secretTemplate:

+                properties:

+                  metadata:

+                    properties:

+                      annotations:

+                        additionalProperties:

+                          type: string

+                        type: object

+                      labels:

+                        additionalProperties:

+                          type: string

+                        type: object

+                    type: object

+                  stringData:

+                    additionalProperties:

+                      type: string

+                    type: object

+                  type:

+                    type: string

+                type: object

+            type: object

+          status:

+            properties:

+              conditions:

+                items:

+                  properties:

+                    message:

+                      description: Human-readable message indicating details about

+                        last transition.

+                      type: string

+                    reason:

+                      description: Unique, this should be a short, machine understandable

+                        string that gives the reason for condition's last transition.

+                        If it reports "ResizeStarted" that means the underlying persistent

+                        volume is being resized.

+                      type: string

+                    status:

+                      type: string

+                    type:

+                      type: string

+                  type: object

+                type: array

+              friendlyDescription:

+                type: string

+              observedGeneration:

+                format: int64

+                type: integer

+            type: object

+        type: object

+    served: true

+    storage: true

+    subresources:

+      status: {}

+---

+apiVersion: apiextensions.k8s.io/v1

+kind: CustomResourceDefinition

+metadata:

+  name: passwords.secretgen.k14s.io

+spec:

+  group: secretgen.k14s.io

+  names:

+    kind: Password

+    listKind: PasswordList

+    plural: passwords

+    singular: password

+  scope: Namespaced

+  versions:

+  - additionalPrinterColumns:

+    - description: Friendly description

+      jsonPath: .status.friendlyDescription

+      name: Description

+      type: string

+    - description: Time since creation

+      jsonPath: .metadata.creationTimestamp

+      name: Age

+      type: date

+    name: v1alpha1

+    schema:

+      openAPIV3Schema:

+        properties:

+          apiVersion:

+            description: 'APIVersion defines the versioned schema of this representation

+              of an object. Servers should convert recognized schemas to the latest

+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'

+            type: string

+          kind:

+            description: 'Kind is a string value representing the REST resource this

+              object represents. Servers may infer this from the endpoint the client

+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'

+            type: string

+          metadata:

+            type: object

+          spec:

+            properties:

+              digits:

+                default: 0

+                type: integer

+              length:

+                default: 40

+                type: integer

+              lowercaseLetters:

+                default: 0

+                type: integer

+              secretTemplate:

+                properties:

+                  metadata:

+                    properties:

+                      annotations:

+                        additionalProperties:

+                          type: string

+                        type: object

+                      labels:

+                        additionalProperties:

+                          type: string

+                        type: object

+                    type: object

+                  stringData:

+                    additionalProperties:

+                      type: string

+                    type: object

+                  type:

+                    type: string

+                type: object

+              symbolCharSet:

+                default: '!@#$%&*;.:'

+                type: string

+              symbols:

+                default: 0

+                type: integer

+              uppercaseLetters:

+                default: 0

+                type: integer

+            type: object

+          status:

+            properties:

+              conditions:

+                items:

+                  properties:

+                    message:

+                      description: Human-readable message indicating details about

+                        last transition.

+                      type: string

+                    reason:

+                      description: Unique, this should be a short, machine understandable

+                        string that gives the reason for condition's last transition.

+                        If it reports "ResizeStarted" that means the underlying persistent

+                        volume is being resized.

+                      type: string

+                    status:

+                      type: string

+                    type:

+                      type: string

+                  type: object

+                type: array

+              friendlyDescription:

+                type: string

+              observedGeneration:

+                format: int64

+                type: integer

+            type: object

+        type: object

+    served: true

+    storage: true

+    subresources:

+      status: {}

+---

+apiVersion: apiextensions.k8s.io/v1

+kind: CustomResourceDefinition

+metadata:

+  name: rsakeys.secretgen.k14s.io

+spec:

+  group: secretgen.k14s.io

+  names:

+    kind: RSAKey

+    listKind: RSAKeyList

+    plural: rsakeys

+    singular: rsakey

+  scope: Namespaced

+  versions:

+  - additionalPrinterColumns:

+    - description: Friendly description

+      jsonPath: .status.friendlyDescription

+      name: Description

+      type: string

+    - description: Time since creation

+      jsonPath: .metadata.creationTimestamp

+      name: Age

+      type: date

+    name: v1alpha1

+    schema:

+      openAPIV3Schema:

+        properties:

+          apiVersion:

+            description: 'APIVersion defines the versioned schema of this representation

+              of an object. Servers should convert recognized schemas to the latest

+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'

+            type: string

+          kind:

+            description: 'Kind is a string value representing the REST resource this

+              object represents. Servers may infer this from the endpoint the client

+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'

+            type: string

+          metadata:

+            type: object

+          spec:

+            properties:

+              secretTemplate:

+                properties:

+                  metadata:

+                    properties:

+                      annotations:

+                        additionalProperties:

+                          type: string

+                        type: object

+                      labels:

+                        additionalProperties:

+                          type: string

+                        type: object

+                    type: object

+                  stringData:

+                    additionalProperties:

+                      type: string

+                    type: object

+                  type:

+                    type: string

+                type: object

+            type: object

+          status:

+            properties:

+              conditions:

+                items:

+                  properties:

+                    message:

+                      description: Human-readable message indicating details about

+                        last transition.

+                      type: string

+                    reason:

+                      description: Unique, this should be a short, machine understandable

+                        string that gives the reason for condition's last transition.

+                        If it reports "ResizeStarted" that means the underlying persistent

+                        volume is being resized.

+                      type: string

+                    status:

+                      type: string

+                    type:

+                      type: string

+                  type: object

+                type: array

+              friendlyDescription:

+                type: string

+              observedGeneration:

+                format: int64

+                type: integer

+            type: object

+        type: object

+    served: true

+    storage: true

+    subresources:

+      status: {}

+---

+apiVersion: apiextensions.k8s.io/v1

+kind: CustomResourceDefinition

+metadata:

+  name: sshkeys.secretgen.k14s.io

+spec:

+  group: secretgen.k14s.io

+  names:

+    kind: SSHKey

+    listKind: SSHKeyList

+    plural: sshkeys

+    singular: sshkey

+  scope: Namespaced

+  versions:

+  - additionalPrinterColumns:

+    - description: Friendly description

+      jsonPath: .status.friendlyDescription

+      name: Description

+      type: string

+    - description: Time since creation

+      jsonPath: .metadata.creationTimestamp

+      name: Age

+      type: date

+    name: v1alpha1

+    schema:

+      openAPIV3Schema:

+        properties:

+          apiVersion:

+            description: 'APIVersion defines the versioned schema of this representation

+              of an object. Servers should convert recognized schemas to the latest

+              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'

+            type: string

+          kind:

+            description: 'Kind is a string value representing the REST resource this

+              object represents. Servers may infer this from the endpoint the client

+              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'

+            type: string

+          metadata:

+            type: object

+          spec:

+            properties:

+              secretTemplate:

+                properties:

+                  metadata:

+                    properties:

+                      annotations:

+                        additionalProperties:

+                          type: string

+                        type: object

+                      labels:

+                        additionalProperties:

+                          type: string

+                        type: object

+                    type: object

+                  stringData:

+                    additionalProperties:

+                      type: string

+                    type: object

+                  type:

+                    type: string

+                type: object

+            type: object

+          status:

+            properties:

+              conditions:

+                items:

+                  properties:

+                    message:

+                      description: Human-readable message indicating details about

+                        last transition.

+                      type: string

+                    reason:

+                      description: Unique, this should be a short, machine understandable

+                        string that gives the reason for condition's last transition.

+                        If it reports "ResizeStarted" that means the underlying persistent

+                        volume is being resized.

+                      type: string

+                    status:

+                      type: string

+                    type:

+                      type: string

+                  type: object

+                type: array

+              friendlyDescription:

+                type: string

+              observedGeneration:

+                format: int64

+                type: integer

+            type: object

+        type: object

+    served: true

+    storage: true

+    subresources:

+      status: {}

+---

+apiVersion: apps/v1

+kind: Deployment

+metadata:

+  annotations:

+    kbld.k14s.io/images: |

+      - origins:

+        - local:

+            path: /home/runner/work/secretgen-controller/secretgen-controller

+        - git:

+            dirty: true

+            remoteURL: https://github.com/carvel-dev/secretgen-controller

+            sha: d806899d96fcb5a07ff2e38f93e37884a3db2b1d

+            tags:

+            - v0.16.0

+        url: ghcr.io/carvel-dev/secretgen-controller@sha256:59ec05ce5847bfd70c8e04f08b5195e918c8f6fbb947ffc91b456494a2958fd5

+    secretgen-controller.carvel.dev/version: v0.16.0

+  name: secretgen-controller

+  namespace: secretgen-controller

+spec:

+  replicas: 1

+  revisionHistoryLimit: 0

+  selector:

+    matchLabels:

+      app: secretgen-controller

+  template:

+    metadata:

+      labels:

+        app: secretgen-controller

+    spec:

+      containers:

+      - image: "{{ atmosphere_images['secretgen_controller'] | vexxhost.kubernetes.docker_image('ref') }}"

+        name: secretgen-controller

+        resources:

+          requests:

+            cpu: 120m

+            memory: 100Mi

+        securityContext:

+          allowPrivilegeEscalation: false

+          capabilities:

+            drop:

+            - ALL

+          readOnlyRootFilesystem: true

+          runAsNonRoot: true

+      serviceAccount: secretgen-controller-sa

+---

+apiVersion: v1

+kind: ServiceAccount

+metadata:

+  name: secretgen-controller-sa

+  namespace: secretgen-controller

+---

+apiVersion: rbac.authorization.k8s.io/v1

+kind: ClusterRole

+metadata:

+  name: secretgen-controller-cluster-role

+rules:

+- apiGroups:

+  - secretgen.k14s.io

+  resources:

+  - '*'

+  verbs:

+  - '*'

+- apiGroups:

+  - secretgen.carvel.dev

+  resources:

+  - '*'

+  verbs:

+  - '*'

+- apiGroups:

+  - ""

+  resources:

+  - secrets

+  verbs:

+  - '*'

+- apiGroups:

+  - ""

+  resources:

+  - namespaces

+  verbs:

+  - list

+  - watch

+  - get

+- apiGroups:

+  - ""

+  resources:

+  - serviceaccounts

+  verbs:

+  - list

+  - watch

+  - get

+- apiGroups:

+  - ""

+  resources:

+  - serviceaccounts/token

+  verbs:

+  - create

+---

+apiVersion: rbac.authorization.k8s.io/v1

+kind: ClusterRoleBinding

+metadata:

+  name: secretgen-controller-cluster-role-binding

+roleRef:

+  apiGroup: rbac.authorization.k8s.io

+  kind: ClusterRole

+  name: secretgen-controller-cluster-role

+subjects:

+- kind: ServiceAccount

+  name: secretgen-controller-sa

+  namespace: secretgen-controller