Implement Cloud Foundry Service Broker API¶
https://blueprints.launchpad.net/murano/+spec/cloudfoundry-api-support
Cloud Foundry is PaaS which supports full lifecycle from initial development, through all testing stages, to deployment. Most well known Cloud Foundry flavours is Cloud Foundry OSS, Pivotal Cloud Foundry and Pivotal Web Services.
If we implement Cloud Foundry Service Broker API in murano, murano apps will be available at Cloud Foundry as services. So Cloud Foundry users will be granted an ability to operate murano applications.
Problem description¶
Typical scenario of Cloud Foundry and murano collaboration will look like:
While configuring murano enable murano service broker in config file. Provide host and port for it.
Add murano Service Broker in Cloud Foundry and grant access to murano apps for Cloud Foundry organization.
Provision murano app as Cloud Foundry service instance using Cloud Foundry tools.
Proposed change¶
We need to write Cloud Foundry Service Broker implementation for murano. One of the parts of this implementation should be some mapping function between Cloud Foundry and OpenStack resources. Now it’s planned to map Cloud Foundry Organizations to OpenStack tenants and Cloud Foundry spaces to murano environments. So, all tenant users will be granted with the privileges based on their existing roles in OpenStack tenant. Each Cloud Foundry space will be linked wih murano environment. The parameters which is needed to murano for successful application deployment will store in service object section parameters. The Service Broker itself will parse them as soon as Cloud Foundry can’t do it. It will be parsed during Provision request. The request body will look like that:
{
"service_id": "service-guid-here",
"plan_id": "plan-guid-here",
"organization_guid": "org-guid-here",
"space_guid": "space-guid-here",
"parameters":{
"parameter1": 1,
"parameter2": "value"
}
}
It’s planned to setup a Service Broker as a separate service. Additional options should be added to the configs. Also we want to use Cloud Foundry experimental asynchronous operations[3].
Alternatives¶
None
Data model impact¶
None
REST API impact¶
No existing API of murano service is going to be changed. New service will be created implementing the standard Cloud Foundry Service Broker API. Its API methods are as follows:
GET /v2/catalog
Request
Method |
URI |
Description |
---|---|---|
GET |
/v2/catalog |
List all available apps |
Parameters:
None
Response
Code |
Description |
---|---|
200 |
OK. The expected resource body as below |
{
"services": [{
"id": "service-guid-here",
"name": "mysql",
"description": "A MySQL-compatible relational database",
"bindable": true,
"plans": [{
"id": "plan1-guid-here",
"name": "small",
"description": "A small shared database with 100mb storage quota and 10 connections"
},{
"id": "plan2-guid-here",
"name": "large",
"description": "A large dedicated database with 10GB storage quota, 512MB of RAM, and 100 connections",
"free": false
}],
"dashboard_client": {
"id": "client-id-1",
"secret": "secret-1",
"redirect_uri": "https://dashboard.service.com"
}
}]
}
PUT /v2/service_instances/:instance_id?accepts_incomplete=true
Request
Method |
URI |
Description |
---|---|---|
PUT |
/v2/service_instances/:instance_id?accepts_incomplete=true |
Create new service resources for developer |
{
"service_id": "service-guid-here",
"plan_id": "plan-guid-here",
"organization_guid": "org-guid-here",
"space_guid": "space-guid-here"
}
Response
Code |
Description |
---|---|
200 |
OK. May be returned if the service instance already exists and the requested parameters are identical to the existing service instance. |
202 |
Accepted. Service instance creation is in progress. |
409 |
Conflict. Should be returned if the requested service instance already exists. The expected response body is “{}” |
422 |
Should be returned if the request did not include ?accepts_incomplete=true |
{
"dashboard_url": "http://example-dashboard.com/9189kdfsk0vfnku"
}
PATCH /v2/service_instances/:instance_id?accepts_incomplete=true
Request
Method |
URI |
Description |
---|---|---|
PATCH |
/v2/service_instances/:instance_id?accepts_incomplete=true |
Update existing service instance |
{
"plan_id": "plan_guid_here"
}
Response
Code |
Description |
---|---|
200 |
Return if only the new plan matches the old one completely |
202 |
Accepted. Service instance update is in progress. |
422 |
Should be returned if the request did not include ?accepts_incomplete=true |
DELETE /v2/service_instances/:instance_id?accepts_incomplete=true
Method |
URI |
Description |
---|---|---|
DELETE |
/v2/service_instances/:instance_id?accepts_incomplete=true |
Delete all resources create during the provision. |
Response
Code |
Description |
---|---|
202 |
Accepted. Service instance deletion in progress. |
410 |
Returned if service does not exist |
422 |
Should be returned if the request did not include ?accepts_incomplete=true |
PUT /v2/service_instances/:instance_id/service_bindings/:binding_id
Request
Method |
URI |
Description |
---|---|---|
PUT |
/v2/service_instances/:instance_id/service_bindings/:binding_id |
Bind service |
{
"plan_id": "plan_guid_here",
"service_id": "service_guid_here",
"app_guid": "app_guid_here"
}
Response
Code |
Description |
---|---|
201 |
Binding has been created. The expected response body is below. |
200 |
May be returned if the binding already exists and the requested parameters are identical to the existing binding. The expected response body is below. |
409 |
Should be returned if the requested binding already exists. The expected response. body is {}, though the description field can be used to return a user-factorin error message. |
{
"credentials": {
"uri": "mysql://mysqluser:pass@mysqlhost:3306/dbname",
"username": "mysqluser",
"password": "pass",
"host": "mysqlhost",
"port": 3306,
"database": "dbname"
}
}
DELETE /v2/service_instances/:instance_id/service_bindings/:binding_id
Request
Method |
URI |
Description |
---|---|---|
DELETE |
/v2/service_instances/:instance_id/service_bindings/:binding_id |
Unbind service |
Response
Code |
Description |
---|---|
200 |
Binding was deleted |
410 |
Returned if binding does not exist |
GET /v2/service_instances/:instance_id/last_operation
Request
Method |
URI |
Description |
---|---|---|
GET |
/v2/service_instances/:instance_id/last_operation |
Polling status of the last 202 operation |
Response
Code |
Description |
---|---|
200 |
OK |
410 |
GONE. Appropriate only for asynchronous delete requests Cloud Foundry will consider this response a success and remove the resource from its database. |
{
"state": "in progress",
"description": "Creating service (10% complete)."
}
Versioning impact¶
None
Other end user impact¶
None
Deployer impact¶
Service Broker should be deployed and enabled in the murano config.
Developer impact¶
None
Murano-dashboard / Horizon impact¶
None
Implementation¶
Assignee(s)¶
- Primary assignee:
starodubcevna
Work Items¶
Changes can be split to this parts:
Implement the stub of Service Broker itself. Add needed config opts and starting point.
Implement basic Cloud Foundry API calls such as list and provision. Also on this step we should add murano specific API calls.
- Series of extensions for Cloud Foundry API support:
Add update and deprovision API calls
Add bind/unbind API calls
Dependencies¶
None
Testing¶
Unit tests should cover new API calls.
Documentation Impact¶
Document “Murano and Cloud Foundry HowTo”. It should be step by step guide for Cloud Foundry and murano cooperation.
References¶
[1] https://youtu.be/ezq9P1WN2LY [2] http://docs.cloudfoundry.org/services/api.html [3] https://docs.cloudfoundry.org/services/asynchronous-operations.html