From 644d14cf09b8b6bea71878d06e755b52b6b70dd1 Mon Sep 17 00:00:00 2001 From: gola <31429180+gola@users.noreply.github.com> Date: Fri, 22 Nov 2019 20:13:49 +0800 Subject: [PATCH] Add CFC --- README.md | 2 + doc/CFC.md | 717 ++++++++++++++++++++++++++++++++++ services/cfc/api/cfc.go | 625 +++++++++++++++++++++++++++++ services/cfc/api/errors.go | 23 ++ services/cfc/api/model.go | 358 +++++++++++++++++ services/cfc/api/request.go | 41 ++ services/cfc/api/util.go | 129 ++++++ services/cfc/api/validator.go | 308 +++++++++++++++ services/cfc/client.go | 312 +++++++++++++++ 9 files changed, 2515 insertions(+) create mode 100644 doc/CFC.md create mode 100644 services/cfc/api/cfc.go create mode 100644 services/cfc/api/errors.go create mode 100644 services/cfc/api/model.go create mode 100644 services/cfc/api/request.go create mode 100644 services/cfc/api/util.go create mode 100644 services/cfc/api/validator.go create mode 100644 services/cfc/client.go diff --git a/README.md b/README.md index 82090b39..4ed71c7b 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ bce-sdk-go | | |--util.go //BOS相关API实现使用的工具 | |--cdn //内容分布网络 | |--cert //SSL证书服务 +| |--cfc //函数计算 | |--eip //弹性公网IP | |--sts //STS服务目录 | |--vca //VCA服务目录 @@ -223,6 +224,7 @@ myLogger.Info("this is my own logger from the sdk") 百度对象存储 | BOS | github.com/baidubce/bce-sdk-go/services/bos | [BOS.md](./doc/BOS.md) 内容分布网络 | CDN | github.com/baidubce/bce-sdk-go/services/cdn | [CDN.md](./doc/CDN.md) SSL证书服务 | CERT | github.com/baidubce/bce-sdk-go/services/cert | [CERT.md](./doc/CERT.md) +函数计算 | CFC | github.com/baidubce/bce-sdk-go/services/cfc | [CFC.md](./doc/CFC.md) 弹性公网IP | EIP | github.com/baidubce/bce-sdk-go/services/eip | [EIP.md](./doc/EIP.md) 安全Token服务| STS | github.com/baidubce/bce-sdk-go/services/sts | [STS.md](./doc/STS.md) 视频内容分析 | VCA | github.com/baidubce/bce-sdk-go/services/vca | diff --git a/doc/CFC.md b/doc/CFC.md new file mode 100644 index 00000000..4d652c54 --- /dev/null +++ b/doc/CFC.md @@ -0,0 +1,717 @@ +# CFC GO SDK文档 + +# 初始化 + +## 确认Endpoint + +目前支持“华北-北京”、“华南-广州” 两个区域。北京区域:`http://cfc.bj.baidubce.com`,广州区域:`http://cfc.gz.baidubce.com` 对应信息为: + +访问区域 | 对应Endpoint +---|--- +BJ | cfc.bj.baidubce.com +GZ | cfc.gz.baidubce.com + +## 获取密钥 + +要使用百度云BOS,您需要拥有一个有效的AK(Access Key ID)和SK(Secret Access Key)用来进行签名认证。AK/SK是由系统分配给用户的,均为字符串,用于标识用户,为访问BOS做签名验证。 + +可以通过如下步骤获得并了解您的AK/SK信息: + +[注册百度云账号](https://login.bce.baidu.com/reg.html?tpl=bceplat&from=portal) + +[创建AK/SK](https://console.bce.baidu.com/iam/?_=1513940574695#/iam/accesslist) + +## CFC Client + +CFC Client是CFC服务的客户端,为开发者与CFC服务进行交互提供了一系列的方法。 + +### 使用AK/SK新建CFC Client + +通过AK/SK方式访问CFC,用户可以参考如下代码新建一个CFC Client: + +```go +import ( + "github.com/baidubce/bce-sdk-go/services/cfc" +) + +func main() { + // 用户的Access Key ID和Secret Access Key + ACCESS_KEY_ID, SECRET_ACCESS_KEY := , + + // 用户指定的Endpoint + ENDPOINT := + + // 初始化一个cfcClient + cfcClient, err := cfc.NewClient(AK, SK, ENDPOINT) +} +``` + +> **注意:**`ENDPOINT`参数需要用指定区域的域名来进行定义,如服务所在区域为北京,则为`http://cfc.bj.baidubce.com`。 + +### 使用STS创建CFC Client + +**申请STS token** + +CFC可以通过STS机制实现第三方的临时授权访问。STS(Security Token Service)是百度云提供的临时授权服务。通过STS,您可以为第三方用户颁发一个自定义时效和权限的访问凭证。第三方用户可以使用该访问凭证直接调用百度云的API或SDK访问百度云资源。 + +通过STS方式访问CFC,用户需要先通过STS的client申请一个认证字符串,申请方式可参见[百度云STS使用介绍](https://cloud.baidu.com/doc/IAM/s/gjwvyc7n7)。 + +**用STS token新建CFC Client** + +申请好STS后,可将STS Token配置到CFC Client中,从而实现通过STS Token创建CFC Client。 + +**代码示例** + +GO SDK实现了STS服务的接口,用户可以参考如下完整代码,实现申请STS Token和创建CFC Client对象: + +```go +import ( + "fmt" + + "github.com/baidubce/bce-sdk-go/auth" //导入认证模块 + "github.com/baidubce/bce-sdk-go/services/cfc" //导入CFC服务模块 + "github.com/baidubce/bce-sdk-go/services/sts" //导入STS服务模块 +) + +func main() { + // 创建STS服务的Client对象,Endpoint使用默认值 + AK, SK := , + stsClient, err := sts.NewClient(AK, SK) + if err != nil { + fmt.Println("create sts client object :", err) + return + } + + // 获取临时认证token,有效期为60秒,ACL为空 + stsObj, err := stsClient.GetSessionToken(60, "") + if err != nil { + fmt.Println("get session token failed:", err) + return + } + fmt.Println("GetSessionToken result:") + fmt.Println(" accessKeyId:", stsObj.AccessKeyId) + fmt.Println(" secretAccessKey:", stsObj.SecretAccessKey) + fmt.Println(" sessionToken:", stsObj.SessionToken) + fmt.Println(" createTime:", stsObj.CreateTime) + fmt.Println(" expiration:", stsObj.Expiration) + fmt.Println(" userId:", stsObj.UserId) + + // 使用申请的临时STS创建CFC服务的Client对象,Endpoint使用默认值 + cfcClient, err := cfc.NewClient(stsObj.AccessKeyId, stsObj.SecretAccessKey, "") + if err != nil { + fmt.Println("create cfc client failed:", err) + return + } + stsCredential, err := auth.NewSessionBceCredentials( + stsObj.AccessKeyId, + stsObj.SecretAccessKey, + stsObj.SessionToken) + if err != nil { + fmt.Println("create sts credential object failed:", err) + return + } + cfcClient.Config.Credentials = stsCredential +} +``` + +> 注意: +> 目前使用STS配置CFC Client时,无论对应CFC服务的Endpoint在哪里,STS的Endpoint都需配置为http://sts.bj.baidubce.com。上述代码中创建STS对象时使用此默认值。 + +## 配置HTTPS协议访问CFC + +CFC支持HTTPS传输协议,您可以通过在创建CFC Client对象时指定的Endpoint中指明HTTPS的方式,在CFC GO SDK中使用HTTPS访问CFC服务: + +```go +// import "github.com/baidubce/bce-sdk-go/services/cfc" + +ENDPOINT := "https://cfc.bj.baidubce.com" //指明使用HTTPS协议 +AK, SK := , +cfcClient, _ := cfc.NewClient(AK, SK, ENDPOINT) +``` + +## 配置cfc Client + +如果用户需要配置CFC Client的一些细节的参数,可以在创建CFC Client对象之后,使用该对象的导出字段`Config`进行自定义配置,可以为客户端配置代理,最大连接数等参数。 + +### 使用代理 + +下面一段代码可以让客户端使用代理访问CFC服务: + +```go +// import "github.com/baidubce/bce-sdk-go/services/cfc" + +//创建CFC Client对象 +AK, SK := , +ENDPOINT := "cfc.bj.baidubce.com" +client, _ := cfc.NewClient(AK, SK, ENDPOINT) + +//代理使用本地的8080端口 +client.Config.ProxyUrl = "127.0.0.1:8080" +``` + +### 设置网络参数 + +用户可以通过如下的示例代码进行网络参数的设置: + +```go +// import "github.com/baidubce/bce-sdk-go/services/cfc" + +AK, SK := , +ENDPOINT := "cfc.bj.baidubce.com" +client, _ := cfc.NewClient(AK, SK, ENDPOINT) + +// 配置不进行重试,默认为Back Off重试 +client.Config.Retry = bce.NewNoRetryPolicy() + +// 配置连接超时时间为30秒 +client.Config.ConnectionTimeoutInMillis = 30 * 1000 +``` + +### 配置生成签名字符串选项 + +```go +// import "github.com/baidubce/bce-sdk-go/services/cfc" + +AK, SK := , +ENDPOINT := "cfc.bj.baidubce.com" +client, _ := cfc.NewClient(AK, SK, ENDPOINT) + +// 配置签名使用的HTTP请求头为`Host` +headersToSign := map[string]struct{}{"Host": struct{}{}} +client.Config.SignOption.HeadersToSign = HeadersToSign + +// 配置签名的有效期为30秒 +client.Config.SignOption.ExpireSeconds = 30 +``` + +**参数说明** + +用户使用GO SDK访问CFC时,创建的CFC Client对象的`Config`字段支持的所有参数如下表所示: + +配置项名称 | 类型 | 含义 +-----------|---------|-------- +Endpoint | string | 请求服务的域名 +ProxyUrl | string | 客户端请求的代理地址 +Region | string | 请求资源的区域 +UserAgent | string | 用户名称,HTTP请求的User-Agent头 +Credentials| \*auth.BceCredentials | 请求的鉴权对象,分为普通AK/SK与STS两种 +SignOption | \*auth.SignOptions | 认证字符串签名选项 +Retry | RetryPolicy | 连接重试策略 +ConnectionTimeoutInMillis| int | 连接超时时间,单位毫秒,默认20分钟 + +说明: + + 1. `Credentials`字段使用`auth.NewBceCredentials`与`auth.NewSessionBceCredentials`函数创建,默认使用前者,后者为使用STS鉴权时使用,详见“使用STS创建CFC Client”小节。 + 2. `SignOption`字段为生成签名字符串时的选项,详见下表说明: + +名称 | 类型 | 含义 +--------------|-------|----------- +HeadersToSign |map[string]struct{} | 生成签名字符串时使用的HTTP头 +Timestamp | int64 | 生成的签名字符串中使用的时间戳,默认使用请求发送时的值 +ExpireSeconds | int | 签名字符串的有效期 + + 其中,HeadersToSign默认为`Host`,`Content-Type`,`Content-Length`,`Content-MD5`;TimeStamp一般为零值,表示使用调用生成认证字符串时的时间戳,用户一般不应该明确指定该字段的值;ExpireSeconds默认为1800秒即30分钟。 + 3. `Retry`字段指定重试策略,目前支持两种:`NoRetryPolicy`和`BackOffRetryPolicy`。默认使用后者,该重试策略是指定最大重试次数、最长重试时间和重试基数,按照重试基数乘以2的指数级增长的方式进行重试,直到达到最大重试测试或者最长重试时间为止。 + + +# 主要接口 + +## 函数调用 + +使用以下代码可以调用执行一个指定的CFC函数 +```go +args := &api.InvocationsArgs{ + FunctionName: "sdk-create", + InvocationType: api.InvocationTypeRequestResponse, + Payload: nil, +} + +// 若想执行特定版本的函数,可以设置 +args.Qualifier = "1" + +result, err := client.Invocations(args) +if err != nil { + fmt.Println("invocation function failed:", err) +} else { + fmt.Println("invocation function success: ", result) +} +``` + +## 函数操作 + +### 创建函数 + +使用以下代码可以创建一个CFC函数 +```go +arge := &api.CreateFunctionArgs{ + // 配置函数的代码,需要上传代码的zip压缩包 + Code: &api.CodeFile{ZipFile: zipFile}, + // 函数名称,每个用户的函数名称不可重复,不可修改 + FunctionName: "sdk-create", + // 函数调用的入口函数 + Handler: "index.handler", + // 函数的runtime + Runtime: "nodejs8.5", + // 函数运行的内存大小,单位mb,必须是128的整数倍,最大可选1024 + MemorySize: 256, + // 函数执行超时时间,可选1-300s + Timeout: 3, + // 函数描述信息 + Description: "sdk create", + // 函数日志存放方式,可选bos,表示函数执行日志存放在bos中 + LogType: "bos", + // 若LogType配置为bos,此参数设置函数执行日志在bos中的存储地址 + LogBosDir: "bos://ashjfdklsfhlk/", +}) + +// 若要配置从bos bucket中上传函数代码,可以如下设置 +// 这两个参数不能和args.Code.ZipFile同时设置 +args.Code.BosBucket = "bucketName" +args.Code.BosObject = "objectKey" + +// 若要直接发布函数,可以设置 +args.Code.Publish = true + +// 若要配置函数访问VPC网络,可以如下设置 +args.VpcConfig = &api.VpcConfig{ + SubnetIds: []string{"subnet_id1"}, + SecurityGroupIds: []string{"security_group_id1"}, +} + +// 若要配置环境变量,可以如下设置 +args.Environment = &api.Environment{ + Variables: map[string]string{ + "key": "value", + }, +}, + +result, err := client.CreateFunction(args) +if err != nil { + fmt.Println("create function failed:", err) +} else { + fmt.Println("create function success: ", result) +} +``` + +### 函数列表 + +使用以下代码可以获取CFC函数的列表 +```go +args := &api.ListFunctionArgs{} + +// 若想查询指定版本1的函数,可以如下设置 +args.FunctionVersion = "1" + +result, err := client.ListFunctions(args) +if err != nil { + fmt.Println("list function failed:", err) +} else { + fmt.Println("list function success: ", result) +} +``` + +### 函数信息 + +使用以下代码可以获取特定函数的信息 +```go +args := &api.GetFunctionArgs{ + FunctionName: "functionName" +} +result, err := client.GetFunction(args) +if err != nil { + fmt.Println("get function failed:", err) +} else { + fmt.Println("get function success: ", result) +} +``` + +### 删除函数 + +使用以下代码可以删除一个特定的CFC函数 +```go +args := &api.DeleteFunctionArgs{ + FunctionName: "sdk-create", +} + +// 若想删除函数的某个版本,可以设置 +args.Qualifier = "1" + +err := client.DeleteFunction(args) +if err != nil { + fmt.Println("delete function failed:", err) +} +``` + +### 更新函数代码 + +使用以下代码可以更新特定CFC函数的代码 +```go +args := &api.UpdateFunctionCodeArgs{ + FunctionName: "sdk-creat" + ZipFile: []byte(functionZipCode) +} + +// 若要配置从bos bucket中上传函数代码,可以如下设置 +// 这两个参数不能和args.ZipFile同时设置 +args.BosBucket = "bucketName" +args.BosObject = "objectKey" + +// 若要直接发布函数,可以设置 +args.Publish = true + +result, err := client.UpdateFunctionCode(args) +if err != nil { + fmt.Println("update function code failed:", err) +} else { + fmt.Println("update function code success: ", result) +} +``` + +### 获取函数配置 + +使用以下代码可以获取特定CFC函数的配置 +```go +args := &api.GetFunctionConfigurationArgs{ + FunctionName: "sdk-create", +} + +// 若想查询特定版本的函数的配置,可以设置 +args.Qualifier = functionBrn + +if err != nil { + fmt.Println("get function configure failed:", err) +} else { + fmt.Println("get function configure success: ", result) +} +``` + +### 更新函数配置 + +使用以下代码可以更新特定CFC函数的配置 +```go +args := &api.UpdateFunctionConfigurationArgs{ + FunctionName: "sdk-create", + Timeout: 20, + Description: "sdk update", + Runtime: "nodejs8.5", + MemorySize: &memorySize, + Environment: &api.Environment{ + Variables: map[string]string{ + "name": "Test", + }, + }, +}) + +result, err := client.UpdateFunctionConfiguration(args) +if err != nil { + fmt.Println("update function configure failed:", err) +} else { + fmt.Println("update function configure success: ", result) +} +``` + +### 设置函数预留并发度 + +使用以下代码可以设置和更新特定CFC函数的预留并发度 +```go +args := &api.ReservedConcurrentExecutionsArgs{ + FunctionName: "sdk-create", + // 预留并发度会由本函数的所有版本共享,最高能设置90 + ReservedConcurrentExecutions: 10, +}) + +err := client.SetReservedConcurrentExecutions(args) +if err != nil { + fmt.Println("set function reserved concurrent executions failed:", err) +} +``` + +### 删除函数预留并发度设置 + +使用以下代码可以删除特定CFC函数的预留并发度设置 +```go +args := &api.DeleteReservedConcurrentExecutionsArgs{ + FunctionName: "sdk-create", +}) + +err := client.DeleteReservedConcurrentExecutions(args) +if err != nil { + fmt.Println("delete function reserved concurrent executions failed:", err) +} +``` + +## 版本操作 + +### 获取函数版本列表 + +使用以下代码可以获取函数版本列表 +```go +args := &api.ListVersionsByFunctionArgs{ + FunctionName: "sdk-create", +} + +result, err := client.ListVersionsByFunction(args) +if err != nil { + fmt.Println("get function version failed:", err) +} else { + fmt.Println("get function version success: ", result) +} +``` + +### 发布版本 + +使用以下代码可以为函数发布一个版本 +```go +args := &api.PublishVersionArgs{ + FunctionName: "sdk-create", +} + +// 若想添加版本描述,可以设置 +args.Descirption = "publish description" + +// 若想对版本的部署包进行sha256验证,可以设置 +args.CodeSha256 = "codeSha256" + +result, err := client.PublishVersion(args) +if err != nil { + fmt.Println("publish function version failed:", err) +} else { + fmt.Println("publish function version success: ", result) +} +``` + +## 别名操作 + +### 获取别名列表 + +使用以下代码可以获取函数的别名列表 +```go +args := &api.ListAliasesArgs{ + FunctionName: "sdk-create", +} + +// 若想获取特定函数版本的别名,可以设置 +args.FunctionVersion = "1" + +result, err := client.ListAliases(args) +if err != nil { + fmt.Println("list function alias failed:", err) +} else { + fmt.Println("list function alias success: ", result) +} +``` + + +### 创建别名 + +使用以下代码可以为特定函数版本创建一个别名 +```go +args := &api.CreateAliasArgs{ + FunctionName: "sdk-create", + Name: "alias-create", +} + +// 若要将别名绑定到特定函数版本,可以设置 +args.FunctionVersion = "1" + +// 若要设置别名标书,可以设置 +args.Description = "alias description" + + +result, err := client.CreateAlias(args) +if err != nil { + fmt.Println("create function alias failed:", err) +} else { + fmt.Println("create function alias success: ", result) +} +``` + +### 获取别名信息 + +使用以下代码可以获取一个特定函数的别名的信息 +```go +args := &api.GetAliasArgs{ + FunctionName: "sdk-create", + AliasName: "alias-create", +} + +result, err := client.GetAlias(args) +if err != nil { + fmt.Println("get function alias failed:", err) +} else { + fmt.Println("get function alias success: ", result) +} +``` + +### 更新别名 + +使用以下代码可以更新一个函数的别名 +```go +args := &api.UpdateAliasArgs{ + FunctionName: "sdk-create", + AliasName: "alias-create", + Description: "test alias", +} + +// 若要修改别名绑定的函数版本,可以设置 +args.FunctionVersion = "$LATEST" + +result, err := client.UpdateAlias(args) +if err != nil { + fmt.Println("update function alias failed:", err) +} else { + fmt.Println("update function alias success: ", result) +} +``` + +### 删除别名 + +使用以下代码可以删除一个函数的别名 +```go +args := &api.DeleteAliasArgs{ + FunctionName: "sdk-create", + AliasName: "alias-create", +} + +err := client.DeleteAlias(args) +if err != nil { + fmt.Println("delete function alias failed:", err) +} +``` + +## 触发器操作 + +### 获取触发器列表 + +使用以下代码可以获取一个触发器的列表 +```go +args := &api.ListTriggersArgs{ + FunctionBrn: "functionBrn", +} + +result, err := client.ListTriggers(args) +if err != nil { + fmt.Println("get function trigger failed:", err) +} else { + fmt.Println("get function trigger success: ", result) +} +``` + +### 创建触发器 + +使用以下代码可以创建一个特定的触发器并绑定 +```go +args := &api.CreateTriggerArgs{ + Target: "functionBrn", + Source: api.SourceTypeCrontab, + // 创建crontab触发器所需的数据 + Data: &api.CrontabTriggerData{ + Name: "sdkName", + Brn: "functionBrn", + ScheduleExpression: "cron(0 10 * * ?)", + Enabled: "Disabled", + }, +} + +result, err := client.CreateTrigger(args) +if err != nil { + fmt.Println("create function trigger failed:", err) +} else { + fmt.Println("create function trigger success: ", result) +} +``` + +> **提示:** +> 1. 不同类型的触发器,其Data字段所需内容不同,具体可以参考文档[触发器配置](https://cloud.baidu.com/doc/CFC/s/Kjwvz47o9#relationconfiguration) + +### 更新触发器 + +使用以下代码可以更新一个函数的触发器 +```go +args := &api.UpdateTriggerArgs{ + RelationId: RelationId, + Target: functionBRN, + Source: api.SourceTypeHTTP, + Data: &api.HttpTriggerData{ + ResourcePath: fmt.Sprintf("tr99-%s", time.Now().Format("2006-01-02T150405")), + Method: "GET", + AuthType: "anonymous", + }, +} + +result, err := client.UpdateTrigger(args) +if err != nil { + fmt.Println("update function trigger failed:", err) +} else { + fmt.Println("update function trigger success: ", result) +} +``` + +### 删除触发器 + +使用以下代码可以删除一个触发器 +```go +args := &api.DeleteTriggerArgs{ + RelationId: RelationId, + Target: functionBRN, + Source: api.SourceTypeHTTP, +} + +err := client.DeleteTrigger(args) +if err != nil { + fmt.Println("delete function trigger failed:", err) +} +``` + + +# 错误处理 + +GO语言以error类型标识错误,CFC支持两种错误见下表: + +错误类型 | 说明 +----------------|------------------- +CFCClientError | 用户操作产生的错误 +BceServiceError | CFC服务返回的错误 + +用户使用SDK调用CFC相关接口,除了返回所需的结果之外还会返回错误,用户可以获取相关错误进行处理。实例如下: + +``` +// cfcClient 为已创建的CFC Client对象 +args := &api.GetFunctionArgs{ + FunctionName: "functionName" +} +result, err := cfcClient.GetFunction(args) +if err != nil { + switch realErr := err.(type) { + case *bce.BceClientError: + fmt.Println("client occurs error:", realErr.Error()) + case *bce.BceServiceError: + fmt.Println("service occurs error:", realErr.Error()) + default: + fmt.Println("unknown error:", err) + } +} else { + fmt.Println("get function detail success: ", result) +} +``` + +## 客户端异常 + +客户端异常表示客户端尝试向CFC发送请求以及数据传输时遇到的异常。例如,当发送请求时网络连接不可用时,则会返回BceClientError;当上传文件时发生IO异常时,也会抛出BceClientError。 + +## 服务端异常 + +当CFC服务端出现异常时,CFC服务端会返回给用户相应的错误信息,以便定位问题。常见服务端异常可参见[CFC错误返回](https://cloud.baidu.com/doc/CFC/s/Djwvz4cwc) + +# 版本变更记录 + +## v0.9.1 [2019-09-26] + +首次发布: + + - 执行函数 + - 创建、查看、列表、删除函数,更新函数代码,更新、获取函数配置 + - 设置、删除函数预留并发度 + - 列表、创建函数版本 + - 列表、创建、获取、更新、删除别名 + - 获取、创建、更新、删除触发器 diff --git a/services/cfc/api/cfc.go b/services/cfc/api/cfc.go new file mode 100644 index 00000000..a9c12812 --- /dev/null +++ b/services/cfc/api/cfc.go @@ -0,0 +1,625 @@ +/* + * Copyright 2017 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +package api + +import ( + "encoding/base64" + "encoding/json" + "io/ioutil" + "reflect" + "strconv" + + "github.com/baidubce/bce-sdk-go/bce" + "github.com/baidubce/bce-sdk-go/http" +) + +func ListFunctions(cli bce.Client, args *ListFunctionsArgs) (*ListFunctionsResult, error) { + op := &Operation{ + HTTPUri: getFunctionsUri(), + HTTPMethod: GET, + } + + if args.MaxItems <= 0 { + args.MaxItems = 10000 + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "FunctionVersion": args.FunctionVersion, + "Marker": args.Marker, + "MaxItems": args.MaxItems, + }, + } + result := &cfcResult{ + Result: &ListFunctionsResult{}, + } + + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*ListFunctionsResult); ok { + return value, nil + } + return nil, nil +} + +func GetFunction(cli bce.Client, args *GetFunctionArgs) (*GetFunctionResult, error) { + op := &Operation{ + HTTPUri: getFunctionUri(args.FunctionName), + HTTPMethod: GET, + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "Qualifier": args.Qualifier, + }, + } + result := &cfcResult{ + Result: &GetFunctionResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*GetFunctionResult); ok { + return value, nil + } + return nil, nil +} + +func CreateFunction(cli bce.Client, args *CreateFunctionArgs) (*CreateFunctionResult, error) { + op := &Operation{ + HTTPUri: getFunctionsUri(), + HTTPMethod: POST, + } + request := &cfcRequest{ + Args: args, + Body: args, + } + result := &cfcResult{ + Result: &CreateFunctionResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*CreateFunctionResult); ok { + return value, nil + } + return nil, nil +} + +func DeleteFunction(cli bce.Client, args *DeleteFunctionArgs) error { + op := &Operation{ + HTTPUri: getFunctionUri(args.FunctionName), + HTTPMethod: DELETE, + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "Qualifier": args.Qualifier, + }, + } + result := &cfcResult{ + Result: nil, + } + err := caller(cli, op, request, result) + if err != nil { + return err + } + return nil +} + +func UpdateFunctionCode(cli bce.Client, args *UpdateFunctionCodeArgs) (*UpdateFunctionCodeResult, error) { + op := &Operation{ + HTTPUri: getFunctionCodeUri(args.FunctionName), + HTTPMethod: PUT, + } + request := &cfcRequest{ + Args: args, + Body: args, + } + result := &cfcResult{ + Result: &UpdateFunctionCodeResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*UpdateFunctionCodeResult); ok { + return value, nil + } + return nil, nil +} + +func GetFunctionConfiguration(cli bce.Client, args *GetFunctionConfigurationArgs) (*GetFunctionConfigurationResult, error) { + op := &Operation{ + HTTPUri: getFunctionConfigurationUri(args.FunctionName), + HTTPMethod: GET, + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "Qualifier": args.Qualifier, + }, + } + result := &cfcResult{ + Result: &GetFunctionConfigurationResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*GetFunctionConfigurationResult); ok { + return value, nil + } + return nil, nil +} + +func UpdateFunctionConfiguration(cli bce.Client, args *UpdateFunctionConfigurationArgs) (*UpdateFunctionConfigurationResult, error) { + op := &Operation{ + HTTPUri: getFunctionConfigurationUri(args.FunctionName), + HTTPMethod: PUT, + } + request := &cfcRequest{ + Args: args, + Body: args, + } + result := &cfcResult{ + Result: &UpdateFunctionConfigurationResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*UpdateFunctionConfigurationResult); ok { + return value, nil + } + return nil, nil +} + +func SetReservedConcurrentExecutions(cli bce.Client, args *ReservedConcurrentExecutionsArgs) error { + op := &Operation{ + HTTPUri: getFunctionConCurrentUri(args.FunctionName), + HTTPMethod: PUT, + } + request := &cfcRequest{ + Args: args, + Body: args, + } + result := &cfcResult{ + Result: nil, + } + err := caller(cli, op, request, result) + if err != nil { + return err + } + return nil +} + +func DeleteReservedConcurrentExecutions(cli bce.Client, args *DeleteReservedConcurrentExecutionsArgs) error { + op := &Operation{ + HTTPUri: getFunctionConCurrentUri(args.FunctionName), + HTTPMethod: DELETE, + } + request := &cfcRequest{ + Args: args, + } + result := &cfcResult{} + err := caller(cli, op, request, result) + if err != nil { + return err + } + return nil +} + +func Invocations(cli bce.Client, args *InvocationsArgs) (*InvocationsResult, error) { + if err := args.Validate(); err != nil { + return nil, err + } + if len(args.InvocationType) == 0 { + args.InvocationType = InvocationTypeRequestResponse + } + if len(args.LogType) == 0 { + args.LogType = LogTypeNone + } + + req := &bce.BceRequest{} + req.SetUri(getInvocationsUri(args.FunctionName)) + req.SetMethod(http.POST) + req.SetParam("invocationType", string(args.InvocationType)) + req.SetParam("logType", string(args.LogType)) + if args.Qualifier != "" { + req.SetParam("qualifier", args.Qualifier) + } + + if args.Payload != nil { + var payloadBytes []byte + var err error + switch args.Payload.(type) { + case string: + payloadBytes = []byte(args.Payload.(string)) + case []byte: + payloadBytes = args.Payload.([]byte) + default: + payloadBytes, err = json.Marshal(args.Payload) + if err != nil { + return nil, err + } + } + var js interface{} + if json.Unmarshal([]byte(payloadBytes), &js) != nil { + return nil, ParseJsonError + } + requestBody, err := bce.NewBodyFromBytes(payloadBytes) + if err != nil { + return nil, err + } + req.SetHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE) + req.SetBody(requestBody) + } + + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return nil, err + } + defer resp.Body().Close() + if resp.IsFail() { + return nil, resp.ServiceError() + } + body, err := ioutil.ReadAll(resp.Body()) + if err != nil { + return nil, err + } + result := &InvocationsResult{ + Payload: string(body), + } + errorStr := resp.Header("x-bce-function-error") + if len(errorStr) > 0 { + result.FunctionError = errorStr + } + logResult := resp.Header("x-bce-log-result") + if len(logResult) > 0 { + decodeBytes, err := base64.StdEncoding.DecodeString(string(logResult)) + if err != nil { + return nil, err + } + result.LogResult = string(decodeBytes) + } + return result, nil +} + +func ListVersionsByFunction(cli bce.Client, args *ListVersionsByFunctionArgs) (*ListVersionsByFunctionResult, error) { + op := &Operation{ + HTTPUri: getFunctionVersionsUri(args.FunctionName), + HTTPMethod: GET, + } + if args.MaxItems <= 0 { + args.MaxItems = 10000 + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "Marker": args.Marker, + "MaxItems": args.MaxItems, + }, + } + result := &cfcResult{ + Result: &ListVersionsByFunctionResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*ListVersionsByFunctionResult); ok { + return value, nil + } + return nil, nil +} + +func PublishVersion(cli bce.Client, args *PublishVersionArgs) (*PublishVersionResult, error) { + op := &Operation{ + HTTPUri: getFunctionVersionsUri(args.FunctionName), + HTTPMethod: POST, + } + request := &cfcRequest{ + Args: args, + Body: map[string]interface{}{ + "Description": args.Description, + "CodeSha256": args.CodeSha256, + }, + } + result := &cfcResult{ + Result: &PublishVersionResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*PublishVersionResult); ok { + return value, nil + } + return nil, nil +} + +func ListAliases(cli bce.Client, args *ListAliasesArgs) (*ListAliasesResult, error) { + op := &Operation{ + HTTPUri: getFunctionAliasesUri(args.FunctionName), + HTTPMethod: GET, + } + if args.MaxItems <= 0 { + args.MaxItems = 10000 + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "FunctionVersion": args.FunctionVersion, + "Marker": args.Marker, + "MaxItems": args.MaxItems, + }, + } + result := &cfcResult{ + Result: &ListAliasesResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*ListAliasesResult); ok { + return value, nil + } + return nil, nil +} + +func CreateAlias(cli bce.Client, args *CreateAliasArgs) (*CreateAliasResult, error) { + op := &Operation{ + HTTPUri: getFunctionAliasesUri(args.FunctionName), + HTTPMethod: POST, + } + request := &cfcRequest{ + Args: args, + Body: map[string]interface{}{ + "FunctionVersion": args.FunctionVersion, + "Name": args.Name, + "Description": args.Description, + }, + } + result := &cfcResult{ + Result: &CreateAliasResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*CreateAliasResult); ok { + return value, nil + } + return nil, nil +} + +func GetAlias(cli bce.Client, args *GetAliasArgs) (*GetAliasResult, error) { + op := &Operation{ + HTTPUri: getFunctionAliasUri(args.FunctionName, args.AliasName), + HTTPMethod: GET, + } + request := &cfcRequest{ + Args: args, + } + result := &cfcResult{ + Result: &GetAliasResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*GetAliasResult); ok { + return value, nil + } + return nil, nil +} + +func UpdateAlias(cli bce.Client, args *UpdateAliasArgs) (*UpdateAliasResult, error) { + op := &Operation{ + HTTPUri: getFunctionAliasUri(args.FunctionName, args.AliasName), + HTTPMethod: PUT, + } + request := &cfcRequest{ + Args: args, + Body: map[string]interface{}{ + "FunctionVersion": args.FunctionVersion, + "Description": args.Description, + }, + } + result := &cfcResult{ + Result: &UpdateAliasResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*UpdateAliasResult); ok { + return value, nil + } + return nil, nil +} + +func DeleteAlias(cli bce.Client, args *DeleteAliasArgs) error { + op := &Operation{ + HTTPUri: getFunctionAliasUri(args.FunctionName, args.AliasName), + HTTPMethod: DELETE, + } + request := &cfcRequest{ + Args: args, + } + result := &cfcResult{} + err := caller(cli, op, request, result) + if err != nil { + return err + } + return nil +} + +func ListTriggers(cli bce.Client, args *ListTriggersArgs) (*ListTriggersResult, error) { + op := &Operation{ + HTTPUri: getTriggerUri(), + HTTPMethod: GET, + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "FunctionBrn": args.FunctionBrn, + }, + } + result := &cfcResult{ + Result: &ListTriggersResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*ListTriggersResult); ok { + return value, nil + } + return nil, nil +} + +func CreateTrigger(cli bce.Client, args *CreateTriggerArgs) (*CreateTriggerResult, error) { + op := &Operation{ + HTTPUri: getTriggerUri(), + HTTPMethod: POST, + } + request := &cfcRequest{ + Args: args, + Body: args, + } + result := &cfcResult{ + Result: &CreateTriggerResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*CreateTriggerResult); ok { + return value, nil + } + return nil, nil + +} + +func UpdateTrigger(cli bce.Client, args *UpdateTriggerArgs) (*UpdateTriggerResult, error) { + op := &Operation{ + HTTPUri: getTriggerUri(), + HTTPMethod: PUT, + } + request := &cfcRequest{ + Args: args, + Body: map[string]interface{}{ + "RelationId": args.RelationId, + "Target": args.Target, + "Source": args.Source, + "Data": args.Data, + }, + } + result := &cfcResult{ + Result: &UpdateTriggerResult{}, + } + err := caller(cli, op, request, result) + if err != nil { + return nil, err + } + if value, ok := result.Result.(*UpdateTriggerResult); ok { + return value, nil + } + return nil, nil +} + +func DeleteTrigger(cli bce.Client, args *DeleteTriggerArgs) error { + op := &Operation{ + HTTPUri: getTriggerUri(), + HTTPMethod: DELETE, + } + request := &cfcRequest{ + Args: args, + Params: map[string]interface{}{ + "RelationId": args.RelationId, + "Target": args.Target, + "Source": string(args.Source), + }, + } + result := &cfcResult{} + err := caller(cli, op, request, result) + if err != nil { + return err + } + return nil +} + +func caller(cli bce.Client, op *Operation, request *cfcRequest, response *cfcResult) error { + if err := request.Args.(Validator).Validate(); err != nil { + return err + } + req := new(bce.BceRequest) + if op.HTTPUri == "" { + return URIIllegal + } + req.SetUri(op.HTTPUri) + if op.HTTPMethod == "" { + return MethodIllegal + } + req.SetMethod(op.HTTPMethod) + if request.Params != nil { + for key, value := range request.Params { + rv := reflect.ValueOf(value) + switch rv.Kind() { + case reflect.String: + req.SetParam(key, value.(string)) + case reflect.Int: + req.SetParam(key, strconv.Itoa(value.(int))) + case reflect.Struct: + if valueBytes, err := json.Marshal(value); err != nil { + req.SetParam(key, string(valueBytes)) + } + } + } + } + if request.Body != nil { + argsBytes, err := json.Marshal(request.Body) + if err != nil { + return err + } + requestBody, err := bce.NewBodyFromBytes(argsBytes) + if err != nil { + return err + } + req.SetHeader(http.CONTENT_TYPE, bce.DEFAULT_CONTENT_TYPE) + req.SetBody(requestBody) + } + resp := &bce.BceResponse{} + if err := cli.SendRequest(req, resp); err != nil { + return err + } + defer resp.Body().Close() + if resp.IsFail() { + return resp.ServiceError() + } + + if response.Result != nil { + if err := resp.ParseJsonBody(response.Result); err != nil { + return err + } + } + return nil +} diff --git a/services/cfc/api/errors.go b/services/cfc/api/errors.go new file mode 100644 index 00000000..4fcf298b --- /dev/null +++ b/services/cfc/api/errors.go @@ -0,0 +1,23 @@ +package api + +import "errors" + +var ( + URIIllegal = errors.New("invalid request uri") + MethodIllegal = errors.New("invalid request method") + InvalidArgument = errors.New("invalid arguments") + ParseJsonError = errors.New("could not parse payload into json") +) + +const ( + requiredIllegal = "the %s field is required" + memoryRangeIllegal = "memory size %d must in %d MB ~ %d MB" + memorySizeIllegal = "memory size %d must be a multiple of %d MB" + functionNameInvalid = "the function name of %s must match " + RegularFunctionName + AliasNameInvalid = "the alias name of %s must match " + RegularAliasName + functionBRNInvalid = "the brn %s must match " + RegularFunctionBRN + FunctionCodeInvalid = "the code of function is invalidate" + VersionInvalid = "the version of function must match " + RegularVersion + QualifierInvalid = "the qualifier is not the function's version or alias" + PaginateInvalid = "the pagination must greater than 0" +) diff --git a/services/cfc/api/model.go b/services/cfc/api/model.go new file mode 100644 index 00000000..4a6cd190 --- /dev/null +++ b/services/cfc/api/model.go @@ -0,0 +1,358 @@ +/* + * Copyright 2017 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +package api + +import ( + "time" +) + +type InvocationType string +type LogType string +type SourceType string +type TriggerType string + +const ( + InvocationTypeEvent InvocationType = "Event" + InvocationTypeRequestResponse InvocationType = "RequestResponse" + InvocationTypeDryRun InvocationType = "DryRun" + + LogTypeTail LogType = "Tail" + LogTypeNone LogType = "None" + + SourceTypeDuerOS SourceType = "dueros" + SourceTypeDuEdge SourceType = "duedge" + SourceTypeHTTP SourceType = "cfc-http-trigger/v1/CFCAPI" + SourceTypeCrontab SourceType = "cfc-crontab-trigger/v1/" + SourceTypeCDN SourceType = "cdn" + + TriggerTypeHTTP TriggerType = "cfc-http-trigger" + TriggerTypeGeneric TriggerType = "generic" +) + +type Function struct { + Uid string `json:"Uid"` + Description string `json:"Description"` + FunctionBrn string `json:"FunctionBrn"` + Region string `json:"Region"` + Timeout int `json:"Timeout"` + VersionDesc string `json:"VersionDesc"` + UpdatedAt time.Time `json:"UpdatedAt"` + LastModified time.Time `json:"LastModified"` + CodeSha256 string `json:"CodeSha256"` + CodeSize int32 `json:"CodeSize"` + FunctionArn string `json:"FunctionArn"` + FunctionName string `json:"FunctionName"` + Handler string `json:"Handler"` + Version string `json:"Version"` + Runtime string `json:"Runtime"` + MemorySize int `json:"MemorySize"` + Environment *Environment `json:"Environment"` + CommitID string `json:"CommitID"` + CodeID string `json:"CodeID"` + Role string `json:"Role"` + VpcConfig *VpcConfig `json:"VpcConfig"` + LogType string `json:"LogType"` + LogBosDir string `json:"LogBosDir"` + SourceTag string `json:"SourceTag"` +} + +//functionInfo +type FunctionInfo struct { + Code *CodeStorage `json:"Code"` + Configuration *Function `json:"Configuration"` +} + +type Alias struct { + AliasBrn string `json:"AliasBrn"` + AliasArn string `json:"AliasArn"` + FunctionName string `json:"FunctionName"` + FunctionVersion string `json:"FunctionVersion"` + Name string `json:"Name"` + Description string `json:"Description"` + Uid string `json:"Uid"` + UpdatedAt time.Time `json:"UpdatedAt"` + CreatedAt time.Time `json:"CreatedAt"` +} + +type RelationInfo struct { + RelationId string `json:"RelationId"` + Sid string `json:"Sid"` + Source SourceType `json:"Source"` + Target string `json:"Target"` + Data interface{} `json:"Data"` +} + +type CodeStorage struct { + Location string `json:"Location"` + RepositoryType string `json:"RepositoryType"` +} + +type Environment struct { + Variables map[string]string +} + +type CodeFile struct { + Publish bool + DryRun bool + ZipFile []byte + BosBucket string + BosObject string +} + +type VpcConfig struct { + VpcId string + SubnetIds []string + SecurityGroupIds []string +} + +type InvocationsArgs struct { + FunctionName string + InvocationType InvocationType + LogType LogType + Qualifier string + Payload interface{} +} + +type InvocationsResult struct { + Payload string + FunctionError string + LogResult string +} + +type GetFunctionArgs struct { + FunctionName string + Qualifier string +} + +type GetFunctionResult struct { + Code CodeStorage + Configuration Function +} + +type ListFunctionsArgs struct { + FunctionVersion string + Marker int + MaxItems int +} + +type ListFunctionsResult struct { + Functions []*Function + NextMarker string +} + +type CreateFunctionArgs struct { + Code *CodeFile + FunctionName string + Handler string + Runtime string + MemorySize int + Timeout int + Description string + Environment *Environment + VpcConfig *VpcConfig + LogType string + LogBosDir string +} + +type CreateFunctionResult Function + +type DeleteFunctionArgs struct { + FunctionName string + Qualifier string +} + +type GetFunctionConfigurationArgs struct { + FunctionName string + Qualifier string +} + +type GetFunctionConfigurationResult Function + +type UpdateFunctionConfigurationArgs struct { + FunctionName string + Timeout int `json:"Timeout,omitempty"` + MemorySize int `json:"MemorySize,omitempty"` + Description string + Handler string + Runtime string + Environment *Environment + VpcConfig *VpcConfig + LogType string + LogBosDir string +} + +type UpdateFunctionConfigurationResult Function + +type UpdateFunctionCodeArgs struct { + FunctionName string + ZipFile []byte + Publish bool + DryRun bool + BosBucket string + BosObject string +} + +type UpdateFunctionCodeResult Function + +type ReservedConcurrentExecutionsArgs struct { + FunctionName string + ReservedConcurrentExecutions int +} + +type DeleteReservedConcurrentExecutionsArgs struct { + FunctionName string +} + +type ListVersionsByFunctionArgs struct { + FunctionName string + Marker int + MaxItems int +} +type ListVersionsByFunctionResult struct { + Versions []*Function + NextMarker string +} + +type PublishVersionArgs struct { + FunctionName string + Description string + CodeSha256 string +} + +type PublishVersionResult Function + +type ListAliasesArgs struct { + FunctionName string + FunctionVersion string + Marker int + MaxItems int +} + +type ListAliasesResult struct { + Aliases []*Alias + NextMarker string +} + +type GetAliasArgs struct { + FunctionName string + AliasName string +} + +type GetAliasResult Alias + +type CreateAliasArgs struct { + FunctionName string + FunctionVersion string + Name string + Description string +} + +type CreateAliasResult Alias + +type UpdateAliasArgs struct { + FunctionName string + AliasName string + FunctionVersion string + Description string +} +type UpdateAliasResult Alias + +type DeleteAliasArgs struct { + FunctionName string + AliasName string +} + +type ListTriggersArgs struct { + FunctionBrn string +} +type ListTriggersResult struct { + Relation []*RelationInfo +} + +type BosEventType string + +const ( + BosEventTypePutObject BosEventType = "PutObject" + BosEventTypePostObject BosEventType = "PostObject" + BosEventTypeAppendObject BosEventType = "AppendObject" + BosEventTypeCopyObject BosEventType = "CopyObject" + BosEventTypeCompleteMultipartObject BosEventType = "CompleteMultipartObject" +) + +type BosTriggerData struct { + Resource string + Status string + EventType []BosEventType + Name string +} + +type HttpTriggerData struct { + ResourcePath string + Method string + AuthType string +} + +type CDNEventType string + +const ( + CDNEventTypeCachedObjectsBlocked CDNEventType = "CachedObjectsBlocked" + CDNEventTypeCachedObjectsPushed CDNEventType = "CachedObjectsPushed" + CDNEventTypeCachedObjectsRefreshed CDNEventType = "CachedObjectsRefreshed" + CDNEventTypeCdnDomainCreated CDNEventType = "CdnDomainCreated" + CDNEventTypeCdnDomainDeleted CDNEventType = "CdnDomainDeleted" + CDNEventTypeLogFileCreated CDNEventType = "LogFileCreated" + CDNEventTypeCdnDomainStarted CDNEventType = "CdnDomainStarted" + CDNEventTypeCdnDomainStopped CDNEventType = "CdnDomainStopped" +) + +type CDNTriggerData struct { + EventType CDNEventType + Domains []string + Remark string + Status string +} + +type CrontabTriggerData struct { + Brn string + Enabled string + Input string + Name string + ScheduleExpression string +} + +type CreateTriggerArgs struct { + Target string + Source SourceType + Data interface{} +} +type CreateTriggerResult struct { + Relation *RelationInfo +} + +type UpdateTriggerArgs struct { + RelationId string + Target string + Source SourceType + Data interface{} +} +type UpdateTriggerResult struct { + Relation *RelationInfo +} + +type DeleteTriggerArgs struct { + RelationId string + Target string + Source SourceType +} diff --git a/services/cfc/api/request.go b/services/cfc/api/request.go new file mode 100644 index 00000000..d827cc8f --- /dev/null +++ b/services/cfc/api/request.go @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +package api + +type HTTPMethod = string + +const ( + GET HTTPMethod = "GET" + PUT HTTPMethod = "PUT" + POST HTTPMethod = "POST" + DELETE HTTPMethod = "DELETE" + HEAD HTTPMethod = "HEAD" + OPTIONS HTTPMethod = "OPTIONS" +) + +type Operation struct { + HTTPMethod HTTPMethod + HTTPUri string +} + +type cfcRequest struct { + Args interface{} + Params map[string]interface{} + Body interface{} +} + +type cfcResult struct { + Result interface{} +} diff --git a/services/cfc/api/util.go b/services/cfc/api/util.go new file mode 100644 index 00000000..d887bbc0 --- /dev/null +++ b/services/cfc/api/util.go @@ -0,0 +1,129 @@ +/* + * Copyright 2017 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +package api + +import ( + "fmt" + "regexp" +) + +const ( + RegularFunctionName = `^[a-zA-Z0-9-_:]+|\$LATEST$` + RegularAliasName = `^[a-zA-Z0-9-_]+$` + RegularFunctionBRN = `^(brn:(bce[a-zA-Z-]*):cfc:)([a-z]{2,5}[0-9]*:)([0-9a-z]{32}:)(function:)([a-zA-Z0-9-_]+)(:(\$LATEST|[a-zA-Z0-9-_]+))?$` + RegularVersion = `^\$LATEST|([0-9]+)$` + + MemoryBase = 128 + minMemoryLimit = 128 + maxMemoryLimit = 3008 +) + +func getInvocationsUri(functionName string) string { + return fmt.Sprintf("/v1/functions/%s/invocations", functionName) +} + +func getFunctionsUri() string { + return fmt.Sprintf("/v1/functions") +} + +func getFunctionUri(functionName string) string { + return fmt.Sprintf("/v1/functions/%s", functionName) +} + +func getFunctionCodeUri(functionName string) string { + return fmt.Sprintf("/v1/functions/%s/code", functionName) +} + +func getFunctionConfigurationUri(functionName string) string { + return fmt.Sprintf("/v1/functions/%s/configuration", functionName) +} + +func getFunctionConCurrentUri(functionName string) string { + return fmt.Sprintf("/v1/functions/%s/concurrency", functionName) +} + +func getFunctionVersionsUri(functionName string) string { + return fmt.Sprintf("/v1/functions/%s/versions", functionName) +} + +func getFunctionAliasesUri(functionName string) string { + return fmt.Sprintf("/v1/functions/%s/aliases", functionName) +} + +func getFunctionAliasUri(functionName string, aliasName string) string { + return fmt.Sprintf("/v1/functions/%s/aliases/%s", functionName, aliasName) +} + +func getTriggerUri() string { + return fmt.Sprintf("/v1/console/relation") +} + +func validateFunctionName(name string) bool { + res, err := regexp.MatchString(RegularFunctionName, name) + if err != nil { + return false + } + return res +} + +func validateAliasName(name string) bool { + res, err := regexp.MatchString(RegularAliasName, name) + if err != nil { + return false + } + return res +} + +func validateMemorySize(size int) error { + if size%MemoryBase != 0 { + return fmt.Errorf(memorySizeIllegal, size, MemoryBase) + } + if size > maxMemoryLimit { + return fmt.Errorf(memoryRangeIllegal, size, minMemoryLimit, maxMemoryLimit) + } + if size < minMemoryLimit { + return fmt.Errorf(memoryRangeIllegal, size, minMemoryLimit, maxMemoryLimit) + } + return nil +} + +func validateFunctionBRN(brn string) bool { + res, err := regexp.MatchString(RegularFunctionBRN, brn) + if err != nil { + return false + } + return res +} + +func validateVersion(version string) bool { + res, err := regexp.MatchString(RegularVersion, version) + if err != nil { + return false + } + return res +} + +func validateQualifier(qualifier string) bool { + var res bool + res, err := regexp.MatchString(RegularAliasName, qualifier) + if err == nil && res == true { + return true + } + res, err = regexp.MatchString(RegularVersion, qualifier) + if err != nil { + return false + } + return res +} diff --git a/services/cfc/api/validator.go b/services/cfc/api/validator.go new file mode 100644 index 00000000..86f24649 --- /dev/null +++ b/services/cfc/api/validator.go @@ -0,0 +1,308 @@ +package api + +import ( + "fmt" +) + +type Validator interface { + Validate() error +} + +func (args InvocationsArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if args.Qualifier != "" && !validateQualifier(args.Qualifier) { + return fmt.Errorf(QualifierInvalid) + } + return nil +} + +func (args ListFunctionsArgs) Validate() error { + if args.Marker < 0 || args.MaxItems < 0 { + return fmt.Errorf(PaginateInvalid) + } + if args.FunctionVersion != "" && !validateVersion(args.FunctionVersion) { + return fmt.Errorf(VersionInvalid) + } + return nil +} + +func (args GetFunctionArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if args.Qualifier != "" && !validateQualifier(args.Qualifier) { + return fmt.Errorf(QualifierInvalid) + } + return nil +} + +func (args CreateFunctionArgs) Validate() error { + if args.Code == nil { + return fmt.Errorf(requiredIllegal, "Code") + } + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if args.Handler == "" { + return fmt.Errorf(requiredIllegal, "Handler") + } + if args.Runtime == "" { + return fmt.Errorf(requiredIllegal, "Runtime") + } + if err := validateMemorySize(args.MemorySize); err != nil { + return err + } + if len(args.Code.ZipFile) == 0 && (len(args.Code.BosBucket) == 0 || len(args.Code.BosObject) == 0){ + return fmt.Errorf(FunctionCodeInvalid) + } + return nil +} + +func (args DeleteFunctionArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if args.Qualifier != "" && !validateQualifier(args.Qualifier) { + return fmt.Errorf(QualifierInvalid) + } + return nil +} + +func (args UpdateFunctionCodeArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + return nil +} + +func (args GetFunctionConfigurationArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if args.Qualifier != "" && !validateQualifier(args.Qualifier) { + return fmt.Errorf(QualifierInvalid) + } + return nil +} + +func (args UpdateFunctionConfigurationArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + return nil +} + +func (args ListVersionsByFunctionArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if args.Marker < 0 || args.MaxItems < 0 { + return fmt.Errorf(PaginateInvalid) + } + return nil +} + +func (args PublishVersionArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + return nil +} + +func (args ListAliasesArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if args.Marker < 0 || args.MaxItems < 0 { + return fmt.Errorf(PaginateInvalid) + } + if args.FunctionVersion != "" && !validateVersion(args.FunctionVersion) { + return fmt.Errorf(VersionInvalid) + } + return nil +} + +func (args CreateAliasArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if args.FunctionVersion == "" { + return fmt.Errorf(requiredIllegal, "FunctionVersion") + } + if args.Name == "" { + return fmt.Errorf(requiredIllegal, "Name") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if !validateVersion(args.FunctionVersion) { + return fmt.Errorf(VersionInvalid) + } + if !validateAliasName(args.Name) { + return fmt.Errorf(AliasNameInvalid, args.FunctionName) + } + return nil +} + +func (args GetAliasArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if args.AliasName == "" { + return fmt.Errorf(requiredIllegal, "AliasName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if !validateAliasName(args.AliasName) { + return fmt.Errorf(AliasNameInvalid, args.FunctionName) + } + return nil +} + +func (args UpdateAliasArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if args.AliasName == "" { + return fmt.Errorf(requiredIllegal, "AliasName") + } + if args.FunctionVersion == "" { + return fmt.Errorf(requiredIllegal, "FunctionVersion") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if !validateAliasName(args.AliasName) { + return fmt.Errorf(AliasNameInvalid, args.FunctionName) + } + if !validateVersion(args.FunctionVersion) { + return fmt.Errorf(VersionInvalid) + } + return nil +} + +func (args DeleteAliasArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + if args.AliasName == "" { + return fmt.Errorf(requiredIllegal, "AliasName") + } + if !validateFunctionName(args.FunctionName) { + return fmt.Errorf(functionNameInvalid, args.FunctionName) + } + if !validateAliasName(args.AliasName) { + return fmt.Errorf(AliasNameInvalid, args.FunctionName) + } + return nil +} + +func (args ListTriggersArgs) Validate() error { + if args.FunctionBrn == "" { + return fmt.Errorf(requiredIllegal, "FunctionBrn") + } + if !validateFunctionBRN(args.FunctionBrn) { + return fmt.Errorf(functionBRNInvalid, args.FunctionBrn) + } + return nil +} + +func (args CreateTriggerArgs) Validate() error { + if args.Target == "" { + return fmt.Errorf(requiredIllegal, "Target") + } + if args.Source == "" { + return fmt.Errorf(requiredIllegal, "Source") + } + if !validateFunctionBRN(args.Target) { + return fmt.Errorf(functionBRNInvalid, args.Target) + } + + return nil +} + +func (args UpdateTriggerArgs) Validate() error { + if args.RelationId == "" { + return fmt.Errorf(requiredIllegal, "RelationId") + } + if args.Target == "" { + return fmt.Errorf(requiredIllegal, "Target") + } + if args.Source == "" { + return fmt.Errorf(requiredIllegal, "Source") + } + if !validateFunctionBRN(args.Target) { + return fmt.Errorf(functionBRNInvalid, args.Target) + } + + return nil +} + +func (args DeleteTriggerArgs) Validate() error { + if args.RelationId == "" { + return fmt.Errorf(requiredIllegal, "RelationId") + } + if args.Target == "" { + return fmt.Errorf(requiredIllegal, "Target") + } + if args.Source == "" { + return fmt.Errorf(requiredIllegal, "Source") + } + if !validateFunctionBRN(args.Target) { + return fmt.Errorf(functionBRNInvalid, args.Target) + } + return nil +} + +func (args ReservedConcurrentExecutionsArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + + if args.ReservedConcurrentExecutions < 0 || args.ReservedConcurrentExecutions > 90 { + return fmt.Errorf(requiredIllegal, "ReservedConcurrentExecutions") + } + + return nil +} + +func (args DeleteReservedConcurrentExecutionsArgs) Validate() error { + if args.FunctionName == "" { + return fmt.Errorf(requiredIllegal, "FunctionName") + } + + return nil +} diff --git a/services/cfc/client.go b/services/cfc/client.go new file mode 100644 index 00000000..c4b457a5 --- /dev/null +++ b/services/cfc/client.go @@ -0,0 +1,312 @@ +/* + * Copyright 2017 Baidu, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +// client.go - define the client for CFC service + +// Package cfc defines the CFC services of BCE. The supported APIs are all defined in sub-package + +package cfc + +import ( + "errors" + + "github.com/baidubce/bce-sdk-go/auth" + "github.com/baidubce/bce-sdk-go/bce" + "github.com/baidubce/bce-sdk-go/services/cfc/api" +) + +const ( + DEFAULT_SERVICE_DOMAIN = "cfc." + bce.DEFAULT_REGION + ".baidubce.com" +) + +// Client of CFC service is a kind of BceClient, so derived from BceClient +type Client struct { + *bce.BceClient +} + +// NewClient make the CFC service client with default configuration. +// Use `cli.Config.xxx` to access the config or change it to non-default value. +func newClient(ak, sk, token, endpoint string) (*Client, error) { + var credentials *auth.BceCredentials + var err error + if len(ak) == 0 || len(sk) == 0 { + return nil, errors.New("ak sk illegal") + } + if len(token) == 0 { + credentials, err = auth.NewBceCredentials(ak, sk) + } else { + credentials, err = auth.NewSessionBceCredentials(ak, sk, token) + } + if err != nil { + return nil, err + } + if len(endpoint) == 0 { + endpoint = DEFAULT_SERVICE_DOMAIN + } + defaultSignOptions := &auth.SignOptions{ + HeadersToSign: auth.DEFAULT_HEADERS_TO_SIGN, + ExpireSeconds: auth.DEFAULT_EXPIRE_SECONDS} + defaultConf := &bce.BceClientConfiguration{ + Endpoint: endpoint, + Region: bce.DEFAULT_REGION, + UserAgent: bce.DEFAULT_USER_AGENT, + Credentials: credentials, + SignOption: defaultSignOptions, + Retry: bce.DEFAULT_RETRY_POLICY, + ConnectionTimeoutInMillis: bce.DEFAULT_CONNECTION_TIMEOUT_IN_MILLIS} + v1Signer := &auth.BceV1Signer{} + client := &Client{bce.NewBceClient(defaultConf, v1Signer)} + return client, nil +} + +func NewClient(ak, sk, endpoint string) (*Client, error) { + return newClient(ak, sk, "", endpoint) +} + +// Invocations - invocation a cfc function with specific parameters +// +// PARAMS: +// - args: the arguments to invocation cfc function +// RETURNS: +// - *api.InvocationsResult: the result of invocation cfc function +// - error: nil if success otherwise the specific error +func (c *Client) Invocations(args *api.InvocationsArgs) (*api.InvocationsResult, error) { + return api.Invocations(c, args) +} + +// Invoke - invoke a cfc function, the same as Invocations +// +// PARAMS: +// - args: the arguments to invocation cfc function +// RETURNS: +// - *api.InvocationsResult: the result of invocation cfc function +// - error: nil if success otherwise the specific error +func (c *Client) Invoke(args *api.InvocationsArgs) (*api.InvocationsResult, error) { + return api.Invocations(c, args) +} + +// ListFunctions - list all functions with the specific parameters +// +// PARAMS: +// - args: the arguments to list all functions +// RETURNS: +// - *api.ListFunctionsResult: the result of list all functions +// - error: nil if success otherwise the specific error +func (c *Client) ListFunctions(args *api.ListFunctionsArgs) (*api.ListFunctionsResult, error) { + return api.ListFunctions(c, args) +} + +// GetFunction - get a specific cfc function +// +// PARAMS: +// - args: the arguments to get a specific cfc function +// RETURNS: +// - *api.GetFunctionResult: the result of get function +// - error: nil if success otherwise the specific error +func (c *Client) GetFunction(args *api.GetFunctionArgs) (*api.GetFunctionResult, error) { + return api.GetFunction(c, args) +} + +// CreateFunction - create a cfc function with specific parameters +// +// PARAMS: +// - args: the arguments to create a cfc function +// RETURNS: +// - *api.CreateFunctionResult: the result of create a cfc function, it contains function information +// - error: nil if success otherwise the specific error +func (c *Client) CreateFunction(args *api.CreateFunctionArgs) (*api.CreateFunctionResult, error) { + return api.CreateFunction(c, args) +} + +// DeleteFunction - delete a specific cfc function +// +// PARAMS: +// - args: the arguments to delete cfc function +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) DeleteFunction(args *api.DeleteFunctionArgs) error { + return api.DeleteFunction(c, args) +} + +// UpdateFunctionCode - update a cfc function code +// +// PARAMS: +// - args: the arguments to update function code +// RETURNS: +// - *api.UpdateFunctionCodeResult: the result of update function code +// - error: nil if success otherwise the specific error +func (c *Client) UpdateFunctionCode(args *api.UpdateFunctionCodeArgs) (*api.UpdateFunctionCodeResult, error) { + return api.UpdateFunctionCode(c, args) +} + +// GetFunctionConfiguration - get a specific cfc function configuration +// +// PARAMS: +// - args: the arguments to get function configuration +// RETURNS: +// - *api.GetFunctionConfigurationResult: the result of function configuration +// - error: nil if success otherwise the specific error +func (c *Client) GetFunctionConfiguration(args *api.GetFunctionConfigurationArgs) (*api.GetFunctionConfigurationResult, error) { + return api.GetFunctionConfiguration(c, args) +} + +// UpdateFunctionConfiguration - update a specific cfc function configuration +// +// PARAMS: +// - args: the arguments to update cfc function +// RETURNS: +// - *api.UpdateFunctionConfigurationResult: the result of update function configuration +// - error: nil if success otherwise the specific error +func (c *Client) UpdateFunctionConfiguration(args *api.UpdateFunctionConfigurationArgs) (*api.UpdateFunctionConfigurationResult, error) { + return api.UpdateFunctionConfiguration(c, args) +} + +// ListVersionsByFunction - list all versions about a specific cfc function +// +// PARAMS: +// - args: the arguments to list all versions +// RETURNS: +// - *api.ListVersionsByFunctionResult: the result of all versions information +// - error: nil if success otherwise the specific error +func (c *Client) ListVersionsByFunction(args *api.ListVersionsByFunctionArgs) (*api.ListVersionsByFunctionResult, error) { + return api.ListVersionsByFunction(c, args) +} + +// PublishVersion - publish a cfc function as a new version +// +// PARAMS: +// - args: the arguments to publish a version +// RETURNS: +// - *api.PublishVersionResult: the result of publish a function version +// - error: nil if success otherwise the specific error +func (c *Client) PublishVersion(args *api.PublishVersionArgs) (*api.PublishVersionResult, error) { + return api.PublishVersion(c, args) +} + +// ListAliases - list all alias about a specific cfc function with specific parameters +// +// PARAMS: +// - args: the arguments to list all alias +// RETURNS: +// - *api.ListAliasesResult: the result of list all alias +// - error: nil if success otherwise the specific error +func (c *Client) ListAliases(args *api.ListAliasesArgs) (*api.ListAliasesResult, error) { + return api.ListAliases(c, args) +} + +// CreateAlias - create an alias which bind one specific cfc function version +// +// PARAMS: +// - args: the arguments to create an alias +// RETURNS: +// - *api.CreateAliasResult: the result of create alias +// - error: nil if success otherwise the specific error +func (c *Client) CreateAlias(args *api.CreateAliasArgs) (*api.CreateAliasResult, error) { + return api.CreateAlias(c, args) +} + +// GetAlias - get alias information which bind one cfc function +// +// PARAMS: +// - args: the arguments to get an alias +// RETURNS: +// - *api.GetAliasResult: the result of get alias +// - error: nil if success otherwise the specific error +func (c *Client) GetAlias(args *api.GetAliasArgs) (*api.GetAliasResult, error) { + return api.GetAlias(c, args) +} + +// UpdateAlias - update an alias configuration +// +// PARAMS: +// - args: the arguments to update an alias +// RETURNS: +// - *api.UpdateAliasResult: the result of update an alias +// - error: nil if success otherwise the specific error +func (c *Client) UpdateAlias(args *api.UpdateAliasArgs) (*api.UpdateAliasResult, error) { + return api.UpdateAlias(c, args) +} + +// DeleteAlias - delete an alias +// +// PARAMS: +// - args: the arguments to delete an alias +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) DeleteAlias(args *api.DeleteAliasArgs) error { + return api.DeleteAlias(c, args) +} + +// ListTriggers - list all triggers in one cfc function version +// +// PARAMS: +// - args: the arguments to list all triggers +// RETURNS: +// - *api.ListTriggersResult: the result of list all triggers +// - error: nil if success otherwise the specific error +func (c *Client) ListTriggers(args *api.ListTriggersArgs) (*api.ListTriggersResult, error) { + return api.ListTriggers(c, args) +} + +// CreateTrigger - create a specific trigger +// +// PARAMS: +// - args: the arguments to create a trigger +// RETURNS: +// - *api.CreateTriggerResult: the result of create a trigger +// - error: nil if success otherwise the specific error +func (c *Client) CreateTrigger(args *api.CreateTriggerArgs) (*api.CreateTriggerResult, error) { + return api.CreateTrigger(c, args) +} + +// UpdateTrigger - update a trigger +// +// PARAMS: +// - args: the arguments to update a trigger +// RETURNS: +// - *api.UpdateTriggerResult: the result of update a trigger +// - error: nil if success otherwise the specific error +func (c *Client) UpdateTrigger(args *api.UpdateTriggerArgs) (*api.UpdateTriggerResult, error) { + return api.UpdateTrigger(c, args) +} + +// DeleteTrigger - delete a trigger +// +// PARAMS: +// - args: the arguments to delete a trigger +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) DeleteTrigger(args *api.DeleteTriggerArgs) error { + return api.DeleteTrigger(c, args) +} + +// SetReservedConcurrentExecutions - set a cfc function reserved concurrent executions +// +// PARAMS: +// - args: the arguments to set reserved concurrent executions +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) SetReservedConcurrentExecutions(args *api.ReservedConcurrentExecutionsArgs) error { + return api.SetReservedConcurrentExecutions(c, args) +} + +// DeleteReservedConcurrentExecutions - delete one cfc function reserved concurrent executions setting +// +// PARAMS: +// - args: the arguments to delete reserved concurrent executions setting +// RETURNS: +// - error: nil if success otherwise the specific error +func (c *Client) DeleteReservedConcurrentExecutions(args *api.DeleteReservedConcurrentExecutionsArgs) error { + return api.DeleteReservedConcurrentExecutions(c, args) +}