API工作流
tsuru发送给service API请求类型有下面几种:
- 创建一个服务的实例 (
tsuru service-add
) - 为应用绑定一个服务实例 (
tsuru service-bind
) - 将服务从应用解除绑定 (
tsuru service-unbind
) - 销毁服务实例 (
tsuru service-remove
) - 检查服务实例的状态 (
tsuru service-status
) - 显示服务的额外信息,包括实例以及可用的计划(
tsuru service-info
)
验证
tsuru通过service API使用HTTP基本验证去做做身份验证。用户可以是用户名或者是服务名,密码定义在构建你的服务中服务清单部分。
Content-types
tsuru 在请求中使用application/x-www-form-urlencoded
,期望返回application/json
。
下面是一个tsuru请求service API请求的例子:
POST /resources HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Content-Length: 38
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
name=myinstance&plan=small&team=myteam
列出可用计划
当用户运行service-info
命令时,tsuru会列出所有可用的计划:
$ tsuru service-info mysql
通过tsuru的service API /resources/plans
GET请求,它会显示用可以访问的服务所有的实例,包括计划的列表。请求的例子如下:
GET /resources/plans HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
API应当返回下面的HTTP返回码及其消息体:
* 200: 操作成功。消息体为JSON格式,包括计划列表。每个计划包含"name"和"description"。消息体例子如下:
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
[{"name":"small","description":"plan for small instances"},
{"name":"medium","description":"plan for medium instances"},
{"name":"huge","description":"plan for huge instances"}]
在失败的情况下,service API返回500,消息体内会解释具体的错误。
创建一个新的实例
当tsuru用户通过命令行工具创建了一个服务实例时,这个过程就开始了:
$ tsuru service-add mysql mysql_instance
tsuru将名字、计划和拥有实例的团队作为参数,通过往service API的/resources
发送POST请求(请注意tsuru不包含尾斜杠)。
POST /resources HTTP/1.1
Host: myserviceapi.com
Content-Length: 56
User-Agent: Go 1.1 package http
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
name=mysql_instance&plan=small&team=myteam&user=username
API应该会返回下面的HTTP返回码和消息体:
* 201: 实例成功创建后返回。tsuru没有期望在返回的消息体中看到成功的信息,所以没有必要包含任何消息体。
* 500: 操作错误时返回。tsuru期望在service API返回的消息体中看到关于错误的解释。
将服务实例绑定到应用
当tsuru客户通过命令行将应用绑定到一个服务实例时,这个过程就开始了:
$ tsuru service-bind mysql mysql_instance --app my_app
现在,tsuru服务有两个绑定端点:/resources/<service-instance-name>/bind
和 /resources/<service-instance-name>/bind-app
.
每次应用添加单元的时候都会调用第一个端点。这个端点是一个POST请求,加上app-host和uniti-host参数,app-host代表app能访问的主机,unit-host是单元的地址。下面是请求的例子:
POST /resources/myinstance/bind HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Content-Length: 48
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
app-host=myapp.cloud.tsuru.io&unit-host=10.4.3.2
当应用绑定到服务时,会调用第二个端点/resources/<service-instance-name>/bind-app
。这个端点是一个POST请求,外加app-host参数,app-host代表应用能访问的主机。下面是请求的例子:
POST /resources/myinstance/bind-app HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Content-Length: 48
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
app-host=myapp.cloud.tsuru.io
service API应当会返回下面的HTTP返回码以及消息体:
* 201: 如果应用成功绑定到服务。返回的JSON消息体必须包含这个实例的环境变量,这样应用可以设置它们来连接到实例上。如果服务没有任何环境变量可以设置,它返回的消息体是`null`或者`{}`。返回的例子如下:
HTTP/1.1 201 CREATED
Content-Type: application/json; charset=UTF-8
{"MYSQL_HOST":"10.10.10.10","MYSQL_PORT":3306,
"MYSQL_USER":"ROOT","MYSQL_PASSWORD":"s3cr3t",
"MYSQL_DATABASE_NAME":"myapp"}
过程中的错误状态码如下:
* 404: 如果服务实例不存在。消息体内不需要包含任何内容。
* 412: 如果服务实例仍然在配置的过程中,还不能进行绑定。service API可能会在消息体中包含一些失败原因的解释。
* 500: 操作中出现任何错误。tsuru期望service API可以在消息体中包含错误的解释。
从服务实例解绑定应用
当tsuru用户通过命令行将一个服务实例从应用解绑定时,过程开始:
$ tsuru service-unbind mysql mysql_instance --app my_app
现在,tsuru有两个解绑定端点:/resources/<service-instance-name>/bind
和/resources/<service-instance-name>/bind-app
。第一个端点会在应用每次删除一个单元的时候调用。这个端点时一个DELETE请求,包含app-host和unit-host参数。请求的例子如下:
DELETE /resources/myinstance/bind HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
app-host=myapp.cloud.tsuru.io&unit-host=10.4.3.2
第二个端点/resources/<service-instance-name>/bind-app
将在应用和服务绑定被解除后运行。该端点是一个DELETE请求,包含app-host参数。请求的例子如下:
DELETE /resources/myinstance/bind-app HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
app-host=myapp.cloud.tsuru.io
API应该返回下面的HTTP返回码和对应的消息体:
* 200: 如果操作成功并且应用不再绑定到服务实例。消息体内不需要包含任何内容。
* 404: 如果服务实例不存在。消息体内不需要包含任何内容。
* 500: 操作中出现任何错误。tsuru期望service API可以在消息体中包含错误的解释。
删除实例
当tsuru用户通过命令行删除服务实例时,这个过程就开始了。:
$ tsuru service-remove mysql mysql_instance -y
tsuru通过DELETE请求去调用service API的/resources/<service-name>
去删除实例(请注意tsuru不包含尾斜线)。请求的例子如下:tsuru calls the service API to remove the instancevia DELETE on
DELETE /resources/myinstance HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
API应该返回下面的HTTP返回码和对应的消息体:
* 200: 如果服务实例删除成功。消息体内不需要包含任何内容。
* 404: 如果服务实例不存在。消息体内不需要包含任何内容。
* 500: 操作中出现任何错误。tsuru期望service API可以在消息体中包含错误的解释。
检查实例的状态
当tsuru用户通过命令行检查实例的状态,这个过程就开始了:
$ tsuru service-status mysql mysql_instance
tsuru通过GET请求调用 service API的/resources/mysql_instance/status
去检查实例状态(请注意tsuru不包含尾斜线)。请求的例子如下:
GET /resources/myinstance/status HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
API应该返回下面的HTTP返回码和对应的消息体:
* 202: 实例仍在配置中(待定)。消息体内不需要包含任何内容。
* 204: 实例在运行,并且可以连接(运行中)。
* 500: 实例没有在运行,或者还不能连接。tsuru期望消息体中有具体原因的解释。
实例的额外信息
当用户运行tsuru service-info <service>
时,tsuru会获得所有实例的信息。service API有一个可选的端点。有些服务没有提供实例的额外信息。请求的例子如下:
GET /resources/myinstance HTTP/1.1
Host: myserviceapi.com
User-Agent: Go 1.1 package http
Accept: application/json
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/x-www-form-urlencoded
API应该返回下面的HTTP返回码和对应的消息体:
* 404: API没有关于服务实例的额外信息。消息体内不需要包含任何内容。
* 200: 服务实例有额外的信息。返回消息体必须是一个包含项目列表的JSON。每个项目都是一个JSON对象,由标签和值组成。返回的例子如下:
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
[{"label":"my label","value":"my value"},
{"label":"myLabel2.0","value":"my value 2.0"}]