From 09b1f4e1be3e982ba78ab3f29749de52dd3e0817 Mon Sep 17 00:00:00 2001 From: yanndegat Date: Mon, 6 Mar 2017 12:25:08 +0100 Subject: [PATCH] provider/openstack: Add openstack_networking_network_v2 datasource (#12304) --- ..._source_openstack_networking_network_v2.go | 112 ++++++++++++++++++ ...ce_openstack_networking_network_v2_test.go | 98 +++++++++++++++ builtin/providers/openstack/provider.go | 3 +- .../d/networking_network_v2.html.markdown | 42 +++++++ website/source/layouts/openstack.erb | 3 + 5 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 builtin/providers/openstack/data_source_openstack_networking_network_v2.go create mode 100644 builtin/providers/openstack/data_source_openstack_networking_network_v2_test.go create mode 100644 website/source/docs/providers/openstack/d/networking_network_v2.html.markdown diff --git a/builtin/providers/openstack/data_source_openstack_networking_network_v2.go b/builtin/providers/openstack/data_source_openstack_networking_network_v2.go new file mode 100644 index 000000000..53e7e1a9f --- /dev/null +++ b/builtin/providers/openstack/data_source_openstack_networking_network_v2.go @@ -0,0 +1,112 @@ +package openstack + +import ( + "fmt" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/schema" + + "github.com/gophercloud/gophercloud" + "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" + "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets" +) + +func dataSourceNetworkingNetworkV2() *schema.Resource { + return &schema.Resource{ + Read: dataSourceNetworkingNetworkV2Read, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "matching_subnet_cidr": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "region": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("OS_REGION_NAME", ""), + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.MultiEnvDefaultFunc([]string{ + "OS_TENANT_ID", + "OS_PROJECT_ID", + }, ""), + Description: descriptions["tenant_id"], + }, + "admin_state_up": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "shared": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourceNetworkingNetworkV2Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + networkingClient, err := config.networkingV2Client(GetRegion(d)) + + listOpts := networks.ListOpts{ + Name: d.Get("name").(string), + TenantID: d.Get("tenant_id").(string), + Status: "ACTIVE", + } + + pages, err := networks.List(networkingClient, listOpts).AllPages() + allNetworks, err := networks.ExtractNetworks(pages) + if err != nil { + return fmt.Errorf("Unable to retrieve networks: %s", err) + } + + var refinedNetworks []networks.Network + if cidr := d.Get("matching_subnet_cidr").(string); cidr != "" { + for _, n := range allNetworks { + for _, s := range n.Subnets { + subnet, err := subnets.Get(networkingClient, s).Extract() + if err != nil { + if _, ok := err.(gophercloud.ErrDefault404); ok { + continue + } + return fmt.Errorf("Unable to retrieve network subnet: %s", err) + } + if cidr == subnet.CIDR { + refinedNetworks = append(refinedNetworks, n) + } + } + } + } else { + refinedNetworks = allNetworks + } + + if len(refinedNetworks) < 1 { + return fmt.Errorf("Your query returned no results. " + + "Please change your search criteria and try again.") + } + + if len(refinedNetworks) > 1 { + return fmt.Errorf("Your query returned more than one result." + + " Please try a more specific search criteria") + } + + network := refinedNetworks[0] + + log.Printf("[DEBUG] Retrieved Network %s: %+v", network.ID, network) + d.SetId(network.ID) + + d.Set("name", network.Name) + d.Set("admin_state_up", strconv.FormatBool(network.AdminStateUp)) + d.Set("shared", strconv.FormatBool(network.Shared)) + d.Set("tenant_id", network.TenantID) + d.Set("region", GetRegion(d)) + + return nil +} diff --git a/builtin/providers/openstack/data_source_openstack_networking_network_v2_test.go b/builtin/providers/openstack/data_source_openstack_networking_network_v2_test.go new file mode 100644 index 000000000..e3dfc860d --- /dev/null +++ b/builtin/providers/openstack/data_source_openstack_networking_network_v2_test.go @@ -0,0 +1,98 @@ +package openstack + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccOpenStackNetworkingNetworkV2DataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccOpenStackNetworkingNetworkV2DataSource_network, + }, + resource.TestStep{ + Config: testAccOpenStackNetworkingNetworkV2DataSource_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckNetworkingNetworkV2DataSourceID("data.openstack_networking_network_v2.net"), + resource.TestCheckResourceAttr( + "data.openstack_networking_network_v2.net", "name", "tf_test_network"), + resource.TestCheckResourceAttr( + "data.openstack_networking_network_v2.net", "admin_state_up", "true"), + ), + }, + }, + }) +} + +func TestAccOpenStackNetworkingNetworkV2DataSource_subnet(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccOpenStackNetworkingNetworkV2DataSource_network, + }, + resource.TestStep{ + Config: testAccOpenStackNetworkingNetworkV2DataSource_subnet, + Check: resource.ComposeTestCheckFunc( + testAccCheckNetworkingNetworkV2DataSourceID("data.openstack_networking_network_v2.net"), + resource.TestCheckResourceAttr( + "data.openstack_networking_network_v2.net", "name", "tf_test_network"), + resource.TestCheckResourceAttr( + "data.openstack_networking_network_v2.net", "admin_state_up", "true"), + ), + }, + }, + }) +} + +func testAccCheckNetworkingNetworkV2DataSourceID(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find network data source: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("Network data source ID not set") + } + + return nil + } +} + +const testAccOpenStackNetworkingNetworkV2DataSource_network = ` +resource "openstack_networking_network_v2" "net" { + name = "tf_test_network" + admin_state_up = "true" +} + +resource "openstack_networking_subnet_v2" "subnet" { + name = "tf_test_subnet" + cidr = "192.168.199.0/24" + no_gateway = true + network_id = "${openstack_networking_network_v2.net.id}" +} +` + +var testAccOpenStackNetworkingNetworkV2DataSource_basic = fmt.Sprintf(` +%s + +data "openstack_networking_network_v2" "net" { + name = "${openstack_networking_network_v2.net.name}" +} +`, testAccOpenStackNetworkingNetworkV2DataSource_network) + +var testAccOpenStackNetworkingNetworkV2DataSource_subnet = fmt.Sprintf(` +%s + +data "openstack_networking_network_v2" "net" { + matching_subnet_cidr = "${openstack_networking_subnet_v2.subnet.cidr}" +} +`, testAccOpenStackNetworkingNetworkV2DataSource_network) diff --git a/builtin/providers/openstack/provider.go b/builtin/providers/openstack/provider.go index 3ac9d870b..294f207e9 100644 --- a/builtin/providers/openstack/provider.go +++ b/builtin/providers/openstack/provider.go @@ -135,7 +135,8 @@ func Provider() terraform.ResourceProvider { }, DataSourcesMap: map[string]*schema.Resource{ - "openstack_images_image_v2": dataSourceImagesImageV2(), + "openstack_images_image_v2": dataSourceImagesImageV2(), + "openstack_networking_network_v2": dataSourceNetworkingNetworkV2(), }, ResourcesMap: map[string]*schema.Resource{ diff --git a/website/source/docs/providers/openstack/d/networking_network_v2.html.markdown b/website/source/docs/providers/openstack/d/networking_network_v2.html.markdown new file mode 100644 index 000000000..c0bdc33d0 --- /dev/null +++ b/website/source/docs/providers/openstack/d/networking_network_v2.html.markdown @@ -0,0 +1,42 @@ +--- +layout: "openstack" +page_title: "OpenStack: openstack_networking_network_v2" +sidebar_current: "docs-openstack-datasource-networking-network-v2" +description: |- + Get information on an OpenStack Network. +--- + +# openstack\_networking\_network\_v2 + +Use this data source to get the ID of an available OpenStack network. + +## Example Usage + +``` +data "openstack_networking_network_v2" "network" { + name = "tf_test_network" +} +``` + +## Argument Reference + +* `region` - (Required) The region in which to obtain the V2 Neutron client. + A Neutron client is needed to retrieve networks ids. If omitted, the + `OS_REGION_NAME` environment variable is used. + +* `name` - (Optional) The name of the network. + +* `matching_subnet_cidr` - (Optional) The CIDR of a subnet within the network. + +* `tenant_id` - (Optional) The owner of the network. + +## Attributes Reference + +`id` is set to the ID of the found network. In addition, the following attributes +are exported: + +* `admin_state_up` - (Optional) The administrative state of the network. +* `name` - See Argument Reference above. +* `region` - See Argument Reference above. +* `shared` - (Optional) Specifies whether the network resource can be accessed + by any tenant or not. diff --git a/website/source/layouts/openstack.erb b/website/source/layouts/openstack.erb index 9d784e74c..0bf025cdf 100644 --- a/website/source/layouts/openstack.erb +++ b/website/source/layouts/openstack.erb @@ -16,6 +16,9 @@ > openstack_images_image_v2 + > + openstack_networking_network_v2 +