From 6fc0ad6759de223978af4d537e8e67d03564e0ce Mon Sep 17 00:00:00 2001 From: Jason Zhang Date: Tue, 25 May 2021 11:18:01 +0800 Subject: [PATCH] add resource dms_kafka_instance --- docs/resources/dms_kafka_instance.md | 224 ++++++++ go.mod | 2 +- go.sum | 4 +- huaweicloud/provider.go | 1 + ...resource_huaweicloud_dms_kafka_instance.go | 490 ++++++++++++++++++ ...rce_huaweicloud_dms_kafka_instance_test.go | 279 ++++++++++ .../dms/v2/kafka/instances/requests.go | 261 ++++++++++ .../dms/v2/kafka/instances/results.go | 137 +++++ .../openstack/dms/v2/kafka/instances/urls.go | 30 ++ vendor/modules.txt | 3 +- 10 files changed, 1427 insertions(+), 4 deletions(-) create mode 100644 docs/resources/dms_kafka_instance.md create mode 100644 huaweicloud/resource_huaweicloud_dms_kafka_instance.go create mode 100644 huaweicloud/resource_huaweicloud_dms_kafka_instance_test.go create mode 100644 vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/requests.go create mode 100644 vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/results.go create mode 100644 vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/urls.go diff --git a/docs/resources/dms_kafka_instance.md b/docs/resources/dms_kafka_instance.md new file mode 100644 index 00000000000..2a944bbe4e3 --- /dev/null +++ b/docs/resources/dms_kafka_instance.md @@ -0,0 +1,224 @@ +--- +subcategory: "Distributed Message Service (DMS)" +--- + +# huaweicloud\_dms\_kafka\_instance + +## Example Usage + +### Basic Instance + +```hcl +data "huaweicloud_dms_az" "test" {} + +data "huaweicloud_vpc" "test" { + name = "vpc-default" +} + +data "huaweicloud_vpc_subnet" "test" { + name = "subnet-default" +} + +data "huaweicloud_dms_product" "test" { + engine = "kafka" + instance_type = "cluster" + version = "2.3.0" +} + +resource "huaweicloud_networking_secgroup" "test" { + name = "secgroup_1" + description = "secgroup for kafka" +} + +resource "huaweicloud_dms_kafka_instance" "test" { + name = "instance_1" + description = "kafka test" + access_user = "user" + password = "Kafkatest@123" + vpc_id = data.huaweicloud_vpc.test.id + subnet_id = data.huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.test.id + available_zones = [data.huaweicloud_dms_az.test.id] + product_id = data.huaweicloud_dms_product.test.id + engine_version = data.huaweicloud_dms_product.test.version + specification = data.huaweicloud_dms_product.test.bandwidth + partition_num = data.huaweicloud_dms_product.test.partition_num + storage_space = data.huaweicloud_dms_product.test.storage + storage_spec_code = data.huaweicloud_dms_product.test.storage_spec_code + kafka_manager_user = "kafka-user" + kafka_manager_password = "Kafkatest@123" + + tags = { + key = "value" + owner = "terraform" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional, String, ForceNew) The region in which to create the DMS kafka instance resource. + If omitted, the provider-level region will be used. Changing this creates a new instance resource. + +* `name` - (Required, String) Specifies the name of the DMS kafka instance. An instance name starts with a letter, + consists of 4 to 64 characters, and supports only letters, digits, hyphens (-) and underscores (_). + +* `description` - (Optional, String) Specifies the description of the DMS kafka instance. It is a character + string containing not more than 1024 characters. + +* `engine_version` - (Required, String, ForceNew) Specifies the version of the kafka engine. + Valid values are "1.1.0" and "2.3.0". + Changing this creates a new instance resource. + +* `specification` - (Required, String, ForceNew) Specifies the baseline bandwidth of the DMS kafka instance, + that is, the maximum amount of data transferred per unit time. Unit: byte/s. Options: 100MB, 300MB, 600MB, 1200MB. + Changing this creates a new instance resource. + +* `storage_space` - (Required, Int, ForceNew) Specifies the message storage space. Value range: + - When specification is 100MB: 600–90000 GB + - When specification is 300MB: 1200–90000 GB + - When specification is 600MB: 2400–90000 GB + - When specification is 1200MB: 4800–90000 GB + + Changing this creates a new instance resource. + +* `storage_spec_code` - (Required, String, ForceNew) Specifies the storage I/O specification. Value range: + - When specification is 100MB: dms.physical.storage.high or dms.physical.storage.ultra + - When specification is 300MB: dms.physical.storage.high or dms.physical.storage.ultra + - When specification is 600MB: dms.physical.storage.ultra + - When specification is 1200MB: dms.physical.storage.ultra + + Changing this creates a new instance resource. + +* `partition_num` - (Required, Int, ForceNew) Specifies the maximum number of topics in the DMS kafka instance. + - When specification is 100MB: 300 + - When specification is 300MB: 900 + - When specification is 600MB: 1800 + - When specification is 1200MB: 1800 + + Changing this creates a new instance resource. + +* `access_user` - (Optional, String, ForceNew) Specifies a username. + A username consists of 4 to 64 characters and supports only letters, digits, and hyphens (-). + Changing this creates a new instance resource. + +* `password` - (Optional, String, ForceNew) Specifies the password of the DMS kafka instance. A password + must meet the following complexity requirements: Must be 8 to 32 characters long. + Must contain at least 2 of the following character types: lowercase letters, uppercase + letters, digits, and special characters (`~!@#$%^&*()-_=+\|[{}]:'",<.>/?). + Changing this creates a new instance resource. + +* `vpc_id` - (Required, String, ForceNew) Specifies the ID of a VPC. Changing this creates a new instance resource. + +* `subnet_id` - (Required, String, ForceNew) Specifies the ID of a subnet. + Changing this creates a new instance resource. + +* `security_group_id` - (Required, String) Specifies the ID of a security group. + +* `available_zones` - (Required, List, ForceNew) Specifies the ID of an AZ. The parameter value can not be + left blank or an empty array. For details, see section Querying AZ Information. + Changing this creates a new instance resource. + +* `product_id` - (Required, String, ForceNew) Specifies a product ID. Changing this creates a new instance resource. + +* `kafka_manager_user` - (Required, String, ForceNew) Specifies the username for logging in to the Kafka Manager. + The username consists of 4 to 64 characters and can contain letters, digits, hyphens (-), and underscores (_). + Changing this creates a new instance resource. + +* `kafka_manager_password` - (Required, String, ForceNew) Specifies the password for logging in to the Kafka Manager. + The password must meet the following complexity requirements: Must be 8 to 32 characters long. + Must contain at least 2 of the following character types: lowercase letters, uppercase + letters, digits, and special characters (`~!@#$%^&*()-_=+\|[{}]:'",<.>/?). + Changing this creates a new instance resource. + +* `maintain_begin` - (Optional, String) Specifies the time at which a maintenance time window starts. + Format: HH:mm:ss. + The start time and end time of a maintenance time window must indicate the time segment of + a supported maintenance time window. For details, see section Querying Maintenance Time Windows. + The start time must be set to 22:00, 02:00, 06:00, 10:00, 14:00, or 18:00. + Parameters `maintain_begin` and `maintain_end` must be set in pairs. If parameter `maintain_begin` + is left blank, parameter `maintain_end` is also blank. In this case, the system automatically + allocates the default start time 02:00. + +* `maintain_end` - (Optional, String) Specifies the time at which a maintenance time window ends. + Format: HH:mm:ss. + The start time and end time of a maintenance time window must indicate the time segment of + a supported maintenance time window. For details, see section Querying Maintenance Time Windows. + The end time is four hours later than the start time. For example, if the start time is 22:00, + the end time is 02:00. + Parameters `maintain_begin` and `maintain_end` must be set in pairs. If parameter `maintain_end` + is left blank, parameter `maintain_begin` is also blank. In this case, the system automatically + allocates the default end time 06:00. + +* `public_ip_ids` - (Optional, List, ForceNew) Specifies the IDs of the elastic IP address (EIP) + bound to the DMS kafka instance. The num of IDs needed ranges: + - When specification is 100MB: 3 + - When specification is 300MB: 3 + - When specification is 600MB: 4 + - When specification is 1200MB: 8 + + Changing this creates a new instance resource. + +* `retention_policy` - (Optional, String) Specifies the action to be taken when the memory usage reaches + the disk capacity threshold. Value range: + - `time_base`: Automatically delete the earliest messages. + - `produce_reject`: Stop producing new messages. + +* `connector_enable` - (Optional, Bool, ForceNew) Specifies whether to enable dumping. + Changing this creates a new instance resource. + +* `enable_auto_topic` - (Optional, Bool, ForceNew) Specifies whether to enable automatic topic creation. Value range: + - `true`: enable + - `false`: disable + + If automatic topic creation is enabled, a topic will be automatically created with 3 partitions and 3 replicas + when a message is produced to or consumed from a topic that does not exist. + Changing this creates a new instance resource. + +* `enterprise_project_id` - (Optional, String) Specifies the enterprise project ID of the kafka instance. + +* `tags` - (Optional, Map) The key/value pairs to associate with the DMS kafka instance. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - Specifies a resource ID in UUID format. +* `engine` - Indicates the message engine. +* `used_storage_space` - Indicates the used message storage space. Unit: GB +* `connect_address` - Indicates the IP address of the DMS kafka instance. +* `port` - Indicates the port number of the DMS kafka instance. +* `status` - Indicates the status of the DMS kafka instance. +* `ssl_enable` - Indicates whether the SSL-encrypted access is enabled. +* `enable_publicip` - Indicates whether public access to the DMS kafka instance is enabled. +* `resource_spec_code` - Indicates a resource specifications identifier. +* `type` - Indicates the DMS kafka instance type. +* `user_id` - Indicates a user ID. +* `user_name` - Indicates a username. +* `manegement_connect_address` - Indicates the connection address of the Kafka Manager of a Kafka instance. + +## Import + +DMS kafka instance can be imported using the instance id, e.g. +``` + $ terraform import huaweicloud_dms_kafka_instance.instance_1 8d3c7938-dc47-4937-a30f-c80de381c5e3 +``` +Note that the imported state may not be identical to your resource definition, due to some attrubutes missing from +the API response, security or some other reason. The missing attributes include: +`password`, `kafka_manager_password` and `public_ip_ids`. +It is generally recommended running `terraform plan` after importing a DMS kafka instance. You can then decide if +changes should be applied to the instance, or the resource definition should be updated to align with the instance. +Also you can ignore changes as below. +``` +resource "huaweicloud_dms_kafka_instance" "instance_1" { + ... + + lifecycle { + ignore_changes = [ + password, kafka_manager_password, + ] + } +} +``` diff --git a/go.mod b/go.mod index b299b469c77..9dcd4d48916 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/hashicorp/errwrap v1.0.0 github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/terraform-plugin-sdk v1.16.0 - github.com/huaweicloud/golangsdk v0.0.0-20210524113822-7a55f63ba01a + github.com/huaweicloud/golangsdk v0.0.0-20210525075112-86e5a49ad5c3 github.com/jen20/awspolicyequivalence v1.1.0 github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa // indirect github.com/stretchr/testify v1.4.0 diff --git a/go.sum b/go.sum index d17ec45ef70..1826e884df0 100644 --- a/go.sum +++ b/go.sum @@ -206,8 +206,8 @@ github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/huaweicloud/golangsdk v0.0.0-20210524113822-7a55f63ba01a h1:YOG5x5keo4dVV542nonlxCha9V0UvpNFo+lhmfEbhwg= -github.com/huaweicloud/golangsdk v0.0.0-20210524113822-7a55f63ba01a/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= +github.com/huaweicloud/golangsdk v0.0.0-20210525075112-86e5a49ad5c3 h1:aDlpSCiobIMFZdaiXCe7bu2e7VOyDw2lUeYfNtbTi7I= +github.com/huaweicloud/golangsdk v0.0.0-20210525075112-86e5a49ad5c3/go.mod h1:fcOI5u+0f62JtJd7zkCch/Z57BNC6bhqb32TKuiF4r0= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 52a260f42b3..dab91b102ef 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -396,6 +396,7 @@ func Provider() terraform.ResourceProvider { "huaweicloud_dms_group": resourceDmsGroupsV1(), "huaweicloud_dms_instance": resourceDmsInstancesV1(), "huaweicloud_dms_queue": resourceDmsQueuesV1(), + "huaweicloud_dms_kafka_instance": resourceDmsKafkaInstance(), "huaweicloud_dns_ptrrecord": ResourceDNSPtrRecordV2(), "huaweicloud_dns_recordset": ResourceDNSRecordSetV2(), "huaweicloud_dns_zone": ResourceDNSZoneV2(), diff --git a/huaweicloud/resource_huaweicloud_dms_kafka_instance.go b/huaweicloud/resource_huaweicloud_dms_kafka_instance.go new file mode 100644 index 00000000000..fa32cf85839 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_dms_kafka_instance.go @@ -0,0 +1,490 @@ +package huaweicloud + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/openstack/common/tags" + "github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +func resourceDmsKafkaInstance() *schema.Resource { + return &schema.Resource{ + Create: resourceDmsKafkaInstanceCreate, + Read: resourceDmsKafkaInstanceRead, + Update: resourceDmsKafkaInstanceUpdate, + Delete: resourceDmsKafkaInstanceDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "engine_version": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "specification": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "storage_space": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + "partition_num": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + "access_user": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + RequiredWith: []string{ + "password", + }, + }, + "password": { + Type: schema.TypeString, + Sensitive: true, + Optional: true, + ForceNew: true, + RequiredWith: []string{ + "access_user", + }, + }, + "vpc_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "security_group_id": { + Type: schema.TypeString, + Required: true, + }, + "subnet_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "available_zones": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "product_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "kafka_manager_user": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "kafka_manager_password": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ForceNew: true, + }, + "maintain_begin": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "maintain_end": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "public_ip_ids": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "retention_policy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice([]string{ + "produce_reject", "time_base", + }, false), + }, + "connector_enable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + ForceNew: true, + }, + "enable_auto_topic": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + ForceNew: true, + }, + "storage_spec_code": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "enterprise_project_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "tags": tagsSchema(), + "engine": { + Type: schema.TypeString, + Computed: true, + }, + "enable_public_ip": { + Type: schema.TypeBool, + Computed: true, + }, + "ssl_enable": { + Type: schema.TypeBool, + Computed: true, + }, + "used_storage_space": { + Type: schema.TypeInt, + Computed: true, + }, + "connect_address": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "resource_spec_code": { + Type: schema.TypeString, + Computed: true, + }, + "user_id": { + Type: schema.TypeString, + Computed: true, + }, + "user_name": { + Type: schema.TypeString, + Computed: true, + }, + "manegement_connect_address": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceDmsKafkaPublicIpIDs(d *schema.ResourceData) (string, error) { + specification := d.Get("specification").(string) + publicIpIDsRaw := d.Get("public_ip_ids").([]interface{}) + + if specification == "100MB" && len(publicIpIDsRaw) != 3 { + return "", fmt.Errorf("error creating HuaweiCloud DMS kafka instance: "+ + "3 public ip IDs needed when specification is set to 100MB, but got %d", len(publicIpIDsRaw)) + } + if specification == "300MB" && len(publicIpIDsRaw) != 3 { + return "", fmt.Errorf("error creating HuaweiCloud DMS kafka instance: "+ + "3 public ip IDs needed when specification is set to 300MB, but got %d", len(publicIpIDsRaw)) + } + if specification == "600MB" && len(publicIpIDsRaw) != 4 { + return "", fmt.Errorf("error creating HuaweiCloud DMS kafka instance: "+ + "4 public ip IDs needed when specification is set to 600MB, but got %d", len(publicIpIDsRaw)) + } + if specification == "1200MB" && len(publicIpIDsRaw) != 8 { + return "", fmt.Errorf("error creating HuaweiCloud DMS kafka instance: "+ + "8 public ip IDs needed when specification is set to 1200MB, but got %d", len(publicIpIDsRaw)) + } + publicIpIDs := make([]string, 0, len(publicIpIDsRaw)) + for _, v := range publicIpIDsRaw { + publicIpIDs = append(publicIpIDs, v.(string)) + } + return strings.Join(publicIpIDs, ","), nil +} + +func resourceDmsKafkaInstanceCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*config.Config) + dmsV2Client, err := config.DmsV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("error creating HuaweiCloud dms instance client: %s", err) + } + + ssl_enable := false + if d.Get("access_user").(string) != "" && d.Get("password").(string) != "" { + ssl_enable = true + } + createOpts := &instances.CreateOps{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Engine: "kafka", + EngineVersion: d.Get("engine_version").(string), + Specification: d.Get("specification").(string), + StorageSpace: d.Get("storage_space").(int), + PartitionNum: d.Get("partition_num").(int), + AccessUser: d.Get("access_user").(string), + VPCID: d.Get("vpc_id").(string), + SecurityGroupID: d.Get("security_group_id").(string), + SubnetID: d.Get("subnet_id").(string), + AvailableZones: getAllAvailableZones(d), + ProductID: d.Get("product_id").(string), + KafkaManagerUser: d.Get("kafka_manager_user").(string), + MaintainBegin: d.Get("maintain_begin").(string), + MaintainEnd: d.Get("maintain_end").(string), + SslEnable: ssl_enable, + RetentionPolicy: d.Get("retention_policy").(string), + ConnectorEnalbe: d.Get("connector_enable").(bool), + EnableAutoTopic: d.Get("enable_auto_topic").(bool), + StorageSpecCode: d.Get("storage_spec_code").(string), + EnterpriseProjectID: GetEnterpriseProjectID(d, config), + } + + if _, ok := d.GetOk("public_ip_ids"); ok { + publicIpIDs, err := resourceDmsKafkaPublicIpIDs(d) + if err != nil { + return err + } + createOpts.EnablePublicIP = true + createOpts.PublicIpID = publicIpIDs + } + + //set tags + tagRaw := d.Get("tags").(map[string]interface{}) + if len(tagRaw) > 0 { + taglist := utils.ExpandResourceTags(tagRaw) + createOpts.Tags = taglist + } + + log.Printf("[DEBUG] Create Options: %#v", createOpts) + // Add password here so it wouldn't go in the above log entry + createOpts.Password = d.Get("password").(string) + createOpts.KafkaManagerPassword = d.Get("kafka_manager_password").(string) + + v, err := instances.Create(dmsV2Client, createOpts).Extract() + if err != nil { + return fmt.Errorf("error creating HuaweiCloud dms kafka instance: %s", err) + } + log.Printf("[INFO] instance ID: %s", v.InstanceID) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"CREATING"}, + Target: []string{"RUNNING"}, + Refresh: DmsKafkaInstanceStateRefreshFunc(dmsV2Client, v.InstanceID), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 300 * time.Second, + MinTimeout: 3 * time.Second, + PollInterval: 10 * time.Second, + } + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf( + "error waiting for instance (%s) to become ready: %s", + v.InstanceID, err) + } + + // Store the instance ID now + d.SetId(v.InstanceID) + + return resourceDmsKafkaInstanceRead(d, meta) +} + +func resourceDmsKafkaInstanceRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*config.Config) + + dmsV2Client, err := config.DmsV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("error creating HuaweiCloud dms instance client: %s", err) + } + v, err := instances.Get(dmsV2Client, d.Id()).Extract() + if err != nil { + return CheckDeleted(d, err, "DMS instance") + } + + log.Printf("[DEBUG] Dms kafka instance %s: %+v", d.Id(), v) + + d.SetId(v.InstanceID) + d.Set("region", GetRegion(d, config)) + d.Set("name", v.Name) + d.Set("description", v.Description) + d.Set("engine", v.Engine) + d.Set("engine_version", v.EngineVersion) + d.Set("specification", v.Specification) + // storage_space indicates total_storage_space while creating + // set value of total_storage_space to storage_space to keep consistent + d.Set("storage_space", v.TotalStorageSpace) + + partitionNum, _ := convertToInt(v.PartitionNum) + d.Set("partition_num", partitionNum) + + d.Set("vpc_id", v.VPCID) + d.Set("security_group_id", v.SecurityGroupID) + d.Set("subnet_id", v.SubnetID) + d.Set("available_zones", v.AvailableZones) + d.Set("product_id", v.ProductID) + d.Set("kafka_manager_user", v.KafkaManagerUser) + d.Set("maintain_begin", v.MaintainBegin) + d.Set("maintain_end", v.MaintainEnd) + d.Set("enable_public_ip", v.EnablePublicIP) + d.Set("ssl_enable", v.SslEnable) + d.Set("retention_policy", v.RetentionPolicy) + d.Set("connector_enable", v.ConnectorEnalbe) + d.Set("enable_auto_topic", v.EnableAutoTopic) + d.Set("storage_spec_code", v.StorageSpecCode) + d.Set("enterprise_project_id", v.EnterpriseProjectID) + d.Set("used_storage_space", v.UsedStorageSpace) + d.Set("connect_address", v.ConnectAddress) + d.Set("port", v.Port) + d.Set("status", v.Status) + d.Set("resource_spec_code", v.ResourceSpecCode) + d.Set("user_id", v.UserID) + d.Set("user_name", v.UserName) + d.Set("manegement_connect_address", v.ManagementConnectAddress) + d.Set("type", v.Type) + d.Set("access_user", v.AccessUser) + + // set tags + engine := "kafka" + if resourceTags, err := tags.Get(dmsV2Client, engine, d.Id()).Extract(); err == nil { + tagmap := utils.TagsToMap(resourceTags.Tags) + if err := d.Set("tags", tagmap); err != nil { + return fmt.Errorf("error saving tags to state for dms kafka instance (%s): %s", d.Id(), err) + } + } else { + log.Printf("[WARN] error fetching tags of dms kafka instance (%s): %s", d.Id(), err) + } + + return nil +} + +func resourceDmsKafkaInstanceUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*config.Config) + dmsV2Client, err := config.DmsV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("error creating HuaweiCloud dms instance client: %s", err) + } + + //lintignore:R019 + if d.HasChanges("name", "description", "maintain_begin", "maintain_end", + "security_group_id", "retention_policy", "enterprise_project_id") { + description := d.Get("description").(string) + updateOpts := instances.UpdateOpts{ + Name: d.Get("name").(string), + Description: &description, + MaintainBegin: d.Get("maintain_begin").(string), + MaintainEnd: d.Get("maintain_end").(string), + SecurityGroupID: d.Get("security_group_id").(string), + RetentionPolicy: d.Get("retention_policy").(string), + EnterpriseProjectID: d.Get("enterprise_project_id").(string), + } + + err = instances.Update(dmsV2Client, d.Id(), updateOpts).Err + if err != nil { + return fmt.Errorf("error updating HuaweiCloud Dms kafka Instance: %s", err) + } + } + + if d.HasChange("tags") { + // update tags + engine := "kafka" + tagErr := utils.UpdateResourceTags(dmsV2Client, d, engine, d.Id()) + if tagErr != nil { + return fmt.Errorf("error updating tags of dms kafka instance:%s, err:%s", d.Id(), tagErr) + } + } + + return resourceDmsKafkaInstanceRead(d, meta) +} + +func resourceDmsKafkaInstanceDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*config.Config) + dmsV2Client, err := config.DmsV2Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("error creating HuaweiCloud dms instance client: %s", err) + } + + _, err = instances.Get(dmsV2Client, d.Id()).Extract() + if err != nil { + return CheckDeleted(d, err, "instance") + } + + err = instances.Delete(dmsV2Client, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("error deleting HuaweiCloud instance: %s", err) + } + + // Wait for the instance to delete before moving on. + log.Printf("[DEBUG] Waiting for instance (%s) to delete", d.Id()) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"DELETING", "RUNNING"}, + Target: []string{"DELETED"}, + Refresh: DmsKafkaInstanceStateRefreshFunc(dmsV2Client, d.Id()), + Timeout: d.Timeout(schema.TimeoutDelete), + Delay: 90 * time.Second, + MinTimeout: 3 * time.Second, + PollInterval: 10 * time.Second, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf( + "error waiting for instance (%s) to delete: %s", + d.Id(), err) + } + + log.Printf("[DEBUG] Dms instance %s deactivated", d.Id()) + d.SetId("") + return nil +} + +func DmsKafkaInstanceStateRefreshFunc(client *golangsdk.ServiceClient, instanceID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + v, err := instances.Get(client, instanceID).Extract() + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + return v, "DELETED", nil + } + return nil, "", err + } + + return v, v.Status, nil + } +} diff --git a/huaweicloud/resource_huaweicloud_dms_kafka_instance_test.go b/huaweicloud/resource_huaweicloud_dms_kafka_instance_test.go new file mode 100644 index 00000000000..f70f476b929 --- /dev/null +++ b/huaweicloud/resource_huaweicloud_dms_kafka_instance_test.go @@ -0,0 +1,279 @@ +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" +) + +func TestAccDmsKafkaInstances_basic(t *testing.T) { + var instance instances.Instance + rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) + updateName := rName + "update" + resourceName := "huaweicloud_dms_kafka_instance.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDmsKafkaInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDmsKafkaInstance_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDmsKafkaInstanceExists(resourceName, instance), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "engine", "kafka"), + resource.TestCheckResourceAttr(resourceName, "tags.key", "value"), + resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "password", + "kafka_manager_password", + }, + }, + { + Config: testAccDmsKafkaInstance_update(rName, updateName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDmsKafkaInstanceExists(resourceName, instance), + resource.TestCheckResourceAttr(resourceName, "name", updateName), + resource.TestCheckResourceAttr(resourceName, "description", "kafka test update"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value"), + resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform_update"), + ), + }, + }, + }) +} + +func TestAccDmsKafkaInstances_withEpsId(t *testing.T) { + var instance instances.Instance + rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandString(5)) + resourceName := "huaweicloud_dms_kafka_instance.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckEpsID(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDmsKafkaInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDmsKafkaInstance_withEpsId(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckDmsKafkaInstanceExists(resourceName, instance), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "engine", "kafka"), + resource.TestCheckResourceAttr(resourceName, "tags.key", "value"), + resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform"), + resource.TestCheckResourceAttr(resourceName, "enterprise_project_id", HW_ENTERPRISE_PROJECT_ID_TEST), + ), + }, + }, + }) +} + +func testAccCheckDmsKafkaInstanceDestroy(s *terraform.State) error { + config := testAccProvider.Meta().(*config.Config) + dmsClient, err := config.DmsV2Client(HW_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud dms instance client: %s", err) + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "huaweicloud_dms_kafka_instance" { + continue + } + + _, err := instances.Get(dmsClient, rs.Primary.ID).Extract() + if err == nil { + return fmt.Errorf("The Dms kafka instance still exists.") + } + } + return nil +} + +func testAccCheckDmsKafkaInstanceExists(n string, instance instances.Instance) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*config.Config) + dmsClient, err := config.DmsV2Client(HW_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating HuaweiCloud dms instance client: %s", err) + } + + v, err := instances.Get(dmsClient, rs.Primary.ID).Extract() + if err != nil { + return fmt.Errorf("Error getting HuaweiCloud dms kafka instance: %s, err: %s", rs.Primary.ID, err) + } + + if v.InstanceID != rs.Primary.ID { + return fmt.Errorf("The Dms kafka instance not found.") + } + instance = *v + return nil + } +} + +func testAccDmsKafkaInstance_basic(rName string) string { + return fmt.Sprintf(` +data "huaweicloud_dms_az" "test" {} + +data "huaweicloud_vpc" "test" { + name = "vpc-default" +} + +data "huaweicloud_vpc_subnet" "test" { + name = "subnet-default" +} + +data "huaweicloud_dms_product" "test" { + engine = "kafka" + instance_type = "cluster" + version = "2.3.0" +} + +resource "huaweicloud_networking_secgroup" "test" { + name = "%s" + description = "secgroup for kafka" +} + +resource "huaweicloud_dms_kafka_instance" "test" { + name = "%s" + description = "kafka test" + access_user = "user" + password = "Kafkatest@123" + vpc_id = data.huaweicloud_vpc.test.id + subnet_id = data.huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.test.id + available_zones = [data.huaweicloud_dms_az.test.id] + product_id = data.huaweicloud_dms_product.test.id + engine_version = data.huaweicloud_dms_product.test.version + specification = data.huaweicloud_dms_product.test.bandwidth + partition_num = data.huaweicloud_dms_product.test.partition_num + storage_space = data.huaweicloud_dms_product.test.storage + storage_spec_code = data.huaweicloud_dms_product.test.storage_spec_code + kafka_manager_user = "kafka-user" + kafka_manager_password = "Kafkatest@123" + + tags = { + key = "value" + owner = "terraform" + } +} +`, rName, rName) +} + +func testAccDmsKafkaInstance_update(rName, updateName string) string { + return fmt.Sprintf(` +data "huaweicloud_dms_az" "test" {} + +data "huaweicloud_vpc" "test" { + name = "vpc-default" +} + +data "huaweicloud_vpc_subnet" "test" { + name = "subnet-default" +} + +data "huaweicloud_dms_product" "test" { + engine = "kafka" + instance_type = "cluster" + version = "2.3.0" +} + +resource "huaweicloud_networking_secgroup" "test" { + name = "%s" + description = "secgroup for kafka" +} + +resource "huaweicloud_dms_kafka_instance" "test" { + name = "%s" + description = "kafka test update" + access_user = "user" + password = "Kafkatest@123" + vpc_id = data.huaweicloud_vpc.test.id + subnet_id = data.huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.test.id + available_zones = [data.huaweicloud_dms_az.test.id] + product_id = data.huaweicloud_dms_product.test.id + engine_version = data.huaweicloud_dms_product.test.version + specification = data.huaweicloud_dms_product.test.bandwidth + partition_num = data.huaweicloud_dms_product.test.partition_num + storage_space = data.huaweicloud_dms_product.test.storage + storage_spec_code = data.huaweicloud_dms_product.test.storage_spec_code + kafka_manager_user = "kafka-user" + kafka_manager_password = "Kafkatest@123" + + tags = { + key1 = "value" + owner = "terraform_update" + } +} +`, rName, updateName) +} + +func testAccDmsKafkaInstance_withEpsId(rName string) string { + return fmt.Sprintf(` +data "huaweicloud_dms_az" "test" {} + +data "huaweicloud_vpc" "test" { + name = "vpc-default" +} + +data "huaweicloud_vpc_subnet" "test" { + name = "subnet-default" +} + +data "huaweicloud_dms_product" "test" { + engine = "kafka" + instance_type = "cluster" + version = "2.3.0" +} + +resource "huaweicloud_networking_secgroup" "test" { + name = "%s" + description = "secgroup for kafka" +} + +resource "huaweicloud_dms_kafka_instance" "test" { + name = "%s" + description = "kafka test" + access_user = "user" + password = "Kafkatest@123" + vpc_id = data.huaweicloud_vpc.test.id + subnet_id = data.huaweicloud_vpc_subnet.test.id + security_group_id = huaweicloud_networking_secgroup.test.id + available_zones = [data.huaweicloud_dms_az.test.id] + product_id = data.huaweicloud_dms_product.test.id + engine_version = data.huaweicloud_dms_product.test.version + specification = data.huaweicloud_dms_product.test.bandwidth + partition_num = data.huaweicloud_dms_product.test.partition_num + storage_space = data.huaweicloud_dms_product.test.storage + storage_spec_code = data.huaweicloud_dms_product.test.storage_spec_code + kafka_manager_user = "kafka-user" + kafka_manager_password = "Kafkatest@123" + enterprise_project_id = "%s" + + tags = { + key = "value" + owner = "terraform" + } +} +`, rName, rName, HW_ENTERPRISE_PROJECT_ID_TEST) +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/requests.go new file mode 100644 index 00000000000..bcf44ab9242 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/requests.go @@ -0,0 +1,261 @@ +package instances + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/openstack/common/tags" + "github.com/huaweicloud/golangsdk/pagination" +) + +// CreateOpsBuilder is used for creating instance parameters. +// any struct providing the parameters should implement this interface +type CreateOpsBuilder interface { + ToInstanceCreateMap() (map[string]interface{}, error) +} + +// CreateOps is a struct that contains all the parameters. +type CreateOps struct { + // Indicates the name of an instance. + // An instance name starts with a letter, + // consists of 4 to 64 characters, and supports + // only letters, digits, hyphens (-), and underscores (_). + Name string `json:"name" required:"true"` + + // Indicates the description of an instance. + // It is a character string containing not more than 1024 characters. + Description string `json:"description,omitempty"` + + // Indicates a message engine. + Engine string `json:"engine" required:"true"` + + // Indicates the version of a message engine. + EngineVersion string `json:"engine_version" required:"true"` + + //Indicates the baseline bandwidth of a Kafka instance, that is, + //the maximum amount of data transferred per unit time. Unit: byte/s. + Specification string `json:"specification" required:"true"` + + // Indicates the message storage space. + StorageSpace int `json:"storage_space" required:"true"` + + //Indicates the maximum number of topics in a Kafka instance. + PartitionNum int `json:"partition_num" required:"true"` + + // Indicates a username. + // A username consists of 1 to 64 characters + // and supports only letters, digits, and hyphens (-). + AccessUser string `json:"access_user,omitempty"` + + // Indicates the password of an instance. + // An instance password must meet the following complexity requirements: + // Must be 6 to 32 characters long. + // Must contain at least two of the following character types: + // Lowercase letters + // Uppercase letters + // Digits + // Special characters (`~!@#$%^&*()-_=+\|[{}]:'",<.>/?) + Password string `json:"password,omitempty"` + + // Indicates the ID of a VPC. + VPCID string `json:"vpc_id" required:"true"` + + // Indicates the ID of a security group. + SecurityGroupID string `json:"security_group_id" required:"true"` + + // Indicates the ID of a subnet. + SubnetID string `json:"subnet_id" required:"true"` + + // Indicates the ID of an AZ. + // The parameter value can be left blank or an empty array. + AvailableZones []string `json:"available_zones" required:"true"` + + // Indicates a product ID. + ProductID string `json:"product_id" required:"true"` + + // Indicates the username for logging in to the Kafka Manager. + // The username consists of 4 to 64 characters and can contain + //letters, digits, hyphens (-), and underscores (_). + KafkaManagerUser string `json:"kafka_manager_user" required:"true"` + + // Indicates the password for logging in to the Kafka Manager. + // The password must meet the following complexity requirements: + // Must be a string consisting of 8 to 32 characters. + // Contains at least three of the following characters: + // Lowercase letters + // Uppercase letters + // Digits + // Special characters `~!@#$%^&*()-_=+\|[{}];:',<.>/? + KafkaManagerPassword string `json:"kafka_manager_password" required:"true"` + + // Indicates the time at which a maintenance time window starts. + // Format: HH:mm:ss + MaintainBegin string `json:"maintain_begin,omitempty"` + + // Indicates the time at which a maintenance time window ends. + // Format: HH:mm:ss + MaintainEnd string `json:"maintain_end,omitempty"` + + // Indicates whether to open the public network access function. Default to false. + EnablePublicIP bool `json:"enable_publicip,omitempty"` + + // Indicates the bandwidth of the public network. + PublicBandWidth int `json:"public_bandwidth,omitempty"` + + // Indicates the ID of the Elastic IP address bound to the instance. + PublicIpID string `json:"publicip_id,omitempty"` + + // Indicates whether to enable SSL-encrypted access. + SslEnable bool `json:"ssl_enable,omitempty"` + + // Indicates the action to be taken when the memory usage reaches the disk capacity threshold. Options: + // time_base: Automatically delete the earliest messages. + // produce_reject: Stop producing new messages. + RetentionPolicy string `json:"retention_policy,omitempty"` + + // Indicates whether to enable dumping. + ConnectorEnalbe bool `json:"connector_enable,omitempty"` + + // Indicates whether to enable automatic topic creation. + EnableAutoTopic bool `json:"enable_auto_topic,omitempty"` + + //Indicates the storage I/O specification. For details on how to select a disk type + StorageSpecCode string `json:"storage_spec_code,omitempty"` + + // Indicates the enterprise project ID. + EnterpriseProjectID string `json:"enterprise_project_id,omitempty"` + + // Indicates the tags of the instance + Tags []tags.ResourceTag `json:"tags,omitempty"` +} + +// ToInstanceCreateMap is used for type convert +func (ops CreateOps) ToInstanceCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(ops, "") +} + +// Create an instance with given parameters. +func Create(client *golangsdk.ServiceClient, ops CreateOpsBuilder) (r CreateResult) { + b, err := ops.ToInstanceCreateMap() + if err != nil { + r.Err = err + return + } + + _, r.Err = client.Post(createURL(client), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + return +} + +// Delete an instance by id +func Delete(client *golangsdk.ServiceClient, id string) (r DeleteResult) { + _, r.Err = client.Delete(deleteURL(client, id), &golangsdk.RequestOpts{ + OkCodes: []int{204}, + }) + return +} + +//UpdateOptsBuilder is an interface which can build the map paramter of update function +type UpdateOptsBuilder interface { + ToInstanceUpdateMap() (map[string]interface{}, error) +} + +//UpdateOpts is a struct which represents the parameters of update function +type UpdateOpts struct { + // Indicates the name of an instance. + // An instance name starts with a letter, + // consists of 4 to 64 characters, + // and supports only letters, digits, and hyphens (-). + Name string `json:"name,omitempty"` + + // Indicates the description of an instance. + // It is a character string containing not more than 1024 characters. + Description *string `json:"description,omitempty"` + + // Indicates the time at which a maintenance time window starts. + // Format: HH:mm:ss + MaintainBegin string `json:"maintain_begin,omitempty"` + + // Indicates the time at which a maintenance time window ends. + // Format: HH:mm:ss + MaintainEnd string `json:"maintain_end,omitempty"` + + // Indicates the ID of a security group. + SecurityGroupID string `json:"security_group_id,omitempty"` + + // Indicates the action to be taken when the memory usage reaches the disk capacity threshold. Options: + // time_base: Automatically delete the earliest messages. + // produce_reject: Stop producing new messages. + RetentionPolicy string `json:"retention_policy,omitempty"` + + // Indicates the enterprise project ID. + EnterpriseProjectID string `json:"enterprise_project_id,omitempty"` +} + +// ToInstanceUpdateMap is used for type convert +func (opts UpdateOpts) ToInstanceUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// Update is a method which can be able to update the instance +// via accessing to the service with Put method and parameters +func Update(client *golangsdk.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { + body, err := opts.ToInstanceUpdateMap() + if err != nil { + r.Err = err + return + } + + _, r.Err = client.Put(updateURL(client, id), body, nil, &golangsdk.RequestOpts{ + OkCodes: []int{204}, + }) + return +} + +// Get a instance with detailed information by id +func Get(client *golangsdk.ServiceClient, id string) (r GetResult) { + _, r.Err = client.Get(getURL(client, id), &r.Body, nil) + return +} + +type ListOpts struct { + InstanceId string `q:"instance_id"` + Name string `q:"name"` + Engine string `q:"engine"` + Status string `q:"status"` + IncludeFailure string `q:"include_failure"` + ExactMatchName string `q:"exact_match_name"` + EnterpriseProjectID string `q:"enterprise_project_id"` +} + +type ListOpsBuilder interface { + ToListDetailQuery() (string, error) +} + +func (opts ListOpts) ToListDetailQuery() (string, error) { + q, err := golangsdk.BuildQueryString(opts) + if err != nil { + return "", err + } + return q.String(), err +} + +func List(client *golangsdk.ServiceClient, opts ListOpsBuilder) pagination.Pager { + url := listURL(client) + if opts != nil { + query, err := opts.ToListDetailQuery() + + if err != nil { + return pagination.Pager{Err: err} + } + url += query + } + + pageList := pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page { + return Page{pagination.SinglePageBase(r)} + }) + + header := map[string]string{"Content-Type": "application/json"} + pageList.Headers = header + return pageList +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/results.go new file mode 100644 index 00000000000..5560af43279 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/results.go @@ -0,0 +1,137 @@ +package instances + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/openstack/common/tags" + "github.com/huaweicloud/golangsdk/pagination" +) + +// InstanceCreate response +type InstanceCreate struct { + InstanceID string `json:"instance_id"` +} + +// CreateResult is a struct that contains all the return parameters of creation +type CreateResult struct { + golangsdk.Result +} + +// Extract from CreateResult +func (r CreateResult) Extract() (*InstanceCreate, error) { + var s InstanceCreate + err := r.Result.ExtractInto(&s) + return &s, err +} + +// DeleteResult is a struct which contains the result of deletion +type DeleteResult struct { + golangsdk.ErrResult +} + +type ListResponse struct { + Instances []Instance `json:"instances"` + TotalCount int `json:"instance_num"` +} + +// Instance response +type Instance struct { + Name string `json:"name"` + Description string `json:"description"` + Engine string `json:"engine"` + EngineVersion string `json:"engine_version"` + Specification string `json:"specification"` + StorageSpace int `json:"storage_space"` + PartitionNum string `json:"partition_num"` + UsedStorageSpace int `json:"used_storage_space"` + ConnectAddress string `json:"connect_address"` + Port int `json:"port"` + Status string `json:"status"` + InstanceID string `json:"instance_id"` + ResourceSpecCode string `json:"resource_spec_code"` + ChargingMode int `json:"charging_mode"` + VPCID string `json:"vpc_id"` + VPCName string `json:"vpc_name"` + CreatedAt string `json:"created_at"` + UserID string `json:"user_id"` + UserName string `json:"user_name"` + OrderID string `json:"order_id"` + MaintainBegin string `json:"maintain_begin"` + MaintainEnd string `json:"maintain_end"` + EnablePublicIP bool `json:"enable_publicip"` + ManagementConnectAddress string `json:"management_connect_address"` + SslEnable bool `json:"ssl_enable"` + EnterpriseProjectID string `json:"enterprise_project_id"` + IsLogicalVolume bool `json:"is_logical_volume"` + ExtendTimes int `json:"extend_times"` + EnableAutoTopic bool `json:"enable_auto_topic"` + Type string `json:"type"` + ProductID string `json:"product_id"` + SecurityGroupID string `json:"security_group_id"` + SecurityGroupName string `json:"security_group_name"` + SubnetID string `json:"subnet_id"` + AvailableZones []string `json:"available_zones"` + TotalStorageSpace int `json:"total_storage_space"` + PublicConnectionAddress string `json:"public_connect_address"` + StorageResourceID string `json:"storage_resource_id"` + StorageSpecCode string `json:"storage_spec_code"` + ServiceType string `json:"service_type"` + StorageType string `json:"storage_type"` + RetentionPolicy string `json:"retention_policy"` + KafkaPublicStatus string `json:"kafka_public_status"` + PublicBandWidth int `json:"public_bandwidth"` + KafkaManagerUser string `json:"kafka_manager_user" required:"true"` + EnableLogCollect bool `json:"enable_log_collection"` + CrossVpcInfo string `json:"cross_vpc_info"` + Ipv6Enable bool `json:"ipv6_enable"` + Ipv6ConnectAddresses []string `json:"ipv6_connect_addresses"` + ConnectorEnalbe bool `json:"connector_enable"` + ConnectorID string `json:"connector_id"` + RestEnable bool `json:"rest_enable"` + RestConnectAddress string `json:"rest_connect_address"` + MessageQueryInstEnable bool `json:"message_query_inst_enable"` + VpcClientPlain bool `json:"vpc_client_plain"` + SupportFeatures string `json:"support_features"` + TraceEnable bool `json:"trace_enable"` + PodConnectAddress string `json:"pod_connect_address"` + DiskEncrypted bool `json:"disk_encrypted"` + KafkaPrivateConnectAddress string `json:"kafka_private_connect_address"` + CesVersion string `json:"ces_version"` + AccessUser string `json:"access_user"` + Tags []tags.ResourceTag `json:"tags"` +} + +// UpdateResult is a struct from which can get the result of update method +type UpdateResult struct { + golangsdk.Result +} + +// GetResult contains the body of getting detailed +type GetResult struct { + golangsdk.Result +} + +// Extract from GetResult +func (r GetResult) Extract() (*Instance, error) { + var s Instance + err := r.Result.ExtractInto(&s) + return &s, err +} + +type Page struct { + pagination.SinglePageBase +} + +func (r Page) IsEmpty() (bool, error) { + data, err := ExtractInstances(r) + if err != nil { + return false, err + } + return len(data.Instances) == 0, err +} + +// ExtractCloudServers is a function that takes a ListResult and returns the services' information. +func ExtractInstances(r pagination.Page) (ListResponse, error) { + var s ListResponse + err := (r.(Page)).ExtractInto(&s) + return s, err +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/urls.go b/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/urls.go new file mode 100644 index 00000000000..106f157dec2 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances/urls.go @@ -0,0 +1,30 @@ +package instances + +import "github.com/huaweicloud/golangsdk" + +// endpoint/instances +const resourcePath = "instances" + +// createURL will build the rest query url of creation +func createURL(client *golangsdk.ServiceClient) string { + return client.ServiceURL(resourcePath) +} + +// deleteURL will build the url of deletion +func deleteURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id) +} + +// updateURL will build the url of update +func updateURL(c *golangsdk.ServiceClient, id string) string { + return c.ServiceURL(resourcePath, id) +} + +// getURL will build the get url of get function +func getURL(client *golangsdk.ServiceClient, id string) string { + return client.ServiceURL(resourcePath, id) +} + +func listURL(client *golangsdk.ServiceClient) string { + return client.ServiceURL(resourcePath) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 25699d26fe5..8951184a4b2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -267,7 +267,7 @@ github.com/hashicorp/terraform-svchost/auth github.com/hashicorp/terraform-svchost/disco # github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d github.com/hashicorp/yamux -# github.com/huaweicloud/golangsdk v0.0.0-20210524113822-7a55f63ba01a +# github.com/huaweicloud/golangsdk v0.0.0-20210525075112-86e5a49ad5c3 ## explicit github.com/huaweicloud/golangsdk github.com/huaweicloud/golangsdk/internal @@ -328,6 +328,7 @@ github.com/huaweicloud/golangsdk/openstack/dms/v1/instances github.com/huaweicloud/golangsdk/openstack/dms/v1/maintainwindows github.com/huaweicloud/golangsdk/openstack/dms/v1/products github.com/huaweicloud/golangsdk/openstack/dms/v1/queues +github.com/huaweicloud/golangsdk/openstack/dms/v2/kafka/instances github.com/huaweicloud/golangsdk/openstack/dns/v2/ptrrecords github.com/huaweicloud/golangsdk/openstack/dns/v2/recordsets github.com/huaweicloud/golangsdk/openstack/dns/v2/zones