diff --git a/common/common_volcengine_version.go b/common/common_volcengine_version.go index 7397520d..ba1a61c9 100644 --- a/common/common_volcengine_version.go +++ b/common/common_volcengine_version.go @@ -2,5 +2,5 @@ package common const ( TerraformProviderName = "terraform-provider-volcengine" - TerraformProviderVersion = "0.0.149" + TerraformProviderVersion = "0.0.150" ) diff --git a/docgen/main.go b/docgen/main.go index fad0a320..69067900 100644 --- a/docgen/main.go +++ b/docgen/main.go @@ -160,6 +160,7 @@ var resourceKeys = map[string]string{ "financial_relation": "FINANCIAL_RELATION", "cloud_identity": "CLOUD_IDENTITY", "kafka": "KAFKA", + "private_zone": "PRIVATE_ZONE", } type Products struct { diff --git a/example/dataPrivateZoneRecordSets/main.tf b/example/dataPrivateZoneRecordSets/main.tf new file mode 100644 index 00000000..2040ee47 --- /dev/null +++ b/example/dataPrivateZoneRecordSets/main.tf @@ -0,0 +1,3 @@ +data "volcengine_private_zone_record_sets" "foo" { + zid = 245**** +} diff --git a/example/dataPrivateZoneRecords/main.tf b/example/dataPrivateZoneRecords/main.tf new file mode 100644 index 00000000..0640e077 --- /dev/null +++ b/example/dataPrivateZoneRecords/main.tf @@ -0,0 +1,4 @@ +data "volcengine_private_zone_records" "foo" { + zid = 245**** + record_id = "907925684878276****" +} diff --git a/example/dataPrivateZoneResolverEndpoints/main.tf b/example/dataPrivateZoneResolverEndpoints/main.tf new file mode 100644 index 00000000..ff1c052e --- /dev/null +++ b/example/dataPrivateZoneResolverEndpoints/main.tf @@ -0,0 +1 @@ +data "volcengine_private_zone_resolver_endpoints" "foo" {} \ No newline at end of file diff --git a/example/dataPrivateZoneResolverRules/main.tf b/example/dataPrivateZoneResolverRules/main.tf new file mode 100644 index 00000000..dc55d4c9 --- /dev/null +++ b/example/dataPrivateZoneResolverRules/main.tf @@ -0,0 +1 @@ +data "volcengine_private_zone_resolver_rules" "foo" {} \ No newline at end of file diff --git a/example/dataPrivateZones/main.tf b/example/dataPrivateZones/main.tf new file mode 100644 index 00000000..d39c7f8a --- /dev/null +++ b/example/dataPrivateZones/main.tf @@ -0,0 +1,7 @@ +data "volcengine_private_zones" "foo" { + zid = 77**** + zone_name = "volces.com" + search_mode = "EXACT" + recursion_mode = true + line_mode = 3 +} diff --git a/example/privateZone/main.tf b/example/privateZone/main.tf new file mode 100644 index 00000000..99be9a22 --- /dev/null +++ b/example/privateZone/main.tf @@ -0,0 +1,14 @@ +resource "volcengine_private_zone" "foo" { + zone_name = "acc-test-pz.com" + remark = "acc-test-new" + recursion_mode = true + intelligent_mode = true + load_balance_mode = true + vpcs { + vpc_id = "vpc-rs4mi0jedipsv0x57pf****" + } + vpcs { + vpc_id = "vpc-3qdzk9xju6o747prml0jk****" + region = "cn-shanghai" + } +} diff --git a/example/privateZoneRecord/main.tf b/example/privateZoneRecord/main.tf new file mode 100644 index 00000000..bbc0e7ad --- /dev/null +++ b/example/privateZoneRecord/main.tf @@ -0,0 +1,22 @@ +resource "volcengine_private_zone_record" "foo" { + zid = 245**** + host = "www" + type = "A" + value = "10.1.1.158" + weight = 8 + ttl = 700 + remark = "tf-test" + enable = true +} + +data "volcengine_private_zone_record_sets" "foo" { + zid = volcengine_private_zone_record.foo.zid + host = volcengine_private_zone_record.foo.host + search_mode = "EXACT" +} + +resource "volcengine_private_zone_record_weight_enabler" "foo" { + zid = volcengine_private_zone_record.foo.zid + record_set_id = [for set in data.volcengine_private_zone_record_sets.foo.record_sets : set.record_set_id if set.type == volcengine_private_zone_record.foo.type][0] + weight_enabled = true +} diff --git a/example/privateZoneRecordWeightEnabler/main.tf b/example/privateZoneRecordWeightEnabler/main.tf new file mode 100644 index 00000000..bbc0e7ad --- /dev/null +++ b/example/privateZoneRecordWeightEnabler/main.tf @@ -0,0 +1,22 @@ +resource "volcengine_private_zone_record" "foo" { + zid = 245**** + host = "www" + type = "A" + value = "10.1.1.158" + weight = 8 + ttl = 700 + remark = "tf-test" + enable = true +} + +data "volcengine_private_zone_record_sets" "foo" { + zid = volcengine_private_zone_record.foo.zid + host = volcengine_private_zone_record.foo.host + search_mode = "EXACT" +} + +resource "volcengine_private_zone_record_weight_enabler" "foo" { + zid = volcengine_private_zone_record.foo.zid + record_set_id = [for set in data.volcengine_private_zone_record_sets.foo.record_sets : set.record_set_id if set.type == volcengine_private_zone_record.foo.type][0] + weight_enabled = true +} diff --git a/example/privateZoneResolverEndpoint/main.tf b/example/privateZoneResolverEndpoint/main.tf new file mode 100644 index 00000000..f95fa54b --- /dev/null +++ b/example/privateZoneResolverEndpoint/main.tf @@ -0,0 +1,26 @@ +resource "volcengine_private_zone_resolver_endpoint" "foo" { + name = "tf-test" + vpc_id = "vpc-13f9uuuqfdjb43n6nu5p1****" + vpc_region = "cn-beijing" + security_group_id = "sg-mj2nsckay29s5smt1b0d****" + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.2" + } + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.3" + } + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.4" + } + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.5" + } +} \ No newline at end of file diff --git a/example/privateZoneResolverRule/main.tf b/example/privateZoneResolverRule/main.tf new file mode 100644 index 00000000..98e1f816 --- /dev/null +++ b/example/privateZoneResolverRule/main.tf @@ -0,0 +1,14 @@ +resource "volcengine_private_zone_resolver_rule" "foo" { + endpoint_id = 346 + name = "tf0" + type = "OUTBOUND" + vpcs { + region = "cn-beijing" + vpc_id = "vpc-13f9uuuqfdjb43n6nu5p1****" + } + forward_ips { + ip = "10.199.38.19" + port = 33 + } + zone_name = ["www.baidu.com"] +} diff --git a/example/privateZoneUserVpcAuthorization/main.tf b/example/privateZoneUserVpcAuthorization/main.tf new file mode 100644 index 00000000..7f6bcdb8 --- /dev/null +++ b/example/privateZoneUserVpcAuthorization/main.tf @@ -0,0 +1,3 @@ +resource "volcengine_private_zone_user_vpc_authorization" "foo" { + account_id = "2100278462" +} diff --git a/example/vkeNodePool/main.tf b/example/vkeNodePool/main.tf index 505947c2..03619e79 100644 --- a/example/vkeNodePool/main.tf +++ b/example/vkeNodePool/main.tf @@ -152,15 +152,15 @@ resource "volcengine_vke_node_pool" "foo1" { instance_type_ids = ["ecs.g1ie.xlarge"] subnet_ids = [volcengine_subnet.foo.id] image_id = [for image in data.volcengine_images.foo.images : image.image_id if image.image_name == "veLinux 1.0 CentOS兼容版 64位"][0] - system_volume { - type = "ESSD_PL0" - size = "50" - } - data_volumes { - type = "ESSD_PL0" - size = "50" - mount_point = "/tf" - } + system_volume { + type = "ESSD_PL0" + size = 50 + } + data_volumes { + type = "ESSD_PL0" + size = 50 + mount_point = "/tf1" + } initialize_script = "ZWNobyBoZWxsbyB0ZXJyYWZvcm0h" security { login { diff --git a/volcengine/ebs/volume/resource_volcengine_volume.go b/volcengine/ebs/volume/resource_volcengine_volume.go index 0612b706..d9127266 100644 --- a/volcengine/ebs/volume/resource_volcengine_volume.go +++ b/volcengine/ebs/volume/resource_volcengine_volume.go @@ -5,7 +5,6 @@ import ( "time" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ve "github.com/volcengine/terraform-provider-volcengine/common" ) @@ -45,24 +44,21 @@ func ResourceVolcengineVolume() *schema.Resource { Description: "The name of Volume.", }, "volume_type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The type of Volume, the value is `PTSSD` or `ESSD_PL0` or `ESSD_PL1` or `ESSD_PL2` or `ESSD_FlexPL`.", - ValidateFunc: validation.StringInSlice([]string{"ESSD_PL0", "ESSD_PL1", "ESSD_PL2", "PTSSD", "ESSD_FlexPL"}, false), + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The type of Volume, the value is `PTSSD` or `ESSD_PL0` or `ESSD_PL1` or `ESSD_PL2` or `ESSD_FlexPL`.", }, "kind": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{"data"}, false), - Description: "The kind of Volume, the value is `data`.", + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The kind of Volume, the value is `data`.", }, "size": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntAtLeast(20), // 最小20GB - Description: "The size of Volume.", + Type: schema.TypeInt, + Required: true, + Description: "The size of Volume.", }, "description": { Type: schema.TypeString, @@ -79,10 +75,9 @@ func ResourceVolcengineVolume() *schema.Resource { "When use this field to attach ecs instance, the attached volume cannot be deleted by terraform, please use `terraform state rm volcengine_volume.resource_name` command to remove it from terraform state file and management.", }, "volume_charge_type": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{"PostPaid", "PrePaid"}, false), - Default: "PostPaid", + Type: schema.TypeString, + Optional: true, + Default: "PostPaid", Description: "The charge type of the Volume, the value is `PostPaid` or `PrePaid`. " + "The `PrePaid` volume cannot be detached. " + "Please note that `PrePaid` type needs to ask the system administrator to apply for a whitelist.", diff --git a/volcengine/private_zone/private_zone/data_source_volcengine_private_zones.go b/volcengine/private_zone/private_zone/data_source_volcengine_private_zones.go new file mode 100644 index 00000000..117b49fe --- /dev/null +++ b/volcengine/private_zone/private_zone/data_source_volcengine_private_zones.go @@ -0,0 +1,170 @@ +package private_zone + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcenginePrivateZones() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcenginePrivateZonesRead, + Schema: map[string]*schema.Schema{ + "zid": { + Type: schema.TypeInt, + Optional: true, + Description: "The zid of Private Zone.", + }, + "zone_name": { + Type: schema.TypeString, + Optional: true, + Description: "The name of Private Zone.", + }, + "region": { + Type: schema.TypeString, + Optional: true, + Description: "The region of Private Zone.", + }, + "vpc_id": { + Type: schema.TypeString, + Optional: true, + Description: "The vpc id associated to Private Zone.", + }, + "recursion_mode": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether the recursion mode of Private Zone is enabled.", + }, + "line_mode": { + Type: schema.TypeInt, + Optional: true, + Description: "The line mode of Private Zone, specified whether the intelligent mode and the load balance function is enabled.", + }, + "search_mode": { + Type: schema.TypeString, + Optional: true, + Default: "LIKE", + ValidateFunc: validation.StringInSlice([]string{"LIKE", "EXACT"}, false), + Description: "The search mode of query. Valid values: `LIKE`, `EXACT`. Default is `LIKE`.", + }, + + "name_regex": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsValidRegExp, + Description: "A Name Regex of Resource.", + }, + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "private_zones": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the private zone.", + }, + "zid": { + Type: schema.TypeInt, + Computed: true, + Description: "The id of the private zone.", + }, + "zone_name": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the private zone.", + }, + "remark": { + Type: schema.TypeString, + Computed: true, + Description: "The remark of the private zone.", + }, + "record_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The record count of the private zone.", + }, + "recursion_mode": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether the recursion mode of the private zone is enabled.", + }, + "line_mode": { + Type: schema.TypeInt, + Computed: true, + Description: "The line mode of the private zone, specified whether the intelligent mode and the load balance function is enabled.", + }, + "last_operator": { + Type: schema.TypeString, + Computed: true, + Description: "The account id of the last operator who created the private zone.", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The created time of the private zone.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The updated time of the private zone.", + }, + "region": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "The region of the private zone.", + }, + "bind_vpcs": { + Type: schema.TypeList, + Computed: true, + Description: "The Bind vpc info of the private zone.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the bind vpc.", + }, + "region": { + Type: schema.TypeString, + Computed: true, + Description: "The region of the bind vpc.", + }, + "region_name": { + Type: schema.TypeString, + Computed: true, + Description: "The region name of the bind vpc.", + }, + "account_id": { + Type: schema.TypeString, + Computed: true, + Description: "The account id of the bind vpc.", + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcenginePrivateZonesRead(d *schema.ResourceData, meta interface{}) error { + service := NewPrivateZoneService(meta.(*ve.SdkClient)) + return service.Dispatcher.Data(service, d, DataSourceVolcenginePrivateZones()) +} diff --git a/volcengine/private_zone/private_zone/resource_volcengine_private_zone.go b/volcengine/private_zone/private_zone/resource_volcengine_private_zone.go new file mode 100644 index 00000000..885ce234 --- /dev/null +++ b/volcengine/private_zone/private_zone/resource_volcengine_private_zone.go @@ -0,0 +1,123 @@ +package private_zone + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +PrivateZone can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone.default resource_id +``` + +*/ + +func ResourceVolcenginePrivateZone() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcenginePrivateZoneCreate, + Read: resourceVolcenginePrivateZoneRead, + Update: resourceVolcenginePrivateZoneUpdate, + Delete: resourceVolcenginePrivateZoneDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "zone_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name of the private zone.", + }, + "remark": { + Type: schema.TypeString, + Optional: true, + Description: "The remark of the private zone.", + }, + "recursion_mode": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether to enable the recursion mode of the private zone.", + }, + "intelligent_mode": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Description: "Whether to enable the intelligent mode of the private zone.", + }, + "load_balance_mode": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether to enable the load balance mode of the private zone.", + }, + "vpcs": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + Description: "The bind vpc object of the private zone. If you want to bind another account's VPC, you need to first use resource volcengine_private_zone_user_vpc_authorization to complete the authorization.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The region of the bind vpc. The default value is the region of the default provider config.", + }, + "vpc_id": { + Type: schema.TypeString, + Required: true, + Description: "The id of the bind vpc.", + }, + }, + }, + }, + }, + } + return resource +} + +func resourceVolcenginePrivateZoneCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Create(service, d, ResourceVolcenginePrivateZone()) + if err != nil { + return fmt.Errorf("error on creating private_zone %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneRead(d, meta) +} + +func resourceVolcenginePrivateZoneRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Read(service, d, ResourceVolcenginePrivateZone()) + if err != nil { + return fmt.Errorf("error on reading private_zone %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcenginePrivateZoneUpdate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Update(service, d, ResourceVolcenginePrivateZone()) + if err != nil { + return fmt.Errorf("error on updating private_zone %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneRead(d, meta) +} + +func resourceVolcenginePrivateZoneDelete(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Delete(service, d, ResourceVolcenginePrivateZone()) + if err != nil { + return fmt.Errorf("error on deleting private_zone %q, %s", d.Id(), err) + } + return err +} diff --git a/volcengine/private_zone/private_zone/service_volcengine_private_zone.go b/volcengine/private_zone/private_zone/service_volcengine_private_zone.go new file mode 100644 index 00000000..31536ebc --- /dev/null +++ b/volcengine/private_zone/private_zone/service_volcengine_private_zone.go @@ -0,0 +1,419 @@ +package private_zone + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcenginePrivateZoneService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewPrivateZoneService(c *ve.SdkClient) *VolcenginePrivateZoneService { + return &VolcenginePrivateZoneService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcenginePrivateZoneService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcenginePrivateZoneService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + data, err = ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 100, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "ListPrivateZones" + + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + + results, err = ve.ObtainSdkValue("Result.Zones", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.Zones is not Slice") + } + return data, err + }) + if err != nil { + return data, err + } + + for _, v := range data { + zone, ok := v.(map[string]interface{}) + if !ok { + return data, fmt.Errorf("Value is not map ") + } + zone["ZoneId"] = strconv.Itoa(int(zone["ZID"].(float64))) + + action := "QueryPrivateZone" + req := map[string]interface{}{ + "ZID": zone["ZID"], + } + logger.Debug(logger.ReqFormat, action, req) + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &req) + if err != nil { + return data, err + } + logger.Debug(logger.RespFormat, action, req, resp) + + bindVpcs, err := ve.ObtainSdkValue("Result.BindVPCs", *resp) + if err != nil { + return data, err + } + zone["BindVpcs"] = bindVpcs + } + + return data, err +} + +func (s *VolcenginePrivateZoneService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ok bool + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + zid, err := strconv.Atoi(id) + if err != nil { + return data, fmt.Errorf(" ZID cannot convert to int ") + } + + req := map[string]interface{}{ + "ZIDs": zid, + } + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + for _, v := range results { + if data, ok = v.(map[string]interface{}); !ok { + return data, errors.New("Value is not map ") + } + } + if len(data) == 0 { + return data, fmt.Errorf("private_zone %s not exist ", id) + } + return data, err +} + +func (s *VolcenginePrivateZoneService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{} +} + +func (VolcenginePrivateZoneService) WithResourceResponseHandlers(d map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return d, map[string]ve.ResponseConvert{ + "ID": { + TargetField: "vpc_id", + }, + "BindVpcs": { + TargetField: "vpcs", + }, + }, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcenginePrivateZoneService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "CreatePrivateZone", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "vpcs": { + Ignore: true, + }, + "intelligent_mode": { + Ignore: true, + }, + "load_balance_mode": { + Ignore: true, + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + intelligentMode := d.Get("intelligent_mode").(bool) + loadBalanceMode := d.Get("load_balance_mode").(bool) + lineMode := 0 + if !intelligentMode && loadBalanceMode { + lineMode = 1 + } else if intelligentMode && !loadBalanceMode { + lineMode = 2 + } else if intelligentMode && loadBalanceMode { + lineMode = 3 + } + (*call.SdkParam)["LineMode"] = lineMode + + vpcSet, ok := d.Get("vpcs").(*schema.Set) + if !ok { + return false, fmt.Errorf(" vpcs is not set ") + } + bindVpcMap := make(map[string][]string) + for _, v := range vpcSet.List() { + var ( + region string + vpcId string + ) + vpcMap, ok := v.(map[string]interface{}) + if !ok { + return false, fmt.Errorf(" vpcs value is not map ") + } + vpcId = vpcMap["vpc_id"].(string) + if regionId, exist := vpcMap["region"]; exist && regionId != "" { + region = regionId.(string) + } else { + region = client.Region + } + bindVpcMap[region] = append(bindVpcMap[region], vpcId) + } + (*call.SdkParam)["VPCs"] = bindVpcMap + + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id, _ := ve.ObtainSdkValue("Result.ZID", *resp) + d.SetId(strconv.Itoa(int(id.(float64)))) + return nil + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + var callbacks []ve.Callback + + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "UpdatePrivateZone", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "recursion_mode": { + TargetField: "RecursionMode", + }, + "load_balance_mode": { + TargetField: "LoadBalance", + }, + "remark": { + TargetField: "Remark", + }, + "vpcs": { + Ignore: true, + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + if len(*call.SdkParam) > 0 { + zid, err := strconv.Atoi(d.Id()) + if err != nil { + return false, fmt.Errorf(" ZID cannot convert to int ") + } + (*call.SdkParam)["ZID"] = zid + return true, nil + } + return false, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.ReqFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + }, + } + callbacks = append(callbacks, callback) + + if resourceData.HasChange("vpcs") { + bindVpcCallback := ve.Callback{ + Call: ve.SdkCall{ + Action: "BindVPC", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "vpcs": { + Ignore: true, + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + zid, err := strconv.Atoi(d.Id()) + if err != nil { + return false, fmt.Errorf(" ZID cannot convert to int ") + } + (*call.SdkParam)["ZID"] = zid + + vpcSet, ok := d.Get("vpcs").(*schema.Set) + if !ok { + return false, fmt.Errorf(" vpcs is not set ") + } + bindVpcMap := make(map[string][]string) + for _, v := range vpcSet.List() { + var ( + region string + vpcId string + ) + vpcMap, ok := v.(map[string]interface{}) + if !ok { + return false, fmt.Errorf(" vpcs value is not map ") + } + vpcId = vpcMap["vpc_id"].(string) + if regionId, exist := vpcMap["region"]; exist { + region = regionId.(string) + } else { + region = client.Region + } + bindVpcMap[region] = append(bindVpcMap[region], vpcId) + } + (*call.SdkParam)["VPCs"] = bindVpcMap + + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.ReqFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + }, + } + callbacks = append(callbacks, bindVpcCallback) + } + + return callbacks +} + +func (s *VolcenginePrivateZoneService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "DeletePrivateZone", + ConvertMode: ve.RequestConvertIgnore, + ContentType: ve.ContentTypeJson, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + zid, err := strconv.Atoi(d.Id()) + if err != nil { + return false, fmt.Errorf(" ZID cannot convert to int ") + } + (*call.SdkParam)["ZID"] = zid + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + return ve.CheckResourceUtilRemoved(d, s.ReadResource, 5*time.Minute) + }, + CallError: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall, baseErr error) error { + //出现错误后重试 + return resource.Retry(15*time.Minute, func() *resource.RetryError { + _, callErr := s.ReadResource(d, "") + if callErr != nil { + if ve.ResourceNotFoundError(callErr) { + return nil + } else { + return resource.NonRetryableError(fmt.Errorf("error on reading private zone on delete %q, %w", d.Id(), callErr)) + } + } + _, callErr = call.ExecuteCall(d, client, call) + if callErr == nil { + return nil + } + return resource.RetryableError(callErr) + }) + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "zid": { + TargetField: "ZIDs", + }, + "vpc_id": { + TargetField: "VpcID", + }, + }, + NameField: "ZoneName", + IdField: "ZoneId", + CollectField: "private_zones", + ResponseConverts: map[string]ve.ResponseConvert{ + "ZoneId": { + TargetField: "id", + }, + "ZID": { + TargetField: "zid", + }, + "ID": { + TargetField: "id", + }, + "AccountID": { + TargetField: "account_id", + }, + }, + } +} + +func (s *VolcenginePrivateZoneService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} + +func getPostUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.POST, + ContentType: ve.ApplicationJSON, + Action: actionName, + } +} diff --git a/volcengine/private_zone/private_zone_record/data_source_volcengine_private_zone_records.go b/volcengine/private_zone/private_zone_record/data_source_volcengine_private_zone_records.go new file mode 100644 index 00000000..e15f186e --- /dev/null +++ b/volcengine/private_zone/private_zone_record/data_source_volcengine_private_zone_records.go @@ -0,0 +1,154 @@ +package private_zone_record + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcenginePrivateZoneRecords() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcenginePrivateZoneRecordsRead, + Schema: map[string]*schema.Schema{ + "zid": { + Type: schema.TypeInt, + Optional: true, + AtLeastOneOf: []string{"zid", "record_id"}, + Description: "The zid of Private Zone.", + }, + "record_id": { + Type: schema.TypeString, + Optional: true, + AtLeastOneOf: []string{"zid", "record_id"}, + Description: "The id of Private Zone Record.", + }, + "host": { + Type: schema.TypeString, + Optional: true, + Description: "The host of Private Zone Record.", + }, + "search_mode": { + Type: schema.TypeString, + Optional: true, + Default: "LIKE", + ValidateFunc: validation.StringInSlice([]string{"LIKE", "EXACT"}, false), + Description: "The search mode of query `host`. Valid values: `LIKE`, `EXACT`. Default is `LIKE`.", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "The domain name of Private Zone Record.", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: "The type of Private Zone Record.", + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: "The value of Private Zone Record.", + }, + "last_operator": { + Type: schema.TypeString, + Optional: true, + Description: "The last operator account id of Private Zone Record.", + }, + "line": { + Type: schema.TypeString, + Optional: true, + Description: "The subnet id of Private Zone Record. This field is only effected when the `intelligent_mode` of the private zone is true.", + }, + + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "records": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "record_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the private zone record.", + }, + "zid": { + Type: schema.TypeInt, + Computed: true, + Description: "The zid of the private zone record.", + }, + "host": { + Type: schema.TypeString, + Computed: true, + Description: "The host of the private zone record.", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "The type of the private zone record.", + }, + "value": { + Type: schema.TypeString, + Computed: true, + Description: "The value of the private zone record.", + }, + "ttl": { + Type: schema.TypeInt, + Computed: true, + Description: "The ttl of the private zone record. Unit: second.", + }, + "line": { + Type: schema.TypeString, + Computed: true, + Description: "The subnet id of the private zone record. This field is only effected when the `intelligent_mode` of the private zone is true.", + }, + "weight": { + Type: schema.TypeInt, + Computed: true, + Description: "The weight of the private zone record.", + }, + "enable": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether the private zone record is enabling.", + }, + "remark": { + Type: schema.TypeString, + Computed: true, + Description: "The remark of the private zone record.", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The created time of the private zone record.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The updated time of the private zone record.", + }, + "last_operator": { + Type: schema.TypeString, + Computed: true, + Description: "The last operator account id of the private zone record.", + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcenginePrivateZoneRecordsRead(d *schema.ResourceData, meta interface{}) error { + service := NewPrivateZoneRecordService(meta.(*ve.SdkClient)) + return service.Dispatcher.Data(service, d, DataSourceVolcenginePrivateZoneRecords()) +} diff --git a/volcengine/private_zone/private_zone_record/resource_volcengine_private_zone_record.go b/volcengine/private_zone/private_zone_record/resource_volcengine_private_zone_record.go new file mode 100644 index 00000000..cbc3fbbe --- /dev/null +++ b/volcengine/private_zone/private_zone_record/resource_volcengine_private_zone_record.go @@ -0,0 +1,128 @@ +package private_zone_record + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +PrivateZoneRecord can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_record.default resource_id +``` + +*/ + +func ResourceVolcenginePrivateZoneRecord() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcenginePrivateZoneRecordCreate, + Read: resourceVolcenginePrivateZoneRecordRead, + Update: resourceVolcenginePrivateZoneRecordUpdate, + Delete: resourceVolcenginePrivateZoneRecordDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "zid": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "The zid of the private zone record.", + }, + "host": { + Type: schema.TypeString, + Required: true, + Description: "The host of the private zone record.", + }, + "type": { + Type: schema.TypeString, + Required: true, + Description: "The type of the private zone record. Valid values: `A`, `AAAA`, `CNAME`, `MX`, `PTR`.", + }, + "value": { + Type: schema.TypeString, + Required: true, + Description: "The value of the private zone record. Record values need to be set based on the value of the `type`.", + }, + "weight": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "The weight of the private zone record. This field is only effected when the `load_balance_mode` of the private zone is true and the `weight_enabled` of the record_set is true. Default is 1.", + }, + "ttl": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "The ttl of the private zone record. Unit: second. Default is 600.", + }, + //"line": { + // Type: schema.TypeString, + // Optional: true, + // Computed: true, + // Description: "The subnet id of the private zone record. This field is only effected when the `intelligent_mode` of the private zone is true. Default is `Default`.", + //}, + "remark": { + Type: schema.TypeString, + Optional: true, + Description: "The remark of the private zone record.", + }, + "enable": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Id() == "" + }, + Description: "Whether to enable the private zone record. This field is only effected when modify this resource.", + }, + }, + } + return resource +} + +func resourceVolcenginePrivateZoneRecordCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneRecordService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Create(service, d, ResourceVolcenginePrivateZoneRecord()) + if err != nil { + return fmt.Errorf("error on creating private_zone_record %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneRecordRead(d, meta) +} + +func resourceVolcenginePrivateZoneRecordRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneRecordService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Read(service, d, ResourceVolcenginePrivateZoneRecord()) + if err != nil { + return fmt.Errorf("error on reading private_zone_record %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcenginePrivateZoneRecordUpdate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneRecordService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Update(service, d, ResourceVolcenginePrivateZoneRecord()) + if err != nil { + return fmt.Errorf("error on updating private_zone_record %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneRecordRead(d, meta) +} + +func resourceVolcenginePrivateZoneRecordDelete(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneRecordService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Delete(service, d, ResourceVolcenginePrivateZoneRecord()) + if err != nil { + return fmt.Errorf("error on deleting private_zone_record %q, %s", d.Id(), err) + } + return err +} diff --git a/volcengine/private_zone/private_zone_record/service_volcengine_private_zone_record.go b/volcengine/private_zone/private_zone_record/service_volcengine_private_zone_record.go new file mode 100644 index 00000000..4a6de242 --- /dev/null +++ b/volcengine/private_zone/private_zone_record/service_volcengine_private_zone_record.go @@ -0,0 +1,291 @@ +package private_zone_record + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcenginePrivateZoneRecordService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewPrivateZoneRecordService(c *ve.SdkClient) *VolcenginePrivateZoneRecordService { + return &VolcenginePrivateZoneRecordService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcenginePrivateZoneRecordService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcenginePrivateZoneRecordService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 100, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "ListRecords" + + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + + results, err = ve.ObtainSdkValue("Result.Records", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.Records is not Slice") + } + return data, err + }) +} + +func (s *VolcenginePrivateZoneRecordService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ok bool + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + req := map[string]interface{}{ + "RecordIDs": id, + } + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + for _, v := range results { + if data, ok = v.(map[string]interface{}); !ok { + return data, errors.New("Value is not map ") + } + } + if len(data) == 0 { + return data, fmt.Errorf("private_zone_record %s not exist ", id) + } + + // 特殊处理,避免 API 返回结果不一致问题 + if v, exist := data["Value"]; exist { + data["Value"] = strings.TrimSuffix(v.(string), ".") + } + + return data, err +} + +func (s *VolcenginePrivateZoneRecordService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{} +} + +func (VolcenginePrivateZoneRecordService) WithResourceResponseHandlers(d map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return d, map[string]ve.ResponseConvert{ + "RecordID": { + TargetField: "record_id", + }, + "ZID": { + TargetField: "zid", + }, + "TTL": { + TargetField: "ttl", + }, + }, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcenginePrivateZoneRecordService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "CreateRecord", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "zid": { + TargetField: "ZID", + }, + "ttl": { + TargetField: "TTL", + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id, _ := ve.ObtainSdkValue("Result.RecordID", *resp) + d.SetId(id.(string)) + return nil + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneRecordService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "UpdateRecord", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "ttl": { + TargetField: "TTL", + }, + "host": { + TargetField: "Host", + }, + "type": { + TargetField: "Type", + }, + "value": { + TargetField: "Value", + }, + "weight": { + TargetField: "Weight", + }, + //"line": { + // TargetField: "Line", + //}, + "remark": { + TargetField: "Remark", + }, + "enable": { + TargetField: "Enable", + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + if len(*call.SdkParam) > 0 { + (*call.SdkParam)["RecordID"] = d.Id() + return true, nil + } + return false, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.ReqFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneRecordService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "DeleteRecord", + ConvertMode: ve.RequestConvertIgnore, + ContentType: ve.ContentTypeJson, + SdkParam: &map[string]interface{}{ + "RecordID": resourceData.Id(), + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + return ve.CheckResourceUtilRemoved(d, s.ReadResource, 5*time.Minute) + }, + CallError: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall, baseErr error) error { + //出现错误后重试 + return resource.Retry(15*time.Minute, func() *resource.RetryError { + _, callErr := s.ReadResource(d, "") + if callErr != nil { + if ve.ResourceNotFoundError(callErr) { + return nil + } else { + return resource.NonRetryableError(fmt.Errorf("error on reading private zone record on delete %q, %w", d.Id(), callErr)) + } + } + _, callErr = call.ExecuteCall(d, client, call) + if callErr == nil { + return nil + } + return resource.RetryableError(callErr) + }) + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneRecordService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "zid": { + TargetField: "ZID", + }, + "record_id": { + TargetField: "RecordIDs", + }, + }, + IdField: "RecordID", + CollectField: "records", + ResponseConverts: map[string]ve.ResponseConvert{ + "RecordID": { + TargetField: "record_id", + }, + "ZID": { + TargetField: "zid", + }, + "TTL": { + TargetField: "ttl", + }, + }, + } +} + +func (s *VolcenginePrivateZoneRecordService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} + +func getPostUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.POST, + ContentType: ve.ApplicationJSON, + Action: actionName, + } +} diff --git a/volcengine/private_zone/private_zone_record_set/data_source_volcengine_private_zone_record_sets.go b/volcengine/private_zone/private_zone_record_set/data_source_volcengine_private_zone_record_sets.go new file mode 100644 index 00000000..e31db52d --- /dev/null +++ b/volcengine/private_zone/private_zone_record_set/data_source_volcengine_private_zone_record_sets.go @@ -0,0 +1,92 @@ +package private_zone_record_set + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcenginePrivateZoneRecordSets() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcenginePrivateZoneRecordSetsRead, + Schema: map[string]*schema.Schema{ + "zid": { + Type: schema.TypeInt, + Required: true, + Description: "The zid of Private Zone.", + }, + "record_set_id": { + Type: schema.TypeString, + Optional: true, + Description: "The id of Private Zone Record Set.", + }, + "host": { + Type: schema.TypeString, + Optional: true, + Description: "The host of Private Zone Record Set.", + }, + "search_mode": { + Type: schema.TypeString, + Optional: true, + Default: "LIKE", + ValidateFunc: validation.StringInSlice([]string{"LIKE", "EXACT"}, false), + Description: "The search mode of query `host`. Valid values: `LIKE`, `EXACT`. Default is `LIKE`.", + }, + + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "record_sets": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "record_set_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the private zone record set.", + }, + "fqdn": { + Type: schema.TypeString, + Computed: true, + Description: "The Complete domain name of the private zone record.", + }, + "host": { + Type: schema.TypeString, + Computed: true, + Description: "The host of the private zone record.", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "The type of the private zone record.", + }, + "line": { + Type: schema.TypeString, + Computed: true, + Description: "The subnet id of the private zone record. This field is only effected when the `intelligent_mode` of the private zone is true.", + }, + "weight_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether to enable the load balance of the private zone record set.", + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcenginePrivateZoneRecordSetsRead(d *schema.ResourceData, meta interface{}) error { + service := NewPrivateZoneRecordSetService(meta.(*ve.SdkClient)) + return service.Dispatcher.Data(service, d, DataSourceVolcenginePrivateZoneRecordSets()) +} diff --git a/volcengine/private_zone/private_zone_record_set/service_volcengine_private_zone_record_set.go b/volcengine/private_zone/private_zone_record_set/service_volcengine_private_zone_record_set.go new file mode 100644 index 00000000..3e877a62 --- /dev/null +++ b/volcengine/private_zone/private_zone_record_set/service_volcengine_private_zone_record_set.go @@ -0,0 +1,131 @@ +package private_zone_record_set + +import ( + "encoding/json" + "errors" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcenginePrivateZoneRecordSetService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewPrivateZoneRecordSetService(c *ve.SdkClient) *VolcenginePrivateZoneRecordSetService { + return &VolcenginePrivateZoneRecordSetService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcenginePrivateZoneRecordSetService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcenginePrivateZoneRecordSetService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 100, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "ListRecordSets" + + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + + results, err = ve.ObtainSdkValue("Result.RecordSets", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.RecordSets is not Slice") + } + return data, err + }) +} + +func (s *VolcenginePrivateZoneRecordSetService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + return nil, nil +} + +func (s *VolcenginePrivateZoneRecordSetService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{} +} + +func (VolcenginePrivateZoneRecordSetService) WithResourceResponseHandlers(d map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return d, nil, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcenginePrivateZoneRecordSetService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcenginePrivateZoneRecordSetService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcenginePrivateZoneRecordSetService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcenginePrivateZoneRecordSetService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "zid": { + TargetField: "ZID", + }, + "record_set_id": { + TargetField: "RecordSetID", + }, + }, + IdField: "ID", + CollectField: "record_sets", + ResponseConverts: map[string]ve.ResponseConvert{ + "ID": { + TargetField: "record_set_id", + }, + "FQDN": { + TargetField: "fqdn", + }, + }, + } +} + +func (s *VolcenginePrivateZoneRecordSetService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} diff --git a/volcengine/private_zone/private_zone_record_weight_enabler/resource_volcengine_private_zone_record_weight_enabler.go b/volcengine/private_zone/private_zone_record_weight_enabler/resource_volcengine_private_zone_record_weight_enabler.go new file mode 100644 index 00000000..90bafe5d --- /dev/null +++ b/volcengine/private_zone/private_zone_record_weight_enabler/resource_volcengine_private_zone_record_weight_enabler.go @@ -0,0 +1,114 @@ +package private_zone_record_weight_enabler + +import ( + "fmt" + "log" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +PrivateZoneRecordWeightEnabler can be imported using the zid:record_set_id, e.g. +``` +$ terraform import volcengine_private_zone_record_weight_enabler.default resource_id +``` + +*/ + +func ResourceVolcenginePrivateZoneRecordWeightEnabler() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcenginePrivateZoneRecordWeightEnablerCreate, + Read: resourceVolcenginePrivateZoneRecordWeightEnablerRead, + Update: resourceVolcenginePrivateZoneRecordWeightEnablerUpdate, + Delete: resourceVolcenginePrivateZoneRecordWeightEnablerDelete, + Importer: &schema.ResourceImporter{ + State: weightEnablerImporter, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "zid": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + Description: "The zid of the private zone record set.", + }, + "record_set_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The id of the private zone record set.", + }, + "weight_enabled": { + Type: schema.TypeBool, + Required: true, + Description: "Whether to enable the load balance of the private zone record set.", + }, + }, + } + return resource +} + +func resourceVolcenginePrivateZoneRecordWeightEnablerCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneRecordWeightEnablerService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Create(service, d, ResourceVolcenginePrivateZoneRecordWeightEnabler()) + if err != nil { + return fmt.Errorf("error on creating private_zone_record_weight_enabler %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneRecordWeightEnablerRead(d, meta) +} + +func resourceVolcenginePrivateZoneRecordWeightEnablerRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneRecordWeightEnablerService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Read(service, d, ResourceVolcenginePrivateZoneRecordWeightEnabler()) + if err != nil { + return fmt.Errorf("error on reading private_zone_record_weight_enabler %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcenginePrivateZoneRecordWeightEnablerUpdate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneRecordWeightEnablerService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Update(service, d, ResourceVolcenginePrivateZoneRecordWeightEnabler()) + if err != nil { + return fmt.Errorf("error on updating private_zone_record_weight_enabler %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneRecordWeightEnablerRead(d, meta) +} + +func resourceVolcenginePrivateZoneRecordWeightEnablerDelete(d *schema.ResourceData, meta interface{}) (err error) { + log.Printf("[DEBUG] deleting a volcengine_private_zone_record_weight_enabler resource only stops managing record weight, The Record Weight enabled status is left in its current state.") + service := NewPrivateZoneRecordWeightEnablerService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Delete(service, d, ResourceVolcenginePrivateZoneRecordWeightEnabler()) + if err != nil { + return fmt.Errorf("error on deleting private_zone_record_weight_enabler %q, %s", d.Id(), err) + } + return err +} + +var weightEnablerImporter = func(data *schema.ResourceData, i interface{}) ([]*schema.ResourceData, error) { + items := strings.Split(data.Id(), ":") + if len(items) != 2 { + return []*schema.ResourceData{data}, fmt.Errorf("import id must split with ':'") + } + zid, err := strconv.Atoi(items[0]) + if err != nil { + return []*schema.ResourceData{data}, fmt.Errorf(" ZID cannot convert to int ") + } + if err := data.Set("zid", zid); err != nil { + return []*schema.ResourceData{data}, err + } + if err := data.Set("record_set_id", items[1]); err != nil { + return []*schema.ResourceData{data}, err + } + return []*schema.ResourceData{data}, nil +} diff --git a/volcengine/private_zone/private_zone_record_weight_enabler/service_volcengine_private_zone_record_weight_enabler.go b/volcengine/private_zone/private_zone_record_weight_enabler/service_volcengine_private_zone_record_weight_enabler.go new file mode 100644 index 00000000..eb711893 --- /dev/null +++ b/volcengine/private_zone/private_zone_record_weight_enabler/service_volcengine_private_zone_record_weight_enabler.go @@ -0,0 +1,208 @@ +package private_zone_record_weight_enabler + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcenginePrivateZoneRecordWeightEnablerService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewPrivateZoneRecordWeightEnablerService(c *ve.SdkClient) *VolcenginePrivateZoneRecordWeightEnablerService { + return &VolcenginePrivateZoneRecordWeightEnablerService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 100, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "ListRecordSets" + + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + + results, err = ve.ObtainSdkValue("Result.RecordSets", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.RecordSets is not Slice") + } + return data, err + }) +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ok bool + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + ids := strings.Split(id, ":") + if len(ids) != 2 { + return data, fmt.Errorf("invalid record weight enabler Id: %s", id) + } + + zid, err := strconv.Atoi(ids[0]) + if err != nil { + return data, fmt.Errorf(" ZID cannot convert to int ") + } + + req := map[string]interface{}{ + "ZID": zid, + "RecordSetID": ids[1], + } + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + for _, v := range results { + if data, ok = v.(map[string]interface{}); !ok { + return data, errors.New("Value is not map ") + } + } + if len(data) == 0 { + return data, fmt.Errorf("private_zone_record_set %s not exist ", id) + } + return data, err +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{} +} + +func (VolcenginePrivateZoneRecordWeightEnablerService) WithResourceResponseHandlers(d map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return d, map[string]ve.ResponseConvert{ + "ID": { + TargetField: "record_set_id", + }, + }, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "UpdateRecordSet", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "record_set_id": { + TargetField: "RecordSetID", + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id, _ := ve.ObtainSdkValue("Result.ID", *resp) + zid := d.Get("zid").(int) + d.SetId(strconv.Itoa(zid) + ":" + id.(string)) + return nil + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "UpdateRecordSet", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "weight_enabled": { + TargetField: "WeightEnabled", + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + (*call.SdkParam)["RecordSetID"] = d.Get("record_set_id").(string) + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.ReqFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{} +} + +func (s *VolcenginePrivateZoneRecordWeightEnablerService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} + +func getPostUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.POST, + ContentType: ve.ApplicationJSON, + Action: actionName, + } +} diff --git a/volcengine/private_zone/private_zone_resolver_endpoint/data_source_volcengine_private_zone_resolver_endpoints.go b/volcengine/private_zone/private_zone_resolver_endpoint/data_source_volcengine_private_zone_resolver_endpoints.go new file mode 100644 index 00000000..ec931da8 --- /dev/null +++ b/volcengine/private_zone/private_zone_resolver_endpoint/data_source_volcengine_private_zone_resolver_endpoints.go @@ -0,0 +1,139 @@ +package private_zone_resolver_endpoint + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcenginePrivateZoneResolverEndpoints() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcenginePrivateZoneResolverEndpointsRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + Description: "The name of the private zone resolver endpoint.", + }, + "vpc_id": { + Type: schema.TypeString, + Optional: true, + Description: "The vpc ID of the private zone resolver endpoint.", + }, + "status": { + Type: schema.TypeString, + Optional: true, + Description: "The status of the private zone resolver endpoint.", + }, + "direction": { + Type: schema.TypeString, + Optional: true, + Description: "The direction of the private zone resolver endpoint.", + }, + "name_regex": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsValidRegExp, + Description: "A Name Regex of Resource.", + }, + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "endpoints": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the endpoint.", + }, + "endpoint_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The endpoint id.", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The created time of the endpoint.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The updated time of the endpoint.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the endpoint.", + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the endpoint.", + }, + "direction": { + Type: schema.TypeString, + Computed: true, + Description: "The direction of the endpoint.", + }, + "vpc_id": { + Type: schema.TypeString, + Computed: true, + Description: "The vpc id of the endpoint.", + }, + "vpc_region": { + Type: schema.TypeString, + Computed: true, + Description: "The vpc region of the endpoint.", + }, + "security_group_id": { + Type: schema.TypeString, + Computed: true, + Description: "The security group id of the endpoint.", + }, + "ip_configs": { + Type: schema.TypeList, + Computed: true, + Description: "List of IP configurations.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "az_id": { + Type: schema.TypeString, + Computed: true, + Description: "The availability zone id of the endpoint.", + }, + "subnet_id": { + Type: schema.TypeString, + Computed: true, + Description: "The subnet id of the endpoint.", + }, + "ip": { + Type: schema.TypeString, + Computed: true, + Description: "The IP address of the endpoint.", + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcenginePrivateZoneResolverEndpointsRead(d *schema.ResourceData, meta interface{}) error { + service := NewPrivateZoneResolverEndpointService(meta.(*ve.SdkClient)) + return service.Dispatcher.Data(service, d, DataSourceVolcenginePrivateZoneResolverEndpoints()) +} diff --git a/volcengine/private_zone/private_zone_resolver_endpoint/resource_volcengine_private_zone_resolver_endpoint.go b/volcengine/private_zone/private_zone_resolver_endpoint/resource_volcengine_private_zone_resolver_endpoint.go new file mode 100644 index 00000000..63468905 --- /dev/null +++ b/volcengine/private_zone/private_zone_resolver_endpoint/resource_volcengine_private_zone_resolver_endpoint.go @@ -0,0 +1,144 @@ +package private_zone_resolver_endpoint + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +PrivateZoneResolverEndpoint can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_resolver_endpoint.default resource_id +``` + +*/ + +func ResourceVolcenginePrivateZoneResolverEndpoint() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcenginePrivateZoneResolverEndpointCreate, + Read: resourceVolcenginePrivateZoneResolverEndpointRead, + Update: resourceVolcenginePrivateZoneResolverEndpointUpdate, + Delete: resourceVolcenginePrivateZoneResolverEndpointDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "The name of the private zone resolver endpoint.", + }, + "direction": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: "OUTBOUND", + Description: "DNS request forwarding direction for terminal nodes. " + + "OUTBOUND: (default) Outbound terminal nodes forward DNS query requests from within the VPC to external DNS servers. " + + "INBOUND: Inbound terminal nodes forward DNS query requests from external sources to resolvers.", + }, + "vpc_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The VPC ID of the endpoint.", + }, + "vpc_region": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The VPC region of the endpoint.", + }, + "security_group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The security group ID of the endpoint.", + }, + "ip_configs": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + //Set: func(i interface{}) int { + // if i == nil { + // return hashcode.String("") + // } + // m := i.(map[string]interface{}) + // var ( + // buf bytes.Buffer + // ) + // buf.WriteString(fmt.Sprintf("%v#%v#%v", m["az_id"], m["subnet_id"], m["ip"])) + // return hashcode.String(buf.String()) + //}, + Description: "Availability zones, subnets, and IP configurations of terminal nodes.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "az_id": { + Type: schema.TypeString, + Required: true, + Description: "Id of the availability zone.", + }, + "subnet_id": { + Type: schema.TypeString, + Required: true, + Description: "Id of the subnet.", + }, + "ip": { + Type: schema.TypeString, + Required: true, + Description: "Source IP address of traffic. You can add up to 6 IP addresses at most. " + + "To ensure high availability, you must add at least two IP addresses.", + }, + }, + }, + }, + }, + } + return resource +} + +func resourceVolcenginePrivateZoneResolverEndpointCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverEndpointService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Create(service, d, ResourceVolcenginePrivateZoneResolverEndpoint()) + if err != nil { + return fmt.Errorf("error on creating private_zone_resolver_endpoint %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneResolverEndpointRead(d, meta) +} + +func resourceVolcenginePrivateZoneResolverEndpointRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverEndpointService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Read(service, d, ResourceVolcenginePrivateZoneResolverEndpoint()) + if err != nil { + return fmt.Errorf("error on reading private_zone_resolver_endpoint %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcenginePrivateZoneResolverEndpointUpdate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverEndpointService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Update(service, d, ResourceVolcenginePrivateZoneResolverEndpoint()) + if err != nil { + return fmt.Errorf("error on updating private_zone_resolver_endpoint %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneResolverEndpointRead(d, meta) +} + +func resourceVolcenginePrivateZoneResolverEndpointDelete(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverEndpointService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Delete(service, d, ResourceVolcenginePrivateZoneResolverEndpoint()) + if err != nil { + return fmt.Errorf("error on deleting private_zone_resolver_endpoint %q, %s", d.Id(), err) + } + return err +} diff --git a/volcengine/private_zone/private_zone_resolver_endpoint/service_volcengine_private_zone_resolver_endpoint.go b/volcengine/private_zone/private_zone_resolver_endpoint/service_volcengine_private_zone_resolver_endpoint.go new file mode 100644 index 00000000..9ba77d81 --- /dev/null +++ b/volcengine/private_zone/private_zone_resolver_endpoint/service_volcengine_private_zone_resolver_endpoint.go @@ -0,0 +1,380 @@ +package private_zone_resolver_endpoint + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcenginePrivateZoneResolverEndpointService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewPrivateZoneResolverEndpointService(c *ve.SdkClient) *VolcenginePrivateZoneResolverEndpointService { + return &VolcenginePrivateZoneResolverEndpointService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcenginePrivateZoneResolverEndpointService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcenginePrivateZoneResolverEndpointService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 100, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "ListResolverEndpoints" + + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + results, err = ve.ObtainSdkValue("Result.Endpoints", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + logger.Debug(logger.RespFormat, action, condition, results) + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.Endpoints is not Slice") + } + + for _, v := range data { + endpoint, ok := v.(map[string]interface{}) + if !ok { + return data, errors.New("Value is not map ") + } + endpoint["EndpointId"] = strconv.Itoa(int(endpoint["ID"].(float64))) + } + + return data, err + }) +} + +func (s *VolcenginePrivateZoneResolverEndpointService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + endpointId, err := strconv.Atoi(id) + if err != nil { + return data, errors.New("endpoint id is not a integer") + } + req := map[string]interface{}{ + //"Id": id, + } + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + for _, v := range results { + tmpData, ok := v.(map[string]interface{}) + if !ok { + return data, errors.New("Value is not map ") + } else if endpointId == int(tmpData["ID"].(float64)) { + data = tmpData + } + } + if len(data) == 0 { + return data, fmt.Errorf("private_zone_resolver_endpoint %s not exist ", id) + } + return data, err +} + +func (s *VolcenginePrivateZoneResolverEndpointService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{ + Pending: []string{}, + Delay: 1 * time.Second, + MinTimeout: 1 * time.Second, + Target: target, + Timeout: timeout, + Refresh: func() (result interface{}, state string, err error) { + var ( + d map[string]interface{} + status interface{} + failStates []string + ) + failStates = append(failStates, "Error") + d, err = s.ReadResource(resourceData, id) + if err != nil { + return nil, "", err + } + status, err = ve.ObtainSdkValue("Status", d) + if err != nil { + return nil, "", err + } + for _, v := range failStates { + if v == status.(string) { + return nil, "", fmt.Errorf("private_zone_resolver_endpoint status error, status: %s", status.(string)) + } + } + return d, status.(string), err + }, + } +} + +func (s *VolcenginePrivateZoneResolverEndpointService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "CreateResolverEndpoint", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "vpc_id": { + TargetField: "VpcID", + }, + "security_group_id": { + TargetField: "SecurityGroupID", + }, + "ip_configs": { + TargetField: "IpConfigs", + ConvertType: ve.ConvertJsonObjectArray, + NextLevelConvert: map[string]ve.RequestConvert{ + "az_id": { + TargetField: "AzID", + }, + "subnet_id": { + TargetField: "SubnetID", + }, + "ip": { + TargetField: "IP", + }, + }, + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id, _ := ve.ObtainSdkValue("Result.EndpointID", *resp) + d.SetId(strconv.Itoa(int(id.(float64)))) + return nil + }, + Refresh: &ve.StateRefresh{ + Target: []string{"Running"}, + Timeout: resourceData.Timeout(schema.TimeoutCreate), + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneResolverEndpointService) WithResourceResponseHandlers(d map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return d, map[string]ve.ResponseConvert{ + "VpcID": { + TargetField: "vpc_id", + }, + "SecurityGroupID": { + TargetField: "security_group_id", + }, + "AzID": { + TargetField: "az_id", + }, + "SubnetID": { + TargetField: "subnet_id", + }, + "IP": { + TargetField: "ip", + }, + }, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcenginePrivateZoneResolverEndpointService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "UpdateResolverEndpoint", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "name": { + TargetField: "Name", + }, + "ip_configs": { + Ignore: true, + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + id, err := strconv.Atoi(d.Id()) + if err != nil { + return false, err + } + (*call.SdkParam)["EndpointID"] = id + + if d.HasChange("ip_configs") { + ipConfigs, ok := d.GetOk("ip_configs") + if ok { + var results []interface{} + for _, ipConfig := range ipConfigs.(*schema.Set).List() { + ipMap := ipConfig.(map[string]interface{}) + result := make(map[string]interface{}) + if _, ok = ipMap["az_id"]; ok { + result["AzID"] = ipMap["az_id"] + } + if _, ok = ipMap["subnet_id"]; ok { + result["SubnetID"] = ipMap["subnet_id"] + } + if _, ok = ipMap["ip"]; ok { + result["IP"] = ipMap["ip"] + } + if len(result) > 0 { + results = append(results, result) + } + } + (*call.SdkParam)["IpConfigs"] = results + } + } + + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.ReqFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + Refresh: &ve.StateRefresh{ + Target: []string{"Running"}, + Timeout: resourceData.Timeout(schema.TimeoutUpdate), + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneResolverEndpointService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "DeleteResolverEndpoint", + ConvertMode: ve.RequestConvertIgnore, + ContentType: ve.ContentTypeJson, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + id, err := strconv.Atoi(d.Id()) + if err != nil { + return false, err + } + (*call.SdkParam)["EndpointID"] = id + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + return ve.CheckResourceUtilRemoved(d, s.ReadResource, 5*time.Minute) + }, + CallError: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall, baseErr error) error { + //出现错误后重试 + return resource.Retry(15*time.Minute, func() *resource.RetryError { + _, callErr := s.ReadResource(d, "") + if callErr != nil { + if ve.ResourceNotFoundError(callErr) { + return nil + } else { + return resource.NonRetryableError(fmt.Errorf("error on reading private zone resolver endpoint on delete %q, %w", d.Id(), callErr)) + } + } + _, callErr = call.ExecuteCall(d, client, call) + if callErr == nil { + return nil + } + return resource.RetryableError(callErr) + }) + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneResolverEndpointService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "vpc_id": { + TargetField: "VpcID", + }, + }, + NameField: "Name", + IdField: "EndpointId", + CollectField: "endpoints", + ResponseConverts: map[string]ve.ResponseConvert{ + "Id": { + TargetField: "endpoint_id", + }, + "EndpointId": { + TargetField: "id", + }, + "VpcID": { + TargetField: "vpc_id", + }, + "SecurityGroupID": { + TargetField: "security_group_id", + }, + "AzID": { + TargetField: "az_id", + }, + "SubnetID": { + TargetField: "subnet_id", + }, + "IP": { + TargetField: "ip", + }, + }, + } +} + +func (s *VolcenginePrivateZoneResolverEndpointService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} + +func getPostUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.POST, + ContentType: ve.ApplicationJSON, + Action: actionName, + } +} diff --git a/volcengine/private_zone/private_zone_resolver_rule/data_source_volcengine_private_zone_resolver_rules.go b/volcengine/private_zone/private_zone_resolver_rule/data_source_volcengine_private_zone_resolver_rules.go new file mode 100644 index 00000000..059cb99f --- /dev/null +++ b/volcengine/private_zone/private_zone_resolver_rule/data_source_volcengine_private_zone_resolver_rules.go @@ -0,0 +1,172 @@ +package private_zone_resolver_rule + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcenginePrivateZoneResolverRules() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcenginePrivateZoneResolverRulesRead, + Schema: map[string]*schema.Schema{ + //"ids": { + // Type: schema.TypeSet, + // Optional: true, + // Elem: &schema.Schema{ + // Type: schema.TypeString, + // }, + // Set: schema.HashString, + // Description: "A list of IDs.", + //}, + //"rule_id": { + // Type: schema.TypeInt, + // Optional: true, + // Description: "The ID of the rule.", + //}, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "The name of the rule.", + }, + "zone_name": { + Type: schema.TypeString, + Optional: true, + Description: "The main domain associated with the forwarding rule. " + + "For example, if you set this parameter to example.com, " + + "DNS requests for example.com and all subdomains of example.com will be forwarded.", + }, + "endpoint_id": { + Type: schema.TypeInt, + Optional: true, + Description: "ID of the exit terminal node.", + }, + "name_regex": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsValidRegExp, + Description: "A Name Regex of Resource.", + }, + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "rules": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the rule.", + }, + "rule_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The id of the rule.", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The created time of the rule.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The updated time of the rule.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the rule.", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "The type of the rule.", + }, + "zone_name": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "The zone name of the rule.", + }, + "endpoint_id": { + Type: schema.TypeInt, + Computed: true, + Description: "The endpoint ID of the rule.", + }, + "line": { + Type: schema.TypeInt, + Computed: true, + Description: "The ISP of the exit IP address of the recursive DNS server.", + }, + "forward_ips": { + Type: schema.TypeList, + Computed: true, + Description: "The IP address and port of the DNS server outside of the VPC.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + Description: "The IP address of the DNS server outside of the VPC.", + }, + "port": { + Type: schema.TypeInt, + Computed: true, + Description: "The port of the DNS server outside of the VPC.", + }, + }, + }, + }, + "bind_vpcs": { + Type: schema.TypeList, + Computed: true, + Description: "", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the bind vpc.", + }, + "region": { + Type: schema.TypeString, + Computed: true, + Description: "The region of the bind vpc.", + }, + "region_name": { + Type: schema.TypeString, + Computed: true, + Description: "The region name of the bind vpc.", + }, + "account_id": { + Type: schema.TypeString, + Computed: true, + Description: "The account id of the bind vpc.", + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcenginePrivateZoneResolverRulesRead(d *schema.ResourceData, meta interface{}) error { + service := NewPrivateZoneResolverRuleService(meta.(*ve.SdkClient)) + return service.Dispatcher.Data(service, d, DataSourceVolcenginePrivateZoneResolverRules()) +} diff --git a/volcengine/private_zone/private_zone_resolver_rule/resource_volcengine_private_zone_resolver_rule.go b/volcengine/private_zone/private_zone_resolver_rule/resource_volcengine_private_zone_resolver_rule.go new file mode 100644 index 00000000..107a7985 --- /dev/null +++ b/volcengine/private_zone/private_zone_resolver_rule/resource_volcengine_private_zone_resolver_rule.go @@ -0,0 +1,172 @@ +package private_zone_resolver_rule + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +PrivateZoneResolverRule can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_resolver_rule.default resource_id +``` + +*/ + +func ResourceVolcenginePrivateZoneResolverRule() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcenginePrivateZoneResolverRuleCreate, + Read: resourceVolcenginePrivateZoneResolverRuleRead, + Update: resourceVolcenginePrivateZoneResolverRuleUpdate, + Delete: resourceVolcenginePrivateZoneResolverRuleDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "The name of the rule.", + }, + "type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Forwarding rule types. " + + "OUTBOUND: Forward to external DNS servers. " + + "LINE: Set the recursive DNS server used for recursive resolution to the recursive DNS server of the Volcano Engine PublicDNS," + + " and customize the operator's exit IP address for the recursive DNS server.", + }, + "zone_name": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Get("type").(string) != "OUTBOUND" + }, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "Domain names associated with forwarding rules. " + + "You can enter one or more domain names. Up to 500 domain names are supported. " + + "This parameter is only valid when the Type parameter is OUTBOUND and is a required parameter.", + }, + "endpoint_id": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Get("type").(string) != "OUTBOUND" + }, + Description: "Terminal node ID. This parameter is only valid and required when the Type parameter is OUTBOUND.", + }, + "forward_ips": { + Type: schema.TypeSet, + Optional: true, + MinItems: 1, + Description: "IP address and port of external DNS server. You can add up to 10 IP addresses. " + + "This parameter is only valid when the Type parameter is OUTBOUND and is a required parameter.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Required: true, + Description: "IP address of the external DNS server. " + + "This parameter is only valid when the Type parameter is OUTBOUND and is a required parameter.", + }, + "port": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "The port of the external DNS server. Default is 53. " + + "This parameter is only valid and optional when the Type parameter is OUTBOUND.", + }, + }, + }, + }, + "line": { + Type: schema.TypeInt, + Optional: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + return d.Get("type").(string) != "LINE" + }, + Description: "The operator of the exit IP address of the recursive DNS server. " + + "This parameter is only valid when the Type parameter is LINE and is a required parameter. " + + "MOBILE, TELECOM, UNICOM.", + }, + "vpcs": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + Description: "The parameter name <region> is a variable that represents the region where the VPC is located, " + + "such as cn-beijing. The parameter value can include one or more VPC IDs, " + + "such as vpc-2750bd1. " + + "For example, if you associate a VPC in the cn-beijing region with a domain name and the VPC ID is vpc-2d6si87atfh1c58ozfd0nzq8k, " + + "the parameter would be \"cn-beijing\":[\"vpc-2d6si87atfh1c58ozfd0nzq8k\"]. " + + "You can add one or more regions. When the Type parameter is OUTBOUND, the VPC region must be the same as the region where the endpoint is located.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The region of the bind vpc. The default value is the region of the default provider config.", + }, + "vpc_id": { + Type: schema.TypeString, + Required: true, + Description: "The id of the bind vpc.", + }, + }, + }, + }, + }, + } + return resource +} + +func resourceVolcenginePrivateZoneResolverRuleCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverRuleService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Create(service, d, ResourceVolcenginePrivateZoneResolverRule()) + if err != nil { + return fmt.Errorf("error on creating private_zone_resolver_rule %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneResolverRuleRead(d, meta) +} + +func resourceVolcenginePrivateZoneResolverRuleRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverRuleService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Read(service, d, ResourceVolcenginePrivateZoneResolverRule()) + if err != nil { + return fmt.Errorf("error on reading private_zone_resolver_rule %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcenginePrivateZoneResolverRuleUpdate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverRuleService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Update(service, d, ResourceVolcenginePrivateZoneResolverRule()) + if err != nil { + return fmt.Errorf("error on updating private_zone_resolver_rule %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneResolverRuleRead(d, meta) +} + +func resourceVolcenginePrivateZoneResolverRuleDelete(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneResolverRuleService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Delete(service, d, ResourceVolcenginePrivateZoneResolverRule()) + if err != nil { + return fmt.Errorf("error on deleting private_zone_resolver_rule %q, %s", d.Id(), err) + } + return err +} diff --git a/volcengine/private_zone/private_zone_resolver_rule/service_volcengine_private_zone_resolver_rule.go b/volcengine/private_zone/private_zone_resolver_rule/service_volcengine_private_zone_resolver_rule.go new file mode 100644 index 00000000..e6df9043 --- /dev/null +++ b/volcengine/private_zone/private_zone_resolver_rule/service_volcengine_private_zone_resolver_rule.go @@ -0,0 +1,496 @@ +package private_zone_resolver_rule + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcenginePrivateZoneResolverRuleService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewPrivateZoneResolverRuleService(c *ve.SdkClient) *VolcenginePrivateZoneResolverRuleService { + return &VolcenginePrivateZoneResolverRuleService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcenginePrivateZoneResolverRuleService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcenginePrivateZoneResolverRuleService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + data, err = ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 100, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "ListResolverRules" + + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + + results, err = ve.ObtainSdkValue("Result.Rules", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.Items is not Slice") + } + return data, err + }) + if err != nil { + return data, err + } + + for _, v := range data { + rule, ok := v.(map[string]interface{}) + if !ok { + return data, errors.New("Value is not map ") + } + rule["RID"] = rule["ID"] + delete(rule, "ID") + rule["RuleId"] = strconv.Itoa(int(rule["RID"].(float64))) + action := "QueryResolverRule" + req := map[string]interface{}{ + "RuleID": rule["RID"], + } + logger.Debug(logger.ReqFormat, action, req) + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &req) + if err != nil { + return data, err + } + logger.Debug(logger.RespFormat, action, req, resp) + + bindVpcs, err := ve.ObtainSdkValue("Result.BindVPCs", *resp) + if err != nil { + return data, err + } + rule["BindVpcs"] = bindVpcs + + if zone, ok := rule["ZoneName"]; ok { + zoneSet := make([]string, 0) + arr := strings.Split(zone.(string), ",") + if len(arr) == 1 { + // 接口自动加的. + if strings.HasSuffix(arr[0], ".") { + zoneSet = append(zoneSet, arr[0][:len(arr[0])-1]) + } + } else { + zoneSet = arr + } + rule["ZoneName"] = zoneSet + } + } + return data, nil +} + +func (s *VolcenginePrivateZoneResolverRuleService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + + ruleId, err := strconv.Atoi(id) + if err != nil { + return data, errors.New("rule id is not a integer") + } + + req := map[string]interface{}{ + //"Id": id, + } + + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + + for _, v := range results { + tmpData, ok := v.(map[string]interface{}) + if !ok { + return data, errors.New("Value is not map ") + } else if ruleId == int(tmpData["RID"].(float64)) { + data = tmpData + } + } + if len(data) == 0 { + return data, fmt.Errorf("private_zone_resolver_rule %s not exist ", id) + } + return data, err +} + +func (s *VolcenginePrivateZoneResolverRuleService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{ + Pending: []string{}, + Delay: 1 * time.Second, + MinTimeout: 1 * time.Second, + Target: target, + Timeout: timeout, + Refresh: func() (result interface{}, state string, err error) { + var ( + d map[string]interface{} + status interface{} + failStates []string + ) + failStates = append(failStates, "Failed") + d, err = s.ReadResource(resourceData, id) + if err != nil { + return nil, "", err + } + status, err = ve.ObtainSdkValue("Status", d) + if err != nil { + return nil, "", err + } + for _, v := range failStates { + if v == status.(string) { + return nil, "", fmt.Errorf("private_zone_resolver_rule status error, status: %s", status.(string)) + } + } + return d, status.(string), err + }, + } +} + +func (s *VolcenginePrivateZoneResolverRuleService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "CreateResolverRule", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "vpcs": { + Ignore: true, + }, + "forward_ips": { + TargetField: "ForwardIPs", + ConvertType: ve.ConvertJsonObjectArray, + NextLevelConvert: map[string]ve.RequestConvert{ + "ip": { + TargetField: "IP", + }, + }, + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + vpcSet, ok := d.Get("vpcs").(*schema.Set) + if !ok { + return false, fmt.Errorf(" vpcs is not set ") + } + bindVpcMap := make(map[string][]string) + for _, v := range vpcSet.List() { + var ( + region string + vpcId string + ) + vpcMap, ok := v.(map[string]interface{}) + if !ok { + return false, fmt.Errorf(" vpcs value is not map ") + } + vpcId = vpcMap["vpc_id"].(string) + if regionId, exist := vpcMap["region"]; exist && regionId != "" { + region = regionId.(string) + } else { + region = client.Region + } + bindVpcMap[region] = append(bindVpcMap[region], vpcId) + } + (*call.SdkParam)["VPCs"] = bindVpcMap + + zoneNames, ok := d.GetOk("zone_name") + if ok { + zoneNamesSet, ok := zoneNames.(*schema.Set) + if ok { + arr := make([]string, 0) + for _, zone := range zoneNamesSet.List() { + arr = append(arr, zone.(string)) + } + (*call.SdkParam)["ZoneName"] = strings.Join(arr, ",") + } + } + + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id, _ := ve.ObtainSdkValue("Result.RuleID", *resp) + d.SetId(strconv.Itoa(int(id.(float64)))) + return nil + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneResolverRuleService) WithResourceResponseHandlers(d map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return d, map[string]ve.ResponseConvert{ + "ID": { + TargetField: "vpc_id", + }, + "BindVpcs": { + TargetField: "vpcs", + }, + "EndpointID": { + TargetField: "endpoint_id", + }, + "ForwardIPs": { + TargetField: "forward_ips", + }, + "IP": { + TargetField: "ip", + }, + }, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcenginePrivateZoneResolverRuleService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + var callbacks []ve.Callback + + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "UpdateResolverRule", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "name": { + TargetField: "Name", + }, + "line": { + TargetField: "Line", + }, + "forward_ips": { + Ignore: true, + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + id, err := strconv.Atoi(d.Id()) + if err != nil { + return false, err + } + (*call.SdkParam)["RuleID"] = id + + if d.HasChange("forward_ips") { + ips, ok := d.GetOk("forward_ips") + if ok { + var results []interface{} + for _, ip := range ips.(*schema.Set).List() { + ipMap := ip.(map[string]interface{}) + result := make(map[string]interface{}) + if _, ok = ipMap["ip"]; ok { + result["IP"] = ipMap["ip"] + } + if _, ok = ipMap["port"]; ok { + result["Port"] = ipMap["port"] + } + if len(result) > 0 { + results = append(results, result) + } + } + (*call.SdkParam)["ForwardIPs"] = results + } + } + + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.ReqFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + }, + } + + callbacks = append(callbacks, callback) + + if resourceData.HasChange("vpcs") { + bindVpcCallback := ve.Callback{ + Call: ve.SdkCall{ + Action: "BindRuleVPC", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "vpcs": { + Ignore: true, + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + id, err := strconv.Atoi(d.Id()) + if err != nil { + return false, err + } + (*call.SdkParam)["RuleID"] = id + + vpcSet, ok := d.Get("vpcs").(*schema.Set) + if !ok { + return false, fmt.Errorf(" vpcs is not set ") + } + bindVpcMap := make(map[string][]string) + for _, v := range vpcSet.List() { + var ( + region string + vpcId string + ) + vpcMap, ok := v.(map[string]interface{}) + if !ok { + return false, fmt.Errorf(" vpcs value is not map ") + } + vpcId = vpcMap["vpc_id"].(string) + if regionId, exist := vpcMap["region"]; exist { + region = regionId.(string) + } else { + region = client.Region + } + bindVpcMap[region] = append(bindVpcMap[region], vpcId) + } + (*call.SdkParam)["VPCs"] = bindVpcMap + + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.ReqFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + }, + } + callbacks = append(callbacks, bindVpcCallback) + } + + return callbacks +} + +func (s *VolcenginePrivateZoneResolverRuleService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "DeleteResolverRule", + ConvertMode: ve.RequestConvertIgnore, + ContentType: ve.ContentTypeJson, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + id, err := strconv.Atoi(d.Id()) + if err != nil { + return false, err + } + (*call.SdkParam)["RuleID"] = id + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + return ve.CheckResourceUtilRemoved(d, s.ReadResource, 5*time.Minute) + }, + CallError: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall, baseErr error) error { + //出现错误后重试 + return resource.Retry(15*time.Minute, func() *resource.RetryError { + _, callErr := s.ReadResource(d, "") + if callErr != nil { + if ve.ResourceNotFoundError(callErr) { + return nil + } else { + return resource.NonRetryableError(fmt.Errorf("error on reading private zone resolver rule on delete %q, %w", d.Id(), callErr)) + } + } + _, callErr = call.ExecuteCall(d, client, call) + if callErr == nil { + return nil + } + return resource.RetryableError(callErr) + }) + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneResolverRuleService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "endpoint_id": { + TargetField: "EndpointID", + }, + }, + NameField: "Name", + IdField: "RuleId", + CollectField: "rules", + ResponseConverts: map[string]ve.ResponseConvert{ + "RuleId": { + TargetField: "id", + }, + "RID": { + TargetField: "rule_id", + }, + "EndpointID": { + TargetField: "endpoint_id", + }, + "ForwardIPs": { + TargetField: "forward_ips", + }, + "IP": { + TargetField: "ip", + }, + }, + } +} + +func (s *VolcenginePrivateZoneResolverRuleService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} + +func getPostUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.POST, + ContentType: ve.ApplicationJSON, + Action: actionName, + } +} diff --git a/volcengine/private_zone/private_zone_user_vpc_authorization/resource_volcengine_private_zone_user_vpc_authorization.go b/volcengine/private_zone/private_zone_user_vpc_authorization/resource_volcengine_private_zone_user_vpc_authorization.go new file mode 100644 index 00000000..76278c95 --- /dev/null +++ b/volcengine/private_zone/private_zone_user_vpc_authorization/resource_volcengine_private_zone_user_vpc_authorization.go @@ -0,0 +1,79 @@ +package private_zone_user_vpc_authorization + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +PrivateZoneUserVpcAuthorization can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_user_vpc_authorization.default resource_id +``` + +*/ + +func ResourceVolcenginePrivateZoneUserVpcAuthorization() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcenginePrivateZoneUserVpcAuthorizationCreate, + Read: resourceVolcenginePrivateZoneUserVpcAuthorizationRead, + Delete: resourceVolcenginePrivateZoneUserVpcAuthorizationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "account_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The account Id which authorizes the private zone resource.", + }, + }, + } + return resource +} + +func resourceVolcenginePrivateZoneUserVpcAuthorizationCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneUserVpcAuthorizationService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Create(service, d, ResourceVolcenginePrivateZoneUserVpcAuthorization()) + if err != nil { + return fmt.Errorf("error on creating private_zone_user_vpc_authorization %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneUserVpcAuthorizationRead(d, meta) +} + +func resourceVolcenginePrivateZoneUserVpcAuthorizationRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneUserVpcAuthorizationService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Read(service, d, ResourceVolcenginePrivateZoneUserVpcAuthorization()) + if err != nil { + return fmt.Errorf("error on reading private_zone_user_vpc_authorization %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcenginePrivateZoneUserVpcAuthorizationUpdate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneUserVpcAuthorizationService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Update(service, d, ResourceVolcenginePrivateZoneUserVpcAuthorization()) + if err != nil { + return fmt.Errorf("error on updating private_zone_user_vpc_authorization %q, %s", d.Id(), err) + } + return resourceVolcenginePrivateZoneUserVpcAuthorizationRead(d, meta) +} + +func resourceVolcenginePrivateZoneUserVpcAuthorizationDelete(d *schema.ResourceData, meta interface{}) (err error) { + service := NewPrivateZoneUserVpcAuthorizationService(meta.(*ve.SdkClient)) + err = service.Dispatcher.Delete(service, d, ResourceVolcenginePrivateZoneUserVpcAuthorization()) + if err != nil { + return fmt.Errorf("error on deleting private_zone_user_vpc_authorization %q, %s", d.Id(), err) + } + return err +} diff --git a/volcengine/private_zone/private_zone_user_vpc_authorization/service_volcengine_private_zone_user_vpc_authorization.go b/volcengine/private_zone/private_zone_user_vpc_authorization/service_volcengine_private_zone_user_vpc_authorization.go new file mode 100644 index 00000000..bfff8b92 --- /dev/null +++ b/volcengine/private_zone/private_zone_user_vpc_authorization/service_volcengine_private_zone_user_vpc_authorization.go @@ -0,0 +1,192 @@ +package private_zone_user_vpc_authorization + +import ( + "encoding/json" + "errors" + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcenginePrivateZoneUserVpcAuthorizationService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewPrivateZoneUserVpcAuthorizationService(c *ve.SdkClient) *VolcenginePrivateZoneUserVpcAuthorizationService { + return &VolcenginePrivateZoneUserVpcAuthorizationService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 100, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "ListAuthorizedUsers" + + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + + results, err = ve.ObtainSdkValue("Result.Users", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.Users is not Slice") + } + return data, err + }) +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + + req := map[string]interface{}{} + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + for _, v := range results { + user, ok := v.(map[string]interface{}) + if !ok { + return data, errors.New("Value is not map ") + } + if user["AccountID"].(string) == id { + data = user + break + } + } + if len(data) == 0 { + return data, fmt.Errorf("private_zone_user_vpc_authorization %s not exist ", id) + } + return data, err +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{} +} + +func (VolcenginePrivateZoneUserVpcAuthorizationService) WithResourceResponseHandlers(d map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return d, map[string]ve.ResponseConvert{ + "AccountID": { + TargetField: "account_id", + }, + }, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "CreateAuthorizedUser", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeJson, + Convert: map[string]ve.RequestConvert{ + "account_id": { + TargetField: "AccountID", + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id := d.Get("account_id") + d.SetId(id.(string)) + return nil + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "DeleteAuthorizedUser", + ConvertMode: ve.RequestConvertIgnore, + ContentType: ve.ContentTypeJson, + SdkParam: &map[string]interface{}{ + "AccountID": resourceData.Id(), + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getPostUniversalInfo(call.Action), call.SdkParam) + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + return ve.CheckResourceUtilRemoved(d, s.ReadResource, 5*time.Minute) + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{} +} + +func (s *VolcenginePrivateZoneUserVpcAuthorizationService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} + +func getPostUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "private_zone", + Version: "2022-06-01", + HttpMethod: ve.POST, + ContentType: ve.ApplicationJSON, + Action: actionName, + } +} diff --git a/volcengine/provider.go b/volcengine/provider.go index 8b15ef8a..400d5186 100644 --- a/volcengine/provider.go +++ b/volcengine/provider.go @@ -10,6 +10,14 @@ import ( "strings" "time" + "github.com/volcengine/terraform-provider-volcengine/volcengine/private_zone/private_zone" + "github.com/volcengine/terraform-provider-volcengine/volcengine/private_zone/private_zone_record" + "github.com/volcengine/terraform-provider-volcengine/volcengine/private_zone/private_zone_record_set" + "github.com/volcengine/terraform-provider-volcengine/volcengine/private_zone/private_zone_record_weight_enabler" + "github.com/volcengine/terraform-provider-volcengine/volcengine/private_zone/private_zone_resolver_endpoint" + "github.com/volcengine/terraform-provider-volcengine/volcengine/private_zone/private_zone_resolver_rule" + "github.com/volcengine/terraform-provider-volcengine/volcengine/private_zone/private_zone_user_vpc_authorization" + "github.com/volcengine/terraform-provider-volcengine/volcengine/kafka/kafka_consumed_partition" "github.com/volcengine/terraform-provider-volcengine/volcengine/kafka/kafka_consumed_topic" "github.com/volcengine/terraform-provider-volcengine/volcengine/kafka/kafka_group" @@ -668,6 +676,13 @@ func Provider() terraform.ResourceProvider { "volcengine_kafka_zones": kafka_zone.DataSourceVolcengineZones(), "volcengine_kafka_consumed_topics": kafka_consumed_topic.DataSourceVolcengineKafkaConsumedTopics(), "volcengine_kafka_consumed_partitions": kafka_consumed_partition.DataSourceVolcengineKafkaConsumedPartitions(), + + // ================ PrivateZone ================ + "volcengine_private_zones": private_zone.DataSourceVolcenginePrivateZones(), + "volcengine_private_zone_resolver_endpoints": private_zone_resolver_endpoint.DataSourceVolcenginePrivateZoneResolverEndpoints(), + "volcengine_private_zone_resolver_rules": private_zone_resolver_rule.DataSourceVolcenginePrivateZoneResolverRules(), + "volcengine_private_zone_records": private_zone_record.DataSourceVolcenginePrivateZoneRecords(), + "volcengine_private_zone_record_sets": private_zone_record_set.DataSourceVolcenginePrivateZoneRecordSets(), }, ResourcesMap: map[string]*schema.Resource{ "volcengine_vpc": vpc.ResourceVolcengineVpc(), @@ -954,6 +969,14 @@ func Provider() terraform.ResourceProvider { "volcengine_kafka_topic": kafka_topic.ResourceVolcengineKafkaTopic(), "volcengine_kafka_instance": kafka_instance.ResourceVolcengineKafkaInstance(), "volcengine_kafka_public_address": kafka_public_address.ResourceVolcengineKafkaPublicAddress(), + + // ================ PrivateZone ================ + "volcengine_private_zone": private_zone.ResourceVolcenginePrivateZone(), + "volcengine_private_zone_resolver_endpoint": private_zone_resolver_endpoint.ResourceVolcenginePrivateZoneResolverEndpoint(), + "volcengine_private_zone_resolver_rule": private_zone_resolver_rule.ResourceVolcenginePrivateZoneResolverRule(), + "volcengine_private_zone_record": private_zone_record.ResourceVolcenginePrivateZoneRecord(), + "volcengine_private_zone_record_weight_enabler": private_zone_record_weight_enabler.ResourceVolcenginePrivateZoneRecordWeightEnabler(), + "volcengine_private_zone_user_vpc_authorization": private_zone_user_vpc_authorization.ResourceVolcenginePrivateZoneUserVpcAuthorization(), }, ConfigureFunc: ProviderConfigure, } diff --git a/website/docs/d/private_zone_record_sets.html.markdown b/website/docs/d/private_zone_record_sets.html.markdown new file mode 100644 index 00000000..c2a637f3 --- /dev/null +++ b/website/docs/d/private_zone_record_sets.html.markdown @@ -0,0 +1,36 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_record_sets" +sidebar_current: "docs-volcengine-datasource-private_zone_record_sets" +description: |- + Use this data source to query detailed information of private zone record sets +--- +# volcengine_private_zone_record_sets +Use this data source to query detailed information of private zone record sets +## Example Usage +```hcl +data "volcengine_private_zone_record_sets" "foo" { + zid = 245 * * * * +} +``` +## Argument Reference +The following arguments are supported: +* `zid` - (Required) The zid of Private Zone. +* `host` - (Optional) The host of Private Zone Record Set. +* `output_file` - (Optional) File name where to save data source results. +* `record_set_id` - (Optional) The id of Private Zone Record Set. +* `search_mode` - (Optional) The search mode of query `host`. Valid values: `LIKE`, `EXACT`. Default is `LIKE`. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `record_sets` - The collection of query. + * `fqdn` - The Complete domain name of the private zone record. + * `host` - The host of the private zone record. + * `line` - The subnet id of the private zone record. This field is only effected when the `intelligent_mode` of the private zone is true. + * `record_set_id` - The id of the private zone record set. + * `type` - The type of the private zone record. + * `weight_enabled` - Whether to enable the load balance of the private zone record set. +* `total_count` - The total count of query. + + diff --git a/website/docs/d/private_zone_records.html.markdown b/website/docs/d/private_zone_records.html.markdown new file mode 100644 index 00000000..bfa302ac --- /dev/null +++ b/website/docs/d/private_zone_records.html.markdown @@ -0,0 +1,49 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_records" +sidebar_current: "docs-volcengine-datasource-private_zone_records" +description: |- + Use this data source to query detailed information of private zone records +--- +# volcengine_private_zone_records +Use this data source to query detailed information of private zone records +## Example Usage +```hcl +data "volcengine_private_zone_records" "foo" { + zid = 245 * * * * + record_id = "907925684878276****" +} +``` +## Argument Reference +The following arguments are supported: +* `host` - (Optional) The host of Private Zone Record. +* `last_operator` - (Optional) The last operator account id of Private Zone Record. +* `line` - (Optional) The subnet id of Private Zone Record. This field is only effected when the `intelligent_mode` of the private zone is true. +* `name` - (Optional) The domain name of Private Zone Record. +* `output_file` - (Optional) File name where to save data source results. +* `record_id` - (Optional) The id of Private Zone Record. +* `search_mode` - (Optional) The search mode of query `host`. Valid values: `LIKE`, `EXACT`. Default is `LIKE`. +* `type` - (Optional) The type of Private Zone Record. +* `value` - (Optional) The value of Private Zone Record. +* `zid` - (Optional) The zid of Private Zone. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `records` - The collection of query. + * `created_at` - The created time of the private zone record. + * `enable` - Whether the private zone record is enabling. + * `host` - The host of the private zone record. + * `last_operator` - The last operator account id of the private zone record. + * `line` - The subnet id of the private zone record. This field is only effected when the `intelligent_mode` of the private zone is true. + * `record_id` - The id of the private zone record. + * `remark` - The remark of the private zone record. + * `ttl` - The ttl of the private zone record. Unit: second. + * `type` - The type of the private zone record. + * `updated_at` - The updated time of the private zone record. + * `value` - The value of the private zone record. + * `weight` - The weight of the private zone record. + * `zid` - The zid of the private zone record. +* `total_count` - The total count of query. + + diff --git a/website/docs/d/private_zone_resolver_endpoints.html.markdown b/website/docs/d/private_zone_resolver_endpoints.html.markdown new file mode 100644 index 00000000..1beef678 --- /dev/null +++ b/website/docs/d/private_zone_resolver_endpoints.html.markdown @@ -0,0 +1,43 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_resolver_endpoints" +sidebar_current: "docs-volcengine-datasource-private_zone_resolver_endpoints" +description: |- + Use this data source to query detailed information of private zone resolver endpoints +--- +# volcengine_private_zone_resolver_endpoints +Use this data source to query detailed information of private zone resolver endpoints +## Example Usage +```hcl +data "volcengine_private_zone_resolver_endpoints" "foo" {} +``` +## Argument Reference +The following arguments are supported: +* `direction` - (Optional) The direction of the private zone resolver endpoint. +* `name_regex` - (Optional) A Name Regex of Resource. +* `name` - (Optional) The name of the private zone resolver endpoint. +* `output_file` - (Optional) File name where to save data source results. +* `status` - (Optional) The status of the private zone resolver endpoint. +* `vpc_id` - (Optional) The vpc ID of the private zone resolver endpoint. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `endpoints` - The collection of query. + * `created_at` - The created time of the endpoint. + * `direction` - The direction of the endpoint. + * `endpoint_id` - The endpoint id. + * `id` - The id of the endpoint. + * `ip_configs` - List of IP configurations. + * `az_id` - The availability zone id of the endpoint. + * `ip` - The IP address of the endpoint. + * `subnet_id` - The subnet id of the endpoint. + * `name` - The name of the endpoint. + * `security_group_id` - The security group id of the endpoint. + * `status` - The status of the endpoint. + * `updated_at` - The updated time of the endpoint. + * `vpc_id` - The vpc id of the endpoint. + * `vpc_region` - The vpc region of the endpoint. +* `total_count` - The total count of query. + + diff --git a/website/docs/d/private_zone_resolver_rules.html.markdown b/website/docs/d/private_zone_resolver_rules.html.markdown new file mode 100644 index 00000000..1561ab85 --- /dev/null +++ b/website/docs/d/private_zone_resolver_rules.html.markdown @@ -0,0 +1,40 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_resolver_rules" +sidebar_current: "docs-volcengine-datasource-private_zone_resolver_rules" +description: |- + Use this data source to query detailed information of private zone resolver rules +--- +# volcengine_private_zone_resolver_rules +Use this data source to query detailed information of private zone resolver rules +## Example Usage +```hcl +data "volcengine_private_zone_resolver_rules" "foo" {} +``` +## Argument Reference +The following arguments are supported: +* `endpoint_id` - (Optional) ID of the exit terminal node. +* `name_regex` - (Optional) A Name Regex of Resource. +* `name` - (Optional) The name of the rule. +* `output_file` - (Optional) File name where to save data source results. +* `zone_name` - (Optional) The main domain associated with the forwarding rule. For example, if you set this parameter to example.com, DNS requests for example.com and all subdomains of example.com will be forwarded. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `rules` - The collection of query. + * `created_at` - The created time of the rule. + * `endpoint_id` - The endpoint ID of the rule. + * `forward_ips` - The IP address and port of the DNS server outside of the VPC. + * `ip` - The IP address of the DNS server outside of the VPC. + * `port` - The port of the DNS server outside of the VPC. + * `id` - The id of the rule. + * `line` - The ISP of the exit IP address of the recursive DNS server. + * `name` - The name of the rule. + * `rule_id` - The id of the rule. + * `type` - The type of the rule. + * `updated_at` - The updated time of the rule. + * `zone_name` - The zone name of the rule. +* `total_count` - The total count of query. + + diff --git a/website/docs/d/private_zones.html.markdown b/website/docs/d/private_zones.html.markdown new file mode 100644 index 00000000..1bc669a0 --- /dev/null +++ b/website/docs/d/private_zones.html.markdown @@ -0,0 +1,54 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zones" +sidebar_current: "docs-volcengine-datasource-private_zones" +description: |- + Use this data source to query detailed information of private zones +--- +# volcengine_private_zones +Use this data source to query detailed information of private zones +## Example Usage +```hcl +data "volcengine_private_zones" "foo" { + zid = 77 * * * * + zone_name = "volces.com" + search_mode = "EXACT" + recursion_mode = true + line_mode = 3 +} +``` +## Argument Reference +The following arguments are supported: +* `line_mode` - (Optional) The line mode of Private Zone, specified whether the intelligent mode and the load balance function is enabled. +* `name_regex` - (Optional) A Name Regex of Resource. +* `output_file` - (Optional) File name where to save data source results. +* `recursion_mode` - (Optional) Whether the recursion mode of Private Zone is enabled. +* `region` - (Optional) The region of Private Zone. +* `search_mode` - (Optional) The search mode of query. Valid values: `LIKE`, `EXACT`. Default is `LIKE`. +* `vpc_id` - (Optional) The vpc id associated to Private Zone. +* `zid` - (Optional) The zid of Private Zone. +* `zone_name` - (Optional) The name of Private Zone. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `private_zones` - The collection of query. + * `bind_vpcs` - The Bind vpc info of the private zone. + * `account_id` - The account id of the bind vpc. + * `id` - The id of the bind vpc. + * `region_name` - The region name of the bind vpc. + * `region` - The region of the bind vpc. + * `created_at` - The created time of the private zone. + * `id` - The id of the private zone. + * `last_operator` - The account id of the last operator who created the private zone. + * `line_mode` - The line mode of the private zone, specified whether the intelligent mode and the load balance function is enabled. + * `record_count` - The record count of the private zone. + * `recursion_mode` - Whether the recursion mode of the private zone is enabled. + * `region` - The region of the private zone. + * `remark` - The remark of the private zone. + * `updated_at` - The updated time of the private zone. + * `zid` - The id of the private zone. + * `zone_name` - The id of the private zone. +* `total_count` - The total count of query. + + diff --git a/website/docs/r/private_zone.html.markdown b/website/docs/r/private_zone.html.markdown new file mode 100644 index 00000000..323e2bb3 --- /dev/null +++ b/website/docs/r/private_zone.html.markdown @@ -0,0 +1,53 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone" +sidebar_current: "docs-volcengine-resource-private_zone" +description: |- + Provides a resource to manage private zone +--- +# volcengine_private_zone +Provides a resource to manage private zone +## Example Usage +```hcl +resource "volcengine_private_zone" "foo" { + zone_name = "acc-test-pz.com" + remark = "acc-test-new" + recursion_mode = true + intelligent_mode = true + load_balance_mode = true + vpcs { + vpc_id = "vpc-rs4mi0jedipsv0x57pf****" + } + vpcs { + vpc_id = "vpc-3qdzk9xju6o747prml0jk****" + region = "cn-shanghai" + } +} +``` +## Argument Reference +The following arguments are supported: +* `vpcs` - (Required) The bind vpc object of the private zone. If you want to bind another account's VPC, you need to first use resource volcengine_private_zone_user_vpc_authorization to complete the authorization. +* `zone_name` - (Required, ForceNew) The name of the private zone. +* `intelligent_mode` - (Optional, ForceNew) Whether to enable the intelligent mode of the private zone. +* `load_balance_mode` - (Optional) Whether to enable the load balance mode of the private zone. +* `recursion_mode` - (Optional) Whether to enable the recursion mode of the private zone. +* `remark` - (Optional) The remark of the private zone. + +The `vpcs` object supports the following: + +* `vpc_id` - (Required) The id of the bind vpc. +* `region` - (Optional) The region of the bind vpc. The default value is the region of the default provider config. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. + + + +## Import +PrivateZone can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone.default resource_id +``` + diff --git a/website/docs/r/private_zone_record.html.markdown b/website/docs/r/private_zone_record.html.markdown new file mode 100644 index 00000000..c036d144 --- /dev/null +++ b/website/docs/r/private_zone_record.html.markdown @@ -0,0 +1,58 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_record" +sidebar_current: "docs-volcengine-resource-private_zone_record" +description: |- + Provides a resource to manage private zone record +--- +# volcengine_private_zone_record +Provides a resource to manage private zone record +## Example Usage +```hcl +resource "volcengine_private_zone_record" "foo" { + zid = 245 * * * * + host = "www" + type = "A" + value = "10.1.1.158" + weight = 8 + ttl = 700 + remark = "tf-test" + enable = true +} + +data "volcengine_private_zone_record_sets" "foo" { + zid = volcengine_private_zone_record.foo.zid + host = volcengine_private_zone_record.foo.host + search_mode = "EXACT" +} + +resource "volcengine_private_zone_record_weight_enabler" "foo" { + zid = volcengine_private_zone_record.foo.zid + record_set_id = [for set in data.volcengine_private_zone_record_sets.foo.record_sets : set.record_set_id if set.type == volcengine_private_zone_record.foo.type][0] + weight_enabled = true +} +``` +## Argument Reference +The following arguments are supported: +* `host` - (Required) The host of the private zone record. +* `type` - (Required) The type of the private zone record. Valid values: `A`, `AAAA`, `CNAME`, `MX`, `PTR`. +* `value` - (Required) The value of the private zone record. Record values need to be set based on the value of the `type`. +* `zid` - (Required, ForceNew) The zid of the private zone record. +* `enable` - (Optional) Whether to enable the private zone record. This field is only effected when modify this resource. +* `remark` - (Optional) The remark of the private zone record. +* `ttl` - (Optional) The ttl of the private zone record. Unit: second. Default is 600. +* `weight` - (Optional) The weight of the private zone record. This field is only effected when the `load_balance_mode` of the private zone is true and the `weight_enabled` of the record_set is true. Default is 1. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. + + + +## Import +PrivateZoneRecord can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_record.default resource_id +``` + diff --git a/website/docs/r/private_zone_record_weight_enabler.html.markdown b/website/docs/r/private_zone_record_weight_enabler.html.markdown new file mode 100644 index 00000000..e1f6451e --- /dev/null +++ b/website/docs/r/private_zone_record_weight_enabler.html.markdown @@ -0,0 +1,53 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_record_weight_enabler" +sidebar_current: "docs-volcengine-resource-private_zone_record_weight_enabler" +description: |- + Provides a resource to manage private zone record weight enabler +--- +# volcengine_private_zone_record_weight_enabler +Provides a resource to manage private zone record weight enabler +## Example Usage +```hcl +resource "volcengine_private_zone_record" "foo" { + zid = 245 * * * * + host = "www" + type = "A" + value = "10.1.1.158" + weight = 8 + ttl = 700 + remark = "tf-test" + enable = true +} + +data "volcengine_private_zone_record_sets" "foo" { + zid = volcengine_private_zone_record.foo.zid + host = volcengine_private_zone_record.foo.host + search_mode = "EXACT" +} + +resource "volcengine_private_zone_record_weight_enabler" "foo" { + zid = volcengine_private_zone_record.foo.zid + record_set_id = [for set in data.volcengine_private_zone_record_sets.foo.record_sets : set.record_set_id if set.type == volcengine_private_zone_record.foo.type][0] + weight_enabled = true +} +``` +## Argument Reference +The following arguments are supported: +* `record_set_id` - (Required, ForceNew) The id of the private zone record set. +* `weight_enabled` - (Required) Whether to enable the load balance of the private zone record set. +* `zid` - (Required, ForceNew) The zid of the private zone record set. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. + + + +## Import +PrivateZoneRecordWeightEnabler can be imported using the zid:record_set_id, e.g. +``` +$ terraform import volcengine_private_zone_record_weight_enabler.default resource_id +``` + diff --git a/website/docs/r/private_zone_resolver_endpoint.html.markdown b/website/docs/r/private_zone_resolver_endpoint.html.markdown new file mode 100644 index 00000000..a7cc3b23 --- /dev/null +++ b/website/docs/r/private_zone_resolver_endpoint.html.markdown @@ -0,0 +1,66 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_resolver_endpoint" +sidebar_current: "docs-volcengine-resource-private_zone_resolver_endpoint" +description: |- + Provides a resource to manage private zone resolver endpoint +--- +# volcengine_private_zone_resolver_endpoint +Provides a resource to manage private zone resolver endpoint +## Example Usage +```hcl +resource "volcengine_private_zone_resolver_endpoint" "foo" { + name = "tf-test" + vpc_id = "vpc-13f9uuuqfdjb43n6nu5p1****" + vpc_region = "cn-beijing" + security_group_id = "sg-mj2nsckay29s5smt1b0d****" + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.2" + } + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.3" + } + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.4" + } + ip_configs { + az_id = "cn-beijing-a" + subnet_id = "subnet-mj2o4co2m2v45smt1bx1****" + ip = "172.16.0.5" + } +} +``` +## Argument Reference +The following arguments are supported: +* `ip_configs` - (Required) Availability zones, subnets, and IP configurations of terminal nodes. +* `name` - (Required) The name of the private zone resolver endpoint. +* `security_group_id` - (Required, ForceNew) The security group ID of the endpoint. +* `vpc_id` - (Required, ForceNew) The VPC ID of the endpoint. +* `vpc_region` - (Required, ForceNew) The VPC region of the endpoint. +* `direction` - (Optional, ForceNew) DNS request forwarding direction for terminal nodes. OUTBOUND: (default) Outbound terminal nodes forward DNS query requests from within the VPC to external DNS servers. INBOUND: Inbound terminal nodes forward DNS query requests from external sources to resolvers. + +The `ip_configs` object supports the following: + +* `az_id` - (Required) Id of the availability zone. +* `ip` - (Required) Source IP address of traffic. You can add up to 6 IP addresses at most. To ensure high availability, you must add at least two IP addresses. +* `subnet_id` - (Required) Id of the subnet. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. + + + +## Import +PrivateZoneResolverEndpoint can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_resolver_endpoint.default resource_id +``` + diff --git a/website/docs/r/private_zone_resolver_rule.html.markdown b/website/docs/r/private_zone_resolver_rule.html.markdown new file mode 100644 index 00000000..87ddfb77 --- /dev/null +++ b/website/docs/r/private_zone_resolver_rule.html.markdown @@ -0,0 +1,59 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_resolver_rule" +sidebar_current: "docs-volcengine-resource-private_zone_resolver_rule" +description: |- + Provides a resource to manage private zone resolver rule +--- +# volcengine_private_zone_resolver_rule +Provides a resource to manage private zone resolver rule +## Example Usage +```hcl +resource "volcengine_private_zone_resolver_rule" "foo" { + endpoint_id = 346 + name = "tf0" + type = "OUTBOUND" + vpcs { + region = "cn-beijing" + vpc_id = "vpc-13f9uuuqfdjb43n6nu5p1****" + } + forward_ips { + ip = "10.199.38.19" + port = 33 + } + zone_name = ["www.baidu.com"] +} +``` +## Argument Reference +The following arguments are supported: +* `name` - (Required) The name of the rule. +* `type` - (Required, ForceNew) Forwarding rule types. OUTBOUND: Forward to external DNS servers. LINE: Set the recursive DNS server used for recursive resolution to the recursive DNS server of the Volcano Engine PublicDNS, and customize the operator's exit IP address for the recursive DNS server. +* `vpcs` - (Required) The parameter name <region> is a variable that represents the region where the VPC is located, such as cn-beijing. The parameter value can include one or more VPC IDs, such as vpc-2750bd1. For example, if you associate a VPC in the cn-beijing region with a domain name and the VPC ID is vpc-2d6si87atfh1c58ozfd0nzq8k, the parameter would be "cn-beijing":["vpc-2d6si87atfh1c58ozfd0nzq8k"]. You can add one or more regions. When the Type parameter is OUTBOUND, the VPC region must be the same as the region where the endpoint is located. +* `endpoint_id` - (Optional, ForceNew) Terminal node ID. This parameter is only valid and required when the Type parameter is OUTBOUND. +* `forward_ips` - (Optional) IP address and port of external DNS server. You can add up to 10 IP addresses. This parameter is only valid when the Type parameter is OUTBOUND and is a required parameter. +* `line` - (Optional) The operator of the exit IP address of the recursive DNS server. This parameter is only valid when the Type parameter is LINE and is a required parameter. MOBILE, TELECOM, UNICOM. +* `zone_name` - (Optional, ForceNew) Domain names associated with forwarding rules. You can enter one or more domain names. Up to 500 domain names are supported. This parameter is only valid when the Type parameter is OUTBOUND and is a required parameter. + +The `forward_ips` object supports the following: + +* `ip` - (Required) IP address of the external DNS server. This parameter is only valid when the Type parameter is OUTBOUND and is a required parameter. +* `port` - (Optional) The port of the external DNS server. Default is 53. This parameter is only valid and optional when the Type parameter is OUTBOUND. + +The `vpcs` object supports the following: + +* `vpc_id` - (Required) The id of the bind vpc. +* `region` - (Optional) The region of the bind vpc. The default value is the region of the default provider config. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. + + + +## Import +PrivateZoneResolverRule can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_resolver_rule.default resource_id +``` + diff --git a/website/docs/r/private_zone_user_vpc_authorization.html.markdown b/website/docs/r/private_zone_user_vpc_authorization.html.markdown new file mode 100644 index 00000000..ca8b2735 --- /dev/null +++ b/website/docs/r/private_zone_user_vpc_authorization.html.markdown @@ -0,0 +1,32 @@ +--- +subcategory: "PRIVATE_ZONE" +layout: "volcengine" +page_title: "Volcengine: volcengine_private_zone_user_vpc_authorization" +sidebar_current: "docs-volcengine-resource-private_zone_user_vpc_authorization" +description: |- + Provides a resource to manage private zone user vpc authorization +--- +# volcengine_private_zone_user_vpc_authorization +Provides a resource to manage private zone user vpc authorization +## Example Usage +```hcl +resource "volcengine_private_zone_user_vpc_authorization" "foo" { + account_id = "2100278462" +} +``` +## Argument Reference +The following arguments are supported: +* `account_id` - (Required, ForceNew) The account Id which authorizes the private zone resource. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. + + + +## Import +PrivateZoneUserVpcAuthorization can be imported using the id, e.g. +``` +$ terraform import volcengine_private_zone_user_vpc_authorization.default resource_id +``` + diff --git a/website/docs/r/vke_node_pool.html.markdown b/website/docs/r/vke_node_pool.html.markdown index 45c80d45..b2af1e66 100644 --- a/website/docs/r/vke_node_pool.html.markdown +++ b/website/docs/r/vke_node_pool.html.markdown @@ -166,12 +166,12 @@ resource "volcengine_vke_node_pool" "foo1" { image_id = [for image in data.volcengine_images.foo.images : image.image_id if image.image_name == "veLinux 1.0 CentOS兼容版 64位"][0] system_volume { type = "ESSD_PL0" - size = "50" + size = 50 } data_volumes { type = "ESSD_PL0" - size = "50" - mount_point = "/tf" + size = 50 + mount_point = "/tf1" } initialize_script = "ZWNobyBoZWxsbyB0ZXJyYWZvcm0h" security { diff --git a/website/volcengine.erb b/website/volcengine.erb index 321294b3..65d053bc 100644 --- a/website/volcengine.erb +++ b/website/volcengine.erb @@ -1132,6 +1132,54 @@ </li> </ul> </li> + <li> + <a href="#">PRIVATE_ZONE</a> + <ul class="nav"> + <li> + <a href="#">Data Sources</a> + <ul class="nav nav-auto-expand"> + <li> + <a href="/docs/providers/volcengine/d/private_zones.html">private_zones</a> + </li> + <li> + <a href="/docs/providers/volcengine/d/private_zone_records.html">private_zone_records</a> + </li> + <li> + <a href="/docs/providers/volcengine/d/private_zone_record_sets.html">private_zone_record_sets</a> + </li> + <li> + <a href="/docs/providers/volcengine/d/private_zone_resolver_endpoints.html">private_zone_resolver_endpoints</a> + </li> + <li> + <a href="/docs/providers/volcengine/d/private_zone_resolver_rules.html">private_zone_resolver_rules</a> + </li> + </ul> + </li> + <li> + <a href="#">Resources</a> + <ul class="nav nav-auto-expand"> + <li> + <a href="/docs/providers/volcengine/r/private_zone.html">private_zone</a> + </li> + <li> + <a href="/docs/providers/volcengine/r/private_zone_record.html">private_zone_record</a> + </li> + <li> + <a href="/docs/providers/volcengine/r/private_zone_record_weight_enabler.html">private_zone_record_weight_enabler</a> + </li> + <li> + <a href="/docs/providers/volcengine/r/private_zone_resolver_endpoint.html">private_zone_resolver_endpoint</a> + </li> + <li> + <a href="/docs/providers/volcengine/r/private_zone_resolver_rule.html">private_zone_resolver_rule</a> + </li> + <li> + <a href="/docs/providers/volcengine/r/private_zone_user_vpc_authorization.html">private_zone_user_vpc_authorization</a> + </li> + </ul> + </li> + </ul> + </li> <li> <a href="#">RDS_MSSQL</a> <ul class="nav">