diff --git a/apis/definition.yaml b/apis/definition.yaml index ed03107..814b5d3 100644 --- a/apis/definition.yaml +++ b/apis/definition.yaml @@ -198,6 +198,19 @@ spec: route53ZoneName: type: string description: "The Route53 zone name for external-dns to manage." + gcp: + type: object + properties: + enabled: + type: boolean + description: "Indicates if GCP external-dns is enabled." + default: true + zoneName: + type: string + description: "The Managed Zone for external-dns to manage." + dnsProject: + type: string + description: "The ID of the Project where the DNS is managed." version: type: string description: "Specifies the version of external-dns to use." diff --git a/apis/space-init/composition.yaml b/apis/space-init/composition.yaml index bbada2e..e1e21da 100644 --- a/apis/space-init/composition.yaml +++ b/apis/space-init/composition.yaml @@ -436,6 +436,94 @@ spec: type: Format type: string + - name: external-dns-workloadidentity + condition: | + "externaldns" in observed.composite.resource.spec.parameters.operators && + "gcp" in observed.composite.resource.spec.parameters.operators.externaldns && + observed.composite.resource.spec.parameters.operators.externaldns.gcp.enabled == true + base: + apiVersion: gcp.platform.upbound.io/v1alpha1 + kind: XWorkloadIdentity + spec: + parameters: + condition: StringEquals + serviceAccount: + name: external-dns + namespace: external-dns + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators.externaldns.gcp.dnsProject + toFieldPath: spec.parameters.dnsProject + - type: ToCompositeFieldPath + fromFieldPath: status.googleServiceAccount.email + toFieldPath: status.status.externalDNS.googleServiceAccount.email + policy: + fromFieldPath: Optional + + - name: external-dns + condition: | + "externaldns" in observed.composite.resource.spec.parameters.operators && + "gcp" in observed.composite.resource.spec.parameters.operators.externaldns && + observed.composite.resource.spec.parameters.operators.externaldns.gcp.enabled == true + base: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + spec: + forProvider: + namespace: external-dns + chart: + name: external-dns + repository: https://charts.bitnami.com/bitnami + values: + replicaCount: 1 + provider: google + policy: sync + source: ingress + registry: txt + google: + batchChangeSize: 4 + rbac: + create: true + serviceAccount: + create: true + name: external-dns + metrics: + enabled: false + serviceMonitor: + enabled: false + replicas: 2 + podDisruptionBudget: + minAvailable: 1 + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators.externaldns.version + toFieldPath: spec.forProvider.chart.version + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators.externaldns.gcp.zoneName + toFieldPath: spec.forProvider.values.domainFilters[0] + - type: FromCompositeFieldPath + fromFieldPath: status.status.externalDNS.googleServiceAccount.email + toFieldPath: spec.forProvider.values.serviceAccount.annotations[iam.gke.io/gcp-service-account] + policy: + fromFieldPath: Required + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators.externaldns.gcp.dnsProject + toFieldPath: spec.forProvider.values.google.project + - type: FromCompositeFieldPath + fromFieldPath: metadata.uid + toFieldPath: spec.forProvider.values.txtOwnerId + transforms: + - string: + fmt: 'upbound-spaces-%s' + type: Format + type: string + - name: universal-crossplane condition: observed.composite.resource.spec.parameters.operators.crossplane.enabled == true base: diff --git a/apis/space-init/definition.yaml b/apis/space-init/definition.yaml index c1ba952..ffa9982 100644 --- a/apis/space-init/definition.yaml +++ b/apis/space-init/definition.yaml @@ -65,6 +65,19 @@ spec: route53ZoneName: type: string description: "The Route53 zone name for external-dns to manage." + gcp: + type: object + properties: + enabled: + type: boolean + description: "Indicates if GCP external-dns is enabled." + default: true + zoneName: + type: string + description: "The Managed Zone for external-dns to manage." + dnsProject: + type: string + description: "The ID of the Project where the DNS is managed." version: type: string description: "Specifies the version of external-dns to use." diff --git a/apis/workload-identity/composition.yaml b/apis/workload-identity/composition.yaml new file mode 100644 index 0000000..cc279ca --- /dev/null +++ b/apis/workload-identity/composition.yaml @@ -0,0 +1,172 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xworkloadidentity.gcp.platform.upbound.io +spec: + compositeTypeRef: + apiVersion: gcp.platform.upbound.io/v1alpha1 + kind: XWorkloadIdentity + mode: Pipeline + pipeline: + - step: patch-and-transform + functionRef: + name: crossplane-contrib-function-patch-and-transform + input: + apiVersion: pt.fn.crossplane.io/v1beta1 + kind: Resources + patchSets: + - name: Name + patches: + - fromFieldPath: metadata.name + toFieldPath: metadata.annotations[crossplane.io/external-name] + type: FromCompositeFieldPath + - name: providerConfigRef + patches: + - fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + type: FromCompositeFieldPath + - name: deletionPolicy + patches: + - fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.deletionPolicy + type: FromCompositeFieldPath + resources: + - name: serviceaccount + base: + apiVersion: cloudplatform.gcp.upbound.io/v1beta1 + kind: ServiceAccount + patches: + - type: PatchSet + patchSetName: Name + - type: PatchSet + patchSetName: providerConfigRef + - type: PatchSet + patchSetName: deletionPolicy + - fromFieldPath: status.workloadIdentity.gkeProject + toFieldPath: spec.forProvider.project + type: FromCompositeFieldPath + - fromFieldPath: status.atProvider.email + toFieldPath: status.googleServiceAccount.email + type: ToCompositeFieldPath + - fromFieldPath: status.atProvider.id + toFieldPath: status.googleServiceAccount.id + type: ToCompositeFieldPath + + - name: projectiammember-dns-admin + base: + apiVersion: cloudplatform.gcp.upbound.io/v1beta1 + kind: ProjectIAMMember + spec: + forProvider: + role: roles/dns.admin + patches: + - type: PatchSet + patchSetName: Name + - type: PatchSet + patchSetName: providerConfigRef + - type: PatchSet + patchSetName: deletionPolicy + - fromFieldPath: spec.parameters.dnsProject + toFieldPath: spec.forProvider.project + type: FromCompositeFieldPath + - fromFieldPath: status.googleServiceAccount.email + toFieldPath: spec.forProvider.member + type: FromCompositeFieldPath + transforms: + - string: + fmt: 'serviceAccount:%s' + type: Format + type: string + + - name: serviceaccountiammember + base: + apiVersion: cloudplatform.gcp.upbound.io/v1beta1 + kind: ServiceAccountIAMMember + spec: + forProvider: + role: roles/iam.workloadIdentityUser + patches: + - type: PatchSet + patchSetName: Name + - type: PatchSet + patchSetName: providerConfigRef + - type: PatchSet + patchSetName: deletionPolicy + - fromFieldPath: status.googleServiceAccount.id + toFieldPath: spec.forProvider.serviceAccountId + type: FromCompositeFieldPath + - combine: + strategy: string + string: + fmt: "serviceAccount:%s.svc.id.goog[%s/%s]" + variables: + - fromFieldPath: status.workloadIdentity.gkeProject + - fromFieldPath: spec.parameters.serviceAccount.namespace + - fromFieldPath: spec.parameters.serviceAccount.name + toFieldPath: spec.forProvider.member + type: CombineFromComposite + + - name: projectiammember-workload-identity-user + base: + apiVersion: cloudplatform.gcp.upbound.io/v1beta1 + kind: ProjectIAMMember + spec: + forProvider: + role: roles/iam.workloadIdentityUser + patches: + - type: PatchSet + patchSetName: Name + - type: PatchSet + patchSetName: providerConfigRef + - type: PatchSet + patchSetName: deletionPolicy + - fromFieldPath: status.workloadIdentity.gkeProject + toFieldPath: spec.forProvider.project + type: FromCompositeFieldPath + - fromFieldPath: status.googleServiceAccount.email + toFieldPath: spec.forProvider.member + type: FromCompositeFieldPath + transforms: + - string: + fmt: 'serviceAccount:%s' + type: Format + type: string + + - name: workloadIdentitySettings + base: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + spec: + deletionPolicy: Orphan + forProvider: + manifest: + apiVersion: v1 + kind: ConfigMap + metadata: + namespace: default + managementPolicies: ["Observe"] + patches: + - fromFieldPath: spec.parameters.id + toFieldPath: spec.providerConfigRef.name + type: FromCompositeFieldPath + - fromFieldPath: spec.parameters.id + toFieldPath: metadata.annotations[crossplane.io/external-name] + transforms: + - string: + fmt: '%s-workload-identity-settings' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: spec.parameters.id + toFieldPath: spec.forProvider.manifest.metadata.name + transforms: + - string: + fmt: '%s-workload-identity-settings' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: status.atProvider.manifest.data.gkeProject + policy: + fromFieldPath: Optional + toFieldPath: status.workloadIdentity.gkeProject + type: ToCompositeFieldPath diff --git a/apis/workload-identity/definition.yaml b/apis/workload-identity/definition.yaml new file mode 100644 index 0000000..bf47441 --- /dev/null +++ b/apis/workload-identity/definition.yaml @@ -0,0 +1,96 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xworkloadidentities.gcp.platform.upbound.io + labels: + provider: gcp +spec: + claimNames: + kind: WorkloadIdentity + plural: workloadidentities + group: gcp.platform.upbound.io + names: + kind: XWorkloadIdentity + plural: xworkloadidentities + versions: + - name: v1alpha1 + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + parameters: + type: object + description: Workload Identity configuration parameters. + properties: + id: + type: string + description: ID of this Workload Identity that other objects will use to refer to it. + deletionPolicy: + description: Delete the external resources when the Claim/XR is deleted. Defaults to Delete. + enum: + - Delete + - Orphan + type: string + default: Delete + providerConfigName: + description: Crossplane ProviderConfig to use for provisioning this resources. + type: string + default: default + serviceAccount: + type: object + description: Configuration for SA + properties: + name: + type: string + description: name kubernetes SA + namespace: + type: string + description: namespace kubernetes SA + required: + - name + - namespace + condition: + type: string + description: This is the whether or not the equals is a hard match or like query + default: StringEquals + enum: + - StringEquals + - StringLike + dnsProject: + type: string + description: The Project ID where the DNS managed zone lives. + required: + - id + - serviceAccount + - dnsProject + required: + - parameters + status: + type: object + properties: + workloadIdentity: + description: Freeform field containing status information for Workload Identity. + type: object + x-kubernetes-preserve-unknown-fields: true + observed: + description: Freeform field containing information about the observed status. + type: object + x-kubernetes-preserve-unknown-fields: true + googleServiceAccount: + type: object + description: Configuration for GSA + properties: + email: + type: string + description: email Google SA + id: + type: string + description: id Google SA + required: + - email + - id diff --git a/crossplane.yaml b/crossplane.yaml index 274bd30..e8721d6 100644 --- a/crossplane.yaml +++ b/crossplane.yaml @@ -29,7 +29,10 @@ spec: version: "v0.5.0" - configuration: xpkg.upbound.io/upbound/configuration-gcp-gke # renovate: datasource=github-releases depName=upbound/configuration-gcp-gke - version: "v0.5.0" + version: "v0.7.0" + - provider: xpkg.upbound.io/upbound/provider-gcp-dns + # renovate: datasource=github-releases depName=upbound/provider-gcp + version: "v1.2.0" - configuration: xpkg.upbound.io/upbound/configuration-gitops-argocd # renovate: datasource=github-releases depName=upbound/configuration-gitops-argocd version: "v0.8.0" diff --git a/examples/gcp-host-space.yaml b/examples/gcp-host-space.yaml index d048e0a..e4fd9dc 100644 --- a/examples/gcp-host-space.yaml +++ b/examples/gcp-host-space.yaml @@ -14,6 +14,13 @@ spec: count: 3 instanceType: e2-standard-4 operators: + externaldns: + gcp: + enabled: true + # To leverage external-dns for managing the spaces.dns.spacesRouterDomain zone entry, + # substitute the placeholder values with your actual Managed Zone Name and GCP DNS Project Name. + zoneName: ${data.gcpZoneName} + dnsProject: ${data.gcpDNSProject} crossplane: providers: - name: provider-helm @@ -24,7 +31,7 @@ spec: localRbac: true argocd: enabled: true - ingressUrl: argocd-platform-ref-upbound-spaces.${data.route53ZoneName} + ingressUrl: argocd-platform-ref-upbound-spaces.${data.gcpZoneName} git: url: https://github.com/upbound/platform-ref-upbound-spaces.git path: gitops @@ -55,7 +62,7 @@ spec: - "*/controlplane-*" spaces: dns: - spacesRouterDomain: platform-ref-upbound-spaces-gke.${data.route53ZoneName} + spacesRouterDomain: platform-ref-upbound-spaces-gke.${data.gcpZoneName} clusterType: gke account: platform-ref writeConnectionSecretToRef: