diff --git a/bigip/resource_bigip_as3.go b/bigip/resource_bigip_as3.go index 140899d0..6e9bb927 100644 --- a/bigip/resource_bigip_as3.go +++ b/bigip/resource_bigip_as3.go @@ -363,6 +363,7 @@ func resourceBigipAs3Update(ctx context.Context, d *schema.ResourceData, meta in defer m.Unlock() as3Json := d.Get("as3_json").(string) log.Printf("[INFO] Updating As3 Config :%s", as3Json) + oldApplicationList := d.Get("application_list").(string) tenantList, _, applicationList := client.GetTenantList(as3Json) _ = d.Set("application_list", applicationList) perApplication, err := client.CheckSetting() @@ -373,6 +374,20 @@ func resourceBigipAs3Update(ctx context.Context, d *schema.ResourceData, meta in if d.Get("per_app_mode").(bool) { if perApplication && len(tenantList) == 0 { oldTenantList := d.Id() + log.Printf("[INFO] oldApplicationList :%s", oldApplicationList) + curApplicationList := client.GetAppsList(as3Json) + log.Printf("[INFO] curApplicationList :%s", curApplicationList) + for _, appName := range strings.Split(oldApplicationList, ",") { + if !strings.Contains(curApplicationList, appName) { + log.Printf("[INFO] Deleting As3 Config for Application:%s in Tenant:%v", appName, oldTenantList) + err := client.DeletePerApplicationAs3Bigip(oldTenantList, appName) + if err != nil { + log.Printf("[ERROR] Unable to DeleteContext: %v :", err) + return diag.FromErr(err) + } + } + } + log.Printf("[INFO] Updating As3 Config for tenant:%s with Per-Application Mode:%v", oldTenantList, perApplication) err, task_id := client.PostPerAppBigIp(as3Json, oldTenantList) log.Printf("[DEBUG] task_id from PostPerAppBigIp:%+v", task_id) @@ -383,6 +398,8 @@ func resourceBigipAs3Update(ctx context.Context, d *schema.ResourceData, meta in _ = d.Set("tenant_list", oldTenantList) _ = d.Set("task_id", task_id) _ = d.Set("tenant_filter", oldTenantList) + _ = d.Set("application_list", curApplicationList) + } else { if !perApplication { return diag.FromErr(fmt.Errorf("Per-Application should be true in Big-IP Setting")) diff --git a/bigip/resource_bigip_as3_test.go b/bigip/resource_bigip_as3_test.go index c68c3bca..6df79f84 100644 --- a/bigip/resource_bigip_as3_test.go +++ b/bigip/resource_bigip_as3_test.go @@ -122,6 +122,13 @@ resource "bigip_as3" "as3-example2" { } ` +var TestAs3PerAppResource3 = ` +resource "bigip_as3" "as3-example1" { + tenant_name = "dmz" + as3_json = "${file("` + dir + `/../examples/as3/as3_per_app_example3.json")}" +} +` + func TestAccBigipAs3_create_SingleTenant(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { @@ -463,7 +470,6 @@ func testCheckAS3AppExists(tenantName, appNames string, exists bool) resource.Te tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} client := &http.Client{Transport: tr} - for _, appName := range strings.Split(appNames, ",") { url := clientBigip.Host + "/mgmt/shared/appsvcs/declare/" + tenantName + "/applications/" + appName req, err := http.NewRequest("GET", url, nil) @@ -561,6 +567,8 @@ func TestAccBigipPer_AppAs3_update_addApplication(t *testing.T) { Check: resource.ComposeTestCheckFunc( testCheckAs3Exists("dmz", true), testCheckAS3AppExists("dmz", "path_app1", true), + testCheckAs3Exists("dmztest", false), + testCheckAS3AppExists("dmztest", "path_app1", false), ), }, { @@ -574,6 +582,35 @@ func TestAccBigipPer_AppAs3_update_addApplication(t *testing.T) { }) } +func TestAccBigipPer_AppAs3_remove_Application(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAcctPreCheck(t) + }, + Providers: testAccProviders, + CheckDestroy: testCheckAs3Destroy, + Steps: []resource.TestStep{ + { + Config: TestAs3PerAppResource3, + + Check: resource.ComposeTestCheckFunc( + testCheckAs3Exists("dmz", true), + testCheckAS3AppExists("dmz", "path_app1", true), + testCheckAS3AppExists("dmz", "path_app2", true), + ), + }, + { + Config: TestAs3PerAppResource1, + Check: resource.ComposeTestCheckFunc( + testCheckAs3Exists("dmz", true), + testCheckAS3AppExists("dmz", "path_app1", true), + testCheckAS3AppExists("dmz", "path_app2", false), + ), + }, + }, + }) +} + // Per-App mode is disabled func TestAccBigipPer_AppAs3_update_invalidJson(t *testing.T) { resource.Test(t, resource.TestCase{ diff --git a/docs/resources/bigip_as3.md b/docs/resources/bigip_as3.md index 657498f6..7f19389c 100644 --- a/docs/resources/bigip_as3.md +++ b/docs/resources/bigip_as3.md @@ -67,9 +67,21 @@ resource "bigip_as3" "as3-example2" { } On running above 2 resources , we will be able to deploy Applications - `path_app1 , path_app2` on Tenant `Test` -now, if we run `terraform destroy -target=bigip_as3.as3-example2` , only `path_app2` will be deleted from Tenant. +now, if we run `terraform destroy -target=bigip_as3.as3-example2` , only `path_app2` will be deleted from Tenant. +resource "bigip_as3" "as3-example1" { + tenant_name = "dmz" + as3_json = "${file("` + dir + `/../examples/as3/as3_per_app_example1.json")}" +} + +resource "bigip_as3" "as3-example1" { + tenant_name = "dmz" + as3_json = "${file("` + dir + `/../examples/as3/as3_per_app_example3.json")}" +} + +On running above calls , first call will create 2 applications `path_app1 , path_app2` and second call , will remove `path_app2` from Tenant + [perApplication as3](#perApplication_example) ```hcl diff --git a/examples/as3/as3_per_app_example3.json b/examples/as3/as3_per_app_example3.json new file mode 100644 index 00000000..feb493ba --- /dev/null +++ b/examples/as3/as3_per_app_example3.json @@ -0,0 +1,47 @@ +{ + "schemaVersion": "3.50.0", + "path_app1": { + "class": "Application", + "vs_name_app1": { + "class": "Service_HTTP", + "virtualAddresses": [ + "192.1.1.24" + ], + "pool": "pool" + }, + "pool": { + "class": "Pool", + "members": [ + { + "servicePort": 80, + "serverAddresses": [ + "192.20.1.10", + "192.30.1.20" + ] + } + ] + } + }, + "path_app2": { + "class": "Application", + "vs_name_app2": { + "class": "Service_HTTP", + "virtualAddresses": [ + "192.1.1.234" + ], + "pool": "pool" + }, + "pool": { + "class": "Pool", + "members": [ + { + "servicePort": 80, + "serverAddresses": [ + "12.20.1.10", + "12.30.1.20" + ] + } + ] + } + } +} \ No newline at end of file