From ece1427b89a18b16c0bc09f030eea269c22704ff Mon Sep 17 00:00:00 2001 From: Deepak Selvakumar <77007253+deepaksibm@users.noreply.github.com> Date: Thu, 8 Feb 2024 20:08:56 +0530 Subject: [PATCH 1/4] deprecate(is-lb-listener-redirect): Deprecate lb listener https redirect arguments and add support for target list policy updates doc update update and doc changes lb listener changes removed unwanted code schema changes --- ibm/flex/structures.go | 37 - .../vpc/resource_ibm_is_lb_listener.go | 335 ++++++--- .../vpc/resource_ibm_is_lb_listener_policy.go | 671 +++++++++++++----- ...resource_ibm_is_lb_listener_policy_test.go | 221 ++++++ .../vpc/resource_ibm_is_lb_listener_test.go | 208 ++++++ website/docs/r/is_lb_listener.html.markdown | 28 +- .../r/is_lb_listener_policy.html.markdown | 18 + 7 files changed, 1202 insertions(+), 316 deletions(-) diff --git a/ibm/flex/structures.go b/ibm/flex/structures.go index a2feb7bb9b..c5d8d28bed 100644 --- a/ibm/flex/structures.go +++ b/ibm/flex/structures.go @@ -2714,43 +2714,6 @@ func ResourceValidateAccessTags(diff *schema.ResourceDiff, meta interface{}) err return nil } -func ResourceLBListenerPolicyCustomizeDiff(diff *schema.ResourceDiff) error { - policyActionIntf, _ := diff.GetOk(isLBListenerPolicyAction) - policyAction := policyActionIntf.(string) - - if policyAction == "forward" { - _, policyTargetIDSet := diff.GetOk(isLBListenerPolicyTargetID) - - if !policyTargetIDSet && diff.NewValueKnown(isLBListenerPolicyTargetID) { - return fmt.Errorf("Load balancer listener policy: When action is forward please specify target_id") - } - } else if policyAction == "redirect" { - _, httpsStatusCodeSet := diff.GetOk(isLBListenerPolicyTargetHTTPStatusCode) - _, targetURLSet := diff.GetOk(isLBListenerPolicyTargetURL) - - if !httpsStatusCodeSet && diff.NewValueKnown(isLBListenerPolicyTargetHTTPStatusCode) { - return fmt.Errorf("Load balancer listener policy: When action is redirect please specify target_http_status_code") - } - - if !targetURLSet && diff.NewValueKnown(isLBListenerPolicyTargetURL) { - return fmt.Errorf("Load balancer listener policy: When action is redirect please specify target_url") - } - } else if policyAction == "https_redirect" { - _, listenerSet := diff.GetOk(isLBListenerPolicyHTTPSRedirectListener) - _, httpsStatusSet := diff.GetOk(isLBListenerPolicyHTTPSRedirectStatusCode) - - if !listenerSet && diff.NewValueKnown(isLBListenerPolicyHTTPSRedirectListener) { - return fmt.Errorf("Load balancer listener policy: When action is https_redirect please specify target_https_redirect_listener") - } - - if !httpsStatusSet && diff.NewValueKnown(isLBListenerPolicyHTTPSRedirectStatusCode) { - return fmt.Errorf("When action is https_redirect please specify target_https_redirect_status_code") - } - } - - return nil -} - func ResourceIBMISLBPoolCookieValidate(diff *schema.ResourceDiff) error { _, sessionPersistenceTypeIntf := diff.GetChange(isLBPoolSessPersistenceType) _, sessionPersistenceCookieNameIntf := diff.GetChange(isLBPoolSessPersistenceAppCookieName) diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener.go b/ibm/service/vpc/resource_ibm_is_lb_listener.go index 767a1d16ae..3652fb61b8 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener.go @@ -4,6 +4,7 @@ package vpc import ( + "context" "fmt" "log" "strings" @@ -12,7 +13,9 @@ import ( "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/validate" + "github.com/IBM/go-sdk-core/v5/core" "github.com/IBM/vpc-go-sdk/vpcv1" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -41,12 +44,12 @@ const ( func ResourceIBMISLBListener() *schema.Resource { return &schema.Resource{ - Create: resourceIBMISLBListenerCreate, - Read: resourceIBMISLBListenerRead, - Update: resourceIBMISLBListenerUpdate, - Delete: resourceIBMISLBListenerDelete, - Exists: resourceIBMISLBListenerExists, - Importer: &schema.ResourceImporter{}, + CreateContext: resourceIBMISLBListenerCreate, + ReadContext: resourceIBMISLBListenerRead, + UpdateContext: resourceIBMISLBListenerUpdate, + DeleteContext: resourceIBMISLBListenerDelete, + Exists: resourceIBMISLBListenerExists, + Importer: &schema.ResourceImporter{}, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(10 * time.Minute), @@ -115,26 +118,83 @@ func ResourceIBMISLBListener() *schema.Resource { }, isLBListenerHTTPSRedirectStatusCode: { - Type: schema.TypeInt, - Optional: true, - RequiredWith: []string{isLBListenerHTTPSRedirectListener}, - Description: "The HTTP status code to be returned in the redirect response", + Type: schema.TypeInt, + Optional: true, + RequiredWith: []string{isLBListenerHTTPSRedirectListener}, + ConflictsWith: []string{"https_redirect"}, + Description: "The HTTP status code to be returned in the redirect response", }, isLBListenerHTTPSRedirectURI: { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{isLBListenerHTTPSRedirectStatusCode, isLBListenerHTTPSRedirectListener}, - Description: "Target URI where traffic will be redirected", + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"https_redirect"}, + RequiredWith: []string{isLBListenerHTTPSRedirectStatusCode, isLBListenerHTTPSRedirectListener}, + Description: "Target URI where traffic will be redirected", }, isLBListenerHTTPSRedirectListener: { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{isLBListenerHTTPSRedirectStatusCode}, - Description: "ID of the listener that will be set as http redirect target", + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"https_redirect"}, + RequiredWith: []string{isLBListenerHTTPSRedirectStatusCode}, + Description: "ID of the listener that will be set as http redirect target", + }, + "https_redirect": &schema.Schema{ + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ConflictsWith: []string{"https_redirect_status_code", "https_redirect_uri", "https_redirect_listener"}, + Description: "If present, the target listener that requests are redirected to.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "http_status_code": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + Description: "The HTTP status code for this redirect.", + }, + "listener": &schema.Schema{ + Type: schema.TypeList, + MinItems: 1, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "deleted": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "If present, this property indicates the referenced resource has been deleted, and providessome supplementary information.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "more_info": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + "href": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The listener's canonical URL.", + }, + "id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "The unique identifier for this load balancer listener.", + }, + }, + }, + }, + "uri": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "The redirect relative target URI.", + }, + }, + }, }, - isLBListenerConnectionLimit: { Type: schema.TypeInt, Optional: true, @@ -209,7 +269,7 @@ func ResourceIBMISLBListenerValidator() *validate.ResourceValidator { return &ibmISLBListenerResourceValidator } -func resourceIBMISLBListenerCreate(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerCreate(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { log.Printf("[DEBUG] LB Listener create") lbID := d.Get(isLBListenerLBID).(string) @@ -221,7 +281,7 @@ func resourceIBMISLBListenerCreate(d *schema.ResourceData, meta interface{}) err if pool, ok := d.GetOk(isLBListenerDefaultPool); ok { lbPool, err := getPoolId(pool.(string)) if err != nil { - return err + diag.FromErr(err) } defPool = lbPool } @@ -263,13 +323,13 @@ func resourceIBMISLBListenerCreate(d *schema.ResourceData, meta interface{}) err return err } - return resourceIBMISLBListenerRead(d, meta) + return resourceIBMISLBListenerRead(context, d, meta) } -func lbListenerCreate(d *schema.ResourceData, meta interface{}, lbID, protocol, defPool, certificateCRN, listener, uri string, port, portMin, portMax, connLimit, httpStatusCode int64) error { +func lbListenerCreate(d *schema.ResourceData, meta interface{}, lbID, protocol, defPool, certificateCRN, listener, uri string, port, portMin, portMax, connLimit, httpStatusCode int64) diag.Diagnostics { sess, err := vpcClient(meta) if err != nil { - return err + return diag.FromErr(err) } options := &vpcv1.CreateLoadBalancerListenerOptions{ @@ -283,11 +343,11 @@ func lbListenerCreate(d *schema.ResourceData, meta interface{}, lbID, protocol, lb, response, err := sess.GetLoadBalancer(getlboptions) if err != nil || lb == nil { - return fmt.Errorf("[ERROR] Error getting Load Balancer : %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error getting Load Balancer : %s\n%s", err, response)) } if lb != nil && *lb.RouteMode && lb.Profile != nil && *lb.Profile.Name == "network-fixed" { if portMin > 0 && portMax > 0 && portMin != 1 && portMax != 65535 { - return fmt.Errorf("[ERROR] Only acceptable value for port_min is 1 and port_max is 65535 for route_mode enabled private network load balancer") + return diag.FromErr(fmt.Errorf("[ERROR] Only acceptable value for port_min is 1 and port_max is 65535 for route_mode enabled private network load balancer")) } pmin := int64(1) pmax := int64(65535) @@ -297,8 +357,8 @@ func lbListenerCreate(d *schema.ResourceData, meta interface{}, lbID, protocol, } else if lb != nil && lb.Profile != nil { if strings.EqualFold(*lb.Profile.Family, "network") && *lb.IsPublic { if port == 0 && (portMin == 0 || portMax == 0) { - return fmt.Errorf( - "[ERROR] Error port_min(%d)/port_max(%d) for public network load balancer(%s) needs to be in between 1-65335", portMin, portMax, lbID) + return diag.FromErr(fmt.Errorf( + "[ERROR] Error port_min(%d)/port_max(%d) for public network load balancer(%s) needs to be in between 1-65335", portMin, portMax, lbID)) } else { if port != 0 { options.Port = &port @@ -308,7 +368,7 @@ func lbListenerCreate(d *schema.ResourceData, meta interface{}, lbID, protocol, } } } else if portMin != portMax { - return fmt.Errorf("[ERROR] Listener port_min and port_max values have to be equal for ALB and private NLB (excluding route mode)") + return diag.FromErr(fmt.Errorf("[ERROR] Listener port_min and port_max values have to be equal for ALB and private NLB (excluding route mode)")) } else { if port != 0 && (portMin == 0 || port == portMin) { options.Port = &port @@ -345,6 +405,13 @@ func lbListenerCreate(d *schema.ResourceData, meta interface{}, lbID, protocol, } options.HTTPSRedirect = httpsRedirect } + if _, ok := d.GetOk("https_redirect"); ok { + httpsRedirectModel, err := resourceIBMIsLbListenerMapToLoadBalancerListenerHTTPSRedirectPrototype(d.Get("https_redirect.0").(map[string]interface{})) + if err != nil { + return diag.FromErr(err) + } + options.SetHTTPSRedirect(httpsRedirectModel) + } if certificateCRN != "" { options.CertificateInstance = &vpcv1.CertificateInstanceIdentity{ CRN: &certificateCRN, @@ -355,21 +422,21 @@ func lbListenerCreate(d *schema.ResourceData, meta interface{}, lbID, protocol, } _, err = isWaitForLBAvailable(sess, lbID, d.Timeout(schema.TimeoutCreate)) if err != nil { - return fmt.Errorf("[ERROR] Error checking for load balancer (%s) is active: %s", lbID, err) + return diag.FromErr(fmt.Errorf("[ERROR] Error checking for load balancer (%s) is active: %s", lbID, err)) } lbListener, response, err := sess.CreateLoadBalancerListener(options) if err != nil { - return fmt.Errorf("[ERROR] Error while creating Load Balanacer Listener err %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error while creating Load Balanacer Listener err %s\n%s", err, response)) } d.SetId(fmt.Sprintf("%s/%s", lbID, *lbListener.ID)) _, err = isWaitForLBListenerAvailable(sess, lbID, *lbListener.ID, d.Timeout(schema.TimeoutCreate)) if err != nil { - return fmt.Errorf("[ERROR] Error waiting for load balancer listener(%s) to become ready: %s", d.Id(), err) + return diag.FromErr(fmt.Errorf("[ERROR] Error waiting for load balancer listener(%s) to become ready: %s", d.Id(), err)) } _, err = isWaitForLBAvailable(sess, lbID, d.Timeout(schema.TimeoutCreate)) if err != nil { - return fmt.Errorf("[ERROR] Error waiting for load balancer (%s) to become ready: %s", lbID, err) + return diag.FromErr(fmt.Errorf("[ERROR] Error waiting for load balancer (%s) to become ready: %s", lbID, err)) } log.Printf("[INFO] Load balancer Listener : %s", *lbListener.ID) @@ -411,28 +478,28 @@ func isLBListenerRefreshFunc(sess *vpcv1.VpcV1, lbID, lbListenerID string) resou } } -func resourceIBMISLBListenerRead(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { parts, err := flex.IdParts(d.Id()) if err != nil { - return err + diag.FromErr(err) } lbID := parts[0] lbListenerID := parts[1] - err = lbListenerGet(d, meta, lbID, lbListenerID) - if err != nil { - return err + diagEerr := lbListenerGet(d, meta, lbID, lbListenerID) + if diagEerr != nil { + return diagEerr } return nil } -func lbListenerGet(d *schema.ResourceData, meta interface{}, lbID, lbListenerID string) error { +func lbListenerGet(d *schema.ResourceData, meta interface{}, lbID, lbListenerID string) diag.Diagnostics { sess, err := vpcClient(meta) if err != nil { - return err + diag.FromErr(err) } getLoadBalancerListenerOptions := &vpcv1.GetLoadBalancerListenerOptions{ LoadBalancerID: &lbID, @@ -444,7 +511,7 @@ func lbListenerGet(d *schema.ResourceData, meta interface{}, lbID, lbListenerID d.SetId("") return nil } - return fmt.Errorf("[ERROR] Error Getting Load Balancer Listener : %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error Getting Load Balancer Listener : %s\n%s", err, response)) } d.Set(isLBListenerLBID, lbID) if lbListener.Port != nil { @@ -463,10 +530,21 @@ func lbListenerGet(d *schema.ResourceData, meta interface{}, lbID, lbListenerID d.Set(isLBListenerDefaultPool, *lbListener.DefaultPool.ID) } if lbListener.HTTPSRedirect != nil { - d.Set(isLBListenerHTTPSRedirectStatusCode, *lbListener.HTTPSRedirect.HTTPStatusCode) - d.Set(isLBListenerHTTPSRedirectListener, *lbListener.HTTPSRedirect.Listener.ID) - if lbListener.HTTPSRedirect.URI != nil { - d.Set(isLBListenerHTTPSRedirectURI, *lbListener.HTTPSRedirect.URI) + if _, ok := d.GetOk("https_redirect"); ok { + httpsRedirectMap, err := resourceIBMIsLbListenerLoadBalancerListenerHTTPSRedirectToMap(lbListener.HTTPSRedirect) + if err != nil { + return diag.FromErr(err) + } + if err = d.Set("https_redirect", []map[string]interface{}{httpsRedirectMap}); err != nil { + return diag.FromErr(fmt.Errorf("Error setting https_redirect: %s", err)) + } + + } else { + d.Set(isLBListenerHTTPSRedirectStatusCode, *lbListener.HTTPSRedirect.HTTPStatusCode) + d.Set(isLBListenerHTTPSRedirectListener, *lbListener.HTTPSRedirect.Listener.ID) + if lbListener.HTTPSRedirect.URI != nil { + d.Set(isLBListenerHTTPSRedirectURI, *lbListener.HTTPSRedirect.URI) + } } } if lbListener.CertificateInstance != nil { @@ -485,34 +563,34 @@ func lbListenerGet(d *schema.ResourceData, meta interface{}, lbID, lbListenerID } lb, response, err := sess.GetLoadBalancer(getLoadBalancerOptions) if err != nil { - return fmt.Errorf("[ERROR] Error Getting Load Balancer : %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error Getting Load Balancer : %s\n%s", err, response)) } d.Set(flex.RelatedCRN, *lb.CRN) return nil } -func resourceIBMISLBListenerUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerUpdate(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { parts, err := flex.IdParts(d.Id()) if err != nil { - return err + diag.FromErr(err) } lbID := parts[0] lbListenerID := parts[1] - err = lbListenerUpdate(d, meta, lbID, lbListenerID) - if err != nil { - return err + diagEerr := lbListenerUpdate(d, meta, lbID, lbListenerID) + if diagEerr != nil { + return diagEerr } - return resourceIBMISLBListenerRead(d, meta) + return resourceIBMISLBListenerRead(context, d, meta) } -func lbListenerUpdate(d *schema.ResourceData, meta interface{}, lbID, lbListenerID string) error { +func lbListenerUpdate(d *schema.ResourceData, meta interface{}, lbID, lbListenerID string) diag.Diagnostics { sess, err := vpcClient(meta) if err != nil { - return err + diag.FromErr(err) } hasChanged := false var certificateInstance, defPool, protocol, listener, uri string @@ -535,7 +613,7 @@ func lbListenerUpdate(d *schema.ResourceData, meta interface{}, lbID, lbListener if d.HasChange(isLBListenerDefaultPool) { lbpool, err := getPoolId(d.Get(isLBListenerDefaultPool).(string)) if err != nil { - return err + diag.FromErr(err) } defPool = lbpool loadBalancerListenerPatchModel.DefaultPool = &vpcv1.LoadBalancerPoolIdentity{ @@ -545,28 +623,54 @@ func lbListenerUpdate(d *schema.ResourceData, meta interface{}, lbID, lbListener } httpsRedirectRemoved := false httpsURIRemoved := false - if d.HasChange(isLBListenerHTTPSRedirectListener) || d.HasChange(isLBListenerHTTPSRedirectURI) || d.HasChange(isLBListenerHTTPSRedirectStatusCode) { - hasChanged = true - listener = d.Get(isLBListenerHTTPSRedirectListener).(string) - httpStatusCode = int64(d.Get(isLBListenerHTTPSRedirectStatusCode).(int)) - uri = d.Get(isLBListenerHTTPSRedirectURI).(string) - if listener == "" { + if d.HasChange("https_redirect") { + httpsRedirect := &vpcv1.LoadBalancerListenerHTTPSRedirectPatch{} + if _, ok := d.GetOk("https_redirect"); !ok { httpsRedirectRemoved = true } else { - HTTPSRedirect := &vpcv1.LoadBalancerListenerHTTPSRedirectPatch{ - HTTPStatusCode: &httpStatusCode, - Listener: &vpcv1.LoadBalancerListenerIdentityByID{ID: &listener}, + if d.HasChange("https_redirect.0.http_status_code") { + httpStatusCode := int64(d.Get("https_redirect.0.http_status_code").(int)) + httpsRedirect.HTTPStatusCode = &httpStatusCode } - if d.HasChange(isLBListenerHTTPSRedirectURI) { + if d.HasChange("https_redirect.0.listener.0.id") { + listenerId := d.Get("https_redirect.0.listener.0.id").(string) + httpsRedirect.Listener = &vpcv1.LoadBalancerListenerIdentityByID{ID: &listenerId} + } + if d.HasChange("https_redirect.0.uri") { + uri := d.Get("https_redirect.0.uri").(string) if uri == "" { - HTTPSRedirect.URI = nil httpsURIRemoved = true } else { - HTTPSRedirect.URI = &uri + httpsRedirect.URI = &uri } } + } + loadBalancerListenerPatchModel.HTTPSRedirect = httpsRedirect + hasChanged = true + } else { + if d.HasChange(isLBListenerHTTPSRedirectListener) || d.HasChange(isLBListenerHTTPSRedirectURI) || d.HasChange(isLBListenerHTTPSRedirectStatusCode) { + hasChanged = true + listener = d.Get(isLBListenerHTTPSRedirectListener).(string) + httpStatusCode = int64(d.Get(isLBListenerHTTPSRedirectStatusCode).(int)) + uri = d.Get(isLBListenerHTTPSRedirectURI).(string) + if listener == "" { + httpsRedirectRemoved = true + } else { + HTTPSRedirect := &vpcv1.LoadBalancerListenerHTTPSRedirectPatch{ + HTTPStatusCode: &httpStatusCode, + Listener: &vpcv1.LoadBalancerListenerIdentityByID{ID: &listener}, + } + if d.HasChange(isLBListenerHTTPSRedirectURI) { + if uri == "" { + HTTPSRedirect.URI = nil + httpsURIRemoved = true + } else { + HTTPSRedirect.URI = &uri + } + } - loadBalancerListenerPatchModel.HTTPSRedirect = HTTPSRedirect + loadBalancerListenerPatchModel.HTTPSRedirect = HTTPSRedirect + } } } if _, ok := d.GetOk(isLBListenerPort); ok && d.HasChange(isLBListenerPort) { @@ -610,7 +714,7 @@ func lbListenerUpdate(d *schema.ResourceData, meta interface{}, lbID, lbListener if hasChanged { loadBalancerListenerPatch, err := loadBalancerListenerPatchModel.AsPatch() if err != nil { - return fmt.Errorf("[ERROR] Error calling asPatch for LoadBalancerListenerPatch: %s", err) + return diag.FromErr(fmt.Errorf("[ERROR] Error calling asPatch for LoadBalancerListenerPatch: %s", err)) } if httpsRedirectRemoved { loadBalancerListenerPatch["https_redirect"] = nil @@ -626,34 +730,34 @@ func lbListenerUpdate(d *schema.ResourceData, meta interface{}, lbID, lbListener _, err = isWaitForLBAvailable(sess, lbID, d.Timeout(schema.TimeoutUpdate)) if err != nil { - return fmt.Errorf( - "Error checking for load balancer (%s) is active: %s", lbID, err) + return diag.FromErr(fmt.Errorf( + "Error checking for load balancer (%s) is active: %s", lbID, err)) } _, response, err := sess.UpdateLoadBalancerListener(updateLoadBalancerListenerOptions) if err != nil { - return fmt.Errorf("[ERROR] Error Updating Load Balancer Listener : %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error Updating Load Balancer Listener : %s\n%s", err, response)) } _, err = isWaitForLBListenerAvailable(sess, lbID, lbListenerID, d.Timeout(schema.TimeoutUpdate)) if err != nil { - return fmt.Errorf( - "Error waiting for load balancer listener(%s) to become ready: %s", d.Id(), err) + return diag.FromErr(fmt.Errorf( + "Error waiting for load balancer listener(%s) to become ready: %s", d.Id(), err)) } _, err = isWaitForLBAvailable(sess, lbID, d.Timeout(schema.TimeoutUpdate)) if err != nil { - return fmt.Errorf( - "Error waiting for load balancer (%s) to become ready: %s", lbID, err) + return diag.FromErr(fmt.Errorf( + "Error waiting for load balancer (%s) to become ready: %s", lbID, err)) } } return nil } -func resourceIBMISLBListenerDelete(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerDelete(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { parts, err := flex.IdParts(d.Id()) if err != nil { - return err + diag.FromErr(err) } lbID := parts[0] @@ -663,18 +767,18 @@ func resourceIBMISLBListenerDelete(d *schema.ResourceData, meta interface{}) err conns.IbmMutexKV.Lock(isLBKey) defer conns.IbmMutexKV.Unlock(isLBKey) - err = lbListenerDelete(d, meta, lbID, lbListenerID) - if err != nil { - return err + diagEerr := lbListenerDelete(d, meta, lbID, lbListenerID) + if diagEerr != nil { + return diagEerr } return nil } -func lbListenerDelete(d *schema.ResourceData, meta interface{}, lbID, lbListenerID string) error { +func lbListenerDelete(d *schema.ResourceData, meta interface{}, lbID, lbListenerID string) diag.Diagnostics { sess, err := vpcClient(meta) if err != nil { - return err + diag.FromErr(err) } getLoadBalancerListenerOptions := &vpcv1.GetLoadBalancerListenerOptions{ LoadBalancerID: &lbID, @@ -687,11 +791,11 @@ func lbListenerDelete(d *schema.ResourceData, meta interface{}, lbID, lbListener d.SetId("") return nil } - return fmt.Errorf("[ERROR] Error Getting vpc load balancer listener(%s): %s\n%s", lbListenerID, err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error Getting vpc load balancer listener(%s): %s\n%s", lbListenerID, err, response)) } _, err = isWaitForLBAvailable(sess, lbID, d.Timeout(schema.TimeoutDelete)) if err != nil { - return fmt.Errorf("[ERROR] Error checking for load balancer (%s) is active: %s", lbID, err) + return diag.FromErr(fmt.Errorf("[ERROR] Error checking for load balancer (%s) is active: %s", lbID, err)) } deleteLoadBalancerListenerOptions := &vpcv1.DeleteLoadBalancerListenerOptions{ LoadBalancerID: &lbID, @@ -699,15 +803,15 @@ func lbListenerDelete(d *schema.ResourceData, meta interface{}, lbID, lbListener } response, err = sess.DeleteLoadBalancerListener(deleteLoadBalancerListenerOptions) if err != nil { - return fmt.Errorf("[ERROR] Error Deleting Load Balancer Pool : %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error Deleting Load Balancer Pool : %s\n%s", err, response)) } _, err = isWaitForLBListenerDeleted(sess, lbID, lbListenerID, d.Timeout(schema.TimeoutDelete)) if err != nil { - return err + diag.FromErr(err) } _, err = isWaitForLBAvailable(sess, lbID, d.Timeout(schema.TimeoutDelete)) if err != nil { - return fmt.Errorf("[ERROR] Error waiting for load balancer (%s) to be active: %s", lbID, err) + return diag.FromErr(fmt.Errorf("[ERROR] Error waiting for load balancer (%s) to be active: %s", lbID, err)) } d.SetId("") @@ -782,3 +886,58 @@ func lbListenerExists(d *schema.ResourceData, meta interface{}, lbID, lbListener } return true, nil } + +func resourceIBMIsLbListenerMapToLoadBalancerListenerHTTPSRedirectPrototype(modelMap map[string]interface{}) (*vpcv1.LoadBalancerListenerHTTPSRedirectPrototype, error) { + model := &vpcv1.LoadBalancerListenerHTTPSRedirectPrototype{} + model.HTTPStatusCode = core.Int64Ptr(int64(modelMap["http_status_code"].(int))) + ListenerModel, err := resourceIBMIsLbListenerMapToLoadBalancerListenerIdentity(modelMap["listener"].([]interface{})[0].(map[string]interface{})) + if err != nil { + return model, err + } + model.Listener = ListenerModel + if modelMap["uri"] != nil && modelMap["uri"].(string) != "" { + model.URI = core.StringPtr(modelMap["uri"].(string)) + } + return model, nil +} + +func resourceIBMIsLbListenerMapToLoadBalancerListenerIdentity(modelMap map[string]interface{}) (vpcv1.LoadBalancerListenerIdentityIntf, error) { + model := &vpcv1.LoadBalancerListenerIdentity{} + if modelMap["id"] != nil && modelMap["id"].(string) != "" { + model.ID = core.StringPtr(modelMap["id"].(string)) + } + return model, nil +} + +func resourceIBMIsLbListenerLoadBalancerListenerHTTPSRedirectToMap(model *vpcv1.LoadBalancerListenerHTTPSRedirect) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + modelMap["http_status_code"] = flex.IntValue(model.HTTPStatusCode) + listenerMap, err := resourceIBMIsLbListenerLoadBalancerListenerReferenceToMap(model.Listener) + if err != nil { + return modelMap, err + } + modelMap["listener"] = []map[string]interface{}{listenerMap} + if model.URI != nil { + modelMap["uri"] = model.URI + } + return modelMap, nil +} + +func resourceIBMIsLbListenerLoadBalancerListenerReferenceToMap(model *vpcv1.LoadBalancerListenerReference) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + if model.Deleted != nil { + deletedMap, err := resourceIBMIsLbListenerLoadBalancerListenerReferenceDeletedToMap(model.Deleted) + if err != nil { + return modelMap, err + } + modelMap["deleted"] = []map[string]interface{}{deletedMap} + } + modelMap["href"] = model.Href + modelMap["id"] = model.ID + return modelMap, nil +} +func resourceIBMIsLbListenerLoadBalancerListenerReferenceDeletedToMap(model *vpcv1.LoadBalancerListenerReferenceDeleted) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + modelMap["more_info"] = model.MoreInfo + return modelMap, nil +} diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener_policy.go b/ibm/service/vpc/resource_ibm_is_lb_listener_policy.go index e8bf3a8d69..03ee1638ad 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener_policy.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener_policy.go @@ -13,8 +13,9 @@ import ( "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" "github.com/IBM-Cloud/terraform-provider-ibm/ibm/validate" + "github.com/IBM/go-sdk-core/v5/core" "github.com/IBM/vpc-go-sdk/vpcv1" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -52,20 +53,12 @@ const ( func ResourceIBMISLBListenerPolicy() *schema.Resource { return &schema.Resource{ - Create: resourceIBMISLBListenerPolicyCreate, - Read: resourceIBMISLBListenerPolicyRead, - Update: resourceIBMISLBListenerPolicyUpdate, - Delete: resourceIBMISLBListenerPolicyDelete, - Exists: resourceIBMISLBListenerPolicyExists, - Importer: &schema.ResourceImporter{}, - - CustomizeDiff: customdiff.All( - customdiff.Sequence( - func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { - return flex.ResourceLBListenerPolicyCustomizeDiff(diff) - }, - ), - ), + CreateContext: resourceIBMISLBListenerPolicyCreate, + ReadContext: resourceIBMISLBListenerPolicyRead, + UpdateContext: resourceIBMISLBListenerPolicyUpdate, + DeleteContext: resourceIBMISLBListenerPolicyDelete, + Exists: resourceIBMISLBListenerPolicyExists, + Importer: &schema.ResourceImporter{}, Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(10 * time.Minute), @@ -114,12 +107,14 @@ func ResourceIBMISLBListenerPolicy() *schema.Resource { Type: schema.TypeInt, Optional: true, RequiredWith: []string{isLBListenerPolicyHTTPSRedirectListener}, + Deprecated: "Please use the argument 'target'", Description: "The HTTP status code to be returned in the redirect response", }, isLBListenerPolicyHTTPSRedirectURI: { Type: schema.TypeString, Optional: true, + Deprecated: "Please use the argument 'target'", RequiredWith: []string{isLBListenerPolicyHTTPSRedirectListener, isLBListenerPolicyHTTPSRedirectStatusCode}, Description: "Target URI where traffic will be redirected", }, @@ -127,6 +122,7 @@ func ResourceIBMISLBListenerPolicy() *schema.Resource { isLBListenerPolicyHTTPSRedirectListener: { Type: schema.TypeString, Optional: true, + Deprecated: "Please use the argument 'target'", RequiredWith: []string{isLBListenerPolicyHTTPSRedirectStatusCode}, Description: "ID of the listener that will be set as http redirect target", }, @@ -207,9 +203,10 @@ func ResourceIBMISLBListenerPolicy() *schema.Resource { }, isLBListenerPolicyTargetID: { - Type: schema.TypeString, - ForceNew: false, - Optional: true, + Type: schema.TypeString, + ForceNew: false, + Optional: true, + Deprecated: "Please use the argument 'target'", DiffSuppressFunc: func(k, o, n string, d *schema.ResourceData) bool { if o == "" { return false @@ -237,6 +234,7 @@ func ResourceIBMISLBListenerPolicy() *schema.Resource { Type: schema.TypeInt, ForceNew: false, Optional: true, + Deprecated: "Please use the argument 'target'", Description: "Listener Policy target HTTPS Status code.", }, @@ -244,9 +242,106 @@ func ResourceIBMISLBListenerPolicy() *schema.Resource { Type: schema.TypeString, ForceNew: false, Optional: true, + Deprecated: "Please use the argument 'target'", Description: "Policy Target URL", }, - + "target": &schema.Schema{ + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ConflictsWith: []string{"target_url", "target_http_status_code", "target_id", "target_https_redirect_listener", "target_https_redirect_uri", "target_https_redirect_status_code"}, + Description: "- If `action` is `forward`, the response is a `LoadBalancerPoolReference`- If `action` is `redirect`, the response is a `LoadBalancerListenerPolicyRedirectURL`- If `action` is `https_redirect`, the response is a `LoadBalancerListenerHTTPSRedirect`.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "deleted": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "If present, this property indicates the referenced resource has been deleted, and providessome supplementary information.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "more_info": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + "href": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The pool's canonical URL.", + }, + "id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + AtLeastOneOf: []string{"target.0.id", "target.0.http_status_code", "target.0.url", "target.0.listener"}, + ConflictsWith: []string{"target.0.http_status_code", "target.0.url", "target.0.listener", "target.0.uri"}, + Description: "The unique identifier for this load balancer pool.", + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The name for this load balancer pool. The name is unique across all pools for the load balancer.", + }, + "http_status_code": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + AtLeastOneOf: []string{"target.0.id", "target.0.http_status_code", "target.0.url", "target.0.listener"}, + ConflictsWith: []string{"target.0.id"}, + Description: "The HTTP status code for this redirect.", + }, + "url": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + AtLeastOneOf: []string{"target.0.id", "target.0.http_status_code", "target.0.url", "target.0.listener"}, + ConflictsWith: []string{"target.0.id", "target.0.listener", "target.0.uri"}, + Description: "The redirect target URL.", + }, + "listener": &schema.Schema{ + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + AtLeastOneOf: []string{"target.0.id", "target.0.http_status_code", "target.0.url", "target.0.listener"}, + ConflictsWith: []string{"target.0.id", "target.0.url"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "deleted": &schema.Schema{ + Type: schema.TypeList, + Computed: true, + Description: "If present, this property indicates the referenced resource has been deleted, and providessome supplementary information.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "more_info": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "Link to documentation about deleted resources.", + }, + }, + }, + }, + "href": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + Description: "The listener's canonical URL.", + }, + "id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "The unique identifier for this load balancer listener.", + }, + }, + }, + }, + "uri": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"target.0.id", "target.0.url"}, + Description: "The redirect relative target URI.", + }, + }, + }, + }, isLBListenerPolicyStatus: { Type: schema.TypeString, Computed: true, @@ -287,7 +382,7 @@ func ResourceIBMISLBListenerPolicyValidator() *validate.ResourceValidator { return &ibmISLBListenerPolicyResourceValidator } -func resourceIBMISLBListenerPolicyCreate(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerPolicyCreate(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { //Get the Load balancer ID lbID := d.Get(isLBListenerPolicyLBID).(string) @@ -295,7 +390,7 @@ func resourceIBMISLBListenerPolicyCreate(d *schema.ResourceData, meta interface{ //User can set listener id as combination of lbID/listenerID, parse and get the listenerID listenerID, err := getListenerID(d.Get(isLBListenerPolicyListenerID).(string)) if err != nil { - return err + return diag.FromErr(err) } action := d.Get(isLBListenerPolicyAction).(string) @@ -307,12 +402,12 @@ func resourceIBMISLBListenerPolicyCreate(d *schema.ResourceData, meta interface{ name = n.(string) } - err = lbListenerPolicyCreate(d, meta, lbID, listenerID, action, name, priority) - if err != nil { - return err + errDiag := lbListenerPolicyCreate(d, meta, lbID, listenerID, action, name, priority) + if errDiag != nil { + return errDiag } - return resourceIBMISLBListenerPolicyRead(d, meta) + return resourceIBMISLBListenerPolicyRead(context, d, meta) } func getListenerID(id string) (string, error) { @@ -341,11 +436,11 @@ func getPoolID(id string) (string, error) { } -func lbListenerPolicyCreate(d *schema.ResourceData, meta interface{}, lbID, listenerID, action, name string, priority int64) error { +func lbListenerPolicyCreate(d *schema.ResourceData, meta interface{}, lbID, listenerID, action, name string, priority int64) diag.Diagnostics { sess, err := vpcClient(meta) if err != nil { - return err + return diag.FromErr(err) } // When `action` is `forward`, `LoadBalancerPoolIdentity` is required to specify which @@ -362,69 +457,75 @@ func lbListenerPolicyCreate(d *schema.ResourceData, meta interface{}, lbID, list listener, listenerSet := d.GetOk(isLBListenerPolicyHTTPSRedirectListener) httpsStatusCode, httpsStatusSet := d.GetOk(isLBListenerPolicyHTTPSRedirectStatusCode) uri, uriSet := d.GetOk(isLBListenerPolicyHTTPSRedirectURI) + if _, ok := d.GetOk("target"); ok { + target, err = resourceIBMIsLbListenerPolicyMapToLoadBalancerListenerPolicyTargetPrototype(d.Get("target.0").(map[string]interface{})) + if err != nil { + return diag.FromErr(err) + } - if actionChk.(string) == "forward" { - if targetIDSet { + } else { + if actionChk.(string) == "forward" { + if targetIDSet { - //User can set the poolId as combination of lbID/poolID, if so parse the string & get the poolID - id, err := getPoolID(tID.(string)) - if err != nil { - return err - } + //User can set the poolId as combination of lbID/poolID, if so parse the string & get the poolID + id, err := getPoolID(tID.(string)) + if err != nil { + return diag.FromErr(err) + } - target = &vpcv1.LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity{ - ID: &id, + target = &vpcv1.LoadBalancerListenerPolicyTargetPrototypeLoadBalancerPoolIdentity{ + ID: &id, + } + } else { + return diag.FromErr(fmt.Errorf("When action is forward please specify target_id")) } - } else { - return fmt.Errorf("When action is forward please specify target_id") - } - } else if actionChk.(string) == "redirect" { + } else if actionChk.(string) == "redirect" { - urlPrototype := vpcv1.LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype{} + urlPrototype := vpcv1.LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerPolicyRedirectURLPrototype{} - if statusSet { - sc := int64(statusCode.(int)) - urlPrototype.HTTPStatusCode = &sc - } else { - return fmt.Errorf("When action is redirect please specify target_http_status_code") - } + if statusSet { + sc := int64(statusCode.(int)) + urlPrototype.HTTPStatusCode = &sc + } else { + return diag.FromErr(fmt.Errorf("When action is redirect please specify target_http_status_code")) + } - if urlSet { - link := url.(string) - urlPrototype.URL = &link - } else { - return fmt.Errorf("When action is redirect please specify target_url") - } + if urlSet { + link := url.(string) + urlPrototype.URL = &link + } else { + return diag.FromErr(fmt.Errorf("When action is redirect please specify target_url")) + } - target = &urlPrototype - } else if actionChk.(string) == "https_redirect" { + target = &urlPrototype + } else if actionChk.(string) == "https_redirect" { - urlPrototype := vpcv1.LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype{} + urlPrototype := vpcv1.LoadBalancerListenerPolicyTargetPrototypeLoadBalancerListenerHTTPSRedirectPrototype{} - if listenerSet { - listener := listener.(string) - urlPrototype.Listener = &vpcv1.LoadBalancerListenerIdentity{ - ID: &listener, + if listenerSet { + listener := listener.(string) + urlPrototype.Listener = &vpcv1.LoadBalancerListenerIdentity{ + ID: &listener, + } + } else { + return diag.FromErr(fmt.Errorf("When action is https_redirect please specify target_https_redirect_listener")) } - } else { - return fmt.Errorf("When action is https_redirect please specify target_https_redirect_listener") - } - if httpsStatusSet { - sc := int64(httpsStatusCode.(int)) - urlPrototype.HTTPStatusCode = &sc - } else { - return fmt.Errorf("When action is https_redirect please specify target_https_redirect_status_code") - } + if httpsStatusSet { + sc := int64(httpsStatusCode.(int)) + urlPrototype.HTTPStatusCode = &sc + } else { + return diag.FromErr(fmt.Errorf("When action is https_redirect please specify target_https_redirect_status_code")) + } - if uriSet { - link := uri.(string) - urlPrototype.URI = &link - } + if uriSet { + link := uri.(string) + urlPrototype.URI = &link + } - target = &urlPrototype + target = &urlPrototype + } } - //Read Rules rulesInfo := make([]vpcv1.LoadBalancerListenerPolicyRulePrototype, 0) if rules, rulesSet := d.GetOk(isLBListenerPolicyRules); rulesSet { @@ -477,20 +578,20 @@ func lbListenerPolicyCreate(d *schema.ResourceData, meta interface{}, lbID, list _, err = isWaitForLbAvailable(sess, lbID, d.Timeout(schema.TimeoutCreate)) if err != nil { - return fmt.Errorf( - "LB-LP Error checking for load balancer (%s) is active: %s", lbID, err) + return diag.FromErr(fmt.Errorf( + "LB-LP Error checking for load balancer (%s) is active: %s", lbID, err)) } policy, response, err := sess.CreateLoadBalancerListenerPolicy(options) if err != nil { - return fmt.Errorf("[ERROR] Error while creating lb listener policy for LB %s: Error %v Response %v", lbID, err, *response) + return diag.FromErr(fmt.Errorf("[ERROR] Error while creating lb listener policy for LB %s: Error %v Response %v", lbID, err, *response)) } d.SetId(fmt.Sprintf("%s/%s/%s", lbID, listenerID, *(policy.ID))) _, err = isWaitForLbListenerPolicyAvailable(sess, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { - return err + return diag.FromErr(err) } return nil } @@ -575,21 +676,21 @@ func isLbListenerPolicyRefreshFunc(vpc *vpcv1.VpcV1, id string) resource.StateRe } } -func resourceIBMISLBListenerPolicyRead(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerPolicyRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { ID := d.Id() parts, err := flex.IdParts(ID) if err != nil { - return err + return diag.FromErr(err) } lbID := parts[0] listenerID := parts[1] policyID := parts[2] - err = lbListenerPolicyGet(d, meta, lbID, listenerID, policyID) - if err != nil { - return err + diag := lbListenerPolicyGet(d, meta, lbID, listenerID, policyID) + if diag != nil { + return diag } return nil @@ -638,29 +739,29 @@ func lbListenerPolicyExists(d *schema.ResourceData, meta interface{}, ID string) } return true, nil } -func resourceIBMISLBListenerPolicyUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerPolicyUpdate(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { parts, err := flex.IdParts(d.Id()) if err != nil { - return err + return diag.FromErr(err) } lbID := parts[0] listenerID := parts[1] policyID := parts[2] - err = lbListenerPolicyUpdate(d, meta, lbID, listenerID, policyID) - if err != nil { - return err + diagErr := lbListenerPolicyUpdate(d, meta, lbID, listenerID, policyID) + if diagErr != nil { + return diagErr } - return resourceIBMISLBListenerPolicyRead(d, meta) + return resourceIBMISLBListenerPolicyRead(context, d, meta) } -func lbListenerPolicyUpdate(d *schema.ResourceData, meta interface{}, lbID, listenerID, ID string) error { +func lbListenerPolicyUpdate(d *schema.ResourceData, meta interface{}, lbID, listenerID, ID string) diag.Diagnostics { sess, err := vpcClient(meta) if err != nil { - return err + return diag.FromErr(err) } hasChanged := false updatePolicyOptions := vpcv1.UpdateLoadBalancerListenerPolicyOptions{} @@ -683,92 +784,101 @@ func lbListenerPolicyUpdate(d *schema.ResourceData, meta interface{}, lbID, list hasChanged = true } httpsURIRemoved := false - var target vpcv1.LoadBalancerListenerPolicyTargetPatchIntf - //If Action is forward and TargetID is changed, set the target to pool ID - if d.Get(isLBListenerPolicyAction).(string) == "forward" && d.HasChange(isLBListenerPolicyTargetID) { - - //User can set the poolId as combination of lbID/poolID, if so parse the string & get the poolID - id, err := getPoolID(d.Get(isLBListenerPolicyTargetID).(string)) + if d.HasChange("target") { + target, err := resourceIBMIsLbListenerPolicyMapToLoadBalancerListenerPolicyTargetPatch(d, d.Get("target.0").(map[string]interface{}), &httpsURIRemoved) if err != nil { - return err - } - target = &vpcv1.LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity{ - ID: &id, + return diag.FromErr(err) } - loadBalancerListenerPolicyPatchModel.Target = target hasChanged = true - } else if d.Get(isLBListenerPolicyAction).(string) == "redirect" { - //if Action is redirect and either status code or URL chnaged, set accordingly - //LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch - redirectPatch := vpcv1.LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch{} + } else { - targetChange := false - if d.HasChange(isLBListenerPolicyTargetHTTPStatusCode) { - status := d.Get(isLBListenerPolicyTargetHTTPStatusCode).(int) - sc := int64(status) - redirectPatch.HTTPStatusCode = &sc - hasChanged = true - targetChange = true - } + //If Action is forward and TargetID is changed, set the target to pool ID + if d.Get(isLBListenerPolicyAction).(string) == "forward" && d.HasChange(isLBListenerPolicyTargetID) { - if d.HasChange(isLBListenerPolicyTargetURL) { - url := d.Get(isLBListenerPolicyTargetURL).(string) - redirectPatch.URL = &url - hasChanged = true - targetChange = true - } + //User can set the poolId as combination of lbID/poolID, if so parse the string & get the poolID + id, err := getPoolID(d.Get(isLBListenerPolicyTargetID).(string)) + if err != nil { + return diag.FromErr(err) + } + target = &vpcv1.LoadBalancerListenerPolicyTargetPatchLoadBalancerPoolIdentity{ + ID: &id, + } - //Update the target only if there is a change in either statusCode or URL - if targetChange { - target = &redirectPatch loadBalancerListenerPolicyPatchModel.Target = target - } - } else if d.Get(isLBListenerPolicyAction).(string) == "https_redirect" { + hasChanged = true + } else if d.Get(isLBListenerPolicyAction).(string) == "redirect" { + //if Action is redirect and either status code or URL chnaged, set accordingly + //LoadBalancerListenerPolicyPatchTargetLoadBalancerListenerPolicyRedirectURLPatch + + redirectPatch := vpcv1.LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerPolicyRedirectURLPatch{} + + targetChange := false + if d.HasChange(isLBListenerPolicyTargetHTTPStatusCode) { + status := d.Get(isLBListenerPolicyTargetHTTPStatusCode).(int) + sc := int64(status) + redirectPatch.HTTPStatusCode = &sc + hasChanged = true + targetChange = true + } - httpsRedirectPatch := vpcv1.LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch{} + if d.HasChange(isLBListenerPolicyTargetURL) { + url := d.Get(isLBListenerPolicyTargetURL).(string) + redirectPatch.URL = &url + hasChanged = true + targetChange = true + } - targetChange := false - if d.HasChange(isLBListenerPolicyHTTPSRedirectListener) { - listener := d.Get(isLBListenerPolicyHTTPSRedirectListener).(string) - httpsRedirectPatch.Listener = &vpcv1.LoadBalancerListenerIdentity{ - ID: &listener, + //Update the target only if there is a change in either statusCode or URL + if targetChange { + target = &redirectPatch + loadBalancerListenerPolicyPatchModel.Target = target } - hasChanged = true - targetChange = true - } + } else if d.Get(isLBListenerPolicyAction).(string) == "https_redirect" { - if d.HasChange(isLBListenerPolicyHTTPSRedirectStatusCode) { - status := d.Get(isLBListenerPolicyHTTPSRedirectStatusCode).(int) - sc := int64(status) - httpsRedirectPatch.HTTPStatusCode = &sc - hasChanged = true - targetChange = true - } + httpsRedirectPatch := vpcv1.LoadBalancerListenerPolicyTargetPatchLoadBalancerListenerHTTPSRedirectPatch{} - if d.HasChange(isLBListenerPolicyHTTPSRedirectURI) { - uri := d.Get(isLBListenerPolicyHTTPSRedirectURI).(string) - httpsRedirectPatch.URI = &uri - hasChanged = true - targetChange = true - if uri == "" { - httpsURIRemoved = true + targetChange := false + if d.HasChange(isLBListenerPolicyHTTPSRedirectListener) { + listener := d.Get(isLBListenerPolicyHTTPSRedirectListener).(string) + httpsRedirectPatch.Listener = &vpcv1.LoadBalancerListenerIdentity{ + ID: &listener, + } + hasChanged = true + targetChange = true } - } - //Update the target only if there is a change in either listener, statusCode or URI - if targetChange { - target = &httpsRedirectPatch - loadBalancerListenerPolicyPatchModel.Target = target + if d.HasChange(isLBListenerPolicyHTTPSRedirectStatusCode) { + status := d.Get(isLBListenerPolicyHTTPSRedirectStatusCode).(int) + sc := int64(status) + httpsRedirectPatch.HTTPStatusCode = &sc + hasChanged = true + targetChange = true + } + + if d.HasChange(isLBListenerPolicyHTTPSRedirectURI) { + uri := d.Get(isLBListenerPolicyHTTPSRedirectURI).(string) + httpsRedirectPatch.URI = &uri + hasChanged = true + targetChange = true + if uri == "" { + httpsURIRemoved = true + } + } + + //Update the target only if there is a change in either listener, statusCode or URI + if targetChange { + target = &httpsRedirectPatch + loadBalancerListenerPolicyPatchModel.Target = target + } } } - if hasChanged { loadBalancerListenerPolicyPatch, err := loadBalancerListenerPolicyPatchModel.AsPatch() if err != nil { - return fmt.Errorf("[ERROR] Error calling asPatch for LoadBalancerListenerPolicyPatch: %s", err) + return diag.FromErr(fmt.Errorf("[ERROR] Error calling asPatch for LoadBalancerListenerPolicyPatch: %s", err)) } if httpsURIRemoved { loadBalancerListenerPolicyPatch["target"].(map[string]interface{})["uri"] = nil @@ -780,28 +890,28 @@ func lbListenerPolicyUpdate(d *schema.ResourceData, meta interface{}, lbID, list _, err = isWaitForLbAvailable(sess, lbID, d.Timeout(schema.TimeoutCreate)) if err != nil { - return fmt.Errorf( - "LB-LP Error checking for load balancer (%s) is active: %s", lbID, err) + return diag.FromErr(fmt.Errorf( + "LB-LP Error checking for load balancer (%s) is active: %s", lbID, err)) } _, response, err := sess.UpdateLoadBalancerListenerPolicy(&updatePolicyOptions) if err != nil { - return fmt.Errorf("[ERROR] Error Updating in policy : %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error Updating in policy : %s\n%s", err, response)) } _, err = isWaitForLbListenerPolicyAvailable(sess, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { - return err + return diag.FromErr(err) } } return nil } -func resourceIBMISLBListenerPolicyDelete(d *schema.ResourceData, meta interface{}) error { +func resourceIBMISLBListenerPolicyDelete(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { //Retrieve lbId, listenerId and policyID parts, err := flex.IdParts(d.Id()) if err != nil { - return err + return diag.FromErr(err) } lbID := parts[0] @@ -814,7 +924,7 @@ func resourceIBMISLBListenerPolicyDelete(d *schema.ResourceData, meta interface{ err = lbListenerPolicyDelete(d, meta, lbID, listenerID, policyID) if err != nil { - return err + return diag.FromErr(err) } d.SetId("") @@ -912,11 +1022,11 @@ func isLbListenerPolicyDeleteRefreshFunc(vpc *vpcv1.VpcV1, id string) resource.S } } -func lbListenerPolicyGet(d *schema.ResourceData, meta interface{}, lbID, listenerID, id string) error { +func lbListenerPolicyGet(d *schema.ResourceData, meta interface{}, lbID, listenerID, id string) diag.Diagnostics { sess, err := vpcClient(meta) if err != nil { - return err + return diag.FromErr(err) } //Getting policy optins @@ -933,7 +1043,7 @@ func lbListenerPolicyGet(d *schema.ResourceData, meta interface{}, lbID, listene d.SetId("") return nil } - return err + return diag.FromErr(err) } //set the argument values @@ -965,7 +1075,7 @@ func lbListenerPolicyGet(d *schema.ResourceData, meta interface{}, lbID, listene d.SetId("") return nil } - return err + return diag.FromErr(err) } l := map[string]interface{}{ @@ -983,41 +1093,222 @@ func lbListenerPolicyGet(d *schema.ResourceData, meta interface{}, lbID, listene // `LoadBalancerPoolReference` is in the response if `action` is `forward`. // `LoadBalancerListenerPolicyRedirectURL` is in the response if `action` is `redirect`. - if *(policy.Action) == "forward" { - if reflect.TypeOf(policy.Target).String() == "*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerPoolReference" { - target, ok := policy.Target.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerPoolReference) - if ok { - d.Set(isLBListenerPolicyTargetID, target.ID) - } - } + if !core.IsNil(policy.Target) { + if _, ok := d.GetOk("target"); ok { - } else if *(policy.Action) == "redirect" { - if reflect.TypeOf(policy.Target).String() == "*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL" { - target, ok := policy.Target.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL) - if ok { - d.Set(isLBListenerPolicyTargetURL, target.URL) - d.Set(isLBListenerPolicyTargetHTTPStatusCode, target.HTTPStatusCode) + targetMap, err := resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetToMap(policy.Target) + if err != nil { + return diag.FromErr(err) } - } - } else if *(policy.Action) == "https_redirect" { - if reflect.TypeOf(policy.Target).String() == "*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect" { - target, ok := policy.Target.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect) - if ok { - d.Set(isLBListenerPolicyHTTPSRedirectListener, target.Listener.ID) - d.Set(isLBListenerPolicyHTTPSRedirectStatusCode, target.HTTPStatusCode) - d.Set(isLBListenerPolicyHTTPSRedirectURI, target.URI) + if err = d.Set("target", []map[string]interface{}{targetMap}); err != nil { + return diag.FromErr(fmt.Errorf("Error setting target: %s", err)) + } + } else { + if *(policy.Action) == "forward" { + if reflect.TypeOf(policy.Target).String() == "*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerPoolReference" { + target, ok := policy.Target.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerPoolReference) + if ok { + d.Set(isLBListenerPolicyTargetID, target.ID) + } + } + + } else if *(policy.Action) == "redirect" { + if reflect.TypeOf(policy.Target).String() == "*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL" { + target, ok := policy.Target.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL) + if ok { + d.Set(isLBListenerPolicyTargetURL, target.URL) + d.Set(isLBListenerPolicyTargetHTTPStatusCode, target.HTTPStatusCode) + } + } + } else if *(policy.Action) == "https_redirect" { + if reflect.TypeOf(policy.Target).String() == "*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect" { + target, ok := policy.Target.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect) + if ok { + d.Set(isLBListenerPolicyHTTPSRedirectListener, target.Listener.ID) + d.Set(isLBListenerPolicyHTTPSRedirectStatusCode, target.HTTPStatusCode) + d.Set(isLBListenerPolicyHTTPSRedirectURI, target.URI) + } + } } } } - getLoadBalancerOptions := &vpcv1.GetLoadBalancerOptions{ ID: &lbID, } lb, response, err := sess.GetLoadBalancer(getLoadBalancerOptions) if err != nil { - return fmt.Errorf("[ERROR] Error Getting Load Balancer : %s\n%s", err, response) + return diag.FromErr(fmt.Errorf("[ERROR] Error Getting Load Balancer : %s\n%s", err, response)) } d.Set(flex.RelatedCRN, *lb.CRN) return nil } + +func resourceIBMIsLbListenerPolicyMapToLoadBalancerListenerPolicyTargetPrototype(modelMap map[string]interface{}) (vpcv1.LoadBalancerListenerPolicyTargetPrototypeIntf, error) { + model := &vpcv1.LoadBalancerListenerPolicyTargetPrototype{} + if modelMap["id"] != nil && modelMap["id"].(string) != "" { + model.ID = core.StringPtr(modelMap["id"].(string)) + } + if modelMap["http_status_code"] != nil && modelMap["http_status_code"].(int) != 0 { + model.HTTPStatusCode = core.Int64Ptr(int64(modelMap["http_status_code"].(int))) + } + if modelMap["url"] != nil && modelMap["url"].(string) != "" { + model.URL = core.StringPtr(modelMap["url"].(string)) + } + if modelMap["listener"] != nil && len(modelMap["listener"].([]interface{})) > 0 { + ListenerModel, err := resourceIBMIsLbListenerPolicyMapToLoadBalancerListenerIdentity(modelMap["listener"].([]interface{})[0].(map[string]interface{})) + if err != nil { + return model, err + } + model.Listener = ListenerModel + } + if modelMap["uri"] != nil && modelMap["uri"].(string) != "" { + model.URI = core.StringPtr(modelMap["uri"].(string)) + } + return model, nil +} +func resourceIBMIsLbListenerPolicyMapToLoadBalancerListenerIdentity(modelMap map[string]interface{}) (vpcv1.LoadBalancerListenerIdentityIntf, error) { + model := &vpcv1.LoadBalancerListenerIdentity{} + if modelMap["id"] != nil && modelMap["id"].(string) != "" { + model.ID = core.StringPtr(modelMap["id"].(string)) + } + return model, nil +} + +func resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetToMap(model vpcv1.LoadBalancerListenerPolicyTargetIntf) (map[string]interface{}, error) { + if _, ok := model.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerPoolReference); ok { + return resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetLoadBalancerPoolReferenceToMap(model.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerPoolReference)) + } else if _, ok := model.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL); ok { + return resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURLToMap(model.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL)) + } else if _, ok := model.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect); ok { + return resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirectToMap(model.(*vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect)) + } else if _, ok := model.(*vpcv1.LoadBalancerListenerPolicyTarget); ok { + modelMap := make(map[string]interface{}) + model := model.(*vpcv1.LoadBalancerListenerPolicyTarget) + if model.Deleted != nil { + deletedMap, err := resourceIBMIsLbListenerPolicyLoadBalancerPoolReferenceDeletedToMap(model.Deleted) + if err != nil { + return modelMap, err + } + modelMap["deleted"] = []map[string]interface{}{deletedMap} + } + if model.Href != nil { + modelMap["href"] = model.Href + } + if model.ID != nil { + modelMap["id"] = model.ID + } + if model.Name != nil { + modelMap["name"] = model.Name + } + if model.HTTPStatusCode != nil { + modelMap["http_status_code"] = flex.IntValue(model.HTTPStatusCode) + } + if model.URL != nil { + modelMap["url"] = model.URL + } + if model.Listener != nil { + listenerMap, err := resourceIBMIsLbListenerPolicyLoadBalancerListenerReferenceToMap(model.Listener) + if err != nil { + return modelMap, err + } + modelMap["listener"] = []map[string]interface{}{listenerMap} + } + if model.URI != nil { + modelMap["uri"] = model.URI + } + return modelMap, nil + } else { + return nil, fmt.Errorf("Unrecognized vpcv1.LoadBalancerListenerPolicyTargetIntf subtype encountered") + } +} + +func resourceIBMIsLbListenerPolicyLoadBalancerPoolReferenceDeletedToMap(model *vpcv1.LoadBalancerPoolReferenceDeleted) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + modelMap["more_info"] = model.MoreInfo + return modelMap, nil +} + +func resourceIBMIsLbListenerPolicyLoadBalancerListenerReferenceToMap(model *vpcv1.LoadBalancerListenerReference) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + if model.Deleted != nil { + deletedMap, err := resourceIBMIsLbListenerPolicyLoadBalancerListenerReferenceDeletedToMap(model.Deleted) + if err != nil { + return modelMap, err + } + modelMap["deleted"] = []map[string]interface{}{deletedMap} + } + modelMap["href"] = model.Href + modelMap["id"] = model.ID + return modelMap, nil +} + +func resourceIBMIsLbListenerPolicyLoadBalancerListenerReferenceDeletedToMap(model *vpcv1.LoadBalancerListenerReferenceDeleted) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + modelMap["more_info"] = model.MoreInfo + return modelMap, nil +} + +func resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetLoadBalancerPoolReferenceToMap(model *vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerPoolReference) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + if model.Deleted != nil { + deletedMap, err := resourceIBMIsLbListenerPolicyLoadBalancerPoolReferenceDeletedToMap(model.Deleted) + if err != nil { + return modelMap, err + } + modelMap["deleted"] = []map[string]interface{}{deletedMap} + } + modelMap["href"] = model.Href + modelMap["id"] = model.ID + modelMap["name"] = model.Name + return modelMap, nil +} + +func resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURLToMap(model *vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerPolicyRedirectURL) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + modelMap["http_status_code"] = flex.IntValue(model.HTTPStatusCode) + modelMap["url"] = model.URL + return modelMap, nil +} + +func resourceIBMIsLbListenerPolicyLoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirectToMap(model *vpcv1.LoadBalancerListenerPolicyTargetLoadBalancerListenerHTTPSRedirect) (map[string]interface{}, error) { + modelMap := make(map[string]interface{}) + modelMap["http_status_code"] = flex.IntValue(model.HTTPStatusCode) + listenerMap, err := resourceIBMIsLbListenerPolicyLoadBalancerListenerReferenceToMap(model.Listener) + if err != nil { + return modelMap, err + } + modelMap["listener"] = []map[string]interface{}{listenerMap} + if model.URI != nil { + modelMap["uri"] = model.URI + } + return modelMap, nil +} + +func resourceIBMIsLbListenerPolicyMapToLoadBalancerListenerPolicyTargetPatch(d *schema.ResourceData, modelMap map[string]interface{}, httpsURIRemoved *bool) (vpcv1.LoadBalancerListenerPolicyTargetPatchIntf, error) { + model := &vpcv1.LoadBalancerListenerPolicyTargetPatch{} + if d.HasChange("target.0.id") && modelMap["id"] != nil && modelMap["id"].(string) != "" { + model.ID = core.StringPtr(modelMap["id"].(string)) + } + if d.HasChange("target.0.http_status_code") && modelMap["http_status_code"] != nil { + model.HTTPStatusCode = core.Int64Ptr(int64(modelMap["http_status_code"].(int))) + } + if d.HasChange("target.0.url") && modelMap["url"] != nil && modelMap["url"].(string) != "" { + model.URL = core.StringPtr(modelMap["url"].(string)) + } + if d.HasChange("target.0.listener") && modelMap["listener"] != nil && len(modelMap["listener"].([]interface{})) > 0 { + ListenerModel, err := resourceIBMIsLbListenerPolicyMapToLoadBalancerListenerIdentity(modelMap["listener"].([]interface{})[0].(map[string]interface{})) + if err != nil { + return model, err + } + model.Listener = ListenerModel + } + if d.HasChange("target.0.uri") { + if modelMap["uri"] != nil && modelMap["uri"].(string) != "" { + model.URI = core.StringPtr(modelMap["uri"].(string)) + } else { + *httpsURIRemoved = true + } + } + return model, nil +} diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go b/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go index 340fbac619..814d41e95c 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go @@ -211,6 +211,60 @@ func TestAccIBMISLBListenerPolicyHttpRedirect_basic(t *testing.T) { }) } +func TestAccIBMISLBListenerPolicyHttpRedirectNew_basic(t *testing.T) { + var lb string + vpcname := fmt.Sprintf("tflblis-vpc-%d", acctest.RandIntRange(10, 100)) + subnetname := fmt.Sprintf("tflblis-subnet-%d", acctest.RandIntRange(10, 100)) + lbname := fmt.Sprintf("tflblis%d", acctest.RandIntRange(10, 100)) + lbpolicyname := fmt.Sprintf("tflblispol%d", acctest.RandIntRange(10, 100)) + protocol1 := "https" + port1 := "9086" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMISLBListenerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISLBListenerPolicyHttpsRedirectNewConfig(vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, lbname, port1, protocol1, lbpolicyname), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBListenerExists("ibm_is_lb_listener_policy.lb_listener_policy", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_LB", "name", lbname), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.http_status_code", "302"), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.uri", "/example?doc=get"), + ), + }, + { + Config: testAccCheckIBMISLBListenerPolicyHttpsRedirectNewConfigUpdate(vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, lbname, port1, protocol1, lbpolicyname), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBListenerExists("ibm_is_lb_listener_policy.lb_listener_policy", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_LB", "name", lbname), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.http_status_code", "301"), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.uri", "/example?doc=getupdated"), + ), + }, + { + Config: testAccCheckIBMISLBListenerPolicyHttpsRedirectNewConfigRemoveUri(vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, lbname, port1, protocol1, lbpolicyname), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBListenerExists("ibm_is_lb_listener_policy.lb_listener_policy", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_LB", "name", lbname), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.http_status_code", "301"), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.uri", "/example?doc=getupdated"), + resource.TestCheckNoResourceAttr("ibm_is_lb_listener_policy.lb_listener_policy", "target.0.uri"), + ), + }, + }, + }) +} func testAccCheckIBMISLBListenerPolicyDestroy(s *terraform.State) error { sess, _ := acc.TestAccProvider.Meta().(conns.ClientSession).VpcV1API() @@ -571,7 +625,174 @@ func testAccCheckIBMISLBListenerPolicyHttpsRedirectConfig(vpcname, subnetname, z }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance, lbpolicyname) } +func testAccCheckIBMISLBListenerPolicyHttpsRedirectNewConfig(vpcname, subnetname, zone, cidr, lbname, port, protocol, lbpolicyname string) 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" + ipv4_cidr_block = "%s" + } + resource "ibm_is_lb" "testacc_LB" { + name = "%s" + subnets = ["${ibm_is_subnet.testacc_subnet.id}"] + } + resource "ibm_is_lb_listener" "lb_listener1"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + resource "ibm_is_lb_listener" "lb_listener2"{ + lb = ibm_is_lb.testacc_LB.id + port = "9087" + protocol = "http" + https_redirect { + http_status_code = 301 + listener { + id = ibm_is_lb_listener.lb_listener1.listener_id + } + uri = "/example?doc=get" + } + } + resource "ibm_is_lb_listener" "lb_listener3"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + + resource "ibm_is_lb_listener_policy" "lb_listener_policy" { + name = "%s" + lb = ibm_is_lb.testacc_LB.id + listener = ibm_is_lb_listener.lb_listener2.listener_id + action = "https_redirect" + target { + http_status_code = 302 + listener { + id = ibm_is_lb_listener.lb_listener1.listener_id + } + uri = "/example?doc=get" + } + priority = 2 + }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance, acc.LbListerenerCertificateInstance, lbpolicyname) + +} +func testAccCheckIBMISLBListenerPolicyHttpsRedirectNewConfigUpdate(vpcname, subnetname, zone, cidr, lbname, port, protocol, lbpolicyname string) 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" + ipv4_cidr_block = "%s" + } + resource "ibm_is_lb" "testacc_LB" { + name = "%s" + subnets = ["${ibm_is_subnet.testacc_subnet.id}"] + } + resource "ibm_is_lb_listener" "lb_listener1"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + resource "ibm_is_lb_listener" "lb_listener2"{ + lb = ibm_is_lb.testacc_LB.id + port = "9087" + protocol = "http" + https_redirect { + http_status_code = 301 + listener { + id = ibm_is_lb_listener.lb_listener1.listener_id + } + uri = "/example?doc=get" + } + } + resource "ibm_is_lb_listener" "lb_listener3"{ + lb = ibm_is_lb.testacc_LB.id + port = "9088" + protocol = "https" + certificate_instance="%s" + } + + resource "ibm_is_lb_listener_policy" "lb_listener_policy" { + name = "%s" + lb = ibm_is_lb.testacc_LB.id + listener = ibm_is_lb_listener.lb_listener2.listener_id + action = "https_redirect" + target { + http_status_code = 301 + listener { + id = ibm_is_lb_listener.lb_listener3.listener_id + } + uri = "/example?doc=getupdated" + } + priority = 2 + }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance, acc.LbListerenerCertificateInstance, lbpolicyname) + +} +func testAccCheckIBMISLBListenerPolicyHttpsRedirectNewConfigRemoveUri(vpcname, subnetname, zone, cidr, lbname, port, protocol, lbpolicyname string) 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" + ipv4_cidr_block = "%s" + } + resource "ibm_is_lb" "testacc_LB" { + name = "%s" + subnets = ["${ibm_is_subnet.testacc_subnet.id}"] + } + resource "ibm_is_lb_listener" "lb_listener1"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + resource "ibm_is_lb_listener" "lb_listener2"{ + lb = ibm_is_lb.testacc_LB.id + port = "9087" + protocol = "http" + + https_redirect { + http_status_code = 301 + listener { + id = ibm_is_lb_listener.lb_listener1.listener_id + } + uri = "/example?doc=get" + } + } + resource "ibm_is_lb_listener" "lb_listener3"{ + lb = ibm_is_lb.testacc_LB.id + port = "9088" + protocol = "https" + certificate_instance="%s" + } + + resource "ibm_is_lb_listener_policy" "lb_listener_policy" { + name = "%s" + lb = ibm_is_lb.testacc_LB.id + listener = ibm_is_lb_listener.lb_listener2.listener_id + action = "https_redirect" + target { + http_status_code = 301 + listener { + id = ibm_is_lb_listener.lb_listener3.listener_id + } + } + priority = 2 + }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance, acc.LbListerenerCertificateInstance, lbpolicyname) +} func testAccCheckIBMISLBListenerPolicyHttpsRedirectConfigUpdate(vpcname, subnetname, zone, cidr, lbname, port, protocol, lbpolicyname string) string { return fmt.Sprintf(` resource "ibm_is_vpc" "testacc_vpc" { diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener_test.go b/ibm/service/vpc/resource_ibm_is_lb_listener_test.go index 68ac22f588..3e21e729b0 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener_test.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener_test.go @@ -299,6 +299,69 @@ func TestAccIBMISLBListenerHttpRedirect_basic(t *testing.T) { }, }) } +func TestAccIBMISLBListenerHttpRedirectNew_basic(t *testing.T) { + var lb string + vpcname := fmt.Sprintf("tflblis-vpc-%d", acctest.RandIntRange(10, 100)) + subnetname := fmt.Sprintf("tflblis-subnet-%d", acctest.RandIntRange(10, 100)) + lbname := fmt.Sprintf("tflblis%d", acctest.RandIntRange(10, 100)) + + protocol1 := "https" + port1 := "9086" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + Providers: acc.TestAccProviders, + CheckDestroy: testAccCheckIBMISLBListenerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckIBMISLBListenerHttpsRedirectNewConfig(vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, lbname, port1, protocol1), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBListenerExists("ibm_is_lb_listener.lb_listener2", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_LB", "name", lbname), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.status_code", "301"), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", "/example?doc=get"), + ), + }, + { + Config: testAccCheckIBMISLBListenerHttpsRedirectNewConfigUpdate(vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, lbname, port1, protocol1), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBListenerExists("ibm_is_lb_listener.lb_listener2", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_LB", "name", lbname), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.status_code", "303"), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", "/example?doc=getupdated"), + ), + }, + { + Config: testAccCheckIBMISLBListenerHttpsRedirectNewConfigURIRemove(vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, lbname, port1, protocol1), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBListenerExists("ibm_is_lb_listener.lb_listener2", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_LB", "name", lbname), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.status_code", "303"), + resource.TestCheckResourceAttr( + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", "/example?doc=getupdated"), + ), + }, + { + Config: testAccCheckIBMISLBListenerHttpsRedirectNewConfigRemove(vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, lbname, port1, protocol1), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISLBListenerExists("ibm_is_lb_listener.lb_listener2", lb), + resource.TestCheckResourceAttr( + "ibm_is_lb.testacc_LB", "name", lbname), + resource.TestCheckNoResourceAttr( + "ibm_is_lb_listener.lb_listener2", "https_redirect"), + ), + }, + }, + }) +} func testAccCheckIBMISLBListenerDestroy(s *terraform.State) error { @@ -536,6 +599,151 @@ func testAccCheckIBMISLBListenerHttpsRedirectConfigRemove(vpcname, subnetname, z }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance) } + +func testAccCheckIBMISLBListenerHttpsRedirectNewConfig(vpcname, subnetname, zone, cidr, lbname, port, protocol string) 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" + ipv4_cidr_block = "%s" + } + resource "ibm_is_lb" "testacc_LB" { + name = "%s" + subnets = ["${ibm_is_subnet.testacc_subnet.id}"] + } + resource "ibm_is_lb_listener" "lb_listener1"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + + resource "ibm_is_lb_listener" "lb_listener2"{ + lb = ibm_is_lb.testacc_LB.id + port = "9087" + protocol = "http" + https_redirect { + http_status_code = 302 + listener { + id = ibm_is_lb_listener.lb_listener1.listener_id + } + uri = "/example?doc=get" + } + }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance) + +} + +func testAccCheckIBMISLBListenerHttpsRedirectNewConfigUpdate(vpcname, subnetname, zone, cidr, lbname, port, protocol string) 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" + ipv4_cidr_block = "%s" + } + resource "ibm_is_lb" "testacc_LB" { + name = "%s" + subnets = ["${ibm_is_subnet.testacc_subnet.id}"] + } + resource "ibm_is_lb_listener" "lb_listener1"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + + resource "ibm_is_lb_listener" "lb_listener2"{ + lb = ibm_is_lb.testacc_LB.id + port = "9087" + protocol = "http" + https_redirect { + http_status_code = 303 + listener { + id = ibm_is_lb_listener.lb_listener1.listener_id + } + uri = "/example?doc=getupdated" + } + }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance) + +} + +func testAccCheckIBMISLBListenerHttpsRedirectNewConfigURIRemove(vpcname, subnetname, zone, cidr, lbname, port, protocol string) 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" + ipv4_cidr_block = "%s" + } + resource "ibm_is_lb" "testacc_LB" { + name = "%s" + subnets = ["${ibm_is_subnet.testacc_subnet.id}"] + } + resource "ibm_is_lb_listener" "lb_listener1"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + + resource "ibm_is_lb_listener" "lb_listener2"{ + lb = ibm_is_lb.testacc_LB.id + port = "9087" + protocol = "http" + https_redirect { + http_status_code = 303 + listener { + id = ibm_is_lb_listener.lb_listener1.listener_id + } + } + }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance) + +} + +func testAccCheckIBMISLBListenerHttpsRedirectNewConfigRemove(vpcname, subnetname, zone, cidr, lbname, port, protocol string) 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" + ipv4_cidr_block = "%s" + } + resource "ibm_is_lb" "testacc_LB" { + name = "%s" + subnets = ["${ibm_is_subnet.testacc_subnet.id}"] + } + resource "ibm_is_lb_listener" "lb_listener1"{ + lb = ibm_is_lb.testacc_LB.id + port = "9086" + protocol = "https" + certificate_instance="%s" + } + + resource "ibm_is_lb_listener" "lb_listener2"{ + lb = ibm_is_lb.testacc_LB.id + port = "9087" + protocol = "http" + }`, vpcname, subnetname, zone, cidr, lbname, acc.LbListerenerCertificateInstance) + +} + func testAccCheckIBMISNLBRouteModeListenerConfig(vpcname, subnetname, zone, cidr, lbname, port, protocol string) string { return fmt.Sprintf(` resource "ibm_is_vpc" "testacc_vpc" { diff --git a/website/docs/r/is_lb_listener.html.markdown b/website/docs/r/is_lb_listener.html.markdown index c9b04be076..2bfcb14858 100644 --- a/website/docs/r/is_lb_listener.html.markdown +++ b/website/docs/r/is_lb_listener.html.markdown @@ -195,6 +195,19 @@ Review the argument references that you can specify for your resource. - `https_redirect_listener` - (Optional, String) ID of the listener that will be set as http redirect target. - `https_redirect_status_code` - (Optional, Integer) The HTTP status code to be returned in the redirect response, one of [301, 302, 303, 307, 308]. - `https_redirect_uri` - (Optional, String) Target URI where traffic will be redirected. + +~**Note** + `https_redirect_listener`, `https_redirect_status_code` and `https_redirect_uri` are deprecated and will be removed in future. Please use `https_redirect` instead + +- `https_redirect` - (Optional, List) If present, the target listener that requests are redirected to. Removing `https_redirect` would update the load balancer listener and disable the `https_redirect` + + Nested schema for **https_redirect**: + - `http_status_code` - (Required, Integer) The HTTP status code for this redirect. Allowable values are: `301`, `302`, `303`, `307`, `308`. + - `listener` - (Required, List) + + Nested schema for **listener**: + - `id` - (Required, String) The unique identifier for this load balancer listener. + - `uri` - (Optional, String) The redirect relative target URI. Removing `uri` would update the load balancer listener and remove the `uri` from `https_redirect` - `idle_connection_timeout` - (Optional, Integer) The idle connection timeout of the listener in seconds. Supported for load balancers in the `application` family. Default value is `50`, allowed value is between `50` - `7200`. ## Attribute reference @@ -202,7 +215,20 @@ In addition to all argument reference list, you can access the following attribu - `id` - (String) The unique identifier of the load balancer listener. - `status` - (String) The status of load balancer listener. - +- `https_redirect` - (List) If present, the target listener that requests are redirected to. + + Nested schema for **https_redirect**: + - `http_status_code` - (Integer) The HTTP status code for this redirect. + - `listener` - (List) + + Nested schema for **listener**: + - `deleted` - (List) If present, this property indicates the referenced resource has been deleted, and providessome supplementary information. + + Nested schema for **deleted**: + - `more_info` - (String) Link to documentation about deleted resources. + - `href` - (String) The listener's canonical URL. + - `id` - (String) The unique identifier for this load balancer listener. + - `uri` - (String) The redirect relative target URI. ## Import The `ibm_is_lb_listener` resource can be imported by using the load balancer ID and listener ID. diff --git a/website/docs/r/is_lb_listener_policy.html.markdown b/website/docs/r/is_lb_listener_policy.html.markdown index b1b66cb646..a3b112d2ac 100644 --- a/website/docs/r/is_lb_listener_policy.html.markdown +++ b/website/docs/r/is_lb_listener_policy.html.markdown @@ -166,6 +166,24 @@ Review the argument references that you can specify for your resource. When action is `redirect`, `target_url` should specify the `url` and `target_http_status_code` to specify the code used in the redirect response. When action is `https_redirect`, `target_https_redirect_listener` should specify the ID of the listener, `target_https_redirect_status_code` to specify the code used in the redirect response and `target_https_redirect_uri` to specify the target URI where traffic will be redirected. Network load balancer does not support `ibm_is_lb_listener_policy`. +- `target` - (Optional, List) - If `action` is `forward`, the response is a `LoadBalancerPoolReference`- If `action` is `redirect`, the response is a `LoadBalancerListenerPolicyRedirectURL`- If `action` is `https_redirect`, the response is a `LoadBalancerListenerHTTPSRedirect`. + Nested schema for **target**: + - `deleted` - (Computed, List) If present, this property indicates the referenced resource has been deleted, and providessome supplementary information. + Nested schema for **deleted**: + - `more_info` - (Computed, String) Link to documentation about deleted resources. + - `href` - (Optional, String) The pool's canonical URL. + - `http_status_code` - (Optional, Integer) The HTTP status code for this redirect. Allowable values are: `301`, `302`, `303`, `307`, `308`. + - `id` - (Optional, String) The unique identifier for this load balancer pool. + - `listener` - (Optional, List) + Nested schema for **listener**: + - `deleted` - (Computed, List) If present, this property indicates the referenced resource has been deleted, and providessome supplementary information. + Nested schema for **deleted**: + - `more_info` - (Computed, String) Link to documentation about deleted resources. + - `href` - (Optional, String) The listener's canonical URL. + - `id` - (Optional, String) The unique identifier for this load balancer listener. + - `name` - (Computed, String) The name for this load balancer pool. The name is unique across all pools for the load balancer. + - `url` - (Optional, String) The redirect target URL. + ## Attribute reference In addition to all argument reference list, you can access the following attribute reference after your resource is created. From 8631c110143b9f86b7d38172649630fedd7be2d2 Mon Sep 17 00:00:00 2001 From: Deepak Selvakumar <77007253+deepaksibm@users.noreply.github.com> Date: Fri, 16 Feb 2024 01:22:32 +0530 Subject: [PATCH 2/4] test changes --- ibm/acctest/acctest.go | 2 +- ibm/service/vpc/resource_ibm_is_lb_listener.go | 5 ++++- ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go | 6 ++---- ibm/service/vpc/resource_ibm_is_lb_listener_test.go | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ibm/acctest/acctest.go b/ibm/acctest/acctest.go index 3066238605..00f94a06f4 100644 --- a/ibm/acctest/acctest.go +++ b/ibm/acctest/acctest.go @@ -591,7 +591,7 @@ func init() { } LbListerenerCertificateInstance = os.Getenv("IBM_LB_LISTENER_CERTIFICATE_INSTANCE") if LbListerenerCertificateInstance == "" { - LbListerenerCertificateInstance = "crn:v1:staging:public:cloudcerts:us-south:a/2d1bace7b46e4815a81e52c6ffeba5cf:af925157-b125-4db2-b642-adacb8b9c7f5:certificate:c81627a1bf6f766379cc4b98fd2a44ed" + LbListerenerCertificateInstance = "crn:v1:bluemix:public:secrets-manager:us-south:a/1431ea2a7958ad20f0fee592ff85f746:2f504783-548b-4a8e-85ba-6a8df9c62a1f:secret:4b9bdfeb-a2a4-23bc-5e9d-3d60a0debd51" fmt.Println("[WARN] Set the environment variable IBM_LB_LISTENER_CERTIFICATE_INSTANCE for testing ibm_is_lb_listener resource for https redirect else it is set to default value 'crn:v1:staging:public:cloudcerts:us-south:a/2d1bace7b46e4815a81e52c6ffeba5cf:af925157-b125-4db2-b642-adacb8b9c7f5:certificate:c81627a1bf6f766379cc4b98fd2a44ed'") } diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener.go b/ibm/service/vpc/resource_ibm_is_lb_listener.go index 3652fb61b8..84ee4ee34e 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener.go @@ -122,6 +122,7 @@ func ResourceIBMISLBListener() *schema.Resource { Optional: true, RequiredWith: []string{isLBListenerHTTPSRedirectListener}, ConflictsWith: []string{"https_redirect"}, + Deprecated: "Please use the argument 'https_redirect'", Description: "The HTTP status code to be returned in the redirect response", }, @@ -129,6 +130,7 @@ func ResourceIBMISLBListener() *schema.Resource { Type: schema.TypeString, Optional: true, ConflictsWith: []string{"https_redirect"}, + Deprecated: "Please use the argument 'https_redirect'", RequiredWith: []string{isLBListenerHTTPSRedirectStatusCode, isLBListenerHTTPSRedirectListener}, Description: "Target URI where traffic will be redirected", }, @@ -137,6 +139,7 @@ func ResourceIBMISLBListener() *schema.Resource { Type: schema.TypeString, Optional: true, ConflictsWith: []string{"https_redirect"}, + Deprecated: "Please use the argument 'https_redirect'", RequiredWith: []string{isLBListenerHTTPSRedirectStatusCode}, Description: "ID of the listener that will be set as http redirect target", }, @@ -181,7 +184,7 @@ func ResourceIBMISLBListener() *schema.Resource { }, "id": &schema.Schema{ Type: schema.TypeString, - Optional: true, + Required: true, Description: "The unique identifier for this load balancer listener.", }, }, diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go b/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go index 814d41e95c..75af6db710 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener_policy_test.go @@ -257,9 +257,7 @@ func TestAccIBMISLBListenerPolicyHttpRedirectNew_basic(t *testing.T) { "ibm_is_lb.testacc_LB", "name", lbname), resource.TestCheckResourceAttr( "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.http_status_code", "301"), - resource.TestCheckResourceAttr( - "ibm_is_lb_listener_policy.lb_listener_policy", "target.0.uri", "/example?doc=getupdated"), - resource.TestCheckNoResourceAttr("ibm_is_lb_listener_policy.lb_listener_policy", "target.0.uri"), + resource.TestCheckResourceAttr("ibm_is_lb_listener_policy.lb_listener_policy", "target.0.uri", ""), ), }, }, @@ -660,7 +658,7 @@ func testAccCheckIBMISLBListenerPolicyHttpsRedirectNewConfig(vpcname, subnetname } resource "ibm_is_lb_listener" "lb_listener3"{ lb = ibm_is_lb.testacc_LB.id - port = "9086" + port = "9088" protocol = "https" certificate_instance="%s" } diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener_test.go b/ibm/service/vpc/resource_ibm_is_lb_listener_test.go index 3e21e729b0..4279c6efc0 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener_test.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener_test.go @@ -346,7 +346,7 @@ func TestAccIBMISLBListenerHttpRedirectNew_basic(t *testing.T) { resource.TestCheckResourceAttr( "ibm_is_lb_listener.lb_listener2", "https_redirect.0.status_code", "303"), resource.TestCheckResourceAttr( - "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", "/example?doc=getupdated"), + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", ""), ), }, { @@ -356,7 +356,7 @@ func TestAccIBMISLBListenerHttpRedirectNew_basic(t *testing.T) { resource.TestCheckResourceAttr( "ibm_is_lb.testacc_LB", "name", lbname), resource.TestCheckNoResourceAttr( - "ibm_is_lb_listener.lb_listener2", "https_redirect"), + "ibm_is_lb_listener.lb_listener2", "https_redirect.#"), ), }, }, @@ -618,7 +618,7 @@ func testAccCheckIBMISLBListenerHttpsRedirectNewConfig(vpcname, subnetname, zone } resource "ibm_is_lb_listener" "lb_listener1"{ lb = ibm_is_lb.testacc_LB.id - port = "9086" + port = "9088" protocol = "https" certificate_instance="%s" } From 7957eeb030742fd1a91598cd2bb314d067f706e9 Mon Sep 17 00:00:00 2001 From: Deepak Selvakumar <77007253+deepaksibm@users.noreply.github.com> Date: Fri, 16 Feb 2024 03:26:06 +0530 Subject: [PATCH 3/4] test correction --- ibm/service/vpc/resource_ibm_is_lb_listener_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ibm/service/vpc/resource_ibm_is_lb_listener_test.go b/ibm/service/vpc/resource_ibm_is_lb_listener_test.go index 4279c6efc0..ed74208173 100644 --- a/ibm/service/vpc/resource_ibm_is_lb_listener_test.go +++ b/ibm/service/vpc/resource_ibm_is_lb_listener_test.go @@ -320,7 +320,7 @@ func TestAccIBMISLBListenerHttpRedirectNew_basic(t *testing.T) { resource.TestCheckResourceAttr( "ibm_is_lb.testacc_LB", "name", lbname), resource.TestCheckResourceAttr( - "ibm_is_lb_listener.lb_listener2", "https_redirect.0.status_code", "301"), + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.http_status_code", "302"), resource.TestCheckResourceAttr( "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", "/example?doc=get"), ), @@ -332,7 +332,7 @@ func TestAccIBMISLBListenerHttpRedirectNew_basic(t *testing.T) { resource.TestCheckResourceAttr( "ibm_is_lb.testacc_LB", "name", lbname), resource.TestCheckResourceAttr( - "ibm_is_lb_listener.lb_listener2", "https_redirect.0.status_code", "303"), + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.http_status_code", "303"), resource.TestCheckResourceAttr( "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", "/example?doc=getupdated"), ), @@ -344,7 +344,7 @@ func TestAccIBMISLBListenerHttpRedirectNew_basic(t *testing.T) { resource.TestCheckResourceAttr( "ibm_is_lb.testacc_LB", "name", lbname), resource.TestCheckResourceAttr( - "ibm_is_lb_listener.lb_listener2", "https_redirect.0.status_code", "303"), + "ibm_is_lb_listener.lb_listener2", "https_redirect.0.http_status_code", "303"), resource.TestCheckResourceAttr( "ibm_is_lb_listener.lb_listener2", "https_redirect.0.uri", ""), ), From 137dae5fe77c0942408c527897c24c3e17497916 Mon Sep 17 00:00:00 2001 From: Deepak Selvakumar <77007253+deepaksibm@users.noreply.github.com> Date: Fri, 16 Feb 2024 09:21:42 +0530 Subject: [PATCH 4/4] doc update --- ibm/acctest/acctest.go | 2 +- website/docs/r/is_lb_listener.html.markdown | 15 +++-- .../r/is_lb_listener_policy.html.markdown | 61 +++++++++---------- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/ibm/acctest/acctest.go b/ibm/acctest/acctest.go index 00f94a06f4..3066238605 100644 --- a/ibm/acctest/acctest.go +++ b/ibm/acctest/acctest.go @@ -591,7 +591,7 @@ func init() { } LbListerenerCertificateInstance = os.Getenv("IBM_LB_LISTENER_CERTIFICATE_INSTANCE") if LbListerenerCertificateInstance == "" { - LbListerenerCertificateInstance = "crn:v1:bluemix:public:secrets-manager:us-south:a/1431ea2a7958ad20f0fee592ff85f746:2f504783-548b-4a8e-85ba-6a8df9c62a1f:secret:4b9bdfeb-a2a4-23bc-5e9d-3d60a0debd51" + LbListerenerCertificateInstance = "crn:v1:staging:public:cloudcerts:us-south:a/2d1bace7b46e4815a81e52c6ffeba5cf:af925157-b125-4db2-b642-adacb8b9c7f5:certificate:c81627a1bf6f766379cc4b98fd2a44ed" fmt.Println("[WARN] Set the environment variable IBM_LB_LISTENER_CERTIFICATE_INSTANCE for testing ibm_is_lb_listener resource for https redirect else it is set to default value 'crn:v1:staging:public:cloudcerts:us-south:a/2d1bace7b46e4815a81e52c6ffeba5cf:af925157-b125-4db2-b642-adacb8b9c7f5:certificate:c81627a1bf6f766379cc4b98fd2a44ed'") } diff --git a/website/docs/r/is_lb_listener.html.markdown b/website/docs/r/is_lb_listener.html.markdown index 2bfcb14858..c152ad1689 100644 --- a/website/docs/r/is_lb_listener.html.markdown +++ b/website/docs/r/is_lb_listener.html.markdown @@ -58,7 +58,7 @@ resource "ibm_is_lb_pool_member" "example" { } ``` -### Sample to create a load balancer listener policy for a `https_redirect` action. +### Sample to create a load balancer listener with `https_redirect`. ```terraform resource "ibm_is_lb" "example2" { @@ -77,9 +77,14 @@ resource "ibm_is_lb_listener" "example2" { lb = ibm_is_lb.example2.id port = "9087" protocol = "http" - https_redirect_listener = ibm_is_lb_listener.example1.listener_id - https_redirect_status_code = 301 - https_redirect_uri = "/example?doc=geta" + idle_connection_timeout = 60 + https_redirect { + http_status_code = 302 + listener { + id = ibm_is_lb_listener.example1.listener_id + } + uri = "/example?doc=get" + } } ``` @@ -147,7 +152,7 @@ resource "ibm_is_lb_listener" "example2" { port_max = 400 } ``` - +### Example to create a listener with ## Timeouts The `ibm_is_lb_listener` resource provides the following [Timeouts](https://www.terraform.io/docs/language/resources/syntax.html) configuration options: diff --git a/website/docs/r/is_lb_listener_policy.html.markdown b/website/docs/r/is_lb_listener_policy.html.markdown index a3b112d2ac..2d10caed99 100644 --- a/website/docs/r/is_lb_listener_policy.html.markdown +++ b/website/docs/r/is_lb_listener_policy.html.markdown @@ -35,19 +35,16 @@ resource "ibm_is_lb_listener" "example" { port = "9086" protocol = "http" } + resource "ibm_is_lb_listener_policy" "example" { - lb = ibm_is_lb.example.id - listener = ibm_is_lb_listener.example.listener_id - action = "redirect" - priority = 2 - name = "example-listener-policy" - target_http_status_code = 302 - target_url = "https://www.redirect.com" - rules { - condition = "contains" - type = "header" - field = "1" - value = "2" + lb = ibm_is_lb.example.id + listener = ibm_is_lb_listener.example.listener_id + action = "redirect" + priority = 4 + name = "example-listener-policy" + target { + http_status_code = 302 + url = "https://www.example.com" } } ``` @@ -79,9 +76,13 @@ resource "ibm_is_lb_listener_policy" "example" { action = "https_redirect" priority = 2 name = "example-listener" - target_https_redirect_listener = ibm_is_lb_listener.example_https_target.listener_id - target_https_redirect_status_code = 301 - target_https_redirect_uri = "/example?doc=geta" + target { + http_status_code = 302 + listener { + id = ibm_is_lb_listener.example_https_target.listener_id + } + uri = "/example?doc=get" + } rules { condition = "contains" type = "header" @@ -91,7 +92,7 @@ resource "ibm_is_lb_listener_policy" "example" { } ``` -### Creating a load balancer listener policy for a `forward` action by using `lb` and `lb listener`. +### Creating a load balancer listener policy for a `forward` action. ```terraform @@ -118,17 +119,13 @@ resource "ibm_is_lb_pool" "example" { } resource "ibm_is_lb_listener_policy" "example" { - lb = ibm_is_lb.example.id - listener = ibm_is_lb_listener.example.listener_id - action = "forward" - priority = 2 - name = "example-listener" - target_id = ibm_is_lb_pool.example.pool_id - rules { - condition = "contains" - type = "header" - field = "1" - value = "2" + lb = ibm_is_lb.example.id + listener = ibm_is_lb_listener.example.listener_id + action = "forward" + priority = 3 + name = "example-listener" + target { + id = ibm_is_lb_pool.example.pool_id } } ``` @@ -162,10 +159,8 @@ Review the argument references that you can specify for your resource. - `target_https_redirect_status_code` - (Optional, Integer) When `action` is set to **https_redirect**, specify the HTTP status code to be returned in the redirect response. Supported values are `301`, `302`, `303`, `307`, `308`. - `target_https_redirect_uri` - (Optional, String) When `action` is set to **https_redirect**, specify the target URI where traffic will be redirected. -~> **Note:** When action is `forward`, `target_id` should specify which pool the load balancer forwards the traffic to. -When action is `redirect`, `target_url` should specify the `url` and `target_http_status_code` to specify the code used in the redirect response. -When action is `https_redirect`, `target_https_redirect_listener` should specify the ID of the listener, `target_https_redirect_status_code` to specify the code used in the redirect response and `target_https_redirect_uri` to specify the target URI where traffic will be redirected. -Network load balancer does not support `ibm_is_lb_listener_policy`. +~> **Note:** `target_id`, `target_http_status_code`, `target_url`, `target_https_redirect_listener`, `target_https_redirect_status_code`, `target_https_redirect_uri` are deprecated and will be removed soon. Please use `target` instead. + - `target` - (Optional, List) - If `action` is `forward`, the response is a `LoadBalancerPoolReference`- If `action` is `redirect`, the response is a `LoadBalancerListenerPolicyRedirectURL`- If `action` is `https_redirect`, the response is a `LoadBalancerListenerHTTPSRedirect`. Nested schema for **target**: - `deleted` - (Computed, List) If present, this property indicates the referenced resource has been deleted, and providessome supplementary information. @@ -184,6 +179,10 @@ Network load balancer does not support `ibm_is_lb_listener_policy`. - `name` - (Computed, String) The name for this load balancer pool. The name is unique across all pools for the load balancer. - `url` - (Optional, String) The redirect target URL. +~> **Note:** When action is `forward`, `target.id` should specify which pool the load balancer forwards the traffic to. +When action is `redirect`, `target.url` should specify the `url` and `target.http_status_code` to specify the code used in the redirect response. +When action is `https_redirect`, `target.listener.id` should specify the ID of the listener, `target.http_status_code` to specify the code used in the redirect response and `target.uri` to specify the target URI where traffic will be redirected. +Network load balancer does not support `ibm_is_lb_listener_policy`. ## Attribute reference In addition to all argument reference list, you can access the following attribute reference after your resource is created.