diff --git a/CHANGELOG.md b/CHANGELOG.md index a6722a0c7..8b95fd5da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ FEATURES +* **New Resource**: lbmetrictable_metric_binding * **New Resource**: citrixadc_videooptimizationdetectionaction * **New Resource**: citrixadc_videooptimizationdetectionpolicy * **New Resource**: citrixadc_aaapreauthenticationaction diff --git a/citrixadc/provider.go b/citrixadc/provider.go index 1dc5aebb5..01d080789 100644 --- a/citrixadc/provider.go +++ b/citrixadc/provider.go @@ -851,6 +851,7 @@ func providerResources() map[string]*schema.Resource { "citrixadc_sslcert": resourceCitrixAdcSslcert(), "citrixadc_sslcertreq": resourceCitrixAdcSslcertreq(), "citrixadc_snmptrap_snmpuser_binding": resourceCitrixAdcSnmptrap_snmpuser_binding(), + "citrixadc_lbmetrictable_metric_binding": resourceCitrixAdcLbmetrictable_metric_binding(), "citrixadc_videooptimizationdetectionaction": resourceCitrixAdcVideooptimizationdetectionaction(), "citrixadc_videooptimizationdetectionpolicy": resourceCitrixAdcVideooptimizationdetectionpolicy(), "citrixadc_aaapreauthenticationaction": resourceCitrixAdcAaapreauthenticationaction(), diff --git a/citrixadc/resource_citrixadc_lbmetrictable_metric_binding.go b/citrixadc/resource_citrixadc_lbmetrictable_metric_binding.go new file mode 100644 index 000000000..201614276 --- /dev/null +++ b/citrixadc/resource_citrixadc_lbmetrictable_metric_binding.go @@ -0,0 +1,150 @@ +package citrixadc + +import ( + "github.com/citrix/adc-nitro-go/resource/config/lb" + "github.com/citrix/adc-nitro-go/service" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + + "fmt" + "log" + "strings" +) + +func resourceCitrixAdcLbmetrictable_metric_binding() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + Create: createLbmetrictable_metric_bindingFunc, + Read: readLbmetrictable_metric_bindingFunc, + Delete: deleteLbmetrictable_metric_bindingFunc, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "metric": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "metrictable": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "snmpoid": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func createLbmetrictable_metric_bindingFunc(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] citrixadc-provider: In createLbmetrictable_metric_bindingFunc") + client := meta.(*NetScalerNitroClient).client + metrictable := d.Get("metrictable") + secondIdComponent := d.Get("metric") + bindingId := fmt.Sprintf("%s,%s", metrictable, secondIdComponent) + lbmetrictable_metric_binding := lb.Lbmetrictablemetricbinding{ + Metric: d.Get("metric").(string), + Metrictable: d.Get("metrictable").(string), + Snmpoid: d.Get("snmpoid").(string), + } + + _, err := client.AddResource(service.Lbmetrictable_metric_binding.Type(), bindingId, &lbmetrictable_metric_binding) + if err != nil { + return err + } + + d.SetId(bindingId) + + err = readLbmetrictable_metric_bindingFunc(d, meta) + if err != nil { + log.Printf("[ERROR] netscaler-provider: ?? we just created this lbmetrictable_metric_binding but we can't read it ?? %s", bindingId) + return nil + } + return nil +} + +func readLbmetrictable_metric_bindingFunc(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] citrixadc-provider: In readLbmetrictable_metric_bindingFunc") + client := meta.(*NetScalerNitroClient).client + bindingId := d.Id() + idSlice := strings.SplitN(bindingId, ",", 2) + + metrictable := idSlice[0] + metric := idSlice[1] + + log.Printf("[DEBUG] citrixadc-provider: Reading lbmetrictable_metric_binding state %s", bindingId) + + findParams := service.FindParams{ + ResourceType: "lbmetrictable_metric_binding", + ResourceName: metrictable, + ResourceMissingErrorCode: 258, + } + dataArr, err := client.FindResourceArrayWithParams(findParams) + + // Unexpected error + if err != nil { + log.Printf("[DEBUG] citrixadc-provider: Error during FindResourceArrayWithParams %s", err.Error()) + return err + } + + // Resource is missing + if len(dataArr) == 0 { + log.Printf("[DEBUG] citrixadc-provider: FindResourceArrayWithParams returned empty array") + log.Printf("[WARN] citrixadc-provider: Clearing lbmetrictable_metric_binding state %s", bindingId) + d.SetId("") + return nil + } + + // Iterate through results to find the one with the right id + foundIndex := -1 + for i, v := range dataArr { + if v["metric"].(string) == metric { + foundIndex = i + break + } + } + + // Resource is missing + if foundIndex == -1 { + log.Printf("[DEBUG] citrixadc-provider: FindResourceArrayWithParams secondIdComponent not found in array") + log.Printf("[WARN] citrixadc-provider: Clearing lbmetrictable_metric_binding state %s", bindingId) + d.SetId("") + return nil + } + // Fallthrough + + data := dataArr[foundIndex] + + d.Set("metric", data["metric"]) + d.Set("metrictable", data["metrictable"]) + d.Set("snmpoid", data["Snmpoid"]) + + return nil + +} + +func deleteLbmetrictable_metric_bindingFunc(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] citrixadc-provider: In deleteLbmetrictable_metric_bindingFunc") + client := meta.(*NetScalerNitroClient).client + + bindingId := d.Id() + idSlice := strings.SplitN(bindingId, ",", 2) + + name := idSlice[0] + metric := idSlice[1] + + args := make([]string, 0) + args = append(args, fmt.Sprintf("metric:%s", metric)) + + err := client.DeleteResourceWithArgs(service.Lbmetrictable_metric_binding.Type(), name, args) + if err != nil { + return err + } + + d.SetId("") + + return nil +} diff --git a/citrixadc/resource_citrixadc_lbmetrictable_metric_binding_test.go b/citrixadc/resource_citrixadc_lbmetrictable_metric_binding_test.go new file mode 100644 index 000000000..9aec8eaa4 --- /dev/null +++ b/citrixadc/resource_citrixadc_lbmetrictable_metric_binding_test.go @@ -0,0 +1,187 @@ +/* +Copyright 2016 Citrix Systems, Inc + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package citrixadc + +import ( + "fmt" + "github.com/citrix/adc-nitro-go/service" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "strings" + "testing" +) + +const testAccLbmetrictable_metric_binding_basic = ` + + resource "citrixadc_lbmetrictable" "Table" { + metrictable = "Table-Custom" + } + resource "citrixadc_lbmetrictable_metric_binding" "tf_bind" { + metric = "2.3.6.4.5" + metrictable = citrixadc_lbmetrictable.Table.metrictable + snmpoid = "1.2.3.6.5" + } +` + +const testAccLbmetrictable_metric_binding_basic_step2 = ` + # Keep the above bound resources without the actual binding to check proper deletion + + resource "citrixadc_lbmetrictable" "Table" { + metrictable = "Table-Custom" + } +` + +func TestAccLbmetrictable_metric_binding_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLbmetrictable_metric_bindingDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccLbmetrictable_metric_binding_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckLbmetrictable_metric_bindingExist("citrixadc_lbmetrictable_metric_binding.tf_bind", nil), + ), + }, + resource.TestStep{ + Config: testAccLbmetrictable_metric_binding_basic_step2, + Check: resource.ComposeTestCheckFunc( + testAccCheckLbmetrictable_metric_bindingNotExist("citrixadc_lbmetrictable_metric_binding.tf_bind", "Table-Custom,2.3.6.4.5"), + ), + }, + }, + }) +} + +func testAccCheckLbmetrictable_metric_bindingExist(n string, id *string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No lbmetrictable_metric_binding id is set") + } + + if id != nil { + if *id != "" && *id != rs.Primary.ID { + return fmt.Errorf("Resource ID has changed!") + } + + *id = rs.Primary.ID + } + + client := testAccProvider.Meta().(*NetScalerNitroClient).client + + bindingId := rs.Primary.ID + + idSlice := strings.SplitN(bindingId, ",", 2) + + metrictable := idSlice[0] + metric := idSlice[1] + + findParams := service.FindParams{ + ResourceType: "lbmetrictable_metric_binding", + ResourceName: metrictable, + ResourceMissingErrorCode: 258, + } + dataArr, err := client.FindResourceArrayWithParams(findParams) + + // Unexpected error + if err != nil { + return err + } + + // Iterate through results to find the one with the matching secondIdComponent + found := false + for _, v := range dataArr { + if v["metric"].(string) == metric { + found = true + break + } + } + + if !found { + return fmt.Errorf("lbmetrictable_metric_binding %s not found", n) + } + + return nil + } +} + +func testAccCheckLbmetrictable_metric_bindingNotExist(n string, id string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*NetScalerNitroClient).client + + if !strings.Contains(id, ",") { + return fmt.Errorf("Invalid id string %v. The id string must contain a comma.", id) + } + idSlice := strings.SplitN(id, ",", 2) + + metrictable := idSlice[0] + metric := idSlice[1] + + findParams := service.FindParams{ + ResourceType: "lbmetrictable_metric_binding", + ResourceName: metrictable, + ResourceMissingErrorCode: 258, + } + dataArr, err := client.FindResourceArrayWithParams(findParams) + + // Unexpected error + if err != nil { + return err + } + + // Iterate through results to hopefully not find the one with the matching secondIdComponent + found := false + for _, v := range dataArr { + if v["metric"].(string) == metric { + found = true + break + } + } + + if found { + return fmt.Errorf("lbmetrictable_metric_binding %s was found, but it should have been destroyed", n) + } + + return nil + } +} + +func testAccCheckLbmetrictable_metric_bindingDestroy(s *terraform.State) error { + nsClient := testAccProvider.Meta().(*NetScalerNitroClient).client + + for _, rs := range s.RootModule().Resources { + if rs.Type != "citrixadc_lbmetrictable_metric_binding" { + continue + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No name is set") + } + + _, err := nsClient.FindResource(service.Lbmetrictable_metric_binding.Type(), rs.Primary.ID) + if err == nil { + return fmt.Errorf("lbmetrictable_metric_binding %s still exists", rs.Primary.ID) + } + + } + + return nil +} diff --git a/docs/resources/lbmetrictable_metric_binding.md b/docs/resources/lbmetrictable_metric_binding.md new file mode 100644 index 000000000..52753ec47 --- /dev/null +++ b/docs/resources/lbmetrictable_metric_binding.md @@ -0,0 +1,45 @@ +--- +subcategory: "Load Balancing" +--- + +# Resource: lbmetrictable_metric_binding + +The lbmetrictable_metric_binding resource is used to bind metric to lb metrictable. + + +## Example usage + +```hcl +resource "citrixadc_lbmetrictable" "Table" { + metrictable = "Table-Custom" +} +resource "citrixadc_lbmetrictable_metric_binding" "tf_bind" { + metric = "2.3.6.4.5" + metrictable = citrixadc_lbmetrictable.Table.metrictable + snmpoid = "1.2.3.6.5" +} + +``` + + +## Argument Reference + +* `metric` - (Required) Name of the metric for which to change the SNMP OID. Minimum length = 1 +* `Snmpoid` - (Required) New SNMP OID of the metric. Minimum length = 1 +* `metrictable` - (Required) Name of the metric table. Minimum length = 1 Maximum length = 31 + + +## Attribute Reference + +In addition to the arguments, the following attributes are available: + +* `id` - The id of the lbmetrictable_metric_binding. It is the concatenation of the `metrictable` and `metric` attributes separated by a comma. + + +## Import + +A lbmetrictable_metric_binding can be imported using its name, e.g. + +```shell +terraform import citrixadc_lbmetrictable_metric_binding.tf_bind Table-Custom,2.3.6.4.5 +```