Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Data Source: azurerm_stack_hci_logical_network #28581

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/services/azurestackhci/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource {
func (r Registration) DataSources() []sdk.DataSource {
return []sdk.DataSource{
StackHCIClusterDataSource{},
StackHCILogicalNetworkDataSource{},
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
package azurestackhci

import (
"context"
"fmt"
"regexp"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-helpers/resourcemanager/tags"
"github.com/hashicorp/go-azure-sdk/resource-manager/azurestackhci/2024-01-01/logicalnetworks"
"github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
)

type StackHCILogicalNetworkDataSource struct{}

var _ sdk.DataSource = StackHCILogicalNetworkDataSource{}

type StackHCILogicalNetworkDataSourceModel struct {
Name string `tfschema:"name"`
ResourceGroupName string `tfschema:"resource_group_name"`
Location string `tfschema:"location"`
CustomLocationId string `tfschema:"custom_location_id"`
DNSServers []string `tfschema:"dns_servers"`
Subnet []StackHCISubnetModel `tfschema:"subnet"`
VirtualSwitchName string `tfschema:"virtual_switch_name"`
Tags map[string]interface{} `tfschema:"tags"`
}

func (r StackHCILogicalNetworkDataSource) ResourceType() string {
return "azurerm_stack_hci_logical_network"
}

func (r StackHCILogicalNetworkDataSource) ModelObject() interface{} {
return &StackHCILogicalNetworkDataSourceModel{}
}

func (r StackHCILogicalNetworkDataSource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`^[a-zA-Z0-9][\-\.\_a-zA-Z0-9]{0,62}[a-zA-Z0-9]$`),
"name must begin and end with an alphanumeric character, be between 2 and 64 characters in length and can only contain alphanumeric characters, hyphens, periods or underscores.",
),
},

"resource_group_name": commonschema.ResourceGroupName(),
}
}

func (r StackHCILogicalNetworkDataSource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"location": commonschema.LocationComputed(),

"custom_location_id": {
Type: pluginsdk.TypeString,
Computed: true,
},

"virtual_switch_name": {
Type: pluginsdk.TypeString,
Computed: true,
},

"dns_servers": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
},
},

"subnet": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"ip_allocation_method": {
Type: pluginsdk.TypeString,
Computed: true,
},

"address_prefix": {
Type: pluginsdk.TypeString,
Computed: true,
},

"ip_pool": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"start": {
Type: pluginsdk.TypeString,
Computed: true,
},
"end": {
Type: pluginsdk.TypeString,
Computed: true,
},
},
},
},

"route": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"address_prefix": {
Type: pluginsdk.TypeString,
Computed: true,
},

"next_hop_ip_address": {
Type: pluginsdk.TypeString,
Computed: true,
},

"name": {
Type: pluginsdk.TypeString,
Computed: true,
},
},
},
},

"vlan_id": {
Type: pluginsdk.TypeInt,
Computed: true,
},
},
},
},

"tags": commonschema.TagsDataSource(),
}
}

func (r StackHCILogicalNetworkDataSource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.AzureStackHCI.LogicalNetworks

var state StackHCILogicalNetworkDataSourceModel
if err := metadata.Decode(&state); err != nil {
return fmt.Errorf("decoding: %+v", err)
}

subscriptionId := metadata.Client.Account.SubscriptionId
id := logicalnetworks.NewLogicalNetworkID(subscriptionId, state.ResourceGroupName, state.Name)

resp, err := client.Get(ctx, id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("%s does not exist", id)
}

return fmt.Errorf("retrieving %s: %+v", id, err)
}

if model := resp.Model; model != nil {
state.Location = location.Normalize(model.Location)
state.Tags = tags.Flatten(model.Tags)

if model.ExtendedLocation != nil && model.ExtendedLocation.Name != nil {
customLocationId, err := customlocations.ParseCustomLocationIDInsensitively(*model.ExtendedLocation.Name)
if err != nil {
return err
}

state.CustomLocationId = customLocationId.ID()
}

if props := model.Properties; props != nil {
state.Subnet = flattenStackHCILogicalNetworkSubnet(props.Subnets)
state.VirtualSwitchName = pointer.From(props.VMSwitchName)

if props.DhcpOptions != nil {
state.DNSServers = pointer.From(props.DhcpOptions.DnsServers)
}
}
}

metadata.SetID(id)

return metadata.Encode(&state)
},
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package azurestackhci_test

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
)

type StackHCILogicalNetworkDataSource struct{}

