From d51bf23b3cacd3fb09eae244d2f97c4bdfbd43e0 Mon Sep 17 00:00:00 2001 From: Tao <104055472+teowa@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:02:02 +0800 Subject: [PATCH] New Resource `azurerm_network_manager_security_admin_configuration`, `azurerm_network_manager_admin_rule_collection`, `azurerm_network_manager_admin_rule` (#20233) --- internal/services/network/client/client.go | 271 ++++++----- ..._manager_admin_rule_collection_resource.go | 257 ++++++++++ ...ger_admin_rule_collection_resource_test.go | 190 ++++++++ .../network_manager_admin_rule_resource.go | 440 ++++++++++++++++++ ...etwork_manager_admin_rule_resource_test.go | 236 ++++++++++ ...onnectivity_configuration_resource_test.go | 2 +- ...nagement_group_connection_resource_test.go | 10 +- ...ork_manager_network_group_resource_test.go | 2 +- .../network/network_manager_resource_test.go | 18 + ..._manager_scope_connection_resource_test.go | 10 +- ...r_security_admin_configuration_resource.go | 261 +++++++++++ ...urity_admin_configuration_resource_test.go | 195 ++++++++ ...ork_manager_static_member_resource_test.go | 2 +- ...r_subscription_connection_resource_test.go | 10 +- .../parse/network_manager_admin_rule.go | 87 ++++ .../network_manager_admin_rule_collection.go | 81 ++++ ...work_manager_admin_rule_collection_test.go | 144 ++++++ .../parse/network_manager_admin_rule_test.go | 160 +++++++ ...rk_manager_security_admin_configuration.go | 75 +++ ...nager_security_admin_configuration_test.go | 128 +++++ internal/services/network/registration.go | 3 + internal/services/network/resourceids.go | 3 + ...etwork_manager_admin_rule_collection_id.go | 23 + ...k_manager_admin_rule_collection_id_test.go | 100 ++++ .../validate/network_manager_admin_rule_id.go | 23 + .../network_manager_admin_rule_id_test.go | 112 +++++ ...manager_security_admin_configuration_id.go | 23 + ...er_security_admin_configuration_id_test.go | 88 ++++ .../network_manager_admin_rule.html.markdown | 139 ++++++ ...anager_admin_rule_collection.html.markdown | 85 ++++ ...security_admin_configuration.html.markdown | 81 ++++ 31 files changed, 3113 insertions(+), 146 deletions(-) create mode 100644 internal/services/network/network_manager_admin_rule_collection_resource.go create mode 100644 internal/services/network/network_manager_admin_rule_collection_resource_test.go create mode 100644 internal/services/network/network_manager_admin_rule_resource.go create mode 100644 internal/services/network/network_manager_admin_rule_resource_test.go create mode 100644 internal/services/network/network_manager_security_admin_configuration_resource.go create mode 100644 internal/services/network/network_manager_security_admin_configuration_resource_test.go create mode 100644 internal/services/network/parse/network_manager_admin_rule.go create mode 100644 internal/services/network/parse/network_manager_admin_rule_collection.go create mode 100644 internal/services/network/parse/network_manager_admin_rule_collection_test.go create mode 100644 internal/services/network/parse/network_manager_admin_rule_test.go create mode 100644 internal/services/network/parse/network_manager_security_admin_configuration.go create mode 100644 internal/services/network/parse/network_manager_security_admin_configuration_test.go create mode 100644 internal/services/network/validate/network_manager_admin_rule_collection_id.go create mode 100644 internal/services/network/validate/network_manager_admin_rule_collection_id_test.go create mode 100644 internal/services/network/validate/network_manager_admin_rule_id.go create mode 100644 internal/services/network/validate/network_manager_admin_rule_id_test.go create mode 100644 internal/services/network/validate/network_manager_security_admin_configuration_id.go create mode 100644 internal/services/network/validate/network_manager_security_admin_configuration_id_test.go create mode 100644 website/docs/r/network_manager_admin_rule.html.markdown create mode 100644 website/docs/r/network_manager_admin_rule_collection.html.markdown create mode 100644 website/docs/r/network_manager_security_admin_configuration.html.markdown diff --git a/internal/services/network/client/client.go b/internal/services/network/client/client.go index a0cb12f4ce81..7a0c334b3a06 100644 --- a/internal/services/network/client/client.go +++ b/internal/services/network/client/client.go @@ -6,70 +6,73 @@ import ( ) type Client struct { - ApplicationGatewaysClient *network.ApplicationGatewaysClient - ApplicationSecurityGroupsClient *network.ApplicationSecurityGroupsClient - BastionHostsClient *network.BastionHostsClient - ConfigurationPolicyGroupClient *network.ConfigurationPolicyGroupsClient - ConnectionMonitorsClient *network.ConnectionMonitorsClient - DDOSProtectionPlansClient *network.DdosProtectionPlansClient - ExpressRouteAuthsClient *network.ExpressRouteCircuitAuthorizationsClient - ExpressRouteCircuitsClient *network.ExpressRouteCircuitsClient - ExpressRouteCircuitConnectionClient *network.ExpressRouteCircuitConnectionsClient - ExpressRouteConnectionsClient *network.ExpressRouteConnectionsClient - ExpressRouteGatewaysClient *network.ExpressRouteGatewaysClient - ExpressRoutePeeringsClient *network.ExpressRouteCircuitPeeringsClient - ExpressRoutePortsClient *network.ExpressRoutePortsClient - FlowLogsClient *network.FlowLogsClient - HubRouteTableClient *network.HubRouteTablesClient - HubVirtualNetworkConnectionClient *network.HubVirtualNetworkConnectionsClient - InterfacesClient *network.InterfacesClient - IPGroupsClient *network.IPGroupsClient - LocalNetworkGatewaysClient *network.LocalNetworkGatewaysClient - ManagersClient *network.ManagersClient - ManagerConnectivityConfigurationsClient *network.ConnectivityConfigurationsClient - ManagerManagementGroupConnectionsClient *network.ManagementGroupNetworkManagerConnectionsClient - ManagerNetworkGroupsClient *network.GroupsClient - ManagerScopeConnectionsClient *network.ScopeConnectionsClient - ManagerStaticMembersClient *network.StaticMembersClient - ManagerSubscriptionConnectionsClient *network.SubscriptionNetworkManagerConnectionsClient - NatRuleClient *network.NatRulesClient - PointToSiteVpnGatewaysClient *network.P2sVpnGatewaysClient - ProfileClient *network.ProfilesClient - PacketCapturesClient *network.PacketCapturesClient - PrivateEndpointClient *network.PrivateEndpointsClient - PublicIPsClient *network.PublicIPAddressesClient - PublicIPPrefixesClient *network.PublicIPPrefixesClient - RouteMapsClient *network.RouteMapsClient - RoutesClient *network.RoutesClient - RouteFiltersClient *network.RouteFiltersClient - RouteTablesClient *network.RouteTablesClient - SecurityGroupClient *network.SecurityGroupsClient - SecurityPartnerProviderClient *network.SecurityPartnerProvidersClient - SecurityRuleClient *network.SecurityRulesClient - ServiceEndpointPoliciesClient *network.ServiceEndpointPoliciesClient - ServiceEndpointPolicyDefinitionsClient *network.ServiceEndpointPolicyDefinitionsClient - ServiceTagsClient *network.ServiceTagsClient - SubnetsClient *network.SubnetsClient - NatGatewayClient *network.NatGatewaysClient - VirtualHubBgpConnectionClient *network.VirtualHubBgpConnectionClient - VirtualHubIPClient *network.VirtualHubIPConfigurationClient - VnetGatewayConnectionsClient *network.VirtualNetworkGatewayConnectionsClient - VnetGatewayNatRuleClient *network.VirtualNetworkGatewayNatRulesClient - VnetGatewayClient *network.VirtualNetworkGatewaysClient - VnetClient *network.VirtualNetworksClient - VnetPeeringsClient *network.VirtualNetworkPeeringsClient - VirtualWanClient *network.VirtualWansClient - VirtualHubClient *network.VirtualHubsClient - VpnConnectionsClient *network.VpnConnectionsClient - VpnGatewaysClient *network.VpnGatewaysClient - VpnServerConfigurationsClient *network.VpnServerConfigurationsClient - VpnSitesClient *network.VpnSitesClient - WatcherClient *network.WatchersClient - WebApplicationFirewallPoliciesClient *network.WebApplicationFirewallPoliciesClient - PrivateDnsZoneGroupClient *network.PrivateDNSZoneGroupsClient - PrivateLinkServiceClient *network.PrivateLinkServicesClient - ServiceAssociationLinkClient *network.ServiceAssociationLinksClient - ResourceNavigationLinkClient *network.ResourceNavigationLinksClient + ApplicationGatewaysClient *network.ApplicationGatewaysClient + ApplicationSecurityGroupsClient *network.ApplicationSecurityGroupsClient + BastionHostsClient *network.BastionHostsClient + ConfigurationPolicyGroupClient *network.ConfigurationPolicyGroupsClient + ConnectionMonitorsClient *network.ConnectionMonitorsClient + DDOSProtectionPlansClient *network.DdosProtectionPlansClient + ExpressRouteAuthsClient *network.ExpressRouteCircuitAuthorizationsClient + ExpressRouteCircuitsClient *network.ExpressRouteCircuitsClient + ExpressRouteCircuitConnectionClient *network.ExpressRouteCircuitConnectionsClient + ExpressRouteConnectionsClient *network.ExpressRouteConnectionsClient + ExpressRouteGatewaysClient *network.ExpressRouteGatewaysClient + ExpressRoutePeeringsClient *network.ExpressRouteCircuitPeeringsClient + ExpressRoutePortsClient *network.ExpressRoutePortsClient + FlowLogsClient *network.FlowLogsClient + HubRouteTableClient *network.HubRouteTablesClient + HubVirtualNetworkConnectionClient *network.HubVirtualNetworkConnectionsClient + InterfacesClient *network.InterfacesClient + IPGroupsClient *network.IPGroupsClient + LocalNetworkGatewaysClient *network.LocalNetworkGatewaysClient + ManagersClient *network.ManagersClient + ManagerAdminRulesClient *network.AdminRulesClient + ManagerAdminRuleCollectionsClient *network.AdminRuleCollectionsClient + ManagerConnectivityConfigurationsClient *network.ConnectivityConfigurationsClient + ManagerManagementGroupConnectionsClient *network.ManagementGroupNetworkManagerConnectionsClient + ManagerNetworkGroupsClient *network.GroupsClient + ManagerScopeConnectionsClient *network.ScopeConnectionsClient + ManagerSecurityAdminConfigurationsClient *network.SecurityAdminConfigurationsClient + ManagerStaticMembersClient *network.StaticMembersClient + ManagerSubscriptionConnectionsClient *network.SubscriptionNetworkManagerConnectionsClient + NatRuleClient *network.NatRulesClient + PointToSiteVpnGatewaysClient *network.P2sVpnGatewaysClient + ProfileClient *network.ProfilesClient + PacketCapturesClient *network.PacketCapturesClient + PrivateEndpointClient *network.PrivateEndpointsClient + PublicIPsClient *network.PublicIPAddressesClient + PublicIPPrefixesClient *network.PublicIPPrefixesClient + RouteMapsClient *network.RouteMapsClient + RoutesClient *network.RoutesClient + RouteFiltersClient *network.RouteFiltersClient + RouteTablesClient *network.RouteTablesClient + SecurityGroupClient *network.SecurityGroupsClient + SecurityPartnerProviderClient *network.SecurityPartnerProvidersClient + SecurityRuleClient *network.SecurityRulesClient + ServiceEndpointPoliciesClient *network.ServiceEndpointPoliciesClient + ServiceEndpointPolicyDefinitionsClient *network.ServiceEndpointPolicyDefinitionsClient + ServiceTagsClient *network.ServiceTagsClient + SubnetsClient *network.SubnetsClient + NatGatewayClient *network.NatGatewaysClient + VirtualHubBgpConnectionClient *network.VirtualHubBgpConnectionClient + VirtualHubIPClient *network.VirtualHubIPConfigurationClient + VnetGatewayConnectionsClient *network.VirtualNetworkGatewayConnectionsClient + VnetGatewayNatRuleClient *network.VirtualNetworkGatewayNatRulesClient + VnetGatewayClient *network.VirtualNetworkGatewaysClient + VnetClient *network.VirtualNetworksClient + VnetPeeringsClient *network.VirtualNetworkPeeringsClient + VirtualWanClient *network.VirtualWansClient + VirtualHubClient *network.VirtualHubsClient + VpnConnectionsClient *network.VpnConnectionsClient + VpnGatewaysClient *network.VpnGatewaysClient + VpnServerConfigurationsClient *network.VpnServerConfigurationsClient + VpnSitesClient *network.VpnSitesClient + WatcherClient *network.WatchersClient + WebApplicationFirewallPoliciesClient *network.WebApplicationFirewallPoliciesClient + PrivateDnsZoneGroupClient *network.PrivateDNSZoneGroupsClient + PrivateLinkServiceClient *network.PrivateLinkServicesClient + ServiceAssociationLinkClient *network.ServiceAssociationLinksClient + ResourceNavigationLinkClient *network.ResourceNavigationLinksClient } func NewClient(o *common.ClientOptions) *Client { @@ -133,12 +136,21 @@ func NewClient(o *common.ClientOptions) *Client { ManagersClient := network.NewManagersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&ManagersClient.Client, o.ResourceManagerAuthorizer) + ManagerAdminRulesClient := network.NewAdminRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ManagerAdminRulesClient.Client, o.ResourceManagerAuthorizer) + + ManagerAdminRuleCollectionsClient := network.NewAdminRuleCollectionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ManagerAdminRuleCollectionsClient.Client, o.ResourceManagerAuthorizer) + ManagerConnectivityConfigurationsClient := network.NewConnectivityConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&ManagerConnectivityConfigurationsClient.Client, o.ResourceManagerAuthorizer) ManagerScopeConnectionsClient := network.NewScopeConnectionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&ManagerScopeConnectionsClient.Client, o.ResourceManagerAuthorizer) + ManagerSecurityAdminConfigurationsClient := network.NewSecurityAdminConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&ManagerSecurityAdminConfigurationsClient.Client, o.ResourceManagerAuthorizer) + ManagerManagementGroupConnectionsClient := network.NewManagementGroupNetworkManagerConnectionsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&ManagerManagementGroupConnectionsClient.Client, o.ResourceManagerAuthorizer) @@ -266,69 +278,72 @@ func NewClient(o *common.ClientOptions) *Client { o.ConfigureClient(&ResourceNavigationLinkClient.Client, o.ResourceManagerAuthorizer) return &Client{ - ApplicationGatewaysClient: &ApplicationGatewaysClient, - ApplicationSecurityGroupsClient: &ApplicationSecurityGroupsClient, - BastionHostsClient: &BastionHostsClient, - ConfigurationPolicyGroupClient: &configurationPolicyGroupClient, - ConnectionMonitorsClient: &ConnectionMonitorsClient, - DDOSProtectionPlansClient: &DDOSProtectionPlansClient, - ExpressRouteAuthsClient: &ExpressRouteAuthsClient, - ExpressRouteCircuitsClient: &ExpressRouteCircuitsClient, - ExpressRouteCircuitConnectionClient: &ExpressRouteCircuitConnectionClient, - ExpressRouteConnectionsClient: &ExpressRouteConnectionsClient, - ExpressRouteGatewaysClient: &ExpressRouteGatewaysClient, - ExpressRoutePeeringsClient: &ExpressRoutePeeringsClient, - ExpressRoutePortsClient: &ExpressRoutePortsClient, - FlowLogsClient: &FlowLogsClient, - HubRouteTableClient: &HubRouteTableClient, - HubVirtualNetworkConnectionClient: &HubVirtualNetworkConnectionClient, - InterfacesClient: &InterfacesClient, - IPGroupsClient: &IpGroupsClient, - LocalNetworkGatewaysClient: &LocalNetworkGatewaysClient, - ManagersClient: &ManagersClient, - ManagerConnectivityConfigurationsClient: &ManagerConnectivityConfigurationsClient, - ManagerManagementGroupConnectionsClient: &ManagerManagementGroupConnectionsClient, - ManagerNetworkGroupsClient: &ManagerNetworkGroupsClient, - ManagerScopeConnectionsClient: &ManagerScopeConnectionsClient, - ManagerStaticMembersClient: &ManagerStaticMembersClient, - ManagerSubscriptionConnectionsClient: &ManagerSubscriptionConnectionsClient, - NatRuleClient: &NatRuleClient, - PointToSiteVpnGatewaysClient: &pointToSiteVpnGatewaysClient, - ProfileClient: &ProfileClient, - PacketCapturesClient: &PacketCapturesClient, - PrivateEndpointClient: &PrivateEndpointClient, - PublicIPsClient: &PublicIPsClient, - PublicIPPrefixesClient: &PublicIPPrefixesClient, - RouteMapsClient: &RouteMapsClient, - RoutesClient: &RoutesClient, - RouteFiltersClient: &RouteFiltersClient, - RouteTablesClient: &RouteTablesClient, - SecurityGroupClient: &SecurityGroupClient, - SecurityPartnerProviderClient: &SecurityPartnerProviderClient, - SecurityRuleClient: &SecurityRuleClient, - ServiceEndpointPoliciesClient: &ServiceEndpointPoliciesClient, - ServiceEndpointPolicyDefinitionsClient: &ServiceEndpointPolicyDefinitionsClient, - ServiceTagsClient: &ServiceTagsClient, - SubnetsClient: &SubnetsClient, - NatGatewayClient: &NatGatewayClient, - VirtualHubBgpConnectionClient: &VirtualHubBgpConnectionClient, - VirtualHubIPClient: &VirtualHubIPClient, - VnetGatewayConnectionsClient: &VnetGatewayConnectionsClient, - VnetGatewayNatRuleClient: &VnetGatewayNatRuleClient, - VnetGatewayClient: &VnetGatewayClient, - VnetClient: &VnetClient, - VnetPeeringsClient: &VnetPeeringsClient, - VirtualWanClient: &VirtualWanClient, - VirtualHubClient: &VirtualHubClient, - VpnConnectionsClient: &vpnConnectionsClient, - VpnGatewaysClient: &vpnGatewaysClient, - VpnServerConfigurationsClient: &vpnServerConfigurationsClient, - VpnSitesClient: &vpnSitesClient, - WatcherClient: &WatcherClient, - WebApplicationFirewallPoliciesClient: &WebApplicationFirewallPoliciesClient, - PrivateDnsZoneGroupClient: &PrivateDnsZoneGroupClient, - PrivateLinkServiceClient: &PrivateLinkServiceClient, - ServiceAssociationLinkClient: &ServiceAssociationLinkClient, - ResourceNavigationLinkClient: &ResourceNavigationLinkClient, + ApplicationGatewaysClient: &ApplicationGatewaysClient, + ApplicationSecurityGroupsClient: &ApplicationSecurityGroupsClient, + BastionHostsClient: &BastionHostsClient, + ConfigurationPolicyGroupClient: &configurationPolicyGroupClient, + ConnectionMonitorsClient: &ConnectionMonitorsClient, + DDOSProtectionPlansClient: &DDOSProtectionPlansClient, + ExpressRouteAuthsClient: &ExpressRouteAuthsClient, + ExpressRouteCircuitsClient: &ExpressRouteCircuitsClient, + ExpressRouteCircuitConnectionClient: &ExpressRouteCircuitConnectionClient, + ExpressRouteConnectionsClient: &ExpressRouteConnectionsClient, + ExpressRouteGatewaysClient: &ExpressRouteGatewaysClient, + ExpressRoutePeeringsClient: &ExpressRoutePeeringsClient, + ExpressRoutePortsClient: &ExpressRoutePortsClient, + FlowLogsClient: &FlowLogsClient, + HubRouteTableClient: &HubRouteTableClient, + HubVirtualNetworkConnectionClient: &HubVirtualNetworkConnectionClient, + InterfacesClient: &InterfacesClient, + IPGroupsClient: &IpGroupsClient, + LocalNetworkGatewaysClient: &LocalNetworkGatewaysClient, + ManagersClient: &ManagersClient, + ManagerAdminRulesClient: &ManagerAdminRulesClient, + ManagerAdminRuleCollectionsClient: &ManagerAdminRuleCollectionsClient, + ManagerConnectivityConfigurationsClient: &ManagerConnectivityConfigurationsClient, + ManagerManagementGroupConnectionsClient: &ManagerManagementGroupConnectionsClient, + ManagerNetworkGroupsClient: &ManagerNetworkGroupsClient, + ManagerScopeConnectionsClient: &ManagerScopeConnectionsClient, + ManagerSecurityAdminConfigurationsClient: &ManagerSecurityAdminConfigurationsClient, + ManagerStaticMembersClient: &ManagerStaticMembersClient, + ManagerSubscriptionConnectionsClient: &ManagerSubscriptionConnectionsClient, + NatRuleClient: &NatRuleClient, + PointToSiteVpnGatewaysClient: &pointToSiteVpnGatewaysClient, + ProfileClient: &ProfileClient, + PacketCapturesClient: &PacketCapturesClient, + PrivateEndpointClient: &PrivateEndpointClient, + PublicIPsClient: &PublicIPsClient, + PublicIPPrefixesClient: &PublicIPPrefixesClient, + RouteMapsClient: &RouteMapsClient, + RoutesClient: &RoutesClient, + RouteFiltersClient: &RouteFiltersClient, + RouteTablesClient: &RouteTablesClient, + SecurityGroupClient: &SecurityGroupClient, + SecurityPartnerProviderClient: &SecurityPartnerProviderClient, + SecurityRuleClient: &SecurityRuleClient, + ServiceEndpointPoliciesClient: &ServiceEndpointPoliciesClient, + ServiceEndpointPolicyDefinitionsClient: &ServiceEndpointPolicyDefinitionsClient, + ServiceTagsClient: &ServiceTagsClient, + SubnetsClient: &SubnetsClient, + NatGatewayClient: &NatGatewayClient, + VirtualHubBgpConnectionClient: &VirtualHubBgpConnectionClient, + VirtualHubIPClient: &VirtualHubIPClient, + VnetGatewayConnectionsClient: &VnetGatewayConnectionsClient, + VnetGatewayNatRuleClient: &VnetGatewayNatRuleClient, + VnetGatewayClient: &VnetGatewayClient, + VnetClient: &VnetClient, + VnetPeeringsClient: &VnetPeeringsClient, + VirtualWanClient: &VirtualWanClient, + VirtualHubClient: &VirtualHubClient, + VpnConnectionsClient: &vpnConnectionsClient, + VpnGatewaysClient: &vpnGatewaysClient, + VpnServerConfigurationsClient: &vpnServerConfigurationsClient, + VpnSitesClient: &vpnSitesClient, + WatcherClient: &WatcherClient, + WebApplicationFirewallPoliciesClient: &WebApplicationFirewallPoliciesClient, + PrivateDnsZoneGroupClient: &PrivateDnsZoneGroupClient, + PrivateLinkServiceClient: &PrivateLinkServiceClient, + ServiceAssociationLinkClient: &ServiceAssociationLinkClient, + ResourceNavigationLinkClient: &ResourceNavigationLinkClient, } } diff --git a/internal/services/network/network_manager_admin_rule_collection_resource.go b/internal/services/network/network_manager_admin_rule_collection_resource.go new file mode 100644 index 000000000000..7dcbff341cea --- /dev/null +++ b/internal/services/network/network_manager_admin_rule_collection_resource.go @@ -0,0 +1,257 @@ +package network + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" +) + +type ManagerAdminRuleCollectionModel struct { + Name string `tfschema:"name"` + SecurityAdminConfigurationId string `tfschema:"security_admin_configuration_id"` + NetworkGroupIds []string `tfschema:"network_group_ids"` + Description string `tfschema:"description"` +} + +type ManagerAdminRuleCollectionResource struct{} + +var _ sdk.ResourceWithUpdate = ManagerAdminRuleCollectionResource{} + +func (r ManagerAdminRuleCollectionResource) ResourceType() string { + return "azurerm_network_manager_admin_rule_collection" +} + +func (r ManagerAdminRuleCollectionResource) ModelObject() interface{} { + return &ManagerAdminRuleCollectionModel{} +} + +func (r ManagerAdminRuleCollectionResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return validate.NetworkManagerAdminRuleCollectionID +} + +func (r ManagerAdminRuleCollectionResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "security_admin_configuration_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NetworkManagerSecurityAdminConfigurationID, + }, + + "network_group_ids": { + Type: pluginsdk.TypeList, + Required: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validate.NetworkManagerNetworkGroupID, + }, + }, + + "description": { + Type: pluginsdk.TypeString, + Optional: true, + }, + } +} + +func (r ManagerAdminRuleCollectionResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ManagerAdminRuleCollectionResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var model ManagerAdminRuleCollectionModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + client := metadata.Client.Network.ManagerAdminRuleCollectionsClient + configurationId, err := parse.NetworkManagerSecurityAdminConfigurationID(model.SecurityAdminConfigurationId) + if err != nil { + return err + } + + id := parse.NewNetworkManagerAdminRuleCollectionID(configurationId.SubscriptionId, configurationId.ResourceGroup, + configurationId.NetworkManagerName, configurationId.SecurityAdminConfigurationName, model.Name) + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName) + + if err != nil && !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for existing %s: %+v", id, err) + } + + if !utils.ResponseWasNotFound(existing.Response) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + adminRuleCollection := &network.AdminRuleCollection{ + AdminRuleCollectionPropertiesFormat: &network.AdminRuleCollectionPropertiesFormat{ + AppliesToGroups: expandNetworkManagerNetworkGroupIds(model.NetworkGroupIds), + }, + } + + if model.Description != "" { + adminRuleCollection.AdminRuleCollectionPropertiesFormat.Description = &model.Description + } + + if _, err := client.CreateOrUpdate(ctx, *adminRuleCollection, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ManagerAdminRuleCollectionResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerAdminRuleCollectionsClient + + id, err := parse.NetworkManagerAdminRuleCollectionID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ManagerAdminRuleCollectionModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + properties := existing.AdminRuleCollectionPropertiesFormat + if properties == nil { + return fmt.Errorf("retrieving %s: properties was nil", id) + } + + if metadata.ResourceData.HasChange("network_group_ids") { + properties.AppliesToGroups = expandNetworkManagerNetworkGroupIds(model.NetworkGroupIds) + } + + if metadata.ResourceData.HasChange("description") { + properties.Description = utils.String(model.Description) + } + + if _, err := client.CreateOrUpdate(ctx, existing, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName); err != nil { + return fmt.Errorf("updating %s: %+v", *id, err) + } + + return nil + }, + } +} + +func (r ManagerAdminRuleCollectionResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerAdminRuleCollectionsClient + + id, err := parse.NetworkManagerAdminRuleCollectionID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName) + if err != nil { + if utils.ResponseWasNotFound(existing.Response) { + return metadata.MarkAsGone(id) + } + + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + properties := existing.AdminRuleCollectionPropertiesFormat + if properties == nil { + return fmt.Errorf("retrieving %s: properties was nil", id) + } + + state := ManagerAdminRuleCollectionModel{ + Name: id.RuleCollectionName, + SecurityAdminConfigurationId: parse.NewNetworkManagerSecurityAdminConfigurationID(id.SubscriptionId, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName).ID(), + NetworkGroupIds: flattenNetworkManagerNetworkGroupIds(properties.AppliesToGroups), + } + + if properties.Description != nil { + state.Description = *properties.Description + } + + return metadata.Encode(&state) + }, + } +} + +func (r ManagerAdminRuleCollectionResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerAdminRuleCollectionsClient + + id, err := parse.NetworkManagerAdminRuleCollectionID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + future, err := client.Delete(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, utils.Bool(true)) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("waiting for deletion of %s: %+v", *id, err) + } + return nil + }, + } +} + +func expandNetworkManagerNetworkGroupIds(inputList []string) *[]network.ManagerSecurityGroupItem { + var outputList []network.ManagerSecurityGroupItem + for _, v := range inputList { + input := v + output := network.ManagerSecurityGroupItem{ + NetworkGroupID: utils.String(input), + } + + outputList = append(outputList, output) + } + + return &outputList +} + +func flattenNetworkManagerNetworkGroupIds(inputList *[]network.ManagerSecurityGroupItem) []string { + var outputList []string + if inputList == nil { + return outputList + } + + for _, input := range *inputList { + if input.NetworkGroupID != nil { + outputList = append(outputList, *input.NetworkGroupID) + } + } + + return outputList +} diff --git a/internal/services/network/network_manager_admin_rule_collection_resource_test.go b/internal/services/network/network_manager_admin_rule_collection_resource_test.go new file mode 100644 index 000000000000..6d08a77ba3a7 --- /dev/null +++ b/internal/services/network/network_manager_admin_rule_collection_resource_test.go @@ -0,0 +1,190 @@ +package network_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type NetworkAdminRuleCollectionResource struct{} + +func testAccNetworkManagerAdminRuleCollection_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule_collection", "test") + r := NetworkAdminRuleCollectionResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func testAccNetworkManagerAdminRuleCollection_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule_collection", "test") + r := NetworkAdminRuleCollectionResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} + +func testAccNetworkManagerAdminRuleCollection_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule_collection", "test") + r := NetworkAdminRuleCollectionResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func testAccNetworkManagerAdminRuleCollection_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule_collection", "test") + r := NetworkAdminRuleCollectionResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r NetworkAdminRuleCollectionResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.NetworkManagerAdminRuleCollectionID(state.ID) + if err != nil { + return nil, err + } + + client := clients.Network.ManagerAdminRuleCollectionsClient + resp, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + return utils.Bool(resp.AdminRuleCollectionPropertiesFormat != nil), nil +} + +func (r NetworkAdminRuleCollectionResource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-network-manager-%d" + location = "%s" +} + +data "azurerm_subscription" "current" { +} + +resource "azurerm_network_manager" "test" { + name = "acctest-nm-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + scope { + subscription_ids = [data.azurerm_subscription.current.id] + } + scope_accesses = ["SecurityAdmin"] +} + +resource "azurerm_network_manager_network_group" "test" { + name = "acctest-nmng-%d" + network_manager_id = azurerm_network_manager.test.id +} + +resource "azurerm_network_manager_security_admin_configuration" "test" { + name = "acctest-nmsac-%d" + network_manager_id = azurerm_network_manager.test.id +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger) +} + +func (r NetworkAdminRuleCollectionResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` + %s + +resource "azurerm_network_manager_admin_rule_collection" "test" { + name = "acctest-nmarc-%d" + security_admin_configuration_id = azurerm_network_manager_security_admin_configuration.test.id + network_group_ids = [azurerm_network_manager_network_group.test.id] +} +`, template, data.RandomInteger) +} + +func (r NetworkAdminRuleCollectionResource) requiresImport(data acceptance.TestData) string { + config := r.basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_admin_rule_collection" "import" { + name = azurerm_network_manager_admin_rule_collection.test.name + security_admin_configuration_id = azurerm_network_manager_admin_rule_collection.test.security_admin_configuration_id + network_group_ids = azurerm_network_manager_admin_rule_collection.test.network_group_ids +} +`, config) +} + +func (r NetworkAdminRuleCollectionResource) complete(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_network_group" "test2" { + name = "acctest-nmng2-%d" + network_manager_id = azurerm_network_manager.test.id +} + +resource "azurerm_network_manager_admin_rule_collection" "test" { + name = "acctest-nmarc-%d" + security_admin_configuration_id = azurerm_network_manager_security_admin_configuration.test.id + description = "test admin rule collection" + network_group_ids = [azurerm_network_manager_network_group.test.id, azurerm_network_manager_network_group.test2.id] +} +`, template, data.RandomInteger, data.RandomInteger) +} + +func (r NetworkAdminRuleCollectionResource) update(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_admin_rule_collection" "test" { + name = "acctest-nmarc-%d" + security_admin_configuration_id = azurerm_network_manager_security_admin_configuration.test.id + network_group_ids = [azurerm_network_manager_network_group.test.id] +} +`, template, data.RandomInteger) +} diff --git a/internal/services/network/network_manager_admin_rule_resource.go b/internal/services/network/network_manager_admin_rule_resource.go new file mode 100644 index 000000000000..162d9360f7f3 --- /dev/null +++ b/internal/services/network/network_manager_admin_rule_resource.go @@ -0,0 +1,440 @@ +package network + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" +) + +type ManagerAdminRuleModel struct { + Name string `tfschema:"name"` + NetworkRuleCollectionId string `tfschema:"admin_rule_collection_id"` + Action network.SecurityConfigurationRuleAccess `tfschema:"action"` + Description string `tfschema:"description"` + DestinationPortRanges []string `tfschema:"destination_port_ranges"` + Destinations []AddressPrefixItemModel `tfschema:"destination"` + Direction network.SecurityConfigurationRuleDirection `tfschema:"direction"` + Priority int32 `tfschema:"priority"` + Protocol network.SecurityConfigurationRuleProtocol `tfschema:"protocol"` + SourcePortRanges []string `tfschema:"source_port_ranges"` + Sources []AddressPrefixItemModel `tfschema:"source"` +} + +type AddressPrefixItemModel struct { + AddressPrefix string `tfschema:"address_prefix"` + AddressPrefixType network.AddressPrefixType `tfschema:"address_prefix_type"` +} + +type ManagerAdminRuleResource struct{} + +var _ sdk.ResourceWithUpdate = ManagerAdminRuleResource{} + +func (r ManagerAdminRuleResource) ResourceType() string { + return "azurerm_network_manager_admin_rule" +} + +func (r ManagerAdminRuleResource) ModelObject() interface{} { + return &ManagerAdminRuleModel{} +} + +func (r ManagerAdminRuleResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return validate.NetworkManagerAdminRuleID +} + +func (r ManagerAdminRuleResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "admin_rule_collection_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NetworkManagerAdminRuleCollectionID, + }, + + "action": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.SecurityConfigurationRuleAccessAllow), + string(network.SecurityConfigurationRuleAccessDeny), + string(network.SecurityConfigurationRuleAccessAlwaysAllow), + }, false), + }, + + "direction": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.SecurityConfigurationRuleDirectionInbound), + string(network.SecurityConfigurationRuleDirectionOutbound), + }, false), + }, + + "priority": { + Type: pluginsdk.TypeInt, + Required: true, + ValidateFunc: validation.IntBetween(1, 4096), + }, + + "protocol": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.SecurityConfigurationRuleProtocolAh), + string(network.SecurityConfigurationRuleProtocolAny), + string(network.SecurityConfigurationRuleProtocolIcmp), + string(network.SecurityConfigurationRuleProtocolEsp), + string(network.SecurityConfigurationRuleProtocolTCP), + string(network.SecurityConfigurationRuleProtocolUDP), + }, false), + }, + + "description": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "destination_port_ranges": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + + "destination": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "address_prefix": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "address_prefix_type": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.AddressPrefixTypeIPPrefix), + string(network.AddressPrefixTypeServiceTag), + }, false), + }, + }, + }, + }, + + "source_port_ranges": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + + "source": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "address_prefix": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "address_prefix_type": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(network.AddressPrefixTypeIPPrefix), + string(network.AddressPrefixTypeServiceTag), + }, false), + }, + }, + }, + }, + } +} + +func (r ManagerAdminRuleResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ManagerAdminRuleResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var model ManagerAdminRuleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + client := metadata.Client.Network.ManagerAdminRulesClient + ruleCollectionId, err := parse.NetworkManagerAdminRuleCollectionID(model.NetworkRuleCollectionId) + if err != nil { + return err + } + + id := parse.NewNetworkManagerAdminRuleID(ruleCollectionId.SubscriptionId, ruleCollectionId.ResourceGroup, + ruleCollectionId.NetworkManagerName, ruleCollectionId.SecurityAdminConfigurationName, ruleCollectionId.RuleCollectionName, model.Name) + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName) + if err != nil && !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for existing %s: %+v", id, err) + } + + if !utils.ResponseWasNotFound(existing.Response) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + rule := &network.AdminRule{ + AdminPropertiesFormat: &network.AdminPropertiesFormat{ + Access: model.Action, + Destinations: expandAddressPrefixItemModel(model.Destinations), + DestinationPortRanges: &model.DestinationPortRanges, + Direction: model.Direction, + Priority: utils.Int32(model.Priority), + Protocol: model.Protocol, + SourcePortRanges: &model.SourcePortRanges, + Sources: expandAddressPrefixItemModel(model.Sources), + }, + } + + if model.Description != "" { + rule.AdminPropertiesFormat.Description = &model.Description + } + + if _, err := client.CreateOrUpdate(ctx, *rule, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ManagerAdminRuleResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerAdminRulesClient + + id, err := parse.NetworkManagerAdminRuleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ManagerAdminRuleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + var rule *network.AdminRule + if adminRule, ok := existing.Value.AsAdminRule(); ok { + rule = adminRule + } + + properties := rule.AdminPropertiesFormat + if properties == nil { + return fmt.Errorf("retrieving %s: properties was nil", id) + } + + if metadata.ResourceData.HasChange("action") { + properties.Access = model.Action + } + + if metadata.ResourceData.HasChange("description") { + if model.Description != "" { + properties.Description = &model.Description + } else { + properties.Description = nil + } + } + + if metadata.ResourceData.HasChange("destination_port_ranges") { + properties.DestinationPortRanges = &model.DestinationPortRanges + } + + if metadata.ResourceData.HasChange("destination") { + properties.Destinations = expandAddressPrefixItemModel(model.Destinations) + } + + if metadata.ResourceData.HasChange("direction") { + properties.Direction = model.Direction + } + + if metadata.ResourceData.HasChange("priority") { + properties.Priority = utils.Int32(model.Priority) + } + + if metadata.ResourceData.HasChange("protocol") { + properties.Protocol = model.Protocol + } + + if metadata.ResourceData.HasChange("source_port_ranges") { + properties.SourcePortRanges = &model.SourcePortRanges + } + + if metadata.ResourceData.HasChange("source") { + properties.Sources = expandAddressPrefixItemModel(model.Sources) + } + + if _, err := client.CreateOrUpdate(ctx, rule, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName); err != nil { + return fmt.Errorf("updating %s: %+v", *id, err) + } + + return nil + }, + } +} + +func (r ManagerAdminRuleResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerAdminRulesClient + + id, err := parse.NetworkManagerAdminRuleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName) + if err != nil { + if utils.ResponseWasNotFound(existing.Response) { + return metadata.MarkAsGone(id) + } + + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + var rule *network.AdminRule + if adminRule, ok := existing.Value.AsAdminRule(); ok { + rule = adminRule + } + + properties := rule.AdminPropertiesFormat + if properties == nil { + return fmt.Errorf("retrieving %s: properties was nil", id) + } + + state := ManagerAdminRuleModel{ + Action: properties.Access, + Name: id.RuleName, + NetworkRuleCollectionId: parse.NewNetworkManagerAdminRuleCollectionID(id.SubscriptionId, id.ResourceGroup, + id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName).ID(), + Destinations: flattenAddressPrefixItemModel(properties.Destinations), + Direction: properties.Direction, + Protocol: properties.Protocol, + Sources: flattenAddressPrefixItemModel(properties.Sources), + } + + if properties.Description != nil { + state.Description = *properties.Description + } + + if properties.DestinationPortRanges != nil { + state.DestinationPortRanges = *properties.DestinationPortRanges + } + + state.Priority = 0 + if properties.Priority != nil { + state.Priority = *properties.Priority + } + + if properties.SourcePortRanges != nil { + state.SourcePortRanges = *properties.SourcePortRanges + } + + return metadata.Encode(&state) + }, + } +} + +func (r ManagerAdminRuleResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerAdminRulesClient + + id, err := parse.NetworkManagerAdminRuleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + future, err := client.Delete(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName, utils.Bool(true)) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("waiting for deletion of %s: %+v", *id, err) + } + + return nil + }, + } +} + +func expandAddressPrefixItemModel(inputList []AddressPrefixItemModel) *[]network.AddressPrefixItem { + var outputList []network.AddressPrefixItem + for _, v := range inputList { + input := v + output := network.AddressPrefixItem{ + AddressPrefixType: input.AddressPrefixType, + } + + if input.AddressPrefix != "" { + output.AddressPrefix = &input.AddressPrefix + } + + outputList = append(outputList, output) + } + + return &outputList +} + +func flattenAddressPrefixItemModel(inputList *[]network.AddressPrefixItem) []AddressPrefixItemModel { + var outputList []AddressPrefixItemModel + if inputList == nil { + return outputList + } + + for _, input := range *inputList { + output := AddressPrefixItemModel{ + AddressPrefixType: input.AddressPrefixType, + } + + if input.AddressPrefix != nil { + output.AddressPrefix = *input.AddressPrefix + } + + outputList = append(outputList, output) + } + + return outputList +} diff --git a/internal/services/network/network_manager_admin_rule_resource_test.go b/internal/services/network/network_manager_admin_rule_resource_test.go new file mode 100644 index 000000000000..dce93f9cc5e7 --- /dev/null +++ b/internal/services/network/network_manager_admin_rule_resource_test.go @@ -0,0 +1,236 @@ +package network_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type ManagerAdminRuleResource struct{} + +func testAccNetworkManagerAdminRule_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule", "test") + r := ManagerAdminRuleResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func testAccNetworkManagerAdminRule_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule", "test") + r := ManagerAdminRuleResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} + +func testAccNetworkManagerAdminRule_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule", "test") + r := ManagerAdminRuleResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func testAccNetworkManagerAdminRule_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_admin_rule", "test") + r := ManagerAdminRuleResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r ManagerAdminRuleResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.NetworkManagerAdminRuleID(state.ID) + if err != nil { + return nil, err + } + + client := clients.Network.ManagerAdminRulesClient + resp, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + _, ok := resp.Value.AsAdminRule() + return utils.Bool(ok), nil +} + +func (r ManagerAdminRuleResource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-network-manager-%d" + location = "%s" +} + +data "azurerm_subscription" "current" { +} + +resource "azurerm_network_manager" "test" { + name = "acctest-nm-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + scope { + subscription_ids = [data.azurerm_subscription.current.id] + } + scope_accesses = ["SecurityAdmin"] +} + +resource "azurerm_network_manager_network_group" "test" { + name = "acctest-nmng-%d" + network_manager_id = azurerm_network_manager.test.id +} + +resource "azurerm_network_manager_security_admin_configuration" "test" { + name = "acctest-nmsac-%d" + network_manager_id = azurerm_network_manager.test.id +} + +resource "azurerm_network_manager_admin_rule_collection" "test" { + name = "acctest-nmarc-%d" + security_admin_configuration_id = azurerm_network_manager_security_admin_configuration.test.id + network_group_ids = [azurerm_network_manager_network_group.test.id] +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) +} + +func (r ManagerAdminRuleResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` + %s + +resource "azurerm_network_manager_admin_rule" "test" { + name = "acctest-nmar-%d" + admin_rule_collection_id = azurerm_network_manager_admin_rule_collection.test.id + action = "Deny" + direction = "Outbound" + protocol = "Tcp" + priority = 1 +} +`, template, data.RandomInteger) +} + +func (r ManagerAdminRuleResource) requiresImport(data acceptance.TestData) string { + config := r.basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_admin_rule" "import" { + name = azurerm_network_manager_admin_rule.test.name + admin_rule_collection_id = azurerm_network_manager_admin_rule.test.admin_rule_collection_id + action = azurerm_network_manager_admin_rule.test.action + direction = azurerm_network_manager_admin_rule.test.direction + priority = azurerm_network_manager_admin_rule.test.priority + protocol = azurerm_network_manager_admin_rule.test.protocol +} +`, config) +} + +func (r ManagerAdminRuleResource) complete(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_admin_rule" "test" { + name = "acctest-nmar-%d" + admin_rule_collection_id = azurerm_network_manager_admin_rule_collection.test.id + action = "Deny" + description = "test admin rule" + direction = "Outbound" + priority = 1 + protocol = "Tcp" + source_port_ranges = ["80", "22", "443"] + destination_port_ranges = ["80", "22"] + source { + address_prefix_type = "ServiceTag" + address_prefix = "Internet" + } + destination { + address_prefix_type = "IPPrefix" + address_prefix = "*" + } +} +`, template, data.RandomInteger) +} + +func (r ManagerAdminRuleResource) update(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_admin_rule" "test" { + name = "acctest-nmar-%d" + admin_rule_collection_id = azurerm_network_manager_admin_rule_collection.test.id + action = "Allow" + description = "test" + direction = "Inbound" + priority = 1234 + protocol = "Ah" + source_port_ranges = ["80", "1024-65535"] + destination_port_ranges = ["80"] + source { + address_prefix_type = "ServiceTag" + address_prefix = "ActionGroup" + } + destination { + address_prefix_type = "IPPrefix" + address_prefix = "10.1.0.1" + } + destination { + address_prefix_type = "IPPrefix" + address_prefix = "10.0.0.0/24" + } +} +`, template, data.RandomInteger) +} diff --git a/internal/services/network/network_manager_connectivity_configuration_resource_test.go b/internal/services/network/network_manager_connectivity_configuration_resource_test.go index df9f538e9b60..4c0e744eb8b2 100644 --- a/internal/services/network/network_manager_connectivity_configuration_resource_test.go +++ b/internal/services/network/network_manager_connectivity_configuration_resource_test.go @@ -123,7 +123,7 @@ provider "azurerm" { } resource "azurerm_resource_group" "test" { - name = "acctest-nmng-%d" + name = "acctestRG-network-manager-%d" location = "%s" } diff --git a/internal/services/network/network_manager_management_group_connection_resource_test.go b/internal/services/network/network_manager_management_group_connection_resource_test.go index a725d774da63..e57944bebc8a 100644 --- a/internal/services/network/network_manager_management_group_connection_resource_test.go +++ b/internal/services/network/network_manager_management_group_connection_resource_test.go @@ -111,7 +111,7 @@ resource "azurerm_management_group_subscription_association" "test" { } resource "azurerm_resource_group" "test" { - name = "acctestRG-nm-%d" + name = "acctestRG-network-manager-%d" location = "%s" } @@ -147,7 +147,7 @@ resource "azurerm_network_manager" "test" { func (r ManagerManagementGroupConnectionResource) basic(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_management_group_connection" "test" { name = "acctest-nmmgc-%d" @@ -160,7 +160,7 @@ resource "azurerm_network_manager_management_group_connection" "test" { func (r ManagerManagementGroupConnectionResource) requiresImport(data acceptance.TestData) string { config := r.basic(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_management_group_connection" "import" { name = azurerm_network_manager_management_group_connection.test.name @@ -173,7 +173,7 @@ resource "azurerm_network_manager_management_group_connection" "import" { func (r ManagerManagementGroupConnectionResource) complete(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_management_group_connection" "test" { name = "acctest-nmmgc-%d" @@ -187,7 +187,7 @@ resource "azurerm_network_manager_management_group_connection" "test" { func (r ManagerManagementGroupConnectionResource) update(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_management_group_connection" "test" { name = "acctest-nmmgc-%d" diff --git a/internal/services/network/network_manager_network_group_resource_test.go b/internal/services/network/network_manager_network_group_resource_test.go index 118b2cede0a0..5dce4983b672 100644 --- a/internal/services/network/network_manager_network_group_resource_test.go +++ b/internal/services/network/network_manager_network_group_resource_test.go @@ -101,7 +101,7 @@ provider "azurerm" { features {} } resource "azurerm_resource_group" "test" { - name = "acctest-nmng-%d" + name = "acctestRG-network-manager-%d" location = "%s" } data "azurerm_subscription" "current" { diff --git a/internal/services/network/network_manager_resource_test.go b/internal/services/network/network_manager_resource_test.go index 6f8096c90174..4a412211d6a9 100644 --- a/internal/services/network/network_manager_resource_test.go +++ b/internal/services/network/network_manager_resource_test.go @@ -62,6 +62,24 @@ func TestAccNetworkManager(t *testing.T) { "update": testAccNetworkManagerConnectivityConfiguration_update, "requiresImport": testAccNetworkManagerConnectivityConfiguration_requiresImport, }, + "SecurityAdminConfiguration": { + "basic": testAccNetworkManagerSecurityAdminConfiguration_basic, + "complete": testAccNetworkManagerSecurityAdminConfiguration_complete, + "update": testAccNetworkManagerSecurityAdminConfiguration_update, + "requiresImport": testAccNetworkManagerSecurityAdminConfiguration_requiresImport, + }, + "AdminRuleCollection": { + "basic": testAccNetworkManagerAdminRuleCollection_basic, + "complete": testAccNetworkManagerAdminRuleCollection_complete, + "update": testAccNetworkManagerAdminRuleCollection_update, + "requiresImport": testAccNetworkManagerAdminRuleCollection_requiresImport, + }, + "AdminRule": { + "basic": testAccNetworkManagerAdminRule_basic, + "complete": testAccNetworkManagerAdminRule_complete, + "update": testAccNetworkManagerAdminRule_update, + "requiresImport": testAccNetworkManagerAdminRule_requiresImport, + }, } for group, m := range testCases { diff --git a/internal/services/network/network_manager_scope_connection_resource_test.go b/internal/services/network/network_manager_scope_connection_resource_test.go index b4c92c5f4e34..6a5746c66162 100644 --- a/internal/services/network/network_manager_scope_connection_resource_test.go +++ b/internal/services/network/network_manager_scope_connection_resource_test.go @@ -102,7 +102,7 @@ provider "azurerm" { } resource "azurerm_resource_group" "test" { - name = "acctestRG-nm-%d" + name = "acctestRG-network-manager-%d" location = "%s" } @@ -127,7 +127,7 @@ resource "azurerm_network_manager" "test" { func (r ManagerScopeConnectionResource) basic(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_scope_connection" "test" { name = "acctest-nsc-%d" @@ -141,7 +141,7 @@ resource "azurerm_network_manager_scope_connection" "test" { func (r ManagerScopeConnectionResource) requiresImport(data acceptance.TestData) string { config := r.basic(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_scope_connection" "import" { name = azurerm_network_manager_scope_connection.test.name @@ -155,7 +155,7 @@ resource "azurerm_network_manager_scope_connection" "import" { func (r ManagerScopeConnectionResource) complete(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_scope_connection" "test" { name = "acctest-nsc-%d" @@ -170,7 +170,7 @@ resource "azurerm_network_manager_scope_connection" "test" { func (r ManagerScopeConnectionResource) update(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_scope_connection" "test" { name = "acctest-nsc-%d" diff --git a/internal/services/network/network_manager_security_admin_configuration_resource.go b/internal/services/network/network_manager_security_admin_configuration_resource.go new file mode 100644 index 000000000000..5d50e2592801 --- /dev/null +++ b/internal/services/network/network_manager_security_admin_configuration_resource.go @@ -0,0 +1,261 @@ +package network + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/utils" + "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" +) + +type ManagerSecurityAdminConfigurationModel struct { + Name string `tfschema:"name"` + NetworkManagerId string `tfschema:"network_manager_id"` + ApplyOnNetworkIntentPolicyBasedServices []string `tfschema:"apply_on_network_intent_policy_based_services"` + Description string `tfschema:"description"` +} + +type ManagerSecurityAdminConfigurationResource struct{} + +var _ sdk.ResourceWithUpdate = ManagerSecurityAdminConfigurationResource{} + +func (r ManagerSecurityAdminConfigurationResource) ResourceType() string { + return "azurerm_network_manager_security_admin_configuration" +} + +func (r ManagerSecurityAdminConfigurationResource) ModelObject() interface{} { + return &ManagerSecurityAdminConfigurationModel{} +} + +func (r ManagerSecurityAdminConfigurationResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return validate.NetworkManagerSecurityAdminConfigurationID +} + +func (r ManagerSecurityAdminConfigurationResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "network_manager_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.NetworkManagerID, + }, + + "apply_on_network_intent_policy_based_services": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(network.IntentPolicyBasedServiceNone), + string(network.IntentPolicyBasedServiceAllowRulesOnly), + string(network.IntentPolicyBasedServiceAll), + }, false), + }, + }, + + "description": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + } +} + +func (r ManagerSecurityAdminConfigurationResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ManagerSecurityAdminConfigurationResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var model ManagerSecurityAdminConfigurationModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + client := metadata.Client.Network.ManagerSecurityAdminConfigurationsClient + networkManagerId, err := parse.NetworkManagerID(model.NetworkManagerId) + if err != nil { + return err + } + + id := parse.NewNetworkManagerSecurityAdminConfigurationID(networkManagerId.SubscriptionId, networkManagerId.ResourceGroup, networkManagerId.Name, model.Name) + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName) + if err != nil && !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for existing %s: %+v", id, err) + } + + if !utils.ResponseWasNotFound(existing.Response) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + conf := &network.SecurityAdminConfiguration{ + SecurityAdminConfigurationPropertiesFormat: &network.SecurityAdminConfigurationPropertiesFormat{ + ApplyOnNetworkIntentPolicyBasedServices: expandNetworkIntentPolicyBasedServiceModel(model.ApplyOnNetworkIntentPolicyBasedServices), + }, + } + + if model.Description != "" { + conf.SecurityAdminConfigurationPropertiesFormat.Description = &model.Description + } + + if _, err := client.CreateOrUpdate(ctx, *conf, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ManagerSecurityAdminConfigurationResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerSecurityAdminConfigurationsClient + + id, err := parse.NetworkManagerSecurityAdminConfigurationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ManagerSecurityAdminConfigurationModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + if err != nil { + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + properties := existing.SecurityAdminConfigurationPropertiesFormat + if properties == nil { + return fmt.Errorf("retrieving %s: properties was nil", id) + } + + if metadata.ResourceData.HasChange("apply_on_network_intent_policy_based_services") { + properties.ApplyOnNetworkIntentPolicyBasedServices = expandNetworkIntentPolicyBasedServiceModel(model.ApplyOnNetworkIntentPolicyBasedServices) + } + + if metadata.ResourceData.HasChange("description") { + properties.Description = utils.String(model.Description) + } + + if _, err := client.CreateOrUpdate(ctx, existing, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName); err != nil { + return fmt.Errorf("updating %s: %+v", *id, err) + } + + return nil + }, + } +} + +func (r ManagerSecurityAdminConfigurationResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerSecurityAdminConfigurationsClient + + id, err := parse.NetworkManagerSecurityAdminConfigurationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + existing, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName) + if err != nil { + if utils.ResponseWasNotFound(existing.Response) { + return metadata.MarkAsGone(id) + } + + return fmt.Errorf("retrieving %s: %+v", *id, err) + } + + properties := existing.SecurityAdminConfigurationPropertiesFormat + if properties == nil { + return fmt.Errorf("retrieving %s: properties was nil", id) + } + + state := ManagerSecurityAdminConfigurationModel{ + Name: id.SecurityAdminConfigurationName, + NetworkManagerId: parse.NewNetworkManagerID(id.SubscriptionId, id.ResourceGroup, id.NetworkManagerName).ID(), + ApplyOnNetworkIntentPolicyBasedServices: flattenNetworkIntentPolicyBasedServiceModel(properties.ApplyOnNetworkIntentPolicyBasedServices), + } + + if properties.Description != nil { + state.Description = *properties.Description + } + + return metadata.Encode(&state) + }, + } +} + +func (r ManagerSecurityAdminConfigurationResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Network.ManagerSecurityAdminConfigurationsClient + + id, err := parse.NetworkManagerSecurityAdminConfigurationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + future, err := client.Delete(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, utils.Bool(true)) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("waiting for deletion of %s: %+v", *id, err) + } + + return nil + }, + } +} + +func expandNetworkIntentPolicyBasedServiceModel(inputList []string) *[]network.IntentPolicyBasedService { + var outputList []network.IntentPolicyBasedService + for _, input := range inputList { + output := network.IntentPolicyBasedService(input) + + outputList = append(outputList, output) + } + + return &outputList +} + +func flattenNetworkIntentPolicyBasedServiceModel(inputList *[]network.IntentPolicyBasedService) []string { + var outputList []string + if inputList == nil { + return outputList + } + + for _, input := range *inputList { + outputList = append(outputList, string(input)) + } + + return outputList +} diff --git a/internal/services/network/network_manager_security_admin_configuration_resource_test.go b/internal/services/network/network_manager_security_admin_configuration_resource_test.go new file mode 100644 index 000000000000..082687f48b3c --- /dev/null +++ b/internal/services/network/network_manager_security_admin_configuration_resource_test.go @@ -0,0 +1,195 @@ +package network_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type ManagerSecurityAdminConfigurationResource struct{} + +func testAccNetworkManagerSecurityAdminConfiguration_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_security_admin_configuration", "test") + r := ManagerSecurityAdminConfigurationResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func testAccNetworkManagerSecurityAdminConfiguration_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_security_admin_configuration", "test") + r := ManagerSecurityAdminConfigurationResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.RequiresImportErrorStep(r.requiresImport), + }) +} + +func testAccNetworkManagerSecurityAdminConfiguration_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_security_admin_configuration", "test") + r := ManagerSecurityAdminConfigurationResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func testAccNetworkManagerSecurityAdminConfiguration_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_network_manager_security_admin_configuration", "test") + r := ManagerSecurityAdminConfigurationResource{} + data.ResourceSequentialTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r ManagerSecurityAdminConfigurationResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.NetworkManagerSecurityAdminConfigurationID(state.ID) + if err != nil { + return nil, err + } + + client := clients.Network.ManagerSecurityAdminConfigurationsClient + resp, err := client.Get(ctx, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + return utils.Bool(resp.SecurityAdminConfigurationPropertiesFormat != nil), nil +} + +func (r ManagerSecurityAdminConfigurationResource) template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-network-manager-%d" + location = "%s" +} + +data "azurerm_subscription" "current" { +} + +resource "azurerm_network_manager" "test" { + name = "acctest-nm-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + scope { + subscription_ids = [data.azurerm_subscription.current.id] + } + scope_accesses = ["SecurityAdmin"] +} + +resource "azurerm_network_manager_network_group" "test" { + name = "acctest-nmng-%d" + network_manager_id = azurerm_network_manager.test.id +} + +resource "azurerm_virtual_network" "test" { + name = "acctest-vnet-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + address_space = ["10.0.0.0/16"] + flow_timeout_in_minutes = 10 +} + +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger) +} + +func (r ManagerSecurityAdminConfigurationResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_security_admin_configuration" "test" { + name = "acctest-nmsac-%d" + network_manager_id = azurerm_network_manager.test.id +} +`, template, data.RandomInteger) +} + +func (r ManagerSecurityAdminConfigurationResource) requiresImport(data acceptance.TestData) string { + config := r.basic(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_security_admin_configuration" "import" { + name = azurerm_network_manager_security_admin_configuration.test.name + network_manager_id = azurerm_network_manager_security_admin_configuration.test.network_manager_id +} +`, config) +} + +func (r ManagerSecurityAdminConfigurationResource) complete(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_security_admin_configuration" "test" { + name = "acctest-nmsac-%d" + network_manager_id = azurerm_network_manager.test.id + description = "test" + apply_on_network_intent_policy_based_services = ["None"] +} +`, template, data.RandomInteger) +} + +func (r ManagerSecurityAdminConfigurationResource) update(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_network_manager_security_admin_configuration" "test" { + name = "acctest-nmsac-%d" + network_manager_id = azurerm_network_manager.test.id + description = "update" + apply_on_network_intent_policy_based_services = ["AllowRulesOnly"] +} +`, template, data.RandomInteger) +} diff --git a/internal/services/network/network_manager_static_member_resource_test.go b/internal/services/network/network_manager_static_member_resource_test.go index bf3c3b4a4f5e..371261313b8c 100644 --- a/internal/services/network/network_manager_static_member_resource_test.go +++ b/internal/services/network/network_manager_static_member_resource_test.go @@ -67,7 +67,7 @@ provider "azurerm" { } resource "azurerm_resource_group" "test" { - name = "acctest-rg-network-manager-%d" + name = "acctestRG-network-manager-%d" location = "%s" } diff --git a/internal/services/network/network_manager_subscription_connection_resource_test.go b/internal/services/network/network_manager_subscription_connection_resource_test.go index fc5a6607bc4c..2eedf7da8c9b 100644 --- a/internal/services/network/network_manager_subscription_connection_resource_test.go +++ b/internal/services/network/network_manager_subscription_connection_resource_test.go @@ -102,7 +102,7 @@ provider "azurerm" { } resource "azurerm_resource_group" "test" { - name = "acctestRG-nm-%d" + name = "acctestRG-network-manager-%d" location = "%s" } @@ -124,7 +124,7 @@ resource "azurerm_network_manager" "test" { func (r ManagerSubscriptionConnectionResource) basic(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_subscription_connection" "test" { name = "acctest-nmsc-%d" @@ -137,7 +137,7 @@ resource "azurerm_network_manager_subscription_connection" "test" { func (r ManagerSubscriptionConnectionResource) requiresImport(data acceptance.TestData) string { config := r.basic(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_subscription_connection" "import" { name = "acctest-nmsc-%d" @@ -150,7 +150,7 @@ resource "azurerm_network_manager_subscription_connection" "import" { func (r ManagerSubscriptionConnectionResource) complete(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_subscription_connection" "test" { name = "acctest-nmsc-%d" @@ -164,7 +164,7 @@ resource "azurerm_network_manager_subscription_connection" "test" { func (r ManagerSubscriptionConnectionResource) update(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` - %s +%s resource "azurerm_network_manager_subscription_connection" "test" { name = "acctest-nmsc-%d" diff --git a/internal/services/network/parse/network_manager_admin_rule.go b/internal/services/network/parse/network_manager_admin_rule.go new file mode 100644 index 000000000000..f2ecb27c4ee1 --- /dev/null +++ b/internal/services/network/parse/network_manager_admin_rule.go @@ -0,0 +1,87 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type NetworkManagerAdminRuleId struct { + SubscriptionId string + ResourceGroup string + NetworkManagerName string + SecurityAdminConfigurationName string + RuleCollectionName string + RuleName string +} + +func NewNetworkManagerAdminRuleID(subscriptionId, resourceGroup, networkManagerName, securityAdminConfigurationName, ruleCollectionName, ruleName string) NetworkManagerAdminRuleId { + return NetworkManagerAdminRuleId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + NetworkManagerName: networkManagerName, + SecurityAdminConfigurationName: securityAdminConfigurationName, + RuleCollectionName: ruleCollectionName, + RuleName: ruleName, + } +} + +func (id NetworkManagerAdminRuleId) String() string { + segments := []string{ + fmt.Sprintf("Rule Name %q", id.RuleName), + fmt.Sprintf("Rule Collection Name %q", id.RuleCollectionName), + fmt.Sprintf("Security Admin Configuration Name %q", id.SecurityAdminConfigurationName), + fmt.Sprintf("Network Manager Name %q", id.NetworkManagerName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Network Manager Admin Rule", segmentsStr) +} + +func (id NetworkManagerAdminRuleId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkManagers/%s/securityAdminConfigurations/%s/ruleCollections/%s/rules/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName, id.RuleName) +} + +// NetworkManagerAdminRuleID parses a NetworkManagerAdminRule ID into an NetworkManagerAdminRuleId struct +func NetworkManagerAdminRuleID(input string) (*NetworkManagerAdminRuleId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := NetworkManagerAdminRuleId{ + SubscriptionId: id.SubscriptionID, + ResourceGroup: id.ResourceGroup, + } + + if resourceId.SubscriptionId == "" { + return nil, fmt.Errorf("ID was missing the 'subscriptions' element") + } + + if resourceId.ResourceGroup == "" { + return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") + } + + if resourceId.NetworkManagerName, err = id.PopSegment("networkManagers"); err != nil { + return nil, err + } + if resourceId.SecurityAdminConfigurationName, err = id.PopSegment("securityAdminConfigurations"); err != nil { + return nil, err + } + if resourceId.RuleCollectionName, err = id.PopSegment("ruleCollections"); err != nil { + return nil, err + } + if resourceId.RuleName, err = id.PopSegment("rules"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/network/parse/network_manager_admin_rule_collection.go b/internal/services/network/parse/network_manager_admin_rule_collection.go new file mode 100644 index 000000000000..a4836b176340 --- /dev/null +++ b/internal/services/network/parse/network_manager_admin_rule_collection.go @@ -0,0 +1,81 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type NetworkManagerAdminRuleCollectionId struct { + SubscriptionId string + ResourceGroup string + NetworkManagerName string + SecurityAdminConfigurationName string + RuleCollectionName string +} + +func NewNetworkManagerAdminRuleCollectionID(subscriptionId, resourceGroup, networkManagerName, securityAdminConfigurationName, ruleCollectionName string) NetworkManagerAdminRuleCollectionId { + return NetworkManagerAdminRuleCollectionId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + NetworkManagerName: networkManagerName, + SecurityAdminConfigurationName: securityAdminConfigurationName, + RuleCollectionName: ruleCollectionName, + } +} + +func (id NetworkManagerAdminRuleCollectionId) String() string { + segments := []string{ + fmt.Sprintf("Rule Collection Name %q", id.RuleCollectionName), + fmt.Sprintf("Security Admin Configuration Name %q", id.SecurityAdminConfigurationName), + fmt.Sprintf("Network Manager Name %q", id.NetworkManagerName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Network Manager Admin Rule Collection", segmentsStr) +} + +func (id NetworkManagerAdminRuleCollectionId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkManagers/%s/securityAdminConfigurations/%s/ruleCollections/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName, id.RuleCollectionName) +} + +// NetworkManagerAdminRuleCollectionID parses a NetworkManagerAdminRuleCollection ID into an NetworkManagerAdminRuleCollectionId struct +func NetworkManagerAdminRuleCollectionID(input string) (*NetworkManagerAdminRuleCollectionId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := NetworkManagerAdminRuleCollectionId{ + SubscriptionId: id.SubscriptionID, + ResourceGroup: id.ResourceGroup, + } + + if resourceId.SubscriptionId == "" { + return nil, fmt.Errorf("ID was missing the 'subscriptions' element") + } + + if resourceId.ResourceGroup == "" { + return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") + } + + if resourceId.NetworkManagerName, err = id.PopSegment("networkManagers"); err != nil { + return nil, err + } + if resourceId.SecurityAdminConfigurationName, err = id.PopSegment("securityAdminConfigurations"); err != nil { + return nil, err + } + if resourceId.RuleCollectionName, err = id.PopSegment("ruleCollections"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/network/parse/network_manager_admin_rule_collection_test.go b/internal/services/network/parse/network_manager_admin_rule_collection_test.go new file mode 100644 index 000000000000..6760d30afb7d --- /dev/null +++ b/internal/services/network/parse/network_manager_admin_rule_collection_test.go @@ -0,0 +1,144 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.Id = NetworkManagerAdminRuleCollectionId{} + +func TestNetworkManagerAdminRuleCollectionIDFormatter(t *testing.T) { + actual := NewNetworkManagerAdminRuleCollectionID("12345678-1234-9876-4563-123456789012", "resGroup1", "manager1", "conf1", "collection1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestNetworkManagerAdminRuleCollectionID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *NetworkManagerAdminRuleCollectionId + }{ + + { + // empty + Input: "", + Error: true, + }, + + { + // missing SubscriptionId + Input: "/", + Error: true, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Error: true, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Error: true, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Error: true, + }, + + { + // missing NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/", + Error: true, + }, + + { + // missing value for NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/", + Error: true, + }, + + { + // missing SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/", + Error: true, + }, + + { + // missing value for SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/", + Error: true, + }, + + { + // missing RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/", + Error: true, + }, + + { + // missing value for RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1", + Expected: &NetworkManagerAdminRuleCollectionId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resGroup1", + NetworkManagerName: "manager1", + SecurityAdminConfigurationName: "conf1", + RuleCollectionName: "collection1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.NETWORK/NETWORKMANAGERS/MANAGER1/SECURITYADMINCONFIGURATIONS/CONF1/RULECOLLECTIONS/COLLECTION1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := NetworkManagerAdminRuleCollectionID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %s", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + if actual.NetworkManagerName != v.Expected.NetworkManagerName { + t.Fatalf("Expected %q but got %q for NetworkManagerName", v.Expected.NetworkManagerName, actual.NetworkManagerName) + } + if actual.SecurityAdminConfigurationName != v.Expected.SecurityAdminConfigurationName { + t.Fatalf("Expected %q but got %q for SecurityAdminConfigurationName", v.Expected.SecurityAdminConfigurationName, actual.SecurityAdminConfigurationName) + } + if actual.RuleCollectionName != v.Expected.RuleCollectionName { + t.Fatalf("Expected %q but got %q for RuleCollectionName", v.Expected.RuleCollectionName, actual.RuleCollectionName) + } + } +} diff --git a/internal/services/network/parse/network_manager_admin_rule_test.go b/internal/services/network/parse/network_manager_admin_rule_test.go new file mode 100644 index 000000000000..0c52797d4fc0 --- /dev/null +++ b/internal/services/network/parse/network_manager_admin_rule_test.go @@ -0,0 +1,160 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.Id = NetworkManagerAdminRuleId{} + +func TestNetworkManagerAdminRuleIDFormatter(t *testing.T) { + actual := NewNetworkManagerAdminRuleID("12345678-1234-9876-4563-123456789012", "resGroup1", "manager1", "conf1", "collection1", "rule1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/rules/rule1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestNetworkManagerAdminRuleID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *NetworkManagerAdminRuleId + }{ + + { + // empty + Input: "", + Error: true, + }, + + { + // missing SubscriptionId + Input: "/", + Error: true, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Error: true, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Error: true, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Error: true, + }, + + { + // missing NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/", + Error: true, + }, + + { + // missing value for NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/", + Error: true, + }, + + { + // missing SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/", + Error: true, + }, + + { + // missing value for SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/", + Error: true, + }, + + { + // missing RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/", + Error: true, + }, + + { + // missing value for RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/", + Error: true, + }, + + { + // missing RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/", + Error: true, + }, + + { + // missing value for RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/rules/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/rules/rule1", + Expected: &NetworkManagerAdminRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resGroup1", + NetworkManagerName: "manager1", + SecurityAdminConfigurationName: "conf1", + RuleCollectionName: "collection1", + RuleName: "rule1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.NETWORK/NETWORKMANAGERS/MANAGER1/SECURITYADMINCONFIGURATIONS/CONF1/RULECOLLECTIONS/COLLECTION1/RULES/RULE1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := NetworkManagerAdminRuleID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %s", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + if actual.NetworkManagerName != v.Expected.NetworkManagerName { + t.Fatalf("Expected %q but got %q for NetworkManagerName", v.Expected.NetworkManagerName, actual.NetworkManagerName) + } + if actual.SecurityAdminConfigurationName != v.Expected.SecurityAdminConfigurationName { + t.Fatalf("Expected %q but got %q for SecurityAdminConfigurationName", v.Expected.SecurityAdminConfigurationName, actual.SecurityAdminConfigurationName) + } + if actual.RuleCollectionName != v.Expected.RuleCollectionName { + t.Fatalf("Expected %q but got %q for RuleCollectionName", v.Expected.RuleCollectionName, actual.RuleCollectionName) + } + if actual.RuleName != v.Expected.RuleName { + t.Fatalf("Expected %q but got %q for RuleName", v.Expected.RuleName, actual.RuleName) + } + } +} diff --git a/internal/services/network/parse/network_manager_security_admin_configuration.go b/internal/services/network/parse/network_manager_security_admin_configuration.go new file mode 100644 index 000000000000..1266f3768e29 --- /dev/null +++ b/internal/services/network/parse/network_manager_security_admin_configuration.go @@ -0,0 +1,75 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type NetworkManagerSecurityAdminConfigurationId struct { + SubscriptionId string + ResourceGroup string + NetworkManagerName string + SecurityAdminConfigurationName string +} + +func NewNetworkManagerSecurityAdminConfigurationID(subscriptionId, resourceGroup, networkManagerName, securityAdminConfigurationName string) NetworkManagerSecurityAdminConfigurationId { + return NetworkManagerSecurityAdminConfigurationId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + NetworkManagerName: networkManagerName, + SecurityAdminConfigurationName: securityAdminConfigurationName, + } +} + +func (id NetworkManagerSecurityAdminConfigurationId) String() string { + segments := []string{ + fmt.Sprintf("Security Admin Configuration Name %q", id.SecurityAdminConfigurationName), + fmt.Sprintf("Network Manager Name %q", id.NetworkManagerName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Network Manager Security Admin Configuration", segmentsStr) +} + +func (id NetworkManagerSecurityAdminConfigurationId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkManagers/%s/securityAdminConfigurations/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.NetworkManagerName, id.SecurityAdminConfigurationName) +} + +// NetworkManagerSecurityAdminConfigurationID parses a NetworkManagerSecurityAdminConfiguration ID into an NetworkManagerSecurityAdminConfigurationId struct +func NetworkManagerSecurityAdminConfigurationID(input string) (*NetworkManagerSecurityAdminConfigurationId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := NetworkManagerSecurityAdminConfigurationId{ + SubscriptionId: id.SubscriptionID, + ResourceGroup: id.ResourceGroup, + } + + if resourceId.SubscriptionId == "" { + return nil, fmt.Errorf("ID was missing the 'subscriptions' element") + } + + if resourceId.ResourceGroup == "" { + return nil, fmt.Errorf("ID was missing the 'resourceGroups' element") + } + + if resourceId.NetworkManagerName, err = id.PopSegment("networkManagers"); err != nil { + return nil, err + } + if resourceId.SecurityAdminConfigurationName, err = id.PopSegment("securityAdminConfigurations"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/network/parse/network_manager_security_admin_configuration_test.go b/internal/services/network/parse/network_manager_security_admin_configuration_test.go new file mode 100644 index 000000000000..f4185dbeb511 --- /dev/null +++ b/internal/services/network/parse/network_manager_security_admin_configuration_test.go @@ -0,0 +1,128 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.Id = NetworkManagerSecurityAdminConfigurationId{} + +func TestNetworkManagerSecurityAdminConfigurationIDFormatter(t *testing.T) { + actual := NewNetworkManagerSecurityAdminConfigurationID("12345678-1234-9876-4563-123456789012", "resGroup1", "manager1", "conf1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestNetworkManagerSecurityAdminConfigurationID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *NetworkManagerSecurityAdminConfigurationId + }{ + + { + // empty + Input: "", + Error: true, + }, + + { + // missing SubscriptionId + Input: "/", + Error: true, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Error: true, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Error: true, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Error: true, + }, + + { + // missing NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/", + Error: true, + }, + + { + // missing value for NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/", + Error: true, + }, + + { + // missing SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/", + Error: true, + }, + + { + // missing value for SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1", + Expected: &NetworkManagerSecurityAdminConfigurationId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resGroup1", + NetworkManagerName: "manager1", + SecurityAdminConfigurationName: "conf1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.NETWORK/NETWORKMANAGERS/MANAGER1/SECURITYADMINCONFIGURATIONS/CONF1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := NetworkManagerSecurityAdminConfigurationID(v.Input) + if err != nil { + if v.Error { + continue + } + + t.Fatalf("Expect a value but got an error: %s", err) + } + if v.Error { + t.Fatal("Expect an error but didn't get one") + } + + if actual.SubscriptionId != v.Expected.SubscriptionId { + t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId) + } + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + if actual.NetworkManagerName != v.Expected.NetworkManagerName { + t.Fatalf("Expected %q but got %q for NetworkManagerName", v.Expected.NetworkManagerName, actual.NetworkManagerName) + } + if actual.SecurityAdminConfigurationName != v.Expected.SecurityAdminConfigurationName { + t.Fatalf("Expected %q but got %q for SecurityAdminConfigurationName", v.Expected.SecurityAdminConfigurationName, actual.SecurityAdminConfigurationName) + } + } +} diff --git a/internal/services/network/registration.go b/internal/services/network/registration.go index 5bb6f9709176..8e749389dcd7 100644 --- a/internal/services/network/registration.go +++ b/internal/services/network/registration.go @@ -34,11 +34,14 @@ func (r Registration) DataSources() []sdk.DataSource { func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ + ManagerAdminRuleResource{}, + ManagerAdminRuleCollectionResource{}, ManagerConnectivityConfigurationResource{}, ManagerManagementGroupConnectionResource{}, ManagerNetworkGroupResource{}, ManagerResource{}, ManagerScopeConnectionResource{}, + ManagerSecurityAdminConfigurationResource{}, ManagerStaticMemberResource{}, ManagerSubscriptionConnectionResource{}, PrivateEndpointApplicationSecurityGroupAssociationResource{}, diff --git a/internal/services/network/resourceids.go b/internal/services/network/resourceids.go index d7fd0f93afe6..f0ef0dc6b7bf 100644 --- a/internal/services/network/resourceids.go +++ b/internal/services/network/resourceids.go @@ -113,8 +113,11 @@ package network // Network Manager //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManager -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerAdminRule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/rules/rule1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerAdminRuleCollection -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerConnectivityConfiguration -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/connectivityConfigurations/conf1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerNetworkGroup -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/networkGroups/group1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerScopeConnection -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/scopeConnections/connection1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerSecurityAdminConfiguration -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerStaticMember -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/networkGroups/group1/staticMembers/member1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=NetworkManagerSubscriptionConnection -id=/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.Network/networkManagerConnections/connection1 diff --git a/internal/services/network/validate/network_manager_admin_rule_collection_id.go b/internal/services/network/validate/network_manager_admin_rule_collection_id.go new file mode 100644 index 000000000000..1746039b3c1c --- /dev/null +++ b/internal/services/network/validate/network_manager_admin_rule_collection_id.go @@ -0,0 +1,23 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" +) + +func NetworkManagerAdminRuleCollectionID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := parse.NetworkManagerAdminRuleCollectionID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/network/validate/network_manager_admin_rule_collection_id_test.go b/internal/services/network/validate/network_manager_admin_rule_collection_id_test.go new file mode 100644 index 000000000000..4e97570b9539 --- /dev/null +++ b/internal/services/network/validate/network_manager_admin_rule_collection_id_test.go @@ -0,0 +1,100 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestNetworkManagerAdminRuleCollectionID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + + { + // empty + Input: "", + Valid: false, + }, + + { + // missing SubscriptionId + Input: "/", + Valid: false, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Valid: false, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Valid: false, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Valid: false, + }, + + { + // missing NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/", + Valid: false, + }, + + { + // missing value for NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/", + Valid: false, + }, + + { + // missing SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/", + Valid: false, + }, + + { + // missing value for SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/", + Valid: false, + }, + + { + // missing RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/", + Valid: false, + }, + + { + // missing value for RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.NETWORK/NETWORKMANAGERS/MANAGER1/SECURITYADMINCONFIGURATIONS/CONF1/RULECOLLECTIONS/COLLECTION1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := NetworkManagerAdminRuleCollectionID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/internal/services/network/validate/network_manager_admin_rule_id.go b/internal/services/network/validate/network_manager_admin_rule_id.go new file mode 100644 index 000000000000..a799c9c5f16c --- /dev/null +++ b/internal/services/network/validate/network_manager_admin_rule_id.go @@ -0,0 +1,23 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" +) + +func NetworkManagerAdminRuleID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := parse.NetworkManagerAdminRuleID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/network/validate/network_manager_admin_rule_id_test.go b/internal/services/network/validate/network_manager_admin_rule_id_test.go new file mode 100644 index 000000000000..c9671a6810bd --- /dev/null +++ b/internal/services/network/validate/network_manager_admin_rule_id_test.go @@ -0,0 +1,112 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestNetworkManagerAdminRuleID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + + { + // empty + Input: "", + Valid: false, + }, + + { + // missing SubscriptionId + Input: "/", + Valid: false, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Valid: false, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Valid: false, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Valid: false, + }, + + { + // missing NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/", + Valid: false, + }, + + { + // missing value for NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/", + Valid: false, + }, + + { + // missing SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/", + Valid: false, + }, + + { + // missing value for SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/", + Valid: false, + }, + + { + // missing RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/", + Valid: false, + }, + + { + // missing value for RuleCollectionName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/", + Valid: false, + }, + + { + // missing RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/", + Valid: false, + }, + + { + // missing value for RuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/rules/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1/ruleCollections/collection1/rules/rule1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.NETWORK/NETWORKMANAGERS/MANAGER1/SECURITYADMINCONFIGURATIONS/CONF1/RULECOLLECTIONS/COLLECTION1/RULES/RULE1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := NetworkManagerAdminRuleID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/internal/services/network/validate/network_manager_security_admin_configuration_id.go b/internal/services/network/validate/network_manager_security_admin_configuration_id.go new file mode 100644 index 000000000000..38e333261729 --- /dev/null +++ b/internal/services/network/validate/network_manager_security_admin_configuration_id.go @@ -0,0 +1,23 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/internal/services/network/parse" +) + +func NetworkManagerSecurityAdminConfigurationID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := parse.NetworkManagerSecurityAdminConfigurationID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/network/validate/network_manager_security_admin_configuration_id_test.go b/internal/services/network/validate/network_manager_security_admin_configuration_id_test.go new file mode 100644 index 000000000000..fd075b0364a3 --- /dev/null +++ b/internal/services/network/validate/network_manager_security_admin_configuration_id_test.go @@ -0,0 +1,88 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestNetworkManagerSecurityAdminConfigurationID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + + { + // empty + Input: "", + Valid: false, + }, + + { + // missing SubscriptionId + Input: "/", + Valid: false, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Valid: false, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Valid: false, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Valid: false, + }, + + { + // missing NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/", + Valid: false, + }, + + { + // missing value for NetworkManagerName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/", + Valid: false, + }, + + { + // missing SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/", + Valid: false, + }, + + { + // missing value for SecurityAdminConfigurationName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.Network/networkManagers/manager1/securityAdminConfigurations/conf1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.NETWORK/NETWORKMANAGERS/MANAGER1/SECURITYADMINCONFIGURATIONS/CONF1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := NetworkManagerSecurityAdminConfigurationID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/website/docs/r/network_manager_admin_rule.html.markdown b/website/docs/r/network_manager_admin_rule.html.markdown new file mode 100644 index 000000000000..c9e73be5e5b7 --- /dev/null +++ b/website/docs/r/network_manager_admin_rule.html.markdown @@ -0,0 +1,139 @@ +--- +subcategory: "Network" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_network_manager_admin_rule" +description: |- + Manages a Network Manager Admin Rule. +--- + +# azurerm_network_manager_admin_rule + +Manages a Network Manager Admin Rule. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +data "azurerm_subscription" "current" { +} + +resource "azurerm_network_manager" "example" { + name = "example-network-manager" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + scope { + subscription_ids = [data.azurerm_subscription.current.id] + } + scope_accesses = ["Connectivity", "SecurityAdmin"] + description = "example network manager" +} + +resource "azurerm_network_manager_network_group" "example" { + name = "example-network-group" + network_manager_id = azurerm_network_manager.example.id +} + +resource "azurerm_network_manager_security_admin_configuration" "example" { + name = "example-admin-conf" + network_manager_id = azurerm_network_manager.example.id +} + +resource "azurerm_network_manager_admin_rule_collection" "example" { + name = "example-admin-rule-collection" + security_admin_configuration_id = azurerm_network_manager_security_admin_configuration.example.id + network_group_ids = [azurerm_network_manager_network_group.example.id] +} + +resource "azurerm_network_manager_admin_rule" "example" { + name = "example-admin-rule" + admin_rule_collection_id = azurerm_network_manager_admin_rule_collection.example.id + action = "Deny" + direction = "Outbound" + priority = 1 + protocol = "Tcp" + source_port_ranges = ["80", "1024-65535"] + destination_port_ranges = ["80"] + source { + address_prefix_type = "ServiceTag" + address_prefix = "Internet" + } + destination { + address_prefix_type = "IPPrefix" + address_prefix = "10.1.0.1" + } + destination { + address_prefix_type = "IPPrefix" + address_prefix = "10.0.0.0/24" + } + description = "example admin rule" +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name which should be used for this Network Manager Admin Rule. Changing this forces a new Network Manager Admin Rule to be created. + +* `admin_rule_collection_id` - (Required) Specifies the ID of the Network Manager Admin Rule Collection. Changing this forces a new Network Manager Admin Rule to be created. + +* `action` - (Required) Specifies the action allowed for this Network Manager Admin Rule. Possible values are `Allow`, `AlwaysAllow`, and `Deny`. + +* `direction` - (Required) Indicates if the traffic matched against the rule in inbound or outbound. Possible values are `Inbound` and `Outbound`. + +* `priority` - (Required) The priority of the rule. Possible values are integers between `1` and `4096`. The priority number must be unique for each rule in the collection. The lower the priority number, the higher the priority of the rule. + +* `protocol` - (Required) Specifies which network protocol this Network Manager Admin Rule applies to. Possible values are `Ah`, `Any`, `Esp`, `Icmp`, `Tcp`, and `Udp`. + +* `description` - (Optional) A description of the Network Manager Admin Rule. + +* `destination_port_ranges` - (Optional) A list of string specifies the destination port ranges. Specify one or more single port number or port ranges such as `1024-65535`. Use `*` to specify any port. + +* `destination` - (Optional) One or more `destination` blocks as defined below. + +* `source_port_ranges` - (Optional) A list of string specifies the source port ranges. Specify one or more single port number or port ranges such as `1024-65535`. Use `*` to specify any port. + +* `source` - (Optional) One or more `source` blocks as defined below. + +--- + +A `destination` block supports the following: + +* `address_prefix` (Required) Specifies the address prefix. + +* `address_prefix_type` (Required) Specifies the address prefix type. Possible values are `IPPrefix` and `ServiceTag`. For more information, please see [this document](https://learn.microsoft.com/en-us/azure/virtual-network-manager/concept-security-admins#source-and-destination-types). + +--- + +A `source` block supports the following: + +* `address_prefix` (Required) Specifies the address prefix. + +* `address_prefix_type` (Required) Specifies the address prefix type. Possible values are `IPPrefix` and `ServiceTag`. For more information, please see [this document](https://learn.microsoft.com/en-us/azure/virtual-network-manager/concept-security-admins#source-and-destination-types). + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Network Manager Admin Rule. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Network Manager Admin Rule. +* `read` - (Defaults to 5 minutes) Used when retrieving the Network Manager Admin Rule. +* `update` - (Defaults to 30 minutes) Used when updating the Network Manager Admin Rule. +* `delete` - (Defaults to 30 minutes) Used when deleting the Network Manager Admin Rule. + +## Import + +Network Manager Admin Rule can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_network_manager_admin_rule.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Network/networkManagers/networkManager1/securityAdminConfigurations/configuration1/ruleCollections/ruleCollection1/rules/rule1 +``` diff --git a/website/docs/r/network_manager_admin_rule_collection.html.markdown b/website/docs/r/network_manager_admin_rule_collection.html.markdown new file mode 100644 index 000000000000..72e7b1d1b9ba --- /dev/null +++ b/website/docs/r/network_manager_admin_rule_collection.html.markdown @@ -0,0 +1,85 @@ +--- +subcategory: "Network" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_network_manager_admin_rule_collection" +description: |- + Manages a Network Manager Admin Rule Collection. +--- + +# azurerm_network_manager_admin_rule_collection + +Manages a Network Manager Admin Rule Collection. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +data "azurerm_subscription" "current" { +} + +resource "azurerm_network_manager" "example" { + name = "example-network-manager" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + scope { + subscription_ids = [data.azurerm_subscription.current.id] + } + scope_accesses = ["Connectivity", "SecurityAdmin"] + description = "example network manager" +} + +resource "azurerm_network_manager_network_group" "example" { + name = "example-network-group" + network_manager_id = azurerm_network_manager.example.id +} + +resource "azurerm_network_manager_security_admin_configuration" "example" { + name = "example-admin-conf" + network_manager_id = azurerm_network_manager.example.id +} + +resource "azurerm_network_manager_admin_rule_collection" "example" { + name = "example-admin-rule-collection" + security_admin_configuration_id = azurerm_network_manager_security_admin_configuration.example.id + network_group_ids = [azurerm_network_manager_network_group.example.id] +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name which should be used for this Network Manager Admin Rule Collection. Changing this forces a new Network Manager Admin Rule Collection to be created. + +* `security_admin_configuration_id` - (Required) Specifies the ID of the Network Manager Security Admin Configuration. Changing this forces a new Network Manager Admin Rule Collection to be created. + +* `network_group_ids` - (Required) A list of Network Group ID which this Network Manager Admin Rule Collection applies to. + +* `description` - (Optional) A description of the Network Manager Admin Rule Collection. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Network Manager Admin Rule Collection. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Network Manager Admin Rule Collection. +* `read` - (Defaults to 5 minutes) Used when retrieving the Network Manager Admin Rule Collection. +* `update` - (Defaults to 30 minutes) Used when updating the Network Manager Admin Rule Collection. +* `delete` - (Defaults to 30 minutes) Used when deleting the Network Manager Admin Rule Collection. + +## Import + +Network Manager Admin Rule Collection can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_network_manager_admin_rule_collection.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Network/networkManagers/networkManager1/securityAdminConfigurations/configuration1/ruleCollections/ruleCollection1 +``` diff --git a/website/docs/r/network_manager_security_admin_configuration.html.markdown b/website/docs/r/network_manager_security_admin_configuration.html.markdown new file mode 100644 index 000000000000..b1d0d5643cb4 --- /dev/null +++ b/website/docs/r/network_manager_security_admin_configuration.html.markdown @@ -0,0 +1,81 @@ +--- +subcategory: "Network" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_network_security_admin_configuration" +description: |- + Manages a Network Manager Security Admin Configuration. +--- + +# azurerm_network_security_admin_configuration + +Manages a Network Manager Security Admin Configuration. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +data "azurerm_subscription" "current" { +} + +resource "azurerm_network_manager" "example" { + name = "example-network-manager" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + scope { + subscription_ids = [data.azurerm_subscription.current.id] + } + scope_accesses = ["Connectivity", "SecurityAdmin"] + description = "example network manager" +} + +resource "azurerm_network_manager_network_group" "example" { + name = "example-network-group" + network_manager_id = azurerm_network_manager.example.id +} + +resource "azurerm_network_manager_security_admin_configuration" "example" { + name = "example-admin-conf" + network_manager_id = azurerm_network_manager.example.id + description = "example admin conf" + apply_on_network_intent_policy_based_services = ["None"] +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name which should be used for this Network Manager Security Admin Configuration. Changing this forces a new Network Manager Security Admin Configuration to be created. + +* `network_manager_id` - (Required) Specifies the ID of the Network Manager Security Admin Configuration. Changing this forces a new Network Manager Security Admin Configuration to be created. + +* `apply_on_network_intent_policy_based_services` - (Optional) A list of network intent policy based services. Possible values are `All`, `None` and `AllowRulesOnly`. Exactly one value should be set. The `All` option requires `Microsoft.Network/AllowAdminRulesOnNipBasedServices` feature registration to Subscription. Please see [this document](https://learn.microsoft.com/en-us/azure/virtual-network-manager/concept-security-admins#network-intent-policies-and-security-admin-rules) for more information. + +* `description` - (Optional) A description of the Security Admin Configuration. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Network Manager Security Admin Configuration. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Network Manager Security Admin Configuration. +* `read` - (Defaults to 5 minutes) Used when retrieving the Network Manager Security Admin Configuration. +* `update` - (Defaults to 30 minutes) Used when updating the Network Manager Security Admin Configuration. +* `delete` - (Defaults to 30 minutes) Used when deleting the Network Manager Security Admin Configuration. + +## Import + +Network Manager Security Admin Configuration can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_network_security_admin_configuration.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.Network/networkManagers/networkManager1/securityAdminConfigurations/configuration1 +```