diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f947e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/.cache +/.work +/_output +/results +/.idea + +*.xpkg +kubeconfig diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c2fad47 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "build"] + path = build + url = https://github.com/upbound/build diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..669c864 --- /dev/null +++ b/.yamllint @@ -0,0 +1,5 @@ +extends: default + +rules: + line-length: disable + document-start: disable diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a603f0b --- /dev/null +++ b/Makefile @@ -0,0 +1,80 @@ +# Project Setup +PROJECT_NAME := configuration-gcp-database +PROJECT_REPO := github.com/upbound/$(PROJECT_NAME) + +# NOTE(hasheddan): the platform is insignificant here as Configuration package +# images are not architecture-specific. We constrain to one platform to avoid +# needlessly pushing a multi-arch image. +PLATFORMS ?= linux_amd64 +-include build/makelib/common.mk + +# ==================================================================================== +# Setup Kubernetes tools + +UP_VERSION = v0.21.0 +UP_CHANNEL = stable +UPTEST_VERSION = v0.9.0 + +-include build/makelib/k8s_tools.mk +# ==================================================================================== +# Setup XPKG +XPKG_DIR = $(shell pwd) +XPKG_IGNORE = .github/workflows/*.yaml,.github/workflows/*.yml,examples/*.yaml,.work/uptest-datasource.yaml +XPKG_REG_ORGS ?= xpkg.upbound.io/upbound +# NOTE(hasheddan): skip promoting on xpkg.upbound.io as channel tags are +# inferred. +XPKG_REG_ORGS_NO_PROMOTE ?= xpkg.upbound.io/upbound +XPKGS = $(PROJECT_NAME) +-include build/makelib/xpkg.mk + +CROSSPLANE_NAMESPACE = upbound-system +-include build/makelib/local.xpkg.mk +-include build/makelib/controlplane.mk + +# ==================================================================================== +# Targets + +# run `make help` to see the targets and options + +# We want submodules to be set up the first time `make` is run. +# We manage the build/ folder and its Makefiles as a submodule. +# The first time `make` is run, the includes of build/*.mk files will +# all fail, and this target will be run. The next time, the default as defined +# by the includes will be run instead. +fallthrough: submodules + @echo Initial setup complete. Running make again . . . + @make + +# Update the submodules, such as the common build scripts. +submodules: + @git submodule sync + @git submodule update --init --recursive + +# We must ensure up is installed in tool cache prior to build as including the k8s_tools machinery prior to the xpkg +# machinery sets UP to point to tool cache. +build.init: $(UP) + +# ==================================================================================== +# End to End Testing + +# This target requires the following environment variables to be set: +# - UPTEST_CLOUD_CREDENTIALS, cloud credentials for the provider being tested, e.g. export UPTEST_CLOUD_CREDENTIALS=$(cat gcp.json) +uptest: $(UPTEST) $(KUBECTL) $(KUTTL) + @$(INFO) running automated tests + @KUBECTL=$(KUBECTL) KUTTL=$(KUTTL) CROSSPLANE_NAMESPACE=$(CROSSPLANE_NAMESPACE) $(UPTEST) e2e examples/network-xr.yaml,examples/postgres-claim.yaml --setup-script=test/setup.sh --default-timeout=2400 || $(FAIL) + @$(OK) running automated tests + +# This target requires the following environment variables to be set: +# - UPTEST_CLOUD_CREDENTIALS, cloud credentials for the provider being tested, e.g. export UPTEST_CLOUD_CREDENTIALS=$(cat gcp.json) +# make e2e UPTEST_GCP_PROJECT=crossplane-playground to use a different project +e2e: build controlplane.up local.xpkg.deploy.configuration.$(PROJECT_NAME) uptest + +render: + crossplane beta render examples/postgres-claim.yaml apis/composition.yaml examples/functions.yaml -r + +yamllint: + @$(INFO) running yamllint + @yamllint ./apis || $(FAIL) + @$(OK) running yamllint + +.PHONY: uptest e2e render yamllint diff --git a/README.md b/README.md index d8db905..e82595f 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # configuration-gcp-database + +GCP Database Configuration is reusable Configuration designed to be primarily used in higher level Configurations. diff --git a/apis/composition.yaml b/apis/composition.yaml new file mode 100644 index 0000000..fe76362 --- /dev/null +++ b/apis/composition.yaml @@ -0,0 +1,92 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xpostgresqlinstances.gcp.platform.upbound.io + labels: + provider: gcp +spec: + writeConnectionSecretsToNamespace: upbound-system + compositeTypeRef: + apiVersion: gcp.platform.upbound.io/v1alpha1 + kind: XPostgreSQLInstance + mode: Pipeline + pipeline: + - step: patch-and-transform + functionRef: + name: upbound-function-patch-and-transform + input: + apiVersion: pt.fn.crossplane.io/v1beta1 + kind: Resources + resources: + - name: PrivateIPAddress + base: + apiVersion: compute.gcp.upbound.io/v1beta1 + kind: GlobalAddress + spec: + forProvider: + addressType: INTERNAL + prefixLength: 16 + purpose: VPC_PEERING + patches: + - fromFieldPath: spec.parameters.networkRef.id + toFieldPath: spec.forProvider.networkSelector.matchLabels[networks.gcp.platform.upbound.io/network-id] + - name: PrivateConnection + base: + apiVersion: servicenetworking.gcp.upbound.io/v1beta1 + kind: Connection + spec: + forProvider: + reservedPeeringRangesSelector: + matchControllerRef: true + service: servicenetworking.googleapis.com + patches: + - fromFieldPath: spec.parameters.networkRef.id + toFieldPath: spec.forProvider.networkSelector.matchLabels[networks.gcp.platform.upbound.io/network-id] + - name: DatabaseUser + base: + apiVersion: sql.gcp.upbound.io/v1beta1 + kind: User + spec: + forProvider: + instanceSelector: + matchControllerRef: true + patches: + - fromFieldPath: spec.parameters.passwordSecretRef.namespace + toFieldPath: spec.forProvider.passwordSecretRef.namespace + - fromFieldPath: spec.parameters.passwordSecretRef.name + toFieldPath: spec.forProvider.passwordSecretRef.name + - fromFieldPath: spec.parameters.passwordSecretRef.key + toFieldPath: spec.forProvider.passwordSecretRef.key + - name: DBInstance + base: + apiVersion: sql.gcp.upbound.io/v1beta1 + kind: DatabaseInstance + spec: + forProvider: + databaseVersion: POSTGRES_13 + deletionProtection: false + region: us-west2 + settings: + - diskSize: 20 + tier: db-f1-micro + patches: + - fromFieldPath: metadata.uid + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - type: string + string: + type: Format + fmt: "%s-gcp-postgresql" + - fromFieldPath: spec.writeConnectionSecretToRef.namespace + toFieldPath: spec.writeConnectionSecretToRef.namespace + - fromFieldPath: spec.parameters.storageGB + toFieldPath: spec.forProvider.settings[0].diskSize + - fromFieldPath: spec.parameters.networkRef.id + toFieldPath: spec.forProvider.settings[0].ipConfiguration[0].privateNetworkRef.name + connectionDetails: + - name: privateIP + type: FromConnectionSecretKey + fromConnectionSecretKey: privateIP + - name: serverCACertificateCert + type: FromConnectionSecretKey + fromConnectionSecretKey: serverCACertificateCert diff --git a/apis/definition.yaml b/apis/definition.yaml new file mode 100644 index 0000000..72644a3 --- /dev/null +++ b/apis/definition.yaml @@ -0,0 +1,61 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xpostgresqlinstances.gcp.platform.upbound.io +spec: + group: gcp.platform.upbound.io + names: + kind: XPostgreSQLInstance + plural: xpostgresqlinstances + claimNames: + kind: PostgreSQLInstance + plural: postgresqlinstances + connectionSecretKeys: + - privateIP + - serverCACertificateCert + versions: + - name: v1alpha1 + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + parameters: + type: object + properties: + storageGB: + type: integer + passwordSecretRef: + type: object + description: "A reference to the Secret object containing database password" + properties: + namespace: + type: string + name: + type: string + key: + type: string + required: + - namespace + - name + - key + networkRef: + type: object + description: "A reference to the Network object that this postgres should be + connected to." + properties: + id: + type: string + description: ID of the Network object this ref points to. + required: + - id + required: + - storageGB + - networkRef + - passwordSecretRef + required: + - parameters diff --git a/build b/build new file mode 160000 index 0000000..75a9fe3 --- /dev/null +++ b/build @@ -0,0 +1 @@ +Subproject commit 75a9fe3ae6b6de82c5f7ddc6a267617940f16b83 diff --git a/crossplane.yaml b/crossplane.yaml new file mode 100644 index 0000000..1b3fa78 --- /dev/null +++ b/crossplane.yaml @@ -0,0 +1,22 @@ +apiVersion: meta.pkg.crossplane.io/v1 +kind: Configuration +metadata: + name: configuration-gcp-database + annotations: + meta.crossplane.io/maintainer: Upbound + meta.crossplane.io/source: github.com/upbound/configuration-gcp-database + meta.crossplane.io/license: Apache-2.0 + +spec: + crossplane: + version: ">=v1.14.1-0" + dependsOn: + - provider: xpkg.upbound.io/upbound/provider-gcp-sql + # renovate: datasource=github-releases depName=upbound/provider-gcp + version: "v0.41.0" + - provider: xpkg.upbound.io/upbound/provider-gcp-servicenetworking + # renovate: datasource=github-releases depName=upbound/provider-gcp + version: "v0.41.0" + - configuration: xpkg.upbound.io/upbound/configuration-gcp-network + # renovate: datasource=github-releases depName=upbound/configuration-gcp-network + version: "v0.1.0" diff --git a/examples/configuration.yaml b/examples/configuration.yaml new file mode 100644 index 0000000..086632f --- /dev/null +++ b/examples/configuration.yaml @@ -0,0 +1,6 @@ +apiVersion: pkg.crossplane.io/v1 +kind: Configuration +metadata: + name: configuration-gcp-database +spec: + package: xpkg.upbound.io/upbound/configuration-gcp-database:v0.1.0 diff --git a/examples/functions.yaml b/examples/functions.yaml new file mode 100644 index 0000000..98c28bd --- /dev/null +++ b/examples/functions.yaml @@ -0,0 +1,6 @@ +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: upbound-function-patch-and-transform +spec: + package: xpkg.upbound.io/upbound/function-patch-and-transform:v0.2.1 diff --git a/examples/network-xr.yaml b/examples/network-xr.yaml new file mode 100644 index 0000000..0f94127 --- /dev/null +++ b/examples/network-xr.yaml @@ -0,0 +1,8 @@ +apiVersion: gcp.platform.upbound.io/v1alpha1 +kind: XNetwork +metadata: + name: configuration-gcp-database +spec: + parameters: + id: configuration-gcp-database + region: us-west2 diff --git a/examples/postgres-claim.yaml b/examples/postgres-claim.yaml new file mode 100644 index 0000000..83d8253 --- /dev/null +++ b/examples/postgres-claim.yaml @@ -0,0 +1,25 @@ +apiVersion: gcp.platform.upbound.io/v1alpha1 +kind: PostgreSQLInstance +metadata: + name: configuration-gcp-database + namespace: default +spec: + parameters: + storageGB: 10 + passwordSecretRef: + namespace: default + name: psqlsecret + key: password + networkRef: + id: configuration-gcp-database + writeConnectionSecretToRef: + name: configuration-gcp-database-conn +--- +apiVersion: v1 +data: + password: dXBiMHVuZHIwY2s1ITMxMzM3 +kind: Secret +metadata: + name: psqlsecret + namespace: default +type: Opaque diff --git a/test/setup.sh b/test/setup.sh new file mode 100755 index 0000000..369627d --- /dev/null +++ b/test/setup.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -aeuo pipefail + +UPTEST_GCP_PROJECT=${UPTEST_GCP_PROJECT:-official-provider-testing} + +echo "Running setup.sh" +echo "Waiting until all configurations are healthy/installed..." +"${KUBECTL}" wait configuration.pkg --all --for=condition=Healthy --timeout 5m +"${KUBECTL}" wait configuration.pkg --all --for=condition=Installed --timeout 5m +"${KUBECTL}" wait configurationrevisions.pkg --all --for=condition=Healthy --timeout 5m + +echo "Creating cloud credential secret..." +"${KUBECTL}" -n upbound-system create secret generic gcp-creds --from-literal=credentials="${UPTEST_CLOUD_CREDENTIALS}" \ + --dry-run=client -o yaml | ${KUBECTL} apply -f - + +echo "Waiting until all installed provider packages are healthy..." +"${KUBECTL}" wait provider.pkg --all --for condition=Healthy --timeout 5m + +echo "Waiting for all pods to come online..." +"${KUBECTL}" -n upbound-system wait --for=condition=Available deployment --all --timeout=5m + +echo "Waiting for all XRDs to be established..." +"${KUBECTL}" wait xrd --all --for condition=Established + +echo "Creating a default provider config..." +cat <