func TestAccStackHCILogicalNetworkDataSource_basic(t *testing.T) {
if os.Getenv(customLocationIdEnv) == "" {
t.Skipf("skipping since %q has not been specified", customLocationIdEnv)
}

data := acceptance.BuildTestData(t, "data.azurerm_stack_hci_logical_network", "test")
d := StackHCILogicalNetworkDataSource{}

data.DataSourceTestInSequence(t, []acceptance.TestStep{
{
Config: d.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("location").IsNotEmpty(),
check.That(data.ResourceName).Key("custom_location_id").IsNotEmpty(),
check.That(data.ResourceName).Key("virtual_switch_name").HasValue("ConvergedSwitch(managementcompute)"),
check.That(data.ResourceName).Key("dns_servers.#").HasValue("2"),
check.That(data.ResourceName).Key("subnet.0.ip_allocation_method").HasValue("Static"),
check.That(data.ResourceName).Key("subnet.0.address_prefix").Exists(),
check.That(data.ResourceName).Key("subnet.0.vlan_id").HasValue("123"),
check.That(data.ResourceName).Key("subnet.0.ip_pool.0.start").Exists(),
check.That(data.ResourceName).Key("subnet.0.ip_pool.1.end").Exists(),
check.That(data.ResourceName).Key("subnet.0.route.0.address_prefix").Exists(),
check.That(data.ResourceName).Key("tags.%").HasValue("2"),
),
},
})
}

func (d StackHCILogicalNetworkDataSource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

data "azurerm_stack_hci_logical_network" "test" {
name = azurerm_stack_hci_logical_network.test.name
resource_group_name = azurerm_stack_hci_logical_network.test.resource_group_name
}
`, StackHCILogicalNetworkResource{}.complete(data))
}
89 changes: 89 additions & 0 deletions website/docs/d/stack_hci_logical_network.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
subcategory: "Azure Stack HCI"
layout: "azurerm"
page_title: "Azure Resource Manager: Data Source: azurerm_stack_hci_logical_network"
description: |-
Gets information about an existing Stack HCI Logical Network.
---

# Data Source: azurerm_stack_hci_logical_network

Use this data source to access information about an existing Stack HCI Logical Network.

## Example Usage

```hcl
data "azurerm_stack_hci_logical_network" "example" {
name = "existing"
resource_group_name = "existing"
}

output "id" {
value = data.azurerm_stack_hci_logical_network.example.id
}
```

## Arguments Reference

The following arguments are supported:

* `name` - (Required) The name of this Stack HCI Logical Network. Changing this forces a new Stack HCI Logical Network to be created.

* `resource_group_name` - (Required) The name of the Resource Group where the Stack HCI Logical Network exists. Changing this forces a new Stack HCI Logical Network to be created.

## Attributes Reference

In addition to the Arguments listed above - the following Attributes are exported:

* `id` - The ID of the Stack HCI Logical Network.

* `custom_location_id` - The ID of the Custom Location where the Azure Stack HCI Logical Network exists.

* `dns_servers` - A `dns_servers` block as defined below.

* `location` - The Azure Region where the Stack HCI Logical Network exists.

* `subnet` - A `subnet` block as defined below.

* `tags` - A mapping of tags assigned to the Stack HCI Logical Network.

* `virtual_switch_name` - The name of the virtual switch on the cluster associates with the Azure Stack HCI Logical Network.

---

A `ip_pool` block exports the following:

* `end` - The IPv4 address of the end of the IP address pool.

* `start` - The IPv4 address of the start of the IP address pool.

---

A `route` block exports the following:

* `address_prefix` - The address prefix in CIDR notation.

* `name` - The name of this route.

* `next_hop_ip_address` - The IPv4 address of the next hop.

---

A `subnet` block exports the following:

* `address_prefix` - The address prefix in CIDR notation.

* `ip_allocation_method` - The IP address allocation method of the subnet.

* `ip_pool` - A `ip_pool` block as defined above.

* `route` - A `route` block as defined above.

* `vlan_id` - The VLAN ID of the Logical Network.

## Timeouts

The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions:

* `read` - (Defaults to 5 minutes) Used when retrieving the Stack HCI Logical Network.

2 changes: 1 addition & 1 deletion website/docs/r/stack_hci_logical_network.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ A `ip_pool` block supports the following:

A `route` block supports the following:

* `address_prefix` - (Optional) The Address in CIDR notation. Changing this forces a new resource to be created.
* `address_prefix` - (Optional) The address prefix in CIDR notation. Changing this forces a new resource to be created.

* `next_hop_ip_address` - (Optional) The IPv4 address of the next hop. Changing this forces a new resource to be created.

Expand Down
Loading