diff --git a/ibm/data_source_ibm_is_lb.go b/ibm/data_source_ibm_is_lb.go index efc30acded..a911999930 100644 --- a/ibm/data_source_ibm_is_lb.go +++ b/ibm/data_source_ibm_is_lb.go @@ -56,6 +56,12 @@ func dataSourceIBMISLB() *schema.Resource { Description: "Load Balancer status", }, + isLBRouteMode: { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether route mode is enabled for this load balancer", + }, + isLBCrn: { Type: schema.TypeString, Computed: true, @@ -285,6 +291,7 @@ func lbGetByName(d *schema.ResourceData, meta interface{}, name string) error { d.Set(isLBType, "private") } d.Set(isLBStatus, *lb.ProvisioningStatus) + d.Set(isLBRouteMode, *lb.RouteMode) d.Set(isLBCrn, *lb.CRN) d.Set(isLBOperatingStatus, *lb.OperatingStatus) publicIpList := make([]string, 0) diff --git a/ibm/data_source_ibm_is_lb_profiles.go b/ibm/data_source_ibm_is_lb_profiles.go index 4bf2583ce4..db219fbbb3 100644 --- a/ibm/data_source_ibm_is_lb_profiles.go +++ b/ibm/data_source_ibm_is_lb_profiles.go @@ -5,6 +5,7 @@ package ibm import ( "fmt" + "reflect" "time" "github.com/IBM/vpc-go-sdk/vpcv1" @@ -42,6 +43,16 @@ func dataSourceIBMISLbProfiles() *schema.Resource { Computed: true, Description: "The product family this load balancer profile belongs to", }, + "route_mode_supported": { + Type: schema.TypeBool, + Computed: true, + Description: "The route mode support for a load balancer with this profile depends on its configuration", + }, + "route_mode_type": { + Type: schema.TypeString, + Computed: true, + Description: "The route mode type for this load balancer profile, one of [fixed, dependent]", + }, }, }, }, @@ -80,6 +91,28 @@ func dataSourceIBMISLbProfilesRead(d *schema.ResourceData, meta interface{}) err "href": *profileCollector.Href, "family": *profileCollector.Family, } + if profileCollector.RouteModeSupported != nil { + routeMode := profileCollector.RouteModeSupported + switch reflect.TypeOf(routeMode).String() { + case "*vpcv1.LoadBalancerProfileRouteModeSupportedFixed": + { + rms := routeMode.(*vpcv1.LoadBalancerProfileRouteModeSupportedFixed) + l["route_mode_supported"] = rms.Value + l["route_mode_type"] = rms.Type + } + case "*vpcv1.LoadBalancerProfileRouteModeSupportedDependent": + { + rms := routeMode.(*vpcv1.LoadBalancerProfileRouteModeSupportedDependent) + l["route_mode_type"] = *rms.Type + } + case "*vpcv1.LoadBalancerProfileRouteModeSupported": + { + rms := routeMode.(*vpcv1.LoadBalancerProfileRouteModeSupported) + l["route_mode_type"] = *rms.Type + l["route_mode_supported"] = *rms.Value + } + } + } lbprofilesInfo = append(lbprofilesInfo, l) } d.SetId(dataSourceIBMISLbProfilesID(d)) diff --git a/ibm/data_source_ibm_is_lb_test.go b/ibm/data_source_ibm_is_lb_test.go index 357485004d..294ebf33c1 100644 --- a/ibm/data_source_ibm_is_lb_test.go +++ b/ibm/data_source_ibm_is_lb_test.go @@ -15,7 +15,7 @@ func TestAccIBMISLBDatasource_basic(t *testing.T) { name := fmt.Sprintf("tflb-name-%d", acctest.RandIntRange(10, 100)) vpcname := fmt.Sprintf("tflb-vpc-%d", acctest.RandIntRange(10, 100)) subnetname := fmt.Sprintf("tflb-subnet-name-%d", acctest.RandIntRange(10, 100)) - + routeMode := "false" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -25,6 +25,8 @@ func TestAccIBMISLBDatasource_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( "data.ibm_is_lb.ds_lb", "name", name), + resource.TestCheckResourceAttr( + "data.ibm_is_lb.ds_lb", "route_mode", routeMode), ), }, }, diff --git a/ibm/data_source_ibm_is_lbs.go b/ibm/data_source_ibm_is_lbs.go index 02a3fcbe51..2c79f10962 100644 --- a/ibm/data_source_ibm_is_lbs.go +++ b/ibm/data_source_ibm_is_lbs.go @@ -54,6 +54,11 @@ func dataSourceIBMISLBS() *schema.Resource { Computed: true, Description: "Load Balancer name", }, + isLBRouteMode: { + Type: schema.TypeBool, + Computed: true, + Description: "Load Balancer route mode", + }, isLBType: { Type: schema.TypeString, @@ -250,6 +255,7 @@ func getLbs(d *schema.ResourceData, meta interface{}) error { // log.Printf("******* lb ******** : (%+v)", lb) lbInfo[ID] = *lb.ID lbInfo[isLBName] = *lb.Name + lbInfo[isLBRouteMode] = *lb.RouteMode lbInfo[CRN] = *lb.CRN lbInfo[ProvisioningStatus] = *lb.ProvisioningStatus diff --git a/ibm/data_source_ibm_is_lbs_test.go b/ibm/data_source_ibm_is_lbs_test.go index 2ed71fa907..7fe2df052f 100644 --- a/ibm/data_source_ibm_is_lbs_test.go +++ b/ibm/data_source_ibm_is_lbs_test.go @@ -34,6 +34,7 @@ func TestAccIBMISLBSDatasource_basic(t *testing.T) { Config: testDSCheckIBMISLBSDatasourceConfig(), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("data.ibm_is_lbs.test_lbs", "load_balancers.0.name"), + resource.TestCheckResourceAttrSet("data.ibm_is_lbs.test_lbs", "load_balancers.0.route_mode"), ), }, }, diff --git a/ibm/resource_ibm_is_lb.go b/ibm/resource_ibm_is_lb.go index 463eaa78d0..857264134e 100644 --- a/ibm/resource_ibm_is_lb.go +++ b/ibm/resource_ibm_is_lb.go @@ -35,6 +35,7 @@ const ( isLBProvisioningDone = "done" isLBResourceGroup = "resource_group" isLBProfile = "profile" + isLBRouteMode = "route_mode" isLBLogging = "logging" isLBSecurityGroups = "security_groups" isLBSecurityGroupsSupported = "security_group_supported" @@ -54,10 +55,16 @@ func resourceIBMISLB() *schema.Resource { Delete: schema.DefaultTimeout(30 * time.Minute), }, - CustomizeDiff: customdiff.Sequence( - func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { - return resourceTagsCustomizeDiff(diff) - }, + CustomizeDiff: customdiff.All( + customdiff.Sequence( + func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { + return resourceTagsCustomizeDiff(diff) + }, + ), + customdiff.Sequence( + func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { + return resourceRouteModeValidate(diff) + }), ), Schema: map[string]*schema.Schema{ @@ -156,6 +163,14 @@ func resourceIBMISLB() *schema.Resource { Computed: true, }, + isLBRouteMode: { + Type: schema.TypeBool, + ForceNew: true, + Optional: true, + Default: false, + Description: "Indicates whether route mode is enabled for this load balancer", + }, + isLBHostName: { Type: schema.TypeString, Computed: true, @@ -271,7 +286,7 @@ func resourceIBMISLBCreate(d *schema.ResourceData, meta interface{}) error { return resourceIBMISLBRead(d, meta) } -func lbCreate(d *schema.ResourceData, meta interface{}, name, lbType, rg string, subnets *schema.Set, isPublic bool, isLogging bool, securityGroups *schema.Set) error { +func lbCreate(d *schema.ResourceData, meta interface{}, name, lbType, rg string, subnets *schema.Set, isPublic, isLogging bool, securityGroups *schema.Set) error { sess, err := vpcClient(meta) if err != nil { return err @@ -282,6 +297,11 @@ func lbCreate(d *schema.ResourceData, meta interface{}, name, lbType, rg string, Name: &name, } + if routeModeBool, ok := d.GetOk(isLBRouteMode); ok { + routeMode := routeModeBool.(bool) + options.RouteMode = &routeMode + } + if subnets.Len() != 0 { subnetobjs := make([]vpcv1.SubnetIdentityIntf, subnets.Len()) for i, subnet := range subnets.List() { @@ -382,6 +402,7 @@ func lbGet(d *schema.ResourceData, meta interface{}, id string) error { } else { d.Set(isLBType, "private") } + d.Set(isLBRouteMode, *lb.RouteMode) d.Set(isLBStatus, *lb.ProvisioningStatus) d.Set(isLBCrn, *lb.CRN) d.Set(isLBOperatingStatus, *lb.OperatingStatus) diff --git a/ibm/resource_ibm_is_lb_test.go b/ibm/resource_ibm_is_lb_test.go index 13558295da..ddc4e765f6 100644 --- a/ibm/resource_ibm_is_lb_test.go +++ b/ibm/resource_ibm_is_lb_test.go @@ -135,6 +135,55 @@ func TestAccIBMISLB_basic_network(t *testing.T) { }) } +func TestAccIBMISLB_basic_network_vnf(t *testing.T) { + var lb string + vpcname := fmt.Sprintf("tflb-vpc-%d", acctest.RandIntRange(10, 100)) + subnetname := fmt.Sprintf("tflb-subnet-name-%d", acctest.RandIntRange(10, 100)) + nlbName := fmt.Sprintf("tfnlbcreate%d", acctest.RandIntRange(10, 100)) + nlbName1 := fmt.Sprintf("tfnlbupdate%d", acctest.RandIntRange(10, 100)) + routeModeTrue := true + routeModeFalse := false + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIBMISLBDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISLBNetworkRouteModeConfig(vpcname, subnetname, ISZoneName, ISCIDR, nlbName, routeModeTrue), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBExists("ibm_is_lb.testacc_NLB", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "route_mode", fmt.Sprintf("%t", routeModeTrue)), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "profile", "network-fixed"), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "type", "private"), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "name", nlbName), + resource.TestCheckResourceAttrSet( + "ibm_is_lb.testacc_NLB", "hostname"), + ), + }, + + { + Config: testAccCheckIBMISLBNetworkRouteModeConfig(vpcname, subnetname, ISZoneName, ISCIDR, nlbName1, routeModeFalse), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBExists("ibm_is_lb.testacc_NLB", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "route_mode", fmt.Sprintf("%t", routeModeFalse)), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "profile", "network-fixed"), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "type", "private"), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_NLB", "name", nlbName1), + ), + }, + }, + }) +} + func TestAccIBMISLB_basic_private(t *testing.T) { var lb string vpcname := fmt.Sprintf("tflbt-vpc-%d", acctest.RandIntRange(10, 100)) @@ -272,6 +321,27 @@ func testAccCheckIBMISLBNetworkConfig(vpcname, subnetname, zone, cidr, nlbName s } +func testAccCheckIBMISLBNetworkRouteModeConfig(vpcname, subnetname, zone, cidr, nlbName string, routeMode bool) string { + return fmt.Sprintf(` + resource "ibm_is_vpc" "testacc_vpc" { + name = "%s" + } + resource "ibm_is_subnet" "testacc_subnet" { + name = "%s" + vpc = ibm_is_vpc.testacc_vpc.id + zone = "%s" + total_ipv4_address_count = 16 + } + resource "ibm_is_lb" "testacc_NLB" { + name = "%s" + subnets = [ibm_is_subnet.testacc_subnet.id] + profile = "network-fixed" + route_mode = %t + type = "private" + }`, vpcname, subnetname, zone, nlbName, routeMode) + +} + func testAccCheckIBMISLBConfigPrivate(vpcname, subnetname, zone, cidr, name string) string { return fmt.Sprintf(` resource "ibm_is_vpc" "testacc_vpc" { diff --git a/ibm/structures.go b/ibm/structures.go index f91e91c213..fbaca160da 100644 --- a/ibm/structures.go +++ b/ibm/structures.go @@ -2212,6 +2212,29 @@ func resourceVolumeValidate(diff *schema.ResourceDiff) error { return nil } +func resourceRouteModeValidate(diff *schema.ResourceDiff) error { + + var lbtype, lbprofile string + if typeOk, ok := diff.GetOk(isLBType); ok { + lbtype = typeOk.(string) + } + if profileOk, ok := diff.GetOk(isLBProfile); ok { + lbprofile = profileOk.(string) + } + if rmOk, ok := diff.GetOk(isLBRouteMode); ok { + routeMode := rmOk.(bool) + + if routeMode && lbtype != "private" { + return fmt.Errorf("'type' must be 'private', at present public load balancers are not supported with route mode enabled.") + } + if routeMode && lbprofile != "network-fixed" { + return fmt.Errorf("'profile' must be 'network-fixed', route mode is supported by private network load balancer.") + } + } + + return nil +} + func flattenRoleData(object []iampolicymanagementv1.Role, roleType string) []map[string]string { var roles []map[string]string diff --git a/website/docs/d/is_lb.html.markdown b/website/docs/d/is_lb.html.markdown index 4a7b9aa459..0e1895d024 100644 --- a/website/docs/d/is_lb.html.markdown +++ b/website/docs/d/is_lb.html.markdown @@ -85,6 +85,7 @@ In addition to all argument reference list, you can access the following attribu - `public_ips` - (String) The public IP addresses assigned to this load balancer. - `private_ips` - (String) The private IP addresses assigned to this load balancer. - `resource_group` - (String) The resource group where the load balancer is created. +- `route_mode` - (Bool) Indicates whether route mode is enabled for this load balancer. - `security_groups`- (String) A list of security groups that are used with this load balancer. This option is supported only for application load balancers. - `security_groups_supported`- (Bool) Indicates if this load balancer supports security groups. - `subnets` - (String) The ID of the subnets to provision this load balancer. diff --git a/website/docs/d/is_lb_profiles.html.markdown b/website/docs/d/is_lb_profiles.html.markdown index 06d4cb08ff..b6117116da 100644 --- a/website/docs/d/is_lb_profiles.html.markdown +++ b/website/docs/d/is_lb_profiles.html.markdown @@ -28,3 +28,5 @@ You can access the following attribute references after your data source is crea - `family` - (String) The product family this load balancer profile belongs to. - `href` - (String) The URL for this load balancer profile. - `name` - (String) The name for this load balancer profile. + - `route_mode_supported` - (Bool) The route mode support for a load balancer with this profile. + - `route_mode_type` - (String) The route mode type for this load balancer profile, one of [fixed, dependent] diff --git a/website/docs/d/is_lbs.html.markdown b/website/docs/d/is_lbs.html.markdown index cc93ab5df1..88d02f40cb 100644 --- a/website/docs/d/is_lbs.html.markdown +++ b/website/docs/d/is_lbs.html.markdown @@ -57,6 +57,7 @@ Review the attribute references that you can access after you retrieve your data - `provisioning_status` - (String) The provisioning status of this load balancer. Possible values are: **active**, **create_pending**, **delete_pending**, **failed**, **maintenance_pending**, **update_pending**- - `public_ips` - (String) The public IP addresses assigned to this load balancer. - `resource_group` - (String) The resource group where the load balancer is created. + - `route_mode` - (Bool) Indicates whether route mode is enabled for this load balancer. - `status` - (String) The status of the load balancers. - `type` - (String) The type of the load balancer. - `tags` - (String) Tags associated with the load balancer. diff --git a/website/docs/r/is_lb.html.markdown b/website/docs/r/is_lb.html.markdown index 6817a990f4..dc1e4633cf 100644 --- a/website/docs/r/is_lb.html.markdown +++ b/website/docs/r/is_lb.html.markdown @@ -47,6 +47,8 @@ Review the argument references that you can specify for your resource. - `name` - (Required, String) The name of the VPC load balancer. - `profile` - (Optional, Forces new resource, String) For a Network Load Balancer, this attribute is required and should be set to `network-fixed`. For Application Load Balancer, profile is not a required attribute. - `resource_group` - (Optional, Forces new resource, String) The resource group where the load balancer to be created. +- `route_mode` - (Optional, Forces new resource, Bool) Indicates whether route mode is enabled for this load balancer. + **NOTE** Currently, public load balancers are not supported with `route_mode` enabled. - `security_groups` (Optional, List) A list of security groups to use for this load balancer. This option is supported only for application load balancers. - `subnets` - (Required, List) List of the subnets IDs to connect to the load balancer. - `tags` (Optional, Array of Strings) A list of tags that you want to add to your load balancer. Tags can help you find the load balancer more easily later.