Skip to content

Commit

Permalink
New Datasource: azurerm_orchestrated_virtual_machine_scale_set (#21050
Browse files Browse the repository at this point in the history
)
  • Loading branch information
mbfrahry authored Mar 21, 2023
1 parent 36a5877 commit 5e0d236
Show file tree
Hide file tree
Showing 5 changed files with 518 additions and 1 deletion.
17 changes: 17 additions & 0 deletions internal/services/compute/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ func flattenSubResourcesToIDs(input *[]compute.SubResource) []interface{} {
return ids
}

func flattenSubResourcesToStringIDs(input *[]compute.SubResource) []string {
ids := make([]string, 0)
if input == nil {
return ids
}

for _, v := range *input {
if v.ID == nil {
continue
}

ids = append(ids, *v.ID)
}

return ids
}

func sortSharedImageVersions(values []compute.GalleryImageVersion) ([]compute.GalleryImageVersion, []error) {
errors := make([]error, 0)
sort.Slice(values, func(i, j int) bool {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
package compute

import (
"context"
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/parse"
computeValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/utils"
"github.com/tombuildsstuff/kermit/sdk/compute/2022-08-01/compute"
)

type OrchestratedVirtualMachineScaleSetDataSource struct{}

var _ sdk.DataSource = OrchestratedVirtualMachineScaleSetDataSource{}

type OrchestratedVirtualMachineScaleSetDataSourceModel struct {
Name string `tfschema:"name"`
ResourceGroup string `tfschema:"resource_group_name"`
Location string `tfschema:"location"`
NetworkInterface []VirtualMachineScaleSetNetworkInterface `tfschema:"network_interface"`
Identity []identity.ModelUserAssigned `tfschema:"identity"`
}

type VirtualMachineScaleSetNetworkInterface struct {
Name string `tfschema:"name"`
IPConfiguration []VirtualMachineScaleSetNetworkInterfaceIPConfiguration `tfschema:"ip_configuration"`
DNSServers []string `tfschema:"dns_servers"`
AcceleratedNetworkingEnabled bool `tfschema:"accelerated_networking_enabled"`
IPForwardingEnabled bool `tfschema:"ip_forwarding_enabled"`
NetworkSecurityGroupId string `tfschema:"network_security_group_id"`
Primary bool `tfschema:"primary"`
}

type VirtualMachineScaleSetNetworkInterfaceIPConfiguration struct {
Name string `tfschema:"name"`
ApplicationGatewayBackendAddressPoolIds []string `tfschema:"application_gateway_backend_address_pool_ids"`
ApplicationSecurityGroupIds []string `tfschema:"application_security_group_ids"`
LoadBalancerBackendAddressPoolIds []string `tfschema:"load_balancer_backend_address_pool_ids"`
Primary bool `tfschema:"primary"`
PublicIPAddress []VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddress `tfschema:"public_ip_address"`
SubnetId string `tfschema:"subnet_id"`
Version string `tfschema:"version"`
}

type VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddress struct {
Name string `tfschema:"name"`
DomainNameLabel string `tfschema:"domain_name_label"`
IdleTimeoutInMinutes int `tfschema:"idle_timeout_in_minutes"`
IPTag []VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddressIPTag `tfschema:"ip_tag"`
PublicIpPrefixId string `tfschema:"public_ip_prefix_id"`
SkuName string `tfschema:"sku_name"`
Version string `tfschema:"version"`
}

type VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddressIPTag struct {
Tag string `tfschema:"tag"`
Type string `tfschema:"type"`
}

func (r OrchestratedVirtualMachineScaleSetDataSource) ModelObject() interface{} {
return &OrchestratedVirtualMachineScaleSetDataSourceModel{}
}

func (r OrchestratedVirtualMachineScaleSetDataSource) ResourceType() string {
return "azurerm_orchestrated_virtual_machine_scale_set"
}

func (r OrchestratedVirtualMachineScaleSetDataSource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: computeValidate.VirtualMachineName,
},

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

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

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

"ip_configuration": virtualMachineScaleSetIPConfigurationSchemaForDataSource(),

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

"accelerated_networking_enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"ip_forwarding_enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

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

"primary": {
Type: pluginsdk.TypeBool,
Computed: true,
},
},
},
},

"identity": commonschema.UserAssignedIdentityComputed(),
}
}

func (r OrchestratedVirtualMachineScaleSetDataSource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.Compute.VMScaleSetClient
subscriptionId := metadata.Client.Account.SubscriptionId

var orchestratedVMSS OrchestratedVirtualMachineScaleSetDataSourceModel
if err := metadata.Decode(&orchestratedVMSS); err != nil {
return err
}

id := parse.NewVirtualMachineScaleSetID(subscriptionId, orchestratedVMSS.ResourceGroup, orchestratedVMSS.Name)

existing, err := client.Get(ctx, id.ResourceGroup, id.Name, compute.ExpandTypesForGetVMScaleSetsUserData)
if err != nil {
if utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("%s not found", id)
}
return fmt.Errorf("retrieving %s: %+v", id, err)
}

orchestratedVMSS.Location = location.NormalizeNilable(existing.Location)

if profile := existing.VirtualMachineProfile; profile != nil {
if nwProfile := profile.NetworkProfile; nwProfile != nil {
orchestratedVMSS.NetworkInterface = flattenVirtualMachineScaleSetNetworkInterface(nwProfile.NetworkInterfaceConfigurations)
}
}

userIdentity, err := flattenOrchestratedVirtualMachineScaleSetIdentityToModel(existing.Identity)
if err != nil {
return err
}
orchestratedVMSS.Identity = userIdentity

metadata.SetID(id)

return metadata.Encode(&orchestratedVMSS)
},
}
}

