-
Notifications
You must be signed in to change notification settings - Fork 359
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
452 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
package openstack | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"strconv" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
|
||
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports" | ||
) | ||
|
||
func dataSourceNetworkingPortV2() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceNetworkingPortV2Read, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"region": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"port_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"description": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"admin_state_up": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
}, | ||
|
||
"network_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"tenant_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"project_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"device_owner": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"mac_address": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"device_id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"fixed_ip": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Optional: true, | ||
}, | ||
|
||
"all_fixed_ips": &schema.Schema{ | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
|
||
"return_ids": &schema.Schema{ | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceNetworkingPortV2Read(d *schema.ResourceData, meta interface{}) error { | ||
config := meta.(*Config) | ||
networkingClient, err := config.networkingV2Client(GetRegion(d, config)) | ||
|
||
var returnIDs bool | ||
listOpts := ports.ListOpts{} | ||
|
||
if v, ok := d.GetOk("return_ids"); ok { | ||
returnIDs = v.(bool) | ||
} | ||
|
||
if v, ok := d.GetOk("port_id"); ok { | ||
listOpts.ID = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("name"); ok { | ||
listOpts.Name = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("description"); ok { | ||
listOpts.Description = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOkExists("admin_state_up"); ok { | ||
asu := v.(bool) | ||
listOpts.AdminStateUp = &asu | ||
} | ||
|
||
if v, ok := d.GetOk("network_id"); ok { | ||
listOpts.Status = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("tenant_id"); ok { | ||
listOpts.TenantID = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("project_id"); ok { | ||
listOpts.ProjectID = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("device_owner"); ok { | ||
listOpts.DeviceOwner = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("mac_address"); ok { | ||
listOpts.MACAddress = v.(string) | ||
} | ||
|
||
if v, ok := d.GetOk("device_id"); ok { | ||
listOpts.DeviceID = v.(string) | ||
} | ||
|
||
pages, err := ports.List(networkingClient, listOpts).AllPages() | ||
if err != nil { | ||
return fmt.Errorf("Unable to list Ports: %s", err) | ||
} | ||
|
||
allPorts, err := ports.ExtractPorts(pages) | ||
if err != nil { | ||
return fmt.Errorf("Unable to retrieve Ports: %s", err) | ||
} | ||
|
||
if len(allPorts) == 0 { | ||
return fmt.Errorf("No Port found") | ||
} | ||
|
||
// Create a slice of all returned Fixed IPs. | ||
// This will be in the order returned by the API, | ||
// which is usually alpha-numeric. | ||
var port ports.Port | ||
var ports []ports.Port | ||
if v, ok := d.GetOk("fixed_ip"); ok { | ||
for _, p := range allPorts { | ||
var ips = []string{} | ||
for _, ipObject := range p.FixedIPs { | ||
ips = append(ips, ipObject.IPAddress) | ||
if v == ipObject.IPAddress { | ||
ports = append(ports, p) | ||
} | ||
} | ||
if len(ports) > 0 && len(ips) > 0 && returnIDs == false { | ||
d.Set("all_fixed_ips", ips) | ||
break | ||
} | ||
} | ||
if len(ports) == 0 { | ||
return fmt.Errorf("No Port found") | ||
} | ||
} else { | ||
ports = allPorts | ||
} | ||
|
||
if len(ports) > 1 && returnIDs { | ||
var portIDs []string | ||
|
||
for _, p := range ports { | ||
portIDs = append(portIDs, p.ID) | ||
} | ||
|
||
log.Printf("[DEBUG] Retrieved %d Ports %s: %+v", len(ports), strings.Join(portIDs, ","), ports) | ||
d.SetId(strings.Join(portIDs, ",")) | ||
|
||
return nil | ||
} | ||
|
||
if len(ports) > 1 { | ||
return fmt.Errorf("More than one Port found (%d). Try to use 'return_ids = true'", len(ports)) | ||
} | ||
|
||
if len(ports) == 1 { | ||
port = ports[0] | ||
} | ||
|
||
log.Printf("[DEBUG] Retrieved Port %s: %+v", port.ID, port) | ||
d.SetId(port.ID) | ||
|
||
d.Set("port_id", port.ID) | ||
d.Set("name", port.Name) | ||
d.Set("description", port.Description) | ||
d.Set("admin_state_up", strconv.FormatBool(port.AdminStateUp)) | ||
d.Set("network_id", port.NetworkID) | ||
d.Set("tenant_id", port.TenantID) | ||
d.Set("project_id", port.ProjectID) | ||
d.Set("device_owner", port.DeviceOwner) | ||
d.Set("mac_address", port.MACAddress) | ||
d.Set("device_id", port.DeviceID) | ||
d.Set("region", GetRegion(d, config)) | ||
|
||
// TODO: add more attributes from "resource_openstack_networking_port_v2" | ||
|
||
return nil | ||
} |
136 changes: 136 additions & 0 deletions
136
openstack/data_source_openstack_networking_port_v2_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package openstack | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
) | ||
|
||
func TestAccNetworkingV2PortDataSource_basic(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckNetworkingV2PortDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccNetworkingV2PortDataSource_basic, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckNetworkingV2PortDataSourceID("data.openstack_networking_port_v2.port"), | ||
resource.TestCheckResourceAttr( | ||
"data.openstack_networking_port_v2.port", "description", "test port"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccNetworkingV2PortDataSource_multiple(t *testing.T) { | ||
var port1, port2 ports.Port | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckNetworkingV2PortDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccNetworkingV2PortDataSource_multiple, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckNetworkingV2PortExists("openstack_networking_port_v2.port_1", &port1), | ||
testAccCheckNetworkingV2PortExists("openstack_networking_port_v2.port_2", &port2), | ||
testAccCheckNetworkingV2PortDataSourceMultipleIDs("data.openstack_networking_port_v2.port", &port1, &port2), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckNetworkingV2PortDataSourceID(n string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Can't find port data source: %s", n) | ||
} | ||
|
||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("Port data source ID not set") | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckNetworkingV2PortDataSourceMultipleIDs(n string, port1, port2 *ports.Port) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[n] | ||
if !ok { | ||
return fmt.Errorf("Can't find share data source: %s", n) | ||
} | ||
|
||
if rs.Primary.ID == "" { | ||
return fmt.Errorf("Share data source ID not set") | ||
} | ||
|
||
portIDs := strings.Split(rs.Primary.ID, ",") | ||
if len(portIDs) != 2 { | ||
return fmt.Errorf("Invalid amount of the detected ports: got %d, want 2", len(portIDs)) | ||
} | ||
|
||
if !strSliceContains(portIDs, port1.ID) || !strSliceContains(portIDs, port2.ID) { | ||
return fmt.Errorf("Failed to find expected port IDs (%s, %s) in %s", port1.ID, port2.ID, rs.Primary.ID) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
const testAccNetworkingV2PortDataSource_basic = ` | ||
resource "openstack_networking_network_v2" "network_1" { | ||
name = "network_1" | ||
admin_state_up = "true" | ||
} | ||
resource "openstack_networking_port_v2" "port_1" { | ||
name = "port" | ||
description = "test port" | ||
network_id = "${openstack_networking_network_v2.network_1.id}" | ||
admin_state_up = "true" | ||
} | ||
data "openstack_networking_port_v2" "port" { | ||
# depends_on = ["openstack_networking_port_v2.port_1"] | ||
# workaround for the https://github.com/hashicorp/terraform/issues/11806 | ||
admin_state_up = "${openstack_networking_port_v2.port_1.admin_state_up}" | ||
name = "port" | ||
} | ||
` | ||
|
||
const testAccNetworkingV2PortDataSource_multiple = ` | ||
resource "openstack_networking_network_v2" "network_1" { | ||
name = "network_1" | ||
admin_state_up = "true" | ||
} | ||
resource "openstack_networking_port_v2" "port_1" { | ||
name = "port" | ||
network_id = "${openstack_networking_network_v2.network_1.id}" | ||
admin_state_up = "true" | ||
} | ||
resource "openstack_networking_port_v2" "port_2" { | ||
name = "port" | ||
network_id = "${openstack_networking_network_v2.network_1.id}" | ||
admin_state_up = "true" | ||
} | ||
data "openstack_networking_port_v2" "port" { | ||
# depends_on = ["openstack_networking_port_v2.port_1","openstack_networking_port_v2.port_2"] | ||
# workaround for the https://github.com/hashicorp/terraform/issues/11806 | ||
admin_state_up = "${openstack_networking_port_v2.port_1.admin_state_up == "true" ? openstack_networking_port_v2.port_1.admin_state_up : openstack_networking_port_v2.port_2.admin_state_up}" | ||
name = "port" | ||
return_ids = true | ||
} | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.