Skip to content

Commit

Permalink
added enhancement to one step delegate resolver in is_vpc
Browse files Browse the repository at this point in the history
  • Loading branch information
ujjwal-ibm authored and hkantare committed Dec 19, 2023
1 parent 9c89bf1 commit c69efb6
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 2 deletions.
96 changes: 95 additions & 1 deletion ibm/service/vpc/resource_ibm_is_vpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,18 @@ func ResourceIBMISVPC() *schema.Resource {
Computed: true,
Description: "The type of the DNS resolver used for the VPC.- `delegated`: DNS server addresses are provided by the DNS resolver of the VPC specified in `dns.resolver.vpc`.- `manual`: DNS server addresses are specified in `dns.resolver.manual_servers`.- `system`: DNS server addresses are provided by the system.",
},

"dns_binding_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
Description: "The VPC dns binding id whose DNS resolver provides the DNS server addresses for this VPC.",
},
"dns_binding_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The VPC dns binding name whose DNS resolver provides the DNS server addresses for this VPC.",
},
"vpc_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -714,6 +726,51 @@ func vpcCreate(d *schema.ResourceData, meta interface{}, name, apm, rg string, i
return err
}

if dnsresolvertpeOk, ok := d.GetOk("dns.0.resolver.0.type"); ok {
if dnsresolvertpeOk.(string) == "delegated" && d.Get("dns.0.resolver.0.vpc_id").(string) != "" {
vpcId := d.Get("dns.0.resolver.0.vpc_id").(string)
createDnsBindings := &vpcv1.CreateVPCDnsResolutionBindingOptions{
VPCID: vpc.ID,
VPC: &vpcv1.VPCIdentity{
ID: &vpcId,
},
}
if bindingNameOk, ok := d.GetOk("dns.0.resolver.0.dns_binding_name"); ok {
bindingName := bindingNameOk.(string)
createDnsBindings.Name = &bindingName
}
_, response, err := sess.CreateVPCDnsResolutionBinding(createDnsBindings)
if err != nil {
log.Printf("[DEBUG] CreateVPCDnsResolutionBindingWithContext failed %s\n%s", err, response)
return fmt.Errorf("[ERROR] CreateVPCDnsResolutionBinding failed in vpc resource %s\n%s", err, response)
}
resolverType := "delegated"
dnsPatch := &vpcv1.VpcdnsPatch{
Resolver: &vpcv1.VpcdnsResolverPatch{
Type: &resolverType,
VPC: &vpcv1.VpcdnsResolverVPCPatch{
ID: &vpcId,
},
},
}
vpcPatchModel := &vpcv1.VPCPatch{}
vpcPatchModel.Dns = dnsPatch
vpcPatchModelAsPatch, err := vpcPatchModel.AsPatch()
if err != nil {
return fmt.Errorf("[ERROR] CreateVPCDnsResolutionBinding failed in vpcpatch as patch %s", err)
}
updateVpcOptions := &vpcv1.UpdateVPCOptions{
ID: vpc.ID,
}
updateVpcOptions.VPCPatch = vpcPatchModelAsPatch
_, response, err = sess.UpdateVPC(updateVpcOptions)
if err != nil {
log.Printf("[DEBUG] Update vpc with delegated failed %s\n%s", err, response)
return fmt.Errorf("[ERROR] Update vpc with delegated failed in vpc resource %s\n%s", err, response)
}
}
}