func flattenVirtualMachineScaleSetNetworkInterface(input *[]compute.VirtualMachineScaleSetNetworkConfiguration) []VirtualMachineScaleSetNetworkInterface {
if input == nil {
return []VirtualMachineScaleSetNetworkInterface{}
}

networkInterfaces := make([]VirtualMachineScaleSetNetworkInterface, 0)
for _, v := range *input {
var name, networkSecurityGroupId string
if v.Name != nil {
name = *v.Name
}
if v.NetworkSecurityGroup != nil && v.NetworkSecurityGroup.ID != nil {
networkSecurityGroupId = *v.NetworkSecurityGroup.ID
}
var acceleratedNetworkingEnabled, ipForwardingEnabled, primary bool
if v.EnableAcceleratedNetworking != nil {
acceleratedNetworkingEnabled = *v.EnableAcceleratedNetworking
}
if v.EnableIPForwarding != nil {
ipForwardingEnabled = *v.EnableIPForwarding
}
if v.Primary != nil {
primary = *v.Primary
}

var dnsServers []string
if settings := v.DNSSettings; settings != nil {
dnsServers = *v.DNSSettings.DNSServers
}

networkInterfaces = append(networkInterfaces, VirtualMachineScaleSetNetworkInterface{
Name: name,
NetworkSecurityGroupId: networkSecurityGroupId,
AcceleratedNetworkingEnabled: acceleratedNetworkingEnabled,
IPForwardingEnabled: ipForwardingEnabled,
Primary: primary,
DNSServers: dnsServers,
IPConfiguration: flattenOrchestratedVirtualMachineScaleSetNetworkInterfaceIPConfiguration(v.IPConfigurations),
})
}

return networkInterfaces
}

func flattenOrchestratedVirtualMachineScaleSetNetworkInterfaceIPConfiguration(input *[]compute.VirtualMachineScaleSetIPConfiguration) []VirtualMachineScaleSetNetworkInterfaceIPConfiguration {
if input == nil {
return []VirtualMachineScaleSetNetworkInterfaceIPConfiguration{}
}

ipConfigurations := make([]VirtualMachineScaleSetNetworkInterfaceIPConfiguration, 0)
for _, v := range *input {
var name, subnetId string
if v.Name != nil {
name = *v.Name
}
if v.Subnet != nil && v.Subnet.ID != nil {
subnetId = *v.Subnet.ID
}

var primary bool
if v.Primary != nil {
primary = *v.Primary
}

ipConfigurations = append(ipConfigurations, VirtualMachineScaleSetNetworkInterfaceIPConfiguration{
Name: name,
SubnetId: subnetId,
Primary: primary,
PublicIPAddress: flattenOrchestratedVirtualMachineScaleSetPublicIPAddress(v.PublicIPAddressConfiguration),
ApplicationGatewayBackendAddressPoolIds: flattenSubResourcesToStringIDs(v.ApplicationGatewayBackendAddressPools),
ApplicationSecurityGroupIds: flattenSubResourcesToStringIDs(v.ApplicationSecurityGroups),
LoadBalancerBackendAddressPoolIds: flattenSubResourcesToStringIDs(v.LoadBalancerBackendAddressPools),
})
}

return ipConfigurations
}

func flattenOrchestratedVirtualMachineScaleSetPublicIPAddress(input *compute.VirtualMachineScaleSetPublicIPAddressConfiguration) []VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddress {
if input == nil {
return []VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddress{}
}

ipTags := make([]VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddressIPTag, 0)
if input.IPTags != nil {
for _, rawTag := range *input.IPTags {
var tag, tagType string

if rawTag.IPTagType != nil {
tagType = *rawTag.IPTagType
}

if rawTag.Tag != nil {
tag = *rawTag.Tag
}

ipTags = append(ipTags, VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddressIPTag{
Tag: tag,
Type: tagType,
})
}
}

var domainNameLabel, name, publicIPPrefixId, version string
if input.DNSSettings != nil && input.DNSSettings.DomainNameLabel != nil {
domainNameLabel = *input.DNSSettings.DomainNameLabel
}

if input.Name != nil {
name = *input.Name
}

if input.PublicIPPrefix != nil && input.PublicIPPrefix.ID != nil {
publicIPPrefixId = *input.PublicIPPrefix.ID
}

if input.PublicIPAddressVersion != "" {
version = string(input.PublicIPAddressVersion)
}

var idleTimeoutInMinutes int
if input.IdleTimeoutInMinutes != nil {
idleTimeoutInMinutes = int(*input.IdleTimeoutInMinutes)
}

return []VirtualMachineScaleSetNetworkInterfaceIPConfigurationPublicIPAddress{{
Name: name,
DomainNameLabel: domainNameLabel,
IdleTimeoutInMinutes: idleTimeoutInMinutes,
IPTag: ipTags,
PublicIpPrefixId: publicIPPrefixId,
Version: version,
}}
}

func flattenOrchestratedVirtualMachineScaleSetIdentityToModel(input *compute.VirtualMachineScaleSetIdentity) ([]identity.ModelUserAssigned, error) {
if input == nil {
return nil, nil
}

identityIds := make(map[string]identity.UserAssignedIdentityDetails, 0)
for k, v := range input.UserAssignedIdentities {
if v != nil {
identityIds[k] = identity.UserAssignedIdentityDetails{
ClientId: v.ClientID,
PrincipalId: v.PrincipalID,
}
}
}

tmp := identity.UserAssignedMap{
Type: identity.Type(input.Type),
IdentityIds: identityIds,
}

output, err := identity.FlattenUserAssignedMapToModel(&tmp)
if err != nil {
return nil, fmt.Errorf("expanding `identity`: %+v", err)
}

return *output, nil
}
Loading

0 comments on commit 5e0d236

Please sign in to comment.