From b487b4a5e06cd18b401e229a26499453c2254fd3 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Tue, 9 May 2023 17:30:36 +0200 Subject: [PATCH 01/26] Remove local dev and debug targets --- .gitignore | 3 + README.md | 11 +- .../claims/vshn-postgres-with-backup.yaml | 21 - .../composition_objectstorage_minio_dev.yaml | 94 -- dev/backup/composition_vshn_postgres.yaml | 1266 ----------------- .../provider_config_helm.yaml | 12 - .../provider_config_kuberentes.yaml | 12 - dev/backup/provider_helm.yaml | 111 -- dev/backup/provider_kubernetes.yaml | 146 -- dev/backup/rbac_helm_provider_dev.yaml | 64 - dev/backup/rbac_objectstorage.yaml | 36 - dev/backup/rbac_vshn_postgres.yaml | 36 - dev/backup/xrd_objectstorage.yaml | 161 --- dev/backup/xrd_vshn_postgres.yaml | 705 --------- dev/certificates/apiserver.crt | 39 - dev/certificates/apiserver.key | 27 - .../exoscale_postgres_offered.yaml | 114 -- .../exoscale_redis_non_offered.yaml | 99 -- .../objectstorage_cloudscale_offered.yaml | 129 -- dev/local.mk | 96 -- kind/config.yaml | 17 - kind/kind.mk | 56 - 22 files changed, 8 insertions(+), 3247 deletions(-) delete mode 100644 dev/backup/claims/vshn-postgres-with-backup.yaml delete mode 100644 dev/backup/composition_objectstorage_minio_dev.yaml delete mode 100644 dev/backup/composition_vshn_postgres.yaml delete mode 100644 dev/backup/provider-configs/provider_config_helm.yaml delete mode 100644 dev/backup/provider-configs/provider_config_kuberentes.yaml delete mode 100644 dev/backup/provider_helm.yaml delete mode 100644 dev/backup/provider_kubernetes.yaml delete mode 100644 dev/backup/rbac_helm_provider_dev.yaml delete mode 100644 dev/backup/rbac_objectstorage.yaml delete mode 100644 dev/backup/rbac_vshn_postgres.yaml delete mode 100644 dev/backup/xrd_objectstorage.yaml delete mode 100644 dev/backup/xrd_vshn_postgres.yaml delete mode 100644 dev/certificates/apiserver.crt delete mode 100644 dev/certificates/apiserver.key delete mode 100644 dev/compositions/exoscale_postgres_offered.yaml delete mode 100644 dev/compositions/exoscale_redis_non_offered.yaml delete mode 100644 dev/compositions/objectstorage_cloudscale_offered.yaml delete mode 100644 dev/local.mk delete mode 100644 kind/config.yaml delete mode 100644 kind/kind.mk diff --git a/.gitignore b/.gitignore index 1b2a626828..f3f073e501 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ appcat-apiserver .cache .public +# debug +apiserver.local.config + diff --git a/README.md b/README.md index 7abd334390..fd18691e04 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,14 @@ On some docker distributions the host IP is accessible via `host.docker.internal For Lima distribution the host IP is accessible via `host.lima.internal`. ```bash -make local-debug +# Run this command in kindev -> https://github.com/vshn/kindev +make appcat-apiserver -HOSTIP=$(docker inspect appcat-apiserver-v1.24.0-control-plane | jq '.[0].NetworkSettings.Networks.kind.Gateway') +HOSTIP=$(docker inspect kindev-control-plane | jq '.[0].NetworkSettings.Networks.kind.Gateway') # HOSTIP=host.docker.internal # On some docker distributions # HOSTIP=host.lima.internal # On lima distributions -kind get kubeconfig --name appcat-apiserver-v1.24.0 > ~/.kube/config +kind get kubeconfig --name kindev > ~/.kube/config cat </.kube/config --authentication-kubeconfig=/.kube/config --authorization-kubeconfig=/.kube/config ``` ## Protobuf installation diff --git a/dev/backup/claims/vshn-postgres-with-backup.yaml b/dev/backup/claims/vshn-postgres-with-backup.yaml deleted file mode 100644 index 832f1e57a8..0000000000 --- a/dev/backup/claims/vshn-postgres-with-backup.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: vshn.appcat.vshn.io/v1 -kind: VSHNPostgreSQL -metadata: - name: pgsql-app1-prod - namespace: default -spec: - parameters: - backup: - schedule: "* * * * *" - deletionProtection: true - deletionRetention: 7 - service: - majorVersion: "15" - pgSettings: - timezone: Europe/Zurich - size: - cpu: "200m" - memory: "350Mi" - disk: "5Gi" - writeConnectionSecretToRef: - name: postgres-creds diff --git a/dev/backup/composition_objectstorage_minio_dev.yaml b/dev/backup/composition_objectstorage_minio_dev.yaml deleted file mode 100644 index 783d29ff30..0000000000 --- a/dev/backup/composition_objectstorage_minio_dev.yaml +++ /dev/null @@ -1,94 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: dev.objectbuckets.appcat.vshn.io - name: dev.objectbuckets.appcat.vshn.io -spec: - compositeTypeRef: - apiVersion: appcat.vshn.io/v1 - kind: XObjectBucket - resources: - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: v1 - kind: Namespace - providerConfigRef: - name: kubernetes - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - type: FromCompositeFieldPath - - base: - apiVersion: helm.crossplane.io/v1beta1 - kind: Release - spec: - connectionDetails: - - apiVersion: v1 - fieldPath: spec.clusterIP - kind: Service - name: minio-server - namespace: minio - toConnectionSecretKey: ENDPOINT_URL - - apiVersion: v1 - fieldPath: data.rootUser - kind: Secret - name: minio-server - namespace: minio - toConnectionSecretKey: AWS_ACCESS_KEY_ID - - apiVersion: v1 - fieldPath: data.rootPassword - kind: Secret - name: minio-server - namespace: minio - toConnectionSecretKey: AWS_SECRET_ACCESS_KEY - deletionPolicy: Delete - forProvider: - chart: - name: minio - repository: https://charts.min.io/ - version: 5.0.7 - namespace: minio - set: - - name: rootUser - value: minioadmin - - name: rootPassword - value: minioadmin - values: - buckets: - - name: '' - policy: none - fullnameOverride: minio-server - mode: standalone - persistence: - size: 1Gi - replicas: 1 - resources: - requests: - memory: 128Mi - providerConfigRef: - name: helm - rollbackLimit: 3 - writeConnectionSecretToRef: - name: '' - namespace: syn-crossplane - connectionDetails: - - fromConnectionSecretKey: AWS_SECRET_ACCESS_KEY - - fromConnectionSecretKey: ENDPOINT_URL - - fromConnectionSecretKey: AWS_ACCESS_KEY_ID - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.values.buckets[0].name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.writeConnectionSecretToRef.name - type: FromCompositeFieldPath - writeConnectionSecretsToNamespace: syn-crossplane diff --git a/dev/backup/composition_vshn_postgres.yaml b/dev/backup/composition_vshn_postgres.yaml deleted file mode 100644 index 13714fe674..0000000000 --- a/dev/backup/composition_vshn_postgres.yaml +++ /dev/null @@ -1,1266 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - metadata.appcat.vshn.io/description: PostgreSQL instances by VSHN - metadata.appcat.vshn.io/displayname: VSHN Managed PostgreSQL - metadata.appcat.vshn.io/end-user-docs-url: https://docs.appuio.cloud/appcat/vshn-dbaas/postgresql/create.html - metadata.appcat.vshn.io/flavor: standalone - metadata.appcat.vshn.io/product-description: https://products.docs.vshn.ch/products/appcat/postgresql.html - metadata.appcat.vshn.io/zone: rma1 - labels: - metadata.appcat.vshn.io/offered: 'true' - metadata.appcat.vshn.io/serviceID: vshn-postgresql - name: vshnpostgres.vshn.appcat.vshn.io - name: vshnpostgres.vshn.appcat.vshn.io -spec: - compositeTypeRef: - apiVersion: vshn.appcat.vshn.io/v1 - kind: XVSHNPostgreSQL - resources: - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: v1 - kind: Namespace - metadata: - labels: - appcat.vshn.io/claim-namespace: '' - appcat.vshn.io/servicename: postgresql-standalone - appuio.io/no-rbac-creation: 'true' - appuio.io/organization: vshn - name: '' - managementPolicy: Observe - providerConfigRef: - name: kubernetes - name: ns-observer - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: ns-observer-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/claim-namespace] - toFieldPath: spec.forProvider.manifest.metadata.name - type: FromCompositeFieldPath - - fromFieldPath: status.atProvider.manifest.metadata.labels[appuio.io/organization] - toFieldPath: metadata.labels[appuio.io/organization] - type: ToCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: v1 - kind: Namespace - metadata: - labels: - appcat.vshn.io/claim-namespace: '' - appcat.vshn.io/servicename: postgresql-standalone - appuio.io/no-rbac-creation: 'true' - appuio.io/organization: vshn - name: '' - providerConfigRef: - name: kubernetes - name: namespace-conditions - patches: - - fromFieldPath: status.conditions - toFieldPath: status.namespaceConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.name - toFieldPath: status.instanceNamespace - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/claim-namespace] - toFieldPath: spec.forProvider.manifest.metadata.labels[appcat.vshn.io/claim-namespace] - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[appuio.io/organization] - toFieldPath: spec.forProvider.manifest.metadata.labels[appuio.io/organization] - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - spec: - forProvider: - manifest: - apiVersion: rbac.authorization.k8s.io/v1 - kind: RoleBinding - metadata: - name: appcat:services:read - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: appcat:services:read - subjects: - - apiGroup: rbac.authorization.k8s.io - kind: Group - name: organization - providerConfigRef: - name: kubernetes - name: namespace-permissions - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-service-rolebinding' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[appuio.io/organization] - toFieldPath: spec.forProvider.manifest.subjects[0].name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: cert-manager.io/v1 - kind: Issuer - metadata: - name: '' - namespace: '' - spec: - selfSigned: - crlDistributionPoints: [] - providerConfigRef: - name: kubernetes - name: local-ca - patches: - - fromFieldPath: status.conditions - toFieldPath: status.localCAConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-localca' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: cert-manager.io/v1 - kind: Certificate - metadata: - name: '' - namespace: '' - spec: - dnsNames: - - vshn.appcat.vshn.ch - duration: 87600h - isCA: false - issuerRef: - group: cert-manager.io - kind: Issuer - name: '' - privateKey: - algorithm: RSA - encoding: PKCS1 - size: 4096 - renewBefore: 2400h - secretName: tls-certificate - subject: - organizations: - - vshn-appcat - usages: - - server auth - - client auth - providerConfigRef: - name: kubernetes - name: certificate - patches: - - fromFieldPath: status.conditions - toFieldPath: status.certificateConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-certificate' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.spec.issuerRef.name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: stackgres.io/v1 - kind: SGInstanceProfile - metadata: {} - spec: - containers: - backup.create-backup: - cpu: 250m - memory: 256Mi - cluster-controller: - cpu: 32m - memory: 188Mi - envoy: - cpu: 32m - memory: 64Mi - pgbouncer: - cpu: 16m - memory: 32Mi - postgres-util: - cpu: 10m - memory: 4Mi - prometheus-postgres-exporter: - cpu: 10m - memory: 32Mi - cpu: '' - initContainers: - cluster-reconciliation-cycle: - cpu: 100m - memory: 100Mi - pgbouncer-auth-file: - cpu: 100m - memory: 100Mi - relocate-binaries: - cpu: 100m - memory: 100Mi - setup-arbitrary-user: - cpu: 100m - memory: 100Mi - setup-scripts: - cpu: 100m - memory: 100Mi - memory: '' - requests: - cpu: null - memory: null - providerConfigRef: - name: kubernetes - name: profile - patches: - - fromFieldPath: status.conditions - toFieldPath: status.profileConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-profile' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.plan - toFieldPath: spec.forProvider.manifest.spec.cpu - transforms: - - map: - plus-2: 400m - plus-4: 900m - standard-2: 400m - standard-4: 900m - type: map - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.plan - toFieldPath: spec.forProvider.manifest.spec.memory - transforms: - - map: - plus-2: 1728Mi - plus-4: 3776Mi - standard-2: 1728Mi - standard-4: 3776Mi - type: map - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.memory - toFieldPath: spec.forProvider.manifest.spec.memory - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.cpu - toFieldPath: spec.forProvider.manifest.spec.cpu - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.requests.memory - toFieldPath: spec.forProvider.manifest.spec.requests.memory - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.requests.cpu - toFieldPath: spec.forProvider.manifest.spec.requests.cpu - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: stackgres.io/v1 - kind: SGPostgresConfig - metadata: {} - spec: - postgresVersion: '' - postgresql.conf: {} - providerConfigRef: - name: kubernetes - name: pg-conf - patches: - - fromFieldPath: status.conditions - toFieldPath: status.pgconfigConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-pgconf' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.majorVersion - toFieldPath: spec.forProvider.manifest.spec.postgresVersion - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.pgSettings - toFieldPath: spec.forProvider.manifest.spec[postgresql.conf] - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: stackgres.io/v1 - kind: SGCluster - metadata: {} - spec: - configurations: - backups: - - cronSchedule: '' - retention: 6 - sgObjectStorage: '' - sgPostgresConfig: '' - instances: 1 - nonProductionOptions: - enableSetPatroniCpuRequests: true - enableSetPatroniMemoryRequests: true - pods: - persistentVolume: - size: '' - postgres: - ssl: - certificateSecretKeySelector: - key: tls.crt - name: tls-certificate - enabled: true - privateKeySecretKeySelector: - key: tls.key - name: tls-certificate - version: '' - sgInstanceProfile: '' - providerConfigRef: - name: kubernetes - name: cluster - patches: - - fromFieldPath: status.conditions - toFieldPath: status.pgclusterConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-cluster' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.plan - toFieldPath: spec.forProvider.manifest.spec.pods.persistentVolume.size - transforms: - - map: - plus-2: 20Gi - plus-4: 40Gi - standard-2: 20Gi - standard-4: 40Gi - type: map - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.disk - toFieldPath: spec.forProvider.manifest.spec.pods.persistentVolume.size - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.plan - toFieldPath: spec.forProvider.manifest.spec.pods.scheduling.nodeSelector - transforms: - - map: - plus-2: - appuio.io/node-class: plus - plus-4: - appuio.io/node-class: plus - standard-2: {} - standard-4: {} - type: map - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.scheduling.nodeSelector - toFieldPath: spec.forProvider.manifest.spec.pods.scheduling.nodeSelector - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.majorVersion - toFieldPath: spec.forProvider.manifest.spec.postgres.version - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.spec.sgInstanceProfile - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.spec.configurations.sgPostgresConfig - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.spec.configurations.backups[0].sgObjectStorage - transforms: - - string: - fmt: sgbackup-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.backup.schedule - toFieldPath: spec.forProvider.manifest.spec.configurations.backups[0].cronSchedule - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.backup.retention - toFieldPath: spec.forProvider.manifest.spec.configurations.backups[0].retention - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: v1 - kind: Secret - metadata: {} - stringData: - POSTGRESQL_DB: postgres - POSTGRESQL_HOST: '' - POSTGRESQL_PORT: '5432' - POSTGRESQL_USER: postgres - providerConfigRef: - name: kubernetes - references: - - patchesFrom: - apiVersion: v1 - fieldPath: data.superuser-password - kind: Secret - name: '' - namespace: '' - toFieldPath: data.POSTGRESQL_PASSWORD - - patchesFrom: - apiVersion: v1 - fieldPath: data[ca.crt] - kind: Secret - name: tls-certificate - namespace: '' - toFieldPath: data[ca.crt] - - patchesFrom: - apiVersion: v1 - fieldPath: data[tls.crt] - kind: Secret - name: tls-certificate - namespace: '' - toFieldPath: data[tls.crt] - - patchesFrom: - apiVersion: v1 - fieldPath: data[tls.key] - kind: Secret - name: tls-certificate - namespace: '' - toFieldPath: data[tls.key] - writeConnectionSecretToRef: - name: '' - namespace: '' - connectionDetails: - - fromConnectionSecretKey: ca.crt - name: ca.crt - type: FromConnectionSecretKey - - fromConnectionSecretKey: tls.crt - name: tls.crt - type: FromConnectionSecretKey - - fromConnectionSecretKey: tls.key - name: tls.key - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_URL - name: POSTGRESQL_URL - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_DB - name: POSTGRESQL_DB - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_HOST - name: POSTGRESQL_HOST - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_PORT - name: POSTGRESQL_PORT - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_USER - name: POSTGRESQL_USER - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_PASSWORD - name: POSTGRESQL_PASSWORD - type: FromConnectionSecretKey - name: connection - patches: - - fromFieldPath: status.conditions - toFieldPath: status.secretConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-connection' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/claim-name] - toFieldPath: spec.forProvider.manifest.metadata.name - transforms: - - string: - fmt: '%s-connection' - type: Format - type: string - type: FromCompositeFieldPath - - combine: - strategy: string - string: - fmt: '%s.vshn-postgresql-%s.svc.cluster.local' - variables: - - fromFieldPath: metadata.labels[crossplane.io/composite] - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.stringData.POSTGRESQL_HOST - type: CombineFromComposite - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.references[0].patchesFrom.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.references[0].patchesFrom.name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.writeConnectionSecretToRef.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/claim-name] - toFieldPath: spec.writeConnectionSecretToRef.name - transforms: - - string: - fmt: '%s-connection' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.references[1].patchesFrom.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.references[2].patchesFrom.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.references[3].patchesFrom.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: appcat.vshn.io/v1 - kind: XObjectBucket - metadata: {} - spec: - parameters: - bucketName: '' - region: us-east-1 - writeConnectionSecretToRef: - name: '' - namespace: '' - name: pg-bucket - patches: - - fromFieldPath: status.conditions - toFieldPath: status.objectBackupConfigConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.parameters.bucketName - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.writeConnectionSecretToRef.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.writeConnectionSecretToRef.name - transforms: - - string: - fmt: pgbucket-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: stackgres.io/v1beta1 - kind: SGObjectStorage - metadata: - name: '' - namespace: '' - spec: - s3Compatible: - awsCredentials: - secretKeySelectors: - accessKeyId: - key: AWS_ACCESS_KEY_ID - name: '' - secretAccessKey: - key: AWS_SECRET_ACCESS_KEY - name: '' - bucket: '' - enablePathStyleAddressing: true - endpoint: http://minio-server.minio:9000 - region: us-east-1 - type: s3Compatible - providerConfigRef: - name: kubernetes - name: sg-backup - patches: - - fromFieldPath: status.conditions - toFieldPath: status.objectBucketConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-object-storage' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - transforms: - - string: - fmt: sgbackup-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.spec.s3Compatible.bucket - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/claim-namespace] - toFieldPath: spec.forProvider.spec.writeConnectionSecretToRef.namespace - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.spec.s3Compatible.awsCredentials.secretKeySelectors.accessKeyId.name - transforms: - - string: - fmt: pgbucket-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.spec.s3Compatible.awsCredentials.secretKeySelectors.secretAccessKey.name - transforms: - - string: - fmt: pgbucket-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: v1 - kind: ServiceAccount - metadata: - annotations: {} - labels: - name: maintenanceserviceaccount - name: maintenanceserviceaccount - providerConfigRef: - name: kubernetes - name: maintenance-serviceaccount - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-maintenanceserviceaccount' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: rbac.authorization.k8s.io/v1 - kind: Role - metadata: - annotations: {} - labels: - name: crossplane-appcat-job-postgres-maintenance - name: crossplane:appcat:job:postgres:maintenance - rules: - - apiGroups: - - stackgres.io - resources: - - sgdbops - verbs: - - delete - - create - providerConfigRef: - name: kubernetes - name: maintenance-role - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-maintenancerole' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: rbac.authorization.k8s.io/v1 - kind: RoleBinding - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: crossplane:appcat:job:postgres:maintenance - subjects: - - apiGroup: '' - kind: ServiceAccount - name: maintenanceserviceaccount - providerConfigRef: - name: kubernetes - name: maintenance-rolebinding - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-maintenancerolebinding' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - transforms: - - string: - fmt: '%s-maintenancerolebinding' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: batch/v1 - kind: CronJob - spec: - jobTemplate: - spec: - template: - spec: - containers: - - args: - - | - #!/bin/sh - set -e - kubectl -n ${TARGET_NAMESPACE} delete sgdbops securitymaintenance || true - cat < 0 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 - for: 1m - labels: - severity: critical - - alert: PostgreSQLPersistentVolumeFillingUp - annotations: - description: |- - Based on recent sampling, the PersistentVolume claimed by {{ - $labels.persistentvolumeclaim }} in Namespace {{ $labels.namespace - }} is expected to fill up within four days. Currently {{ $value | - humanizePercentage }} is available. - runbook_url: https://runbooks.prometheus-operator.dev/runbooks/kubernetes/kubepersistentvolumefillingup - summary: PersistentVolume is filling up. - expr: |- - ( - kubelet_volume_stats_available_bytes{job="kubelet", metrics_path="/metrics"} - / - kubelet_volume_stats_capacity_bytes{job="kubelet", metrics_path="/metrics"} - ) < 0.15 - and - kubelet_volume_stats_used_bytes{job="kubelet", metrics_path="/metrics"} > 0 - and - predict_linear(kubelet_volume_stats_available_bytes{job="kubelet", metrics_path="/metrics"}[6h], 4 * 24 * 3600) < 0 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_access_mode{ access_mode="ReadOnlyMany"} == 1 - unless on(namespace, persistentvolumeclaim) - kube_persistentvolumeclaim_labels{label_excluded_from_alerts="true"} == 1 - for: 1h - labels: - severity: warning - - name: postgresql-memory - rules: - - alert: PostgreSQLMemoryCritical - annotations: - description: |- - The memory claimed by {{ $labels.pod }} has been over 85% for 2 hours. - Please reducde the load of this instance, or increase the memory. - summary: Memory usage critical - expr: |- - (container_memory_working_set_bytes{container="patroni"} - / on(container,pod) - kube_pod_container_resource_limits{resource="memory"} * 100) - > 85 - for: 120m - labels: - severity: critical - - name: postgresql-connections - rules: - - alert: PostgreSQLConnectionsCritical - annotations: - description: |- - The connections to {{ $labels.pod }} have been over 90% of the configured connections for 2 hours. - Please reduce the load of this instance. - summary: Connection usage critical - expr: |- - sum(pg_stat_activity_count) by (pod) - > 90/100 * sum(pg_settings_max_connections) by (pod) - for: 120m - labels: - severity: critical - providerConfigRef: - name: kubernetes - name: prometheusrule - patches: - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-prometheusrule' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - base: - apiVersion: kubernetes.crossplane.io/v1alpha1 - kind: Object - metadata: {} - spec: - forProvider: - manifest: - apiVersion: networking.k8s.io/v1 - kind: NetworkPolicy - metadata: {} - spec: - ingress: - - from: - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: '' - - namespaceSelector: - matchLabels: - kubernetes.io/metadata.name: appcat-slos - podSelector: {} - policyTypes: - - Ingress - providerConfigRef: - name: kubernetes - name: network-policy - patches: - - fromFieldPath: status.conditions - toFieldPath: status.networkPolicyConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - transforms: - - string: - fmt: '%s-network-policy' - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.namespace - transforms: - - string: - fmt: vshn-postgresql-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.manifest.metadata.name - transforms: - - string: - fmt: allow-from-claim-namespace-%s - type: Format - type: string - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/claim-namespace] - toFieldPath: spec.forProvider.manifest.spec.ingress[0].from[0].namespaceSelector.matchLabels[kubernetes.io/metadata.name] - type: FromCompositeFieldPath - writeConnectionSecretsToNamespace: syn-crossplane diff --git a/dev/backup/provider-configs/provider_config_helm.yaml b/dev/backup/provider-configs/provider_config_helm.yaml deleted file mode 100644 index 2e7c240401..0000000000 --- a/dev/backup/provider-configs/provider_config_helm.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: helm.crossplane.io/v1beta1 -kind: ProviderConfig -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: helm - name: helm -spec: - credentials: - source: InjectedIdentity diff --git a/dev/backup/provider-configs/provider_config_kuberentes.yaml b/dev/backup/provider-configs/provider_config_kuberentes.yaml deleted file mode 100644 index c42609d192..0000000000 --- a/dev/backup/provider-configs/provider_config_kuberentes.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: kubernetes.crossplane.io/v1alpha1 -kind: ProviderConfig -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: kubernetes - name: kubernetes -spec: - credentials: - source: InjectedIdentity diff --git a/dev/backup/provider_helm.yaml b/dev/backup/provider_helm.yaml deleted file mode 100644 index e04f41b44b..0000000000 --- a/dev/backup/provider_helm.yaml +++ /dev/null @@ -1,111 +0,0 @@ -apiVersion: pkg.crossplane.io/v1 -kind: Provider -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: helm - name: helm -spec: - controllerConfigRef: - name: helm - package: docker.io/crossplane/provider-helm:v0.11.1 ---- -apiVersion: pkg.crossplane.io/v1alpha1 -kind: ControllerConfig -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: helm - name: helm -spec: - serviceAccountName: provider-helm ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - annotations: {} - labels: - name: provider-helm - name: provider-helm - namespace: syn-crossplane ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: {} - labels: - name: crossplane-provider-provider-helm-system-custom - name: crossplane:provider:provider-helm:system:custom -rules: - - apiGroups: - - helm.crossplane.io - resources: - - '*' - verbs: - - get - - list - - watch - - update - - patch - - create - - delete - - apiGroups: - - '' - resources: - - namespaces - - serviceaccounts - - services - verbs: - - get - - list - - watch - - create - - watch - - patch - - update - - delete - - apiGroups: - - apps - resources: - - statefulsets - verbs: - - get - - list - - watch - - create - - watch - - patch - - update - - delete - - apiGroups: - - networking.k8s.io - resources: - - networkpolicies - verbs: - - get - - list - - watch - - update - - patch - - create - - delete ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - annotations: {} - labels: - name: crossplane-provider-provider-helm-system-custom - name: crossplane:provider:provider-helm:system:custom -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: crossplane:provider:provider-helm:system:custom -subjects: - - kind: ServiceAccount - name: provider-helm - namespace: syn-crossplane diff --git a/dev/backup/provider_kubernetes.yaml b/dev/backup/provider_kubernetes.yaml deleted file mode 100644 index def589d954..0000000000 --- a/dev/backup/provider_kubernetes.yaml +++ /dev/null @@ -1,146 +0,0 @@ -apiVersion: pkg.crossplane.io/v1 -kind: Provider -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: kubernetes - name: kubernetes -spec: - controllerConfigRef: - name: kubernetes - package: docker.io/crossplane/provider-kubernetes:v0.4.0 ---- -apiVersion: pkg.crossplane.io/v1alpha1 -kind: ControllerConfig -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: kubernetes - name: kubernetes -spec: - serviceAccountName: provider-kubernetes ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - annotations: {} - labels: - name: provider-kubernetes - name: provider-kubernetes - namespace: syn-crossplane ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: {} - labels: - name: crossplane-provider-provider-kubernetes-system-custom - name: crossplane:provider:provider-kubernetes:system:custom -rules: - - apiGroups: - - kubernetes.crossplane.io - resources: - - '*' - verbs: - - get - - list - - watch - - update - - patch - - create - - delete - - apiGroups: - - '' - - coordination.k8s.io - resources: - - secrets - - configmaps - - events - - leases - verbs: - - '*' - - apiGroups: - - '' - resources: - - namespaces - verbs: - - get - - list - - watch - - create - - watch - - patch - - update - - delete - - apiGroups: - - stackgres.io - resources: - - sginstanceprofiles - - sgclusters - - sgpgconfigs - - sgobjectstorages - verbs: - - get - - list - - watch - - update - - patch - - create - - delete - - apiGroups: - - networking.k8s.io - resources: - - networkpolicies - verbs: - - get - - list - - watch - - update - - patch - - create - - delete - - apiGroups: - - appcat.vshn.io - resources: - - xobjectbuckets - verbs: - - get - - list - - watch - - update - - patch - - create - - delete - - apiGroups: - - cert-manager.io - resources: - - issuers - - certificates - verbs: - - get - - list - - watch - - update - - patch - - create - - delete ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - annotations: {} - labels: - name: crossplane-provider-provider-kubernetes-system-custom - name: crossplane:provider:provider-kubernetes:system:custom -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: crossplane:provider:provider-kubernetes:system:custom -subjects: - - kind: ServiceAccount - name: provider-kubernetes - namespace: syn-crossplane diff --git a/dev/backup/rbac_helm_provider_dev.yaml b/dev/backup/rbac_helm_provider_dev.yaml deleted file mode 100644 index 737b370690..0000000000 --- a/dev/backup/rbac_helm_provider_dev.yaml +++ /dev/null @@ -1,64 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: {} - labels: - name: crossplane-provider-provider-helm-system-dev - name: crossplane:provider:provider-helm:system:dev -rules: - - apiGroups: - - '' - resources: - - persistentvolumeclaims - - deployments - verbs: - - get - - list - - watch - - create - - watch - - patch - - update - - delete - - apiGroups: - - apps - resources: - - deployments - verbs: - - get - - list - - watch - - create - - watch - - patch - - update - - delete - - apiGroups: - - batch - resources: - - jobs - verbs: - - get - - list - - watch - - create - - watch - - patch - - update - - delete ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - annotations: {} - labels: - name: crossplane-provider-provider-helm-system-dev - name: crossplane:provider:provider-helm:system:dev -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: crossplane:provider:provider-helm:system:dev -subjects: - - kind: ServiceAccount - name: provider-helm - namespace: syn-crossplane diff --git a/dev/backup/rbac_objectstorage.yaml b/dev/backup/rbac_objectstorage.yaml deleted file mode 100644 index 5e96894156..0000000000 --- a/dev/backup/rbac_objectstorage.yaml +++ /dev/null @@ -1,36 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: {} - labels: - rbac.authorization.k8s.io/aggregate-to-view: 'true' - name: appcat:composite:xobjectbuckets.appcat.vshn.io:claim-view -rules: - - apiGroups: - - appcat.vshn.io - resources: - - objectbuckets - - objectbuckets/status - - objectbuckets/finalizers - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: {} - labels: - rbac.authorization.k8s.io/aggregate-to-admin: 'true' - rbac.authorization.k8s.io/aggregate-to-edit: 'true' - name: appcat:composite:xobjectbuckets.appcat.vshn.io:claim-edit -rules: - - apiGroups: - - appcat.vshn.io - resources: - - objectbuckets - - objectbuckets/status - - objectbuckets/finalizers - verbs: - - '*' diff --git a/dev/backup/rbac_vshn_postgres.yaml b/dev/backup/rbac_vshn_postgres.yaml deleted file mode 100644 index f956ea674b..0000000000 --- a/dev/backup/rbac_vshn_postgres.yaml +++ /dev/null @@ -1,36 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: {} - labels: - rbac.authorization.k8s.io/aggregate-to-view: 'true' - name: appcat:composite:xvshnpostgresqls.vshn.appcat.vshn.io:claim-view -rules: - - apiGroups: - - vshn.appcat.vshn.io - resources: - - vshnpostgresqls - - vshnpostgresqls/status - - vshnpostgresqls/finalizers - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - annotations: {} - labels: - rbac.authorization.k8s.io/aggregate-to-admin: 'true' - rbac.authorization.k8s.io/aggregate-to-edit: 'true' - name: appcat:composite:xvshnpostgresqls.vshn.appcat.vshn.io:claim-edit -rules: - - apiGroups: - - vshn.appcat.vshn.io - resources: - - vshnpostgresqls - - vshnpostgresqls/status - - vshnpostgresqls/finalizers - verbs: - - '*' diff --git a/dev/backup/xrd_objectstorage.yaml b/dev/backup/xrd_objectstorage.yaml deleted file mode 100644 index 88f11f8082..0000000000 --- a/dev/backup/xrd_objectstorage.yaml +++ /dev/null @@ -1,161 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: CompositeResourceDefinition -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: xobjectbuckets.appcat.vshn.io - name: xobjectbuckets.appcat.vshn.io -spec: - claimNames: - kind: ObjectBucket - plural: objectbuckets - connectionSecretKeys: - - AWS_ACCESS_KEY_ID - - AWS_SECRET_ACCESS_KEY - - AWS_REGION - - ENDPOINT - - ENDPOINT_URL - - BUCKET_NAME - defaultCompositionRef: - name: dev.objectbuckets.appcat.vshn.io - group: appcat.vshn.io - names: - kind: XObjectBucket - plural: xobjectbuckets - versions: - - additionalPrinterColumns: - - jsonPath: .spec.parameters.bucketName - name: Bucket Name - type: string - - jsonPath: .spec.parameters.region - name: Region - type: string - name: v1 - referenceable: true - schema: - openAPIV3Schema: - description: ObjectBucket is the API for creating S3 buckets. - properties: - spec: - description: ObjectBucketSpec defines the desired state of a ObjectBucket. - properties: - parameters: - description: ObjectBucketParameters are the configurable fields - of a ObjectBucket. - properties: - bucketName: - description: BucketName is the name of the bucket to create. - Cannot be changed after bucket is created. Name must be acceptable - by the S3 protocol, which follows RFC 1123. Be aware that - S3 providers may require a unique name across the platform - or region. - type: string - region: - description: Region is the name of the region where the bucket - shall be created. The region must be available in the S3 endpoint. - type: string - required: - - bucketName - - region - type: object - type: object - status: - description: ObjectBucketStatus reflects the observed state of a ObjectBucket. - properties: - accessUserConditions: - description: AccessUserConditions contains a copy of the claim's - underlying user account conditions. - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - bucketConditions: - description: BucketConditions contains a copy of the claim's underlying - bucket conditions. - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - type: object - required: - - spec - type: object - served: true diff --git a/dev/backup/xrd_vshn_postgres.yaml b/dev/backup/xrd_vshn_postgres.yaml deleted file mode 100644 index 6d038a58c9..0000000000 --- a/dev/backup/xrd_vshn_postgres.yaml +++ /dev/null @@ -1,705 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: CompositeResourceDefinition -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - labels: - name: xvshnpostgresqls.vshn.appcat.vshn.io - name: xvshnpostgresqls.vshn.appcat.vshn.io -spec: - claimNames: - kind: VSHNPostgreSQL - plural: vshnpostgresqls - connectionSecretKeys: - - ca.crt - - tls.crt - - tls.key - - POSTGRESQL_URL - - POSTGRESQL_DB - - POSTGRESQL_HOST - - POSTGRESQL_PORT - - POSTGRESQL_USER - - POSTGRESQL_PASSWORD - defaultCompositionRef: - name: vshnpostgres.vshn.appcat.vshn.io - group: vshn.appcat.vshn.io - names: - kind: XVSHNPostgreSQL - plural: xvshnpostgresqls - versions: - - name: v1 - referenceable: true - schema: - openAPIV3Schema: - description: VSHNPostgreSQL is the API for creating Postgresql clusters. - properties: - spec: - description: Spec defines the desired state of a VSHNPostgreSQL. - properties: - parameters: - default: {} - description: Parameters are the configurable fields of a VSHNPostgreSQL. - properties: - backup: - default: {} - description: Backup contains settings to control the backups - of an instance. - properties: - deletionProtection: - default: true - description: DeletionProtection will protect the instance - from being deleted for the given retention time. This - is enabled by default. - type: boolean - deletionRetention: - default: 7 - description: DeletionRetention specifies in days how long - the instance should be kept after deletion. The default - is keeping it one week. - type: integer - retention: - default: 6 - pattern: ^[1-9][0-9]*$ - type: integer - x-kubernetes-int-or-string: true - schedule: - default: 0 22 * * * - pattern: ^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) - (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) - (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$ - type: string - type: object - maintenance: - default: {} - description: Maintenance contains settings to control the maintenance - of an instance. - properties: - dayOfWeek: - default: tuesday - description: DayOfWeek specifies at which weekday the maintenance - is held place. Allowed values are [monday, tuesday, wednesday, - thursday, friday, saturday, sunday] - enum: - - monday - - tuesday - - wednesday - - thursday - - friday - - saturday - - sunday - type: string - timeOfDay: - default: '22:30:00' - description: 'TimeOfDay for installing updates in UTC. Format: - "hh:mm:ss".' - pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ - type: string - type: object - network: - description: Network contains any network related settings. - properties: - ipFilter: - default: - - 0.0.0.0/0 - description: IPFilter is a list of allowed IPv4 CIDR ranges - that can access the service. If no IP Filter is set, you - may not be able to reach the service. A value of `0.0.0.0/0` - will open the service to all addresses on the public internet. - items: - type: string - type: array - type: object - restore: - description: Restore contains settings to control the restore - of an instance. - properties: - backupName: - description: BackupName is the name of the specific backup - you want to restore. - type: string - claimName: - description: ClaimName specifies the name of the instance - you want to restore from. The claim has to be in the same - namespace as this new instance. - type: string - recoveryTimeStamp: - description: RecoveryTimeStamp an ISO 8601 date, that holds - UTC date indicating at which point-in-time the database - has to be restored. This is optional and if no PIT recovery - is required, it can be left empty. - pattern: ^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)$ - type: string - type: object - scheduling: - description: Scheduling contains settings to control the scheduling - of an instance. - properties: - nodeSelector: - additionalProperties: - type: string - description: "NodeSelector is a selector which must match\ - \ a node\u2019s labels for the pod to be scheduled on\ - \ that node" - type: object - type: object - service: - default: {} - description: Service contains PostgreSQL DBaaS specific properties - properties: - majorVersion: - default: '15' - description: MajorVersion contains supported version of - PostgreSQL. Multiple versions are supported. The latest - version "15" is the default version. - enum: - - '12' - - '13' - - '14' - - '15' - type: string - pgSettings: - description: PGSettings contains additional PostgreSQL settings. - type: object - x-kubernetes-preserve-unknown-fields: true - type: object - size: - default: {} - description: Size contains settings to control the sizing of - a service. - properties: - cpu: - description: CPU defines the amount of Kubernetes CPUs for - an instance. - type: string - disk: - description: Disk defines the amount of disk space for an - instance. - type: string - memory: - description: Memory defines the amount of memory in units - of bytes for an instance. - type: string - plan: - default: standard-2 - description: | - Plan is the name of the resource plan that defines the compute resources. - - The following plans are available: - - plus-2 - CPU: 400m; Memory: 1728Mi; Disk: 20Gi - Will be scheduled on APPUiO Cloud plus nodes - - plus-4 - CPU: 900m; Memory: 3776Mi; Disk: 40Gi - Will be scheduled on APPUiO Cloud plus nodes - - standard-2 - CPU: 400m; Memory: 1728Mi; Disk: 20Gi - - standard-4 - CPU: 900m; Memory: 3776Mi; Disk: 40Gi - enum: - - plus-2 - - plus-4 - - standard-2 - - standard-4 - type: string - requests: - description: Requests defines CPU and memory requests for - an instance - properties: - cpu: - description: CPU defines the amount of Kubernetes CPUs - for an instance. - type: string - memory: - description: Memory defines the amount of memory in - units of bytes for an instance. - type: string - type: object - type: object - type: object - type: object - status: - description: Status reflects the observed state of a VSHNPostgreSQL. - properties: - ObjectBackupConfigConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - ObjectBucketConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - certificateConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - instanceNamespace: - description: InstanceNamespace contains the name of the namespace - where the instance resides - type: string - localCAConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - namespaceConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - networkPolicyConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - pgclusterConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - pgconfigConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - postgresqlConditions: - description: PostgreSQLConditions contains the status conditions - of the backing object. - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - profileConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - secretConditions: - items: - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: Message is a human-readable message indicating - details about the transition. - maxLength: 32768 - type: string - observedGeneration: - description: ObservedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if - .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: Reason contains a programmatic identifier indicating - the reason for the condition's last transition. - maxLength: 1024 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - enum: - - 'True' - - 'False' - - Unknown - type: string - type: - description: Type of condition. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - type: object - type: array - type: object - required: - - spec - type: object - served: true diff --git a/dev/certificates/apiserver.crt b/dev/certificates/apiserver.crt deleted file mode 100644 index 1cabe1634b..0000000000 --- a/dev/certificates/apiserver.crt +++ /dev/null @@ -1,39 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDOTCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdsb2Nh -bGhvc3QtY2FAMTY3NTk1NzAxMjAeFw0yMzAyMDkxNDM2NTJaFw0yNDAyMDkxNDM2 -NTJaMB8xHTAbBgNVBAMMFGxvY2FsaG9zdEAxNjc1OTU3MDEyMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvLDSjqB/8Qifz/I0atVTKACKX0MGM1xi8Esu -+sBLmYeA2W8n6zsCI+3yEcjBNuIn+V/mCfKJWormlVEsHR2648Z/a5Njq8O4dDxL -yTSnPxqDNdESIqAGozmJ0UDAwg8pgmLT7n3nE1HBKmcTBWY+5tTjJ9RmIy6a22Ph -9vW+80OrJWA+KvUHxzmbFGfFQtly6jUs1Obg1A+z2uVzQe7aYoLUrRRNMqrl7zio -Fn11Y7ItMVEgFJW6rhTIAbg6z5mAVBn97saDFHRn7MSYQzL4msVSbCEigPcvgaPx -t8dSzLSdVg6hGrqxa1Cf+iD3TadXcoa4pVisxbsizL923uYkxwIDAQABo30wezAO -BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIw -ADAfBgNVHSMEGDAWgBT1A1la0p3kWUk1mF+JAxBc+VUzrzAlBgNVHREEHjAcggls -b2NhbGhvc3SCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAkGLb -3Me0CGJNct7V9Oy65YyMIhCS1+FIzB3ER5h27SVdM3kmGTP5ELsESEInbdAGOyZJ -jybUvt/Qs9QGU0+WOoLKjZTMIxCCKDq8taduRCDPNMfPNp7f5XxCr5WknY0y6wPs -+Hhw0AdxQ4zxbrlc3OLRSbG3SwnPXS1IxqGbc22SdwlHEkR/viO7lcuwjT0AZuKT -JfO4ElIM+xy9d2ZrnDHNIcRorYyyNGLv/yx2/x8HKhl7P1yByRn3MOeZs2i7x6Po -koTlzTHa1KwLaW4a5O+31HoNbtAsiBlxQczdoUnDUlfVcE0MMMwxZ8Skhbhn3MpK -qW7zEUVnEKI7f1boYA== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDATCCAemgAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdsb2Nh -bGhvc3QtY2FAMTY3NTk1NzAxMjAeFw0yMzAyMDkxNDM2NTJaFw0yNDAyMDkxNDM2 -NTJaMCIxIDAeBgNVBAMMF2xvY2FsaG9zdC1jYUAxNjc1OTU3MDEyMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx00cH63XOnb5QMtI1zrhwDhJHk7QItdd -1IIuvrXQaMfET2rIdrc6I8lyBaVEVj2lOcnOkhsH2Oky7Dje5se2kp8SYWkfD14z -g6Xt6/6yq/+c7S5KM7t044JNXDfJcuNWUqT+dil8iIw/Xp67+GY/gjr0uh8rGQ6x -pDM5hrwiy56GEnY+C56baBR4S8vxVFOLOeJk+R96yxF5B340Cw/HweXYmOR6HKiS -W7dtdn6kZSOd+nC0zgHig1nxwEhrisa63+Ql/xInCG/MUQutyuS5it1UaskwSaaB -cPQ+Ru5/AniT9LCXYoNvFsaXBdQXVcI6+xlorX5SqFIv2P+zHYkQ4QIDAQABo0Iw -QDAOBgNVHQ8BAf8EBAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU9QNZ -WtKd5FlJNZhfiQMQXPlVM68wDQYJKoZIhvcNAQELBQADggEBAIvi3GbM+aEO0LSs -XhmDwJpmfnOZB3hb+WQCC5ZKLWqmyPgWdpfkm1r7Xf1gdFS65CtmqlzDB0+OU2Js -0aFDJsmHGFeDIlWW3XKnoxID4SqGnT3GcuTwcKc8Cpqs6GNBaKDHFQsgZbn+PunX -XFqPNlZsglAAzo5jLVe2s0IQm8ktAWfK99ekzfPYLzm932v4m4FHn2uVMVtAyId9 -xY6v/iBcKcNR+4bu98IqVP8neuRixiP/b1JIsDRQxG4Ctes7A+sAdUOjIj8iUjuj -7zy0dWJS5jG5padkGoLlOFPy2nSXh4UjYXKnNaAMGuDi06m8KBP/+fFtzNeu3ODR -diZLMfg= ------END CERTIFICATE----- diff --git a/dev/certificates/apiserver.key b/dev/certificates/apiserver.key deleted file mode 100644 index 3ad0395d1e..0000000000 --- a/dev/certificates/apiserver.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAvLDSjqB/8Qifz/I0atVTKACKX0MGM1xi8Esu+sBLmYeA2W8n -6zsCI+3yEcjBNuIn+V/mCfKJWormlVEsHR2648Z/a5Njq8O4dDxLyTSnPxqDNdES -IqAGozmJ0UDAwg8pgmLT7n3nE1HBKmcTBWY+5tTjJ9RmIy6a22Ph9vW+80OrJWA+ -KvUHxzmbFGfFQtly6jUs1Obg1A+z2uVzQe7aYoLUrRRNMqrl7zioFn11Y7ItMVEg -FJW6rhTIAbg6z5mAVBn97saDFHRn7MSYQzL4msVSbCEigPcvgaPxt8dSzLSdVg6h -Grqxa1Cf+iD3TadXcoa4pVisxbsizL923uYkxwIDAQABAoIBAD3Ctrh+akIvq3d5 -9JQ/TN+cBa6WlpH7HFtAkJj8lgIjqxYAXxWMk+/Es2YEytE3BxSFwhrhavna2wxm -rES/dWuWjiBc9tPC1T4eekPaWx+5gtb7nq78qA+HBsgaJL2gDtshk/LM/PSC3vIN -GNm8lLwjVFK2H9RGLeO/drfJyf1/SRJLmjGy8dqIYzQPtNA68B4dsDO9HP6mieI1 -ocCnbXexRIxFOC7gdFHCs4jBpD85WQjIGLUqFy3V2TXy8A53yXE7maA6thGNB/9C -mvm5XfHTwCBLB9e96c1l1bg/kH9QcudXNwaPCpCcow0FvSIWVbAfGuaD+w+ZLX3d -KESwIHECgYEAxx+t1s7vooLFAmyCzARhcyDYvwry/r6XXSVC3Ucb385ZE31JQcig -ZuWNgymp+ehhN9IIg/Xtpx71JP78yuFzWECkQN8/DODh+ax4Viw2kdrab/sgN9qf -YBsciK90JweG6mmEjhl0UcwE/Bex6C8Vt/beRG+dnnVNSus2Ybhi/dkCgYEA8pZC -a2bLxVHj9Q6Kle22kN6kWjMmDr6PHVtb3Uh3Ojjn1t1ayUw4yVx6wnNkzgUjDnrr -72SwTpABojm2DgqT//DvECLxKL7axOPJ9UDuNCJwEgvcDOE0jNP1Le75Kp0zHUu5 -lG8Oe/tjm6dr/XiI9iGzX5qlwirPSOWrPJUyc58CgYBXsU3fsha63RhiLuOTccJw -72BFEk9dfRYwAT7nMG/IKpn0CVL/05lAd4vQ3cJrurlF2gvCAcZ9uRaBCoLN3mfr -z9wGbcrYoxkh2aDNYn9N0LIuaswPjQpvSsFQOOTQY3I5PesQoYkmlNEFLHI/LK1F -7USJoxYpOMOnYNr8QjXmUQKBgQDRsfeqNYrRf69IpxA+9+RHqF1zpyEvv6Ogoddw -GfMOPiCSSHfw59VyomFvcyZhPGmIW9NU9bm9v5fZ7n8j9hrnNBLC5SGHsisT5UAv -o7gFEvvDbcMC0y2Eyrf2w8tY/dgwa8P4vmNL4wvAgmHEEox6DrmqW9kLVcwm3Hk/ -/kxFSwKBgAjpdYszQ7KtmqDbtb7bX2MLEXcBnnRVV92HAuHa228hBPXzrDBnycpx -9LpBtjkdoxi7AASZFvJyewje4NOJwR2MzKgs7yJzbTsr5znNQHBoXkeaKbpt9X0A -l/f/O2mH5ssz1kdOHcbfZpT0rxsQqR7fXem5xoHrHmT1NFPVjr2Q ------END RSA PRIVATE KEY----- diff --git a/dev/compositions/exoscale_postgres_offered.yaml b/dev/compositions/exoscale_postgres_offered.yaml deleted file mode 100644 index 68e58f4ee9..0000000000 --- a/dev/compositions/exoscale_postgres_offered.yaml +++ /dev/null @@ -1,114 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - metadata.appcat.vshn.io/description: PostgreSQL DBaaS instances by Exoscale - metadata.appcat.vshn.io/displayname: Exoscale PostgreSQL - metadata.appcat.vshn.io/end-user-docs-url: https://docs.appuio.cloud/appcat/exoscale-dbaas/postgresql/create.html - metadata.appcat.vshn.io/product-description: https://products.docs.vshn.ch/products/appcat/exoscale_dbaas.html - metadata.appcat.vshn.io/zone: 'Exoscale zones: de-fra-1, de-muc-1, at-vie-1, ch-gva-2, - ch-dk-2, bg-sof-1' - labels: - metadata.appcat.vshn.io/offered: 'true' - metadata.appcat.vshn.io/serviceID: exoscale-postgresql - name: exoscalepostgres.exoscale.appcat.vshn.io - name: exoscalepostgres.exoscale.appcat.vshn.io -spec: - compositeTypeRef: - apiVersion: exoscale.appcat.vshn.io/v1 - kind: XExoscalePostgreSQL - patchSets: - - name: annotations - patches: - - fromFieldPath: metadata.annotations - toFieldPath: metadata.annotations - type: FromCompositeFieldPath - - name: labels - patches: - - fromFieldPath: metadata.labels - toFieldPath: metadata.labels - type: FromCompositeFieldPath - resources: - - base: - apiVersion: exoscale.crossplane.io/v1 - kind: PostgreSQL - metadata: {} - spec: - forProvider: - backup: - timeOfDay: '' - ipFilter: '' - maintenance: - dayOfWeek: '' - timeOfDay: '' - pgSettings: {} - size: - plan: '' - terminationProtection: false - version: '' - zone: '' - providerConfigRef: - name: exoscale - writeConnectionSecretToRef: - name: '' - namespace: syn-provider-exoscale-secrets - connectionDetails: - - fromConnectionSecretKey: POSTGRESQL_URL - name: POSTGRESQL_URL - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_DB - name: POSTGRESQL_DB - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_HOST - name: POSTGRESQL_HOST - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_PORT - name: POSTGRESQL_PORT - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_USER - name: POSTGRESQL_USER - type: FromConnectionSecretKey - - fromConnectionSecretKey: POSTGRESQL_PASSWORD - name: POSTGRESQL_PASSWORD - type: FromConnectionSecretKey - - fromConnectionSecretKey: ca.crt - name: ca.crt - type: FromConnectionSecretKey - patches: - - patchSetName: annotations - type: PatchSet - - patchSetName: labels - type: PatchSet - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.writeConnectionSecretToRef.name - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.majorVersion - toFieldPath: spec.forProvider.version - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.pgSettings - toFieldPath: spec.forProvider.pgSettings - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.zone - toFieldPath: spec.forProvider.zone - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.network.ipFilter - toFieldPath: spec.forProvider.ipFilter - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.plan - toFieldPath: spec.forProvider.size.plan - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.maintenance.dayOfWeek - toFieldPath: spec.forProvider.maintenance.dayOfWeek - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.maintenance.timeOfDay - toFieldPath: spec.forProvider.maintenance.timeOfDay - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.backup.timeOfDay - toFieldPath: spec.forProvider.backup.timeOfDay - type: FromCompositeFieldPath - writeConnectionSecretsToNamespace: syn-crossplane diff --git a/dev/compositions/exoscale_redis_non_offered.yaml b/dev/compositions/exoscale_redis_non_offered.yaml deleted file mode 100644 index a906fd3ca6..0000000000 --- a/dev/compositions/exoscale_redis_non_offered.yaml +++ /dev/null @@ -1,99 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - metadata.appcat.vshn.io/description: Redis DBaaS instances by Exoscale - metadata.appcat.vshn.io/displayname: Exoscale Redis - metadata.appcat.vshn.io/end-user-docs-url: https://docs.appuio.cloud/appcat/exoscale-dbaas/redis/create.html - metadata.appcat.vshn.io/product-description: https://products.docs.vshn.ch/products/appcat/exoscale_dbaas.html - metadata.appcat.vshn.io/zone: 'Exoscale zones: de-fra-1, de-muc-1, at-vie-1, ch-gva-2, - ch-dk-2, bg-sof-1' - labels: - metadata.appcat.vshn.io/offered: 'false' - metadata.appcat.vshn.io/serviceID: exoscale-redis - name: exoscaleredis.exoscale.appcat.vshn.io - name: exoscaleredis.exoscale.appcat.vshn.io -spec: - compositeTypeRef: - apiVersion: exoscale.appcat.vshn.io/v1 - kind: XExoscaleRedis - patchSets: - - name: annotations - patches: - - fromFieldPath: metadata.annotations - toFieldPath: metadata.annotations - type: FromCompositeFieldPath - - name: labels - patches: - - fromFieldPath: metadata.labels - toFieldPath: metadata.labels - type: FromCompositeFieldPath - resources: - - base: - apiVersion: exoscale.crossplane.io/v1 - kind: Redis - metadata: {} - spec: - forProvider: - ipFilter: '' - maintenance: - dayOfWeek: '' - timeOfDay: '' - redisSettings: {} - size: - plan: '' - terminationProtection: false - zone: '' - providerConfigRef: - name: exoscale - writeConnectionSecretToRef: - name: '' - namespace: syn-provider-exoscale-secrets - connectionDetails: - - fromConnectionSecretKey: REDIS_HOST - name: REDIS_HOST - type: FromConnectionSecretKey - - fromConnectionSecretKey: REDIS_PORT - name: REDIS_PORT - type: FromConnectionSecretKey - - fromConnectionSecretKey: REDIS_USERNAME - name: REDIS_USERNAME - type: FromConnectionSecretKey - - fromConnectionSecretKey: REDIS_PASSWORD - name: REDIS_PASSWORD - type: FromConnectionSecretKey - - fromConnectionSecretKey: REDIS_URL - name: REDIS_URL - type: FromConnectionSecretKey - patches: - - patchSetName: annotations - type: PatchSet - - patchSetName: labels - type: PatchSet - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.writeConnectionSecretToRef.name - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.redisSettings - toFieldPath: spec.forProvider.redisSettings - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.service.zone - toFieldPath: spec.forProvider.zone - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.network.ipFilter - toFieldPath: spec.forProvider.ipFilter - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.size.plan - toFieldPath: spec.forProvider.size.plan - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.maintenance.dayOfWeek - toFieldPath: spec.forProvider.maintenance.dayOfWeek - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.maintenance.timeOfDay - toFieldPath: spec.forProvider.maintenance.timeOfDay - type: FromCompositeFieldPath - writeConnectionSecretsToNamespace: syn-crossplane diff --git a/dev/compositions/objectstorage_cloudscale_offered.yaml b/dev/compositions/objectstorage_cloudscale_offered.yaml deleted file mode 100644 index c9983dd531..0000000000 --- a/dev/compositions/objectstorage_cloudscale_offered.yaml +++ /dev/null @@ -1,129 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - annotations: - argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true - argocd.argoproj.io/sync-wave: '10' - metadata.appcat.vshn.io/description: S3 compatible object storage hosted by cloudscale.ch - metadata.appcat.vshn.io/displayname: cloudscale.ch Object Storage - metadata.appcat.vshn.io/end-user-docs-url: https://docs.appuio.cloud/appcat/object-storage/create.html - metadata.appcat.vshn.io/product-description: https://products.docs.vshn.ch/products/appcat/objectstorage.html - metadata.appcat.vshn.io/zone: 'cloudscale.ch zones: lpgandrma' - labels: - metadata.appcat.vshn.io/offered: 'true' - metadata.appcat.vshn.io/serviceID: cloudscale-objectbucket - name: cloudscale.objectbuckets.appcat.vshn.io - name: cloudscale.objectbuckets.appcat.vshn.io -spec: - compositeTypeRef: - apiVersion: appcat.vshn.io/v1 - kind: XObjectBucket - patchSets: - - name: annotations - patches: - - fromFieldPath: metadata.annotations - toFieldPath: metadata.annotations - type: FromCompositeFieldPath - - name: labels - patches: - - fromFieldPath: metadata.labels - toFieldPath: metadata.labels - type: FromCompositeFieldPath - resources: - - base: - apiVersion: cloudscale.crossplane.io/v1 - kind: ObjectsUser - metadata: {} - spec: - forProvider: - displayName: '' - tags: - namespace: null - tenant: null - providerConfigRef: - name: cloudscale - writeConnectionSecretToRef: - name: '' - namespace: syn-provider-cloudscale-secrets - connectionDetails: - - fromConnectionSecretKey: AWS_ACCESS_KEY_ID - name: AWS_ACCESS_KEY_ID - type: FromConnectionSecretKey - - fromConnectionSecretKey: AWS_SECRET_ACCESS_KEY - name: AWS_SECRET_ACCESS_KEY - type: FromConnectionSecretKey - patches: - - patchSetName: annotations - type: PatchSet - - patchSetName: labels - type: PatchSet - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - type: FromCompositeFieldPath - - fromFieldPath: status.conditions - toFieldPath: status.accessUserConditions - type: ToCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.writeConnectionSecretToRef.name - type: FromCompositeFieldPath - - combine: - strategy: string - string: - fmt: '%s.%s' - variables: - - fromFieldPath: metadata.labels[crossplane.io/claim-namespace] - - fromFieldPath: metadata.labels[crossplane.io/claim-name] - toFieldPath: spec.forProvider.displayName - type: CombineFromComposite - - base: - apiVersion: cloudscale.crossplane.io/v1 - kind: Bucket - metadata: {} - spec: - forProvider: - bucketDeletionPolicy: DeleteAll - bucketName: '' - credentialsSecretRef: - name: '' - namespace: syn-provider-cloudscale-secrets - endpointURL: '' - region: '' - connectionDetails: - - fromFieldPath: status.endpoint - name: ENDPOINT - type: FromFieldPath - - fromFieldPath: status.endpointURL - name: ENDPOINT_URL - type: FromFieldPath - - fromFieldPath: spec.forProvider.region - name: AWS_REGION - type: FromFieldPath - - fromFieldPath: status.atProvider.bucketName - name: BUCKET_NAME - type: FromFieldPath - patches: - - patchSetName: annotations - type: PatchSet - - patchSetName: labels - type: PatchSet - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: metadata.name - type: FromCompositeFieldPath - - fromFieldPath: status.conditions - toFieldPath: status.bucketConditions - type: ToCompositeFieldPath - - fromFieldPath: spec.parameters.bucketName - toFieldPath: spec.forProvider.bucketName - type: FromCompositeFieldPath - - fromFieldPath: metadata.labels[crossplane.io/composite] - toFieldPath: spec.forProvider.credentialsSecretRef.name - type: FromCompositeFieldPath - - fromFieldPath: spec.parameters.region - toFieldPath: spec.forProvider.region - transforms: - - map: - lpg: lpg - rma: rma - type: map - type: FromCompositeFieldPath - writeConnectionSecretsToNamespace: syn-crossplane diff --git a/dev/local.mk b/dev/local.mk deleted file mode 100644 index fcdda6aa66..0000000000 --- a/dev/local.mk +++ /dev/null @@ -1,96 +0,0 @@ -crossplane_sentinel = $(kind_dir)/crossplane_sentinel -stackgres_sentinel = $(kind_dir)/stackgres_sentinel -cert_manager_sentinel = $(kind_dir)/cert_manager_sentinel - -.PHONY: local-install ## Install dependencies, AppCat APIServer and apply test cases -local-install: export KUBECONFIG = $(KIND_KUBECONFIG) -local-install: local-debug appcat-apiserver appcat-controller - -.PHONY: local-debug ## Install dependencies and apply test cases. API Server should be installed separately for debugging purposes -local-debug: export KUBECONFIG = $(KIND_KUBECONFIG) -local-debug: export IMG_TAG=v0.0.1 -local-debug: kind-load-image install-dependencies - -.PHONY: apply-test-cases ## Apply test cases to the running cluster -local-debug: export KUBECONFIG = $(KIND_KUBECONFIG) -apply-test-cases: - kubectl apply -f dev/compositions - kubectl apply -f dev/backup - make .wait-provider provider=helm - make .wait-provider provider=kubernetes - kubectl apply -f dev/backup/provider-configs - kubectl apply -f dev/backup/claims - -.PHONY: install-dependencies ## Installs all dependencies for this API Server -install-dependencies: export KUBECONFIG = $(KIND_KUBECONFIG) -install-dependencies: crossplane stackgres cert-manager - -.PHONY: crossplane -crossplane: $(crossplane_sentinel) ## Installs Crossplane in kind cluster - -$(crossplane_sentinel): export KUBECONFIG = $(KIND_KUBECONFIG) -$(crossplane_sentinel): $(KIND_KUBECONFIG) - helm repo add --force-update crossplane https://charts.crossplane.io/stable - helm repo update - helm upgrade --install crossplane crossplane/crossplane \ - --create-namespace \ - --namespace syn-crossplane \ - --set "args[0]='--debug'" \ - --set "args[1]='--enable-composition-revisions'" \ - --set "args[2]='--enable-composition-functions'" \ - --set "args[3]='--enable-environment-configs'" \ - --set "xfn.enabled=true" \ - --set "xfn.image.repository=ghcr.io/vshn/appcat-comp-functions" \ - --set "xfn.image.tag=latest" \ - --set webhooks.enabled=true \ - --wait - @touch $@ - -.PHONY: stackgres -stackgres: $(stackgres_sentinel) ## Installs Stackgres in kind cluster and create a cluster with backup for testing purposes - -$(stackgres_sentinel): export KUBECONFIG = $(KIND_KUBECONFIG) -$(stackgres_sentinel): $(KIND_KUBECONFIG) - helm repo add --force-update stackgres-charts https://stackgres.io/downloads/stackgres-k8s/stackgres/helm/ - helm repo update - helm upgrade --install stackgres-operator stackgres-charts/stackgres-operator \ - --create-namespace \ - --namespace stackgres-system \ - --wait - @touch $@ - -.PHONY: cert-manager -cert-manager: $(cert_manager_sentinel) ## Installs Cert Manager in kind cluster - -$(cert_manager_sentinel): export KUBECONFIG = $(KIND_KUBECONFIG) -$(cert_manager_sentinel): $(KIND_KUBECONFIG) - kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.yaml - @touch $@ - -.PHONY: appcat-apiserver ## Installs AppCat APIServer in kind cluster -appcat-apiserver: export KUBECONFIG = $(KIND_KUBECONFIG) -appcat-apiserver: export IMG_TAG=v0.0.1 -appcat-apiserver: export CONTAINER_IMAGE = ghcr.io/vshn/appcat-apiserver:${IMG_TAG} -appcat-apiserver: local-debug apply-test-cases - kubectl apply -f config/apiserver/namespace.yaml - kubectl apply -f config/apiserver - yq e '.spec.template.spec.containers[0].image=strenv(CONTAINER_IMAGE)' config/apiserver/aggregated-apiserver.yaml | kubectl apply -f - - yq e '.spec.insecureSkipTLSVerify=true' config/apiserver/apiservice.yaml | kubectl apply -f - - -.PHONY: appcat-controller ## Installs AppCat APIServer in kind cluster -appcat-controller: export KUBECONFIG = $(KIND_KUBECONFIG) -appcat-controller: export IMG_TAG=v0.0.1 -appcat-controller: export CONTAINER_IMAGE = ghcr.io/vshn/appcat-apiserver:${IMG_TAG} -appcat-controller: local-debug apply-test-cases - kubectl apply -f config/controller/namespace.yaml - kubectl apply -f config/controller - yq e '.spec.template.spec.containers[0].image=strenv(CONTAINER_IMAGE)' config/controller/deployment.yaml | kubectl apply -f - - -.PHONY: .wait-provider -.wait-provider: - @until kubectl get pod -n syn-crossplane --selector=pkg.crossplane.io/provider=provider-$(provider) -o=jsonpath='{.items[0].metadata.name}' >/dev/null 2>&1; do \ - echo 'Waiting for providers'; \ - sleep 1; \ - done - kubectl wait --timeout=60s --for=condition=Ready pod --selector=pkg.crossplane.io/provider=provider-$(provider) -n syn-crossplane - diff --git a/kind/config.yaml b/kind/config.yaml deleted file mode 100644 index eff7657d13..0000000000 --- a/kind/config.yaml +++ /dev/null @@ -1,17 +0,0 @@ -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: - - role: control-plane - kubeadmConfigPatches: - - | - kind: InitConfiguration - nodeRegistration: - kubeletExtraArgs: - node-labels: "ingress-ready=true" - extraPortMappings: - - containerPort: 80 - hostPort: 8081 - protocol: TCP - - containerPort: 443 - hostPort: 8443 - protocol: TCP diff --git a/kind/kind.mk b/kind/kind.mk deleted file mode 100644 index 6d6cf3077f..0000000000 --- a/kind/kind.mk +++ /dev/null @@ -1,56 +0,0 @@ -kind_dir ?= $(PWD)/.kind -kind_bin = $(go_bin)/kind - -# https://hub.docker.com/r/kindest/node/tags -KIND_NODE_VERSION ?= v1.24.0 -KIND_IMAGE ?= docker.io/kindest/node:$(KIND_NODE_VERSION) -KIND_KUBECONFIG ?= $(kind_dir)/kind-kubeconfig-$(KIND_NODE_VERSION) -KIND_CLUSTER ?= $(PROJECT_NAME)-$(KIND_NODE_VERSION) - -# Prepare kind binary -$(kind_bin): export GOOS = $(shell go env GOOS) -$(kind_bin): export GOARCH = $(shell go env GOARCH) -$(kind_bin): export GOBIN = $(go_bin) -$(kind_bin): | $(go_bin) - go install sigs.k8s.io/kind@latest - - -.PHONY: kind -kind: export KUBECONFIG = $(KIND_KUBECONFIG) -kind: kind-setup-ingress kind-load-image ## All-in-one kind target - -.PHONY: kind-setup -kind-setup: export KUBECONFIG = $(KIND_KUBECONFIG) -kind-setup: $(KIND_KUBECONFIG) ## Creates the kind cluster - -.PHONY: kind-setup-ingress -kind-setup-ingress: export KUBECONFIG = $(KIND_KUBECONFIG) -kind-setup-ingress: kind-setup ## Install NGINX as ingress controller onto kind cluster (localhost:8081) - kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml - -.PHONY: kind-load-image -# We fix the arch to linux/amd64 since kind runs in amd64 even on Mac/arm. -kind-load-image: export GOOS = linux -kind-load-image: export GOARCH = amd64 -kind-load-image: kind-setup docker-build ## Load the container image onto kind cluster - $(kind_bin) load docker-image --name $(KIND_CLUSTER) $(GHCR_IMG) - -.PHONY: kind-clean -kind-clean: export KUBECONFIG = $(KIND_KUBECONFIG) -kind-clean: ## Removes the kind Cluster - @$(kind_bin) delete cluster --name $(KIND_CLUSTER) || true - rm -rf $(kind_dir) $(kind_bin) - -$(KIND_KUBECONFIG): export KUBECONFIG = $(KIND_KUBECONFIG) -$(KIND_KUBECONFIG): $(kind_bin) - $(kind_bin) create cluster \ - --name $(KIND_CLUSTER) \ - --image $(KIND_IMAGE) \ - --config kind/config.yaml - @kubectl version - @kubectl cluster-info - @kubectl config use-context kind-$(KIND_CLUSTER) - @echo ======= - @echo "Setup finished. To interact with the local dev cluster, set the KUBECONFIG environment variable as follows:" - @echo "export KUBECONFIG=$$(realpath "$(KIND_KUBECONFIG)")" - @echo ======= From 0652fb3c4d5ec0cb458fcd93807d4be487868e13 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Tue, 9 May 2023 17:54:11 +0200 Subject: [PATCH 02/26] Fix generation target bugs --- Makefile | 6 ++---- apis/appcat/v1/vshn_postgres_backup_types.go | 2 +- {hack => apiserver/hack}/boilerplate.txt | 0 3 files changed, 3 insertions(+), 5 deletions(-) rename {hack => apiserver/hack}/boilerplate.txt (100%) diff --git a/Makefile b/Makefile index aaf1221c06..fb037239e0 100644 --- a/Makefile +++ b/Makefile @@ -45,8 +45,6 @@ $(protoc_bin): | $(go_bin) @unzip $(go_bin)/protoc.zip -d .work @rm $(go_bin)/protoc.zip -include kind/kind.mk -include dev/local.mk -include docs/antora-preview.mk docs/antora-build.mk .PHONY: help @@ -58,11 +56,11 @@ generate: export PATH := $(go_bin):$(PATH) generate: $(protoc_bin) ## Generate code with controller-gen and protobuf. go generate ./... go run sigs.k8s.io/controller-tools/cmd/controller-gen object paths="./apis/..." - go run sigs.k8s.io/controller-tools/cmd/controller-gen rbac:roleName=appcat-apiserver paths="{./apis/...,./apiserver/...}" output:artifacts:config=config/ + go run sigs.k8s.io/controller-tools/cmd/controller-gen rbac:roleName=appcat-apiserver paths="{./apis/...,./apiserver/...}" output:artifacts:config=config/apiserver go run k8s.io/code-generator/cmd/go-to-protobuf \ --packages=github.com/vshn/appcat-apiserver/apis/appcat/v1 \ --output-base=./.work/tmp \ - --go-header-file=./hack/boilerplate.txt \ + --go-header-file=./apiserver/hack/boilerplate.txt \ --apimachinery-packages='-k8s.io/apimachinery/pkg/util/intstr,-k8s.io/apimachinery/pkg/api/resource,-k8s.io/apimachinery/pkg/runtime/schema,-k8s.io/apimachinery/pkg/runtime,-k8s.io/apimachinery/pkg/apis/meta/v1,-k8s.io/apimachinery/pkg/apis/meta/v1beta1,-k8s.io/api/core/v1,-k8s.io/api/rbac/v1' \ --proto-import=./.work/kubernetes/vendor/ && \ mv ./.work/tmp/github.com/vshn/appcat-apiserver/apis/appcat/v1/generated.pb.go ./apis/appcat/v1/ && \ diff --git a/apis/appcat/v1/vshn_postgres_backup_types.go b/apis/appcat/v1/vshn_postgres_backup_types.go index 9f36c9c1cf..bd6f7c230a 100644 --- a/apis/appcat/v1/vshn_postgres_backup_types.go +++ b/apis/appcat/v1/vshn_postgres_backup_types.go @@ -8,7 +8,7 @@ import ( ) // +kubebuilder:rbac:groups="stackgres.io",resources=sgbackups,verbs=get;list;watch -// +kubebuilder:rbac:groups="vshn.appcat.vshn.io",resources=vshnpostgresqls,verbs=get;list;watch +// +kubebuilder:rbac:groups="vshn.appcat.vshn.io",resources=xvshnpostgresqls,verbs=get;list;watch var ( // ResourceBackup is the name of this backup resource in plural form diff --git a/hack/boilerplate.txt b/apiserver/hack/boilerplate.txt similarity index 100% rename from hack/boilerplate.txt rename to apiserver/hack/boilerplate.txt From 78d67983f08cb2e17ebe1b7b6ea8405234036e24 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Thu, 11 May 2023 10:00:47 +0200 Subject: [PATCH 03/26] Port SLI Exporter into repository --- README.md | 42 ++- command/postgresql_controller.go | 101 ++++++ command/root.go | 7 +- ...ontroller.go => xpostgresql_controller.go} | 29 +- .../{ => postgres}/cluster-role-binding.yaml | 0 .../{ => postgres}/cluster-role.yaml | 0 .../controller/{ => postgres}/deployment.yaml | 0 .../controller/{ => postgres}/namespace.yaml | 0 .../role-binding-leader-election.yaml | 0 .../{ => postgres}/role-leader-election.yaml | 0 .../{ => postgres}/service-account.yaml | 0 .../sli-exporter/default/kustomization.yaml | 28 ++ .../default/manager_auth_proxy_patch.yaml | 26 ++ .../sli-exporter/manager/kustomization.yaml | 5 + .../sli-exporter/manager/manager.yaml | 54 +++ .../prometheus/kustomization.yaml | 2 + .../sli-exporter/prometheus/monitor.yaml | 21 ++ .../rbac/auth_proxy_client_clusterrole.yaml | 9 + .../sli-exporter/rbac/auth_proxy_role.yaml | 17 + .../rbac/auth_proxy_role_binding.yaml | 12 + .../sli-exporter/rbac/auth_proxy_service.yaml | 15 + .../sli-exporter/rbac/kustomization.yaml | 13 + config/controller/sli-exporter/rbac/role.yaml | 21 ++ .../sli-exporter/rbac/role_binding.yaml | 12 + .../sli-exporter/rbac/service_account.yaml | 5 + controller/sli-exporter/probes/manager.go | 138 ++++++++ .../sli-exporter/probes/manager_test.go | 276 +++++++++++++++ controller/sli-exporter/probes/postgresql.go | 112 ++++++ .../sli-exporter/probes/postgresql_test.go | 90 +++++ .../sli-exporter/vshnpostgresql_controller.go | 143 ++++++++ .../vshnpostgresql_controller_test.go | 323 ++++++++++++++++++ go.mod | 28 +- go.sum | 77 ++++- 33 files changed, 1570 insertions(+), 36 deletions(-) create mode 100644 command/postgresql_controller.go rename command/{controller.go => xpostgresql_controller.go} (65%) rename config/controller/{ => postgres}/cluster-role-binding.yaml (100%) rename config/controller/{ => postgres}/cluster-role.yaml (100%) rename config/controller/{ => postgres}/deployment.yaml (100%) rename config/controller/{ => postgres}/namespace.yaml (100%) rename config/controller/{ => postgres}/role-binding-leader-election.yaml (100%) rename config/controller/{ => postgres}/role-leader-election.yaml (100%) rename config/controller/{ => postgres}/service-account.yaml (100%) create mode 100644 config/controller/sli-exporter/default/kustomization.yaml create mode 100644 config/controller/sli-exporter/default/manager_auth_proxy_patch.yaml create mode 100644 config/controller/sli-exporter/manager/kustomization.yaml create mode 100644 config/controller/sli-exporter/manager/manager.yaml create mode 100644 config/controller/sli-exporter/prometheus/kustomization.yaml create mode 100644 config/controller/sli-exporter/prometheus/monitor.yaml create mode 100644 config/controller/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml create mode 100644 config/controller/sli-exporter/rbac/auth_proxy_role.yaml create mode 100644 config/controller/sli-exporter/rbac/auth_proxy_role_binding.yaml create mode 100644 config/controller/sli-exporter/rbac/auth_proxy_service.yaml create mode 100644 config/controller/sli-exporter/rbac/kustomization.yaml create mode 100644 config/controller/sli-exporter/rbac/role.yaml create mode 100644 config/controller/sli-exporter/rbac/role_binding.yaml create mode 100644 config/controller/sli-exporter/rbac/service_account.yaml create mode 100644 controller/sli-exporter/probes/manager.go create mode 100644 controller/sli-exporter/probes/manager_test.go create mode 100644 controller/sli-exporter/probes/postgresql.go create mode 100644 controller/sli-exporter/probes/postgresql_test.go create mode 100644 controller/sli-exporter/vshnpostgresql_controller.go create mode 100644 controller/sli-exporter/vshnpostgresql_controller_test.go diff --git a/README.md b/README.md index fd18691e04..d64039d003 100644 --- a/README.md +++ b/README.md @@ -105,4 +105,44 @@ A postgres controller has been added to this API Server. The controller takes ca The controller insures via a finalizer in composite `XVSHNPostgreSQL` resource that the backups are still available when the database instance is deleted. When deletion retention expires, the backups with the remaining resources are cleaned up automatically. -This controller addition to this repository is a temporary solution until we move to a common AppCat repository. \ No newline at end of file +This controller addition to this repository is a temporary solution until we move to a common AppCat repository. + + +## SLI Exporter +### Metrics + +The exporter exposes a histogram `appcat_probes_seconds` with four labels + +* `service`, the service type that was probed (e.g. `VSHNPostgreSQL`) +* `namespace`, the namespace of the claim that was monitored +* `name`, the name of the claim that was monitored +* `reason`, if the probe was successful. Can either be `success`, `fail-timeout`, or `fail-unkown` + +### Architecture + +``` +. +├── config // Kustomize files to deploy the exporter +├── controllers +│   └── vshnpostgresql_controller.go // starts probes for VSHNPostgreSQL claims +├── Dockerfile +├── main.go +├── probes +│   ├── manager.go // manages all started probes and exposes metrics +│   └── postgresql.go // prober implementation for postgresql +├── README.md +└── tools.go +``` + +#### Adding a Prober + +To add a prober for a new service, add a file in `probes/` that adds another implementation of the `Prober` interface. + +#### Adding an AppCat service + +There should be a separate controller per AppCat Claim type. +Add another controller for each service that should be probed. + +#### Adding SLA exceptions + +If possible SLA exceptions should be implemented as a middleware for the `Prober` interface. diff --git a/command/postgresql_controller.go b/command/postgresql_controller.go new file mode 100644 index 0000000000..4f259c047d --- /dev/null +++ b/command/postgresql_controller.go @@ -0,0 +1,101 @@ +package command + +import ( + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + "github.com/go-logr/logr" + "github.com/spf13/cobra" + sli_exporter "github.com/vshn/appcat-apiserver/controller/sli-exporter" + "github.com/vshn/appcat-apiserver/controller/sli-exporter/probes" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "os" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/metrics" + "strconv" + "time" +) + +func init() { + _ = corev1.SchemeBuilder.AddToScheme(s_prober) + _ = xkube.SchemeBuilder.AddToScheme(s_prober) + _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s_prober) + + sliProber.Flags().StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + sliProber.Flags().StringVar(&healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") + sliProber.Flags().BoolVar(&leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + sliProber.Flags().BoolVar(&enableVSHNPostgreSQL, "vshn-postgresql", getEnvBool("APPCAT_SLI_VSHNPOSTGRESQL"), + "Enable probing of VSHNPostgreSQL instances") +} + +var sliProber = &cobra.Command{ + Use: "sli-prober", + Short: "SLI Prober Controller", + Long: "Run the SLI Prober Controller", + RunE: executeProberController, +} + +var s_prober = runtime.NewScheme() + +// Run will run the controller mode of the composition function runner. +func executeProberController(cmd *cobra.Command, _ []string) error { + log := logr.FromContextOrDiscard(cmd.Context()) + ctrl.SetLogger(log) + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: s_prober, + MetricsBindAddress: metricsAddr, + Port: 9443, + HealthProbeBindAddress: probeAddr, + LeaderElection: leaderElect, + LeaderElectionID: "05f8b574.appcat.vshn.io", + }) + if err != nil { + log.Error(err, "unable to start manager") + return err + } + probeManager := probes.NewManager(log) + + err = metrics.Registry.Register(probeManager.Collector()) + if err != nil { + log.Error(err, "unable to register metrics") + return err + } + + if enableVSHNPostgreSQL { + if err = (&sli_exporter.VSHNPostgreSQLReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + ProbeManager: &probeManager, + StartupGracePeriod: 15 * time.Minute, + PostgreDialer: probes.NewPostgreSQL, + }).SetupWithManager(mgr); err != nil { + log.Error(err, "unable to create controller", "controller", "VSHNPostgreSQL") + return err + } + } + //+kubebuilder:scaffold:builder + + if err = mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + log.Error(err, "unable to set up health check") + return err + } + if err = mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + log.Error(err, "unable to set up ready check") + return err + } + + log.Info("starting manager") + if err = mgr.Start(ctrl.SetupSignalHandler()); err != nil { + log.Error(err, "problem running manager") + return err + } + return nil +} + +func getEnvBool(key string) bool { + b, err := strconv.ParseBool(os.Getenv(key)) + return err == nil && b +} diff --git a/command/root.go b/command/root.go index 29b45ad9e2..1c52fe55fa 100644 --- a/command/root.go +++ b/command/root.go @@ -7,6 +7,11 @@ import ( "os" ) +var ( + metricsAddr, healthAddr, probeAddr string + leaderElect, enableVSHNPostgreSQL bool +) + var ( logLevel int logFormat string @@ -31,7 +36,7 @@ func Execute() { } func init() { - rootCmd.AddCommand(controller, apiServerCmd) + rootCmd.AddCommand(xpostgresql, apiServerCmd, sliProber) } func setupLogging(cmd *cobra.Command, _ []string) error { diff --git a/command/controller.go b/command/xpostgresql_controller.go similarity index 65% rename from command/controller.go rename to command/xpostgresql_controller.go index bf7200ccf1..d3da5f11a9 100644 --- a/command/controller.go +++ b/command/xpostgresql_controller.go @@ -13,37 +13,32 @@ import ( ) func init() { - _ = corev1.SchemeBuilder.AddToScheme(s) - _ = xkube.SchemeBuilder.AddToScheme(s) - _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s) + _ = corev1.SchemeBuilder.AddToScheme(s_xpostgres) + _ = xkube.SchemeBuilder.AddToScheme(s_xpostgres) + _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s_xpostgres) - controller.Flags().StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") - controller.Flags().StringVar(&healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") - controller.Flags().BoolVar(&leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ + xpostgresql.Flags().StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + xpostgresql.Flags().StringVar(&healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") + xpostgresql.Flags().BoolVar(&leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") } -var ( - metricsAddr, healthAddr string - leaderElect bool -) - -var controller = &cobra.Command{ - Use: "controller", +var xpostgresql = &cobra.Command{ + Use: "postgres-controller", Short: "Postgres Controller", Long: "Run the Postgres Controller", - RunE: executeController, + RunE: executeXVSHNPostgreSQLController, } -var s = runtime.NewScheme() +var s_xpostgres = runtime.NewScheme() // Run will run the controller mode of the composition function runner. -func executeController(cmd *cobra.Command, _ []string) error { +func executeXVSHNPostgreSQLController(cmd *cobra.Command, _ []string) error { log := logr.FromContextOrDiscard(cmd.Context()) ctrl.SetLogger(log) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: s, + Scheme: s_xpostgres, MetricsBindAddress: metricsAddr, Port: 9443, HealthProbeBindAddress: healthAddr, diff --git a/config/controller/cluster-role-binding.yaml b/config/controller/postgres/cluster-role-binding.yaml similarity index 100% rename from config/controller/cluster-role-binding.yaml rename to config/controller/postgres/cluster-role-binding.yaml diff --git a/config/controller/cluster-role.yaml b/config/controller/postgres/cluster-role.yaml similarity index 100% rename from config/controller/cluster-role.yaml rename to config/controller/postgres/cluster-role.yaml diff --git a/config/controller/deployment.yaml b/config/controller/postgres/deployment.yaml similarity index 100% rename from config/controller/deployment.yaml rename to config/controller/postgres/deployment.yaml diff --git a/config/controller/namespace.yaml b/config/controller/postgres/namespace.yaml similarity index 100% rename from config/controller/namespace.yaml rename to config/controller/postgres/namespace.yaml diff --git a/config/controller/role-binding-leader-election.yaml b/config/controller/postgres/role-binding-leader-election.yaml similarity index 100% rename from config/controller/role-binding-leader-election.yaml rename to config/controller/postgres/role-binding-leader-election.yaml diff --git a/config/controller/role-leader-election.yaml b/config/controller/postgres/role-leader-election.yaml similarity index 100% rename from config/controller/role-leader-election.yaml rename to config/controller/postgres/role-leader-election.yaml diff --git a/config/controller/service-account.yaml b/config/controller/postgres/service-account.yaml similarity index 100% rename from config/controller/service-account.yaml rename to config/controller/postgres/service-account.yaml diff --git a/config/controller/sli-exporter/default/kustomization.yaml b/config/controller/sli-exporter/default/kustomization.yaml new file mode 100644 index 0000000000..36e1dccf5f --- /dev/null +++ b/config/controller/sli-exporter/default/kustomization.yaml @@ -0,0 +1,28 @@ +# Adds namespace to all resources. +namespace: appcat-sli-exporter + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: appcat-sli-exporter- + +# Labels to add to all resources and selectors. +#commonLabels: +# someName: someValue + +bases: +- ../rbac +- ../manager +- ../prometheus + +patchesStrategicMerge: +# Protect the /metrics endpoint by putting it behind auth. +# If you want your controller-manager to expose the /metrics +# endpoint w/o any authn/z, please comment the following line. +- manager_auth_proxy_patch.yaml + +# the following config is for teaching kustomize how to do var substitution +vars: + diff --git a/config/controller/sli-exporter/default/manager_auth_proxy_patch.yaml b/config/controller/sli-exporter/default/manager_auth_proxy_patch.yaml new file mode 100644 index 0000000000..bb88cffe8b --- /dev/null +++ b/config/controller/sli-exporter/default/manager_auth_proxy_patch.yaml @@ -0,0 +1,26 @@ +# This patch inject a sidecar container which is a HTTP proxy for the +# controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: kube-rbac-proxy + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + ports: + - containerPort: 8443 + protocol: TCP + name: https + - name: manager + args: + - "--health-probe-bind-address=:8081" + - "--metrics-bind-address=127.0.0.1:8080" diff --git a/config/controller/sli-exporter/manager/kustomization.yaml b/config/controller/sli-exporter/manager/kustomization.yaml new file mode 100644 index 0000000000..4fe5ccaa3a --- /dev/null +++ b/config/controller/sli-exporter/manager/kustomization.yaml @@ -0,0 +1,5 @@ +resources: +- manager.yaml + +generatorOptions: + disableNameSuffixHash: true diff --git a/config/controller/sli-exporter/manager/manager.yaml b/config/controller/sli-exporter/manager/manager.yaml new file mode 100644 index 0000000000..6c739fa745 --- /dev/null +++ b/config/controller/sli-exporter/manager/manager.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-manager + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system + labels: + control-plane: controller-manager +spec: + selector: + matchLabels: + control-plane: controller-manager + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + spec: + securityContext: + runAsNonRoot: true + containers: + - image: ghcr.io/vshn/appcat-sli-exporter:latest + name: manager + securityContext: + allowPrivilegeEscalation: false + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 10m + memory: 128Mi + serviceAccountName: controller-manager + terminationGracePeriodSeconds: 10 diff --git a/config/controller/sli-exporter/prometheus/kustomization.yaml b/config/controller/sli-exporter/prometheus/kustomization.yaml new file mode 100644 index 0000000000..ed137168a1 --- /dev/null +++ b/config/controller/sli-exporter/prometheus/kustomization.yaml @@ -0,0 +1,2 @@ +resources: +- monitor.yaml diff --git a/config/controller/sli-exporter/prometheus/monitor.yaml b/config/controller/sli-exporter/prometheus/monitor.yaml new file mode 100644 index 0000000000..38faa0b0c9 --- /dev/null +++ b/config/controller/sli-exporter/prometheus/monitor.yaml @@ -0,0 +1,21 @@ + +# Prometheus Monitor Service (Metrics) +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + control-plane: controller-manager + name: controller-manager-metrics-monitor + namespace: system +spec: + endpoints: + - path: /metrics + port: https + scheme: https + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + tlsConfig: + insecureSkipVerify: true + selector: + matchLabels: + control-plane: controller-manager diff --git a/config/controller/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml b/config/controller/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 0000000000..51a75db47a --- /dev/null +++ b/config/controller/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/config/controller/sli-exporter/rbac/auth_proxy_role.yaml b/config/controller/sli-exporter/rbac/auth_proxy_role.yaml new file mode 100644 index 0000000000..80e1857c59 --- /dev/null +++ b/config/controller/sli-exporter/rbac/auth_proxy_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-role +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/config/controller/sli-exporter/rbac/auth_proxy_role_binding.yaml b/config/controller/sli-exporter/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 0000000000..ec7acc0a1b --- /dev/null +++ b/config/controller/sli-exporter/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-role +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: system diff --git a/config/controller/sli-exporter/rbac/auth_proxy_service.yaml b/config/controller/sli-exporter/rbac/auth_proxy_service.yaml new file mode 100644 index 0000000000..71f1797279 --- /dev/null +++ b/config/controller/sli-exporter/rbac/auth_proxy_service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + name: controller-manager-metrics-service + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager diff --git a/config/controller/sli-exporter/rbac/kustomization.yaml b/config/controller/sli-exporter/rbac/kustomization.yaml new file mode 100644 index 0000000000..4dbc73ea64 --- /dev/null +++ b/config/controller/sli-exporter/rbac/kustomization.yaml @@ -0,0 +1,13 @@ +resources: +# All RBAC will be applied under this service account in +# the deployment namespace. You may comment out this resource +# if your manager will use a service account that exists at +# runtime. Be sure to update RoleBinding and ClusterRoleBinding +# subjects if changing service account names. +- service_account.yaml +- role.yaml +- role_binding.yaml +- auth_proxy_service.yaml +- auth_proxy_role.yaml +- auth_proxy_role_binding.yaml +- auth_proxy_client_clusterrole.yaml diff --git a/config/controller/sli-exporter/rbac/role.yaml b/config/controller/sli-exporter/rbac/role.yaml new file mode 100644 index 0000000000..f9c12bb312 --- /dev/null +++ b/config/controller/sli-exporter/rbac/role.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: appcat-sli-exporter +rules: +- apiGroups: + - vshn.appcat.vshn.io + resources: + - vshnpostgresqls + verbs: + - get + - list + - watch +- apiGroups: + - vshn.appcat.vshn.io + resources: + - vshnpostgresqls/status + verbs: + - get diff --git a/config/controller/sli-exporter/rbac/role_binding.yaml b/config/controller/sli-exporter/rbac/role_binding.yaml new file mode 100644 index 0000000000..38338f238a --- /dev/null +++ b/config/controller/sli-exporter/rbac/role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: glrf-test-appcat-sli-probe +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: controller-manager + namespace: glrf-test diff --git a/config/controller/sli-exporter/rbac/service_account.yaml b/config/controller/sli-exporter/rbac/service_account.yaml new file mode 100644 index 0000000000..e04a4c10e1 --- /dev/null +++ b/config/controller/sli-exporter/rbac/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-manager + namespace: glrf-test diff --git a/controller/sli-exporter/probes/manager.go b/controller/sli-exporter/probes/manager.go new file mode 100644 index 0000000000..9e4a50b7d7 --- /dev/null +++ b/controller/sli-exporter/probes/manager.go @@ -0,0 +1,138 @@ +package probes + +import ( + "context" + "errors" + "time" + + "github.com/go-logr/logr" + "github.com/prometheus/client_golang/prometheus" +) + +// Manager manages a collection of Probers the check connectivity to AppCat services. +type Manager struct { + probers map[ProbeInfo]context.CancelFunc + hist prometheus.ObserverVec + log logr.Logger + + newTicker func() (<-chan time.Time, func()) +} + +// Prober checks the connectivity to an AppCat service +type Prober interface { + GetInfo() ProbeInfo + Probe(ctx context.Context) error + Close() error +} + +// ProbeInfo uniquely identifies a prober and in turn an AppCat service instance +type ProbeInfo struct { + Service string + Name string + Namespace string +} + +var ErrTimeout = errors.New("probe timed out") + +func NewManager(l logr.Logger) Manager { + hist := prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Name: "appcat_probes_seconds", + Help: "Latency of probes to appact services", + Buckets: []float64{0.001, 0.002, 0.003, 0.004, 0.005, 0.01, 0.015, 0.02, 0.025, 0.05, 0.1, .5, 1}, + }, []string{"service", "namespace", "name", "reason"}) + + return Manager{ + probers: map[ProbeInfo]context.CancelFunc{}, + hist: hist, + log: l, + newTicker: newTickerChan, + } +} + +// Collector returns the histogram to store the probe results +func (m Manager) Collector() prometheus.Collector { + return m.hist +} + +// StartProbe will send a probe once every second using the provided prober. +// If a prober with the same ProbeInfo already runs, it will stop the running prober. +func (m Manager) StartProbe(p Prober) { + l := m.log.WithValues("namespace", p.GetInfo().Namespace, "name", p.GetInfo().Name) + cancel, ok := m.probers[p.GetInfo()] + if ok { + l.Info("Cancel Probe") + cancel() + } + + ctx, cancel := context.WithCancel(context.Background()) + m.probers[p.GetInfo()] = cancel + l.Info("Start Probe") + go m.runProbe(ctx, p) +} + +// StopProbe will stop the prober with the provided ProbeInfo. +// Is a Noop if none is running. +func (m Manager) StopProbe(pi ProbeInfo) { + cancel, ok := m.probers[pi] + if ok { + cancel() + } +} + +func (m Manager) runProbe(ctx context.Context, p Prober) { + ticker, stop := m.newTicker() + defer stop() + defer p.Close() + + for { + select { + case <-ctx.Done(): + return + case <-ticker: + go m.sendProbe(ctx, p) + } + } +} + +func (m Manager) sendProbe(ctx context.Context, p Prober) { + pi := p.GetInfo() + o, err := m.hist.CurryWith(prometheus.Labels{ + "service": pi.Service, + "namespace": pi.Namespace, + "name": pi.Name, + }) + if err != nil { + return + } + l := m.log.WithValues("service", pi.Service, "namespace", pi.Namespace, "name", pi.Name) + + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + start := time.Now() + err = p.Probe(ctx) + latency := time.Since(start) + + switch { + case err == nil: + o.With( + prometheus.Labels{"reason": "success"}, + ).Observe(latency.Seconds()) + case errors.Is(err, ErrTimeout) || errors.Is(ctx.Err(), context.DeadlineExceeded): + o.With( + prometheus.Labels{"reason": "fail-timeout"}, + ).Observe(latency.Seconds()) + case errors.Is(ctx.Err(), context.Canceled): + l.V(0).Info("Probe Canceled") + default: + l.V(0).Info("Probe Failure", "error", err) + o.With( + prometheus.Labels{"reason": "fail-unknown"}, + ).Observe(latency.Seconds()) + } +} + +func newTickerChan() (<-chan time.Time, func()) { + ticker := time.NewTicker(time.Second) + return ticker.C, ticker.Stop +} diff --git a/controller/sli-exporter/probes/manager_test.go b/controller/sli-exporter/probes/manager_test.go new file mode 100644 index 0000000000..6ab565a736 --- /dev/null +++ b/controller/sli-exporter/probes/manager_test.go @@ -0,0 +1,276 @@ +package probes + +import ( + "context" + "errors" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/go-logr/logr" + "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/assert" +) + +func TestManger_Simple(t *testing.T) { + t.Parallel() + + m := NewManager(logr.Discard()) + observer := &fakeObserveVec{ + observations: &[]observation{}, + mu: &sync.Mutex{}, + curried: observation{ + labels: map[string]string{}, + }, + } + m.hist = observer + p := newFakeProbe("fake", "bar", "foo") + m.newTicker = func() (<-chan time.Time, func()) { + return p.ticker, func() {} + } + + m.StartProbe(p) + p.tick(nil) + p.tick(nil) + p.tick(errors.New("ups")) + p.tick(nil) + p.tick(nil) + + assert.Eventually(t, func() bool { + return p.getCount() == 5 + }, time.Second, 10*time.Millisecond) + assert.EqualValues(t, 5, p.getCount()) + + m.StopProbe(p.GetInfo()) + assert.EqualValues(t, 1, observer.countWithout("reason", "success")) + + p.tick(nil) + assert.Never(t, func() bool { + return p.getCount() > 5 + }, 250*time.Millisecond, 10*time.Millisecond) + +} + +func TestManger_Multi(t *testing.T) { + t.Parallel() + + m := NewManager(logr.Discard()) + tickerChan := make(chan chan time.Time) + m.newTicker = func() (<-chan time.Time, func()) { + return <-tickerChan, func() {} + } + observer := &fakeObserveVec{ + observations: &[]observation{}, + mu: &sync.Mutex{}, + curried: observation{ + labels: map[string]string{}, + }, + } + m.hist = observer + + pa := newFakeProbe("fake", "foo", "alice") + pb := newFakeProbe("fake", "foo", "bob") + + m.StartProbe(pa) + tickerChan <- pa.ticker + m.StartProbe(pb) + tickerChan <- pb.ticker + pa.tick(nil) + pb.tick(errors.New("Failure")) + pa.tick(nil) + pb.tick(nil) + pa.tick(nil) + pa.tick(nil) + pa.tick(errors.New("Failure")) + pa.tick(errors.New("Failure")) + pb.tick(nil) + pa.tick(errors.New("Failure")) + pb.tick(nil) + pa.tick(nil) + pa.tick(nil) + + assert.Eventually(t, func() bool { + return pa.getCount() == 9 + }, time.Second, 10*time.Millisecond) + assert.EqualValues(t, 9, pa.getCount()) + m.StopProbe(pa.GetInfo()) + + pb.tick(nil) + pb.tick(nil) + pa.tick(errors.New("Failure")) + + assert.Eventually(t, func() bool { + return pb.getCount() == 6 + }, time.Second, 10*time.Millisecond) + assert.EqualValues(t, 6, pb.getCount()) + m.StopProbe(pb.GetInfo()) + + assert.EqualValues(t, 4, observer.countWithout("reason", "success")) + assert.EqualValues(t, 6, observer.countWith("name", "bob")) + assert.EqualValues(t, 9, observer.countWith("name", "alice")) + + assert.Never(t, func() bool { + return pa.getCount() > 9 + }, 250*time.Millisecond, 10*time.Millisecond) + +} + +func newFakeProbe(service, namespace, name string) *fakeProbe { + return &fakeProbe{ + info: ProbeInfo{ + Service: service, + Name: name, + Namespace: namespace, + }, + results: make(chan error, 10), + ticker: make(chan time.Time, 10), + } + +} + +func (f *fakeProbe) tick(res error) { + f.results <- res + f.ticker <- f.current + f.current = f.current.Add(5 * time.Second) +} + +type fakeProbe struct { + info ProbeInfo + + results chan error + ticker chan time.Time + current time.Time + count uint64 +} + +// Close implements Prober +func (p *fakeProbe) Close() error { + return nil +} + +// GetInfo implements Prober +func (p *fakeProbe) GetInfo() ProbeInfo { + return p.info +} + +// Probe implements Prober +func (f *fakeProbe) Probe(ctx context.Context) error { + atomic.AddUint64(&f.count, 1) + err := <-f.results + return err +} + +func (f *fakeProbe) getCount() uint64 { + return atomic.LoadUint64(&f.count) +} + +type observation struct { + labels prometheus.Labels + value float64 +} + +type fakeObserveVec struct { + observations *[]observation + mu *sync.Mutex + + curried observation +} + +func (f *fakeObserveVec) countWith(key, val string) int { + count := 0 + for _, o := range *f.observations { + if o.labels[key] == val { + count++ + } + } + return count +} +func (f *fakeObserveVec) countWithout(key, val string) int { + count := 0 + for _, o := range *f.observations { + if o.labels[key] != val { + count++ + } + } + return count +} + +// CurryWith implements prometheus.ObserverVec +func (f *fakeObserveVec) CurryWith(l prometheus.Labels) (prometheus.ObserverVec, error) { + res := f.with(l) + return res, nil +} + +// With implements prometheus.ObserverVec +func (f *fakeObserveVec) With(l prometheus.Labels) prometheus.Observer { + return f.with(l) +} + +func (f *fakeObserveVec) with(l prometheus.Labels) *fakeObserveVec { + f.mu.Lock() + defer f.mu.Unlock() + res := fakeObserveVec{ + observations: f.observations, + mu: f.mu, + } + res.curried = f.observationWith(f.curried, l) + return &res +} + +func (f *fakeObserveVec) observationWith(obs observation, l prometheus.Labels) observation { + //log.Printf("observationWith: %v prev %v\n", l, f.curried.labels) + res := observation{ + labels: prometheus.Labels{}, + } + for key, val := range f.curried.labels { + res.labels[key] = val + } + for key, val := range l { + res.labels[key] = val + } + return res +} + +func (f *fakeObserveVec) Observe(v float64) { + f.mu.Lock() + defer f.mu.Unlock() + obs := observation{ + labels: map[string]string{}, + value: v, + } + for key, val := range f.curried.labels { + obs.labels[key] = val + } + *f.observations = append(*f.observations, obs) +} + +// Collect implements prometheus.ObserverVec +func (fakeObserveVec) Collect(chan<- prometheus.Metric) { + panic("unimplemented") +} + +// Describe implements prometheus.ObserverVec +func (fakeObserveVec) Describe(chan<- *prometheus.Desc) { + panic("unimplemented") +} + +// GetMetricWith implements prometheus.ObserverVec +func (fakeObserveVec) GetMetricWith(prometheus.Labels) (prometheus.Observer, error) { + panic("unimplemented") +} + +// GetMetricWithLabelValues implements prometheus.ObserverVec +func (fakeObserveVec) GetMetricWithLabelValues(lvs ...string) (prometheus.Observer, error) { + panic("unimplemented") +} + +// MustCurryWith implements prometheus.ObserverVec +func (fakeObserveVec) MustCurryWith(prometheus.Labels) prometheus.ObserverVec { + panic("unimplemented") +} + +// WithLabelValues implements prometheus.ObserverVec +func (fakeObserveVec) WithLabelValues(...string) prometheus.Observer { + panic("unimplemented") +} diff --git a/controller/sli-exporter/probes/postgresql.go b/controller/sli-exporter/probes/postgresql.go new file mode 100644 index 0000000000..1874a6ffe4 --- /dev/null +++ b/controller/sli-exporter/probes/postgresql.go @@ -0,0 +1,112 @@ +package probes + +import ( + "context" + "crypto/tls" + "crypto/x509" + "errors" + "time" + + "github.com/jackc/pgx/v5/pgxpool" +) + +var _ Prober = PostgreSQL{} + +// PostgreSQL is a prober to test the uptime of a PostgreSQL instance. +type PostgreSQL struct { + db *pgxpool.Pool + + Service string + Instance string + Namespace string +} + +// Close closes open connections to the PostgreSQL server. +func (p PostgreSQL) Close() error { + if p.db != nil { + p.db.Close() + } + return nil +} + +// GetInfo returns the prober infos +func (p PostgreSQL) GetInfo() ProbeInfo { + return ProbeInfo{ + Service: p.Service, + Name: p.Instance, + Namespace: p.Namespace, + } +} + +// Probe sends a test query to the configured PostgreSQL server. +// Will return an error if the prober does not have a valid db connection. +func (p PostgreSQL) Probe(ctx context.Context) error { + if p.db == nil { + return errors.New("invalid credentials") + } + _, err := p.db.Exec(ctx, "SELECT 1") + return err +} + +// NewPostgreSQL connects to the provided dsn and returns a prober +func NewPostgreSQL(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*PostgreSQL, error) { + conf, err := pgxpool.ParseConfig(dsn) + if err != nil { + return nil, err + } + conf.ConnConfig.ConnectTimeout = 5 * time.Second + conf.MaxConns = 1 + + for _, op := range ops { + err := op(conf) + if err != nil { + return nil, err + } + } + + db, err := pgxpool.NewWithConfig(context.Background(), conf) + if err != nil { + return nil, err + } + + return &PostgreSQL{ + db: db, + Service: service, + Instance: name, + Namespace: namespace, + }, nil +} + +// NewFailingPostgreSQL creates a prober that will fail. +// Can be used if the controller can't access valid credentials. +func NewFailingPostgreSQL(service, name, namespace string) (*PostgreSQL, error) { + return &PostgreSQL{ + Service: service, + Instance: name, + Namespace: namespace, + }, nil +} + +// PGWithCA adds the provided CA to the rootCAs of the pgxpool. +func PGWithCA(ca []byte) func(*pgxpool.Config) error { + return func(conf *pgxpool.Config) error { + if conf.ConnConfig.TLSConfig == nil { + conf.ConnConfig.TLSConfig = &tls.Config{ + RootCAs: x509.NewCertPool(), + } + } + + if conf.ConnConfig.TLSConfig.RootCAs == nil { + conf.ConnConfig.TLSConfig.RootCAs = x509.NewCertPool() + } + + if ca == nil { + return errors.New("got nil CA") + } + + if !conf.ConnConfig.TLSConfig.RootCAs.AppendCertsFromPEM(ca) { + return errors.New("cannot append root CA certificates") + } + return nil + } +} diff --git a/controller/sli-exporter/probes/postgresql_test.go b/controller/sli-exporter/probes/postgresql_test.go new file mode 100644 index 0000000000..73f2bdffe6 --- /dev/null +++ b/controller/sli-exporter/probes/postgresql_test.go @@ -0,0 +1,90 @@ +package probes + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/ory/dockertest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPostgreSQL_Probe(t *testing.T) { + t.Parallel() + + pool, err := dockertest.NewPool("") + require.NoError(t, err) + + user := "foo" + password := "bar" + db := "buzz" + + res, err := pool.Run("postgres", "12.3", []string{ + "POSTGRES_USER=" + user, + "POSTGRES_PASSWORD=" + password, + "POSTGRES_DB=" + db, + }) + require.NoError(t, err) + defer pool.Purge(res) + + var p Prober + assert.Eventually(t, func() bool { + p, err = NewPostgreSQL("VSHN", "test", "test", + fmt.Sprintf( + "postgresql://%s:%s@%s:%s/%s?sslmode=disable", + user, + password, + "localhost", + res.GetPort("5432/tcp"), + db, + ), + ) + return err == nil + }, 2*time.Second, 500*time.Millisecond) + require.NoError(t, err) + + assert.Eventually(t, func() bool { + err = p.Probe(context.TODO()) + return err == nil + }, 2*time.Second, 500*time.Millisecond) + assert.NoError(t, err) + + assert.Never(t, func() bool { + err = p.Probe(context.TODO()) + return err != nil + }, 1*time.Second, 100*time.Millisecond) + + require.NoError(t, res.Close()) + + assert.Eventually(t, func() bool { + err = p.Probe(context.TODO()) + return err != nil + }, 2*time.Second, 500*time.Millisecond) + assert.Error(t, err) + + assert.Never(t, func() bool { + err = p.Probe(context.TODO()) + return err == nil + }, 1*time.Second, 100*time.Millisecond) + + assert.NoError(t, p.Close()) + +} + +func TestPostgreSQL_Fail(t *testing.T) { + t.Parallel() + p, err := NewFailingPostgreSQL("FAKE", "foo", "bar") + require.NoError(t, err) + + require.NotPanics(t, func() { + assert.Error(t, p.Probe(context.Background())) + + pi := p.GetInfo() + assert.Equal(t, pi.Service, "FAKE") + assert.Equal(t, pi.Name, "foo") + assert.Equal(t, pi.Namespace, "bar") + assert.NoError(t, p.Close()) + }) +} diff --git a/controller/sli-exporter/vshnpostgresql_controller.go b/controller/sli-exporter/vshnpostgresql_controller.go new file mode 100644 index 0000000000..fd97cf44dc --- /dev/null +++ b/controller/sli-exporter/vshnpostgresql_controller.go @@ -0,0 +1,143 @@ +/* +Copyright 2023. + +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. +*/ + +package sli_exporter + +import ( + "context" + "fmt" + "github.com/vshn/appcat-apiserver/controller/sli-exporter/probes" + "time" + + "github.com/jackc/pgx/v5/pgxpool" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" +) + +var vshnpostgresqlsServiceKey = "VSHNPostgreSQL" + +// VSHNPostgreSQLReconciler reconciles a VSHNPostgreSQL object +type VSHNPostgreSQLReconciler struct { + client.Client + Scheme *runtime.Scheme + + ProbeManager probeManager + StartupGracePeriod time.Duration + PostgreDialer func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) +} + +type probeManager interface { + StartProbe(p probes.Prober) + StopProbe(p probes.ProbeInfo) +} + +//+kubebuilder:rbac:groups=vshn.appcat.vshn.io,resources=vshnpostgresqls,verbs=get;list;watch +//+kubebuilder:rbac:groups=vshn.appcat.vshn.io,resources=vshnpostgresqls/status,verbs=get + +// Reconcile start or stops a prober for a VSHNPostgreSQL instance. +// Will only probe an instance once it is ready or after the StartupGracePeriod. +func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + l := log.FromContext(ctx).WithValues("namespace", req.Namespace, "instance", req.Name) + res := ctrl.Result{} + + inst := &vshnv1.VSHNPostgreSQL{} + err := r.Get(ctx, req.NamespacedName, inst) + + if apierrors.IsNotFound(err) || inst.DeletionTimestamp != nil { + l.Info("Stopping Probe") + r.ProbeManager.StopProbe(probes.ProbeInfo{ + Service: vshnpostgresqlsServiceKey, + Name: req.Name, + Namespace: req.Namespace, + }) + return ctrl.Result{}, nil + } + if err != nil { + return ctrl.Result{}, err + } + + if inst.Spec.WriteConnectionSecretToRef.Name == "" { + l.Info("No connection secret requested. Skipping.") + return ctrl.Result{}, nil + } + + probe, err := r.fetchProberFor(ctx, inst) + if err != nil && !apierrors.IsNotFound(err) { + return ctrl.Result{}, err + } + if apierrors.IsNotFound(err) { + l.WithValues("credentials", inst.Spec.WriteConnectionSecretToRef.Name, "error", err.Error()). + Info("Failed to find credentials. Backing off") + res.Requeue = true + res.RequeueAfter = 30 * time.Second + + if time.Now().Sub(inst.GetCreationTimestamp().Time) < r.StartupGracePeriod { + // Instance is starting up. Postpone probing until ready. + return res, nil + } + + // Create a pobe that will always fail + probe, err = probes.NewFailingPostgreSQL(vshnpostgresqlsServiceKey, inst.Name, inst.Namespace) + if err != nil { + return ctrl.Result{}, err + } + } + + l.Info("Starting Probe") + r.ProbeManager.StartProbe(probe) + return res, nil +} + +func (r VSHNPostgreSQLReconciler) fetchProberFor(ctx context.Context, inst *vshnv1.VSHNPostgreSQL) (probes.Prober, error) { + + credSecret := corev1.Secret{} + err := r.Get(ctx, types.NamespacedName{ + Name: inst.Spec.WriteConnectionSecretToRef.Name, + Namespace: inst.Namespace, + }, &credSecret) + + if err != nil { + return nil, err + } + + probe, err := r.PostgreDialer(vshnpostgresqlsServiceKey, inst.Name, inst.Namespace, + fmt.Sprintf( + "postgresql://%s:%s@%s:%s/%s?sslmode=verify-ca", + credSecret.Data["POSTGRESQL_USER"], + credSecret.Data["POSTGRESQL_PASSWORD"], + credSecret.Data["POSTGRESQL_HOST"], + credSecret.Data["POSTGRESQL_PORT"], + credSecret.Data["POSTGRESQL_DB"], + ), probes.PGWithCA(credSecret.Data["ca.crt"])) + if err != nil { + return nil, err + } + return probe, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *VSHNPostgreSQLReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&vshnv1.VSHNPostgreSQL{}). + Complete(r) +} diff --git a/controller/sli-exporter/vshnpostgresql_controller_test.go b/controller/sli-exporter/vshnpostgresql_controller_test.go new file mode 100644 index 0000000000..5aaa57015d --- /dev/null +++ b/controller/sli-exporter/vshnpostgresql_controller_test.go @@ -0,0 +1,323 @@ +package sli_exporter + +import ( + "context" + "github.com/vshn/appcat-apiserver/controller/sli-exporter/probes" + "testing" + "time" + + "github.com/jackc/pgx/v5/pgxpool" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + + appcatv1 "github.com/vshn/component-appcat/apis/v1" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" +) + +func TestVSHNPostgreSQL_StartStop(t *testing.T) { + db := newTestVSHNPostgre("bar", "foo", "creds") + r, manager, client := setupVSHNPostgreTest(t, + db, + newTestVSHNPostgreCred("bar", "creds"), + ) + + req := ctrl.Request{ + NamespacedName: types.NamespacedName{ + Namespace: "bar", + Name: "foo", + }, + } + pi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "bar", + } + + _, err := r.Reconcile(context.TODO(), req) + assert.NoError(t, err) + assert.True(t, manager.probers[pi]) + + require.NoError(t, client.Delete(context.TODO(), db)) + _, err = r.Reconcile(context.TODO(), req) + assert.NoError(t, err) + assert.False(t, manager.probers[pi]) +} + +func TestVSHNPostgreSQL_StartStop_WithFializer(t *testing.T) { + db := newTestVSHNPostgre("bar", "foo", "creds") + db.SetFinalizers([]string{"foobar.vshn.io"}) + r, manager, client := setupVSHNPostgreTest(t, + db, + newTestVSHNPostgreCred("bar", "creds"), + ) + + req := ctrl.Request{ + NamespacedName: types.NamespacedName{ + Namespace: "bar", + Name: "foo", + }, + } + pi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "bar", + } + + _, err := r.Reconcile(context.TODO(), req) + assert.NoError(t, err) + assert.True(t, manager.probers[pi]) + + require.NoError(t, client.Delete(context.TODO(), db)) + _, err = r.Reconcile(context.TODO(), req) + assert.NoError(t, err) + assert.False(t, manager.probers[pi]) +} + +func TestVSHNPostgreSQL_Multi(t *testing.T) { + dbBar := newTestVSHNPostgre("bar", "foo", "creds") + dbBarer := newTestVSHNPostgre("bar", "fooer", "credentials") + dbBuzz := newTestVSHNPostgre("buzz", "foo", "creds") + r, manager, c := setupVSHNPostgreTest(t, + dbBar, + newTestVSHNPostgreCred("bar", "creds"), + dbBarer, + newTestVSHNPostgreCred("bar", "credentials"), + dbBuzz, + newTestVSHNPostgreCred("buzz", "creds"), + ) + + barPi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "bar", + } + barerPi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "fooer", + Namespace: "bar", + } + buzzPi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "buzz", + } + + _, err := r.Reconcile(context.TODO(), recReq("bar", "foo")) + assert.NoError(t, err) + _, err = r.Reconcile(context.TODO(), recReq("bar", "fooer")) + assert.NoError(t, err) + + assert.True(t, manager.probers[barPi]) + assert.True(t, manager.probers[barerPi]) + assert.False(t, manager.probers[buzzPi]) + + require.NoError(t, c.Delete(context.TODO(), dbBar)) + _, err = r.Reconcile(context.TODO(), recReq("bar", "foo")) + assert.NoError(t, err) + _, err = r.Reconcile(context.TODO(), recReq("buzz", "foo")) + assert.NoError(t, err) + + assert.False(t, manager.probers[barPi]) + assert.True(t, manager.probers[barerPi]) + assert.True(t, manager.probers[buzzPi]) +} + +func TestVSHNPostgreSQL_Startup_NoCreds_Dont_Probe(t *testing.T) { + db := newTestVSHNPostgre("bar", "foo", "creds") + db.SetCreationTimestamp(metav1.Now()) + r, manager, _ := setupVSHNPostgreTest(t, + db, + ) + pi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "bar", + } + + res, err := r.Reconcile(context.TODO(), recReq("bar", "foo")) + assert.NoError(t, err) + assert.Greater(t, res.RequeueAfter.Microseconds(), int64(0)) + + assert.False(t, manager.probers[pi]) +} + +func TestVSHNPostgreSQL_NoRef_Dont_Probe(t *testing.T) { + db := newTestVSHNPostgre("bar", "foo", "creds") + db.Spec.WriteConnectionSecretToRef.Name = "" + r, manager, _ := setupVSHNPostgreTest(t, + db, + ) + pi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "bar", + } + + _, err := r.Reconcile(context.TODO(), recReq("bar", "foo")) + assert.NoError(t, err) + assert.False(t, manager.probers[pi]) +} + +func TestVSHNPostgreSQL_Started_NoCreds_Probe_Failure(t *testing.T) { + db := newTestVSHNPostgre("bar", "foo", "creds") + db.SetCreationTimestamp(metav1.Time{Time: time.Now().Add(-1 * time.Hour)}) + r, manager, _ := setupVSHNPostgreTest(t, + db, + ) + pi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "bar", + } + + res, err := r.Reconcile(context.TODO(), recReq("bar", "foo")) + assert.NoError(t, err) + assert.Greater(t, res.RequeueAfter.Microseconds(), int64(0)) + + assert.True(t, manager.probers[pi]) +} + +func TestVSHNPostgreSQL_PassCerdentials(t *testing.T) { + db := newTestVSHNPostgre("bar", "foo", "creds") + cred := newTestVSHNPostgreCred("bar", "creds") + cred.Data = map[string][]byte{ + "POSTGRESQL_USER": []byte("userfoo"), + "POSTGRESQL_PASSWORD": []byte("password"), + "POSTGRESQL_HOST": []byte("foo.bar"), + "POSTGRESQL_PORT": []byte("5433"), + "POSTGRESQL_DB": []byte("pg"), + "ca.crt": []byte("-----BEGIN CERTIFICATE-----MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG..."), + } + r, manager, client := setupVSHNPostgreTest(t, + db, + cred, + ) + r.PostgreDialer = func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) { + + assert.Equal(t, "VSHNPostgreSQL", service) + assert.Equal(t, "foo", name) + assert.Equal(t, "bar", namespace) + assert.Equal(t, "postgresql://userfoo:password@foo.bar:5433/pg?sslmode=verify-ca", dsn) + + return fakePostgreDialer(service, name, namespace, dsn, ops...) + } + req := ctrl.Request{ + NamespacedName: types.NamespacedName{ + Namespace: "bar", + Name: "foo", + }, + } + pi := probes.ProbeInfo{ + Service: "VSHNPostgreSQL", + Name: "foo", + Namespace: "bar", + } + + _, err := r.Reconcile(context.TODO(), req) + assert.NoError(t, err) + assert.True(t, manager.probers[pi]) + + require.NoError(t, client.Delete(context.TODO(), db)) + _, err = r.Reconcile(context.TODO(), req) + assert.NoError(t, err) + assert.False(t, manager.probers[pi]) +} + +func fakePostgreDialer(service string, name string, namespace string, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) { + p := &probes.PostgreSQL{ + Service: service, + Instance: name, + Namespace: namespace, + } + return p, nil +} + +var _ probeManager = &fakeProbeManager{} + +type fakeProbeManager struct { + probers map[probes.ProbeInfo]bool +} + +func newFakeProbeManager() *fakeProbeManager { + return &fakeProbeManager{ + probers: map[probes.ProbeInfo]bool{}, + } +} + +// StartProbe implements probeManager +func (m *fakeProbeManager) StartProbe(p probes.Prober) { + m.probers[p.GetInfo()] = true +} + +// StopProbe implements probeManager +func (m *fakeProbeManager) StopProbe(p probes.ProbeInfo) { + m.probers[p] = false +} + +func setupVSHNPostgreTest(t *testing.T, objs ...client.Object) (VSHNPostgreSQLReconciler, *fakeProbeManager, client.Client) { + scheme := runtime.NewScheme() + require.NoError(t, clientgoscheme.AddToScheme(scheme)) + require.NoError(t, vshnv1.AddToScheme(scheme)) + client := fake.NewClientBuilder(). + WithScheme(scheme). + WithObjects(objs...). + Build() + + manager := newFakeProbeManager() + r := VSHNPostgreSQLReconciler{ + Client: client, + Scheme: scheme, + ProbeManager: manager, + StartupGracePeriod: 5 * time.Minute, + PostgreDialer: fakePostgreDialer, + } + + return r, manager, client +} + +func newTestVSHNPostgre(namespace, name, cred string) *vshnv1.VSHNPostgreSQL { + return &vshnv1.VSHNPostgreSQL{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: vshnv1.VSHNPostgreSQLSpec{ + WriteConnectionSecretToRef: appcatv1.LocalObjectReference{ + Name: cred, + }, + }, + } +} +func newTestVSHNPostgreCred(namespace, name string) *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: map[string][]byte{ + "POSTGRESQL_USER": []byte("user"), + "POSTGRESQL_PASSWORD": []byte("password"), + "POSTGRESQL_HOST": []byte("foo.bar"), + "POSTGRESQL_PORT": []byte("5432"), + "POSTGRESQL_DB": []byte("pg"), + "ca.crt": []byte("-----BEGIN CERTIFICATE-----MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG..."), + }, + } +} + +func recReq(namespace, name string) ctrl.Request { + return ctrl.Request{ + NamespacedName: types.NamespacedName{ + Namespace: namespace, + Name: name, + }, + } +} diff --git a/go.mod b/go.mod index 921d680a89..449f9def4b 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,12 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.2 + github.com/jackc/pgx/v5 v5.3.1 + github.com/ory/dockertest v3.3.5+incompatible + github.com/prometheus/client_golang v1.14.0 + github.com/spf13/cobra v1.6.1 + github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.2 - github.com/urfave/cli/v2 v2.25.1 github.com/vektra/mockery/v2 v2.26.1 github.com/vshn/component-appcat/apis v0.0.0-20230414110116-c7334ac8d3b1 go.uber.org/zap v1.24.0 @@ -30,19 +34,25 @@ require ( ) require ( + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/BurntSushi/toml v1.2.1 // indirect + github.com/Microsoft/go-winio v0.6.0 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect + github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chigopher/pathlib v0.13.0 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect @@ -67,6 +77,9 @@ require ( github.com/iancoleman/strcase v0.2.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/puddle/v2 v2.2.0 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -80,26 +93,25 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc2 // indirect + github.com/opencontainers/runc v1.1.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.63.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/rs/zerolog v1.29.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.etcd.io/etcd/api/v3 v3.5.6 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect go.etcd.io/etcd/client/v3 v3.5.6 // indirect @@ -115,7 +127,7 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.5.0 // indirect + golang.org/x/crypto v0.6.0 // indirect golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect diff --git a/go.sum b/go.sum index c17849f883..62b4ba56bf 100644 --- a/go.sum +++ b/go.sum @@ -39,13 +39,19 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -66,6 +72,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -73,11 +81,13 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chigopher/pathlib v0.13.0 h1:9AYqYGR+JaYJtZfTSsC+Wvz7CBd2jcZFb4fva7Z4r+4= github.com/chigopher/pathlib v0.13.0/go.mod h1:EJ5UtJ/sK8Nt6q3VWN+EwZLZ3g0afJiG8NegYiQQ/gQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -87,13 +97,16 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 h1:rtAn27wIbmOGUs7RIbVgPEjb31ehTVniDwPGXyMxm5U= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crossplane-contrib/provider-kubernetes v0.7.0 h1:0IfhEpkcn4TeiGfRRI57pcXefSZ9ejW/MWLFQrS6n+M= @@ -102,9 +115,15 @@ github.com/crossplane/crossplane v1.11.2 h1:YVj9Y2caO6gKf7WAlLe1X3w2GVp4u/nFvlTV github.com/crossplane/crossplane v1.11.2/go.mod h1:Uf2DJIqlO2RyEqmDOqV1KrC+4oUcfezjLb6qEi3Agx0= github.com/crossplane/crossplane-runtime v0.19.2 h1:9qBnhpqKN4x6apF2siaQ6PvgxqBXbGcKmgeD8mSIDO8= github.com/crossplane/crossplane-runtime v0.19.2/go.mod h1:OJQ1NxtQK2ZTRmvtnQPoy8LsXsARTnVydRVDQEgIuz4= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -130,6 +149,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -166,6 +186,7 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/gobuffalo/flect v0.3.0 h1:erfPWM+K1rFNIQeRPdeEXxo8yFr/PO17lhRnS8FUrtk= github.com/gobuffalo/flect v0.3.0/go.mod h1:5pf3aGnsvqvCj50AVni7mJJF8ICxGZ8HomberC3pXLE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -250,6 +271,7 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -271,6 +293,14 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk= +github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= @@ -295,11 +325,13 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -323,6 +355,7 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -330,6 +363,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -339,6 +373,16 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= github.com/onsi/gomega v1.24.2 h1:J/tulyYK6JwBldPViHJReihxxZ+22FHs0piGjQAvoUE= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= @@ -383,16 +427,20 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -430,19 +478,21 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= -github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= -github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vektra/mockery/v2 v2.26.1 h1:Y8mlLkWHWjuUpsJBwhFb1LeG1ZnWFvo+prsIuiABJ88= github.com/vektra/mockery/v2 v2.26.1/go.mod h1:BOVUIv65DB6wuTYzoPtyMoBYce3n2C1IcsOdWu6Rpu4= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vshn/appcat-sli-exporter v0.1.1 h1:QYgdnXkFwtA7yOW5SdO1cVC3p0zi+teVpRQlDqW6nVw= +github.com/vshn/appcat-sli-exporter v0.1.1/go.mod h1:M3XkeMFCcyECgs/VSsH/rERTfgQ0KfM/eI1yRJRfYXw= github.com/vshn/component-appcat/apis v0.0.0-20230414110116-c7334ac8d3b1 h1:cC5UIdvVbP+ClW2V/PNJxtTtiVwpaVAotTG0DZetZJw= github.com/vshn/component-appcat/apis v0.0.0-20230414110116-c7334ac8d3b1/go.mod h1:1DA8TgDuQ5NWTGrYLXk7EfnClwt8dHyrLJ66EiiibLo= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -508,8 +558,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -624,9 +674,12 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -661,10 +714,15 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= @@ -888,6 +946,7 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 4a7b46d70ee0a58d09c0770cc1e2fe71c3e949d9 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Thu, 11 May 2023 12:00:26 +0200 Subject: [PATCH 04/26] Port GRPC server with composition functions --- Makefile | 3 +- README.md | 101 +++ command/grpc.go | 119 +++ command/root.go | 2 +- .../functions/vshn-postgres-func/alerting.go | 139 ++++ .../vshn-postgres-func/alerting_test.go | 140 ++++ .../vshn-postgres-func/common_test.go | 35 + .../vshn-postgres-func/encrypted_pvc.go | 82 ++ .../vshn-postgres-func/encrypted_pvc_test.go | 124 +++ .../functions/vshn-postgres-func/schedule.go | 56 ++ .../vshn-postgres-func/schedule_test.go | 167 ++++ .../functions/vshn-postgres-func/url.go | 82 ++ .../functions/vshn-postgres-func/url_test.go | 103 +++ comp-functions/runtime/desired.go | 214 +++++ comp-functions/runtime/logger.go | 57 ++ comp-functions/runtime/observed.go | 79 ++ comp-functions/runtime/result.go | 60 ++ comp-functions/runtime/run.go | 61 ++ comp-functions/runtime/runtime.go | 149 ++++ comp-functions/runtime/types.go | 16 + docs/modules/ROOT/nav.adoc | 4 +- .../explanations/comp-functions/runtime.adoc | 26 + .../comp-functions/vshn-postgres.adoc | 10 + go.mod | 18 +- go.sum | 23 +- test/example.yaml | 759 ++++++++++++++++++ test/grpc-client/main.go | 52 ++ .../alerting/01-GivenNoMonitoringParams.yaml | 57 ++ .../alerting/01-ThenExpectNoOutput.yaml | 57 ++ .../02-GivenConfigRefNoSecretRef.yaml | 59 ++ .../alerting/02-ThenExpectError.yaml | 59 ++ .../alerting/03-GivenConfigRefAndSecret.yaml | 59 ++ .../04-GivenConfigTemplateAndSecret.yaml | 69 ++ .../05-GivenNoStatusInstanceNamespace.yaml | 58 ++ test/transforms/vshn-postgres/base.yaml | 54 ++ .../enc_pvc/01-GivenNoEncryptionParams.yaml | 54 ++ .../enc_pvc/01-ThenExpectNoOutput.yaml | 54 ++ .../02-GivenEncryptionParamsFalse.yaml | 56 ++ .../enc_pvc/02-ThenExpectFalseOutput.yaml | 56 ++ .../enc_pvc/03-GivenEncryptionParams.yaml | 58 ++ ...3-GivenEncryptionParamsExistingSecret.yaml | 90 +++ ...enEncryptionParamsNoInstanceNamespace.yaml | 56 ++ .../01_expected_no-instance-namespace.yaml | 74 ++ .../url/01_input_no-instance-namespace.yaml | 74 ++ .../url/02_input_function-io.yaml | 441 ++++++++++ 45 files changed, 4150 insertions(+), 16 deletions(-) create mode 100644 command/grpc.go create mode 100644 comp-functions/functions/vshn-postgres-func/alerting.go create mode 100644 comp-functions/functions/vshn-postgres-func/alerting_test.go create mode 100644 comp-functions/functions/vshn-postgres-func/common_test.go create mode 100644 comp-functions/functions/vshn-postgres-func/encrypted_pvc.go create mode 100644 comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go create mode 100644 comp-functions/functions/vshn-postgres-func/schedule.go create mode 100644 comp-functions/functions/vshn-postgres-func/schedule_test.go create mode 100644 comp-functions/functions/vshn-postgres-func/url.go create mode 100644 comp-functions/functions/vshn-postgres-func/url_test.go create mode 100644 comp-functions/runtime/desired.go create mode 100644 comp-functions/runtime/logger.go create mode 100644 comp-functions/runtime/observed.go create mode 100644 comp-functions/runtime/result.go create mode 100644 comp-functions/runtime/run.go create mode 100644 comp-functions/runtime/runtime.go create mode 100644 comp-functions/runtime/types.go create mode 100644 docs/modules/ROOT/pages/explanations/comp-functions/runtime.adoc create mode 100644 docs/modules/ROOT/pages/explanations/comp-functions/vshn-postgres.adoc create mode 100644 test/example.yaml create mode 100644 test/grpc-client/main.go create mode 100644 test/transforms/vshn-postgres/alerting/01-GivenNoMonitoringParams.yaml create mode 100644 test/transforms/vshn-postgres/alerting/01-ThenExpectNoOutput.yaml create mode 100644 test/transforms/vshn-postgres/alerting/02-GivenConfigRefNoSecretRef.yaml create mode 100644 test/transforms/vshn-postgres/alerting/02-ThenExpectError.yaml create mode 100644 test/transforms/vshn-postgres/alerting/03-GivenConfigRefAndSecret.yaml create mode 100644 test/transforms/vshn-postgres/alerting/04-GivenConfigTemplateAndSecret.yaml create mode 100644 test/transforms/vshn-postgres/alerting/05-GivenNoStatusInstanceNamespace.yaml create mode 100644 test/transforms/vshn-postgres/base.yaml create mode 100644 test/transforms/vshn-postgres/enc_pvc/01-GivenNoEncryptionParams.yaml create mode 100644 test/transforms/vshn-postgres/enc_pvc/01-ThenExpectNoOutput.yaml create mode 100644 test/transforms/vshn-postgres/enc_pvc/02-GivenEncryptionParamsFalse.yaml create mode 100644 test/transforms/vshn-postgres/enc_pvc/02-ThenExpectFalseOutput.yaml create mode 100644 test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParams.yaml create mode 100644 test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsExistingSecret.yaml create mode 100644 test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsNoInstanceNamespace.yaml create mode 100644 test/transforms/vshn-postgres/url/01_expected_no-instance-namespace.yaml create mode 100644 test/transforms/vshn-postgres/url/01_input_no-instance-namespace.yaml create mode 100644 test/transforms/vshn-postgres/url/02_input_function-io.yaml diff --git a/Makefile b/Makefile index fb037239e0..a0b7f544f0 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,5 @@ docker-push: docker-build ## Push docker image with the manager. docker push ${GHCR_IMG} .PHONY: clean -clean: kind-clean clean: - rm -rf bin/ appcat-apiserver .work/ docs/node_modules $docs_out_dir .public .cache + rm -rf bin/ appcat-apiserver .work/ docs/node_modules $docs_out_dir .public .cache apiserver.local.config diff --git a/README.md b/README.md index d64039d003..4fef3efece 100644 --- a/README.md +++ b/README.md @@ -146,3 +146,104 @@ Add another controller for each service that should be probed. #### Adding SLA exceptions If possible SLA exceptions should be implemented as a middleware for the `Prober` interface. + + +## Crossplane Composition Functions with GRPS Server + +``` +. +├── docs +├── functions +│ ├── vshn-common-func +│ ├── vshn-postgres-func +│ └── vshn-redis-func +├── kind +├── runtime +└── test +``` + +- `./docs` contains relevant documentation in regard to this repository +- `./functions` contains the actual logic for each function-io. Each function-io can have multiple transformation go functions +- `./runtime` contains a library with helper methods which helps with adding new functions. +- `./kind` contains relevant files for local dev cluster +- `./test` contains test files + +Check out the docs to understand how functions from this repository work. + +### Add a new function-io + +The framework is designed to easily add new composition functions to any AppCat service. +A function-io corresponds to one and only one composition thus multiple transformation go functions +can be added to a function-io. +For instance, in `vshn-postgres-func` there are multiple transformation go functions such as `url` or `alerting`. + + +To add a new function to PostgreSQL by VSHN: + +- Create a new package under `./functions/`. +- Create a go file and add a new transform go function to the list in `./cmd/`. +- Implement the actual `Transform()` go function by using the helper functions from `runtime/desired.go` and `runtime/observed.go`. +- Register the transform go function in the `main.go`. +- Create a new app.go under `./cmd/` and define a new `AppInfo` object. + +This architecture allows us to run all the functions with a single command. But for debugging and development purpose it's possible to run each function separately, by using the `--function` flag. + +### Manually testing a function +To test a function you can leverage the FunctionIO file in the `./test` folder. + +`cat test/function-io.yaml | go run cmd/vshn-postgres-func/main.go --function myfunction > test.yaml` + + +### Usage of gRPC server - local development + kind cluster + +entrypoint to start working with gRPC server is to run: +``` +go run main.go -socket default.sock +``` + +it will create a socket file in Your local directory which is easier for development - no need to set permissions and directory structure. + +It's also possible to trigger fake request to gRPC server by client (to imitate Crossplane): +``` +cd test/grpc-client +go run main.go +``` + +if You want to run gRPC server in local kind cluster, please use: +1. [kindev](https://github.com/vshn/kindev). In makefile replace target: + 1. ``` + $(crossplane_sentinel): export KUBECONFIG = $(KIND_KUBECONFIG) + $(crossplane_sentinel): kind-setup local-pv-setup + # below line loads image to kind + kind load docker-image --name kindev ghcr.io/vshn/appcat-comp-functions + helm repo add crossplane https://charts.crossplane.io/stable + helm upgrade --install crossplane --create-namespace --namespace syn-crossplane crossplane/crossplane \ + --set "args[0]='--debug'" \ + --set "args[1]='--enable-composition-functions'" \ + --set "args[2]='--enable-environment-configs'" \ + --set "xfn.enabled=true" \ + --set "xfn.args={--debug}" \ + --set "xfn.image.repository=ghcr.io/vshn/appcat-comp-functions" \ + --set "xfn.image.tag=latest" \ + --wait + @touch $@ + ``` +2. [component-appcat](https://github.com/vshn/component-appcat) please append [file](https://github.com/vshn/component-appcat/blob/master/tests/golden/vshn/appcat/appcat/21_composition_vshn_postgres.yaml) with: + 1. ``` + compositeTypeRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + # we have to add functions declaration to postgresql + functions: + - container: + image: postgresql + runner: + endpoint: unix-abstract:crossplane/fn/default.sock + name: pgsql-func + type: Container + resources: + - base: + apiVersion: kubernetes.crossplane.io/v1alpha1 + ``` + +That's all - You can now run Your claims. This documentation and above workaround is just temporary solution, it should disappear once we actually implement composition functions. diff --git a/command/grpc.go b/command/grpc.go new file mode 100644 index 0000000000..08d41205f9 --- /dev/null +++ b/command/grpc.go @@ -0,0 +1,119 @@ +package command + +import ( + "context" + pb "github.com/crossplane/crossplane/apis/apiextensions/fn/proto/v1alpha1" + "github.com/go-logr/logr" + "github.com/spf13/cobra" + vshnpostgres "github.com/vshn/appcat-apiserver/comp-functions/functions/vshn-postgres-func" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "net" + "os" + ctrl "sigs.k8s.io/controller-runtime" +) + +func init() { + grpcCommand.Flags().StringVar(&Network, "network", "unix", "network type") + grpcCommand.Flags().StringVar(&AddressFlag, "socket", "@crossplane/fn/default.sock", "set where socket should be located") +} + +var ( + Network = "unix" + AddressFlag = "@crossplane/fn/default.sock" +) + +var grpcCommand = &cobra.Command{ + Use: "grpc", + Short: "GRPC Server", + Long: "Run the GRPC Server for crossplane composition functions", + RunE: executeGRPCServer, +} + +var postgresFunctions = []runtime.Transform{ + { + Name: "url-connection-details", + TransformFunc: vshnpostgres.AddUrlToConnectionDetails, + }, + { + Name: "user-alerting", + TransformFunc: vshnpostgres.AddUserAlerting, + }, + { + Name: "random-default-schedule", + TransformFunc: vshnpostgres.TransformSchedule, + }, + { + Name: "encrypted-pvc-secret", + TransformFunc: vshnpostgres.AddPvcSecret, + }, +} + +type server struct { + pb.UnimplementedContainerizedFunctionRunnerServiceServer + logger logr.Logger +} + +// Run will run the controller mode of the composition function runner. +func executeGRPCServer(cmd *cobra.Command, _ []string) error { + log := logr.FromContextOrDiscard(cmd.Context()) + ctrl.SetLogger(log) + + if err := cleanStart(AddressFlag); err != nil { + log.Error(err, "cannot clean start GRPC server.") + return err + } + + lis, err := net.Listen(Network, AddressFlag) + if err != nil { + log.Error(err, "failed to listen.") + return err + } + + s := grpc.NewServer() + + pb.RegisterContainerizedFunctionRunnerServiceServer(s, &server{logger: log}) + log.Info("server listening at", "address", lis.Addr()) + if err = s.Serve(lis); err != nil { + log.Error(err, "failed to serve.") + return err + } + return nil +} + +func (s *server) RunFunction(ctx context.Context, in *pb.RunFunctionRequest) (*pb.RunFunctionResponse, error) { + ctx = logr.NewContext(ctx, s.logger) + switch in.Image { + case "postgresql": + fnio, err := runtime.RunCommand(ctx, in.Input, postgresFunctions) + if err != nil { + return &pb.RunFunctionResponse{ + Output: fnio, + }, status.Errorf(codes.Aborted, "Can't process request for PostgreSQL") + } + return &pb.RunFunctionResponse{ + Output: fnio, + }, nil + case "redis": + return &pb.RunFunctionResponse{ + // return what was sent as it's currently not supported + Output: in.Input, + }, status.Error(codes.Unimplemented, "Redis is not yet implemented") + default: + return &pb.RunFunctionResponse{ + Output: []byte("Bad configuration"), + }, status.Error(codes.NotFound, "Unknown request") + } +} + +// socket isn't removed after server stop listening and blocks another starts +func cleanStart(socketName string) error { + if _, err := os.Stat(socketName); err == nil { + err = os.RemoveAll(socketName) + return err + } + + return nil +} diff --git a/command/root.go b/command/root.go index 1c52fe55fa..1017071a09 100644 --- a/command/root.go +++ b/command/root.go @@ -36,7 +36,7 @@ func Execute() { } func init() { - rootCmd.AddCommand(xpostgresql, apiServerCmd, sliProber) + rootCmd.AddCommand(xpostgresql, apiServerCmd, sliProber, grpcCommand) } func setupLogging(cmd *cobra.Command, _ []string) error { diff --git a/comp-functions/functions/vshn-postgres-func/alerting.go b/comp-functions/functions/vshn-postgres-func/alerting.go new file mode 100644 index 0000000000..cc3c2b9c2a --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/alerting.go @@ -0,0 +1,139 @@ +package vshnpostgres + +import ( + "context" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + controllerruntime "sigs.k8s.io/controller-runtime" + + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" +) + +// AddUserAlerting adds user alerting to the PostgreSQL instance. +func AddUserAlerting(ctx context.Context, iof *runtime.Runtime) runtime.Result { + log := controllerruntime.LoggerFrom(ctx) + log.Info("Check if alerting references are set") + + log.V(1).Info("Transforming", "obj", iof) + + err := runtime.AddToScheme(alertmanagerv1alpha1.SchemeBuilder) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot add scheme builder to scheme", err) + } + comp := &vshnv1.VSHNPostgreSQL{} + err = iof.Observed.GetComposite(ctx, comp) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot get composite from function io", err) + } + + // Wait for the next reconciliation in case instance namespace is missing + if comp.Status.InstanceNamespace == "" { + return runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + } + + monitoringSpec := comp.Spec.Parameters.Monitoring + + if monitoringSpec.AlertmanagerConfigRef != "" { + + if monitoringSpec.AlertmanagerConfigSecretRef == "" { + return runtime.NewFatal(ctx, "Found AlertmanagerConfigRef but no AlertmanagerConfigSecretRef, please specify as well") + } + + refName := comp.Spec.Parameters.Monitoring.AlertmanagerConfigRef + log.Info("Found an AlertmanagerConfigRef, deploying...", "refName", refName) + + err = deployAlertmanagerFromRef(ctx, comp, iof) + if err != nil { + return runtime.NewFatalErr(ctx, "Could not deploy alertmanager from ref", err) + } + } + + if monitoringSpec.AlertmanagerConfigSpecTemplate != nil { + + if monitoringSpec.AlertmanagerConfigSecretRef == "" { + return runtime.NewFatal(ctx, "Found AlertmanagerConfigTemplate but no AlertmanagerConfigSecretRef, please specify as well") + } + + log.Info("Found an AlertmanagerConfigTemplate, deploying...") + + err = deployAlertmanagerFromTemplate(ctx, comp, iof) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot deploy alertmanager from template", err) + } + } + + if monitoringSpec.AlertmanagerConfigSecretRef != "" { + refName := comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef + log.Info("Found an AlertmanagerConfigSecretRef, deploying...", "refName", refName) + + err = deploySecretRef(ctx, comp, iof) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot deploy secret ref", err) + } + } + + return runtime.NewNormal() +} + +func deployAlertmanagerFromRef(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime.Runtime) error { + ac := &alertmanagerv1alpha1.AlertmanagerConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "postgresql-alertmanagerconfig", + Namespace: comp.Status.InstanceNamespace, + }, + } + + xRef := xkube.Reference{ + PatchesFrom: &xkube.PatchesFrom{ + DependsOn: xkube.DependsOn{ + APIVersion: "monitoring.coreos.com/v1alpha1", + Kind: "AlertmanagerConfig", + Namespace: comp.ObjectMeta.Labels["crossplane.io/claim-namespace"], + Name: comp.Spec.Parameters.Monitoring.AlertmanagerConfigRef, + }, + FieldPath: pointer.String("spec"), + }, + ToFieldPath: pointer.String("spec"), + } + + return iof.Desired.PutIntoObject(ctx, ac, comp.Name+"-alertmanagerconfig", xRef) +} + +func deployAlertmanagerFromTemplate(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime.Runtime) error { + ac := &alertmanagerv1alpha1.AlertmanagerConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef, + Namespace: comp.Status.InstanceNamespace, + }, + Spec: *comp.Spec.Parameters.Monitoring.AlertmanagerConfigSpecTemplate, + } + + return iof.Desired.PutIntoObject(ctx, ac, comp.Name+"-alertmanagerconfig") +} + +func deploySecretRef(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime.Runtime) error { + s := &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef, + Namespace: comp.Status.InstanceNamespace, + }, + } + xRef := xkube.Reference{ + PatchesFrom: &xkube.PatchesFrom{ + DependsOn: xkube.DependsOn{ + APIVersion: "v1", + Kind: "Secret", + Namespace: comp.ObjectMeta.Labels["crossplane.io/claim-namespace"], + Name: comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef, + }, + FieldPath: pointer.String("data"), + }, + ToFieldPath: pointer.String("data"), + } + + return iof.Desired.PutIntoObject(ctx, s, comp.Name+"-alertmanagerconfigsecret", xRef) +} diff --git a/comp-functions/functions/vshn-postgres-func/alerting_test.go b/comp-functions/functions/vshn-postgres-func/alerting_test.go new file mode 100644 index 0000000000..29b59aab14 --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/alerting_test.go @@ -0,0 +1,140 @@ +package vshnpostgres + +import ( + "context" + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + v1 "k8s.io/api/core/v1" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAddUserAlerting_NoInstanceNamespace(t *testing.T) { + ctx := context.Background() + expectResult := runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + + t.Run("WhenNoInstance_ThenNoErrorAndNoChanges", func(t *testing.T) { + + //Given + io := loadRuntimeFromFile(t, "alerting/05-GivenNoStatusInstanceNamespace.yaml") + + // When + result := AddUserAlerting(ctx, io) + + // Then + assert.Equal(t, expectResult, result) + }) +} + +func TestAddUserAlerting(t *testing.T) { + ctx := context.Background() + + type args struct { + expectedFuncIO string + inputFuncIO string + } + tests := []struct { + name string + args args + expResult xfnv1alpha1.Result + }{ + { + name: "GivenNoMonitoringParams_ThenExpectNoOutput", + args: args{ + expectedFuncIO: "alerting/01-ThenExpectNoOutput.yaml", + inputFuncIO: "alerting/01-GivenNoMonitoringParams.yaml", + }, + expResult: xfnv1alpha1.Result{ + Severity: xfnv1alpha1.SeverityNormal, + Message: "function ran successfully", + }, + }, + { + name: "GivenConfigRefNoSecretRef_ThenExpectError", + expResult: runtime.NewFatal(ctx, "Found AlertmanagerConfigRef but no AlertmanagerConfigSecretRef, please specify as well").Resolve(), + args: args{ + expectedFuncIO: "alerting/02-ThenExpectError.yaml", + inputFuncIO: "alerting/02-GivenConfigRefNoSecretRef.yaml", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + iof := loadRuntimeFromFile(t, tt.args.inputFuncIO) + expIof := loadRuntimeFromFile(t, tt.args.expectedFuncIO) + + r := AddUserAlerting(ctx, iof) + + assert.Equal(t, tt.expResult, r.Resolve()) + assert.Equal(t, getFunctionIo(expIof), getFunctionIo(iof)) + }) + } +} + +func TestGivenConfigRefAndSecretThenExpectOutput(t *testing.T) { + + ctx := context.Background() + + t.Run("GivenConfigRefAndSecret_ThenExpectOutput", func(t *testing.T) { + + iof := loadRuntimeFromFile(t, "alerting/03-GivenConfigRefAndSecret.yaml") + + r := AddUserAlerting(ctx, iof) + assert.Equal(t, runtime.NewNormal(), r) + + resName := "psql-alertmanagerconfig" + kubeObject := &xkube.Object{} + assert.NoError(t, iof.Desired.Get(ctx, kubeObject, resName)) + + comp := &vshnv1.VSHNPostgreSQL{} + assert.NoError(t, iof.Observed.GetComposite(ctx, comp)) + assert.Equal(t, comp.Labels["crossplane.io/claim-namespace"], kubeObject.Spec.References[0].PatchesFrom.Namespace) + assert.Equal(t, comp.Spec.Parameters.Monitoring.AlertmanagerConfigRef, kubeObject.Spec.References[0].PatchesFrom.Name) + + alertConfig := &alertmanagerv1alpha1.AlertmanagerConfig{} + assert.NoError(t, iof.Desired.GetFromObject(ctx, alertConfig, resName)) + assert.Equal(t, comp.Status.InstanceNamespace, alertConfig.GetNamespace()) + + secretName := "psql-alertmanagerconfigsecret" + secret := &v1.Secret{} + assert.NoError(t, iof.Desired.GetFromObject(ctx, secret, secretName)) + + assert.Equal(t, comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef, secret.GetName()) + }) +} + +func TestGivenConfigTemplateAndSecretThenExpectOutput(t *testing.T) { + ctx := context.Background() + + t.Run("GivenConfigTemplateAndSecret_ThenExpectOutput", func(t *testing.T) { + + iof := loadRuntimeFromFile(t, "alerting/04-GivenConfigTemplateAndSecret.yaml") + + r := AddUserAlerting(ctx, iof) + assert.Equal(t, runtime.NewNormal(), r) + + resName := "psql-alertmanagerconfig" + kubeObject := &xkube.Object{} + assert.NoError(t, iof.Desired.Get(ctx, kubeObject, resName)) + + assert.Empty(t, kubeObject.Spec.References) + + alertConfig := &alertmanagerv1alpha1.AlertmanagerConfig{} + comp := &vshnv1.VSHNPostgreSQL{} + assert.NoError(t, iof.Desired.GetFromObject(ctx, alertConfig, resName)) + assert.NoError(t, iof.Observed.GetComposite(ctx, comp)) + assert.Equal(t, comp.Status.InstanceNamespace, alertConfig.GetNamespace()) + assert.Equal(t, comp.Spec.Parameters.Monitoring.AlertmanagerConfigSpecTemplate, &alertConfig.Spec) + + secretName := "psql-alertmanagerconfigsecret" + secret := &v1.Secret{} + assert.NoError(t, iof.Desired.GetFromObject(ctx, secret, secretName)) + + assert.Equal(t, comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef, secret.GetName()) + }) +} diff --git a/comp-functions/functions/vshn-postgres-func/common_test.go b/comp-functions/functions/vshn-postgres-func/common_test.go new file mode 100644 index 0000000000..3958bf05d5 --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/common_test.go @@ -0,0 +1,35 @@ +package vshnpostgres + +import ( + "context" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "os" + "path/filepath" + "reflect" + "strings" + "unsafe" + + xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + + "github.com/stretchr/testify/assert" +) + +func loadRuntimeFromFile(t assert.TestingT, file string) *runtime.Runtime { + p, _ := filepath.Abs(".") + before, _, _ := strings.Cut(p, "/functions") + f, err := os.Open(before + "/test/transforms/vshn-postgres/" + file) + assert.NoError(t, err) + b1, err := os.ReadFile(f.Name()) + if err != nil { + assert.FailNow(t, "can't get example") + } + funcIO, err := runtime.NewRuntime(context.Background(), b1) + assert.NoError(t, err) + + return funcIO +} + +func getFunctionIo(funcIO *runtime.Runtime) xfnv1alpha1.FunctionIO { + field := reflect.ValueOf(funcIO).Elem().FieldByName("io") + return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface().(xfnv1alpha1.FunctionIO) +} diff --git a/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go b/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go new file mode 100644 index 0000000000..38323681ef --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go @@ -0,0 +1,82 @@ +package vshnpostgres + +import ( + "context" + "fmt" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + + "github.com/sethvargo/go-password/password" + controllerruntime "sigs.k8s.io/controller-runtime" + + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// AddPvcSecret adds a secret for the encrypted PVC for the PostgreSQL instance. +func AddPvcSecret(ctx context.Context, iof *runtime.Runtime) runtime.Result { + + log := controllerruntime.LoggerFrom(ctx) + + comp := &vshnv1.VSHNPostgreSQL{} + err := iof.Observed.GetComposite(ctx, comp) + + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot get composite", err) + } + log.Info("Check if encrypted storage is enabled") + + log.V(1).Info("Transforming", "obj", iof) + + encryptionSpec := comp.Spec.Parameters.Encryption + + if !encryptionSpec.Enabled { + log.Info("Encryption not enabled") + return runtime.NewNormal() + } + + if comp.Status.InstanceNamespace == "" { + return runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + } + + log.Info("Adding secret to composite") + + secret := &v1.Secret{} + + // luksSecretResourceName is the resource name defined in the composition + // This name is different from metadata.name of the same resource + // The value is hardcoded in the composition for each resource and due to crossplane limitation + // it cannot be matched to the metadata.name + luksSecretResourceName := comp.Name + "-luks-key" + + err = iof.Observed.GetFromObject(ctx, secret, luksSecretResourceName) + luksKey := "" + if err == runtime.ErrNotFound { + log.Info("Secret does not exist yet. Creating...") + luksKey, err = password.Generate(64, 10, 1, false, true) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot generate new luksKey", err) + } + } else if err == nil { + log.Info("retreiviing existing secret key...") + luksKey = string(secret.Data["luksKey"]) + } else { + return runtime.NewFatalErr(ctx, "Cannot get luks secret object", err) + } + + secret = &v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-data-%s-0-luks-key", comp.ObjectMeta.Labels["crossplane.io/composite"], comp.ObjectMeta.Labels["crossplane.io/composite"]), + Namespace: comp.Status.InstanceNamespace, + }, + Data: map[string][]byte{ + "luksKey": []byte(luksKey), + }, + } + err = iof.Desired.PutIntoObject(ctx, secret, luksSecretResourceName) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot add luks secret object", err) + } + + return runtime.NewNormal() +} diff --git a/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go b/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go new file mode 100644 index 0000000000..1ca4f1b32d --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go @@ -0,0 +1,124 @@ +package vshnpostgres + +import ( + "context" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "testing" + + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + "github.com/stretchr/testify/assert" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + v1 "k8s.io/api/core/v1" + "sigs.k8s.io/yaml" +) + +func TestNoEncryptedPVC(t *testing.T) { + ctx := context.Background() + + type args struct { + expectedFuncIO string + inputFuncIO string + } + tests := []struct { + name string + args args + expResult xfnv1alpha1.Result + }{ + { + name: "GivenNoEncryptionParams_ThenExpectNoOutput", + args: args{ + expectedFuncIO: "enc_pvc/01-ThenExpectNoOutput.yaml", + inputFuncIO: "enc_pvc/01-GivenNoEncryptionParams.yaml", + }, + expResult: xfnv1alpha1.Result{ + Severity: xfnv1alpha1.SeverityNormal, + Message: "function ran successfully", + }, + }, + { + name: "GivenEncryptionParamsToFalse_ThenExpectFalseOutput", + args: args{ + expectedFuncIO: "enc_pvc/02-ThenExpectFalseOutput.yaml", + inputFuncIO: "enc_pvc/02-GivenEncryptionParamsFalse.yaml", + }, + expResult: xfnv1alpha1.Result{ + Severity: xfnv1alpha1.SeverityNormal, + Message: "function ran successfully", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + iof := loadRuntimeFromFile(t, tt.args.inputFuncIO) + expIof := loadRuntimeFromFile(t, tt.args.expectedFuncIO) + + r := AddPvcSecret(ctx, iof) + + assert.Equal(t, tt.expResult, r.Resolve()) + assert.Equal(t, getFunctionIo(expIof), getFunctionIo(iof)) + }) + } +} + +func TestGivenEncrypedPvcThenExpectOutput(t *testing.T) { + + ctx := context.Background() + + t.Run("GivenEncryptionEnabledNoInstanceNamespace_ThenExpectWarningOutput", func(t *testing.T) { + + iof := loadRuntimeFromFile(t, "enc_pvc/03-GivenEncryptionParamsNoInstanceNamespace.yaml") + + r := AddPvcSecret(ctx, iof) + + assert.Equal(t, runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation"), r) + }) + + t.Run("GivenEncryptionEnabled_ThenExpectOutput", func(t *testing.T) { + + iof := loadRuntimeFromFile(t, "enc_pvc/03-GivenEncryptionParams.yaml") + + r := AddPvcSecret(ctx, iof) + + assert.Equal(t, runtime.NewNormal(), r) + + comp := &vshnv1.VSHNPostgreSQL{} + + assert.NoError(t, iof.Observed.GetComposite(ctx, comp)) + + resName := comp.Name + "-luks-key" + kubeObject := &xkube.Object{} + assert.NoError(t, iof.Desired.Get(ctx, kubeObject, resName)) + + //resName := inComp.Name + "-luks-key" + //assert.NoError(t, iof.Desired.GetManagedResource(resName, kubeObject)) + s := &v1.Secret{} + assert.NoError(t, yaml.Unmarshal(kubeObject.Spec.ForProvider.Manifest.Raw, s)) + assert.NotEmpty(t, s.Data["luksKey"]) + }) + + t.Run("GivenEncryptionEnabledExistingSecret_ThenExpectOutput", func(t *testing.T) { + + iof := loadRuntimeFromFile(t, "enc_pvc/03-GivenEncryptionParamsExistingSecret.yaml") + + r := AddPvcSecret(ctx, iof) + + assert.Equal(t, runtime.NewNormal(), r) + + comp := &vshnv1.VSHNPostgreSQL{} + + assert.NoError(t, iof.Observed.GetComposite(ctx, comp)) + + resName := comp.Name + "-luks-key" + kubeObject := &xkube.Object{} + assert.NoError(t, iof.Desired.Get(ctx, kubeObject, resName)) + + //resName := inComp.Name + "-luks-key" + //assert.NoError(t, iof.Desired.GetManagedResource(resName, kubeObject)) + s := &v1.Secret{} + assert.NoError(t, yaml.Unmarshal(kubeObject.Spec.ForProvider.Manifest.Raw, s)) + assert.NotEmpty(t, s.Data["luksKey"]) + }) + +} diff --git a/comp-functions/functions/vshn-postgres-func/schedule.go b/comp-functions/functions/vshn-postgres-func/schedule.go new file mode 100644 index 0000000000..500c94ab56 --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/schedule.go @@ -0,0 +1,56 @@ +package vshnpostgres + +import ( + "context" + "fmt" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "math/rand" + "time" + + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" +) + +var ( + maitenanceWindowStart = time.Date(1970, 1, 1, 21, 0, 0, 0, time.UTC) + maitenanceWindowEnd = time.Date(1970, 1, 2, 5, 0, 0, 0, time.UTC) + maitenanceWindowRange = maitenanceWindowEnd.Unix() - maitenanceWindowStart.Unix() +) + +// TransformSchedule initializes the backup and maintenance schedules if the user did not explicitly provide a schedule. +// The maintenance will be set to a random time on Tuesday night between 21:00 and 5:00, and the backup schedule will be set to once a day between 20:00 and 4:00. +// If neither maintenance nor backup is set, the function will make sure that there will be backup scheduled one hour before the maintenance. +func TransformSchedule(ctx context.Context, iof *runtime.Runtime) runtime.Result { + + comp := vshnv1.VSHNPostgreSQL{} + err := iof.Desired.GetComposite(ctx, &comp) + if err != nil { + return runtime.NewFatalErr(ctx, "failed to parse composite", err) + } + + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + maintTime := time.Unix(maitenanceWindowStart.Unix()+rng.Int63n(maitenanceWindowRange), 0).In(time.UTC) + backupTime := maintTime.Add(-1 * time.Hour).In(time.UTC) + + if comp.Spec.Parameters.Backup.Schedule == "" { + comp.Spec.Parameters.Backup.Schedule = fmt.Sprintf("%d %d * * *", backupTime.Minute(), backupTime.Hour()) + } + + if comp.Spec.Parameters.Maintenance.TimeOfDay == "" { + comp.Spec.Parameters.Maintenance.TimeOfDay = maintTime.Format(time.TimeOnly) + } + + if comp.Spec.Parameters.Maintenance.DayOfWeek == "" { + day := "tuesday" + if maintTime.Day() > 1 { + day = "wednesday" + } + comp.Spec.Parameters.Maintenance.DayOfWeek = day + } + + err = iof.Desired.SetComposite(ctx, &comp) + if err != nil { + return runtime.NewFatalErr(ctx, "failed to set composite", err) + } + + return runtime.NewNormal() +} diff --git a/comp-functions/functions/vshn-postgres-func/schedule_test.go b/comp-functions/functions/vshn-postgres-func/schedule_test.go new file mode 100644 index 0000000000..baf4e653ae --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/schedule_test.go @@ -0,0 +1,167 @@ +package vshnpostgres + +import ( + "context" + "fmt" + "strconv" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + + fnv1aplha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" +) + +func TestTransformSchedule_SetRandomSchedule(t *testing.T) { + + for i := 0; i < 50; i++ { + t.Run(fmt.Sprintf("Round %d", i), func(t *testing.T) { + iof := loadRuntimeFromFile(t, "base.yaml") + + res := TransformSchedule(context.TODO(), iof) + assert.Equal(t, fnv1aplha1.SeverityNormal, res.Resolve().Severity) + + out := &vshnv1.VSHNPostgreSQL{} + err := iof.Desired.GetComposite(context.TODO(), out) + assert.NoError(t, err) + + backupTime := parseAndValidateBackupSchedule(t, out) + maintTime := parseAndValidateMaitenance(t, out) + + t.Logf("Backup Time: %q\n", backupTime.Format(time.RFC3339)) + t.Logf("Maintenance Time: %q\n", maintTime.Format(time.RFC3339)) + + diff := maintTime.Truncate(time.Minute).Sub(backupTime) + assert.Equal(t, time.Hour, diff) + }) + } + +} + +func TestTransformSchedule_DontOverwriteBackup(t *testing.T) { + iof := loadRuntimeFromFile(t, "base.yaml") + + comp := &vshnv1.VSHNPostgreSQL{} + err := iof.Desired.GetComposite(context.TODO(), comp) + assert.NoError(t, err) + comp.Spec.Parameters.Backup.Schedule = "3 2 * * *" + err = iof.Desired.SetComposite(context.TODO(), comp) + assert.NoError(t, err) + + res := TransformSchedule(context.TODO(), iof) + assert.Equal(t, fnv1aplha1.SeverityNormal, res.Resolve().Severity) + + err = iof.Desired.GetComposite(context.TODO(), comp) + assert.NoError(t, err) + assert.Equal(t, "3 2 * * *", comp.Spec.Parameters.Backup.Schedule) + + _ = parseAndValidateMaitenance(t, comp) +} + +func TestTransformSchedule_DontOverwriteMaitenance(t *testing.T) { + iof := loadRuntimeFromFile(t, "base.yaml") + + comp := &vshnv1.VSHNPostgreSQL{} + err := iof.Desired.GetComposite(context.TODO(), comp) + assert.NoError(t, err) + comp.Spec.Parameters.Maintenance.DayOfWeek = "thursday" + comp.Spec.Parameters.Maintenance.TimeOfDay = "11:12:23" + err = iof.Desired.SetComposite(context.TODO(), comp) + assert.NoError(t, err) + + res := TransformSchedule(context.TODO(), iof) + assert.Equal(t, fnv1aplha1.SeverityNormal, res.Resolve().Severity) + + err = iof.Desired.GetComposite(context.TODO(), comp) + assert.NoError(t, err) + assert.Equal(t, "thursday", comp.Spec.Parameters.Maintenance.DayOfWeek) + assert.Equal(t, "11:12:23", comp.Spec.Parameters.Maintenance.TimeOfDay) + + _ = parseAndValidateBackupSchedule(t, comp) +} + +func TestTransformSchedule_DontOverwriteBackupOrMaintenance(t *testing.T) { + iof := loadRuntimeFromFile(t, "base.yaml") + + comp := &vshnv1.VSHNPostgreSQL{} + err := iof.Desired.GetComposite(context.TODO(), comp) + assert.NoError(t, err) + comp.Spec.Parameters.Backup.Schedule = "3 2 * * *" + comp.Spec.Parameters.Maintenance.DayOfWeek = "thursday" + comp.Spec.Parameters.Maintenance.TimeOfDay = "11:12:23" + err = iof.Desired.SetComposite(context.TODO(), comp) + assert.NoError(t, err) + + res := TransformSchedule(context.TODO(), iof) + assert.Equal(t, fnv1aplha1.SeverityNormal, res.Resolve().Severity) + + err = iof.Desired.GetComposite(context.TODO(), comp) + assert.NoError(t, err) + assert.Equal(t, "3 2 * * *", comp.Spec.Parameters.Backup.Schedule) + assert.Equal(t, "thursday", comp.Spec.Parameters.Maintenance.DayOfWeek) + assert.Equal(t, "11:12:23", comp.Spec.Parameters.Maintenance.TimeOfDay) +} + +func parseAndValidateBackupSchedule(t *testing.T, comp *vshnv1.VSHNPostgreSQL) time.Time { + var backupTime time.Time + t.Run("validateBackupSchedule", func(t *testing.T) { + t.Logf("backup schedule %q", comp.Spec.Parameters.Backup.Schedule) + + assert.NotEmpty(t, comp.Spec.Parameters.Backup.Schedule) + backupSchedule := strings.Fields(comp.Spec.Parameters.Backup.Schedule) + assert.Equal(t, "*", backupSchedule[4]) + assert.Equal(t, "*", backupSchedule[3]) + assert.Equal(t, "*", backupSchedule[2]) + + backupMinute, err := strconv.Atoi(backupSchedule[0]) + assert.NoError(t, err) + assert.Less(t, backupMinute, 60) + assert.GreaterOrEqual(t, backupMinute, 0) + backupHour, err := strconv.Atoi(backupSchedule[1]) + assert.Less(t, backupHour, 24) + assert.GreaterOrEqual(t, backupHour, 0) + assert.NoError(t, err) + backupDay := 1 + if backupHour < 6 { + backupDay = 2 + } + backupTime = time.Date(0, 1, backupDay, backupHour, backupMinute, 0, 0, time.UTC) + + backupWindowStart := time.Date(0, 1, 1, 20, 0, 0, 0, time.UTC) + backupWindowEnd := time.Date(0, 1, 2, 4, 0, 0, 0, time.UTC) + assert.LessOrEqual(t, backupWindowStart, backupTime) + assert.LessOrEqual(t, backupTime, backupWindowEnd) + + }) + return backupTime +} + +func parseAndValidateMaitenance(t *testing.T, comp *vshnv1.VSHNPostgreSQL) time.Time { + var maintTime time.Time + t.Run("validateMaintenanceSchedule", func(t *testing.T) { + + t.Logf("maintenance time %q", comp.Spec.Parameters.Maintenance.TimeOfDay) + t.Logf("maintenance day %q", comp.Spec.Parameters.Maintenance.DayOfWeek) + + var err error + assert.NotEmpty(t, comp.Spec.Parameters.Maintenance.TimeOfDay) + maintTime, err = time.ParseInLocation(time.TimeOnly, comp.Spec.Parameters.Maintenance.TimeOfDay, time.UTC) + assert.NoError(t, err) + assert.NotEmpty(t, comp.Spec.Parameters.Maintenance.DayOfWeek) + switch comp.Spec.Parameters.Maintenance.DayOfWeek { + case "tuesday": + case "wednesday": + maintTime = maintTime.Add(24 * time.Hour) + default: + assert.Failf(t, "unexpected Maintenance day", "Day: %q", comp.Spec.Parameters.Maintenance.DayOfWeek) + } + + maintWindowStart := time.Date(0, 1, 1, 21, 0, 0, 0, time.UTC) + maintWindowEnd := time.Date(0, 1, 2, 5, 0, 0, 0, time.UTC) + assert.LessOrEqual(t, maintWindowStart, maintTime) + assert.LessOrEqual(t, maintTime, maintWindowEnd) + }) + return maintTime +} diff --git a/comp-functions/functions/vshn-postgres-func/url.go b/comp-functions/functions/vshn-postgres-func/url.go new file mode 100644 index 0000000000..9474161ff6 --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/url.go @@ -0,0 +1,82 @@ +package vshnpostgres + +import ( + "context" + "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + v1 "k8s.io/api/core/v1" + controllerruntime "sigs.k8s.io/controller-runtime" +) + +var ( + // PostgresqlHost is env variable in the connection secret + PostgresqlHost = "POSTGRESQL_HOST" + // PostgresqlUser is env variable in the connection secret + PostgresqlUser = "POSTGRESQL_USER" + // PostgresqlPassword is env variable in the connection secret + PostgresqlPassword = "POSTGRESQL_PASSWORD" + // PostgresqlPort is env variable in the connection secret + PostgresqlPort = "POSTGRESQL_PORT" + // PostgresqlDb is env variable in the connection secret + PostgresqlDb = "POSTGRESQL_DB" + // PostgresqlUrl is env variable in the connection secret + PostgresqlUrl = "POSTGRESQL_URL" +) + +// connectionSecretResourceName is the resource name defined in the composition +// This name is different from metadata.name of the same resource +// The value is hardcoded in the composition for each resource and due to crossplane limitation +// it cannot be matched to the metadata.name +var connectionSecretResourceName = "connection" + +// AddUrlToConnectionDetails changes the desired state of a FunctionIO +func AddUrlToConnectionDetails(ctx context.Context, iof *runtime.Runtime) runtime.Result { + log := controllerruntime.LoggerFrom(ctx) + + comp := &vshnv1.VSHNPostgreSQL{} + err := iof.Desired.GetComposite(ctx, comp) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot get composite from function io", err) + } + + // Wait for the next reconciliation in case instance namespace is missing + if comp.Status.InstanceNamespace == "" { + return runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + } + + log.Info("Getting connection secret from managed kubernetes object") + s := &v1.Secret{} + + err = iof.Observed.GetFromObject(ctx, s, connectionSecretResourceName) + if err != nil { + return runtime.NewFatalErr(ctx, "Cannot get connection secret object", err) + } + + log.Info("Setting POSTRESQL_URL env variable into connection secret") + val := getPostgresURL(s) + if val == "" { + return runtime.NewWarning(ctx, "User, pass, host, port or db value is missing from connection secret, skipping transformation") + } + iof.Desired.PutCompositeConnectionDetail(ctx, v1alpha1.ExplicitConnectionDetail{ + Name: PostgresqlUrl, + Value: val, + }) + + return runtime.NewNormal() +} + +func getPostgresURL(s *v1.Secret) string { + user := string(s.Data[PostgresqlUser]) + pwd := string(s.Data[PostgresqlPassword]) + host := string(s.Data[PostgresqlHost]) + port := string(s.Data[PostgresqlPort]) + db := string(s.Data[PostgresqlDb]) + + // The values are still missing, wait for the next reconciliation + if user == "" || pwd == "" || host == "" || port == "" || db == "" { + return "" + } + + return "postgres://" + user + ":" + pwd + "@" + host + ":" + port + "/" + db +} diff --git a/comp-functions/functions/vshn-postgres-func/url_test.go b/comp-functions/functions/vshn-postgres-func/url_test.go new file mode 100644 index 0000000000..32ee025029 --- /dev/null +++ b/comp-functions/functions/vshn-postgres-func/url_test.go @@ -0,0 +1,103 @@ +package vshnpostgres + +import ( + "context" + "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" +) + +func TestTransform_NoInstanceNamespace(t *testing.T) { + ctx := context.Background() + expectIo := loadRuntimeFromFile(t, "url/01_expected_no-instance-namespace.yaml") + expectResult := runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + + t.Run("WhenNoInstance_ThenNoErrorAndNoChanges", func(t *testing.T) { + + //Given + io := loadRuntimeFromFile(t, "url/01_input_no-instance-namespace.yaml") + + // When + result := AddUrlToConnectionDetails(ctx, io) + + // Then + assert.Equal(t, expectResult, result) + assert.Equal(t, expectIo, io) + }) +} + +func TestTransform(t *testing.T) { + ctx := context.Background() + expectURL := "postgres://postgres:639b-9076-4de6-a35@" + + "pgsql-gc9x4.vshn-postgresql-pgsql-gc9x4.svc.cluster.local:5432/postgres" + expectResult := runtime.NewNormal() + + t.Run("WhenNormalIO_ThenAddPostgreSQLUrl", func(t *testing.T) { + + //Given + r := loadRuntimeFromFile(t, "url/02_input_function-io.yaml") + + // When + result := AddUrlToConnectionDetails(ctx, r) + + // Then + assert.Equal(t, expectResult, result) + assert.Equal(t, expectURL, r.Desired.GetCompositeConnectionDetails(ctx)[0].Value) + }) +} + +func TestGetPostgresURL(t *testing.T) { + tests := map[string]struct { + secret *v1.Secret + expectUrl string + }{ + "WhenMissingUserAndPortThenReturnNoUrlInSecret": { + secret: &v1.Secret{ + Data: map[string][]byte{ + PostgresqlPassword: []byte("test"), + PostgresqlDb: []byte("db-test"), + PostgresqlHost: []byte("localhost"), + }, + }, + expectUrl: "", + }, + "WhenMissingPasswordThenReturnNoUrlInSecret": { + secret: &v1.Secret{ + Data: map[string][]byte{ + PostgresqlDb: []byte("db-test"), + PostgresqlHost: []byte("localhost"), + PostgresqlUser: []byte("user"), + PostgresqlPort: []byte("5432"), + }, + }, + expectUrl: "", + }, + "WhenDataThenReturnSecretWithUrl": { + secret: &v1.Secret{ + Data: map[string][]byte{ + PostgresqlPassword: []byte("test"), + PostgresqlDb: []byte("db-test"), + PostgresqlHost: []byte("localhost"), + PostgresqlUser: []byte("user"), + PostgresqlPort: []byte("5432"), + }, + StringData: map[string]string{ + "place": "test", + }, + }, + expectUrl: "postgres://user:test@localhost:5432/db-test", + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + + // When + url := getPostgresURL(tc.secret) + + // Then + assert.Equal(t, tc.expectUrl, url) + }) + } +} diff --git a/comp-functions/runtime/desired.go b/comp-functions/runtime/desired.go new file mode 100644 index 0000000000..d5c21c2915 --- /dev/null +++ b/comp-functions/runtime/desired.go @@ -0,0 +1,214 @@ +package runtime + +import ( + "context" + "encoding/json" + "fmt" + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + v1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "reflect" + controllerruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +// the default provider kubernetes name +var providerConfigRefName = "kubernetes" + +type DesiredResources struct { + resources []Resource + composite xfnv1alpha1.DesiredComposite +} + +// List returns the list of managed resources from desired object +func (d *DesiredResources) List(_ context.Context) []Resource { + return d.resources +} + +// Get unmarshalls the resource from the desired array. +// This will return any changes that a previous function has made to the desired array. +func (d *DesiredResources) Get(ctx context.Context, obj client.Object, resName string) error { + return getFrom(ctx, &d.resources, obj, resName) +} + +// Put adds the object as is to the FunctionIO desired array. +// It assumes that the given object is adheres to Crossplane's ManagedResource model. +func (d *DesiredResources) Put(ctx context.Context, obj client.Object) error { + return d.put(ctx, obj, obj.GetName()) +} + +// Remove removes a resource by name from the managed resources +// expect an error if resource not found +func (d *DesiredResources) Remove(ctx context.Context, name string) error { + log := controllerruntime.LoggerFrom(ctx) + for i, r := range d.resources { + if r.GetName() == name { + log.V(1).Info("Removing resource from desired resources", "resource name", name) + d.resources = append(d.resources[:i], d.resources[i+1:]...) + return nil + } + } + return ErrNotFound +} + +// GetFromObject gets the k8s resource o from a provider kubernetes object kon (Kube Object Name) +// from the desired array of the FunctionIO. +func (d *DesiredResources) GetFromObject(ctx context.Context, o client.Object, kon string) error { + ko, err := getKubeObjectFrom(ctx, &d.resources, kon) + if err != nil { + return fmt.Errorf("cannot get resource from desired kube object: %v", err) + } + return d.fromKubeObject(ctx, ko, o) +} + +// PutIntoObject adds or updates the desired resource into its kube object +func (d *DesiredResources) PutIntoObject(ctx context.Context, o client.Object, kon string, refs ...xkube.Reference) error { + log := controllerruntime.LoggerFrom(ctx) + + ko := &xkube.Object{ + TypeMeta: metav1.TypeMeta{ + Kind: xkube.ObjectKind, + APIVersion: xkube.ObjectKindAPIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: kon, + }, + Spec: xkube.ObjectSpec{ + ResourceSpec: v1.ResourceSpec{ + ProviderConfigReference: &v1.Reference{ + Name: providerConfigRefName, + }, + }, + References: refs, + }, + } + err := getFrom(ctx, &d.resources, ko, kon) + if err != nil && err != ErrNotFound { + return err + } + + log.V(1).Info("Preparing to put object into desired kube object", "object", o, "kube object name", kon) + err = updateKubeObject(o, ko) + if err != nil { + return err + } + + return d.put(ctx, ko, kon) +} + +// GetComposite unmarshalls the desired composite from the function io to the given object. +func (d *DesiredResources) GetComposite(_ context.Context, obj client.Object) error { + err := json.Unmarshal(d.composite.Resource.Raw, obj) + if err != nil { + return fmt.Errorf("cannot unmarshall desired composite: %v", err) + } + return nil +} + +// SetComposite sets a new desired composite to the function from the given object. +func (d *DesiredResources) SetComposite(_ context.Context, obj client.Object) error { + raw, err := json.Marshal(obj) + if err != nil { + return fmt.Errorf("cannot marshal desired composite: %v", err) + } + d.composite.Resource.Raw = raw + return nil +} + +// GetCompositeConnectionDetails returns the connection details of the desired composite +func (d *DesiredResources) GetCompositeConnectionDetails(_ context.Context) []xfnv1alpha1.ExplicitConnectionDetail { + return d.composite.ConnectionDetails +} + +// PutCompositeConnectionDetail appends a connection detail to the connection details slice +// of this desired composite +func (d *DesiredResources) PutCompositeConnectionDetail(ctx context.Context, cd xfnv1alpha1.ExplicitConnectionDetail) { + log := controllerruntime.LoggerFrom(ctx) + for i, c := range d.composite.ConnectionDetails { + if cd.Name == c.Name { + log.V(1).Info("Updating existing desired composite connection detail", "cd", cd) + d.composite.ConnectionDetails[i] = cd + return + } + } + log.V(1).Info("Adding desired composite connection detail", "cd", cd) + d.composite.ConnectionDetails = append(d.composite.ConnectionDetails, cd) +} + +// RemoveCompositeConnectionDetail removes a connection detail from the slice of connection details +// of this desired composite +func (d *DesiredResources) RemoveCompositeConnectionDetail(ctx context.Context, cd xfnv1alpha1.ExplicitConnectionDetail) error { + log := controllerruntime.LoggerFrom(ctx) + cds := d.composite.ConnectionDetails + for i, c := range cds { + if cd.Name == c.Name { + log.V(1).Info("Removing connection detail from desired connection details slice", "cd", cd) + d.composite.ConnectionDetails = append(cds[:i], cds[i+1:]...) + return nil + } + } + return ErrNotFound +} + +// fromKubeObject checks into spec field instead of status. The status may not have the latest updates +// when there might be multiple transformation functions in the pipeline +func (d *DesiredResources) fromKubeObject(ctx context.Context, kobj *xkube.Object, obj client.Object) error { + log := controllerruntime.LoggerFrom(ctx) + log.V(1).Info("Unmarshalling resource from desired kube object", "kube object", kobj, reflect.TypeOf(obj).Kind()) + if kobj.Spec.ForProvider.Manifest.Raw == nil { + return ErrNotFound + } + return json.Unmarshal(kobj.Spec.ForProvider.Manifest.Raw, obj) +} + +func (d *DesiredResources) put(ctx context.Context, obj client.Object, resName string) error { + log := controllerruntime.LoggerFrom(ctx) + log.V(1).Info("Putting object into desired kube object", "object", obj, "kube object name", resName) + kind, _, err := s.ObjectKinds(obj) + if err != nil { + return fmt.Errorf("cannot get object kinds from %s: %v", obj.GetName(), err) + } + + obj.GetObjectKind().SetGroupVersionKind(kind[0]) + rawData, err := json.Marshal(obj) + if err != nil { + return fmt.Errorf("cannot marshall object %s: %v", obj.GetName(), err) + } + + for _, res := range d.resources { + if res.GetName() == resName { + log.V(1).Info("Updating existing desired kube object with resource", "object", obj, "kube object name", resName) + res.SetRaw(rawData) + return nil + } + } + + log.V(1).Info("No desired kube object found, adding new one with resource", "object", obj, "kube object name", resName) + d.resources = append(d.resources, desiredResource( + xfnv1alpha1.DesiredResource{ + Name: resName, + Resource: runtime.RawExtension{ + Raw: rawData, + }, + }, + )) + return nil +} + +// desiredResource is a wrapper around xfnv1alpha1.DesiredResource +// so we can satisfy the Resource interface. +type desiredResource xfnv1alpha1.DesiredResource + +func (d desiredResource) GetName() string { + return d.Name +} + +func (d desiredResource) GetRaw() []byte { + return d.Resource.Raw +} + +func (d desiredResource) SetRaw(raw []byte) { + d.Resource.Raw = raw +} diff --git a/comp-functions/runtime/logger.go b/comp-functions/runtime/logger.go new file mode 100644 index 0000000000..944f5736f0 --- /dev/null +++ b/comp-functions/runtime/logger.go @@ -0,0 +1,57 @@ +package runtime + +import ( + "context" + "fmt" + "os" + "runtime" + + "github.com/go-logr/logr" + "github.com/go-logr/zapr" + "github.com/urfave/cli/v2" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func init() { + // Remove `-v` short option from --version flag in favor of verbosity. + cli.VersionFlag.(*cli.BoolFlag).Aliases = nil +} + +// LogMetadata prints various metadata to the root logger. +// It prints version, architecture and current user ID and returns nil. +func LogMetadata(c context.Context, a AppInfo) error { + log := logr.FromContextOrDiscard(c) + log.WithValues( + "version", a.Version, + "date", a.Date, + "go_os", runtime.GOOS, + "go_arch", runtime.GOARCH, + "go_version", runtime.Version(), + "uid", os.Getuid(), + "gid", os.Getgid(), + ).Info("Starting up " + a.AppName) + return nil +} + +func NewZapLogger(name, version string, verbosityLevel int, useProductionConfig bool) (logr.Logger, error) { + cfg := zap.NewDevelopmentConfig() + cfg.EncoderConfig.ConsoleSeparator = " | " + if useProductionConfig { + cfg = zap.NewProductionConfig() + } + // Zap's levels get more verbose as the number gets smaller, + // bug logr's level increases with greater numbers. + cfg.Level = zap.NewAtomicLevelAt(zapcore.Level(verbosityLevel * -1)) + z, err := cfg.Build() + if err != nil { + return logr.Discard(), fmt.Errorf("error configuring the logging stack: %w", err) + } + zap.ReplaceGlobals(z) + zlog := zapr.NewLogger(z).WithName(name) + if useProductionConfig { + // Append the version to each log so that logging stacks like EFK/Loki can correlate errors with specific versions. + return zlog.WithValues("version", version), nil + } + return zlog, nil +} diff --git a/comp-functions/runtime/observed.go b/comp-functions/runtime/observed.go new file mode 100644 index 0000000000..3eafdae9cd --- /dev/null +++ b/comp-functions/runtime/observed.go @@ -0,0 +1,79 @@ +package runtime + +import ( + "context" + "encoding/json" + "fmt" + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + "reflect" + controllerruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type ObservedResources struct { + resources []Resource + composite xfnv1alpha1.ObservedComposite +} + +// List return the list of managed resources from observed object +func (o *ObservedResources) List(_ context.Context) []Resource { + return o.resources +} + +// Get unmarshalls the managed resource with the given name into the given object. +// It reads from the Observed array. +func (o *ObservedResources) Get(ctx context.Context, obj client.Object, resName string) error { + return getFrom(ctx, &o.resources, obj, resName) +} + +// GetFromObject gets the k8s resource o from a provider kubernetes object kon (Kube Object Name) +// from the observed array of the FunctionIO. +func (o *ObservedResources) GetFromObject(ctx context.Context, obj client.Object, kon string) error { + ko, err := getKubeObjectFrom(ctx, &o.resources, kon) + if err != nil { + return err + } + return o.fromKubeObject(ctx, ko, obj) +} + +// GetComposite unmarshalls the observed composite from the function io to the given object. +func (o *ObservedResources) GetComposite(_ context.Context, obj client.Object) error { + err := json.Unmarshal(o.composite.Resource.Raw, obj) + if err != nil { + return fmt.Errorf("cannot unmarshall observed composite: %v", err) + } + return nil +} + +// GetCompositeConnectionDetails returns the connection details of the observed composite +func (o *ObservedResources) GetCompositeConnectionDetails(_ context.Context) *[]xfnv1alpha1.ExplicitConnectionDetail { + return &o.composite.ConnectionDetails +} + +// fromKubeObject checks into status field instead of spec. The spec may not show all the relevant data +// and the status field will not be changed with multiple transformation functions +func (o *ObservedResources) fromKubeObject(ctx context.Context, kobj *xkube.Object, obj client.Object) error { + log := controllerruntime.LoggerFrom(ctx) + log.V(1).Info("Unmarshalling resource from observed kube object", "kube object", kobj, reflect.TypeOf(obj).Kind()) + if kobj.Status.AtProvider.Manifest.Raw == nil { + return ErrNotFound + } + return json.Unmarshal(kobj.Status.AtProvider.Manifest.Raw, obj) +} + +// observedResource is a wrapper around xfnv1alpha1.ObservedResource +// so we can satisfy the Resource interface. +type observedResource xfnv1alpha1.ObservedResource + +func (o observedResource) GetName() string { + return o.Name +} + +func (o observedResource) GetRaw() []byte { + return o.Resource.Raw +} + +func (o observedResource) SetRaw(raw []byte) { + o.Resource.Raw = raw +} diff --git a/comp-functions/runtime/result.go b/comp-functions/runtime/result.go new file mode 100644 index 0000000000..f4a5cabdb1 --- /dev/null +++ b/comp-functions/runtime/result.go @@ -0,0 +1,60 @@ +package runtime + +import ( + "context" + "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + controllerruntime "sigs.k8s.io/controller-runtime" +) + +type Result interface { + Resolve() v1alpha1.Result +} + +type result v1alpha1.Result + +// NewWarning returns a warning Result from a message string. The entire +// Composition will run to completion but warning events and debug logs +// associated with the composite resource will be emitted. +func NewWarning(ctx context.Context, msg string) Result { + controllerruntime.LoggerFrom(ctx).Info(msg) + return result{ + Severity: v1alpha1.SeverityWarning, + Message: msg, + } +} + +// NewFatalErr returns a fatal Result from a message string and an error. The result is fatal, +// subsequent Composition Functions may run, but the Composition Function pipeline run +// will be considered a failure and the first error will be returned. +func NewFatalErr(ctx context.Context, msg string, err error) Result { + controllerruntime.LoggerFrom(ctx).Error(err, msg) + return result{ + Severity: v1alpha1.SeverityFatal, + Message: msg, + } +} + +// NewFatal returns a fatal Result from a message string. The result is fatal, +// subsequent Composition Functions may run, but the Composition Function +// pipeline run will be considered a failure and the first error will be returned. +func NewFatal(ctx context.Context, msg string) Result { + controllerruntime.LoggerFrom(ctx).Info(msg) + return result{ + Severity: v1alpha1.SeverityFatal, + Message: msg, + } +} + +// NewNormal results are emitted as normal events and debug logs associated +// with the composite resource. +func NewNormal() Result { + return result{ + Severity: v1alpha1.SeverityNormal, + Message: "function ran successfully", + } +} + +// Resolve returns the wrapped object v1alpha1.Result from crossplane +func (r result) Resolve() v1alpha1.Result { + return v1alpha1.Result(r) +} diff --git a/comp-functions/runtime/run.go b/comp-functions/runtime/run.go new file mode 100644 index 0000000000..33f3d019c1 --- /dev/null +++ b/comp-functions/runtime/run.go @@ -0,0 +1,61 @@ +package runtime + +import ( + "context" + "fmt" + + xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + "github.com/go-logr/logr" + "sigs.k8s.io/yaml" +) + +// Exec reads FunctionIO from stdin and return the desired state via transform function +func Exec(ctx context.Context, log logr.Logger, runtime *Runtime, transform Transform) error { + + log.V(1).Info("Executing transformation function") + res := transform.TransformFunc(ctx, runtime).Resolve() + res.Message = fmt.Sprintf("Function %s result: %s", transform.Name, res.Message) + + runtime.io.Results = append(runtime.io.Results, res) + + runtime.io.Desired.Composite.Resource.Raw = runtime.Desired.composite.Resource.Raw + runtime.io.Desired.Composite.ConnectionDetails = runtime.Desired.composite.ConnectionDetails + + runtime.io.Desired.Resources = make([]xfnv1alpha1.DesiredResource, len(runtime.Desired.resources)) + for i, r := range runtime.Desired.resources { + runtime.io.Desired.Resources[i] = xfnv1alpha1.DesiredResource(r.(desiredResource)) + } + + return nil +} + +// printFunctionIO prints the whole FunctionIO to stdout, so Crossplane can +// pick it up again. +func printFunctionIO(iof *xfnv1alpha1.FunctionIO, log logr.Logger) ([]byte, error) { + log.V(1).Info("Marshalling FunctionIO") + fnc, err := yaml.Marshal(iof) + if err != nil { + return []byte{}, fmt.Errorf("failed to marshal function io: %w", err) + } + return fnc, nil +} + +func RunCommand(ctx context.Context, input []byte, transforms []Transform) ([]byte, error) { + log := logr.FromContextOrDiscard(ctx) + + log.V(1).Info("Creating new runtime") + funcIO, err := NewRuntime(ctx, input) + if err != nil { + return []byte{}, err + } + + for _, function := range transforms { + log.Info("Starting function", "name", function.Name) + err = Exec(ctx, log, funcIO, function) + if err != nil { + return []byte{}, err + } + } + + return printFunctionIO(&funcIO.io, log) +} diff --git a/comp-functions/runtime/runtime.go b/comp-functions/runtime/runtime.go new file mode 100644 index 0000000000..6042562af8 --- /dev/null +++ b/comp-functions/runtime/runtime.go @@ -0,0 +1,149 @@ +package runtime + +import ( + "context" + "encoding/json" + "errors" + "fmt" + + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + controllerruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/yaml" +) + +var s = runtime.NewScheme() + +type contextKey int + +// Runtime a struct which encapsulates crossplane FunctionIO +type Runtime struct { + io xfnv1alpha1.FunctionIO + Observed ObservedResources + Desired DesiredResources +} + +type Resource interface { + GetName() string + GetRaw() []byte + SetRaw([]byte) +} + +// KeyFuncIO is the key to the context value where the functionIO pointer is stored +const KeyFuncIO contextKey = iota + +func init() { + _ = corev1.SchemeBuilder.AddToScheme(s) + _ = xkube.SchemeBuilder.SchemeBuilder.AddToScheme(s) + _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s) +} + +var ErrNotFound = errors.New("not found") + +// NewRuntime creates a new Runtime object. +func NewRuntime(ctx context.Context, input []byte) (*Runtime, error) { + log := controllerruntime.LoggerFrom(ctx) + + log.V(1).Info("Unmarshalling FunctionIO from stdin") + r := Runtime{} + err := yaml.Unmarshal(input, &r.io) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal function io: %w", err) + } + r.Observed = ObservedResources{ + resources: *observedResources(r.io.Observed.Resources), + composite: r.io.Observed.Composite, + } + r.Desired = DesiredResources{ + resources: *desiredResources(r.io.Desired.Resources), + composite: r.io.Desired.Composite, + } + + return &r, nil +} + +func getKubeObjectFrom(ctx context.Context, resources *[]Resource, kon string) (*xkube.Object, error) { + log := controllerruntime.LoggerFrom(ctx) + log.V(1).Info("Getting kube object from resources", "name", kon) + ko := &xkube.Object{ + TypeMeta: metav1.TypeMeta{ + Kind: xkube.ObjectKind, + APIVersion: xkube.ObjectKindAPIVersion, + }, + } + err := getFrom(ctx, resources, ko, kon) + if err != nil { + return nil, err + } + + return ko, nil +} + +func getFrom(ctx context.Context, resources *[]Resource, obj client.Object, resName string) error { + log := controllerruntime.LoggerFrom(ctx) + gvk := obj.GetObjectKind() + + log.V(1).Info("Searching resource by resource name", "name", resName) + for _, res := range *resources { + if res.GetName() == resName { + err := yaml.Unmarshal(res.GetRaw(), obj) + if err != nil { + return fmt.Errorf("cannot unmarshal desired resource: %w", err) + } + + // matching by name is not enough, group and kind should match + ogvk := obj.GetObjectKind() + if gvk == ogvk { + return nil + } + } + } + + log.V(1).Info("No resource found", "name", resName) + return ErrNotFound +} + +func desiredResources(dr []xfnv1alpha1.DesiredResource) *[]Resource { + resources := make([]Resource, len(dr)) + + for i := range dr { + resources[i] = desiredResource(dr[i]) + } + + return &resources +} + +func observedResources(or []xfnv1alpha1.ObservedResource) *[]Resource { + resources := make([]Resource, len(or)) + + for i := range or { + resources[i] = observedResource(or[i]) + } + + return &resources +} + +func updateKubeObject(obj client.Object, ko *xkube.Object) error { + kind, _, err := s.ObjectKinds(obj) + if err != nil { + return fmt.Errorf("cannot get object kinds from %s: %v", obj.GetName(), err) + } + obj.GetObjectKind().SetGroupVersionKind(kind[0]) + + rawData, err := json.Marshal(obj) + if err != nil { + return fmt.Errorf("cannot marshall object %s: %v", obj.GetName(), err) + } + ko.Spec.ForProvider.Manifest = runtime.RawExtension{Raw: rawData} + return nil +} + +// AddToScheme adds given SchemeBuilder to the Scheme. +func AddToScheme(obj runtime.SchemeBuilder) error { + return obj.AddToScheme(s) +} diff --git a/comp-functions/runtime/types.go b/comp-functions/runtime/types.go new file mode 100644 index 0000000000..061d43708f --- /dev/null +++ b/comp-functions/runtime/types.go @@ -0,0 +1,16 @@ +package runtime + +import ( + "context" +) + +// AppInfo defines application information +type AppInfo struct { + Version, Commit, Date, AppName, AppLongName string +} + +// Transform specifies a transformation function to be run against the given FunctionIO. +type Transform struct { + Name string + TransformFunc func(c context.Context, io *Runtime) Result +} diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 64839bb3ac..dce6015d47 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -1,4 +1,3 @@ -// TODO: Edit navigation * xref:index.adoc[Introduction] * https://github.com/vshn/go-bootstrap/releases[Changelog,window=_blank] 🔗 @@ -13,3 +12,6 @@ .Explanation * xref:explanations/boostrap.adoc[Boostrap] +* xref:explanations/comp-functions/runtime.adoc[Runtime Library] +* xref:explanations/comp-functions/vshn-postgres.adoc[VSHN Postgres Functions] + diff --git a/docs/modules/ROOT/pages/explanations/comp-functions/runtime.adoc b/docs/modules/ROOT/pages/explanations/comp-functions/runtime.adoc new file mode 100644 index 0000000000..850039e0b8 --- /dev/null +++ b/docs/modules/ROOT/pages/explanations/comp-functions/runtime.adoc @@ -0,0 +1,26 @@ += Runtime Library + +The runtime library helps to facilitate the implementation of transformation go functions. +It allows to operate on underlying function-io resources and composites. There are 2 objects accessible +from a runtime object: + +- `Observed` - the observed state of the XR and any existing composed resources. +- `Desired` - the desired state of the XR and any composed resources. + +For more information on how function-io operates check the https://docs.crossplane.io/knowledge-base/guides/composition-functions/#functionio[documentation] +from Crossplane. + +== Desired Object + +The runtime desired object has methods to obtain and update desired resources from function-io. + +== Observed Object + +The runtime observed object has methods to obtain observed resources from function-io. + +== Result Object + +Any transformation go function expects a `runtime.Result` object. This object type wraps the Crossplane +own Result type. The runtime library has simple functions that allows creation of `runtime.Result` objects +in various states - `fatal`, `warning` or `normal`. To understand the difference between these states +consult crossplane https://docs.crossplane.io/knowledge-base/guides/composition-functions/#functionio[documentation]. diff --git a/docs/modules/ROOT/pages/explanations/comp-functions/vshn-postgres.adoc b/docs/modules/ROOT/pages/explanations/comp-functions/vshn-postgres.adoc new file mode 100644 index 0000000000..e31fb05bb1 --- /dev/null +++ b/docs/modules/ROOT/pages/explanations/comp-functions/vshn-postgres.adoc @@ -0,0 +1,10 @@ += VSHN Postgres Function-io + +The set of transformation go functions applied to a VSHN Postgres composition. + +== Transformation URL-CONNECTION-DETAILS + +The function URL-CONNECTION-DETAILS adds a new `POSTGRES_URL` entry in the connection detail of the composite. The value is defined as `postgres://user:password@host:port/db`. Once it is executed the client has access to the URL of its database via connection secret. + + + diff --git a/go.mod b/go.mod index 449f9def4b..8b0af90d5d 100644 --- a/go.mod +++ b/go.mod @@ -13,24 +13,30 @@ require ( github.com/golang/protobuf v1.5.2 github.com/jackc/pgx/v5 v5.3.1 github.com/ory/dockertest v3.3.5+incompatible + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.63.0 github.com/prometheus/client_golang v1.14.0 + github.com/sethvargo/go-password v0.2.0 github.com/spf13/cobra v1.6.1 github.com/spf13/viper v1.15.0 github.com/stretchr/testify v1.8.2 + github.com/urfave/cli/v2 v2.25.3 github.com/vektra/mockery/v2 v2.26.1 - github.com/vshn/component-appcat/apis v0.0.0-20230414110116-c7334ac8d3b1 + github.com/vshn/component-appcat/apis v0.0.0-20230508083110-a8e04b7b9a13 go.uber.org/zap v1.24.0 golang.org/x/text v0.8.0 + google.golang.org/grpc v1.52.0 gotest.tools/v3 v3.0.3 k8s.io/api v0.26.3 k8s.io/apimachinery v0.26.3 k8s.io/apiserver v0.26.3 k8s.io/client-go v0.26.3 k8s.io/code-generator v0.26.3 + k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 sigs.k8s.io/apiserver-runtime v1.1.2-0.20221226021050-33c901856927 sigs.k8s.io/controller-runtime v0.14.5 sigs.k8s.io/controller-tools v0.11.3 sigs.k8s.io/kind v0.17.0 + sigs.k8s.io/yaml v1.3.0 ) require ( @@ -50,6 +56,7 @@ require ( github.com/containerd/continuity v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect @@ -71,6 +78,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -93,6 +101,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.6.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/opencontainers/runc v1.1.5 // indirect @@ -100,11 +109,11 @@ require ( github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.63.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/rs/zerolog v1.29.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -112,6 +121,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.etcd.io/etcd/api/v3 v3.5.6 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect go.etcd.io/etcd/client/v3 v3.5.6 // indirect @@ -139,22 +149,20 @@ require ( gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect - google.golang.org/grpc v1.52.0 // indirect google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gotest.tools v2.2.0+incompatible // indirect k8s.io/apiextensions-apiserver v0.26.3 // indirect k8s.io/component-base v0.26.3 // indirect k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect k8s.io/klog/v2 v2.90.1 // indirect k8s.io/kms v0.26.3 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect - k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.36 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 62b4ba56bf..9087725ca3 100644 --- a/go.sum +++ b/go.sum @@ -107,6 +107,7 @@ github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 h1:rtAn27 github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crossplane-contrib/provider-kubernetes v0.7.0 h1:0IfhEpkcn4TeiGfRRI57pcXefSZ9ejW/MWLFQrS6n+M= @@ -272,6 +273,7 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -331,7 +333,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -371,7 +373,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= +github.com/onsi/ginkgo/v2 v2.6.1 h1:1xQPCjcqYw/J5LchOcp4/2q/jzJFjiAOc25chhnDw+Q= +github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= github.com/onsi/gomega v1.24.2 h1:J/tulyYK6JwBldPViHJReihxxZ+22FHs0piGjQAvoUE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -427,13 +430,16 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI= +github.com/sethvargo/go-password v0.2.0/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -481,18 +487,20 @@ github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNG github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.25.3 h1:VJkt6wvEBOoSjPFQvOkv6iWIrsJyCrKGtCtxXWwmGeY= +github.com/urfave/cli/v2 v2.25.3/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/vektra/mockery/v2 v2.26.1 h1:Y8mlLkWHWjuUpsJBwhFb1LeG1ZnWFvo+prsIuiABJ88= github.com/vektra/mockery/v2 v2.26.1/go.mod h1:BOVUIv65DB6wuTYzoPtyMoBYce3n2C1IcsOdWu6Rpu4= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vshn/appcat-sli-exporter v0.1.1 h1:QYgdnXkFwtA7yOW5SdO1cVC3p0zi+teVpRQlDqW6nVw= -github.com/vshn/appcat-sli-exporter v0.1.1/go.mod h1:M3XkeMFCcyECgs/VSsH/rERTfgQ0KfM/eI1yRJRfYXw= -github.com/vshn/component-appcat/apis v0.0.0-20230414110116-c7334ac8d3b1 h1:cC5UIdvVbP+ClW2V/PNJxtTtiVwpaVAotTG0DZetZJw= -github.com/vshn/component-appcat/apis v0.0.0-20230414110116-c7334ac8d3b1/go.mod h1:1DA8TgDuQ5NWTGrYLXk7EfnClwt8dHyrLJ66EiiibLo= +github.com/vshn/component-appcat/apis v0.0.0-20230508083110-a8e04b7b9a13 h1:GoRKKQzu7sUpp82v5+xqsIbWKtQZIv/vrS6+r5UzsaQ= +github.com/vshn/component-appcat/apis v0.0.0-20230508083110-a8e04b7b9a13/go.mod h1:+zmzGcEUhwhz3QlIMMo+XQTRSoIK8MY/kSlIcEzC6I8= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -947,6 +955,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/test/example.yaml b/test/example.yaml new file mode 100644 index 0000000000..436eff51fd --- /dev/null +++ b/test/example.yaml @@ -0,0 +1,759 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"vshn.appcat.vshn.io/v1","kind":"VSHNPostgreSQL","metadata":{"annotations":{},"name":"pgsql","namespace":"glrf-test"},"spec":{"parameters":{"service":{"majorVersion":"15"}},"writeConnectionSecretToRef":{"name":"postgres-creds"}}} + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: glrf-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + resourceVersion: "481074263" + uid: 0cbf744b-7529-4d33-afe6-26bc5a575f7c + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: glrf-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + monitoring: + alertmanagerConfigSecretRef: test + alertmanagerConfigTemplate: + route: + groupBy: [ 'job' ] + groupWait: 30s + groupInterval: 5m + repeatInterval: 12h + receiver: 'webhook' + receivers: + - name: 'webhook' + webhookConfigs: + - url: 'http://example.com/' + encryption: + enabled: "true" + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: ns-observer-pgsql-gc9x4 + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: vshn-postgresql-pgsql-gc9x4 + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-service-rolebinding + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-localca + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-certificate + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-profile + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-pgconf + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-cluster + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection + - apiVersion: appcat.vshn.io/v1 + kind: XObjectBucket + name: pgsql-gc9x4 + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-object-storage + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenanceserviceaccount + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenancerole + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenancerolebinding + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenancejob + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-podmonitor + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-prometheusrule + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-network-policy + writeConnectionSecretToRef: + name: 0cbf744b-7529-4d33-afe6-26bc5a575f7c + namespace: syn-crossplane + status: + certificateConditions: + - lastTransitionTime: "2023-03-21T16:53:16Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + conditions: + - lastTransitionTime: "2023-03-21T16:52:32Z" + reason: ReconcileSuccess + status: "True" + type: Synced + - lastTransitionTime: "2023-03-23T09:01:04Z" + reason: Available + status: "True" + type: Ready + connectionDetails: + lastPublishedTime: "2023-03-21T16:54:36Z" + instanceNamespace: vshn-postgresql-pgsql-gc9x4 + localCAConditions: + - lastTransitionTime: "2023-03-21T16:53:15Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + namespaceConditions: + - lastTransitionTime: "2023-03-21T16:53:14Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:51Z" + reason: ReconcileSuccess + status: "True" + type: Synced + networkPolicyConditions: + - lastTransitionTime: "2023-03-21T16:53:24Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:53:00Z" + reason: ReconcileSuccess + status: "True" + type: Synced + pgclusterConditions: + - lastTransitionTime: "2023-03-21T16:53:44Z" + reason: Available + status: "True" + type: Ready + pgconfigConditions: + - lastTransitionTime: "2023-03-21T16:53:16Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + profileConditions: + - lastTransitionTime: "2023-03-21T16:53:16Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + secretConditions: + - lastTransitionTime: "2023-03-21T16:54:07Z" + reason: ReconcileSuccess + status: "True" + type: Synced + - lastTransitionTime: "2023-03-21T16:54:07Z" + reason: Available + status: "True" + type: Ready + resources: + - name: connection + resource: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + metadata: + name: pgsql-gc9x4-connection + namespace: test + spec: + forProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: pgsql-connection + namespace: vshn-postgresql-pgsql-gc9x4 + data: + PPOSTGRESQL_DB: cG9zdGdyZXM= + POSTGRESQL_HOST: cGdzcWwtYXBwMS1wcm9kLXpkejRzLnZzaG4tcG9zdGdyZXNxbC1wZ3NxbC1hcHAxLXByb2QtemR6NHMuc3ZjLmNsdXN0ZXIubG9jYWw= + POSTGRESQL_PASSWORD: NTY4MC0xNTI2LTRmMGQtYTAw + POSTGRESQL_PORT: NTQzMg== + POSTGRESQL_USER: cG9zdGdyZXM= + providerConfigRef: + name: kubernetes + references: + - patchesFrom: + apiVersion: v1 + fieldPath: data.superuser-password + kind: Secret + name: "" + namespace: "" + toFieldPath: data.POSTGRESQL_PASSWORD + - patchesFrom: + apiVersion: v1 + fieldPath: data[ca.crt] + kind: Secret + name: tls-certificate + namespace: "" + toFieldPath: data[ca.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.crt] + kind: Secret + name: tls-certificate + namespace: "" + toFieldPath: data[tls.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.key] + kind: Secret + name: tls-certificate + namespace: "" + toFieldPath: data[tls.key] + writeConnectionSecretToRef: + name: "" + namespace: "" + status: + atProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: pgsql-connection + namespace: vshn-postgresql-pgsql-gc9x4 + data: + POSTGRESQL_DB: cG9zdGdyZXM= + POSTGRESQL_HOST: cGdzcWwtYXBwMS1wcm9kLXpkejRzLnZzaG4tcG9zdGdyZXNxbC1wZ3NxbC1hcHAxLXByb2QtemR6NHMuc3ZjLmNsdXN0ZXIubG9jYWw= + POSTGRESQL_PASSWORD: NTY4MC0xNTI2LTRmMGQtYTAw + POSTGRESQL_PORT: NTQzMg== + POSTGRESQL_USER: cG9zdGdyZXM= + connectionDetails: + - fromConnectionSecretKey: ca.crt + name: ca.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.crt + name: tls.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.key + name: tls.key + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_URL + name: POSTGRESQL_URL + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_DB + name: POSTGRESQL_DB + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_HOST + name: POSTGRESQL_HOST + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PORT + name: POSTGRESQL_PORT + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_USER + name: POSTGRESQL_USER + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PASSWORD + name: POSTGRESQL_PASSWORD + type: FromConnectionSecretKey + patches: + - fromFieldPath: status.conditions + toFieldPath: status.secretConditions + type: ToCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.metadata.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.forProvider.manifest.metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - combine: + strategy: string + string: + fmt: '%s.vshn-postgresql-%s.svc.cluster.local' + variables: + - fromFieldPath: metadata.labels[crossplane.io/composite] + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.stringData.POSTGRESQL_HOST + type: CombineFromComposite + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.name + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.writeConnectionSecretToRef.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[1].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[2].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[3].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath +desired: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"vshn.appcat.vshn.io/v1","kind":"VSHNPostgreSQL","metadata":{"annotations":{},"name":"pgsql","namespace":"glrf-test"},"spec":{"parameters":{"service":{"majorVersion":"15"}},"writeConnectionSecretToRef":{"name":"postgres-creds"}}} + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: glrf-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + resourceVersion: "481074263" + uid: 0cbf744b-7529-4d33-afe6-26bc5a575f7c + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: glrf-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: ns-observer-pgsql-gc9x4 + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: vshn-postgresql-pgsql-gc9x4 + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-service-rolebinding + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-localca + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-certificate + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-profile + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-pgconf + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-cluster + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection + - apiVersion: appcat.vshn.io/v1 + kind: XObjectBucket + name: pgsql-gc9x4 + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-object-storage + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenanceserviceaccount + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenancerole + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenancerolebinding + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-maintenancejob + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-podmonitor + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-prometheusrule + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-network-policy + writeConnectionSecretToRef: + name: 0cbf744b-7529-4d33-afe6-26bc5a575f7c + namespace: syn-crossplane + status: + certificateConditions: + - lastTransitionTime: "2023-03-21T16:53:16Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + conditions: + - lastTransitionTime: "2023-03-21T16:52:32Z" + reason: ReconcileSuccess + status: "True" + type: Synced + - lastTransitionTime: "2023-03-23T09:01:04Z" + reason: Available + status: "True" + type: Ready + connectionDetails: + lastPublishedTime: "2023-03-21T16:54:36Z" + instanceNamespace: vshn-postgresql-pgsql-gc9x4 + localCAConditions: + - lastTransitionTime: "2023-03-21T16:53:15Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + namespaceConditions: + - lastTransitionTime: "2023-03-21T16:53:14Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:51Z" + reason: ReconcileSuccess + status: "True" + type: Synced + networkPolicyConditions: + - lastTransitionTime: "2023-03-21T16:53:24Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:53:00Z" + reason: ReconcileSuccess + status: "True" + type: Synced + pgclusterConditions: + - lastTransitionTime: "2023-03-21T16:53:44Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-23T09:00:30Z" + message: | + update failed: cannot apply object: cannot patch object: admission webhook + "sgcluster.stackgres-operator.syn-stackgres-operator" denied the request: Decrease + of persistent volume size is not supported' + reason: ReconcileError + status: "False" + type: Synced + pgconfigConditions: + - lastTransitionTime: "2023-03-21T16:53:16Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + profileConditions: + - lastTransitionTime: "2023-03-21T16:53:16Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-03-21T16:52:52Z" + reason: ReconcileSuccess + status: "True" + type: Synced + secretConditions: + - lastTransitionTime: "2023-03-21T16:54:07Z" + reason: ReconcileSuccess + status: "True" + type: Synced + - lastTransitionTime: "2023-03-21T16:54:07Z" + reason: Available + status: "True" + type: Ready + resources: + - name: connection + resource: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + metadata: + name: pgsql-gc9x4-connection + namespace: test + spec: + forProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: pgsql-connection + namespace: vshn-postgresql-pgsql-gc9x4 + data: + POSTGRESQL_PASSWORD: NjM5Yi05MDc2LTRkZTYtYTM1 + stringData: + POSTGRESQL_DB: postgres + POSTGRESQL_HOST: pgsql-gc9x4.vshn-postgresql-pgsql-gc9x4.svc.cluster.local + POSTGRESQL_PORT: "5432" + POSTGRESQL_USER: postgres + providerConfigRef: + name: kubernetes + references: + - patchesFrom: + apiVersion: v1 + fieldPath: data.superuser-password + kind: Secret + name: "" + namespace: "" + toFieldPath: data.POSTGRESQL_PASSWORD + - patchesFrom: + apiVersion: v1 + fieldPath: data[ca.crt] + kind: Secret + name: tls-certificate + namespace: "" + toFieldPath: data[ca.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.crt] + kind: Secret + name: tls-certificate + namespace: "" + toFieldPath: data[tls.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.key] + kind: Secret + name: tls-certificate + namespace: "" + toFieldPath: data[tls.key] + writeConnectionSecretToRef: + name: "" + namespace: "" + connectionDetails: + - fromConnectionSecretKey: ca.crt + name: ca.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.crt + name: tls.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.key + name: tls.key + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_URL + name: POSTGRESQL_URL + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_DB + name: POSTGRESQL_DB + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_HOST + name: POSTGRESQL_HOST + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PORT + name: POSTGRESQL_PORT + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_USER + name: POSTGRESQL_USER + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PASSWORD + name: POSTGRESQL_PASSWORD + type: FromConnectionSecretKey + patches: + - fromFieldPath: status.conditions + toFieldPath: status.secretConditions + type: ToCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.metadata.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.forProvider.manifest.metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - combine: + strategy: string + string: + fmt: '%s.vshn-postgresql-%s.svc.cluster.local' + variables: + - fromFieldPath: metadata.labels[crossplane.io/composite] + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.stringData.POSTGRESQL_HOST + type: CombineFromComposite + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.name + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.writeConnectionSecretToRef.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[1].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[2].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[3].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath +results: + - severity: Normal + message: "Successfully composed VSHNPostgreSQL database" diff --git a/test/grpc-client/main.go b/test/grpc-client/main.go new file mode 100644 index 0000000000..0dbc9af843 --- /dev/null +++ b/test/grpc-client/main.go @@ -0,0 +1,52 @@ +/* + +Client is just for debugging purposes, it sends the same request as crossplane would send + +*/ + +package main + +import ( + "context" + "fmt" + "log" + "os" + "time" + + pb "github.com/crossplane/crossplane/apis/apiextensions/fn/proto/v1alpha1" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +var ( + Network = "unix" + Address = "../../default.sock" +) + +func main() { + // reuse the same output as we use in tests + // You must run this file from it's directory or adjust file path + b1, err := os.ReadFile("../../test/example.yaml") + if err != nil { + log.Fatal(err) + } + conn, err := grpc.Dial(fmt.Sprintf("%s:%s", Network, Address), grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + client := pb.NewContainerizedFunctionRunnerServiceClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + sample_request := pb.RunFunctionRequest{ + Input: b1, + Image: "postgresql", + } + + resp, err := client.RunFunction(ctx, &sample_request) + if err != nil { + log.Fatal(err) + } + + fmt.Println(string(resp.GetOutput())) +} diff --git a/test/transforms/vshn-postgres/alerting/01-GivenNoMonitoringParams.yaml b/test/transforms/vshn-postgres/alerting/01-GivenNoMonitoringParams.yaml new file mode 100644 index 0000000000..0f8bf81357 --- /dev/null +++ b/test/transforms/vshn-postgres/alerting/01-GivenNoMonitoringParams.yaml @@ -0,0 +1,57 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: null + status: + instanceNamespace: my-psql +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: + instanceNamespace: my-psql diff --git a/test/transforms/vshn-postgres/alerting/01-ThenExpectNoOutput.yaml b/test/transforms/vshn-postgres/alerting/01-ThenExpectNoOutput.yaml new file mode 100644 index 0000000000..0e13c50d6d --- /dev/null +++ b/test/transforms/vshn-postgres/alerting/01-ThenExpectNoOutput.yaml @@ -0,0 +1,57 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: + instanceNamespace: my-psql +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: null + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: null + status: + instanceNamespace: my-psql diff --git a/test/transforms/vshn-postgres/alerting/02-GivenConfigRefNoSecretRef.yaml b/test/transforms/vshn-postgres/alerting/02-GivenConfigRefNoSecretRef.yaml new file mode 100644 index 0000000000..1edb476d2b --- /dev/null +++ b/test/transforms/vshn-postgres/alerting/02-GivenConfigRefNoSecretRef.yaml @@ -0,0 +1,59 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + monitoring: + alertmanagerConfigRef: test + status: + instanceNamespace: my-psql +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: + instanceNamespace: my-psql diff --git a/test/transforms/vshn-postgres/alerting/02-ThenExpectError.yaml b/test/transforms/vshn-postgres/alerting/02-ThenExpectError.yaml new file mode 100644 index 0000000000..1edb476d2b --- /dev/null +++ b/test/transforms/vshn-postgres/alerting/02-ThenExpectError.yaml @@ -0,0 +1,59 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + monitoring: + alertmanagerConfigRef: test + status: + instanceNamespace: my-psql +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: + instanceNamespace: my-psql diff --git a/test/transforms/vshn-postgres/alerting/03-GivenConfigRefAndSecret.yaml b/test/transforms/vshn-postgres/alerting/03-GivenConfigRefAndSecret.yaml new file mode 100644 index 0000000000..3aea1d3a53 --- /dev/null +++ b/test/transforms/vshn-postgres/alerting/03-GivenConfigRefAndSecret.yaml @@ -0,0 +1,59 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + monitoring: + alertmanagerConfigRef: test + alertmanagerConfigSecretRef: test + status: + instanceNamespace: my-psql +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/alerting/04-GivenConfigTemplateAndSecret.yaml b/test/transforms/vshn-postgres/alerting/04-GivenConfigTemplateAndSecret.yaml new file mode 100644 index 0000000000..781369a10c --- /dev/null +++ b/test/transforms/vshn-postgres/alerting/04-GivenConfigTemplateAndSecret.yaml @@ -0,0 +1,69 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + monitoring: + alertmanagerConfigSecretRef: test + alertmanagerConfigTemplate: + route: + groupBy: ['job'] + groupWait: 30s + groupInterval: 5m + repeatInterval: 12h + receiver: 'webhook' + receivers: + - name: 'webhook' + webhookConfigs: + - url: 'http://example.com/' + status: + instanceNamespace: my-psql +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/alerting/05-GivenNoStatusInstanceNamespace.yaml b/test/transforms/vshn-postgres/alerting/05-GivenNoStatusInstanceNamespace.yaml new file mode 100644 index 0000000000..cb6be2bf0e --- /dev/null +++ b/test/transforms/vshn-postgres/alerting/05-GivenNoStatusInstanceNamespace.yaml @@ -0,0 +1,58 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + monitoring: + alertmanagerConfigRef: test + alertmanagerConfigSecretRef: test + status: {} +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/base.yaml b/test/transforms/vshn-postgres/base.yaml new file mode 100644 index 0000000000..cb35d2520d --- /dev/null +++ b/test/transforms/vshn-postgres/base.yaml @@ -0,0 +1,54 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: null +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/enc_pvc/01-GivenNoEncryptionParams.yaml b/test/transforms/vshn-postgres/enc_pvc/01-GivenNoEncryptionParams.yaml new file mode 100644 index 0000000000..cb35d2520d --- /dev/null +++ b/test/transforms/vshn-postgres/enc_pvc/01-GivenNoEncryptionParams.yaml @@ -0,0 +1,54 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: null +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/enc_pvc/01-ThenExpectNoOutput.yaml b/test/transforms/vshn-postgres/enc_pvc/01-ThenExpectNoOutput.yaml new file mode 100644 index 0000000000..bb0d738967 --- /dev/null +++ b/test/transforms/vshn-postgres/enc_pvc/01-ThenExpectNoOutput.yaml @@ -0,0 +1,54 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: null + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: null diff --git a/test/transforms/vshn-postgres/enc_pvc/02-GivenEncryptionParamsFalse.yaml b/test/transforms/vshn-postgres/enc_pvc/02-GivenEncryptionParamsFalse.yaml new file mode 100644 index 0000000000..7307f831bc --- /dev/null +++ b/test/transforms/vshn-postgres/enc_pvc/02-GivenEncryptionParamsFalse.yaml @@ -0,0 +1,56 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + encryption: + enabled: false +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/enc_pvc/02-ThenExpectFalseOutput.yaml b/test/transforms/vshn-postgres/enc_pvc/02-ThenExpectFalseOutput.yaml new file mode 100644 index 0000000000..228b078b0e --- /dev/null +++ b/test/transforms/vshn-postgres/enc_pvc/02-ThenExpectFalseOutput.yaml @@ -0,0 +1,56 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: null + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: pgsql-gc9x4 + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + encryption: + enabled: false diff --git a/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParams.yaml b/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParams.yaml new file mode 100644 index 0000000000..6a81347f1f --- /dev/null +++ b/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParams.yaml @@ -0,0 +1,58 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + encryption: + enabled: true + status: + instanceNamespace: my-psql +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsExistingSecret.yaml b/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsExistingSecret.yaml new file mode 100644 index 0000000000..0b498a3e3f --- /dev/null +++ b/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsExistingSecret.yaml @@ -0,0 +1,90 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + encryption: + enabled: true + status: + instanceNamespace: my-psql + resources: + - name: psql-luks-key + resource: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + metadata: + name: pgsql-gc9x4-luks-key + namespace: test + spec: + forProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: psql-data-psql-0-luks-key + namespace: vshn-postgresql-pgsql-gc9x4 + data: + luksKey: Rm9vMTIzNDU2Nzg5MEJhcjA5ODc2NTQzMjE= + providerConfigRef: + name: kubernetes + status: + atProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: psql-data-psql-0-luks-key + namespace: vshn-postgresql-pgsql-gc9x4 + data: + luksKey: Rm9vMTIzNDU2Nzg5MEJhcjA5ODc2NTQzMjE= + providerConfigRef: + name: kubernetes +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsNoInstanceNamespace.yaml b/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsNoInstanceNamespace.yaml new file mode 100644 index 0000000000..fc5577d8a5 --- /dev/null +++ b/test/transforms/vshn-postgres/enc_pvc/03-GivenEncryptionParamsNoInstanceNamespace.yaml @@ -0,0 +1,56 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + annotations: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: unit-test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + encryption: + enabled: true +desired: + composite: + connectionDetails: null + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + creationTimestamp: "2023-03-21T16:52:31Z" + finalizers: + - composite.apiextensions.crossplane.io + generateName: pgsql- + generation: 13 + labels: + appuio.io/organization: vshn + crossplane.io/claim-name: pgsql + crossplane.io/claim-namespace: unit-test + crossplane.io/composite: psql + name: psql + spec: + parameters: null + writeConnectionSecretToRef: {} + status: {} diff --git a/test/transforms/vshn-postgres/url/01_expected_no-instance-namespace.yaml b/test/transforms/vshn-postgres/url/01_expected_no-instance-namespace.yaml new file mode 100644 index 0000000000..90aed51335 --- /dev/null +++ b/test/transforms/vshn-postgres/url/01_expected_no-instance-namespace.yaml @@ -0,0 +1,74 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection +desired: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection diff --git a/test/transforms/vshn-postgres/url/01_input_no-instance-namespace.yaml b/test/transforms/vshn-postgres/url/01_input_no-instance-namespace.yaml new file mode 100644 index 0000000000..90aed51335 --- /dev/null +++ b/test/transforms/vshn-postgres/url/01_input_no-instance-namespace.yaml @@ -0,0 +1,74 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection +desired: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection diff --git a/test/transforms/vshn-postgres/url/02_input_function-io.yaml b/test/transforms/vshn-postgres/url/02_input_function-io.yaml new file mode 100644 index 0000000000..3fabfd3288 --- /dev/null +++ b/test/transforms/vshn-postgres/url/02_input_function-io.yaml @@ -0,0 +1,441 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: FunctionIO +observed: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection + status: + instanceNamespace: vshn-postgresql-pgsql-gc9x4 + resources: + - name: connection + resource: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + metadata: + name: pgsql-gc9x4-connection + namespace: test + spec: + forProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: pgsql-connection + namespace: vshn-postgresql-pgsql-gc9x4 + data: + POSTGRESQL_PASSWORD: NjM5Yi05MDc2LTRkZTYtYTM1 + stringData: + POSTGRESQL_DB: postgres + POSTGRESQL_HOST: pgsql-gc9x4.vshn-postgresql-pgsql-gc9x4.svc.cluster.local + POSTGRESQL_PORT: "5432" + POSTGRESQL_USER: postgres + providerConfigRef: + name: kubernetes + references: + - patchesFrom: + apiVersion: v1 + fieldPath: data.superuser-password + kind: Secret + name: final-test + namespace: test + toFieldPath: data.POSTGRESQL_PASSWORD + - patchesFrom: + apiVersion: v1 + fieldPath: data[ca.crt] + kind: Secret + name: tls-certificate + namespace: test + toFieldPath: data[ca.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.crt] + kind: Secret + name: tls-certificate + namespace: test + toFieldPath: data[tls.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.key] + kind: Secret + name: tls-certificate + namespace: test + toFieldPath: data[tls.key] + writeConnectionSecretToRef: + name: final-test + namespace: test + status: + atProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: pgsql-connection + namespace: vshn-postgresql-pgsql-gc9x4 + data: + POSTGRESQL_PASSWORD: NjM5Yi05MDc2LTRkZTYtYTM1 + POSTGRESQL_DB: cG9zdGdyZXM= + POSTGRESQL_HOST: cGdzcWwtZ2M5eDQudnNobi1wb3N0Z3Jlc3FsLXBnc3FsLWdjOXg0LnN2Yy5jbHVzdGVyLmxvY2Fs + POSTGRESQL_PORT: NTQzMg== + POSTGRESQL_USER: cG9zdGdyZXM= + connectionDetails: + - fromConnectionSecretKey: ca.crt + name: ca.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.crt + name: tls.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.key + name: tls.key + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_URL + name: POSTGRESQL_URL + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_DB + name: POSTGRESQL_DB + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_HOST + name: POSTGRESQL_HOST + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PORT + name: POSTGRESQL_PORT + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_USER + name: POSTGRESQL_USER + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PASSWORD + name: POSTGRESQL_PASSWORD + type: FromConnectionSecretKey + patches: + - fromFieldPath: status.conditions + toFieldPath: status.secretConditions + type: ToCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.metadata.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.forProvider.manifest.metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - combine: + strategy: string + string: + fmt: '%s.vshn-postgresql-%s.svc.cluster.local' + variables: + - fromFieldPath: metadata.labels[crossplane.io/composite] + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.stringData.POSTGRESQL_HOST + type: CombineFromComposite + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.name + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.writeConnectionSecretToRef.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[1].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[2].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[3].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath +desired: + composite: + resource: + apiVersion: vshn.appcat.vshn.io/v1 + kind: XVSHNPostgreSQL + metadata: + name: pgsql-gc9x4 + spec: + claimRef: + apiVersion: vshn.appcat.vshn.io/v1 + kind: VSHNPostgreSQL + name: pgsql + namespace: test + compositionRef: + name: vshnpostgres.vshn.appcat.vshn.io + compositionRevisionRef: + name: vshnpostgres.vshn.appcat.vshn.io-ce52f13 + compositionUpdatePolicy: Automatic + parameters: + backup: + retention: 6 + schedule: 0 22 * * * + maintenance: + dayOfWeek: tuesday + timeOfDay: "22:30:00" + service: + majorVersion: "15" + size: + cpu: 600m + disk: 5Gi + memory: 3500Mi + plan: standard-2 + resourceRefs: + - apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + name: pgsql-gc9x4-connection + status: + instanceNamespace: vshn-postgresql-pgsql-gc9x4 + resources: + - name: connection + resource: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + metadata: + name: pgsql-gc9x4-connection + namespace: test + spec: + forProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: pgsql-connection + namespace: vshn-postgresql-pgsql-gc9x4 + data: + POSTGRESQL_PASSWORD: NjM5Yi05MDc2LTRkZTYtYTM1 + stringData: + POSTGRESQL_DB: postgres + POSTGRESQL_HOST: pgsql-gc9x4.vshn-postgresql-pgsql-gc9x4.svc.cluster.local + POSTGRESQL_PORT: "5432" + POSTGRESQL_USER: postgres + providerConfigRef: + name: kubernetes + references: + - patchesFrom: + apiVersion: v1 + fieldPath: data.superuser-password + kind: Secret + name: final-test + namespace: test + toFieldPath: data.POSTGRESQL_PASSWORD + - patchesFrom: + apiVersion: v1 + fieldPath: data[ca.crt] + kind: Secret + name: tls-certificate + namespace: test + toFieldPath: data[ca.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.crt] + kind: Secret + name: tls-certificate + namespace: test + toFieldPath: data[tls.crt] + - patchesFrom: + apiVersion: v1 + fieldPath: data[tls.key] + kind: Secret + name: tls-certificate + namespace: test + toFieldPath: data[tls.key] + writeConnectionSecretToRef: + name: final-test + namespace: test + connectionDetails: + - fromConnectionSecretKey: ca.crt + name: ca.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.crt + name: tls.crt + type: FromConnectionSecretKey + - fromConnectionSecretKey: tls.key + name: tls.key + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_URL + name: POSTGRESQL_URL + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_DB + name: POSTGRESQL_DB + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_HOST + name: POSTGRESQL_HOST + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PORT + name: POSTGRESQL_PORT + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_USER + name: POSTGRESQL_USER + type: FromConnectionSecretKey + - fromConnectionSecretKey: POSTGRESQL_PASSWORD + name: POSTGRESQL_PASSWORD + type: FromConnectionSecretKey + patches: + - fromFieldPath: status.conditions + toFieldPath: status.secretConditions + type: ToCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.metadata.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.forProvider.manifest.metadata.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - combine: + strategy: string + string: + fmt: '%s.vshn-postgresql-%s.svc.cluster.local' + variables: + - fromFieldPath: metadata.labels[crossplane.io/composite] + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.forProvider.manifest.stringData.POSTGRESQL_HOST + type: CombineFromComposite + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[0].patchesFrom.name + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.writeConnectionSecretToRef.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/claim-name] + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - string: + fmt: '%s-connection' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[1].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[2].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: metadata.labels[crossplane.io/composite] + toFieldPath: spec.references[3].patchesFrom.namespace + transforms: + - string: + fmt: vshn-postgresql-%s + type: Format + type: string + type: FromCompositeFieldPath +results: + - severity: Normal + message: "Successfully composed VSHNPostgreSQL database" From d02dfc677d7642a8d6c039abca2ad79ebc0827e4 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Thu, 11 May 2023 14:42:50 +0200 Subject: [PATCH 05/26] Port appcat component apis --- .gitignore | 3 +- Makefile | 3 +- apis/exoscale/v1/dbaas_exoscale.go | 50 + apis/exoscale/v1/dbaas_exoscale_kafka.go | 82 + apis/exoscale/v1/dbaas_exoscale_mysql.go | 75 + apis/exoscale/v1/dbaas_exoscale_opensearch.go | 73 + apis/exoscale/v1/dbaas_exoscale_postgresql.go | 75 + apis/exoscale/v1/dbaas_exoscale_redis.go | 63 + apis/exoscale/v1/groupversion_info.go | 5 + apis/exoscale/v1/zz_generated.deepcopy.go | 619 +++ apis/generate.mk | 21 + apis/v1/conditions.go | 48 + apis/v1/groupversion_info.go | 5 + apis/v1/objectreference.go | 13 + apis/v1/objectstorage_types.go | 51 + apis/v1/zz_generated.deepcopy.go | 129 + apis/vshn/v1/dbaas_vshn_postgresql.go | 269 ++ apis/vshn/v1/dbaas_vshn_redis.go | 111 + apis/vshn/v1/groupversion_info.go | 25 + apis/vshn/v1/zz_generated.deepcopy.go | 614 +++ apiserver/vshn/postgres/backup.go | 2 +- apiserver/vshn/postgres/backup_test.go | 2 +- apiserver/vshn/postgres/get_test.go | 2 +- apiserver/vshn/postgres/list_test.go | 2 +- apiserver/vshn/postgres/vshnpostgresql.go | 2 +- .../vshn/postgres/vshnpostgresql_test.go | 2 +- command/postgresql_controller.go | 2 +- command/xpostgresql_controller.go | 2 +- .../functions/vshn-postgres-func/alerting.go | 2 +- .../vshn-postgres-func/alerting_test.go | 2 +- .../vshn-postgres-func/encrypted_pvc.go | 2 +- .../vshn-postgres-func/encrypted_pvc_test.go | 2 +- .../functions/vshn-postgres-func/schedule.go | 2 +- .../vshn-postgres-func/schedule_test.go | 2 +- .../functions/vshn-postgres-func/url.go | 2 +- comp-functions/runtime/runtime.go | 2 +- controller/postgres/reconciler.go | 2 +- controller/postgres/reconciler_test.go | 5 +- .../sli-exporter/vshnpostgresql_controller.go | 2 +- .../vshnpostgresql_controller_test.go | 6 +- crds/appcat.vshn.io_objectbuckets.yaml | 172 + ...xoscale.appcat.vshn.io_exoscalekafkas.yaml | 176 + ...xoscale.appcat.vshn.io_exoscalemysqls.yaml | 180 + ...e.appcat.vshn.io_exoscaleopensearches.yaml | 181 + ...le.appcat.vshn.io_exoscalepostgresqls.yaml | 180 + ...exoscale.appcat.vshn.io_exoscaleredis.yaml | 164 + crds/vshn.appcat.vshn.io_vshnpostgresqls.yaml | 4008 +++++++++++++++++ crds/vshn.appcat.vshn.io_vshnredis.yaml | 332 ++ go.mod | 1 - go.sum | 4 +- test/mocks/mock_vshnpostgresqls.go | 6 +- 51 files changed, 7752 insertions(+), 33 deletions(-) create mode 100644 apis/exoscale/v1/dbaas_exoscale.go create mode 100644 apis/exoscale/v1/dbaas_exoscale_kafka.go create mode 100644 apis/exoscale/v1/dbaas_exoscale_mysql.go create mode 100644 apis/exoscale/v1/dbaas_exoscale_opensearch.go create mode 100644 apis/exoscale/v1/dbaas_exoscale_postgresql.go create mode 100644 apis/exoscale/v1/dbaas_exoscale_redis.go create mode 100644 apis/exoscale/v1/groupversion_info.go create mode 100644 apis/exoscale/v1/zz_generated.deepcopy.go create mode 100644 apis/generate.mk create mode 100644 apis/v1/conditions.go create mode 100644 apis/v1/groupversion_info.go create mode 100644 apis/v1/objectreference.go create mode 100644 apis/v1/objectstorage_types.go create mode 100644 apis/v1/zz_generated.deepcopy.go create mode 100644 apis/vshn/v1/dbaas_vshn_postgresql.go create mode 100644 apis/vshn/v1/dbaas_vshn_redis.go create mode 100644 apis/vshn/v1/groupversion_info.go create mode 100644 apis/vshn/v1/zz_generated.deepcopy.go create mode 100644 crds/appcat.vshn.io_objectbuckets.yaml create mode 100644 crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml create mode 100644 crds/exoscale.appcat.vshn.io_exoscalemysqls.yaml create mode 100644 crds/exoscale.appcat.vshn.io_exoscaleopensearches.yaml create mode 100644 crds/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml create mode 100644 crds/exoscale.appcat.vshn.io_exoscaleredis.yaml create mode 100644 crds/vshn.appcat.vshn.io_vshnpostgresqls.yaml create mode 100644 crds/vshn.appcat.vshn.io_vshnredis.yaml diff --git a/.gitignore b/.gitignore index f3f073e501..52e547f1cc 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ appcat-apiserver # debug apiserver.local.config - +# Kubebuilder +/apis/generated/ diff --git a/Makefile b/Makefile index a0b7f544f0..52591fe1a7 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,7 @@ $(protoc_bin): | $(go_bin) @rm $(go_bin)/protoc.zip -include docs/antora-preview.mk docs/antora-build.mk +-include apis/generate.mk .PHONY: help help: ## Display this help. @@ -108,4 +109,4 @@ docker-push: docker-build ## Push docker image with the manager. .PHONY: clean clean: - rm -rf bin/ appcat-apiserver .work/ docs/node_modules $docs_out_dir .public .cache apiserver.local.config + rm -rf bin/ appcat-apiserver .work/ docs/node_modules $docs_out_dir .public .cache apiserver.local.config apis/generated diff --git a/apis/exoscale/v1/dbaas_exoscale.go b/apis/exoscale/v1/dbaas_exoscale.go new file mode 100644 index 0000000000..b270b55767 --- /dev/null +++ b/apis/exoscale/v1/dbaas_exoscale.go @@ -0,0 +1,50 @@ +package v1 + +type ExoscaleDBaaSServiceSpec struct { + // +kubebuilder:validation:Enum=ch-gva-2;ch-dk-2;de-fra-1;de-muc-1;at-vie-1;bg-sof-1 + // +kubebuilder:default="ch-gva-2" + + // Zone is the datacenter identifier in which the instance runs in. + Zone string `json:"zone,omitempty"` +} + +type ExoscaleDBaaSMaintenanceScheduleSpec struct { + // +kubebuilder:validation:Enum=monday;tuesday;wednesday;thursday;friday;saturday;sunday;never + // +kubebuilder:default="tuesday" + + // DayOfWeek specifies at which weekday the maintenance is held place. + // Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday, never] + DayOfWeek string `json:"dayOfWeek,omitempty"` + + // +kubebuilder:validation:Pattern="^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$" + // +kubebuilder:default="22:30:00" + + // TimeOfDay for installing updates in UTC. + // Format: "hh:mm:ss". + TimeOfDay string `json:"timeOfDay,omitempty"` +} + +type ExoscaleDBaaSSizeSpec struct { + // +kubebuilder:default="startup-4" + + // Plan is the name of the resource plan that defines the compute resources. + Plan string `json:"plan,omitempty"` +} + +type ExoscaleDBaaSNetworkSpec struct { + // +kubebuilder:default={"0.0.0.0/0"} + + // IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. + // If no IP Filter is set, you may not be able to reach the service. + // A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + IPFilter []string `json:"ipFilter,omitempty"` +} + +type ExoscaleDBaaSBackupSpec struct { + // +kubebuilder:validation:Pattern="^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$" + // +kubebuilder:default="21:30:00" + + // TimeOfDay for doing daily backups, in UTC. + // Format: "hh:mm:ss". + TimeOfDay string `json:"timeOfDay,omitempty"` +} diff --git a/apis/exoscale/v1/dbaas_exoscale_kafka.go b/apis/exoscale/v1/dbaas_exoscale_kafka.go new file mode 100644 index 0000000000..618c61c6c5 --- /dev/null +++ b/apis/exoscale/v1/dbaas_exoscale_kafka.go @@ -0,0 +1,82 @@ +package v1 + +import ( + "github.com/vshn/appcat-apiserver/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalekafkas.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalekafkas.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.maintenance.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalekafkas.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalekafkas.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalekafkas.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.network.default={})" + +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Plan",type="string",JSONPath=".spec.parameters.size.plan" +// +kubebuilder:printcolumn:name="Zone",type="string",JSONPath=".spec.parameters.service.zone" +// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.version" + +// ExoscaleKafka is the API for creating Kafka instances on Exoscale. +type ExoscaleKafka struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a ExoscaleKafka. + Spec ExoscaleKafkaSpec `json:"spec,omitempty"` + // Status reflects the observed state of a ExoscaleKafka. + Status ExoscaleKafkaStatus `json:"status,omitempty"` +} + +type ExoscaleKafkaSpec struct { + // Parameters are the configurable fields of a ExoscaleKafka. + Parameters ExoscaleKafkaParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +type ExoscaleKafkaParameters struct { + + // Service contains Exoscale Kafka DBaaS specific properties + Service ExoscaleKafkaServiceSpec `json:"service,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance ExoscaleDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` + + // Size contains settings to control the sizing of a service. + Size ExoscaleKafkaDBaaSSizeSpec `json:"size,omitempty"` + + // Network contains any network related settings. + Network ExoscaleDBaaSNetworkSpec `json:"network,omitempty"` +} + +type ExoscaleKafkaDBaaSSizeSpec struct { + // +kubebuilder:default="startup-2" + + // Plan is the name of the resource plan that defines the compute resources. + Plan string `json:"plan,omitempty"` +} + +type ExoscaleKafkaServiceSpec struct { + ExoscaleDBaaSServiceSpec `json:",inline"` + // KafkaSettings contains additional Kafka settings. + KafkaSettings runtime.RawExtension `json:"kafkaSettings,omitempty"` + + // +kubebuilder:validation:Enum="3.2" + // +kubebuilder:default="3.2" + + // Version contains the minor version for Kafka. + // Currently only "3.2" is supported. Leave it empty to always get the latest supported version. + Version string `json:"version,omitempty"` +} + +type ExoscaleKafkaStatus struct { + // KafkaConditions contains the status conditions of the backing object. + KafkaConditions []v1.Condition `json:"kafkaConditions,omitempty"` + + // The actual observed Kafka version. + Version string `json:"version,omitempty"` +} diff --git a/apis/exoscale/v1/dbaas_exoscale_mysql.go b/apis/exoscale/v1/dbaas_exoscale_mysql.go new file mode 100644 index 0000000000..ce615ee76e --- /dev/null +++ b/apis/exoscale/v1/dbaas_exoscale_mysql.go @@ -0,0 +1,75 @@ +package v1 + +import ( + "github.com/vshn/appcat-apiserver/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalemysqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalemysqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.maintenance.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalemysqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalemysqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalemysqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalemysqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.network.default={})" + +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Plan",type="string",JSONPath=".spec.parameters.size.plan" +// +kubebuilder:printcolumn:name="Zone",type="string",JSONPath=".spec.parameters.service.zone" + +// ExoscaleMySQL is the API for creating MySQL on Exoscale. +type ExoscaleMySQL struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a ExoscaleMySQL. + Spec ExoscaleMySQLSpec `json:"spec,omitempty"` + // Status reflects the observed state of a ExoscaleMySQL. + Status ExoscaleMySQLStatus `json:"status,omitempty"` +} + +type ExoscaleMySQLSpec struct { + // Parameters are the configurable fields of a ExoscaleMySQL. + Parameters ExoscaleMySQLParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +type ExoscaleMySQLParameters struct { + // Service contains Exoscale MySQL DBaaS specific properties + Service ExoscaleMySQLServiceSpec `json:"service,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance ExoscaleDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` + + // Size contains settings to control the sizing of a service. + Size ExoscaleDBaaSSizeSpec `json:"size,omitempty"` + + // Network contains any network related settings. + Network ExoscaleDBaaSNetworkSpec `json:"network,omitempty"` + + // Backup contains settings to control the backups of an instance. + Backup ExoscaleDBaaSBackupSpec `json:"backup,omitempty"` +} + +type ExoscaleMySQLServiceSpec struct { + ExoscaleDBaaSServiceSpec `json:",inline"` + + // +kubebuilder:validation:Enum="8" + // +kubebuilder:default="8" + + // MajorVersion contains the major version for MySQL. + // Currently only "8" is supported. Leave it empty to always get the latest supported version. + MajorVersion string `json:"majorVersion,omitempty"` + + // MySQLSettings contains additional MySQL settings. + MySQLSettings runtime.RawExtension `json:"mysqlSettings,omitempty"` +} + +type ExoscaleMySQLStatus struct { + // MySQLConditions contains the status conditions of the backing object. + MySQLConditions []v1.Condition `json:"mysqlConditions,omitempty"` +} diff --git a/apis/exoscale/v1/dbaas_exoscale_opensearch.go b/apis/exoscale/v1/dbaas_exoscale_opensearch.go new file mode 100644 index 0000000000..5298a6cfe0 --- /dev/null +++ b/apis/exoscale/v1/dbaas_exoscale_opensearch.go @@ -0,0 +1,73 @@ +package v1 + +import ( + v1 "github.com/vshn/appcat-apiserver/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleopensearches.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleopensearches.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.maintenance.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleopensearches.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleopensearches.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleopensearches.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleopensearches.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.network.default={})" + +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Plan",type="string",JSONPath=".spec.parameters.size.plan" +// +kubebuilder:printcolumn:name="Zone",type="string",JSONPath=".spec.parameters.service.zone" + +// ExoscaleOpenSearch is the api for creating OpenSearch on Exoscale +type ExoscaleOpenSearch struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + //Spec defines the desired state of an ExoscaleOpenSearch + Spec ExoscaleOpenSearchSpec `json:"spec,omitempty"` + // Status reflects the observed state of a ExoscaleOpenSearch + Status ExoscaleOpenSearchStatus `json:"status,omitempty"` +} + +type ExoscaleOpenSearchServiceSpec struct { + ExoscaleDBaaSServiceSpec `json:",inline"` + + // +kubebuilder:validation:Enum="1";"2"; + // +kubebuilder:default="2" + // MajorVersion contains the version for OpenSearch. + // Currently only "2" and "1" is supported. Leave it empty to always get the latest supported version. + MajorVersion string `json:"majorVersion,omitempty"` + + // OpenSearchSettings contains additional OpenSearch settings. + OpenSearchSettings runtime.RawExtension `json:"opensearchSettings,omitempty"` +} + +type ExoscaleOpenSearchParameters struct { + // Service contains Exoscale OpenSearch DBaaS specific properties + Service ExoscaleOpenSearchServiceSpec `json:"service,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance ExoscaleDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` + + // Size contains settings to control the sizing of a service. + Size ExoscaleDBaaSSizeSpec `json:"size,omitempty"` + + // Network contains any network related settings. + Network ExoscaleDBaaSNetworkSpec `json:"network,omitempty"` + + // Backup contains settings to control the backups of an instance. + Backup ExoscaleDBaaSBackupSpec `json:"backup,omitempty"` +} + +type ExoscaleOpenSearchSpec struct { + // Parameters are the configurable fields of a ExoscaleOpenSearch. + Parameters ExoscaleOpenSearchParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} +type ExoscaleOpenSearchStatus struct { + // OpenSearchConditions contains the status conditions of the backing object. + OpenSearchConditions []v1.Condition `json:"opensearchConditions,omitempty"` +} diff --git a/apis/exoscale/v1/dbaas_exoscale_postgresql.go b/apis/exoscale/v1/dbaas_exoscale_postgresql.go new file mode 100644 index 0000000000..d520426665 --- /dev/null +++ b/apis/exoscale/v1/dbaas_exoscale_postgresql.go @@ -0,0 +1,75 @@ +package v1 + +import ( + v1 "github.com/vshn/appcat-apiserver/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.maintenance.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.network.default={})" + +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Plan",type="string",JSONPath=".spec.parameters.size.plan" +// +kubebuilder:printcolumn:name="Zone",type="string",JSONPath=".spec.parameters.service.zone" + +// ExoscalePostgreSQL is the API for creating PostgreSQL on Exoscale. +type ExoscalePostgreSQL struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a ExoscalePostgreSQL. + Spec ExoscalePostgreSQLSpec `json:"spec,omitempty"` + // Status reflects the observed state of a ExoscalePostgreSQL. + Status ExoscalePostgreSQLStatus `json:"status,omitempty"` +} + +type ExoscalePostgreSQLSpec struct { + // Parameters are the configurable fields of a ExoscalePostgreSQL. + Parameters ExoscalePostgreSQLParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +type ExoscalePostgreSQLParameters struct { + // Service contains Exoscale PostgreSQL DBaaS specific properties + Service ExoscalePostgreSQLServiceSpec `json:"service,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance ExoscaleDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` + + // Size contains settings to control the sizing of a service. + Size ExoscaleDBaaSSizeSpec `json:"size,omitempty"` + + // Network contains any network related settings. + Network ExoscaleDBaaSNetworkSpec `json:"network,omitempty"` + + // Backup contains settings to control the backups of an instance. + Backup ExoscaleDBaaSBackupSpec `json:"backup,omitempty"` +} + +type ExoscalePostgreSQLServiceSpec struct { + ExoscaleDBaaSServiceSpec `json:",inline"` + + // +kubebuilder:validation:Enum="14" + // +kubebuilder:default="14" + + // MajorVersion contains the major version for PostgreSQL. + // Currently only "14" is supported. Leave it empty to always get the latest supported version. + MajorVersion string `json:"majorVersion,omitempty"` + + // PGSettings contains additional PostgreSQL settings. + PostgreSQLSettings runtime.RawExtension `json:"pgSettings,omitempty"` +} + +type ExoscalePostgreSQLStatus struct { + // PostgreSQLConditions contains the status conditions of the backing object. + PostgreSQLConditions []v1.Condition `json:"postgresqlConditions,omitempty"` +} diff --git a/apis/exoscale/v1/dbaas_exoscale_redis.go b/apis/exoscale/v1/dbaas_exoscale_redis.go new file mode 100644 index 0000000000..2d77854f88 --- /dev/null +++ b/apis/exoscale/v1/dbaas_exoscale_redis.go @@ -0,0 +1,63 @@ +package v1 + +import ( + v1 "github.com/vshn/appcat-apiserver/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.maintenance.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/exoscale.appcat.vshn.io_exoscaleredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.network.default={})" + +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Plan",type="string",JSONPath=".spec.parameters.size.plan" +// +kubebuilder:printcolumn:name="Zone",type="string",JSONPath=".spec.parameters.service.zone" + +// ExoscaleRedis is the API for creating Redis instances on Exoscale. +type ExoscaleRedis struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a ExoscaleRedis. + Spec ExoscaleRedisSpec `json:"spec,omitempty"` + // Status reflects the observed state of a ExoscaleRedis. + Status ExoscaleRedisStatus `json:"status,omitempty"` +} + +type ExoscaleRedisSpec struct { + // Parameters are the configurable fields of a ExoscaleRedis. + Parameters ExoscaleRedisParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +type ExoscaleRedisParameters struct { + // Service contains Exoscale Redis DBaaS specific properties + Service ExoscaleRedisServiceSpec `json:"service,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance ExoscaleDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` + + // Size contains settings to control the sizing of a service. + Size ExoscaleDBaaSSizeSpec `json:"size,omitempty"` + + // Network contains any network related settings. + Network ExoscaleDBaaSNetworkSpec `json:"network,omitempty"` +} + +type ExoscaleRedisServiceSpec struct { + ExoscaleDBaaSServiceSpec `json:",inline"` + // RedisSettings contains additional Redis settings. + RedisSettings runtime.RawExtension `json:"redisSettings,omitempty"` +} + +type ExoscaleRedisStatus struct { + // RedisConditions contains the status conditions of the backing object. + RedisConditions []v1.Condition `json:"redisConditions,omitempty"` +} diff --git a/apis/exoscale/v1/groupversion_info.go b/apis/exoscale/v1/groupversion_info.go new file mode 100644 index 0000000000..e87b1a0f68 --- /dev/null +++ b/apis/exoscale/v1/groupversion_info.go @@ -0,0 +1,5 @@ +// +kubebuilder:object:generate=true +// +groupName=exoscale.appcat.vshn.io +// +versionName=v1 + +package v1 diff --git a/apis/exoscale/v1/zz_generated.deepcopy.go b/apis/exoscale/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..096a4ae69f --- /dev/null +++ b/apis/exoscale/v1/zz_generated.deepcopy.go @@ -0,0 +1,619 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + apisv1 "github.com/vshn/appcat-apiserver/apis/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleDBaaSBackupSpec) DeepCopyInto(out *ExoscaleDBaaSBackupSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleDBaaSBackupSpec. +func (in *ExoscaleDBaaSBackupSpec) DeepCopy() *ExoscaleDBaaSBackupSpec { + if in == nil { + return nil + } + out := new(ExoscaleDBaaSBackupSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleDBaaSMaintenanceScheduleSpec) DeepCopyInto(out *ExoscaleDBaaSMaintenanceScheduleSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleDBaaSMaintenanceScheduleSpec. +func (in *ExoscaleDBaaSMaintenanceScheduleSpec) DeepCopy() *ExoscaleDBaaSMaintenanceScheduleSpec { + if in == nil { + return nil + } + out := new(ExoscaleDBaaSMaintenanceScheduleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleDBaaSNetworkSpec) DeepCopyInto(out *ExoscaleDBaaSNetworkSpec) { + *out = *in + if in.IPFilter != nil { + in, out := &in.IPFilter, &out.IPFilter + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleDBaaSNetworkSpec. +func (in *ExoscaleDBaaSNetworkSpec) DeepCopy() *ExoscaleDBaaSNetworkSpec { + if in == nil { + return nil + } + out := new(ExoscaleDBaaSNetworkSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleDBaaSServiceSpec) DeepCopyInto(out *ExoscaleDBaaSServiceSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleDBaaSServiceSpec. +func (in *ExoscaleDBaaSServiceSpec) DeepCopy() *ExoscaleDBaaSServiceSpec { + if in == nil { + return nil + } + out := new(ExoscaleDBaaSServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleDBaaSSizeSpec) DeepCopyInto(out *ExoscaleDBaaSSizeSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleDBaaSSizeSpec. +func (in *ExoscaleDBaaSSizeSpec) DeepCopy() *ExoscaleDBaaSSizeSpec { + if in == nil { + return nil + } + out := new(ExoscaleDBaaSSizeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleKafka) DeepCopyInto(out *ExoscaleKafka) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleKafka. +func (in *ExoscaleKafka) DeepCopy() *ExoscaleKafka { + if in == nil { + return nil + } + out := new(ExoscaleKafka) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExoscaleKafka) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleKafkaDBaaSSizeSpec) DeepCopyInto(out *ExoscaleKafkaDBaaSSizeSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleKafkaDBaaSSizeSpec. +func (in *ExoscaleKafkaDBaaSSizeSpec) DeepCopy() *ExoscaleKafkaDBaaSSizeSpec { + if in == nil { + return nil + } + out := new(ExoscaleKafkaDBaaSSizeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleKafkaParameters) DeepCopyInto(out *ExoscaleKafkaParameters) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + out.Maintenance = in.Maintenance + out.Size = in.Size + in.Network.DeepCopyInto(&out.Network) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleKafkaParameters. +func (in *ExoscaleKafkaParameters) DeepCopy() *ExoscaleKafkaParameters { + if in == nil { + return nil + } + out := new(ExoscaleKafkaParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleKafkaServiceSpec) DeepCopyInto(out *ExoscaleKafkaServiceSpec) { + *out = *in + out.ExoscaleDBaaSServiceSpec = in.ExoscaleDBaaSServiceSpec + in.KafkaSettings.DeepCopyInto(&out.KafkaSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleKafkaServiceSpec. +func (in *ExoscaleKafkaServiceSpec) DeepCopy() *ExoscaleKafkaServiceSpec { + if in == nil { + return nil + } + out := new(ExoscaleKafkaServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleKafkaSpec) DeepCopyInto(out *ExoscaleKafkaSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleKafkaSpec. +func (in *ExoscaleKafkaSpec) DeepCopy() *ExoscaleKafkaSpec { + if in == nil { + return nil + } + out := new(ExoscaleKafkaSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleKafkaStatus) DeepCopyInto(out *ExoscaleKafkaStatus) { + *out = *in + if in.KafkaConditions != nil { + in, out := &in.KafkaConditions, &out.KafkaConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleKafkaStatus. +func (in *ExoscaleKafkaStatus) DeepCopy() *ExoscaleKafkaStatus { + if in == nil { + return nil + } + out := new(ExoscaleKafkaStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleMySQL) DeepCopyInto(out *ExoscaleMySQL) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleMySQL. +func (in *ExoscaleMySQL) DeepCopy() *ExoscaleMySQL { + if in == nil { + return nil + } + out := new(ExoscaleMySQL) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExoscaleMySQL) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleMySQLParameters) DeepCopyInto(out *ExoscaleMySQLParameters) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + out.Maintenance = in.Maintenance + out.Size = in.Size + in.Network.DeepCopyInto(&out.Network) + out.Backup = in.Backup +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleMySQLParameters. +func (in *ExoscaleMySQLParameters) DeepCopy() *ExoscaleMySQLParameters { + if in == nil { + return nil + } + out := new(ExoscaleMySQLParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleMySQLServiceSpec) DeepCopyInto(out *ExoscaleMySQLServiceSpec) { + *out = *in + out.ExoscaleDBaaSServiceSpec = in.ExoscaleDBaaSServiceSpec + in.MySQLSettings.DeepCopyInto(&out.MySQLSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleMySQLServiceSpec. +func (in *ExoscaleMySQLServiceSpec) DeepCopy() *ExoscaleMySQLServiceSpec { + if in == nil { + return nil + } + out := new(ExoscaleMySQLServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleMySQLSpec) DeepCopyInto(out *ExoscaleMySQLSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleMySQLSpec. +func (in *ExoscaleMySQLSpec) DeepCopy() *ExoscaleMySQLSpec { + if in == nil { + return nil + } + out := new(ExoscaleMySQLSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleMySQLStatus) DeepCopyInto(out *ExoscaleMySQLStatus) { + *out = *in + if in.MySQLConditions != nil { + in, out := &in.MySQLConditions, &out.MySQLConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleMySQLStatus. +func (in *ExoscaleMySQLStatus) DeepCopy() *ExoscaleMySQLStatus { + if in == nil { + return nil + } + out := new(ExoscaleMySQLStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleOpenSearch) DeepCopyInto(out *ExoscaleOpenSearch) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleOpenSearch. +func (in *ExoscaleOpenSearch) DeepCopy() *ExoscaleOpenSearch { + if in == nil { + return nil + } + out := new(ExoscaleOpenSearch) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExoscaleOpenSearch) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleOpenSearchParameters) DeepCopyInto(out *ExoscaleOpenSearchParameters) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + out.Maintenance = in.Maintenance + out.Size = in.Size + in.Network.DeepCopyInto(&out.Network) + out.Backup = in.Backup +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleOpenSearchParameters. +func (in *ExoscaleOpenSearchParameters) DeepCopy() *ExoscaleOpenSearchParameters { + if in == nil { + return nil + } + out := new(ExoscaleOpenSearchParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleOpenSearchServiceSpec) DeepCopyInto(out *ExoscaleOpenSearchServiceSpec) { + *out = *in + out.ExoscaleDBaaSServiceSpec = in.ExoscaleDBaaSServiceSpec + in.OpenSearchSettings.DeepCopyInto(&out.OpenSearchSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleOpenSearchServiceSpec. +func (in *ExoscaleOpenSearchServiceSpec) DeepCopy() *ExoscaleOpenSearchServiceSpec { + if in == nil { + return nil + } + out := new(ExoscaleOpenSearchServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleOpenSearchSpec) DeepCopyInto(out *ExoscaleOpenSearchSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleOpenSearchSpec. +func (in *ExoscaleOpenSearchSpec) DeepCopy() *ExoscaleOpenSearchSpec { + if in == nil { + return nil + } + out := new(ExoscaleOpenSearchSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleOpenSearchStatus) DeepCopyInto(out *ExoscaleOpenSearchStatus) { + *out = *in + if in.OpenSearchConditions != nil { + in, out := &in.OpenSearchConditions, &out.OpenSearchConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleOpenSearchStatus. +func (in *ExoscaleOpenSearchStatus) DeepCopy() *ExoscaleOpenSearchStatus { + if in == nil { + return nil + } + out := new(ExoscaleOpenSearchStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscalePostgreSQL) DeepCopyInto(out *ExoscalePostgreSQL) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscalePostgreSQL. +func (in *ExoscalePostgreSQL) DeepCopy() *ExoscalePostgreSQL { + if in == nil { + return nil + } + out := new(ExoscalePostgreSQL) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExoscalePostgreSQL) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscalePostgreSQLParameters) DeepCopyInto(out *ExoscalePostgreSQLParameters) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + out.Maintenance = in.Maintenance + out.Size = in.Size + in.Network.DeepCopyInto(&out.Network) + out.Backup = in.Backup +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscalePostgreSQLParameters. +func (in *ExoscalePostgreSQLParameters) DeepCopy() *ExoscalePostgreSQLParameters { + if in == nil { + return nil + } + out := new(ExoscalePostgreSQLParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscalePostgreSQLServiceSpec) DeepCopyInto(out *ExoscalePostgreSQLServiceSpec) { + *out = *in + out.ExoscaleDBaaSServiceSpec = in.ExoscaleDBaaSServiceSpec + in.PostgreSQLSettings.DeepCopyInto(&out.PostgreSQLSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscalePostgreSQLServiceSpec. +func (in *ExoscalePostgreSQLServiceSpec) DeepCopy() *ExoscalePostgreSQLServiceSpec { + if in == nil { + return nil + } + out := new(ExoscalePostgreSQLServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscalePostgreSQLSpec) DeepCopyInto(out *ExoscalePostgreSQLSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscalePostgreSQLSpec. +func (in *ExoscalePostgreSQLSpec) DeepCopy() *ExoscalePostgreSQLSpec { + if in == nil { + return nil + } + out := new(ExoscalePostgreSQLSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscalePostgreSQLStatus) DeepCopyInto(out *ExoscalePostgreSQLStatus) { + *out = *in + if in.PostgreSQLConditions != nil { + in, out := &in.PostgreSQLConditions, &out.PostgreSQLConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscalePostgreSQLStatus. +func (in *ExoscalePostgreSQLStatus) DeepCopy() *ExoscalePostgreSQLStatus { + if in == nil { + return nil + } + out := new(ExoscalePostgreSQLStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleRedis) DeepCopyInto(out *ExoscaleRedis) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleRedis. +func (in *ExoscaleRedis) DeepCopy() *ExoscaleRedis { + if in == nil { + return nil + } + out := new(ExoscaleRedis) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExoscaleRedis) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleRedisParameters) DeepCopyInto(out *ExoscaleRedisParameters) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + out.Maintenance = in.Maintenance + out.Size = in.Size + in.Network.DeepCopyInto(&out.Network) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleRedisParameters. +func (in *ExoscaleRedisParameters) DeepCopy() *ExoscaleRedisParameters { + if in == nil { + return nil + } + out := new(ExoscaleRedisParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleRedisServiceSpec) DeepCopyInto(out *ExoscaleRedisServiceSpec) { + *out = *in + out.ExoscaleDBaaSServiceSpec = in.ExoscaleDBaaSServiceSpec + in.RedisSettings.DeepCopyInto(&out.RedisSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleRedisServiceSpec. +func (in *ExoscaleRedisServiceSpec) DeepCopy() *ExoscaleRedisServiceSpec { + if in == nil { + return nil + } + out := new(ExoscaleRedisServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleRedisSpec) DeepCopyInto(out *ExoscaleRedisSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleRedisSpec. +func (in *ExoscaleRedisSpec) DeepCopy() *ExoscaleRedisSpec { + if in == nil { + return nil + } + out := new(ExoscaleRedisSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExoscaleRedisStatus) DeepCopyInto(out *ExoscaleRedisStatus) { + *out = *in + if in.RedisConditions != nil { + in, out := &in.RedisConditions, &out.RedisConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExoscaleRedisStatus. +func (in *ExoscaleRedisStatus) DeepCopy() *ExoscaleRedisStatus { + if in == nil { + return nil + } + out := new(ExoscaleRedisStatus) + in.DeepCopyInto(out) + return out +} diff --git a/apis/generate.mk b/apis/generate.mk new file mode 100644 index 0000000000..0749f2287d --- /dev/null +++ b/apis/generate.mk @@ -0,0 +1,21 @@ +clean_targets += .clean-apis +OS := $(shell uname) +ifeq ($(OS), Darwin) + sed ?= gsed +else + sed ?= sed +endif + +.PHONY: generate-xrd +generate-crd: ## Generates the CRDs using Kubebuilder, these CRDs will be used as a base for the XRDs by the component + @rm -rf apis/generated + @cd apis && go run sigs.k8s.io/controller-tools/cmd/controller-gen paths=./... crd:crdVersions=v1 output:artifacts:config=./generated + @cd apis && go run sigs.k8s.io/controller-tools/cmd/controller-gen object paths=./... + @cd apis && go generate ./... + @# Because yaml is such a fun and easy specification, we need to hack some things here. + @# Depending on the yaml parser implementation the equal sign (=) has special meaning, or not... + @# So we make it explicitly a string. + @$(sed) -i ':a;N;$$!ba;s/- =\n/- "="\n/g' apis/generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml + @rm -rf crds && cp -r apis/generated crds +.clean-apis: + rm -rf apis/generated diff --git a/apis/v1/conditions.go b/apis/v1/conditions.go new file mode 100644 index 0000000000..9e913a749b --- /dev/null +++ b/apis/v1/conditions.go @@ -0,0 +1,48 @@ +package v1 + +import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +// The reason we need a custom condition type is that metav1.Condition declares all fields as required. +// However, we have seen issues where Crossplane's properties in Conditions aren't all required and lead to Crossplane not being able to copy conditions. + +type Condition struct { + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Pattern=`^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$` + // +kubebuilder:validation:MaxLength=316 + + // Type of condition. + Type string `json:"type,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Enum=True;False;Unknown + + // Status of the condition, one of True, False, Unknown. + Status metav1.ConditionStatus `json:"status,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Minimum=0 + + // ObservedGeneration represents the .metadata.generation that the condition was set based upon. + // For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:Format=date-time + + // LastTransitionTime is the last time the condition transitioned from one status to another. + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:validation:MaxLength=1024 + // +kubebuilder:validation:Pattern=`^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$` + + // Reason contains a programmatic identifier indicating the reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:validation:MaxLength=32768 + + // Message is a human-readable message indicating details about the transition. + Message string `json:"message,omitempty"` +} diff --git a/apis/v1/groupversion_info.go b/apis/v1/groupversion_info.go new file mode 100644 index 0000000000..e55312a66c --- /dev/null +++ b/apis/v1/groupversion_info.go @@ -0,0 +1,5 @@ +// +kubebuilder:object:generate=true +// +groupName=appcat.vshn.io +// +versionName=v1 + +package v1 diff --git a/apis/v1/objectreference.go b/apis/v1/objectreference.go new file mode 100644 index 0000000000..939097f0f1 --- /dev/null +++ b/apis/v1/objectreference.go @@ -0,0 +1,13 @@ +package v1 + +// We use a custom LocalObjectReference as the description of corev1.LocalObjectReference contains a todo + +// LocalObjectReference contains enough information to let you locate the +// referenced object inside the same namespace. +// +structType=atomic +type LocalObjectReference struct { + // Name of the referent. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` + Namespace string `json:"namespace,omitempty" protobuf:"bytes,2,opt,name=namespace"` +} diff --git a/apis/v1/objectstorage_types.go b/apis/v1/objectstorage_types.go new file mode 100644 index 0000000000..bb28365d5b --- /dev/null +++ b/apis/v1/objectstorage_types.go @@ -0,0 +1,51 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +kubebuilder:object:root=true +// +kubebuilder:printcolumn:name="Bucket Name",type="string",JSONPath=".spec.parameters.bucketName" +// +kubebuilder:printcolumn:name="Region",type="string",JSONPath=".spec.parameters.region" + +// ObjectBucket is the API for creating S3 buckets. +type ObjectBucket struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ObjectBucketSpec `json:"spec"` + Status ObjectBucketStatus `json:"status,omitempty"` +} + +// ObjectBucketSpec defines the desired state of a ObjectBucket. +type ObjectBucketSpec struct { + Parameters ObjectBucketParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +// ObjectBucketParameters are the configurable fields of a ObjectBucket. +type ObjectBucketParameters struct { + // +kubebuilder:validation:Required + + // BucketName is the name of the bucket to create. + // Cannot be changed after bucket is created. + // Name must be acceptable by the S3 protocol, which follows RFC 1123. + // Be aware that S3 providers may require a unique name across the platform or region. + BucketName string `json:"bucketName"` + + // +kubebuilder:validation:Required + + // Region is the name of the region where the bucket shall be created. + // The region must be available in the S3 endpoint. + Region string `json:"region"` +} + +// ObjectBucketStatus reflects the observed state of a ObjectBucket. +type ObjectBucketStatus struct { + // AccessUserConditions contains a copy of the claim's underlying user account conditions. + AccessUserConditions []Condition `json:"accessUserConditions,omitempty"` + // BucketConditions contains a copy of the claim's underlying bucket conditions. + BucketConditions []Condition `json:"bucketConditions,omitempty"` +} diff --git a/apis/v1/zz_generated.deepcopy.go b/apis/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..bd691d9b6b --- /dev/null +++ b/apis/v1/zz_generated.deepcopy.go @@ -0,0 +1,129 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalObjectReference) DeepCopyInto(out *LocalObjectReference) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalObjectReference. +func (in *LocalObjectReference) DeepCopy() *LocalObjectReference { + if in == nil { + return nil + } + out := new(LocalObjectReference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucket) DeepCopyInto(out *ObjectBucket) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucket. +func (in *ObjectBucket) DeepCopy() *ObjectBucket { + if in == nil { + return nil + } + out := new(ObjectBucket) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ObjectBucket) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketParameters) DeepCopyInto(out *ObjectBucketParameters) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketParameters. +func (in *ObjectBucketParameters) DeepCopy() *ObjectBucketParameters { + if in == nil { + return nil + } + out := new(ObjectBucketParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketSpec) DeepCopyInto(out *ObjectBucketSpec) { + *out = *in + out.Parameters = in.Parameters + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketSpec. +func (in *ObjectBucketSpec) DeepCopy() *ObjectBucketSpec { + if in == nil { + return nil + } + out := new(ObjectBucketSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectBucketStatus) DeepCopyInto(out *ObjectBucketStatus) { + *out = *in + if in.AccessUserConditions != nil { + in, out := &in.AccessUserConditions, &out.AccessUserConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.BucketConditions != nil { + in, out := &in.BucketConditions, &out.BucketConditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectBucketStatus. +func (in *ObjectBucketStatus) DeepCopy() *ObjectBucketStatus { + if in == nil { + return nil + } + out := new(ObjectBucketStatus) + in.DeepCopyInto(out) + return out +} diff --git a/apis/vshn/v1/dbaas_vshn_postgresql.go b/apis/vshn/v1/dbaas_vshn_postgresql.go new file mode 100644 index 0000000000..60588861b7 --- /dev/null +++ b/apis/vshn/v1/dbaas_vshn_postgresql.go @@ -0,0 +1,269 @@ +package v1 + +import ( + alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" + v1 "github.com/vshn/appcat-apiserver/apis/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.maintenance.default={})" + +// +kubebuilder:object:root=true + +// VSHNPostgreSQL is the API for creating Postgresql clusters. +type VSHNPostgreSQL struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a VSHNPostgreSQL. + Spec VSHNPostgreSQLSpec `json:"spec"` + + // Status reflects the observed state of a VSHNPostgreSQL. + Status VSHNPostgreSQLStatus `json:"status,omitempty"` +} + +// VSHNPostgreSQLSpec defines the desired state of a VSHNPostgreSQL. +type VSHNPostgreSQLSpec struct { + // Parameters are the configurable fields of a VSHNPostgreSQL. + Parameters VSHNPostgreSQLParameters `json:"parameters,omitempty"` + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` + + // ResourceRef contains a reference to the composite. + ResourceRef corev1.ObjectReference `json:"resourceRef,omitempty"` + + // CompositeDeletePolicy defines how the claim should behave if it's deleted. + // This field definition will be overwritten by crossplane again, once the XRD is applied to a cluster. + // It's added here so it can be marshalled correctly in third party operators or composition functions. + CompositeDeletePolicy string `json:"compositeDeletePolicy,omitempty"` +} + +// VSHNPostgreSQLParameters are the configurable fields of a VSHNPostgreSQL. +type VSHNPostgreSQLParameters struct { + // Service contains PostgreSQL DBaaS specific properties + Service VSHNPostgreSQLServiceSpec `json:"service,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance VSHNDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` + + // Size contains settings to control the sizing of a service. + Size VSHNDBaaSSizeSpec `json:"size,omitempty"` + + // Scheduling contains settings to control the scheduling of an instance. + Scheduling VSHNDBaaSSchedulingSpec `json:"scheduling,omitempty"` + + // Network contains any network related settings. + Network VSHNDBaaSNetworkSpec `json:"network,omitempty"` + + // Backup contains settings to control the backups of an instance. + Backup VSHNPostgreSQLBackup `json:"backup,omitempty"` + + // Restore contains settings to control the restore of an instance. + Restore VSHNPostgreSQLRestore `json:"restore,omitempty"` + + // Monitoring contains settings to control monitoring. + Monitoring VSHNPostgreSQLMonitoring `json:"monitoring,omitempty"` + + // Encryption contains settings to control the storage encryption of an instance. + Encryption VSHNPostgreSQLEncryption `json:"encryption,omitempty"` + + // UpdateStrategy indicates when updates to the instance spec will be applied. + UpdateStrategy VSHNPostgreSQLUpdateStrategy `json:"updateStrategy,omitempty"` +} + +const VSHNPostgreSQLUpdateStrategyTypeImmediate = "Immediate" +const VSHNPostgreSQLUpdateStrategyTypeOnRestart = "OnRestart" + +// VSHNPostgreSQLUpdateStrategy indicates how and when updates to the instance spec will be applied. +type VSHNPostgreSQLUpdateStrategy struct { + // +kubebuilder:validation:Enum="Immediate";"OnRestart" + // +kubebuilder:default="Immediate" + + // Type indicates the type of the UpdateStrategy. Default is OnRestart. + // Possible enum values: + // - `"OnRestart"` indicates that the changes to the spec will only be applied once the instance is restarted by other means, most likely during maintenance. + // - `"Immediate"` indicates that update will be applied to the instance as soon as the spec changes. Please be aware that this might lead to short downtime. + Type string `json:"type,omitempty"` +} + +// VSHNPostgreSQLServiceSpec contains PostgreSQL DBaaS specific properties +type VSHNPostgreSQLServiceSpec struct { + // +kubebuilder:validation:Enum="12";"13";"14";"15" + // +kubebuilder:default="15" + + // MajorVersion contains supported version of PostgreSQL. + // Multiple versions are supported. The latest version "15" is the default version. + MajorVersion string `json:"majorVersion,omitempty"` + + // PGSettings contains additional PostgreSQL settings. + PostgreSQLSettings runtime.RawExtension `json:"pgSettings,omitempty"` +} + +// VSHNDBaaSSchedulingSpec contains settings to control the scheduling of an instance. +type VSHNDBaaSSchedulingSpec struct { + // NodeSelector is a selector which must match a node’s labels for the pod to be scheduled on that node + NodeSelector map[string]string `json:"nodeSelector,omitempty"` +} + +// VSHNDBaaSMaintenanceScheduleSpec contains settings to control the maintenance of an instance. +type VSHNDBaaSMaintenanceScheduleSpec struct { + // +kubebuilder:validation:Enum=monday;tuesday;wednesday;thursday;friday;saturday;sunday + + // DayOfWeek specifies at which weekday the maintenance is held place. + // Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + DayOfWeek string `json:"dayOfWeek,omitempty"` + + // +kubebuilder:validation:Pattern="^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$" + + // TimeOfDay for installing updates in UTC. + // Format: "hh:mm:ss". + TimeOfDay string `json:"timeOfDay,omitempty"` +} + +// VSHNDBaaSSizeSpec contains settings to control the sizing of a service. +type VSHNDBaaSSizeSpec struct { + // CPU defines the amount of Kubernetes CPUs for an instance. + CPU string `json:"cpu,omitempty"` + + // Memory defines the amount of memory in units of bytes for an instance. + Memory string `json:"memory,omitempty"` + + // Requests defines CPU and memory requests for an instance + Requests VSHNDBaaSSizeRequestsSpec `json:"requests,omitempty"` + + // Disk defines the amount of disk space for an instance. + Disk string `json:"disk,omitempty"` + + // Plan is the name of the resource plan that defines the compute resources. + Plan string `json:"plan,omitempty"` +} + +// VSHNDBaaSSizeRequestsSpec contains settings to control the resoure requests of a service. +type VSHNDBaaSSizeRequestsSpec struct { + // CPU defines the amount of Kubernetes CPUs for an instance. + CPU string `json:"cpu,omitempty"` + + // Memory defines the amount of memory in units of bytes for an instance. + Memory string `json:"memory,omitempty"` +} + +// VSHNDBaaSNetworkSpec contains any network related settings. +type VSHNDBaaSNetworkSpec struct { + // +kubebuilder:default={"0.0.0.0/0"} + + // IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. + // If no IP Filter is set, you may not be able to reach the service. + // A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + IPFilter []string `json:"ipFilter,omitempty"` +} + +type VSHNPostgreSQLBackup struct { + // +kubebuilder:validation:Pattern=^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$ + Schedule string `json:"schedule,omitempty"` + + // +kubebuilder:validation:Pattern="^[1-9][0-9]*$" + // +kubebuilder:default=6 + // +kubebuilder:validation:XIntOrString + Retention int `json:"retention,omitempty"` + + // DeletionProtection will protect the instance from being deleted for the given retention time. + // This is enabled by default. + // +kubebuilder:default=true + DeletionProtection bool `json:"deletionProtection,omitempty"` + + // DeletionRetention specifies in days how long the instance should be kept after deletion. + // The default is keeping it one week. + // +kubebuilder:default=7 + DeletionRetention int `json:"deletionRetention,omitempty"` +} + +// VSHNPostgreSQLRestore contains restore specific parameters. +type VSHNPostgreSQLRestore struct { + + // ClaimName specifies the name of the instance you want to restore from. + // The claim has to be in the same namespace as this new instance. + ClaimName string `json:"claimName,omitempty"` + + // BackupName is the name of the specific backup you want to restore. + BackupName string `json:"backupName,omitempty"` + + // RecoveryTimeStamp an ISO 8601 date, that holds UTC date indicating at which point-in-time the database has to be restored. + // This is optional and if no PIT recovery is required, it can be left empty. + // +kubebuilder:validation:Pattern=`^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)$` + RecoveryTimeStamp string `json:"recoveryTimeStamp,omitempty"` +} + +// VSHNPostgreSQLMonitoring contains settings to configure monitoring aspects of PostgreSQL +type VSHNPostgreSQLMonitoring struct { + // AlertmanagerConfigRef contains the name of the AlertmanagerConfig that should be copied over to the + // namespace of the PostgreSQL instance. + AlertmanagerConfigRef string `json:"alertmanagerConfigRef,omitempty"` + + // AlertmanagerConfigSecretRef contains the name of the secret that is used + // in the referenced AlertmanagerConfig + AlertmanagerConfigSecretRef string `json:"alertmanagerConfigSecretRef,omitempty"` + + // AlertmanagerConfigSpecTemplate takes an AlertmanagerConfigSpec object. + // This takes precedence over the AlertmanagerConfigRef. + AlertmanagerConfigSpecTemplate *alertmanagerv1alpha1.AlertmanagerConfigSpec `json:"alertmanagerConfigTemplate,omitempty"` +} + +// VSHNPostgreSQLEncryption contains storage encryption specific parameters +type VSHNPostgreSQLEncryption struct { + + // Enabled specifies if the instance should use encrypted storage for the instance. + Enabled bool `json:"enabled,omitempty"` +} + +// VSHNPostgreSQLStatus reflects the observed state of a VSHNPostgreSQL. +type VSHNPostgreSQLStatus struct { + // InstanceNamespace contains the name of the namespace where the instance resides + InstanceNamespace string `json:"instanceNamespace,omitempty"` + // PostgreSQLConditions contains the status conditions of the backing object. + PostgreSQLConditions []v1.Condition `json:"postgresqlConditions,omitempty"` + NamespaceConditions []v1.Condition `json:"namespaceConditions,omitempty"` + ProfileConditions []v1.Condition `json:"profileConditions,omitempty"` + PGConfigConditions []v1.Condition `json:"pgconfigConditions,omitempty"` + PGClusterConditions []v1.Condition `json:"pgclusterConditions,omitempty"` + SecretsConditions []v1.Condition `json:"secretConditions,omitempty"` + ObjectBucketConditions []v1.Condition `json:"ObjectBucketConditions,omitempty"` + ObjectBackupConfigConditions []v1.Condition `json:"ObjectBackupConfigConditions,omitempty"` + NetworkPolicyConditions []v1.Condition `json:"networkPolicyConditions,omitempty"` + LocalCAConditions []v1.Condition `json:"localCAConditions,omitempty"` + CertificateConditions []v1.Condition `json:"certificateConditions,omitempty"` +} + +// +kubebuilder:object:root=true + +// VSHNPostgreSQLList defines a list of VSHNPostgreSQL +type VSHNPostgreSQLList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []VSHNPostgreSQL `json:"items"` +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// XVSHNPostgreSQL represents the internal composite of this claim +type XVSHNPostgreSQL VSHNPostgreSQL + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// XVSHNPostgreSQLList represents a list of composites +type XVSHNPostgreSQLList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []XVSHNPostgreSQL `json:"items"` +} diff --git a/apis/vshn/v1/dbaas_vshn_redis.go b/apis/vshn/v1/dbaas_vshn_redis.go new file mode 100644 index 0000000000..a69522516f --- /dev/null +++ b/apis/vshn/v1/dbaas_vshn_redis.go @@ -0,0 +1,111 @@ +package v1 + +import ( + v1 "github.com/vshn/appcat-apiserver/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnredis.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.tls.default={})" + +// +kubebuilder:object:root=true + +// VSHNRedis is the API for creating Redis clusters. +type VSHNRedis struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a VSHNRedis. + Spec VSHNRedisSpec `json:"spec"` + + // Status reflects the observed state of a VSHNRedis. + Status VSHNRedisStatus `json:"status,omitempty"` +} + +// VSHNRedisSpec defines the desired state of a VSHNRedis. +type VSHNRedisSpec struct { + // Parameters are the configurable fields of a VSHNRedis. + Parameters VSHNRedisParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +// VSHNRedisParameters are the configurable fields of a VSHNRedis. +type VSHNRedisParameters struct { + // Service contains Redis DBaaS specific properties + Service VSHNRedisServiceSpec `json:"service,omitempty"` + + // Size contains settings to control the sizing of a service. + Size VSHNRedisSizeSpec `json:"size,omitempty"` + + // Scheduling contains settings to control the scheduling of an instance. + Scheduling VSHNDBaaSSchedulingSpec `json:"scheduling,omitempty"` + + // TLS contains settings to control tls traffic of a service. + TLS VSHNRedisTLSSpec `json:"tls,omitempty"` +} + +// VSHNRedisServiceSpec contains Redis DBaaS specific properties +type VSHNRedisServiceSpec struct { + // +kubebuilder:validation:Enum="6.2";"7.0" + // +kubebuilder:default="7.0" + + // Version contains supported version of Redis. + // Multiple versions are supported. The latest version "7.0" is the default version. + Version string `json:"version,omitempty"` + + // RedisSettings contains additional Redis settings. + RedisSettings string `json:"redisSettings,omitempty"` +} + +// VSHNRedisSizeSpec contains settings to control the sizing of a service. +type VSHNRedisSizeSpec struct { + + // CPURequests defines the requests amount of Kubernetes CPUs for an instance. + CPURequests string `json:"cpuRequests,omitempty"` + + // CPULimits defines the limits amount of Kubernetes CPUs for an instance. + CPULimits string `json:"cpuLimits,omitempty"` + + // MemoryRequests defines the requests amount of memory in units of bytes for an instance. + MemoryRequests string `json:"memoryRequests,omitempty"` + + // MemoryLimits defines the limits amount of memory in units of bytes for an instance. + MemoryLimits string `json:"memoryLimits,omitempty"` + + // Disk defines the amount of disk space for an instance. + Disk string `json:"disk,omitempty"` + + // Plan is the name of the resource plan that defines the compute resources. + Plan string `json:"plan,omitempty"` +} + +// VSHNRedisTLSSpec contains settings to control tls traffic of a service. +type VSHNRedisTLSSpec struct { + // +kubebuilder:default=true + + // TLSEnabled enables TLS traffic for the service + TLSEnabled bool `json:"enabled,omitempty"` + + // +kubebuilder:default=true + // TLSAuthClients enables client authentication requirement + TLSAuthClients bool `json:"authClients,omitempty"` +} + +// VSHNRedisStatus reflects the observed state of a VSHNRedis. +type VSHNRedisStatus struct { + // RedisConditions contains the status conditions of the backing object. + NamespaceConditions []v1.Condition `json:"namespaceConditions,omitempty"` + SelfSignedIssuerConditions []v1.Condition `json:"selfSignedIssuerConditions,omitempty"` + LocalCAConditions []v1.Condition `json:"localCAConditions,omitempty"` + CaCertificateConditions []v1.Condition `json:"caCertificateConditions,omitempty"` + ServerCertificateConditions []v1.Condition `json:"serverCertificateConditions,omitempty"` + ClientCertificateConditions []v1.Condition `json:"clientCertificateConditions,omitempty"` + // InstanceNamespace contains the name of the namespace where the instance resides + InstanceNamespace string `json:"instanceNamespace,omitempty"` +} diff --git a/apis/vshn/v1/groupversion_info.go b/apis/vshn/v1/groupversion_info.go new file mode 100644 index 0000000000..b452f1e4ec --- /dev/null +++ b/apis/vshn/v1/groupversion_info.go @@ -0,0 +1,25 @@ +// +kubebuilder:object:generate=true +// +groupName=vshn.appcat.vshn.io +// +versionName=v1 + +package v1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "vshn.appcat.vshn.io", Version: "v1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +func init() { + SchemeBuilder.Register(&VSHNPostgreSQL{}, &VSHNPostgreSQLList{}, &XVSHNPostgreSQL{}, &XVSHNPostgreSQLList{}) +} diff --git a/apis/vshn/v1/zz_generated.deepcopy.go b/apis/vshn/v1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..dc4d7a4833 --- /dev/null +++ b/apis/vshn/v1/zz_generated.deepcopy.go @@ -0,0 +1,614 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by controller-gen. DO NOT EDIT. + +package v1 + +import ( + "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" + apisv1 "github.com/vshn/appcat-apiserver/apis/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNDBaaSMaintenanceScheduleSpec) DeepCopyInto(out *VSHNDBaaSMaintenanceScheduleSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNDBaaSMaintenanceScheduleSpec. +func (in *VSHNDBaaSMaintenanceScheduleSpec) DeepCopy() *VSHNDBaaSMaintenanceScheduleSpec { + if in == nil { + return nil + } + out := new(VSHNDBaaSMaintenanceScheduleSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNDBaaSNetworkSpec) DeepCopyInto(out *VSHNDBaaSNetworkSpec) { + *out = *in + if in.IPFilter != nil { + in, out := &in.IPFilter, &out.IPFilter + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNDBaaSNetworkSpec. +func (in *VSHNDBaaSNetworkSpec) DeepCopy() *VSHNDBaaSNetworkSpec { + if in == nil { + return nil + } + out := new(VSHNDBaaSNetworkSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNDBaaSSchedulingSpec) DeepCopyInto(out *VSHNDBaaSSchedulingSpec) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNDBaaSSchedulingSpec. +func (in *VSHNDBaaSSchedulingSpec) DeepCopy() *VSHNDBaaSSchedulingSpec { + if in == nil { + return nil + } + out := new(VSHNDBaaSSchedulingSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNDBaaSSizeRequestsSpec) DeepCopyInto(out *VSHNDBaaSSizeRequestsSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNDBaaSSizeRequestsSpec. +func (in *VSHNDBaaSSizeRequestsSpec) DeepCopy() *VSHNDBaaSSizeRequestsSpec { + if in == nil { + return nil + } + out := new(VSHNDBaaSSizeRequestsSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNDBaaSSizeSpec) DeepCopyInto(out *VSHNDBaaSSizeSpec) { + *out = *in + out.Requests = in.Requests +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNDBaaSSizeSpec. +func (in *VSHNDBaaSSizeSpec) DeepCopy() *VSHNDBaaSSizeSpec { + if in == nil { + return nil + } + out := new(VSHNDBaaSSizeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQL) DeepCopyInto(out *VSHNPostgreSQL) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQL. +func (in *VSHNPostgreSQL) DeepCopy() *VSHNPostgreSQL { + if in == nil { + return nil + } + out := new(VSHNPostgreSQL) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSHNPostgreSQL) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLBackup) DeepCopyInto(out *VSHNPostgreSQLBackup) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLBackup. +func (in *VSHNPostgreSQLBackup) DeepCopy() *VSHNPostgreSQLBackup { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLBackup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLEncryption) DeepCopyInto(out *VSHNPostgreSQLEncryption) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLEncryption. +func (in *VSHNPostgreSQLEncryption) DeepCopy() *VSHNPostgreSQLEncryption { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLEncryption) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLList) DeepCopyInto(out *VSHNPostgreSQLList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VSHNPostgreSQL, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLList. +func (in *VSHNPostgreSQLList) DeepCopy() *VSHNPostgreSQLList { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSHNPostgreSQLList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLMonitoring) DeepCopyInto(out *VSHNPostgreSQLMonitoring) { + *out = *in + if in.AlertmanagerConfigSpecTemplate != nil { + in, out := &in.AlertmanagerConfigSpecTemplate, &out.AlertmanagerConfigSpecTemplate + *out = new(v1alpha1.AlertmanagerConfigSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLMonitoring. +func (in *VSHNPostgreSQLMonitoring) DeepCopy() *VSHNPostgreSQLMonitoring { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLMonitoring) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLParameters) DeepCopyInto(out *VSHNPostgreSQLParameters) { + *out = *in + in.Service.DeepCopyInto(&out.Service) + out.Maintenance = in.Maintenance + out.Size = in.Size + in.Scheduling.DeepCopyInto(&out.Scheduling) + in.Network.DeepCopyInto(&out.Network) + out.Backup = in.Backup + out.Restore = in.Restore + in.Monitoring.DeepCopyInto(&out.Monitoring) + out.Encryption = in.Encryption + out.UpdateStrategy = in.UpdateStrategy +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLParameters. +func (in *VSHNPostgreSQLParameters) DeepCopy() *VSHNPostgreSQLParameters { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLRestore) DeepCopyInto(out *VSHNPostgreSQLRestore) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLRestore. +func (in *VSHNPostgreSQLRestore) DeepCopy() *VSHNPostgreSQLRestore { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLRestore) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLServiceSpec) DeepCopyInto(out *VSHNPostgreSQLServiceSpec) { + *out = *in + in.PostgreSQLSettings.DeepCopyInto(&out.PostgreSQLSettings) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLServiceSpec. +func (in *VSHNPostgreSQLServiceSpec) DeepCopy() *VSHNPostgreSQLServiceSpec { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLSpec) DeepCopyInto(out *VSHNPostgreSQLSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef + out.ResourceRef = in.ResourceRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLSpec. +func (in *VSHNPostgreSQLSpec) DeepCopy() *VSHNPostgreSQLSpec { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLStatus) DeepCopyInto(out *VSHNPostgreSQLStatus) { + *out = *in + if in.PostgreSQLConditions != nil { + in, out := &in.PostgreSQLConditions, &out.PostgreSQLConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.NamespaceConditions != nil { + in, out := &in.NamespaceConditions, &out.NamespaceConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ProfileConditions != nil { + in, out := &in.ProfileConditions, &out.ProfileConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.PGConfigConditions != nil { + in, out := &in.PGConfigConditions, &out.PGConfigConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.PGClusterConditions != nil { + in, out := &in.PGClusterConditions, &out.PGClusterConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SecretsConditions != nil { + in, out := &in.SecretsConditions, &out.SecretsConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ObjectBucketConditions != nil { + in, out := &in.ObjectBucketConditions, &out.ObjectBucketConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ObjectBackupConfigConditions != nil { + in, out := &in.ObjectBackupConfigConditions, &out.ObjectBackupConfigConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.NetworkPolicyConditions != nil { + in, out := &in.NetworkPolicyConditions, &out.NetworkPolicyConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LocalCAConditions != nil { + in, out := &in.LocalCAConditions, &out.LocalCAConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CertificateConditions != nil { + in, out := &in.CertificateConditions, &out.CertificateConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLStatus. +func (in *VSHNPostgreSQLStatus) DeepCopy() *VSHNPostgreSQLStatus { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNPostgreSQLUpdateStrategy) DeepCopyInto(out *VSHNPostgreSQLUpdateStrategy) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNPostgreSQLUpdateStrategy. +func (in *VSHNPostgreSQLUpdateStrategy) DeepCopy() *VSHNPostgreSQLUpdateStrategy { + if in == nil { + return nil + } + out := new(VSHNPostgreSQLUpdateStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNRedis) DeepCopyInto(out *VSHNRedis) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNRedis. +func (in *VSHNRedis) DeepCopy() *VSHNRedis { + if in == nil { + return nil + } + out := new(VSHNRedis) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSHNRedis) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNRedisParameters) DeepCopyInto(out *VSHNRedisParameters) { + *out = *in + out.Service = in.Service + out.Size = in.Size + in.Scheduling.DeepCopyInto(&out.Scheduling) + out.TLS = in.TLS +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNRedisParameters. +func (in *VSHNRedisParameters) DeepCopy() *VSHNRedisParameters { + if in == nil { + return nil + } + out := new(VSHNRedisParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNRedisServiceSpec) DeepCopyInto(out *VSHNRedisServiceSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNRedisServiceSpec. +func (in *VSHNRedisServiceSpec) DeepCopy() *VSHNRedisServiceSpec { + if in == nil { + return nil + } + out := new(VSHNRedisServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNRedisSizeSpec) DeepCopyInto(out *VSHNRedisSizeSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNRedisSizeSpec. +func (in *VSHNRedisSizeSpec) DeepCopy() *VSHNRedisSizeSpec { + if in == nil { + return nil + } + out := new(VSHNRedisSizeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNRedisSpec) DeepCopyInto(out *VSHNRedisSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNRedisSpec. +func (in *VSHNRedisSpec) DeepCopy() *VSHNRedisSpec { + if in == nil { + return nil + } + out := new(VSHNRedisSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNRedisStatus) DeepCopyInto(out *VSHNRedisStatus) { + *out = *in + if in.NamespaceConditions != nil { + in, out := &in.NamespaceConditions, &out.NamespaceConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SelfSignedIssuerConditions != nil { + in, out := &in.SelfSignedIssuerConditions, &out.SelfSignedIssuerConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LocalCAConditions != nil { + in, out := &in.LocalCAConditions, &out.LocalCAConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CaCertificateConditions != nil { + in, out := &in.CaCertificateConditions, &out.CaCertificateConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ServerCertificateConditions != nil { + in, out := &in.ServerCertificateConditions, &out.ServerCertificateConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ClientCertificateConditions != nil { + in, out := &in.ClientCertificateConditions, &out.ClientCertificateConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNRedisStatus. +func (in *VSHNRedisStatus) DeepCopy() *VSHNRedisStatus { + if in == nil { + return nil + } + out := new(VSHNRedisStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNRedisTLSSpec) DeepCopyInto(out *VSHNRedisTLSSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNRedisTLSSpec. +func (in *VSHNRedisTLSSpec) DeepCopy() *VSHNRedisTLSSpec { + if in == nil { + return nil + } + out := new(VSHNRedisTLSSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNPostgreSQL) DeepCopyInto(out *XVSHNPostgreSQL) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNPostgreSQL. +func (in *XVSHNPostgreSQL) DeepCopy() *XVSHNPostgreSQL { + if in == nil { + return nil + } + out := new(XVSHNPostgreSQL) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *XVSHNPostgreSQL) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNPostgreSQLList) DeepCopyInto(out *XVSHNPostgreSQLList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]XVSHNPostgreSQL, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNPostgreSQLList. +func (in *XVSHNPostgreSQLList) DeepCopy() *XVSHNPostgreSQLList { + if in == nil { + return nil + } + out := new(XVSHNPostgreSQLList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *XVSHNPostgreSQLList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/apiserver/vshn/postgres/backup.go b/apiserver/vshn/postgres/backup.go index 14a81fd23f..ab0d8dedfb 100644 --- a/apiserver/vshn/postgres/backup.go +++ b/apiserver/vshn/postgres/backup.go @@ -2,7 +2,7 @@ package postgres import ( "github.com/vshn/appcat-apiserver/apis/appcat/v1" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" diff --git a/apiserver/vshn/postgres/backup_test.go b/apiserver/vshn/postgres/backup_test.go index cb9f05ee15..6b524ab5aa 100644 --- a/apiserver/vshn/postgres/backup_test.go +++ b/apiserver/vshn/postgres/backup_test.go @@ -4,7 +4,7 @@ import ( "github.com/vshn/appcat-apiserver/apis/appcat/v1" "github.com/vshn/appcat-apiserver/test/mocks" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" diff --git a/apiserver/vshn/postgres/get_test.go b/apiserver/vshn/postgres/get_test.go index 99917eb24e..45f2ca1083 100644 --- a/apiserver/vshn/postgres/get_test.go +++ b/apiserver/vshn/postgres/get_test.go @@ -2,8 +2,8 @@ package postgres import ( "github.com/vshn/appcat-apiserver/apis/appcat/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "github.com/vshn/appcat-apiserver/test/mocks" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "testing" diff --git a/apiserver/vshn/postgres/list_test.go b/apiserver/vshn/postgres/list_test.go index 3f2d418d39..8b6ff5f6a6 100644 --- a/apiserver/vshn/postgres/list_test.go +++ b/apiserver/vshn/postgres/list_test.go @@ -3,8 +3,8 @@ package postgres import ( "fmt" "github.com/vshn/appcat-apiserver/apis/appcat/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "github.com/vshn/appcat-apiserver/test/mocks" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/apiserver/vshn/postgres/vshnpostgresql.go b/apiserver/vshn/postgres/vshnpostgresql.go index c6eb42d597..f297523fa4 100644 --- a/apiserver/vshn/postgres/vshnpostgresql.go +++ b/apiserver/vshn/postgres/vshnpostgresql.go @@ -2,7 +2,7 @@ package postgres import ( "context" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/apiserver/vshn/postgres/vshnpostgresql_test.go b/apiserver/vshn/postgres/vshnpostgresql_test.go index 81d97d815f..79cc839245 100644 --- a/apiserver/vshn/postgres/vshnpostgresql_test.go +++ b/apiserver/vshn/postgres/vshnpostgresql_test.go @@ -4,8 +4,8 @@ import ( "context" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "github.com/vshn/appcat-apiserver/test/mocks" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" ) diff --git a/command/postgresql_controller.go b/command/postgresql_controller.go index 4f259c047d..1847fc2d39 100644 --- a/command/postgresql_controller.go +++ b/command/postgresql_controller.go @@ -4,9 +4,9 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/go-logr/logr" "github.com/spf13/cobra" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" sli_exporter "github.com/vshn/appcat-apiserver/controller/sli-exporter" "github.com/vshn/appcat-apiserver/controller/sli-exporter/probes" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "os" diff --git a/command/xpostgresql_controller.go b/command/xpostgresql_controller.go index d3da5f11a9..5bc44e9279 100644 --- a/command/xpostgresql_controller.go +++ b/command/xpostgresql_controller.go @@ -4,8 +4,8 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/go-logr/logr" "github.com/spf13/cobra" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "github.com/vshn/appcat-apiserver/controller/postgres" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" diff --git a/comp-functions/functions/vshn-postgres-func/alerting.go b/comp-functions/functions/vshn-postgres-func/alerting.go index cc3c2b9c2a..7d8ded1c7a 100644 --- a/comp-functions/functions/vshn-postgres-func/alerting.go +++ b/comp-functions/functions/vshn-postgres-func/alerting.go @@ -7,7 +7,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" diff --git a/comp-functions/functions/vshn-postgres-func/alerting_test.go b/comp-functions/functions/vshn-postgres-func/alerting_test.go index 29b59aab14..c708bebac8 100644 --- a/comp-functions/functions/vshn-postgres-func/alerting_test.go +++ b/comp-functions/functions/vshn-postgres-func/alerting_test.go @@ -5,8 +5,8 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "github.com/vshn/appcat-apiserver/comp-functions/runtime" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" v1 "k8s.io/api/core/v1" "testing" diff --git a/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go b/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go index 38323681ef..73f4901832 100644 --- a/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go +++ b/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go @@ -8,7 +8,7 @@ import ( "github.com/sethvargo/go-password/password" controllerruntime "sigs.k8s.io/controller-runtime" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go b/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go index 1ca4f1b32d..1519a7b9a3 100644 --- a/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go +++ b/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go @@ -8,7 +8,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" "github.com/stretchr/testify/assert" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" v1 "k8s.io/api/core/v1" "sigs.k8s.io/yaml" ) diff --git a/comp-functions/functions/vshn-postgres-func/schedule.go b/comp-functions/functions/vshn-postgres-func/schedule.go index 500c94ab56..d531fea875 100644 --- a/comp-functions/functions/vshn-postgres-func/schedule.go +++ b/comp-functions/functions/vshn-postgres-func/schedule.go @@ -7,7 +7,7 @@ import ( "math/rand" "time" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" ) var ( diff --git a/comp-functions/functions/vshn-postgres-func/schedule_test.go b/comp-functions/functions/vshn-postgres-func/schedule_test.go index baf4e653ae..89b1c62fee 100644 --- a/comp-functions/functions/vshn-postgres-func/schedule_test.go +++ b/comp-functions/functions/vshn-postgres-func/schedule_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/stretchr/testify/assert" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" fnv1aplha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" ) diff --git a/comp-functions/functions/vshn-postgres-func/url.go b/comp-functions/functions/vshn-postgres-func/url.go index 9474161ff6..97f31e2758 100644 --- a/comp-functions/functions/vshn-postgres-func/url.go +++ b/comp-functions/functions/vshn-postgres-func/url.go @@ -3,8 +3,8 @@ package vshnpostgres import ( "context" "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" "github.com/vshn/appcat-apiserver/comp-functions/runtime" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" v1 "k8s.io/api/core/v1" controllerruntime "sigs.k8s.io/controller-runtime" ) diff --git a/comp-functions/runtime/runtime.go b/comp-functions/runtime/runtime.go index 6042562af8..e711763f91 100644 --- a/comp-functions/runtime/runtime.go +++ b/comp-functions/runtime/runtime.go @@ -8,7 +8,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/controller/postgres/reconciler.go b/controller/postgres/reconciler.go index b5b1857d0f..3660728bbd 100644 --- a/controller/postgres/reconciler.go +++ b/controller/postgres/reconciler.go @@ -5,9 +5,9 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/crossplane/crossplane-runtime/pkg/errors" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/controller/postgres/reconciler_test.go b/controller/postgres/reconciler_test.go index 9011f786b5..6751d5bbdf 100644 --- a/controller/postgres/reconciler_test.go +++ b/controller/postgres/reconciler_test.go @@ -8,7 +8,6 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/stretchr/testify/assert" v1 "github.com/vshn/component-appcat/apis/vshn/v1" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -24,7 +23,7 @@ var ( ) func init() { - _ = vshnv1.AddToScheme(s) + _ = v1.AddToScheme(s) _ = corev1.AddToScheme(s) _ = xkube.SchemeBuilder.AddToScheme(s) } @@ -262,7 +261,7 @@ func Test_Reconcile(t *testing.T) { assert.Equal(t, tc.expectedResult, result) // Assert that the composite finalizers are as expected - resultComposite := &vshnv1.XVSHNPostgreSQL{} + resultComposite := &v1.XVSHNPostgreSQL{} getObjectToAssert(t, resultComposite, fclient, client.ObjectKeyFromObject(&tc.inst)) // Assert that the namespace also has the finalizers diff --git a/controller/sli-exporter/vshnpostgresql_controller.go b/controller/sli-exporter/vshnpostgresql_controller.go index fd97cf44dc..f2270a053f 100644 --- a/controller/sli-exporter/vshnpostgresql_controller.go +++ b/controller/sli-exporter/vshnpostgresql_controller.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" ) var vshnpostgresqlsServiceKey = "VSHNPostgreSQL" diff --git a/controller/sli-exporter/vshnpostgresql_controller_test.go b/controller/sli-exporter/vshnpostgresql_controller_test.go index 5aaa57015d..a68e890314 100644 --- a/controller/sli-exporter/vshnpostgresql_controller_test.go +++ b/controller/sli-exporter/vshnpostgresql_controller_test.go @@ -18,8 +18,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - appcatv1 "github.com/vshn/component-appcat/apis/v1" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + v1 "github.com/vshn/appcat-apiserver/apis/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" ) func TestVSHNPostgreSQL_StartStop(t *testing.T) { @@ -290,7 +290,7 @@ func newTestVSHNPostgre(namespace, name, cred string) *vshnv1.VSHNPostgreSQL { Namespace: namespace, }, Spec: vshnv1.VSHNPostgreSQLSpec{ - WriteConnectionSecretToRef: appcatv1.LocalObjectReference{ + WriteConnectionSecretToRef: v1.LocalObjectReference{ Name: cred, }, }, diff --git a/crds/appcat.vshn.io_objectbuckets.yaml b/crds/appcat.vshn.io_objectbuckets.yaml new file mode 100644 index 0000000000..4aaac62924 --- /dev/null +++ b/crds/appcat.vshn.io_objectbuckets.yaml @@ -0,0 +1,172 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: objectbuckets.appcat.vshn.io +spec: + group: appcat.vshn.io + names: + kind: ObjectBucket + listKind: ObjectBucketList + plural: objectbuckets + singular: objectbucket + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.parameters.bucketName + name: Bucket Name + type: string + - jsonPath: .spec.parameters.region + name: Region + type: string + name: v1 + schema: + openAPIV3Schema: + description: ObjectBucket is the API for creating S3 buckets. + 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: ObjectBucketSpec defines the desired state of a ObjectBucket. + properties: + parameters: + description: ObjectBucketParameters are the configurable fields of + a ObjectBucket. + properties: + bucketName: + description: BucketName is the name of the bucket to create. Cannot + be changed after bucket is created. Name must be acceptable + by the S3 protocol, which follows RFC 1123. Be aware that S3 + providers may require a unique name across the platform or region. + type: string + region: + description: Region is the name of the region where the bucket + shall be created. The region must be available in the S3 endpoint. + type: string + required: + - bucketName + - region + type: object + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which + the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: ObjectBucketStatus reflects the observed state of a ObjectBucket. + properties: + accessUserConditions: + description: AccessUserConditions contains a copy of the claim's underlying + user account conditions. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + bucketConditions: + description: BucketConditions contains a copy of the claim's underlying + bucket conditions. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml b/crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml new file mode 100644 index 0000000000..bac637d274 --- /dev/null +++ b/crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml @@ -0,0 +1,176 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: exoscalekafkas.exoscale.appcat.vshn.io +spec: + group: exoscale.appcat.vshn.io + names: + kind: ExoscaleKafka + listKind: ExoscaleKafkaList + plural: exoscalekafkas + singular: exoscalekafka + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.parameters.size.plan + name: Plan + type: string + - jsonPath: .spec.parameters.service.zone + name: Zone + type: string + - jsonPath: .status.version + name: Version + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExoscaleKafka is the API for creating Kafka instances on Exoscale. + 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: Spec defines the desired state of a ExoscaleKafka. + properties: + parameters: + description: Parameters are the configurable fields of a ExoscaleKafka. + properties: + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + default: tuesday + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday, never] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + - never + type: string + timeOfDay: + default: "22:30:00" + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + network: + description: Network contains any network related settings. + properties: + ipFilter: + default: + - 0.0.0.0/0 + description: IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. If no IP Filter is set, you may not be able to reach the service. A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + items: + type: string + type: array + type: object + default: {} + service: + description: Service contains Exoscale Kafka DBaaS specific properties + properties: + kafkaSettings: + description: KafkaSettings contains additional Kafka settings. + type: object + x-kubernetes-preserve-unknown-fields: true + version: + default: "3.2" + description: Version contains the minor version for Kafka. Currently only "3.2" is supported. Leave it empty to always get the latest supported version. + enum: + - "3.2" + type: string + zone: + default: ch-gva-2 + description: Zone is the datacenter identifier in which the instance runs in. + enum: + - ch-gva-2 + - ch-dk-2 + - de-fra-1 + - de-muc-1 + - at-vie-1 + - bg-sof-1 + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + plan: + default: startup-2 + description: Plan is the name of the resource plan that defines the compute resources. + type: string + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a ExoscaleKafka. + properties: + kafkaConditions: + description: KafkaConditions contains the status conditions of the backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + version: + description: The actual observed Kafka version. + type: string + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/crds/exoscale.appcat.vshn.io_exoscalemysqls.yaml b/crds/exoscale.appcat.vshn.io_exoscalemysqls.yaml new file mode 100644 index 0000000000..9ac001a2c5 --- /dev/null +++ b/crds/exoscale.appcat.vshn.io_exoscalemysqls.yaml @@ -0,0 +1,180 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: exoscalemysqls.exoscale.appcat.vshn.io +spec: + group: exoscale.appcat.vshn.io + names: + kind: ExoscaleMySQL + listKind: ExoscaleMySQLList + plural: exoscalemysqls + singular: exoscalemysql + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.parameters.size.plan + name: Plan + type: string + - jsonPath: .spec.parameters.service.zone + name: Zone + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExoscaleMySQL is the API for creating MySQL on Exoscale. + 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: Spec defines the desired state of a ExoscaleMySQL. + properties: + parameters: + description: Parameters are the configurable fields of a ExoscaleMySQL. + properties: + backup: + description: Backup contains settings to control the backups of an instance. + properties: + timeOfDay: + default: "21:30:00" + description: 'TimeOfDay for doing daily backups, in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + default: tuesday + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday, never] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + - never + type: string + timeOfDay: + default: "22:30:00" + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + network: + description: Network contains any network related settings. + properties: + ipFilter: + default: + - 0.0.0.0/0 + description: IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. If no IP Filter is set, you may not be able to reach the service. A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + items: + type: string + type: array + type: object + default: {} + service: + description: Service contains Exoscale MySQL DBaaS specific properties + properties: + majorVersion: + default: "8" + description: MajorVersion contains the major version for MySQL. Currently only "8" is supported. Leave it empty to always get the latest supported version. + enum: + - "8" + type: string + mysqlSettings: + description: MySQLSettings contains additional MySQL settings. + type: object + x-kubernetes-preserve-unknown-fields: true + zone: + default: ch-gva-2 + description: Zone is the datacenter identifier in which the instance runs in. + enum: + - ch-gva-2 + - ch-dk-2 + - de-fra-1 + - de-muc-1 + - at-vie-1 + - bg-sof-1 + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + plan: + default: startup-4 + description: Plan is the name of the resource plan that defines the compute resources. + type: string + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a ExoscaleMySQL. + properties: + mysqlConditions: + description: MySQLConditions contains the status conditions of the backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/crds/exoscale.appcat.vshn.io_exoscaleopensearches.yaml b/crds/exoscale.appcat.vshn.io_exoscaleopensearches.yaml new file mode 100644 index 0000000000..a1c5754209 --- /dev/null +++ b/crds/exoscale.appcat.vshn.io_exoscaleopensearches.yaml @@ -0,0 +1,181 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: exoscaleopensearches.exoscale.appcat.vshn.io +spec: + group: exoscale.appcat.vshn.io + names: + kind: ExoscaleOpenSearch + listKind: ExoscaleOpenSearchList + plural: exoscaleopensearches + singular: exoscaleopensearch + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.parameters.size.plan + name: Plan + type: string + - jsonPath: .spec.parameters.service.zone + name: Zone + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExoscaleOpenSearch is the api for creating OpenSearch on Exoscale + 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: Spec defines the desired state of an ExoscaleOpenSearch + properties: + parameters: + description: Parameters are the configurable fields of a ExoscaleOpenSearch. + properties: + backup: + description: Backup contains settings to control the backups of an instance. + properties: + timeOfDay: + default: "21:30:00" + description: 'TimeOfDay for doing daily backups, in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + default: tuesday + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday, never] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + - never + type: string + timeOfDay: + default: "22:30:00" + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + network: + description: Network contains any network related settings. + properties: + ipFilter: + default: + - 0.0.0.0/0 + description: IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. If no IP Filter is set, you may not be able to reach the service. A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + items: + type: string + type: array + type: object + default: {} + service: + description: Service contains Exoscale OpenSearch DBaaS specific properties + properties: + majorVersion: + default: "2" + description: MajorVersion contains the version for OpenSearch. Currently only "2" and "1" is supported. Leave it empty to always get the latest supported version. + enum: + - "1" + - "2" + type: string + opensearchSettings: + description: OpenSearchSettings contains additional OpenSearch settings. + type: object + x-kubernetes-preserve-unknown-fields: true + zone: + default: ch-gva-2 + description: Zone is the datacenter identifier in which the instance runs in. + enum: + - ch-gva-2 + - ch-dk-2 + - de-fra-1 + - de-muc-1 + - at-vie-1 + - bg-sof-1 + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + plan: + default: startup-4 + description: Plan is the name of the resource plan that defines the compute resources. + type: string + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a ExoscaleOpenSearch + properties: + opensearchConditions: + description: OpenSearchConditions contains the status conditions of the backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/crds/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml b/crds/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml new file mode 100644 index 0000000000..2de320501d --- /dev/null +++ b/crds/exoscale.appcat.vshn.io_exoscalepostgresqls.yaml @@ -0,0 +1,180 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: exoscalepostgresqls.exoscale.appcat.vshn.io +spec: + group: exoscale.appcat.vshn.io + names: + kind: ExoscalePostgreSQL + listKind: ExoscalePostgreSQLList + plural: exoscalepostgresqls + singular: exoscalepostgresql + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.parameters.size.plan + name: Plan + type: string + - jsonPath: .spec.parameters.service.zone + name: Zone + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExoscalePostgreSQL is the API for creating PostgreSQL on Exoscale. + 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: Spec defines the desired state of a ExoscalePostgreSQL. + properties: + parameters: + description: Parameters are the configurable fields of a ExoscalePostgreSQL. + properties: + backup: + description: Backup contains settings to control the backups of an instance. + properties: + timeOfDay: + default: "21:30:00" + description: 'TimeOfDay for doing daily backups, in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + default: tuesday + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday, never] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + - never + type: string + timeOfDay: + default: "22:30:00" + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + network: + description: Network contains any network related settings. + properties: + ipFilter: + default: + - 0.0.0.0/0 + description: IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. If no IP Filter is set, you may not be able to reach the service. A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + items: + type: string + type: array + type: object + default: {} + service: + description: Service contains Exoscale PostgreSQL DBaaS specific properties + properties: + majorVersion: + default: "14" + description: MajorVersion contains the major version for PostgreSQL. Currently only "14" is supported. Leave it empty to always get the latest supported version. + enum: + - "14" + type: string + pgSettings: + description: PGSettings contains additional PostgreSQL settings. + type: object + x-kubernetes-preserve-unknown-fields: true + zone: + default: ch-gva-2 + description: Zone is the datacenter identifier in which the instance runs in. + enum: + - ch-gva-2 + - ch-dk-2 + - de-fra-1 + - de-muc-1 + - at-vie-1 + - bg-sof-1 + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + plan: + default: startup-4 + description: Plan is the name of the resource plan that defines the compute resources. + type: string + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a ExoscalePostgreSQL. + properties: + postgresqlConditions: + description: PostgreSQLConditions contains the status conditions of the backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/crds/exoscale.appcat.vshn.io_exoscaleredis.yaml b/crds/exoscale.appcat.vshn.io_exoscaleredis.yaml new file mode 100644 index 0000000000..248d9f6eb2 --- /dev/null +++ b/crds/exoscale.appcat.vshn.io_exoscaleredis.yaml @@ -0,0 +1,164 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: exoscaleredis.exoscale.appcat.vshn.io +spec: + group: exoscale.appcat.vshn.io + names: + kind: ExoscaleRedis + listKind: ExoscaleRedisList + plural: exoscaleredis + singular: exoscaleredis + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.parameters.size.plan + name: Plan + type: string + - jsonPath: .spec.parameters.service.zone + name: Zone + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExoscaleRedis is the API for creating Redis instances on Exoscale. + 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: Spec defines the desired state of a ExoscaleRedis. + properties: + parameters: + description: Parameters are the configurable fields of a ExoscaleRedis. + properties: + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + default: tuesday + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday, never] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + - never + type: string + timeOfDay: + default: "22:30:00" + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + network: + description: Network contains any network related settings. + properties: + ipFilter: + default: + - 0.0.0.0/0 + description: IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. If no IP Filter is set, you may not be able to reach the service. A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + items: + type: string + type: array + type: object + default: {} + service: + description: Service contains Exoscale Redis DBaaS specific properties + properties: + redisSettings: + description: RedisSettings contains additional Redis settings. + type: object + x-kubernetes-preserve-unknown-fields: true + zone: + default: ch-gva-2 + description: Zone is the datacenter identifier in which the instance runs in. + enum: + - ch-gva-2 + - ch-dk-2 + - de-fra-1 + - de-muc-1 + - at-vie-1 + - bg-sof-1 + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + plan: + default: startup-4 + description: Plan is the name of the resource plan that defines the compute resources. + type: string + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a ExoscaleRedis. + properties: + redisConditions: + description: RedisConditions contains the status conditions of the backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: {} diff --git a/crds/vshn.appcat.vshn.io_vshnpostgresqls.yaml b/crds/vshn.appcat.vshn.io_vshnpostgresqls.yaml new file mode 100644 index 0000000000..baaa4ae0c5 --- /dev/null +++ b/crds/vshn.appcat.vshn.io_vshnpostgresqls.yaml @@ -0,0 +1,4008 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: vshnpostgresqls.vshn.appcat.vshn.io +spec: + group: vshn.appcat.vshn.io + names: + kind: VSHNPostgreSQL + listKind: VSHNPostgreSQLList + plural: vshnpostgresqls + singular: vshnpostgresql + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: VSHNPostgreSQL is the API for creating Postgresql clusters. + 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: Spec defines the desired state of a VSHNPostgreSQL. + properties: + compositeDeletePolicy: + description: CompositeDeletePolicy defines how the claim should behave if it's deleted. This field definition will be overwritten by crossplane again, once the XRD is applied to a cluster. It's added here so it can be marshalled correctly in third party operators or composition functions. + type: string + parameters: + description: Parameters are the configurable fields of a VSHNPostgreSQL. + properties: + backup: + description: Backup contains settings to control the backups of an instance. + properties: + deletionProtection: + default: true + description: DeletionProtection will protect the instance from being deleted for the given retention time. This is enabled by default. + type: boolean + deletionRetention: + default: 7 + description: DeletionRetention specifies in days how long the instance should be kept after deletion. The default is keeping it one week. + type: integer + retention: + default: 6 + pattern: ^[1-9][0-9]*$ + type: integer + x-kubernetes-int-or-string: true + schedule: + pattern: ^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$ + type: string + type: object + default: {} + encryption: + description: Encryption contains settings to control the storage encryption of an instance. + properties: + enabled: + description: Enabled specifies if the instance should use encrypted storage for the instance. + type: boolean + type: object + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + default: {} + monitoring: + description: Monitoring contains settings to control monitoring. + properties: + alertmanagerConfigRef: + description: AlertmanagerConfigRef contains the name of the AlertmanagerConfig that should be copied over to the namespace of the PostgreSQL instance. + type: string + alertmanagerConfigSecretRef: + description: AlertmanagerConfigSecretRef contains the name of the secret that is used in the referenced AlertmanagerConfig + type: string + alertmanagerConfigTemplate: + description: AlertmanagerConfigSpecTemplate takes an AlertmanagerConfigSpec object. This takes precedence over the AlertmanagerConfigRef. + properties: + inhibitRules: + description: List of inhibition rules. The rules will only apply to alerts matching the resource's namespace. + items: + description: InhibitRule defines an inhibition rule that allows to mute alerts when other alerts are already firing. See https://prometheus.io/docs/alerting/latest/configuration/#inhibit_rule + properties: + equal: + description: Labels that must have an equal value in the source and target alert for the inhibition to take effect. + items: + type: string + type: array + sourceMatch: + description: Matchers for which one or more alerts have to exist for the inhibition to take effect. The operator enforces that the alert matches the resource's namespace. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: Match operation available with AlertManager >= v0.22.0 and takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: Whether to match on equality (false) or regular-expression (true). Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + targetMatch: + description: Matchers that have to be fulfilled in the alerts to be muted. The operator enforces that the alert matches the resource's namespace. + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: Match operation available with AlertManager >= v0.22.0 and takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: Whether to match on equality (false) or regular-expression (true). Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + type: object + type: array + muteTimeIntervals: + description: List of MuteTimeInterval specifying when the routes should be muted. + items: + description: MuteTimeInterval specifies the periods in time when notifications will be muted + properties: + name: + description: Name of the time interval + type: string + timeIntervals: + description: TimeIntervals is a list of TimeInterval + items: + description: TimeInterval describes intervals of time + properties: + daysOfMonth: + description: DaysOfMonth is a list of DayOfMonthRange + items: + description: DayOfMonthRange is an inclusive range of days of the month beginning at 1 + properties: + end: + description: End of the inclusive range + maximum: 31 + minimum: -31 + type: integer + start: + description: Start of the inclusive range + maximum: 31 + minimum: -31 + type: integer + type: object + type: array + months: + description: Months is a list of MonthRange + items: + description: MonthRange is an inclusive range of months of the year beginning in January Months can be specified by name (e.g 'January') by numerical month (e.g '1') or as an inclusive range (e.g 'January:March', '1:3', '1:March') + pattern: ^((?i)january|february|march|april|may|june|july|august|september|october|november|december|[1-12])(?:((:((?i)january|february|march|april|may|june|july|august|september|october|november|december|[1-12]))$)|$) + type: string + type: array + times: + description: Times is a list of TimeRange + items: + description: TimeRange defines a start and end time in 24hr format + properties: + endTime: + description: EndTime is the end time in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + startTime: + description: StartTime is the start time in 24hr format. + pattern: ^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$) + type: string + type: object + type: array + weekdays: + description: Weekdays is a list of WeekdayRange + items: + description: WeekdayRange is an inclusive range of days of the week beginning on Sunday Days can be specified by name (e.g 'Sunday') or as an inclusive range (e.g 'Monday:Friday') + pattern: ^((?i)sun|mon|tues|wednes|thurs|fri|satur)day(?:((:(sun|mon|tues|wednes|thurs|fri|satur)day)$)|$) + type: string + type: array + years: + description: Years is a list of YearRange + items: + description: YearRange is an inclusive range of years + pattern: ^2\d{3}(?::2\d{3}|$) + type: string + type: array + type: object + type: array + type: object + type: array + receivers: + description: List of receivers. + items: + description: Receiver defines one or more notification integrations. + properties: + emailConfigs: + description: List of Email configurations. + items: + description: EmailConfig configures notifications via Email. + properties: + authIdentity: + description: The identity to use for authentication. + type: string + authPassword: + description: The secret's key that contains the password to use for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authSecret: + description: The secret's key that contains the CRAM-MD5 secret. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authUsername: + description: The username to use for authentication. + type: string + from: + description: The sender address. + type: string + headers: + description: Further headers email header key/value pairs. Overrides any headers previously set by the notification implementation. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + hello: + description: The hostname to identify to the SMTP server. + type: string + html: + description: The HTML body of the email notification. + type: string + requireTLS: + description: The SMTP TLS requirement. Note that Go does not support unencrypted connections to remote SMTP endpoints. + type: boolean + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + smarthost: + description: The SMTP host and port through which emails are sent. E.g. example.com:25 + type: string + text: + description: The text body of the email notification. + type: string + tlsConfig: + description: TLS configuration + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + to: + description: The email address to send notifications to. + type: string + type: object + type: array + name: + description: Name of the receiver. Must be unique across all items from the list. + minLength: 1 + type: string + opsgenieConfigs: + description: List of OpsGenie configurations. + items: + description: OpsGenieConfig configures notifications via OpsGenie. See https://prometheus.io/docs/alerting/latest/configuration/#opsgenie_config + properties: + actions: + description: Comma separated list of actions that will be available for the alert. + type: string + apiKey: + description: The secret's key that contains the OpsGenie API key. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiURL: + description: The URL to send OpsGenie API requests to. + type: string + description: + description: Description of the incident. + type: string + details: + description: A set of arbitrary key/value pairs that provide further detail about the incident. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entity: + description: Optional field that can be used to specify which domain alert is related to. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Alert text limited to 130 characters. + type: string + note: + description: Additional alert note. + type: string + priority: + description: Priority level of alert. Possible values are P1, P2, P3, P4, and P5. + type: string + responders: + description: List of responders responsible for notifications. + items: + description: OpsGenieConfigResponder defines a responder to an incident. One of `id`, `name` or `username` has to be defined. + properties: + id: + description: ID of the responder. + type: string + name: + description: Name of the responder. + type: string + type: + description: Type of responder. + enum: + - team + - teams + - user + - escalation + - schedule + minLength: 1 + type: string + username: + description: Username of the responder. + type: string + required: + - type + type: object + type: array + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + source: + description: Backlink to the sender of the notification. + type: string + tags: + description: Comma separated list of tags attached to the notifications. + type: string + updateAlerts: + description: Whether to update message and description of the alert in OpsGenie if it already exists By default, the alert is never updated in OpsGenie, the new message only appears in activity log. + type: boolean + type: object + type: array + pagerdutyConfigs: + description: List of PagerDuty configurations. + items: + description: PagerDutyConfig configures notifications via PagerDuty. See https://prometheus.io/docs/alerting/latest/configuration/#pagerduty_config + properties: + class: + description: The class/type of the event. + type: string + client: + description: Client identification. + type: string + clientURL: + description: Backlink to the sender of notification. + type: string + component: + description: The part or component of the affected system that is broken. + type: string + description: + description: Description of the incident. + type: string + details: + description: Arbitrary key/value pairs that provide further detail about the incident. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + group: + description: A cluster or grouping of sources. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + pagerDutyImageConfigs: + description: A list of image details to attach that provide further detail about an incident. + items: + description: PagerDutyImageConfig attaches images to an incident + properties: + alt: + description: Alt is the optional alternative text for the image. + type: string + href: + description: Optional URL; makes the image a clickable link. + type: string + src: + description: Src of the image being attached to the incident + type: string + type: object + type: array + pagerDutyLinkConfigs: + description: A list of link details to attach that provide further detail about an incident. + items: + description: PagerDutyLinkConfig attaches text links to an incident + properties: + alt: + description: Text that describes the purpose of the link, and can be used as the link's text. + type: string + href: + description: Href is the URL of the link to be attached + type: string + type: object + type: array + routingKey: + description: The secret's key that contains the PagerDuty integration key (when using Events API v2). Either this field or `serviceKey` needs to be defined. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + serviceKey: + description: The secret's key that contains the PagerDuty service key (when using integration type "Prometheus"). Either this field or `routingKey` needs to be defined. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + severity: + description: Severity of the incident. + type: string + url: + description: The URL to send requests to. + type: string + type: object + type: array + pushoverConfigs: + description: List of Pushover configurations. + items: + description: PushoverConfig configures notifications via Pushover. See https://prometheus.io/docs/alerting/latest/configuration/#pushover_config + properties: + expire: + description: How long your notification will continue to be retried for, unless the user acknowledges the notification. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + html: + description: Whether notification message is HTML or plain text. + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Notification message. + type: string + priority: + description: Priority, see https://pushover.net/api#priority + type: string + retry: + description: How often the Pushover servers will send the same notification to the user. Must be at least 30 seconds. + pattern: ^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$ + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + sound: + description: The name of one of the sounds supported by device clients to override the user's default sound choice + type: string + title: + description: Notification title. + type: string + token: + description: The secret's key that contains the registered application's API token, see https://pushover.net/apps. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + url: + description: A supplementary URL shown alongside the message. + type: string + urlTitle: + description: A title for supplementary URL, otherwise just the URL is shown + type: string + userKey: + description: The secret's key that contains the recipient user's user key. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: array + slackConfigs: + description: List of Slack configurations. + items: + description: SlackConfig configures notifications via Slack. See https://prometheus.io/docs/alerting/latest/configuration/#slack_config + properties: + actions: + description: A list of Slack actions that are sent with each notification. + items: + description: SlackAction configures a single Slack action that is sent with each notification. See https://api.slack.com/docs/message-attachments#action_fields and https://api.slack.com/docs/message-buttons for more information. + properties: + confirm: + description: SlackConfirmationField protect users from destructive actions or particularly distinguished decisions by asking them to confirm their button click one more time. See https://api.slack.com/docs/interactive-message-field-guide#confirmation_fields for more information. + properties: + dismissText: + type: string + okText: + type: string + text: + minLength: 1 + type: string + title: + type: string + required: + - text + type: object + name: + type: string + style: + type: string + text: + minLength: 1 + type: string + type: + minLength: 1 + type: string + url: + type: string + value: + type: string + required: + - text + - type + type: object + type: array + apiURL: + description: The secret's key that contains the Slack webhook URL. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + callbackId: + type: string + channel: + description: The channel or user to send notifications to. + type: string + color: + type: string + fallback: + type: string + fields: + description: A list of Slack fields that are sent with each notification. + items: + description: SlackField configures a single Slack field that is sent with each notification. Each field must contain a title, value, and optionally, a boolean value to indicate if the field is short enough to be displayed next to other fields designated as short. See https://api.slack.com/docs/message-attachments#fields for more information. + properties: + short: + type: boolean + title: + minLength: 1 + type: string + value: + minLength: 1 + type: string + required: + - title + - value + type: object + type: array + footer: + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + iconEmoji: + type: string + iconURL: + type: string + imageURL: + type: string + linkNames: + type: boolean + mrkdwnIn: + items: + type: string + type: array + pretext: + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + shortFields: + type: boolean + text: + type: string + thumbURL: + type: string + title: + type: string + titleLink: + type: string + username: + type: string + type: object + type: array + snsConfigs: + description: List of SNS configurations + items: + description: SNSConfig configures notifications via AWS SNS. See https://prometheus.io/docs/alerting/latest/configuration/#sns_configs + properties: + apiURL: + description: The SNS API URL i.e. https://sns.us-east-2.amazonaws.com. If not specified, the SNS API URL from the SNS SDK will be used. + type: string + attributes: + additionalProperties: + type: string + description: SNS message attributes. + type: object + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: The message content of the SNS notification. + type: string + phoneNumber: + description: Phone number if message is delivered via SMS in E.164 format. If you don't specify this value, you must specify a value for the TopicARN or TargetARN. + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + sigv4: + description: Configures AWS's Signature Verification 4 signing process to sign requests. + properties: + accessKey: + description: AccessKey is the AWS API key. If blank, the environment variable `AWS_ACCESS_KEY_ID` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile used to authenticate. + type: string + region: + description: Region is the AWS region. If blank, the region from the default credentials chain used. + type: string + roleArn: + description: RoleArn is the named AWS profile used to authenticate. + type: string + secretKey: + description: SecretKey is the AWS API secret. If blank, the environment variable `AWS_SECRET_ACCESS_KEY` is used. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + subject: + description: Subject line when the message is delivered to email endpoints. + type: string + targetARN: + description: The mobile platform endpoint ARN if message is delivered via mobile notifications. If you don't specify this value, you must specify a value for the topic_arn or PhoneNumber. + type: string + topicARN: + description: SNS topic ARN, i.e. arn:aws:sns:us-east-2:698519295917:My-Topic If you don't specify this value, you must specify a value for the PhoneNumber or TargetARN. + type: string + type: object + type: array + telegramConfigs: + description: List of Telegram configurations. + items: + description: TelegramConfig configures notifications via Telegram. See https://prometheus.io/docs/alerting/latest/configuration/#telegram_config + properties: + apiURL: + description: The Telegram API URL i.e. https://api.telegram.org. If not specified, default API URL will be used. + type: string + botToken: + description: Telegram bot token The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + chatID: + description: The Telegram chat ID. + format: int64 + type: integer + disableNotifications: + description: Disable telegram notifications + type: boolean + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: Message template + type: string + parseMode: + description: Parse mode for telegram message + enum: + - MarkdownV2 + - Markdown + - HTML + type: string + sendResolved: + description: Whether to notify about resolved alerts. + type: boolean + type: object + type: array + victoropsConfigs: + description: List of VictorOps configurations. + items: + description: VictorOpsConfig configures notifications via VictorOps. See https://prometheus.io/docs/alerting/latest/configuration/#victorops_config + properties: + apiKey: + description: The secret's key that contains the API key to use when talking to the VictorOps API. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiUrl: + description: The VictorOps API URL. + type: string + customFields: + description: Additional custom fields for notification. + items: + description: KeyValue defines a (key, value) tuple. + properties: + key: + description: Key of the tuple. + minLength: 1 + type: string + value: + description: Value of the tuple. + type: string + required: + - key + - value + type: object + type: array + entityDisplayName: + description: Contains summary of the alerted problem. + type: string + httpConfig: + description: The HTTP client's configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + messageType: + description: Describes the behavior of the alert (CRITICAL, WARNING, INFO). + type: string + monitoringTool: + description: The monitoring tool the state message is from. + type: string + routingKey: + description: A key used to map the alert to a team. + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + stateMessage: + description: Contains long explanation of the alerted problem. + type: string + type: object + type: array + webhookConfigs: + description: List of webhook configurations. + items: + description: WebhookConfig configures notifications via a generic receiver supporting the webhook payload. See https://prometheus.io/docs/alerting/latest/configuration/#webhook_config + properties: + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + maxAlerts: + description: Maximum number of alerts to be sent per webhook message. When 0, all alerts are included. + format: int32 + minimum: 0 + type: integer + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + url: + description: The URL to send HTTP POST requests to. `urlSecret` takes precedence over `url`. One of `urlSecret` and `url` should be defined. + type: string + urlSecret: + description: The secret's key that contains the webhook URL to send HTTP requests to. `urlSecret` takes precedence over `url`. One of `urlSecret` and `url` should be defined. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + type: array + wechatConfigs: + description: List of WeChat configurations. + items: + description: WeChatConfig configures notifications via WeChat. See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config + properties: + agentID: + type: string + apiSecret: + description: The secret's key that contains the WeChat API key. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + apiURL: + description: The WeChat API URL. + type: string + corpID: + description: The corp id for authentication. + type: string + httpConfig: + description: HTTP client configuration. + properties: + authorization: + description: Authorization header configuration for the client. This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. + properties: + credentials: + description: The secret's key that contains the credentials of the request + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth for the client. This is mutually exclusive with Authorization. If both are defined, BasicAuth takes precedence. + properties: + password: + description: The secret in the service monitor namespace that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: The secret's key that contains the bearer token to be used by the client for authentication. The secret needs to be in the same namespace as the AlertmanagerConfig object and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + followRedirects: + description: FollowRedirects specifies whether the client should follow HTTP 3xx redirects. + type: boolean + oauth2: + description: OAuth2 client credentials used to fetch a token for the targets. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyURL: + description: Optional proxy URL. + type: string + tlsConfig: + description: TLS configuration for the client. + properties: + ca: + description: Certificate authority used when verifying server certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + 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 + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + 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 + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + message: + description: API request data as defined by the WeChat API. + type: string + messageType: + type: string + sendResolved: + description: Whether or not to notify about resolved alerts. + type: boolean + toParty: + type: string + toTag: + type: string + toUser: + type: string + type: object + type: array + required: + - name + type: object + type: array + route: + description: The Alertmanager route definition for alerts matching the resource's namespace. If present, it will be added to the generated Alertmanager configuration as a first-level route. + properties: + activeTimeIntervals: + description: ActiveTimeIntervals is a list of MuteTimeInterval names when this route should be active. + items: + type: string + type: array + continue: + description: Boolean indicating whether an alert should continue matching subsequent sibling nodes. It will always be overridden to true for the first-level route by the Prometheus operator. + type: boolean + groupBy: + description: List of labels to group by. Labels must not be repeated (unique list). Special label "..." (aggregate by all possible labels), if provided, must be the only element in the list. + items: + type: string + type: array + groupInterval: + description: 'How long to wait before sending an updated notification. Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` Example: "5m"' + type: string + groupWait: + description: 'How long to wait before sending the initial notification. Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` Example: "30s"' + type: string + matchers: + description: 'List of matchers that the alert''s labels should match. For the first level route, the operator removes any existing equality and regexp matcher on the `namespace` label and adds a `namespace: ` matcher.' + items: + description: Matcher defines how to match on alert's labels. + properties: + matchType: + description: Match operation available with AlertManager >= v0.22.0 and takes precedence over Regex (deprecated) if non-empty. + enum: + - '!=' + - "=" + - =~ + - '!~' + type: string + name: + description: Label to match. + minLength: 1 + type: string + regex: + description: Whether to match on equality (false) or regular-expression (true). Deprecated as of AlertManager >= v0.22.0 where a user should use MatchType instead. + type: boolean + value: + description: Label value to match. + type: string + required: + - name + type: object + type: array + muteTimeIntervals: + description: 'Note: this comment applies to the field definition above but appears below otherwise it gets included in the generated manifest. CRD schema doesn''t support self-referential types for now (see https://github.com/kubernetes/kubernetes/issues/62872). We have to use an alternative type to circumvent the limitation. The downside is that the Kube API can''t validate the data beyond the fact that it is a valid JSON representation. MuteTimeIntervals is a list of MuteTimeInterval names that will mute this route when matched,' + items: + type: string + type: array + receiver: + description: Name of the receiver for this route. If not empty, it should be listed in the `receivers` field. + type: string + repeatInterval: + description: 'How long to wait before repeating the last notification. Must match the regular expression`^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$` Example: "4h"' + type: string + routes: + description: Child routes. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + type: object + type: object + type: object + network: + description: Network contains any network related settings. + properties: + ipFilter: + default: + - 0.0.0.0/0 + description: IPFilter is a list of allowed IPv4 CIDR ranges that can access the service. If no IP Filter is set, you may not be able to reach the service. A value of `0.0.0.0/0` will open the service to all addresses on the public internet. + items: + type: string + type: array + type: object + restore: + description: Restore contains settings to control the restore of an instance. + properties: + backupName: + description: BackupName is the name of the specific backup you want to restore. + type: string + claimName: + description: ClaimName specifies the name of the instance you want to restore from. The claim has to be in the same namespace as this new instance. + type: string + recoveryTimeStamp: + description: RecoveryTimeStamp an ISO 8601 date, that holds UTC date indicating at which point-in-time the database has to be restored. This is optional and if no PIT recovery is required, it can be left empty. + pattern: ^(?:[1-9]\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:Z|[+-][01]\d:[0-5]\d)$ + type: string + type: object + scheduling: + description: Scheduling contains settings to control the scheduling of an instance. + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a selector which must match a node’s labels for the pod to be scheduled on that node + type: object + type: object + service: + description: Service contains PostgreSQL DBaaS specific properties + properties: + majorVersion: + default: "15" + description: MajorVersion contains supported version of PostgreSQL. Multiple versions are supported. The latest version "15" is the default version. + enum: + - "12" + - "13" + - "14" + - "15" + type: string + pgSettings: + description: PGSettings contains additional PostgreSQL settings. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for an instance. + type: string + disk: + description: Disk defines the amount of disk space for an instance. + type: string + memory: + description: Memory defines the amount of memory in units of bytes for an instance. + type: string + plan: + description: Plan is the name of the resource plan that defines the compute resources. + type: string + requests: + description: Requests defines CPU and memory requests for an instance + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for an instance. + type: string + memory: + description: Memory defines the amount of memory in units of bytes for an instance. + type: string + type: object + type: object + default: {} + updateStrategy: + description: UpdateStrategy indicates when updates to the instance spec will be applied. + properties: + type: + default: Immediate + description: 'Type indicates the type of the UpdateStrategy. Default is OnRestart. Possible enum values: - `"OnRestart"` indicates that the changes to the spec will only be applied once the instance is restarted by other means, most likely during maintenance. - `"Immediate"` indicates that update will be applied to the instance as soon as the spec changes. Please be aware that this might lead to short downtime.' + enum: + - Immediate + - OnRestart + type: string + type: object + type: object + default: {} + resourceRef: + description: ResourceRef contains a reference to the composite. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a VSHNPostgreSQL. + properties: + ObjectBackupConfigConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + ObjectBucketConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + certificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + instanceNamespace: + description: InstanceNamespace contains the name of the namespace where the instance resides + type: string + localCAConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + namespaceConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + networkPolicyConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + pgclusterConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + pgconfigConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + postgresqlConditions: + description: PostgreSQLConditions contains the status conditions of the backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + profileConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + secretConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/crds/vshn.appcat.vshn.io_vshnredis.yaml b/crds/vshn.appcat.vshn.io_vshnredis.yaml new file mode 100644 index 0000000000..08dbdd5b3e --- /dev/null +++ b/crds/vshn.appcat.vshn.io_vshnredis.yaml @@ -0,0 +1,332 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: vshnredis.vshn.appcat.vshn.io +spec: + group: vshn.appcat.vshn.io + names: + kind: VSHNRedis + listKind: VSHNRedisList + plural: vshnredis + singular: vshnredis + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: VSHNRedis is the API for creating Redis clusters. + 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: Spec defines the desired state of a VSHNRedis. + properties: + parameters: + description: Parameters are the configurable fields of a VSHNRedis. + properties: + scheduling: + description: Scheduling contains settings to control the scheduling of an instance. + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a selector which must match a node’s labels for the pod to be scheduled on that node + type: object + type: object + service: + description: Service contains Redis DBaaS specific properties + properties: + redisSettings: + description: RedisSettings contains additional Redis settings. + type: string + version: + default: "7.0" + description: Version contains supported version of Redis. Multiple versions are supported. The latest version "7.0" is the default version. + enum: + - "6.2" + - "7.0" + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + cpuLimits: + description: CPULimits defines the limits amount of Kubernetes CPUs for an instance. + type: string + cpuRequests: + description: CPURequests defines the requests amount of Kubernetes CPUs for an instance. + type: string + disk: + description: Disk defines the amount of disk space for an instance. + type: string + memoryLimits: + description: MemoryLimits defines the limits amount of memory in units of bytes for an instance. + type: string + memoryRequests: + description: MemoryRequests defines the requests amount of memory in units of bytes for an instance. + type: string + plan: + description: Plan is the name of the resource plan that defines the compute resources. + type: string + type: object + default: {} + tls: + description: TLS contains settings to control tls traffic of a service. + properties: + authClients: + default: true + description: TLSAuthClients enables client authentication requirement + type: boolean + enabled: + default: true + description: TLSEnabled enables TLS traffic for the service + type: boolean + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a VSHNRedis. + properties: + caCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + clientCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + instanceNamespace: + description: InstanceNamespace contains the name of the namespace where the instance resides + type: string + localCAConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + namespaceConditions: + description: RedisConditions contains the status conditions of the backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + selfSignedIssuerConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + serverCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/go.mod b/go.mod index 8b0af90d5d..194eb8feed 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/stretchr/testify v1.8.2 github.com/urfave/cli/v2 v2.25.3 github.com/vektra/mockery/v2 v2.26.1 - github.com/vshn/component-appcat/apis v0.0.0-20230508083110-a8e04b7b9a13 go.uber.org/zap v1.24.0 golang.org/x/text v0.8.0 google.golang.org/grpc v1.52.0 diff --git a/go.sum b/go.sum index 9087725ca3..a32a8745f2 100644 --- a/go.sum +++ b/go.sum @@ -430,7 +430,7 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= @@ -493,8 +493,6 @@ github.com/vektra/mockery/v2 v2.26.1 h1:Y8mlLkWHWjuUpsJBwhFb1LeG1ZnWFvo+prsIuiAB github.com/vektra/mockery/v2 v2.26.1/go.mod h1:BOVUIv65DB6wuTYzoPtyMoBYce3n2C1IcsOdWu6Rpu4= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vshn/component-appcat/apis v0.0.0-20230508083110-a8e04b7b9a13 h1:GoRKKQzu7sUpp82v5+xqsIbWKtQZIv/vrS6+r5UzsaQ= -github.com/vshn/component-appcat/apis v0.0.0-20230508083110-a8e04b7b9a13/go.mod h1:+zmzGcEUhwhz3QlIMMo+XQTRSoIK8MY/kSlIcEzC6I8= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= diff --git a/test/mocks/mock_vshnpostgresqls.go b/test/mocks/mock_vshnpostgresqls.go index 13d36fe657..65fd5f5d9d 100644 --- a/test/mocks/mock_vshnpostgresqls.go +++ b/test/mocks/mock_vshnpostgresqls.go @@ -9,7 +9,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - v1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" ) // MockvshnPostgresqlProvider is a mock of vshnPostgresqlProvider interface. @@ -36,10 +36,10 @@ func (m *MockvshnPostgresqlProvider) EXPECT() *MockvshnPostgresqlProviderMockRec } // ListXVSHNPostgreSQL mocks base method. -func (m *MockvshnPostgresqlProvider) ListXVSHNPostgreSQL(ctx context.Context, namespace string) (*v1.XVSHNPostgreSQLList, error) { +func (m *MockvshnPostgresqlProvider) ListXVSHNPostgreSQL(ctx context.Context, namespace string) (*vshnv1.XVSHNPostgreSQLList, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListXVSHNPostgreSQL", ctx, namespace) - ret0, _ := ret[0].(*v1.XVSHNPostgreSQLList) + ret0, _ := ret[0].(*vshnv1.XVSHNPostgreSQLList) ret1, _ := ret[1].(error) return ret0, ret1 } From f414c9ac1c6ef8fd72ac895040257a32050e4656 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Thu, 11 May 2023 16:29:02 +0200 Subject: [PATCH 06/26] Improve cobra commands --- {command => cmd}/apiserver.go | 12 ++- cmd/controller.go | 77 +++++++++++++++++++ {command => cmd}/grpc.go | 20 ++--- .../sliprober.go | 59 +++++++------- command/root.go | 49 ------------ command/xpostgresql_controller.go | 70 ----------------- command/log.go => log.go | 2 +- main.go | 42 +++++++++- {apiserver => pkg/apiserver}/appcat/appcat.go | 0 .../apiserver}/appcat/appcat_test.go | 0 .../apiserver}/appcat/composition.go | 0 {apiserver => pkg/apiserver}/appcat/create.go | 0 {apiserver => pkg/apiserver}/appcat/delete.go | 0 {apiserver => pkg/apiserver}/appcat/get.go | 2 +- .../apiserver}/appcat/get_test.go | 0 {apiserver => pkg/apiserver}/appcat/list.go | 2 +- .../apiserver}/appcat/list_test.go | 0 {apiserver => pkg/apiserver}/appcat/table.go | 0 .../apiserver}/appcat/table_test.go | 0 {apiserver => pkg/apiserver}/appcat/update.go | 0 {apiserver => pkg/apiserver}/common.go | 0 .../apiserver}/hack/boilerplate.txt | 0 .../apiserver}/vshn/postgres/backup.go | 0 .../apiserver}/vshn/postgres/backup_test.go | 0 .../apiserver}/vshn/postgres/create.go | 0 .../apiserver}/vshn/postgres/delete.go | 0 .../apiserver}/vshn/postgres/get.go | 2 +- .../apiserver}/vshn/postgres/get_test.go | 0 .../apiserver}/vshn/postgres/list.go | 2 +- .../apiserver}/vshn/postgres/list_test.go | 0 .../apiserver}/vshn/postgres/multiwatch.go | 0 .../apiserver}/vshn/postgres/sgbackups.go | 0 .../vshn/postgres/sgbackups_test.go | 0 .../apiserver}/vshn/postgres/table.go | 0 .../apiserver}/vshn/postgres/table_test.go | 0 .../apiserver}/vshn/postgres/update.go | 0 .../vshn/postgres/vshnpostgresql.go | 0 .../vshn/postgres/vshnpostgresql_test.go | 0 .../functions/vshn-postgres-func/alerting.go | 30 ++++---- .../vshn-postgres-func/alerting_test.go | 2 +- .../vshn-postgres-func/common_test.go | 2 +- .../vshn-postgres-func/encrypted_pvc.go | 20 ++--- .../vshn-postgres-func/encrypted_pvc_test.go | 2 +- .../functions/vshn-postgres-func/schedule.go | 10 +-- .../vshn-postgres-func/schedule_test.go | 0 .../functions/vshn-postgres-func/url.go | 14 ++-- .../functions/vshn-postgres-func/url_test.go | 2 +- .../comp-functions}/runtime/desired.go | 0 .../comp-functions}/runtime/logger.go | 0 .../comp-functions}/runtime/observed.go | 0 .../comp-functions}/runtime/result.go | 0 .../comp-functions}/runtime/run.go | 0 .../comp-functions}/runtime/runtime.go | 0 .../comp-functions}/runtime/types.go | 0 .../postgres/deletion_protection.go | 0 .../postgres/deletion_protection_test.go | 0 .../controller}/postgres/reconciler.go | 10 +-- .../controller}/postgres/reconciler_test.go | 4 +- .../sli-exporter/probes/manager.go | 0 .../sli-exporter/probes/manager_test.go | 0 .../sli-exporter/probes/postgresql.go | 0 .../sli-exporter/probes/postgresql_test.go | 0 .../sli-exporter/vshnpostgresql_controller.go | 16 ++-- .../vshnpostgresql_controller_test.go | 34 ++++---- 64 files changed, 246 insertions(+), 239 deletions(-) rename {command => cmd}/apiserver.go (87%) create mode 100644 cmd/controller.go rename {command => cmd}/grpc.go (81%) rename command/postgresql_controller.go => cmd/sliprober.go (58%) delete mode 100644 command/root.go delete mode 100644 command/xpostgresql_controller.go rename command/log.go => log.go (99%) rename {apiserver => pkg/apiserver}/appcat/appcat.go (100%) rename {apiserver => pkg/apiserver}/appcat/appcat_test.go (100%) rename {apiserver => pkg/apiserver}/appcat/composition.go (100%) rename {apiserver => pkg/apiserver}/appcat/create.go (100%) rename {apiserver => pkg/apiserver}/appcat/delete.go (100%) rename {apiserver => pkg/apiserver}/appcat/get.go (94%) rename {apiserver => pkg/apiserver}/appcat/get_test.go (100%) rename {apiserver => pkg/apiserver}/appcat/list.go (98%) rename {apiserver => pkg/apiserver}/appcat/list_test.go (100%) rename {apiserver => pkg/apiserver}/appcat/table.go (100%) rename {apiserver => pkg/apiserver}/appcat/table_test.go (100%) rename {apiserver => pkg/apiserver}/appcat/update.go (100%) rename {apiserver => pkg/apiserver}/common.go (100%) rename {apiserver => pkg/apiserver}/hack/boilerplate.txt (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/backup.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/backup_test.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/create.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/delete.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/get.go (96%) rename {apiserver => pkg/apiserver}/vshn/postgres/get_test.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/list.go (98%) rename {apiserver => pkg/apiserver}/vshn/postgres/list_test.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/multiwatch.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/sgbackups.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/sgbackups_test.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/table.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/table_test.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/update.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/vshnpostgresql.go (100%) rename {apiserver => pkg/apiserver}/vshn/postgres/vshnpostgresql_test.go (100%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/alerting.go (76%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/alerting_test.go (98%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/common_test.go (93%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/encrypted_pvc.go (75%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/encrypted_pvc_test.go (98%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/schedule.go (83%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/schedule_test.go (100%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/url.go (82%) rename {comp-functions => pkg/comp-functions}/functions/vshn-postgres-func/url_test.go (97%) rename {comp-functions => pkg/comp-functions}/runtime/desired.go (100%) rename {comp-functions => pkg/comp-functions}/runtime/logger.go (100%) rename {comp-functions => pkg/comp-functions}/runtime/observed.go (100%) rename {comp-functions => pkg/comp-functions}/runtime/result.go (100%) rename {comp-functions => pkg/comp-functions}/runtime/run.go (100%) rename {comp-functions => pkg/comp-functions}/runtime/runtime.go (100%) rename {comp-functions => pkg/comp-functions}/runtime/types.go (100%) rename {controller => pkg/controller}/postgres/deletion_protection.go (100%) rename {controller => pkg/controller}/postgres/deletion_protection_test.go (100%) rename {controller => pkg/controller}/postgres/reconciler.go (85%) rename {controller => pkg/controller}/postgres/reconciler_test.go (98%) rename {controller => pkg/controller}/sli-exporter/probes/manager.go (100%) rename {controller => pkg/controller}/sli-exporter/probes/manager_test.go (100%) rename {controller => pkg/controller}/sli-exporter/probes/postgresql.go (100%) rename {controller => pkg/controller}/sli-exporter/probes/postgresql_test.go (100%) rename {controller => pkg/controller}/sli-exporter/vshnpostgresql_controller.go (89%) rename {controller => pkg/controller}/sli-exporter/vshnpostgresql_controller_test.go (92%) diff --git a/command/apiserver.go b/cmd/apiserver.go similarity index 87% rename from command/apiserver.go rename to cmd/apiserver.go index f16986ef72..eaa2337bd1 100644 --- a/command/apiserver.go +++ b/cmd/apiserver.go @@ -1,10 +1,10 @@ -package command +package cmd import ( "github.com/spf13/cobra" appcatv1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/apiserver/appcat" - "github.com/vshn/appcat-apiserver/apiserver/vshn/postgres" + "github.com/vshn/appcat-apiserver/pkg/apiserver/appcat" + "github.com/vshn/appcat-apiserver/pkg/apiserver/vshn/postgres" "log" "os" "sigs.k8s.io/apiserver-runtime/pkg/builder" @@ -13,11 +13,15 @@ import ( var apiServerCMDStr = "apiserver" -var apiServerCmd = newAPIServerCMD() +var APIServerCMD = newAPIServerCMD() func newAPIServerCMD() *cobra.Command { var appcatEnabled, vshnBackupsEnabled bool + if len(os.Args) < 2 { + return &cobra.Command{} + } + if os.Args[1] == apiServerCMDStr { appcatEnabled, vshnBackupsEnabled = parseEnvVariables() } diff --git a/cmd/controller.go b/cmd/controller.go new file mode 100644 index 0000000000..9d2e15f79e --- /dev/null +++ b/cmd/controller.go @@ -0,0 +1,77 @@ +package cmd + +import ( + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + "github.com/go-logr/logr" + "github.com/spf13/cobra" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + "github.com/vshn/appcat-apiserver/pkg/controller/postgres" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/healthz" +) + +type controller struct { + scheme *runtime.Scheme + metricsAddr, healthAddr string + leaderElect bool +} + +var c = controller{ + scheme: runtime.NewScheme(), +} + +var ControllerCMD = &cobra.Command{ + Use: "controller", + Short: "Controller", + Long: "Run the Controller", + RunE: c.executeController, +} + +func init() { + _ = corev1.SchemeBuilder.AddToScheme(c.scheme) + _ = xkube.SchemeBuilder.AddToScheme(c.scheme) + _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(c.scheme) + + ControllerCMD.Flags().StringVar(&c.metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + ControllerCMD.Flags().StringVar(&c.healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") + ControllerCMD.Flags().BoolVar(&c.leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") +} + +// Run will run the controller mode of the composition function runner. +func (c *controller) executeController(cmd *cobra.Command, _ []string) error { + log := logr.FromContextOrDiscard(cmd.Context()) + ctrl.SetLogger(log) + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: c.scheme, + Port: 9443, + HealthProbeBindAddress: c.healthAddr, + LeaderElection: c.leaderElect, + LeaderElectionID: "35t6u158.appcat.vshn.io", + }) + if err != nil { + return err + } + + xpg := &postgres.XPostgreSQLReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + } + + err = xpg.SetupWithManager(mgr) + if err != nil { + return err + } + + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + return err + } + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + return err + } + + return mgr.Start(ctrl.SetupSignalHandler()) +} diff --git a/command/grpc.go b/cmd/grpc.go similarity index 81% rename from command/grpc.go rename to cmd/grpc.go index 08d41205f9..11c2821059 100644 --- a/command/grpc.go +++ b/cmd/grpc.go @@ -1,12 +1,12 @@ -package command +package cmd import ( "context" pb "github.com/crossplane/crossplane/apis/apiextensions/fn/proto/v1alpha1" "github.com/go-logr/logr" "github.com/spf13/cobra" - vshnpostgres "github.com/vshn/appcat-apiserver/comp-functions/functions/vshn-postgres-func" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + vpf "github.com/vshn/appcat-apiserver/pkg/comp-functions/functions/vshn-postgres-func" + "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -16,8 +16,8 @@ import ( ) func init() { - grpcCommand.Flags().StringVar(&Network, "network", "unix", "network type") - grpcCommand.Flags().StringVar(&AddressFlag, "socket", "@crossplane/fn/default.sock", "set where socket should be located") + GrpcCMD.Flags().StringVar(&Network, "network", "unix", "network type") + GrpcCMD.Flags().StringVar(&AddressFlag, "socket", "@crossplane/fn/default.sock", "set where socket should be located") } var ( @@ -25,7 +25,7 @@ var ( AddressFlag = "@crossplane/fn/default.sock" ) -var grpcCommand = &cobra.Command{ +var GrpcCMD = &cobra.Command{ Use: "grpc", Short: "GRPC Server", Long: "Run the GRPC Server for crossplane composition functions", @@ -35,19 +35,19 @@ var grpcCommand = &cobra.Command{ var postgresFunctions = []runtime.Transform{ { Name: "url-connection-details", - TransformFunc: vshnpostgres.AddUrlToConnectionDetails, + TransformFunc: vpf.AddUrlToConnectionDetails, }, { Name: "user-alerting", - TransformFunc: vshnpostgres.AddUserAlerting, + TransformFunc: vpf.AddUserAlerting, }, { Name: "random-default-schedule", - TransformFunc: vshnpostgres.TransformSchedule, + TransformFunc: vpf.TransformSchedule, }, { Name: "encrypted-pvc-secret", - TransformFunc: vshnpostgres.AddPvcSecret, + TransformFunc: vpf.AddPvcSecret, }, } diff --git a/command/postgresql_controller.go b/cmd/sliprober.go similarity index 58% rename from command/postgresql_controller.go rename to cmd/sliprober.go index 1847fc2d39..ff975463f4 100644 --- a/command/postgresql_controller.go +++ b/cmd/sliprober.go @@ -1,12 +1,12 @@ -package command +package cmd import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/go-logr/logr" "github.com/spf13/cobra" vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - sli_exporter "github.com/vshn/appcat-apiserver/controller/sli-exporter" - "github.com/vshn/appcat-apiserver/controller/sli-exporter/probes" + "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter" + probes2 "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter/probes" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "os" @@ -17,46 +17,53 @@ import ( "time" ) -func init() { - _ = corev1.SchemeBuilder.AddToScheme(s_prober) - _ = xkube.SchemeBuilder.AddToScheme(s_prober) - _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s_prober) +type sliProber struct { + scheme *runtime.Scheme + metricsAddr, probeAddr string + leaderElect, enableVSHNPostgreSQL bool +} - sliProber.Flags().StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") - sliProber.Flags().StringVar(&healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") - sliProber.Flags().BoolVar(&leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") - sliProber.Flags().BoolVar(&enableVSHNPostgreSQL, "vshn-postgresql", getEnvBool("APPCAT_SLI_VSHNPOSTGRESQL"), - "Enable probing of VSHNPostgreSQL instances") +var s = sliProber{ + scheme: runtime.NewScheme(), } -var sliProber = &cobra.Command{ - Use: "sli-prober", +var SLIProberCMD = &cobra.Command{ + Use: "sliprober", Short: "SLI Prober Controller", Long: "Run the SLI Prober Controller", - RunE: executeProberController, + RunE: s.executeSLIProber, } -var s_prober = runtime.NewScheme() +func init() { + _ = corev1.SchemeBuilder.AddToScheme(s.scheme) + _ = xkube.SchemeBuilder.AddToScheme(s.scheme) + _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s.scheme) + + SLIProberCMD.Flags().StringVar(&s.metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + SLIProberCMD.Flags().StringVar(&s.probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + SLIProberCMD.Flags().BoolVar(&s.leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + SLIProberCMD.Flags().BoolVar(&s.enableVSHNPostgreSQL, "vshn-postgresql", getEnvBool("APPCAT_SLI_VSHNPOSTGRESQL"), + "Enable probing of VSHNPostgreSQL instances") +} -// Run will run the controller mode of the composition function runner. -func executeProberController(cmd *cobra.Command, _ []string) error { +func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { log := logr.FromContextOrDiscard(cmd.Context()) ctrl.SetLogger(log) mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: s_prober, - MetricsBindAddress: metricsAddr, + Scheme: s.scheme, + MetricsBindAddress: s.metricsAddr, Port: 9443, - HealthProbeBindAddress: probeAddr, - LeaderElection: leaderElect, + HealthProbeBindAddress: s.probeAddr, + LeaderElection: s.leaderElect, LeaderElectionID: "05f8b574.appcat.vshn.io", }) if err != nil { log.Error(err, "unable to start manager") return err } - probeManager := probes.NewManager(log) + probeManager := probes2.NewManager(log) err = metrics.Registry.Register(probeManager.Collector()) if err != nil { @@ -64,13 +71,13 @@ func executeProberController(cmd *cobra.Command, _ []string) error { return err } - if enableVSHNPostgreSQL { + if s.enableVSHNPostgreSQL { if err = (&sli_exporter.VSHNPostgreSQLReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), ProbeManager: &probeManager, StartupGracePeriod: 15 * time.Minute, - PostgreDialer: probes.NewPostgreSQL, + PostgreDialer: probes2.NewPostgreSQL, }).SetupWithManager(mgr); err != nil { log.Error(err, "unable to create controller", "controller", "VSHNPostgreSQL") return err diff --git a/command/root.go b/command/root.go deleted file mode 100644 index 1017071a09..0000000000 --- a/command/root.go +++ /dev/null @@ -1,49 +0,0 @@ -package command - -import ( - "fmt" - "github.com/spf13/cobra" - "github.com/spf13/viper" - "os" -) - -var ( - metricsAddr, healthAddr, probeAddr string - leaderElect, enableVSHNPostgreSQL bool -) - -var ( - logLevel int - logFormat string - rootCmd = &cobra.Command{ - Short: "API Server for AppCat", - PersistentPreRunE: setupLogging, - } -) - -func init() { - rootCmd.PersistentFlags().IntVarP(&logLevel, "log-level", "v", 0, "Number of the log level verbosity.") - rootCmd.PersistentFlags().StringVar(&logFormat, "log-format", "console", "Sets the log format (values: [json, console]).") - viper.AutomaticEnv() -} - -// Execute executes the root command. -func Execute() { - if err := rootCmd.Execute(); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - -func init() { - rootCmd.AddCommand(xpostgresql, apiServerCmd, sliProber, grpcCommand) -} - -func setupLogging(cmd *cobra.Command, _ []string) error { - err := SetupLogging(cmd, logLevel, logFormat) - if err != nil { - return err - } - - return LogMetadata(cmd) -} diff --git a/command/xpostgresql_controller.go b/command/xpostgresql_controller.go deleted file mode 100644 index 5bc44e9279..0000000000 --- a/command/xpostgresql_controller.go +++ /dev/null @@ -1,70 +0,0 @@ -package command - -import ( - xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" - "github.com/go-logr/logr" - "github.com/spf13/cobra" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/controller/postgres" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/healthz" -) - -func init() { - _ = corev1.SchemeBuilder.AddToScheme(s_xpostgres) - _ = xkube.SchemeBuilder.AddToScheme(s_xpostgres) - _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s_xpostgres) - - xpostgresql.Flags().StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") - xpostgresql.Flags().StringVar(&healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") - xpostgresql.Flags().BoolVar(&leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ - "Enabling this will ensure there is only one active controller manager.") -} - -var xpostgresql = &cobra.Command{ - Use: "postgres-controller", - Short: "Postgres Controller", - Long: "Run the Postgres Controller", - RunE: executeXVSHNPostgreSQLController, -} - -var s_xpostgres = runtime.NewScheme() - -// Run will run the controller mode of the composition function runner. -func executeXVSHNPostgreSQLController(cmd *cobra.Command, _ []string) error { - log := logr.FromContextOrDiscard(cmd.Context()) - ctrl.SetLogger(log) - - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ - Scheme: s_xpostgres, - MetricsBindAddress: metricsAddr, - Port: 9443, - HealthProbeBindAddress: healthAddr, - LeaderElection: leaderElect, - LeaderElectionID: "35t6u158.appcat.vshn.io", - }) - if err != nil { - return err - } - - xpg := &postgres.XPostgreSQLDeletionProtectionReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - } - - err = xpg.SetupWithManager(mgr) - if err != nil { - return err - } - - if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { - return err - } - if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { - return err - } - - return mgr.Start(ctrl.SetupSignalHandler()) -} diff --git a/command/log.go b/log.go similarity index 99% rename from command/log.go rename to log.go index f5e78fe4c6..0ca21abc50 100644 --- a/command/log.go +++ b/log.go @@ -1,4 +1,4 @@ -package command +package main import ( "fmt" diff --git a/main.go b/main.go index 323faab6c9..f717c4ee06 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,45 @@ package main -import "github.com/vshn/appcat-apiserver/command" +import ( + "fmt" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/vshn/appcat-apiserver/cmd" + "os" +) + +func init() { + rootCmd.AddCommand(cmd.ControllerCMD, cmd.APIServerCMD, cmd.SLIProberCMD, cmd.GrpcCMD) +} func main() { - command.Execute() + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +var ( + logLevel int + logFormat string + rootCmd = &cobra.Command{ + Short: "AppCat", + Long: "AppCat controllers, api servers, grpc servers and probers", + PersistentPreRunE: setupLogging, + } +) + +func init() { + rootCmd.PersistentFlags().IntVarP(&logLevel, "log-level", "v", 0, "Number of the log level verbosity.") + rootCmd.PersistentFlags().StringVar(&logFormat, "log-format", "console", "Sets the log format (values: [json, console]).") + viper.AutomaticEnv() +} + +func setupLogging(cmd *cobra.Command, _ []string) error { + err := SetupLogging(cmd, logLevel, logFormat) + if err != nil { + return err + } + + return LogMetadata(cmd) } diff --git a/apiserver/appcat/appcat.go b/pkg/apiserver/appcat/appcat.go similarity index 100% rename from apiserver/appcat/appcat.go rename to pkg/apiserver/appcat/appcat.go diff --git a/apiserver/appcat/appcat_test.go b/pkg/apiserver/appcat/appcat_test.go similarity index 100% rename from apiserver/appcat/appcat_test.go rename to pkg/apiserver/appcat/appcat_test.go diff --git a/apiserver/appcat/composition.go b/pkg/apiserver/appcat/composition.go similarity index 100% rename from apiserver/appcat/composition.go rename to pkg/apiserver/appcat/composition.go diff --git a/apiserver/appcat/create.go b/pkg/apiserver/appcat/create.go similarity index 100% rename from apiserver/appcat/create.go rename to pkg/apiserver/appcat/create.go diff --git a/apiserver/appcat/delete.go b/pkg/apiserver/appcat/delete.go similarity index 100% rename from apiserver/appcat/delete.go rename to pkg/apiserver/appcat/delete.go diff --git a/apiserver/appcat/get.go b/pkg/apiserver/appcat/get.go similarity index 94% rename from apiserver/appcat/get.go rename to pkg/apiserver/appcat/get.go index e814f37c85..9e245e4a06 100644 --- a/apiserver/appcat/get.go +++ b/pkg/apiserver/appcat/get.go @@ -3,7 +3,7 @@ package appcat import ( "context" v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/apiserver" + "github.com/vshn/appcat-apiserver/pkg/apiserver" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/apiserver/appcat/get_test.go b/pkg/apiserver/appcat/get_test.go similarity index 100% rename from apiserver/appcat/get_test.go rename to pkg/apiserver/appcat/get_test.go diff --git a/apiserver/appcat/list.go b/pkg/apiserver/appcat/list.go similarity index 98% rename from apiserver/appcat/list.go rename to pkg/apiserver/appcat/list.go index 11fb75256a..ae5513aec9 100644 --- a/apiserver/appcat/list.go +++ b/pkg/apiserver/appcat/list.go @@ -4,7 +4,7 @@ import ( "context" crossplanev1 "github.com/crossplane/crossplane/apis/apiextensions/v1" "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/apiserver" + "github.com/vshn/appcat-apiserver/pkg/apiserver" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" diff --git a/apiserver/appcat/list_test.go b/pkg/apiserver/appcat/list_test.go similarity index 100% rename from apiserver/appcat/list_test.go rename to pkg/apiserver/appcat/list_test.go diff --git a/apiserver/appcat/table.go b/pkg/apiserver/appcat/table.go similarity index 100% rename from apiserver/appcat/table.go rename to pkg/apiserver/appcat/table.go diff --git a/apiserver/appcat/table_test.go b/pkg/apiserver/appcat/table_test.go similarity index 100% rename from apiserver/appcat/table_test.go rename to pkg/apiserver/appcat/table_test.go diff --git a/apiserver/appcat/update.go b/pkg/apiserver/appcat/update.go similarity index 100% rename from apiserver/appcat/update.go rename to pkg/apiserver/appcat/update.go diff --git a/apiserver/common.go b/pkg/apiserver/common.go similarity index 100% rename from apiserver/common.go rename to pkg/apiserver/common.go diff --git a/apiserver/hack/boilerplate.txt b/pkg/apiserver/hack/boilerplate.txt similarity index 100% rename from apiserver/hack/boilerplate.txt rename to pkg/apiserver/hack/boilerplate.txt diff --git a/apiserver/vshn/postgres/backup.go b/pkg/apiserver/vshn/postgres/backup.go similarity index 100% rename from apiserver/vshn/postgres/backup.go rename to pkg/apiserver/vshn/postgres/backup.go diff --git a/apiserver/vshn/postgres/backup_test.go b/pkg/apiserver/vshn/postgres/backup_test.go similarity index 100% rename from apiserver/vshn/postgres/backup_test.go rename to pkg/apiserver/vshn/postgres/backup_test.go diff --git a/apiserver/vshn/postgres/create.go b/pkg/apiserver/vshn/postgres/create.go similarity index 100% rename from apiserver/vshn/postgres/create.go rename to pkg/apiserver/vshn/postgres/create.go diff --git a/apiserver/vshn/postgres/delete.go b/pkg/apiserver/vshn/postgres/delete.go similarity index 100% rename from apiserver/vshn/postgres/delete.go rename to pkg/apiserver/vshn/postgres/delete.go diff --git a/apiserver/vshn/postgres/get.go b/pkg/apiserver/vshn/postgres/get.go similarity index 96% rename from apiserver/vshn/postgres/get.go rename to pkg/apiserver/vshn/postgres/get.go index 605ee4b426..84e65ff4a1 100644 --- a/apiserver/vshn/postgres/get.go +++ b/pkg/apiserver/vshn/postgres/get.go @@ -4,7 +4,7 @@ import ( "context" "fmt" "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/apiserver" + "github.com/vshn/appcat-apiserver/pkg/apiserver" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/apiserver/vshn/postgres/get_test.go b/pkg/apiserver/vshn/postgres/get_test.go similarity index 100% rename from apiserver/vshn/postgres/get_test.go rename to pkg/apiserver/vshn/postgres/get_test.go diff --git a/apiserver/vshn/postgres/list.go b/pkg/apiserver/vshn/postgres/list.go similarity index 98% rename from apiserver/vshn/postgres/list.go rename to pkg/apiserver/vshn/postgres/list.go index 645e652a22..573a290d7e 100644 --- a/apiserver/vshn/postgres/list.go +++ b/pkg/apiserver/vshn/postgres/list.go @@ -4,7 +4,7 @@ import ( "context" "fmt" "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/apiserver" + "github.com/vshn/appcat-apiserver/pkg/apiserver" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" diff --git a/apiserver/vshn/postgres/list_test.go b/pkg/apiserver/vshn/postgres/list_test.go similarity index 100% rename from apiserver/vshn/postgres/list_test.go rename to pkg/apiserver/vshn/postgres/list_test.go diff --git a/apiserver/vshn/postgres/multiwatch.go b/pkg/apiserver/vshn/postgres/multiwatch.go similarity index 100% rename from apiserver/vshn/postgres/multiwatch.go rename to pkg/apiserver/vshn/postgres/multiwatch.go diff --git a/apiserver/vshn/postgres/sgbackups.go b/pkg/apiserver/vshn/postgres/sgbackups.go similarity index 100% rename from apiserver/vshn/postgres/sgbackups.go rename to pkg/apiserver/vshn/postgres/sgbackups.go diff --git a/apiserver/vshn/postgres/sgbackups_test.go b/pkg/apiserver/vshn/postgres/sgbackups_test.go similarity index 100% rename from apiserver/vshn/postgres/sgbackups_test.go rename to pkg/apiserver/vshn/postgres/sgbackups_test.go diff --git a/apiserver/vshn/postgres/table.go b/pkg/apiserver/vshn/postgres/table.go similarity index 100% rename from apiserver/vshn/postgres/table.go rename to pkg/apiserver/vshn/postgres/table.go diff --git a/apiserver/vshn/postgres/table_test.go b/pkg/apiserver/vshn/postgres/table_test.go similarity index 100% rename from apiserver/vshn/postgres/table_test.go rename to pkg/apiserver/vshn/postgres/table_test.go diff --git a/apiserver/vshn/postgres/update.go b/pkg/apiserver/vshn/postgres/update.go similarity index 100% rename from apiserver/vshn/postgres/update.go rename to pkg/apiserver/vshn/postgres/update.go diff --git a/apiserver/vshn/postgres/vshnpostgresql.go b/pkg/apiserver/vshn/postgres/vshnpostgresql.go similarity index 100% rename from apiserver/vshn/postgres/vshnpostgresql.go rename to pkg/apiserver/vshn/postgres/vshnpostgresql.go diff --git a/apiserver/vshn/postgres/vshnpostgresql_test.go b/pkg/apiserver/vshn/postgres/vshnpostgresql_test.go similarity index 100% rename from apiserver/vshn/postgres/vshnpostgresql_test.go rename to pkg/apiserver/vshn/postgres/vshnpostgresql_test.go diff --git a/comp-functions/functions/vshn-postgres-func/alerting.go b/pkg/comp-functions/functions/vshn-postgres-func/alerting.go similarity index 76% rename from comp-functions/functions/vshn-postgres-func/alerting.go rename to pkg/comp-functions/functions/vshn-postgres-func/alerting.go index 7d8ded1c7a..a850e3658c 100644 --- a/comp-functions/functions/vshn-postgres-func/alerting.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/alerting.go @@ -2,7 +2,7 @@ package vshnpostgres import ( "context" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" controllerruntime "sigs.k8s.io/controller-runtime" xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" @@ -14,25 +14,25 @@ import ( ) // AddUserAlerting adds user alerting to the PostgreSQL instance. -func AddUserAlerting(ctx context.Context, iof *runtime.Runtime) runtime.Result { +func AddUserAlerting(ctx context.Context, iof *runtime2.Runtime) runtime2.Result { log := controllerruntime.LoggerFrom(ctx) log.Info("Check if alerting references are set") log.V(1).Info("Transforming", "obj", iof) - err := runtime.AddToScheme(alertmanagerv1alpha1.SchemeBuilder) + err := runtime2.AddToScheme(alertmanagerv1alpha1.SchemeBuilder) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot add scheme builder to scheme", err) + return runtime2.NewFatalErr(ctx, "Cannot add scheme builder to scheme", err) } comp := &vshnv1.VSHNPostgreSQL{} err = iof.Observed.GetComposite(ctx, comp) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot get composite from function io", err) + return runtime2.NewFatalErr(ctx, "Cannot get composite from function io", err) } // Wait for the next reconciliation in case instance namespace is missing if comp.Status.InstanceNamespace == "" { - return runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + return runtime2.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") } monitoringSpec := comp.Spec.Parameters.Monitoring @@ -40,7 +40,7 @@ func AddUserAlerting(ctx context.Context, iof *runtime.Runtime) runtime.Result { if monitoringSpec.AlertmanagerConfigRef != "" { if monitoringSpec.AlertmanagerConfigSecretRef == "" { - return runtime.NewFatal(ctx, "Found AlertmanagerConfigRef but no AlertmanagerConfigSecretRef, please specify as well") + return runtime2.NewFatal(ctx, "Found AlertmanagerConfigRef but no AlertmanagerConfigSecretRef, please specify as well") } refName := comp.Spec.Parameters.Monitoring.AlertmanagerConfigRef @@ -48,21 +48,21 @@ func AddUserAlerting(ctx context.Context, iof *runtime.Runtime) runtime.Result { err = deployAlertmanagerFromRef(ctx, comp, iof) if err != nil { - return runtime.NewFatalErr(ctx, "Could not deploy alertmanager from ref", err) + return runtime2.NewFatalErr(ctx, "Could not deploy alertmanager from ref", err) } } if monitoringSpec.AlertmanagerConfigSpecTemplate != nil { if monitoringSpec.AlertmanagerConfigSecretRef == "" { - return runtime.NewFatal(ctx, "Found AlertmanagerConfigTemplate but no AlertmanagerConfigSecretRef, please specify as well") + return runtime2.NewFatal(ctx, "Found AlertmanagerConfigTemplate but no AlertmanagerConfigSecretRef, please specify as well") } log.Info("Found an AlertmanagerConfigTemplate, deploying...") err = deployAlertmanagerFromTemplate(ctx, comp, iof) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot deploy alertmanager from template", err) + return runtime2.NewFatalErr(ctx, "Cannot deploy alertmanager from template", err) } } @@ -72,14 +72,14 @@ func AddUserAlerting(ctx context.Context, iof *runtime.Runtime) runtime.Result { err = deploySecretRef(ctx, comp, iof) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot deploy secret ref", err) + return runtime2.NewFatalErr(ctx, "Cannot deploy secret ref", err) } } - return runtime.NewNormal() + return runtime2.NewNormal() } -func deployAlertmanagerFromRef(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime.Runtime) error { +func deployAlertmanagerFromRef(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime2.Runtime) error { ac := &alertmanagerv1alpha1.AlertmanagerConfig{ ObjectMeta: metav1.ObjectMeta{ Name: "postgresql-alertmanagerconfig", @@ -103,7 +103,7 @@ func deployAlertmanagerFromRef(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, return iof.Desired.PutIntoObject(ctx, ac, comp.Name+"-alertmanagerconfig", xRef) } -func deployAlertmanagerFromTemplate(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime.Runtime) error { +func deployAlertmanagerFromTemplate(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime2.Runtime) error { ac := &alertmanagerv1alpha1.AlertmanagerConfig{ ObjectMeta: metav1.ObjectMeta{ Name: comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef, @@ -115,7 +115,7 @@ func deployAlertmanagerFromTemplate(ctx context.Context, comp *vshnv1.VSHNPostgr return iof.Desired.PutIntoObject(ctx, ac, comp.Name+"-alertmanagerconfig") } -func deploySecretRef(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime.Runtime) error { +func deploySecretRef(ctx context.Context, comp *vshnv1.VSHNPostgreSQL, iof *runtime2.Runtime) error { s := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: comp.Spec.Parameters.Monitoring.AlertmanagerConfigSecretRef, diff --git a/comp-functions/functions/vshn-postgres-func/alerting_test.go b/pkg/comp-functions/functions/vshn-postgres-func/alerting_test.go similarity index 98% rename from comp-functions/functions/vshn-postgres-func/alerting_test.go rename to pkg/comp-functions/functions/vshn-postgres-func/alerting_test.go index c708bebac8..cd8dd6a2ae 100644 --- a/comp-functions/functions/vshn-postgres-func/alerting_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/alerting_test.go @@ -6,7 +6,7 @@ import ( xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" v1 "k8s.io/api/core/v1" "testing" diff --git a/comp-functions/functions/vshn-postgres-func/common_test.go b/pkg/comp-functions/functions/vshn-postgres-func/common_test.go similarity index 93% rename from comp-functions/functions/vshn-postgres-func/common_test.go rename to pkg/comp-functions/functions/vshn-postgres-func/common_test.go index 3958bf05d5..4c8c36f5e1 100644 --- a/comp-functions/functions/vshn-postgres-func/common_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/common_test.go @@ -2,7 +2,7 @@ package vshnpostgres import ( "context" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" "os" "path/filepath" "reflect" diff --git a/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go similarity index 75% rename from comp-functions/functions/vshn-postgres-func/encrypted_pvc.go rename to pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go index 73f4901832..28e18912c3 100644 --- a/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go @@ -3,7 +3,7 @@ package vshnpostgres import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" "github.com/sethvargo/go-password/password" controllerruntime "sigs.k8s.io/controller-runtime" @@ -14,7 +14,7 @@ import ( ) // AddPvcSecret adds a secret for the encrypted PVC for the PostgreSQL instance. -func AddPvcSecret(ctx context.Context, iof *runtime.Runtime) runtime.Result { +func AddPvcSecret(ctx context.Context, iof *runtime2.Runtime) runtime2.Result { log := controllerruntime.LoggerFrom(ctx) @@ -22,7 +22,7 @@ func AddPvcSecret(ctx context.Context, iof *runtime.Runtime) runtime.Result { err := iof.Observed.GetComposite(ctx, comp) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot get composite", err) + return runtime2.NewFatalErr(ctx, "Cannot get composite", err) } log.Info("Check if encrypted storage is enabled") @@ -32,11 +32,11 @@ func AddPvcSecret(ctx context.Context, iof *runtime.Runtime) runtime.Result { if !encryptionSpec.Enabled { log.Info("Encryption not enabled") - return runtime.NewNormal() + return runtime2.NewNormal() } if comp.Status.InstanceNamespace == "" { - return runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + return runtime2.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") } log.Info("Adding secret to composite") @@ -51,17 +51,17 @@ func AddPvcSecret(ctx context.Context, iof *runtime.Runtime) runtime.Result { err = iof.Observed.GetFromObject(ctx, secret, luksSecretResourceName) luksKey := "" - if err == runtime.ErrNotFound { + if err == runtime2.ErrNotFound { log.Info("Secret does not exist yet. Creating...") luksKey, err = password.Generate(64, 10, 1, false, true) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot generate new luksKey", err) + return runtime2.NewFatalErr(ctx, "Cannot generate new luksKey", err) } } else if err == nil { log.Info("retreiviing existing secret key...") luksKey = string(secret.Data["luksKey"]) } else { - return runtime.NewFatalErr(ctx, "Cannot get luks secret object", err) + return runtime2.NewFatalErr(ctx, "Cannot get luks secret object", err) } secret = &v1.Secret{ @@ -75,8 +75,8 @@ func AddPvcSecret(ctx context.Context, iof *runtime.Runtime) runtime.Result { } err = iof.Desired.PutIntoObject(ctx, secret, luksSecretResourceName) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot add luks secret object", err) + return runtime2.NewFatalErr(ctx, "Cannot add luks secret object", err) } - return runtime.NewNormal() + return runtime2.NewNormal() } diff --git a/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go similarity index 98% rename from comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go rename to pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go index 1519a7b9a3..d010c86d4b 100644 --- a/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go @@ -2,7 +2,7 @@ package vshnpostgres import ( "context" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" "testing" xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" diff --git a/comp-functions/functions/vshn-postgres-func/schedule.go b/pkg/comp-functions/functions/vshn-postgres-func/schedule.go similarity index 83% rename from comp-functions/functions/vshn-postgres-func/schedule.go rename to pkg/comp-functions/functions/vshn-postgres-func/schedule.go index d531fea875..eea4f5f9ff 100644 --- a/comp-functions/functions/vshn-postgres-func/schedule.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/schedule.go @@ -3,7 +3,7 @@ package vshnpostgres import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" "math/rand" "time" @@ -19,12 +19,12 @@ var ( // TransformSchedule initializes the backup and maintenance schedules if the user did not explicitly provide a schedule. // The maintenance will be set to a random time on Tuesday night between 21:00 and 5:00, and the backup schedule will be set to once a day between 20:00 and 4:00. // If neither maintenance nor backup is set, the function will make sure that there will be backup scheduled one hour before the maintenance. -func TransformSchedule(ctx context.Context, iof *runtime.Runtime) runtime.Result { +func TransformSchedule(ctx context.Context, iof *runtime2.Runtime) runtime2.Result { comp := vshnv1.VSHNPostgreSQL{} err := iof.Desired.GetComposite(ctx, &comp) if err != nil { - return runtime.NewFatalErr(ctx, "failed to parse composite", err) + return runtime2.NewFatalErr(ctx, "failed to parse composite", err) } rng := rand.New(rand.NewSource(time.Now().UnixNano())) @@ -49,8 +49,8 @@ func TransformSchedule(ctx context.Context, iof *runtime.Runtime) runtime.Result err = iof.Desired.SetComposite(ctx, &comp) if err != nil { - return runtime.NewFatalErr(ctx, "failed to set composite", err) + return runtime2.NewFatalErr(ctx, "failed to set composite", err) } - return runtime.NewNormal() + return runtime2.NewNormal() } diff --git a/comp-functions/functions/vshn-postgres-func/schedule_test.go b/pkg/comp-functions/functions/vshn-postgres-func/schedule_test.go similarity index 100% rename from comp-functions/functions/vshn-postgres-func/schedule_test.go rename to pkg/comp-functions/functions/vshn-postgres-func/schedule_test.go diff --git a/comp-functions/functions/vshn-postgres-func/url.go b/pkg/comp-functions/functions/vshn-postgres-func/url.go similarity index 82% rename from comp-functions/functions/vshn-postgres-func/url.go rename to pkg/comp-functions/functions/vshn-postgres-func/url.go index 97f31e2758..f50906d0e2 100644 --- a/comp-functions/functions/vshn-postgres-func/url.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/url.go @@ -4,7 +4,7 @@ import ( "context" "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" v1 "k8s.io/api/core/v1" controllerruntime "sigs.k8s.io/controller-runtime" ) @@ -31,18 +31,18 @@ var ( var connectionSecretResourceName = "connection" // AddUrlToConnectionDetails changes the desired state of a FunctionIO -func AddUrlToConnectionDetails(ctx context.Context, iof *runtime.Runtime) runtime.Result { +func AddUrlToConnectionDetails(ctx context.Context, iof *runtime2.Runtime) runtime2.Result { log := controllerruntime.LoggerFrom(ctx) comp := &vshnv1.VSHNPostgreSQL{} err := iof.Desired.GetComposite(ctx, comp) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot get composite from function io", err) + return runtime2.NewFatalErr(ctx, "Cannot get composite from function io", err) } // Wait for the next reconciliation in case instance namespace is missing if comp.Status.InstanceNamespace == "" { - return runtime.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") + return runtime2.NewWarning(ctx, "Composite is missing instance namespace, skipping transformation") } log.Info("Getting connection secret from managed kubernetes object") @@ -50,20 +50,20 @@ func AddUrlToConnectionDetails(ctx context.Context, iof *runtime.Runtime) runtim err = iof.Observed.GetFromObject(ctx, s, connectionSecretResourceName) if err != nil { - return runtime.NewFatalErr(ctx, "Cannot get connection secret object", err) + return runtime2.NewFatalErr(ctx, "Cannot get connection secret object", err) } log.Info("Setting POSTRESQL_URL env variable into connection secret") val := getPostgresURL(s) if val == "" { - return runtime.NewWarning(ctx, "User, pass, host, port or db value is missing from connection secret, skipping transformation") + return runtime2.NewWarning(ctx, "User, pass, host, port or db value is missing from connection secret, skipping transformation") } iof.Desired.PutCompositeConnectionDetail(ctx, v1alpha1.ExplicitConnectionDetail{ Name: PostgresqlUrl, Value: val, }) - return runtime.NewNormal() + return runtime2.NewNormal() } func getPostgresURL(s *v1.Secret) string { diff --git a/comp-functions/functions/vshn-postgres-func/url_test.go b/pkg/comp-functions/functions/vshn-postgres-func/url_test.go similarity index 97% rename from comp-functions/functions/vshn-postgres-func/url_test.go rename to pkg/comp-functions/functions/vshn-postgres-func/url_test.go index 32ee025029..78ba7b9057 100644 --- a/comp-functions/functions/vshn-postgres-func/url_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/url_test.go @@ -2,7 +2,7 @@ package vshnpostgres import ( "context" - "github.com/vshn/appcat-apiserver/comp-functions/runtime" + "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" "testing" "github.com/stretchr/testify/assert" diff --git a/comp-functions/runtime/desired.go b/pkg/comp-functions/runtime/desired.go similarity index 100% rename from comp-functions/runtime/desired.go rename to pkg/comp-functions/runtime/desired.go diff --git a/comp-functions/runtime/logger.go b/pkg/comp-functions/runtime/logger.go similarity index 100% rename from comp-functions/runtime/logger.go rename to pkg/comp-functions/runtime/logger.go diff --git a/comp-functions/runtime/observed.go b/pkg/comp-functions/runtime/observed.go similarity index 100% rename from comp-functions/runtime/observed.go rename to pkg/comp-functions/runtime/observed.go diff --git a/comp-functions/runtime/result.go b/pkg/comp-functions/runtime/result.go similarity index 100% rename from comp-functions/runtime/result.go rename to pkg/comp-functions/runtime/result.go diff --git a/comp-functions/runtime/run.go b/pkg/comp-functions/runtime/run.go similarity index 100% rename from comp-functions/runtime/run.go rename to pkg/comp-functions/runtime/run.go diff --git a/comp-functions/runtime/runtime.go b/pkg/comp-functions/runtime/runtime.go similarity index 100% rename from comp-functions/runtime/runtime.go rename to pkg/comp-functions/runtime/runtime.go diff --git a/comp-functions/runtime/types.go b/pkg/comp-functions/runtime/types.go similarity index 100% rename from comp-functions/runtime/types.go rename to pkg/comp-functions/runtime/types.go diff --git a/controller/postgres/deletion_protection.go b/pkg/controller/postgres/deletion_protection.go similarity index 100% rename from controller/postgres/deletion_protection.go rename to pkg/controller/postgres/deletion_protection.go diff --git a/controller/postgres/deletion_protection_test.go b/pkg/controller/postgres/deletion_protection_test.go similarity index 100% rename from controller/postgres/deletion_protection_test.go rename to pkg/controller/postgres/deletion_protection_test.go diff --git a/controller/postgres/reconciler.go b/pkg/controller/postgres/reconciler.go similarity index 85% rename from controller/postgres/reconciler.go rename to pkg/controller/postgres/reconciler.go index 3660728bbd..bd96053953 100644 --- a/controller/postgres/reconciler.go +++ b/pkg/controller/postgres/reconciler.go @@ -17,12 +17,12 @@ import ( logging "sigs.k8s.io/controller-runtime/pkg/log" ) -type XPostgreSQLDeletionProtectionReconciler struct { +type XPostgreSQLReconciler struct { client.Client Scheme *runtime.Scheme } -func (p *XPostgreSQLDeletionProtectionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { +func (p *XPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := logging.FromContext(ctx, "namespace", req.Namespace, "instance", req.Name) inst := &vshnv1.XVSHNPostgreSQL{} err := p.Get(ctx, req.NamespacedName, inst) @@ -51,7 +51,7 @@ func (p *XPostgreSQLDeletionProtectionReconciler) Reconcile(ctx context.Context, }, err } -func (p *XPostgreSQLDeletionProtectionReconciler) handleDeletionProtection(ctx context.Context, inst *vshnv1.XVSHNPostgreSQL) error { +func (p *XPostgreSQLReconciler) handleDeletionProtection(ctx context.Context, inst *vshnv1.XVSHNPostgreSQL) error { log := logging.FromContext(ctx, "namespace", inst.GetNamespace(), "instance", inst.GetName()) protectionEnabled := inst.Spec.Parameters.Backup.DeletionProtection @@ -100,7 +100,7 @@ func (p *XPostgreSQLDeletionProtectionReconciler) handleDeletionProtection(ctx c return nil } -func (p *XPostgreSQLDeletionProtectionReconciler) deletePostgresDB(ctx context.Context, inst *vshnv1.XVSHNPostgreSQL) error { +func (p *XPostgreSQLReconciler) deletePostgresDB(ctx context.Context, inst *vshnv1.XVSHNPostgreSQL) error { log := logging.FromContext(ctx, "namespace", inst.GetNamespace(), "instance", inst.GetName()) log.V(1).Info("Deleting sgcluster object") @@ -118,7 +118,7 @@ func (p *XPostgreSQLDeletionProtectionReconciler) deletePostgresDB(ctx context.C } // SetupWithManager sets up the controller with the Manager. -func (p *XPostgreSQLDeletionProtectionReconciler) SetupWithManager(mgr ctrl.Manager) error { +func (p *XPostgreSQLReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&vshnv1.XVSHNPostgreSQL{}). Owns(&corev1.Namespace{}). diff --git a/controller/postgres/reconciler_test.go b/pkg/controller/postgres/reconciler_test.go similarity index 98% rename from controller/postgres/reconciler_test.go rename to pkg/controller/postgres/reconciler_test.go index 6751d5bbdf..e1bb0dba92 100644 --- a/controller/postgres/reconciler_test.go +++ b/pkg/controller/postgres/reconciler_test.go @@ -7,7 +7,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/stretchr/testify/assert" - v1 "github.com/vshn/component-appcat/apis/vshn/v1" + v1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -245,7 +245,7 @@ func Test_Reconcile(t *testing.T) { WithScheme(s). WithObjects(&tc.inst, &tc.instanceNamespace). Build() - reconciler := XPostgreSQLDeletionProtectionReconciler{ + reconciler := XPostgreSQLReconciler{ Client: fclient, } diff --git a/controller/sli-exporter/probes/manager.go b/pkg/controller/sli-exporter/probes/manager.go similarity index 100% rename from controller/sli-exporter/probes/manager.go rename to pkg/controller/sli-exporter/probes/manager.go diff --git a/controller/sli-exporter/probes/manager_test.go b/pkg/controller/sli-exporter/probes/manager_test.go similarity index 100% rename from controller/sli-exporter/probes/manager_test.go rename to pkg/controller/sli-exporter/probes/manager_test.go diff --git a/controller/sli-exporter/probes/postgresql.go b/pkg/controller/sli-exporter/probes/postgresql.go similarity index 100% rename from controller/sli-exporter/probes/postgresql.go rename to pkg/controller/sli-exporter/probes/postgresql.go diff --git a/controller/sli-exporter/probes/postgresql_test.go b/pkg/controller/sli-exporter/probes/postgresql_test.go similarity index 100% rename from controller/sli-exporter/probes/postgresql_test.go rename to pkg/controller/sli-exporter/probes/postgresql_test.go diff --git a/controller/sli-exporter/vshnpostgresql_controller.go b/pkg/controller/sli-exporter/vshnpostgresql_controller.go similarity index 89% rename from controller/sli-exporter/vshnpostgresql_controller.go rename to pkg/controller/sli-exporter/vshnpostgresql_controller.go index f2270a053f..d64150e331 100644 --- a/controller/sli-exporter/vshnpostgresql_controller.go +++ b/pkg/controller/sli-exporter/vshnpostgresql_controller.go @@ -19,7 +19,7 @@ package sli_exporter import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/controller/sli-exporter/probes" + probes2 "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter/probes" "time" "github.com/jackc/pgx/v5/pgxpool" @@ -43,12 +43,12 @@ type VSHNPostgreSQLReconciler struct { ProbeManager probeManager StartupGracePeriod time.Duration - PostgreDialer func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) + PostgreDialer func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes2.PostgreSQL, error) } type probeManager interface { - StartProbe(p probes.Prober) - StopProbe(p probes.ProbeInfo) + StartProbe(p probes2.Prober) + StopProbe(p probes2.ProbeInfo) } //+kubebuilder:rbac:groups=vshn.appcat.vshn.io,resources=vshnpostgresqls,verbs=get;list;watch @@ -65,7 +65,7 @@ func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Reque if apierrors.IsNotFound(err) || inst.DeletionTimestamp != nil { l.Info("Stopping Probe") - r.ProbeManager.StopProbe(probes.ProbeInfo{ + r.ProbeManager.StopProbe(probes2.ProbeInfo{ Service: vshnpostgresqlsServiceKey, Name: req.Name, Namespace: req.Namespace, @@ -97,7 +97,7 @@ func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Reque } // Create a pobe that will always fail - probe, err = probes.NewFailingPostgreSQL(vshnpostgresqlsServiceKey, inst.Name, inst.Namespace) + probe, err = probes2.NewFailingPostgreSQL(vshnpostgresqlsServiceKey, inst.Name, inst.Namespace) if err != nil { return ctrl.Result{}, err } @@ -108,7 +108,7 @@ func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Reque return res, nil } -func (r VSHNPostgreSQLReconciler) fetchProberFor(ctx context.Context, inst *vshnv1.VSHNPostgreSQL) (probes.Prober, error) { +func (r VSHNPostgreSQLReconciler) fetchProberFor(ctx context.Context, inst *vshnv1.VSHNPostgreSQL) (probes2.Prober, error) { credSecret := corev1.Secret{} err := r.Get(ctx, types.NamespacedName{ @@ -128,7 +128,7 @@ func (r VSHNPostgreSQLReconciler) fetchProberFor(ctx context.Context, inst *vshn credSecret.Data["POSTGRESQL_HOST"], credSecret.Data["POSTGRESQL_PORT"], credSecret.Data["POSTGRESQL_DB"], - ), probes.PGWithCA(credSecret.Data["ca.crt"])) + ), probes2.PGWithCA(credSecret.Data["ca.crt"])) if err != nil { return nil, err } diff --git a/controller/sli-exporter/vshnpostgresql_controller_test.go b/pkg/controller/sli-exporter/vshnpostgresql_controller_test.go similarity index 92% rename from controller/sli-exporter/vshnpostgresql_controller_test.go rename to pkg/controller/sli-exporter/vshnpostgresql_controller_test.go index a68e890314..f1484e6f57 100644 --- a/controller/sli-exporter/vshnpostgresql_controller_test.go +++ b/pkg/controller/sli-exporter/vshnpostgresql_controller_test.go @@ -2,7 +2,7 @@ package sli_exporter import ( "context" - "github.com/vshn/appcat-apiserver/controller/sli-exporter/probes" + probes2 "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter/probes" "testing" "time" @@ -35,7 +35,7 @@ func TestVSHNPostgreSQL_StartStop(t *testing.T) { Name: "foo", }, } - pi := probes.ProbeInfo{ + pi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -65,7 +65,7 @@ func TestVSHNPostgreSQL_StartStop_WithFializer(t *testing.T) { Name: "foo", }, } - pi := probes.ProbeInfo{ + pi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -94,17 +94,17 @@ func TestVSHNPostgreSQL_Multi(t *testing.T) { newTestVSHNPostgreCred("buzz", "creds"), ) - barPi := probes.ProbeInfo{ + barPi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", } - barerPi := probes.ProbeInfo{ + barerPi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "fooer", Namespace: "bar", } - buzzPi := probes.ProbeInfo{ + buzzPi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "buzz", @@ -136,7 +136,7 @@ func TestVSHNPostgreSQL_Startup_NoCreds_Dont_Probe(t *testing.T) { r, manager, _ := setupVSHNPostgreTest(t, db, ) - pi := probes.ProbeInfo{ + pi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -155,7 +155,7 @@ func TestVSHNPostgreSQL_NoRef_Dont_Probe(t *testing.T) { r, manager, _ := setupVSHNPostgreTest(t, db, ) - pi := probes.ProbeInfo{ + pi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -172,7 +172,7 @@ func TestVSHNPostgreSQL_Started_NoCreds_Probe_Failure(t *testing.T) { r, manager, _ := setupVSHNPostgreTest(t, db, ) - pi := probes.ProbeInfo{ + pi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -200,7 +200,7 @@ func TestVSHNPostgreSQL_PassCerdentials(t *testing.T) { db, cred, ) - r.PostgreDialer = func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) { + r.PostgreDialer = func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes2.PostgreSQL, error) { assert.Equal(t, "VSHNPostgreSQL", service) assert.Equal(t, "foo", name) @@ -215,7 +215,7 @@ func TestVSHNPostgreSQL_PassCerdentials(t *testing.T) { Name: "foo", }, } - pi := probes.ProbeInfo{ + pi := probes2.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -231,8 +231,8 @@ func TestVSHNPostgreSQL_PassCerdentials(t *testing.T) { assert.False(t, manager.probers[pi]) } -func fakePostgreDialer(service string, name string, namespace string, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) { - p := &probes.PostgreSQL{ +func fakePostgreDialer(service string, name string, namespace string, dsn string, ops ...func(*pgxpool.Config) error) (*probes2.PostgreSQL, error) { + p := &probes2.PostgreSQL{ Service: service, Instance: name, Namespace: namespace, @@ -243,22 +243,22 @@ func fakePostgreDialer(service string, name string, namespace string, dsn string var _ probeManager = &fakeProbeManager{} type fakeProbeManager struct { - probers map[probes.ProbeInfo]bool + probers map[probes2.ProbeInfo]bool } func newFakeProbeManager() *fakeProbeManager { return &fakeProbeManager{ - probers: map[probes.ProbeInfo]bool{}, + probers: map[probes2.ProbeInfo]bool{}, } } // StartProbe implements probeManager -func (m *fakeProbeManager) StartProbe(p probes.Prober) { +func (m *fakeProbeManager) StartProbe(p probes2.Prober) { m.probers[p.GetInfo()] = true } // StopProbe implements probeManager -func (m *fakeProbeManager) StopProbe(p probes.ProbeInfo) { +func (m *fakeProbeManager) StopProbe(p probes2.ProbeInfo) { m.probers[p] = false } From 6622f0d20bc608e58e65bd4f3b3151edc0f7b858 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Fri, 12 May 2023 11:12:06 +0200 Subject: [PATCH 07/26] Update SLI exporter k8s manifests --- config/controller/{postgres => }/cluster-role-binding.yaml | 0 config/controller/{postgres => }/cluster-role.yaml | 0 config/controller/{postgres => }/deployment.yaml | 0 config/controller/{postgres => }/namespace.yaml | 0 .../{postgres => }/role-binding-leader-election.yaml | 0 config/controller/{postgres => }/role-leader-election.yaml | 0 config/controller/{postgres => }/service-account.yaml | 0 .../{controller => }/sli-exporter/default/kustomization.yaml | 4 ---- .../sli-exporter/default/manager_auth_proxy_patch.yaml | 1 + .../{controller => }/sli-exporter/manager/kustomization.yaml | 0 config/{controller => }/sli-exporter/manager/manager.yaml | 0 .../sli-exporter/prometheus/kustomization.yaml | 0 config/{controller => }/sli-exporter/prometheus/monitor.yaml | 0 .../sli-exporter/rbac/auth_proxy_client_clusterrole.yaml | 0 .../{controller => }/sli-exporter/rbac/auth_proxy_role.yaml | 0 .../sli-exporter/rbac/auth_proxy_role_binding.yaml | 0 .../sli-exporter/rbac/auth_proxy_service.yaml | 0 config/{controller => }/sli-exporter/rbac/kustomization.yaml | 0 config/{controller => }/sli-exporter/rbac/role.yaml | 0 config/{controller => }/sli-exporter/rbac/role_binding.yaml | 0 .../{controller => }/sli-exporter/rbac/service_account.yaml | 0 21 files changed, 1 insertion(+), 4 deletions(-) rename config/controller/{postgres => }/cluster-role-binding.yaml (100%) rename config/controller/{postgres => }/cluster-role.yaml (100%) rename config/controller/{postgres => }/deployment.yaml (100%) rename config/controller/{postgres => }/namespace.yaml (100%) rename config/controller/{postgres => }/role-binding-leader-election.yaml (100%) rename config/controller/{postgres => }/role-leader-election.yaml (100%) rename config/controller/{postgres => }/service-account.yaml (100%) rename config/{controller => }/sli-exporter/default/kustomization.yaml (89%) rename config/{controller => }/sli-exporter/default/manager_auth_proxy_patch.yaml (97%) rename config/{controller => }/sli-exporter/manager/kustomization.yaml (100%) rename config/{controller => }/sli-exporter/manager/manager.yaml (100%) rename config/{controller => }/sli-exporter/prometheus/kustomization.yaml (100%) rename config/{controller => }/sli-exporter/prometheus/monitor.yaml (100%) rename config/{controller => }/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml (100%) rename config/{controller => }/sli-exporter/rbac/auth_proxy_role.yaml (100%) rename config/{controller => }/sli-exporter/rbac/auth_proxy_role_binding.yaml (100%) rename config/{controller => }/sli-exporter/rbac/auth_proxy_service.yaml (100%) rename config/{controller => }/sli-exporter/rbac/kustomization.yaml (100%) rename config/{controller => }/sli-exporter/rbac/role.yaml (100%) rename config/{controller => }/sli-exporter/rbac/role_binding.yaml (100%) rename config/{controller => }/sli-exporter/rbac/service_account.yaml (100%) diff --git a/config/controller/postgres/cluster-role-binding.yaml b/config/controller/cluster-role-binding.yaml similarity index 100% rename from config/controller/postgres/cluster-role-binding.yaml rename to config/controller/cluster-role-binding.yaml diff --git a/config/controller/postgres/cluster-role.yaml b/config/controller/cluster-role.yaml similarity index 100% rename from config/controller/postgres/cluster-role.yaml rename to config/controller/cluster-role.yaml diff --git a/config/controller/postgres/deployment.yaml b/config/controller/deployment.yaml similarity index 100% rename from config/controller/postgres/deployment.yaml rename to config/controller/deployment.yaml diff --git a/config/controller/postgres/namespace.yaml b/config/controller/namespace.yaml similarity index 100% rename from config/controller/postgres/namespace.yaml rename to config/controller/namespace.yaml diff --git a/config/controller/postgres/role-binding-leader-election.yaml b/config/controller/role-binding-leader-election.yaml similarity index 100% rename from config/controller/postgres/role-binding-leader-election.yaml rename to config/controller/role-binding-leader-election.yaml diff --git a/config/controller/postgres/role-leader-election.yaml b/config/controller/role-leader-election.yaml similarity index 100% rename from config/controller/postgres/role-leader-election.yaml rename to config/controller/role-leader-election.yaml diff --git a/config/controller/postgres/service-account.yaml b/config/controller/service-account.yaml similarity index 100% rename from config/controller/postgres/service-account.yaml rename to config/controller/service-account.yaml diff --git a/config/controller/sli-exporter/default/kustomization.yaml b/config/sli-exporter/default/kustomization.yaml similarity index 89% rename from config/controller/sli-exporter/default/kustomization.yaml rename to config/sli-exporter/default/kustomization.yaml index 36e1dccf5f..6a28016d6a 100644 --- a/config/controller/sli-exporter/default/kustomization.yaml +++ b/config/sli-exporter/default/kustomization.yaml @@ -22,7 +22,3 @@ patchesStrategicMerge: # If you want your controller-manager to expose the /metrics # endpoint w/o any authn/z, please comment the following line. - manager_auth_proxy_patch.yaml - -# the following config is for teaching kustomize how to do var substitution -vars: - diff --git a/config/controller/sli-exporter/default/manager_auth_proxy_patch.yaml b/config/sli-exporter/default/manager_auth_proxy_patch.yaml similarity index 97% rename from config/controller/sli-exporter/default/manager_auth_proxy_patch.yaml rename to config/sli-exporter/default/manager_auth_proxy_patch.yaml index bb88cffe8b..e73ed12aa0 100644 --- a/config/controller/sli-exporter/default/manager_auth_proxy_patch.yaml +++ b/config/sli-exporter/default/manager_auth_proxy_patch.yaml @@ -22,5 +22,6 @@ spec: name: https - name: manager args: + - "sliprober" - "--health-probe-bind-address=:8081" - "--metrics-bind-address=127.0.0.1:8080" diff --git a/config/controller/sli-exporter/manager/kustomization.yaml b/config/sli-exporter/manager/kustomization.yaml similarity index 100% rename from config/controller/sli-exporter/manager/kustomization.yaml rename to config/sli-exporter/manager/kustomization.yaml diff --git a/config/controller/sli-exporter/manager/manager.yaml b/config/sli-exporter/manager/manager.yaml similarity index 100% rename from config/controller/sli-exporter/manager/manager.yaml rename to config/sli-exporter/manager/manager.yaml diff --git a/config/controller/sli-exporter/prometheus/kustomization.yaml b/config/sli-exporter/prometheus/kustomization.yaml similarity index 100% rename from config/controller/sli-exporter/prometheus/kustomization.yaml rename to config/sli-exporter/prometheus/kustomization.yaml diff --git a/config/controller/sli-exporter/prometheus/monitor.yaml b/config/sli-exporter/prometheus/monitor.yaml similarity index 100% rename from config/controller/sli-exporter/prometheus/monitor.yaml rename to config/sli-exporter/prometheus/monitor.yaml diff --git a/config/controller/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml b/config/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml rename to config/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml diff --git a/config/controller/sli-exporter/rbac/auth_proxy_role.yaml b/config/sli-exporter/rbac/auth_proxy_role.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/auth_proxy_role.yaml rename to config/sli-exporter/rbac/auth_proxy_role.yaml diff --git a/config/controller/sli-exporter/rbac/auth_proxy_role_binding.yaml b/config/sli-exporter/rbac/auth_proxy_role_binding.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/auth_proxy_role_binding.yaml rename to config/sli-exporter/rbac/auth_proxy_role_binding.yaml diff --git a/config/controller/sli-exporter/rbac/auth_proxy_service.yaml b/config/sli-exporter/rbac/auth_proxy_service.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/auth_proxy_service.yaml rename to config/sli-exporter/rbac/auth_proxy_service.yaml diff --git a/config/controller/sli-exporter/rbac/kustomization.yaml b/config/sli-exporter/rbac/kustomization.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/kustomization.yaml rename to config/sli-exporter/rbac/kustomization.yaml diff --git a/config/controller/sli-exporter/rbac/role.yaml b/config/sli-exporter/rbac/role.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/role.yaml rename to config/sli-exporter/rbac/role.yaml diff --git a/config/controller/sli-exporter/rbac/role_binding.yaml b/config/sli-exporter/rbac/role_binding.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/role_binding.yaml rename to config/sli-exporter/rbac/role_binding.yaml diff --git a/config/controller/sli-exporter/rbac/service_account.yaml b/config/sli-exporter/rbac/service_account.yaml similarity index 100% rename from config/controller/sli-exporter/rbac/service_account.yaml rename to config/sli-exporter/rbac/service_account.yaml From 077e79a5015a95596814e56ce86a9eaa912b87d4 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Fri, 12 May 2023 11:51:47 +0200 Subject: [PATCH 08/26] Update README --- README.md | 15 +++++++++++++++ .../default/kustomization.yaml | 0 .../default/manager_auth_proxy_patch.yaml | 0 .../manager/kustomization.yaml | 0 .../manager/manager.yaml | 2 +- .../prometheus/kustomization.yaml | 0 .../prometheus/monitor.yaml | 0 .../rbac/auth_proxy_client_clusterrole.yaml | 0 .../rbac/auth_proxy_role.yaml | 0 .../rbac/auth_proxy_role_binding.yaml | 0 .../rbac/auth_proxy_service.yaml | 0 .../rbac/kustomization.yaml | 0 .../{sli-exporter => sliexporter}/rbac/role.yaml | 0 .../rbac/role_binding.yaml | 0 .../rbac/service_account.yaml | 0 15 files changed, 16 insertions(+), 1 deletion(-) rename config/{sli-exporter => sliexporter}/default/kustomization.yaml (100%) rename config/{sli-exporter => sliexporter}/default/manager_auth_proxy_patch.yaml (100%) rename config/{sli-exporter => sliexporter}/manager/kustomization.yaml (100%) rename config/{sli-exporter => sliexporter}/manager/manager.yaml (95%) rename config/{sli-exporter => sliexporter}/prometheus/kustomization.yaml (100%) rename config/{sli-exporter => sliexporter}/prometheus/monitor.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/auth_proxy_client_clusterrole.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/auth_proxy_role.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/auth_proxy_role_binding.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/auth_proxy_service.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/kustomization.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/role.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/role_binding.yaml (100%) rename config/{sli-exporter => sliexporter}/rbac/service_account.yaml (100%) diff --git a/README.md b/README.md index 4fef3efece..d17a7e6f81 100644 --- a/README.md +++ b/README.md @@ -247,3 +247,18 @@ if You want to run gRPC server in local kind cluster, please use: ``` That's all - You can now run Your claims. This documentation and above workaround is just temporary solution, it should disappear once we actually implement composition functions. + + +## Generate XRDs with Go / KubeBuilder + +In `/apis` there is code in Go to generate the XRDs (composites) as this is in OpenAPI. +This code generates the OpenAPI scheme using [Kubebuilder](https://kubebuilder.io/). + +See following pages for learning how to do that: +- https://kubebuilder.io/reference/generating-crd.html +- https://kubebuilder.io/reference/markers.html + +To run the composition generator, run `make generate-crd`. +You need to have `go` installed for this to work. + +After that, you are able to update the golden files for the component: `make gen-golden-all`. diff --git a/config/sli-exporter/default/kustomization.yaml b/config/sliexporter/default/kustomization.yaml similarity index 100% rename from config/sli-exporter/default/kustomization.yaml rename to config/sliexporter/default/kustomization.yaml diff --git a/config/sli-exporter/default/manager_auth_proxy_patch.yaml b/config/sliexporter/default/manager_auth_proxy_patch.yaml similarity index 100% rename from config/sli-exporter/default/manager_auth_proxy_patch.yaml rename to config/sliexporter/default/manager_auth_proxy_patch.yaml diff --git a/config/sli-exporter/manager/kustomization.yaml b/config/sliexporter/manager/kustomization.yaml similarity index 100% rename from config/sli-exporter/manager/kustomization.yaml rename to config/sliexporter/manager/kustomization.yaml diff --git a/config/sli-exporter/manager/manager.yaml b/config/sliexporter/manager/manager.yaml similarity index 95% rename from config/sli-exporter/manager/manager.yaml rename to config/sliexporter/manager/manager.yaml index 6c739fa745..774d2ab7a9 100644 --- a/config/sli-exporter/manager/manager.yaml +++ b/config/sliexporter/manager/manager.yaml @@ -27,7 +27,7 @@ spec: securityContext: runAsNonRoot: true containers: - - image: ghcr.io/vshn/appcat-sli-exporter:latest + - image: ghcr.io/vshn/appcat-apiserver:common-repo name: manager securityContext: allowPrivilegeEscalation: false diff --git a/config/sli-exporter/prometheus/kustomization.yaml b/config/sliexporter/prometheus/kustomization.yaml similarity index 100% rename from config/sli-exporter/prometheus/kustomization.yaml rename to config/sliexporter/prometheus/kustomization.yaml diff --git a/config/sli-exporter/prometheus/monitor.yaml b/config/sliexporter/prometheus/monitor.yaml similarity index 100% rename from config/sli-exporter/prometheus/monitor.yaml rename to config/sliexporter/prometheus/monitor.yaml diff --git a/config/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml b/config/sliexporter/rbac/auth_proxy_client_clusterrole.yaml similarity index 100% rename from config/sli-exporter/rbac/auth_proxy_client_clusterrole.yaml rename to config/sliexporter/rbac/auth_proxy_client_clusterrole.yaml diff --git a/config/sli-exporter/rbac/auth_proxy_role.yaml b/config/sliexporter/rbac/auth_proxy_role.yaml similarity index 100% rename from config/sli-exporter/rbac/auth_proxy_role.yaml rename to config/sliexporter/rbac/auth_proxy_role.yaml diff --git a/config/sli-exporter/rbac/auth_proxy_role_binding.yaml b/config/sliexporter/rbac/auth_proxy_role_binding.yaml similarity index 100% rename from config/sli-exporter/rbac/auth_proxy_role_binding.yaml rename to config/sliexporter/rbac/auth_proxy_role_binding.yaml diff --git a/config/sli-exporter/rbac/auth_proxy_service.yaml b/config/sliexporter/rbac/auth_proxy_service.yaml similarity index 100% rename from config/sli-exporter/rbac/auth_proxy_service.yaml rename to config/sliexporter/rbac/auth_proxy_service.yaml diff --git a/config/sli-exporter/rbac/kustomization.yaml b/config/sliexporter/rbac/kustomization.yaml similarity index 100% rename from config/sli-exporter/rbac/kustomization.yaml rename to config/sliexporter/rbac/kustomization.yaml diff --git a/config/sli-exporter/rbac/role.yaml b/config/sliexporter/rbac/role.yaml similarity index 100% rename from config/sli-exporter/rbac/role.yaml rename to config/sliexporter/rbac/role.yaml diff --git a/config/sli-exporter/rbac/role_binding.yaml b/config/sliexporter/rbac/role_binding.yaml similarity index 100% rename from config/sli-exporter/rbac/role_binding.yaml rename to config/sliexporter/rbac/role_binding.yaml diff --git a/config/sli-exporter/rbac/service_account.yaml b/config/sliexporter/rbac/service_account.yaml similarity index 100% rename from config/sli-exporter/rbac/service_account.yaml rename to config/sliexporter/rbac/service_account.yaml From df784bd14929e86cff2f629518b5801fb79ca035 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 15 May 2023 15:09:18 +0200 Subject: [PATCH 09/26] Fix arguments on commands --- cmd/controller.go | 2 +- cmd/grpc.go | 2 +- cmd/sliprober.go | 2 +- config/sliexporter/manager/manager.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/controller.go b/cmd/controller.go index 9d2e15f79e..13d32644c1 100644 --- a/cmd/controller.go +++ b/cmd/controller.go @@ -34,7 +34,7 @@ func init() { _ = xkube.SchemeBuilder.AddToScheme(c.scheme) _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(c.scheme) - ControllerCMD.Flags().StringVar(&c.metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + ControllerCMD.Flags().StringVar(&c.metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") ControllerCMD.Flags().StringVar(&c.healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") ControllerCMD.Flags().BoolVar(&c.leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") diff --git a/cmd/grpc.go b/cmd/grpc.go index 11c2821059..e2ae21ddf8 100644 --- a/cmd/grpc.go +++ b/cmd/grpc.go @@ -26,7 +26,7 @@ var ( ) var GrpcCMD = &cobra.Command{ - Use: "grpc", + Use: "start grpc", Short: "GRPC Server", Long: "Run the GRPC Server for crossplane composition functions", RunE: executeGRPCServer, diff --git a/cmd/sliprober.go b/cmd/sliprober.go index ff975463f4..29acc0f106 100644 --- a/cmd/sliprober.go +++ b/cmd/sliprober.go @@ -39,7 +39,7 @@ func init() { _ = xkube.SchemeBuilder.AddToScheme(s.scheme) _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s.scheme) - SLIProberCMD.Flags().StringVar(&s.metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.") + SLIProberCMD.Flags().StringVar(&s.metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") SLIProberCMD.Flags().StringVar(&s.probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") SLIProberCMD.Flags().BoolVar(&s.leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") diff --git a/config/sliexporter/manager/manager.yaml b/config/sliexporter/manager/manager.yaml index 774d2ab7a9..6c739fa745 100644 --- a/config/sliexporter/manager/manager.yaml +++ b/config/sliexporter/manager/manager.yaml @@ -27,7 +27,7 @@ spec: securityContext: runAsNonRoot: true containers: - - image: ghcr.io/vshn/appcat-apiserver:common-repo + - image: ghcr.io/vshn/appcat-sli-exporter:latest name: manager securityContext: allowPrivilegeEscalation: false From 54419ada9f84fc3f0cfcf4413b38ef7510eb654f Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 15 May 2023 15:17:37 +0200 Subject: [PATCH 10/26] Refactor grpc --- cmd/grpc.go | 74 ++++++++----------- cmd/sliprober.go | 8 +- .../sli-exporter/probes/manager.go | 0 .../sli-exporter/probes/manager_test.go | 0 .../sli-exporter/probes/postgresql.go | 0 .../sli-exporter/probes/postgresql_test.go | 0 .../sli-exporter/vshnpostgresql_controller.go | 16 ++-- .../vshnpostgresql_controller_test.go | 34 ++++----- 8 files changed, 59 insertions(+), 73 deletions(-) rename pkg/{controller => }/sli-exporter/probes/manager.go (100%) rename pkg/{controller => }/sli-exporter/probes/manager_test.go (100%) rename pkg/{controller => }/sli-exporter/probes/postgresql.go (100%) rename pkg/{controller => }/sli-exporter/probes/postgresql_test.go (100%) rename pkg/{controller => }/sli-exporter/vshnpostgresql_controller.go (89%) rename pkg/{controller => }/sli-exporter/vshnpostgresql_controller_test.go (92%) diff --git a/cmd/grpc.go b/cmd/grpc.go index e2ae21ddf8..28da80598e 100644 --- a/cmd/grpc.go +++ b/cmd/grpc.go @@ -32,30 +32,6 @@ var GrpcCMD = &cobra.Command{ RunE: executeGRPCServer, } -var postgresFunctions = []runtime.Transform{ - { - Name: "url-connection-details", - TransformFunc: vpf.AddUrlToConnectionDetails, - }, - { - Name: "user-alerting", - TransformFunc: vpf.AddUserAlerting, - }, - { - Name: "random-default-schedule", - TransformFunc: vpf.TransformSchedule, - }, - { - Name: "encrypted-pvc-secret", - TransformFunc: vpf.AddPvcSecret, - }, -} - -type server struct { - pb.UnimplementedContainerizedFunctionRunnerServiceServer - logger logr.Logger -} - // Run will run the controller mode of the composition function runner. func executeGRPCServer(cmd *cobra.Command, _ []string) error { log := logr.FromContextOrDiscard(cmd.Context()) @@ -83,29 +59,39 @@ func executeGRPCServer(cmd *cobra.Command, _ []string) error { return nil } +var images = map[string][]runtime.Transform{ + "postgresql": { + { + Name: "url-connection-details", + TransformFunc: vpf.AddUrlToConnectionDetails, + }, + { + Name: "user-alerting", + TransformFunc: vpf.AddUserAlerting, + }, + { + Name: "random-default-schedule", + TransformFunc: vpf.TransformSchedule, + }, + { + Name: "encrypted-pvc-secret", + TransformFunc: vpf.AddPvcSecret, + }, + }, +} + +type server struct { + pb.UnimplementedContainerizedFunctionRunnerServiceServer + logger logr.Logger +} + func (s *server) RunFunction(ctx context.Context, in *pb.RunFunctionRequest) (*pb.RunFunctionResponse, error) { ctx = logr.NewContext(ctx, s.logger) - switch in.Image { - case "postgresql": - fnio, err := runtime.RunCommand(ctx, in.Input, postgresFunctions) - if err != nil { - return &pb.RunFunctionResponse{ - Output: fnio, - }, status.Errorf(codes.Aborted, "Can't process request for PostgreSQL") - } - return &pb.RunFunctionResponse{ - Output: fnio, - }, nil - case "redis": - return &pb.RunFunctionResponse{ - // return what was sent as it's currently not supported - Output: in.Input, - }, status.Error(codes.Unimplemented, "Redis is not yet implemented") - default: - return &pb.RunFunctionResponse{ - Output: []byte("Bad configuration"), - }, status.Error(codes.NotFound, "Unknown request") + fnio, err := runtime.RunCommand(ctx, in.Input, images[in.Image]) + if err != nil { + err = status.Errorf(codes.Aborted, "Can't process request for PostgreSQL") } + return &pb.RunFunctionResponse{Output: fnio}, err } // socket isn't removed after server stop listening and blocks another starts diff --git a/cmd/sliprober.go b/cmd/sliprober.go index 29acc0f106..45ee4aa804 100644 --- a/cmd/sliprober.go +++ b/cmd/sliprober.go @@ -5,8 +5,8 @@ import ( "github.com/go-logr/logr" "github.com/spf13/cobra" vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter" - probes2 "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter/probes" + "github.com/vshn/appcat-apiserver/pkg/sli-exporter" + "github.com/vshn/appcat-apiserver/pkg/sli-exporter/probes" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "os" @@ -63,7 +63,7 @@ func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { log.Error(err, "unable to start manager") return err } - probeManager := probes2.NewManager(log) + probeManager := probes.NewManager(log) err = metrics.Registry.Register(probeManager.Collector()) if err != nil { @@ -77,7 +77,7 @@ func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { Scheme: mgr.GetScheme(), ProbeManager: &probeManager, StartupGracePeriod: 15 * time.Minute, - PostgreDialer: probes2.NewPostgreSQL, + PostgreDialer: probes.NewPostgreSQL, }).SetupWithManager(mgr); err != nil { log.Error(err, "unable to create controller", "controller", "VSHNPostgreSQL") return err diff --git a/pkg/controller/sli-exporter/probes/manager.go b/pkg/sli-exporter/probes/manager.go similarity index 100% rename from pkg/controller/sli-exporter/probes/manager.go rename to pkg/sli-exporter/probes/manager.go diff --git a/pkg/controller/sli-exporter/probes/manager_test.go b/pkg/sli-exporter/probes/manager_test.go similarity index 100% rename from pkg/controller/sli-exporter/probes/manager_test.go rename to pkg/sli-exporter/probes/manager_test.go diff --git a/pkg/controller/sli-exporter/probes/postgresql.go b/pkg/sli-exporter/probes/postgresql.go similarity index 100% rename from pkg/controller/sli-exporter/probes/postgresql.go rename to pkg/sli-exporter/probes/postgresql.go diff --git a/pkg/controller/sli-exporter/probes/postgresql_test.go b/pkg/sli-exporter/probes/postgresql_test.go similarity index 100% rename from pkg/controller/sli-exporter/probes/postgresql_test.go rename to pkg/sli-exporter/probes/postgresql_test.go diff --git a/pkg/controller/sli-exporter/vshnpostgresql_controller.go b/pkg/sli-exporter/vshnpostgresql_controller.go similarity index 89% rename from pkg/controller/sli-exporter/vshnpostgresql_controller.go rename to pkg/sli-exporter/vshnpostgresql_controller.go index d64150e331..bd66b60e56 100644 --- a/pkg/controller/sli-exporter/vshnpostgresql_controller.go +++ b/pkg/sli-exporter/vshnpostgresql_controller.go @@ -19,7 +19,7 @@ package sli_exporter import ( "context" "fmt" - probes2 "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter/probes" + "github.com/vshn/appcat-apiserver/pkg/sli-exporter/probes" "time" "github.com/jackc/pgx/v5/pgxpool" @@ -43,12 +43,12 @@ type VSHNPostgreSQLReconciler struct { ProbeManager probeManager StartupGracePeriod time.Duration - PostgreDialer func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes2.PostgreSQL, error) + PostgreDialer func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) } type probeManager interface { - StartProbe(p probes2.Prober) - StopProbe(p probes2.ProbeInfo) + StartProbe(p probes.Prober) + StopProbe(p probes.ProbeInfo) } //+kubebuilder:rbac:groups=vshn.appcat.vshn.io,resources=vshnpostgresqls,verbs=get;list;watch @@ -65,7 +65,7 @@ func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Reque if apierrors.IsNotFound(err) || inst.DeletionTimestamp != nil { l.Info("Stopping Probe") - r.ProbeManager.StopProbe(probes2.ProbeInfo{ + r.ProbeManager.StopProbe(probes.ProbeInfo{ Service: vshnpostgresqlsServiceKey, Name: req.Name, Namespace: req.Namespace, @@ -97,7 +97,7 @@ func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Reque } // Create a pobe that will always fail - probe, err = probes2.NewFailingPostgreSQL(vshnpostgresqlsServiceKey, inst.Name, inst.Namespace) + probe, err = probes.NewFailingPostgreSQL(vshnpostgresqlsServiceKey, inst.Name, inst.Namespace) if err != nil { return ctrl.Result{}, err } @@ -108,7 +108,7 @@ func (r *VSHNPostgreSQLReconciler) Reconcile(ctx context.Context, req ctrl.Reque return res, nil } -func (r VSHNPostgreSQLReconciler) fetchProberFor(ctx context.Context, inst *vshnv1.VSHNPostgreSQL) (probes2.Prober, error) { +func (r VSHNPostgreSQLReconciler) fetchProberFor(ctx context.Context, inst *vshnv1.VSHNPostgreSQL) (probes.Prober, error) { credSecret := corev1.Secret{} err := r.Get(ctx, types.NamespacedName{ @@ -128,7 +128,7 @@ func (r VSHNPostgreSQLReconciler) fetchProberFor(ctx context.Context, inst *vshn credSecret.Data["POSTGRESQL_HOST"], credSecret.Data["POSTGRESQL_PORT"], credSecret.Data["POSTGRESQL_DB"], - ), probes2.PGWithCA(credSecret.Data["ca.crt"])) + ), probes.PGWithCA(credSecret.Data["ca.crt"])) if err != nil { return nil, err } diff --git a/pkg/controller/sli-exporter/vshnpostgresql_controller_test.go b/pkg/sli-exporter/vshnpostgresql_controller_test.go similarity index 92% rename from pkg/controller/sli-exporter/vshnpostgresql_controller_test.go rename to pkg/sli-exporter/vshnpostgresql_controller_test.go index f1484e6f57..804c8c98ed 100644 --- a/pkg/controller/sli-exporter/vshnpostgresql_controller_test.go +++ b/pkg/sli-exporter/vshnpostgresql_controller_test.go @@ -2,7 +2,7 @@ package sli_exporter import ( "context" - probes2 "github.com/vshn/appcat-apiserver/pkg/controller/sli-exporter/probes" + "github.com/vshn/appcat-apiserver/pkg/sli-exporter/probes" "testing" "time" @@ -35,7 +35,7 @@ func TestVSHNPostgreSQL_StartStop(t *testing.T) { Name: "foo", }, } - pi := probes2.ProbeInfo{ + pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -65,7 +65,7 @@ func TestVSHNPostgreSQL_StartStop_WithFializer(t *testing.T) { Name: "foo", }, } - pi := probes2.ProbeInfo{ + pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -94,17 +94,17 @@ func TestVSHNPostgreSQL_Multi(t *testing.T) { newTestVSHNPostgreCred("buzz", "creds"), ) - barPi := probes2.ProbeInfo{ + barPi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", } - barerPi := probes2.ProbeInfo{ + barerPi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "fooer", Namespace: "bar", } - buzzPi := probes2.ProbeInfo{ + buzzPi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "buzz", @@ -136,7 +136,7 @@ func TestVSHNPostgreSQL_Startup_NoCreds_Dont_Probe(t *testing.T) { r, manager, _ := setupVSHNPostgreTest(t, db, ) - pi := probes2.ProbeInfo{ + pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -155,7 +155,7 @@ func TestVSHNPostgreSQL_NoRef_Dont_Probe(t *testing.T) { r, manager, _ := setupVSHNPostgreTest(t, db, ) - pi := probes2.ProbeInfo{ + pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -172,7 +172,7 @@ func TestVSHNPostgreSQL_Started_NoCreds_Probe_Failure(t *testing.T) { r, manager, _ := setupVSHNPostgreTest(t, db, ) - pi := probes2.ProbeInfo{ + pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -200,7 +200,7 @@ func TestVSHNPostgreSQL_PassCerdentials(t *testing.T) { db, cred, ) - r.PostgreDialer = func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes2.PostgreSQL, error) { + r.PostgreDialer = func(service, name, namespace, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) { assert.Equal(t, "VSHNPostgreSQL", service) assert.Equal(t, "foo", name) @@ -215,7 +215,7 @@ func TestVSHNPostgreSQL_PassCerdentials(t *testing.T) { Name: "foo", }, } - pi := probes2.ProbeInfo{ + pi := probes.ProbeInfo{ Service: "VSHNPostgreSQL", Name: "foo", Namespace: "bar", @@ -231,8 +231,8 @@ func TestVSHNPostgreSQL_PassCerdentials(t *testing.T) { assert.False(t, manager.probers[pi]) } -func fakePostgreDialer(service string, name string, namespace string, dsn string, ops ...func(*pgxpool.Config) error) (*probes2.PostgreSQL, error) { - p := &probes2.PostgreSQL{ +func fakePostgreDialer(service string, name string, namespace string, dsn string, ops ...func(*pgxpool.Config) error) (*probes.PostgreSQL, error) { + p := &probes.PostgreSQL{ Service: service, Instance: name, Namespace: namespace, @@ -243,22 +243,22 @@ func fakePostgreDialer(service string, name string, namespace string, dsn string var _ probeManager = &fakeProbeManager{} type fakeProbeManager struct { - probers map[probes2.ProbeInfo]bool + probers map[probes.ProbeInfo]bool } func newFakeProbeManager() *fakeProbeManager { return &fakeProbeManager{ - probers: map[probes2.ProbeInfo]bool{}, + probers: map[probes.ProbeInfo]bool{}, } } // StartProbe implements probeManager -func (m *fakeProbeManager) StartProbe(p probes2.Prober) { +func (m *fakeProbeManager) StartProbe(p probes.Prober) { m.probers[p.GetInfo()] = true } // StopProbe implements probeManager -func (m *fakeProbeManager) StopProbe(p probes2.ProbeInfo) { +func (m *fakeProbeManager) StopProbe(p probes.ProbeInfo) { m.probers[p] = false } From 813f8df8297a1b6604dd35ff4acabd1c665f8ee3 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 15 May 2023 15:55:31 +0200 Subject: [PATCH 11/26] Fix tests --- pkg/comp-functions/functions/vshn-postgres-func/common_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/comp-functions/functions/vshn-postgres-func/common_test.go b/pkg/comp-functions/functions/vshn-postgres-func/common_test.go index 4c8c36f5e1..632a6219db 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/common_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/common_test.go @@ -16,7 +16,7 @@ import ( func loadRuntimeFromFile(t assert.TestingT, file string) *runtime.Runtime { p, _ := filepath.Abs(".") - before, _, _ := strings.Cut(p, "/functions") + before, _, _ := strings.Cut(p, "pkg") f, err := os.Open(before + "/test/transforms/vshn-postgres/" + file) assert.NoError(t, err) b1, err := os.ReadFile(f.Name()) From f17a178523abbbb02bff7c29d8a8c549428ebac0 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 15 May 2023 16:34:54 +0200 Subject: [PATCH 12/26] Update generate target --- Makefile | 20 ++++++++++++++++---- apis/generate.mk | 21 --------------------- test/generate.go | 6 +++--- test/mocks/mock_composition.go | 2 +- test/mocks/mock_sgbackups.go | 2 +- test/mocks/mock_vshnpostgresqls.go | 8 ++++---- 6 files changed, 25 insertions(+), 34 deletions(-) delete mode 100644 apis/generate.mk diff --git a/Makefile b/Makefile index 52591fe1a7..37bbfacdd4 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,13 @@ else GOBIN=$(shell go env GOBIN) endif +OS := $(shell uname) +ifeq ($(OS), Darwin) + sed ?= gsed +else + sed ?= sed +endif + # For alpine image it is required the following env before building the application DOCKER_IMAGE_GOOS = linux DOCKER_IMAGE_GOARCH = amd64 @@ -46,7 +53,6 @@ $(protoc_bin): | $(go_bin) @rm $(go_bin)/protoc.zip -include docs/antora-preview.mk docs/antora-build.mk --include apis/generate.mk .PHONY: help help: ## Display this help. @@ -55,13 +61,19 @@ help: ## Display this help. .PHONY: generate generate: export PATH := $(go_bin):$(PATH) generate: $(protoc_bin) ## Generate code with controller-gen and protobuf. + rm -rf apis/generated + go run sigs.k8s.io/controller-tools/cmd/controller-gen paths=./apis/... object crd:crdVersions=v1 output:artifacts:config=./apis/generated go generate ./... - go run sigs.k8s.io/controller-tools/cmd/controller-gen object paths="./apis/..." - go run sigs.k8s.io/controller-tools/cmd/controller-gen rbac:roleName=appcat-apiserver paths="{./apis/...,./apiserver/...}" output:artifacts:config=config/apiserver + # Because yaml is such a fun and easy specification, we need to hack some things here. + # Depending on the yaml parser implementation the equal sign (=) has special meaning, or not... + # So we make it explicitly a string. + $(sed) -i ':a;N;$$!ba;s/- =\n/- "="\n/g' apis/generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml + rm -rf crds && cp -r apis/generated crds + go run sigs.k8s.io/controller-tools/cmd/controller-gen rbac:roleName=appcat-apiserver paths="{./apis/...,./pkg/apiserver/...}" output:artifacts:config=config/apiserver go run k8s.io/code-generator/cmd/go-to-protobuf \ --packages=github.com/vshn/appcat-apiserver/apis/appcat/v1 \ --output-base=./.work/tmp \ - --go-header-file=./apiserver/hack/boilerplate.txt \ + --go-header-file=./pkg/apiserver/hack/boilerplate.txt \ --apimachinery-packages='-k8s.io/apimachinery/pkg/util/intstr,-k8s.io/apimachinery/pkg/api/resource,-k8s.io/apimachinery/pkg/runtime/schema,-k8s.io/apimachinery/pkg/runtime,-k8s.io/apimachinery/pkg/apis/meta/v1,-k8s.io/apimachinery/pkg/apis/meta/v1beta1,-k8s.io/api/core/v1,-k8s.io/api/rbac/v1' \ --proto-import=./.work/kubernetes/vendor/ && \ mv ./.work/tmp/github.com/vshn/appcat-apiserver/apis/appcat/v1/generated.pb.go ./apis/appcat/v1/ && \ diff --git a/apis/generate.mk b/apis/generate.mk deleted file mode 100644 index 0749f2287d..0000000000 --- a/apis/generate.mk +++ /dev/null @@ -1,21 +0,0 @@ -clean_targets += .clean-apis -OS := $(shell uname) -ifeq ($(OS), Darwin) - sed ?= gsed -else - sed ?= sed -endif - -.PHONY: generate-xrd -generate-crd: ## Generates the CRDs using Kubebuilder, these CRDs will be used as a base for the XRDs by the component - @rm -rf apis/generated - @cd apis && go run sigs.k8s.io/controller-tools/cmd/controller-gen paths=./... crd:crdVersions=v1 output:artifacts:config=./generated - @cd apis && go run sigs.k8s.io/controller-tools/cmd/controller-gen object paths=./... - @cd apis && go generate ./... - @# Because yaml is such a fun and easy specification, we need to hack some things here. - @# Depending on the yaml parser implementation the equal sign (=) has special meaning, or not... - @# So we make it explicitly a string. - @$(sed) -i ':a;N;$$!ba;s/- =\n/- "="\n/g' apis/generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml - @rm -rf crds && cp -r apis/generated crds -.clean-apis: - rm -rf apis/generated diff --git a/test/generate.go b/test/generate.go index 2cbcf2e58f..845cd1e62d 100644 --- a/test/generate.go +++ b/test/generate.go @@ -4,10 +4,10 @@ package controllertest //go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_client.go -package=mocks sigs.k8s.io/controller-runtime/pkg/client Client // mock vshnpostgresqls -//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_vshnpostgresqls.go -package=mocks -source=../apiserver/vshn/postgres/vshnpostgresql.go +//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_vshnpostgresqls.go -package=mocks -source=../pkg/apiserver/vshn/postgres/vshnpostgresql.go // mock sgbackups -//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_sgbackups.go -package=mocks -source=../apiserver/vshn/postgres/sgbackups.go +//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_sgbackups.go -package=mocks -source=../pkg/apiserver/vshn/postgres/sgbackups.go // mock composition -//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_composition.go -package=mocks -source=../apiserver/appcat/composition.go +//go:generate go run github.com/golang/mock/mockgen -destination=mocks/mock_composition.go -package=mocks -source=../pkg/apiserver/appcat/composition.go diff --git a/test/mocks/mock_composition.go b/test/mocks/mock_composition.go index 1ca4df2f33..5280ff4cda 100644 --- a/test/mocks/mock_composition.go +++ b/test/mocks/mock_composition.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ../apiserver/appcat/composition.go +// Source: ../pkg/apiserver/appcat/composition.go // Package mocks is a generated GoMock package. package mocks diff --git a/test/mocks/mock_sgbackups.go b/test/mocks/mock_sgbackups.go index d208b4c867..3c9e103241 100644 --- a/test/mocks/mock_sgbackups.go +++ b/test/mocks/mock_sgbackups.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ../apiserver/vshn/postgres/sgbackups.go +// Source: ../pkg/apiserver/vshn/postgres/sgbackups.go // Package mocks is a generated GoMock package. package mocks diff --git a/test/mocks/mock_vshnpostgresqls.go b/test/mocks/mock_vshnpostgresqls.go index 65fd5f5d9d..9d45fe68fa 100644 --- a/test/mocks/mock_vshnpostgresqls.go +++ b/test/mocks/mock_vshnpostgresqls.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: ../apiserver/vshn/postgres/vshnpostgresql.go +// Source: ../pkg/apiserver/vshn/postgres/vshnpostgresql.go // Package mocks is a generated GoMock package. package mocks @@ -9,7 +9,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + v1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" ) // MockvshnPostgresqlProvider is a mock of vshnPostgresqlProvider interface. @@ -36,10 +36,10 @@ func (m *MockvshnPostgresqlProvider) EXPECT() *MockvshnPostgresqlProviderMockRec } // ListXVSHNPostgreSQL mocks base method. -func (m *MockvshnPostgresqlProvider) ListXVSHNPostgreSQL(ctx context.Context, namespace string) (*vshnv1.XVSHNPostgreSQLList, error) { +func (m *MockvshnPostgresqlProvider) ListXVSHNPostgreSQL(ctx context.Context, namespace string) (*v1.XVSHNPostgreSQLList, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ListXVSHNPostgreSQL", ctx, namespace) - ret0, _ := ret[0].(*vshnv1.XVSHNPostgreSQLList) + ret0, _ := ret[0].(*v1.XVSHNPostgreSQLList) ret1, _ := ret[1].(error) return ret0, ret1 } From 1fd6d373a2a098db04b2cc37a4962238b557628f Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 15 May 2023 16:47:33 +0200 Subject: [PATCH 13/26] Add github actions --- .github/workflows/build.yml | 30 ++++++++++++++++++ .github/workflows/docs.yml | 63 +++++++++++++++++++++++++++++++++++++ .github/workflows/lint.yml | 2 +- 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..9b1a1282be --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: Build + +on: + pull_request: {} + push: + branches: + - master + +jobs: + go-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Determine Go version from go.mod + run: echo "GO_VERSION=$(go mod edit -json | jq -r .Go)" >> $GITHUB_ENV + + - uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + + - uses: actions/cache@v3 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Run build + run: make build diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000000..2d5aa7874c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,63 @@ +name: Docs + +on: + push: + branches: + - master + tags: + - "*" + +jobs: + antora: + runs-on: ubuntu-latest + if: ${{ contains(github.ref, 'tags') }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Configure Git + run: | + git config user.name "Antora via GitHub Actions" + git config user.email "actions@github.com" + + - name: Parse semver string + id: semver + uses: booxmedialtd/ws-action-parse-semver@v1 + with: + input_string: ${{ github.ref }} + version_extractor_regex: '\/v(.*)$' + - name: Set variables + run: | + echo "MINOR_VERSION=${{ steps.semver.outputs.major }}.${{ steps.semver.outputs.minor }}" >> $GITHUB_ENV + echo "BRANCH_NAME=docs/v${{ steps.semver.outputs.major }}.${{ steps.semver.outputs.minor }}" >> $GITHUB_ENV + - name: Set branch name for Prerelease + if: ${{ steps.semver.outputs.prerelease != '' }} + run: echo "BRANCH_NAME=${{ env.BRANCH_NAME }}-rc" >> $GITHUB_ENV + + - name: Checkout remote branch if exists + run: git checkout ${{ env.BRANCH_NAME }} + continue-on-error: true + - name: Rebase if possible + run: git rebase ${GITHUB_REF##*/} ${{ env.BRANCH_NAME }} + continue-on-error: true + - name: Create new branch if not existing + run: git switch --create ${{ env.BRANCH_NAME }} + continue-on-error: true + + - name: Patch Antora file for Release + run: yq eval 'del(.prerelease) | del (.display_version) | .version = "${{ env.MINOR_VERSION }}"' -i docs/antora.yml + if: ${{ steps.semver.outputs.prerelease == '' }} + - name: Patch Antora file for Prerelease + run: yq eval 'del (.display_version) | .version = "${{ env.MINOR_VERSION }}", .prerelease = "-${{ steps.semver.outputs.prerelease }}"' -i docs/antora.yml + if: ${{ steps.semver.outputs.prerelease != '' }} + + - name: Commit + run: git commit --all --message "Update version for Antora" + continue-on-error: true + - name: Push + run: git push --atomic --force --set-upstream origin ${{ env.BRANCH_NAME }} + + - name: Cleanup prerelease branch if existing + if: ${{ steps.semver.outputs.prerelease == '' }} + run: git push origin --delete ${{ env.BRANCH_NAME }}-rc + continue-on-error: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c60c909176..c82fb46286 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,4 +26,4 @@ jobs: ${{ runner.os }}-go- - name: Run linters - run: make generate lint + run: make lint From 518695cc8ed254eecbff1ab698fa48ac1f8465ee Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 15 May 2023 16:50:02 +0200 Subject: [PATCH 14/26] Update clean target --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 37bbfacdd4..f2ec98573a 100644 --- a/Makefile +++ b/Makefile @@ -121,4 +121,4 @@ docker-push: docker-build ## Push docker image with the manager. .PHONY: clean clean: - rm -rf bin/ appcat-apiserver .work/ docs/node_modules $docs_out_dir .public .cache apiserver.local.config apis/generated + rm -rf bin/ appcat-apiserver .work/ docs/node_modules $docs_out_dir .public .cache apiserver.local.config apis/generated default.sock From fe6247c292da2ace66e347c5b5b009c75a2a75c5 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Tue, 16 May 2023 15:17:16 +0200 Subject: [PATCH 15/26] Update documentation --- Makefile | 4 - README.md | 163 +++++++++--------- cmd/{sliprober.go => sliexporter.go} | 6 +- config/sliexporter/default/kustomization.yaml | 4 +- docs/modules/ROOT/nav.adoc | 6 +- .../{ => apiserver}/boostrap.adoc | 0 .../{ => apiserver}/env-variables.adoc | 0 .../ROOT/pages/tutorials/dev-environment.adoc | 9 - .../probes/manager.go | 0 .../probes/manager_test.go | 0 .../probes/postgresql.go | 0 .../probes/postgresql_test.go | 0 .../vshnpostgresql_controller.go | 4 +- .../vshnpostgresql_controller_test.go | 4 +- 14 files changed, 89 insertions(+), 111 deletions(-) rename cmd/{sliprober.go => sliexporter.go} (95%) rename docs/modules/ROOT/pages/explanations/{ => apiserver}/boostrap.adoc (100%) rename docs/modules/ROOT/pages/references/{ => apiserver}/env-variables.adoc (100%) delete mode 100644 docs/modules/ROOT/pages/tutorials/dev-environment.adoc rename pkg/{sli-exporter => sliexporter}/probes/manager.go (100%) rename pkg/{sli-exporter => sliexporter}/probes/manager_test.go (100%) rename pkg/{sli-exporter => sliexporter}/probes/postgresql.go (100%) rename pkg/{sli-exporter => sliexporter}/probes/postgresql_test.go (100%) rename pkg/{sli-exporter => sliexporter}/vshnpostgresql_controller.go (98%) rename pkg/{sli-exporter => sliexporter}/vshnpostgresql_controller_test.go (99%) diff --git a/Makefile b/Makefile index f2ec98573a..7128a8900e 100644 --- a/Makefile +++ b/Makefile @@ -105,10 +105,6 @@ build: test: ## Run tests go test ./... -.PHONY: run -run: manifests generate fmt vet ## Run a controller from your host. - go run ./main.go - .PHONY: docker-build docker-build: env CGO_ENABLED=0 GOOS=$(DOCKER_IMAGE_GOOS) GOARCH=$(DOCKER_IMAGE_GOARCH) \ diff --git a/README.md b/README.md index d17a7e6f81..a9bcbd1c12 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,52 @@ [![Version](https://img.shields.io/github/v/release/appuio/control-api)](https://github.com/appuio/control-api/releases) [![GitHub downloads](https://img.shields.io/github/downloads/vshn/appcat-apiserver/total)](https://github.com/appuio/control-api/releases) -# appcat-apiserver +# AppCat -## Generate Kubernetes code +This repository has k8s tools to manage AppCat services. + +## Architecture + +``` +. +├── apis +|   ├── appcat // API server related apis +|   ├── exoscale // exoscale apis +|   ├── v1 // common apis +|   ├── vshn // VSHN managed services apis +├── cmd // cobra command lines for each AppCat tool +|   ├── apiserver.go +|   ├── controller.go +|   ├── grpc.go +│   └── sliexporter.go +├── config // kubernetes resources +|   ├── apiserver +│   ├── controller +│   └── sliexporter // uses kustomize +├── crds // VSHN exposed resources from apis +├── docs +├── pkg // go code for each AppCat tool +|   ├── apiserver +|   ├── controller +|   ├── grpc +│   └── sliexporter +├── test // mocks, test cases, grps test client +├── Dockerfile +├── log.go +├── main.go +├── probes +├── README.md +└── tools.go +``` + +## Generate Kubernetes code, XRDs with Go / KubeBuilder + +In `/apis` there is code in Go to generate the XRDs (composites) as this is in OpenAPI. +This code generates the OpenAPI scheme using [Kubebuilder](https://kubebuilder.io/). + +See following pages for learning how to do that: +- https://kubebuilder.io/reference/generating-crd.html +- https://kubebuilder.io/reference/markers.html If you make changes to the auto generated code you'll need to run code generation. This can be done with make: @@ -25,19 +68,22 @@ See `make help` for a list of build targets. ## Local development environment -You can setup a [kind]-based local environment with +You can setup a [kind]-based local environment with all dependencies in [kindev](https://github.com/vshn/kindev). -```bash -make local-install -``` +## API Server + +The AppCat API Server facilitates work with AppCat services. -See [docs](./docs/modules/ROOT/pages/tutorials/dev-environment.md) for more details on the local environment setup. +### Capabilities -Please be aware that the productive deployment of the appcat-apiserver may run on a different Kubernetes distribution than [kind]. +The API Server is able to manage the following: -[kind]: https://kind.sigs.k8s.io/ +| RESOURCE | DESCRIPTION | +|--------------------|---------------------------------------------------------| +| `AppCat` | Shows active AppCat services in a cluster | +| `PotsgreSQLBackup` | Shows available backups of an AppCat PostgreSQL service | -## Debugging in IDE +### Debugging in IDE To run the API server on your local machine you need to register the IDE running instance with kind cluster. This can be achieved with the following guide. @@ -95,18 +141,22 @@ After the above steps just run the API server via IDE with the following argumen apiserver --secure-port=9443 --kubeconfig=/.kube/config --authentication-kubeconfig=/.kube/config --authorization-kubeconfig=/.kube/config ``` -## Protobuf installation +### Protobuf installation Protocol Buffers (Protobuf) is a free and open-source cross-platform data format used to serialize structured data. Kubernetes internally uses gRPC clients with protobuf serialization. APIServer objects when handled internally in K8S need to implement protobuf interface. The implementation of the interface is done by [code-generator](https://github.com/kubernetes/code-generator). Two dependencies are required to use this tool [protoc](https://github.com/protocolbuffers/protobuf) and [protoc-gen-go](https://google.golang.org/protobuf/cmd/protoc-gen-go). + ## Controller -A postgres controller has been added to this API Server. The controller takes care of database deletion protection. -The controller insures via a finalizer in composite `XVSHNPostgreSQL` resource that the backups are still available -when the database instance is deleted. When deletion retention expires, the backups with the remaining resources -are cleaned up automatically. -This controller addition to this repository is a temporary solution until we move to a common AppCat repository. +The AppCat Controller resolves certain issues that cannot be achieved with crossplane. + +### Capabilities +The controller manages and achieves the following: + +| RESOURCE | GOAL | DESCRIPTION | +|-------------------|-----------------------------|----------------------------------------------| +| `XVSHNPostgreSQL` | Deletion Protection Support | Manages finalizers before and after deletion | ## SLI Exporter ### Metrics @@ -118,57 +168,24 @@ The exporter exposes a histogram `appcat_probes_seconds` with four labels * `name`, the name of the claim that was monitored * `reason`, if the probe was successful. Can either be `success`, `fail-timeout`, or `fail-unkown` -### Architecture - -``` -. -├── config // Kustomize files to deploy the exporter -├── controllers -│   └── vshnpostgresql_controller.go // starts probes for VSHNPostgreSQL claims -├── Dockerfile -├── main.go -├── probes -│   ├── manager.go // manages all started probes and exposes metrics -│   └── postgresql.go // prober implementation for postgresql -├── README.md -└── tools.go -``` - #### Adding a Prober -To add a prober for a new service, add a file in `probes/` that adds another implementation of the `Prober` interface. +To add a prober for a new service, add a file in `pkg/sliexporter/probes/` that adds another implementation of the `Prober` interface. #### Adding an AppCat service There should be a separate controller per AppCat Claim type. -Add another controller for each service that should be probed. +Add another controller for each service that should be probed in `pkg/sliexporter/`. #### Adding SLA exceptions If possible SLA exceptions should be implemented as a middleware for the `Prober` interface. -## Crossplane Composition Functions with GRPS Server - -``` -. -├── docs -├── functions -│ ├── vshn-common-func -│ ├── vshn-postgres-func -│ └── vshn-redis-func -├── kind -├── runtime -└── test -``` +## Crossplane Composition Functions with gRPC Server -- `./docs` contains relevant documentation in regard to this repository -- `./functions` contains the actual logic for each function-io. Each function-io can have multiple transformation go functions -- `./runtime` contains a library with helper methods which helps with adding new functions. -- `./kind` contains relevant files for local dev cluster -- `./test` contains test files - -Check out the docs to understand how functions from this repository work. +The gRPC Server that manages crossplane composition functions. The functions are found in `pkg/comp-functions/functions` +There package `pkg/comp-functions/runtime` contains a library with helper methods which helps with adding new functions. ### Add a new function-io @@ -177,28 +194,17 @@ A function-io corresponds to one and only one composition thus multiple transfor can be added to a function-io. For instance, in `vshn-postgres-func` there are multiple transformation go functions such as `url` or `alerting`. - To add a new function to PostgreSQL by VSHN: -- Create a new package under `./functions/`. -- Create a go file and add a new transform go function to the list in `./cmd/`. -- Implement the actual `Transform()` go function by using the helper functions from `runtime/desired.go` and `runtime/observed.go`. -- Register the transform go function in the `main.go`. -- Create a new app.go under `./cmd/` and define a new `AppInfo` object. - -This architecture allows us to run all the functions with a single command. But for debugging and development purpose it's possible to run each function separately, by using the `--function` flag. - -### Manually testing a function -To test a function you can leverage the FunctionIO file in the `./test` folder. - -`cat test/function-io.yaml | go run cmd/vshn-postgres-func/main.go --function myfunction > test.yaml` - +- Create a new package under `./pkg/comp-functions/functions/` in case one does not exist for a composition. +- Implement a `Transform()` go function by using the helper functions from `runtime/desired.go` and `runtime/observed.go`. +- Add a new transform go function to the `images` variable in `./cmd/grpc.go`. ### Usage of gRPC server - local development + kind cluster entrypoint to start working with gRPC server is to run: ``` -go run main.go -socket default.sock +go run main.go start grpc --socket default.sock ``` it will create a socket file in Your local directory which is easier for development - no need to set permissions and directory structure. @@ -206,7 +212,7 @@ it will create a socket file in Your local directory which is easier for develop It's also possible to trigger fake request to gRPC server by client (to imitate Crossplane): ``` cd test/grpc-client -go run main.go +go run main.go start grpc ``` if You want to run gRPC server in local kind cluster, please use: @@ -246,19 +252,4 @@ if You want to run gRPC server in local kind cluster, please use: apiVersion: kubernetes.crossplane.io/v1alpha1 ``` -That's all - You can now run Your claims. This documentation and above workaround is just temporary solution, it should disappear once we actually implement composition functions. - - -## Generate XRDs with Go / KubeBuilder - -In `/apis` there is code in Go to generate the XRDs (composites) as this is in OpenAPI. -This code generates the OpenAPI scheme using [Kubebuilder](https://kubebuilder.io/). - -See following pages for learning how to do that: -- https://kubebuilder.io/reference/generating-crd.html -- https://kubebuilder.io/reference/markers.html - -To run the composition generator, run `make generate-crd`. -You need to have `go` installed for this to work. - -After that, you are able to update the golden files for the component: `make gen-golden-all`. +That's all - You can now run Your claims. This documentation and above workaround is just temporary solution, it should disappear once we actually implement composition functions. diff --git a/cmd/sliprober.go b/cmd/sliexporter.go similarity index 95% rename from cmd/sliprober.go rename to cmd/sliexporter.go index 45ee4aa804..1d398e0536 100644 --- a/cmd/sliprober.go +++ b/cmd/sliexporter.go @@ -5,8 +5,8 @@ import ( "github.com/go-logr/logr" "github.com/spf13/cobra" vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/pkg/sli-exporter" - "github.com/vshn/appcat-apiserver/pkg/sli-exporter/probes" + "github.com/vshn/appcat-apiserver/pkg/sliexporter" + "github.com/vshn/appcat-apiserver/pkg/sliexporter/probes" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "os" @@ -72,7 +72,7 @@ func (s *sliProber) executeSLIProber(cmd *cobra.Command, _ []string) error { } if s.enableVSHNPostgreSQL { - if err = (&sli_exporter.VSHNPostgreSQLReconciler{ + if err = (&sliexporter.VSHNPostgreSQLReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), ProbeManager: &probeManager, diff --git a/config/sliexporter/default/kustomization.yaml b/config/sliexporter/default/kustomization.yaml index 6a28016d6a..3455691687 100644 --- a/config/sliexporter/default/kustomization.yaml +++ b/config/sliexporter/default/kustomization.yaml @@ -1,12 +1,12 @@ # Adds namespace to all resources. -namespace: appcat-sli-exporter +namespace: appcat-sliexporter # Value of this field is prepended to the # names of all resources, e.g. a deployment named # "wordpress" becomes "alices-wordpress". # Note that it should also match with the prefix (text before '-') of the namespace # field above. -namePrefix: appcat-sli-exporter- +namePrefix: appcat-sliexporter- # Labels to add to all resources and selectors. #commonLabels: diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index dce6015d47..0e7d8b2d26 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -2,16 +2,16 @@ * https://github.com/vshn/go-bootstrap/releases[Changelog,window=_blank] 🔗 .Tutorials -* xref:tutorials/dev-environment.adoc[Dev] +//* xref:tutorials/example.adoc[Dev] .How To //* xref:how-tos/example.adoc[Example How-To] .Technical reference -* xref:references/env-variables.adoc[Env variables] +* xref:references/apiserver/env-variables.adoc[Env variables] .Explanation -* xref:explanations/boostrap.adoc[Boostrap] +* xref:explanations/apiserver/boostrap.adoc[Boostrap] * xref:explanations/comp-functions/runtime.adoc[Runtime Library] * xref:explanations/comp-functions/vshn-postgres.adoc[VSHN Postgres Functions] diff --git a/docs/modules/ROOT/pages/explanations/boostrap.adoc b/docs/modules/ROOT/pages/explanations/apiserver/boostrap.adoc similarity index 100% rename from docs/modules/ROOT/pages/explanations/boostrap.adoc rename to docs/modules/ROOT/pages/explanations/apiserver/boostrap.adoc diff --git a/docs/modules/ROOT/pages/references/env-variables.adoc b/docs/modules/ROOT/pages/references/apiserver/env-variables.adoc similarity index 100% rename from docs/modules/ROOT/pages/references/env-variables.adoc rename to docs/modules/ROOT/pages/references/apiserver/env-variables.adoc diff --git a/docs/modules/ROOT/pages/tutorials/dev-environment.adoc b/docs/modules/ROOT/pages/tutorials/dev-environment.adoc deleted file mode 100644 index 7a9d2e583f..0000000000 --- a/docs/modules/ROOT/pages/tutorials/dev-environment.adoc +++ /dev/null @@ -1,9 +0,0 @@ -= Dev Environment - -The repository allows to install the api server in a kind cluster for local development. It also installs test compositions for further checking out how appcat-apiserver works. - -. Run `make local-install` -. Access the cluster `kind get kubeconfig --name appcat-apiserver-v1.24.0 > ~/.kube/config` -. Check the appcat services `kubectl get appcat` - - diff --git a/pkg/sli-exporter/probes/manager.go b/pkg/sliexporter/probes/manager.go similarity index 100% rename from pkg/sli-exporter/probes/manager.go rename to pkg/sliexporter/probes/manager.go diff --git a/pkg/sli-exporter/probes/manager_test.go b/pkg/sliexporter/probes/manager_test.go similarity index 100% rename from pkg/sli-exporter/probes/manager_test.go rename to pkg/sliexporter/probes/manager_test.go diff --git a/pkg/sli-exporter/probes/postgresql.go b/pkg/sliexporter/probes/postgresql.go similarity index 100% rename from pkg/sli-exporter/probes/postgresql.go rename to pkg/sliexporter/probes/postgresql.go diff --git a/pkg/sli-exporter/probes/postgresql_test.go b/pkg/sliexporter/probes/postgresql_test.go similarity index 100% rename from pkg/sli-exporter/probes/postgresql_test.go rename to pkg/sliexporter/probes/postgresql_test.go diff --git a/pkg/sli-exporter/vshnpostgresql_controller.go b/pkg/sliexporter/vshnpostgresql_controller.go similarity index 98% rename from pkg/sli-exporter/vshnpostgresql_controller.go rename to pkg/sliexporter/vshnpostgresql_controller.go index bd66b60e56..e6841ebf75 100644 --- a/pkg/sli-exporter/vshnpostgresql_controller.go +++ b/pkg/sliexporter/vshnpostgresql_controller.go @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -package sli_exporter +package sliexporter import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/pkg/sli-exporter/probes" + "github.com/vshn/appcat-apiserver/pkg/sliexporter/probes" "time" "github.com/jackc/pgx/v5/pgxpool" diff --git a/pkg/sli-exporter/vshnpostgresql_controller_test.go b/pkg/sliexporter/vshnpostgresql_controller_test.go similarity index 99% rename from pkg/sli-exporter/vshnpostgresql_controller_test.go rename to pkg/sliexporter/vshnpostgresql_controller_test.go index 804c8c98ed..8455c19135 100644 --- a/pkg/sli-exporter/vshnpostgresql_controller_test.go +++ b/pkg/sliexporter/vshnpostgresql_controller_test.go @@ -1,8 +1,8 @@ -package sli_exporter +package sliexporter import ( "context" - "github.com/vshn/appcat-apiserver/pkg/sli-exporter/probes" + "github.com/vshn/appcat-apiserver/pkg/sliexporter/probes" "testing" "time" From 33daee20d5a4d7223d061f30d05e65c7e77604c2 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 10:00:17 +0200 Subject: [PATCH 16/26] Update exoscale kafka version --- apis/exoscale/v1/dbaas_exoscale_kafka.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apis/exoscale/v1/dbaas_exoscale_kafka.go b/apis/exoscale/v1/dbaas_exoscale_kafka.go index 618c61c6c5..284c852d7b 100644 --- a/apis/exoscale/v1/dbaas_exoscale_kafka.go +++ b/apis/exoscale/v1/dbaas_exoscale_kafka.go @@ -65,11 +65,11 @@ type ExoscaleKafkaServiceSpec struct { // KafkaSettings contains additional Kafka settings. KafkaSettings runtime.RawExtension `json:"kafkaSettings,omitempty"` - // +kubebuilder:validation:Enum="3.2" - // +kubebuilder:default="3.2" + // +kubebuilder:validation:Enum="3.4" + // +kubebuilder:default="3.4" // Version contains the minor version for Kafka. - // Currently only "3.2" is supported. Leave it empty to always get the latest supported version. + // Currently only "3.4" is supported. Leave it empty to always get the latest supported version. Version string `json:"version,omitempty"` } From 63389e14a1007d9b690ce4214d92c6460db03438 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 10:37:50 +0200 Subject: [PATCH 17/26] Adjust log --- log.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/log.go b/log.go index 0ca21abc50..0b9184c852 100644 --- a/log.go +++ b/log.go @@ -31,12 +31,12 @@ func LogMetadata(cmd *cobra.Command) error { func SetupLogging(cmd *cobra.Command, logLevel int, logFormat string) error { isJson := strings.EqualFold("JSON", logFormat) - log, err := newZapLogger(strings.ToUpper(cmd.Use), "v0.0.1", logLevel, isJson) + log, err := newZapLogger(strings.ToUpper(cmd.Use), logLevel, isJson) cmd.SetContext(logr.NewContext(cmd.Context(), log)) return err } -func newZapLogger(name, version string, verbosityLevel int, useProductionConfig bool) (logr.Logger, error) { +func newZapLogger(name string, verbosityLevel int, useProductionConfig bool) (logr.Logger, error) { cfg := zap.NewDevelopmentConfig() cfg.EncoderConfig.ConsoleSeparator = " | " if useProductionConfig { @@ -51,9 +51,5 @@ func newZapLogger(name, version string, verbosityLevel int, useProductionConfig } zap.ReplaceGlobals(z) zlog := zapr.NewLogger(z).WithName(name) - if useProductionConfig { - // Append the version to each log so that logging stacks like EFK/Loki can correlate errors with specific versions. - return zlog.WithValues("version", version), nil - } return zlog, nil } From 5bea2cda38fe6c5962f5f2f9f9d6e02b73fb9b4f Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 10:53:32 +0200 Subject: [PATCH 18/26] Update generated content --- crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml | 6 +++--- pkg/controller/postgres/deletion_protection_test.go | 2 +- pkg/controller/postgres/reconciler.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml b/crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml index bac637d274..39ab08d891 100644 --- a/crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml +++ b/crds/exoscale.appcat.vshn.io_exoscalekafkas.yaml @@ -87,10 +87,10 @@ spec: type: object x-kubernetes-preserve-unknown-fields: true version: - default: "3.2" - description: Version contains the minor version for Kafka. Currently only "3.2" is supported. Leave it empty to always get the latest supported version. + default: "3.4" + description: Version contains the minor version for Kafka. Currently only "3.4" is supported. Leave it empty to always get the latest supported version. enum: - - "3.2" + - "3.4" type: string zone: default: ch-gva-2 diff --git a/pkg/controller/postgres/deletion_protection_test.go b/pkg/controller/postgres/deletion_protection_test.go index f3213d1271..657b18c1ec 100644 --- a/pkg/controller/postgres/deletion_protection_test.go +++ b/pkg/controller/postgres/deletion_protection_test.go @@ -10,7 +10,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/go-logr/logr" "github.com/stretchr/testify/assert" - vshnv1 "github.com/vshn/component-appcat/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/pkg/controller/postgres/reconciler.go b/pkg/controller/postgres/reconciler.go index bd96053953..4bad7262ab 100644 --- a/pkg/controller/postgres/reconciler.go +++ b/pkg/controller/postgres/reconciler.go @@ -6,8 +6,8 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/crossplane/crossplane-runtime/pkg/errors" - corev1 "k8s.io/api/core/v1" vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" From 21069766467a2e917e76c42c14676b9913dfb97c Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 11:00:24 +0200 Subject: [PATCH 19/26] Remove hardcoded version --- log.go | 1 - 1 file changed, 1 deletion(-) diff --git a/log.go b/log.go index 0b9184c852..94461b9e77 100644 --- a/log.go +++ b/log.go @@ -18,7 +18,6 @@ import ( func LogMetadata(cmd *cobra.Command) error { log := logr.FromContextOrDiscard(cmd.Context()) log.WithValues( - "version", "v0.0.1", "date", time.Now(), "go_os", runtime.GOOS, "go_arch", runtime.GOARCH, From 8953e88faa1fc85bd4176258557abe98d9c9411a Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 11:08:22 +0200 Subject: [PATCH 20/26] BUmp go version --- go.mod | 2 +- .../functions/vshn-postgres-func/schedule.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 194eb8feed..d6bec17438 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/vshn/appcat-apiserver -go 1.19 +go 1.20 require ( github.com/crossplane-contrib/provider-kubernetes v0.7.0 diff --git a/pkg/comp-functions/functions/vshn-postgres-func/schedule.go b/pkg/comp-functions/functions/vshn-postgres-func/schedule.go index eea4f5f9ff..0acd6eb9af 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/schedule.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/schedule.go @@ -3,7 +3,7 @@ package vshnpostgres import ( "context" "fmt" - runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" "math/rand" "time" @@ -19,12 +19,12 @@ var ( // TransformSchedule initializes the backup and maintenance schedules if the user did not explicitly provide a schedule. // The maintenance will be set to a random time on Tuesday night between 21:00 and 5:00, and the backup schedule will be set to once a day between 20:00 and 4:00. // If neither maintenance nor backup is set, the function will make sure that there will be backup scheduled one hour before the maintenance. -func TransformSchedule(ctx context.Context, iof *runtime2.Runtime) runtime2.Result { +func TransformSchedule(ctx context.Context, iof *runtime.Runtime) runtime.Result { comp := vshnv1.VSHNPostgreSQL{} err := iof.Desired.GetComposite(ctx, &comp) if err != nil { - return runtime2.NewFatalErr(ctx, "failed to parse composite", err) + return runtime.NewFatalErr(ctx, "failed to parse composite", err) } rng := rand.New(rand.NewSource(time.Now().UnixNano())) @@ -49,8 +49,8 @@ func TransformSchedule(ctx context.Context, iof *runtime2.Runtime) runtime2.Resu err = iof.Desired.SetComposite(ctx, &comp) if err != nil { - return runtime2.NewFatalErr(ctx, "failed to set composite", err) + return runtime.NewFatalErr(ctx, "failed to set composite", err) } - return runtime2.NewNormal() + return runtime.NewNormal() } From 864cc0e568614b3b83fd9b83189fc27ef83b4335 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura <58511627+zugao@users.noreply.github.com> Date: Mon, 22 May 2023 11:12:51 +0200 Subject: [PATCH 21/26] Fix format in README Co-authored-by: Kidswiss --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a9bcbd1c12..65525d2631 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,8 @@ go run main.go start grpc if You want to run gRPC server in local kind cluster, please use: 1. [kindev](https://github.com/vshn/kindev). In makefile replace target: - 1. ``` + 1. + ``` $(crossplane_sentinel): export KUBECONFIG = $(KIND_KUBECONFIG) $(crossplane_sentinel): kind-setup local-pv-setup # below line loads image to kind @@ -235,7 +236,8 @@ if You want to run gRPC server in local kind cluster, please use: @touch $@ ``` 2. [component-appcat](https://github.com/vshn/component-appcat) please append [file](https://github.com/vshn/component-appcat/blob/master/tests/golden/vshn/appcat/appcat/21_composition_vshn_postgres.yaml) with: - 1. ``` + 1. + ``` compositeTypeRef: apiVersion: vshn.appcat.vshn.io/v1 kind: XVSHNPostgreSQL From 1c9e38eb963b154113405323160cf40a6883d7dd Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 11:41:32 +0200 Subject: [PATCH 22/26] Refactor runtime scheme --- cmd/controller.go | 10 ++-------- cmd/sliexporter.go | 10 ++-------- pkg/scheme.go | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 pkg/scheme.go diff --git a/cmd/controller.go b/cmd/controller.go index 13d32644c1..2555a3df4b 100644 --- a/cmd/controller.go +++ b/cmd/controller.go @@ -1,12 +1,10 @@ package cmd import ( - xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/go-logr/logr" "github.com/spf13/cobra" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + "github.com/vshn/appcat-apiserver/pkg" "github.com/vshn/appcat-apiserver/pkg/controller/postgres" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" @@ -19,7 +17,7 @@ type controller struct { } var c = controller{ - scheme: runtime.NewScheme(), + scheme: pkg.SetupScheme(), } var ControllerCMD = &cobra.Command{ @@ -30,10 +28,6 @@ var ControllerCMD = &cobra.Command{ } func init() { - _ = corev1.SchemeBuilder.AddToScheme(c.scheme) - _ = xkube.SchemeBuilder.AddToScheme(c.scheme) - _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(c.scheme) - ControllerCMD.Flags().StringVar(&c.metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") ControllerCMD.Flags().StringVar(&c.healthAddr, "health-addr", ":8081", "The address the probe endpoint binds to.") ControllerCMD.Flags().BoolVar(&c.leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ diff --git a/cmd/sliexporter.go b/cmd/sliexporter.go index 1d398e0536..3843944f34 100644 --- a/cmd/sliexporter.go +++ b/cmd/sliexporter.go @@ -1,13 +1,11 @@ package cmd import ( - xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/go-logr/logr" "github.com/spf13/cobra" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + "github.com/vshn/appcat-apiserver/pkg" "github.com/vshn/appcat-apiserver/pkg/sliexporter" "github.com/vshn/appcat-apiserver/pkg/sliexporter/probes" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "os" ctrl "sigs.k8s.io/controller-runtime" @@ -24,7 +22,7 @@ type sliProber struct { } var s = sliProber{ - scheme: runtime.NewScheme(), + scheme: pkg.SetupScheme(), } var SLIProberCMD = &cobra.Command{ @@ -35,10 +33,6 @@ var SLIProberCMD = &cobra.Command{ } func init() { - _ = corev1.SchemeBuilder.AddToScheme(s.scheme) - _ = xkube.SchemeBuilder.AddToScheme(s.scheme) - _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s.scheme) - SLIProberCMD.Flags().StringVar(&s.metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") SLIProberCMD.Flags().StringVar(&s.probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") SLIProberCMD.Flags().BoolVar(&s.leaderElect, "leader-elect", false, "Enable leader election for controller manager. "+ diff --git a/pkg/scheme.go b/pkg/scheme.go new file mode 100644 index 0000000000..0ff894ceb5 --- /dev/null +++ b/pkg/scheme.go @@ -0,0 +1,16 @@ +package pkg + +import ( + xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" + vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func SetupScheme() *runtime.Scheme { + s := runtime.NewScheme() + _ = corev1.SchemeBuilder.AddToScheme(s) + _ = xkube.SchemeBuilder.AddToScheme(s) + _ = vshnv1.SchemeBuilder.SchemeBuilder.AddToScheme(s) + return s +} From 7239ea37c51fd6e6eefc175f1e4ea74799cfc00d Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 14:29:04 +0200 Subject: [PATCH 23/26] Change repository to appcat --- .gitignore | 2 +- .goreleaser.yml | 18 +-- Dockerfile | 6 +- Makefile | 15 ++- README.md | 4 +- apis/appcat/v1/generated.pb.go | 124 +++++++++--------- apis/exoscale/v1/dbaas_exoscale_kafka.go | 2 +- apis/exoscale/v1/dbaas_exoscale_mysql.go | 2 +- apis/exoscale/v1/dbaas_exoscale_opensearch.go | 2 +- apis/exoscale/v1/dbaas_exoscale_postgresql.go | 2 +- apis/exoscale/v1/dbaas_exoscale_redis.go | 2 +- apis/exoscale/v1/zz_generated.deepcopy.go | 2 +- apis/vshn/v1/dbaas_vshn_postgresql.go | 2 +- apis/vshn/v1/dbaas_vshn_redis.go | 2 +- apis/vshn/v1/zz_generated.deepcopy.go | 2 +- cmd/apiserver.go | 6 +- cmd/controller.go | 4 +- cmd/grpc.go | 4 +- cmd/sliexporter.go | 6 +- config/apiserver/aggregated-apiserver.yaml | 2 +- config/apiserver/role.yaml | 2 +- config/controller/deployment.yaml | 2 +- go.mod | 2 +- main.go | 2 +- pkg/apiserver/appcat/appcat.go | 2 +- pkg/apiserver/appcat/appcat_test.go | 4 +- pkg/apiserver/appcat/delete.go | 2 +- pkg/apiserver/appcat/get.go | 4 +- pkg/apiserver/appcat/get_test.go | 2 +- pkg/apiserver/appcat/list.go | 4 +- pkg/apiserver/appcat/list_test.go | 2 +- pkg/apiserver/appcat/table.go | 2 +- pkg/apiserver/appcat/table_test.go | 2 +- pkg/apiserver/appcat/update.go | 2 +- pkg/apiserver/vshn/postgres/backup.go | 4 +- pkg/apiserver/vshn/postgres/backup_test.go | 6 +- pkg/apiserver/vshn/postgres/delete.go | 2 +- pkg/apiserver/vshn/postgres/get.go | 4 +- pkg/apiserver/vshn/postgres/get_test.go | 6 +- pkg/apiserver/vshn/postgres/list.go | 4 +- pkg/apiserver/vshn/postgres/list_test.go | 6 +- pkg/apiserver/vshn/postgres/sgbackups.go | 2 +- pkg/apiserver/vshn/postgres/sgbackups_test.go | 2 +- pkg/apiserver/vshn/postgres/table.go | 2 +- pkg/apiserver/vshn/postgres/table_test.go | 2 +- pkg/apiserver/vshn/postgres/update.go | 2 +- pkg/apiserver/vshn/postgres/vshnpostgresql.go | 2 +- .../vshn/postgres/vshnpostgresql_test.go | 4 +- .../functions/vshn-postgres-func/alerting.go | 4 +- .../vshn-postgres-func/alerting_test.go | 4 +- .../vshn-postgres-func/common_test.go | 2 +- .../vshn-postgres-func/encrypted_pvc.go | 4 +- .../vshn-postgres-func/encrypted_pvc_test.go | 4 +- .../functions/vshn-postgres-func/schedule.go | 4 +- .../vshn-postgres-func/schedule_test.go | 2 +- .../functions/vshn-postgres-func/url.go | 4 +- .../functions/vshn-postgres-func/url_test.go | 2 +- pkg/comp-functions/runtime/runtime.go | 2 +- .../postgres/deletion_protection_test.go | 2 +- pkg/controller/postgres/reconciler.go | 2 +- pkg/controller/postgres/reconciler_test.go | 2 +- pkg/scheme.go | 2 +- pkg/sliexporter/vshnpostgresql_controller.go | 4 +- .../vshnpostgresql_controller_test.go | 6 +- test/mocks/mock_sgbackups.go | 2 +- test/mocks/mock_vshnpostgresqls.go | 2 +- 66 files changed, 173 insertions(+), 172 deletions(-) diff --git a/.gitignore b/.gitignore index 52e547f1cc..0b6c2d4881 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ dist/ .github/release-notes.md # Binaries for programs and plugins -appcat-apiserver +appcat # temp file, editor and IDE paraphernalia .idea diff --git a/.goreleaser.yml b/.goreleaser.yml index 27788a0fd1..29638e8c8a 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,5 @@ builds: - - binary: appcat-apiserver + - binary: appcat env: - CGO_ENABLED=0 # this is needed otherwise the Docker image build is faulty goarch: @@ -26,27 +26,27 @@ dockers: build_flag_templates: - "--platform=linux/amd64" image_templates: - - "ghcr.io/vshn/appcat-apiserver:v{{ .Version }}-amd64" + - "ghcr.io/vshn/appcat:v{{ .Version }}-amd64" - goarch: arm64 use: buildx build_flag_templates: - "--platform=linux/arm64/v8" image_templates: - - "ghcr.io/vshn/appcat-apiserver:v{{ .Version }}-arm64" + - "ghcr.io/vshn/appcat:v{{ .Version }}-arm64" docker_manifests: # For prereleases, updating `latest` does not make sense. # Only the image for the exact version should be pushed. - - name_template: "{{ if not .Prerelease }}ghcr.io/vshn/appcat-apiserver:latest{{ end }}" + - name_template: "{{ if not .Prerelease }}ghcr.io/vshn/appcat:latest{{ end }}" image_templates: - - "ghcr.io/vshn/appcat-apiserver:v{{ .Version }}-amd64" - - "ghcr.io/vshn/appcat-apiserver:v{{ .Version }}-arm64" + - "ghcr.io/vshn/appcat:v{{ .Version }}-amd64" + - "ghcr.io/vshn/appcat:v{{ .Version }}-arm64" - - name_template: "ghcr.io/vshn/appcat-apiserver:v{{ .Version }}" + - name_template: "ghcr.io/vshn/appcat:v{{ .Version }}" image_templates: - - "ghcr.io/vshn/appcat-apiserver:v{{ .Version }}-amd64" - - "ghcr.io/vshn/appcat-apiserver:v{{ .Version }}-arm64" + - "ghcr.io/vshn/appcat:v{{ .Version }}-amd64" + - "ghcr.io/vshn/appcat:v{{ .Version }}-arm64" release: prerelease: auto diff --git a/Dockerfile b/Dockerfile index 7f62a3d96f..e662e176de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM docker.io/library/alpine:3.15 as runtime -ENTRYPOINT ["appcat-apiserver"] +ENTRYPOINT ["appcat"] RUN \ apk add --update --no-cache \ @@ -11,8 +11,8 @@ RUN \ RUN \ mkdir /.cache && chmod -R g=u /.cache -COPY appcat-apiserver /usr/local/bin/ +COPY appcat /usr/local/bin/ -RUN chmod a+x /usr/local/bin/appcat-apiserver +RUN chmod a+x /usr/local/bin/appcat USER 65532:0 diff --git a/Makefile b/Makefile index 7128a8900e..89f4a6916f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Image URL to use all building/pushing image targets IMG_TAG ?= latest -GHCR_IMG ?= ghcr.io/vshn/appcat-apiserver:$(IMG_TAG) +GHCR_IMG ?= ghcr.io/vshn/appcat:$(IMG_TAG) DOCKER_CMD ?= docker # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) @@ -23,11 +23,11 @@ DOCKER_IMAGE_GOOS = linux DOCKER_IMAGE_GOARCH = amd64 PROJECT_ROOT_DIR = . -PROJECT_NAME ?= appcat-apiserver +PROJECT_NAME ?= appcat PROJECT_OWNER ?= vshn PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) -BIN_FILENAME ?= $(PROJECT_DIR)/appcat-apiserver +BIN_FILENAME ?= $(PROJECT_DIR)/appcat ## BUILD:go go_bin ?= $(PWD)/.work/bin @@ -61,6 +61,7 @@ help: ## Display this help. .PHONY: generate generate: export PATH := $(go_bin):$(PATH) generate: $(protoc_bin) ## Generate code with controller-gen and protobuf. + go version rm -rf apis/generated go run sigs.k8s.io/controller-tools/cmd/controller-gen paths=./apis/... object crd:crdVersions=v1 output:artifacts:config=./apis/generated go generate ./... @@ -69,14 +70,14 @@ generate: $(protoc_bin) ## Generate code with controller-gen and protobuf. # So we make it explicitly a string. $(sed) -i ':a;N;$$!ba;s/- =\n/- "="\n/g' apis/generated/vshn.appcat.vshn.io_vshnpostgresqls.yaml rm -rf crds && cp -r apis/generated crds - go run sigs.k8s.io/controller-tools/cmd/controller-gen rbac:roleName=appcat-apiserver paths="{./apis/...,./pkg/apiserver/...}" output:artifacts:config=config/apiserver + go run sigs.k8s.io/controller-tools/cmd/controller-gen rbac:roleName=appcat paths="{./apis/...,./pkg/apiserver/...}" output:artifacts:config=config/apiserver go run k8s.io/code-generator/cmd/go-to-protobuf \ - --packages=github.com/vshn/appcat-apiserver/apis/appcat/v1 \ + --packages=github.com/vshn/appcat/apis/appcat/v1 \ --output-base=./.work/tmp \ --go-header-file=./pkg/apiserver/hack/boilerplate.txt \ --apimachinery-packages='-k8s.io/apimachinery/pkg/util/intstr,-k8s.io/apimachinery/pkg/api/resource,-k8s.io/apimachinery/pkg/runtime/schema,-k8s.io/apimachinery/pkg/runtime,-k8s.io/apimachinery/pkg/apis/meta/v1,-k8s.io/apimachinery/pkg/apis/meta/v1beta1,-k8s.io/api/core/v1,-k8s.io/api/rbac/v1' \ --proto-import=./.work/kubernetes/vendor/ && \ - mv ./.work/tmp/github.com/vshn/appcat-apiserver/apis/appcat/v1/generated.pb.go ./apis/appcat/v1/ && \ + mv ./.work/tmp/github.com/vshn/appcat/apis/appcat/v1/generated.pb.go ./apis/appcat/v1/ && \ rm -rf ./.work/tmp .PHONY: fmt @@ -117,4 +118,4 @@ docker-push: docker-build ## Push docker image with the manager. .PHONY: clean clean: - rm -rf bin/ appcat-apiserver .work/ docs/node_modules $docs_out_dir .public .cache apiserver.local.config apis/generated default.sock + rm -rf bin/ appcat .work/ docs/node_modules $docs_out_dir .public .cache apiserver.local.config apis/generated default.sock diff --git a/README.md b/README.md index 65525d2631..51a7965a53 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -[![Build](https://img.shields.io/github/actions/workflow/status/vshn/appcat-apiserver/test.yml?branch=master)](https://github.com/vshn/appcat-apiserver/actions?query=workflow%3ATest) +[![Build](https://img.shields.io/github/actions/workflow/status/vshn/appcat/test.yml?branch=master)](https://github.com/vshn/appcat/actions?query=workflow%3ATest) ![Go version](https://img.shields.io/github/go-mod/go-version/appuio/control-api) ![Kubernetes version](https://img.shields.io/badge/k8s-v1.24-blue) [![Version](https://img.shields.io/github/v/release/appuio/control-api)](https://github.com/appuio/control-api/releases) -[![GitHub downloads](https://img.shields.io/github/downloads/vshn/appcat-apiserver/total)](https://github.com/appuio/control-api/releases) +[![GitHub downloads](https://img.shields.io/github/downloads/vshn/appcat/total)](https://github.com/appuio/control-api/releases) # AppCat diff --git a/apis/appcat/v1/generated.pb.go b/apis/appcat/v1/generated.pb.go index 9ef6678b3f..dc29d46fea 100644 --- a/apis/appcat/v1/generated.pb.go +++ b/apis/appcat/v1/generated.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: .work/tmp/github.com/vshn/appcat-apiserver/apis/appcat/v1/generated.proto +// source: .work/tmp/github.com/vshn/appcat/apis/appcat/v1/generated.proto package v1 @@ -32,7 +32,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package func (m *AppCat) Reset() { *m = AppCat{} } func (*AppCat) ProtoMessage() {} func (*AppCat) Descriptor() ([]byte, []int) { - return fileDescriptor_ade2e39f600d64ee, []int{0} + return fileDescriptor_3f37f7f54c7900be, []int{0} } func (m *AppCat) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -60,7 +60,7 @@ var xxx_messageInfo_AppCat proto.InternalMessageInfo func (m *AppCatList) Reset() { *m = AppCatList{} } func (*AppCatList) ProtoMessage() {} func (*AppCatList) Descriptor() ([]byte, []int) { - return fileDescriptor_ade2e39f600d64ee, []int{1} + return fileDescriptor_3f37f7f54c7900be, []int{1} } func (m *AppCatList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -88,7 +88,7 @@ var xxx_messageInfo_AppCatList proto.InternalMessageInfo func (m *AppCatStatus) Reset() { *m = AppCatStatus{} } func (*AppCatStatus) ProtoMessage() {} func (*AppCatStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_ade2e39f600d64ee, []int{2} + return fileDescriptor_3f37f7f54c7900be, []int{2} } func (m *AppCatStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -116,7 +116,7 @@ var xxx_messageInfo_AppCatStatus proto.InternalMessageInfo func (m *SGBackupInfo) Reset() { *m = SGBackupInfo{} } func (*SGBackupInfo) ProtoMessage() {} func (*SGBackupInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_ade2e39f600d64ee, []int{3} + return fileDescriptor_3f37f7f54c7900be, []int{3} } func (m *SGBackupInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -144,7 +144,7 @@ var xxx_messageInfo_SGBackupInfo proto.InternalMessageInfo func (m *VSHNPostgresBackup) Reset() { *m = VSHNPostgresBackup{} } func (*VSHNPostgresBackup) ProtoMessage() {} func (*VSHNPostgresBackup) Descriptor() ([]byte, []int) { - return fileDescriptor_ade2e39f600d64ee, []int{4} + return fileDescriptor_3f37f7f54c7900be, []int{4} } func (m *VSHNPostgresBackup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -172,7 +172,7 @@ var xxx_messageInfo_VSHNPostgresBackup proto.InternalMessageInfo func (m *VSHNPostgresBackupList) Reset() { *m = VSHNPostgresBackupList{} } func (*VSHNPostgresBackupList) ProtoMessage() {} func (*VSHNPostgresBackupList) Descriptor() ([]byte, []int) { - return fileDescriptor_ade2e39f600d64ee, []int{5} + return fileDescriptor_3f37f7f54c7900be, []int{5} } func (m *VSHNPostgresBackupList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -200,7 +200,7 @@ var xxx_messageInfo_VSHNPostgresBackupList proto.InternalMessageInfo func (m *VSHNPostgresBackupStatus) Reset() { *m = VSHNPostgresBackupStatus{} } func (*VSHNPostgresBackupStatus) ProtoMessage() {} func (*VSHNPostgresBackupStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_ade2e39f600d64ee, []int{6} + return fileDescriptor_3f37f7f54c7900be, []int{6} } func (m *VSHNPostgresBackupStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -226,66 +226,66 @@ func (m *VSHNPostgresBackupStatus) XXX_DiscardUnknown() { var xxx_messageInfo_VSHNPostgresBackupStatus proto.InternalMessageInfo func init() { - proto.RegisterType((*AppCat)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.AppCat") - proto.RegisterMapType((AppCatSpec)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.AppCat.SpecEntry") - proto.RegisterType((*AppCatList)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.AppCatList") - proto.RegisterType((*AppCatStatus)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.AppCatStatus") - proto.RegisterType((*SGBackupInfo)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.SGBackupInfo") - proto.RegisterType((*VSHNPostgresBackup)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.VSHNPostgresBackup") - proto.RegisterType((*VSHNPostgresBackupList)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.VSHNPostgresBackupList") - proto.RegisterType((*VSHNPostgresBackupStatus)(nil), "github.com.vshn.appcat_apiserver.apis.appcat.v1.VSHNPostgresBackupStatus") + proto.RegisterType((*AppCat)(nil), "github.com.vshn.appcat.apis.appcat.v1.AppCat") + proto.RegisterMapType((AppCatSpec)(nil), "github.com.vshn.appcat.apis.appcat.v1.AppCat.SpecEntry") + proto.RegisterType((*AppCatList)(nil), "github.com.vshn.appcat.apis.appcat.v1.AppCatList") + proto.RegisterType((*AppCatStatus)(nil), "github.com.vshn.appcat.apis.appcat.v1.AppCatStatus") + proto.RegisterType((*SGBackupInfo)(nil), "github.com.vshn.appcat.apis.appcat.v1.SGBackupInfo") + proto.RegisterType((*VSHNPostgresBackup)(nil), "github.com.vshn.appcat.apis.appcat.v1.VSHNPostgresBackup") + proto.RegisterType((*VSHNPostgresBackupList)(nil), "github.com.vshn.appcat.apis.appcat.v1.VSHNPostgresBackupList") + proto.RegisterType((*VSHNPostgresBackupStatus)(nil), "github.com.vshn.appcat.apis.appcat.v1.VSHNPostgresBackupStatus") } func init() { - proto.RegisterFile(".work/tmp/github.com/vshn/appcat-apiserver/apis/appcat/v1/generated.proto", fileDescriptor_ade2e39f600d64ee) + proto.RegisterFile(".work/tmp/github.com/vshn/appcat/apis/appcat/v1/generated.proto", fileDescriptor_3f37f7f54c7900be) } -var fileDescriptor_ade2e39f600d64ee = []byte{ - // 703 bytes of a gzipped FileDescriptorProto +var fileDescriptor_3f37f7f54c7900be = []byte{ + // 693 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x4f, 0x13, 0x41, - 0x14, 0xef, 0x96, 0xff, 0x53, 0x94, 0x32, 0xf1, 0x4f, 0xed, 0x61, 0x21, 0x3d, 0x71, 0x61, 0x56, - 0x88, 0x11, 0x62, 0xe2, 0x81, 0x05, 0xa2, 0x4d, 0x14, 0x71, 0xab, 0xc6, 0x18, 0x12, 0x9d, 0x2e, - 0xc3, 0x76, 0xad, 0xbb, 0x33, 0xee, 0x4c, 0x17, 0xb9, 0xf9, 0x11, 0xfc, 0x1c, 0x7e, 0x10, 0xd3, - 0x23, 0x47, 0x4e, 0x04, 0xea, 0xc9, 0xaf, 0x60, 0x62, 0x62, 0x66, 0x67, 0x28, 0xa5, 0xdb, 0x2a, - 0x6d, 0x08, 0xb7, 0x79, 0x6f, 0xe7, 0xfd, 0x7e, 0x6f, 0x7e, 0xef, 0xfd, 0x92, 0x05, 0x65, 0xb4, - 0x4f, 0xa3, 0xba, 0x25, 0x02, 0x66, 0x79, 0xbe, 0xa8, 0x35, 0xaa, 0xc8, 0xa5, 0x81, 0x15, 0xf3, - 0x5a, 0x68, 0x61, 0xc6, 0x5c, 0x2c, 0x16, 0x31, 0xf3, 0x39, 0x89, 0x62, 0x12, 0x59, 0xf2, 0xa4, - 0xb3, 0x56, 0xbc, 0x64, 0x79, 0x24, 0x24, 0x11, 0x16, 0x64, 0x17, 0xb1, 0x88, 0x0a, 0x0a, 0x3b, - 0x00, 0x90, 0x04, 0x40, 0xea, 0xea, 0xfb, 0x36, 0x00, 0x92, 0x27, 0x9d, 0x45, 0xf1, 0x52, 0x71, - 0xb1, 0x83, 0xd1, 0xa3, 0x1e, 0xb5, 0x12, 0x9c, 0x6a, 0x63, 0x2f, 0x89, 0x92, 0x20, 0x39, 0x29, - 0xfc, 0xe2, 0x83, 0xfa, 0x2a, 0x47, 0x3e, 0x95, 0x6d, 0x04, 0xd8, 0xad, 0xf9, 0x21, 0x89, 0x0e, - 0x2c, 0x56, 0xf7, 0x54, 0x5f, 0x01, 0x11, 0xb8, 0x47, 0x57, 0x45, 0xab, 0x5f, 0x55, 0xd4, 0x08, - 0x85, 0x1f, 0x90, 0x54, 0xc1, 0xc3, 0xff, 0x15, 0x70, 0xb7, 0x46, 0x02, 0xdc, 0x5d, 0x57, 0xfa, - 0x93, 0x05, 0xe3, 0x6b, 0x8c, 0xad, 0x63, 0x01, 0x3f, 0x80, 0x49, 0xd9, 0xce, 0x2e, 0x16, 0xb8, - 0x60, 0xcc, 0x1b, 0x0b, 0xb9, 0xe5, 0xfb, 0x48, 0xa1, 0xa2, 0x4e, 0x54, 0xc4, 0xea, 0x9e, 0xd2, - 0x44, 0xde, 0x46, 0xf1, 0x12, 0x7a, 0x51, 0xfd, 0x48, 0x5c, 0xf1, 0x9c, 0x08, 0x6c, 0xc3, 0xe6, - 0xf1, 0x5c, 0xa6, 0x75, 0x3c, 0x07, 0xce, 0x73, 0x4e, 0x1b, 0x15, 0x7e, 0x06, 0xa3, 0x9c, 0x11, - 0xb7, 0x90, 0x9d, 0x1f, 0x59, 0xc8, 0x2d, 0xaf, 0xa1, 0x01, 0xa5, 0x47, 0xaa, 0x51, 0x54, 0x61, - 0xc4, 0xdd, 0x0c, 0x45, 0x74, 0x60, 0x17, 0x35, 0xdd, 0xa8, 0x4c, 0xfd, 0x3e, 0x9e, 0x03, 0xea, - 0x86, 0x8c, 0x9c, 0x84, 0x0a, 0x12, 0x30, 0xce, 0x05, 0x16, 0x0d, 0x5e, 0x18, 0x49, 0x9e, 0xf4, - 0x78, 0x48, 0xd2, 0x4a, 0x02, 0x62, 0xdf, 0xd4, 0x84, 0xe3, 0x2a, 0x76, 0x34, 0x78, 0x71, 0x05, - 0x4c, 0xb5, 0xbb, 0x82, 0x79, 0x30, 0x52, 0x27, 0x07, 0x89, 0x86, 0x53, 0x8e, 0x3c, 0xc2, 0x5b, - 0x60, 0x2c, 0xc6, 0x9f, 0x1a, 0xa4, 0x90, 0x4d, 0x72, 0x2a, 0x78, 0x94, 0x5d, 0x35, 0x4a, 0x4d, - 0x03, 0xe8, 0xa6, 0x9f, 0xf9, 0x5c, 0xc0, 0x9d, 0xd4, 0x0c, 0xd0, 0xe5, 0x66, 0x20, 0xab, 0x93, - 0x09, 0xe4, 0x75, 0x87, 0x93, 0x67, 0x99, 0x0e, 0xfd, 0x77, 0xc0, 0x98, 0x2f, 0x48, 0xc0, 0xf5, - 0x00, 0x56, 0x86, 0xd4, 0xc2, 0xbe, 0xa1, 0x39, 0xc6, 0xca, 0x12, 0xcd, 0x51, 0xa0, 0xa5, 0x97, - 0x60, 0xba, 0x53, 0x2b, 0xb8, 0x06, 0x66, 0x5c, 0x1a, 0x30, 0xca, 0x7d, 0xe1, 0xd3, 0x70, 0x0b, - 0x07, 0x44, 0x49, 0x62, 0xdf, 0xd5, 0xe5, 0x33, 0xeb, 0x17, 0x3f, 0x3b, 0xdd, 0xf7, 0x4b, 0x3f, - 0xb2, 0x60, 0xba, 0xf2, 0xc4, 0xc6, 0x6e, 0xbd, 0xc1, 0xca, 0xe1, 0x1e, 0x85, 0xbb, 0x00, 0xd0, - 0xf6, 0x66, 0x5d, 0xe9, 0x96, 0x76, 0xe0, 0xc2, 0xb7, 0x60, 0x82, 0x45, 0xd4, 0x25, 0x9c, 0x27, - 0x03, 0xcb, 0x2d, 0x2f, 0xf6, 0xa5, 0xd0, 0xf6, 0x42, 0x0e, 0xde, 0xdf, 0xfc, 0x22, 0x48, 0xc8, - 0x7d, 0x1a, 0xda, 0x33, 0x1a, 0x7f, 0x62, 0x5b, 0xa1, 0x38, 0x67, 0x70, 0x30, 0x06, 0xb3, 0xd5, - 0xf6, 0x6b, 0xa2, 0x00, 0xcb, 0x97, 0xea, 0xcd, 0x1c, 0x90, 0xe3, 0x9e, 0xe6, 0x98, 0xb5, 0xbb, - 0xf1, 0x9c, 0x34, 0x45, 0xe9, 0x97, 0x01, 0xe0, 0x9b, 0xca, 0xd3, 0xad, 0x6d, 0xca, 0x85, 0x17, - 0x11, 0xae, 0x8a, 0xae, 0xc5, 0xf2, 0x67, 0xfe, 0x53, 0x4a, 0x96, 0x07, 0xde, 0xb9, 0x74, 0xdb, - 0xff, 0xf6, 0x62, 0xe9, 0xc4, 0x00, 0x77, 0xd2, 0x45, 0xd7, 0x60, 0xaf, 0xda, 0x45, 0x7b, 0xad, - 0x5f, 0xc1, 0x53, 0xfb, 0x58, 0xed, 0x7b, 0x16, 0x14, 0xfa, 0xe9, 0x02, 0x5f, 0x9d, 0x6f, 0xaf, - 0x31, 0xcc, 0x66, 0xe5, 0x7a, 0x6e, 0x6e, 0xd4, 0x6b, 0x73, 0x87, 0x72, 0xc7, 0xed, 0xcb, 0x6e, - 0x2d, 0xdc, 0x00, 0x79, 0x29, 0x6c, 0x15, 0x73, 0x52, 0x0e, 0xb9, 0xc0, 0xa1, 0x4b, 0x12, 0xb3, - 0x4c, 0xd9, 0x05, 0x2d, 0x4b, 0x7e, 0xa3, 0xeb, 0xbb, 0x93, 0xaa, 0xb0, 0x5f, 0x37, 0x4f, 0xcd, - 0xcc, 0xe1, 0xa9, 0x99, 0x39, 0x3a, 0x35, 0x33, 0x5f, 0x5b, 0xa6, 0xd1, 0x6c, 0x99, 0xc6, 0x61, - 0xcb, 0x34, 0x8e, 0x5a, 0xa6, 0x71, 0xd2, 0x32, 0x8d, 0x6f, 0x3f, 0xcd, 0xcc, 0xbb, 0x41, 0x7f, - 0x24, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x80, 0x59, 0x03, 0x04, 0x84, 0x08, 0x00, 0x00, + 0x1c, 0xed, 0x96, 0xff, 0x03, 0x4a, 0x99, 0xf8, 0xa7, 0xf6, 0xb0, 0x90, 0x26, 0x24, 0x5c, 0x98, + 0x15, 0x34, 0x82, 0x5e, 0x08, 0x0b, 0x44, 0x89, 0x8a, 0xb8, 0x35, 0xc6, 0xa8, 0x31, 0x4e, 0x97, + 0x61, 0xbb, 0xd6, 0xdd, 0x99, 0xec, 0x4c, 0x8b, 0xdc, 0xfc, 0x08, 0x7e, 0x0e, 0x3f, 0x84, 0x47, + 0xc3, 0x91, 0x93, 0xe1, 0x84, 0x52, 0x4f, 0x7e, 0x05, 0x4f, 0x66, 0xfe, 0xb4, 0x94, 0x2e, 0xd5, + 0x42, 0x0c, 0xb7, 0x99, 0xd9, 0x79, 0xef, 0xfd, 0xe6, 0xf5, 0xbd, 0xa4, 0x60, 0x09, 0xed, 0xd0, + 0xa4, 0xea, 0x88, 0x88, 0x39, 0x41, 0x28, 0x2a, 0xb5, 0x32, 0xf2, 0x69, 0xe4, 0xd4, 0x79, 0x25, + 0x76, 0x30, 0x63, 0x3e, 0x16, 0x0e, 0x66, 0x21, 0x6f, 0xae, 0xeb, 0x73, 0x4e, 0x40, 0x62, 0x92, + 0x60, 0x41, 0xb6, 0x10, 0x4b, 0xa8, 0xa0, 0x70, 0xfa, 0x18, 0x86, 0x24, 0x0c, 0xe9, 0xab, 0x48, + 0xc2, 0x9a, 0xeb, 0xfa, 0x5c, 0x61, 0xb6, 0x8d, 0x3d, 0xa0, 0x01, 0x75, 0x14, 0xba, 0x5c, 0xdb, + 0x56, 0x3b, 0xb5, 0x51, 0x2b, 0xcd, 0x5a, 0xb8, 0x5d, 0x5d, 0xe4, 0x28, 0xa4, 0x52, 0x3c, 0xc2, + 0x7e, 0x25, 0x8c, 0x49, 0xb2, 0xeb, 0xb0, 0x6a, 0xa0, 0xa7, 0x89, 0x88, 0xc0, 0xa7, 0xcc, 0x52, + 0x70, 0xba, 0xa1, 0x92, 0x5a, 0x2c, 0xc2, 0x88, 0xa4, 0x00, 0x77, 0xfe, 0x05, 0xe0, 0x7e, 0x85, + 0x44, 0xb8, 0x13, 0x57, 0xfc, 0x95, 0x05, 0x83, 0xcb, 0x8c, 0xad, 0x60, 0x01, 0xdf, 0x82, 0x61, + 0x39, 0xce, 0x16, 0x16, 0x38, 0x6f, 0x4d, 0x59, 0x33, 0xa3, 0xf3, 0x37, 0x91, 0x66, 0x45, 0xed, + 0xac, 0x88, 0x55, 0x03, 0xed, 0x89, 0xbc, 0x8d, 0xea, 0x73, 0xe8, 0x49, 0xf9, 0x1d, 0xf1, 0xc5, + 0x63, 0x22, 0xb0, 0x0b, 0xf7, 0x0e, 0x27, 0x33, 0x8d, 0xc3, 0x49, 0x70, 0x7c, 0xe6, 0xb5, 0x58, + 0x61, 0x00, 0xfa, 0x39, 0x23, 0x7e, 0x3e, 0x3b, 0xd5, 0x37, 0x33, 0x3a, 0xbf, 0x80, 0x7a, 0x32, + 0x1c, 0xe9, 0xf1, 0x50, 0x89, 0x11, 0x7f, 0x2d, 0x16, 0xc9, 0xae, 0x5b, 0x30, 0x22, 0xfd, 0xf2, + 0xe8, 0xf7, 0xe1, 0x24, 0xd0, 0x37, 0xe4, 0xce, 0x53, 0x02, 0xf0, 0x15, 0x18, 0xe4, 0x02, 0x8b, + 0x1a, 0xcf, 0xf7, 0xa9, 0x87, 0xdc, 0x3a, 0x93, 0x54, 0x49, 0x41, 0xdd, 0xcb, 0x46, 0x66, 0x50, + 0xef, 0x3d, 0x43, 0x59, 0x58, 0x00, 0x23, 0xad, 0x59, 0x60, 0x0e, 0xf4, 0x55, 0xc9, 0xae, 0xf2, + 0x6b, 0xc4, 0x93, 0x4b, 0x78, 0x05, 0x0c, 0xd4, 0xf1, 0xfb, 0x1a, 0xc9, 0x67, 0xd5, 0x99, 0xde, + 0xdc, 0xcb, 0x2e, 0x5a, 0xc5, 0x2f, 0x16, 0x30, 0xa3, 0x3e, 0x0a, 0xb9, 0x80, 0xaf, 0x53, 0x7e, + 0xa3, 0xde, 0xfc, 0x96, 0x68, 0xe5, 0x76, 0xce, 0x4c, 0x38, 0xdc, 0x3c, 0x69, 0xf3, 0xda, 0x03, + 0x03, 0xa1, 0x20, 0x11, 0x37, 0x66, 0xcf, 0x9e, 0xc9, 0x01, 0xf7, 0x92, 0x61, 0x1e, 0x58, 0x97, + 0x1c, 0x9e, 0xa6, 0x2a, 0x3e, 0x05, 0x63, 0xed, 0x0e, 0xc1, 0x65, 0x30, 0xee, 0xd3, 0x88, 0x51, + 0x1e, 0x8a, 0x90, 0xc6, 0x1b, 0x38, 0x22, 0xda, 0x08, 0xf7, 0xba, 0x81, 0x8f, 0xaf, 0x9c, 0xfc, + 0xec, 0x75, 0xde, 0x2f, 0x7e, 0xcd, 0x82, 0xb1, 0xd2, 0x7d, 0x17, 0xfb, 0xd5, 0x1a, 0x5b, 0x8f, + 0xb7, 0x29, 0xdc, 0x02, 0x80, 0xb6, 0xb2, 0xf3, 0x5f, 0x73, 0xd8, 0xc6, 0x0b, 0x5f, 0x80, 0x21, + 0x96, 0x50, 0x9f, 0x70, 0xae, 0x7e, 0x26, 0xe9, 0x4f, 0x37, 0x09, 0x53, 0x20, 0xe4, 0xe1, 0x9d, + 0xb5, 0x0f, 0x82, 0xc4, 0x3c, 0xa4, 0xb1, 0x3b, 0x6e, 0xf8, 0x87, 0x36, 0x35, 0x8b, 0xd7, 0xa4, + 0x83, 0x75, 0x30, 0x51, 0x6e, 0xbd, 0x26, 0x89, 0xb0, 0x7c, 0xa9, 0x49, 0xe1, 0x19, 0x35, 0x6e, + 0x18, 0x8d, 0x09, 0xb7, 0x93, 0xcf, 0x4b, 0x4b, 0x14, 0xbf, 0x5b, 0x00, 0x3e, 0x2f, 0x3d, 0xd8, + 0xd8, 0xa4, 0x5c, 0x04, 0x09, 0xe1, 0x1a, 0x74, 0x21, 0xa5, 0x6e, 0x76, 0x4d, 0x3b, 0xb9, 0xd4, + 0x63, 0xd2, 0xd2, 0xc3, 0xfe, 0xbd, 0x77, 0xc5, 0x6f, 0x16, 0xb8, 0x96, 0x06, 0x5d, 0x40, 0x95, + 0xde, 0x9c, 0xac, 0xd2, 0xdd, 0x73, 0x3f, 0xb0, 0x4b, 0xad, 0x3e, 0x67, 0x41, 0xbe, 0x9b, 0x1b, + 0xf0, 0xd9, 0x71, 0x52, 0xad, 0xf3, 0xa4, 0x68, 0xf4, 0xd4, 0x94, 0x26, 0xa7, 0xa5, 0xf4, 0x5c, + 0x4d, 0xb8, 0xda, 0x6b, 0x42, 0xe1, 0x2a, 0xc8, 0x49, 0x3b, 0xcb, 0x98, 0x93, 0xf5, 0x98, 0x0b, + 0x1c, 0xfb, 0x44, 0x15, 0x63, 0xc4, 0xcd, 0x1b, 0x5b, 0x72, 0xab, 0x1d, 0xdf, 0xbd, 0x14, 0xc2, + 0x7d, 0xb8, 0x77, 0x64, 0x67, 0xf6, 0x8f, 0xec, 0xcc, 0xc1, 0x91, 0x9d, 0xf9, 0xd8, 0xb0, 0xad, + 0xbd, 0x86, 0x6d, 0xed, 0x37, 0x6c, 0xeb, 0xa0, 0x61, 0x5b, 0x3f, 0x1a, 0xb6, 0xf5, 0xe9, 0xa7, + 0x9d, 0x79, 0x39, 0xdd, 0xd3, 0x5f, 0x80, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xb1, 0xc6, + 0xd6, 0x34, 0x08, 0x00, 0x00, } func (m *AppCat) Marshal() (dAtA []byte, err error) { diff --git a/apis/exoscale/v1/dbaas_exoscale_kafka.go b/apis/exoscale/v1/dbaas_exoscale_kafka.go index 284c852d7b..41be2b3ae5 100644 --- a/apis/exoscale/v1/dbaas_exoscale_kafka.go +++ b/apis/exoscale/v1/dbaas_exoscale_kafka.go @@ -1,7 +1,7 @@ package v1 import ( - "github.com/vshn/appcat-apiserver/apis/v1" + "github.com/vshn/appcat/apis/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/exoscale/v1/dbaas_exoscale_mysql.go b/apis/exoscale/v1/dbaas_exoscale_mysql.go index ce615ee76e..e627c1dd12 100644 --- a/apis/exoscale/v1/dbaas_exoscale_mysql.go +++ b/apis/exoscale/v1/dbaas_exoscale_mysql.go @@ -1,7 +1,7 @@ package v1 import ( - "github.com/vshn/appcat-apiserver/apis/v1" + "github.com/vshn/appcat/apis/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/exoscale/v1/dbaas_exoscale_opensearch.go b/apis/exoscale/v1/dbaas_exoscale_opensearch.go index 5298a6cfe0..34c8fc1f42 100644 --- a/apis/exoscale/v1/dbaas_exoscale_opensearch.go +++ b/apis/exoscale/v1/dbaas_exoscale_opensearch.go @@ -1,7 +1,7 @@ package v1 import ( - v1 "github.com/vshn/appcat-apiserver/apis/v1" + v1 "github.com/vshn/appcat/apis/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/exoscale/v1/dbaas_exoscale_postgresql.go b/apis/exoscale/v1/dbaas_exoscale_postgresql.go index d520426665..e426f23bb2 100644 --- a/apis/exoscale/v1/dbaas_exoscale_postgresql.go +++ b/apis/exoscale/v1/dbaas_exoscale_postgresql.go @@ -1,7 +1,7 @@ package v1 import ( - v1 "github.com/vshn/appcat-apiserver/apis/v1" + v1 "github.com/vshn/appcat/apis/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/exoscale/v1/dbaas_exoscale_redis.go b/apis/exoscale/v1/dbaas_exoscale_redis.go index 2d77854f88..f310e3dfde 100644 --- a/apis/exoscale/v1/dbaas_exoscale_redis.go +++ b/apis/exoscale/v1/dbaas_exoscale_redis.go @@ -1,7 +1,7 @@ package v1 import ( - v1 "github.com/vshn/appcat-apiserver/apis/v1" + v1 "github.com/vshn/appcat/apis/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/exoscale/v1/zz_generated.deepcopy.go b/apis/exoscale/v1/zz_generated.deepcopy.go index 096a4ae69f..5c643f46af 100644 --- a/apis/exoscale/v1/zz_generated.deepcopy.go +++ b/apis/exoscale/v1/zz_generated.deepcopy.go @@ -6,7 +6,7 @@ package v1 import ( - apisv1 "github.com/vshn/appcat-apiserver/apis/v1" + apisv1 "github.com/vshn/appcat/apis/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/apis/vshn/v1/dbaas_vshn_postgresql.go b/apis/vshn/v1/dbaas_vshn_postgresql.go index 60588861b7..87a24e933c 100644 --- a/apis/vshn/v1/dbaas_vshn_postgresql.go +++ b/apis/vshn/v1/dbaas_vshn_postgresql.go @@ -2,7 +2,7 @@ package v1 import ( alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" - v1 "github.com/vshn/appcat-apiserver/apis/v1" + v1 "github.com/vshn/appcat/apis/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/apis/vshn/v1/dbaas_vshn_redis.go b/apis/vshn/v1/dbaas_vshn_redis.go index a69522516f..651f8e62f2 100644 --- a/apis/vshn/v1/dbaas_vshn_redis.go +++ b/apis/vshn/v1/dbaas_vshn_redis.go @@ -1,7 +1,7 @@ package v1 import ( - v1 "github.com/vshn/appcat-apiserver/apis/v1" + v1 "github.com/vshn/appcat/apis/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/apis/vshn/v1/zz_generated.deepcopy.go b/apis/vshn/v1/zz_generated.deepcopy.go index dc4d7a4833..dc67ea75f1 100644 --- a/apis/vshn/v1/zz_generated.deepcopy.go +++ b/apis/vshn/v1/zz_generated.deepcopy.go @@ -7,7 +7,7 @@ package v1 import ( "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" - apisv1 "github.com/vshn/appcat-apiserver/apis/v1" + apisv1 "github.com/vshn/appcat/apis/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/cmd/apiserver.go b/cmd/apiserver.go index eaa2337bd1..9e61ae3bcb 100644 --- a/cmd/apiserver.go +++ b/cmd/apiserver.go @@ -2,9 +2,9 @@ package cmd import ( "github.com/spf13/cobra" - appcatv1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/pkg/apiserver/appcat" - "github.com/vshn/appcat-apiserver/pkg/apiserver/vshn/postgres" + appcatv1 "github.com/vshn/appcat/apis/appcat/v1" + "github.com/vshn/appcat/pkg/apiserver/appcat" + "github.com/vshn/appcat/pkg/apiserver/vshn/postgres" "log" "os" "sigs.k8s.io/apiserver-runtime/pkg/builder" diff --git a/cmd/controller.go b/cmd/controller.go index 2555a3df4b..c38ae7e5ba 100644 --- a/cmd/controller.go +++ b/cmd/controller.go @@ -3,8 +3,8 @@ package cmd import ( "github.com/go-logr/logr" "github.com/spf13/cobra" - "github.com/vshn/appcat-apiserver/pkg" - "github.com/vshn/appcat-apiserver/pkg/controller/postgres" + "github.com/vshn/appcat/pkg" + "github.com/vshn/appcat/pkg/controller/postgres" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" diff --git a/cmd/grpc.go b/cmd/grpc.go index 28da80598e..98020d5a99 100644 --- a/cmd/grpc.go +++ b/cmd/grpc.go @@ -5,8 +5,8 @@ import ( pb "github.com/crossplane/crossplane/apis/apiextensions/fn/proto/v1alpha1" "github.com/go-logr/logr" "github.com/spf13/cobra" - vpf "github.com/vshn/appcat-apiserver/pkg/comp-functions/functions/vshn-postgres-func" - "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + vpf "github.com/vshn/appcat/pkg/comp-functions/functions/vshn-postgres-func" + "github.com/vshn/appcat/pkg/comp-functions/runtime" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/cmd/sliexporter.go b/cmd/sliexporter.go index 3843944f34..71677079bb 100644 --- a/cmd/sliexporter.go +++ b/cmd/sliexporter.go @@ -3,9 +3,9 @@ package cmd import ( "github.com/go-logr/logr" "github.com/spf13/cobra" - "github.com/vshn/appcat-apiserver/pkg" - "github.com/vshn/appcat-apiserver/pkg/sliexporter" - "github.com/vshn/appcat-apiserver/pkg/sliexporter/probes" + "github.com/vshn/appcat/pkg" + "github.com/vshn/appcat/pkg/sliexporter" + "github.com/vshn/appcat/pkg/sliexporter/probes" "k8s.io/apimachinery/pkg/runtime" "os" ctrl "sigs.k8s.io/controller-runtime" diff --git a/config/apiserver/aggregated-apiserver.yaml b/config/apiserver/aggregated-apiserver.yaml index 272d7ea334..d3f7ad3b71 100644 --- a/config/apiserver/aggregated-apiserver.yaml +++ b/config/apiserver/aggregated-apiserver.yaml @@ -20,7 +20,7 @@ spec: spec: containers: - name: apiserver - image: "ghcr.io/vshn/appcat-apiserver:v0.0.1" #patched + image: "ghcr.io/vshn/appcat:v0.0.1" #patched volumeMounts: - name: apiserver-certs mountPath: /apiserver.local.config/certificates diff --git a/config/apiserver/role.yaml b/config/apiserver/role.yaml index 9d9e4c807f..b36843f5a1 100644 --- a/config/apiserver/role.yaml +++ b/config/apiserver/role.yaml @@ -3,7 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null - name: appcat-apiserver + name: appcat rules: - apiGroups: - "" diff --git a/config/controller/deployment.yaml b/config/controller/deployment.yaml index 05b597e8cd..f88850cc31 100644 --- a/config/controller/deployment.yaml +++ b/config/controller/deployment.yaml @@ -21,7 +21,7 @@ spec: - args: - "controller" - "--leader-elect" - image: "ghcr.io/vshn/appcat-apiserver:v0.0.1" #patched + image: "ghcr.io/vshn/appcat:v0.0.1" #patched name: manager livenessProbe: httpGet: diff --git a/go.mod b/go.mod index d6bec17438..deb1516622 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/vshn/appcat-apiserver +module github.com/vshn/appcat go 1.20 diff --git a/main.go b/main.go index f717c4ee06..87c6200e6e 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/vshn/appcat-apiserver/cmd" + "github.com/vshn/appcat/cmd" "os" ) diff --git a/pkg/apiserver/appcat/appcat.go b/pkg/apiserver/appcat/appcat.go index 3eab31f3a6..37ae923236 100644 --- a/pkg/apiserver/appcat/appcat.go +++ b/pkg/apiserver/appcat/appcat.go @@ -2,7 +2,7 @@ package appcat import ( crossplane "github.com/crossplane/crossplane/apis/apiextensions/v1" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" + v1 "github.com/vshn/appcat/apis/appcat/v1" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" diff --git a/pkg/apiserver/appcat/appcat_test.go b/pkg/apiserver/appcat/appcat_test.go index 1bcf4b0b36..76f52c72df 100644 --- a/pkg/apiserver/appcat/appcat_test.go +++ b/pkg/apiserver/appcat/appcat_test.go @@ -2,8 +2,8 @@ package appcat import ( crossplanev1 "github.com/crossplane/crossplane/apis/apiextensions/v1" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/test/mocks" + v1 "github.com/vshn/appcat/apis/appcat/v1" + "github.com/vshn/appcat/test/mocks" "k8s.io/apiserver/pkg/registry/rest" "testing" diff --git a/pkg/apiserver/appcat/delete.go b/pkg/apiserver/appcat/delete.go index 058fd2aba0..d9164c9265 100644 --- a/pkg/apiserver/appcat/delete.go +++ b/pkg/apiserver/appcat/delete.go @@ -2,7 +2,7 @@ package appcat import ( "context" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" + v1 "github.com/vshn/appcat/apis/appcat/v1" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/apiserver/appcat/get.go b/pkg/apiserver/appcat/get.go index 9e245e4a06..d687a03a4f 100644 --- a/pkg/apiserver/appcat/get.go +++ b/pkg/apiserver/appcat/get.go @@ -2,8 +2,8 @@ package appcat import ( "context" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/pkg/apiserver" + v1 "github.com/vshn/appcat/apis/appcat/v1" + "github.com/vshn/appcat/pkg/apiserver" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/apiserver/appcat/get_test.go b/pkg/apiserver/appcat/get_test.go index abe8e5c5e6..a86648836e 100644 --- a/pkg/apiserver/appcat/get_test.go +++ b/pkg/apiserver/appcat/get_test.go @@ -2,7 +2,7 @@ package appcat import ( crossplanev1 "github.com/crossplane/crossplane/apis/apiextensions/v1" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" + v1 "github.com/vshn/appcat/apis/appcat/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/apiserver/appcat/list.go b/pkg/apiserver/appcat/list.go index ae5513aec9..3db8c9fbc0 100644 --- a/pkg/apiserver/appcat/list.go +++ b/pkg/apiserver/appcat/list.go @@ -3,8 +3,8 @@ package appcat import ( "context" crossplanev1 "github.com/crossplane/crossplane/apis/apiextensions/v1" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/pkg/apiserver" + "github.com/vshn/appcat/apis/appcat/v1" + "github.com/vshn/appcat/pkg/apiserver" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/apiserver/appcat/list_test.go b/pkg/apiserver/appcat/list_test.go index 68253d96a0..c1f86a5e07 100644 --- a/pkg/apiserver/appcat/list_test.go +++ b/pkg/apiserver/appcat/list_test.go @@ -2,7 +2,7 @@ package appcat import ( crossplanev1 "github.com/crossplane/crossplane/apis/apiextensions/v1" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" + v1 "github.com/vshn/appcat/apis/appcat/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/apiserver/appcat/table.go b/pkg/apiserver/appcat/table.go index 882cac9b74..14b8ff4552 100644 --- a/pkg/apiserver/appcat/table.go +++ b/pkg/apiserver/appcat/table.go @@ -3,7 +3,7 @@ package appcat import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" + "github.com/vshn/appcat/apis/appcat/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/apiserver/appcat/table_test.go b/pkg/apiserver/appcat/table_test.go index c56342be1b..f258b883ed 100644 --- a/pkg/apiserver/appcat/table_test.go +++ b/pkg/apiserver/appcat/table_test.go @@ -2,7 +2,7 @@ package appcat import ( "context" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" + v1 "github.com/vshn/appcat/apis/appcat/v1" "testing" "github.com/stretchr/testify/assert" diff --git a/pkg/apiserver/appcat/update.go b/pkg/apiserver/appcat/update.go index 92903e098a..ff52d1e214 100644 --- a/pkg/apiserver/appcat/update.go +++ b/pkg/apiserver/appcat/update.go @@ -2,7 +2,7 @@ package appcat import ( "context" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" + v1 "github.com/vshn/appcat/apis/appcat/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" diff --git a/pkg/apiserver/vshn/postgres/backup.go b/pkg/apiserver/vshn/postgres/backup.go index ab0d8dedfb..e0f9b895d1 100644 --- a/pkg/apiserver/vshn/postgres/backup.go +++ b/pkg/apiserver/vshn/postgres/backup.go @@ -1,8 +1,8 @@ package postgres import ( - "github.com/vshn/appcat-apiserver/apis/appcat/v1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + "github.com/vshn/appcat/apis/appcat/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" "k8s.io/apimachinery/pkg/runtime" genericregistry "k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/rest" diff --git a/pkg/apiserver/vshn/postgres/backup_test.go b/pkg/apiserver/vshn/postgres/backup_test.go index 6b524ab5aa..806a4bf08c 100644 --- a/pkg/apiserver/vshn/postgres/backup_test.go +++ b/pkg/apiserver/vshn/postgres/backup_test.go @@ -1,10 +1,10 @@ package postgres import ( - "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/test/mocks" + "github.com/vshn/appcat/apis/appcat/v1" + "github.com/vshn/appcat/test/mocks" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" diff --git a/pkg/apiserver/vshn/postgres/delete.go b/pkg/apiserver/vshn/postgres/delete.go index 24fd3b1ddc..d331150524 100644 --- a/pkg/apiserver/vshn/postgres/delete.go +++ b/pkg/apiserver/vshn/postgres/delete.go @@ -2,7 +2,7 @@ package postgres import ( "context" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" + "github.com/vshn/appcat/apis/appcat/v1" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/apiserver/vshn/postgres/get.go b/pkg/apiserver/vshn/postgres/get.go index 84e65ff4a1..cdbf05e0ac 100644 --- a/pkg/apiserver/vshn/postgres/get.go +++ b/pkg/apiserver/vshn/postgres/get.go @@ -3,8 +3,8 @@ package postgres import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/pkg/apiserver" + "github.com/vshn/appcat/apis/appcat/v1" + "github.com/vshn/appcat/pkg/apiserver" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/apiserver/vshn/postgres/get_test.go b/pkg/apiserver/vshn/postgres/get_test.go index 45f2ca1083..eafab8ea8d 100644 --- a/pkg/apiserver/vshn/postgres/get_test.go +++ b/pkg/apiserver/vshn/postgres/get_test.go @@ -1,9 +1,9 @@ package postgres import ( - "github.com/vshn/appcat-apiserver/apis/appcat/v1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/test/mocks" + "github.com/vshn/appcat/apis/appcat/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" + "github.com/vshn/appcat/test/mocks" apierrors "k8s.io/apimachinery/pkg/api/errors" "testing" diff --git a/pkg/apiserver/vshn/postgres/list.go b/pkg/apiserver/vshn/postgres/list.go index 573a290d7e..c059eef9cc 100644 --- a/pkg/apiserver/vshn/postgres/list.go +++ b/pkg/apiserver/vshn/postgres/list.go @@ -3,8 +3,8 @@ package postgres import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" - "github.com/vshn/appcat-apiserver/pkg/apiserver" + "github.com/vshn/appcat/apis/appcat/v1" + "github.com/vshn/appcat/pkg/apiserver" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/apiserver/vshn/postgres/list_test.go b/pkg/apiserver/vshn/postgres/list_test.go index 8b6ff5f6a6..56e9ec4a9f 100644 --- a/pkg/apiserver/vshn/postgres/list_test.go +++ b/pkg/apiserver/vshn/postgres/list_test.go @@ -2,9 +2,9 @@ package postgres import ( "fmt" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/test/mocks" + "github.com/vshn/appcat/apis/appcat/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" + "github.com/vshn/appcat/test/mocks" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/apiserver/vshn/postgres/sgbackups.go b/pkg/apiserver/vshn/postgres/sgbackups.go index 7753fadd6a..420532d053 100644 --- a/pkg/apiserver/vshn/postgres/sgbackups.go +++ b/pkg/apiserver/vshn/postgres/sgbackups.go @@ -3,7 +3,7 @@ package postgres import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" + "github.com/vshn/appcat/apis/appcat/v1" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/apiserver/vshn/postgres/sgbackups_test.go b/pkg/apiserver/vshn/postgres/sgbackups_test.go index e277bbfeb1..ca6cc4004a 100644 --- a/pkg/apiserver/vshn/postgres/sgbackups_test.go +++ b/pkg/apiserver/vshn/postgres/sgbackups_test.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" + "github.com/vshn/appcat/apis/appcat/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/apiserver/vshn/postgres/table.go b/pkg/apiserver/vshn/postgres/table.go index 794680215e..8bff45e430 100644 --- a/pkg/apiserver/vshn/postgres/table.go +++ b/pkg/apiserver/vshn/postgres/table.go @@ -3,7 +3,7 @@ package postgres import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" + "github.com/vshn/appcat/apis/appcat/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/apiserver/vshn/postgres/table_test.go b/pkg/apiserver/vshn/postgres/table_test.go index 6a8e3242f2..98fa501192 100644 --- a/pkg/apiserver/vshn/postgres/table_test.go +++ b/pkg/apiserver/vshn/postgres/table_test.go @@ -2,7 +2,7 @@ package postgres import ( "context" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" + "github.com/vshn/appcat/apis/appcat/v1" "testing" "github.com/stretchr/testify/assert" diff --git a/pkg/apiserver/vshn/postgres/update.go b/pkg/apiserver/vshn/postgres/update.go index 743dab08cb..ed1b79e4b1 100644 --- a/pkg/apiserver/vshn/postgres/update.go +++ b/pkg/apiserver/vshn/postgres/update.go @@ -2,7 +2,7 @@ package postgres import ( "context" - "github.com/vshn/appcat-apiserver/apis/appcat/v1" + "github.com/vshn/appcat/apis/appcat/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" diff --git a/pkg/apiserver/vshn/postgres/vshnpostgresql.go b/pkg/apiserver/vshn/postgres/vshnpostgresql.go index f297523fa4..6cd687a76d 100644 --- a/pkg/apiserver/vshn/postgres/vshnpostgresql.go +++ b/pkg/apiserver/vshn/postgres/vshnpostgresql.go @@ -2,7 +2,7 @@ package postgres import ( "context" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/pkg/apiserver/vshn/postgres/vshnpostgresql_test.go b/pkg/apiserver/vshn/postgres/vshnpostgresql_test.go index 79cc839245..db5be99b03 100644 --- a/pkg/apiserver/vshn/postgres/vshnpostgresql_test.go +++ b/pkg/apiserver/vshn/postgres/vshnpostgresql_test.go @@ -4,8 +4,8 @@ import ( "context" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/test/mocks" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" + "github.com/vshn/appcat/test/mocks" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "testing" ) diff --git a/pkg/comp-functions/functions/vshn-postgres-func/alerting.go b/pkg/comp-functions/functions/vshn-postgres-func/alerting.go index a850e3658c..97bebbed72 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/alerting.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/alerting.go @@ -2,12 +2,12 @@ package vshnpostgres import ( "context" - runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + runtime2 "github.com/vshn/appcat/pkg/comp-functions/runtime" controllerruntime "sigs.k8s.io/controller-runtime" xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" diff --git a/pkg/comp-functions/functions/vshn-postgres-func/alerting_test.go b/pkg/comp-functions/functions/vshn-postgres-func/alerting_test.go index cd8dd6a2ae..71fbb09330 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/alerting_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/alerting_test.go @@ -5,8 +5,8 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" alertmanagerv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" + "github.com/vshn/appcat/pkg/comp-functions/runtime" v1 "k8s.io/api/core/v1" "testing" diff --git a/pkg/comp-functions/functions/vshn-postgres-func/common_test.go b/pkg/comp-functions/functions/vshn-postgres-func/common_test.go index 632a6219db..e091f0cc0b 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/common_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/common_test.go @@ -2,7 +2,7 @@ package vshnpostgres import ( "context" - "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + "github.com/vshn/appcat/pkg/comp-functions/runtime" "os" "path/filepath" "reflect" diff --git a/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go index 28e18912c3..896dfa9711 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc.go @@ -3,12 +3,12 @@ package vshnpostgres import ( "context" "fmt" - runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + runtime2 "github.com/vshn/appcat/pkg/comp-functions/runtime" "github.com/sethvargo/go-password/password" controllerruntime "sigs.k8s.io/controller-runtime" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go index d010c86d4b..e7d4c39afe 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/encrypted_pvc_test.go @@ -2,13 +2,13 @@ package vshnpostgres import ( "context" - "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + "github.com/vshn/appcat/pkg/comp-functions/runtime" "testing" xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" "github.com/stretchr/testify/assert" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" v1 "k8s.io/api/core/v1" "sigs.k8s.io/yaml" ) diff --git a/pkg/comp-functions/functions/vshn-postgres-func/schedule.go b/pkg/comp-functions/functions/vshn-postgres-func/schedule.go index 0acd6eb9af..cb8f931307 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/schedule.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/schedule.go @@ -3,11 +3,11 @@ package vshnpostgres import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + "github.com/vshn/appcat/pkg/comp-functions/runtime" "math/rand" "time" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" ) var ( diff --git a/pkg/comp-functions/functions/vshn-postgres-func/schedule_test.go b/pkg/comp-functions/functions/vshn-postgres-func/schedule_test.go index 89b1c62fee..e5069fab95 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/schedule_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/schedule_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/stretchr/testify/assert" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" fnv1aplha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" ) diff --git a/pkg/comp-functions/functions/vshn-postgres-func/url.go b/pkg/comp-functions/functions/vshn-postgres-func/url.go index f50906d0e2..8b4bc29dd9 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/url.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/url.go @@ -3,8 +3,8 @@ package vshnpostgres import ( "context" "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" - runtime2 "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" + runtime2 "github.com/vshn/appcat/pkg/comp-functions/runtime" v1 "k8s.io/api/core/v1" controllerruntime "sigs.k8s.io/controller-runtime" ) diff --git a/pkg/comp-functions/functions/vshn-postgres-func/url_test.go b/pkg/comp-functions/functions/vshn-postgres-func/url_test.go index 78ba7b9057..ce02233a46 100644 --- a/pkg/comp-functions/functions/vshn-postgres-func/url_test.go +++ b/pkg/comp-functions/functions/vshn-postgres-func/url_test.go @@ -2,7 +2,7 @@ package vshnpostgres import ( "context" - "github.com/vshn/appcat-apiserver/pkg/comp-functions/runtime" + "github.com/vshn/appcat/pkg/comp-functions/runtime" "testing" "github.com/stretchr/testify/assert" diff --git a/pkg/comp-functions/runtime/runtime.go b/pkg/comp-functions/runtime/runtime.go index e711763f91..d58401568e 100644 --- a/pkg/comp-functions/runtime/runtime.go +++ b/pkg/comp-functions/runtime/runtime.go @@ -8,7 +8,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" xfnv1alpha1 "github.com/crossplane/crossplane/apis/apiextensions/fn/io/v1alpha1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/controller/postgres/deletion_protection_test.go b/pkg/controller/postgres/deletion_protection_test.go index 657b18c1ec..0c2da795ce 100644 --- a/pkg/controller/postgres/deletion_protection_test.go +++ b/pkg/controller/postgres/deletion_protection_test.go @@ -10,7 +10,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/go-logr/logr" "github.com/stretchr/testify/assert" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/pkg/controller/postgres/reconciler.go b/pkg/controller/postgres/reconciler.go index 4bad7262ab..3cce45d1ea 100644 --- a/pkg/controller/postgres/reconciler.go +++ b/pkg/controller/postgres/reconciler.go @@ -6,7 +6,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/crossplane/crossplane-runtime/pkg/errors" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/controller/postgres/reconciler_test.go b/pkg/controller/postgres/reconciler_test.go index e1bb0dba92..3d479e2b69 100644 --- a/pkg/controller/postgres/reconciler_test.go +++ b/pkg/controller/postgres/reconciler_test.go @@ -7,7 +7,7 @@ import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" "github.com/stretchr/testify/assert" - v1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + v1 "github.com/vshn/appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/scheme.go b/pkg/scheme.go index 0ff894ceb5..5a9ee345d5 100644 --- a/pkg/scheme.go +++ b/pkg/scheme.go @@ -2,7 +2,7 @@ package pkg import ( xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" ) diff --git a/pkg/sliexporter/vshnpostgresql_controller.go b/pkg/sliexporter/vshnpostgresql_controller.go index e6841ebf75..a31c996a4a 100644 --- a/pkg/sliexporter/vshnpostgresql_controller.go +++ b/pkg/sliexporter/vshnpostgresql_controller.go @@ -19,7 +19,7 @@ package sliexporter import ( "context" "fmt" - "github.com/vshn/appcat-apiserver/pkg/sliexporter/probes" + "github.com/vshn/appcat/pkg/sliexporter/probes" "time" "github.com/jackc/pgx/v5/pgxpool" @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" ) var vshnpostgresqlsServiceKey = "VSHNPostgreSQL" diff --git a/pkg/sliexporter/vshnpostgresql_controller_test.go b/pkg/sliexporter/vshnpostgresql_controller_test.go index 8455c19135..bb3425d786 100644 --- a/pkg/sliexporter/vshnpostgresql_controller_test.go +++ b/pkg/sliexporter/vshnpostgresql_controller_test.go @@ -2,7 +2,7 @@ package sliexporter import ( "context" - "github.com/vshn/appcat-apiserver/pkg/sliexporter/probes" + "github.com/vshn/appcat/pkg/sliexporter/probes" "testing" "time" @@ -18,8 +18,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - v1 "github.com/vshn/appcat-apiserver/apis/v1" - vshnv1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + v1 "github.com/vshn/appcat/apis/v1" + vshnv1 "github.com/vshn/appcat/apis/vshn/v1" ) func TestVSHNPostgreSQL_StartStop(t *testing.T) { diff --git a/test/mocks/mock_sgbackups.go b/test/mocks/mock_sgbackups.go index 3c9e103241..ef90f1b87b 100644 --- a/test/mocks/mock_sgbackups.go +++ b/test/mocks/mock_sgbackups.go @@ -9,7 +9,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - v1 "github.com/vshn/appcat-apiserver/apis/appcat/v1" + v1 "github.com/vshn/appcat/apis/appcat/v1" internalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" watch "k8s.io/apimachinery/pkg/watch" ) diff --git a/test/mocks/mock_vshnpostgresqls.go b/test/mocks/mock_vshnpostgresqls.go index 9d45fe68fa..7fed5775c6 100644 --- a/test/mocks/mock_vshnpostgresqls.go +++ b/test/mocks/mock_vshnpostgresqls.go @@ -9,7 +9,7 @@ import ( reflect "reflect" gomock "github.com/golang/mock/gomock" - v1 "github.com/vshn/appcat-apiserver/apis/vshn/v1" + v1 "github.com/vshn/appcat/apis/vshn/v1" ) // MockvshnPostgresqlProvider is a mock of vshnPostgresqlProvider interface. From ea8821bb879d04e1313f13d521377bb9dd4b0c6c Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Mon, 22 May 2023 15:01:25 +0200 Subject: [PATCH 24/26] Update docs --- .../pages/explanations/apiserver/boostrap.adoc | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/docs/modules/ROOT/pages/explanations/apiserver/boostrap.adoc b/docs/modules/ROOT/pages/explanations/apiserver/boostrap.adoc index c3511a9b7b..b666c1bc88 100644 --- a/docs/modules/ROOT/pages/explanations/apiserver/boostrap.adoc +++ b/docs/modules/ROOT/pages/explanations/apiserver/boostrap.adoc @@ -10,17 +10,4 @@ In order to achieve the scaffolding the following operations have been made: . Initialize the repository `apiserver-boot init repo --domain vshn.io` . Create API `apiserver-boot create group version resource --group appcat --version v1 --kind AppCat --non-namespaced` . Clean go dependencies `go mod tidy` -. Generate necessary boilerplate code `make generate` - -== Trying the api server - -. Create certificate folder `mkdir -p config/certificates` -. Create a certificate `openssl req -x509 -newkey rsa:2048 -keyout config/certificates/apiserver_ca.key -out config/certificates/apiserver_ca.crt -days 365 -nodes -subj /C=un/ST=st/L=l/O=o/OU=ou/CN=appcat-certificate-authority` -. Build the image ex `apiserver-boot build container --image="docker.io/gsaratura/appcat-apiserver-test:v0.0.1"` -. Generate k8s manifests `apiserver-boot build config --namespace default --name appcat --image="docker.io/gsaratura/appcat-apiserver-test:v0.0.1"` -. Create a kind cluster `kind create cluster --name test-api-server` -. Access the cluster `kind get kubeconfig --name test-api-server > ~/.kube/config` -. Load the build docker image into the cluster `kind load docker-image "docker.io/gsaratura/appcat-apiserver-test:v0.0.1" --nodes test-api-server-control-plane --name test-api-server` -. Apply the manifests `kubectl create -f config/` -. Check the api server `kubectl get pods` - +. Generate necessary boilerplate code `make generate` \ No newline at end of file From cd8d8bedf416d1489dcb88d7dfd2d919d6bd03c7 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Tue, 23 May 2023 10:02:02 +0200 Subject: [PATCH 25/26] Update sli expoter image --- config/sliexporter/manager/manager.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sliexporter/manager/manager.yaml b/config/sliexporter/manager/manager.yaml index 6c739fa745..2c7b17be36 100644 --- a/config/sliexporter/manager/manager.yaml +++ b/config/sliexporter/manager/manager.yaml @@ -27,7 +27,7 @@ spec: securityContext: runAsNonRoot: true containers: - - image: ghcr.io/vshn/appcat-sli-exporter:latest + - image: ghcr.io/vshn/appcat:latest name: manager securityContext: allowPrivilegeEscalation: false From 3621f883288e3023a906c318f10b0609ac996e62 Mon Sep 17 00:00:00 2001 From: Gabriel Saratura Date: Tue, 23 May 2023 10:08:51 +0200 Subject: [PATCH 26/26] Fix controller cluster role --- config/controller/cluster-role.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/controller/cluster-role.yaml b/config/controller/cluster-role.yaml index 7b96ecf648..efa2df0f68 100644 --- a/config/controller/cluster-role.yaml +++ b/config/controller/cluster-role.yaml @@ -7,6 +7,7 @@ rules: - vshn.appcat.vshn.io resources: - xvshnpostgresqls + - xvshnpostgresqls/finalizers verbs: - get - list @@ -28,3 +29,4 @@ rules: - update - list - watch + - delete \ No newline at end of file