diff --git a/plugin/providers/phpipam/data_source_phpipam_subnet.go b/plugin/providers/phpipam/data_source_phpipam_subnet.go index 2c7966b..2030378 100644 --- a/plugin/providers/phpipam/data_source_phpipam_subnet.go +++ b/plugin/providers/phpipam/data_source_phpipam_subnet.go @@ -1 +1,45 @@ package phpipam + +import ( + "errors" + "fmt" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/paybyphone/phpipam-sdk-go/controllers/subnets" +) + +func dataSourcePHPIPAMSubnet() *schema.Resource { + return &schema.Resource{ + Read: dataSourcePHPIPAMSubnetRead, + Schema: dataSourceSubnetSchema(), + } +} + +func dataSourcePHPIPAMSubnetRead(d *schema.ResourceData, meta interface{}) error { + c := meta.(*ProviderPHPIPAMClient).subnetsController + var out subnets.Subnet + // We need to determine how to get the subnet. An ID search takes priority, + // and after that subnets. + if id := d.Get("subnet_id").(int); id != 0 { + var err error + out, err = c.GetSubnetByID(id) + if err != nil { + return err + } + } else { + v, err := c.GetSubnetsByCIDR(fmt.Sprintf("%s/%d", d.Get("subnet_address"), d.Get("subnet_mask"))) + if err != nil { + return err + } + // This should not happen, as a CIDR search from what I have seen so far + // generally only returns 1 subnet ever. Nontheless, the API spec and the + // function return a slice of subnets, so we need to assert that the search + // has only retuned a single match. + if len(v) != 1 { + return errors.New("CIDR search returned either zero or multiple results. Please correct your search and try again") + } + out = v[0] + } + flattenSubnet(out, d) + return nil +} diff --git a/plugin/providers/phpipam/data_source_phpipam_subnet_test.go b/plugin/providers/phpipam/data_source_phpipam_subnet_test.go new file mode 100644 index 0000000..c387b92 --- /dev/null +++ b/plugin/providers/phpipam/data_source_phpipam_subnet_test.go @@ -0,0 +1,35 @@ +package phpipam + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +const testAccDataSourcePHPIPAMSubnetConfig = ` +data "phpipam_subnet" "subnet_by_cidr" { + subnet_address = "10.10.2.0" + subnet_mask = 24 +} + +data "phpipam_subnet" "subnet_by_id" { + subnet_id = "${data.phpipam_subnet.subnet_by_cidr.subnet_id}" +} +` + +func TestAccDataSourcePHPIPAMSubnet(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccDataSourcePHPIPAMSubnetConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair("data.phpipam_subnet.subnet_by_cidr", "subnet_id", "data.phpipam_subnet.subnet_by_id", "subnet_id"), + resource.TestCheckResourceAttrPair("data.phpipam_subnet.subnet_by_cidr", "subnet_address", "data.phpipam_subnet.subnet_by_id", "subnet_address"), + resource.TestCheckResourceAttrPair("data.phpipam_subnet.subnet_by_cidr", "subnet_mask", "data.phpipam_subnet.subnet_by_id", "subnet_mask"), + ), + }, + }, + }) +} diff --git a/plugin/providers/phpipam/provider.go b/plugin/providers/phpipam/provider.go index 95a2bef..82079be 100644 --- a/plugin/providers/phpipam/provider.go +++ b/plugin/providers/phpipam/provider.go @@ -39,6 +39,10 @@ func Provider() terraform.ResourceProvider { "phpipam_subnet": resourcePHPIPAMSubnet(), }, + DataSourcesMap: map[string]*schema.Resource{ + "phpipam_subnet": dataSourcePHPIPAMSubnet(), + }, + ConfigureFunc: providerConfigure, } } diff --git a/plugin/providers/phpipam/resource_phpipam_subnet.go b/plugin/providers/phpipam/resource_phpipam_subnet.go index a5abc11..31d802f 100644 --- a/plugin/providers/phpipam/resource_phpipam_subnet.go +++ b/plugin/providers/phpipam/resource_phpipam_subnet.go @@ -1,17 +1,16 @@ package phpipam -import ( - "errors" - "fmt" - - "github.com/hashicorp/terraform/helper/schema" - "github.com/paybyphone/phpipam-sdk-go/controllers/subnets" -) +import "github.com/hashicorp/terraform/helper/schema" +// resourcePHPIPAMSubnet returns the resource structure for the phpipam_subnet +// resource. +// +// Note that we use the data source read function here to pull down data, as +// read workflow is identical for both the resource and the data source. func resourcePHPIPAMSubnet() *schema.Resource { return &schema.Resource{ Create: resourcePHPIPAMSubnetCreate, - Read: resourcePHPIPAMSubnetRead, + Read: dataSourcePHPIPAMSubnetRead, Update: resourcePHPIPAMSubnetUpdate, Delete: resourcePHPIPAMSubnetDelete, Schema: resourceSubnetSchema(), @@ -29,36 +28,7 @@ func resourcePHPIPAMSubnetCreate(d *schema.ResourceData, meta interface{}) error return err } - return resourcePHPIPAMSubnetRead(d, meta) -} - -func resourcePHPIPAMSubnetRead(d *schema.ResourceData, meta interface{}) error { - c := meta.(*ProviderPHPIPAMClient).subnetsController - var out subnets.Subnet - // We need to determine how to get the subnet. An ID search takes priority, - // and after that subnets. - if id := d.Get("subnet_id").(int); id != 0 { - var err error - out, err = c.GetSubnetByID(id) - if err != nil { - return err - } - } else { - v, err := c.GetSubnetsByCIDR(fmt.Sprintf("%s/%d", d.Get("subnet_address"), d.Get("subnet_mask"))) - if err != nil { - return err - } - // This should not happen, as a CIDR search from what I have seen so far - // generally only returns 1 subnet ever. Nontheless, the API spec and the - // function return a slice of subnets, so we need to assert that the search - // has only retuned a single match. - if len(v) != 1 { - return errors.New("CIDR search returned either zero or multiple results. Please correct your search and try again") - } - out = v[0] - } - flattenSubnet(out, d) - return nil + return dataSourcePHPIPAMSubnetRead(d, meta) } func resourcePHPIPAMSubnetUpdate(d *schema.ResourceData, meta interface{}) error { @@ -74,7 +44,7 @@ func resourcePHPIPAMSubnetUpdate(d *schema.ResourceData, meta interface{}) error return err } - return resourcePHPIPAMSubnetRead(d, meta) + return dataSourcePHPIPAMSubnetRead(d, meta) } func resourcePHPIPAMSubnetDelete(d *schema.ResourceData, meta interface{}) error { diff --git a/plugin/providers/phpipam/resource_phpipam_subnet_test.go b/plugin/providers/phpipam/resource_phpipam_subnet_test.go index 2ac17f7..e6a5ab2 100644 --- a/plugin/providers/phpipam/resource_phpipam_subnet_test.go +++ b/plugin/providers/phpipam/resource_phpipam_subnet_test.go @@ -10,9 +10,9 @@ import ( "github.com/hashicorp/terraform/terraform" ) -const testAccPHPIPAMSubnetName = "phpipam_subnet.subnet" -const testAccPHPIPAMSubnetCIDR = "10.10.3.0/24" -const testAccPHPIPAMSubnetConfig = ` +const testAccResourcePHPIPAMSubnetName = "phpipam_subnet.subnet" +const testAccResourcePHPIPAMSubnetCIDR = "10.10.3.0/24" +const testAccResourcePHPIPAMSubnetConfig = ` resource "phpipam_subnet" "subnet" { subnet_address = "10.10.3.0" subnet_mask = 24 @@ -21,16 +21,16 @@ resource "phpipam_subnet" "subnet" { } ` -func TestAccPHPIPAMSubnet(t *testing.T) { +func TestAccResourcePHPIPAMSubnet(t *testing.T) { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckPHPIPAMSubnetDeleted, + CheckDestroy: testAccCheckResourcePHPIPAMSubnetDeleted, Steps: []resource.TestStep{ resource.TestStep{ - Config: testAccPHPIPAMSubnetConfig, + Config: testAccResourcePHPIPAMSubnetConfig, Check: resource.ComposeTestCheckFunc( - testAccCheckPHPIPAMSubnetCreated, + testAccCheckResourcePHPIPAMSubnetCreated, resource.TestCheckResourceAttr("phpipam_subnet.subnet", "subnet_address", "10.10.3.0"), resource.TestCheckResourceAttr("phpipam_subnet.subnet", "subnet_mask", "24"), resource.TestCheckResourceAttr("phpipam_subnet.subnet", "description", "Terraform test subnet"), @@ -40,10 +40,10 @@ func TestAccPHPIPAMSubnet(t *testing.T) { }) } -func testAccCheckPHPIPAMSubnetCreated(s *terraform.State) error { - r, ok := s.RootModule().Resources[testAccPHPIPAMSubnetName] +func testAccCheckResourcePHPIPAMSubnetCreated(s *terraform.State) error { + r, ok := s.RootModule().Resources[testAccResourcePHPIPAMSubnetName] if !ok { - return fmt.Errorf("Resource name %s could not be found", testAccPHPIPAMSubnetName) + return fmt.Errorf("Resource name %s could not be found", testAccResourcePHPIPAMSubnetName) } if r.Primary.ID == "" { return errors.New("No ID is set") @@ -58,9 +58,9 @@ func testAccCheckPHPIPAMSubnetCreated(s *terraform.State) error { return nil } -func testAccCheckPHPIPAMSubnetDeleted(s *terraform.State) error { +func testAccCheckResourcePHPIPAMSubnetDeleted(s *terraform.State) error { c := testAccProvider.Meta().(*ProviderPHPIPAMClient).subnetsController - _, err := c.GetSubnetsByCIDR(testAccPHPIPAMSubnetCIDR) + _, err := c.GetSubnetsByCIDR(testAccResourcePHPIPAMSubnetCIDR) switch { case err == nil: return errors.New("Expected error, got none")