创建私有provider
功能介绍
创建私有provider(CreatePrivateProvider)
创建一个私有的空provider。如果用户给予了provider_version和function_graph_urn,则在创建私有provider的同时,还会在私有provider下创建一个私有provider版本。
-
私有provider允许用户将自定义的provider注册到RFS中,并仅提供给当前用户使用。
-
如果同名私有provider在当前账户中已经存在,则会返回409。
-
版本号遵循语义化版本号(Semantic Version),为用户自定义。
-
在本API中,provider_version和function_graph_urn需要搭配使用,如果只指定其中一个参数,则会返回400。
-
资源编排服务只会对function_graph_urn进行浅校验,如是否符合正则,是否仅指定为当前region等。并不会深度校验,即用户是否存在权限调用,是否真实存在等。
-
该API会返回provider_source字段,该字段按照“huawei.com/private-provider/{provider_name}”的形式拼接。关于provider_name和provider_source字段在模板中的使用细节,详见下方描述中。
-
如果用户期望使用名称中不含有大写英文的provider,可以按照如下展示将provider_source字段指定为模板中定义的required_providers中的source参数。
-
如果用户期望使用名称含有大写英文的provider,需要将provider_name完全转化为小写英文创建。同时用户既可以在模板中使用API返回的provider_source参数,也可以在模板中以 “huawei.com/private-provider”为固定前缀,按照原含大写英文的provider_name,拼写provider_source参数。
以HCL格式的模板为例,模板中引用私有provider的语法如下:
Provider "{provider_name}" { source = "{provider_source}" version = "{provider_version}" }
以JSON格式的模板为例,模板中引用私有provider的语法如下:
{ "terraform":{ "required_providers":[ { "{provider_name}":{ "source":"{provider_source}", "version":"{provider_version}" } } ] } }
RFS在支持用户使用FunctionGraph(以下简称:FG)的HTTP函数运行私有Provider时,定义了一套详细的对接规则,以实现RFS与私有Provider之间的成功交互。
其中关于FG的HTTP函数使用,请参考官网文档: https://support.huaweicloud.com/productdesc-functiongraph/functiongraph_02_1002.html。
用户需要在提供的FG的HTTP函数方法中,按照如下规则实现一系列对应方法:
-
用户需要首先在FG中启动一个HTTP Server,用于接受来自RFS的HTTP请求,请求的Path固定为"/provider",请求方法为"POST"。RFS规定了发送给FG的HTTP请求体,请求体格式如下所示:
{ "method_name": String, "request_data": String, "context":{ "session_id": String, "config_data": String } }
用户提供的FG的HTTP函数需要能够接收如上请求。否则会调用私有Provider失败,导致资源编排失败。
-
下面对FG中如何使用请求体中的各个参数,以实现FG与RFS的成功交互做详细解释:
"method_name":RFS期望FG的HTTP函数中调用的私有provider的gRPC方法名。RFS会在请求体中,根据实际业务场景,每次从如下方法中选择一个进行传递。其中每个方法名需要与provider中原生的gRPC方法一一对应。在收到携带有某个方法名的请求后,FG的HTTP函数内能够调用对应的私有provider的原生gRPC方法,实现具体资源的处理逻辑。
provider内提供的原生gRPC协议请参考:tfplugin5.proto和grpc_controller.proto。方法名列表如下:
tfplugin5.proto: "/tfplugin5.Provider/GetSchema" "/tfplugin5.Provider/PrepareProviderConfig" "/tfplugin5.Provider/ValidateResourceTypeConfig" "/tfplugin5.Provider/ValidateDataSourceConfig" "/tfplugin5.Provider/UpgradeResourceState" "/tfplugin5.Provider/Configure" "/tfplugin5.Provider/ReadResource" "/tfplugin5.Provider/PlanResourceChange" "/tfplugin5.Provider/ApplyResourceChange" "/tfplugin5.Provider/ImportResourceState" "/tfplugin5.Provider/ReadDataSource" "/tfplugin5.Provider/Stop" grpc_controller.proto: "/plugin.GRPCController/Shutdown"
"request_data":RFS传递给FG的HTTP函数中每个方法的请求内容。在每个方法的处理逻辑中,需要先将request_data中的数据使用base64解码,然后作为私有provider的gRPC方法的数据传入。
"config_data":用于自定义provider处理实际请求前的初始化,如果context中config_data非空,FG的HTTP函数需要先将config_data作为输入调用/tfplugin5.Provider/Configure方法,进行初始化,再根据method_name调用对应的方法获取响应。
"session_id":表示请求是否来自同一个模板中的同一批编排任务。session_id相同,表示请求来自同一个模板中的同一批编排任务。
注意:用户启动的同一个provider进程不能接受多个来自RFS的请求。RFS推荐用户处理请求时,每次都启动新的进程处理相关请求。
-
在FG的HTTP函数中实现的请求响应按照固定格式进行返回,响应体的格式如下,成功响应码固定为200,任何其他响应码均视为失败请求,会导致资源编排失败。
{ "response_data": String, "error": String }
"response_data":调用私有provider的gRPC方法返回的内容。在FG的HTTP函数中,需要将gRPC方法返回的响应序列化后使用base64编码返回。
"error":调用gRPC方法返回的错误信息。
约束与限制:
-
私有provider为用户自行定义,提供给RFS的provider插件,RFS不负责校验其内部逻辑是否正确。
-
RFS不负责维护私有provider的生命周期。用户使用私有provider部署的资源栈,由于私有provider缺失或问题,导致资源栈无法继续部署管理的,RFS不负责提供解决方案。
-
RFS不负责保障私有provider的信息安全。用户使用私有provider部署的资源栈,由于模板中存在敏感数据,进而导致敏感信息泄露给第三方相关资源的,RFS不承担其相关责任。
-
当前调用私有provider过程中增加了网络因素,因此使用私有provider部署的失败概率会增加。如果出现因网络原因导致的部署失败,可以增加重试操作。
-
当前RFS会同步调用用户在FG中定义的一系列方法,单次方法需要确保运行时间不超过30s,否则会极大增加失败概率。
-
当前仅支持在模板中固定私有provider版本,不支持>,>=,<,<=,~>等定义宽松版本的表达式。
URI
POST /v1/private-providers
请求参数
参数 |
是否必选 |
参数类型 |
描述 |
---|---|---|---|
Client-Request-Id |
是 |
String |
用户指定的,对于此请求的唯一Id,用于定位某个请求,推荐使用UUID |
参数 |
是否必选 |
参数类型 |
描述 |
---|---|---|---|
provider_name |
是 |
String |
私有provider(private-provider)的名称。此名字在domain_id+region下应唯一,可以使用小写英文、数字、中划线。仅支持以小写英文、数字开头结尾。 按照HCL最佳实践,该名称推荐为在模板中定义的provider的本地名称(local_name)。 创建私有Provider(CreatePrivateProvider)API 还会以 “huawei.com/private-provider”为固定前缀,并以“huawei.com/private-provider/{provider_name}”的形式返回provider_source字段。关于provider_name和provider_source字段在模板中的使用细节,详见创建私有Provider的API描述。 |
provider_description |
否 |
String |
私有provider(private-provider)的描述。可用于客户识别被管理的私有provider。 |
provider_version |
否 |
String |
provider的版本号。版本号必须遵循语义化版本号(Semantic Version),为用户自定义 |
version_description |
否 |
String |
私有provider版本(provider version)的描述。可用于客户识别并管理私有provider的版本。注意:provider版本为不可更新(immutable),所以该字段不可更新,如果需要更新,请删除后重建 |
function_graph_urn |
否 |
String |
FunctionGraph方法的统一资源标识,用于唯一标识的FunctionGraph方法。当前只支持和RFS同region的function_graph_urn,如果给予了关于其他region的,会报错400。 关于该参数的详细解释,请参考官方文档:https://support.huaweicloud.com/api-functiongraph/functiongraph_06_0102.html |
响应参数
状态码: 201
参数 |
参数类型 |
描述 |
---|---|---|
provider_id |
String |
私有provider(private-provider)的唯一Id。 此Id由资源编排服务在生成provider的时候生成,为UUID。 由于私有provider名仅仅在同一时间下唯一,即用户允许先生成一个叫HelloWorld的私有provider,删除,再重新创建一个同名私有provider。 对于团队并行开发,用户可能希望确保,当前我操作的私有provider就是我以为的那个,而不是其他队友删除后创建的同名私有provider。因此,使用Id就可以做到强匹配。 资源编排服务保证每次创建的私有provider所对应的Id都不相同,更新不会影响Id。如果给予的provider_id和当前provider的Id不一致,则返回400 |
provider_source |
String |
用户使用私有provider,在Terraform模板中定义required_providers信息时,需要指明的source参数。 该参数按照“huawei.com/private-provider/{provider_name}”的形式拼接。关于provider_name和provider_source字段在模板中的使用细节,详见创建私有Provider的API描述。 |
状态码: 400
参数 |
参数类型 |
描述 |
---|---|---|
error_code |
String |
响应码 |
error_msg |
String |
响应消息 |
encoded_authorization_message |
String |
包含有关未经授权请求的信息。 |
details |
Array of Detail objects |
权限拒绝时服务返回的详细错误信息。 |
状态码: 401
参数 |
参数类型 |
描述 |
---|---|---|
error_code |
String |
响应码 |
error_msg |
String |
响应消息 |
encoded_authorization_message |
String |
包含有关未经授权请求的信息。 |
details |
Array of Detail objects |
权限拒绝时服务返回的详细错误信息。 |
状态码: 403
参数 |
参数类型 |
描述 |
---|---|---|
error_code |
String |
响应码 |
error_msg |
String |
响应消息 |
encoded_authorization_message |
String |
包含有关未经授权请求的信息。 |
details |
Array of Detail objects |
权限拒绝时服务返回的详细错误信息。 |
状态码: 409
参数 |
参数类型 |
描述 |
---|---|---|
error_code |
String |
响应码 |
error_msg |
String |
响应消息 |
encoded_authorization_message |
String |
包含有关未经授权请求的信息。 |
details |
Array of Detail objects |
权限拒绝时服务返回的详细错误信息。 |
状态码: 429
参数 |
参数类型 |
描述 |
---|---|---|
error_code |
String |
响应码 |
error_msg |
String |
响应消息 |
encoded_authorization_message |
String |
包含有关未经授权请求的信息。 |
details |
Array of Detail objects |
权限拒绝时服务返回的详细错误信息。 |
状态码: 500
参数 |
参数类型 |
描述 |
---|---|---|
error_code |
String |
响应码 |
error_msg |
String |
响应消息 |
encoded_authorization_message |
String |
包含有关未经授权请求的信息。 |
details |
Array of Detail objects |
权限拒绝时服务返回的详细错误信息。 |
请求示例
-
创建一个空的私有provider
POST https://{endpoint}/v1/private-providers { "provider_name" : "my-hello-world-provider-name", "provider_description" : "my first private provider" }
-
创建一个带有版本的的私有provider
POST https://{endpoint}/v1/private-providers { "provider_name" : "my-hello-world-provider-name", "provider_description" : "my first hello world private provider", "provider_version" : "0.0.1", "function_graph_urn" : "urn:fss:cn-north-7:a61dfe3154de42829367056598d5040f:function:default:test:latest", "version_description" : "my first private provider version" }
响应示例
状态码: 201
创建成功
{ "provider_id" : "1b15e005-bdbb-4bd7-8f9a-a09b6774b4b3", "provider_source" : "huawei.com/private-provider/my-hello-world-provider-name" }
状态码
状态码 |
描述 |
---|---|
201 |
创建成功 |
400 |
用户请求非法 |
401 |
用户身份认证失败 |
403 |
|
409 |
创建冲突,同名的私有provider已经存在 |
429 |
请求数量过多 |
500 |
服务器内部错误 |