diff --git a/go.mod b/go.mod index 651e8194a9..b800cf6b0b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ require ( github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/go-cleanhttp v0.5.1 github.com/hashicorp/terraform-plugin-sdk v1.0.0 - github.com/huaweicloud/golangsdk v0.0.0-20200214070017-e223495ff90d + github.com/huaweicloud/golangsdk v0.0.0-20200229071744-cde13ac05a94 github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a github.com/mitchellh/go-homedir v1.1.0 github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa // indirect diff --git a/go.sum b/go.sum index 63ad9a6ed0..60be5dd0a9 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,9 @@ github.com/huaweicloud/golangsdk v0.0.0-20191210113552-8f6bd7a6f1d8 h1:7dfGs0ENj github.com/huaweicloud/golangsdk v0.0.0-20191210113552-8f6bd7a6f1d8/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= github.com/huaweicloud/golangsdk v0.0.0-20200204080439-744c2b9d7746 h1:c2HOmXuDF1VSiBdCZAPo6kbOSTt9Kh6jV87mmiegkE0= github.com/huaweicloud/golangsdk v0.0.0-20200204080439-744c2b9d7746/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= -github.com/huaweicloud/golangsdk v0.0.0-20200214070017-e223495ff90d h1:9zNtiJP0i3E6p/Psh4sC3OiRpJyc5oVmvReMgovwqp0= -github.com/huaweicloud/golangsdk v0.0.0-20200214070017-e223495ff90d/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= +github.com/huaweicloud/golangsdk v0.0.0-20200226090834-31e7d87f9e61 h1:cHkhULuZneNT7GRwigfbRM8IXxLH4mNdDEUezszJ3go= +github.com/huaweicloud/golangsdk v0.0.0-20200229071744-cde13ac05a94 h1:3MKOAqfBneQCxf7+GMMql6n+JIvE+rmdgtjoM1IhDWc= +github.com/huaweicloud/golangsdk v0.0.0-20200229071744-cde13ac05a94/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a h1:FyS/ubzBR5xJlnJGRTwe7GUHpJOR4ukYK3y+LFNffuA= github.com/jen20/awspolicyequivalence v0.0.0-20170831201602-3d48364a137a/go.mod h1:uoIMjNxUfXi48Ci40IXkPRbghZ1vbti6v9LCbNqRgHY= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= diff --git a/huaweicloud/config.go b/huaweicloud/config.go index 9e02ec8564..7933a20307 100644 --- a/huaweicloud/config.go +++ b/huaweicloud/config.go @@ -436,6 +436,13 @@ func (c *Config) newObjectStorageClient(region string) (*obs.ObsClient, error) { return obs.New(c.AccessKey, c.SecretKey, client.Endpoint) } +func (c *Config) apiGatewayV1Client(region string) (*golangsdk.ServiceClient, error) { + return huaweisdk.ApiGateWayV1(c.HwClient, golangsdk.EndpointOpts{ + Region: c.determineRegion(region), + Availability: c.getHwEndpointType(), + }) +} + func (c *Config) blockStorageV1Client(region string) (*golangsdk.ServiceClient, error) { return huaweisdk.NewBlockStorageV1(c.HwClient, golangsdk.EndpointOpts{ Region: c.determineRegion(region), diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 0c33a9479d..72b22ad0a3 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -233,6 +233,8 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ + "huaweicloud_api_gateway_group": resourceAPIGatewayGroup(), + "huaweicloud_api_gateway_api": resourceAPIGatewayAPI(), "huaweicloud_blockstorage_volume_v2": resourceBlockStorageVolumeV2(), "huaweicloud_compute_instance_v2": resourceComputeInstanceV2(), "huaweicloud_compute_interface_attach_v2": resourceComputeInterfaceAttachV2(), diff --git a/huaweicloud/resource_huaweicloud_api_gateway_api.go b/huaweicloud/resource_huaweicloud_api_gateway_api.go new file mode 100644 index 0000000000..eed63d1c79 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_api_gateway_api.go @@ -0,0 +1,546 @@ +package huaweicloud + +import ( + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/huaweicloud/golangsdk/openstack/apigw/apis" +) + +func resourceAPIGatewayAPI() *schema.Resource { + return &schema.Resource{ + Create: resourceAPIGatewayAPICreate, + Read: resourceAPIGatewayAPIRead, + Update: resourceAPIGatewayAPIUpdate, + Delete: resourceAPIGatewayAPIDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "visibility": { + Type: schema.TypeInt, + Optional: true, + Default: 2, + }, + "auth_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "APP", "IAM", "NONE", + }, false), + }, + "request_protocol": { + Type: schema.TypeString, + Optional: true, + Default: "HTTPS", + ValidateFunc: validation.StringInSlice([]string{ + "HTTP", "HTTPS", "BOTH", + }, false), + }, + "request_uri": { + Type: schema.TypeString, + Required: true, + }, + "request_method": { + Type: schema.TypeString, + Required: true, + }, + "backend_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "HTTP", "FUNCTION", "MOCK", + }, false), + }, + "http_backend": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "protocol": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "HTTP", "HTTPS", + }, false), + }, + "method": { + Type: schema.TypeString, + Required: true, + }, + "uri": { + Type: schema.TypeString, + Required: true, + }, + "url_domain": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"http_backend.0.vpc_channel"}, + }, + "vpc_channel": { + Type: schema.TypeString, + Optional: true, + }, + "timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 50000, + }, + }, + }, + }, + "mock_backend": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "result_content": { + Type: schema.TypeString, + Optional: true, + }, + "version": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "function_backend": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "function_urn": { + Type: schema.TypeString, + Required: true, + }, + "version": { + Type: schema.TypeString, + Required: true, + }, + "invocation_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "sync", "async", + }, true), + }, + "timeout": { + Type: schema.TypeInt, + Optional: true, + Default: 50000, + }, + }, + }, + }, + "request_parameter": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "location": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Required: true, + }, + "required": { + Type: schema.TypeBool, + Required: true, + }, + "default": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "backend_parameter": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "location": { + Type: schema.TypeString, + Required: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + "type": { + Type: schema.TypeString, + Optional: true, + Default: "Request", + ValidateFunc: validation.StringInSlice([]string{ + "Request", "Constant", "System", + }, false), + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + "tags": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "cors": { + Type: schema.TypeBool, + Optional: true, + ForceNew: false, + }, + "example_success_response": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + }, + "example_failure_response": { + Type: schema.TypeString, + Optional: true, + ForceNew: false, + }, + "group_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceAPIGatewayAPICreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + createOpts, err := buildApiParameter(d) + if err != nil { + return err + } + + log.Printf("[DEBUG] Create API Options: %#v", createOpts) + v, err := apis.Create(apigwClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway api: %s", err) + } + + // Store the ID now + d.SetId(v.Id) + + return resourceAPIGatewayAPIRead(d, meta) +} + +func resourceAPIGatewayAPIRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + v, err := apis.Get(apigwClient, d.Id()).Extract() + if err != nil { + return fmt.Errorf("Error retrieving HuaweiCloud api gateway api: %s", err) + } + + log.Printf("[DEBUG] Retrieved api gateway api %s: %+v", d.Id(), v) + + d.Set("group_id", v.GroupId) + d.Set("group_name", v.GroupName) + d.Set("name", v.Name) + d.Set("description", v.Remark) + d.Set("tags", v.Tags) + d.Set("version", v.Version) + d.Set("visibility", v.Type) + d.Set("auth_type", v.AuthType) + d.Set("request_protocol", v.ReqProtocol) + d.Set("request_method", v.ReqMethod) + d.Set("request_uri", v.ReqUri) + d.Set("backend_type", v.BackendType) + d.Set("example_success_response", v.ResultNormalSample) + d.Set("example_failure_response", v.ResultFailureSample) + d.Set("request_parameter", v.ReqParams) + d.Set("backend_parameter", v.BackendParams) + + backend := make([]map[string]interface{}, 0, 1) + switch v.BackendType { + case "HTTP": + httpInfo := map[string]interface{}{ + "protocol": v.BackendInfo.Protocol, + "method": v.BackendInfo.Method, + "uri": v.BackendInfo.Uri, + "url_domain": v.BackendInfo.UrlDomain, + "vpc_channel": v.BackendInfo.VpcInfo, + "timeout": v.BackendInfo.Timeout, + } + backend = append(backend, httpInfo) + if err := d.Set("http_backend", backend); err != nil { + return fmt.Errorf("failed to save http_backend: %s", err) + } + case "FUNCTION": + functionInfo := map[string]interface{}{ + "function_urn": v.FunctionInfo.FunctionUrn, + "invocation_type": v.FunctionInfo.InvocationType, + "version": v.FunctionInfo.Version, + "timeout": v.FunctionInfo.Timeout, + } + backend = append(backend, functionInfo) + if err := d.Set("function_backend", backend); err != nil { + return fmt.Errorf("failed to save function_backend: %s", err) + } + case "MOCK": + mockInfo := map[string]interface{}{ + "result_content": v.MockInfo.ResultContent, + "version": v.MockInfo.Version, + "description": v.MockInfo.Remark, + } + backend = append(backend, mockInfo) + if err := d.Set("mock_backend", backend); err != nil { + return fmt.Errorf("failed to save mock_backend: %s", err) + } + } + + return nil +} + +func resourceAPIGatewayAPIUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + updateOpts, err := buildApiParameter(d) + if err != nil { + return err + } + + log.Printf("[DEBUG] Update API Options: %#v", updateOpts) + _, err = apis.Update(apigwClient, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating HuaweiCloud api gateway api: %s", err) + } + + return resourceAPIGatewayAPIRead(d, meta) +} + +func resourceAPIGatewayAPIDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + if err := apis.Delete(apigwClient, d.Id()).ExtractErr(); err != nil { + return CheckDeleted(d, err, "api apis") + } + + d.SetId("") + return nil +} + +func buildApiParameter(d *schema.ResourceData) (*apis.CreateOpts, error) { + backendType := d.Get("backend_type").(string) + v := d.Get("tags").(*schema.Set) + apiTags := buildApiTags(v) + + opts := &apis.CreateOpts{ + GroupId: d.Get("group_id").(string), + Name: d.Get("name").(string), + Remark: d.Get("description").(string), + Type: d.Get("visibility").(int), + AuthType: d.Get("auth_type").(string), + ReqProtocol: d.Get("request_protocol").(string), + ReqMethod: d.Get("request_method").(string), + ReqUri: d.Get("request_uri").(string), + BackendType: backendType, + Tags: apiTags, + ResultNormalSample: d.Get("example_success_response").(string), + ResultFailureSample: d.Get("example_failure_response").(string), + } + + switch backendType { + case "HTTP": + httpBackend := buildHttpBackendParam(d) + if httpBackend == nil { + return nil, fmt.Errorf("The argument \"http_backend\" is required under HTTP backend type") + } + opts.BackendOpts = *httpBackend + case "FUNCTION": + funcBackend := buildFunctionBackendParam(d) + if funcBackend == nil { + return nil, fmt.Errorf("The argument \"function_backend\" is required under FUNCTION backend type") + } + opts.FunctionOpts = *funcBackend + case "MOCK": + mockBackend := buildMockBackendParam(d) + if mockBackend == nil { + return nil, fmt.Errorf("The argument \"mock_backend\" is required under MOCK backend type") + } + opts.MockOpts = *mockBackend + } + opts.ReqParams = buildRequestParameters(d) + opts.BackendParams = buildBackendParameters(d) + + return opts, nil +} + +func buildApiTags(v *schema.Set) []string { + var tags []string + for _, v := range v.List() { + tags = append(tags, v.(string)) + } + return tags +} + +func buildHttpBackendParam(d *schema.ResourceData) *apis.BackendOpts { + raw := d.Get("http_backend").([]interface{}) + + if len(raw) == 1 { + httpBackend := &apis.BackendOpts{} + config := raw[0].(map[string]interface{}) + httpBackend.Protocol = config["protocol"].(string) + httpBackend.Method = config["method"].(string) + httpBackend.Uri = config["uri"].(string) + httpBackend.Timeout = config["timeout"].(int) + + if v, ok := config["vpc_channel"]; ok && v.(string) != "" { + httpBackend.VpcStatus = 1 + httpBackend.VpcInfo.VpcId = v.(string) + } else { + httpBackend.VpcStatus = 2 + httpBackend.UrlDomain = config["url_domain"].(string) + } + return httpBackend + } + + return nil +} + +func buildFunctionBackendParam(d *schema.ResourceData) *apis.FunctionOpts { + raw := d.Get("function_backend").([]interface{}) + + if len(raw) == 1 { + funcBackend := &apis.FunctionOpts{} + config := raw[0].(map[string]interface{}) + funcBackend.FunctionUrn = config["function_urn"].(string) + funcBackend.InvocationType = config["invocation_type"].(string) + funcBackend.Version = config["version"].(string) + funcBackend.Timeout = config["timeout"].(int) + return funcBackend + } + + return nil +} + +func buildMockBackendParam(d *schema.ResourceData) *apis.MockOpts { + raw := d.Get("mock_backend").([]interface{}) + + // all parameters of mock_backend are optional + mockBackend := &apis.MockOpts{} + if len(raw) == 1 { + config := raw[0].(map[string]interface{}) + mockBackend.ResultContent = config["result_content"].(string) + mockBackend.Version = config["version"].(string) + mockBackend.Remark = config["description"].(string) + } + + return mockBackend +} + +func buildRequestParameters(d *schema.ResourceData) []apis.RequestParameter { + var requestList []apis.RequestParameter + + rawParams := d.Get("request_parameter").([]interface{}) + for i := range rawParams { + parameter := rawParams[i].(map[string]interface{}) + request := apis.RequestParameter{ + Name: parameter["name"].(string), + Location: parameter["location"].(string), + Type: parameter["type"].(string), + Remark: parameter["description"].(string), + // disable validity check + ValidEnable: 2, + } + if parameter["required"].(bool) { + request.Required = 1 + } else { + request.Required = 2 + // the default value is used when the input parameter was optional + request.DefaultValue = parameter["default"].(string) + } + requestList = append(requestList, request) + } + return requestList +} + +func buildBackendParameters(d *schema.ResourceData) []apis.BackendParameter { + var backendList []apis.BackendParameter + + rawParams := d.Get("backend_parameter").([]interface{}) + for i := range rawParams { + parameter := rawParams[i].(map[string]interface{}) + request := apis.BackendParameter{ + Name: parameter["name"].(string), + Location: parameter["location"].(string), + Origin: parameter["type"].(string), + Value: parameter["value"].(string), + Remark: parameter["description"].(string), + } + + backendList = append(backendList, request) + } + return backendList +} diff --git a/huaweicloud/resource_huaweicloud_api_gateway_api_test.go b/huaweicloud/resource_huaweicloud_api_gateway_api_test.go new file mode 100644 index 0000000000..e5304de656 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_api_gateway_api_test.go @@ -0,0 +1,157 @@ +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/huaweicloud/golangsdk/openstack/apigw/apis" +) + +func TestAccApiGatewayAPI_basic(t *testing.T) { + var resName = "huaweicloud_api_gateway_api.acc_apigw_api" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckApiGatewayApiDestroy, + Steps: []resource.TestStep{ + { + Config: testAccApigwAPI_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckApiGatewayApiExists(resName), + resource.TestCheckResourceAttr(resName, "name", "acc_apigw_api"), + resource.TestCheckResourceAttr(resName, "group_name", "acc_apigw_group_1"), + resource.TestCheckResourceAttr(resName, "auth_type", "NONE"), + resource.TestCheckResourceAttr(resName, "backend_type", "HTTP"), + resource.TestCheckResourceAttr(resName, "request_protocol", "HTTPS"), + resource.TestCheckResourceAttr(resName, "request_method", "GET"), + resource.TestCheckResourceAttr(resName, "request_uri", "/test/path1"), + resource.TestCheckResourceAttr(resName, "http_backend.0.protocol", "HTTPS"), + resource.TestCheckResourceAttr(resName, "http_backend.0.method", "GET"), + resource.TestCheckResourceAttr(resName, "http_backend.0.uri", "/web/openapi"), + resource.TestCheckResourceAttr(resName, "http_backend.0.timeout", "10000"), + ), + }, + { + Config: testAccApigwAPI_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckApiGatewayApiExists(resName), + resource.TestCheckResourceAttr(resName, "description", "updated by acc test"), + resource.TestCheckResourceAttr(resName, "auth_type", "IAM"), + resource.TestCheckResourceAttr(resName, "request_protocol", "BOTH"), + resource.TestCheckResourceAttr(resName, "request_uri", "/test/path2"), + ), + }, + }, + }) +} + +func testAccCheckApiGatewayApiDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + apigwClient, err := config.apiGatewayV1Client(OS_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "huaweicloud_api_gateway_api" { + continue + } + + _, err := apis.Get(apigwClient, rs.Primary.ID).Extract() + if err == nil { + return fmt.Errorf("api gateway API still exists") + } + } + + return nil +} + +func testAccCheckApiGatewayApiExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Resource %s not found", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + apigwClient, err := config.apiGatewayV1Client(OS_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + found, err := apis.Get(apigwClient, rs.Primary.ID).Extract() + if err != nil { + return err + } + + if found.Id != rs.Primary.ID { + return fmt.Errorf("apigateway API not found") + } + + return nil + } +} + +const testAccApigwAPI_basic = ` +resource "huaweicloud_api_gateway_group" "acc_apigw_group" { + name = "acc_apigw_group_1" + description = "created by acc test" +} + +resource "huaweicloud_api_gateway_api" "acc_apigw_api" { + group_id = huaweicloud_api_gateway_group.acc_apigw_group.id + name = "acc_apigw_api" + description = "created by acc test" + tags = ["tag1","tag2"] + visibility = 2 + auth_type = "NONE" + backend_type = "HTTP" + request_protocol = "HTTPS" + request_method = "GET" + request_uri = "/test/path1" + example_success_response = "this is a successful response" + + http_backend { + protocol = "HTTPS" + method = "GET" + uri = "/web/openapi" + url_domain = "myhuaweicloud.com" + timeout = 10000 + } +} +` +const testAccApigwAPI_update = ` +resource "huaweicloud_api_gateway_group" "acc_apigw_group" { + name = "acc_apigw_group_1" + description = "created by acc test" +} + +resource "huaweicloud_api_gateway_api" "acc_apigw_api" { + group_id = huaweicloud_api_gateway_group.acc_apigw_group.id + name = "acc_apigw_api" + description = "updated by acc test" + tags = ["tag1","tag2"] + visibility = 2 + auth_type = "IAM" + backend_type = "HTTP" + request_protocol = "BOTH" + request_method = "GET" + request_uri = "/test/path2" + example_success_response = "this is a successful response" + + http_backend { + protocol = "HTTPS" + method = "GET" + uri = "/web/openapi" + url_domain = "myhuaweicloud.com" + timeout = 10000 + } +} +` diff --git a/huaweicloud/resource_huaweicloud_api_gateway_group.go b/huaweicloud/resource_huaweicloud_api_gateway_group.go new file mode 100644 index 0000000000..45b0530d06 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_api_gateway_group.go @@ -0,0 +1,124 @@ +package huaweicloud + +import ( + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/huaweicloud/golangsdk/openstack/apigw/groups" +) + +func resourceAPIGatewayGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceAPIGatewayGroupCreate, + Read: resourceAPIGatewayGroupRead, + Update: resourceAPIGatewayGroupUpdate, + Delete: resourceAPIGatewayGroupDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: false, + }, + "status": { + Type: schema.TypeInt, + Computed: true, + }, + }, + } +} + +func resourceAPIGatewayGroupCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + createOpts := &groups.CreateOpts{ + Name: d.Get("name").(string), + Remark: d.Get("description").(string), + } + + log.Printf("[DEBUG] Create Options: %#v", createOpts) + v, err := groups.Create(apigwClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api group: %s", err) + } + + // Store the ID now + d.SetId(v.ID) + + return resourceAPIGatewayGroupRead(d, meta) +} + +func resourceAPIGatewayGroupRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + v, err := groups.Get(apigwClient, d.Id()).Extract() + if err != nil { + return fmt.Errorf("Error retrieving HuaweiCloud api group: %s", err) + } + + log.Printf("[DEBUG] Retrieved api group %s: %+v", d.Id(), v) + + d.Set("name", v.Name) + d.Set("description", v.Remark) + d.Set("status", v.Status) + + return nil +} + +func resourceAPIGatewayGroupUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + updateOpts := groups.UpdateOpts{ + Name: d.Get("name").(string), + Remark: d.Get("description").(string), + } + + _, err = groups.Update(apigwClient, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating HuaweiCloud api group: %s", err) + } + + return resourceAPIGatewayGroupRead(d, meta) +} + +func resourceAPIGatewayGroupDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + apigwClient, err := config.apiGatewayV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + if err := groups.Delete(apigwClient, d.Id()).ExtractErr(); err != nil { + return CheckDeleted(d, err, "api groups") + } + + d.SetId("") + return nil +} diff --git a/huaweicloud/resource_huaweicloud_api_gateway_group_test.go b/huaweicloud/resource_huaweicloud_api_gateway_group_test.go new file mode 100644 index 0000000000..e15bca2ae2 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_api_gateway_group_test.go @@ -0,0 +1,106 @@ +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/huaweicloud/golangsdk/openstack/apigw/groups" +) + +func TestAccApiGatewayGroup_basic(t *testing.T) { + var resName = "huaweicloud_api_gateway_group.acc_apigw_group" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckApiGatewayGroupDestroy, + Steps: []resource.TestStep{ + { + Config: testAccApigwGroup_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckApiGatewayGroupExists(resName), + resource.TestCheckResourceAttr( + resName, "name", "acc_apigw_group_1"), + resource.TestCheckResourceAttr( + resName, "description", "created by acc test"), + ), + }, + { + Config: testAccApigwGroup_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckApiGatewayGroupExists(resName), + resource.TestCheckResourceAttr( + resName, "name", "acc_apigw_group_update"), + resource.TestCheckResourceAttr( + resName, "description", "updated by acc test"), + ), + }, + }, + }) +} + +func testAccCheckApiGatewayGroupDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + apigwClient, err := config.apiGatewayV1Client(OS_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "huaweicloud_api_gateway_group" { + continue + } + + _, err := groups.Get(apigwClient, rs.Primary.ID).Extract() + if err == nil { + return fmt.Errorf("api gateway group still exists") + } + } + + return nil +} + +func testAccCheckApiGatewayGroupExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Resource %s not found", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + apigwClient, err := config.apiGatewayV1Client(OS_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud api gateway client: %s", err) + } + + found, err := groups.Get(apigwClient, rs.Primary.ID).Extract() + if err != nil { + return err + } + + if found.ID != rs.Primary.ID { + return fmt.Errorf("apigateway group not found") + } + + return nil + } +} + +const testAccApigwGroup_basic = ` +resource "huaweicloud_api_gateway_group" "acc_apigw_group" { + name = "acc_apigw_group_1" + description = "created by acc test" +} +` +const testAccApigwGroup_update = ` +resource "huaweicloud_api_gateway_group" "acc_apigw_group" { + name = "acc_apigw_group_update" + description = "updated by acc test" +} +` diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/requests.go new file mode 100644 index 0000000000..c1abb75c95 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/requests.go @@ -0,0 +1,128 @@ +package apis + +import ( + "github.com/huaweicloud/golangsdk" +) + +type VpcChannel struct { + VpcId string `json:"vpc_id" required:"true"` + VpcProxyHost string `json:"vpc_proxy_host,omitempty"` +} + +type BackendOpts struct { + Protocol string `json:"req_protocol" required:"true"` + Method string `json:"req_method" required:"true"` + Uri string `json:"req_uri" required:"true"` + Timeout int `json:"timeout" required:"true"` + VpcStatus int `json:"vpc_status,omitempty"` + VpcInfo VpcChannel `json:"vpc_info,omitempty"` + UrlDomain string `json:"url_domain,omitempty"` + Version string `json:"version,omitempty"` + Remark string `json:"remark,omitempty"` + AuthorizerId string `json:"authorizer_id,omitempty"` +} +type FunctionOpts FunctionInfo +type MockOpts MockInfo + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToAPICreateMap() (map[string]interface{}, error) +} + +// CreateOpts contains options for creating a API. This object is passed to +// the APIs Create function. +type CreateOpts struct { + // ID of the API group to which the API to be created will belong + // The value cannot be modified when updating + GroupId string `json:"group_id" required:"true"` + // Name of the API + Name string `json:"name" required:"true"` + // Type of the API. 1: public, 2: private + Type int `json:"type" required:"true"` + // Request method + ReqMethod string `json:"req_method" required:"true"` + // Access address + ReqUri string `json:"req_uri" required:"true"` + // Request protocol, defaults to HTTPS + ReqProtocol string `json:"req_protocol,omitempty"` + // Request parameter list + ReqParams []RequestParameter `json:"req_params,omitempty"` + // Security authentication mode, which can be: None, App and IAM + AuthType string `json:"auth_type" required:"true"` + // backend type, which can be: HTTP, Function and MOCK + BackendType string `json:"backend_type" required:"true"` + // Backend parameter list + BackendParams []BackendParameter `json:"backend_params,omitempty"` + //Web backend details + BackendOpts BackendOpts `json:"backend_api,omitempty"` + // FunctionGraph backend details + FunctionOpts FunctionOpts `json:"func_info,omitempty"` + // Mock backend details + MockOpts MockOpts `json:"mock_info,omitempty"` + // Example response for a successful request + ResultNormalSample string `json:"result_normal_sample" required:"true"` + // Example response for a failed request + ResultFailureSample string `json:"result_failure_sample,omitempty"` + // ID of customer authorizer + AuthorizerId string `json:"authorizer_id,omitempty"` + // Version of the API + Version string `json:"version,omitempty"` + // Route matching mode + MatchMode string `json:"match_mode,omitempty"` + // Description of the API + Remark string `json:"remark,omitempty"` + // tags of the API + Tags []string `json:"tags,omitempty"` + // Description of the API request body + BodyRemark string `json:"body_remark,omitempty"` + // whether CORS is supported + Cors bool `json:"cors,omitempty"` +} + +// ToAPICreateMap assembles a request body based on the contents of a +// CreateOpts. +func (opts CreateOpts) ToAPICreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// Create will create a new API based on the values in CreateOpts. +func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToAPICreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{201}, + }) + return +} + +// Update will update the API with provided information. To extract the updated +// API from the response, call the Extract method on the UpdateResult. +// parameters of update is same with parameters of create. (group_id cannot be modified) +func Update(client *golangsdk.ServiceClient, id string, opts CreateOptsBuilder) (r UpdateResult) { + b, err := opts.ToAPICreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Put(groupURL(client, id), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete will delete the existing API with the provided ID. +func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(groupURL(client, id), nil) + return +} + +// Get retrieves the API with the provided ID. To extract the API object +// from the response, call the Extract method on the GetResult. +func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(groupURL(client, id), &r.Body, nil) + return +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/results.go new file mode 100644 index 0000000000..146a1dc7e1 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/results.go @@ -0,0 +1,147 @@ +package apis + +import ( + "time" + + "github.com/huaweicloud/golangsdk" +) + +type BackendInfo struct { + Protocol string `json:"req_protocol"` + Method string `json:"req_method"` + Uri string `json:"req_uri"` + Timeout int `json:"timeout"` + VpcStatus int `json:"vpc_status"` + VpcInfo string `json:"vpc_info"` + UrlDomain string `json:"url_domain"` + Version string `json:"version"` + Remark string `json:"remark"` +} + +type FunctionInfo struct { + FunctionUrn string `json:"function_urn" required:"true"` + InvocationType string `json:"invocation_type" required:"true"` + Timeout int `json:"timeout" required:"true"` + Version string `json:"version,omitempty"` + Remark string `json:"remark,omitempty"` +} + +type MockInfo struct { + ResultContent string `json:"result_content,omitempty"` + Version string `json:"version,omitempty"` + Remark string `json:"remark,omitempty"` +} + +type BackendParameter struct { + Name string `json:"name" required:"true"` + Location string `json:"location" required:"true"` + Origin string `json:"origin" required:"true"` + Value string `json:"value" required:"true"` + Remark string `json:"remark,omitempty"` +} + +type RequestParameter struct { + Name string `json:"name" required:"true"` + Type string `json:"type" required:"true"` + Location string `json:"location" required:"true"` + Required int `json:"required" required:"true"` + ValidEnable int `json:"valid_enable" required:"true"` + DefaultValue string `json:"default_value,omitempty"` + SampleValue string `json:"sample_value,omitempty"` + Remark string `json:"remark,omitempty"` + Enumerations string `json:"enumerations,omitempty"` + MinNum int `json:"min_num,omitempty"` + MaxNum int `json:"max_num,omitempty"` + MinSize int `json:"min_size,omitempty"` + MaxSize int `json:"max_size,omitempty"` +} + +// ApiInstance contains all the information associated with a API. +type ApiInstance struct { + // ID of the API + Id string `json:"id"` + // Name of the API + Name string `json:"name"` + // ID of the API group to which the API to be created will belong + GroupId string `json:"group_id"` + // Name of the API group + GroupName string `json:"group_name"` + // status of the API + Status int `json:"status"` + // Type of the API. 1: public, 2: private + Type int `json:"type"` + // Version of the API + Version string `json:"version"` + // Request protocol + ReqProtocol string `json:"req_protocol"` + // Request method + ReqMethod string `json:"req_method"` + // Access address + ReqUri string `json:"req_uri"` + // Request parameter list + ReqParams []RequestParameter `json:"req_params"` + // Security authentication mode, which can be: None, App and IAM + AuthType string `json:"auth_type"` + // Route matching mode + MatchMode string `json:"match_mode"` + // backend type, which can be: HTTP, Function and MOCK + BackendType string `json:"backend_type"` + // Backend parameter list + BackendParams []BackendParameter `json:"backend_params"` + //Web backend details + BackendInfo BackendInfo `json:"backend_api"` + // FunctionGraph backend details + FunctionInfo FunctionInfo `json:"func_info"` + // Mock backend details + MockInfo MockInfo `json:"mock_info"` + // Example response for a successful request + ResultNormalSample string `json:"result_normal_sample"` + // Example response for a failed request + ResultFailureSample string `json:"result_failure_sample"` + // Description of the API + Remark string `json:"remark"` + // tags of the API + Tags []string `json:"tags"` + // Description of the API request body + BodyRemark string `json:"body_remark"` + // whether CORS is supported + Cors bool `json:"cors"` + + EnvName string `json:"run_env_name"` + EnvId string `json:"run_env_id"` + PublishId string `json:"publish_id"` + ArrangeNecessary int `json:"arrange_necessary"` + RegisterAt time.Time `json:"-"` + UpdateAt time.Time `json:"-"` +} + +type commonResult struct { + golangsdk.Result +} + +// Extract will get the Group object out of the commonResult object. +func (r commonResult) Extract() (*ApiInstance, error) { + var s ApiInstance + err := r.ExtractInto(&s) + return &s, err +} + +// CreateResult contains the response body and error from a Create request. +type CreateResult struct { + commonResult +} + +// GetResult contains the response body and error from a Get request. +type GetResult struct { + commonResult +} + +// UpdateResult contains the response body and error from an Update request. +type UpdateResult struct { + commonResult +} + +// DeleteResult contains the response body and error from a Delete request. +type DeleteResult struct { + golangsdk.ErrResult +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/urls.go b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/urls.go new file mode 100644 index 0000000000..028c18c5a2 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/apis/urls.go @@ -0,0 +1,11 @@ +package apis + +import "github.com/huaweicloud/golangsdk" + +func createURL(c *golangsdk.ServiceClient) string { + return c.ServiceURL("apis") +} + +func groupURL(c *golangsdk.ServiceClient, id string) string { + return c.ServiceURL("apis", id) +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/requests.go new file mode 100644 index 0000000000..8c81ddbdea --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/requests.go @@ -0,0 +1,86 @@ +package groups + +import ( + "github.com/huaweicloud/golangsdk" +) + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToGroupCreateMap() (map[string]interface{}, error) +} + +// CreateOpts contains options for creating a API group. This object is passed to +// the API groups Create function. +type CreateOpts struct { + // Name of the API group + Name string `json:"name" required:"true"` + // Description of the API group + Remark string `json:"remark,omitempty"` +} + +// ToGroupCreateMap assembles a request body based on the contents of a +// CreateOpts. +func (opts CreateOpts) ToGroupCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// Create will create a new API group based on the values in CreateOpts. +func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToGroupCreateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200, 201}, + }) + return +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToGroupUpdateMap() (map[string]interface{}, error) +} + +// UpdateOpts contain options for updating an existing API group. +type UpdateOpts struct { + // Name of the API group + Name string `json:"name" required:"true"` + // Description of the API group + Remark string `json:"remark,omitempty"` +} + +// ToGroupUpdateMap assembles a request body based on the contents of an +// UpdateOpts. +func (opts UpdateOpts) ToGroupUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// Update will update the API group with provided information. To extract the updated +// API group from the response, call the Extract method on the UpdateResult. +func Update(client *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToGroupUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Put(groupURL(client, id), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete will delete the existing group with the provided ID. +func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(groupURL(client, id), nil) + return +} + +// Get retrieves the group with the provided ID. To extract the Group object +// from the response, call the Extract method on the GetResult. +func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(groupURL(client, id), &r.Body, nil) + return +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/results.go new file mode 100644 index 0000000000..effea54570 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/results.go @@ -0,0 +1,74 @@ +package groups + +import ( + "time" + + "github.com/huaweicloud/golangsdk" +) + +type UrlDomain struct { + ID string `json:"id"` + Domain string `json:"domain"` + CnameStatus int `json:"cname_status"` + SslID string `json:"ssl_id"` + SslName string `json:"ssl_name"` +} + +// Group contains all the information associated with a API group. +type Group struct { + // Unique identifier for the Group. + ID string `json:"id"` + // Human-readable display name for the Group. + Name string `json:"name"` + // Description of the API group. + Remark string `json:"remark"` + // Status of the Group. + Status int `json:"status"` + // Indicates whether the API group has been listed on the marketplace. + OnSellStatus int `json:"on_sell_status"` + // Subdomain name automatically allocated by the system to the API group. + SlDomain string `json:"sl_domain"` + // Total number of times all APIs in the API group can be accessed. + CallLimits int `json:"call_limits"` + // The type of Group to create, either SATA or SSD. + TimeInterval int `json:"time_interval"` + // Time unit for limiting the number of API calls + TimeUnit string `json:"time_unit"` + // List of independent domain names bound to the API group + UrlDomains []UrlDomain `json:"url_domains"` + // Time when the API group is created + RegisterTime time.Time `json:"-"` + // Time when the API group was last modified + UpdateTime time.Time `json:"-"` +} + +type commonResult struct { + golangsdk.Result +} + +// Extract will get the Group object out of the commonResult object. +func (r commonResult) Extract() (*Group, error) { + var s Group + err := r.ExtractInto(&s) + return &s, err +} + +// CreateResult contains the response body and error from a Create request. +type CreateResult struct { + commonResult +} + +// GetResult contains the response body and error from a Get request. +type GetResult struct { + commonResult +} + +// UpdateResult contains the response body and error from an Update request. +type UpdateResult struct { + commonResult +} + +// DeleteResult contains the response body and error from a Delete request. +type DeleteResult struct { + golangsdk.ErrResult +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/urls.go b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/urls.go new file mode 100644 index 0000000000..5ef8a051d9 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/apigw/groups/urls.go @@ -0,0 +1,11 @@ +package groups + +import "github.com/huaweicloud/golangsdk" + +func createURL(c *golangsdk.ServiceClient) string { + return c.ServiceURL("api-groups") +} + +func groupURL(c *golangsdk.ServiceClient, id string) string { + return c.ServiceURL("api-groups", id) +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/client.go b/vendor/github.com/huaweicloud/golangsdk/openstack/client.go index a2033d99bd..45bfc9f516 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/client.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/client.go @@ -576,6 +576,15 @@ func initcommonServiceClient(client *golangsdk.ProviderClient, eo golangsdk.Endp return sc, err } +// TODO: Need to change to apig client type from apig once available +// ApiGateWayV1 creates a service client that is used for Huawei cloud for API gateway. +func ApiGateWayV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "network") + sc.Endpoint = strings.Replace(sc.Endpoint, "vpc", "apig", 1) + sc.ResourceBase = sc.Endpoint + "v1.0/apigw/" + return sc, err +} + // NewObjectStorageV1 creates a ServiceClient that may be used with the v1 // object storage package. func NewObjectStorageV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { @@ -1023,6 +1032,14 @@ func SDRSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golan return sc, err } +// TMSV1 creates a ServiceClient that may be used with the v1 TMS service. +func TMSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "network") + sc.Endpoint = "https://tms.myhuaweicloud.com/v1.0/" + sc.ResourceBase = sc.Endpoint + return sc, err +} + // NewSDRSV1 creates a ServiceClient that may be used to access the SDRS service. func NewSDRSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { sc, err := initClientOpts(client, eo, "sdrs") @@ -1065,3 +1082,10 @@ func NewLTSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*gol sc, err := initcommonServiceClient(client, eo, "lts", "v2.0") return sc, err } + +// NewFGSV2 creates a ServiceClient that may be used with the v2 as +// package. +func NewFGSV2(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "fgsv2") + return sc, err +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go index 65cff82e96..7288186525 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/requests.go @@ -39,6 +39,7 @@ type CreateOpts struct { LogCollection int `json:"log_collection,omitempty"` ComponentList []ComponentOpts `json:"component_list" required:"true"` AddJobs []JobOpts `json:"add_jobs,omitempty"` + BootstrapScripts []ScriptOpts `json:"bootstrap_scripts,omitempty"` } type ComponentOpts struct { @@ -60,6 +61,16 @@ type JobOpts struct { HiveScriptPath string `json:"hive_script_path" required:"true"` } +type ScriptOpts struct { + Name string `json:"name" required:"true"` + Uri string `json:"uri" required:"true"` + Parameters string `json:"parameters,omitempty"` + Nodes []string `json:"nodes" required:"true"` + ActiveMaster bool `json:"active_master,omitempty"` + BeforeComponentStart bool `json:"before_component_start,omitempty"` + FailAction string `json:"fail_action" required:"true"` +} + type CreateOptsBuilder interface { ToClusterCreateMap() (map[string]interface{}, error) } diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go index 63d2daf4e4..7bf5156fea 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/mrs/v1/cluster/results.go @@ -3,55 +3,56 @@ package cluster import "github.com/huaweicloud/golangsdk" type Cluster struct { - Clusterid string `json:"clusterId"` - Clustername string `json:"clusterName"` - Masternodenum string `json:"masterNodeNum"` - Corenodenum string `json:"coreNodeNum"` - Clusterstate string `json:"clusterState"` - Createat string `json:"createAt"` - Updateat string `json:"updateAt"` - Billingtype string `json:"billingType"` - Datacenter string `json:"dataCenter"` - Vpc string `json:"vpc"` - Duration string `json:"duration"` - Fee string `json:"fee"` - Hadoopversion string `json:"hadoopVersion"` - Masternodesize string `json:"masterNodeSize"` - Corenodesize string `json:"coreNodeSize"` - Componentlist []Component `json:"componentList"` - Externalip string `json:"externalIp"` - Externalalternateip string `json:"externalAlternateIp"` - Internalip string `json:"internalIp"` - Deploymentid string `json:"deploymentId"` - Remark string `json:"remark"` - Orderid string `json:"orderId"` - Azid string `json:"azId"` - Masternodeproductid string `json:"masterNodeProductId"` - Masternodespecid string `json:"masterNodeSpecId"` - Corenodeproductid string `json:"coreNodeProductId"` - Corenodespecid string `json:"coreNodeSpecId"` - Azname string `json:"azName"` - Instanceid string `json:"instanceId"` - Vnc string `json:"vnc"` - Tenantid string `json:"tenantId"` - Volumesize int `json:"volumeSize"` - Subnetname string `json:"subnetName"` - Securitygroupsid string `json:"securityGroupsId"` - Slavesecuritygroupsid string `json:"slaveSecurityGroupsId"` - Safemode int `json:"safeMode"` - Clusterversion string `json:"clusterVersion"` - Nodepubliccertname string `json:"nodePublicCertName"` - Masternodeip string `json:"masterNodeIp"` - Privateipfirst string `json:"privateIpFirst"` - Errorinfo string `json:"errorInfo"` - Chargingstarttime string `json:"chargingStartTime"` - LogCollection int `json:"log_collection"` - MasterDataVolumeType string `json:"masterDataVolumeType"` - MasterDataVolumeSize int `json:"masterDataVolumeSize"` - MasterDataVolumeCount int `json:"masterDataVolumeCount"` - CoreDataVolumeType string `json:"coreDataVolumeType"` - CoreDataVolumeSize int `json:"coreDataVolumeSize"` - CoreDataVolumeCount int `json:"coreDataVolumeCount"` + Clusterid string `json:"clusterId"` + Clustername string `json:"clusterName"` + Masternodenum string `json:"masterNodeNum"` + Corenodenum string `json:"coreNodeNum"` + Clusterstate string `json:"clusterState"` + Createat string `json:"createAt"` + Updateat string `json:"updateAt"` + Billingtype string `json:"billingType"` + Datacenter string `json:"dataCenter"` + Vpc string `json:"vpc"` + Duration string `json:"duration"` + Fee string `json:"fee"` + Hadoopversion string `json:"hadoopVersion"` + Masternodesize string `json:"masterNodeSize"` + Corenodesize string `json:"coreNodeSize"` + Componentlist []Component `json:"componentList"` + Externalip string `json:"externalIp"` + Externalalternateip string `json:"externalAlternateIp"` + Internalip string `json:"internalIp"` + Deploymentid string `json:"deploymentId"` + Remark string `json:"remark"` + Orderid string `json:"orderId"` + Azid string `json:"azId"` + Masternodeproductid string `json:"masterNodeProductId"` + Masternodespecid string `json:"masterNodeSpecId"` + Corenodeproductid string `json:"coreNodeProductId"` + Corenodespecid string `json:"coreNodeSpecId"` + Azname string `json:"azName"` + Instanceid string `json:"instanceId"` + Vnc string `json:"vnc"` + Tenantid string `json:"tenantId"` + Volumesize int `json:"volumeSize"` + Subnetname string `json:"subnetName"` + Securitygroupsid string `json:"securityGroupsId"` + Slavesecuritygroupsid string `json:"slaveSecurityGroupsId"` + Safemode int `json:"safeMode"` + Clusterversion string `json:"clusterVersion"` + Nodepubliccertname string `json:"nodePublicCertName"` + Masternodeip string `json:"masterNodeIp"` + Privateipfirst string `json:"privateIpFirst"` + Errorinfo string `json:"errorInfo"` + Chargingstarttime string `json:"chargingStartTime"` + LogCollection int `json:"log_collection"` + MasterDataVolumeType string `json:"masterDataVolumeType"` + MasterDataVolumeSize int `json:"masterDataVolumeSize"` + MasterDataVolumeCount int `json:"masterDataVolumeCount"` + CoreDataVolumeType string `json:"coreDataVolumeType"` + CoreDataVolumeSize int `json:"coreDataVolumeSize"` + CoreDataVolumeCount int `json:"coreDataVolumeCount"` + BootstrapScripts []ScriptOpts `json:"bootstrapScripts"` } type Component struct { diff --git a/vendor/modules.txt b/vendor/modules.txt index bc9c36c336..b2f6cf5c1f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -177,10 +177,12 @@ github.com/hashicorp/terraform-plugin-sdk/internal/svchost github.com/hashicorp/terraform-plugin-sdk/internal/svchost/auth # github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d github.com/hashicorp/yamux -# github.com/huaweicloud/golangsdk v0.0.0-20200214070017-e223495ff90d +# github.com/huaweicloud/golangsdk v0.0.0-20200229071744-cde13ac05a94 github.com/huaweicloud/golangsdk github.com/huaweicloud/golangsdk/openstack github.com/huaweicloud/golangsdk/openstack/antiddos/v1/antiddos +github.com/huaweicloud/golangsdk/openstack/apigw/apis +github.com/huaweicloud/golangsdk/openstack/apigw/groups github.com/huaweicloud/golangsdk/openstack/autoscaling/v1/configurations github.com/huaweicloud/golangsdk/openstack/autoscaling/v1/groups github.com/huaweicloud/golangsdk/openstack/autoscaling/v1/instances diff --git a/website/docs/r/api_gateway_api.html.markdown b/website/docs/r/api_gateway_api.html.markdown new file mode 100644 index 0000000000..235a05a426 --- /dev/null +++ b/website/docs/r/api_gateway_api.html.markdown @@ -0,0 +1,154 @@ +--- +layout: "huaweicloud" +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_api_gateway_api" +sidebar_current: "docs-huaweicloud-resource-api-gateway-api" +description: |- + Provides an API gateway API resource. +--- + +# huaweicloud\_api\_gateway\_api + +Provides an API gateway API resource. + +## Example Usage + +```hcl +resource "huaweicloud_api_gateway_group" "tf_apigw_group" { + name = "tf_apigw_group" + description = "your descpiption" +} + +resource "huaweicloud_api_gateway_api" "tf_apigw_api" { + group_id = huaweicloud_api_gateway_group.tf_apigw_group.id + name = "tf_apigw_api" + description = "your descpiption" + tags = ["tag1","tag2"] + visibility = 2 + auth_type = "IAM" + backend_type = "HTTP" + request_protocol = "HTTPS" + request_method = "GET" + request_uri = "/test/path1" + example_success_response = "example response" + + http_backend { + protocol = "HTTPS" + method = "GET" + uri = "/web/openapi" + url_domain = "myhuaweicloud.com" + timeout = 10000 + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the API. An API name consists of 3–64 characters, + starting with a letter. Only letters, digits, and underscores (_) are allowed. + +* `group_id` - (Required) Specifies the ID of the API group. + Changing this creates a new resource. + +* `description` - (Optional) Specifies the description of the API. + The description cannot exceed 255 characters. + +* `visibility` - (Optional) Specifies whether the API is available to the public. + The value can be 1 (public) and 2 (private). Defaults to 2. + +* `auth_type` - (Required) Specifies the security authentication mode. + The value can be 'App', 'IAM', and 'NONE'. + +* `request_protocol` - (Optional) Specifies the request protocol. The value can be 'HTTP', 'HTTPS', and 'BOTH' + which means the API can be accessed through both 'HTTP' and 'HTTPS'. Defaults to 'HTTPS'. + +* `request_method` - (Required) Specifies the request method, including 'GET','POST','PUT' and etc.. + +* `request_uri` - (Required) Specifies the request path of the API. The value must comply with URI specifications. + +* `backend_type` - (Required) Specifies the service backend type. The value can be: + - 'HTTP': the web service backend + - 'FUNCTION': the FunctionGraph service backend + - 'MOCK': the Mock service backend + +* `http_backend` - (Optional) Specifies the configuration when backend_type selected 'HTTP' (documented below). +* `function_backend` - (Optional) Specifies the configuration when backend_type selected 'FUNCTION' (documented below). +* `mock_backend` - (Optional) Specifies the configuration when backend_type selected 'MOCK' (documented below). + +* `request_parameter` - (Optional) the request parameter list (documented below). +* `backend_parameter` - (Optional) the backend parameter list (documented below). + +* `tags` - (Optional) the tags of API in format of string list. + +* `version` - (Optional) Specifies the version of the API. A maximum of 16 characters are allowed. + +* `cors` - (Optional) Specifies whether CORS is supported or not. + +* `example_success_response` - (Required) Specifies the example response for a successful request. + The length cannot exceed 20,480 characters. + +* `example_failure_response` - (Optional) Specifies the example response for a failed request + The length cannot exceed 20,480 characters. + +The `http_backend` object supports the following: + +* `protocol` - (Required) Specifies the backend request protocol. The value can be 'HTTP' and 'HTTPS'. +* `method` - (Optional) Specifies the backend request method, including 'GET','POST','PUT' and etc.. +* `uri` - (Required) Specifies the backend request path. The value must comply with URI specifications. +* `vpc_channel` - (Optional) Specifies the VPC channel ID. This parameter and `url_domain` are alternative. +* `url_domain` - (Optional) Specifies the backend service address. An endpoint URL is in the format of + "domain name (or IP address):port number", with up to 255 characters. This parameter and `vpc_channel` are alternative. +* `timeout` - (Optional) Timeout duration (in ms) for API Gateway to request for the backend service. Defaults to 50000. + +The `function_backend` object supports the following: + +* `function_urn` - (Required) Specifies the function URN. +* `invocation_type` - (Required) Specifies the invocation mode, which can be 'async' or 'sync'. +* `version` - (Optional) Specifies the function version. +* `timeout` - (Optional) Timeout duration (in ms) for API Gateway to request for FunctionGraph. Defaults to 50000. + +The `mock_backend` object supports the following: + +* `result_content` (Optional) Specifies the return result. +* `version` (Optional) Specifies the version of the Mock backend. +* `description` (Optional) Specifies the description of the Mock backend. The description cannot exceed 255 characters. + +The `request_parameter` object supports the following: + +* `name` - (Required) Specifies the input parameter name. A parameter name consists of 1–32 characters, starting with a letter. + Only letters, digits, periods (.), hyphens (-), and underscores (_) are allowed. +* `location` - (Required) Specifies the input parameter location, which can be 'PATH', 'QUERY' or 'HEADER'. +* `type` - (Required) Specifies the input parameter type, which can be 'STRING' or 'NUMBER'. +* `required` - (Optional) Specifies whether the parameter is mandatory or not. +* `default` - (Optional) Specifies the default value when the parameter is optional. +* `description` - (Optional) Specifies the description of the parameter. The description cannot exceed 255 characters. + +The `backend_parameter` object supports the following: + +* `name` - (Required) Specifies the parameter name. A parameter name consists of 1–32 characters, starting with a letter. + Only letters, digits, periods (.), hyphens (-), and underscores (_) are allowed. +* `location` - (Required) Specifies the parameter location, which can be 'PATH', 'QUERY' or 'HEADER'. +* `type` - (Required) Specifies the parameter type, which can be 'REQUEST', 'CONSTANT', or 'SYSTEM'. +* `value` - (Required) Specifies the parameter value, which is a string of not more than 255 characters. + The value varies depending on the parameter type: + - 'REQUEST': parameter name in `request_parameter` + - 'CONSTANT': real value of the parameter + - 'SYSTEM': gateway parameter name +* `description` - (Optional) Specifies the description of the parameter. The description cannot exceed 255 characters. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the API. +* `group_name` - The name of the API group to which the API belongs. + +## Import + +API can be imported using the `id`, e.g. + +``` +$ terraform import huaweicloud_api_gateway_api.api "774438a28a574ac8a496325d1bf51807" +``` diff --git a/website/docs/r/api_gateway_group.html.markdown b/website/docs/r/api_gateway_group.html.markdown new file mode 100644 index 0000000000..fb2517fc6f --- /dev/null +++ b/website/docs/r/api_gateway_group.html.markdown @@ -0,0 +1,39 @@ +--- +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_api_gateway_group" +sidebar_current: "docs-huaweicloud-resource-api-gateway-group" +description: |- + Provides an API gateway group resource. +--- + +# huaweicloud\_api\_gateway\_group + +Provides an API gateway group resource. + +## Example Usage + +```hcl +resource "huaweicloud_api_gateway_group" "apigw_group" { + name = "apigw_group" + description = "your descpiption" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the API group. An API group name consists of 3–64 characters, + starting with a letter. Only letters, digits, and underscores (_) are allowed. + +* `description` - (Optional) Specifies the description of the API group. + The description cannot exceed 255 characters. + +## Attributes Reference + +The following attributes are exported: + +* `id` - ID of the API group. +* `status` - Status of the API group. +* `name` - See Argument Reference above. +* `description` - See Argument Reference above. \ No newline at end of file diff --git a/website/huaweicloud.erb b/website/huaweicloud.erb index 51136daf0c..7c217c0458 100644 --- a/website/huaweicloud.erb +++ b/website/huaweicloud.erb @@ -130,6 +130,18 @@ +