diff --git a/README.md b/README.md index 8ce0d9573..007b79e1a 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,11 @@ ADC](https://www.citrix.com/products/netscaler-adc/) ## Description -This project is a terraform custom provider for Citrix ADC. It uses the [Nitro API](https://developer-docs.citrix.com/projects/netscaler-nitro-api/en/12.0/) to create/configure LB configurations. +This project is a terraform custom provider for Citrix ADC. Configure your ADCs using Terraform for different use-cases such as Load Balancing, SSL, Content Switching, GSLB, NAT etc. These ADCs could be deployed anywhere - Public Cloud , On-Prem etc. + +All the ADC modules available for Terraform automation can be found in citrixadc folder. It uses the [Nitro API](https://developer-docs.citrix.com/projects/citrix-adc-nitro-api-reference/en/latest/) to create/configure LB configurations. To get you started quickly we also have configuration examples in the example folder. You can modify them for your configurations or create your own. + +To deploy Citrix ADC in public clouds, check out cloud scripts in github repo [terraform-cloud-scripts](https://github.com/citrix/terraform-cloud-scripts) . **Important note: The provider will not commit the config changes to Citrix ADC's persistent store.** diff --git a/citrixadc/provider.go b/citrixadc/provider.go index aee677c0d..b92ea8f63 100644 --- a/citrixadc/provider.go +++ b/citrixadc/provider.go @@ -139,6 +139,7 @@ func providerResources() map[string]*schema.Resource { "citrixadc_servicegroup_lbmonitor_binding": resourceCitrixAdcServicegroup_lbmonitor_binding(), "citrixadc_nsparam": resourceCitrixAdcNsparam(), "citrixadc_sslvserver_sslpolicy_binding": resourceCitrixAdcSslvserver_sslpolicy_binding(), + "citrixadc_sslprofile_sslcipher_binding": resourceCitrixAdcSslprofile_sslcipher_binding(), } } diff --git a/citrixadc/resource_citrixadc_sslcipher.go b/citrixadc/resource_citrixadc_sslcipher.go index 3cfb016f2..f3592658c 100644 --- a/citrixadc/resource_citrixadc_sslcipher.go +++ b/citrixadc/resource_citrixadc_sslcipher.go @@ -20,8 +20,8 @@ func resourceCitrixAdcSslcipher() *schema.Resource { SchemaVersion: 1, Create: createSslcipherFunc, Read: readSslcipherFunc, - // Update: updateSslcipherFunc, // All fields are ForceNew or Computed w/out Optional, Update is superfluous - Delete: deleteSslcipherFunc, + Update: updateSslcipherFunc, + Delete: deleteSslcipherFunc, Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -35,7 +35,6 @@ func resourceCitrixAdcSslcipher() *schema.Resource { "ciphersuitebinding": { Type: schema.TypeSet, Required: true, - ForceNew: true, Set: sslcipherCipherSuitebindingMappingHash, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -84,6 +83,24 @@ func createSslcipherFunc(d *schema.ResourceData, meta interface{}) error { return nil } +func updateSslcipherFunc(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] citrixadc-provider: In updateSslcipherFunc") + sslcipherGroupName := d.Get("ciphergroupname").(string) + hasChange := false + if d.HasChange("ciphersuitebinding") { + log.Printf("[DEBUG] citrixadc-provider: Ciphersuitebinding has changed for sslcipherGroupName %s, starting update", sslcipherGroupName) + hasChange = true + } + if hasChange { + err := updateSslCipherCipherSuiteBindings(d, meta) + if err != nil { + return err + } + } + + return nil +} + func readSslcipherFunc(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] citrixadc-provider: In readSslcipherFunc") client := meta.(*NetScalerNitroClient).client @@ -121,8 +138,6 @@ func deleteSslcipherFunc(d *schema.ResourceData, meta interface{}) error { return nil } -// sslcipher_sslciphersuite_binding - type cipherPriority struct { cipherName string cipherPriority int @@ -197,18 +212,32 @@ func addSingleSslCipherCipherSuiteBinding(d *schema.ResourceData, meta interface func updateSslCipherCipherSuiteBindings(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] citrixadc-provider: In updateSslCipherCipherSuiteBindings") - oldSet, newSet := d.GetChange("ciphersuitebinding") - log.Printf("[DEBUG] citrixadc-provider: oldSet %v\n", oldSet) - log.Printf("[DEBUG] citrixadc-provider: newSet %v\n", newSet) - remove := oldSet.(*schema.Set).Difference(newSet.(*schema.Set)) - add := newSet.(*schema.Set).Difference(oldSet.(*schema.Set)) - - for _, binding := range remove.List() { - if err := deleteSingleSslCipherCipherSuiteBinding(d, meta, binding.(map[string]interface{})); err != nil { + client := meta.(*NetScalerNitroClient).client + + findParams := netscaler.FindParams{ + ResourceType: "sslcipher_sslciphersuite_binding", + ResourceName: d.Get("ciphergroupname").(string), + } + + dataArr, err := client.FindResourceArrayWithParams(findParams) + if err != nil { + return err + } + + // We need to do this since adding a ciphersuite with lower priority than an existing one + // will bump the existing priority by one. + // Delete all existing bindings + for _, data := range dataArr { + binding := make(map[string]interface{}) + binding["ciphername"] = data["ciphername"] + binding["cipherpriority"] = data["cipherpriority"] + + if err := deleteSingleSslCipherCipherSuiteBinding(d, meta, binding); err != nil { return err } } - + // Add all configured bindings + add := d.Get("ciphersuitebinding").(*schema.Set) for _, binding := range getSortedCipherBindigs(add) { if err := addSingleSslCipherCipherSuiteBinding(d, meta, binding); err != nil { return err diff --git a/citrixadc/resource_citrixadc_sslcipher_test.go b/citrixadc/resource_citrixadc_sslcipher_test.go index 734f74b82..627d4e81d 100644 --- a/citrixadc/resource_citrixadc_sslcipher_test.go +++ b/citrixadc/resource_citrixadc_sslcipher_test.go @@ -28,7 +28,7 @@ import ( const testAccSslcipher_add = ` resource "citrixadc_sslcipher" "foo" { ciphergroupname = "tfAccsslcipher" - + # ciphersuitebinding is MANDATORY attribute # Any change in the ciphersuitebinding will result in re-creation of the whole sslcipher resource. ciphersuitebinding { @@ -46,11 +46,32 @@ const testAccSslcipher_add = ` } ` +const testAccSslcipher_transpose = ` + resource "citrixadc_sslcipher" "foo" { + ciphergroupname = "tfAccsslcipher" + + # ciphersuitebinding is MANDATORY attribute + # Any change in the ciphersuitebinding will result in re-creation of the whole sslcipher resource. + ciphersuitebinding { + ciphername = "TLS1.2-ECDHE-RSA-AES128-GCM-SHA256" + cipherpriority = 3 + } + ciphersuitebinding { + ciphername = "TLS1.2-ECDHE-RSA-AES256-GCM-SHA384" + cipherpriority = 2 + } + ciphersuitebinding { + ciphername = "TLS1.2-ECDHE-RSA-AES-128-SHA256" + cipherpriority = 1 + } + } +` + // Update re-creates the while ciphergroup const testAccSslcipher_update = ` resource "citrixadc_sslcipher" "foo" { ciphergroupname = "tfAccsslcipher" - + # ciphersuitebinding is MANDATORY attribute # Any change in the ciphersuitebinding will result in re-creation of the whole sslcipher resource. ciphersuitebinding { @@ -76,6 +97,16 @@ func TestAccSslcipher_basic(t *testing.T) { testAccCheckSslcipherCiphersuiteBinding("tfAccsslcipher", "TLS1.2-ECDHE-RSA-AES-128-SHA256", 3), ), }, + resource.TestStep{ + Config: testAccSslcipher_transpose, + Check: resource.ComposeTestCheckFunc( + testAccCheckSslcipherExist("citrixadc_sslcipher.foo", nil), + resource.TestCheckResourceAttr("citrixadc_sslcipher.foo", "ciphergroupname", "tfAccsslcipher"), + testAccCheckSslcipherCiphersuiteBinding("tfAccsslcipher", "TLS1.2-ECDHE-RSA-AES128-GCM-SHA256", 3), + testAccCheckSslcipherCiphersuiteBinding("tfAccsslcipher", "TLS1.2-ECDHE-RSA-AES256-GCM-SHA384", 2), + testAccCheckSslcipherCiphersuiteBinding("tfAccsslcipher", "TLS1.2-ECDHE-RSA-AES-128-SHA256", 1), + ), + }, resource.TestStep{ Config: testAccSslcipher_update, Check: resource.ComposeTestCheckFunc( diff --git a/citrixadc/resource_citrixadc_sslprofile.go b/citrixadc/resource_citrixadc_sslprofile.go index 205667175..ab0a7c81b 100644 --- a/citrixadc/resource_citrixadc_sslprofile.go +++ b/citrixadc/resource_citrixadc_sslprofile.go @@ -1226,6 +1226,11 @@ func updateSslprofileCipherBindings(d *schema.ResourceData, meta interface{}) er func readSslprofileCipherbindings(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] citrixadc-provider: In readSslprofileCipherbindings") client := meta.(*NetScalerNitroClient).client + + // Ignore bindings unless there is an explicit configuration for it + if _, ok := d.GetOk("cipherbindings"); !ok { + return nil + } sslprofileName := d.Get("name").(string) bindings, _ := client.FindResourceArray(netscaler.Sslprofile_sslcipher_binding.Type(), sslprofileName) log.Printf("bindings %v\n", bindings) diff --git a/citrixadc/resource_citrixadc_sslprofile_sslcipher_binding.go b/citrixadc/resource_citrixadc_sslprofile_sslcipher_binding.go new file mode 100644 index 000000000..f72bb71d4 --- /dev/null +++ b/citrixadc/resource_citrixadc_sslprofile_sslcipher_binding.go @@ -0,0 +1,166 @@ +package citrixadc + +import ( + "github.com/chiradeep/go-nitro/config/ssl" + + "github.com/chiradeep/go-nitro/netscaler" + "github.com/hashicorp/terraform/helper/schema" + + "fmt" + "log" + "strings" +) + +func resourceCitrixAdcSslprofile_sslcipher_binding() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + Create: createSslprofile_sslcipher_bindingFunc, + Read: readSslprofile_sslcipher_bindingFunc, + Delete: deleteSslprofile_sslcipher_bindingFunc, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "ciphername": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "cipherpriority": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + } +} + +func createSslprofile_sslcipher_bindingFunc(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] citrixadc-provider: In createSslprofile_sslcipher_bindingFunc") + client := meta.(*NetScalerNitroClient).client + profileName := d.Get("name").(string) + cipherName := d.Get("ciphername").(string) + + // Use `,` as the separator since it is invalid character for adc entity strings + bindingId := fmt.Sprintf("%s,%s", profileName, cipherName) + + sslprofile_sslcipher_binding := ssl.Sslprofilesslcipherbinding{ + Ciphername: d.Get("ciphername").(string), + Cipherpriority: d.Get("cipherpriority").(int), + Name: d.Get("name").(string), + } + + err := client.UpdateUnnamedResource(netscaler.Sslprofile_sslcipher_binding.Type(), &sslprofile_sslcipher_binding) + if err != nil { + return err + } + + d.SetId(bindingId) + + err = readSslprofile_sslcipher_bindingFunc(d, meta) + if err != nil { + log.Printf("[ERROR] netscaler-provider: ?? we just created this sslprofile_sslcipher_binding but we can't read it ?? %s", bindingId) + return nil + } + return nil +} + +func readSslprofile_sslcipher_bindingFunc(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] citrixadc-provider: In readSslprofile_sslcipher_bindingFunc") + client := meta.(*NetScalerNitroClient).client + + bindingId := d.Id() + idSlice := strings.Split(bindingId, ",") + + if len(idSlice) < 2 { + return fmt.Errorf("Cannot deduce ciphername from id string") + } + + if len(idSlice) > 2 { + return fmt.Errorf("Too many separators \",\" in id string") + } + + profileName := idSlice[0] + cipherName := idSlice[1] + + findParams := netscaler.FindParams{ + ResourceType: "sslprofile_sslcipher_binding", + ResourceName: profileName, + ResourceMissingErrorCode: 3248, + } + + dataArr, err := client.FindResourceArrayWithParams(findParams) + + if err != nil { + if strings.Contains(err.Error(), "\"errorcode\": 3248") { + return nil + } else { + // Unexpected error + 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 sslprofile_sslcipher_binding state %s", bindingId) + d.SetId("") + return nil + } + + // Iterate through results to find the one with the right policy name + foundIndex := -1 + for i, v := range dataArr { + if v["cipheraliasname"].(string) == cipherName { + foundIndex = i + break + } + } + + // Resource is missing + if foundIndex == -1 { + log.Printf("[DEBUG] citrixadc-provider: FindResourceArrayWithParams cipher name not found in array") + log.Printf("[WARN] citrixadc-provider: Clearing sslprofile_sslcipher_binding state %s", bindingId) + d.SetId("") + return nil + } + // Fallthrough + + data := dataArr[foundIndex] + + d.Set("name", data["name"]) + d.Set("ciphername", data["cipheraliasname"]) + d.Set("cipherpriority", data["cipherpriority"]) + + return nil + +} + +func deleteSslprofile_sslcipher_bindingFunc(d *schema.ResourceData, meta interface{}) error { + log.Printf("[DEBUG] citrixadc-provider: In deleteSslprofile_sslcipher_bindingFunc") + client := meta.(*NetScalerNitroClient).client + + bindingId := d.Id() + idSlice := strings.Split(bindingId, ",") + + profileName := idSlice[0] + cipherName := idSlice[1] + + args := make([]string, 0) + args = append(args, fmt.Sprintf("ciphername:%v", cipherName)) + + err := client.DeleteResourceWithArgs(netscaler.Sslprofile_sslcipher_binding.Type(), profileName, args) + if err != nil { + return err + } + + d.SetId("") + + return nil +} diff --git a/citrixadc/resource_citrixadc_sslprofile_sslcipher_binding_test.go b/citrixadc/resource_citrixadc_sslprofile_sslcipher_binding_test.go new file mode 100644 index 000000000..b5c5b75b8 --- /dev/null +++ b/citrixadc/resource_citrixadc_sslprofile_sslcipher_binding_test.go @@ -0,0 +1,223 @@ +/* +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/chiradeep/go-nitro/netscaler" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "strings" + "testing" +) + +func TestAccSslprofile_sslcipher_binding_basic(t *testing.T) { + + if isCpxRun { + t.Skip("Operation not permitted under CPX") + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckSslprofile_sslcipher_bindingDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccSslprofile_sslcipher_binding_basic_step1, + Check: resource.ComposeTestCheckFunc( + testAccCheckSslprofile_sslcipher_bindingExist("citrixadc_sslprofile_sslcipher_binding.tf_binding", nil), + testAccCheckSslprofile_sslcipher_bindingExist("citrixadc_sslprofile_sslcipher_binding.tf_binding2", nil), + ), + }, + resource.TestStep{ + Config: testAccSslprofile_sslcipher_binding_basic_step2, + Check: resource.ComposeTestCheckFunc( + testAccCheckSslprofile_sslcipher_bindingExist("citrixadc_sslprofile_sslcipher_binding.tf_binding", nil), + testAccCheckSslprofile_sslcipher_bindingExist("citrixadc_sslprofile_sslcipher_binding.tf_binding2", nil), + ), + }, + resource.TestStep{ + Config: testAccSslprofile_sslcipher_binding_basic_step3, + Check: resource.ComposeTestCheckFunc( + testAccCheckSslprofile_sslcipher_bindingExist("citrixadc_sslprofile_sslcipher_binding.tf_binding", nil), + ), + }, + }, + }) +} + +func testAccCheckSslprofile_sslcipher_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 lb vserver name is set") + } + + if id != nil { + if *id != "" && *id != rs.Primary.ID { + return fmt.Errorf("Resource ID has changed!") + } + + *id = rs.Primary.ID + } + + nsClient := testAccProvider.Meta().(*NetScalerNitroClient).client + bindingId := rs.Primary.ID + idSlice := strings.Split(bindingId, ",") + + profileName := idSlice[0] + cipherName := idSlice[1] + + findParams := netscaler.FindParams{ + ResourceType: "sslprofile_sslcipher_binding", + ResourceName: profileName, + ResourceMissingErrorCode: 3248, + } + + dataArr, err := nsClient.FindResourceArrayWithParams(findParams) + + if err != nil { + return err + } + + if len(dataArr) == 0 { + return fmt.Errorf("[DEBUG] citrixadc-provider: FindResourceArrayWithParams returned empty array") + } + + foundIndex := -1 + for i, v := range dataArr { + if v["cipheraliasname"].(string) == cipherName { + foundIndex = i + break + } + } + + if foundIndex == -1 { + return fmt.Errorf("[DEBUG] citrixadc-provider: FindResourceArrayWithParams cipher name not found in array") + } + + return nil + } +} + +func testAccCheckSslprofile_sslcipher_bindingDestroy(s *terraform.State) error { + nsClient := testAccProvider.Meta().(*NetScalerNitroClient).client + + for _, rs := range s.RootModule().Resources { + if rs.Type != "citrixadc_sslprofile_sslcipher_binding" { + continue + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No name is set") + } + + idSlice := strings.Split(rs.Primary.ID, ",") + + profileName := idSlice[0] + + findParams := netscaler.FindParams{ + ResourceType: "sslprofile_sslcipher_binding", + ResourceName: profileName, + ResourceMissingErrorCode: 3248, + } + + dataArr, err := nsClient.FindResourceArrayWithParams(findParams) + + if err != nil { + if strings.Contains(err.Error(), "\"errorcode\": 3248") { + // Expected since ssl profile is already deleted + return nil + } else { + // Unexpected error + return err + } + } + + if len(dataArr) > 0 { + return fmt.Errorf("sslcipher binding %s still exists", rs.Primary.ID) + } + + } + + return nil +} + +const testAccSslprofile_sslcipher_binding_basic_step1 = ` + +resource "citrixadc_sslprofile" "tf_sslprofile" { + name = "tf_sslprofile" + + ecccurvebindings = [] + +} + +resource "citrixadc_sslprofile_sslcipher_binding" "tf_binding" { + name = citrixadc_sslprofile.tf_sslprofile.name + ciphername = "HIGH" + cipherpriority = 10 +} + +resource "citrixadc_sslprofile_sslcipher_binding" "tf_binding2" { + name = citrixadc_sslprofile.tf_sslprofile.name + ciphername = "LOW" + cipherpriority = 20 +} + +` + +const testAccSslprofile_sslcipher_binding_basic_step2 = ` + +resource "citrixadc_sslprofile" "tf_sslprofile" { + name = "tf_sslprofile" + + ecccurvebindings = [] + +} + +resource "citrixadc_sslprofile_sslcipher_binding" "tf_binding" { + name = citrixadc_sslprofile.tf_sslprofile.name + ciphername = "HIGH" + cipherpriority = 10 +} + +resource "citrixadc_sslprofile_sslcipher_binding" "tf_binding2" { + name = citrixadc_sslprofile.tf_sslprofile.name + ciphername = "LOW" + cipherpriority = 30 +} + +` + +const testAccSslprofile_sslcipher_binding_basic_step3 = ` + +resource "citrixadc_sslprofile" "tf_sslprofile" { + name = "tf_sslprofile" + + ecccurvebindings = [] + +} + +resource "citrixadc_sslprofile_sslcipher_binding" "tf_binding" { + name = citrixadc_sslprofile.tf_sslprofile.name + ciphername = "HIGH" + cipherpriority = 10 +} +` diff --git a/examples/sslprofile_sslcipher_binding/provider.tf b/examples/sslprofile_sslcipher_binding/provider.tf new file mode 100644 index 000000000..3d4508593 --- /dev/null +++ b/examples/sslprofile_sslcipher_binding/provider.tf @@ -0,0 +1,3 @@ +provider "citrixadc" { + endpoint = "http://localhost:8080" +} diff --git a/examples/sslprofile_sslcipher_binding/resources.tf b/examples/sslprofile_sslcipher_binding/resources.tf new file mode 100644 index 000000000..4672ea195 --- /dev/null +++ b/examples/sslprofile_sslcipher_binding/resources.tf @@ -0,0 +1,20 @@ +resource "citrixadc_sslprofile" "tf_sslprofile" { + name = "tf_sslprofile" + + ecccurvebindings = [] + // Don't define any bindings here + // since we are using the explicit bindings resource + +} + +resource "citrixadc_sslprofile_sslcipher_binding" "tf_binding" { + name = citrixadc_sslprofile.tf_sslprofile.name + ciphername = "HIGH" + cipherpriority = 10 +} + +resource "citrixadc_sslprofile_sslcipher_binding" "tf_binding2" { + name = citrixadc_sslprofile.tf_sslprofile.name + ciphername = "LOW" + cipherpriority = 20 +} diff --git a/go.mod b/go.mod index e21ec3f90..a44c63d2f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/citrix/terraform-provider-citrixadc go 1.13 require ( - github.com/chiradeep/go-nitro v0.0.0-20200724075413-fe307aa68464 + github.com/chiradeep/go-nitro v0.0.0-20200810081113-38f10d7cdab9 github.com/hashicorp/terraform v0.12.20 github.com/hashicorp/terraform-plugin-sdk v1.6.0 github.com/mitchellh/mapstructure v1.1.2 diff --git a/go.sum b/go.sum index 84e4bf8b2..f357c97ae 100644 --- a/go.sum +++ b/go.sum @@ -93,6 +93,8 @@ github.com/chiradeep/go-nitro v0.0.0-20200723075907-bf03b0d21306 h1:wuZCDMb2/1c5 github.com/chiradeep/go-nitro v0.0.0-20200723075907-bf03b0d21306/go.mod h1:RIyfAubyIck4tVaQrEiNGW4Y1e6CcTONDnYSX8VktH8= github.com/chiradeep/go-nitro v0.0.0-20200724075413-fe307aa68464 h1:y8Ovob0o1JKjOvh8LwhfjQSNbFvYVHSRr0t19PqcJlY= github.com/chiradeep/go-nitro v0.0.0-20200724075413-fe307aa68464/go.mod h1:RIyfAubyIck4tVaQrEiNGW4Y1e6CcTONDnYSX8VktH8= +github.com/chiradeep/go-nitro v0.0.0-20200810081113-38f10d7cdab9 h1:ulx8BRigWcZRRBSPL5LZG7Ddh0jAZ+O2HTl/mGFEy0g= +github.com/chiradeep/go-nitro v0.0.0-20200810081113-38f10d7cdab9/go.mod h1:RIyfAubyIck4tVaQrEiNGW4Y1e6CcTONDnYSX8VktH8= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= diff --git a/vendor/github.com/chiradeep/go-nitro/netscaler/config.go b/vendor/github.com/chiradeep/go-nitro/netscaler/config.go index 7d7920835..82393c30a 100644 --- a/vendor/github.com/chiradeep/go-nitro/netscaler/config.go +++ b/vendor/github.com/chiradeep/go-nitro/netscaler/config.go @@ -522,9 +522,10 @@ func (c *NitroClient) FindResourceArrayWithParams(findParams FindParams) ([]map[ url := urlBuilder.String() - log.Printf("[TRACE] go-nitro: url is %s", url) + log.Printf("[TRACE] go-nitro: FindResourceArrayWithParams: url is %s", url) result, httpErr := c.doHTTPRequest("GET", url, bytes.NewBuffer([]byte{}), readResponseHandler) - log.Printf("result %v", string(result)) + log.Printf("[TRACE] go-nitro: FindResourceArrayWithParams: HTTP GET result: %v", string(result)) + log.Printf("[TRACE] go-nitro: FindResourceArrayWithParams: HTTP GET error: %v", httpErr) // Ignore 404. // We need to parse the NITRO errorcode value to determine if this is an actual error @@ -532,7 +533,7 @@ func (c *NitroClient) FindResourceArrayWithParams(findParams FindParams) ([]map[ if !strings.Contains(httpErr.Error(), "404") { return nil, httpErr } else { - log.Printf("[DEBUG] go-nitro: FindResource: Ignoring 404 http status. %s", httpErr.Error()) + log.Printf("[DEBUG] go-nitro: FindResourceArrayWithParams: Ignoring 404 http status. %s", httpErr.Error()) } } @@ -540,18 +541,18 @@ func (c *NitroClient) FindResourceArrayWithParams(findParams FindParams) ([]map[ err := json.Unmarshal(result, &jsonData) if err != nil { - return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceWithParams: JSON unmarshal error: %s", err.Error()) + return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceArrayWithParams: JSON unmarshal error: %s", err.Error()) } nitroData, ok := jsonData.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceWithParams: Type assertion map[string]interface{} does not hold. Actual type %T", jsonData) + return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceArrayWithParams: Type assertion map[string]interface{} does not hold. Actual type %T", jsonData) } // Get error code from nitro resource errorcode, errok := nitroData["errorcode"] if !errok { - return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceWithParams: there is no error code in nitro response") + return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceArrayWithParams: there is no error code in nitro response") } errorcode = int(errorcode.(float64)) @@ -567,7 +568,7 @@ func (c *NitroClient) FindResourceArrayWithParams(findParams FindParams) ([]map[ // Fallthrough if errorcode != 0 { - return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceWithParams: non zero errorcode %d", errorcode) + return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceArrayWithParams: non zero errorcode %d", errorcode) } // Fallthrough @@ -580,7 +581,7 @@ func (c *NitroClient) FindResourceArrayWithParams(findParams FindParams) ([]map[ } // Falthrough - log.Printf("[DEBUG] go-nitro: FindResourceWithParams: retrieved NITRO object: %v", resourceData) + log.Printf("[DEBUG] go-nitro: FindResourceArrayWithParams: retrieved NITRO object: %v", resourceData) // resource data assertion resourceArray, arrayOk := resourceData.([]interface{}) @@ -602,7 +603,7 @@ func (c *NitroClient) FindResourceArrayWithParams(findParams FindParams) ([]map[ } // Fallthrough to error condition - return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceWithParams: Cannot handle returned NITRO resource data type %T", resourceData) + return nil, fmt.Errorf("[ERROR] go-nitro: FindResourceArrayWithParams: Cannot handle returned NITRO resource data type %T", resourceData) } diff --git a/vendor/github.com/chiradeep/go-nitro/netscaler/netscaler_resource.go b/vendor/github.com/chiradeep/go-nitro/netscaler/netscaler_resource.go index a1d26a18b..6ca87bccd 100644 --- a/vendor/github.com/chiradeep/go-nitro/netscaler/netscaler_resource.go +++ b/vendor/github.com/chiradeep/go-nitro/netscaler/netscaler_resource.go @@ -148,6 +148,9 @@ func (c *NitroClient) createHTTPRequest(method string, urlstr string, buff *byte func (c *NitroClient) doHTTPRequest(method string, urlstr string, bytes *bytes.Buffer, respHandler responseHandlerFunc) ([]byte, error) { req, err := c.createHTTPRequest(method, urlstr, bytes) + log.Printf("[TRACE] go-nitro: doHTTPRequest HTTP method: %v", method) + log.Printf("[TRACE] go-nitro: doHTTPRequest HTTP url: %v", urlstr) + log.Printf("[TRACE] go-nitro: doHTTPRequest HTTP body: %v", bytes.String()) resp, err := c.client.Do(req) if resp != nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index 3247949cd..db9edacb4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -60,7 +60,7 @@ github.com/bgentry/speakeasy github.com/blang/semver # github.com/bmatcuk/doublestar v1.1.5 github.com/bmatcuk/doublestar -# github.com/chiradeep/go-nitro v0.0.0-20200724075413-fe307aa68464 +# github.com/chiradeep/go-nitro v0.0.0-20200810081113-38f10d7cdab9 github.com/chiradeep/go-nitro/config/audit github.com/chiradeep/go-nitro/config/basic github.com/chiradeep/go-nitro/config/cluster