if sgAclRules, ok := d.GetOk(isVPCNoSgAclRules); ok {
sgAclRules := sgAclRules.(bool)
if sgAclRules {
Expand Down Expand Up @@ -920,6 +977,38 @@ func vpcGet(d *schema.ResourceData, meta interface{}, id string) error {
if err != nil {
return err
}
resolverMapArray := dnsMap["resolver"].([]map[string]interface{})
resolverMap := resolverMapArray[0]
if resolverMap["type"] != nil && resolverMap["vpc_id"] != nil {
resType := resolverMap["type"].(*string)
resVpc := resolverMap["vpc_id"].(string)
if *resType == "delegated" {
listVPCDnsResolutionBindingOptions := &vpcv1.ListVPCDnsResolutionBindingsOptions{
VPCID: vpc.ID,
}

pager, err := sess.NewVPCDnsResolutionBindingsPager(listVPCDnsResolutionBindingOptions)
if err != nil {
return fmt.Errorf("[ERROR] Error getting VPC dns bindings: %s", err)
}
var allResults []vpcv1.VpcdnsResolutionBinding
for pager.HasNext() {
nextPage, err := pager.GetNext()
if err != nil {
return fmt.Errorf("[ERROR] Error getting VPC dns bindings pager next: %s", err)
}
allResults = append(allResults, nextPage...)
}
for _, binding := range allResults {
if *binding.VPC.ID == resVpc {
resolverMap["dns_binding_id"] = binding.ID
resolverMap["dns_binding_name"] = binding.Name
resolverMapArray[0] = resolverMap
dnsMap["resolver"] = resolverMapArray
}
}
}
}
if err = d.Set(isVPCDns, []map[string]interface{}{dnsMap}); err != nil {
return fmt.Errorf("[ERROR] Error setting dns: %s", err)
}
Expand Down Expand Up @@ -1543,7 +1632,11 @@ func resourceIBMIsVPCMapToVpcdnsPrototype(modelMap map[string]interface{}) (*vpc
func resourceIBMIsVPCMapToVpcdnsResolverPrototype(modelMap map[string]interface{}) (vpcv1.VpcdnsResolverPrototypeIntf, error) {
model := &vpcv1.VpcdnsResolverPrototype{}
if modelMap["type"] != nil && modelMap["type"].(string) != "" {
model.Type = core.StringPtr(modelMap["type"].(string))
if modelMap["type"].(string) == "delegated" {
model.Type = core.StringPtr("system")
} else {
model.Type = core.StringPtr(modelMap["type"].(string))
}
}
if modelMap["manual_servers"] != nil && modelMap["manual_servers"].(*schema.Set).Len() > 0 {
model.Type = core.StringPtr("manual")
Expand Down Expand Up @@ -1583,6 +1676,7 @@ func resourceIBMIsVPCVpcdnsToMap(model *vpcv1.Vpcdns, vpcId, vpcCrn string) (map
return modelMap, err
}
modelMap["resolver"] = []map[string]interface{}{resolverMap}

return modelMap, nil
}

Expand Down
110 changes: 110 additions & 0 deletions ibm/service/vpc/resource_ibm_is_vpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,53 @@ func TestAccIBMISVPC_dns_delegated(t *testing.T) {
},
})
}
func TestAccIBMISVPC_dns_delegated_first(t *testing.T) {
var vpc string
name1 := fmt.Sprintf("terraformvpcuat-%d", acctest.RandIntRange(10, 100))
name2 := fmt.Sprintf("terraformvpcuat-%d", acctest.RandIntRange(10, 100))
subnet1 := fmt.Sprintf("terraformsubnet-%d", acctest.RandIntRange(10, 100))
subnet2 := fmt.Sprintf("terraformsubnet-%d", acctest.RandIntRange(10, 100))
resourecinstance := fmt.Sprintf("terraformresource-%d", acctest.RandIntRange(10, 100))
resolver1 := fmt.Sprintf("terraformresolver-%d", acctest.RandIntRange(10, 100))
binding := fmt.Sprintf("terraformbinding-%d", acctest.RandIntRange(10, 100))
enableHubTrue := true
enableHubFalse := false
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMISVPCDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMISVPCDnsDelegatedFirstConfig(name1, name2, subnet1, subnet2, resourecinstance, resolver1, binding, enableHubTrue, enableHubFalse),
Check: resource.ComposeTestCheckFunc(
testAccCheckIBMISVPCExists("ibm_is_vpc.hub_true", vpc),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_true", "name", name1),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_false_delegated", "name", name2),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_true", "dns.0.enable_hub", fmt.Sprintf("%t", enableHubTrue)),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_true", "dns.0.resolver.0.type", "system"),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_false_delegated", "dns.0.enable_hub", fmt.Sprintf("%t", enableHubFalse)),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_false_delegated", "dns.0.resolver.0.type", "delegated"),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_false_delegated", "dns.0.resolution_binding_count", "1"),
resource.TestCheckResourceAttr(
"ibm_is_vpc.hub_false_delegated", "dns.0.resolver.0.dns_binding_name", binding),
resource.TestCheckResourceAttrSet(
"ibm_is_vpc.hub_false_delegated", "dns.0.resolver.0.dns_binding_id"),
resource.TestCheckResourceAttrSet(
"ibm_is_vpc.hub_false_delegated", "dns.0.resolver.0.vpc_id"),
resource.TestCheckResourceAttrSet(
"ibm_is_vpc.hub_false_delegated", "dns.0.resolver.0.vpc_name"),
),
},
},
})
}

