diff --git a/Makefile b/Makefile index 0618f58..d8c8710 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ PLATFORMS ?= linux_amd64 UP_VERSION = v0.24.1 UP_CHANNEL = stable -UPTEST_VERSION = v0.11.0 +UPTEST_VERSION = v0.11.1 -include build/makelib/k8s_tools.mk # ==================================================================================== @@ -23,7 +23,7 @@ UPTEST_VERSION = v0.11.0 # certain conventions such as the default examples root or package directory. XPKG_DIR = $(shell pwd) XPKG_EXAMPLES_DIR = .up/examples -XPKG_IGNORE = .github/workflows/*.yml,.github/workflows/*.yaml,init/*.yaml,examples/flux/*.yaml,examples/*.yaml,examples/argocd/*.yaml,.work/uptest-datasource.yaml +XPKG_IGNORE = .github/workflows/*.yml,.github/workflows/*.yaml,init/*.yaml,examples/*.yaml,.work/uptest-datasource.yaml,examples/**/*.yaml XPKG_REG_ORGS ?= xpkg.upbound.io/upbound # NOTE(hasheddan): skip promoting on xpkg.upbound.io as channel tags are @@ -64,24 +64,27 @@ build.init: $(UP) # End to End Testing # This target requires the following environment variables to be set: -# $ export UPTEST_CLOUD_CREDENTIALS=$(echo "AWS='$(cat ~/.aws/credentials)'\nAZURE='$(cat ~/.azure/credentials.json)'\nGCP='$(cat ~/.gcloud/credentials.json)") +# $ export UPTEST_CLOUD_CREDENTIALS=$(echo "AWS='$(cat ~/.aws/credentials)'\nAZURE='$(cat ~/.azure/credentials.json)'\nGCP='$(cat ~/.gcloud/credentials.json)'\nSPACES='$(cat ~/.gcloud/key.json)'") uptest: $(UPTEST) $(KUBECTL) $(KUTTL) @$(INFO) running automated tests - @KUBECTL=$(KUBECTL) KUTTL=$(KUTTL) CROSSPLANE_NAMESPACE=$(CROSSPLANE_NAMESPACE) $(UPTEST) e2e "${UPTEST_EXAMPLE_LIST}" --data-source="${UPTEST_DATASOURCE_PATH}" --setup-script=test/setup.sh --default-timeout=4800 || $(FAIL) + @KUBECTL=$(KUBECTL) KUTTL=$(KUTTL) CROSSPLANE_NAMESPACE=$(CROSSPLANE_NAMESPACE) $(UPTEST) e2e "${UPTEST_EXAMPLE_LIST}" --data-source="${UPTEST_DATASOURCE_PATH}" --setup-script=test/setup.sh --default-timeout=4800 ${SKIP_DELETE} || $(FAIL) @$(OK) running automated tests # This target requires the following environment variables to be set: -# $ export UPTEST_CLOUD_CREDENTIALS=$(echo "AWS='$(cat ~/.aws/credentials)'\nAZURE='$(cat ~/.azure/credentials.json)'\nGCP='$(cat ~/.gcloud/credentials.json)") +# $ export UPTEST_CLOUD_CREDENTIALS=$(echo "AWS='$(cat ~/.aws/credentials)'\nAZURE='$(cat ~/.azure/credentials.json)'\nGCP='$(cat ~/.gcloud/credentials.json)'\nSPACES='$(cat ~/.gcloud/key.json)'") e2e: build controlplane.up local.xpkg.deploy.configuration.$(PROJECT_NAME) uptest render: - crossplane beta render examples/aws-cluster.yaml apis/composition.yaml examples/functions.yaml -r - crossplane beta render examples/azure-cluster.yaml apis/composition.yaml examples/functions.yaml -r - crossplane beta render examples/space.yaml apis/composition.yaml examples/functions.yaml -r + crossplane beta render examples/xr/aws-hostcluster.yaml apis/cluster/composition.yaml examples/functions.yaml -r + crossplane beta render examples/xr/azure-hostcluster.yaml apis/cluster/composition.yaml examples/functions.yaml -r + crossplane beta render examples/xr/gcp-hostcluster.yaml apis/cluster/composition.yaml examples/functions.yaml -r + crossplane beta render examples/xr/space-init.yaml apis/space-init/composition.yaml examples/functions.yaml -r + crossplane beta render examples/xr/space-core.yaml apis/space-core/composition.yaml examples/functions.yaml -r + crossplane beta render examples/aws-host-space.yaml apis/composition.yaml examples/functions.yaml -r yamllint: @$(INFO) running yamllint @yamllint ./apis || $(FAIL) @$(OK) running yamllint -.PHONY: uptest e2e render yamllint \ No newline at end of file +.PHONY: uptest e2e render yamllint diff --git a/apis/cluster/composition.yaml b/apis/cluster/composition.yaml new file mode 100644 index 0000000..dc03e00 --- /dev/null +++ b/apis/cluster/composition.yaml @@ -0,0 +1,238 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xclusters.spaces.platformref.upbound.io +spec: + writeConnectionSecretsToNamespace: upbound-system + compositeTypeRef: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XCluster + mode: Pipeline + pipeline: + - step: patch-and-transform + functionRef: + name: upboundcare-function-conditional-patch-and-transform + input: + apiVersion: pt.fn.crossplane.io/v1beta1 + kind: Resources + resources: + - name: XNetworkAWS + condition: observed.composite.resource.spec.parameters.cloud == "aws" + base: + apiVersion: aws.platform.upbound.io/v1alpha1 + kind: XNetwork + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.region + toFieldPath: spec.parameters.region + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.parameters.deletionPolicy + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.networkSelector + toFieldPath: spec.compositionSelector.matchLabels[type] + - type: ToCompositeFieldPath + fromFieldPath: status.subnetIds + policy: + fromFieldPath: Required + toFieldPath: status.subnetIds + + - name: XEKS + condition: observed.composite.resource.spec.parameters.cloud == "aws" + base: + apiVersion: aws.platform.upbound.io/v1alpha1 + kind: XEKS + connectionDetails: + - type: FromConnectionSecretKey + fromConnectionSecretKey: kubeconfig + name: kubeconfig + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: metadata.labels[xeks.aws.platform.upbound.io/cluster-id] + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.region + toFieldPath: spec.parameters.region + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.parameters.deletionPolicy + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: metadata.annotations[crossplane.io/external-name] + - type: FromCompositeFieldPath + fromFieldPath: metadata.uid + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - type: string + string: + fmt: '%s-eks' + type: Format + - type: FromCompositeFieldPath + fromFieldPath: spec.writeConnectionSecretToRef.namespace + toFieldPath: spec.writeConnectionSecretToRef.namespace + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.version + toFieldPath: spec.parameters.version + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.nodes.count + toFieldPath: spec.parameters.nodes.count + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.nodes.instanceType + toFieldPath: spec.parameters.nodes.instanceType + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.iam.roleArn + toFieldPath: spec.parameters.iam.roleArn + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.iam.userArn + toFieldPath: spec.parameters.iam.userArn + + - name: XNetworkAZURE + condition: observed.composite.resource.spec.parameters.cloud == "azure" + base: + apiVersion: azure.platform.upbound.io/v1alpha1 + kind: XNetwork + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.region + toFieldPath: spec.parameters.region + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.parameters.deletionPolicy + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.networkSelector + toFieldPath: spec.compositionSelector.matchLabels[type] + + - name: XAKS + condition: observed.composite.resource.spec.parameters.cloud == "azure" + base: + apiVersion: azure.platform.upbound.io/v1alpha1 + kind: XAKS + connectionDetails: + - type: FromConnectionSecretKey + fromConnectionSecretKey: kubeconfig + name: kubeconfig + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: metadata.labels[xaks.azure.platform.upbound.io/cluster-id] + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.region + toFieldPath: spec.parameters.region + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.parameters.deletionPolicy + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: metadata.uid + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - type: string + string: + fmt: '%s-aks' + type: Format + - type: FromCompositeFieldPath + fromFieldPath: spec.writeConnectionSecretToRef.namespace + toFieldPath: spec.writeConnectionSecretToRef.namespace + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.version + toFieldPath: spec.parameters.version + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.nodes.count + toFieldPath: spec.parameters.nodes.count + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.nodes.instanceType + toFieldPath: spec.parameters.nodes.instanceType + + - name: XNetworkGCP + condition: observed.composite.resource.spec.parameters.cloud == "gcp" + base: + apiVersion: gcp.platform.upbound.io/v1alpha1 + kind: XNetwork + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.region + toFieldPath: spec.parameters.region + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.parameters.deletionPolicy + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.networkSelector + toFieldPath: spec.compositionSelector.matchLabels[type] + + - name: XGKE + condition: observed.composite.resource.spec.parameters.cloud == "gcp" + base: + apiVersion: gcp.platform.upbound.io/v1alpha1 + kind: XGKE + connectionDetails: + - type: FromConnectionSecretKey + fromConnectionSecretKey: kubeconfig + name: kubeconfig + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: metadata.labels[xgke.gcp.platform.upbound.io/cluster-id] + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.region + toFieldPath: spec.parameters.region + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.parameters.deletionPolicy + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: metadata.annotations[crossplane.io/external-name] + - type: FromCompositeFieldPath + fromFieldPath: metadata.uid + toFieldPath: spec.writeConnectionSecretToRef.name + transforms: + - type: string + string: + fmt: '%s-gke' + type: Format + - type: FromCompositeFieldPath + fromFieldPath: spec.writeConnectionSecretToRef.namespace + toFieldPath: spec.writeConnectionSecretToRef.namespace + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.version + toFieldPath: spec.parameters.version + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.nodes.count + toFieldPath: spec.parameters.nodes.count + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.nodes.instanceType + toFieldPath: spec.parameters.nodes.instanceType diff --git a/apis/cluster/definition.yaml b/apis/cluster/definition.yaml new file mode 100644 index 0000000..080d9f2 --- /dev/null +++ b/apis/cluster/definition.yaml @@ -0,0 +1,109 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xclusters.spaces.platformref.upbound.io +spec: + defaultCompositeDeletePolicy: Foreground + group: spaces.platformref.upbound.io + names: + kind: XCluster + plural: xclusters + claimNames: + kind: Cluster + plural: clusters + connectionSecretKeys: + - kubeconfig + versions: + - name: v1alpha1 + additionalPrinterColumns: + - jsonPath: .spec.parameters.cloud + name: CLOUD + type: string + - jsonPath: .spec.compositionRevisionRef.name + name: COMPOSITION REVISION + type: string + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + parameters: + type: object + description: Cluster configuration parameters. + properties: + cloud: + description: Cloud is the cloud provider you'd like your cluster resources to be created in. + type: string + enum: + - aws + - gcp + - azure + id: + type: string + description: ID of this Cluster that other objects will use to refer to it. + region: + type: string + description: Region is the region you'd like your resource to be created in. + iam: + type: object + description: IAM configuration to connect as ClusterAdmin. + properties: + roleArn: + description: The IAM Role ARN to connect as ClusterAdmin. + type: string + userArn: + description: The IAM User ARN to connect as ClusterAdmin. + type: string + networkSelector: + type: string + description: NetworkSelector employs a specific type of network architecture. + enum: + - basic + default: basic + 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 + version: + type: string + description: Kubernetes version of the Cluster + nodes: + type: object + description: Cluster node configuration parameters. + properties: + count: + type: integer + description: Desired node count, from 1 to 100. + instanceType: + type: string + description: instance types associated with the Node Group. + required: + - count + - instanceType + required: + - deletionPolicy + - id + - cloud + - nodes + - providerConfigName + - region + required: + - parameters + status: + type: object + properties: + subnetIds: + type: array + items: + type: string diff --git a/apis/composition.yaml b/apis/composition.yaml new file mode 100644 index 0000000..9816d28 --- /dev/null +++ b/apis/composition.yaml @@ -0,0 +1,121 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xspaces.spaces.platformref.upbound.io +spec: + writeConnectionSecretsToNamespace: upbound-system + compositeTypeRef: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XSpace + mode: Pipeline + pipeline: + - step: patch-and-transform + functionRef: + name: upboundcare-function-conditional-patch-and-transform + input: + apiVersion: pt.fn.crossplane.io/v1beta1 + kind: Resources + resources: + - name: aws-kubernetes-cluster + base: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XCluster + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.deletionPolicy + toFieldPath: spec.parameters.deletionPolicy + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.cloud + toFieldPath: spec.parameters.cloud + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.id + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.region + toFieldPath: spec.parameters.region + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.version + toFieldPath: spec.parameters.version + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.iam + toFieldPath: spec.parameters.iam + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.nodes + toFieldPath: spec.parameters.nodes + + - name: spaces-init + base: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XInit + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators + toFieldPath: spec.parameters.operators + + - name: spaces-core + base: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XCore + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.id + toFieldPath: spec.parameters.providerConfigName + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.spaces + toFieldPath: spec.parameters.spaces + + - name: usageXInitByXCore + base: + apiVersion: apiextensions.crossplane.io/v1alpha1 + kind: Usage + spec: + by: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XCore + resourceSelector: + matchControllerRef: true + of: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XInit + resourceSelector: + matchControllerRef: true + readinessChecks: + - type: None + + - name: usageXClusterByXInit + base: + apiVersion: apiextensions.crossplane.io/v1alpha1 + kind: Usage + spec: + by: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XInit + resourceSelector: + matchControllerRef: true + of: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XCluster + resourceSelector: + matchControllerRef: true + readinessChecks: + - type: None + + - step: ordered-creation + functionRef: + name: crossplane-contrib-function-sequencer + input: + apiVersion: template.fn.crossplane.io/v1beta1 + kind: Input + rules: + - sequence: + - aws-kubernetes-cluster + - spaces-init + - sequence: + - spaces-init + - spaces-core diff --git a/apis/definition.yaml b/apis/definition.yaml new file mode 100644 index 0000000..cd79d42 --- /dev/null +++ b/apis/definition.yaml @@ -0,0 +1,280 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xspaces.spaces.platformref.upbound.io +spec: + defaultCompositeDeletePolicy: Foreground + group: spaces.platformref.upbound.io + names: + kind: XSpace + plural: xspaces + claimNames: + kind: Space + plural: spaces + connectionSecretKeys: + - kubeconfig + versions: + - name: v1alpha1 + additionalPrinterColumns: + - jsonPath: .spec.parameters.cloud + name: CLOUD + type: string + - jsonPath: .spec.compositionRevisionRef.name + name: COMPOSITION REVISION + type: string + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + parameters: + type: object + description: Cluster configuration parameters. + properties: + cloud: + description: Cloud is the cloud provider you'd like your cluster resources to be created in. + type: string + enum: + - aws + - gcp + - azure + id: + type: string + description: ID of this Cluster that other objects will use to refer to it. + region: + type: string + description: Region is the region you'd like your resource to be created in. + iam: + type: object + description: IAM configuration to connect as ClusterAdmin. + properties: + roleArn: + description: The IAM Role ARN to connect as ClusterAdmin. + type: string + userArn: + description: The IAM User ARN to connect as ClusterAdmin. + type: string + networkSelector: + type: string + description: NetworkSelector employs a specific type of network architecture. + enum: + - basic + default: basic + 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 + version: + type: string + description: Kubernetes version of the Cluster + nodes: + type: object + description: Cluster node configuration parameters. + default: + count: 5 + instanceType: m5.2xlarge + properties: + count: + type: integer + description: Desired node count, from 1 to 100. + default: 5 + instanceType: + type: string + description: instance types associated with the Node Group. + default: m5.2xlarge + required: + - count + - instanceType + operators: + type: object + description: "Defines the operators to be deployed with their enabled status and versions." + default: + certmanager: + enabled: true + version: "v1.14.3" + ingressnginx: + enabled: true + version: "4.9.1" + externaldns: + version: "6.34.2" + crossplane: + enabled: true + version: "v1.14.6-up.1" + providers: [] + properties: + certmanager: + type: object + default: + enabled: true + version: "v1.14.3" + properties: + enabled: + type: boolean + description: "Indicates if cert-manager is enabled." + default: true + version: + type: string + description: "Specifies the version of cert-manager to use." + default: "v1.14.3" + required: + - enabled + - version + ingressnginx: + type: object + default: + enabled: true + version: "4.9.1" + properties: + enabled: + type: boolean + description: "Indicates if ingress-nginx is enabled." + default: true + version: + type: string + description: "Specifies the version of ingress-nginx to use." + default: "4.9.1" + required: + - enabled + - version + externaldns: + type: object + properties: + aws: + type: object + properties: + enabled: + type: boolean + description: "Indicates if AWS external-dns is enabled." + default: true + route53ZoneId: + type: string + description: "The Route53 zone ID for external-dns to manage." + route53ZoneName: + type: string + description: "The Route53 zone name for external-dns to manage." + version: + type: string + description: "Specifies the version of external-dns to use." + default: "6.34.2" + required: + - version + crossplane: + type: object + default: + enabled: true + version: "v1.14.6-up.1" + providers: [] + properties: + enabled: + type: boolean + description: "Indicates if Crossplane is enabled." + default: true + version: + type: string + description: "Specifies the version of Crossplane to use." + default: "v1.14.6-up.1" + providers: + type: array + items: + type: object + properties: + name: + type: string + description: "The name of the Crossplane provider." + package: + type: string + description: "The package of the Crossplane provider." + enabled: + type: boolean + description: "Indicates if the Crossplane provider is enabled." + default: true + localRbac: + type: boolean + description: "Indicates if local RBAC is enabled for the provider." + required: + - enabled + - version + - providers + spaces: + type: object + description: "Defines the configuration for spaces." + default: + version: "1.2.1" + account: "" + clusterType: "" + dns: + spacesRouterDomain: "" + pullSecretRef: + name: upbound-provider-helm-pull + namespace: upbound-system + properties: + version: + type: string + description: "The version of the space configuration." + default: "1.2.1" + dns: + type: object + properties: + spacesRouterDomain: + type: string + description: "The domain for the spaces router." + required: + - spacesRouterDomain + account: + type: string + description: "The account identifier for the space." + clusterType: + type: string + description: "The type of cluster to deploy for the space." + pullSecretRef: + type: object + default: + name: upbound-provider-helm-pull + namespace: upbound-system + properties: + name: + type: string + description: "The name of the pull secret to use." + default: upbound-provider-helm-pull + namespace: + type: string + description: "The namespace of the pull secret." + default: upbound-system + required: + - name + - namespace + required: + - version + - dns + - account + - clusterType + - pullSecretRef + required: + - cloud + - deletionPolicy + - id + - nodes + - operators + - providerConfigName + - region + - spaces + required: + - parameters + status: + type: object + properties: + subnetIds: + type: array + items: + type: string diff --git a/apis/irsa/composition.yaml b/apis/irsa/composition.yaml new file mode 100644 index 0000000..1748d04 --- /dev/null +++ b/apis/irsa/composition.yaml @@ -0,0 +1,182 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xirsas.aws.platform.upbound.io +spec: + compositeTypeRef: + apiVersion: aws.platform.upbound.io/v1alpha1 + kind: XIRSA + 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: irsaRole + base: + apiVersion: iam.aws.upbound.io/v1beta1 + kind: Role + metadata: + labels: + resource: Role + patches: + - patchSetName: Name + type: PatchSet + - patchSetName: providerConfigRef + type: PatchSet + - patchSetName: deletionPolicy + type: PatchSet + - fromFieldPath: status.atProvider.arn + policy: + fromFieldPath: Optional + toFieldPath: status.roleArn + type: ToCompositeFieldPath + - fromFieldPath: status.conditions + policy: + fromFieldPath: Optional + toFieldPath: status.observed.role.conditions + type: ToCompositeFieldPath + - combine: + strategy: string + string: + fmt: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "%s" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "%s": { + "%s:sub": "system:serviceaccount:%s:%s" + } + } + } + ] + } + variables: + - fromFieldPath: status.irsa.oidc_arn + - fromFieldPath: spec.parameters.condition + - fromFieldPath: status.irsa.oidc_host + - fromFieldPath: spec.parameters.serviceAccount.namespace + - fromFieldPath: spec.parameters.serviceAccount.name + toFieldPath: spec.forProvider.assumeRolePolicy + type: CombineFromComposite + + - name: irsaPolicy + base: + apiVersion: iam.aws.upbound.io/v1beta1 + kind: Policy + metadata: + labels: + resource: Policy + patches: + - patchSetName: providerConfigRef + type: PatchSet + - patchSetName: deletionPolicy + type: PatchSet + - fromFieldPath: spec.parameters.policyDocument + toFieldPath: spec.forProvider.policy + type: FromCompositeFieldPath + - fromFieldPath: metadata.annotations[crossplane.io/external-name] + toFieldPath: status.policyArn + type: ToCompositeFieldPath + - fromFieldPath: status.conditions + policy: + fromFieldPath: Optional + toFieldPath: status.observed.policy.conditions + type: ToCompositeFieldPath + + - name: irsaAttachment + base: + apiVersion: iam.aws.upbound.io/v1beta1 + kind: RolePolicyAttachment + metadata: + labels: + resource: RolePolicyAttachment + spec: + forProvider: + policyArnSelector: + matchControllerRef: true + matchLabels: + resource: Policy + roleSelector: + matchControllerRef: true + matchLabels: + resource: Role + patches: + - patchSetName: providerConfigRef + type: PatchSet + - patchSetName: deletionPolicy + type: PatchSet + - fromFieldPath: status.conditions + policy: + fromFieldPath: Optional + toFieldPath: status.observed.rpa.conditions + type: ToCompositeFieldPath + + - name: irsaSettings + base: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + spec: + deletionPolicy: Orphan + forProvider: + manifest: + apiVersion: v1 + kind: ConfigMap + metadata: + namespace: default + managementPolicy: 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-irsa-settings' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: spec.parameters.id + toFieldPath: spec.forProvider.manifest.metadata.name + transforms: + - string: + fmt: '%s-irsa-settings' + type: Format + type: string + type: FromCompositeFieldPath + - fromFieldPath: status.atProvider.manifest.data.oidc_arn + policy: + fromFieldPath: Optional + toFieldPath: status.irsa.oidc_arn + type: ToCompositeFieldPath + - fromFieldPath: status.atProvider.manifest.data.oidc_host + policy: + fromFieldPath: Optional + toFieldPath: status.irsa.oidc_host + type: ToCompositeFieldPath diff --git a/apis/irsa/definition.yaml b/apis/irsa/definition.yaml new file mode 100644 index 0000000..02fe6b1 --- /dev/null +++ b/apis/irsa/definition.yaml @@ -0,0 +1,90 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xirsas.aws.platform.upbound.io + labels: + provider: aws +spec: + claimNames: + kind: IRSA + plural: irsas + group: aws.platform.upbound.io + names: + kind: XIRSA + plural: xirsas + versions: + - name: v1alpha1 + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + parameters: + type: object + description: IRSA configuration parameters. + properties: + id: + type: string + description: ID of this Cluster 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 + policyDocument: + type: string + description: The JSON policy document that is the content for the policy. + required: + - id + - condition + - policyDocument + - serviceAccount + required: + - parameters + status: + type: object + properties: + irsa: + description: Freeform field containing status information for irsa + type: object + x-kubernetes-preserve-unknown-fields: true + roleArn: + description: The arn of the role + type: string + policyArn: + description: The arn of the policy + type: string + observed: + description: Freeform field containing information about the observed status. + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/apis/space-core/composition.yaml b/apis/space-core/composition.yaml new file mode 100644 index 0000000..4781715 --- /dev/null +++ b/apis/space-core/composition.yaml @@ -0,0 +1,56 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xcore.spaces.platformref.upbound.io +spec: + writeConnectionSecretsToNamespace: upbound-system + compositeTypeRef: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XCore + mode: Pipeline + pipeline: + - step: patch-and-transform + functionRef: + name: upboundcare-function-conditional-patch-and-transform + input: + apiVersion: pt.fn.crossplane.io/v1beta1 + kind: Resources + resources: + - name: spaces + base: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + spec: + rollbackLimit: 3 + forProvider: + namespace: upbound-system + chart: + name: spaces + repository: oci://us-west1-docker.pkg.dev/orchestration-build/upbound-environments + set: + - name: "account" + - name: "clusterType" + - name: "ingress.host" + - name: "features.alpha.eso.enabled" + value: "true" + - name: "features.alpha.eso.namespace" + value: "external-secrets" + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.spaces.account + toFieldPath: spec.forProvider.set[0].value + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.spaces.clusterType + toFieldPath: spec.forProvider.set[1].value + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.spaces.dns.spacesRouterDomain + toFieldPath: spec.forProvider.set[2].value + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.spaces.pullSecretRef + toFieldPath: spec.forProvider.chart.pullSecretRef + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.spaces.version + toFieldPath: spec.forProvider.chart.version diff --git a/apis/space-core/definition.yaml b/apis/space-core/definition.yaml new file mode 100644 index 0000000..2a49f22 --- /dev/null +++ b/apis/space-core/definition.yaml @@ -0,0 +1,65 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xcore.spaces.platformref.upbound.io +spec: + defaultCompositeDeletePolicy: Foreground + group: spaces.platformref.upbound.io + names: + kind: XCore + plural: xcore + versions: + - name: v1alpha1 + additionalPrinterColumns: + - jsonPath: .spec.parameters.spaces.version + name: SPACES + type: string + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + parameters: + type: object + properties: + providerConfigName: + type: string + spaces: + type: object + description: "Defines the configuration for spaces." + properties: + version: + type: string + description: "The version of the space configuration." + dns: + type: object + properties: + spacesRouterDomain: + type: string + description: "The domain for the spaces router." + account: + type: string + description: "The account identifier for the space." + clusterType: + type: string + description: "The type of cluster to deploy for the space." + pullSecretRef: + type: object + properties: + name: + type: string + description: "The name of the pull secret to use." + namespace: + type: string + description: "The namespace of the pull secret." + status: + type: object + properties: + status: + description: Freeform field containing status information + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/apis/space-init/composition.yaml b/apis/space-init/composition.yaml new file mode 100644 index 0000000..8de4cba --- /dev/null +++ b/apis/space-init/composition.yaml @@ -0,0 +1,474 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xinit.spaces.platformref.upbound.io +spec: + writeConnectionSecretsToNamespace: upbound-system + compositeTypeRef: + apiVersion: spaces.platformref.upbound.io/v1alpha1 + kind: XInit + mode: Pipeline + pipeline: + - step: providers + functionRef: + name: crossplane-contrib-function-go-templating + input: + apiVersion: gotemplating.fn.crossplane.io/v1beta1 + kind: GoTemplate + source: Inline + inline: + template: | + {{ $spec := .observed.composite.resource.spec }} + {{- range $i, $provider := $spec.parameters.operators.crossplane.providers }} + --- + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-p + labels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-p + spec: + forProvider: + manifest: + apiVersion: pkg.crossplane.io/v1 + kind: Provider + metadata: + name: {{ $provider.name }} + spec: + package: {{ $provider.package }} + {{- if $provider.localRbac }} + runtimeConfigRef: + apiVersion: pkg.crossplane.io/v1beta1 + kind: DeploymentRuntimeConfig + name: {{ $provider.name }} + {{- end }} + providerConfigRef: + name: {{ $spec.parameters.providerConfigName }} + --- + apiVersion: apiextensions.crossplane.io/v1alpha1 + kind: Usage + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-p-usage + spec: + by: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + resourceSelector: + matchControllerRef: true + matchLabels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-p + of: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + resourceSelector: + matchControllerRef: true + matchLabels: + type: crossplane + {{- if $provider.localRbac }} + --- + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-drc + labels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-drc + spec: + forProvider: + manifest: + apiVersion: pkg.crossplane.io/v1beta1 + kind: DeploymentRuntimeConfig + metadata: + name: {{ $provider.name }} + spec: + serviceAccountTemplate: + metadata: + name: provider-kubernetes + providerConfigRef: + name: {{ $spec.parameters.providerConfigName }} + --- + apiVersion: apiextensions.crossplane.io/v1alpha1 + kind: Usage + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-drc-usage + spec: + by: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + resourceSelector: + matchControllerRef: true + matchLabels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-drc + of: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + resourceSelector: + matchControllerRef: true + matchLabels: + type: crossplane + --- + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-crb + labels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-crb + spec: + forProvider: + manifest: + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRoleBinding + metadata: + name: {{ $provider.name }}-admin-binding + subjects: + - kind: ServiceAccount + name: {{ $provider.name }} + namespace: upbound-system + roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io + providerConfigRef: + name: {{ $spec.parameters.providerConfigName }} + --- + apiVersion: apiextensions.crossplane.io/v1alpha1 + kind: Usage + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-crb-usage + spec: + by: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + resourceSelector: + matchControllerRef: true + matchLabels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-crb + of: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + resourceSelector: + matchControllerRef: true + matchLabels: + type: crossplane + --- + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-pc + labels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-pc + spec: + forProvider: + manifest: + {{- if eq $provider.name "provider-kubernetes" }} + apiVersion: kubernetes.crossplane.io/v1alpha1 + {{- end }} + {{- if eq $provider.name "provider-helm" }} + apiVersion: helm.crossplane.io/v1beta1 + {{- end }} + kind: ProviderConfig + metadata: + name: upbound-cluster + spec: + credentials: + source: InjectedIdentity + providerConfigRef: + name: {{ $spec.parameters.providerConfigName }} + --- + apiVersion: apiextensions.crossplane.io/v1alpha1 + kind: Usage + metadata: + annotations: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-pc-usage + spec: + by: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + resourceSelector: + matchControllerRef: true + matchLabels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-pc + of: + apiVersion: kubernetes.crossplane.io/v1alpha2 + kind: Object + resourceSelector: + matchControllerRef: true + matchLabels: + gotemplating.fn.crossplane.io/composition-resource-name: {{ $spec.parameters.providerConfigName }}-{{ $provider.name }}-p + {{- end }} + {{- end }} + + - step: patch-and-transform + functionRef: + name: upboundcare-function-conditional-patch-and-transform + input: + apiVersion: pt.fn.crossplane.io/v1beta1 + kind: Resources + resources: + - name: copy-provider-helm-pull-secret + base: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + spec: + references: + - patchesFrom: + apiVersion: v1 + kind: Secret + name: upbound-provider-helm-pull + namespace: upbound-system + fieldPath: data[username] + toFieldPath: data[username] + - patchesFrom: + apiVersion: v1 + kind: Secret + name: upbound-provider-helm-pull + namespace: upbound-system + fieldPath: data[password] + toFieldPath: data[password] + forProvider: + manifest: + apiVersion: v1 + kind: Secret + metadata: + name: upbound-provider-helm-pull + namespace: upbound-system + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + + - name: copy-crossplane-pull-secret + base: + apiVersion: kubernetes.crossplane.io/v1alpha1 + kind: Object + spec: + references: + - patchesFrom: + apiVersion: v1 + kind: Secret + name: upbound-pull-secret + namespace: upbound-system + fieldPath: data[.dockerconfigjson] + toFieldPath: data[.dockerconfigjson] + forProvider: + manifest: + apiVersion: v1 + kind: Secret + type: kubernetes.io/dockerconfigjson + metadata: + name: upbound-pull-secret + namespace: upbound-system + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + + - name: cert-manager + condition: observed.composite.resource.spec.parameters.operators.certmanager.enabled == true + base: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + spec: + rollbackLimit: 3 + forProvider: + namespace: cert-manager + chart: + name: cert-manager + repository: https://charts.jetstack.io + values: + installCRDs: true + waitTimeout: "360s" + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators.certmanager.version + toFieldPath: spec.forProvider.chart.version + + - name: ingress-nginx + condition: observed.composite.resource.spec.parameters.operators.ingressnginx.enabled == true + base: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + spec: + rollbackLimit: 3 + forProvider: + namespace: ingress-nginx + chart: + name: ingress-nginx + repository: https://kubernetes.github.io/ingress-nginx + set: + - name: "controller.service.type" + value: "LoadBalancer" + - name: "controller.allowSnippetAnnotations" + value: "true" + - name: controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path" + value: "/healthz" + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators.ingressnginx.version + toFieldPath: spec.forProvider.chart.version + - type: ToCompositeFieldPath + fromFieldPath: metadata.annotations[crossplane.io/external-name] + toFieldPath: status.status.ingressNginxName + policy: + fromFieldPath: Optional + + - name: external-dns-irsa + condition: observed.composite.resource.spec.parameters.operators.externaldns.aws.enabled == true + base: + apiVersion: aws.platform.upbound.io/v1alpha1 + kind: XIRSA + spec: + parameters: + condition: StringEquals + serviceAccount: + name: external-dns + namespace: external-dns + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.parameters.id + - type: ToCompositeFieldPath + fromFieldPath: status.roleArn + toFieldPath: status.status.externalDNS.IRSARoleArn + policy: + fromFieldPath: Optional + - type: CombineFromComposite + policy: + fromFieldPath: Required + combine: + variables: + - fromFieldPath: spec.parameters.operators.externaldns.aws.route53ZoneId + strategy: string + string: + fmt: | + { + "Version":"2012-10-17", + "Statement":[ + { + "Effect":"Allow", + "Action":[ + "route53:ListResourceRecordSets", + "route53:ListHostedZones" + ], + "Resource":"*" + }, + { + "Effect":"Allow", + "Action":"route53:ChangeResourceRecordSets", + "Resource":"arn:aws:route53:::hostedzone/%s" + } + ] + } + toFieldPath: spec.parameters.policyDocument + + - name: external-dns + condition: observed.composite.resource.spec.parameters.operators.externaldns.aws.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: aws + policy: sync + source: ingress + registry: txt + aws: + batchChangeSize: 4 + zoneType: public + region: us-east-1 + 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.aws.route53ZoneName + toFieldPath: spec.forProvider.values.domainFilters[0] + - type: FromCompositeFieldPath + fromFieldPath: status.status.externalDNS.IRSARoleArn + toFieldPath: spec.forProvider.values.serviceAccount.annotations[eks.amazonaws.com/role-arn] + policy: + fromFieldPath: Required + - 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: + apiVersion: helm.crossplane.io/v1beta1 + kind: Release + metadata: + labels: + type: crossplane + spec: + rollbackLimit: 3 + forProvider: + namespace: upbound-system + chart: + name: universal-crossplane + repository: https://charts.upbound.io/stable + values: + args: + - --enable-usages + - --max-reconcile-rate=1000 + resourcesCrossplane: + limits: + cpu: 2000m + memory: 4096Mi + requests: + cpu: 1000m + memory: 2048Mi + patches: + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.providerConfigName + toFieldPath: spec.providerConfigRef.name + - type: FromCompositeFieldPath + fromFieldPath: spec.parameters.operators.crossplane.version + toFieldPath: spec.forProvider.chart.version + transforms: + - type: string + string: + type: TrimPrefix + trim: "v" + + - step: automatically-detect-ready-composed-resources + functionRef: + name: crossplane-contrib-function-auto-ready diff --git a/apis/space-init/definition.yaml b/apis/space-init/definition.yaml new file mode 100644 index 0000000..c1ba952 --- /dev/null +++ b/apis/space-init/definition.yaml @@ -0,0 +1,103 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xinit.spaces.platformref.upbound.io +spec: + defaultCompositeDeletePolicy: Foreground + group: spaces.platformref.upbound.io + names: + kind: XInit + plural: xinit + versions: + - name: v1alpha1 + additionalPrinterColumns: + - jsonPath: .spec.parameters.operators.crossplane.version + name: CROSSPLANE + type: string + served: true + referenceable: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + parameters: + type: object + properties: + providerConfigName: + type: string + operators: + type: object + description: "Defines the operators to be deployed with their enabled status and versions." + properties: + certmanager: + type: object + properties: + enabled: + type: boolean + description: "Indicates if cert-manager is enabled." + version: + type: string + description: "Specifies the version of cert-manager to use." + ingressnginx: + type: object + properties: + enabled: + type: boolean + description: "Indicates if ingress-nginx is enabled." + version: + type: string + description: "Specifies the version of ingress-nginx to use." + externaldns: + type: object + properties: + aws: + type: object + properties: + enabled: + type: boolean + description: "Indicates if AWS external-dns is enabled." + route53ZoneId: + type: string + description: "The Route53 zone ID for external-dns to manage." + route53ZoneName: + type: string + description: "The Route53 zone name for external-dns to manage." + version: + type: string + description: "Specifies the version of external-dns to use." + crossplane: + type: object + properties: + enabled: + type: boolean + description: "Indicates if Crossplane is enabled." + version: + type: string + description: "Specifies the version of Crossplane to use." + providers: + type: array + items: + type: object + properties: + name: + type: string + description: "The name of the Crossplane provider." + package: + type: string + description: "The package of the Crossplane provider." + enabled: + type: boolean + description: "Indicates if the Crossplane provider is enabled." + localRbac: + type: boolean + description: "Indicates if local RBAC is enabled for the provider." + status: + type: object + properties: + status: + description: Freeform field containing status information + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/crossplane.yaml b/crossplane.yaml index 127dafe..f7b99cc 100644 --- a/crossplane.yaml +++ b/crossplane.yaml @@ -32,3 +32,18 @@ spec: version: "v0.3.0" - function: xpkg.upbound.io/upboundcare/function-conditional-patch-and-transform version: "v0.4.0" + - function: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform + # renovate: datasource=github-releases depName=crossplane-contrib/function-patch-and-transform + version: "v0.3.0" + - function: xpkg.upbound.io/crossplane-contrib/function-auto-ready + # renovate: datasource=github-releases depName=crossplane-contrib/function-auto-ready + version: "v0.2.1" + - function: xpkg.upbound.io/crossplane-contrib/function-go-templating + # renovate: datasource=github-releases depName=crossplane-contrib/function-go-templating + version: "v0.4.1" + - function: xpkg.upbound.io/crossplane-contrib/function-sequencer + # renovate: datasource=github-releases depName=crossplane-contrib/function-sequencer + version: "v0.1.0" + - provider: xpkg.upbound.io/upbound/provider-aws-elb + # renovate: datasource=github-releases depName=upbound/provider-aws + version: "v1.1.0" diff --git a/examples/aws-host-space.yaml b/examples/aws-host-space.yaml new file mode 100644 index 0000000..cccd5be --- /dev/null +++ b/examples/aws-host-space.yaml @@ -0,0 +1,46 @@ +apiVersion: spaces.platformref.upbound.io/v1alpha1 +kind: Space +metadata: + name: hostcluster + namespace: default +spec: + compositeDeletePolicy: Foreground + parameters: + cloud: aws + id: hostcluster + region: us-west-2 + version: "1.27" + iam: + # Important: Please specify an iamRoleArn to access the AWS EKS Cluster deployed as part of CNOE. + # Without specifying a valid roleArn, you will not be able to log in to the EKS cluster. + # If you are using AWS SSO Roles, ensure to remove 'aws-reserved/sso.amazonaws.com/' from the ARN. + # For example, convert this: + # arn:aws:iam::123456789:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + # To this: + # arn:aws:iam::123456789:role/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + # roleArn: arn:aws:iam::123456789:role/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + roleArn: arn:aws:iam::609897127049:role/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + operators: + externaldns: + aws: + # To leverage external-dns for managing the spaces.dns.spacesRouterDomain zone entry, + # substitute the placeholder values with your actual Route53 Zone ID and Route53 Zone Name. + # route53zoneId: Z0000000000000000000 + # route53ZoneName: example.com + route53ZoneId: Z0115025YFQ7ZQF6BJ6N + route53ZoneName: upboundrocks.cloud + crossplane: + providers: + - name: provider-helm + package: xpkg.upbound.io/crossplane-contrib/provider-helm:v0.17.0 + localRbac: true + - name: provider-kubernetes + package: xpkg.upbound.io/crossplane-contrib/provider-kubernetes:v0.12.1 + localRbac: true + spaces: + dns: + spacesRouterDomain: platform-ref-upbound-spaces.upboundrocks.cloud + clusterType: eks + account: platform-ref + writeConnectionSecretToRef: + name: hostcluster-kubeconfig diff --git a/examples/ctp-1.yaml b/examples/ctp-1.yaml new file mode 100644 index 0000000..2e71f04 --- /dev/null +++ b/examples/ctp-1.yaml @@ -0,0 +1,21 @@ +# This demo manifest illustrates how to create control planes in alternative spaces. +apiVersion: kubernetes.crossplane.io/v1alpha2 +kind: Object +spec: + forProvider: + manifest: + apiVersion: spaces.upbound.io/v1beta1 + kind: ControlPlane + metadata: + name: ctp-remote + namespace: default + spec: + crossplane: + version: 1.14.6-up.1 + autoUpgrade: + channel: Stable + writeConnectionSecretToRef: + name: ctp-remote + namespace: default + providerConfigRef: + name: hostcluster diff --git a/examples/functions.yaml b/examples/functions.yaml new file mode 100644 index 0000000..89a5329 --- /dev/null +++ b/examples/functions.yaml @@ -0,0 +1,34 @@ +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: upboundcare-function-conditional-patch-and-transform +spec: + package: xpkg.upbound.io/upboundcare/function-conditional-patch-and-transform:v0.4.0 +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: crossplane-contrib-function-patch-and-transform +spec: + package: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.3.0 +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: crossplane-contrib-function-go-templating +spec: + package: xpkg.upbound.io/crossplane-contrib/function-go-templating:v0.4.1 +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: crossplane-contrib-function-auto-ready +spec: + package: xpkg.upbound.io/crossplane-contrib/function-auto-ready:v0.2.1 +--- +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: crossplane-contrib-function-sequencer +spec: + package: xpkg.upbound.io/crossplane-contrib/function-sequencer:v0.1.0 diff --git a/examples/xr/aws-hostcluster.yaml b/examples/xr/aws-hostcluster.yaml new file mode 100644 index 0000000..fa9b288 --- /dev/null +++ b/examples/xr/aws-hostcluster.yaml @@ -0,0 +1,27 @@ +apiVersion: spaces.platformref.upbound.io/v1alpha1 +kind: Cluster +metadata: + name: aws-spaces-hostcluster + namespace: default +spec: + compositeDeletePolicy: Foreground + parameters: + cloud: aws + id: aws-spaces-hostcluster + region: us-west-2 + version: "1.27" + iam: + # Important: Please specify an iamRoleArn to access the AWS EKS Cluster deployed as part of CNOE. + # Without specifying a valid roleArn, you will not be able to log in to the EKS cluster. + # If you are using AWS SSO Roles, ensure to remove 'aws-reserved/sso.amazonaws.com/' from the ARN. + # For example, convert this: + # arn:aws:iam::123456789:role/aws-reserved/sso.amazonaws.com/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + # To this: + # arn:aws:iam::123456789:role/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + # roleArn: arn:aws:iam::123456789:role/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + roleArn: arn:aws:iam::609897127049:role/AWSReservedSSO_AdministratorAccess_d703c73ed340fde7 + nodes: + count: 5 + instanceType: m5.2xlarge + writeConnectionSecretToRef: + name: aws-spaces-hostcluster-kubeconfig diff --git a/examples/xr/azure-hostcluster.yaml b/examples/xr/azure-hostcluster.yaml new file mode 100644 index 0000000..ebce672 --- /dev/null +++ b/examples/xr/azure-hostcluster.yaml @@ -0,0 +1,17 @@ +apiVersion: spaces.platformref.upbound.io/v1alpha1 +kind: Cluster +metadata: + name: azure-spaces-hostcluster + namespace: default +spec: + compositeDeletePolicy: Foreground + parameters: + cloud: azure + id: azure-spaces-hostcluster + region: westus + version: "1.27.3" + nodes: + count: 1 + instanceType: Standard_B2s + writeConnectionSecretToRef: + name: azure-spaces-hostcluster-kubeconfig diff --git a/examples/xr/gcp-hostcluster.yaml b/examples/xr/gcp-hostcluster.yaml new file mode 100644 index 0000000..92f2402 --- /dev/null +++ b/examples/xr/gcp-hostcluster.yaml @@ -0,0 +1,17 @@ +apiVersion: spaces.platformref.upbound.io/v1alpha1 +kind: Cluster +metadata: + name: gcp-spaces-hostcluster + namespace: default +spec: + compositeDeletePolicy: Foreground + parameters: + cloud: gcp + id: gcp-spaces-hostcluster + region: us-west2 + version: latest + nodes: + count: 3 + instanceType: n1-standard-4 + writeConnectionSecretToRef: + name: gcp-spaces-hostcluster-kubeconfig diff --git a/examples/xr/space-core.yaml b/examples/xr/space-core.yaml new file mode 100644 index 0000000..ba058b5 --- /dev/null +++ b/examples/xr/space-core.yaml @@ -0,0 +1,16 @@ +apiVersion: spaces.platformref.upbound.io/v1alpha1 +kind: XCore +metadata: + name: space-base +spec: + parameters: + providerConfigName: aws-spaces-hostcluster + spaces: + version: 1.2.1 + dns: + spacesRouterDomain: platform-ref-upbound-spaces.upboundrocks.cloud + clusterType: eks + account: platform-ref + pullSecretRef: + name: upbound-provider-helm-pull + namespace: upbound-system diff --git a/examples/xr/space-init.yaml b/examples/xr/space-init.yaml new file mode 100644 index 0000000..fe47910 --- /dev/null +++ b/examples/xr/space-init.yaml @@ -0,0 +1,32 @@ +apiVersion: spaces.platformref.upbound.io/v1alpha1 +kind: XInit +metadata: + name: space-base +spec: + parameters: + providerConfigName: aws-spaces-hostcluster + operators: + certmanager: + enabled: true + version: v1.14.3 + ingressnginx: + enabled: true + version: "4.9.1" + externaldns: + aws: + enabled: true + route53ZoneId: Z0115025YFQ7ZQF6BJ6N + route53ZoneName: upboundrocks.cloud + version: "6.34.2" + crossplane: + enabled: true + version: v1.14.6-up.1 + providers: + - name: provider-helm + package: xpkg.upbound.io/crossplane-contrib/provider-helm:v0.17.0 + enabled: true + localRbac: true + - name: provider-kubernetes + package: xpkg.upbound.io/crossplane-contrib/provider-kubernetes:v0.12.1 + enabled: true + localRbac: true diff --git a/test/setup.sh b/test/setup.sh index 5e2f384..fdc9850 100755 --- a/test/setup.sh +++ b/test/setup.sh @@ -62,6 +62,20 @@ spec: EOF fi + if [[ -n "${SPACES:-}" ]]; then + echo "Creating the SPACES pull secrets..." + + ${KUBECTL} -n upbound-system create secret generic upbound-provider-helm-pull \ + --from-literal=username="_json_key" \ + --from-literal=password="${SPACES}" + + ${KUBECTL} -n upbound-system create secret docker-registry upbound-pull-secret \ + --docker-server="https://us-west1-docker.pkg.dev" \ + --docker-username="_json_key" \ + --docker-password="${SPACES}" \ + --docker-email="uptest@upbound.io" + fi + if [[ -n "${AZURE:-}" ]]; then echo "Creating the AZURE default cloud credentials secret..." ${KUBECTL} -n upbound-system create secret generic azure-creds --from-literal=credentials="${AZURE}" --dry-run=client -o yaml | ${KUBECTL} apply -f -