├── .cfignore ├── .dockerignore ├── .gitignore ├── .gitmodules ├── AUTHORS ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── NOTICE ├── OSDF.txt ├── Procfile ├── README.md ├── TESTING.md ├── brokerapi └── brokers │ ├── broker_config.go │ ├── broker_config_test.go │ ├── brokers_test.go │ └── gcp_service_broker.go ├── ci ├── README.md ├── cloudbuild-release.yaml ├── cloudbuild.yaml └── tasks │ ├── build-server.sh │ ├── bundle.sh │ ├── metadata.sh │ └── osb-integration-tests.sh ├── cmd ├── client.go ├── config.go ├── generate.go ├── pak.go ├── root.go ├── serve.go ├── tf.go └── version.go ├── db_service ├── dao.go ├── dao_generator.go ├── dao_test.go ├── db_service.go ├── migrations.go ├── migrations_test.go ├── models │ ├── db.go │ └── historical_db.go ├── setup_db.go ├── vcap.go └── vcap_test.go ├── deployments └── helm │ └── gcp-service-broker │ ├── .gitignore │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── cf-tutorial.md │ ├── requirements.lock │ ├── requirements.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── clusterservicebroker.yaml │ ├── deployment.yaml │ ├── ingress.yaml │ ├── secrets.yaml │ ├── service.yaml │ └── tests │ │ └── test-connection.yaml │ └── values.yaml ├── docs ├── _config.yml ├── add-builtin-service.md ├── billing.md ├── brokerpak-intro.md ├── brokerpak-specification.md ├── classes │ ├── google-bigquery.md │ ├── google-bigtable.md │ ├── google-cloudsql-mysql-vpc.md │ ├── google-cloudsql-mysql.md │ ├── google-cloudsql-postgres-vpc.md │ ├── google-cloudsql-postgres.md │ ├── google-dataflow.md │ ├── google-datastore.md │ ├── google-dialogflow.md │ ├── google-filestore.md │ ├── google-firestore.md │ ├── google-memorystore-redis.md │ ├── google-ml-apis.md │ ├── google-pubsub.md │ ├── google-spanner.md │ ├── google-stackdriver-debugger.md │ ├── google-stackdriver-monitoring.md │ ├── google-stackdriver-profiler.md │ ├── google-stackdriver-trace.md │ └── google-storage.md ├── customization.md ├── installation.md ├── releasing.md ├── upgrading.md └── use.md ├── gcp_logo.png ├── go.mod ├── go.sum ├── google-brokers ├── cloud-storage.yml ├── dataproc.yml ├── google-redis.yml └── manifest.yml ├── hack ├── build.sh ├── test.sh ├── update-osdf.sh └── verify-generated.sh ├── main.go ├── manifest.yml ├── missing-properties.yml ├── pkg ├── broker │ ├── broker_test.go │ ├── brokerfakes │ │ └── fake_service_provider.go │ ├── catalog.go │ ├── example.go │ ├── policy │ │ ├── policy.go │ │ └── policy_test.go │ ├── registry.go │ ├── registry_test.go │ ├── service_definition.go │ ├── service_provider.go │ ├── variables.go │ └── variables_test.go ├── brokerpak │ ├── cmd.go │ ├── cmd_test.go │ ├── config.go │ ├── config_test.go │ ├── fetch.go │ ├── fetch_test.go │ ├── manifest.go │ ├── manifest_test.go │ ├── platform.go │ ├── platform_test.go │ ├── reader.go │ ├── registrar.go │ ├── registrar_test.go │ ├── testdata │ │ ├── dummy-brokerpaks │ │ │ ├── first.brokerpak │ │ │ ├── not-a-brokerpak │ │ │ └── second.brokerpak │ │ └── no-brokerpaks │ │ │ └── not-a-brokerpak │ ├── tf_resource.go │ └── tf_resource_test.go ├── client │ ├── broker-response.go │ ├── client.go │ ├── example-runner.go │ ├── example-runner_test.go │ └── testdata │ │ └── complete-service-examples-testfile.json ├── config │ └── migration │ │ ├── diff.go │ │ ├── diff_test.go │ │ ├── migration.go │ │ └── migration_test.go ├── generator │ ├── customization-md.go │ ├── forms.go │ ├── pcf-artifacts.go │ └── types.go ├── providers │ ├── builtin │ │ ├── account_managers │ │ │ ├── iam.go │ │ │ ├── iam_test.go │ │ │ ├── service_account_manager.go │ │ │ └── service_account_manager_test.go │ │ ├── base │ │ │ ├── basefakes │ │ │ │ └── fake_service_account_manager.go │ │ │ ├── broker_base.go │ │ │ ├── mixins.go │ │ │ ├── peered_network_service.go │ │ │ └── variables.go │ │ ├── bigquery │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── bigtable │ │ │ ├── broker.go │ │ │ ├── broker_test.go │ │ │ └── definition.go │ │ ├── builtins_test.go │ │ ├── cloudsql │ │ │ ├── broker.go │ │ │ ├── broker_test.go │ │ │ ├── builder.go │ │ │ ├── common-definition.go │ │ │ ├── mysql-definition.go │ │ │ ├── mysql-vpc-definition.go │ │ │ ├── postgres-definition.go │ │ │ ├── postgres-vpc-definition.go │ │ │ ├── sql_account_manager.go │ │ │ └── testdata │ │ │ │ └── golden │ │ │ │ └── Test_createProvisionRequest │ │ │ │ ├── google-cloudsql-mysql-vpc │ │ │ │ ├── Development_Sandbox │ │ │ │ └── HA_Instance │ │ │ │ ├── google-cloudsql-mysql │ │ │ │ ├── Development_Sandbox │ │ │ │ └── HA_Instance │ │ │ │ ├── google-cloudsql-postgres-vpc │ │ │ │ ├── Dedicated_Machine_Sandbox │ │ │ │ └── HA_Instance │ │ │ │ ├── google-cloudsql-postgres │ │ │ │ ├── Dedicated_Machine_Sandbox │ │ │ │ ├── Development_Sandbox │ │ │ │ └── HA_Instance │ │ │ │ └── google-cloudsql-postgresql-vpc │ │ │ │ ├── Dedicated_Machine_Sandbox │ │ │ │ └── HA_Instance │ │ ├── dataflow │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── datastore │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── dialogflow │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── filestore │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── firestore │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── ml │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── pubsub │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── redis │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── registry.go │ │ ├── registry_test.go │ │ ├── spanner │ │ │ ├── broker.go │ │ │ └── definition.go │ │ ├── stackdriver │ │ │ ├── broker.go │ │ │ ├── debugger_definition.go │ │ │ ├── monitoring_definition.go │ │ │ ├── profiler_definition.go │ │ │ └── trace_definition.go │ │ └── storage │ │ │ ├── broker.go │ │ │ └── definition.go │ └── tf │ │ ├── definition.go │ │ ├── definition_test.go │ │ ├── job_runner.go │ │ ├── provider.go │ │ └── wrapper │ │ ├── instance.go │ │ ├── instance_test.go │ │ ├── module.go │ │ ├── module_test.go │ │ ├── tfstate.go │ │ ├── tfstate_test.go │ │ ├── workspace.go │ │ └── workspace_test.go ├── server │ ├── cf_sharing.go │ ├── cf_sharing_test.go │ ├── docs.go │ ├── docs_test.go │ ├── examples.go │ ├── examples_test.go │ ├── fakes │ │ └── servicebroker.go │ ├── health.go │ └── health_test.go ├── toggles │ ├── toggle.go │ └── toggle_test.go ├── validation │ ├── constraint_builder.go │ ├── constraint_builder_test.go │ ├── field_error.go │ ├── field_error_test.go │ ├── struct_validator.go │ └── struct_validator_test.go └── varcontext │ ├── builder.go │ ├── builder_test.go │ ├── interpolation │ ├── eval.go │ ├── eval_test.go │ └── funcs.go │ ├── varcontext.go │ └── varcontext_test.go ├── tile.yml ├── tools └── osdfgen │ ├── .gitignore │ ├── README.md │ ├── go.mod │ ├── go.sum │ ├── osdfgen.go │ └── osdfgen_test.go └── utils ├── set.go ├── set_test.go ├── stream ├── stream.go └── stream_test.go ├── utils.go ├── utils_test.go ├── version.go └── ziputil ├── zip.go └── zip_test.go /.cfignore: -------------------------------------------------------------------------------- 1 | product/ 2 | release/ 3 | integration_tests/ 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .envrc 2 | .idea/ 3 | *.coverprofile 4 | *.DS_Store 5 | *.brokerpak 6 | *.sqlite3 7 | gcp-service-broker 8 | product/ 9 | release/ 10 | tile-history.yml 11 | ci/parameters.yml 12 | ci/vars.yml 13 | config.yml 14 | 15 | !pkg/brokerpak/testdata/dummy-brokerpaks/*.brokerpak 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/gcp-service-broker/2f676b434e3f9d570f3b1d831f81e3a3de8c7664/.gitmodules -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | 1. Pivotal Software, Inc. 2 | 2. Google Inc. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub PR Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM golang:1.14-alpine AS build 16 | 17 | WORKDIR /go/src/github.com/GoogleCloudPlatform/gcp-service-broker 18 | COPY . . 19 | 20 | RUN CGO_ENABLED=0 go build -mod=mod -o /bin/gcp-service-broker 21 | 22 | # Get latest CA certs 23 | FROM alpine:latest as certs 24 | RUN apk --update add ca-certificates 25 | 26 | FROM scratch 27 | 28 | COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt 29 | COPY --from=build /go/src/github.com/GoogleCloudPlatform/gcp-service-broker /src 30 | COPY --from=build /bin/gcp-service-broker /bin/gcp-service-broker 31 | 32 | ENV PORT 8080 33 | EXPOSE 8080/tcp 34 | 35 | WORKDIR /tmp 36 | WORKDIR / 37 | 38 | ENTRYPOINT ["/bin/gcp-service-broker"] 39 | CMD ["help"] 40 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Google Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gcp-service-broker -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## This project is archived 2 | 3 | This project is now deprecated. Please use the https://github.com/cloudfoundry/cloud-service-broker instead which is a fork of this service broker and is actively supported by the community. 4 | 5 | ---- 6 | 7 | ## Open Service Broker for Google Cloud Platform 8 | 9 | This is a service broker built to be used with [Cloud Foundry](https://docs.cloudfoundry.org/services/overview.html) and Kubernetes. 10 | It adheres to the [Open Service Broker API v2.13](https://github.com/openservicebrokerapi/servicebroker/blob/v2.13/spec.md). 11 | 12 | Service brokers provide a consistent way to create resources and accounts that can access those resources across a variety of different services. 13 | 14 | ## Installation 15 | 16 | This application can be installed as either a Tanzu Ops Man Tile _or_ deployed as a Cloud Foundry application. 17 | See the [installation instructions](https://github.com/GoogleCloudPlatform/gcp-service-broker/blob/master/docs/installation.md) for a more detailed walkthrough. 18 | 19 | ## Upgrading 20 | 21 | If you're upgrading, check the [upgrade guide](https://github.com/GoogleCloudPlatform/gcp-service-broker/blob/master/docs/upgrading.md). 22 | 23 | ## Usage 24 | 25 | For operators: see [docs/customization.md](https://github.com/GoogleCloudPlatform/gcp-service-broker/blob/master/docs/customization.md) for details about configuring the service broker. 26 | 27 | For developers: see [docs/use.md](https://github.com/GoogleCloudPlatform/gcp-service-broker/blob/master/docs/use.md) for information about creating and binding specific GCP services with the broker. 28 | Complete Spring Boot sample applications which use services can be found in the [service-broker-samples repository](https://github.com/GoogleCloudPlatform/service-broker-samples). 29 | 30 | You can get documentation specific to your install from the `/docs` endpoint of your deployment. 31 | 32 | ## Commands 33 | 34 | The service broker can be run as both a server (the service broker) and as a general purpose command line utility. 35 | It supports the following sub-commands: 36 | 37 | * `client` - A CLI client for the service broker. 38 | * `config` - Show and merge configuration options together. 39 | * `generate` - Generate documentation and tiles. 40 | * `help` - Help about any command. 41 | * `serve` - Start the service broker. 42 | 43 | ## Support 44 | 45 | **This is not an officially supported Google product.** 46 | 47 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | # Testing Locally 2 | 3 | ## End to End Tests 4 | 5 | The service broker has both unit and end-to-end tests. 6 | End to end tests are generated from the documentation and examples and run outside the standard `go test` framework. 7 | This ensures the auto-generated docs are always up-to-date and the examples work. 8 | By executing the examples as an OSB client, it also ensures the service broker implements the OSB spec correctly. 9 | 10 | To run the suite of end-to-end tests: 11 | 12 | 1. Start an instance of the broker `./gcp-service-broker serve`. 13 | 2. In a separate window, run the examples: `./gcp-service-broker client run-examples` 14 | 3. Wait for the examples to run and check the exit code. Exit codes other than 0 mean the end-to-end tests failed. 15 | 16 | You can also target specific services in the end-to-end tests using the `--service-name` flag. 17 | See `./gcp-service-broker client run-examples --help` for more details. 18 | 19 | ## Database Setup 20 | 21 | You can set up a local MySQL database for testing using Docker: 22 | 23 | ``` 24 | $ docker run -p 3306:3306 --name test-mysql -e MYSQL_ROOT_PASSWORD=password -d mysql:5.7 25 | $ docker exec -it test-mysql mysql -uroot -p 26 | $ mysql> CREATE DATABASE servicebroker; 27 | $ mysql> exit 28 | ``` 29 | 30 | Or, you can run the service broker using SQLite3 for development by specifying 31 | the `db.type` and `db.path` fields: 32 | 33 | ``` 34 | db.type: sqlite3 35 | db.path: service-broker-db.sqlite3 36 | ``` 37 | 38 | ## Database Exploration 39 | 40 | You can debug the database locally using the `show` sub-command. 41 | It will dump a database table as JSON to stdout. 42 | You can dump: `bindings`, `instances`, `migrations`, and `provisions`. 43 | 44 | ``` 45 | $ ./gcp-service-broker --config test.yaml show provisions 46 | [ 47 | { 48 | "ID": 1, 49 | "CreatedAt": "2018-07-17T10:08:07-07:00", 50 | "UpdatedAt": "2018-07-17T10:08:07-07:00", 51 | "DeletedAt": null, 52 | "ServiceInstanceId": "my-cloud-storage", 53 | "RequestDetails": "" 54 | } 55 | ] 56 | ``` 57 | 58 | ## Configuration 59 | 60 | Rather than setting environment variables to run the broker you can use the 61 | settings file below and just set the service account JSON as an environment variable: 62 | 63 | ROOT_SERVICE_ACCOUNT_JSON=$(cat service-account.json) ./gcp-service-broker serve --config testconfig.yml 64 | 65 | 66 | 67 | **testconfig.yml** 68 | 69 | ``` 70 | db: 71 | host: localhost 72 | name: servicebroker 73 | password: password 74 | port: "3306" 75 | user: root 76 | api: 77 | user: user 78 | password: pass 79 | port: 8000 80 | ``` 81 | 82 | 83 | ## Useful commands 84 | 85 | Create unbind commands for all bindings: 86 | 87 | ./gcp-service-broker show bindings | jq --raw-output '.[] | "./gcp-service-broker client unbind --bindingid \(.BindingId) --instanceid \(.ServiceInstanceId) --planid \(.PlanId) --serviceid \(.ServiceId)"' 88 | 89 | Create deprovision commands for all bindings: 90 | 91 | ./gcp-service-broker show instances | jq --raw-output '.[] | "./gcp-service-broker client deprovision --instanceid \(.ID) --serviceid \(.ServiceId) --planid \(.PlanId)"' 92 | -------------------------------------------------------------------------------- /brokerapi/brokers/broker_config.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokers 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/brokerpak" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin" 23 | "github.com/GoogleCloudPlatform/gcp-service-broker/utils" 24 | "golang.org/x/oauth2/jwt" 25 | ) 26 | 27 | type BrokerConfig struct { 28 | HttpConfig *jwt.Config 29 | ProjectId string 30 | Registry broker.BrokerRegistry 31 | } 32 | 33 | func NewBrokerConfigFromEnv() (*BrokerConfig, error) { 34 | projectId, err := utils.GetDefaultProjectId() 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | conf, err := utils.GetAuthedConfig() 40 | if err != nil { 41 | return nil, err 42 | } 43 | 44 | registry := builtin.BuiltinBrokerRegistry() 45 | if err := brokerpak.RegisterAll(registry); err != nil { 46 | return nil, fmt.Errorf("Error loading brokerpaks: %v", err) 47 | } 48 | 49 | return &BrokerConfig{ 50 | ProjectId: projectId, 51 | HttpConfig: conf, 52 | Registry: registry, 53 | }, nil 54 | } 55 | -------------------------------------------------------------------------------- /brokerapi/brokers/broker_config_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokers 16 | 17 | import ( 18 | "os" 19 | "reflect" 20 | "testing" 21 | 22 | "golang.org/x/oauth2/jwt" 23 | ) 24 | 25 | const testServiceAccountJson = `{ 26 | "type": "service_account", 27 | "project_id": "foo", 28 | "private_key_id": "something", 29 | "private_key": "foobar", 30 | "client_email": "example@gmail.com", 31 | "client_id": "1", 32 | "auth_uri": "somelink", 33 | "token_uri": "somelink", 34 | "auth_provider_x509_cert_url": "somelink", 35 | "client_x509_cert_url": "somelink" 36 | }` 37 | 38 | func TestNewBrokerConfigFromEnv(t *testing.T) { 39 | os.Setenv("ROOT_SERVICE_ACCOUNT_JSON", testServiceAccountJson) 40 | defer os.Unsetenv("ROOT_SERVICE_ACCOUNT_JSON") 41 | 42 | cfg, err := NewBrokerConfigFromEnv() 43 | if err != nil { 44 | t.Fatal(err) 45 | } 46 | 47 | t.Run("has-default-client", func(t *testing.T) { 48 | if cfg.HttpConfig == nil { 49 | t.Fatal("Expected HttpCofnig to be non-nil, got: ") 50 | } 51 | 52 | if reflect.DeepEqual(cfg.HttpConfig, &jwt.Config{}) { 53 | t.Errorf("Expected HttpConfig to not be an empty JWT config, got: %#v", cfg.HttpConfig) 54 | } 55 | }) 56 | 57 | t.Run("parsed-projectid-from-config", func(t *testing.T) { 58 | if !reflect.DeepEqual(cfg.ProjectId, "foo") { 59 | t.Errorf("Expected ProjectId to be %v, got: %v", "foo", cfg.ProjectId) 60 | } 61 | }) 62 | } 63 | -------------------------------------------------------------------------------- /ci/README.md: -------------------------------------------------------------------------------- 1 | ## Cloud Build Configuration 2 | 3 | ### Substitutions 4 | The `cloudbuild-release.yaml` template requires two substitutions: 5 | 6 | 1. `COMMIT_SHA`: The git commit (`git rev-parse HEAD`) of the repository being 7 | released 8 | 1. `GS_URL`: The URL of the GCS bucket, including path, that release artifacts 9 | will be uploaded to. For example, `gs://release-bucket/releases` 10 | 11 | ### Secrets 12 | The JSON key for a service account with project owner permissions is required to 13 | run service broker integration tests. That JSON key must be stored in Secrets 14 | Manager in the project where the Cloud Build execution occurs. The secret should 15 | be named `ROOT_SERVICE_ACCOUNT_JSON`. Configure it with these instructions: https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials 16 | 17 | ## Run 18 | 19 | ### Test only 20 | To execute unit and integration tests - but not create a release - run this from 21 | the root of the repository: 22 | 23 | `gcloud builds submit --config=ci/cloudbuild.yaml .` 24 | 25 | ### Release 26 | To execute unit and integration tests and then publish release artifacts to GCS, 27 | run this from the root of the repository: 28 | 29 | ``` 30 | gcloud builds submit \ 31 | --config=ci/cloudbuild-release.yaml \ 32 | --substitutions=COMMIT_SHA=$(git rev-parse HEAD) . 33 | ``` 34 | -------------------------------------------------------------------------------- /ci/cloudbuild-release.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - name: gcr.io/cloud-builders/go 3 | id: unit 4 | args: ['test', '-v', './...', '-tags=service_broker'] 5 | env: 6 | - 'PROJECT_ROOT=github.com/GoogleCloudPlatform/gcp-service-broker' 7 | 8 | - name: gcr.io/cloud-builders/go 9 | id: build 10 | args: ['build', '-o', '/workspace/compiled-broker/gcp-service-broker'] 11 | waitFor: ['-'] 12 | env: 13 | - 'PROJECT_ROOT=github.com/GoogleCloudPlatform/gcp-service-broker' 14 | 15 | - name: gcr.io/cloud-builders/gcloud 16 | id: secrets 17 | entrypoint: 'sh' 18 | args: [ '-c', 'gcloud secrets versions access latest --secret=ROOT_SERVICE_ACCOUNT_JSON > /secrets/sa.json' ] 19 | waitFor: ['-'] 20 | 21 | - name: alpine 22 | id: integration 23 | args: 24 | - 'sh' 25 | - '-c' 26 | - |- 27 | ROOT_SERVICE_ACCOUNT_JSON=$(cat /secrets/sa.json) ci/tasks/osb-integration-tests.sh 28 | env: 29 | - 'DB_TYPE=sqlite3' 30 | - 'DB_PATH=service-broker-db.sqlite3' 31 | 32 | - name: alpine 33 | id: metadata 34 | args: 35 | - 'sh' 36 | - '-c' 37 | - |- 38 | ci/tasks/metadata.sh 39 | env: 40 | - 'COMMIT_SHA=$COMMIT_SHA' 41 | - 'DB_PATH=service-broker-db.sqlite3' 42 | 43 | - name: alpine 44 | id: build-server 45 | args: 46 | - 'sh' 47 | - '-c' 48 | - |- 49 | ci/tasks/build-server.sh 50 | 51 | - name: gcr.io/cloud-builders/go 52 | id: build-darwin 53 | args: ['build', '-o', '/artifacts/client-darwin/gcp-service-broker-darwin'] 54 | env: 55 | - 'PROJECT_ROOT=github.com/GoogleCloudPlatform/gcp-service-broker' 56 | - 'GOOS=darwin' 57 | - 'GOARCH=amd64' 58 | 59 | - name: gcr.io/cloud-builders/go 60 | id: build-linux 61 | args: ['build', '-o', '/artifacts/client-linux/gcp-service-broker-linux'] 62 | env: 63 | - 'PROJECT_ROOT=github.com/GoogleCloudPlatform/gcp-service-broker' 64 | - 'GOOS=linux' 65 | - 'GOARCH=amd64' 66 | 67 | - name: gcr.io/cloud-builders/go 68 | id: build-windows 69 | args: ['build', '-o', '/artifacts/client-windows/gcp-service-broker-windows.exe'] 70 | env: 71 | - 'PROJECT_ROOT=github.com/GoogleCloudPlatform/gcp-service-broker' 72 | - 'GOOS=windows' 73 | - 'GOARCH=amd64' 74 | 75 | - name: alpine 76 | id: bundle 77 | args: 78 | - 'sh' 79 | - '-c' 80 | - |- 81 | ci/tasks/bundle.sh 82 | 83 | - name: gcr.io/cloud-builders/gsutil 84 | id: upload 85 | args: ['cp', '/artifacts/bundle/*', '$_GS_URL'] 86 | 87 | substitutions: 88 | _GS_URL: '' # gs://your/bucket/and/path 89 | 90 | options: 91 | machineType: 'N1_HIGHCPU_8' 92 | volumes: 93 | - name: 'secrets' 94 | path: '/secrets' 95 | - name: 'artifacts' 96 | path: '/artifacts' 97 | 98 | timeout: 14400s # 4h 99 | -------------------------------------------------------------------------------- /ci/cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - name: gcr.io/cloud-builders/go 3 | id: unit 4 | args: ['test', '-v', './...', '-tags=service_broker'] 5 | env: 6 | - 'PROJECT_ROOT=github.com/GoogleCloudPlatform/gcp-service-broker' 7 | 8 | - name: gcr.io/cloud-builders/go 9 | id: build 10 | args: ['build', '-o', '/workspace/compiled-broker/gcp-service-broker'] 11 | waitFor: ['-'] 12 | env: 13 | - 'PROJECT_ROOT=github.com/GoogleCloudPlatform/gcp-service-broker' 14 | 15 | - name: gcr.io/cloud-builders/gcloud 16 | id: secrets 17 | entrypoint: 'sh' 18 | args: [ '-c', 'gcloud secrets versions access latest --secret=ROOT_SERVICE_ACCOUNT_JSON > /secrets/sa.json' ] 19 | waitFor: ['-'] 20 | 21 | - name: alpine 22 | id: integration 23 | args: 24 | - 'sh' 25 | - '-c' 26 | - |- 27 | ROOT_SERVICE_ACCOUNT_JSON=$(cat /secrets/sa.json) ci/tasks/osb-integration-tests.sh 28 | env: 29 | - 'DB_TYPE=sqlite3' 30 | - 'DB_PATH=service-broker-db.sqlite3' 31 | 32 | options: 33 | machineType: 'N1_HIGHCPU_8' 34 | volumes: 35 | - name: 'secrets' 36 | path: '/secrets' 37 | - name: 'artifacts' 38 | path: '/artifacts' 39 | 40 | timeout: 14400s # 4h 41 | -------------------------------------------------------------------------------- /ci/tasks/build-server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | 4 | echo "Installing zip" 5 | apk update 6 | apk add zip 7 | 8 | export OUTPUT_DIR="/artifacts/servers" 9 | export CURRENT_VERSION="$(cat /artifacts/metadata/version)" 10 | mkdir -p $OUTPUT_DIR 11 | 12 | echo "Creating source/CF app archive" 13 | zip $OUTPUT_DIR/gcp-service-broker-$CURRENT_VERSION-cf-app.zip -r . -x *.git* product/\* release/\* examples/\* > /dev/null 2>&1 14 | ls -la $OUTPUT_DIR 15 | -------------------------------------------------------------------------------- /ci/tasks/bundle.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | 4 | echo "Installing zip" 5 | apk update 6 | apk add zip 7 | 8 | export CURRENT_VERSION="$(cat /artifacts/metadata/version)" 9 | export REVISION="$(cat /artifacts/metadata/revision)" 10 | 11 | # Bundle up the output 12 | mkdir /artifacts/staging 13 | mkdir /artifacts/bundle 14 | 15 | echo "Staging files from the source" 16 | cp CHANGELOG.md /artifacts/staging/ 17 | cp OSDF*.txt /artifacts/staging/ 18 | ls -la /artifacts/staging/ 19 | 20 | echo "Staging files from metadata" 21 | cp /artifacts/metadata/version /artifacts/staging/ 22 | cp -r /artifacts/metadata/docs /artifacts/staging/ 23 | ls -la /artifacts/staging/ 24 | 25 | echo "Staging server binaries" 26 | mkdir -p /artifacts/staging/servers 27 | cp /artifacts/servers/* /artifacts/staging/servers 28 | ls -la /artifacts/staging/ 29 | 30 | echo "Staging client binaries" 31 | mkdir -p /artifacts/staging/clients 32 | cp /artifacts/client-darwin/* /artifacts/staging/clients 33 | cp /artifacts/client-linux/* /artifacts/staging/clients 34 | cp /artifacts/client-windows/* /artifacts/staging/clients 35 | 36 | echo "Creating release from /artifacts/staging" 37 | ls -la /artifacts/staging/ 38 | zip /artifacts/bundle/gcp-service-broker-$CURRENT_VERSION-$REVISION.zip -r /artifacts/staging/* 39 | 40 | echo Root 41 | ls -la / 42 | 43 | echo "/artifacts" 44 | ls -la /artifacts 45 | 46 | -------------------------------------------------------------------------------- /ci/tasks/metadata.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | 4 | echo "Generating metadata" 5 | mkdir -p /artifacts/metadata/docs 6 | 7 | echo $COMMIT_SHA > /artifacts/metadata/revision 8 | /workspace/compiled-broker/gcp-service-broker version > /artifacts/metadata/version 9 | /workspace/compiled-broker/gcp-service-broker generate tile > /artifacts/metadata/tile.yml 10 | /workspace/compiled-broker/gcp-service-broker generate use > /artifacts/metadata/manifest.yml 11 | /workspace/compiled-broker/gcp-service-broker generate customization > /artifacts/metadata/docs/customization.md 12 | /workspace/compiled-broker/gcp-service-broker generate use --destination-dir="/artifacts/metadata/docs/" 13 | -------------------------------------------------------------------------------- /ci/tasks/osb-integration-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -e 3 | 4 | # set up alpine 5 | apk update 6 | apk add ca-certificates 7 | 8 | # use the compiled broker 9 | cd /workspace/compiled-broker 10 | 11 | # Setup Environment 12 | export SECURITY_USER_NAME=user 13 | export SECURITY_USER_PASSWORD=password 14 | export PORT=8080 15 | 16 | echo "Running brokerpak tests" 17 | ./gcp-service-broker pak test 18 | 19 | echo "Starting server" 20 | ./gcp-service-broker serve & 21 | 22 | sleep 5 23 | ./gcp-service-broker client run-examples 24 | -------------------------------------------------------------------------------- /cmd/generate.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/generator" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin" 22 | "github.com/spf13/cobra" 23 | ) 24 | 25 | func init() { 26 | generateCmd := &cobra.Command{ 27 | Use: "generate", 28 | Short: "Generate documentation and tiles", 29 | Long: `Generate documentation and tiles`, 30 | Run: func(cmd *cobra.Command, args []string) { 31 | cmd.Help() 32 | }, 33 | } 34 | rootCmd.AddCommand(generateCmd) 35 | 36 | var useDestinationDir string 37 | useCmd := &cobra.Command{ 38 | Use: "use", 39 | Short: "Generate use markdown file", 40 | Long: `Generates the use.md file with: 41 | 42 | * details about what each service is 43 | * available parameters 44 | 45 | `, 46 | Run: func(cmd *cobra.Command, args []string) { 47 | if useDestinationDir == "" { 48 | fmt.Println(generator.CatalogDocumentation(builtin.BuiltinBrokerRegistry())) 49 | } else { 50 | generator.CatalogDocumentationToDir(builtin.BuiltinBrokerRegistry(), useDestinationDir) 51 | } 52 | 53 | }, 54 | } 55 | useCmd.Flags().StringVar(&useDestinationDir, "destination-dir", "", "Destination directory to generate usage docs about all available broker classes") 56 | generateCmd.AddCommand(useCmd) 57 | 58 | generateCmd.AddCommand(&cobra.Command{ 59 | Use: "customization", 60 | Short: "Generate customization documentation", 61 | Run: func(cmd *cobra.Command, args []string) { 62 | fmt.Println(generator.GenerateCustomizationMd()) 63 | }, 64 | }) 65 | 66 | generateCmd.AddCommand(&cobra.Command{ 67 | Use: "tile", 68 | Short: "Generate tile.yml file", 69 | Run: func(cmd *cobra.Command, args []string) { 70 | fmt.Print(generator.GenerateTile()) 71 | }, 72 | }) 73 | 74 | generateCmd.AddCommand(&cobra.Command{ 75 | Use: "manifest", 76 | Short: "Generate manifest.yml file", 77 | Run: func(cmd *cobra.Command, args []string) { 78 | fmt.Println(generator.GenerateManifest()) 79 | }, 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "fmt" 19 | "log" 20 | "os" 21 | 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/utils" 23 | "github.com/spf13/cobra" 24 | "github.com/spf13/viper" 25 | ) 26 | 27 | var cfgFile string 28 | 29 | var rootCmd = &cobra.Command{ 30 | Use: "gcp-service-broker", 31 | Short: "GCP Service Broker is an OSB compatible service broker", 32 | Long: `An OSB compatible service broker for Google Cloud Platform.`, 33 | Run: func(cmd *cobra.Command, args []string) { 34 | fmt.Println("WARNING: In the future running the broker from the root") 35 | fmt.Println("WARNING: command will show help instead.") 36 | fmt.Println("WARNING: Update your scripts to run gcp-service-broker serve") 37 | 38 | serve() 39 | }, 40 | } 41 | 42 | func Execute() { 43 | if err := rootCmd.Execute(); err != nil { 44 | fmt.Println(err) 45 | os.Exit(1) 46 | } 47 | } 48 | 49 | func init() { 50 | cobra.OnInitialize(initConfig) 51 | rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "Configuration file to be read") 52 | viper.SetEnvPrefix(utils.EnvironmentVarPrefix) 53 | viper.SetEnvKeyReplacer(utils.PropertyToEnvReplacer) 54 | viper.AutomaticEnv() 55 | } 56 | 57 | func initConfig() { 58 | if cfgFile == "" { 59 | return 60 | } 61 | 62 | viper.SetConfigFile(cfgFile) 63 | 64 | if err := viper.ReadInConfig(); err != nil { 65 | log.Fatalf("Can't read config: %v\n", err) 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package cmd 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/utils" 21 | "github.com/spf13/cobra" 22 | ) 23 | 24 | func init() { 25 | versionCmd := &cobra.Command{ 26 | Use: "version", 27 | Short: "Show the version info of the broker", 28 | Long: `Show the version info of the broker`, 29 | Run: func(cmd *cobra.Command, args []string) { 30 | fmt.Println(utils.Version) 31 | }, 32 | } 33 | 34 | rootCmd.AddCommand(versionCmd) 35 | } 36 | -------------------------------------------------------------------------------- /db_service/db_service.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | //go:generate go run dao_generator.go 16 | 17 | package db_service 18 | 19 | import ( 20 | "fmt" 21 | "sync" 22 | 23 | "code.cloudfoundry.org/lager" 24 | "github.com/jinzhu/gorm" 25 | 26 | _ "github.com/jinzhu/gorm/dialects/sqlite" 27 | ) 28 | 29 | var DbConnection *gorm.DB 30 | var once sync.Once 31 | 32 | // Instantiates the db connection and runs migrations 33 | func New(logger lager.Logger) *gorm.DB { 34 | once.Do(func() { 35 | DbConnection = SetupDb(logger) 36 | if err := RunMigrations(DbConnection); err != nil { 37 | panic(fmt.Sprintf("Error migrating database: %s", err.Error())) 38 | } 39 | }) 40 | return DbConnection 41 | } 42 | 43 | // defaultDatastore gets the default datastore for the given default database 44 | // instantiated in New(). In the future, all accesses of DbConnection will be 45 | // done through SqlDatastore and it will become the globally shared instance. 46 | func defaultDatastore() *SqlDatastore { 47 | return &SqlDatastore{db: DbConnection} 48 | } 49 | 50 | type SqlDatastore struct { 51 | db *gorm.DB 52 | } 53 | -------------------------------------------------------------------------------- /db_service/models/db.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package models 16 | 17 | import ( 18 | "encoding/json" 19 | ) 20 | 21 | const ( 22 | // The following operation types are used as part of the OSB process. 23 | // The types correspond to asynchronous provision/deprovision/update calls 24 | // and will exist on a ServiceInstanceDetails with an operation ID that can be 25 | // used to look up the state of an operation. 26 | ProvisionOperationType = "provision" 27 | DeprovisionOperationType = "deprovision" 28 | UpdateOperationType = "update" 29 | ClearOperationType = "" 30 | ) 31 | 32 | // ServiceBindingCredentials holds credentials returned to the users after 33 | // binding to a service. 34 | type ServiceBindingCredentials ServiceBindingCredentialsV1 35 | 36 | // ServiceInstanceDetails holds information about provisioned services. 37 | type ServiceInstanceDetails ServiceInstanceDetailsV2 38 | 39 | // SetOtherDetails marshals the value passed in into a JSON string and sets 40 | // OtherDetails to it if marshalling was successful. 41 | func (si *ServiceInstanceDetails) SetOtherDetails(toSet interface{}) error { 42 | out, err := json.Marshal(toSet) 43 | if err != nil { 44 | return err 45 | } 46 | 47 | si.OtherDetails = string(out) 48 | return nil 49 | } 50 | 51 | // GetOtherDetails returns an unmarshalls the OtherDetails field into the given 52 | // struct. An empty OtherDetails field does not get unmarshalled and does not error. 53 | func (si ServiceInstanceDetails) GetOtherDetails(v interface{}) error { 54 | if si.OtherDetails == "" { 55 | return nil 56 | } 57 | 58 | return json.Unmarshal([]byte(si.OtherDetails), v) 59 | } 60 | 61 | // ProvisionRequestDetails holds user-defined properties passed to a call 62 | // to provision a service. 63 | type ProvisionRequestDetails ProvisionRequestDetailsV1 64 | 65 | // Migration represents the mgirations table. It holds a monotonically 66 | // increasing number that gets incremented with every database schema revision. 67 | type Migration MigrationV1 68 | 69 | // CloudOperation holds information about the status of Google Cloud 70 | // long-running operations. 71 | type CloudOperation CloudOperationV1 72 | 73 | // TerraformDeployment holds Terraform state and plan information for resources 74 | // that use that execution system. 75 | type TerraformDeployment TerraformDeploymentV1 76 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/.gitignore: -------------------------------------------------------------------------------- 1 | charts/* 2 | gcp-service-broker-*.tgz 3 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | --- 15 | apiVersion: v1 16 | appVersion: "1.0" # This is automatically set by the build process. 17 | version: 0.1.0 # This is automatically set by the build process. 18 | description: A Helm chart for the Google Cloud Platform (GCP) Service Broker 19 | name: gcp-service-broker 20 | icon: https://cloud.google.com/_static/images/cloud/products/logos/svg/gcp.svg 21 | keywords: 22 | - gcp 23 | - google cloud 24 | - services 25 | - service broker 26 | home: https://github.com/GoogleCloudPlatform/gcp-service-broker 27 | sources: 28 | - https://github.com/GoogleCloudPlatform/gcp-service-broker 29 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/README.md: -------------------------------------------------------------------------------- 1 | # GCP Service Broker Helm chart 2 | 3 | This is a helm chart for deploying the GCP Service Broker into Kubernetes. 4 | 5 | ## Configuration 6 | 7 | By default, the helm chart provides enough to get you running, but you'll need 8 | to change things for a robust production environment. 9 | 10 | For all environments: 11 | 12 | * Set `broker.service_account_json` to be the JSON key of a service account that 13 | has owner permission on the GCP project you want to manage. 14 | * Add key/value pairs to `broker.env` for environment variables you want to set 15 | on the broker. You can find a list of possible environment variables in the 16 | [customization document](https://github.com/GoogleCloudPlatform/gcp-service-broker/blob/master/docs/customization.md). 17 | 18 | Things to change for production: 19 | 20 | * `mysql.embedded` should be set to false and you should provide credentials 21 | for an external MySQL database that has automatic backups and failover. 22 | 23 | ## Building 24 | 25 | You can build a copy of this Helm chart suitable for releasing with the following commands: 26 | 27 | ``` .sh 28 | BROKER_VERSION=5.0.0 29 | helm package --app-version=$BROKER_VERSION --dependency-update --version=$BROKER_VERSION . 30 | ``` 31 | 32 | ## Installing 33 | 34 | | Tutorial Name | Tutorial Link | 35 | |:--------------|:--------------| 36 | | Install the Service Broker into K8s for use with CF | [![Open in Cloud Shell](http://gstatic.com/cloudssh/images/open-btn.svg)](https://console.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2FGoogleCloudPlatform%2Fgcp-service-broker&cloudshell_open_in_editor=values.yaml&cloudshell_working_dir=deployments%2Fhelm%2Fgcp-service-broker&cloudshell_tutorial=cf-tutorial.md&cloudshell_git_branch=master) | 37 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/requirements.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: mysql 3 | repository: https://kubernetes-charts.storage.googleapis.com/ 4 | version: 0.15.0 5 | digest: sha256:d3a612d1a30d2a8d9de3512dfafeea91bbc2a0cbc7d5100ebaa86cc629d98f09 6 | generated: 2019-03-05T13:02:47.045729841-08:00 7 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/requirements.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | --- 15 | dependencies: 16 | - name: mysql 17 | version: "1.6.3" 18 | condition: mysql.embedded 19 | repository: https://charts.helm.sh/stable 20 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | {{- if .Values.svccat.register }} 2 | 3 | The broker has been registered with the Kubernetes Service Catalog. The catalog 4 | will update its service and plan listings once the broker becomes healthy. 5 | 6 | You can check on its status by running: 7 | 8 | kubectl describe clusterservicebroker {{.Values.svccat.name}} 9 | 10 | {{- else }} 11 | 12 | The broker has been installed in Kubernetes, but still needs to be registered 13 | with the Service Catalog or Cloud Foundry. 14 | 15 | You can register it with Cloud Foundry by running: 16 | 17 | SECRET={{ template "gcp-service-broker.fullname" . }}-auth 18 | USERNAME="$(kubectl get secret $SECRET -o jsonpath='{.data.username}' | base64 --decode)" 19 | PASSWORD="$(kubectl get secret $SECRET -o jsonpath='{.data.password}' | base64 --decode)" 20 | URL=http://{{ template "gcp-service-broker.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local 21 | cf create-service-broker {{ .Values.svccat.name }} $USERNAME $PASSWORD $URL 22 | 23 | {{- end }} 24 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "gcp-service-broker.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "gcp-service-broker.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "gcp-service-broker.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/templates/clusterservicebroker.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # This file registers the broker with the Service Catalog so the services can 16 | # be discovered and registered into the cluster. 17 | {{ if .Values.svccat.register }} 18 | --- 19 | apiVersion: servicecatalog.k8s.io/v1beta1 20 | kind: ClusterServiceBroker 21 | metadata: 22 | name: {{ .Values.svccat.name }} 23 | labels: 24 | app.kubernetes.io/name: {{ include "gcp-service-broker.name" . }} 25 | helm.sh/chart: {{ include "gcp-service-broker.chart" . }} 26 | app.kubernetes.io/instance: {{ .Release.Name }} 27 | app.kubernetes.io/managed-by: {{ .Release.Service }} 28 | spec: 29 | url: http://{{ template "gcp-service-broker.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local 30 | authInfo: 31 | basic: 32 | secretRef: 33 | name: "{{ template "gcp-service-broker.fullname" . }}-auth" 34 | namespace: {{ .Release.Namespace | quote }} 35 | {{- end }} 36 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | --- 15 | {{- if .Values.ingress.enabled -}} 16 | {{- $fullName := include "gcp-service-broker.fullname" . -}} 17 | apiVersion: extensions/v1beta1 18 | kind: Ingress 19 | metadata: 20 | name: {{ $fullName }} 21 | labels: 22 | app.kubernetes.io/name: {{ include "gcp-service-broker.name" . }} 23 | helm.sh/chart: {{ include "gcp-service-broker.chart" . }} 24 | app.kubernetes.io/instance: {{ .Release.Name }} 25 | app.kubernetes.io/managed-by: {{ .Release.Service }} 26 | {{- with .Values.ingress.annotations }} 27 | annotations: 28 | {{- toYaml . | nindent 4 }} 29 | {{- end }} 30 | spec: 31 | {{- if .Values.ingress.tls }} 32 | tls: 33 | {{- range .Values.ingress.tls }} 34 | - hosts: 35 | {{- range .hosts }} 36 | - {{ . | quote }} 37 | {{- end }} 38 | secretName: {{ .secretName }} 39 | {{- end }} 40 | {{- end }} 41 | rules: 42 | {{- range .Values.ingress.hosts }} 43 | - host: {{ .host | quote }} 44 | http: 45 | paths: 46 | {{- range .paths }} 47 | - path: {{ . }} 48 | backend: 49 | serviceName: {{ $fullName }} 50 | servicePort: http 51 | {{- end }} 52 | {{- end }} 53 | {{- end }} 54 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | --- 16 | # This secret stores the credentials used by the Service Catalog or Cloud Foundry 17 | # to connect to the service broker. 18 | apiVersion: v1 19 | kind: Secret 20 | metadata: 21 | name: {{ template "gcp-service-broker.fullname" . }}-auth 22 | labels: 23 | app.kubernetes.io/name: {{ include "gcp-service-broker.name" . }} 24 | helm.sh/chart: {{ include "gcp-service-broker.chart" . }} 25 | app.kubernetes.io/instance: {{ .Release.Name }} 26 | app.kubernetes.io/managed-by: {{ .Release.Service }} 27 | type: Opaque 28 | data: 29 | username: {{ .Values.broker.username | b64enc | quote }} 30 | {{ if .Values.broker.password }} 31 | password: {{ .Values.broker.password | b64enc | quote }} 32 | {{ else }} 33 | password: {{ randAlphaNum 10 | b64enc | quote }} 34 | {{ end }} 35 | --- 36 | # This secret stores the credentials used by the service broker to connect to 37 | # the database. 38 | apiVersion: v1 39 | kind: Secret 40 | metadata: 41 | name: {{ template "gcp-service-broker.fullname" . }}-creds 42 | labels: 43 | app.kubernetes.io/name: {{ include "gcp-service-broker.name" . }} 44 | helm.sh/chart: {{ include "gcp-service-broker.chart" . }} 45 | app.kubernetes.io/instance: {{ .Release.Name }} 46 | app.kubernetes.io/managed-by: {{ .Release.Service }} 47 | type: Opaque 48 | data: 49 | db_username: {{ .Values.mysql.mysqlUser | b64enc | quote }} 50 | db_password: {{ .Values.mysql.mysqlPassword | b64enc | quote }} 51 | db_ca_cert: {{ .Values.mysql.ca_cert | b64enc | quote }} 52 | db_client_cert: {{ .Values.mysql.client_cert | b64enc | quote }} 53 | db_client_key: {{ .Values.mysql.client_key | b64enc | quote }} 54 | service_account: {{ required "A value is required for broker.service_account_json" .Values.broker.service_account_json | b64enc | quote }} 55 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/templates/service.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | --- 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: {{ include "gcp-service-broker.fullname" . }} 19 | labels: 20 | app.kubernetes.io/name: {{ include "gcp-service-broker.name" . }} 21 | helm.sh/chart: {{ include "gcp-service-broker.chart" . }} 22 | app.kubernetes.io/instance: {{ .Release.Name }} 23 | app.kubernetes.io/managed-by: {{ .Release.Service }} 24 | spec: 25 | type: {{ .Values.service.type }} 26 | ports: 27 | - port: {{ .Values.service.port }} 28 | targetPort: http 29 | protocol: TCP 30 | name: http 31 | selector: 32 | app.kubernetes.io/name: {{ include "gcp-service-broker.name" . }} 33 | app.kubernetes.io/instance: {{ .Release.Name }} 34 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "gcp-service-broker.fullname" . }}-test-connection" 5 | labels: 6 | app.kubernetes.io/name: {{ include "gcp-service-broker.name" . }} 7 | helm.sh/chart: {{ include "gcp-service-broker.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | annotations: 11 | "helm.sh/hook": test-success 12 | spec: 13 | containers: 14 | - name: wget 15 | image: busybox 16 | command: ['wget'] 17 | args: ['{{ include "gcp-service-broker.fullname" . }}:{{ .Values.service.port }}'] 18 | restartPolicy: Never 19 | -------------------------------------------------------------------------------- /deployments/helm/gcp-service-broker/values.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | --- 15 | replicaCount: 1 16 | 17 | image: 18 | repository: gcr.io/gcp-service-broker/gcp-service-broker 19 | tag: master 20 | pullPolicy: IfNotPresent 21 | 22 | # Settings for integrating the broker with the Kubernetes Service Catalog. 23 | svccat: 24 | # Whether the broker should be registered with the Kubernetes Service Catalog. 25 | # If true, the service catalog should already be installed in the cluster. 26 | register: true 27 | # The name the broker will get in the service catalog. 28 | name: gcp-service-broker 29 | 30 | service: 31 | type: ClusterIP 32 | port: 80 33 | 34 | ingress: 35 | enabled: false 36 | hosts: 37 | - host: chart-example.local 38 | paths: [] 39 | 40 | broker: 41 | # Basicauth credentials the service catalog or CF will use to authenticate 42 | # to the broker. If the password is blank, it will be auto-generated. 43 | username: 'root' 44 | password: '' 45 | 46 | # The root service account for your GCP project. 47 | service_account_json: '' 48 | 49 | # Additional environment variables you want to pass wo the broker. 50 | # See: docs/customization.md for a full listing. 51 | env: 52 | GSB_BROKERPAK_CONFIG: '{}' 53 | GSB_SERVICE_CONFIG: '{}' 54 | 55 | # Database connection info. The database will store all mappings between 56 | # the service broker and provisioned services. 57 | # 58 | # If this database disappears you will have to manually track down and managed 59 | # all orphaned services so make sure it's backed up. 60 | mysql: 61 | # embedded determines if a MySQL instance should be created in your kubernetes 62 | # cluster byHelm. 63 | embedded: true 64 | # Required if not embedded, the hostname or IP address of the MySQL database 65 | # to connect to. 66 | host: '' 67 | # Database port. 68 | port: 3306 69 | # Username for the service broker on the database. 70 | mysqlUser: 'broker' 71 | # Password of the user. 72 | mysqlPassword: 'password' 73 | # Name for new database to create. 74 | mysqlDatabase: 'servicebroker' 75 | 76 | # The following options are used if you're connecting over secure tunnels with 77 | # Google CloudSQL. 78 | ca_cert: '' 79 | client_cert: '' 80 | client_key: '' 81 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /docs/billing.md: -------------------------------------------------------------------------------- 1 | # Billing 2 | 3 | The GCP Service Broker automatically labels supported resources with organization GUID, space GUID and instance ID. 4 | 5 | When these supported services are provisioned, they will have the following labels populated with information from the request: 6 | 7 | * `pcf-organization-guid` 8 | * `pcf-space-guid` 9 | * `pcf-instance-id` 10 | 11 | GCP labels have a more restricted character set than the Service Broker so unsupported characters will be mapped to the underscore character (`_`). 12 | 13 | ## Support 14 | 15 | The following resources support these automatically generated labels: 16 | 17 | * BigQuery 18 | * CloudSQL (PostgreSQL and MySQL) 19 | * Cloud Storage 20 | * Spanner 21 | 22 | ## Usage 23 | 24 | You can use these labels with the [BigQuery Billing Export](https://cloud.google.com/billing/docs/how-to/bq-examples) 25 | to create reports about which organizations and spaces are incurring cost in your GCP project. 26 | -------------------------------------------------------------------------------- /docs/classes/google-dialogflow.md: -------------------------------------------------------------------------------- 1 | # ![](https://cloud.google.com/_static/images/cloud/products/logos/svg/dialogflow-enterprise.svg) Google Cloud Dialogflow 2 | Dialogflow is an end-to-end, build-once deploy-everywhere development suite for creating conversational interfaces for websites, mobile applications, popular messaging platforms, and IoT devices. 3 | 4 | * [Documentation](https://cloud.google.com/dialogflow-enterprise/docs/) 5 | * [Support](https://cloud.google.com/dialogflow-enterprise/docs/support) 6 | * Catalog Metadata ID: `e84b69db-3de9-4688-8f5c-26b9d5b1f129` 7 | * Tags: gcp, dialogflow, preview 8 | * Service Name: `google-dialogflow` 9 | 10 | ## Provisioning 11 | 12 | **Request Parameters** 13 | 14 | _No parameters supported._ 15 | 16 | 17 | ## Binding 18 | 19 | **Request Parameters** 20 | 21 | _No parameters supported._ 22 | 23 | **Response Parameters** 24 | 25 | * `Email` _string_ - **Required** Email address of the service account. 26 | * Examples: [pcf-binding-ex312029@my-project.iam.gserviceaccount.com]. 27 | * The string must match the regular expression `^pcf-binding-[a-z0-9-]+@.+\.gserviceaccount\.com$`. 28 | * `Name` _string_ - **Required** The name of the service account. 29 | * Examples: [pcf-binding-ex312029]. 30 | * `PrivateKeyData` _string_ - **Required** Service account private key data. Base64 encoded JSON. 31 | * The string must have at least 512 characters. 32 | * The string must match the regular expression `^[A-Za-z0-9+/]*=*$`. 33 | * `ProjectId` _string_ - **Required** ID of the project that owns the service account. 34 | * Examples: [my-project]. 35 | * The string must have at most 30 characters. 36 | * The string must have at least 6 characters. 37 | * The string must match the regular expression `^[a-z0-9-]+$`. 38 | * `UniqueId` _string_ - **Required** Unique and stable ID of the service account. 39 | * Examples: [112447814736626230844]. 40 | 41 | ## Plans 42 | 43 | The following plans are built-in to the GCP Service Broker and may be overridden 44 | or disabled by the broker administrator. 45 | 46 | 47 | * **`default`** 48 | * Plan ID: `3ac4e1bd-b22d-4a99-864b-d3a3ac582348`. 49 | * Description: Dialogflow default plan. 50 | * This plan doesn't override user variables on provision. 51 | * This plan doesn't override user variables on bind. 52 | 53 | 54 | ## Examples 55 | 56 | 57 | 58 | 59 | ### Reader 60 | 61 | 62 | Creates a Dialogflow user and grants it permission to detect intent and read/write session properties (contexts, session entity types, etc.). 63 | Uses plan: `3ac4e1bd-b22d-4a99-864b-d3a3ac582348`. 64 | 65 | **Provision** 66 | 67 | ```javascript 68 | {} 69 | ``` 70 | 71 | **Bind** 72 | 73 | ```javascript 74 | {} 75 | ``` 76 | 77 | **Cloud Foundry Example** 78 | 79 |
80 | $ cf create-service google-dialogflow default my-google-dialogflow-example -c `{}`
81 | $ cf bind-service my-app my-google-dialogflow-example -c `{}`
82 | 
-------------------------------------------------------------------------------- /docs/classes/google-ml-apis.md: -------------------------------------------------------------------------------- 1 | # ![](https://cloud.google.com/_static/images/cloud/products/logos/svg/machine-learning.svg) Google Machine Learning APIs 2 | Machine Learning APIs including Vision, Translate, Speech, and Natural Language. 3 | 4 | * [Documentation](https://cloud.google.com/ml/) 5 | * [Support](https://cloud.google.com/support/) 6 | * Catalog Metadata ID: `5ad2dce0-51f7-4ede-8b46-293d6df1e8d4` 7 | * Tags: gcp, ml 8 | * Service Name: `google-ml-apis` 9 | 10 | ## Provisioning 11 | 12 | **Request Parameters** 13 | 14 | _No parameters supported._ 15 | 16 | 17 | ## Binding 18 | 19 | **Request Parameters** 20 | 21 | 22 | * `role` _string_ - The role for the account without the "roles/" prefix. See: https://cloud.google.com/iam/docs/understanding-roles for more details. Default: `ml.modelUser`. 23 | * The value must be one of: [ml.developer ml.jobOwner ml.modelOwner ml.modelUser ml.operationOwner ml.viewer]. 24 | 25 | **Response Parameters** 26 | 27 | * `Email` _string_ - **Required** Email address of the service account. 28 | * Examples: [pcf-binding-ex312029@my-project.iam.gserviceaccount.com]. 29 | * The string must match the regular expression `^pcf-binding-[a-z0-9-]+@.+\.gserviceaccount\.com$`. 30 | * `Name` _string_ - **Required** The name of the service account. 31 | * Examples: [pcf-binding-ex312029]. 32 | * `PrivateKeyData` _string_ - **Required** Service account private key data. Base64 encoded JSON. 33 | * The string must have at least 512 characters. 34 | * The string must match the regular expression `^[A-Za-z0-9+/]*=*$`. 35 | * `ProjectId` _string_ - **Required** ID of the project that owns the service account. 36 | * Examples: [my-project]. 37 | * The string must have at most 30 characters. 38 | * The string must have at least 6 characters. 39 | * The string must match the regular expression `^[a-z0-9-]+$`. 40 | * `UniqueId` _string_ - **Required** Unique and stable ID of the service account. 41 | * Examples: [112447814736626230844]. 42 | 43 | ## Plans 44 | 45 | The following plans are built-in to the GCP Service Broker and may be overridden 46 | or disabled by the broker administrator. 47 | 48 | 49 | * **`default`** 50 | * Plan ID: `be7954e1-ecfb-4936-a0b6-db35e6424c7a`. 51 | * Description: Machine Learning API default plan. 52 | * This plan doesn't override user variables on provision. 53 | * This plan doesn't override user variables on bind. 54 | 55 | 56 | ## Examples 57 | 58 | 59 | 60 | 61 | ### Basic Configuration 62 | 63 | 64 | Create an account with developer access to your ML models. 65 | Uses plan: `be7954e1-ecfb-4936-a0b6-db35e6424c7a`. 66 | 67 | **Provision** 68 | 69 | ```javascript 70 | {} 71 | ``` 72 | 73 | **Bind** 74 | 75 | ```javascript 76 | { 77 | "role": "ml.developer" 78 | } 79 | ``` 80 | 81 | **Cloud Foundry Example** 82 | 83 |
84 | $ cf create-service google-ml-apis default my-google-ml-apis-example -c `{}`
85 | $ cf bind-service my-app my-google-ml-apis-example -c `{"role":"ml.developer"}`
86 | 
-------------------------------------------------------------------------------- /docs/classes/google-stackdriver-debugger.md: -------------------------------------------------------------------------------- 1 | # ![](https://cloud.google.com/_static/images/cloud/products/logos/svg/debugger.svg) Stackdriver Debugger 2 | Inspect the state of an app, at any code location, without stopping or slowing it down. 3 | 4 | * [Documentation](https://cloud.google.com/debugger/docs/) 5 | * [Support](https://cloud.google.com/stackdriver/docs/getting-support) 6 | * Catalog Metadata ID: `83837945-1547-41e0-b661-ea31d76eed11` 7 | * Tags: gcp, stackdriver, debugger 8 | * Service Name: `google-stackdriver-debugger` 9 | 10 | ## Provisioning 11 | 12 | **Request Parameters** 13 | 14 | _No parameters supported._ 15 | 16 | 17 | ## Binding 18 | 19 | **Request Parameters** 20 | 21 | _No parameters supported._ 22 | 23 | **Response Parameters** 24 | 25 | * `Email` _string_ - **Required** Email address of the service account. 26 | * Examples: [pcf-binding-ex312029@my-project.iam.gserviceaccount.com]. 27 | * The string must match the regular expression `^pcf-binding-[a-z0-9-]+@.+\.gserviceaccount\.com$`. 28 | * `Name` _string_ - **Required** The name of the service account. 29 | * Examples: [pcf-binding-ex312029]. 30 | * `PrivateKeyData` _string_ - **Required** Service account private key data. Base64 encoded JSON. 31 | * The string must have at least 512 characters. 32 | * The string must match the regular expression `^[A-Za-z0-9+/]*=*$`. 33 | * `ProjectId` _string_ - **Required** ID of the project that owns the service account. 34 | * Examples: [my-project]. 35 | * The string must have at most 30 characters. 36 | * The string must have at least 6 characters. 37 | * The string must match the regular expression `^[a-z0-9-]+$`. 38 | * `UniqueId` _string_ - **Required** Unique and stable ID of the service account. 39 | * Examples: [112447814736626230844]. 40 | 41 | ## Plans 42 | 43 | The following plans are built-in to the GCP Service Broker and may be overridden 44 | or disabled by the broker administrator. 45 | 46 | 47 | * **`default`** 48 | * Plan ID: `10866183-a775-49e8-96e3-4e7a901e4a79`. 49 | * Description: Stackdriver Debugger default plan. 50 | * This plan doesn't override user variables on provision. 51 | * This plan doesn't override user variables on bind. 52 | 53 | 54 | ## Examples 55 | 56 | 57 | 58 | 59 | ### Basic Configuration 60 | 61 | 62 | Creates an account with the permission `clouddebugger.agent`. 63 | Uses plan: `10866183-a775-49e8-96e3-4e7a901e4a79`. 64 | 65 | **Provision** 66 | 67 | ```javascript 68 | {} 69 | ``` 70 | 71 | **Bind** 72 | 73 | ```javascript 74 | {} 75 | ``` 76 | 77 | **Cloud Foundry Example** 78 | 79 |
80 | $ cf create-service google-stackdriver-debugger default my-google-stackdriver-debugger-example -c `{}`
81 | $ cf bind-service my-app my-google-stackdriver-debugger-example -c `{}`
82 | 
-------------------------------------------------------------------------------- /docs/classes/google-stackdriver-monitoring.md: -------------------------------------------------------------------------------- 1 | # ![](https://cloud.google.com/_static/images/cloud/products/logos/svg/stackdriver.svg) Stackdriver Monitoring 2 | Stackdriver Monitoring provides visibility into the performance, uptime, and overall health of cloud-powered applications. 3 | 4 | * [Documentation](https://cloud.google.com/monitoring/docs/) 5 | * [Support](https://cloud.google.com/stackdriver/docs/getting-support) 6 | * Catalog Metadata ID: `2bc0d9ed-3f68-4056-b842-4a85cfbc727f` 7 | * Tags: gcp, stackdriver, monitoring, preview 8 | * Service Name: `google-stackdriver-monitoring` 9 | 10 | ## Provisioning 11 | 12 | **Request Parameters** 13 | 14 | _No parameters supported._ 15 | 16 | 17 | ## Binding 18 | 19 | **Request Parameters** 20 | 21 | _No parameters supported._ 22 | 23 | **Response Parameters** 24 | 25 | * `Email` _string_ - **Required** Email address of the service account. 26 | * Examples: [pcf-binding-ex312029@my-project.iam.gserviceaccount.com]. 27 | * The string must match the regular expression `^pcf-binding-[a-z0-9-]+@.+\.gserviceaccount\.com$`. 28 | * `Name` _string_ - **Required** The name of the service account. 29 | * Examples: [pcf-binding-ex312029]. 30 | * `PrivateKeyData` _string_ - **Required** Service account private key data. Base64 encoded JSON. 31 | * The string must have at least 512 characters. 32 | * The string must match the regular expression `^[A-Za-z0-9+/]*=*$`. 33 | * `ProjectId` _string_ - **Required** ID of the project that owns the service account. 34 | * Examples: [my-project]. 35 | * The string must have at most 30 characters. 36 | * The string must have at least 6 characters. 37 | * The string must match the regular expression `^[a-z0-9-]+$`. 38 | * `UniqueId` _string_ - **Required** Unique and stable ID of the service account. 39 | * Examples: [112447814736626230844]. 40 | 41 | ## Plans 42 | 43 | The following plans are built-in to the GCP Service Broker and may be overridden 44 | or disabled by the broker administrator. 45 | 46 | 47 | * **`default`** 48 | * Plan ID: `2e4b85c1-0ce6-46e4-91f5-eebeb373e3f5`. 49 | * Description: Stackdriver Monitoring default plan. 50 | * This plan doesn't override user variables on provision. 51 | * This plan doesn't override user variables on bind. 52 | 53 | 54 | ## Examples 55 | 56 | 57 | 58 | 59 | ### Basic Configuration 60 | 61 | 62 | Creates an account with the permission `monitoring.metricWriter` for writing metrics. 63 | Uses plan: `2e4b85c1-0ce6-46e4-91f5-eebeb373e3f5`. 64 | 65 | **Provision** 66 | 67 | ```javascript 68 | {} 69 | ``` 70 | 71 | **Bind** 72 | 73 | ```javascript 74 | {} 75 | ``` 76 | 77 | **Cloud Foundry Example** 78 | 79 |
80 | $ cf create-service google-stackdriver-monitoring default my-google-stackdriver-monitoring-example -c `{}`
81 | $ cf bind-service my-app my-google-stackdriver-monitoring-example -c `{}`
82 | 
-------------------------------------------------------------------------------- /docs/classes/google-stackdriver-profiler.md: -------------------------------------------------------------------------------- 1 | # ![](https://cloud.google.com/_static/images/cloud/products/logos/svg/stackdriver.svg) Stackdriver Profiler 2 | Continuous CPU and heap profiling to improve performance and reduce costs. 3 | 4 | * [Documentation](https://cloud.google.com/profiler/docs/) 5 | * [Support](https://cloud.google.com/stackdriver/docs/getting-support) 6 | * Catalog Metadata ID: `00b9ca4a-7cd6-406a-a5b7-2f43f41ade75` 7 | * Tags: gcp, stackdriver, profiler 8 | * Service Name: `google-stackdriver-profiler` 9 | 10 | ## Provisioning 11 | 12 | **Request Parameters** 13 | 14 | _No parameters supported._ 15 | 16 | 17 | ## Binding 18 | 19 | **Request Parameters** 20 | 21 | _No parameters supported._ 22 | 23 | **Response Parameters** 24 | 25 | * `Email` _string_ - **Required** Email address of the service account. 26 | * Examples: [pcf-binding-ex312029@my-project.iam.gserviceaccount.com]. 27 | * The string must match the regular expression `^pcf-binding-[a-z0-9-]+@.+\.gserviceaccount\.com$`. 28 | * `Name` _string_ - **Required** The name of the service account. 29 | * Examples: [pcf-binding-ex312029]. 30 | * `PrivateKeyData` _string_ - **Required** Service account private key data. Base64 encoded JSON. 31 | * The string must have at least 512 characters. 32 | * The string must match the regular expression `^[A-Za-z0-9+/]*=*$`. 33 | * `ProjectId` _string_ - **Required** ID of the project that owns the service account. 34 | * Examples: [my-project]. 35 | * The string must have at most 30 characters. 36 | * The string must have at least 6 characters. 37 | * The string must match the regular expression `^[a-z0-9-]+$`. 38 | * `UniqueId` _string_ - **Required** Unique and stable ID of the service account. 39 | * Examples: [112447814736626230844]. 40 | 41 | ## Plans 42 | 43 | The following plans are built-in to the GCP Service Broker and may be overridden 44 | or disabled by the broker administrator. 45 | 46 | 47 | * **`default`** 48 | * Plan ID: `594627f6-35f5-462f-9074-10fb033fb18a`. 49 | * Description: Stackdriver Profiler default plan. 50 | * This plan doesn't override user variables on provision. 51 | * This plan doesn't override user variables on bind. 52 | 53 | 54 | ## Examples 55 | 56 | 57 | 58 | 59 | ### Basic Configuration 60 | 61 | 62 | Creates an account with the permission `cloudprofiler.agent`. 63 | Uses plan: `594627f6-35f5-462f-9074-10fb033fb18a`. 64 | 65 | **Provision** 66 | 67 | ```javascript 68 | {} 69 | ``` 70 | 71 | **Bind** 72 | 73 | ```javascript 74 | {} 75 | ``` 76 | 77 | **Cloud Foundry Example** 78 | 79 |
80 | $ cf create-service google-stackdriver-profiler default my-google-stackdriver-profiler-example -c `{}`
81 | $ cf bind-service my-app my-google-stackdriver-profiler-example -c `{}`
82 | 
-------------------------------------------------------------------------------- /docs/classes/google-stackdriver-trace.md: -------------------------------------------------------------------------------- 1 | # ![](https://cloud.google.com/_static/images/cloud/products/logos/svg/trace.svg) Stackdriver Trace 2 | A real-time distributed tracing system. 3 | 4 | * [Documentation](https://cloud.google.com/trace/docs/) 5 | * [Support](https://cloud.google.com/stackdriver/docs/getting-support) 6 | * Catalog Metadata ID: `c5ddfe15-24d9-47f8-8ffe-f6b7daa9cf4a` 7 | * Tags: gcp, stackdriver, trace 8 | * Service Name: `google-stackdriver-trace` 9 | 10 | ## Provisioning 11 | 12 | **Request Parameters** 13 | 14 | _No parameters supported._ 15 | 16 | 17 | ## Binding 18 | 19 | **Request Parameters** 20 | 21 | _No parameters supported._ 22 | 23 | **Response Parameters** 24 | 25 | * `Email` _string_ - **Required** Email address of the service account. 26 | * Examples: [pcf-binding-ex312029@my-project.iam.gserviceaccount.com]. 27 | * The string must match the regular expression `^pcf-binding-[a-z0-9-]+@.+\.gserviceaccount\.com$`. 28 | * `Name` _string_ - **Required** The name of the service account. 29 | * Examples: [pcf-binding-ex312029]. 30 | * `PrivateKeyData` _string_ - **Required** Service account private key data. Base64 encoded JSON. 31 | * The string must have at least 512 characters. 32 | * The string must match the regular expression `^[A-Za-z0-9+/]*=*$`. 33 | * `ProjectId` _string_ - **Required** ID of the project that owns the service account. 34 | * Examples: [my-project]. 35 | * The string must have at most 30 characters. 36 | * The string must have at least 6 characters. 37 | * The string must match the regular expression `^[a-z0-9-]+$`. 38 | * `UniqueId` _string_ - **Required** Unique and stable ID of the service account. 39 | * Examples: [112447814736626230844]. 40 | 41 | ## Plans 42 | 43 | The following plans are built-in to the GCP Service Broker and may be overridden 44 | or disabled by the broker administrator. 45 | 46 | 47 | * **`default`** 48 | * Plan ID: `ab6c2287-b4bc-4ff4-a36a-0575e7910164`. 49 | * Description: Stackdriver Trace default plan. 50 | * This plan doesn't override user variables on provision. 51 | * This plan doesn't override user variables on bind. 52 | 53 | 54 | ## Examples 55 | 56 | 57 | 58 | 59 | ### Basic Configuration 60 | 61 | 62 | Creates an account with the permission `cloudtrace.agent`. 63 | Uses plan: `ab6c2287-b4bc-4ff4-a36a-0575e7910164`. 64 | 65 | **Provision** 66 | 67 | ```javascript 68 | {} 69 | ``` 70 | 71 | **Bind** 72 | 73 | ```javascript 74 | {} 75 | ``` 76 | 77 | **Cloud Foundry Example** 78 | 79 |
80 | $ cf create-service google-stackdriver-trace default my-google-stackdriver-trace-example -c `{}`
81 | $ cf bind-service my-app my-google-stackdriver-trace-example -c `{}`
82 | 
-------------------------------------------------------------------------------- /docs/releasing.md: -------------------------------------------------------------------------------- 1 | # Release Process 2 | 3 | ## Before continuing 4 | 5 | - [ ] Open a ticket with the name `release-vX.Y.Z` and copy the contents of this file into its description. 6 | - [ ] Create a new pre-release branch in the GitHub repository labeled `release-vX.Y.Z`. 7 | 8 | ## Update the project in the branch 9 | 10 | - [ ] Update version in `utils/version.go`. 11 | - [ ] Update the stemcell and go version in `pkg/generator/pcf-artifacts.go` 12 | - [ ] Run `./hack/build.sh`. 13 | - [ ] Update the `CHANGELOG.md` to match the new version. 14 | - [ ] Commit the changes on the new branch. 15 | - [ ] Wait for the system to build and all Concourse tests to pass. 16 | 17 | ## Generate the OSDF 18 | 19 | ### Option 1: automatic 20 | 21 | - [ ] Run `./hack/update-osdf.sh X.Y.Z` 22 | 23 | ### Option 2: fallback 24 | 25 | - [ ] Get a list of licenses using the [license_finder](https://github.com/pivotal-legacy/LicenseFinder) tool. 26 | - [ ] Fill in the [license template](https://docs.google.com/spreadsheets/d/1gqS1jwmpSIEdgTadQXhkbQqhm1hO3qOU1-AWwIYQqnw/edit#gid=0) with them. 27 | - [ ] Download it as a CSV. 28 | - [ ] Upload the CSV to the [OSDF Generator](http://osdf-generator.cfapps.io/static/index.html) and download the new OSDF file. 29 | - [ ] Replace the current OSDF file in the root of the project with the OSDF for the release and commit the change. 30 | 31 | ## Our repository 32 | 33 | - [ ] Draft a new release in GitHub with the tag `vX.Y.Z-rc` 34 | - [ ] Include the version's changelog entry in the description. 35 | - [ ] Upload the built tile and OSDF to the pre-release. 36 | - [ ] Check the box labeled **This is a pre-release**. 37 | - [ ] Publish the pre-release. 38 | 39 | ## Release on PivNet 40 | 41 | - [ ] Validate that the name in the generated tile's `metadata.yml` matches the slug on PivNet. 42 | - [ ] Ensure the release version is consistent on the tile and documentation. 43 | - [ ] Create a [new release on Tanzu Network](network.pivotal.io) as an Admin Only release. 44 | - [ ] Upload the tile and OSDF files that were staged to GitHub. 45 | - [ ] Check that the tile passes the tests in the [build dashboard](https://tile-dashboard.cfapps.io/tiles/gcp-service-broker). 46 | 47 | ## Upgrade the documentation 48 | 49 | - [ ] Submit a pull request to the [documentation repository](https://github.com/pivotal-cf/docs-google/tree/master/docs-content). 50 | - [ ] Include the new release notes, changes, and the ERT/PAS and Ops Managers versions, as well as your Product Version and Release Date in the Product Snapshot on PivNet. 51 | 52 | ## File for release 53 | 54 | - [ ] Fill out the [release form](https://docs.google.com/forms/d/e/1FAIpQLSctLGMU8iOuwq6NqDYI65aMhJ7widDQGo9SawDG0b8TFfq7Ag/viewform). 55 | - [ ] An ISV Program Manager will make the release available to "All Users" after review. Partner Admins can make the release available to "Admin Users". 56 | - [ ] Merge the release branch once done. 57 | - [ ] Make a release announcement in the gcp-service-broker Google Group like [this one](https://groups.google.com/forum/#!topic/gcp-service-broker/7Ae9D2B1AzE). 58 | - [ ] Submit an issue to https://github.com/cf-platform-eng/gcp-pcf-quickstart to update the GCP PCF quickstart. 59 | -------------------------------------------------------------------------------- /docs/upgrading.md: -------------------------------------------------------------------------------- 1 | ## Upgrading 2 | 3 | ### v3.X to 4.0 4 | 5 | Version 4.0 of the broker contains significant improvements to security, ability to self-service, and documentation. 6 | Specifically, new forms allow you to: 7 | 8 | * Set role whitelists on your services 9 | * Enable or disable services entirely 10 | * Set the database name 11 | 12 | Plans also come with a GUID so they'll be consistent across installs. 13 | 14 | If you: 15 | 16 | * Changed service details, description, names, GUID, or URLs via environment variables: 17 | * These will continue to work, but are deprecated. 18 | * Rely on custom roles: 19 | * You will need to add the roles to the whitelists for the services they apply to. 20 | * Used built-in plans prior to 4.0: 21 | * Enable **Compatibility with GCP Service Broker v3.X plans** in the **Compatibility** form. 22 | * You will also need to enable the new plans for your developers so they can upgrade. 23 | * If you are not using the tile, you can set the `GSB_COMPATIBILITY_THREE_TO_FOUR_LEGACY_PLANS` 24 | environment variable to true. 25 | * Have scripts using the Cloud Storage `reduced_availability` plan: 26 | * Upgrade them to use `reduced-availability` instead (underscore to dash). 27 | * Wanted to completely disable some services: 28 | * You can now do that using the enable/disable service properties. 29 | * Set a custom environment variable to change the name of the database: 30 | * You can now set it in the database form of the PCF tile. 31 | * Use a BigQuery billing export for chargebacks: 32 | * Read the [billing docs](https://github.com/GoogleCloudPlatform/gcp-service-broker/blob/master/docs/billing.md) to understand how labels are automatically applied to services now. 33 | 34 | ### v3.X to 5.0 35 | 36 | You MUST upgrade your 3.X version to 4.x before upgrading to 5.x. 37 | -------------------------------------------------------------------------------- /gcp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/gcp-service-broker/2f676b434e3f9d570f3b1d831f81e3a3de8c7664/gcp_logo.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoogleCloudPlatform/gcp-service-broker 2 | 3 | go 1.14 4 | 5 | require ( 6 | cloud.google.com/go v0.38.0 7 | code.cloudfoundry.org/lager v1.1.0 8 | github.com/aws/aws-sdk-go v1.15.88 9 | github.com/beorn7/perks v1.0.1 10 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d 11 | github.com/fsnotify/fsnotify v1.4.7 12 | github.com/go-sql-driver/mysql v1.4.0 13 | github.com/golang/protobuf v1.3.2 14 | github.com/googleapis/gax-go v2.0.0+incompatible 15 | github.com/gorilla/context v1.1.1 16 | github.com/gorilla/mux v1.6.2 17 | github.com/hashicorp/errwrap v1.0.0 18 | github.com/hashicorp/go-cleanhttp v0.5.0 19 | github.com/hashicorp/go-getter v0.0.0-20181119194526-bd1edc22f8ea 20 | github.com/hashicorp/go-multierror v1.0.0 21 | github.com/hashicorp/go-safetemp v1.0.0 22 | github.com/hashicorp/go-version v1.0.0 23 | github.com/hashicorp/hcl v1.0.0 24 | github.com/hashicorp/hil v0.0.0-20170627220502-fa9f258a9250 25 | github.com/heptiolabs/healthcheck v0.0.0-20180807145615-6ff867650f40 26 | github.com/inconshreveable/mousetrap v1.0.0 27 | github.com/jinzhu/gorm v1.9.1 28 | github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a 29 | github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 30 | github.com/magiconair/properties v1.8.0 31 | github.com/mattn/go-sqlite3 v1.9.0 32 | github.com/matttproud/golang_protobuf_extensions v1.0.1 33 | github.com/mitchellh/go-homedir v1.0.0 34 | github.com/mitchellh/go-testing-interface v1.0.0 35 | github.com/mitchellh/mapstructure v1.0.0 36 | github.com/mitchellh/reflectwalk v1.0.0 37 | github.com/pelletier/go-toml v1.2.0 38 | github.com/pivotal-cf/brokerapi v4.2.1+incompatible 39 | github.com/pkg/errors v0.8.1 40 | github.com/prometheus/client_golang v1.1.1-0.20190813114604-4efc3ccc7a66 41 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 42 | github.com/prometheus/common v0.6.0 43 | github.com/prometheus/procfs v0.0.3 44 | github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d 45 | github.com/russross/blackfriday v1.5.2 46 | github.com/spf13/afero v1.1.1 47 | github.com/spf13/cast v1.2.0 48 | github.com/spf13/cobra v0.0.3 49 | github.com/spf13/jwalterweatherman v0.0.0-20180814060501-14d3d4c51834 50 | github.com/spf13/pflag v1.0.2 51 | github.com/spf13/viper v1.1.0 52 | github.com/ulikunitz/xz v0.5.5 53 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f 54 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 55 | github.com/xeipuuv/gojsonschema v0.0.0-20180816142147-da425ebb7609 56 | go.opencensus.io v0.21.0 57 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 58 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 59 | golang.org/x/sync v0.0.0-20190423024810-112230192c58 60 | golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 61 | golang.org/x/text v0.3.2 62 | google.golang.org/api v0.7.0 63 | google.golang.org/appengine v1.5.0 64 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 65 | google.golang.org/grpc v1.23.1 66 | gopkg.in/sourcemap.v1 v1.0.5 67 | gopkg.in/yaml.v2 v2.2.1 68 | ) 69 | -------------------------------------------------------------------------------- /google-brokers/manifest.yml: -------------------------------------------------------------------------------- 1 | packversion: 1 2 | name: google-services 3 | version: 1.0.0 4 | metadata: 5 | author: Google LLC 6 | platforms: 7 | - os: linux 8 | arch: "386" 9 | - os: linux 10 | arch: amd64 11 | terraform_binaries: 12 | - name: terraform 13 | version: 0.11.9 14 | source: https://github.com/hashicorp/terraform/archive/v0.11.9.zip 15 | - name: terraform-provider-google 16 | version: 1.19.0 17 | source: https://github.com/terraform-providers/terraform-provider-google/archive/v1.19.0.zip 18 | service_definitions: 19 | - dataproc.yml 20 | - google-redis.yml 21 | -------------------------------------------------------------------------------- /hack/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Copyright 2019 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the License); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an AS IS BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eux 18 | go build -mod=mod -o gcp-service-broker 19 | 20 | ./gcp-service-broker generate tile > tile.yml 21 | ./gcp-service-broker generate manifest > manifest.yml 22 | ./gcp-service-broker generate customization > docs/customization.md 23 | ./gcp-service-broker generate use --destination-dir="docs/" 24 | ./gcp-service-broker generate use > docs/use.md 25 | -------------------------------------------------------------------------------- /hack/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Copyright 2019 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the License); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an AS IS BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eux 18 | 19 | go test -mod=mod -v ./... -tags=service_broker 20 | -------------------------------------------------------------------------------- /hack/update-osdf.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2020 Google LLC 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 | # https://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 | set -eux 17 | cd "${0%/*}"/.. 18 | 19 | if [ "$#" == "0" ]; then 20 | echo "Usage: $0 broker-version" 21 | exit 1 22 | fi 23 | 24 | temp_dir=$(mktemp -d) 25 | 26 | go run ./tools/osdfgen/osdfgen.go -p . -o "$temp_dir/osdf.csv" 27 | 28 | curl -X POST -F "name=gcp-service-broker" -F "version=$1" -F "file=@$temp_dir/osdf.csv" http://osdf-generator.cfapps.io/generate-disclosure > OSDF.txt 29 | -------------------------------------------------------------------------------- /hack/verify-generated.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google LLC 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 | # https://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 | # This is a helper script for validating if GCP Service Broker generators were executed and results were committed 18 | # 19 | set -o nounset 20 | set -o errexit 21 | set -o pipefail 22 | 23 | readonly CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 24 | 25 | # Prints first argument as header. Additionally prints current date. 26 | shout() { 27 | echo -e " 28 | ################################################################################################# 29 | # $(date) 30 | # $1 31 | ################################################################################################# 32 | " 33 | } 34 | 35 | shout "- Running GCP Service Broker generators..." 36 | ${CURRENT_DIR}/build.sh 37 | 38 | shout "- Checking for modified files..." 39 | 40 | # The porcelain format is used because it guarantees not to change in a backwards-incompatible 41 | # way between Git versions or based on user configuration. 42 | # source: https://git-scm.com/docs/git-status#_porcelain_format_version_1 43 | if [[ -n "$(git status --porcelain)" ]]; then 44 | echo "Detected modified files:" 45 | git status --porcelain 46 | 47 | echo " 48 | Run: 49 | ./hack/build.sh 50 | in the root of the repository and commit changes. 51 | " 52 | exit 1 53 | else 54 | echo "No issues detected. Have a nice day :-)" 55 | fi 56 | 57 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package main 16 | 17 | import ( 18 | "github.com/GoogleCloudPlatform/gcp-service-broker/cmd" 19 | ) 20 | 21 | func main() { 22 | cmd.Execute() 23 | } 24 | -------------------------------------------------------------------------------- /manifest.yml: -------------------------------------------------------------------------------- 1 | # Copyright the Service Broker Project Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This file is AUTOGENERATED by ./gcp-service-broker generate, DO NOT EDIT IT. 16 | 17 | --- 18 | applications: 19 | - name: gcp-service-broker 20 | memory: 1G 21 | buildpack: go_buildpack 22 | env: 23 | GOPACKAGENAME: github.com/GoogleCloudPlatform/gcp-service-broker 24 | GOVERSION: go1.14 25 | -------------------------------------------------------------------------------- /missing-properties.yml: -------------------------------------------------------------------------------- 1 | --- 2 | -------------------------------------------------------------------------------- /pkg/broker/catalog.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package broker 16 | 17 | import ( 18 | "github.com/pivotal-cf/brokerapi" 19 | ) 20 | 21 | // Service overrides the canonical Service Broker service type using a custom 22 | // type for Plans, everything else is the same. 23 | type Service struct { 24 | brokerapi.Service 25 | 26 | Plans []ServicePlan `json:"plans"` 27 | } 28 | 29 | // ToPlain converts this service to a plain PCF Service definition. 30 | func (s Service) ToPlain() brokerapi.Service { 31 | plain := s.Service 32 | plainPlans := []brokerapi.ServicePlan{} 33 | 34 | for _, plan := range s.Plans { 35 | plainPlans = append(plainPlans, plan.ServicePlan) 36 | } 37 | 38 | plain.Plans = plainPlans 39 | 40 | return plain 41 | } 42 | 43 | // ServicePlan extends the OSB ServicePlan by including a map of key/value 44 | // pairs that can be used to pass additional information to the back-end. 45 | type ServicePlan struct { 46 | brokerapi.ServicePlan 47 | 48 | ServiceProperties map[string]string `json:"service_properties"` 49 | ProvisionOverrides map[string]interface{} `json:"provision_overrides,omitempty"` 50 | BindOverrides map[string]interface{} `json:"bind_overrides,omitempty"` 51 | } 52 | 53 | // GetServiceProperties gets the plan settings variables as a string->interface map. 54 | func (sp *ServicePlan) GetServiceProperties() map[string]interface{} { 55 | props := make(map[string]interface{}) 56 | for k, v := range sp.ServiceProperties { 57 | props[k] = v 58 | } 59 | 60 | return props 61 | } 62 | -------------------------------------------------------------------------------- /pkg/broker/example.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package broker 16 | 17 | import "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation" 18 | 19 | // ServiceExample holds example configurations for a service that _should_ 20 | // work. 21 | type ServiceExample struct { 22 | // Name is a human-readable name of the example. 23 | Name string `json:"name" yaml:"name"` 24 | // Description is a long-form description of what this example is about. 25 | Description string `json:"description" yaml:"description"` 26 | // PlanId is the plan this example will run against. 27 | PlanId string `json:"plan_id" yaml:"plan_id"` 28 | 29 | // ProvisionParams is the JSON object that will be passed to provision. 30 | ProvisionParams map[string]interface{} `json:"provision_params" yaml:"provision_params"` 31 | 32 | // BindParams is the JSON object that will be passed to bind. If nil, 33 | // this example DOES NOT include a bind portion. 34 | BindParams map[string]interface{} `json:"bind_params" yaml:"bind_params"` 35 | } 36 | 37 | var _ validation.Validatable = (*ServiceExample)(nil) 38 | 39 | // Validate implements validation.Validatable. 40 | func (action *ServiceExample) Validate() (errs *validation.FieldError) { 41 | return errs.Also( 42 | validation.ErrIfBlank(action.Name, "name"), 43 | validation.ErrIfBlank(action.Description, "description"), 44 | validation.ErrIfBlank(action.PlanId, "plan_id"), 45 | ) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/broker/registry_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package broker 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/pivotal-cf/brokerapi" 21 | "github.com/spf13/viper" 22 | ) 23 | 24 | func TestRegistry_GetEnabledServices(t *testing.T) { 25 | cases := map[string]struct { 26 | Tag string 27 | Property string 28 | }{ 29 | "preview": { 30 | Tag: "preview", 31 | Property: "compatibility.enable-preview-services", 32 | }, 33 | "unmaintained": { 34 | Tag: "unmaintained", 35 | Property: "compatibility.enable-unmaintained-services", 36 | }, 37 | "eol": { 38 | Tag: "eol", 39 | Property: "compatibility.enable-eol-services", 40 | }, 41 | "beta": { 42 | Tag: "beta", 43 | Property: "compatibility.enable-gcp-beta-services", 44 | }, 45 | "deprecated": { 46 | Tag: "deprecated", 47 | Property: "compatibility.enable-gcp-deprecated-services", 48 | }, 49 | } 50 | 51 | for tn, tc := range cases { 52 | t.Run(tn, func(t *testing.T) { 53 | defer viper.Reset() 54 | 55 | sd := ServiceDefinition{ 56 | Id: "b9e4332e-b42b-4680-bda5-ea1506797474", 57 | Name: "test-service", 58 | Tags: []string{"gcp", tc.Tag}, 59 | Plans: []ServicePlan{ 60 | { 61 | ServicePlan: brokerapi.ServicePlan{ 62 | ID: "e1d11f65-da66-46ad-977c-6d56513baf43", 63 | Name: "Builtin!", 64 | Description: "Standard storage class", 65 | }, 66 | }, 67 | }, 68 | IsBuiltin: true, 69 | } 70 | 71 | registry := BrokerRegistry{} 72 | registry.Register(&sd) 73 | 74 | // shouldn't show up when property is false even if builtins are enabled 75 | viper.Set("compatibility.enable-builtin-services", true) 76 | viper.Set(tc.Property, false) 77 | if defns, err := registry.GetEnabledServices(); err != nil { 78 | t.Fatal(err) 79 | } else if len(defns) != 0 { 80 | t.Fatalf("Expected 0 definitions with %s disabled, but got %d", tc.Property, len(defns)) 81 | } 82 | 83 | // should show up when property is true 84 | viper.Set(tc.Property, true) 85 | if defns, err := registry.GetEnabledServices(); err != nil { 86 | t.Fatal(err) 87 | } else if len(defns) != 1 { 88 | t.Fatalf("Expected 1 definition with %s enabled, but got %d", tc.Property, len(defns)) 89 | } 90 | 91 | // should not show up if the service is explicitly disabled 92 | viper.Set("compatibility.enable-builtin-services", false) 93 | if defns, err := registry.GetEnabledServices(); err != nil { 94 | t.Fatal(err) 95 | } else if len(defns) != 0 { 96 | t.Fatalf("Expected no definition with builtins disabled, but got %d", len(defns)) 97 | } 98 | }) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /pkg/broker/service_provider.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package broker 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 22 | "github.com/pivotal-cf/brokerapi" 23 | ) 24 | 25 | //go:generate counterfeiter . ServiceProvider 26 | 27 | // ServiceProvider performs the actual provisoning/deprovisioning part of a service broker request. 28 | // The broker will handle storing state and validating inputs while a ServiceProvider changes GCP to match the desired state. 29 | // ServiceProviders are expected to interact with the state of the system entirely through their inputs and outputs. 30 | // Specifically, they MUST NOT modify any general state of the broker in the database. 31 | type ServiceProvider interface { 32 | // Provision creates the necessary resources that an instance of this service 33 | // needs to operate. 34 | Provision(ctx context.Context, provisionContext *varcontext.VarContext) (models.ServiceInstanceDetails, error) 35 | 36 | // Bind provisions the necessary resources for a user to be able to connect to the provisioned service. 37 | // This may include creating service accounts, granting permissions, and adding users to services e.g. a SQL database user. 38 | // It stores information necessary to access the service _and_ delete the binding in the returned map. 39 | Bind(ctx context.Context, vc *varcontext.VarContext) (map[string]interface{}, error) 40 | // BuildInstanceCredentials combines the bindRecord with any additional 41 | // info from the instance to create credentials for the binding. 42 | BuildInstanceCredentials(ctx context.Context, bindRecord models.ServiceBindingCredentials, instance models.ServiceInstanceDetails) (*brokerapi.Binding, error) 43 | // Unbind deprovisions the resources created with Bind. 44 | Unbind(ctx context.Context, instance models.ServiceInstanceDetails, details models.ServiceBindingCredentials) error 45 | // Deprovision deprovisions the service. 46 | // If the deprovision is asynchronous (results in a long-running job), then operationId is returned. 47 | // If no error and no operationId are returned, then the deprovision is expected to have been completed successfully. 48 | Deprovision(ctx context.Context, instance models.ServiceInstanceDetails, details brokerapi.DeprovisionDetails) (operationId *string, err error) 49 | PollInstance(ctx context.Context, instance models.ServiceInstanceDetails) (bool, error) 50 | ProvisionsAsync() bool 51 | DeprovisionsAsync() bool 52 | 53 | // UpdateInstanceDetails updates the ServiceInstanceDetails with the most recent state from GCP. 54 | // This function is optional, but will be called after async provisions, updates, and possibly 55 | // on broker version changes. 56 | // Return a nil error if you choose not to implement this function. 57 | UpdateInstanceDetails(ctx context.Context, instance *models.ServiceInstanceDetails) error 58 | } 59 | -------------------------------------------------------------------------------- /pkg/brokerpak/fetch_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokerpak 16 | 17 | import ( 18 | "testing" 19 | 20 | getter "github.com/hashicorp/go-getter" 21 | ) 22 | 23 | func TestDefaultGetters(t *testing.T) { 24 | getters := defaultGetters() 25 | 26 | // gcs SHOULD NOT be in there 27 | for _, prefix := range []string{"gs", "gcs"} { 28 | if getters[prefix] != nil { 29 | t.Errorf("expected default getters not to contain %q", prefix) 30 | } 31 | } 32 | 33 | for _, prefix := range []string{"http", "https", "git", "hg"} { 34 | if getters[prefix] == nil { 35 | t.Errorf("expected default getters not to contain %q", prefix) 36 | } 37 | } 38 | } 39 | 40 | func TestNewFileGetterClient(t *testing.T) { 41 | source := "http://www.example.com/foo/bar/bazz" 42 | dest := "/tmp/path/to/dest" 43 | client := newFileGetterClient(source, dest) 44 | 45 | if client.Src != source { 46 | t.Errorf("Expected Src to be %q got %q", source, client.Src) 47 | } 48 | 49 | if client.Dst != dest { 50 | t.Errorf("Expected Dst to be %q got %q", dest, client.Dst) 51 | } 52 | 53 | if client.Mode != getter.ClientModeFile { 54 | t.Errorf("Expected Dst to be %q got %q", getter.ClientModeFile, client.Mode) 55 | } 56 | 57 | if client.Getters == nil { 58 | t.Errorf("Expected getters to be set") 59 | } 60 | 61 | if client.Decompressors == nil { 62 | t.Errorf("Expected decompressors to be set") 63 | } 64 | 65 | if len(client.Decompressors) != 0 { 66 | t.Errorf("Expected decompressors to be empty") 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /pkg/brokerpak/manifest_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokerpak 16 | 17 | import ( 18 | "errors" 19 | "testing" 20 | 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation" 22 | ) 23 | 24 | func TestNewExampleManifest(t *testing.T) { 25 | exampleManifest := NewExampleManifest() 26 | 27 | if err := exampleManifest.Validate(); err != nil { 28 | t.Fatalf("example manifest should be valid, but got error: %v", err) 29 | } 30 | } 31 | 32 | func TestManifestParameter_Validate(t *testing.T) { 33 | cases := map[string]validation.ValidatableTest{ 34 | "blank obj": { 35 | Object: &ManifestParameter{}, 36 | Expect: errors.New("missing field(s): description, name"), 37 | }, 38 | "good obj": { 39 | Object: &ManifestParameter{ 40 | Name: "TEST", 41 | Description: "Usage goes here", 42 | }, 43 | }, 44 | } 45 | 46 | for tn, tc := range cases { 47 | t.Run(tn, func(t *testing.T) { 48 | tc.Assert(t) 49 | }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /pkg/brokerpak/platform.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokerpak 16 | 17 | import ( 18 | "fmt" 19 | "runtime" 20 | 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation" 22 | ) 23 | 24 | // Platform holds an os/architecture pair. 25 | type Platform struct { 26 | Os string `yaml:"os"` 27 | Arch string `yaml:"arch"` 28 | } 29 | 30 | var _ validation.Validatable = (*Platform)(nil) 31 | 32 | // Validate implements validation.Validatable. 33 | func (p Platform) Validate() (errs *validation.FieldError) { 34 | return errs.Also( 35 | validation.ErrIfBlank(p.Os, "os"), 36 | validation.ErrIfBlank(p.Arch, "arch"), 37 | ) 38 | } 39 | 40 | // String formats the platform as an os/arch pair. 41 | func (p Platform) String() string { 42 | return fmt.Sprintf("%s/%s", p.Os, p.Arch) 43 | } 44 | 45 | // Equals is an equality test between this platform and the other. 46 | func (p Platform) Equals(other Platform) bool { 47 | return p.String() == other.String() 48 | } 49 | 50 | // MatchesCurrent returns true if the platform matches this binary's GOOS/GOARCH combination. 51 | func (p Platform) MatchesCurrent() bool { 52 | return p.Equals(CurrentPlatform()) 53 | } 54 | 55 | // CurrentPlatform returns the platform defined by GOOS and GOARCH. 56 | func CurrentPlatform() Platform { 57 | return Platform{Os: runtime.GOOS, Arch: runtime.GOARCH} 58 | } 59 | -------------------------------------------------------------------------------- /pkg/brokerpak/platform_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokerpak 16 | 17 | import ( 18 | "errors" 19 | "fmt" 20 | "testing" 21 | 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation" 23 | ) 24 | 25 | func ExamplePlatform_String() { 26 | p := Platform{Os: "bsd", Arch: "amd64"} 27 | fmt.Println(p.String()) 28 | 29 | // Output: bsd/amd64 30 | } 31 | 32 | func ExamplePlatform_Equals() { 33 | p := Platform{Os: "beos", Arch: "webasm"} 34 | fmt.Println(p.Equals(p)) 35 | fmt.Println(p.Equals(CurrentPlatform())) 36 | 37 | // Output: true 38 | // false 39 | } 40 | 41 | func ExamplePlatform_MatchesCurrent() { 42 | fmt.Println(CurrentPlatform().MatchesCurrent()) 43 | 44 | // Output: true 45 | } 46 | 47 | func TestPlatform_Validate(t *testing.T) { 48 | cases := map[string]validation.ValidatableTest{ 49 | "blank obj": { 50 | Object: &Platform{}, 51 | Expect: errors.New("missing field(s): arch, os"), 52 | }, 53 | "good obj": { 54 | Object: &Platform{ 55 | Os: "linux", 56 | Arch: "amd64", 57 | }, 58 | }, 59 | } 60 | 61 | for tn, tc := range cases { 62 | t.Run(tn, func(t *testing.T) { 63 | tc.Assert(t) 64 | }) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /pkg/brokerpak/testdata/dummy-brokerpaks/first.brokerpak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/gcp-service-broker/2f676b434e3f9d570f3b1d831f81e3a3de8c7664/pkg/brokerpak/testdata/dummy-brokerpaks/first.brokerpak -------------------------------------------------------------------------------- /pkg/brokerpak/testdata/dummy-brokerpaks/not-a-brokerpak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/gcp-service-broker/2f676b434e3f9d570f3b1d831f81e3a3de8c7664/pkg/brokerpak/testdata/dummy-brokerpaks/not-a-brokerpak -------------------------------------------------------------------------------- /pkg/brokerpak/testdata/dummy-brokerpaks/second.brokerpak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/gcp-service-broker/2f676b434e3f9d570f3b1d831f81e3a3de8c7664/pkg/brokerpak/testdata/dummy-brokerpaks/second.brokerpak -------------------------------------------------------------------------------- /pkg/brokerpak/testdata/no-brokerpaks/not-a-brokerpak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/gcp-service-broker/2f676b434e3f9d570f3b1d831f81e3a3de8c7664/pkg/brokerpak/testdata/no-brokerpaks/not-a-brokerpak -------------------------------------------------------------------------------- /pkg/brokerpak/tf_resource.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokerpak 16 | 17 | import ( 18 | "strings" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation" 21 | ) 22 | 23 | // HashicorpUrlTemplate holds the default template for Hashicorp's terraform binary archive downloads. 24 | const HashicorpUrlTemplate = "https://releases.hashicorp.com/${name}/${version}/${name}_${version}_${os}_${arch}.zip" 25 | 26 | // TerraformResource represents a downloadable binary dependency (Terraform 27 | // version or Provider). 28 | type TerraformResource struct { 29 | // Name holds the name of this resource. e.g. terraform-provider-google-beta 30 | Name string `yaml:"name"` 31 | 32 | // Version holds the version of the resource e.g. 1.19.0 33 | Version string `yaml:"version"` 34 | 35 | // Source holds the URI of an archive that contains the source code for this release. 36 | Source string `yaml:"source"` 37 | 38 | // UrlTemplate holds a custom URL template to get the release of the given tool. 39 | // Paramaters available are ${name}, ${version}, ${os}, and ${arch}. 40 | // If non is specified HashicorpUrlTemplate is used. 41 | UrlTemplate string `yaml:"url_template,omitempty"` 42 | } 43 | 44 | var _ validation.Validatable = (*TerraformResource)(nil) 45 | 46 | // Validate implements validation.Validatable. 47 | func (tr *TerraformResource) Validate() (errs *validation.FieldError) { 48 | return errs.Also( 49 | validation.ErrIfBlank(tr.Name, "name"), 50 | validation.ErrIfBlank(tr.Version, "version"), 51 | validation.ErrIfBlank(tr.Source, "source"), 52 | ) 53 | } 54 | 55 | // Url constructs a download URL based on a platform. 56 | func (tr *TerraformResource) Url(platform Platform) string { 57 | replacer := strings.NewReplacer("${name}", tr.Name, "${version}", tr.Version, "${os}", platform.Os, "${arch}", platform.Arch) 58 | url := tr.UrlTemplate 59 | if url == "" { 60 | url = HashicorpUrlTemplate 61 | } 62 | 63 | return replacer.Replace(url) 64 | } 65 | -------------------------------------------------------------------------------- /pkg/brokerpak/tf_resource_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package brokerpak 16 | 17 | import ( 18 | "errors" 19 | "testing" 20 | 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation" 22 | ) 23 | 24 | func TestTerraformResource_Validate(t *testing.T) { 25 | cases := map[string]validation.ValidatableTest{ 26 | "blank obj": { 27 | Object: &TerraformResource{}, 28 | Expect: errors.New("missing field(s): name, source, version"), 29 | }, 30 | "good obj": { 31 | Object: &TerraformResource{ 32 | Name: "foo", 33 | Version: "1.0", 34 | Source: "github.com/myproject", 35 | }, 36 | }, 37 | } 38 | 39 | for tn, tc := range cases { 40 | t.Run(tn, func(t *testing.T) { 41 | tc.Assert(t) 42 | }) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pkg/client/broker-response.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package client 16 | 17 | import ( 18 | "encoding/json" 19 | "fmt" 20 | "io/ioutil" 21 | "net/http" 22 | ) 23 | 24 | // BrokerResponse encodes an OSB HTTP response in a (technical) human and 25 | // machine readable way. 26 | type BrokerResponse struct { 27 | // WARNING: BrokerResponse is exposed to users and automated tooling 28 | // so DO NOT remove or rename fields unless strictly necessary. 29 | // You MAY add new fields. 30 | Error error `json:"error,omitempty"` 31 | Url string `json:"url,omitempty"` 32 | Method string `json:"http_method,omitempty"` 33 | StatusCode int `json:"status_code,omitempty"` 34 | ResponseBody json.RawMessage `json:"response,omitempty"` 35 | } 36 | 37 | func (br *BrokerResponse) UpdateError(err error) { 38 | if br.Error == nil { 39 | br.Error = err 40 | } 41 | } 42 | 43 | func (br *BrokerResponse) UpdateRequest(req *http.Request) { 44 | if req == nil { 45 | return 46 | } 47 | 48 | br.Url = req.URL.String() 49 | br.Method = req.Method 50 | } 51 | 52 | func (br *BrokerResponse) UpdateResponse(res *http.Response) { 53 | if res == nil { 54 | return 55 | } 56 | 57 | br.StatusCode = res.StatusCode 58 | 59 | body, err := ioutil.ReadAll(res.Body) 60 | if err != nil { 61 | br.UpdateError(err) 62 | } else { 63 | br.ResponseBody = json.RawMessage(body) 64 | } 65 | } 66 | 67 | func (br *BrokerResponse) InError() bool { 68 | return br.Error != nil 69 | } 70 | 71 | func (br *BrokerResponse) String() string { 72 | if br.InError() { 73 | return fmt.Sprintf("%s %s -> %d, Error: %q)", br.Method, br.Url, br.StatusCode, br.Error) 74 | } 75 | 76 | return fmt.Sprintf("%s %s -> %d, %q", br.Method, br.Url, br.StatusCode, br.ResponseBody) 77 | } 78 | -------------------------------------------------------------------------------- /pkg/client/testdata/complete-service-examples-testfile.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Basic Configuration", 4 | "description": "Creates an account with the permission `clouddebugger.agent`.", 5 | "plan_id": "10866183-a775-49e8-96e3-4e7a901e4a79", 6 | "provision_params": {}, 7 | "bind_params": {}, 8 | "ServiceName": "google-stackdriver-debugger", 9 | "ServiceId": "83837945-1547-41e0-b661-ea31d76eed11", 10 | "ExpectedOutput": { 11 | "$schema": "http://json-schema.org/draft-04/schema#", 12 | "properties": { 13 | "Email": { 14 | "description": "Email address of the service account.", 15 | "title": "Email", 16 | "type": "string" 17 | } 18 | }, 19 | "required": [ 20 | "Email" 21 | ], 22 | "type": "object" 23 | } 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /pkg/config/migration/diff.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package migration 16 | 17 | import "github.com/GoogleCloudPlatform/gcp-service-broker/utils" 18 | 19 | // Diff holds the difference between two strings. 20 | type Diff struct { 21 | Old string `yaml:"old,omitempty"` 22 | New string `yaml:"new"` // new is intentionally not omitempty to show change 23 | } 24 | 25 | // DiffStringMap creates a diff between the two maps. 26 | func DiffStringMap(old, new map[string]string) map[string]Diff { 27 | allKeys := utils.NewStringSetFromStringMapKeys(old) 28 | newKeys := utils.NewStringSetFromStringMapKeys(new) 29 | allKeys.Add(newKeys.ToSlice()...) 30 | 31 | out := make(map[string]Diff) 32 | for _, k := range allKeys.ToSlice() { 33 | if old[k] != new[k] { 34 | out[k] = Diff{Old: old[k], New: new[k]} 35 | } 36 | } 37 | 38 | return out 39 | } 40 | -------------------------------------------------------------------------------- /pkg/config/migration/diff_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package migration 16 | 17 | import ( 18 | "reflect" 19 | "testing" 20 | ) 21 | 22 | func TestDiffStringMap(t *testing.T) { 23 | cases := map[string]struct { 24 | Old map[string]string 25 | New map[string]string 26 | Expected map[string]Diff 27 | }{ 28 | "same": { 29 | Old: map[string]string{"a": "b"}, 30 | New: map[string]string{"a": "b"}, 31 | Expected: map[string]Diff{}, 32 | }, 33 | "removed": { 34 | Old: map[string]string{"a": "old"}, 35 | New: map[string]string{}, 36 | Expected: map[string]Diff{"a": Diff{Old: "old", New: ""}}, 37 | }, 38 | "added": { 39 | Old: map[string]string{}, 40 | New: map[string]string{"a": "new"}, 41 | Expected: map[string]Diff{"a": Diff{Old: "", New: "new"}}, 42 | }, 43 | "changed": { 44 | Old: map[string]string{"a": "old"}, 45 | New: map[string]string{"a": "new"}, 46 | Expected: map[string]Diff{"a": Diff{Old: "old", New: "new"}}, 47 | }, 48 | "full-gambit": { 49 | Old: map[string]string{ 50 | "removed": "removed", 51 | "changed": "orig", 52 | }, 53 | New: map[string]string{ 54 | "changed": "new", 55 | "added": "added", 56 | }, 57 | Expected: map[string]Diff{ 58 | "removed": Diff{Old: "removed", New: ""}, 59 | "changed": Diff{Old: "orig", New: "new"}, 60 | "added": Diff{Old: "", New: "added"}, 61 | }, 62 | }, 63 | } 64 | 65 | for tn, tc := range cases { 66 | t.Run(tn, func(t *testing.T) { 67 | actual := DiffStringMap(tc.Old, tc.New) 68 | 69 | if !reflect.DeepEqual(tc.Expected, actual) { 70 | t.Errorf("Expected: %#v Actual: %#v", tc.Expected, actual) 71 | } 72 | }) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pkg/providers/builtin/account_managers/iam.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package account_managers 16 | 17 | import ( 18 | "github.com/GoogleCloudPlatform/gcp-service-broker/utils" 19 | cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v1" 20 | ) 21 | 22 | // Merge multiple Bindings such that Bindings with the same Role result in 23 | // a single Binding with combined Members 24 | func mergeBindings(bindings []*cloudresourcemanager.Binding) []*cloudresourcemanager.Binding { 25 | rb := []*cloudresourcemanager.Binding{} 26 | 27 | for role, members := range rolesToMembersMap(bindings) { 28 | if members.IsEmpty() { 29 | continue 30 | } 31 | 32 | rb = append(rb, &cloudresourcemanager.Binding{ 33 | Role: role, 34 | Members: members.ToSlice(), 35 | }) 36 | } 37 | 38 | return rb 39 | } 40 | 41 | // Map a role to a map of members, allowing easy merging of multiple bindings. 42 | func rolesToMembersMap(bindings []*cloudresourcemanager.Binding) map[string]utils.StringSet { 43 | bm := make(map[string]utils.StringSet) 44 | for _, b := range bindings { 45 | if set, ok := bm[b.Role]; ok { 46 | set.Add(b.Members...) 47 | } else { 48 | bm[b.Role] = utils.NewStringSet(b.Members...) 49 | } 50 | } 51 | 52 | return bm 53 | } 54 | 55 | // Remove a member from all role bindings to clean up the iam policy before deleting a service account. 56 | func removeMemberFromBindings(bindings []*cloudresourcemanager.Binding, memberToRemove string) []*cloudresourcemanager.Binding { 57 | for _, binding := range bindings { 58 | for i, member := range binding.Members { 59 | if member == memberToRemove { 60 | binding.Members = append(binding.Members[:i], binding.Members[i+1:]...) 61 | break 62 | } 63 | } 64 | } 65 | 66 | return bindings 67 | } 68 | -------------------------------------------------------------------------------- /pkg/providers/builtin/account_managers/service_account_manager_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package account_managers 16 | 17 | import ( 18 | "reflect" 19 | "testing" 20 | 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 22 | ) 23 | 24 | func TestServiceAccountWhitelistWithDefault(t *testing.T) { 25 | details := `The role for the account without the "roles/" prefix. See: https://cloud.google.com/iam/docs/understanding-roles for more details.` 26 | 27 | cases := map[string]struct { 28 | Whitelist []string 29 | DefaultRole string 30 | Expected broker.BrokerVariable 31 | }{ 32 | "default in whitelist": { 33 | Whitelist: []string{"foo"}, 34 | DefaultRole: "foo", 35 | Expected: broker.BrokerVariable{ 36 | FieldName: "role", 37 | Type: broker.JsonTypeString, 38 | Details: details, 39 | 40 | Required: false, 41 | Default: "foo", 42 | Enum: map[interface{}]string{"foo": "roles/foo"}, 43 | }, 44 | }, 45 | 46 | "default not in whitelist": { 47 | Whitelist: []string{"foo"}, 48 | DefaultRole: "test", 49 | Expected: broker.BrokerVariable{ 50 | FieldName: "role", 51 | Type: broker.JsonTypeString, 52 | Details: details, 53 | 54 | Required: false, 55 | Default: "test", 56 | Enum: map[interface{}]string{"foo": "roles/foo"}, 57 | }, 58 | }, 59 | } 60 | 61 | for tn, tc := range cases { 62 | t.Run(tn, func(t *testing.T) { 63 | vars := ServiceAccountWhitelistWithDefault(tc.Whitelist, tc.DefaultRole) 64 | if len(vars) != 1 { 65 | t.Fatalf("Expected 1 input variable, got %d", len(vars)) 66 | } 67 | 68 | if !reflect.DeepEqual(vars[0], tc.Expected) { 69 | t.Fatalf("Expected %#v, got %#v", tc.Expected, vars[0]) 70 | } 71 | }) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /pkg/providers/builtin/base/broker_base.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package base 16 | 17 | import ( 18 | "context" 19 | 20 | "code.cloudfoundry.org/lager" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/account_managers" 23 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 24 | 25 | "golang.org/x/oauth2/jwt" 26 | ) 27 | 28 | //go:generate counterfeiter . ServiceAccountManager 29 | 30 | type ServiceAccountManager interface { 31 | CreateCredentials(ctx context.Context, vc *varcontext.VarContext) (map[string]interface{}, error) 32 | DeleteCredentials(ctx context.Context, creds models.ServiceBindingCredentials) error 33 | } 34 | 35 | // NewBrokerBase creates a new broker base and account manager it uses from the 36 | // given settings. 37 | func NewBrokerBase(projectId string, auth *jwt.Config, logger lager.Logger) BrokerBase { 38 | saManager := &account_managers.ServiceAccountManager{ 39 | HttpConfig: auth, 40 | ProjectId: projectId, 41 | Logger: logger, 42 | } 43 | 44 | return BrokerBase{ 45 | AccountManager: saManager, 46 | HttpConfig: auth, 47 | ProjectId: projectId, 48 | Logger: logger, 49 | } 50 | } 51 | 52 | // BrokerBase is the reference bind and unbind implementation for brokers that 53 | // bind and unbind with only Service Accounts. 54 | type BrokerBase struct { 55 | synchronousBase 56 | MergedInstanceCredsMixin 57 | 58 | AccountManager ServiceAccountManager 59 | HttpConfig *jwt.Config 60 | ProjectId string 61 | Logger lager.Logger 62 | } 63 | 64 | // Bind creates a service account with access to the provisioned resource with 65 | // the given instance. 66 | func (b *BrokerBase) Bind(ctx context.Context, vc *varcontext.VarContext) (map[string]interface{}, error) { 67 | return b.AccountManager.CreateCredentials(ctx, vc) 68 | } 69 | 70 | // Unbind deletes the created service account from the GCP Project. 71 | func (b *BrokerBase) Unbind(ctx context.Context, instance models.ServiceInstanceDetails, creds models.ServiceBindingCredentials) error { 72 | return b.AccountManager.DeleteCredentials(ctx, creds) 73 | } 74 | 75 | // UpdateInstanceDetails updates the ServiceInstanceDetails with the most recent state from GCP. 76 | // This instance is a no-op method. 77 | func (b *BrokerBase) UpdateInstanceDetails(ctx context.Context, instance *models.ServiceInstanceDetails) error { 78 | return nil 79 | } 80 | -------------------------------------------------------------------------------- /pkg/providers/builtin/base/peered_network_service.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package base 16 | 17 | import ( 18 | "code.cloudfoundry.org/lager" 19 | "golang.org/x/oauth2/jwt" 20 | ) 21 | 22 | // NewPeeredNetworkServiceBase creates a new PeeredNetworkServiceBase from the 23 | // given settings. 24 | func NewPeeredNetworkServiceBase(projectID string, auth *jwt.Config, logger lager.Logger) PeeredNetworkServiceBase { 25 | return PeeredNetworkServiceBase{ 26 | HTTPConfig: auth, 27 | DefaultProjectID: projectID, 28 | Logger: logger, 29 | } 30 | } 31 | 32 | // PeeredNetworkServiceBase is a base for services that are attached to a 33 | // project via peered network. 34 | type PeeredNetworkServiceBase struct { 35 | MergedInstanceCredsMixin 36 | 37 | AccountManager ServiceAccountManager 38 | HTTPConfig *jwt.Config 39 | DefaultProjectID string 40 | Logger lager.Logger 41 | } 42 | -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/mysql-vpc-definition.go: -------------------------------------------------------------------------------- 1 | package cloudsql 2 | 3 | import ( 4 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 5 | "github.com/pivotal-cf/brokerapi" 6 | ) 7 | 8 | const mySQLVPCID = "b48d2a6b-b1b0-499f-8389-57ba33bfbb19" 9 | 10 | // MySQLVPCServiceDefinition creates a new ServiceDefinition object for the MySQL service 11 | // on a VPC. 12 | func MySQLVPCServiceDefinition() *broker.ServiceDefinition { 13 | definition := buildDatabase(cloudSQLOptions{ 14 | DatabaseType: mySQLDatabaseType, 15 | CustomizableActivationPolicy: false, 16 | AdminControlsTier: false, 17 | AdminControlsMaxDiskSize: false, 18 | VPCNetwork: true, 19 | }) 20 | definition.Id = mySQLVPCID 21 | definition.Plans = []broker.ServicePlan{ 22 | { 23 | ServicePlan: brokerapi.ServicePlan{ 24 | ID: "89e2c84e-4d5c-457c-ad14-329dcf44b806", 25 | Name: "default", 26 | Description: "MySQL attached to a VPC", 27 | Free: brokerapi.FreeValue(false), 28 | }, 29 | ServiceProperties: map[string]string{}, 30 | }, 31 | } 32 | 33 | definition.Examples = []broker.ServiceExample{ 34 | { 35 | Name: "HA Instance", 36 | Description: "A regionally available database with automatic failover.", 37 | PlanId: "89e2c84e-4d5c-457c-ad14-329dcf44b806", 38 | ProvisionParams: map[string]interface{}{ 39 | "tier": "db-n1-standard-1", 40 | "backups_enabled": "true", 41 | "binlog": "true", 42 | "availability_type": "REGIONAL", 43 | }, 44 | BindParams: map[string]interface{}{ 45 | "role": "cloudsql.editor", 46 | }, 47 | }, 48 | { 49 | Name: "Development Sandbox", 50 | Description: "An inexpensive MySQL sandbox for developing with no backups.", 51 | PlanId: "89e2c84e-4d5c-457c-ad14-329dcf44b806", 52 | ProvisionParams: map[string]interface{}{ 53 | "tier": "db-n1-standard-1", 54 | "backups_enabled": "false", 55 | "binlog": "false", 56 | "disk_size": "10", 57 | }, 58 | BindParams: map[string]interface{}{ 59 | "role": "cloudsql.editor", 60 | }, 61 | }, 62 | } 63 | 64 | return definition 65 | } 66 | -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/postgres-vpc-definition.go: -------------------------------------------------------------------------------- 1 | package cloudsql 2 | 3 | import ( 4 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 5 | "github.com/pivotal-cf/brokerapi" 6 | ) 7 | 8 | const postgresVPCID = "c90ea118-605a-47e8-8f63-57fc09c113f1" 9 | 10 | // PostgresVPCServiceDefinition creates a new ServiceDefinition object for the 11 | // Postgres service on a VPC. 12 | func PostgresVPCServiceDefinition() *broker.ServiceDefinition { 13 | definition := buildDatabase(cloudSQLOptions{ 14 | DatabaseType: postgresDatabaseType, 15 | CustomizableActivationPolicy: false, 16 | AdminControlsTier: false, 17 | AdminControlsMaxDiskSize: false, 18 | VPCNetwork: true, 19 | }) 20 | definition.Id = postgresVPCID 21 | definition.Name = "google-cloudsql-postgres-vpc" 22 | definition.Plans = []broker.ServicePlan{ 23 | { 24 | ServicePlan: brokerapi.ServicePlan{ 25 | ID: "60f0b6c0-c48f-4f84-baab-57836611e013", 26 | Name: "default", 27 | Description: "PostgreSQL attached to a VPC", 28 | Free: brokerapi.FreeValue(false), 29 | }, 30 | ServiceProperties: map[string]string{}, 31 | }, 32 | } 33 | 34 | definition.Examples = []broker.ServiceExample{ 35 | { 36 | Name: "Dedicated Machine Sandbox", 37 | Description: "A low end PostgreSQL sandbox that uses a dedicated machine.", 38 | PlanId: "60f0b6c0-c48f-4f84-baab-57836611e013", 39 | ProvisionParams: map[string]interface{}{ 40 | "tier": "db-custom-1-3840", 41 | "backups_enabled": "false", 42 | "disk_size": "25", 43 | }, 44 | BindParams: map[string]interface{}{ 45 | "role": "cloudsql.editor", 46 | }, 47 | }, 48 | { 49 | Name: "HA Instance", 50 | Description: "A regionally available database with automatic failover.", 51 | PlanId: "60f0b6c0-c48f-4f84-baab-57836611e013", 52 | ProvisionParams: map[string]interface{}{ 53 | "tier": "db-custom-1-3840", 54 | "backups_enabled": "true", 55 | "disk_size": "25", 56 | "availability_type": "REGIONAL", 57 | }, 58 | BindParams: map[string]interface{}{ 59 | "role": "cloudsql.editor", 60 | }, 61 | }, 62 | } 63 | 64 | return definition 65 | } 66 | -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-mysql-vpc/Development_Sandbox: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "Development Sandbox", 4 | // "description": "An inexpensive MySQL sandbox for developing with no backups.", 5 | // "plan_id": "89e2c84e-4d5c-457c-ad14-329dcf44b806", 6 | // "provision_params": { 7 | // "backups_enabled": "false", 8 | // "binlog": "false", 9 | // "disk_size": "10", 10 | // "tier": "db-n1-standard-1" 11 | // }, 12 | // "bind_params": { 13 | // "role": "cloudsql.editor" 14 | // } 15 | // } 16 | // } 17 | { 18 | "databaseVersion": "MYSQL_5_7", 19 | "name": "NONDETERMINISTIC", 20 | "region": "us-central", 21 | "settings": { 22 | "activationPolicy": "ALWAYS", 23 | "availabilityType": "ZONAL", 24 | "backupConfiguration": { 25 | "startTime": "06:00" 26 | }, 27 | "dataDiskSizeGb": "10", 28 | "dataDiskType": "PD_SSD", 29 | "ipConfiguration": { 30 | "ipv4Enabled": false, 31 | "privateNetwork": "default", 32 | "requireSsl": true 33 | }, 34 | "locationPreference": {}, 35 | "maintenanceWindow": { 36 | "day": 1, 37 | "hour": 0, 38 | "updateTrack": "stable" 39 | }, 40 | "pricingPlan": "PER_USE", 41 | "storageAutoResize": false, 42 | "tier": "db-n1-standard-1", 43 | "userLabels": { 44 | "pcf-instance-id": "instance-id-here", 45 | "pcf-organization-guid": "", 46 | "pcf-space-guid": "" 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-mysql-vpc/HA_Instance: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "HA Instance", 4 | // "description": "A regionally available database with automatic failover.", 5 | // "plan_id": "89e2c84e-4d5c-457c-ad14-329dcf44b806", 6 | // "provision_params": { 7 | // "availability_type": "REGIONAL", 8 | // "backups_enabled": "true", 9 | // "binlog": "true", 10 | // "tier": "db-n1-standard-1" 11 | // }, 12 | // "bind_params": { 13 | // "role": "cloudsql.editor" 14 | // } 15 | // } 16 | // } 17 | { 18 | "databaseVersion": "MYSQL_5_7", 19 | "name": "NONDETERMINISTIC", 20 | "region": "us-central", 21 | "settings": { 22 | "activationPolicy": "ALWAYS", 23 | "availabilityType": "REGIONAL", 24 | "backupConfiguration": { 25 | "binaryLogEnabled": true, 26 | "enabled": true, 27 | "startTime": "06:00" 28 | }, 29 | "dataDiskSizeGb": "10", 30 | "dataDiskType": "PD_SSD", 31 | "ipConfiguration": { 32 | "ipv4Enabled": false, 33 | "privateNetwork": "default", 34 | "requireSsl": true 35 | }, 36 | "locationPreference": {}, 37 | "maintenanceWindow": { 38 | "day": 1, 39 | "hour": 0, 40 | "updateTrack": "stable" 41 | }, 42 | "pricingPlan": "PER_USE", 43 | "storageAutoResize": false, 44 | "tier": "db-n1-standard-1", 45 | "userLabels": { 46 | "pcf-instance-id": "instance-id-here", 47 | "pcf-organization-guid": "", 48 | "pcf-space-guid": "" 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-mysql/Development_Sandbox: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "Development Sandbox", 4 | // "description": "An inexpensive MySQL sandbox for developing with no backups.", 5 | // "plan_id": "7d8f9ade-30c1-4c96-b622-ea0205cc5f0b", 6 | // "provision_params": { 7 | // "backups_enabled": "false", 8 | // "binlog": "false", 9 | // "disk_size": "10" 10 | // }, 11 | // "bind_params": { 12 | // "role": "cloudsql.editor" 13 | // } 14 | // } 15 | // } 16 | { 17 | "databaseVersion": "MYSQL_5_7", 18 | "name": "NONDETERMINISTIC", 19 | "region": "us-central", 20 | "settings": { 21 | "activationPolicy": "ALWAYS", 22 | "availabilityType": "ZONAL", 23 | "backupConfiguration": { 24 | "startTime": "06:00" 25 | }, 26 | "dataDiskSizeGb": "10", 27 | "dataDiskType": "PD_SSD", 28 | "ipConfiguration": { 29 | "ipv4Enabled": true, 30 | "requireSsl": true 31 | }, 32 | "locationPreference": {}, 33 | "maintenanceWindow": { 34 | "day": 1, 35 | "hour": 0, 36 | "updateTrack": "stable" 37 | }, 38 | "pricingPlan": "PER_USE", 39 | "storageAutoResize": false, 40 | "tier": "db-f1-micro", 41 | "userLabels": { 42 | "pcf-instance-id": "instance-id-here", 43 | "pcf-organization-guid": "", 44 | "pcf-space-guid": "" 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-mysql/HA_Instance: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "HA Instance", 4 | // "description": "A regionally available database with automatic failover.", 5 | // "plan_id": "7d8f9ade-30c1-4c96-b622-ea0205cc5f0b", 6 | // "provision_params": { 7 | // "availability_type": "REGIONAL", 8 | // "backups_enabled": "true", 9 | // "binlog": "true" 10 | // }, 11 | // "bind_params": { 12 | // "role": "cloudsql.editor" 13 | // } 14 | // } 15 | // } 16 | { 17 | "databaseVersion": "MYSQL_5_7", 18 | "name": "NONDETERMINISTIC", 19 | "region": "us-central", 20 | "settings": { 21 | "activationPolicy": "ALWAYS", 22 | "availabilityType": "REGIONAL", 23 | "backupConfiguration": { 24 | "binaryLogEnabled": true, 25 | "enabled": true, 26 | "startTime": "06:00" 27 | }, 28 | "dataDiskSizeGb": "10", 29 | "dataDiskType": "PD_SSD", 30 | "ipConfiguration": { 31 | "ipv4Enabled": true, 32 | "requireSsl": true 33 | }, 34 | "locationPreference": {}, 35 | "maintenanceWindow": { 36 | "day": 1, 37 | "hour": 0, 38 | "updateTrack": "stable" 39 | }, 40 | "pricingPlan": "PER_USE", 41 | "storageAutoResize": false, 42 | "tier": "db-f1-micro", 43 | "userLabels": { 44 | "pcf-instance-id": "instance-id-here", 45 | "pcf-organization-guid": "", 46 | "pcf-space-guid": "" 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-postgres-vpc/Dedicated_Machine_Sandbox: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "Dedicated Machine Sandbox", 4 | // "description": "A low end PostgreSQL sandbox that uses a dedicated machine.", 5 | // "plan_id": "60f0b6c0-c48f-4f84-baab-57836611e013", 6 | // "provision_params": { 7 | // "backups_enabled": "false", 8 | // "disk_size": "25", 9 | // "tier": "db-custom-1-3840" 10 | // }, 11 | // "bind_params": { 12 | // "role": "cloudsql.editor" 13 | // } 14 | // } 15 | // } 16 | { 17 | "databaseVersion": "POSTGRES_11", 18 | "name": "NONDETERMINISTIC", 19 | "region": "us-central", 20 | "settings": { 21 | "activationPolicy": "ALWAYS", 22 | "availabilityType": "ZONAL", 23 | "backupConfiguration": { 24 | "startTime": "06:00" 25 | }, 26 | "dataDiskSizeGb": "25", 27 | "dataDiskType": "PD_SSD", 28 | "ipConfiguration": { 29 | "ipv4Enabled": false, 30 | "privateNetwork": "default", 31 | "requireSsl": true 32 | }, 33 | "locationPreference": {}, 34 | "maintenanceWindow": { 35 | "day": 1, 36 | "hour": 0, 37 | "updateTrack": "stable" 38 | }, 39 | "pricingPlan": "PER_USE", 40 | "storageAutoResize": false, 41 | "tier": "db-custom-1-3840", 42 | "userLabels": { 43 | "pcf-instance-id": "instance-id-here", 44 | "pcf-organization-guid": "", 45 | "pcf-space-guid": "" 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-postgres-vpc/HA_Instance: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "HA Instance", 4 | // "description": "A regionally available database with automatic failover.", 5 | // "plan_id": "60f0b6c0-c48f-4f84-baab-57836611e013", 6 | // "provision_params": { 7 | // "availability_type": "REGIONAL", 8 | // "backups_enabled": "true", 9 | // "disk_size": "25", 10 | // "tier": "db-custom-1-3840" 11 | // }, 12 | // "bind_params": { 13 | // "role": "cloudsql.editor" 14 | // } 15 | // } 16 | // } 17 | { 18 | "databaseVersion": "POSTGRES_11", 19 | "name": "NONDETERMINISTIC", 20 | "region": "us-central", 21 | "settings": { 22 | "activationPolicy": "ALWAYS", 23 | "availabilityType": "REGIONAL", 24 | "backupConfiguration": { 25 | "enabled": true, 26 | "startTime": "06:00" 27 | }, 28 | "dataDiskSizeGb": "25", 29 | "dataDiskType": "PD_SSD", 30 | "ipConfiguration": { 31 | "ipv4Enabled": false, 32 | "privateNetwork": "default", 33 | "requireSsl": true 34 | }, 35 | "locationPreference": {}, 36 | "maintenanceWindow": { 37 | "day": 1, 38 | "hour": 0, 39 | "updateTrack": "stable" 40 | }, 41 | "pricingPlan": "PER_USE", 42 | "storageAutoResize": false, 43 | "tier": "db-custom-1-3840", 44 | "userLabels": { 45 | "pcf-instance-id": "instance-id-here", 46 | "pcf-organization-guid": "", 47 | "pcf-space-guid": "" 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-postgres/Dedicated_Machine_Sandbox: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "Dedicated Machine Sandbox", 4 | // "description": "A low end PostgreSQL sandbox that uses a dedicated machine.", 5 | // "plan_id": "c4e68ab5-34ca-4d02-857d-3e6b3ab079a7", 6 | // "provision_params": { 7 | // "backups_enabled": "false", 8 | // "disk_size": "25" 9 | // }, 10 | // "bind_params": { 11 | // "role": "cloudsql.editor" 12 | // } 13 | // } 14 | // } 15 | { 16 | "databaseVersion": "POSTGRES_11", 17 | "name": "NONDETERMINISTIC", 18 | "region": "us-central", 19 | "settings": { 20 | "activationPolicy": "ALWAYS", 21 | "availabilityType": "ZONAL", 22 | "backupConfiguration": { 23 | "startTime": "06:00" 24 | }, 25 | "dataDiskSizeGb": "25", 26 | "dataDiskType": "PD_SSD", 27 | "ipConfiguration": { 28 | "ipv4Enabled": true, 29 | "requireSsl": true 30 | }, 31 | "locationPreference": {}, 32 | "maintenanceWindow": { 33 | "day": 1, 34 | "hour": 0, 35 | "updateTrack": "stable" 36 | }, 37 | "pricingPlan": "PER_USE", 38 | "storageAutoResize": false, 39 | "tier": "db-custom-1-3840", 40 | "userLabels": { 41 | "pcf-instance-id": "instance-id-here", 42 | "pcf-organization-guid": "", 43 | "pcf-space-guid": "" 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-postgres/Development_Sandbox: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "Development Sandbox", 4 | // "description": "An inexpensive PostgreSQL sandbox for developing with no backups.", 5 | // "plan_id": "2513d4d9-684b-4c3c-add4-6404969006de", 6 | // "provision_params": { 7 | // "backups_enabled": "false", 8 | // "disk_size": "10" 9 | // }, 10 | // "bind_params": { 11 | // "role": "cloudsql.editor" 12 | // } 13 | // } 14 | // } 15 | { 16 | "databaseVersion": "POSTGRES_11", 17 | "name": "NONDETERMINISTIC", 18 | "region": "us-central", 19 | "settings": { 20 | "activationPolicy": "ALWAYS", 21 | "availabilityType": "ZONAL", 22 | "backupConfiguration": { 23 | "startTime": "06:00" 24 | }, 25 | "dataDiskSizeGb": "10", 26 | "dataDiskType": "PD_SSD", 27 | "ipConfiguration": { 28 | "ipv4Enabled": true, 29 | "requireSsl": true 30 | }, 31 | "locationPreference": {}, 32 | "maintenanceWindow": { 33 | "day": 1, 34 | "hour": 0, 35 | "updateTrack": "stable" 36 | }, 37 | "pricingPlan": "PER_USE", 38 | "storageAutoResize": false, 39 | "tier": "db-f1-micro", 40 | "userLabels": { 41 | "pcf-instance-id": "instance-id-here", 42 | "pcf-organization-guid": "", 43 | "pcf-space-guid": "" 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-postgres/HA_Instance: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "HA Instance", 4 | // "description": "A regionally available database with automatic failover.", 5 | // "plan_id": "c4e68ab5-34ca-4d02-857d-3e6b3ab079a7", 6 | // "provision_params": { 7 | // "availability_type": "REGIONAL", 8 | // "backups_enabled": "false", 9 | // "disk_size": "25" 10 | // }, 11 | // "bind_params": { 12 | // "role": "cloudsql.editor" 13 | // } 14 | // } 15 | // } 16 | { 17 | "databaseVersion": "POSTGRES_11", 18 | "name": "NONDETERMINISTIC", 19 | "region": "us-central", 20 | "settings": { 21 | "activationPolicy": "ALWAYS", 22 | "availabilityType": "REGIONAL", 23 | "backupConfiguration": { 24 | "startTime": "06:00" 25 | }, 26 | "dataDiskSizeGb": "25", 27 | "dataDiskType": "PD_SSD", 28 | "ipConfiguration": { 29 | "ipv4Enabled": true, 30 | "requireSsl": true 31 | }, 32 | "locationPreference": {}, 33 | "maintenanceWindow": { 34 | "day": 1, 35 | "hour": 0, 36 | "updateTrack": "stable" 37 | }, 38 | "pricingPlan": "PER_USE", 39 | "storageAutoResize": false, 40 | "tier": "db-custom-1-3840", 41 | "userLabels": { 42 | "pcf-instance-id": "instance-id-here", 43 | "pcf-organization-guid": "", 44 | "pcf-space-guid": "" 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-postgresql-vpc/Dedicated_Machine_Sandbox: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "Dedicated Machine Sandbox", 4 | // "description": "A low end PostgreSQL sandbox that uses a dedicated machine.", 5 | // "plan_id": "60f0b6c0-c48f-4f84-baab-57836611e013", 6 | // "provision_params": { 7 | // "backups_enabled": "false", 8 | // "disk_size": "25", 9 | // "tier": "db-custom-1-3840" 10 | // }, 11 | // "bind_params": { 12 | // "role": "cloudsql.editor" 13 | // } 14 | // } 15 | // } 16 | { 17 | "databaseVersion": "POSTGRES_9_6", 18 | "name": "NONDETERMINISTIC", 19 | "region": "us-central", 20 | "settings": { 21 | "activationPolicy": "ALWAYS", 22 | "availabilityType": "ZONAL", 23 | "backupConfiguration": { 24 | "startTime": "06:00" 25 | }, 26 | "dataDiskSizeGb": "25", 27 | "dataDiskType": "PD_SSD", 28 | "ipConfiguration": { 29 | "ipv4Enabled": false, 30 | "privateNetwork": "default", 31 | "requireSsl": true 32 | }, 33 | "locationPreference": {}, 34 | "maintenanceWindow": { 35 | "day": 1, 36 | "hour": 0, 37 | "updateTrack": "stable" 38 | }, 39 | "pricingPlan": "PER_USE", 40 | "storageAutoResize": false, 41 | "tier": "db-custom-1-3840", 42 | "userLabels": { 43 | "pcf-instance-id": "instance-id-here", 44 | "pcf-organization-guid": "", 45 | "pcf-space-guid": "" 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/cloudsql/testdata/golden/Test_createProvisionRequest/google-cloudsql-postgresql-vpc/HA_Instance: -------------------------------------------------------------------------------- 1 | // { 2 | // "example": { 3 | // "name": "HA Instance", 4 | // "description": "A regionally available database with automatic failover.", 5 | // "plan_id": "60f0b6c0-c48f-4f84-baab-57836611e013", 6 | // "provision_params": { 7 | // "availability_type": "REGIONAL", 8 | // "backups_enabled": "true", 9 | // "disk_size": "25", 10 | // "tier": "db-custom-1-3840" 11 | // }, 12 | // "bind_params": { 13 | // "role": "cloudsql.editor" 14 | // } 15 | // } 16 | // } 17 | { 18 | "databaseVersion": "POSTGRES_9_6", 19 | "name": "NONDETERMINISTIC", 20 | "region": "us-central", 21 | "settings": { 22 | "activationPolicy": "ALWAYS", 23 | "availabilityType": "REGIONAL", 24 | "backupConfiguration": { 25 | "enabled": true, 26 | "startTime": "06:00" 27 | }, 28 | "dataDiskSizeGb": "25", 29 | "dataDiskType": "PD_SSD", 30 | "ipConfiguration": { 31 | "ipv4Enabled": false, 32 | "privateNetwork": "default", 33 | "requireSsl": true 34 | }, 35 | "locationPreference": {}, 36 | "maintenanceWindow": { 37 | "day": 1, 38 | "hour": 0, 39 | "updateTrack": "stable" 40 | }, 41 | "pricingPlan": "PER_USE", 42 | "storageAutoResize": false, 43 | "tier": "db-custom-1-3840", 44 | "userLabels": { 45 | "pcf-instance-id": "instance-id-here", 46 | "pcf-organization-guid": "", 47 | "pcf-space-guid": "" 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /pkg/providers/builtin/dataflow/broker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package dataflow 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 23 | "github.com/pivotal-cf/brokerapi" 24 | ) 25 | 26 | // DataflowBroker is the service-broker back-end for creating and binding Dataflow clients. 27 | type DataflowBroker struct { 28 | base.BrokerBase 29 | } 30 | 31 | // Provision is a no-op call because only service accounts need to be bound/unbound for Dataflow. 32 | func (b *DataflowBroker) Provision(ctx context.Context, provisionContext *varcontext.VarContext) (models.ServiceInstanceDetails, error) { 33 | return models.ServiceInstanceDetails{}, nil 34 | } 35 | 36 | // Deprovision is a no-op call because only service accounts need to be bound/unbound for Dataflow. 37 | func (b *DataflowBroker) Deprovision(ctx context.Context, instance models.ServiceInstanceDetails, details brokerapi.DeprovisionDetails) (*string, error) { 38 | return nil, nil 39 | } 40 | -------------------------------------------------------------------------------- /pkg/providers/builtin/datastore/broker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package datastore 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 23 | "github.com/pivotal-cf/brokerapi" 24 | ) 25 | 26 | // InstanceInformation holds the details needed to bind a service to a DatastoreBroker. 27 | type InstanceInformation struct { 28 | Namespace string `json:"namespace,omitempty"` 29 | } 30 | 31 | // DatastoreBroker is the service-broker back-end for creating and binding Datastore instances. 32 | type DatastoreBroker struct { 33 | base.BrokerBase 34 | } 35 | 36 | // Provision stores the namespace for future reference. 37 | func (b *DatastoreBroker) Provision(ctx context.Context, provisionContext *varcontext.VarContext) (models.ServiceInstanceDetails, error) { 38 | // return models.ServiceInstanceDetails{}, nil 39 | 40 | ii := InstanceInformation{ 41 | Namespace: provisionContext.GetString("namespace"), 42 | } 43 | 44 | if err := provisionContext.Error(); err != nil { 45 | return models.ServiceInstanceDetails{}, err 46 | } 47 | 48 | details := models.ServiceInstanceDetails{} 49 | if err := details.SetOtherDetails(ii); err != nil { 50 | return models.ServiceInstanceDetails{}, err 51 | } 52 | 53 | return details, nil 54 | } 55 | 56 | // Deprovision is a no-op call because only service accounts need to be bound/unbound for Datastore. 57 | func (b *DatastoreBroker) Deprovision(ctx context.Context, instance models.ServiceInstanceDetails, details brokerapi.DeprovisionDetails) (*string, error) { 58 | return nil, nil 59 | } 60 | -------------------------------------------------------------------------------- /pkg/providers/builtin/dialogflow/broker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package dialogflow 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 23 | "github.com/pivotal-cf/brokerapi" 24 | ) 25 | 26 | // DialogflowBroker is the service-broker back-end for creating and binding Dialogflow clients. 27 | type DialogflowBroker struct { 28 | base.BrokerBase 29 | } 30 | 31 | // Provision is a no-op call because only service accounts need to be bound/unbound for Dialogflow. 32 | func (b *DialogflowBroker) Provision(ctx context.Context, provisionContext *varcontext.VarContext) (models.ServiceInstanceDetails, error) { 33 | return models.ServiceInstanceDetails{}, nil 34 | } 35 | 36 | // Deprovision is a no-op call because only service accounts need to be bound/unbound for Dialogflow. 37 | func (b *DialogflowBroker) Deprovision(ctx context.Context, instance models.ServiceInstanceDetails, details brokerapi.DeprovisionDetails) (*string, error) { 38 | return nil, nil 39 | } 40 | -------------------------------------------------------------------------------- /pkg/providers/builtin/dialogflow/definition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package dialogflow 16 | 17 | import ( 18 | "code.cloudfoundry.org/lager" 19 | accountmanagers "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/account_managers" 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 22 | "github.com/pivotal-cf/brokerapi" 23 | "golang.org/x/oauth2/jwt" 24 | ) 25 | 26 | // ServiceDefinition creates a new ServiceDefinition object for the Dialogflow service. 27 | func ServiceDefinition() *broker.ServiceDefinition { 28 | return &broker.ServiceDefinition{ 29 | Id: "e84b69db-3de9-4688-8f5c-26b9d5b1f129", 30 | Name: "google-dialogflow", 31 | Description: "Dialogflow is an end-to-end, build-once deploy-everywhere development suite for creating conversational interfaces for websites, mobile applications, popular messaging platforms, and IoT devices.", 32 | DisplayName: "Google Cloud Dialogflow", 33 | ImageUrl: "https://cloud.google.com/_static/images/cloud/products/logos/svg/dialogflow-enterprise.svg", 34 | DocumentationUrl: "https://cloud.google.com/dialogflow-enterprise/docs/", 35 | SupportUrl: "https://cloud.google.com/dialogflow-enterprise/docs/support", 36 | Tags: []string{"gcp", "dialogflow", "preview"}, 37 | Bindable: true, 38 | PlanUpdateable: false, 39 | Plans: []broker.ServicePlan{ 40 | { 41 | ServicePlan: brokerapi.ServicePlan{ 42 | ID: "3ac4e1bd-b22d-4a99-864b-d3a3ac582348", 43 | Name: "default", 44 | Description: "Dialogflow default plan.", 45 | Free: brokerapi.FreeValue(false), 46 | }, 47 | ServiceProperties: map[string]string{}, 48 | }, 49 | }, 50 | ProvisionInputVariables: []broker.BrokerVariable{}, 51 | BindInputVariables: []broker.BrokerVariable{}, 52 | BindComputedVariables: accountmanagers.FixedRoleBindComputedVariables("dialogflow.client"), 53 | BindOutputVariables: accountmanagers.ServiceAccountBindOutputVariables(), 54 | Examples: []broker.ServiceExample{ 55 | { 56 | Name: "Reader", 57 | Description: "Creates a Dialogflow user and grants it permission to detect intent and read/write session properties (contexts, session entity types, etc.).", 58 | PlanId: "3ac4e1bd-b22d-4a99-864b-d3a3ac582348", 59 | ProvisionParams: map[string]interface{}{}, 60 | BindParams: map[string]interface{}{}, 61 | }, 62 | }, 63 | ProviderBuilder: func(projectId string, auth *jwt.Config, logger lager.Logger) broker.ServiceProvider { 64 | bb := base.NewBrokerBase(projectId, auth, logger) 65 | return &DialogflowBroker{BrokerBase: bb} 66 | }, 67 | IsBuiltin: true, 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /pkg/providers/builtin/firestore/broker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package firestore 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 23 | "github.com/pivotal-cf/brokerapi" 24 | ) 25 | 26 | // FirestoreBroker is the service-broker back-end for creating and binding Firestore clients. 27 | type FirestoreBroker struct { 28 | base.BrokerBase 29 | } 30 | 31 | // Provision is a no-op call because only service accounts need to be bound/unbound for Firestore. 32 | func (b *FirestoreBroker) Provision(ctx context.Context, provisionContext *varcontext.VarContext) (models.ServiceInstanceDetails, error) { 33 | return models.ServiceInstanceDetails{}, nil 34 | } 35 | 36 | // Deprovision is a no-op call because only service accounts need to be bound/unbound for Firestore. 37 | func (b *FirestoreBroker) Deprovision(ctx context.Context, instance models.ServiceInstanceDetails, details brokerapi.DeprovisionDetails) (*string, error) { 38 | return nil, nil 39 | } 40 | -------------------------------------------------------------------------------- /pkg/providers/builtin/ml/broker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package ml 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 23 | "github.com/pivotal-cf/brokerapi" 24 | ) 25 | 26 | // ApiServiceBroker is the service-broker back-end for creating Google Machine Learning API accounts. 27 | type ApiServiceBroker struct { 28 | base.BrokerBase 29 | } 30 | 31 | // Provision is a no-op call because only service accounts need to be bound/unbound for Google Machine Learning APIs. 32 | func (b *ApiServiceBroker) Provision(ctx context.Context, provisionContext *varcontext.VarContext) (models.ServiceInstanceDetails, error) { 33 | return models.ServiceInstanceDetails{}, nil 34 | } 35 | 36 | // Deprovision is a no-op call because only service accounts need to be bound/unbound for Google Machine Learning APIs. 37 | func (b *ApiServiceBroker) Deprovision(ctx context.Context, dataset models.ServiceInstanceDetails, details brokerapi.DeprovisionDetails) (*string, error) { 38 | return nil, nil 39 | } 40 | -------------------------------------------------------------------------------- /pkg/providers/builtin/ml/definition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package ml 16 | 17 | import ( 18 | "code.cloudfoundry.org/lager" 19 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 20 | accountmanagers "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/account_managers" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 22 | "github.com/pivotal-cf/brokerapi" 23 | "golang.org/x/oauth2/jwt" 24 | ) 25 | 26 | // ServiceDefinition creates a new ServiceDefinition object for the ML service. 27 | func ServiceDefinition() *broker.ServiceDefinition { 28 | roleWhitelist := []string{ 29 | "ml.developer", 30 | "ml.viewer", 31 | "ml.modelOwner", 32 | "ml.modelUser", 33 | "ml.jobOwner", 34 | "ml.operationOwner", 35 | } 36 | 37 | return &broker.ServiceDefinition{ 38 | Id: "5ad2dce0-51f7-4ede-8b46-293d6df1e8d4", 39 | Name: "google-ml-apis", 40 | Description: "Machine Learning APIs including Vision, Translate, Speech, and Natural Language.", 41 | DisplayName: "Google Machine Learning APIs", 42 | ImageUrl: "https://cloud.google.com/_static/images/cloud/products/logos/svg/machine-learning.svg", 43 | DocumentationUrl: "https://cloud.google.com/ml/", 44 | SupportUrl: "https://cloud.google.com/support/", 45 | Tags: []string{"gcp", "ml"}, 46 | Bindable: true, 47 | PlanUpdateable: false, 48 | Plans: []broker.ServicePlan{ 49 | { 50 | ServicePlan: brokerapi.ServicePlan{ 51 | ID: "be7954e1-ecfb-4936-a0b6-db35e6424c7a", 52 | Name: "default", 53 | Description: "Machine Learning API default plan.", 54 | Free: brokerapi.FreeValue(false), 55 | }, 56 | ServiceProperties: map[string]string{}, 57 | }, 58 | }, 59 | ProvisionInputVariables: []broker.BrokerVariable{}, 60 | DefaultRoleWhitelist: roleWhitelist, 61 | BindInputVariables: accountmanagers.ServiceAccountWhitelistWithDefault(roleWhitelist, "ml.modelUser"), 62 | BindOutputVariables: accountmanagers.ServiceAccountBindOutputVariables(), 63 | BindComputedVariables: accountmanagers.ServiceAccountBindComputedVariables(), 64 | Examples: []broker.ServiceExample{ 65 | { 66 | Name: "Basic Configuration", 67 | Description: "Create an account with developer access to your ML models.", 68 | PlanId: "be7954e1-ecfb-4936-a0b6-db35e6424c7a", 69 | ProvisionParams: map[string]interface{}{}, 70 | BindParams: map[string]interface{}{ 71 | "role": "ml.developer", 72 | }, 73 | }, 74 | }, 75 | ProviderBuilder: func(projectId string, auth *jwt.Config, logger lager.Logger) broker.ServiceProvider { 76 | bb := base.NewBrokerBase(projectId, auth, logger) 77 | return &ApiServiceBroker{BrokerBase: bb} 78 | }, 79 | IsBuiltin: true, 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /pkg/providers/builtin/stackdriver/broker.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package stackdriver 16 | 17 | import ( 18 | "context" 19 | 20 | "code.cloudfoundry.org/lager" 21 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/base" 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/db_service/models" 23 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 24 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/varcontext" 25 | "github.com/pivotal-cf/brokerapi" 26 | "golang.org/x/oauth2/jwt" 27 | ) 28 | 29 | // StackdriverServiceAccountProvider is the provider for binding new services to Stackdriver. 30 | // It has no-op calls for Provision and Deprovision because Stackdriver is a single-instance API service. 31 | type StackdriverAccountProvider struct { 32 | base.BrokerBase 33 | } 34 | 35 | // Provision is a no-op call because only service accounts need to be bound/unbound for Stackdriver. 36 | func (b *StackdriverAccountProvider) Provision(ctx context.Context, provisionContext *varcontext.VarContext) (models.ServiceInstanceDetails, error) { 37 | return models.ServiceInstanceDetails{}, nil 38 | } 39 | 40 | // Deprovision is a no-op call because only service accounts need to be bound/unbound for Stackdriver. 41 | func (b *StackdriverAccountProvider) Deprovision(ctx context.Context, instance models.ServiceInstanceDetails, details brokerapi.DeprovisionDetails) (*string, error) { 42 | return nil, nil 43 | } 44 | 45 | // NewStackdriverAccountProvider creates a new StackdriverAccountProvider for the given project. 46 | func NewStackdriverAccountProvider(projectId string, auth *jwt.Config, logger lager.Logger) broker.ServiceProvider { 47 | bb := base.NewBrokerBase(projectId, auth, logger) 48 | return &StackdriverAccountProvider{BrokerBase: bb} 49 | } 50 | -------------------------------------------------------------------------------- /pkg/providers/builtin/stackdriver/debugger_definition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package stackdriver 16 | 17 | import ( 18 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 19 | accountmanagers "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/account_managers" 20 | "github.com/pivotal-cf/brokerapi" 21 | ) 22 | 23 | // StackdriverDebuggerServiceDefinition creates a new ServiceDefinition object 24 | // for the Stackdriver Debugger service. 25 | func StackdriverDebuggerServiceDefinition() *broker.ServiceDefinition { 26 | return &broker.ServiceDefinition{ 27 | Id: "83837945-1547-41e0-b661-ea31d76eed11", 28 | Name: "google-stackdriver-debugger", 29 | Description: "Inspect the state of an app, at any code location, without stopping or slowing it down.", 30 | DisplayName: "Stackdriver Debugger", 31 | ImageUrl: "https://cloud.google.com/_static/images/cloud/products/logos/svg/debugger.svg", 32 | DocumentationUrl: "https://cloud.google.com/debugger/docs/", 33 | SupportUrl: "https://cloud.google.com/stackdriver/docs/getting-support", 34 | Tags: []string{"gcp", "stackdriver", "debugger"}, 35 | Bindable: true, 36 | PlanUpdateable: false, 37 | Plans: []broker.ServicePlan{ 38 | { 39 | ServicePlan: brokerapi.ServicePlan{ 40 | ID: "10866183-a775-49e8-96e3-4e7a901e4a79", 41 | Name: "default", 42 | Description: "Stackdriver Debugger default plan.", 43 | Free: brokerapi.FreeValue(false), 44 | }, 45 | ServiceProperties: map[string]string{}, 46 | }, 47 | }, 48 | ProvisionInputVariables: []broker.BrokerVariable{}, 49 | BindInputVariables: []broker.BrokerVariable{}, 50 | BindComputedVariables: accountmanagers.FixedRoleBindComputedVariables("clouddebugger.agent"), 51 | BindOutputVariables: accountmanagers.ServiceAccountBindOutputVariables(), 52 | Examples: []broker.ServiceExample{ 53 | { 54 | Name: "Basic Configuration", 55 | Description: "Creates an account with the permission `clouddebugger.agent`.", 56 | PlanId: "10866183-a775-49e8-96e3-4e7a901e4a79", 57 | ProvisionParams: map[string]interface{}{}, 58 | BindParams: map[string]interface{}{}, 59 | }, 60 | }, 61 | ProviderBuilder: NewStackdriverAccountProvider, 62 | IsBuiltin: true, 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pkg/providers/builtin/stackdriver/monitoring_definition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package stackdriver 16 | 17 | import ( 18 | accountmanagers "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/account_managers" 19 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 20 | "github.com/pivotal-cf/brokerapi" 21 | ) 22 | 23 | // StackdriverMonitoringServiceDefinition creates a new ServiceDefinition object 24 | // for the Stackdriver Monitoring service. 25 | func StackdriverMonitoringServiceDefinition() *broker.ServiceDefinition { 26 | return &broker.ServiceDefinition{ 27 | Id: "2bc0d9ed-3f68-4056-b842-4a85cfbc727f", 28 | Name: "google-stackdriver-monitoring", 29 | Description: "Stackdriver Monitoring provides visibility into the performance, uptime, and overall health of cloud-powered applications.", 30 | DisplayName: "Stackdriver Monitoring", 31 | ImageUrl: "https://cloud.google.com/_static/images/cloud/products/logos/svg/stackdriver.svg", 32 | DocumentationUrl: "https://cloud.google.com/monitoring/docs/", 33 | SupportUrl: "https://cloud.google.com/stackdriver/docs/getting-support", 34 | Tags: []string{"gcp", "stackdriver", "monitoring", "preview"}, 35 | Bindable: true, 36 | PlanUpdateable: false, 37 | Plans: []broker.ServicePlan{ 38 | { 39 | ServicePlan: brokerapi.ServicePlan{ 40 | ID: "2e4b85c1-0ce6-46e4-91f5-eebeb373e3f5", 41 | Name: "default", 42 | Description: "Stackdriver Monitoring default plan.", 43 | Free: brokerapi.FreeValue(false), 44 | }, 45 | ServiceProperties: map[string]string{}, 46 | }, 47 | }, 48 | ProvisionInputVariables: []broker.BrokerVariable{}, 49 | BindInputVariables: []broker.BrokerVariable{}, 50 | BindComputedVariables: accountmanagers.FixedRoleBindComputedVariables("monitoring.metricWriter"), 51 | BindOutputVariables: accountmanagers.ServiceAccountBindOutputVariables(), 52 | Examples: []broker.ServiceExample{ 53 | { 54 | Name: "Basic Configuration", 55 | Description: "Creates an account with the permission `monitoring.metricWriter` for writing metrics.", 56 | PlanId: "2e4b85c1-0ce6-46e4-91f5-eebeb373e3f5", 57 | ProvisionParams: map[string]interface{}{}, 58 | BindParams: map[string]interface{}{}, 59 | }, 60 | }, 61 | ProviderBuilder: NewStackdriverAccountProvider, 62 | IsBuiltin: true, 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pkg/providers/builtin/stackdriver/profiler_definition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package stackdriver 16 | 17 | import ( 18 | accountmanagers "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/account_managers" 19 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 20 | "github.com/pivotal-cf/brokerapi" 21 | ) 22 | 23 | // StackdriverProfilerServiceDefinition creates a new ServiceDefinition object 24 | // for the Stackdriver Profiler service. 25 | func StackdriverProfilerServiceDefinition() *broker.ServiceDefinition { 26 | return &broker.ServiceDefinition{ 27 | Id: "00b9ca4a-7cd6-406a-a5b7-2f43f41ade75", 28 | Name: "google-stackdriver-profiler", 29 | Description: "Continuous CPU and heap profiling to improve performance and reduce costs.", 30 | DisplayName: "Stackdriver Profiler", 31 | ImageUrl: "https://cloud.google.com/_static/images/cloud/products/logos/svg/stackdriver.svg", 32 | DocumentationUrl: "https://cloud.google.com/profiler/docs/", 33 | SupportUrl: "https://cloud.google.com/stackdriver/docs/getting-support", 34 | Tags: []string{"gcp", "stackdriver", "profiler"}, 35 | Bindable: true, 36 | PlanUpdateable: false, 37 | Plans: []broker.ServicePlan{ 38 | { 39 | ServicePlan: brokerapi.ServicePlan{ 40 | ID: "594627f6-35f5-462f-9074-10fb033fb18a", 41 | Name: "default", 42 | Description: "Stackdriver Profiler default plan.", 43 | Free: brokerapi.FreeValue(false), 44 | }, 45 | ServiceProperties: map[string]string{}, 46 | }, 47 | }, 48 | ProvisionInputVariables: []broker.BrokerVariable{}, 49 | BindInputVariables: []broker.BrokerVariable{}, 50 | BindComputedVariables: accountmanagers.FixedRoleBindComputedVariables("cloudprofiler.agent"), 51 | BindOutputVariables: accountmanagers.ServiceAccountBindOutputVariables(), 52 | Examples: []broker.ServiceExample{ 53 | { 54 | Name: "Basic Configuration", 55 | Description: "Creates an account with the permission `cloudprofiler.agent`.", 56 | PlanId: "594627f6-35f5-462f-9074-10fb033fb18a", 57 | ProvisionParams: map[string]interface{}{}, 58 | BindParams: map[string]interface{}{}, 59 | }, 60 | }, 61 | ProviderBuilder: NewStackdriverAccountProvider, 62 | IsBuiltin: true, 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pkg/providers/builtin/stackdriver/trace_definition.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package stackdriver 16 | 17 | import ( 18 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/broker" 19 | accountmanagers "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin/account_managers" 20 | "github.com/pivotal-cf/brokerapi" 21 | ) 22 | 23 | // StackdriverTraceServiceDefinition creates a new ServiceDefinition object 24 | // for the Stackdriver Trace service. 25 | func StackdriverTraceServiceDefinition() *broker.ServiceDefinition { 26 | return &broker.ServiceDefinition{ 27 | Id: "c5ddfe15-24d9-47f8-8ffe-f6b7daa9cf4a", 28 | Name: "google-stackdriver-trace", 29 | Description: "A real-time distributed tracing system.", 30 | DisplayName: "Stackdriver Trace", 31 | ImageUrl: "https://cloud.google.com/_static/images/cloud/products/logos/svg/trace.svg", 32 | DocumentationUrl: "https://cloud.google.com/trace/docs/", 33 | SupportUrl: "https://cloud.google.com/stackdriver/docs/getting-support", 34 | Tags: []string{"gcp", "stackdriver", "trace"}, 35 | Bindable: true, 36 | PlanUpdateable: false, 37 | Plans: []broker.ServicePlan{ 38 | { 39 | ServicePlan: brokerapi.ServicePlan{ 40 | ID: "ab6c2287-b4bc-4ff4-a36a-0575e7910164", 41 | Name: "default", 42 | Description: "Stackdriver Trace default plan.", 43 | Free: brokerapi.FreeValue(false), 44 | }, 45 | ServiceProperties: map[string]string{}, 46 | }, 47 | }, 48 | ProvisionInputVariables: []broker.BrokerVariable{}, 49 | BindInputVariables: []broker.BrokerVariable{}, 50 | BindComputedVariables: accountmanagers.FixedRoleBindComputedVariables("cloudtrace.agent"), 51 | BindOutputVariables: accountmanagers.ServiceAccountBindOutputVariables(), 52 | Examples: []broker.ServiceExample{ 53 | { 54 | Name: "Basic Configuration", 55 | Description: "Creates an account with the permission `cloudtrace.agent`.", 56 | PlanId: "ab6c2287-b4bc-4ff4-a36a-0575e7910164", 57 | ProvisionParams: map[string]interface{}{}, 58 | BindParams: map[string]interface{}{}, 59 | }, 60 | }, 61 | ProviderBuilder: NewStackdriverAccountProvider, 62 | IsBuiltin: true, 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /pkg/providers/tf/wrapper/instance.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package wrapper 16 | 17 | import "encoding/json" 18 | 19 | // ModuleInstance represents the configuration of a single instance of a module. 20 | type ModuleInstance struct { 21 | ModuleName string `json:"module_name"` 22 | InstanceName string `json:"instance_name"` 23 | Configuration map[string]interface{} `json:"configuration"` 24 | } 25 | 26 | // MarshalDefinition converts the module instance definition into a JSON 27 | // definition that can be fed to Terraform to be created/destroyed. 28 | func (instance *ModuleInstance) MarshalDefinition() (json.RawMessage, error) { 29 | instanceConfig := make(map[string]interface{}) 30 | for k, v := range instance.Configuration { 31 | instanceConfig[k] = v 32 | } 33 | 34 | instanceConfig["source"] = instance.ModuleName 35 | 36 | defn := map[string]interface{}{ 37 | "module": map[string]interface{}{ 38 | instance.InstanceName: instanceConfig, 39 | }, 40 | } 41 | 42 | return json.Marshal(defn) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/providers/tf/wrapper/instance_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package wrapper 16 | 17 | import "fmt" 18 | 19 | func ExampleModuleInstance_MarshalDefinition() { 20 | instance := ModuleInstance{ 21 | ModuleName: "foo-module", 22 | InstanceName: "instance", 23 | Configuration: map[string]interface{}{"foo": "bar"}, 24 | } 25 | 26 | defnJson, err := instance.MarshalDefinition() 27 | fmt.Println(err) 28 | fmt.Printf("%s\n", string(defnJson)) 29 | 30 | // Output: 31 | // {"module":{"instance":{"foo":"bar","source":"foo-module"}}} 32 | } 33 | -------------------------------------------------------------------------------- /pkg/providers/tf/wrapper/module.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package wrapper 16 | 17 | import ( 18 | "sort" 19 | 20 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/validation" 21 | "github.com/hashicorp/hcl" 22 | ) 23 | 24 | // ModuleDefinition represents a module in a Terraform workspace. 25 | type ModuleDefinition struct { 26 | Name string 27 | Definition string 28 | } 29 | 30 | var _ (validation.Validatable) = (*ModuleDefinition)(nil) 31 | 32 | // Validate checks the validity of the ModuleDefinition struct. 33 | func (module *ModuleDefinition) Validate() (errs *validation.FieldError) { 34 | return errs.Also( 35 | validation.ErrIfBlank(module.Name, "Name"), 36 | validation.ErrIfNotTerraformIdentifier(module.Name, "Name"), 37 | validation.ErrIfNotHCL(module.Definition, "Definition"), 38 | ) 39 | } 40 | 41 | // Inputs gets the input parameter names for the module. 42 | func (module *ModuleDefinition) Inputs() ([]string, error) { 43 | defn := terraformModuleHcl{} 44 | if err := hcl.Decode(&defn, module.Definition); err != nil { 45 | return nil, err 46 | } 47 | 48 | return sortedKeys(defn.Inputs), nil 49 | } 50 | 51 | // Outputs gets the output parameter names for the module. 52 | func (module *ModuleDefinition) Outputs() ([]string, error) { 53 | defn := terraformModuleHcl{} 54 | if err := hcl.Decode(&defn, module.Definition); err != nil { 55 | return nil, err 56 | } 57 | 58 | return sortedKeys(defn.Outputs), nil 59 | } 60 | 61 | func sortedKeys(m map[string]interface{}) []string { 62 | var keys []string 63 | for key, _ := range m { 64 | keys = append(keys, key) 65 | } 66 | 67 | sort.Slice(keys, func(i int, j int) bool { return keys[i] < keys[j] }) 68 | return keys 69 | } 70 | 71 | // terraformModuleHcl is a struct used for marshaling/unmarshaling details about 72 | // Terraform modules. 73 | // 74 | // See https://www.terraform.io/docs/modules/create.html for their structure. 75 | type terraformModuleHcl struct { 76 | Inputs map[string]interface{} `hcl:"variable"` 77 | Outputs map[string]interface{} `hcl:"output"` 78 | } 79 | -------------------------------------------------------------------------------- /pkg/providers/tf/wrapper/module_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package wrapper 16 | 17 | import ( 18 | "fmt" 19 | "strings" 20 | "testing" 21 | ) 22 | 23 | func ExampleModuleDefinition_Inputs() { 24 | module := ModuleDefinition{ 25 | Name: "cloud_storage", 26 | Definition: ` 27 | variable name {type = "string"} 28 | variable storage_class {type = "string"} 29 | 30 | resource "google_storage_bucket" "bucket" { 31 | name = "${var.name}" 32 | storage_class = "${var.storage_class}" 33 | } 34 | `, 35 | } 36 | 37 | inputs, err := module.Inputs() 38 | if err != nil { 39 | panic(err) 40 | } 41 | fmt.Printf("%v\n", inputs) 42 | 43 | // Output: [name storage_class] 44 | } 45 | 46 | func ExampleModuleDefinition_Outputs() { 47 | module := ModuleDefinition{ 48 | Name: "cloud_storage", 49 | Definition: ` 50 | resource "google_storage_bucket" "bucket" { 51 | name = "my-bucket" 52 | storage_class = "STANDARD" 53 | } 54 | 55 | output id {value = "${google_storage_bucket.bucket.id}"} 56 | output bucket_name {value = "my-bucket"} 57 | `, 58 | } 59 | 60 | outputs, err := module.Outputs() 61 | if err != nil { 62 | panic(err) 63 | } 64 | fmt.Printf("%v\n", outputs) 65 | 66 | // Output: [bucket_name id] 67 | } 68 | 69 | func TestModuleDefinition_Validate(t *testing.T) { 70 | cases := map[string]struct { 71 | Module ModuleDefinition 72 | ErrContains string 73 | }{ 74 | "nominal": { 75 | Module: ModuleDefinition{ 76 | Name: "my_module", 77 | Definition: ` 78 | resource "google_storage_bucket" "bucket" { 79 | name = "my-bucket" 80 | storage_class = "STANDARD" 81 | }`, 82 | }, 83 | ErrContains: "", 84 | }, 85 | "bad-name": { 86 | Module: ModuleDefinition{ 87 | Name: "my module", 88 | Definition: ` 89 | resource "google_storage_bucket" "bucket" { 90 | name = "my-bucket" 91 | storage_class = "STANDARD" 92 | }`, 93 | }, 94 | ErrContains: "field must match '^[a-z_]*$': Name", 95 | }, 96 | "bad-hcl": { 97 | Module: ModuleDefinition{ 98 | Name: "my_module", 99 | Definition: ` 100 | resource "bucket" { 101 | name = "my-bucket"`, 102 | }, 103 | ErrContains: "invalid HCL: Definition", 104 | }, 105 | } 106 | 107 | for tn, tc := range cases { 108 | t.Run(tn, func(t *testing.T) { 109 | err := tc.Module.Validate() 110 | if tc.ErrContains == "" { 111 | if err != nil { 112 | t.Fatalf("Expected no error but got: %v", err) 113 | } 114 | } else { 115 | if err == nil { 116 | t.Fatalf("Expected error containing %q but got nil", tc.ErrContains) 117 | } 118 | if !strings.Contains(err.Error(), tc.ErrContains) { 119 | t.Fatalf("Expected error containing %q but got %v", tc.ErrContains, err) 120 | } 121 | } 122 | }) 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /pkg/providers/tf/wrapper/tfstate.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package wrapper 16 | 17 | import ( 18 | "encoding/json" 19 | "fmt" 20 | "reflect" 21 | "strings" 22 | ) 23 | 24 | const ( 25 | supportedTfStateVersion = 3 26 | ) 27 | 28 | // NewTfstate deserializes a tfstate file. 29 | func NewTfstate(stateFile []byte) (*Tfstate, error) { 30 | state := Tfstate{} 31 | if err := json.Unmarshal(stateFile, &state); err != nil { 32 | return nil, err 33 | } 34 | 35 | if state.Version != supportedTfStateVersion { 36 | return nil, fmt.Errorf("unsupported tfstate version: %d", state.Version) 37 | } 38 | 39 | return &state, nil 40 | } 41 | 42 | // Tfstate is a struct that can help us deserialize the tfstate JSON file. 43 | type Tfstate struct { 44 | Version int `json:"version"` 45 | Modules []TfstateModule `json:"modules"` 46 | } 47 | 48 | // GetModule gets a module at a given path or nil if none exists for that path. 49 | func (state *Tfstate) GetModule(path ...string) *TfstateModule { 50 | for _, module := range state.Modules { 51 | if reflect.DeepEqual(module.Path, path) { 52 | return &module 53 | } 54 | } 55 | 56 | return nil 57 | } 58 | 59 | type TfstateModule struct { 60 | Path []string `json:"path"` 61 | Outputs map[string]struct { 62 | Type string `json:"type"` 63 | Value interface{} `json:"value"` 64 | } `json:"outputs"` 65 | } 66 | 67 | func (module *TfstateModule) String() string { 68 | path := strings.Join(module.Path, "/") 69 | return fmt.Sprintf("[module: %s with %d outputs]", path, len(module.Outputs)) 70 | } 71 | 72 | // GetOutputs gets the key/value outputs defined for a module. 73 | func (module *TfstateModule) GetOutputs() map[string]interface{} { 74 | out := make(map[string]interface{}) 75 | 76 | for outputName, tfOutput := range module.Outputs { 77 | out[outputName] = tfOutput.Value 78 | } 79 | 80 | return out 81 | } 82 | -------------------------------------------------------------------------------- /pkg/providers/tf/wrapper/tfstate_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package wrapper 16 | 17 | import "fmt" 18 | 19 | func ExampleNewTfstate_Good() { 20 | state := `{ 21 | "version": 3, 22 | "terraform_version": "0.11.10", 23 | "serial": 2, 24 | "modules": [ 25 | { 26 | "path": ["root"], 27 | "outputs": {}, 28 | "resources": {}, 29 | "depends_on": [] 30 | }, 31 | { 32 | "path": ["root", "instance"], 33 | "outputs": {}, 34 | "resources": {}, 35 | "depends_on": [] 36 | } 37 | ] 38 | }` 39 | 40 | _, err := NewTfstate([]byte(state)) 41 | fmt.Printf("%v", err) 42 | 43 | // Output: 44 | } 45 | 46 | func ExampleNewTfstate_BadVersion() { 47 | state := `{ 48 | "version": 4, 49 | "terraform_version": "0.11.10", 50 | "serial": 2, 51 | "modules": [ 52 | { 53 | "path": ["root"], 54 | "outputs": {}, 55 | "resources": {}, 56 | "depends_on": [] 57 | } 58 | ] 59 | }` 60 | 61 | _, err := NewTfstate([]byte(state)) 62 | fmt.Printf("%v", err) 63 | 64 | // Output: unsupported tfstate version: 4 65 | } 66 | 67 | func ExampleTfstate_GetModule() { 68 | state := `{ 69 | "version": 3, 70 | "terraform_version": "0.11.10", 71 | "serial": 2, 72 | "modules": [ 73 | { 74 | "path": ["root", "instance"], 75 | "outputs": { 76 | "Name": { 77 | "sensitive": false, 78 | "type": "string", 79 | "value": "pcf-binding-ex351277" 80 | } 81 | }, 82 | "resources": {}, 83 | "depends_on": [] 84 | } 85 | ] 86 | }` 87 | 88 | tfstate, _ := NewTfstate([]byte(state)) 89 | fmt.Printf("%v\n", tfstate.GetModule("does-not-exist")) 90 | fmt.Printf("%v\n", tfstate.GetModule("root", "instance")) 91 | 92 | // Output: 93 | // [module: root/instance with 1 outputs] 94 | } 95 | -------------------------------------------------------------------------------- /pkg/server/cf_sharing.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package server 16 | 17 | import ( 18 | "context" 19 | 20 | "github.com/pivotal-cf/brokerapi" 21 | ) 22 | 23 | //go:generate counterfeiter -o ./fakes/servicebroker.go ../../vendor/github.com/pivotal-cf/brokerapi ServiceBroker 24 | 25 | // CfSharingWrapper enables the Shareable flag for every service provided by 26 | // the broker. 27 | type CfSharingWraper struct { 28 | brokerapi.ServiceBroker 29 | } 30 | 31 | // Services augments the response from the wrapped ServiceBroker by adding 32 | // the shareable flag. 33 | func (w *CfSharingWraper) Services(ctx context.Context) (services []brokerapi.Service, err error) { 34 | services, err = w.ServiceBroker.Services(ctx) 35 | 36 | for i, _ := range services { 37 | if services[i].Metadata == nil { 38 | services[i].Metadata = &brokerapi.ServiceMetadata{} 39 | } 40 | 41 | services[i].Metadata.Shareable = brokerapi.BindableValue(true) 42 | } 43 | 44 | return 45 | } 46 | 47 | // NewCfSharingWrapper wraps the given servicebroker with the augmenter that 48 | // sets the Shareable flag on all services. 49 | func NewCfSharingWrapper(wrapped brokerapi.ServiceBroker) brokerapi.ServiceBroker { 50 | return &CfSharingWraper{ServiceBroker: wrapped} 51 | } 52 | -------------------------------------------------------------------------------- /pkg/server/cf_sharing_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package server 16 | 17 | import ( 18 | "context" 19 | "errors" 20 | "testing" 21 | 22 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/server/fakes" 23 | "github.com/pivotal-cf/brokerapi" 24 | ) 25 | 26 | func TestCfSharingWraper_Services(t *testing.T) { 27 | cases := map[string]struct { 28 | Services []brokerapi.Service 29 | Error error 30 | }{ 31 | "nil services": { 32 | Services: nil, 33 | Error: nil, 34 | }, 35 | "empty services": { 36 | Services: []brokerapi.Service{}, 37 | Error: nil, 38 | }, 39 | 40 | "single service": { 41 | Services: []brokerapi.Service{ 42 | brokerapi.Service{Name: "foo", Metadata: &brokerapi.ServiceMetadata{}}, 43 | }, 44 | Error: nil, 45 | }, 46 | "missing metadata": { 47 | Services: []brokerapi.Service{ 48 | brokerapi.Service{Name: "foo"}, 49 | }, 50 | Error: nil, 51 | }, 52 | "multiple services": { 53 | Services: []brokerapi.Service{ 54 | brokerapi.Service{Name: "foo", Metadata: &brokerapi.ServiceMetadata{}}, 55 | brokerapi.Service{Name: "bar", Metadata: &brokerapi.ServiceMetadata{}}, 56 | }, 57 | Error: nil, 58 | }, 59 | "error passed": { 60 | Services: nil, 61 | Error: errors.New("returned error"), 62 | }, 63 | "services and err": { 64 | Services: []brokerapi.Service{ 65 | brokerapi.Service{Name: "foo", Metadata: &brokerapi.ServiceMetadata{}}, 66 | brokerapi.Service{Name: "bar", Metadata: &brokerapi.ServiceMetadata{}}, 67 | }, 68 | Error: errors.New("returned error"), 69 | }, 70 | } 71 | 72 | for tn, tc := range cases { 73 | t.Run(tn, func(t *testing.T) { 74 | wrapped := &fakes.FakeServiceBroker{} 75 | wrapped.ServicesReturns(tc.Services, tc.Error) 76 | 77 | sw := NewCfSharingWrapper(wrapped) 78 | services, actualErr := sw.Services(context.Background()) 79 | 80 | if tc.Error != actualErr { 81 | t.Fatalf("Expected error: %v got: %v", tc.Error, actualErr) 82 | } 83 | 84 | if wrapped.ServicesCallCount() != 1 { 85 | t.Errorf("Expected 1 call to Services() got %v", wrapped.ServicesCallCount()) 86 | } 87 | 88 | if len(services) != len(tc.Services) { 89 | t.Errorf("Expected to get back %d services got %d", len(tc.Services), len(services)) 90 | } 91 | 92 | for i, svc := range services { 93 | if svc.Metadata == nil { 94 | t.Fatalf("Expected service %d to have metadata, but was nil", i) 95 | } 96 | 97 | if svc.Metadata.Shareable == nil { 98 | t.Fatalf("Expected service %d to have shareable, but was nil", i) 99 | } 100 | 101 | if *svc.Metadata.Shareable != true { 102 | t.Fatalf("Expected service %d to be shareable, but was %v", i, *svc.Metadata.Shareable) 103 | } 104 | } 105 | }) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /pkg/server/docs_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package server 16 | 17 | import ( 18 | "bytes" 19 | "net/http" 20 | "net/http/httptest" 21 | "testing" 22 | 23 | "github.com/GoogleCloudPlatform/gcp-service-broker/pkg/providers/builtin" 24 | "github.com/gorilla/mux" 25 | ) 26 | 27 | func TestNewDocsHandler(t *testing.T) { 28 | registry := builtin.BuiltinBrokerRegistry() 29 | router := mux.NewRouter() 30 | // Test that the handler sets the correct header and contains some imporant 31 | // strings that will indicate (but not prove!) that the rendering was correct. 32 | AddDocsHandler(router, registry) 33 | request := httptest.NewRequest(http.MethodGet, "/docs", nil) 34 | w := httptest.NewRecorder() 35 | 36 | router.ServeHTTP(w, request) 37 | 38 | if w.Code != http.StatusOK { 39 | t.Errorf("Expected response code: %d got: %d", http.StatusOK, w.Code) 40 | } 41 | 42 | contentType := w.Header().Get("Content-Type") 43 | if contentType != "text/html" { 44 | t.Errorf("Expected text/html content type got: %q", contentType) 45 | } 46 | 47 | importantStrings := []string{" 36 | } 37 | 38 | func TestNewExampleHandler(t *testing.T) { 39 | 40 | // Validate that the handler returns the correct Content-Type 41 | handler := NewExampleHandler(builtin.BuiltinBrokerRegistry()) 42 | request := httptest.NewRequest(http.MethodGet, "/examples", nil) 43 | w := httptest.NewRecorder() 44 | 45 | handler(w, request) 46 | 47 | if w.Code != http.StatusOK { 48 | t.Errorf("Expected response code: %d got: %d", http.StatusOK, w.Code) 49 | } 50 | 51 | contentType := w.Header().Get("Content-Type") 52 | if contentType != "application/json" { 53 | t.Errorf("Expected application/json content type got: %q", contentType) 54 | } 55 | 56 | // Validate that the results can be unmarshalled to a CompleteServiceExamples type 57 | body := w.Body.Bytes() 58 | var allExamples []client.CompleteServiceExample 59 | 60 | err := json.Unmarshal(body, &allExamples) 61 | if err != nil { 62 | t.Errorf("Error unmarshalling json data: %q", err) 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /pkg/server/health.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package server 16 | 17 | import ( 18 | "database/sql" 19 | "time" 20 | 21 | "github.com/gorilla/mux" 22 | "github.com/heptiolabs/healthcheck" 23 | ) 24 | 25 | // AddHealthHandler creates a new handler for health and liveness checks and 26 | // adds it to the /live and /ready endpoints. 27 | func AddHealthHandler(router *mux.Router, db *sql.DB) healthcheck.Handler { 28 | health := healthcheck.NewHandler() 29 | 30 | if db != nil { 31 | health.AddReadinessCheck("database", healthcheck.DatabasePingCheck(db, 2*time.Second)) 32 | } 33 | 34 | router.HandleFunc("/live", health.LiveEndpoint) 35 | router.HandleFunc("/ready", health.ReadyEndpoint) 36 | 37 | return health 38 | } 39 | -------------------------------------------------------------------------------- /pkg/toggles/toggle_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package toggles 16 | 17 | import ( 18 | "fmt" 19 | 20 | "github.com/spf13/viper" 21 | ) 22 | 23 | func ExampleToggle_EnvironmentVariable() { 24 | ts := NewToggleSet("foo.") 25 | toggle := ts.Toggle("bar", true, "bar gets a default of true") 26 | 27 | fmt.Println(toggle.EnvironmentVariable()) 28 | 29 | // Output: GSB_FOO_BAR 30 | } 31 | 32 | func ExampleToggle_IsActive() { 33 | ts := NewToggleSet("foo.") 34 | toggle := ts.Toggle("bar", true, "bar gets a default of true") 35 | 36 | fmt.Println(toggle.IsActive()) 37 | viper.Set("foo.bar", "false") 38 | defer viper.Reset() 39 | 40 | fmt.Println(toggle.IsActive()) 41 | 42 | // Output: true 43 | // false 44 | } 45 | 46 | func ExampleToggleSet_Toggles() { 47 | ts := NewToggleSet("foo.") 48 | 49 | // add some toggles 50 | ts.Toggle("z", true, "a toggle") 51 | ts.Toggle("a", false, "another toggle") 52 | ts.Toggle("b", true, "a third toggle") 53 | 54 | for _, tgl := range ts.Toggles() { 55 | fmt.Printf("name: %s, var: %s, description: %q, default: %v\n", tgl.Name, tgl.EnvironmentVariable(), tgl.Description, tgl.Default) 56 | } 57 | 58 | // Output: name: a, var: GSB_FOO_A, description: "another toggle", default: false 59 | // name: b, var: GSB_FOO_B, description: "a third toggle", default: true 60 | // name: z, var: GSB_FOO_Z, description: "a toggle", default: true 61 | } 62 | -------------------------------------------------------------------------------- /pkg/validation/struct_validator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package validation 16 | 17 | import ( 18 | "encoding/json" 19 | "fmt" 20 | ) 21 | 22 | func ExampleErrIfNotOSBName() { 23 | fmt.Println("Good is nil:", ErrIfNotOSBName("google-storage", "my-field") == nil) 24 | fmt.Println("Bad:", ErrIfNotOSBName("google storage", "my-field")) 25 | 26 | // Output: Good is nil: true 27 | // Bad: field must match '^[a-zA-Z0-9-\.]+$': my-field 28 | } 29 | 30 | func ExampleErrIfNotJSONSchemaType() { 31 | fmt.Println("Good is nil:", ErrIfNotJSONSchemaType("string", "my-field") == nil) 32 | fmt.Println("Bad:", ErrIfNotJSONSchemaType("str", "my-field")) 33 | 34 | // Output: Good is nil: true 35 | // Bad: field must match '^(|object|boolean|array|number|string|integer)$': my-field 36 | } 37 | 38 | func ExampleErrIfNotHCL() { 39 | fmt.Println("Good HCL is nil:", ErrIfNotHCL(`provider "google" { 40 | credentials = "${file("account.json")}" 41 | project = "my-project-id" 42 | region = "us-central1" 43 | }`, "my-field") == nil) 44 | 45 | fmt.Println("Good JSON is nil:", ErrIfNotHCL(`{"a":42, "s":"foo"}`, "my-field") == nil) 46 | 47 | fmt.Println("Bad:", ErrIfNotHCL("google storage", "my-field")) 48 | 49 | // Output: Good HCL is nil: true 50 | // Good JSON is nil: true 51 | // Bad: invalid HCL: my-field 52 | } 53 | 54 | func ExampleErrIfNotTerraformIdentifier() { 55 | fmt.Println("Good is nil:", ErrIfNotTerraformIdentifier("good_id", "my-field") == nil) 56 | fmt.Println("Bad:", ErrIfNotTerraformIdentifier("bad id", "my-field")) 57 | 58 | // Output: Good is nil: true 59 | // Bad: field must match '^[a-z_]*$': my-field 60 | } 61 | 62 | func ExampleErrIfNotJSON() { 63 | fmt.Println("Good is nil:", ErrIfNotJSON(json.RawMessage("{}"), "my-field") == nil) 64 | fmt.Println("Bad:", ErrIfNotJSON(json.RawMessage(""), "my-field")) 65 | 66 | // Output: Good is nil: true 67 | // Bad: invalid JSON: my-field 68 | } 69 | -------------------------------------------------------------------------------- /pkg/varcontext/interpolation/eval.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package interpolation 16 | 17 | import ( 18 | "reflect" 19 | 20 | "github.com/hashicorp/hil" 21 | "github.com/hashicorp/hil/ast" 22 | ) 23 | 24 | // Eval evaluates the tempate string using hil https://github.com/hashicorp/hil 25 | // with the given variables that can be accessed form the string. 26 | func Eval(templateString string, variables map[string]interface{}) (interface{}, error) { 27 | tree, err := hil.Parse(templateString) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | varMap := make(map[string]ast.Variable) 33 | for vn, vv := range variables { 34 | converted, err := hil.InterfaceToVariable(vv) 35 | if err != nil { 36 | return nil, err 37 | } 38 | varMap[vn] = converted 39 | } 40 | 41 | config := &hil.EvalConfig{ 42 | GlobalScope: &ast.BasicScope{ 43 | VarMap: varMap, 44 | FuncMap: hilStandardLibrary, 45 | }, 46 | } 47 | 48 | result, err := hil.Eval(tree, config) 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | return result.Value, err 54 | } 55 | 56 | // IsHILExpression returns true if the template is a HIL expression and false 57 | // otherwise. 58 | func IsHILExpression(template string) bool { 59 | tree, err := hil.Parse(template) 60 | if err != nil { 61 | return false 62 | } 63 | 64 | // Eval will error if it can't resolve a reference so we know the template is 65 | // a HIL expression 66 | result, err := hil.Eval(tree, &hil.EvalConfig{GlobalScope: &ast.BasicScope{}}) 67 | if err != nil { 68 | return true 69 | } 70 | 71 | // if the template doesn't match the result value then we know something was 72 | // evaluated 73 | return !reflect.DeepEqual(template, result.Value) 74 | } 75 | -------------------------------------------------------------------------------- /tools/osdfgen/.gitignore: -------------------------------------------------------------------------------- 1 | osdfgen 2 | -------------------------------------------------------------------------------- /tools/osdfgen/README.md: -------------------------------------------------------------------------------- 1 | `osdfgen` can be used to build a CSV suitable for uploading to Pivotal's [OSDF Generator](http://osdf-generator.cfapps.io/static/index.html). 2 | It determines licenses by sniffing the dependencies listed in `Gopkg.lock`. 3 | 4 | Example: 5 | 6 | ```bash 7 | go run osdfgen.go -p ../../ -o test.csv 8 | ``` 9 | 10 | The `-p` flag points at the project root and the `-o` flag is the place to put the output (stdout by default). 11 | -------------------------------------------------------------------------------- /tools/osdfgen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/GoogleCloudPlatform/gcp-service-broker-tools/osdfgen 2 | 3 | go 1.12 4 | 5 | replace gopkg.in/russross/blackfriday.v2 => github.com/russross/blackfriday/v2 v2.0.1 6 | 7 | require ( 8 | github.com/pelletier/go-toml v1.4.0 9 | gopkg.in/src-d/go-license-detector.v2 v2.0.3 10 | ) 11 | -------------------------------------------------------------------------------- /utils/set.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import ( 18 | "fmt" 19 | "reflect" 20 | "sort" 21 | ) 22 | 23 | // NewStringSet creates a new string set with the given contents. 24 | func NewStringSet(contents ...string) StringSet { 25 | set := StringSet{} 26 | set.Add(contents...) 27 | return set 28 | } 29 | 30 | // NewStringSet creates a new string set with the given contents. 31 | func NewStringSetFromStringMapKeys(contents map[string]string) StringSet { 32 | set := StringSet{} 33 | for k, _ := range contents { 34 | set.Add(k) 35 | } 36 | return set 37 | } 38 | 39 | // StringSet is a set data structure for strings 40 | type StringSet map[string]bool 41 | 42 | // Add puts one or more elements into the set. 43 | func (set StringSet) Add(str ...string) { 44 | for _, s := range str { 45 | set[s] = true 46 | } 47 | } 48 | 49 | // ToSlice converts the set to a slice with sort.Strings order. 50 | func (set StringSet) ToSlice() []string { 51 | out := []string{} 52 | for k := range set { 53 | out = append(out, k) 54 | } 55 | 56 | sort.Strings(out) 57 | return out 58 | } 59 | 60 | // IsEmpty determines if the set has zero elements. 61 | func (set StringSet) IsEmpty() bool { 62 | return len(set) == 0 63 | } 64 | 65 | // Equals compares the contents of the two sets and returns true if they are 66 | // the same. 67 | func (set StringSet) Equals(other StringSet) bool { 68 | return reflect.DeepEqual(set, other) 69 | } 70 | 71 | // Contains performs a set membership check. 72 | func (set StringSet) Contains(other string) bool { 73 | _, ok := set[other] 74 | return ok 75 | } 76 | 77 | // Returns a copy of this set with every string in the other removed. 78 | func (set StringSet) Minus(other StringSet) StringSet { 79 | difference := NewStringSet() 80 | 81 | for k, _ := range set { 82 | if !other.Contains(k) { 83 | difference.Add(k) 84 | } 85 | } 86 | 87 | return difference 88 | } 89 | 90 | // String converts this set to a human readable string. 91 | func (set StringSet) String() string { 92 | return fmt.Sprintf("%v", set.ToSlice()) 93 | } 94 | -------------------------------------------------------------------------------- /utils/set_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | import "fmt" 18 | 19 | func ExampleStringSet_Add() { 20 | set := NewStringSet() 21 | set.Add("a") 22 | set.Add("b") 23 | 24 | fmt.Println(set) 25 | set.Add("a") 26 | fmt.Println(set) 27 | 28 | // Output: [a b] 29 | // [a b] 30 | } 31 | 32 | func ExampleNewStringSet() { 33 | a := NewStringSet() 34 | a.Add("a") 35 | a.Add("b") 36 | 37 | b := NewStringSet("b", "a") 38 | 39 | fmt.Println(a.Equals(b)) 40 | 41 | // Output: true 42 | } 43 | 44 | func ExampleNewStringSetFromStringMapKeys() { 45 | m := map[string]string{ 46 | "a": "some a value", 47 | "b": "some b value", 48 | } 49 | 50 | set := NewStringSetFromStringMapKeys(m) 51 | fmt.Println(set) 52 | 53 | // Output: [a b] 54 | } 55 | 56 | func ExampleStringSet_ToSlice() { 57 | a := NewStringSet() 58 | a.Add("z") 59 | a.Add("b") 60 | 61 | fmt.Println(a.ToSlice()) 62 | 63 | // Output: [b z] 64 | } 65 | 66 | func ExampleStringSet_IsEmpty() { 67 | a := NewStringSet() 68 | 69 | fmt.Println(a.IsEmpty()) 70 | a.Add("a") 71 | fmt.Println(a.IsEmpty()) 72 | 73 | // Output: true 74 | // false 75 | } 76 | 77 | func ExampleStringSet_Equals() { 78 | a := NewStringSet("a", "b") 79 | b := NewStringSet("a", "b", "c") 80 | fmt.Println(a.Equals(b)) 81 | 82 | a.Add("c") 83 | fmt.Println(a.Equals(b)) 84 | 85 | // Output: false 86 | // true 87 | } 88 | 89 | func ExampleStringSet_Contains() { 90 | a := NewStringSet("a", "b") 91 | fmt.Println(a.Contains("z")) 92 | fmt.Println(a.Contains("a")) 93 | 94 | // Output: false 95 | // true 96 | } 97 | 98 | func ExampleStringSet_Minus() { 99 | a := NewStringSet("a", "b") 100 | b := NewStringSet("b", "c") 101 | delta := a.Minus(b) 102 | 103 | fmt.Println(delta) 104 | // Output: [a] 105 | } 106 | -------------------------------------------------------------------------------- /utils/version.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 the Service Broker Project Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package utils 16 | 17 | // Version sets the version for the whole GCP service broker software. 18 | const Version = "5.1.0" 19 | 20 | // This custom user agent string is added to provision calls so that Google can track the aggregated use of this tool 21 | // We can better advocate for devoting resources to supporting cloud foundry and this service broker if we can show 22 | // good usage statistics for it, so if you feel the need to fork this repo, please leave this string in place! 23 | const CustomUserAgent = "cf-gcp-service-broker " + Version 24 | --------------------------------------------------------------------------------