func TestAccIBMISVPC_basic_apm(t *testing.T) {
var vpc string
Expand Down Expand Up @@ -597,6 +644,69 @@ func testAccCheckIBMISVPCDnsDelegatedConfig(vpcname, vpcname2, subnetname1, subn
`, vpcname, enableHub, vpcname2, enablehubfalse, subnetname1, acc.ISZoneName, subnetname2, acc.ISZoneName, subnetname3, acc.ISZoneName, subnetname4, acc.ISZoneName, resourceinstance, resolver1, resolver2, bindingname)

}
func testAccCheckIBMISVPCDnsDelegatedFirstConfig(vpcname, vpcname2, subnetname1, subnetname2, resourceinstance, resolver1, bindingname string, enableHub, enablehubfalse bool) string {
return fmt.Sprintf(`
data "ibm_resource_group" "rg" {
is_default = true
}
resource ibm_is_vpc hub_true {
name = "%s"
dns {
enable_hub = %t
}
}
resource ibm_is_vpc hub_false_delegated {
depends_on = [ ibm_dns_custom_resolver.test_hub_true ]
name = "%s"
dns {
enable_hub = %t
resolver {
type = "delegated"
vpc_id = ibm_is_vpc.hub_true.id
dns_binding_name = "%s"
}
}
}
resource "ibm_is_subnet" "hub_true_sub1" {
name = "%s"
vpc = ibm_is_vpc.hub_true.id
zone = "%s"
total_ipv4_address_count = 16
}
resource "ibm_is_subnet" "hub_true_sub2" {
name = "%s"
vpc = ibm_is_vpc.hub_true.id
zone = "%s"
total_ipv4_address_count = 16
}
resource "ibm_resource_instance" "dns-cr-instance" {
name = "%s"
resource_group_id = data.ibm_resource_group.rg.id
location = "global"
service = "dns-svcs"
plan = "standard-dns"
}
resource "ibm_dns_custom_resolver" "test_hub_true" {
name = "%s"
instance_id = ibm_resource_instance.dns-cr-instance.guid
description = "new test CR - TF"
high_availability = true
enabled = true
locations {
subnet_crn = ibm_is_subnet.hub_true_sub1.crn
enabled = true
}
locations {
subnet_crn = ibm_is_subnet.hub_true_sub2.crn
enabled = true
}
}
`, vpcname, enableHub, vpcname2, enablehubfalse, bindingname, subnetname1, acc.ISZoneName, subnetname2, acc.ISZoneName, resourceinstance, resolver1)

}
func testAccCheckIBMISVPCDnsDelegatedUpdate1Config(vpcname, vpcname2, subnetname1, subnetname2, subnetname3, subnetname4, resourceinstance, resolver1, resolver2, bindingname string, enableHub, enablehubfalse bool) string {
return fmt.Sprintf(`
Expand Down
21 changes: 20 additions & 1 deletion website/docs/r/is_vpc.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,22 @@ resource "ibm_is_vpc" "example-system" {
}
}
// delegated type resolver
resource "ibm_is_vpc" "example-delegated" {
// required : add a dependency on ibm dns custom resolver of the hub vpc
depends_on = [ ibm_dns_custom_resolver.example-hub ]
name = "example-hub-false-delegated"
dns {
enable_hub = false
resolver {
type = "delegated"
vpc_id = ibm_is_vpc.example.id
dns_binding_name = "example-vpc-binding"
}
}
}
```

## Timeouts
Expand Down Expand Up @@ -116,6 +132,9 @@ Review the argument references that you can specify for your resource.
- `resolver` - (Optional, List) The zone list this backup policy plan will create snapshot clones in.
Nested scheme for `resolver`:

- `dns_binding_id` - (String) The VPC dns binding id whose DNS resolver provides the DNS server addresses for this VPC. (If any)
- `dns_binding_name` - (Optional, String) The VPC dns binding name whose DNS resolver provides the DNS server addresses for this VPC. Only applicable for `delegated`, providing value would create binding with this name.

~> **Note:**
`manual_servers` must be set if and only if `dns.resolver.type` is manual.
- `manual_servers` - (Optional, List) The DNS servers to use for this VPC, replacing any existing servers. All the DNS servers must either: **have a unique zone_affinity**, or **not have a zone_affinity**.
Expand All @@ -139,7 +158,7 @@ Review the argument references that you can specify for your resource.
~> **Note:**
Updating from `manual` requires dns resolver `manual_servers` to be specified as null.<br/>
Updating to `manual` requires dns resolver `manual_servers` to be specified and not empty.<br/>
Updating from `delegated` requires `dns.resolver.vpc` to be specified as null.
Updating from `delegated` requires `dns.resolver.vpc` to be specified as null. If type is `delegated` while creation then `vpc_id` is required
- `vpc_id` - (Optional, List) (update only) The VPC ID to provide DNS server addresses for this VPC. The specified VPC must be configured with a DNS Services custom resolver and must be in one of this VPC's DNS resolution bindings. Mutually exclusive with `vpc_crn`

~> **Note:**
Expand Down

0 comments on commit c69efb6

Please sign in to comment.