diff --git a/openstack/data_source_openstack_fw_group_v2.go b/openstack/data_source_openstack_fw_group_v2.go new file mode 100644 index 000000000..fd0c16018 --- /dev/null +++ b/openstack/data_source_openstack_fw_group_v2.go @@ -0,0 +1,178 @@ +package openstack + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/fwaas_v2/groups" +) + +func dataSourceFWGroupV2() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceFWGroupV2Read, + + Schema: map[string]*schema.Schema{ + "region": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "name": { + Type: schema.TypeString, + Optional: true, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "group_id": { + Type: schema.TypeString, + Optional: true, + }, + + "tenant_id": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ConflictsWith: []string{"project_id"}, + }, + + "project_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"tenant_id"}, + }, + + "shared": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + }, + + "admin_state_up": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + }, + + "ingress_firewall_policy_id": { + Type: schema.TypeString, + Optional: true, + }, + + "egress_firewall_policy_id": { + Type: schema.TypeString, + Optional: true, + }, + + "ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "status": { + Type: schema.TypeString, + Computed: true, + Optional: true, + }, + }, + } +} + +func dataSourceFWGroupV2Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*Config) + networkingClient, err := config.NetworkingV2Client(GetRegion(d, config)) + if err != nil { + return diag.Errorf("Error creating OpenStack networking client: %s", err) + } + + listOpts := groups.ListOpts{} + + if v, ok := d.GetOk("group_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.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("shared"); ok { + shared := v.(bool) + listOpts.Shared = &shared + } + + if v, ok := d.GetOk("admin_state_up"); ok { + AdminStateUp := v.(bool) + listOpts.AdminStateUp = &AdminStateUp + } + + if v, ok := d.GetOk("ingress_firewall_policy_id"); ok { + listOpts.IngressFirewallPolicyID = v.(string) + } + + if v, ok := d.GetOk("egress_firewall_policy_id"); ok { + listOpts.EgressFirewallPolicyID = v.(string) + } + + if v, ok := d.GetOk("status"); ok { + listOpts.Status = v.(string) + } + + pages, err := groups.List(networkingClient, listOpts).AllPages() + if err != nil { + return diag.Errorf("Unable to list openstack_fw_group_v2 groups: %s", err) + } + + allGroups, err := groups.ExtractGroups(pages) + if err != nil { + return diag.Errorf("Unable to retrieve openstack_fw_group_v2: %s", err) + } + + if len(allGroups) < 1 { + return diag.Errorf("Your openstack_fw_group_v2 query returned no results") + } + + if len(allGroups) > 1 { + return diag.Errorf("Your openstack_fw_group_v2 query returned more than one result") + } + + group := allGroups[0] + + log.Printf("[DEBUG] Retrieved openstack_fw_policy_v2 %s: %+v", group.ID, group) + + d.SetId(group.ID) + + d.Set("name", group.Name) + d.Set("description", group.Description) + d.Set("tenant_id", group.TenantID) + d.Set("project_id", group.ProjectID) + d.Set("shared", group.Shared) + d.Set("admin_state_up", group.AdminStateUp) + d.Set("ingress_firewall_policy_id", group.IngressFirewallPolicyID) + d.Set("egress_firewall_policy_id", group.EgressFirewallPolicyID) + d.Set("ports", group.Ports) + d.Set("status", group.Status) + d.Set("region", GetRegion(d, config)) + + return nil +} diff --git a/openstack/data_source_openstack_fw_group_v2_test.go b/openstack/data_source_openstack_fw_group_v2_test.go new file mode 100644 index 000000000..32ef7a05d --- /dev/null +++ b/openstack/data_source_openstack_fw_group_v2_test.go @@ -0,0 +1,191 @@ +package openstack + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccFWGroupV2DataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckNonAdminOnly(t) + testAccPreCheckFW(t) + }, + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccFWGroupV2DataSourceGroup, + }, + { + Config: testAccFWGroupV2DataSourceBasic(), + Check: resource.ComposeTestCheckFunc( + testAccCheckFWGroupV2DataSourceID("data.openstack_fw_group_v2.group_1"), + resource.TestCheckResourceAttr( + "data.openstack_fw_group_v2.group_1", "name", "group_1"), + resource.TestCheckResourceAttr( + "data.openstack_fw_group_v2.group_1", "description", "My firewall group"), + resource.TestCheckResourceAttr( + "data.openstack_fw_group_v2.group_1", "shared", "false"), + resource.TestCheckResourceAttrSet( + "data.openstack_fw_group_v2.group_1", "ingress_firewall_policy_id"), + resource.TestCheckResourceAttrSet( + "data.openstack_fw_group_v2.group_1", "egress_firewall_policy_id"), + ), + }, + }, + }) +} + +func TestAccFWGroupV2DataSource_shared(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckAdminOnly(t) + testAccPreCheckFW(t) + }, + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccFWGroupV2DataSourceGroupShared, + }, + { + Config: testAccFWGroupV2DataSourceShared(), + Check: resource.ComposeTestCheckFunc( + testAccCheckFWGroupV2DataSourceID("data.openstack_fw_group_v2.group_1"), + resource.TestCheckResourceAttr( + "data.openstack_fw_group_v2.group_1", "name", "group_1"), + resource.TestCheckResourceAttr( + "data.openstack_fw_group_v2.group_1", "description", "My firewall group"), + resource.TestCheckResourceAttr( + "data.openstack_fw_group_v2.group_1", "shared", "true"), + resource.TestCheckResourceAttrSet( + "data.openstack_fw_group_v2.group_1", "ingress_firewall_policy_id"), + resource.TestCheckResourceAttrSet( + "data.openstack_fw_group_v2.group_1", "egress_firewall_policy_id"), + ), + }, + }, + }) +} + +func TestAccFWGroupV2DataSource_FWGroupID(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { + testAccPreCheck(t) + testAccPreCheckNonAdminOnly(t) + testAccPreCheckFW(t) + }, + ProviderFactories: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccFWGroupV2DataSourceGroup, + }, + { + Config: testAccFWGroupV2DataSourceGroupID(), + Check: resource.ComposeTestCheckFunc( + testAccCheckFWGroupV2DataSourceID("data.openstack_fw_group_v2.group_1"), + resource.TestCheckResourceAttr( + "data.openstack_fw_group_v2.group_1", "name", "group_1"), + ), + }, + }, + }) +} + +func testAccCheckFWGroupV2DataSourceID(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find firewall group data source: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("Firewall group data source ID not set") + } + + return nil + } +} + +const testAccFWGroupV2DataSourceGroup = ` +resource "openstack_fw_policy_v2" "policy_1" { + name = "policy_1" + description = "My firewall ingress policy" +} + +resource "openstack_fw_policy_v2" "policy_2" { + name = "policy_2" + description = "My firewall egress policy" +} + +resource "openstack_fw_group_v2" "group_1" { + name = "group_1" + description = "My firewall group" + ingress_firewall_policy_id = "${openstack_fw_policy_v2.policy_1.id}" + egress_firewall_policy_id = "${openstack_fw_policy_v2.policy_2.id}" +} +` + +func testAccFWGroupV2DataSourceBasic() string { + return fmt.Sprintf(` +%s + +data "openstack_fw_group_v2" "group_1" { + name = "group_1" + description = "My firewall group" + project_id = "${openstack_fw_group_v2.group_1.project_id}" + shared = false + ingress_firewall_policy_id = "${openstack_fw_policy_v2.policy_1.id}" + egress_firewall_policy_id = "${openstack_fw_policy_v2.policy_2.id}" +} +`, testAccFWGroupV2DataSourceGroup) +} + +const testAccFWGroupV2DataSourceGroupShared = ` +resource "openstack_fw_policy_v2" "policy_1" { + name = "policy_1" + description = "My firewall ingress policy" +} + +resource "openstack_fw_policy_v2" "policy_2" { + name = "policy_2" + description = "My firewall egress policy" +} + +resource "openstack_fw_group_v2" "group_1" { + name = "group_1" + description = "My firewall group" + shared = true + ingress_firewall_policy_id = "${openstack_fw_policy_v2.policy_1.id}" + egress_firewall_policy_id = "${openstack_fw_policy_v2.policy_2.id}" +} +` + +func testAccFWGroupV2DataSourceShared() string { + return fmt.Sprintf(` +%s + +data "openstack_fw_group_v2" "group_1" { + name = "group_1" + description = "My firewall group" + tenant_id = "${openstack_fw_group_v2.group_1.tenant_id}" + shared = true + ingress_firewall_policy_id = "${openstack_fw_policy_v2.policy_1.id}" + egress_firewall_policy_id = "${openstack_fw_policy_v2.policy_2.id}" +} +`, testAccFWGroupV2DataSourceGroupShared) +} + +func testAccFWGroupV2DataSourceGroupID() string { + return fmt.Sprintf(` +%s + +data "openstack_fw_group_v2" "group_1" { + group_id = "${openstack_fw_group_v2.group_1.id}" +} +`, testAccFWGroupV2DataSourceGroup) +} diff --git a/openstack/provider.go b/openstack/provider.go index 6380f7d59..1eb639e48 100644 --- a/openstack/provider.go +++ b/openstack/provider.go @@ -283,6 +283,7 @@ func Provider() *schema.Provider { "openstack_containerinfra_clustertemplate_v1": dataSourceContainerInfraClusterTemplateV1(), "openstack_containerinfra_cluster_v1": dataSourceContainerInfraCluster(), "openstack_dns_zone_v2": dataSourceDNSZoneV2(), + "openstack_fw_group_v2": dataSourceFWGroupV2(), "openstack_fw_policy_v1": dataSourceFWPolicyV1(), "openstack_fw_policy_v2": dataSourceFWPolicyV2(), "openstack_fw_rule_v2": dataSourceFWRuleV2(), diff --git a/website/docs/d/fw_group_v2.html.markdown b/website/docs/d/fw_group_v2.html.markdown new file mode 100644 index 000000000..dc6edcb83 --- /dev/null +++ b/website/docs/d/fw_group_v2.html.markdown @@ -0,0 +1,65 @@ +--- +subcategory: "Networking / Neutron" +layout: "openstack" +page_title: "OpenStack: openstack_fw_group_v2" +sidebar_current: "docs-openstack-datasource-fw-group-v2" +description: |- + Get information on an OpenStack Firewall Group V2. +--- + +# openstack\_fw\_group\_v2 + +Use this data source to get information of an available OpenStack firewall group v2. + +## Example Usage + +```hcl +data "openstack_fw_group_v2" "group" { + name = "tf_test_group" +} +``` + +## Argument Reference + +* `region` - (Optional) The region in which to obtain the V2 Neutron client. + A Neutron client is needed to retrieve firewall group ids. If omitted, the + `region` argument of the provider is used. + +* `name` - (Optional) The name of the firewall group. + +* `description` - (Optional) Human-readable description of the firewall group. + +* `group_id` - (Optional) The ID of the firewall group. + +* `tenant_id` - (Optional) - This argument conflict and interchangeable with + `project_id`. The owner of the firewall group. + +* `project_id` - (Optional) - This argument conflict and interchangeable with + `tenant_id`. The owner of the firewall group. + +* `shared` - (Optional) The sharing status of the firewall group. + +* `admin_state_up` - (Optional) Administrative up/down status for the firewall group. + +* `ingress_firewall_policy_id` - (Optional) The ingress policy ID of the firewall group. + +* `egress_firewall_policy_id` - (Optional) The egress policy ID of the firewall group. + +* `status` - (Optional) Enabled status for the firewall group. + +## Attributes Reference + +The following attributes are exported: + +* `region` - See Argument Reference above. +* `name` - See Argument Reference above. +* `description` - See Argument Reference above. +* `group_id` - See Argument Reference above. +* `tenant_id` - See Argument Reference above. +* `project_id` - See Argument Reference above. +* `shared` - See Argument Reference above. +* `admin_state_up` - See Argument Reference above. +* `ingress_firewall_policy_id` - See Argument Reference above. +* `egress_firewall_policy_id` - See Argument Reference above. +* `ports` - Ports associated with the firewall group. +* `status` - See Argument Reference above. diff --git a/website/openstack.erb b/website/openstack.erb index 4482f5e9b..97122647a 100644 --- a/website/openstack.erb +++ b/website/openstack.erb @@ -58,6 +58,9 @@ > openstack_dns_zone_v2 + > + openstack_fw_group_v2 + > openstack_fw_policy_v1