├── VERSION ├── .envrc ├── apis ├── v1alpha1 │ ├── doc.go │ ├── binding.go │ ├── groupversion_info.go │ ├── zz_generated.pculist.go │ ├── zz_generated.pc.go │ └── zz_generated.pcu.go ├── account │ ├── v1beta1 │ │ ├── doc.go │ │ ├── groupversion_info.go │ │ └── zz_generated.managedlist.go │ ├── v1alpha1 │ │ ├── doc.go │ │ ├── constants.go │ │ ├── zz_tested.go │ │ ├── zz_generated.conversion_hubs.go │ │ ├── zz_groupversion_info.go │ │ └── entitlement_types_test.go │ └── account.go ├── oidc │ ├── v1alpha1 │ │ ├── doc.go │ │ ├── groupversion_info.go │ │ └── zz_generated.managedlist.go │ └── oidc.go ├── environment │ ├── v1alpha1 │ │ ├── doc.go │ │ ├── groupversion_info.go │ │ ├── zz_extractors.go │ │ └── zz_generated.managedlist.go │ └── environment.go ├── managed_tested.go ├── v1beta1 │ └── groupversion_info.go ├── template.go ├── security │ └── v1alpha1 │ │ ├── zz_generated.conversion_hubs.go │ │ ├── zz_extractors.go │ │ └── zz_groupversion_info.go └── zz_register.go ├── internal ├── controller │ ├── doc.go │ ├── account │ │ ├── entitlement │ │ │ ├── fake │ │ │ │ └── fake.go │ │ │ └── zz_setup.go │ │ ├── subscription │ │ │ └── zz_setup.go │ │ ├── globalaccount │ │ │ ├── zz_setup.go │ │ │ └── globalaccount_test.go │ │ ├── subaccount │ │ │ ├── zz_setup.go │ │ │ └── api_accessor.go │ │ ├── directory │ │ │ ├── zz_setup.go │ │ │ └── fake_client.go │ │ ├── servicebinding │ │ │ └── zz_setup.go │ │ ├── resourceusage │ │ │ ├── enqueue_handlers_test.go │ │ │ └── setup.go │ │ ├── serviceinstance │ │ │ └── zz_setup.go │ │ └── cloudmanagement │ │ │ └── zz_setup.go │ ├── oidc │ │ ├── certbasedoidclogin │ │ │ ├── certlogin_mock.go │ │ │ └── zz_setup.go │ │ ├── kubeconfiggenerator │ │ │ ├── zz_setup.go │ │ │ └── kubeconfigclient_mock.go │ │ └── test_utils.go │ ├── security │ │ ├── rolecollection │ │ │ └── zz_setup.go │ │ └── rolecollectionassignment │ │ │ └── zz_setup.go │ ├── kymamodule │ │ └── zz_setup.go │ ├── environment │ │ ├── cloudfoundry │ │ │ ├── zz_setup.go │ │ │ └── fake │ │ │ │ └── fake.go │ │ └── kyma │ │ │ ├── zz_setup.go │ │ │ └── fake │ │ │ └── fake.go │ └── kymaenvironmentbinding │ │ └── zz_setup.go ├── clients │ ├── oidc │ │ ├── test_keystores │ │ │ ├── openssl │ │ │ │ ├── keystore.pass.txt │ │ │ │ └── keystore.p12 │ │ │ └── legacy-openssl │ │ │ │ ├── keystore.pass.txt │ │ │ │ ├── keystore.p12 │ │ │ │ └── key.pem │ │ └── client.go │ ├── client_factory.go │ ├── kymaenvironmentbinding │ │ └── client.go │ ├── kymamodule │ │ ├── fakes.go │ │ └── client.go │ ├── account │ │ └── servicebinding │ │ │ └── naming.go │ └── tfclient │ │ └── tf_async_callback.go ├── openapi_clients │ ├── btp-service-manager-api-go │ │ ├── .openapi-generator │ │ │ └── VERSION │ │ ├── swagger-patch.json │ │ ├── pkg │ │ │ ├── .openapi-generator │ │ │ │ ├── VERSION │ │ │ │ └── FILES │ │ │ └── .openapi-generator-ignore │ │ └── README.md │ ├── btp-xsuaa-service-api-go │ │ ├── pkg │ │ │ ├── .openapi-generator │ │ │ │ └── VERSION │ │ │ ├── .openapi-generator-ignore │ │ │ └── response.go │ │ ├── .envrc │ │ ├── Makefile │ │ └── README.md │ ├── btp-accounts-service-api-go │ │ ├── pkg │ │ │ ├── .openapi-generator │ │ │ │ ├── VERSION │ │ │ │ └── FILES │ │ │ └── .openapi-generator-ignore │ │ ├── README.md │ │ └── example_usage │ │ │ └── api_test.go │ ├── btp-entitlements-service-api-go │ │ ├── pkg │ │ │ ├── .openapi-generator │ │ │ │ ├── VERSION │ │ │ │ └── FILES │ │ │ └── .openapi-generator-ignore │ │ ├── README.md │ │ └── example_usage │ │ │ └── api_test.go │ ├── btp-provisioning-service-api-go │ │ ├── pkg │ │ │ ├── .openapi-generator │ │ │ │ ├── VERSION │ │ │ │ └── FILES │ │ │ └── .openapi-generator-ignore │ │ ├── README.md │ │ └── example-usage │ │ │ └── api_test.go │ └── btp-saas-provisioning-api-go │ │ ├── pkg │ │ ├── .openapi-generator │ │ │ ├── VERSION │ │ │ └── FILES │ │ └── .openapi-generator-ignore │ │ └── README.md ├── version │ └── version.go ├── di │ └── creatorfns.go ├── features │ └── features.go ├── utils_test.go ├── testutils │ ├── error_helper_utils.go │ └── error_helper_utils_test.go └── tracking │ └── test │ └── noop.go ├── Logo.png ├── .gitmodules ├── hack ├── helpers │ ├── apis │ │ └── GROUP_LOWER │ │ │ ├── APIVERSION │ │ │ ├── doc.go.tmpl │ │ │ └── groupversion_info.go.tmpl │ │ │ └── GROUP_LOWER.go.tmpl │ ├── disable_crds.sh │ └── controller │ │ └── KIND_LOWER │ │ └── KIND_LOWER_test.go.tmpl └── boilerplate.go.txt ├── cluster └── images │ ├── crossplane-provider-btp-controller │ └── terraformrc.hcl │ └── crossplane-provider-btp │ ├── Dockerfile │ └── Makefile ├── test └── e2e │ ├── testdata │ └── crs │ │ ├── kyma_env │ │ ├── module.yaml │ │ ├── binding.yaml │ │ ├── kyma.yaml │ │ ├── subaccount.yaml │ │ ├── entitlements.yaml │ │ └── services.yaml │ │ ├── cloudmanagement │ │ ├── env │ │ │ ├── services.yaml │ │ │ ├── entitlements.yaml │ │ │ └── subaccount.yaml │ │ ├── creationDefaultName │ │ │ └── cloudmanagement.yaml │ │ └── creation │ │ │ └── cloudmanagement.yaml │ │ ├── cloudfoundry_env │ │ ├── entitlements.yaml │ │ ├── subaccount.yaml │ │ ├── cf-environment.yaml │ │ └── services.yaml │ │ ├── subscription │ │ ├── create_flow │ │ │ ├── services.yaml │ │ │ ├── subscription.yaml │ │ │ ├── cloudmanagement.yaml │ │ │ ├── subaccount.yaml │ │ │ └── entitlements.yaml │ │ └── import │ │ │ ├── environment │ │ │ ├── services.yaml │ │ │ ├── cloudmanagement.yaml │ │ │ ├── subaccount.yaml │ │ │ └── entitlements.yaml │ │ │ └── resource │ │ │ └── subscription.yaml │ │ ├── GlobalaccountTrustConfiguration │ │ └── trustconfiguration.yaml │ │ ├── servicemanager │ │ ├── create_flow │ │ │ ├── services.yaml │ │ │ └── subaccount.yaml │ │ └── import │ │ │ └── environment │ │ │ └── subaccount.yaml │ │ ├── servicebinding │ │ ├── env │ │ │ ├── servicemanager.yaml │ │ │ ├── serviceinstance.yaml │ │ │ └── subaccount.yaml │ │ ├── no-rotation │ │ │ └── servicebinding.yaml │ │ └── rotation │ │ │ └── servicebinding-rotation.yaml │ │ ├── serviceinstance │ │ ├── servicemanager.yaml │ │ ├── serviceinstance.yaml │ │ └── subaccount.yaml │ │ ├── SubaccountTrustConfiguration │ │ ├── trustconfiguration.yaml │ │ └── subaccount.yaml │ │ ├── entitlement │ │ ├── cf-runtime-memory.yaml │ │ ├── subaccount.yaml │ │ ├── dynatrace.yaml │ │ └── postgresql-development.yaml │ │ ├── entitlement_cf │ │ ├── entitlement.yaml │ │ └── subaccount.yaml │ │ ├── SubaccountApiCredentialsIntegration │ │ ├── subaccountapicredential.yaml │ │ ├── rolecollectionasignment.yaml │ │ ├── subaccount.yaml │ │ └── rolecollection.yaml │ │ ├── SubaccountApiCredentialsStandalone │ │ ├── subaccountapicredential.yaml │ │ └── subaccount.yaml │ │ ├── subaccount │ │ ├── subaccount.yaml │ │ └── directory.yaml │ │ ├── directory │ │ └── directory.yaml │ │ └── DirectoryEntitlement │ │ ├── directoryentitlement.yaml │ │ └── directory.yaml │ ├── mocks.go │ ├── subaccount_service_binding_v1alpha1_test.go │ ├── subaccount_service_instance_v1alpha1_test.go │ ├── generator │ └── resource_test.go.tmpl │ ├── subaccount_service_broker_v1alpha1_test.go │ ├── cloudfoundry_env_test.go │ ├── subaccount_api_credential_integration_test.go │ ├── globalaccount_trust_configuration_v1alpha1_test.go │ ├── kyma_env_test.go │ └── subaccount_trust_configuration_v1alpha1_test.go ├── dev.env ├── examples ├── sample │ ├── subscription.yaml │ ├── subaccount.yaml │ ├── globalaccount_trustconfiguration.yaml │ ├── subaccount_trustconfiguration.yaml │ ├── cf-environment.yaml │ ├── entitlement-basic.yaml │ ├── entitlement-log.yaml │ ├── globalaccount.yaml │ ├── subaccount-log.yaml │ ├── servicebinding.yaml │ ├── kubeconfig-generator.yaml │ ├── certs.tpl.sh │ ├── rolecollection.yaml │ ├── cert-based-oidc.yaml │ ├── rolecollectionassignment.yaml │ ├── directory.yaml │ ├── directory_entitlement.yaml │ ├── entitlements.yaml │ └── services.yaml ├── provider │ └── config.yaml └── storeconfig │ └── vault.yaml ├── .github ├── workflows │ ├── add-to-backlog-project.yml │ ├── reuse-scan.yaml │ ├── check-go-licenses.yaml │ ├── unit_test.yaml │ ├── pr-test.yaml │ ├── reviewable_check_diff.yaml │ └── label-merge-blocker.yaml ├── release.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── btp └── client.go ├── examples-generated ├── security │ └── v1alpha1 │ │ ├── globalaccounttrustconfiguration.yaml │ │ ├── subaccounttrustconfiguration.yaml │ │ └── subaccountapicredential.yaml └── account │ └── v1alpha1 │ ├── directoryentitlement.yaml │ └── subaccountservicebroker.yaml ├── .editorconfig ├── config ├── globalaccount_trust_configuration │ └── config.go ├── directory_entitlement │ └── config.go ├── subaccount_trust_configuration │ └── config.go ├── subaccount_service_binding │ └── config.go ├── subaccount_service_instance │ └── config.go ├── subaccount_service_broker │ └── config.go └── external_name.go ├── renovate.json ├── .goreleaser.yaml ├── package └── crossplane.yaml ├── cmd └── generator │ └── main.go ├── docs └── user │ └── external-name.md └── REUSE.toml /VERSION: -------------------------------------------------------------------------------- 1 | 0.7.5 2 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | dotenv_if_exists 2 | 3 | 4 | -------------------------------------------------------------------------------- /apis/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | -------------------------------------------------------------------------------- /apis/account/v1beta1/doc.go: -------------------------------------------------------------------------------- 1 | package v1beta1 2 | -------------------------------------------------------------------------------- /apis/oidc/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | -------------------------------------------------------------------------------- /apis/account/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | -------------------------------------------------------------------------------- /apis/environment/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | -------------------------------------------------------------------------------- /internal/controller/doc.go: -------------------------------------------------------------------------------- 1 | package controller 2 | -------------------------------------------------------------------------------- /internal/clients/oidc/test_keystores/openssl/keystore.pass.txt: -------------------------------------------------------------------------------- 1 | abc -------------------------------------------------------------------------------- /Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP/crossplane-provider-btp/HEAD/Logo.png -------------------------------------------------------------------------------- /internal/clients/oidc/test_keystores/legacy-openssl/keystore.pass.txt: -------------------------------------------------------------------------------- 1 | k5U.p-P34Fg.4 -------------------------------------------------------------------------------- /internal/openapi_clients/btp-service-manager-api-go/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.3.0 -------------------------------------------------------------------------------- /apis/oidc/oidc.go: -------------------------------------------------------------------------------- 1 | // Package oidc contains group oidc API versions 2 | package oidc 3 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-service-manager-api-go/swagger-patch.json: -------------------------------------------------------------------------------- 1 | [ 2 | 3 | ] 4 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-service-manager-api-go/pkg/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.8.0 2 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-xsuaa-service-api-go/pkg/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.8.0 2 | -------------------------------------------------------------------------------- /internal/version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | var ProviderVersion string = "dev" 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "build"] 2 | path = build 3 | url = https://github.com/upbound/build 4 | -------------------------------------------------------------------------------- /apis/v1alpha1/binding.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | const ( 4 | RawBindingKey = "__raw" 5 | ) 6 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-accounts-service-api-go/pkg/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.14.0 2 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-entitlements-service-api-go/pkg/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.10.0 2 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-provisioning-service-api-go/pkg/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.14.0 2 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-saas-provisioning-api-go/pkg/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.12.0 2 | -------------------------------------------------------------------------------- /apis/account/account.go: -------------------------------------------------------------------------------- 1 | // Package account contains group account API versions 2 | package account 3 | -------------------------------------------------------------------------------- /hack/helpers/apis/GROUP_LOWER/APIVERSION/doc.go.tmpl: -------------------------------------------------------------------------------- 1 | package {{ .Env.APIVERSION | strings.ToLower }} 2 | -------------------------------------------------------------------------------- /apis/environment/environment.go: -------------------------------------------------------------------------------- 1 | // Package environment contains group environment API versions 2 | package environment 3 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-xsuaa-service-api-go/.envrc: -------------------------------------------------------------------------------- 1 | # powered by direnv 2 | [[ -f example_usage/secret.env ]] && dotenv example_usage/secret.env 3 | -------------------------------------------------------------------------------- /internal/clients/oidc/test_keystores/openssl/keystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP/crossplane-provider-btp/HEAD/internal/clients/oidc/test_keystores/openssl/keystore.p12 -------------------------------------------------------------------------------- /hack/helpers/apis/GROUP_LOWER/GROUP_LOWER.go.tmpl: -------------------------------------------------------------------------------- 1 | // Package {{ .Env.GROUP | strings.ToLower }} contains group {{ .Env.GROUP }} API versions 2 | package {{ .Env.GROUP | strings.ToLower }} 3 | -------------------------------------------------------------------------------- /internal/clients/oidc/test_keystores/legacy-openssl/keystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAP/crossplane-provider-btp/HEAD/internal/clients/oidc/test_keystores/legacy-openssl/keystore.p12 -------------------------------------------------------------------------------- /apis/managed_tested.go: -------------------------------------------------------------------------------- 1 | package apis 2 | 3 | import "github.com/crossplane/crossplane-runtime/pkg/resource" 4 | 5 | type ManagedTested interface { 6 | resource.Managed 7 | SetExternalID(newID string) 8 | GetExternalID() string 9 | } 10 | -------------------------------------------------------------------------------- /cluster/images/crossplane-provider-btp-controller/terraformrc.hcl: -------------------------------------------------------------------------------- 1 | provider_installation { 2 | filesystem_mirror { 3 | path = "/terraform/provider-mirror" 4 | include = ["*/*"] 5 | } 6 | direct { 7 | exclude = ["*/*"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /internal/clients/client_factory.go: -------------------------------------------------------------------------------- 1 | package clients 2 | 3 | // ClientFactory creates different kind of clients used by the controllers 4 | // its inherits several interfaces as part of their definitions (see client folders) 5 | type ClientFactory struct { 6 | } 7 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/kyma_env/module.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: environment.btp.sap.crossplane.io/v1alpha1 2 | kind: KymaModule 3 | metadata: 4 | name: cloud-manager-module 5 | spec: 6 | kymaEnvironmentBindingRef: 7 | name: kyma-environment-binding 8 | forProvider: 9 | name: cloud-manager 10 | channel: regular -------------------------------------------------------------------------------- /dev.env: -------------------------------------------------------------------------------- 1 | CLUSTER_NAME=btp-e2e 2 | TEST_REUSE_CLUSTER=0 3 | BUILD_ID=pr-0-0 4 | UUT_IMAGES={"crossplane/provider-btp-account":"build-4ac71306/crossplane/provider-btp-account:v0.4.4-197.g2bcbe0d.dirty","crossplane/provider-btp-account-controller":"build-4ac71306/crossplane/provider-btp-account-controller:v0.4.4-197.g2bcbe0d.dirty"} 5 | -------------------------------------------------------------------------------- /examples/sample/subscription.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subscription 3 | metadata: 4 | namespace: default 5 | name: subscription-example 6 | spec: 7 | forProvider: 8 | appName: sapappstudio 9 | planName: standard-edition 10 | cloudManagementRef: 11 | name: cis-local 12 | -------------------------------------------------------------------------------- /examples/sample/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: test-12345 6 | spec: 7 | forProvider: 8 | displayName: test-12345 9 | region: eu10 10 | subdomain: test-1234q342645asd 11 | subaccountAdmins: 12 | - 13 | -------------------------------------------------------------------------------- /examples/sample/globalaccount_trustconfiguration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: GlobalaccountTrustConfiguration 3 | metadata: 4 | name: meta-trustconfiguration 5 | spec: 6 | forProvider: 7 | name: simple-global-trust 8 | description: "my-descriptions" 9 | identityProvider: "" 10 | 11 | -------------------------------------------------------------------------------- /apis/account/v1alpha1/constants.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | const ( 4 | // SubaccountOperatorLabel Unique identifier of this operator, 5 | //workaround as the label query for cis local does not work with dots (.) 6 | SubaccountOperatorLabel = "orchestrate.cloud.sap/subaccount-operator" 7 | SMLabel = "orchestrate_cloud_sap_subaccount_operator" 8 | ) 9 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudmanagement/env/services.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1beta1 2 | kind: ServiceManager 3 | metadata: 4 | name: e2e-sm-cis 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sm-cis 9 | namespace: default 10 | forProvider: 11 | subaccountRef: 12 | name: cis-sa-test 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudfoundry_env/entitlements.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: cis-local-entitlement 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: cis 9 | servicePlanName: local 10 | enable: true 11 | subaccountRef: 12 | name: cf-test-subaccount 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/create_flow/services.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1beta1 2 | kind: ServiceManager 3 | metadata: 4 | name: e2e-sm-sub 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sm-sub 9 | namespace: default 10 | forProvider: 11 | subaccountRef: 12 | name: sub-sa-test 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudmanagement/env/entitlements.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: cis-sa-test-cis-entitlement 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: cis 9 | servicePlanName: local 10 | enable: true 11 | subaccountRef: 12 | name: cis-sa-test 13 | -------------------------------------------------------------------------------- /examples/sample/subaccount_trustconfiguration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: SubaccountTrustConfiguration 3 | metadata: 4 | name: meta-trustconfiguration 5 | spec: 6 | forProvider: 7 | name: simple-trust 8 | description: "my-descriptions" 9 | subaccountRef: 10 | name: stephan-trust-test 11 | identityProvider: "" 12 | 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/GlobalaccountTrustConfiguration/trustconfiguration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: GlobalaccountTrustConfiguration 3 | metadata: 4 | name: e2e-global-trustconfiguration 5 | spec: 6 | forProvider: 7 | name: $BUILD_ID-e2e-global-trust 8 | description: "e2e-testing-of-global-trust" 9 | identityProvider: "$IDP_URL" 10 | 11 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicemanager/create_flow/services.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceManager 3 | metadata: 4 | name: e2e-sm-servicemanager 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sm-servicemanager 9 | namespace: default 10 | forProvider: 11 | subaccountRef: 12 | name: sm-sa-test 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/import/environment/services.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1beta1 2 | kind: ServiceManager 3 | metadata: 4 | name: e2e-sm-sub-import 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sm-sub-import 9 | namespace: default 10 | forProvider: 11 | subaccountRef: 12 | name: sub-import-sa-test 13 | -------------------------------------------------------------------------------- /.github/workflows/add-to-backlog-project.yml: -------------------------------------------------------------------------------- 1 | name: Add Refined Issues to Backlog 2 | 3 | on: 4 | schedule: 5 | - cron: "0 7 * * *" # Runs at 07:00 UTC every day 6 | workflow_dispatch: # Allows manual trigger 7 | 8 | env: 9 | ACTIONS_STEP_DEBUG: true 10 | 11 | jobs: 12 | call-reusable-workflow: 13 | uses: openmcp-project/.github/workflows/addRefinedIssuesToBacklog.yml@main 14 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicebinding/env/servicemanager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceManager 3 | metadata: 4 | name: e2e-sm-servicebinding 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sm-servicebinding 9 | namespace: default 10 | forProvider: 11 | subaccountRef: 12 | name: e2e-test-servicebinding 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/serviceinstance/servicemanager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceManager 3 | metadata: 4 | name: e2e-sm-serviceinstance 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sm-serviceinstance 9 | namespace: default 10 | forProvider: 11 | subaccountRef: 12 | name: e2e-test-serviceinstance 13 | -------------------------------------------------------------------------------- /examples/sample/cf-environment.yaml: -------------------------------------------------------------------------------- 1 | #apiVersion: environment.btp.sap.crossplane.io/v1alpha1 2 | #kind: CloudFoundryEnvironment 3 | #metadata: 4 | # name: fc-env 5 | # namespace: default 6 | #spec: 7 | # forProvider: 8 | # cloudManagementRef: 9 | # name: cis-local 10 | # initialOrgManagers: 11 | # - 12 | # landscape: cf-eu10 13 | # SubaccountRef: 14 | # name: test-123455 15 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/create_flow/subscription.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subscription 3 | metadata: 4 | namespace: default 5 | name: sub-test 6 | spec: 7 | forProvider: 8 | appName: auditlog-viewer 9 | planName: free 10 | parameters: 11 | key1: value1 12 | key2: value2 13 | cloudManagementRef: 14 | name: e2e-sub-cis-local 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.cache 2 | /.work 3 | /_output 4 | cover.out 5 | /vendor 6 | /.vendor-new 7 | .vscode 8 | .idea 9 | .DS_Store 10 | /examples/provider/secret.yaml 11 | __debug_bin 12 | .env 13 | *.p12 14 | !internal/clients/oidc/test_keystores/**/*.p12 15 | /examples/sample/certs.sh 16 | crossplane-provider-btp-account.iml 17 | /test/e2e/testdata/secrets 18 | kubeconfig 19 | dist/ 20 | *.local.yaml 21 | *.log 22 | 23 | *~ 24 | -------------------------------------------------------------------------------- /examples/sample/entitlement-basic.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: postgres-svc 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: postgresql-db 9 | servicePlanName: development 10 | #enable: true 11 | amount: 100 12 | subaccountRef: 13 | name: test-12345 14 | providerConfigRef: 15 | name: default 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountTrustConfiguration/trustconfiguration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: SubaccountTrustConfiguration 3 | metadata: 4 | name: e2e-trustconfiguration 5 | spec: 6 | forProvider: 7 | name: $BUILD_ID-e2e-simple-trust 8 | description: "my-descriptions" 9 | subaccountRef: 10 | name: sub-trust-test 11 | identityProvider: "$IDP_URL" 12 | 13 | -------------------------------------------------------------------------------- /btp/client.go: -------------------------------------------------------------------------------- 1 | package btp 2 | 3 | import "github.com/pkg/errors" 4 | 5 | func NewBTPClient(cisSecretData []byte, serviceAccountSecretData []byte) (*Client, error) { 6 | 7 | accountsServiceClient, err := ServiceClientFromSecret(cisSecretData, serviceAccountSecretData) 8 | if err != nil { 9 | return nil, errors.Wrap(err, "failed to get BTP accounts service client.") 10 | } 11 | return &accountsServiceClient, nil 12 | } 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/entitlement/cf-runtime-memory.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: cf-runtime-memory 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: APPLICATION_RUNTIME 9 | servicePlanName: MEMORY 10 | amount: 1 11 | subaccountRef: 12 | name: entitlement-sa-test 13 | providerConfigRef: 14 | name: default 15 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/entitlement_cf/entitlement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: cf-runtime-quota 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: APPLICATION_RUNTIME 9 | servicePlanName: MEMORY 10 | amount: 1 11 | subaccountRef: 12 | name: entitlement-cf-sa-test 13 | providerConfigRef: 14 | name: default 15 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountApiCredentialsIntegration/subaccountapicredential.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: SubaccountApiCredential 3 | metadata: 4 | name: sac-subaccountapicredentials 5 | spec: 6 | forProvider: 7 | readOnly: false 8 | subaccountRef: 9 | name: sac-subaccount 10 | writeConnectionSecretToRef: 11 | name: xsuaa-creds-subaccountapicredentials 12 | namespace: default -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountApiCredentialsStandalone/subaccountapicredential.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: SubaccountApiCredential 3 | metadata: 4 | name: sac-subaccountapicredentials 5 | spec: 6 | forProvider: 7 | readOnly: false 8 | subaccountRef: 9 | name: sac-subaccount 10 | writeConnectionSecretToRef: 11 | name: xsuaa-creds-subaccountapicredentials 12 | namespace: default -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/import/resource/subscription.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subscription 3 | metadata: 4 | namespace: default 5 | name: sub-import-test 6 | annotations: 7 | crossplane.io/external-name: auditlog-viewer/free 8 | spec: 9 | forProvider: 10 | appName: auditlog-viewer 11 | planName: free 12 | cloudManagementRef: 13 | name: e2e-sub-import-cis-local 14 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - release-notes/ignore 5 | categories: 6 | - title: New Features 🚀 7 | labels: 8 | - release-notes/new-feature 9 | - title: Bug Fixes 🐞 10 | labels: 11 | - release-notes/bugfix 12 | - title: Dependencies 🔗 13 | labels: 14 | - release-notes/dependencies 15 | - title: Other Changes 16 | labels: 17 | - "*" -------------------------------------------------------------------------------- /examples/sample/entitlement-log.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: audit-log-viewer-entl 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: auditlog-viewer 9 | servicePlanName: default 10 | #enable: true 11 | amount: 1 12 | subaccountRef: 13 | name: entitlement-sa-test 14 | providerConfigRef: 15 | name: account-provider-config 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudmanagement/creationDefaultName/cloudmanagement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1beta1 2 | kind: CloudManagement 3 | metadata: 4 | name: e2e-cis-created 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-cis-created 9 | namespace: default 10 | forProvider: 11 | serviceManagerRef: 12 | name: e2e-sm-cis 13 | subaccountRef: 14 | name: cis-sa-test -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/create_flow/cloudmanagement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: CloudManagement 3 | metadata: 4 | name: e2e-sub-cis-local 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sub-cis-local 9 | namespace: default 10 | forProvider: 11 | serviceManagerRef: 12 | name: e2e-sm-sub 13 | subaccountRef: 14 | name: sub-sa-test 15 | -------------------------------------------------------------------------------- /examples-generated/security/v1alpha1/globalaccounttrustconfiguration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: GlobalaccountTrustConfiguration 3 | metadata: 4 | annotations: 5 | meta.upbound.io/example-id: security/v1alpha1/globalaccounttrustconfiguration 6 | labels: 7 | testing.upbound.io/example-name: simple 8 | name: simple 9 | spec: 10 | forProvider: 11 | identityProvider: terraformint.accounts400.ondemand.com 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | indent_style = space 8 | indent_size = 2 9 | 10 | [{Makefile,go.mod,go.sum,*.go,.gitmodules}] 11 | indent_style = tab 12 | indent_size = 4 13 | 14 | [*.md] 15 | indent_size = 4 16 | trim_trailing_whitespace = false 17 | 18 | [Dockerfile] 19 | indent_size = 4 20 | 21 | [internal/clients/oidc/test_keystores/**] 22 | insert_final_newline = false -------------------------------------------------------------------------------- /examples/sample/globalaccount.yaml: -------------------------------------------------------------------------------- 1 | # DEPRECATED: GlobalAccount is deprecated and will be removed in a future release. Use globalaccount reference in providerconfig to specify your GlobalAccount instead. 2 | 3 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 4 | kind: GlobalAccount 5 | metadata: 6 | annotations: 7 | crossplane.io/external-name: SAP Cloud Orchestration Canary 8 | name: co-ga-canary 9 | spec: 10 | providerConfigRef: 11 | name: default 12 | -------------------------------------------------------------------------------- /examples/sample/subaccount-log.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: entitlement-sa-test 6 | spec: 7 | providerConfigRef: 8 | name: account-provider-config 9 | forProvider: 10 | displayName: e2e-test-sa-entx 11 | region: eu10 12 | subdomain: e2e-test-sa-entx 13 | labels: 14 | safe-to-delete: [ "yes" ] 15 | subaccountAdmins: 16 | - 17 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/import/environment/cloudmanagement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1beta1 2 | kind: CloudManagement 3 | metadata: 4 | name: e2e-sub-import-cis-local 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-sub-import-cis-local 9 | namespace: default 10 | forProvider: 11 | serviceManagerRef: 12 | name: e2e-sm-sub-import 13 | subaccountRef: 14 | name: sub-import-sa-test 15 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountApiCredentialsIntegration/rolecollectionasignment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: RoleCollectionAssignment 3 | metadata: 4 | namespace: default 5 | name: sac-rolecollectionasignment 6 | spec: 7 | forProvider: 8 | origin: "sap.default" 9 | roleCollectionName: "Subaccount Administrator" 10 | groupName: some-usergroup 11 | subaccountApiCredentialRef: 12 | name: sac-subaccountapicredentials 13 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/kyma_env/binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: environment.btp.sap.crossplane.io/v1alpha1 2 | kind: KymaEnvironmentBinding 3 | metadata: 4 | name: kyma-environment-binding 5 | namespace: default 6 | spec: 7 | kymaEnvironmentRef: 8 | name: kyma-environment 9 | writeConnectionSecretToRef: 10 | name: kyma-binding 11 | namespace: default 12 | cloudManagementRef: 13 | name: kyma-cis-local 14 | forProvider: 15 | rotationInterval: 3m 16 | ttl: 10m 17 | -------------------------------------------------------------------------------- /config/globalaccount_trust_configuration/config.go: -------------------------------------------------------------------------------- 1 | package subaccount_trust_configuration 2 | 3 | import ( 4 | "github.com/crossplane/upjet/pkg/config" 5 | ) 6 | 7 | // Configure configures individual resources by adding custom ResourceConfigurators. 8 | func Configure(p *config.Provider) { 9 | p.AddResourceConfigurator("btp_globalaccount_trust_configuration", func(r *config.Resource) { 10 | r.ShortGroup = "security" 11 | r.Kind = "GlobalaccountTrustConfiguration" 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-accounts-service-api-go/pkg/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | git_push.sh 8 | .travis.yml 9 | .gitignore 10 | docs/ 11 | test/ 12 | go.mod 13 | go.sum 14 | VERSION 15 | sonar-project.properties 16 | README.md 17 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-service-manager-api-go/pkg/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | git_push.sh 8 | .travis.yml 9 | .gitignore 10 | docs/ 11 | test/ 12 | go.mod 13 | go.sum 14 | VERSION 15 | sonar-project.properties 16 | README.md 17 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-xsuaa-service-api-go/pkg/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | git_push.sh 8 | .travis.yml 9 | .gitignore 10 | docs/ 11 | test/ 12 | go.mod 13 | go.sum 14 | VERSION 15 | sonar-project.properties 16 | README.md 17 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudmanagement/env/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: cis-sa-test 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sa-cis 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sa-cis-sub 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/entitlement/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: entitlement-sa-test 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sa-ent 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sa-ent-sub 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-entitlements-service-api-go/pkg/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | git_push.sh 8 | .travis.yml 9 | .gitignore 10 | docs/ 11 | test/ 12 | go.mod 13 | go.sum 14 | VERSION 15 | sonar-project.properties 16 | README.md 17 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-provisioning-service-api-go/pkg/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | git_push.sh 8 | .travis.yml 9 | .gitignore 10 | docs/ 11 | test/ 12 | go.mod 13 | go.sum 14 | VERSION 15 | sonar-project.properties 16 | README.md 17 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-saas-provisioning-api-go/pkg/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # Swagger Codegen Ignore 2 | # Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | git_push.sh 8 | .travis.yml 9 | .gitignore 10 | docs/ 11 | test/ 12 | go.mod 13 | go.sum 14 | VERSION 15 | sonar-project.properties 16 | README.md 17 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subaccount/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: e2e-test-sa 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sa 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sa-co-12111 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/kyma_env/kyma.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: environment.btp.sap.crossplane.io/v1alpha1 2 | kind: KymaEnvironment 3 | metadata: 4 | name: kyma-environment 5 | namespace: default 6 | spec: 7 | forProvider: 8 | name: my-kyma-instance 9 | planName: azure 10 | parameters: 11 | region: westeurope 12 | administrators: 13 | - $TECHNICAL_USER_EMAIL 14 | subaccountRef: 15 | name: kyma-test-subaccount 16 | cloudManagementRef: 17 | name: kyma-cis-local 18 | -------------------------------------------------------------------------------- /examples/provider/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: btp.sap.crossplane.io/v1alpha1 2 | kind: ProviderConfig 3 | metadata: 4 | name: default 5 | spec: 6 | serviceAccountSecret: 7 | source: Secret 8 | secretRef: 9 | namespace: default 10 | name: sa-provider-secret 11 | key: credentials 12 | cisCredentials: 13 | source: Secret 14 | secretRef: 15 | namespace: default 16 | name: cis-provider-secret 17 | key: data 18 | # cliServerUrl: ... 19 | # globalAccount: ... 20 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountTrustConfiguration/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: sub-trust-test 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sub-trust 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sub-trust-sub 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /examples/storeconfig/vault.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: template.crossplane.io/v1alpha1 2 | kind: StoreConfig 3 | metadata: 4 | name: vault 5 | spec: 6 | type: Vault 7 | defaultScope: crossplane-system 8 | vault: 9 | server: http://vault.vault-system:8200 10 | mountPath: secret/ 11 | version: v2 12 | auth: 13 | method: Token 14 | token: 15 | source: Secret 16 | secretRef: 17 | namespace: crossplane-system 18 | name: vault-token 19 | key: token 20 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/kyma_env/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: kyma-test-subaccount 6 | spec: 7 | forProvider: 8 | displayName: "$BUILD_ID-Created while test: Kyma Environment setup" 9 | labels: 10 | safe-to-delete: ["yes"] 11 | BUILD_ID: ["$BUILD_ID"] 12 | region: eu20 13 | subdomain: $BUILD_ID-co-e2e-test-kyma-case 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicebinding/no-rotation/servicebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceBinding 3 | metadata: 4 | name: e2e-destination-binding 5 | namespace: default 6 | spec: 7 | forProvider: 8 | name: e2e-destination-binding 9 | serviceInstanceRef: 10 | name: e2e-destination-instance 11 | subaccountRef: 12 | name: e2e-test-servicebinding 13 | writeConnectionSecretToRef: 14 | name: e2e-destination-binding 15 | namespace: default -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/create_flow/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: sub-sa-test 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sa-subscription 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sa-subscription-sub 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudfoundry_env/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: cf-test-subaccount 6 | spec: 7 | forProvider: 8 | displayName: "$BUILD_ID-Created while test: CF Environment setup" 9 | labels: 10 | safe-to-delete: ["yes"] 11 | BUILD_ID: [ "$BUILD_ID" ] 12 | region: eu10 13 | subdomain: $BUILD_ID-co-e2e-test-cf-case-3 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicemanager/create_flow/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: sm-sa-test 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sa-servicemanager 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sa-servicemanager-sub 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudmanagement/creation/cloudmanagement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1beta1 2 | kind: CloudManagement 3 | metadata: 4 | name: e2e-cis-created 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: e2e-cis-created 9 | namespace: default 10 | forProvider: 11 | serviceManagerRef: 12 | name: e2e-sm-cis 13 | subaccountRef: 14 | name: cis-sa-test 15 | serviceInstanceName: "e2e-si-created" 16 | serviceBindingName: "e2e-sb-created" -------------------------------------------------------------------------------- /test/e2e/testdata/crs/serviceinstance/serviceinstance.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceInstance 3 | metadata: 4 | name: e2e-destination-instance 5 | namespace: default 6 | spec: 7 | forProvider: 8 | name: e2e-destination-instance 9 | parameters: 10 | HTML5Runtime_enabled: false 11 | serviceManagerRef: 12 | name: e2e-sm-serviceinstance 13 | offeringName: destination 14 | planName: lite 15 | subaccountRef: 16 | name: e2e-test-serviceinstance -------------------------------------------------------------------------------- /apis/account/v1alpha1/zz_tested.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | func (md *Directory) SetExternalID(newID string) { 4 | md.Spec.ForProvider.DisplayName = &newID 5 | } 6 | 7 | func (md *Directory) GetExternalID() string { 8 | return *md.Spec.ForProvider.DisplayName 9 | } 10 | 11 | func (ms *Subaccount) SetExternalID(newID string) { 12 | ms.Spec.ForProvider.DisplayName = newID 13 | ms.Spec.ForProvider.Subdomain = newID 14 | } 15 | func (ms *Subaccount) GetExternalID() string { 16 | return ms.Spec.ForProvider.DisplayName 17 | } 18 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicebinding/env/serviceinstance.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceInstance 3 | metadata: 4 | name: e2e-destination-instance 5 | namespace: default 6 | spec: 7 | forProvider: 8 | name: e2e-destination-instance-for-binding 9 | parameters: 10 | HTML5Runtime_enabled: false 11 | serviceManagerRef: 12 | name: e2e-sm-servicebinding 13 | offeringName: destination 14 | planName: lite 15 | subaccountRef: 16 | name: e2e-test-servicebinding -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicebinding/env/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: e2e-test-servicebinding 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-servicebinding 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-servicebinding-co-12111 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/serviceinstance/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: e2e-test-serviceinstance 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-serviceinstance 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-serviceinstance-co-12111 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicemanager/import/environment/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: sm-import-sa-test 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sa-servicemanager-import 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sa-servicemanager-import-sub 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/import/environment/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: sub-import-sa-test 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-e2e-test-sa-import-subscription 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-sa-import-subscription-sub 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | -------------------------------------------------------------------------------- /.github/workflows/reuse-scan.yaml: -------------------------------------------------------------------------------- 1 | # This workflow is triggered by the user and runs the REUSE compliance check (reuse lint) on the repository. 2 | 3 | name: REUSE Compliance Check 4 | permissions: 5 | contents: read 6 | 7 | on: 8 | workflow_call: 9 | 10 | 11 | jobs: 12 | lint-reuse: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 16 | - name: REUSE Compliance Check 17 | uses: fsfe/reuse-action@3ae3c6bdf1257ab19397fab11fd3312144692083 # v4.0.0 -------------------------------------------------------------------------------- /examples-generated/security/v1alpha1/subaccounttrustconfiguration.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: SubaccountTrustConfiguration 3 | metadata: 4 | annotations: 5 | meta.upbound.io/example-id: security/v1alpha1/subaccounttrustconfiguration 6 | labels: 7 | testing.upbound.io/example-name: simple 8 | name: simple 9 | spec: 10 | forProvider: 11 | identityProvider: terraformint.accounts400.ondemand.com 12 | subaccountSelector: 13 | matchLabels: 14 | testing.upbound.io/example-name: example 15 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountApiCredentialsIntegration/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: sac-subaccount 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-subaccount-subaccountapicredentials 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-subaccount-subaccountapicredentials 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | 17 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountApiCredentialsStandalone/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: sac-subaccount 6 | spec: 7 | forProvider: 8 | displayName: $BUILD_ID-subaccount-subaccountapicredentials 9 | region: eu10 10 | subdomain: $BUILD_ID-e2e-test-subaccount-subaccountapicredentials 11 | labels: 12 | safe-to-delete: [ "yes" ] 13 | BUILD_ID: [ "$BUILD_ID" ] 14 | subaccountAdmins: 15 | - $TECHNICAL_USER_EMAIL 16 | 17 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/entitlement_cf/subaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Subaccount 3 | metadata: 4 | namespace: default 5 | name: entitlement-cf-sa-test 6 | spec: 7 | forProvider: 8 | globalAccountRef: 9 | name: my-global-account 10 | displayName: $BUILD_ID-e2e-test-sa-ent-cf 11 | region: eu10 12 | subdomain: $BUILD_ID-e2e-test-sa-ent-cf 13 | labels: 14 | safe-to-delete: [ "yes" ] 15 | BUILD_ID: [ "$BUILD_ID" ] 16 | subaccountAdmins: 17 | - $TECHNICAL_USER_EMAIL 18 | -------------------------------------------------------------------------------- /examples-generated/security/v1alpha1/subaccountapicredential.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: SubaccountApiCredential 3 | metadata: 4 | annotations: 5 | meta.upbound.io/example-id: security/v1alpha1/subaccountapicredential 6 | labels: 7 | testing.upbound.io/example-name: with-secret 8 | name: with-secret 9 | spec: 10 | forProvider: 11 | name: subaccount-api-credential-with-secret 12 | readOnly: false 13 | subaccountSelector: 14 | matchLabels: 15 | testing.upbound.io/example-name: example 16 | -------------------------------------------------------------------------------- /examples-generated/account/v1alpha1/directoryentitlement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: DirectoryEntitlement 3 | metadata: 4 | annotations: 5 | meta.upbound.io/example-id: account/v1alpha1/directoryentitlement 6 | labels: 7 | testing.upbound.io/example-name: alert_notification_service 8 | name: alert-notification-service 9 | spec: 10 | forProvider: 11 | directorySelector: 12 | matchLabels: 13 | testing.upbound.io/example-name: example 14 | planName: free 15 | serviceName: alert-notification 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudfoundry_env/cf-environment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: environment.btp.sap.crossplane.io/v1alpha1 2 | kind: CloudFoundryEnvironment 3 | metadata: 4 | name: cloudfoundry-environment 5 | namespace: default 6 | spec: 7 | writeConnectionSecretToRef: 8 | name: cf-env 9 | namespace: default 10 | forProvider: 11 | landscape: cf-eu10 12 | orgName: "$BUILD_ID-cfenv-e2e-test-org" 13 | environmentName: "$BUILD_ID-cfenv-e2e-test-org-env" 14 | subaccountRef: 15 | name: cf-test-subaccount 16 | cloudManagementRef: 17 | name: cis-local 18 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/directory/directory.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Directory 3 | metadata: 4 | name: e2e-test-directory 5 | spec: 6 | forProvider: 7 | description: "$BUILD_ID- created by e2e tests" 8 | directoryAdmins: 9 | - "$SECOND_DIRECTORY_ADMIN_EMAIL" 10 | - "$TECHNICAL_USER_EMAIL" 11 | directoryFeatures: 12 | - "DEFAULT" 13 | displayName: $BUILD_ID-e2e-test-directory 14 | labels: 15 | custom_label: ["custom_value"] 16 | another_label: ["onevalue", "twovalue"] 17 | BUILD_ID: [ "$BUILD_ID" ] 18 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subaccount/directory.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Directory 3 | metadata: 4 | name: e2e-test-directory-sa 5 | spec: 6 | forProvider: 7 | description: "$BUILD_ID-created by e2e tests" 8 | directoryAdmins: 9 | - "$SECOND_DIRECTORY_ADMIN_EMAIL" 10 | - "$TECHNICAL_USER_EMAIL" 11 | directoryFeatures: 12 | - "DEFAULT" 13 | displayName: $BUILD_ID-e2e-test-directory-sa 14 | labels: 15 | custom_label: ["custom_value"] 16 | another_label: ["onevalue", "twovalue"] 17 | BUILD_ID: [ "$BUILD_ID" ] 18 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/servicebinding/rotation/servicebinding-rotation.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceBinding 3 | metadata: 4 | name: e2e-destination-binding-rotation 5 | namespace: default 6 | spec: 7 | forProvider: 8 | name: e2e-destination-binding-rotation 9 | serviceInstanceRef: 10 | name: e2e-destination-instance 11 | subaccountRef: 12 | name: e2e-test-servicebinding 13 | rotation: 14 | frequency: 2m 15 | ttl: 5m 16 | writeConnectionSecretToRef: 17 | name: e2e-destination-binding-rotation 18 | namespace: default 19 | -------------------------------------------------------------------------------- /examples/sample/servicebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: ServiceBinding 3 | metadata: 4 | name: destination-binding 5 | spec: 6 | forProvider: 7 | name: destination-binding 8 | # parameters: ... same options for setting parameters via json, yaml or secrets as for instances 9 | serviceInstanceRef: 10 | name: destination-instance 11 | subaccountRef: 12 | name: sa-serviceinstance 13 | # Optional: Enable rotation 14 | # rotation: 15 | # ttl: 1440h 16 | # frequency: 720h 17 | writeConnectionSecretToRef: 18 | name: destination-binding 19 | namespace: default 20 | -------------------------------------------------------------------------------- /examples/sample/kubeconfig-generator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: oidc.btp.sap.crossplane.io/v1alpha1 2 | kind: KubeConfigGenerator 3 | metadata: 4 | name: example-kubeconfig 5 | spec: 6 | forProvider: 7 | kubeconfigTemplate: 8 | source: Secret 9 | secretRef: 10 | namespace: crossplane-system 11 | name: kyma-connection-secret 12 | key: kubeconfig 13 | oidcToken: 14 | source: Secret 15 | secretRef: 16 | namespace: crossplane-system 17 | name: oidc-token 18 | key: IDToken 19 | writeConnectionSecretToRef: 20 | name: kubeconfig-published 21 | namespace: crossplane-system 22 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/kyma_env/entitlements.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: kyma-azure 5 | spec: 6 | forProvider: 7 | serviceName: kymaruntime 8 | servicePlanName: azure 9 | amount: 1 10 | subaccountRef: 11 | name: kyma-test-subaccount 12 | --- 13 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 14 | kind: Entitlement 15 | metadata: 16 | name: cis-local-entitlement 17 | namespace: default 18 | spec: 19 | forProvider: 20 | serviceName: cis 21 | servicePlanName: local 22 | enable: true 23 | subaccountRef: 24 | name: kyma-test-subaccount 25 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/DirectoryEntitlement/directoryentitlement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: DirectoryEntitlement 3 | metadata: 4 | name: e2e-directory-ent-cis-local 5 | spec: 6 | forProvider: 7 | directoryRef: 8 | name: e2e-directory-for-entitlement-testing 9 | planName: local 10 | serviceName: cis 11 | --- 12 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 13 | kind: DirectoryEntitlement 14 | metadata: 15 | name: e2e-audit-log-viewer-ent 16 | spec: 17 | forProvider: 18 | serviceName: postgresql-db 19 | planName: development 20 | amount: 1 21 | directoryRef: 22 | name: e2e-directory-for-entitlement-testing 23 | -------------------------------------------------------------------------------- /examples/sample/certs.tpl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SOURCE=${BASH_SOURCE[0]} 4 | while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink 5 | DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd ) 6 | SOURCE=$(readlink "$SOURCE") 7 | [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located 8 | done 9 | DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd ) 10 | 11 | 12 | kubectl create secret generic example-login-cert-secret --namespace=crossplane-system --from-file=cert="$DIR/cert_tech_user.p12" --from-literal=password=$KEYSTORE_PASSWORD 13 | 14 | -------------------------------------------------------------------------------- /internal/clients/kymaenvironmentbinding/client.go: -------------------------------------------------------------------------------- 1 | package kymaenvironmentbinding 2 | 3 | import ( 4 | "context" 5 | 6 | provisioningclient "github.com/sap/crossplane-provider-btp/internal/openapi_clients/btp-provisioning-service-api-go/pkg" 7 | 8 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 9 | ) 10 | 11 | type Client interface { 12 | DescribeInstance(ctx context.Context, kymaInstanceId string) ( 13 | []provisioningclient.EnvironmentInstanceBindingMetadata, 14 | error, 15 | ) 16 | CreateInstance(ctx context.Context, kymaInstanceId string, ttl int) (*Binding, error) 17 | DeleteInstances(ctx context.Context, bindings []v1alpha1.Binding, kymaInstanceId string) error 18 | } 19 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/DirectoryEntitlement/directory.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Directory 3 | metadata: 4 | namespace: default 5 | name: e2e-directory-for-entitlement-testing 6 | spec: 7 | forProvider: 8 | description: "$BUILD_ID- created by code" 9 | directoryAdmins: 10 | - "$SECOND_DIRECTORY_ADMIN_EMAIL" 11 | - "$TECHNICAL_USER_EMAIL" 12 | directoryFeatures: 13 | - "DEFAULT" 14 | - "ENTITLEMENTS" 15 | - "AUTHORIZATIONS" 16 | displayName: $BUILD_ID-e2e-directory-for-entitlement-testing 17 | labels: 18 | custom_label: ["custom_value"] 19 | another_label: ["onevalue", "twovalue"] 20 | BUILD_ID: [ "$BUILD_ID" ] 21 | -------------------------------------------------------------------------------- /internal/di/creatorfns.go: -------------------------------------------------------------------------------- 1 | package di 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/sap/crossplane-provider-btp/btp" 7 | "github.com/sap/crossplane-provider-btp/internal/clients/servicemanager" 8 | ) 9 | 10 | // This file contains creator functions for initializers and clients to decouple that logic from controllers and share it across them 11 | 12 | func NewPlanIdResolverFn(ctx context.Context, secretData map[string][]byte) (servicemanager.PlanIdResolver, error) { 13 | binding, err := servicemanager.NewCredsFromOperatorSecret(secretData) 14 | if err != nil { 15 | return nil, err 16 | } 17 | return servicemanager.NewServiceManagerClient(btp.NewBackgroundContextWithDebugPrintHTTPClient(), &binding) 18 | } 19 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/create_flow/entitlements.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: sub-test-cis-entitlement 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: cis 9 | servicePlanName: local 10 | enable: true 11 | subaccountRef: 12 | name: sub-sa-test 13 | --- 14 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 15 | kind: Entitlement 16 | metadata: 17 | name: sub-test-auditlog-viewer-entitlement 18 | namespace: default 19 | spec: 20 | forProvider: 21 | serviceName: auditlog-viewer 22 | servicePlanName: free 23 | enable: true 24 | subaccountRef: 25 | name: sub-sa-test 26 | 27 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "postUpdateOptions": [ 7 | "gomodTidy" 8 | ], 9 | "labels": ["release-notes/dependencies"], 10 | "customManagers": [ 11 | { 12 | "fileMatch": [ 13 | "(^|/)Makefile$", 14 | "(^|/)Dockerfile$", 15 | "(^|/)config.yml$" 16 | ], 17 | "matchStrings": [ 18 | "(export|ARG|--build-arg=) *TERRAFORM_PROVIDER_VERSION *[:|\\?]?= *(?\\d+\\.\\d+\\.\\d+)" 19 | ], 20 | "datasourceTemplate": "terraform-provider", 21 | "versioningTemplate": "hashicorp", 22 | "depNameTemplate": "SAP/btp" 23 | } 24 | ] 25 | } -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # Visit https://goreleaser.com for documentation on how to customize this 2 | # behavior. 3 | version: 2 4 | 5 | builds: 6 | - id: binary-build 7 | env: 8 | - CGO_ENABLED=0 9 | mod_timestamp: "{{ .CommitTimestamp }}" 10 | main: ./cmd/provider 11 | flags: 12 | - -trimpath 13 | goos: 14 | - linux 15 | - darwin 16 | goarch: 17 | - amd64 18 | - arm64 19 | ignore: 20 | - goos: darwin 21 | goarch: "386" 22 | binary: "{{ .ProjectName }}_v{{ .Version }}" 23 | archives: 24 | - format: zip 25 | builds: 26 | - binary-build 27 | name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}" 28 | changelog: 29 | use: github-native -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a bug to help us improve 4 | title: "[BUG] " 5 | type: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Tested with Provider Version** 14 | v1.x.x 15 | 16 | **To Reproduce** 17 | Steps to reproduce the behavior: 18 | 1. Go to '...' 19 | 2. Click on '....' 20 | 3. Scroll down to '....' 21 | 4. See error 22 | 23 | **Expected behavior** 24 | A clear and concise description of what you expected to happen. 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/subscription/import/environment/entitlements.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Entitlement 3 | metadata: 4 | name: sub-import-test-cis-entitlement 5 | namespace: default 6 | spec: 7 | forProvider: 8 | serviceName: cis 9 | servicePlanName: local 10 | enable: true 11 | subaccountRef: 12 | name: sub-import-sa-test 13 | --- 14 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 15 | kind: Entitlement 16 | metadata: 17 | name: sub-import-test-auditlog-viewer-entitlement 18 | namespace: default 19 | spec: 20 | forProvider: 21 | serviceName: auditlog-viewer 22 | servicePlanName: free 23 | enable: true 24 | subaccountRef: 25 | name: sub-import-sa-test 26 | 27 | -------------------------------------------------------------------------------- /examples-generated/account/v1alpha1/subaccountservicebroker.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: SubaccountServiceBroker 3 | metadata: 4 | annotations: 5 | meta.upbound.io/example-id: account/v1alpha1/subaccountservicebroker 6 | labels: 7 | testing.upbound.io/example-name: my_broker 8 | name: my-broker 9 | spec: 10 | forProvider: 11 | description: Service broker for provisioning example services. 12 | name: my-broker 13 | passwordSecretRef: 14 | key: example-key 15 | name: example-secret 16 | namespace: upbound-system 17 | subaccountSelector: 18 | matchLabels: 19 | testing.upbound.io/example-name: example 20 | url: https://my.broker.com 21 | username: platform_user 22 | -------------------------------------------------------------------------------- /internal/features/features.go: -------------------------------------------------------------------------------- 1 | package features 2 | 3 | import "github.com/crossplane/crossplane-runtime/pkg/feature" 4 | 5 | // Feature flags. 6 | const ( 7 | // EnableAlphaExternalSecretStores enables alpha support for 8 | // External Secret Stores. See the below design for more details. 9 | // https://github.com/crossplane/crossplane/blob/390ddd/design/design-doc-external-secret-stores.md 10 | EnableAlphaExternalSecretStores feature.Flag = "EnableAlphaExternalSecretStores" 11 | 12 | // EnableBetaManagementPolicies enables alpha support for 13 | // Management Policies. See the below design for more details. 14 | // https://github.com/crossplane/crossplane/pull/3531 15 | EnableBetaManagementPolicies feature.Flag = "EnableAlphaManagementPolicies" 16 | ) 17 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/cloudfoundry_env/services.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: account.btp.sap.crossplane.io/v1beta1 3 | kind: ServiceManager 4 | metadata: 5 | name: service-manager 6 | namespace: default 7 | spec: 8 | writeConnectionSecretToRef: 9 | name: service-manager 10 | namespace: default 11 | forProvider: 12 | subaccountRef: 13 | name: cf-test-subaccount 14 | --- 15 | apiVersion: account.btp.sap.crossplane.io/v1beta1 16 | kind: CloudManagement 17 | metadata: 18 | name: cis-local 19 | namespace: default 20 | spec: 21 | writeConnectionSecretToRef: 22 | name: cis-local 23 | namespace: default 24 | forProvider: 25 | serviceManagerRef: 26 | name: service-manager 27 | subaccountRef: 28 | name: cf-test-subaccount 29 | -------------------------------------------------------------------------------- /package/crossplane.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: meta.pkg.crossplane.io/v1alpha1 2 | kind: Provider 3 | metadata: 4 | name: provider-btp 5 | annotations: 6 | meta.crossplane.io/maintainer: SAP Cloud Orchestrator Crossplane Maintainers 7 | meta.crossplane.io/source: github.com/sap/crossplane-provider-btp 8 | meta.crossplane.io/license: Apache-2.0 9 | meta.orchestrate.cloud.sap/release-status: early-access 10 | friendly-name.meta.crossplane.io: Provider BTP 11 | meta.crossplane.io/description: | 12 | A Crossplane Provider for SAP BTP. Supports with management of Subaccounts, Environments, Entitlements and Services. 13 | 14 | spec: 15 | controller: 16 | image: DOCKER_REGISTRY/crossplane/provider-btp-controller:VERSION 17 | 18 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/SubaccountApiCredentialsIntegration/rolecollection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: RoleCollection 3 | metadata: 4 | namespace: default 5 | name: sac-rolecollection 6 | spec: 7 | forProvider: 8 | name: "subaccountapicredentials-custom-admin-rolecollection" 9 | description: "this is a custom rolecollection from e2e tests" 10 | roles: 11 | - name: "Destination Administrator" 12 | roleTemplateAppId: "destination-xsappname!b404" 13 | roleTemplateName: "Destination_Administrator" 14 | - name: "Subaccount Admin" 15 | roleTemplateAppId: "cis-local!b14" 16 | roleTemplateName: "Subaccount_Admin" 17 | subaccountApiCredentialRef: 18 | name: sac-subaccountapicredentials 19 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/kyma_env/services.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 3 | kind: ServiceManager 4 | metadata: 5 | name: kyma-service-manager 6 | namespace: default 7 | spec: 8 | writeConnectionSecretToRef: 9 | name: kyma-service-manager 10 | namespace: default 11 | forProvider: 12 | subaccountRef: 13 | name: kyma-test-subaccount 14 | --- 15 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 16 | kind: CloudManagement 17 | metadata: 18 | name: kyma-cis-local 19 | namespace: default 20 | spec: 21 | writeConnectionSecretToRef: 22 | name: kyma-cis-local 23 | namespace: default 24 | forProvider: 25 | serviceManagerRef: 26 | name: kyma-service-manager 27 | subaccountRef: 28 | name: kyma-test-subaccount 29 | -------------------------------------------------------------------------------- /internal/utils_test.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestVal(t *testing.T) { 10 | 11 | // nil pointer 12 | var ptrString *string 13 | assert.Equal(t, "", Val(ptrString)) 14 | 15 | // value pointer 16 | str := "Foo" 17 | ptrString = &str 18 | assert.Equal(t, "Foo", Val(ptrString)) 19 | 20 | // pointer to empty value 21 | emptyStr := "" 22 | ptrString = &emptyStr 23 | assert.Equal(t, "", Val(ptrString)) 24 | 25 | // same tests for bool to ensure its generic 26 | var ptrBool *bool 27 | assert.Equal(t, false, Val(ptrBool)) 28 | b := true 29 | ptrBool = &b 30 | assert.Equal(t, true, Val(ptrBool)) 31 | 32 | emptyB := false 33 | ptrBool = &emptyB 34 | assert.Equal(t, false, Val(ptrBool)) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /config/directory_entitlement/config.go: -------------------------------------------------------------------------------- 1 | package subaccount_trust_configuration 2 | 3 | import ( 4 | "github.com/crossplane/upjet/pkg/config" 5 | ) 6 | 7 | // Configure configures individual resources by adding custom ResourceConfigurators. 8 | func Configure(p *config.Provider) { 9 | p.AddResourceConfigurator("btp_directory_entitlement", func(r *config.Resource) { 10 | r.ShortGroup = "account" 11 | r.Kind = "DirectoryEntitlement" 12 | 13 | r.References["directory_id"] = config.Reference{ 14 | Type: "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1.Directory", 15 | Extractor: "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1.DirectoryUuid()", 16 | RefFieldName: "DirectoryRef", 17 | SelectorFieldName: "DirectorySelector", 18 | } 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /examples/sample/rolecollection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.orchestrate.cloud.sap/v1alpha1 2 | kind: RoleCollection 3 | metadata: 4 | namespace: default 5 | name: example-custom-admin-rolecollection 6 | spec: 7 | forProvider: 8 | name: "example-custom-admin-rolecollection" 9 | description: "this is a custom rolecollection" 10 | roles: 11 | - name: "Destination Administrator" 12 | roleTemplateAppId: "destination-xsappname!b9" 13 | roleTemplateName: "Destination_Administrator" 14 | - name: "Subaccount Admin" 15 | roleTemplateAppId: "cis-local!b2" 16 | roleTemplateName: "Subaccount_Admin" 17 | apiCredentials: 18 | source: "Secret" 19 | secretRef: 20 | name: xsuaa-subaccount-credentials 21 | namespace: default 22 | key: credentials 23 | -------------------------------------------------------------------------------- /cluster/images/crossplane-provider-btp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | 3 | COPY package.yaml . 4 | 5 | ARG BUILD_TIMESTAMP 6 | ARG GIT_COMMIT 7 | 8 | LABEL org.opencontainers.image.title="crossplane-provider-btp" \ 9 | org.opencontainers.image.description="Configuration for btp-account provider" \ 10 | org.opencontainers.image.documentation="https://pages.github.tools.sap/cloud-orchestration/" \ 11 | org.opencontainers.image.url="https://github.com/sap/crossplane-provider-btp" \ 12 | org.opencontainers.image.source="https://github.com/sap/crossplane-provider-btp.git" \ 13 | org.opencontainers.image.vendor="SAP SE" \ 14 | org.opencontainers.image.base.name="scratch" \ 15 | org.opencontainers.image.revision="$GIT_COMMIT" \ 16 | org.opencontainers.image.created="$BUILD_TIMESTAMP" 17 | -------------------------------------------------------------------------------- /apis/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // Package v1alpha1 contains the v1alpha1 group Sample resources of the BTPAccount provider. 2 | // +kubebuilder:object:generate=true 3 | // +groupName=btp.sap.crossplane.io 4 | // +versionName=v1alpha1 5 | package v1alpha1 6 | 7 | import ( 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | "sigs.k8s.io/controller-runtime/pkg/scheme" 10 | ) 11 | 12 | // Package type metadata. 13 | const ( 14 | Group = "btp.sap.crossplane.io" 15 | Version = "v1alpha1" 16 | ) 17 | 18 | var ( 19 | // SchemeGroupVersion is group version used to register these objects 20 | SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} 21 | 22 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 23 | SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} 24 | ) 25 | -------------------------------------------------------------------------------- /apis/account/v1beta1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // Package v1beta1 contains the v1alpha1 group Sample resources of the btp provider. 2 | // +kubebuilder:object:generate=true 3 | // +groupName=account.btp.sap.crossplane.io 4 | // +versionName=v1beta1 5 | package v1beta1 6 | 7 | import ( 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | "sigs.k8s.io/controller-runtime/pkg/scheme" 10 | ) 11 | 12 | // Package type metadata. 13 | const ( 14 | Group = "account.btp.sap.crossplane.io" 15 | Version = "v1beta1" 16 | ) 17 | 18 | var ( 19 | // SchemeGroupVersion is group version used to register these objects 20 | SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} 21 | 22 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 23 | SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} 24 | ) 25 | -------------------------------------------------------------------------------- /apis/v1beta1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // Package v1beta1 contains the v1beta1 group Sample resources of the BTPAccount provider. 2 | // +kubebuilder:object:generate=true 3 | // +groupName=account.btp.sap.crossplane.io 4 | // +versionName=v1beta1 5 | package v1beta1 6 | 7 | import ( 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | "sigs.k8s.io/controller-runtime/pkg/scheme" 10 | ) 11 | 12 | // Package type metadata. 13 | const ( 14 | Group = "account.btp.sap.crossplane.io" 15 | Version = "v1beta1" 16 | ) 17 | 18 | var ( 19 | // SchemeGroupVersion is group version used to register these objects 20 | SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} 21 | 22 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 23 | SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} 24 | ) 25 | -------------------------------------------------------------------------------- /cmd/generator/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Upbound Inc. 3 | */ 4 | 5 | package main 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "path/filepath" 11 | 12 | "github.com/crossplane/upjet/pkg/pipeline" 13 | 14 | "github.com/sap/crossplane-provider-btp/config" 15 | ) 16 | 17 | func main() { 18 | if len(os.Args) < 2 || os.Args[1] == "" { 19 | panic("root directory is required to be given as argument") 20 | } 21 | rootDir := os.Args[1] 22 | absRootDir, err := filepath.Abs(rootDir) 23 | if err != nil { 24 | panic(fmt.Sprintf("cannot calculate the absolute path with %s", rootDir)) 25 | } 26 | 27 | // need to overide the rootgroup as we as want to control the name of the CRD groups 28 | provider := config.GetProvider() 29 | rg := provider.RootGroup 30 | fmt.Println(rg) 31 | 32 | pipeline.Run(provider, absRootDir) 33 | } 34 | -------------------------------------------------------------------------------- /apis/oidc/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // Package v1alpha1 contains the v1alpha1 group Sample resources of the btp-account provider. 2 | // +kubebuilder:object:generate=true 3 | // +groupName=oidc.btp.sap.crossplane.io 4 | // +versionName=v1alpha1 5 | package v1alpha1 6 | 7 | import ( 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | "sigs.k8s.io/controller-runtime/pkg/scheme" 10 | ) 11 | 12 | // Package type metadata. 13 | const ( 14 | Group = "oidc.btp.sap.crossplane.io" 15 | Version = "v1alpha1" 16 | ) 17 | 18 | var ( 19 | // SchemeGroupVersion is group version used to register these objects 20 | SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} 21 | 22 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 23 | SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} 24 | ) 25 | -------------------------------------------------------------------------------- /config/subaccount_trust_configuration/config.go: -------------------------------------------------------------------------------- 1 | package subaccount_trust_configuration 2 | 3 | import ( 4 | "github.com/crossplane/upjet/pkg/config" 5 | ) 6 | 7 | // Configure configures individual resources by adding custom ResourceConfigurators. 8 | func Configure(p *config.Provider) { 9 | p.AddResourceConfigurator("btp_subaccount_trust_configuration", func(r *config.Resource) { 10 | r.ShortGroup = "security" 11 | r.Kind = "SubaccountTrustConfiguration" 12 | 13 | r.References["subaccount_id"] = config.Reference{ 14 | Type: "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1.Subaccount", 15 | Extractor: "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1.SubaccountUuid()", 16 | RefFieldName: "SubaccountRef", 17 | SelectorFieldName: "SubaccountSelector", 18 | } 19 | 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-entitlements-service-api-go/README.md: -------------------------------------------------------------------------------- 1 | ## Btp Entitlements Service API Go 2 | 3 | ### Prerequisites 4 | Install openapi-generator-cli (using mac) 5 | ```bash 6 | brew install openapi-generator 7 | ``` 8 | for other OS see [official guide](https://openapi-generator.tech/docs/installation) 9 | 10 | ### How to regenerate 11 | ```bash 12 | openapi-generator generate -i swagger-patched.json -g go -o pkg/ 13 | go mod tidy -v 14 | ``` 15 | 16 | ### Apply patches 17 | Sometimes api specs need to be patched prior to generating code out of them. 18 | For that the widely accepted json-patch standard can be used. To not introduce any more dependencies into the project 19 | we do not include an opinionated json-patch library but rather leave it up to the contributor to choose one. 20 | You can find a list here: https://jsonpatch.com 21 | -------------------------------------------------------------------------------- /apis/environment/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | // Package v1alpha1 contains the v1alpha1 group Sample resources of the btp provider. 2 | // +kubebuilder:object:generate=true 3 | // +groupName=environment.btp.sap.crossplane.io 4 | // +versionName=v1alpha1 5 | package v1alpha1 6 | 7 | import ( 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | "sigs.k8s.io/controller-runtime/pkg/scheme" 10 | ) 11 | 12 | // Package type metadata. 13 | const ( 14 | Group = "environment.btp.sap.crossplane.io" 15 | Version = "v1alpha1" 16 | ) 17 | 18 | var ( 19 | // SchemeGroupVersion is group version used to register these objects 20 | SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} 21 | 22 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 23 | SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} 24 | ) 25 | -------------------------------------------------------------------------------- /.github/workflows/check-go-licenses.yaml: -------------------------------------------------------------------------------- 1 | name: Check Go Dependency Licenses 2 | 3 | on: 4 | workflow_call: 5 | 6 | permissions: 7 | contents: read 8 | 9 | jobs: 10 | license-check: 11 | name: Check licenses of dependencies 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: checkout repo 15 | uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 16 | 17 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 18 | with: 19 | go-version: '1.24' 20 | 21 | - name: Install go-licenses 22 | run: | 23 | go install github.com/google/go-licenses@latest 24 | 25 | - name: check licenses 26 | run: | 27 | go-licenses check --allowed_licenses="Apache-2.0,BSD-3-Clause,MIT,MPL-2.0,ISC,BSD-2-Clause" ./... 28 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-xsuaa-service-api-go/Makefile: -------------------------------------------------------------------------------- 1 | .DEFAULT_GOAL := ci 2 | #.SILENT: 3 | 4 | .PHONY: help 5 | help: ## Show this help screen 6 | @echo 'Usage: make ... ' 7 | @echo '' 8 | @echo 'Available targets are:' 9 | @echo '' 10 | @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 11 | 12 | ci: apply generate 13 | 14 | .PHONY: generate 15 | generate: 16 | openapi-generator-cli generate -i swagger.json -g go -o pkg/ --additional-properties=generateInterfaces=true,structPrefix=true --skip-validate-spec 17 | go mod tidy -v 18 | 19 | #.PHONY: download 20 | #download: 21 | # @echo "Downloading Spec from $(SPEC_URL)" 22 | # @curl -sL $(SPEC_URL)| jq -S '.' > swagger.json -------------------------------------------------------------------------------- /internal/testutils/error_helper_utils.go: -------------------------------------------------------------------------------- 1 | package testutils 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | // ContainsError While testing there is no point in mimicking wrapped error hierarchies, but we do want to distinguish check 8 | // whether an error is part of the stacktrace 9 | // when error message itself contains :, the split contains logic is not enough, add compare of error message itself 10 | func ContainsError(wrappedErr error, containedErr error) bool { 11 | if containedErr == nil && wrappedErr == nil { 12 | return true 13 | } 14 | if containedErr == nil || wrappedErr == nil { 15 | return false 16 | } 17 | 18 | errMsg := wrappedErr.Error() 19 | split := strings.Split(errMsg, ":") 20 | for _, v := range split { 21 | if strings.TrimSpace(v) == containedErr.Error() { 22 | return true 23 | } 24 | } 25 | return errMsg == containedErr.Error() 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/unit_test.yaml: -------------------------------------------------------------------------------- 1 | # This workflow will builds a golang project and runs unit-tests 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go 3 | 4 | name: Unit Tests 5 | 6 | on: 7 | workflow_call: 8 | 9 | permissions: 10 | contents: read 11 | jobs: 12 | 13 | unit-tests: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 17 | with: 18 | submodules: true 19 | 20 | - name: Set up Go 21 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 22 | with: 23 | go-version: '1.21' 24 | 25 | - name: Build 26 | run: go build -v ./... 27 | 28 | - name: Unit-Test Init 29 | run: make test.init 30 | - name: Unit-Test Run 31 | run: make test.run 32 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-service-manager-api-go/README.md: -------------------------------------------------------------------------------- 1 | ## Btp Service Manager Service API Go 2 | 3 | ### Prerequisites 4 | Install openapi-generator-cli (using mac) 5 | ```bash 6 | brew install openapi-generator 7 | ``` 8 | for other OS see [official guide](https://openapi-generator.tech/docs/installation) 9 | 10 | ### How to regenerate 11 | ```bash 12 | openapi-generator generate -i swagger-patched.json -g go -o pkg/ --additional-properties=generateInterfaces=true 13 | go mod tidy -v 14 | ``` 15 | 16 | ### Apply patches 17 | Sometimes api specs need to be patched prior to generating code out of them. 18 | For that the widely accepted json-patch standard can be used. To not introduce any more dependencies into the project 19 | we do not include an opinionated json-patch library but rather leave it up to the contributor to choose one. 20 | You can find a list here: https://jsonpatch.com 21 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-saas-provisioning-api-go/README.md: -------------------------------------------------------------------------------- 1 | ## Btp SaaS-Provisioning Service API Go 2 | 3 | ### Prerequisites 4 | Install openapi-generator-cli (using mac) 5 | ```bash 6 | brew install openapi-generator 7 | ``` 8 | for other OS see [official guide](https://openapi-generator.tech/docs/installation) 9 | 10 | ### How to regenerate 11 | ```bash 12 | openapi-generator generate -i swagger-patched.json -g go -o pkg/ --additional-properties=generateInterfaces=true 13 | go mod tidy -v 14 | ``` 15 | 16 | ### Apply patches 17 | Sometimes api specs need to be patched prior to generating code out of them. 18 | For that the widely accepted json-patch standard can be used. To not introduce any more dependencies into the project 19 | we do not include an opinionated json-patch library but rather leave it up to the contributor to choose one. 20 | You can find a list here: https://jsonpatch.com 21 | -------------------------------------------------------------------------------- /examples/sample/cert-based-oidc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: oidc.btp.sap.crossplane.io/v1alpha1 2 | kind: CertBasedOIDCLogin 3 | metadata: 4 | name: example-login 5 | spec: 6 | forProvider: 7 | issuer: 8 | clientId: 9 | certificate: 10 | type: sap-ias 11 | source: Secret 12 | secretRef: 13 | namespace: crossplane-system 14 | name: example-login-cert-secret 15 | key: cert 16 | password: 17 | source: Secret 18 | secretRef: 19 | namespace: crossplane-system 20 | name: example-login-cert-secret 21 | key: password 22 | writeConnectionSecretToRef: 23 | name: oidc-token 24 | namespace: crossplane-system 25 | --- 26 | # To generate cert secret from downloaded cert: 27 | # kubectl create secret generic example-login-cert-secret --namespace=crossplane-system --from-file=cert=/tmp/personal.p12 28 | --- 29 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-provisioning-service-api-go/README.md: -------------------------------------------------------------------------------- 1 | ## Btp Provisioning Service API Go 2 | 3 | ### Prerequisites 4 | Install openapi-generator-cli (using mac) 5 | ```bash 6 | brew install openapi-generator 7 | ``` 8 | for other OS see [official guide](https://openapi-generator.tech/docs/installation) 9 | 10 | ### How to regenerate 11 | ```bash 12 | openapi-generator generate -i swagger-patched.json -g go -o pkg/ --additional-properties=generateInterfaces=true 13 | go fmt ./... 14 | go mod tidy -v 15 | ``` 16 | 17 | ### Apply patches 18 | Sometimes api specs need to be patched prior to generating code out of them. 19 | For that the widely accepted json-patch standard can be used. To not introduce any more dependencies into the project 20 | we do not include an opinionated json-patch library but rather leave it up to the contributor to choose one. 21 | You can find a list here: https://jsonpatch.com 22 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-xsuaa-service-api-go/README.md: -------------------------------------------------------------------------------- 1 | ## Btp Xsuaa Service API Go 2 | 3 | ### Prerequisites 4 | Install openapi-generator-cli (using mac) 5 | ```bash 6 | brew install openapi-generator 7 | ``` 8 | for other OS see [official guide](https://openapi-generator.tech/docs/installation) 9 | 10 | ### How to regenerate 11 | ```bash 12 | openapi-generator generate -i swagger.json -g go -o pkg/ --additional-properties=generateInterfaces=true,structPrefix=true --skip-validate-spec 13 | go mod tidy -v 14 | ``` 15 | 16 | ### Apply patches 17 | Sometimes api specs need to be patched prior to generating code out of them. 18 | For that the widely accepted json-patch standard can be used. To not introduce any more dependencies into the project 19 | we do not include an opinionated json-patch library but rather leave it up to the contributor to choose one. 20 | You can find a list here: https://jsonpatch.com 21 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/entitlement/dynatrace.yaml: -------------------------------------------------------------------------------- 1 | # Test case for multiple entitlements with same kind and service for only enabling (without amount) 2 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 3 | kind: Entitlement 4 | metadata: 5 | namespace: default 6 | name: dynatrace-entitlement 7 | spec: 8 | forProvider: 9 | enable: true 10 | serviceName: dynatrace 11 | servicePlanName: environment 12 | subaccountRef: 13 | name: entitlement-sa-test 14 | providerConfigRef: 15 | name: default 16 | --- 17 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 18 | kind: Entitlement 19 | metadata: 20 | namespace: default 21 | name: dynatrace-entitlement2 22 | spec: 23 | forProvider: 24 | enable: true 25 | serviceName: dynatrace 26 | servicePlanName: environment 27 | subaccountRef: 28 | name: entitlement-sa-test 29 | providerConfigRef: 30 | name: default 31 | -------------------------------------------------------------------------------- /test/e2e/testdata/crs/entitlement/postgresql-development.yaml: -------------------------------------------------------------------------------- 1 | # Test Case for having multiple entitlements with same kind and service and different amounts 2 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 3 | kind: Entitlement 4 | metadata: 5 | name: postgres-development 6 | namespace: default 7 | spec: 8 | forProvider: 9 | serviceName: postgresql-db 10 | servicePlanName: development 11 | amount: 1 12 | subaccountRef: 13 | name: entitlement-sa-test 14 | providerConfigRef: 15 | name: default 16 | --- 17 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 18 | kind: Entitlement 19 | metadata: 20 | name: postgres-development2 21 | namespace: default 22 | spec: 23 | forProvider: 24 | serviceName: postgresql-db 25 | servicePlanName: development 26 | amount: 1 27 | subaccountRef: 28 | name: entitlement-sa-test 29 | providerConfigRef: 30 | name: default 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an new Feature or Improvement 4 | title: "[FEATURE]" 5 | type: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Context** 11 | Tell us about the scenario you and use case, you seek additional functionality in. 12 | 13 | **Scope** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Out of scope** 17 | If needed, describe what parts of a feature can be ignored for now. 18 | 19 | _Hint_: Smaller feature wishes tend to be implemented and shipped quicker! 20 | 21 | **Technical Steps** 22 | (Optional) - outline steps for contributors to give implementation guidance and allow transparent technical discussions. 23 | 24 | **Workarounds & Alternatives** 25 | Describe, if possible, how you are solving this problem today. 26 | 27 | **Additional context** 28 | Add any other context or screenshots about the feature request here. 29 | -------------------------------------------------------------------------------- /.github/workflows/pr-test.yaml: -------------------------------------------------------------------------------- 1 | # The on.pull_request pipeline runs on changes to a pull request. With this trigger, the pipeline never receives secrets from gh and the GITHUB_TOKEN is read only. 2 | # Therefore, we can not run our e2e tests here, this needs to be done in an on.pull_request_target pipeline. 3 | name: PullRequest Tests and Pre-Checks 4 | 5 | on: 6 | pull_request: 7 | types: 8 | - opened 9 | - reopened 10 | - synchronize 11 | - ready_for_review 12 | paths-ignore: 13 | - '*.md' 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | run-go-license-check: 20 | uses: ./.github/workflows/check-go-licenses.yaml 21 | 22 | run-reuse-license-check: 23 | uses: ./.github/workflows/reuse-scan.yaml 24 | 25 | run-unit-test: 26 | uses: ./.github/workflows/unit_test.yaml 27 | 28 | run-make-reviewable-and-check-diff: 29 | uses: ./.github/workflows/reviewable_check_diff.yaml -------------------------------------------------------------------------------- /internal/openapi_clients/btp-accounts-service-api-go/README.md: -------------------------------------------------------------------------------- 1 | ## Btp Accounts Service API Go 2 | 3 | ### Prerequisites 4 | Install openapi-generator-cli (using mac) 5 | ```bash 6 | brew install openapi-generator 7 | ``` 8 | for other OS see [official guide](https://openapi-generator.tech/docs/installation) 9 | 10 | ### How to regenerate 11 | ```bash 12 | openapi-generator generate -i swagger-patched.json -g go -o pkg/ --additional-properties=generateInterfaces=true,disallowAdditionalPropertiesIfNotPresent=false 13 | go mod tidy -v 14 | ``` 15 | 16 | ### Apply patches 17 | Sometimes api specs need to be patched prior to generating code out of them. 18 | For that the widely accepted json-patch standard can be used. To not introduce any more dependencies into the project 19 | we do not include an opinionated json-patch library but rather leave it up to the contributor to choose one. 20 | You can find a list here: https://jsonpatch.com 21 | -------------------------------------------------------------------------------- /apis/template.go: -------------------------------------------------------------------------------- 1 | // Package apis contains Kubernetes API for the Template provider. 2 | package apis 3 | 4 | import ( 5 | accountv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 6 | accountv1beta1 "github.com/sap/crossplane-provider-btp/apis/account/v1beta1" 7 | environmentv1alpha1 "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 8 | oidcv1alpha1 "github.com/sap/crossplane-provider-btp/apis/oidc/v1alpha1" 9 | "github.com/sap/crossplane-provider-btp/apis/v1alpha1" 10 | ) 11 | 12 | func init() { 13 | // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back 14 | AddToSchemes = append( 15 | AddToSchemes, 16 | v1alpha1.SchemeBuilder.AddToScheme, 17 | accountv1alpha1.SchemeBuilder.AddToScheme, 18 | environmentv1alpha1.SchemeBuilder.AddToScheme, 19 | oidcv1alpha1.SchemeBuilder.AddToScheme, 20 | accountv1beta1.SchemeBuilder.AddToScheme, 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /config/subaccount_service_binding/config.go: -------------------------------------------------------------------------------- 1 | package subaccount_trust_configuration 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/crossplane/upjet/pkg/config" 7 | ) 8 | 9 | // Configure configures individual resources by adding custom ResourceConfigurators. 10 | func Configure(p *config.Provider) { 11 | p.AddResourceConfigurator("btp_subaccount_service_binding", func(r *config.Resource) { 12 | r.ShortGroup = "account" 13 | r.Kind = "SubaccountServiceBinding" 14 | r.ExternalName.GetIDFn = func(_ context.Context, externalName string, _ map[string]any, _ map[string]any) (string, error) { 15 | // When using "" as ID the API endpoint call will fail, so we need to use anything else that 16 | // won't yield a result 17 | if externalName == "" { 18 | return "NOT_EMPTY_GUID", nil 19 | } 20 | return externalName, nil 21 | } 22 | // note: can be overwritten during initialization 23 | r.UseAsync = true 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /hack/helpers/disable_crds.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd .. 3 | # expects a list of paths relative to internal/controller and will remove those controllers and their references as well as the crds belonging to that one 4 | for folder in "$@"; do 5 | controllerFolder="internal/controller/$folder" 6 | # extract package name as used in zz_setup.go 7 | package=$(grep "$controllerFolder" internal/controller/zz_setup.go | grep -Eo '^[^ ]+' | sed -e 's/^[ \t]*//') 8 | # remove all usages of that reference from file 9 | awk "!/$package/" internal/controller/zz_setup.go > tmpfile && mv tmpfile internal/controller/zz_setup.go 10 | # remove controller folder itself 11 | rm -rf "$controllerFolder" 12 | # remove crd from package/crds folder 13 | pluralname=$(basename "$folder")s 14 | rm package/crds/*$pluralname* 15 | # remove generated examples 16 | rm examples-generated/*/*/$(basename "$folder").yaml 17 | done 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /internal/controller/account/entitlement/fake/fake.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import ( 4 | "context" 5 | 6 | apisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 7 | "github.com/sap/crossplane-provider-btp/internal/clients/entitlement" 8 | ) 9 | 10 | type MockClient struct { 11 | MockDescribeCluster func(ctx context.Context, input apisv1alpha1.Entitlement) (*entitlement.Instance, error) 12 | } 13 | 14 | func (c MockClient) DescribeInstance(ctx context.Context, cr *apisv1alpha1.Entitlement) ( 15 | *entitlement.Instance, 16 | error, 17 | ) { 18 | return c.MockDescribeCluster(ctx, *cr) 19 | } 20 | func (c MockClient) CreateInstance(ctx context.Context, cr *apisv1alpha1.Entitlement) error { 21 | return nil 22 | } 23 | func (c MockClient) UpdateInstance(ctx context.Context, cr *apisv1alpha1.Entitlement) error { 24 | return nil 25 | } 26 | func (c MockClient) DeleteInstance(ctx context.Context, cr *apisv1alpha1.Entitlement) error { 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /internal/testutils/error_helper_utils_test.go: -------------------------------------------------------------------------------- 1 | package testutils 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/pkg/errors" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestContainsError(t *testing.T) { 11 | 12 | t.Run("Detect Wrapped error", func(t *testing.T) { 13 | assert.False(t, 14 | ContainsError(errors.Wrap(errors.New("Contained"), "Wrapping"), errors.New("Other Error")), 15 | ) 16 | }) 17 | 18 | t.Run("Detect Wrapped error", func(t *testing.T) { 19 | assert.True(t, 20 | ContainsError(errors.Wrap(errors.New("Contained"), "Wrapping"), errors.New("Contained")), 21 | ) 22 | }) 23 | 24 | t.Run("Detect Wrapping error", func(t *testing.T) { 25 | assert.True(t, 26 | ContainsError(errors.Wrap(errors.New("Contained"), "Wrapping"), errors.New("Wrapping")), 27 | ) 28 | }) 29 | 30 | t.Run("Detect regular error", func(t *testing.T) { 31 | assert.True(t, 32 | ContainsError(errors.New("Error"), errors.New("Error")), 33 | ) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /internal/clients/kymamodule/fakes.go: -------------------------------------------------------------------------------- 1 | package kymamodule 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 7 | ) 8 | 9 | type MockKymaModuleClient struct { 10 | err error 11 | apiResponse *v1alpha1.ModuleStatus 12 | } 13 | 14 | // ObserveModule implements KymaModuleClient.ObserveModule 15 | func (m *MockKymaModuleClient) ObserveModule(ctx context.Context, moduleCr *v1alpha1.KymaModule) (*v1alpha1.ModuleStatus, error) { 16 | return m.apiResponse, m.err 17 | } 18 | 19 | // CreateModule implements KymaModuleClient.CreateModule 20 | func (m *MockKymaModuleClient) CreateModule(ctx context.Context, moduleName string, moduleChannel string, customResourcePolicy string) error { 21 | return m.err 22 | } 23 | 24 | // DeleteModule implements KymaModuleClient.DeleteModule 25 | func (m *MockKymaModuleClient) DeleteModule(ctx context.Context, moduleName string) error { 26 | return m.err 27 | } 28 | 29 | var _ Client = &MockKymaModuleClient{} 30 | -------------------------------------------------------------------------------- /.github/workflows/reviewable_check_diff.yaml: -------------------------------------------------------------------------------- 1 | # This workflow will run make reviewable and make check-diff as checks 2 | 3 | name: Reviewable&Check-Diff 4 | permissions: 5 | contents: read 6 | 7 | on: 8 | workflow_call: 9 | 10 | env: 11 | GO_IMPORT_VERSION: 'v0.16.1' 12 | 13 | jobs: 14 | reviewable-checkdiff: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 18 | with: 19 | submodules: true 20 | 21 | - name: Set up Go 22 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 23 | with: 24 | go-version: '1.21' 25 | 26 | - name: Install goimports 27 | run: | 28 | cd /tmp 29 | go install golang.org/x/tools/cmd/goimports@${{ env.GO_IMPORT_VERSION }} 30 | 31 | - name: Make Reviewable 32 | run: make reviewable 33 | env: 34 | RUNNING_IN_CI: 'true' 35 | - name: Make Check-Diff 36 | run: make check-diff 37 | -------------------------------------------------------------------------------- /examples/sample/rolecollectionassignment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 2 | kind: RoleCollectionAssignment 3 | metadata: 4 | namespace: default 5 | name: example-assigned-user 6 | spec: 7 | forProvider: 8 | origin: "sap.default" 9 | roleCollectionName: "Subaccount Administrator" 10 | userName: 11 | apiCredentials: 12 | source: "Secret" 13 | secretRef: 14 | name: xsuaa-subaccount-credentials 15 | namespace: default 16 | key: credentials 17 | --- 18 | apiVersion: security.btp.sap.crossplane.io/v1alpha1 19 | kind: RoleCollectionAssignment 20 | metadata: 21 | namespace: default 22 | name: example-assigned-group 23 | spec: 24 | forProvider: 25 | origin: "sap.default" 26 | roleCollectionName: "Subaccount Administrator" 27 | groupName: some-usergroup 28 | apiCredentials: 29 | source: "Secret" 30 | secretRef: 31 | name: xsuaa-subaccount-credentials 32 | namespace: default 33 | key: credentials 34 | -------------------------------------------------------------------------------- /examples/sample/directory.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Directory 3 | metadata: 4 | namespace: default 5 | name: example-directory-parent 6 | spec: 7 | forProvider: 8 | description: "created by code" 9 | directoryAdmins: 10 | - "" 11 | directoryFeatures: 12 | - "DEFAULT" 13 | displayName: dir_from_code-parent 14 | labels: 15 | custom_label: ["custom_value"] 16 | another_label: ["onevalue", "twovalue"] 17 | --- 18 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 19 | kind: Directory 20 | metadata: 21 | namespace: default 22 | name: example-directory-child 23 | spec: 24 | forProvider: 25 | directoryRef: 26 | name: example-directory-parent 27 | description: "created by code" 28 | directoryAdmins: 29 | - "" 30 | directoryFeatures: 31 | - "DEFAULT" 32 | displayName: dir_from_code-child 33 | labels: 34 | custom_label: ["custom_value"] 35 | another_label: ["onevalue", "twovalue"] 36 | -------------------------------------------------------------------------------- /test/e2e/mocks.go: -------------------------------------------------------------------------------- 1 | package e2e 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" 7 | "github.com/crossplane/crossplane-runtime/pkg/resource" 8 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 | "k8s.io/apimachinery/pkg/runtime" 10 | "sigs.k8s.io/controller-runtime/pkg/client" 11 | "sigs.k8s.io/e2e-framework/klient/k8s" 12 | ) 13 | 14 | type MockList struct { 15 | client.ObjectList 16 | 17 | Items []k8s.Object 18 | } 19 | type FakeManaged struct { 20 | metav1.TypeMeta 21 | metav1.ObjectMeta 22 | resource.ProviderConfigReferencer 23 | resource.ConnectionSecretWriterTo 24 | resource.ConnectionDetailsPublisherTo 25 | resource.Orphanable 26 | resource.Manageable 27 | xpv1.ConditionedStatus 28 | } 29 | 30 | // DeepCopyObject returns a copy of the object as runtime.Object 31 | func (m *FakeManaged) DeepCopyObject() runtime.Object { 32 | out := &FakeManaged{} 33 | j, err := json.Marshal(m) 34 | if err != nil { 35 | panic(err) 36 | } 37 | _ = json.Unmarshal(j, out) 38 | return out 39 | } 40 | -------------------------------------------------------------------------------- /apis/security/v1alpha1/zz_generated.conversion_hubs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by upjet. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | // Hub marks this type as a conversion hub. 22 | func (tr *GlobalaccountTrustConfiguration) Hub() {} 23 | 24 | // Hub marks this type as a conversion hub. 25 | func (tr *SubaccountApiCredential) Hub() {} 26 | 27 | // Hub marks this type as a conversion hub. 28 | func (tr *SubaccountTrustConfiguration) Hub() {} 29 | -------------------------------------------------------------------------------- /hack/helpers/apis/GROUP_LOWER/APIVERSION/groupversion_info.go.tmpl: -------------------------------------------------------------------------------- 1 | // Package v1alpha1 contains the v1alpha1 group Sample resources of the {{ .Env.PROVIDER }} provider. 2 | // +kubebuilder:object:generate=true 3 | // +groupName={{ .Env.GROUP | strings.ToLower }}.{{ .Env.PROVIDER | strings.ToLower }}.sap.crossplane.io 4 | // +versionName={{ .Env.APIVERSION | strings.ToLower }} 5 | package {{ .Env.APIVERSION | strings.ToLower }} 6 | 7 | import ( 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | "sigs.k8s.io/controller-runtime/pkg/scheme" 10 | ) 11 | 12 | // Package type metadata. 13 | const ( 14 | Group = "{{ .Env.GROUP | strings.ToLower }}.{{ .Env.PROVIDER | strings.ToLower }}..orchestrate.cloud.sap" 15 | Version = "{{ .Env.APIVERSION | strings.ToLower }}" 16 | ) 17 | 18 | var ( 19 | // SchemeGroupVersion is group version used to register these objects 20 | SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version} 21 | 22 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 23 | SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} 24 | ) 25 | -------------------------------------------------------------------------------- /internal/controller/oidc/certbasedoidclogin/certlogin_mock.go: -------------------------------------------------------------------------------- 1 | package certbasedoidclogin 2 | 3 | import ( 4 | "context" 5 | oidc2 "github.com/int128/kubelogin/pkg/oidc" 6 | "github.com/pkg/errors" 7 | "github.com/sap/crossplane-provider-btp/internal/clients/oidc" 8 | ) 9 | 10 | var ( 11 | errMockedLogin = errors.New("mocked login error") 12 | errMockedRefresh = errors.New("refresh error") 13 | ) 14 | 15 | type CertLoginMock struct { 16 | TokenSet *oidc2.TokenSet 17 | Expired bool 18 | } 19 | 20 | var _ oidc.LoginPerformer = &CertLoginMock{} 21 | 22 | func (cLMock *CertLoginMock) DoLogin(ctx context.Context) (*oidc2.TokenSet, error) { 23 | if cLMock.TokenSet == nil { 24 | return nil, errMockedLogin 25 | } 26 | return cLMock.TokenSet, nil 27 | } 28 | 29 | func (cLMock *CertLoginMock) IsExpired(idToken string) bool { 30 | return cLMock.Expired 31 | } 32 | 33 | func (cLMock *CertLoginMock) Refresh(ctx context.Context, refreshToken string) (*oidc2.TokenSet, error) { 34 | if cLMock.TokenSet == nil { 35 | return nil, errMockedRefresh 36 | } 37 | return cLMock.TokenSet, nil 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/label-merge-blocker.yaml: -------------------------------------------------------------------------------- 1 | # This workflow blocks merging pull request when labels are set or missing. 2 | # This way we ensure that merging with label "do-not-merge" is blocked 3 | # and that a label starting with "release-notes/" is always present. 4 | name: "Label Blocker" 5 | 6 | on: 7 | pull_request: 8 | types: [labeled, unlabeled, opened, synchronize] 9 | 10 | permissions: {} 11 | 12 | jobs: 13 | do-not-merge-block: 14 | if: contains(github.event.pull_request.labels.*.name, 'do-not-merge') 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Fail if 'do-not-merge' label is present 18 | run: | 19 | echo "The 'do-not-merge' label is present. Remove to succeed the job." 20 | exit 1 21 | 22 | release-note-missing-block: 23 | if: ${{ !contains(toJSON(github.event.pull_request.labels.*.name), '"release-notes/') }} 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Fail if no release-notes label is present 27 | run: | 28 | echo "A label starting with 'release-notes/' is required." 29 | exit 1 -------------------------------------------------------------------------------- /apis/v1alpha1/zz_generated.pculist.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by angryjet. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | import resource "github.com/crossplane/crossplane-runtime/pkg/resource" 22 | 23 | // GetItems of this ProviderConfigUsageList. 24 | func (p *ProviderConfigUsageList) GetItems() []resource.ProviderConfigUsage { 25 | items := make([]resource.ProviderConfigUsage, len(p.Items)) 26 | for i := range p.Items { 27 | items[i] = &p.Items[i] 28 | } 29 | return items 30 | } 31 | -------------------------------------------------------------------------------- /apis/security/v1alpha1/zz_extractors.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/reference" 5 | "github.com/crossplane/crossplane-runtime/pkg/resource" 6 | ) 7 | 8 | // SubaccountApiCredentialSecret extracts the Reference of a cis instance to a secret name 9 | func SubaccountApiCredentialSecret() reference.ExtractValueFn { 10 | return func(mg resource.Managed) string { 11 | sg, ok := mg.(*SubaccountApiCredential) 12 | if !ok { 13 | return "" 14 | } 15 | if sg.Spec.WriteConnectionSecretToReference == nil { 16 | return "" 17 | } 18 | return sg.Spec.WriteConnectionSecretToReference.Name 19 | } 20 | } 21 | 22 | // SubaccountApiCredentialSecretNamespace extracts the Reference of a cis instance to the namespace of secret 23 | func SubaccountApiCredentialSecretNamespace() reference.ExtractValueFn { 24 | return func(mg resource.Managed) string { 25 | sg, ok := mg.(*SubaccountApiCredential) 26 | if !ok { 27 | return "" 28 | } 29 | if sg.Spec.WriteConnectionSecretToReference == nil { 30 | return "" 31 | } 32 | return sg.Spec.WriteConnectionSecretToReference.Namespace 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /apis/account/v1alpha1/zz_generated.conversion_hubs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by upjet. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | // Hub marks this type as a conversion hub. 22 | func (tr *DirectoryEntitlement) Hub() {} 23 | 24 | // Hub marks this type as a conversion hub. 25 | func (tr *SubaccountServiceBinding) Hub() {} 26 | 27 | // Hub marks this type as a conversion hub. 28 | func (tr *SubaccountServiceBroker) Hub() {} 29 | 30 | // Hub marks this type as a conversion hub. 31 | func (tr *SubaccountServiceInstance) Hub() {} 32 | -------------------------------------------------------------------------------- /apis/environment/v1alpha1/zz_extractors.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/reference" 5 | "github.com/crossplane/crossplane-runtime/pkg/resource" 6 | ) 7 | 8 | // KymaEnvironmentBindingSecret extracts the Reference of some Kyma credentials to a secret name 9 | func KymaEnvironmentBindingSecret() reference.ExtractValueFn { 10 | return func(mg resource.Managed) string { 11 | sg, ok := mg.(*KymaEnvironmentBinding) 12 | if !ok { 13 | return "" 14 | } 15 | if sg.Spec.WriteConnectionSecretToReference == nil { 16 | return "" 17 | } 18 | return sg.Spec.WriteConnectionSecretToReference.Name 19 | } 20 | } 21 | 22 | // KymaEnvironmentBindingSecretNamespace extracts the Reference of some Kyma credentials to the namespace of secret 23 | func KymaEnvironmentBindingSecretNamespace() reference.ExtractValueFn { 24 | return func(mg resource.Managed) string { 25 | sg, ok := mg.(*KymaEnvironmentBinding) 26 | if !ok { 27 | return "" 28 | } 29 | if sg.Spec.WriteConnectionSecretToReference == nil { 30 | return "" 31 | } 32 | return sg.Spec.WriteConnectionSecretToReference.Namespace 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/sample/directory_entitlement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 2 | kind: Directory 3 | metadata: 4 | namespace: default 5 | name: directory-for-entitlement-testing 6 | spec: 7 | forProvider: 8 | description: "created by code" 9 | directoryAdmins: 10 | - "" 11 | directoryFeatures: 12 | - "DEFAULT" 13 | - "ENTITLEMENTS" 14 | displayName: dir_for_entitlement_testing 15 | labels: 16 | custom_label: ["custom_value"] 17 | another_label: ["onevalue", "twovalue"] 18 | --- 19 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 20 | kind: DirectoryEntitlement 21 | metadata: 22 | name: directory-ent-cis-local 23 | spec: 24 | forProvider: 25 | directoryRef: 26 | name: directory-for-entitlement-testing 27 | planName: local 28 | serviceName: cis 29 | --- 30 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 31 | kind: DirectoryEntitlement 32 | metadata: 33 | name: audit-log-viewer-ent 34 | spec: 35 | forProvider: 36 | serviceName: postgresql-db 37 | planName: development 38 | amount: 1 39 | directoryRef: 40 | name: directory-for-entitlement-testing 41 | -------------------------------------------------------------------------------- /config/subaccount_service_instance/config.go: -------------------------------------------------------------------------------- 1 | package subaccount_service_instance 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/crossplane/upjet/pkg/config" 7 | ) 8 | 9 | // Configure configures individual resources by adding custom ResourceConfigurators. 10 | func Configure(p *config.Provider) { 11 | p.AddResourceConfigurator("btp_subaccount_service_instance", func(r *config.Resource) { 12 | r.ShortGroup = "account" 13 | r.Kind = "SubaccountServiceInstance" 14 | 15 | r.ExternalName.OmittedFields = []string{"timeouts"} 16 | r.ExternalName.GetIDFn = func(_ context.Context, externalName string, _ map[string]any, _ map[string]any) (string, error) { 17 | // When using "" as ID the API endpoint call will fail, so we need to use anything else that 18 | // won't yield a result 19 | if externalName == "" { 20 | return "NOT_EMPTY_GUID", nil 21 | } 22 | return externalName, nil 23 | } 24 | // note: can be overwritten during initialization 25 | r.UseAsync = true 26 | 27 | // we only use this resource internally, so there is no harm in avoiding usage of secrets here it makes the setup a lot easier 28 | r.TerraformResource.Schema["parameters"].Sensitive = false 29 | 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /internal/controller/oidc/certbasedoidclogin/zz_setup.go: -------------------------------------------------------------------------------- 1 | package certbasedoidclogin 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | oidcapisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/oidc/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 12 | "github.com/sap/crossplane-provider-btp/internal/tracking" 13 | ) 14 | 15 | // Setup adds a controller that reconciles GlobalAccount managed resources. 16 | func Setup(mgr ctrl.Manager, o controller.Options) error { 17 | return providerconfig.DefaultSetup(mgr, o, &oidcapisv1alpha1.CertBasedOIDCLogin{}, oidcapisv1alpha1.CertBasedOIDCLoginGroupKind, oidcapisv1alpha1.CertBasedOIDCLoginGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 18 | return &connector{ 19 | kube: kube, 20 | usage: usage, 21 | newServiceFn: newServiceFn, 22 | } 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /config/subaccount_service_broker/config.go: -------------------------------------------------------------------------------- 1 | package subaccountservicebroker 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/crossplane/upjet/pkg/config" 7 | ) 8 | 9 | // Configure configures individual resources by adding custom ResourceConfigurators. 10 | func Configure(p *config.Provider) { 11 | p.AddResourceConfigurator("btp_subaccount_service_broker", func(r *config.Resource) { 12 | r.ShortGroup = "account" 13 | r.Kind = "SubaccountServiceBroker" 14 | 15 | r.ExternalName.GetIDFn = func(_ context.Context, externalName string, _ map[string]any, _ map[string]any) (string, error) { 16 | // When using "" as ID the API endpoint call will fail, so we need to use anything else that 17 | // won't yield a result 18 | if externalName == "" { 19 | return "NOT_EMPTY_GUID", nil 20 | } 21 | return externalName, nil 22 | } 23 | 24 | r.References["subaccount_id"] = config.Reference{ 25 | Type: "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1.Subaccount", 26 | Extractor: "github.com/crossplane/crossplane-runtime/pkg/reference.ExternalName()", 27 | RefFieldName: "SubaccountRef", 28 | SelectorFieldName: "SubaccountSelector", 29 | } 30 | 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /internal/controller/oidc/kubeconfiggenerator/zz_setup.go: -------------------------------------------------------------------------------- 1 | package kubeconfiggenerator 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | oidcapisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/oidc/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 12 | "github.com/sap/crossplane-provider-btp/internal/tracking" 13 | ) 14 | 15 | // Setup adds a controller that reconciles GlobalAccount managed resources. 16 | func Setup(mgr ctrl.Manager, o controller.Options) error { 17 | return providerconfig.DefaultSetup(mgr, o, &oidcapisv1alpha1.KubeConfigGenerator{}, oidcapisv1alpha1.KubeConfigGeneratorGroupKind, oidcapisv1alpha1.KubeConfigGeneratorGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 18 | return &connector{ 19 | kube: kube, 20 | usage: usage, 21 | newServiceFn: newKubeConfigClientFn, 22 | } 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /internal/controller/account/subscription/zz_setup.go: -------------------------------------------------------------------------------- 1 | package subscription 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | apisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 12 | "github.com/sap/crossplane-provider-btp/internal/tracking" 13 | ) 14 | 15 | // Setup adds a controller that reconciles GlobalAccount managed resources. 16 | func Setup(mgr ctrl.Manager, o controller.Options) error { 17 | return providerconfig.DefaultSetup(mgr, o, &apisv1alpha1.Subscription{}, apisv1alpha1.SubscriptionGroupKind, apisv1alpha1.SubscriptionGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 18 | return &connector{ 19 | kube: kube, 20 | usage: usage, 21 | newServiceFn: newSubscriptionClientFn, 22 | resourcetracker: resourcetracker, 23 | } 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /internal/controller/security/rolecollection/zz_setup.go: -------------------------------------------------------------------------------- 1 | package rolecollection 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/sap/crossplane-provider-btp/apis/security/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 12 | "github.com/sap/crossplane-provider-btp/internal/tracking" 13 | ) 14 | 15 | // Setup adds a controller that reconciles RoleCollection managed resources. 16 | func Setup(mgr ctrl.Manager, o controller.Options) error { 17 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.RoleCollection{}, v1alpha1.RoleCollectionGroupKind, v1alpha1.RoleCollectionGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 18 | return &connector{ 19 | kube: kube, 20 | usage: usage, 21 | newServiceFn: configureRoleCollectionMaintainerFn, 22 | resourcetracker: resourcetracker, 23 | } 24 | }) 25 | } 26 | -------------------------------------------------------------------------------- /internal/controller/account/entitlement/zz_setup.go: -------------------------------------------------------------------------------- 1 | package entitlement 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | apisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/btp" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles Entitlement managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetup(mgr, o, &apisv1alpha1.Entitlement{}, apisv1alpha1.EntitlementGroupKind, apisv1alpha1.EntitlementGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | resourcetracker: resourcetracker, 23 | newServiceFn: btp.NewBTPClient, 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /internal/controller/kymamodule/zz_setup.go: -------------------------------------------------------------------------------- 1 | package kymamodule 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/internal/clients/kymamodule" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles KymaModule managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.KymaModule{}, v1alpha1.KymaModuleKind, v1alpha1.KymaModuleGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | newServiceFn: kymamodule.NewKymaModuleClient, 23 | resourcetracker: resourcetracker, 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /internal/controller/environment/cloudfoundry/zz_setup.go: -------------------------------------------------------------------------------- 1 | package cloudfoundry 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/btp" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles GlobalAccount managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.CloudFoundryEnvironment{}, v1alpha1.CfEnvironmentGroupKind, v1alpha1.CfEnvironmentGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | newServiceFn: btp.NewBTPClient, 23 | resourcetracker: resourcetracker, 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /internal/tracking/test/noop.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | 9 | providerv1alpha1 "github.com/sap/crossplane-provider-btp/apis/v1alpha1" 10 | ) 11 | 12 | // NoOpReferenceResolverTracker For testing purposes 13 | type NoOpReferenceResolverTracker struct { 14 | // IsResourceBlocked indicates whether the resource should be blocked for deletion or not 15 | IsResourceBlocked bool 16 | } 17 | 18 | func (n NoOpReferenceResolverTracker) Track(ctx context.Context, mg resource.Managed) error { 19 | return nil 20 | } 21 | 22 | func (n NoOpReferenceResolverTracker) SetConditions(ctx context.Context, mg resource.Managed) { 23 | // No-op 24 | } 25 | 26 | func (n NoOpReferenceResolverTracker) ResolveSource(ctx context.Context, ru providerv1alpha1.ResourceUsage) (*metav1.PartialObjectMetadata, error) { 27 | return nil, nil 28 | } 29 | 30 | func (n NoOpReferenceResolverTracker) ResolveTarget(ctx context.Context, ru providerv1alpha1.ResourceUsage) (*metav1.PartialObjectMetadata, error) { 31 | return nil, nil 32 | } 33 | 34 | func (n NoOpReferenceResolverTracker) DeleteShouldBeBlocked(mg resource.Managed) bool { 35 | return n.IsResourceBlocked 36 | } 37 | -------------------------------------------------------------------------------- /internal/controller/account/globalaccount/zz_setup.go: -------------------------------------------------------------------------------- 1 | package globalaccount 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | apisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/btp" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles GlobalAccount managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetup(mgr, o, &apisv1alpha1.GlobalAccount{}, apisv1alpha1.GlobalAccountKind, apisv1alpha1.GlobalAccountGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | newServiceFn: btp.NewBTPClient, 23 | resourcetracker: resourcetracker, 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /internal/controller/account/subaccount/zz_setup.go: -------------------------------------------------------------------------------- 1 | package subaccount 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | apisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/btp" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles GlobalAccount managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetupWithoutDefaultInitializer(mgr, o, &apisv1alpha1.Subaccount{}, apisv1alpha1.SubaccountGroupKind, apisv1alpha1.SubaccountGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | newServiceFn: btp.NewBTPClient, 23 | resourcetracker: resourcetracker, 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /internal/controller/environment/kyma/zz_setup.go: -------------------------------------------------------------------------------- 1 | package kyma 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/btp" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles KymaEnvironment managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.KymaEnvironment{}, v1alpha1.KymaEnvironmentKind, v1alpha1.KymaEnvironmentGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | log: mgr.GetLogger(), 23 | newServiceFn: btp.NewBTPClient, 24 | resourcetracker: resourcetracker, 25 | } 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /internal/controller/kymaenvironmentbinding/zz_setup.go: -------------------------------------------------------------------------------- 1 | package kymaenvironmentbinding 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/btp" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles KymaEnvironment managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.KymaEnvironmentBinding{}, v1alpha1.KymaEnvironmentBindingKind, v1alpha1.KymaEnvironmentBindingGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | newServiceFn: btp.NewBTPClient, 23 | resourcetracker: resourcetracker, 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /internal/controller/account/directory/zz_setup.go: -------------------------------------------------------------------------------- 1 | package directory 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | apisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/btp" 12 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 13 | "github.com/sap/crossplane-provider-btp/internal/tracking" 14 | ) 15 | 16 | // Setup adds a controller that reconciles GlobalAccount managed resources. 17 | func Setup(mgr ctrl.Manager, o controller.Options) error { 18 | return providerconfig.DefaultSetup(mgr, o, &apisv1alpha1.Directory{}, apisv1alpha1.DirectoryGroupKind, apisv1alpha1.DirectoryGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | newServiceFn: btp.NewBTPClient, 23 | newDirHandlerFn: newDirHandlerFn, 24 | resourcetracker: resourcetracker, 25 | } 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /internal/controller/oidc/kubeconfiggenerator/kubeconfigclient_mock.go: -------------------------------------------------------------------------------- 1 | package kubeconfiggenerator 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | "github.com/sap/crossplane-provider-btp/internal/clients/oidc" 6 | ) 7 | 8 | var _ oidc.KubeConfigClient = &KubeConfigClientMock{} 9 | 10 | var errGenerate = errors.New("Generate error") 11 | 12 | var ( 13 | MockedKubeConfigHash = []byte("KUBECONFIGHASH") 14 | MockedTokenHash = []byte("TOKENHASH") 15 | ) 16 | 17 | type KubeConfigClientMock struct { 18 | UpToDate bool 19 | GeneratedContent string 20 | ServerUrl string 21 | } 22 | 23 | func (k *KubeConfigClientMock) WithHashes(kubeConfigHash []byte, tokenHash []byte) oidc.KubeConfigClient { 24 | return k 25 | } 26 | 27 | func (k *KubeConfigClientMock) IsUpToDate(kubeConfig []byte, token []byte) bool { 28 | return k.UpToDate 29 | } 30 | 31 | func (k *KubeConfigClientMock) Generate(kubeConfig []byte, token []byte, config *oidc.GenerateConfig) (oidc.GenerateResult, error) { 32 | if k.GeneratedContent == "" { 33 | return oidc.GenerateResult{}, errGenerate 34 | } 35 | return oidc.GenerateResult{ 36 | SourceKubeConfigHash: MockedKubeConfigHash, 37 | SourceTokenHash: MockedTokenHash, 38 | GeneratedKubeConfig: []byte(k.GeneratedContent), 39 | ServerUrl: k.ServerUrl, 40 | }, nil 41 | } 42 | -------------------------------------------------------------------------------- /internal/controller/security/rolecollectionassignment/zz_setup.go: -------------------------------------------------------------------------------- 1 | package rolecollectionassignment 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/sap/crossplane-provider-btp/apis/security/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 12 | "github.com/sap/crossplane-provider-btp/internal/tracking" 13 | ) 14 | 15 | // Setup adds a controller that reconciles GlobalAccount managed resources. 16 | func Setup(mgr ctrl.Manager, o controller.Options) error { 17 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.RoleCollectionAssignment{}, v1alpha1.RoleCollectionAssignmentGroupKind, v1alpha1.RoleCollectionAssignmentGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 18 | return &connector{ 19 | kube: kube, 20 | usage: usage, 21 | newUserAssignerFn: configureUserAssignerFn, 22 | newGroupAssignerFn: configureGroupAssignerFn, 23 | resourcetracker: resourcetracker, 24 | } 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /internal/controller/account/servicebinding/zz_setup.go: -------------------------------------------------------------------------------- 1 | package servicebinding 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | ctrl "sigs.k8s.io/controller-runtime" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 11 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 12 | "github.com/sap/crossplane-provider-btp/internal/tracking" 13 | ) 14 | 15 | // Setup adds a controller that reconciles ServiceBinding managed resources. 16 | func Setup(mgr ctrl.Manager, o controller.Options) error { 17 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.ServiceBinding{}, v1alpha1.ServiceBindingGroupKind, v1alpha1.ServiceBindingGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 18 | tfConnector := newTfConnectorFn(kube) 19 | return &connector{ 20 | kube: kube, 21 | usage: usage, 22 | resourcetracker: resourcetracker, 23 | clientFactory: newServiceBindingClientFactory(kube, tfConnector), 24 | newSBKeyRotatorFn: newSBKeyRotatorFn, 25 | } 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /apis/account/v1beta1/zz_generated.managedlist.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by angryjet. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import resource "github.com/crossplane/crossplane-runtime/pkg/resource" 22 | 23 | // GetItems of this CloudManagementList. 24 | func (l *CloudManagementList) GetItems() []resource.Managed { 25 | items := make([]resource.Managed, len(l.Items)) 26 | for i := range l.Items { 27 | items[i] = &l.Items[i] 28 | } 29 | return items 30 | } 31 | 32 | // GetItems of this ServiceManagerList. 33 | func (l *ServiceManagerList) GetItems() []resource.Managed { 34 | items := make([]resource.Managed, len(l.Items)) 35 | for i := range l.Items { 36 | items[i] = &l.Items[i] 37 | } 38 | return items 39 | } 40 | -------------------------------------------------------------------------------- /apis/oidc/v1alpha1/zz_generated.managedlist.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by angryjet. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | import resource "github.com/crossplane/crossplane-runtime/pkg/resource" 22 | 23 | // GetItems of this CertBasedOIDCLoginList. 24 | func (l *CertBasedOIDCLoginList) GetItems() []resource.Managed { 25 | items := make([]resource.Managed, len(l.Items)) 26 | for i := range l.Items { 27 | items[i] = &l.Items[i] 28 | } 29 | return items 30 | } 31 | 32 | // GetItems of this KubeConfigGeneratorList. 33 | func (l *KubeConfigGeneratorList) GetItems() []resource.Managed { 34 | items := make([]resource.Managed, len(l.Items)) 35 | for i := range l.Items { 36 | items[i] = &l.Items[i] 37 | } 38 | return items 39 | } 40 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-accounts-service-api-go/example_usage/api_test.go: -------------------------------------------------------------------------------- 1 | package example_usage 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | openapi "github.com/sap/crossplane-provider-btp/internal/openapi_clients/btp-accounts-service-api-go/pkg" 9 | "golang.org/x/oauth2/clientcredentials" 10 | ) 11 | 12 | func Test_openapi_EnvironmentsApiService(t *testing.T) { 13 | 14 | configuration := openapi.NewConfiguration() 15 | 16 | config := clientcredentials.Config{ 17 | // credentials from local cis binding (referenced by subaccount in providers) 18 | //ClientID: "...", 19 | //ClientSecret: "...", 20 | //TokenURL: "...", 21 | } 22 | 23 | ctx := context.Background() 24 | 25 | configuration.HTTPClient = config.Client(context.Background()) 26 | configuration.Servers = []openapi.ServerConfiguration{{ 27 | // provisioning service url from local cis binding 28 | URL: "https://accounts-service.cfapps.sap.hana.ondemand.com", 29 | }} 30 | 31 | client := openapi.NewAPIClient(configuration) 32 | 33 | t.Run("Test AccountsAPI GetSubaccounts", func(t *testing.T) { 34 | 35 | req := client.SubaccountOperationsAPI.GetSubaccounts(ctx) 36 | 37 | execute, h, err := req.Execute() 38 | if err != nil { 39 | return 40 | } 41 | 42 | fmt.Println(execute) 43 | fmt.Println(h) 44 | fmt.Println(err) 45 | 46 | }) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /internal/controller/environment/kyma/fake/fake.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import ( 4 | "context" 5 | 6 | environments "github.com/sap/crossplane-provider-btp/internal/clients/kymaenvironment" 7 | provisioningclient "github.com/sap/crossplane-provider-btp/internal/openapi_clients/btp-provisioning-service-api-go/pkg" 8 | 9 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 10 | ) 11 | 12 | var _ environments.Client = &MockClient{} 13 | 14 | type MockClient struct { 15 | MockDescribeCluster func(ctx context.Context, input *v1alpha1.KymaEnvironment) (*provisioningclient.BusinessEnvironmentInstanceResponseObject, bool, error) 16 | MockCreateCluster func(ctx context.Context, input *v1alpha1.KymaEnvironment) (string, error) 17 | } 18 | 19 | func (c MockClient) DescribeInstance(ctx context.Context, cr v1alpha1.KymaEnvironment) ( 20 | *provisioningclient.BusinessEnvironmentInstanceResponseObject, 21 | bool, 22 | error, 23 | ) { 24 | return c.MockDescribeCluster(ctx, &cr) 25 | } 26 | func (c MockClient) CreateInstance(ctx context.Context, cr v1alpha1.KymaEnvironment) (string, error) { 27 | return c.MockCreateCluster(ctx, &cr) 28 | } 29 | func (c MockClient) UpdateInstance(ctx context.Context, cr v1alpha1.KymaEnvironment) error { 30 | return nil 31 | } 32 | func (c MockClient) DeleteInstance(ctx context.Context, cr v1alpha1.KymaEnvironment) error { 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-provisioning-service-api-go/example-usage/api_test.go: -------------------------------------------------------------------------------- 1 | package example_usage 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | openapi "github.com/sap/crossplane-provider-btp/internal/openapi_clients/btp-provisioning-service-api-go/pkg" 9 | "golang.org/x/oauth2/clientcredentials" 10 | ) 11 | 12 | func Test_openapi_EnvironmentsApiService(t *testing.T) { 13 | 14 | configuration := openapi.NewConfiguration() 15 | 16 | config := clientcredentials.Config{ 17 | // credentials from local cis binding (referenced by subaccount in providers) 18 | //ClientID: "...", 19 | //ClientSecret: "...", 20 | //TokenURL: "...", 21 | } 22 | 23 | ctx := context.Background() 24 | 25 | configuration.HTTPClient = config.Client(context.Background()) 26 | configuration.Servers = []openapi.ServerConfiguration{{ 27 | // provisioning service url from local cis binding 28 | // URL: "...", 29 | }} 30 | 31 | client := openapi.NewAPIClient(configuration) 32 | 33 | t.Run("Test EnvironmentsApiService GetAvailableEnvironments", func(t *testing.T) { 34 | 35 | req := client.EnvironmentsAPI.GetAvailableEnvironments(ctx) 36 | req = req.Authorization("") 37 | 38 | execute, h, err := req.Execute() 39 | if err != nil { 40 | return 41 | } 42 | 43 | fmt.Println(execute) 44 | fmt.Println(h) 45 | fmt.Println(err) 46 | 47 | }) 48 | 49 | } 50 | -------------------------------------------------------------------------------- /apis/v1alpha1/zz_generated.pc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by angryjet. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | import xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" 22 | 23 | // GetCondition of this ProviderConfig. 24 | func (p *ProviderConfig) GetCondition(ct xpv1.ConditionType) xpv1.Condition { 25 | return p.Status.GetCondition(ct) 26 | } 27 | 28 | // GetUsers of this ProviderConfig. 29 | func (p *ProviderConfig) GetUsers() int64 { 30 | return p.Status.Users 31 | } 32 | 33 | // SetConditions of this ProviderConfig. 34 | func (p *ProviderConfig) SetConditions(c ...xpv1.Condition) { 35 | p.Status.SetConditions(c...) 36 | } 37 | 38 | // SetUsers of this ProviderConfig. 39 | func (p *ProviderConfig) SetUsers(i int64) { 40 | p.Status.Users = i 41 | } 42 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-entitlements-service-api-go/pkg/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | api/openapi.yaml 2 | api_job_management.go 3 | api_manage_assigned_entitlements.go 4 | api_regions_for_global_account.go 5 | client.go 6 | configuration.go 7 | model_api_exception_response_object.go 8 | model_api_exception_response_object_error.go 9 | model_assigned_service_plan_response_object.go 10 | model_assigned_service_plan_subaccount_dto.go 11 | model_assigned_service_response_object.go 12 | model_business_category_response_object.go 13 | model_commercial_model_response_object.go 14 | model_data_center_response_collection.go 15 | model_data_center_response_object.go 16 | model_directory_assignments_patch_update_request_payload.go 17 | model_directory_assignments_patch_update_request_payload_collection.go 18 | model_directory_assignments_request_payload.go 19 | model_directory_assignments_request_payload_collection.go 20 | model_entitled_and_assigned_services_response_object.go 21 | model_entitled_services_response_object.go 22 | model_entitlement_amount_response_object.go 23 | model_external_resource_request_payload.go 24 | model_nesting_error_details_response_object.go 25 | model_service_plan_assignment_request_payload.go 26 | model_service_plan_response_object.go 27 | model_subaccount_service_plan_request_payload.go 28 | model_subaccount_service_plans_request_payload_collection.go 29 | response.go 30 | utils.go 31 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-entitlements-service-api-go/example_usage/api_test.go: -------------------------------------------------------------------------------- 1 | package example_usage 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | openapi "github.com/sap/crossplane-provider-btp/internal/openapi_clients/btp-entitlements-service-api-go/pkg" 9 | "golang.org/x/oauth2/clientcredentials" 10 | ) 11 | 12 | func Test_openapi_EnvironmentsApiService(t *testing.T) { 13 | 14 | configuration := openapi.NewConfiguration() 15 | 16 | config := clientcredentials.Config{ 17 | // credentials from local cis binding (referenced by subaccount in providers) 18 | //ClientID: "...", 19 | //ClientSecret: "...", 20 | //TokenURL: "...", 21 | } 22 | 23 | ctx := context.Background() 24 | 25 | configuration.HTTPClient = config.Client(context.Background()) 26 | configuration.Servers = []openapi.ServerConfiguration{{ 27 | // provisioning service url from local cis binding 28 | URL: "https://entitlements-service.cfapps.sap.hana.ondemand.com", 29 | }} 30 | 31 | client := openapi.NewAPIClient(configuration) 32 | 33 | t.Run("Test EntitlementsAPI GetAvailableEnvironments", func(t *testing.T) { 34 | 35 | req := client.ManageAssignedEntitlementsAPI.GetGlobalAccountAssignments(ctx) 36 | 37 | execute, h, err := req.Execute() 38 | if err != nil { 39 | return 40 | } 41 | 42 | fmt.Println(execute) 43 | fmt.Println(h) 44 | fmt.Println(err) 45 | 46 | }) 47 | 48 | } 49 | -------------------------------------------------------------------------------- /internal/controller/account/directory/fake_client.go: -------------------------------------------------------------------------------- 1 | package directory 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 7 | "github.com/sap/crossplane-provider-btp/internal/clients/directory" 8 | ) 9 | 10 | type MockClient struct { 11 | needsCreation bool 12 | needsCreationErr error 13 | 14 | needsUpdate bool 15 | 16 | createErr error 17 | createResult v1alpha1.Directory 18 | 19 | updateErr error 20 | 21 | deleteErr error 22 | 23 | syncErr error 24 | 25 | available bool 26 | } 27 | 28 | func (d MockClient) IsAvailable() bool { 29 | return d.available 30 | } 31 | 32 | func (d MockClient) SyncStatus(ctx context.Context) error { 33 | return d.syncErr 34 | } 35 | 36 | func (d MockClient) UpdateDirectory(ctx context.Context) (*v1alpha1.Directory, error) { 37 | return nil, d.updateErr 38 | } 39 | 40 | func (d MockClient) CreateDirectory(ctx context.Context) (*v1alpha1.Directory, error) { 41 | return &d.createResult, d.createErr 42 | } 43 | 44 | func (d MockClient) NeedsUpdate(ctx context.Context) (bool, error) { 45 | return d.needsUpdate, nil 46 | } 47 | 48 | func (d MockClient) NeedsCreation(ctx context.Context) (bool, error) { 49 | return d.needsCreation, d.needsCreationErr 50 | } 51 | 52 | func (d MockClient) DeleteDirectory(ctx context.Context) error { 53 | return d.deleteErr 54 | } 55 | 56 | var _ directory.DirectoryClientI = &MockClient{} 57 | -------------------------------------------------------------------------------- /internal/controller/oidc/test_utils.go: -------------------------------------------------------------------------------- 1 | package oidc 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | "github.com/crossplane/crossplane-runtime/pkg/test" 8 | "github.com/pkg/errors" 9 | corev1 "k8s.io/api/core/v1" 10 | "sigs.k8s.io/controller-runtime/pkg/client" 11 | ) 12 | 13 | var ( 14 | ErrNoResource = errors.New("Can't find resource") 15 | ) 16 | 17 | type TrackerMock struct { 18 | wasCalled bool 19 | } 20 | 21 | func (t *TrackerMock) Track(ctx context.Context, mg resource.Managed) error { 22 | t.wasCalled = true 23 | return nil 24 | } 25 | 26 | func MockTracker() resource.Tracker { 27 | return &TrackerMock{} 28 | } 29 | 30 | func MockCertLookup(certs []corev1.Secret, deleteRecorder *string) *test.MockClient { 31 | return &test.MockClient{ 32 | MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error { 33 | secret, ok := obj.(*corev1.Secret) 34 | if !ok { 35 | return errors.New("Unexpected lookup") 36 | } 37 | for _, v := range certs { 38 | if key.Name == v.Name { 39 | secret.Name = v.Name 40 | secret.Data = v.Data 41 | return nil 42 | } 43 | } 44 | return ErrNoResource 45 | }, 46 | MockDelete: func(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error { 47 | if deleteRecorder != nil { 48 | *deleteRecorder = obj.GetName() 49 | } 50 | return nil 51 | }, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/e2e/subaccount_service_binding_v1alpha1_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | 3 | // Code initially generated by test-generator. 4 | 5 | package e2e 6 | 7 | import ( 8 | "context" 9 | "testing" 10 | 11 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 12 | meta_api "github.com/sap/crossplane-provider-btp/apis" 13 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 14 | "sigs.k8s.io/e2e-framework/pkg/envconf" 15 | "sigs.k8s.io/e2e-framework/pkg/features" 16 | ) 17 | 18 | func Test_SubaccountServiceBinding_v1alpha1(t *testing.T) { 19 | t.Skip("skipping test until the feature is implemented") 20 | t.Parallel() 21 | resource := resources.NewResourceTestConfig(nil, "SubaccountServiceBinding") 22 | 23 | fB := features.New(resource.Kind) 24 | fB.WithLabel("kind", resource.Kind) 25 | fB.Setup( 26 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 27 | // as soon as we move to use the xp-testing framework, we can remove this manually setup and use the preconfigured one 28 | r, _ := res.New(cfg.Client().RESTConfig()) 29 | _ = meta_api.AddToScheme(r.GetScheme()) 30 | 31 | t.Logf("Apply %s", resource.Kind) 32 | resources.ImportResources(ctx, t, cfg, resource.Kind) 33 | 34 | return ctx 35 | }, 36 | ) 37 | fB.Assess("create", resource.AssessCreate) 38 | fB.Assess("delete", resource.AssessDelete) 39 | fB.Teardown(resource.Teardown) 40 | 41 | testenv.TestInParallel(t, fB.Feature()) 42 | } 43 | -------------------------------------------------------------------------------- /test/e2e/subaccount_service_instance_v1alpha1_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | 3 | // Code initially generated by test-generator. 4 | 5 | package e2e 6 | 7 | import ( 8 | "context" 9 | "testing" 10 | 11 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 12 | meta_api "github.com/sap/crossplane-provider-btp/apis" 13 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 14 | "sigs.k8s.io/e2e-framework/pkg/envconf" 15 | "sigs.k8s.io/e2e-framework/pkg/features" 16 | ) 17 | 18 | func Test_SubaccountServiceInstance_v1alpha1(t *testing.T) { 19 | t.Skip("skipping test until the feature is implemented") 20 | t.Parallel() 21 | resource := resources.NewResourceTestConfig(nil, "SubaccountServiceInstance") 22 | 23 | fB := features.New(resource.Kind) 24 | fB.WithLabel("kind", resource.Kind) 25 | fB.Setup( 26 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 27 | // as soon as we move to use the xp-testing framework, we can remove this manually setup and use the preconfigured one 28 | r, _ := res.New(cfg.Client().RESTConfig()) 29 | _ = meta_api.AddToScheme(r.GetScheme()) 30 | 31 | t.Logf("Apply %s", resource.Kind) 32 | resources.ImportResources(ctx, t, cfg, resource.Kind) 33 | 34 | return ctx 35 | }, 36 | ) 37 | fB.Assess("create", resource.AssessCreate) 38 | fB.Assess("delete", resource.AssessDelete) 39 | fB.Teardown(resource.Teardown) 40 | 41 | testenv.TestInParallel(t, fB.Feature()) 42 | } 43 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-provisioning-service-api-go/pkg/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | api/openapi.yaml 2 | api_environments.go 3 | api_job_management.go 4 | api_quota_assignments.go 5 | client.go 6 | configuration.go 7 | model_available_environment_response_collection.go 8 | model_available_environment_response_object.go 9 | model_business_environment_instance_response_object.go 10 | model_business_environment_instances_response_collection.go 11 | model_create_environment_instance_binding_request.go 12 | model_create_environment_instance_request_payload.go 13 | model_created_environment_instance_response_object.go 14 | model_delete_environment_instance_binding_response.go 15 | model_environment_instance_binding_metadata.go 16 | model_environment_instance_response_object.go 17 | model_environment_instances_response_collection.go 18 | model_error_response.go 19 | model_get_all_instance_bindings_response.go 20 | model_get_environment_instance_binding_200_response.go 21 | model_get_environment_instance_binding_response.go 22 | model_job_parameter.go 23 | model_job_status_response_object.go 24 | model_label_assignment_request_payload.go 25 | model_labels_response_object.go 26 | model_nesting_error_details_response_object.go 27 | model_quota_resources_response_object.go 28 | model_service_plan_assignments_response_collection.go 29 | model_service_plan_assignments_response_object.go 30 | model_update_environment_instance_request_payload.go 31 | response.go 32 | utils.go 33 | -------------------------------------------------------------------------------- /test/e2e/generator/resource_test.go.tmpl: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | 3 | {{ .Header }} 4 | {{ .GenStatement }} 5 | 6 | package e2e 7 | 8 | import ( 9 | "context" 10 | "testing" 11 | 12 | "github.com/sap/crossplane-provider-btp/{{ .CRD.TypeLocation }}" 13 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 14 | "sigs.k8s.io/e2e-framework/pkg/envconf" 15 | "sigs.k8s.io/e2e-framework/pkg/features" 16 | ) 17 | 18 | func Test_{{ .CRD.Kind }}_{{ .CRD.APIVersion }}(t *testing.T) { 19 | t.Skip("skipping test until the feature is implemented") 20 | t.Parallel() 21 | 22 | resource := resources.ResourceTestConfig{ 23 | Kind: "{{ .CRD.Kind }}", 24 | Obj: &{{ .CRD.APIVersion }}.{{ .CRD.Kind }}{}, 25 | } 26 | 27 | fB := features.New(resource.Kind) 28 | fB.WithLabel("kind", resource.Kind) 29 | fB.Setup( 30 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 31 | // as soon as we move to use the xp-testing framework, we can remove this manually setup and use the preconfigured one 32 | r, _ := res.New(cfg.Client().RESTConfig()) 33 | _ = meta_api.AddToScheme(r.GetScheme()) 34 | 35 | t.Logf("Apply %s", resource.Kind) 36 | resources.ImportResources(ctx, t, cfg, resource.Kind) 37 | 38 | return ctx 39 | }, 40 | ) 41 | fB.Assess("create", resource.AssessCreate) 42 | fB.Assess("delete", resource.AssessDelete) 43 | fB.Teardown(resource.Teardown) 44 | 45 | testenv.TestInParallel(t, fB.Feature()) 46 | } 47 | -------------------------------------------------------------------------------- /cluster/images/crossplane-provider-btp/Makefile: -------------------------------------------------------------------------------- 1 | # ==================================================================================== 2 | # Setup Project 3 | 4 | PLATFORMS := linux_amd64 linux_arm64 5 | include ../../../build/makelib/common.mk 6 | 7 | # ==================================================================================== 8 | # Options 9 | DOCKER_REGISTRY ?= crossplane 10 | IMAGE = $(BUILD_REGISTRY)/crossplane/provider-btp 11 | OSBASEIMAGE = scratch 12 | include ../../../build/makelib/image.mk 13 | 14 | # ==================================================================================== 15 | # Targets 16 | 17 | img.build: 18 | @$(INFO) docker build $(IMAGE) 19 | @cp Dockerfile $(IMAGE_TEMP_DIR) || $(FAIL) 20 | @cp -R ../../../package $(IMAGE_TEMP_DIR) || $(FAIL) 21 | @cd $(IMAGE_TEMP_DIR) && $(SED_CMD) 's|BASEIMAGE|$(OSBASEIMAGE)|g' Dockerfile || $(FAIL) 22 | @cd $(IMAGE_TEMP_DIR) && $(SED_CMD) 's|VERSION|$(VERSION)|g' package/crossplane.yaml || $(FAIL) 23 | @cd $(IMAGE_TEMP_DIR) && $(SED_CMD) 's|DOCKER_REGISTRY|$(BUILD_REGISTRY)|g' package/crossplane.yaml || $(FAIL) 24 | @cd $(IMAGE_TEMP_DIR) && find package -type f -name '*.yaml' -exec cat {} >> 'package.yaml' \; -exec printf '\n---\n' \; || $(FAIL) 25 | @docker build $(BUILD_ARGS) \ 26 | --build-arg GIT_COMMIT="${COMMIT_HASH}" \ 27 | --build-arg BUILD_TIMESTAMP="$(TIME_LONG)" \ 28 | -t $(IMAGE) \ 29 | -t $(IMAGE):$(VERSION) \ 30 | $(IMAGE_TEMP_DIR) || $(FAIL) 31 | @$(OK) docker build $(IMAGE) 32 | -------------------------------------------------------------------------------- /test/e2e/subaccount_service_broker_v1alpha1_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | 3 | // Code initially generated by test-generator. 4 | 5 | package e2e 6 | 7 | import ( 8 | "context" 9 | "testing" 10 | 11 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 12 | meta_api "github.com/sap/crossplane-provider-btp/apis" 13 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 14 | "sigs.k8s.io/e2e-framework/pkg/envconf" 15 | "sigs.k8s.io/e2e-framework/pkg/features" 16 | ) 17 | 18 | func Test_SubaccountServiceBroker_v1alpha1(t *testing.T) { 19 | t.Skip("Requires a working service broker to test, won't be fully implemented until promoting to v1beta1, skipping test until then") 20 | t.Parallel() 21 | 22 | resource := resources.NewResourceTestConfig(nil, "SubaccountServiceBroker") 23 | 24 | fB := features.New(resource.Kind) 25 | fB.WithLabel("kind", resource.Kind) 26 | fB.Setup( 27 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 28 | // as soon as we move to use the xp-testing framework, we can remove this manually setup and use the preconfigured one 29 | r, _ := res.New(cfg.Client().RESTConfig()) 30 | _ = meta_api.AddToScheme(r.GetScheme()) 31 | 32 | t.Logf("Apply %s", resource.Kind) 33 | resources.ImportResources(ctx, t, cfg, resource.Kind) 34 | 35 | return ctx 36 | }, 37 | ) 38 | fB.Assess("create", resource.AssessCreate) 39 | fB.Assess("delete", resource.AssessDelete) 40 | fB.Teardown(resource.Teardown) 41 | 42 | testenv.TestInParallel(t, fB.Feature()) 43 | } 44 | -------------------------------------------------------------------------------- /docs/user/external-name.md: -------------------------------------------------------------------------------- 1 | # External name 2 | 3 | `External name` in `Crossplane` is a key concept that maps `Crossplane` resources to their corresponding external resources in the managed infrastructure. 4 | 5 | ## What is External Name 6 | 7 | The `External name` is an annotation (`crossplane.io/external-name`) that stores the identifier of the actual resource in the external system. It bridges the gap between: 8 | 9 | - Crossplane resource name: The Kubernetes-style name in your cluster 10 | - External resource ID: The actual identifier in the provider's API (e.g., BTP Subaccount ID) 11 | 12 | In the BTP provider you can use the `External name` annotation to import existing recourses. 13 | 14 | ## BTP resources 15 | 16 | To import existing BTP resources you need to add annotation with existing resource identifier 17 | 18 | ```yaml 19 | ... 20 | metadata.annotations.crossplane.io/external-name: 21 | ... 22 | ``` 23 | 24 | ## Generated Data Below 25 | 26 | ### Directory 27 | 28 | - Follows Standard: yes 29 | - Format: Directory GUID (UUID format) 30 | - How to find: 31 | 32 | - UI: Global Account → Account Explorer → Directories → [Select Directory] → Directory ID 33 | - CLI: btp list accounts/directory (field: guid) 34 | 35 | ### Subaccount 36 | 37 | - Follows Standard: yes 38 | - Format: Subaccount GUID (UUID format) 39 | - How to find: 40 | 41 | - UI: Global Account → Account Explorer → Subaccounts → [Select Subaccount] → Subaccount ID 42 | - CLI: btp list accounts/subaccount (field: guid) 43 | -------------------------------------------------------------------------------- /internal/controller/account/resourceusage/enqueue_handlers_test.go: -------------------------------------------------------------------------------- 1 | package resourceusage 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/google/go-cmp/cmp" 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | "k8s.io/apimachinery/pkg/runtime" 9 | "k8s.io/apimachinery/pkg/types" 10 | "sigs.k8s.io/controller-runtime/pkg/handler" 11 | "sigs.k8s.io/controller-runtime/pkg/reconcile" 12 | 13 | "github.com/sap/crossplane-provider-btp/apis/v1alpha1" 14 | ) 15 | 16 | var ( 17 | _ handler.EventHandler = &EnqueueRequestForResourceUsage{} 18 | ) 19 | 20 | type addFn func(item reconcile.Request) 21 | 22 | func (fn addFn) Add(item reconcile.Request) { 23 | fn(item) 24 | } 25 | 26 | func TestAddResourceUsage(t *testing.T) { 27 | name := "coolname" 28 | 29 | cases := map[string]struct { 30 | obj runtime.Object 31 | queue adder 32 | }{ 33 | "NotResourceUsageReferencer": { 34 | queue: addFn(func(got reconcile.Request) { t.Errorf("queue.Add() called unexpectedly") }), 35 | }, 36 | "IsResourceUsageReferencer": { 37 | obj: &v1alpha1.ResourceUsage{ 38 | ObjectMeta: metav1.ObjectMeta{ 39 | Name: name, 40 | }, 41 | }, 42 | queue: addFn( 43 | func(got reconcile.Request) { 44 | want := reconcile.Request{NamespacedName: types.NamespacedName{Name: name}} 45 | if diff := cmp.Diff(want, got); diff != "" { 46 | t.Errorf("-want, +got:\n%s", diff) 47 | } 48 | }, 49 | ), 50 | }, 51 | } 52 | 53 | for _, tc := range cases { 54 | addResourceUsage(tc.obj, tc.queue) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /examples/sample/entitlements.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 4 | kind: Entitlement 5 | metadata: 6 | name: test-12345-cis-entitlement 7 | namespace: default 8 | spec: 9 | forProvider: 10 | serviceName: cis 11 | servicePlanName: local 12 | enable: true 13 | amount: 2 14 | subaccountRef: 15 | name: co-mirza-sa-test 16 | providerConfigRef: 17 | name: account-provider-config 18 | --- 19 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 20 | kind: Entitlement 21 | metadata: 22 | name: cls-entitlement-1 23 | namespace: default 24 | spec: 25 | forProvider: 26 | serviceName: cloud-logging 27 | servicePlanName: standard 28 | amount: 2 29 | subaccountRef: 30 | name: co-mirza-sa-test 31 | providerConfigRef: 32 | name: account-provider-config 33 | --- 34 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 35 | kind: Entitlement 36 | metadata: 37 | name: cls-entitlement-2 38 | namespace: default 39 | spec: 40 | forProvider: 41 | serviceName: cloud-logging 42 | servicePlanName: standard 43 | amount: 1 44 | subaccountRef: 45 | name: co-mirza-sa-test 46 | providerConfigRef: 47 | name: account-provider-config 48 | --- 49 | #apiVersion: account.btp.sap.crossplane.io/v1alpha1 50 | #kind: Entitlement 51 | #metadata: 52 | # name: test-123455-cis-entitlement2 53 | # namespace: default 54 | #spec: 55 | # forProvider: 56 | # serviceName: "cis" 57 | # servicePlanName: "local" 58 | # SubaccountRef: 59 | # name: test-123455 60 | -------------------------------------------------------------------------------- /apis/v1alpha1/zz_generated.pcu.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by angryjet. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | import xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" 22 | 23 | // GetProviderConfigReference of this ProviderConfigUsage. 24 | func (p *ProviderConfigUsage) GetProviderConfigReference() xpv1.Reference { 25 | return p.ProviderConfigReference 26 | } 27 | 28 | // GetResourceReference of this ProviderConfigUsage. 29 | func (p *ProviderConfigUsage) GetResourceReference() xpv1.TypedReference { 30 | return p.ResourceReference 31 | } 32 | 33 | // SetProviderConfigReference of this ProviderConfigUsage. 34 | func (p *ProviderConfigUsage) SetProviderConfigReference(r xpv1.Reference) { 35 | p.ProviderConfigReference = r 36 | } 37 | 38 | // SetResourceReference of this ProviderConfigUsage. 39 | func (p *ProviderConfigUsage) SetResourceReference(r xpv1.TypedReference) { 40 | p.ResourceReference = r 41 | } 42 | -------------------------------------------------------------------------------- /internal/clients/oidc/client.go: -------------------------------------------------------------------------------- 1 | package oidc 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/int128/kubelogin/pkg/oidc" 7 | ) 8 | 9 | type LoginPerformer interface { 10 | DoLogin(ctx context.Context) (*oidc.TokenSet, error) 11 | IsExpired(idToken string) bool 12 | Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error) 13 | } 14 | 15 | type KubeConfigClient interface { 16 | WithHashes(kubeConfigHash []byte, tokenHash []byte) KubeConfigClient 17 | IsUpToDate(kubeConfig []byte, token []byte) bool 18 | Generate(kubeConfig []byte, token []byte, config *GenerateConfig) (GenerateResult, error) 19 | } 20 | 21 | type GenerateResult struct { 22 | SourceKubeConfigHash []byte 23 | SourceTokenHash []byte 24 | GeneratedKubeConfig []byte 25 | ServerUrl string 26 | } 27 | 28 | // Configuration to control process of generation kubeconfig from template 29 | type GenerateConfig struct { 30 | userIndex int 31 | setInline bool 32 | } 33 | 34 | // Entry point for building configuration for generate process 35 | func ConfigureGenerate() *GenerateConfig { 36 | return &GenerateConfig{ 37 | userIndex: 0, 38 | setInline: false, 39 | } 40 | } 41 | 42 | // User to injec the user to, starting with index 0 43 | func (gConfig *GenerateConfig) UserIndex(i int) *GenerateConfig { 44 | gConfig.userIndex = i 45 | return gConfig 46 | } 47 | 48 | // If true replaces only token, but leaves rest of user untouched 49 | func (gConfig *GenerateConfig) InjectInline() *GenerateConfig { 50 | gConfig.setInline = true 51 | return gConfig 52 | } 53 | -------------------------------------------------------------------------------- /apis/account/v1alpha1/zz_groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by upjet. DO NOT EDIT. 18 | 19 | // +kubebuilder:object:generate=true 20 | // +groupName=account.btp.sap.crossplane.io 21 | // +versionName=v1alpha1 22 | package v1alpha1 23 | 24 | import ( 25 | "k8s.io/apimachinery/pkg/runtime/schema" 26 | "sigs.k8s.io/controller-runtime/pkg/scheme" 27 | ) 28 | 29 | // Package type metadata. 30 | const ( 31 | CRDGroup = "account.btp.sap.crossplane.io" 32 | CRDVersion = "v1alpha1" 33 | ) 34 | 35 | var ( 36 | // CRDGroupVersion is the API Group Version used to register the objects 37 | CRDGroupVersion = schema.GroupVersion{Group: CRDGroup, Version: CRDVersion} 38 | 39 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 40 | SchemeBuilder = &scheme.Builder{GroupVersion: CRDGroupVersion} 41 | 42 | // AddToScheme adds the types in this group-version to the given scheme. 43 | AddToScheme = SchemeBuilder.AddToScheme 44 | ) 45 | -------------------------------------------------------------------------------- /apis/security/v1alpha1/zz_groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by upjet. DO NOT EDIT. 18 | 19 | // +kubebuilder:object:generate=true 20 | // +groupName=security.btp.sap.crossplane.io 21 | // +versionName=v1alpha1 22 | package v1alpha1 23 | 24 | import ( 25 | "k8s.io/apimachinery/pkg/runtime/schema" 26 | "sigs.k8s.io/controller-runtime/pkg/scheme" 27 | ) 28 | 29 | // Package type metadata. 30 | const ( 31 | CRDGroup = "security.btp.sap.crossplane.io" 32 | CRDVersion = "v1alpha1" 33 | ) 34 | 35 | var ( 36 | // CRDGroupVersion is the API Group Version used to register the objects 37 | CRDGroupVersion = schema.GroupVersion{Group: CRDGroup, Version: CRDVersion} 38 | 39 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 40 | SchemeBuilder = &scheme.Builder{GroupVersion: CRDGroupVersion} 41 | 42 | // AddToScheme adds the types in this group-version to the given scheme. 43 | AddToScheme = SchemeBuilder.AddToScheme 44 | ) 45 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-saas-provisioning-api-go/pkg/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | api/openapi.yaml 2 | api_application_operations_for_app_providers.go 3 | api_asynchronous_callback_operations_for_sap_authorization_and_trust_management_service_xsuaa.go 4 | api_job_management.go 5 | api_job_management_for_application_operations_for_app_providers.go 6 | api_subscription_operations_for_app_consumers.go 7 | client.go 8 | configuration.go 9 | model_application_resource_dto.go 10 | model_application_subscriptions_response_object.go 11 | model_batch_update_xsuaa_subscription_dependencies.go 12 | model_create_subscription_request_payload.go 13 | model_dependencies_response_object.go 14 | model_entitled_applications_error_response_object.go 15 | model_entitled_applications_response_collection.go 16 | model_entitled_applications_response_object.go 17 | model_entitled_applications_response_object_metadata.go 18 | model_entitled_applications_response_object_params_schema.go 19 | model_error_response.go 20 | model_error_response_error.go 21 | model_group_version_type.go 22 | model_job_error_response_object.go 23 | model_job_parameter.go 24 | model_job_state_response_object.go 25 | model_job_status_response_object.go 26 | model_label_assignment_request_payload.go 27 | model_nesting_error_details_response_object.go 28 | model_registration_details_response_object.go 29 | model_saas_async_subscription_request_payload.go 30 | model_subscriptions_list_response_object.go 31 | model_update_application_dependencies_request_payload.go 32 | model_update_subscription_request_payload.go 33 | response.go 34 | utils.go 35 | -------------------------------------------------------------------------------- /internal/controller/account/serviceinstance/zz_setup.go: -------------------------------------------------------------------------------- 1 | package serviceinstance 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 8 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 9 | "github.com/sap/crossplane-provider-btp/internal/tracking" 10 | "sigs.k8s.io/controller-runtime/pkg/client" 11 | 12 | ctrl "sigs.k8s.io/controller-runtime" 13 | ) 14 | 15 | // Setup adds a controller that reconciles ServiceInstance managed resources. 16 | func Setup(mgr ctrl.Manager, o controller.Options) error { 17 | return providerconfig.DefaultSetup(mgr, o, &v1alpha1.ServiceInstance{}, v1alpha1.ServiceInstanceGroupKind, v1alpha1.ServiceInstanceGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 18 | return &connector{ 19 | kube: kube, 20 | usage: usage, 21 | 22 | newServicePlanInitializerFn: newServicePlanInitializerFn, 23 | 24 | // instead of passing the creatorFn as usual we need to execute here to make sure the connector has only one instance of the client 25 | // this is required to ensure terraform workspace is shared among reconciliation loops, since the state of async operations is stored in the client 26 | clientConnector: newClientCreatorFn(mgr.GetClient()), 27 | resourcetracker: resourcetracker, 28 | } 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /internal/controller/account/resourceusage/setup.go: -------------------------------------------------------------------------------- 1 | package resourceusage 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/resource" 5 | ctrl "sigs.k8s.io/controller-runtime" 6 | 7 | "github.com/crossplane/crossplane-runtime/pkg/controller" 8 | "github.com/crossplane/crossplane-runtime/pkg/event" 9 | "github.com/crossplane/crossplane-runtime/pkg/ratelimiter" 10 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/providerconfig" 11 | 12 | "github.com/sap/crossplane-provider-btp/apis/v1alpha1" 13 | ) 14 | 15 | const ( 16 | errGetPC = "cannot get ResourceUsage" 17 | errGetCreds = "cannot get credentials" 18 | errTrackRUsage = "cannot track ResourceUsage" 19 | errTrackPCUsage = "cannot track ResourceUsage usage" 20 | errNewClient = "cannot create new Service" 21 | ) 22 | 23 | // Setup adds a controller that reconciles ResourceUsages by accounting for 24 | // their current usage. 25 | func Setup(mgr ctrl.Manager, o controller.Options) error { 26 | name := providerconfig.ControllerName(v1alpha1.ResourceUsageGroupKind) 27 | 28 | r := NewReconciler( 29 | mgr, 30 | WithLogger(o.Logger.WithValues("controller", name)), 31 | WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), 32 | ) 33 | 34 | return ctrl.NewControllerManagedBy(mgr). 35 | Named(name). 36 | WithOptions(o.ForControllerRuntime()). 37 | For(&v1alpha1.ResourceUsage{}). 38 | Watches(&v1alpha1.ResourceUsage{}, &EnqueueRequestForResourceUsage{}). 39 | WithEventFilter(resource.DesiredStateChanged()). 40 | Complete(ratelimiter.NewReconciler(name, r, o.GlobalRateLimiter)) 41 | } 42 | -------------------------------------------------------------------------------- /internal/controller/account/subaccount/api_accessor.go: -------------------------------------------------------------------------------- 1 | package subaccount 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/pkg/errors" 7 | "github.com/sap/crossplane-provider-btp/btp" 8 | accountclient "github.com/sap/crossplane-provider-btp/internal/openapi_clients/btp-accounts-service-api-go/pkg" 9 | ) 10 | 11 | // AccountsApiAccessor abstraction to handle API operations by coordinating to generated api client 12 | type AccountsApiAccessor interface { 13 | MoveSubaccount(ctx context.Context, subaccountGuid string, targetId string) error 14 | UpdateSubaccount(ctx context.Context, subaccountGuid string, payload accountclient.UpdateSubaccountRequestPayload) error 15 | } 16 | 17 | type AccountsClient struct { 18 | btp btp.Client 19 | } 20 | 21 | func (a *AccountsClient) UpdateSubaccount(ctx context.Context, subaccountGuid string, payload accountclient.UpdateSubaccountRequestPayload) error { 22 | _, _, err := a.btp.AccountsServiceClient.SubaccountOperationsAPI. 23 | UpdateSubaccount(ctx, subaccountGuid). 24 | UpdateSubaccountRequestPayload(payload). 25 | Execute() 26 | return err 27 | } 28 | 29 | func (a *AccountsClient) MoveSubaccount(ctx context.Context, subaccountGuid string, targetId string) error { 30 | if targetId == "" { 31 | return errors.New("targetId must be set for move subaccount api call") 32 | } 33 | _, _, err := a.btp.AccountsServiceClient.SubaccountOperationsAPI. 34 | MoveSubaccount(ctx, subaccountGuid). 35 | MoveSubaccountRequestPayload( 36 | accountclient.MoveSubaccountRequestPayload{TargetAccountGUID: targetId}). 37 | Execute() 38 | return err 39 | } 40 | 41 | var _ AccountsApiAccessor = &AccountsClient{} 42 | -------------------------------------------------------------------------------- /examples/sample/services.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 3 | kind: ServiceManager 4 | metadata: 5 | name: test-12345 6 | namespace: default 7 | spec: 8 | writeConnectionSecretToRef: 9 | name: service-manager 10 | namespace: default 11 | forProvider: 12 | subaccountRef: 13 | name: test-12345 14 | --- 15 | apiVersion: account.btp.sap.crossplane.io/v1beta1 16 | kind: ServiceManager 17 | metadata: 18 | name: test-12345 19 | namespace: default 20 | spec: 21 | writeConnectionSecretToRef: 22 | name: service-manager 23 | namespace: default 24 | forProvider: 25 | subaccountRef: 26 | name: test-12345 27 | planName: "subaccount-admin" 28 | serviceInstanceName: "service-manager" 29 | serviceBindingName: "service-manager-binding" 30 | --- 31 | apiVersion: account.btp.sap.crossplane.io/v1alpha1 32 | kind: CloudManagement 33 | metadata: 34 | name: cis-local 35 | namespace: default 36 | spec: 37 | writeConnectionSecretToRef: 38 | name: cis-local 39 | namespace: default 40 | forProvider: 41 | serviceManagerRef: 42 | name: test-12345 43 | subaccountRef: 44 | name: test-12345 45 | --- 46 | apiVersion: account.btp.sap.crossplane.io/v1beta1 47 | kind: CloudManagement 48 | metadata: 49 | name: cis-local 50 | namespace: default 51 | spec: 52 | writeConnectionSecretToRef: 53 | name: cis-local 54 | namespace: default 55 | forProvider: 56 | serviceManagerRef: 57 | name: test-12345 58 | subaccountRef: 59 | name: test-12345 60 | serviceInstanceName: "cloud-management" 61 | serviceBindingName: "cloud-management-binding" 62 | -------------------------------------------------------------------------------- /apis/account/v1alpha1/entitlement_types_test.go: -------------------------------------------------------------------------------- 1 | package v1alpha1 2 | 3 | import ( 4 | "testing" 5 | 6 | v1 "github.com/crossplane/crossplane-runtime/apis/common/v1" 7 | corev1 "k8s.io/api/core/v1" 8 | ) 9 | 10 | func TestValidationCondition(t *testing.T) { 11 | type args struct { 12 | validationIssues []string 13 | } 14 | tests := []struct { 15 | name string 16 | args args 17 | want v1.Condition 18 | }{ 19 | { 20 | name: "nil Validation Issue, NoValidationIssue", 21 | args: args{ 22 | validationIssues: nil, 23 | }, 24 | want: v1.Condition{ 25 | Type: SoftValidationCondition, 26 | Status: corev1.ConditionFalse, 27 | Reason: NoValidationIssues, 28 | }, 29 | }, 30 | { 31 | name: "One validation Issue, ValidationIssue", 32 | args: args{ 33 | validationIssues: []string{"asd"}, 34 | }, 35 | want: v1.Condition{ 36 | Type: SoftValidationCondition, 37 | Status: corev1.ConditionTrue, 38 | Reason: HasValidationIssues, 39 | Message: "asd", 40 | }, 41 | }, 42 | { 43 | name: "Multiple validation Issue, ValidationIssue with joind message", 44 | args: args{ 45 | validationIssues: []string{"foo", "bar"}, 46 | }, 47 | want: v1.Condition{ 48 | Type: SoftValidationCondition, 49 | Status: corev1.ConditionTrue, 50 | Reason: HasValidationIssues, 51 | Message: "foo\nbar", 52 | }, 53 | }, 54 | } 55 | for _, tt := range tests { 56 | t.Run(tt.name, func(t *testing.T) { 57 | if got := ValidationCondition(tt.args.validationIssues); !tt.want.Equal(got) { 58 | t.Errorf("ValidationCondition() = %v, want %v", got, tt.want) 59 | } 60 | }) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /config/external_name.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 Upbound Inc. 3 | */ 4 | 5 | package config 6 | 7 | import "github.com/crossplane/upjet/pkg/config" 8 | 9 | // ExternalNameConfigs contains all external name configurations for this 10 | // provider. 11 | var ExternalNameConfigs = map[string]config.ExternalName{ 12 | "btp_subaccount_trust_configuration": config.IdentifierFromProvider, 13 | "btp_globalaccount_trust_configuration": config.IdentifierFromProvider, 14 | "btp_directory_entitlement": config.IdentifierFromProvider, 15 | "btp_subaccount_service_instance": config.IdentifierFromProvider, 16 | "btp_subaccount_service_binding": config.IdentifierFromProvider, 17 | "btp_subaccount_service_broker": config.IdentifierFromProvider, 18 | "btp_subaccount_api_credential": config.IdentifierFromProvider, 19 | } 20 | 21 | // ExternalNameConfigurations applies all external name configs listed in the 22 | // table ExternalNameConfigs and sets the version of those resources to v1beta1 23 | // assuming they will be tested. 24 | func ExternalNameConfigurations() config.ResourceOption { 25 | return func(r *config.Resource) { 26 | if e, ok := ExternalNameConfigs[r.Name]; ok { 27 | r.ExternalName = e 28 | } 29 | } 30 | } 31 | 32 | // ExternalNameConfigured returns the list of all resources whose external name 33 | // is configured manually. 34 | func ExternalNameConfigured() []string { 35 | l := make([]string, len(ExternalNameConfigs)) 36 | i := 0 37 | for name := range ExternalNameConfigs { 38 | // $ is added to match the exact string since the format is regex. 39 | l[i] = name + "$" 40 | i++ 41 | } 42 | return l 43 | } 44 | -------------------------------------------------------------------------------- /test/e2e/cloudfoundry_env_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | // +build e2e 3 | 4 | package e2e 5 | 6 | import ( 7 | "context" 8 | "testing" 9 | "time" 10 | 11 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 12 | meta "github.com/sap/crossplane-provider-btp/apis" 13 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 14 | 15 | "sigs.k8s.io/e2e-framework/klient/wait" 16 | "sigs.k8s.io/e2e-framework/pkg/envconf" 17 | "sigs.k8s.io/e2e-framework/pkg/features" 18 | ) 19 | 20 | func TestCloudFoundryEnvironment(t *testing.T) { 21 | var manifestDir = "testdata/crs/cloudfoundry_env" 22 | 23 | crudFeature := features.New("BTP CF Environment Controller"). 24 | Setup( 25 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 26 | resources.ImportResources(ctx, t, cfg, manifestDir) 27 | r, _ := res.New(cfg.Client().RESTConfig()) 28 | _ = meta.AddToScheme(r.GetScheme()) 29 | return ctx 30 | }, 31 | ). 32 | Assess( 33 | "Await resources to become synced", 34 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 35 | if err := resources.WaitForResourcesToBeSynced(ctx, cfg, manifestDir, nil, wait.WithTimeout(time.Minute*25)); err != nil { 36 | t.Fatal(err) 37 | } 38 | return ctx 39 | }, 40 | ). 41 | Assess( 42 | "Check Resources Delete", 43 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 44 | resources.DeleteResources(ctx, t, cfg, manifestDir, wait.WithTimeout(time.Minute*25)) 45 | return ctx 46 | }, 47 | ). 48 | Teardown(resources.DumpManagedResources). 49 | Feature() 50 | 51 | testenv.Test(t, crudFeature) 52 | } 53 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-accounts-service-api-go/pkg/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | api/openapi.yaml 2 | api_directory_operations.go 3 | api_global_account_operations.go 4 | api_job_management.go 5 | api_subaccount_operations.go 6 | client.go 7 | configuration.go 8 | model_add_property_request_payload.go 9 | model_api_exception_response_object.go 10 | model_api_exception_response_object_error.go 11 | model_clone_neo_subaccount_request_payload.go 12 | model_create_directory_request_payload.go 13 | model_create_service_manager_binding_request_payload.go 14 | model_create_subaccount_request_payload.go 15 | model_data_response_object.go 16 | model_directory_response_object.go 17 | model_entity_settings_request_payload.go 18 | model_global_account_response_object.go 19 | model_label_assignment_request_payload.go 20 | model_labels_response_object.go 21 | model_legal_links_dto.go 22 | model_move_subaccount_request_payload.go 23 | model_move_subaccounts_request_payload.go 24 | model_move_subaccounts_request_payload_collection.go 25 | model_nesting_error_details_response_object.go 26 | model_property_data_response_object.go 27 | model_property_response_object.go 28 | model_response_collection.go 29 | model_service_manager_binding_extended_response_object.go 30 | model_service_manager_binding_response_object.go 31 | model_service_manager_bindings_response_list.go 32 | model_subaccount_response_object.go 33 | model_update_directory_request_payload.go 34 | model_update_directory_type_request_payload.go 35 | model_update_entity_settings_request_payload.go 36 | model_update_global_account_request_payload.go 37 | model_update_property_request_payload.go 38 | model_update_subaccount_request_payload.go 39 | response.go 40 | utils.go 41 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-xsuaa-service-api-go/pkg/response.go: -------------------------------------------------------------------------------- 1 | /* 2 | SAP XSUAA REST API 3 | 4 | Provides access to RoleTemplates, Roles, RoleCollection etc. using the XSUAA REST API 5 | 6 | API version: 1.0.0 7 | */ 8 | 9 | // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. 10 | 11 | package openapi 12 | 13 | import ( 14 | "net/http" 15 | ) 16 | 17 | // APIResponse stores the API response returned by the server. 18 | type APIResponse struct { 19 | *http.Response `json:"-"` 20 | Message string `json:"message,omitempty"` 21 | // Operation is the name of the OpenAPI operation. 22 | Operation string `json:"operation,omitempty"` 23 | // RequestURL is the request URL. This value is always available, even if the 24 | // embedded *http.Response is nil. 25 | RequestURL string `json:"url,omitempty"` 26 | // Method is the HTTP method used for the request. This value is always 27 | // available, even if the embedded *http.Response is nil. 28 | Method string `json:"method,omitempty"` 29 | // Payload holds the contents of the response body (which may be nil or empty). 30 | // This is provided here as the raw response.Body() reader will have already 31 | // been drained. 32 | Payload []byte `json:"-"` 33 | } 34 | 35 | // NewAPIResponse returns a new APIResponse object. 36 | func NewAPIResponse(r *http.Response) *APIResponse { 37 | 38 | response := &APIResponse{Response: r} 39 | return response 40 | } 41 | 42 | // NewAPIResponseWithError returns a new APIResponse object with the provided error message. 43 | func NewAPIResponseWithError(errorMessage string) *APIResponse { 44 | 45 | response := &APIResponse{Message: errorMessage} 46 | return response 47 | } 48 | -------------------------------------------------------------------------------- /internal/clients/kymamodule/client.go: -------------------------------------------------------------------------------- 1 | package kymamodule 2 | 3 | import ( 4 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | ) 7 | 8 | // KymaCr is the Schema for the KymaCR inside the Kyma Cluster. 9 | // ref https://github.com/kyma-project/cli/blob/838d9b9e8506489da336bf790e4814fbe1caba0b/internal/kube/kyma/types.go#L97 10 | type KymaCr struct { 11 | metav1.TypeMeta `json:",inline"` 12 | metav1.ObjectMeta `json:"metadata,omitempty"` 13 | 14 | Spec KymaSpec `json:"spec,omitempty"` 15 | Status KymaStatus `json:"status,omitempty"` 16 | } 17 | 18 | // KymaSpec defines the desired state of Kyma. 19 | // ref https://github.com/kyma-project/cli/blob/838d9b9e8506489da336bf790e4814fbe1caba0b/internal/kube/kyma/types.go#L106 20 | type KymaSpec struct { 21 | Channel string `json:"channel"` 22 | Modules []Module `json:"modules,omitempty"` 23 | } 24 | 25 | // KymaStatus defines the observed state of Kyma 26 | // ref https://github.com/kyma-project/cli/blob/838d9b9e8506489da336bf790e4814fbe1caba0b/internal/kube/kyma/types.go#L121 27 | type KymaStatus struct { 28 | Modules []v1alpha1.ModuleStatus `json:"modules,omitempty"` 29 | } 30 | 31 | // Module defines the components to be installed. 32 | // ref https://github.com/kyma-project/cli/blob/838d9b9e8506489da336bf790e4814fbe1caba0b/internal/kube/kyma/types.go#L112 33 | type Module struct { 34 | Name string `json:"name"` 35 | ControllerName string `json:"controller,omitempty"` 36 | Channel string `json:"channel,omitempty"` 37 | CustomResourcePolicy string `json:"customResourcePolicy,omitempty"` 38 | Managed *bool `json:"managed,omitempty"` 39 | } 40 | -------------------------------------------------------------------------------- /internal/clients/account/servicebinding/naming.go: -------------------------------------------------------------------------------- 1 | package servicebindingclient 2 | 3 | import ( 4 | "math/rand" 5 | "strings" 6 | "sync" 7 | "time" 8 | 9 | "k8s.io/apimachinery/pkg/types" 10 | ) 11 | 12 | const letterBytes = "abcdefghijklmnopqrstuvwxyz1234567890" 13 | 14 | const ( 15 | letterIdxBits = 6 // 6 bits to represent a letter index 16 | letterIdxMask = 1<= 0; { 33 | if remain == 0 { 34 | cache, remain = src.Int63(), letterIdxMax 35 | } 36 | if idx := int(cache & letterIdxMask); idx < len(letterBytes) { 37 | sb.WriteByte(letterBytes[idx]) 38 | i-- 39 | } 40 | cache >>= letterIdxBits 41 | remain-- 42 | } 43 | 44 | return sb.String() 45 | } 46 | 47 | // Trailing dashes in the source name are ignored 48 | func GenerateRandomName(name string) string { 49 | if len(name) > 0 && name[len(name)-1] == '-' { 50 | name = name[:len(name)-1] 51 | } 52 | newName := name + "-" + RandomString(5) 53 | return newName 54 | } 55 | 56 | // GenerateInstanceUID creates a deterministic UID by combining the original ServiceBinding UID with the instance name 57 | func GenerateInstanceUID(originalUID types.UID, instanceName string) types.UID { 58 | combined := string(originalUID) + "-" + instanceName 59 | return types.UID(combined) 60 | } 61 | -------------------------------------------------------------------------------- /internal/controller/environment/cloudfoundry/fake/fake.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/sap/crossplane-provider-btp/apis/environment/v1alpha1" 7 | environments "github.com/sap/crossplane-provider-btp/internal/clients/cfenvironment" 8 | provisioningclient "github.com/sap/crossplane-provider-btp/internal/openapi_clients/btp-provisioning-service-api-go/pkg" 9 | ) 10 | 11 | type MockClient struct { 12 | MockDescribeCluster func(cr v1alpha1.CloudFoundryEnvironment) (*provisioningclient.BusinessEnvironmentInstanceResponseObject, []v1alpha1.User, error) 13 | MockCreate func(cr v1alpha1.CloudFoundryEnvironment) (string, error) 14 | MockDelete func(cr v1alpha1.CloudFoundryEnvironment) error 15 | MockUpdate func(cr v1alpha1.CloudFoundryEnvironment) error 16 | 17 | MockNeedsUpdate func(cr v1alpha1.CloudFoundryEnvironment) bool 18 | } 19 | 20 | func (m MockClient) NeedsUpdate(cr v1alpha1.CloudFoundryEnvironment) bool { 21 | return m.MockNeedsUpdate(cr) 22 | } 23 | 24 | func (m MockClient) DescribeInstance(ctx context.Context, cr v1alpha1.CloudFoundryEnvironment) (*provisioningclient.BusinessEnvironmentInstanceResponseObject, []v1alpha1.User, error) { 25 | return m.MockDescribeCluster(cr) 26 | } 27 | 28 | func (m MockClient) CreateInstance(ctx context.Context, cr v1alpha1.CloudFoundryEnvironment) (string, error) { 29 | return m.MockCreate(cr) 30 | } 31 | 32 | func (m MockClient) UpdateInstance(ctx context.Context, cr v1alpha1.CloudFoundryEnvironment) error { 33 | return m.MockUpdate(cr) 34 | } 35 | 36 | func (m MockClient) DeleteInstance(ctx context.Context, cr v1alpha1.CloudFoundryEnvironment) error { 37 | return m.MockDelete(cr) 38 | } 39 | 40 | var _ environments.Client = &MockClient{} 41 | -------------------------------------------------------------------------------- /test/e2e/subaccount_api_credential_integration_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | // +build e2e 3 | 4 | package e2e 5 | 6 | import ( 7 | "context" 8 | "testing" 9 | "time" 10 | 11 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 12 | 13 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 14 | 15 | meta "github.com/sap/crossplane-provider-btp/apis" 16 | 17 | "sigs.k8s.io/e2e-framework/klient/wait" 18 | "sigs.k8s.io/e2e-framework/pkg/envconf" 19 | "sigs.k8s.io/e2e-framework/pkg/features" 20 | ) 21 | 22 | func TestSubaccountApiCredentialsIntegration(t *testing.T) { 23 | var manifestDir = "testdata/crs/SubaccountApiCredentialsIntegration" 24 | crudFeature := features.New("SubaccountApiCredentials Integration Creation Flow"). 25 | Setup( 26 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 27 | resources.ImportResources(ctx, t, cfg, manifestDir) 28 | r, _ := res.New(cfg.Client().RESTConfig()) 29 | _ = meta.AddToScheme(r.GetScheme()) 30 | return ctx 31 | }, 32 | ). 33 | Assess( 34 | "Await resources to become synced", 35 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 36 | if err := resources.WaitForResourcesToBeSynced(ctx, cfg, manifestDir, nil, wait.WithTimeout(time.Minute*7)); err != nil { 37 | t.Fatal(err) 38 | } 39 | return ctx 40 | }, 41 | ). 42 | Assess( 43 | "Check Resources Delete", 44 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 45 | resources.DeleteResources(ctx, t, cfg, manifestDir, wait.WithTimeout(time.Minute*7)) 46 | return ctx 47 | }, 48 | ). 49 | Teardown(resources.DumpManagedResources). 50 | Feature() 51 | 52 | testenv.Test(t, crudFeature) 53 | } 54 | -------------------------------------------------------------------------------- /apis/zz_register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by upjet. DO NOT EDIT. 18 | 19 | // Package apis contains Kubernetes API for the provider. 20 | package apis 21 | 22 | import ( 23 | "k8s.io/apimachinery/pkg/runtime" 24 | 25 | v1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 26 | v1alpha1security "github.com/sap/crossplane-provider-btp/apis/security/v1alpha1" 27 | v1alpha1apis "github.com/sap/crossplane-provider-btp/apis/v1alpha1" 28 | v1beta1 "github.com/sap/crossplane-provider-btp/apis/v1beta1" 29 | ) 30 | 31 | func init() { 32 | // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back 33 | AddToSchemes = append(AddToSchemes, 34 | v1alpha1.SchemeBuilder.AddToScheme, 35 | v1alpha1security.SchemeBuilder.AddToScheme, 36 | v1alpha1apis.SchemeBuilder.AddToScheme, 37 | v1beta1.SchemeBuilder.AddToScheme, 38 | ) 39 | } 40 | 41 | // AddToSchemes may be used to add all resources defined in the project to a Scheme 42 | var AddToSchemes runtime.SchemeBuilder 43 | 44 | // AddToScheme adds all Resources to the Scheme 45 | func AddToScheme(s *runtime.Scheme) error { 46 | return AddToSchemes.AddToScheme(s) 47 | } 48 | -------------------------------------------------------------------------------- /hack/helpers/controller/KIND_LOWER/KIND_LOWER_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package {{ .Env.KIND | strings.ToLower }} 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/google/go-cmp/cmp" 8 | 9 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 10 | "github.com/crossplane/crossplane-runtime/pkg/resource" 11 | "github.com/crossplane/crossplane-runtime/pkg/test" 12 | ) 13 | 14 | // Unlike many Kubernetes projects Crossplane does not use third party testing 15 | // libraries, per the common Go test review comments. Crossplane encourages the 16 | // use of table driven unit tests. The tests of the crossplane-runtime project 17 | // are representative of the testing style Crossplane encourages. 18 | // 19 | // https://github.com/golang/go/wiki/TestComments 20 | // https://github.com/crossplane/crossplane/blob/master/CONTRIBUTING.md#contributing-code 21 | 22 | func TestObserve(t *testing.T) { 23 | type fields struct { 24 | service interface{} 25 | } 26 | 27 | type args struct { 28 | ctx context.Context 29 | mg resource.Managed 30 | } 31 | 32 | type want struct { 33 | o managed.ExternalObservation 34 | err error 35 | } 36 | 37 | cases := map[string]struct { 38 | reason string 39 | fields fields 40 | args args 41 | want want 42 | }{ 43 | // TODO: Add test cases. 44 | } 45 | 46 | for name, tc := range cases { 47 | t.Run(name, func(t *testing.T) { 48 | e := external{service: tc.fields.service} 49 | got, err := e.Observe(tc.args.ctx, tc.args.mg) 50 | if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { 51 | t.Errorf("\n%s\ne.Observe(...): -want error, +got error:\n%s\n", tc.reason, diff) 52 | } 53 | if diff := cmp.Diff(tc.want.o, got); diff != "" { 54 | t.Errorf("\n%s\ne.Observe(...): -want, +got:\n%s\n", tc.reason, diff) 55 | } 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /internal/clients/oidc/test_keystores/legacy-openssl/key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCYvLg4Da6bHQfV 3 | hFGotqeBWHL7ZLmZISIyVUvO/dSC3dlzrFqugyrLrlMU26IZW7OVu6QEBAOhhvCF 4 | HsSo4iI0IXxSopV9lP32lTf+l21lCRJM+IDB9M+AgmrCnhwTL4uz04BC7YTXV3J6 5 | NrzeeYlHMD5JP9R+B2CF9k/frVBpvpyKNWuh0KQZoHxFOVhGAXZEDKAix7pRa0Q8 6 | kezPDmNo8crMm+JhZ6zmJWd3JbnGMfjzHQZ79Y7wCOsmzv7brnnGYFT1ZiAPIJau 7 | wP0IRfBDTZlJdzayMzOdpwd5nQqlIcSREV5GUY510m2nuYwZdXW4Ae/Hhe9qoBEL 8 | P2Fa8PF3AgMBAAECggEAZH7fszoFZdgfHHT4icrMwgVhelmW6NNtPbLzs1k+J3Ez 9 | L7H65JI3aVblIXc12/uDWQTicSX3AaPYw64v9XL80FIsC+8f70ZGJ6Wc9y3Jc84Z 10 | NX3YskWS9lpZRn5juJfzEroZzW+clVfbYeB8OuG62pU6llWiSd4uu1YKzgCqRThx 11 | /UMkLaURWPNa+HoWOoEhvQsEbCju7+0DiK8eogD1d30A1ze2m6QKQ1yZAdgz5yki 12 | JF/U60PrntOelYc3i6yg61QCuEpey0anxZzjF4oeyYR6PEN9HYiq5SWIyGRlMWv4 13 | I0SZ2MUWm4SQQ6YT57MI2uwO0DZx44/yg1BYVs9AeQKBgQD+7lsF9iNcnahaQ0tz 14 | FM4Z+43HiEYScUuCM2Z2K0YfVpGsWRJlcImB+NE7odSz73Y431D82OafxXTTr8Vg 15 | ltVc8JnmhzHwQydUYLBUgrMEzhT4X2eoFMHhBm3W5nSNdjq3aMWlGP6C3NiJFWPY 16 | Fe25Hm352zftuQ9u9yDzquR+/QKBgQCZYKsmTXt/1gm30r/T3Xpc6tmicnj+UN0k 17 | /3KH4SQwMVnOYvVRoUUBVOKJ/O5wJw1KS2OjOI8xc7ZYLlS6330GD9NNUbsCsndx 18 | 7Z/Cn47VU+V/TUERTqUhYDp6e3ahotpWYVmOLLspkBZ3x2C+B8yTjB0mPa28k9oz 19 | hzjX4MSugwKBgQCaRcw3s1h6972lwguqvPBssNp/4WvmRUGYrVpYMJ/i3xSQ4+ZK 20 | FOxiBx03pRt/OG6mxB3SpcAK+AdXA4vChATilYfNBgumhj0KxuhufBmx0rTGCZZF 21 | FSqu7qER56yo3t9xlqnk21dKAjPX4WXmon6WBGAxUARsjA1W7Z63VreoUQKBgBoJ 22 | O+RroLxJpCqtPt0DKsNdJoaZ8goRxgiCyHlicZcwuXL8f3JU8vbP5wjPg9ZL+siS 23 | 1Z4eeshFQT3k14NFbt65jwAAEMPbccVINid+mGuEK2AZyCLc+9EXmbWzAadckr25 24 | Fs+4rijXCclZcgWwIz0kusoEDFsHqjG3EaIryJdrAoGAPWokGFVwl++C0x8pdAF9 25 | 94TLA+UmyygWa915u8UhRPndSoScnFgd6eEr7Gn7fx/FFLXMS1UI4/xrm9qjVJDH 26 | HTuWpU6TB+oYSREwEh5JmTgDjskOPB79WYFtKB7aECPN08Wfp1x6QhlWY6uLkaZP 27 | i62vnQN3nqOLSK6ocn/BY2U= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /test/e2e/globalaccount_trust_configuration_v1alpha1_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | 3 | // Code initially generated by test-generator. 4 | 5 | package e2e 6 | 7 | import ( 8 | "context" 9 | "testing" 10 | "time" 11 | 12 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 13 | meta_api "github.com/sap/crossplane-provider-btp/apis" 14 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 15 | "sigs.k8s.io/e2e-framework/klient/wait" 16 | "sigs.k8s.io/e2e-framework/pkg/envconf" 17 | "sigs.k8s.io/e2e-framework/pkg/features" 18 | ) 19 | 20 | func Test_TrustConfiguration_v1alpha1(t *testing.T) { 21 | 22 | resource := resources.ResourceTestConfig{ 23 | Kind: "GlobalaccountTrustConfiguration", 24 | ResourceDirectory: "testdata/crs/GlobalaccountTrustConfiguration", 25 | } 26 | 27 | fB := features.New(resource.Kind) 28 | fB.WithLabel("kind", resource.Kind) 29 | fB.Setup( 30 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 31 | // as soon as we move to use the xp-testing framework, we can remove this manually setup and use the preconfigured one 32 | r, _ := res.New(cfg.Client().RESTConfig()) 33 | _ = meta_api.AddToScheme(r.GetScheme()) 34 | 35 | t.Logf("Apply %s", resource.Kind) 36 | resources.ImportResources(ctx, t, cfg, resource.ResourceDirectory) 37 | 38 | return ctx 39 | }, 40 | ) 41 | fB.Assess("create", 42 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 43 | if err := resources.WaitForResourcesToBeSynced(ctx, cfg, resource.ResourceDirectory, nil, wait.WithTimeout(time.Minute*7)); err != nil { 44 | resources.DumpManagedResources(ctx, t, cfg) 45 | t.Fatal(err) 46 | } 47 | return ctx 48 | }, 49 | ) 50 | fB.Assess("delete", resource.AssessDelete) 51 | fB.Teardown(resource.Teardown) 52 | 53 | testenv.Test(t, fB.Feature()) 54 | } 55 | -------------------------------------------------------------------------------- /internal/controller/account/globalaccount/globalaccount_test.go: -------------------------------------------------------------------------------- 1 | package globalaccount 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/google/go-cmp/cmp" 8 | 9 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 10 | "github.com/crossplane/crossplane-runtime/pkg/resource" 11 | "github.com/crossplane/crossplane-runtime/pkg/test" 12 | 13 | "github.com/sap/crossplane-provider-btp/btp" 14 | ) 15 | 16 | // Unlike many Kubernetes projects Crossplane does not use third party testing 17 | // libraries, per the common Go test review comments. Crossplane encourages the 18 | // use of table driven unit tests. The tests of the crossplane-runtime project 19 | // are representative of the testing style Crossplane encourages. 20 | // 21 | // https://github.com/golang/go/wiki/TestComments 22 | // https://github.com/crossplane/crossplane/blob/master/CONTRIBUTING.md#contributing-code 23 | 24 | func TestObserve(t *testing.T) { 25 | type fields struct { 26 | service btp.Client 27 | } 28 | 29 | type args struct { 30 | ctx context.Context 31 | mg resource.Managed 32 | } 33 | 34 | type want struct { 35 | o managed.ExternalObservation 36 | err error 37 | } 38 | 39 | cases := map[string]struct { 40 | reason string 41 | fields fields 42 | args args 43 | want want 44 | }{ 45 | // TODO: Add test cases. 46 | } 47 | 48 | for name, tc := range cases { 49 | t.Run(name, func(t *testing.T) { 50 | e := external{btp: tc.fields.service} 51 | got, err := e.Observe(tc.args.ctx, tc.args.mg) 52 | if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { 53 | t.Errorf("\n%s\ne.Observe(...): -want error, +got error:\n%s\n", tc.reason, diff) 54 | } 55 | if diff := cmp.Diff(tc.want.o, got); diff != "" { 56 | t.Errorf("\n%s\ne.Observe(...): -want, +got:\n%s\n", tc.reason, diff) 57 | } 58 | }) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /apis/environment/v1alpha1/zz_generated.managedlist.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2022 The Crossplane Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by angryjet. DO NOT EDIT. 18 | 19 | package v1alpha1 20 | 21 | import resource "github.com/crossplane/crossplane-runtime/pkg/resource" 22 | 23 | // GetItems of this CloudFoundryEnvironmentList. 24 | func (l *CloudFoundryEnvironmentList) GetItems() []resource.Managed { 25 | items := make([]resource.Managed, len(l.Items)) 26 | for i := range l.Items { 27 | items[i] = &l.Items[i] 28 | } 29 | return items 30 | } 31 | 32 | // GetItems of this KymaEnvironmentBindingList. 33 | func (l *KymaEnvironmentBindingList) GetItems() []resource.Managed { 34 | items := make([]resource.Managed, len(l.Items)) 35 | for i := range l.Items { 36 | items[i] = &l.Items[i] 37 | } 38 | return items 39 | } 40 | 41 | // GetItems of this KymaEnvironmentList. 42 | func (l *KymaEnvironmentList) GetItems() []resource.Managed { 43 | items := make([]resource.Managed, len(l.Items)) 44 | for i := range l.Items { 45 | items[i] = &l.Items[i] 46 | } 47 | return items 48 | } 49 | 50 | // GetItems of this KymaModuleList. 51 | func (l *KymaModuleList) GetItems() []resource.Managed { 52 | items := make([]resource.Managed, len(l.Items)) 53 | for i := range l.Items { 54 | items[i] = &l.Items[i] 55 | } 56 | return items 57 | } 58 | -------------------------------------------------------------------------------- /internal/openapi_clients/btp-service-manager-api-go/pkg/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | api/openapi.yaml 2 | api_agents.go 3 | api_operations.go 4 | api_platforms.go 5 | api_service_bindings.go 6 | api_service_brokers.go 7 | api_service_instances.go 8 | api_service_offerings.go 9 | api_service_plans.go 10 | client.go 11 | configuration.go 12 | model_agent_versions_response_object.go 13 | model_create_by_offering_and_plan_name.go 14 | model_create_by_plan_id.go 15 | model_create_service_binding_request_payload.go 16 | model_create_service_instance_request_payload.go 17 | model_created_service_binding_response_object.go 18 | model_created_service_instance_response_object.go 19 | model_credentials.go 20 | model_credentials_basic.go 21 | model_error.go 22 | model_label.go 23 | model_listed_platform_response_object.go 24 | model_listed_service_binding_response_object.go 25 | model_listed_service_broker_response_object.go 26 | model_listed_service_instance_response_object.go 27 | model_operation_response_object.go 28 | model_platform_response_list.go 29 | model_platform_response_object.go 30 | model_register_platform_request_payload.go 31 | model_registered_platform_response_object.go 32 | model_service_binding_response_list.go 33 | model_service_binding_response_object.go 34 | model_service_broker_response_list.go 35 | model_service_broker_response_object.go 36 | model_service_instance_response_list.go 37 | model_service_instance_response_object.go 38 | model_service_offering_metadata.go 39 | model_service_offering_response_list.go 40 | model_service_offering_response_object.go 41 | model_service_plan_metadata.go 42 | model_service_plan_response_list.go 43 | model_service_plan_response_object.go 44 | model_transitive_resource.go 45 | model_update_platform_request_payload.go 46 | model_update_service_instance_request_payload.go 47 | model_updated_platform_response_object.go 48 | model_updated_service_instance_response_object.go 49 | response.go 50 | utils.go 51 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | SPDX-PackageName = "crossplane-provider-btp" 3 | SPDX-PackageSupplier = "Organization: SAP SE" 4 | SPDX-PackageDownloadLocation = "https://github.com/SAP/crossplane-provider-btp" 5 | SPDX-PackageComment = "The code in this project may include calls to APIs (\"API Calls\") of\n SAP or third-party products or services developed outside of this project\n (\"External Products\").\n \"APIs\" means application programming interfaces, as well as their respective\n specifications and implementing code that allows software to communicate with\n other software.\n API Calls to External Products are not licensed under the open source license\n that governs this project. The use of such API Calls and related External\n Products are subject to applicable additional agreements with the relevant\n provider of the External Products. In no event shall the open source license\n that governs this project grant any rights in or to any External Products, or\n alter, expand or supersede any terms of the applicable additional agreements.\n If you have a valid license agreement with SAP for the use of a particular SAP\n External Product, then you may make use of any API Calls included in this\n project's code for that SAP External Product, subject to the terms of such\n license agreement. If you do not have a valid license agreement for the use of\n a particular SAP External Product, then you may only make use of any API Calls\n in this project for that SAP External Product for your internal, non-productive\n and non-commercial test and evaluation of such API Calls. Nothing herein grants\n you any rights to use or access any SAP External Product, or provide any third\n parties the right to use of access any SAP External Product, through API Calls." 6 | 7 | [[annotations]] 8 | path = "**" 9 | precedence = "closest" 10 | SPDX-FileCopyrightText = "2024 SAP SE or an SAP affiliate company and crossplane-provider-btp contributors" 11 | SPDX-License-Identifier = "Apache-2.0" 12 | -------------------------------------------------------------------------------- /test/e2e/kyma_env_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | // +build e2e 3 | 4 | package e2e 5 | 6 | import ( 7 | "context" 8 | "testing" 9 | "time" 10 | 11 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 12 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 13 | 14 | meta "github.com/sap/crossplane-provider-btp/apis" 15 | 16 | "sigs.k8s.io/e2e-framework/klient/wait" 17 | "sigs.k8s.io/e2e-framework/pkg/envconf" 18 | "sigs.k8s.io/e2e-framework/pkg/features" 19 | ) 20 | 21 | func TestKymaEnvironment(t *testing.T) { 22 | if testing.Short() { 23 | t.Skip("skipping kyma in short mode") 24 | return 25 | } 26 | var manifestDir = "testdata/crs/kyma_env" 27 | crudFeature := features.New("BTP Kyma Environment Controller"). 28 | Setup( 29 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 30 | resources.ImportResources(ctx, t, cfg, manifestDir) 31 | r, _ := res.New(cfg.Client().RESTConfig()) 32 | _ = meta.AddToScheme(r.GetScheme()) 33 | return ctx 34 | }, 35 | ). 36 | Assess( 37 | "Await resources to become synced", 38 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 39 | if err := resources.WaitForResourcesToBeSynced(ctx, cfg, manifestDir, nil, wait.WithTimeout(time.Minute*50)); err != nil { 40 | t.Fatal(err) 41 | } 42 | return ctx 43 | }, 44 | ). 45 | Assess( 46 | "Check Resources Delete", 47 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 48 | resources.DeleteResources(ctx, t, cfg, manifestDir, wait.WithTimeout(time.Minute*50)) 49 | return ctx 50 | }, 51 | ).Teardown( 52 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 53 | DeleteResourcesIgnoreMissing(ctx, t, cfg, manifestDir, wait.WithTimeout(time.Minute*5)) 54 | return ctx 55 | }, 56 | ). 57 | Teardown(resources.DumpManagedResources). 58 | Feature() 59 | 60 | testenv.Test(t, crudFeature) 61 | } 62 | -------------------------------------------------------------------------------- /test/e2e/subaccount_trust_configuration_v1alpha1_test.go: -------------------------------------------------------------------------------- 1 | //go:build e2e 2 | 3 | // Code initially generated by test-generator. 4 | 5 | package e2e 6 | 7 | import ( 8 | "context" 9 | "testing" 10 | "time" 11 | 12 | "github.com/crossplane-contrib/xp-testing/pkg/resources" 13 | meta_api "github.com/sap/crossplane-provider-btp/apis" 14 | "github.com/sap/crossplane-provider-btp/apis/security/v1alpha1" 15 | res "sigs.k8s.io/e2e-framework/klient/k8s/resources" 16 | "sigs.k8s.io/e2e-framework/klient/wait" 17 | "sigs.k8s.io/e2e-framework/pkg/envconf" 18 | "sigs.k8s.io/e2e-framework/pkg/features" 19 | ) 20 | 21 | func Test_SubaccountTrustConfiguration_v1alpha1(t *testing.T) { 22 | resource := resources.ResourceTestConfig{ 23 | Kind: "SubaccountTrustConfiguration", 24 | ResourceDirectory: "testdata/crs/SubaccountTrustConfiguration", 25 | } 26 | 27 | fB := features.New(resource.Kind) 28 | fB.WithLabel("kind", resource.Kind) 29 | fB.Setup( 30 | func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 31 | // as soon as we move to use the xp-testing framework, we can remove this manually setup and use the preconfigured one 32 | r, _ := res.New(cfg.Client().RESTConfig()) 33 | _ = meta_api.AddToScheme(r.GetScheme()) 34 | 35 | t.Logf("Apply %s", resource.Kind) 36 | resources.ImportResources(ctx, t, cfg, resource.ResourceDirectory) 37 | 38 | return ctx 39 | }, 40 | ) 41 | fB.Assess("create", resource.AssessCreate) 42 | fB.Assess("delete", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { 43 | trustConfig := &v1alpha1.SubaccountTrustConfiguration{} 44 | MustGetResource(t, cfg, "e2e-trustconfiguration", nil, trustConfig) 45 | resources.AwaitResourceDeletionOrFail(ctx, t, cfg, trustConfig) 46 | 47 | return DeleteResourcesIgnoreMissing(ctx, t, cfg, resource.Kind, wait.WithTimeout(time.Minute*5)) 48 | }) 49 | fB.Teardown(resource.Teardown) 50 | 51 | testenv.Test(t, fB.Feature()) 52 | } 53 | -------------------------------------------------------------------------------- /internal/controller/account/cloudmanagement/zz_setup.go: -------------------------------------------------------------------------------- 1 | package cloudmanagement 2 | 3 | import ( 4 | "github.com/crossplane/crossplane-runtime/pkg/controller" 5 | "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" 6 | "github.com/crossplane/crossplane-runtime/pkg/resource" 7 | cmClient "github.com/sap/crossplane-provider-btp/internal/clients/cis" 8 | "github.com/sap/crossplane-provider-btp/internal/clients/tfclient" 9 | "github.com/sap/crossplane-provider-btp/internal/di" 10 | ctrl "sigs.k8s.io/controller-runtime" 11 | "sigs.k8s.io/controller-runtime/pkg/client" 12 | 13 | apisv1alpha1 "github.com/sap/crossplane-provider-btp/apis/account/v1alpha1" 14 | apisv1beta1 "github.com/sap/crossplane-provider-btp/apis/account/v1beta1" 15 | 16 | "github.com/sap/crossplane-provider-btp/internal/controller/providerconfig" 17 | "github.com/sap/crossplane-provider-btp/internal/tracking" 18 | ) 19 | 20 | // Setup adds a controller that reconciles CloudManagement managed resources. 21 | func Setup(mgr ctrl.Manager, o controller.Options) error { 22 | return providerconfig.DefaultSetup(mgr, o, &apisv1beta1.CloudManagement{}, apisv1beta1.CloudManagementKind, apisv1beta1.CloudManagementGroupVersionKind, func(kube client.Client, usage resource.Tracker, resourcetracker tracking.ReferenceResolverTracker) managed.ExternalConnecter { 23 | return &connector{ 24 | kube: kube, 25 | usage: usage, 26 | resourcetracker: resourcetracker, 27 | newPlanIdResolverFn: di.NewPlanIdResolverFn, 28 | 29 | newClientInitalizerFn: func() cmClient.ITfClientInitializer { 30 | return cmClient.NewTfClient( 31 | tfclient.NewInternalTfConnector(mgr.GetClient(), "btp_subaccount_service_instance", apisv1alpha1.SubaccountServiceInstance_GroupVersionKind, false, nil), 32 | tfclient.NewInternalTfConnector(mgr.GetClient(), "btp_subaccount_service_binding", apisv1alpha1.SubaccountServiceBinding_GroupVersionKind, false, nil), 33 | ) 34 | }, 35 | } 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /internal/clients/tfclient/tf_async_callback.go: -------------------------------------------------------------------------------- 1 | package tfclient 2 | 3 | import ( 4 | "context" 5 | 6 | ujresource "github.com/crossplane/upjet/pkg/resource" 7 | "github.com/crossplane/upjet/pkg/terraform" 8 | "sigs.k8s.io/controller-runtime/pkg/client" 9 | 10 | "github.com/pkg/errors" 11 | ) 12 | 13 | var errUpdateStatusFmt = "cannot update status of the resource %s after an async %s" 14 | 15 | func NewAPICallbacks(kube client.Client, saveConditionsFn SaveConditionsFn) *APICallbacks { 16 | return &APICallbacks{ 17 | kube: kube, 18 | saveCallbackFn: saveConditionsFn, 19 | } 20 | } 21 | 22 | type APICallbacks struct { 23 | kube client.Client 24 | 25 | saveCallbackFn SaveConditionsFn 26 | } 27 | 28 | // Create makes sure the error is saved in async operation condition. 29 | func (ac *APICallbacks) Create(name string) terraform.CallbackFn { 30 | return func(err error, ctx context.Context) error { 31 | uErr := ac.saveCallbackFn(ctx, ac.kube, name, ujresource.LastAsyncOperationCondition(err), ujresource.AsyncOperationFinishedCondition()) 32 | return errors.Wrapf(uErr, errUpdateStatusFmt, name, "create") 33 | } 34 | } 35 | 36 | // Update makes sure the error is saved in async operation condition. 37 | func (ac *APICallbacks) Update(name string) terraform.CallbackFn { 38 | return func(err error, ctx context.Context) error { 39 | uErr := ac.saveCallbackFn(ctx, ac.kube, name, ujresource.LastAsyncOperationCondition(err), ujresource.AsyncOperationFinishedCondition()) 40 | return errors.Wrapf(uErr, errUpdateStatusFmt, name, "update") 41 | } 42 | } 43 | 44 | // Destroy makes sure the error is saved in async operation condition. 45 | func (ac *APICallbacks) Destroy(name string) terraform.CallbackFn { 46 | return func(err error, ctx context.Context) error { 47 | uErr := ac.saveCallbackFn(ctx, ac.kube, name, ujresource.LastAsyncOperationCondition(err), ujresource.AsyncOperationFinishedCondition()) 48 | return errors.Wrapf(uErr, errUpdateStatusFmt, name, "destroy") 49 | } 50 | } 51 | --------------------------------------------------------------------------------