From 4af190720b49c3137df183aca9c2ce96172bdf88 Mon Sep 17 00:00:00 2001 From: Bruce Harrison Date: Fri, 9 Aug 2024 05:23:23 -0500 Subject: [PATCH] [New Resource] - `azurerm_postgresql_flexible_server_virtual_endpoint` (#26708) * add virtual endpoint client to postgres client.go * expose virtual endpoint client * add resource file * build out methods * complete initial pass * all behaviors implemented * fix index error * workaround api limitation * refine behavior * remove unnecessary update or create logic * add test file * complete basic tests * fix tests * first tests pass * complete tests * fix fmt * add docs page * fix description * lock region during test * fix typo * update docs * fix timeouts * update to new format * add service to typed services list * add properties to state upon read * get rid of if/else nesting * alphabetize services lists * Update internal/services/postgres/custompollers/postgresql_flexible_server_virtual_endpoint_resource_poller.go Add context to error message Co-authored-by: stephybun * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go Use built-in function for ID validation Co-authored-by: stephybun * add validation to name prop * reorder services * remove test provider feature * Update website/docs/r/azurerm_postgresql_flexible_server_virtual_endpoint.html.markdown Capitalization Co-authored-by: stephybun * Update website/docs/r/azurerm_postgresql_flexible_server_virtual_endpoint.html.markdown use standardized import example Co-authored-by: stephybun * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go Use standard error message Co-authored-by: stephybun * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go use standard pointer conversion Co-authored-by: stephybun * add pointer import * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go properly exit Delete method Co-authored-by: stephybun * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go use standard error message Co-authored-by: stephybun * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go use standard pointer conversion Co-authored-by: stephybun * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go use more explicit pointer conversion on return type Co-authored-by: stephybun * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go Use consistent styling Co-authored-by: stephybun * fixup * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go remove unnecessary test conditions Co-authored-by: stephybun * fix fmt * add test for update * slightly tweak test for readability * rename docs page, add note * shorten resource names to avoid errors * Update internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go Co-authored-by: stephybun --------- Co-authored-by: stephybun --- internal/provider/services.go | 45 ++-- internal/services/postgres/client/client.go | 9 + ...server_virtual_endpoint_resource_poller.go | 71 +++++ ...exible_server_virtual_endpoint_resource.go | 244 ++++++++++++++++++ ...e_server_virtual_endpoint_resource_test.go | 202 +++++++++++++++ internal/services/postgres/registration.go | 15 +- .../virtualendpoints/README.md | 99 +++++++ .../virtualendpoints/client.go | 26 ++ .../virtualendpoints/constants.go | 48 ++++ .../virtualendpoints/id_flexibleserver.go | 130 ++++++++++ .../virtualendpoints/id_virtualendpoint.go | 139 ++++++++++ .../virtualendpoints/method_create.go | 76 ++++++ .../virtualendpoints/method_delete.go | 70 +++++ .../virtualendpoints/method_get.go | 54 ++++ .../virtualendpoints/method_listbyserver.go | 105 ++++++++ .../virtualendpoints/method_update.go | 75 ++++++ .../model_virtualendpointresource.go | 16 ++ .../model_virtualendpointresourceforpatch.go | 8 + ...model_virtualendpointresourceproperties.go | 10 + .../virtualendpoints/predicates.go | 27 ++ .../virtualendpoints/version.go | 12 + vendor/modules.txt | 1 + ...ible_server_virtual_endpoint.html.markdown | 95 +++++++ 23 files changed, 1554 insertions(+), 23 deletions(-) create mode 100644 internal/services/postgres/custompollers/postgresql_flexible_server_virtual_endpoint_resource_poller.go create mode 100644 internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go create mode 100644 internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/README.md create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/client.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/constants.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_flexibleserver.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_virtualendpoint.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_create.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_delete.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_get.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_listbyserver.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_update.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresource.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceforpatch.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceproperties.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/predicates.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/version.go create mode 100644 website/docs/r/postgresql_flexible_server_virtual_endpoint.html.markdown diff --git a/internal/provider/services.go b/internal/provider/services.go index 30fb0e987a0f..4505a786a387 100644 --- a/internal/provider/services.go +++ b/internal/provider/services.go @@ -173,10 +173,9 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration { eventhub.Registration{}, fluidrelay.Registration{}, graphservices.Registration{}, - storagecache.Registration{}, hybridcompute.Registration{}, - iothub.Registration{}, iotcentral.Registration{}, + iothub.Registration{}, keyvault.Registration{}, kusto.Registration{}, labservice.Registration{}, @@ -187,36 +186,38 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration { maintenance.Registration{}, managedhsm.Registration{}, media.Registration{}, - monitor.Registration{}, mobilenetwork.Registration{}, + monitor.Registration{}, mssql.Registration{}, mssqlmanagedinstance.Registration{}, mysql.Registration{}, - network.Registration{}, netapp.Registration{}, + network.Registration{}, networkfunction.Registration{}, newrelic.Registration{}, nginx.Registration{}, + orbital.Registration{}, paloalto.Registration{}, policy.Registration{}, + postgres.Registration{}, privatednsresolver.Registration{}, recoveryservices.Registration{}, - redis.Registration{}, redhatopenshift.Registration{}, + redis.Registration{}, resource.Registration{}, + search.Registration{}, + securitycenter.Registration{}, sentinel.Registration{}, serviceconnector.Registration{}, servicefabricmanaged.Registration{}, servicenetworking.Registration{}, + signalr.Registration{}, + springcloud.Registration{}, storage.Registration{}, + storagecache.Registration{}, storagemover.Registration{}, - signalr.Registration{}, - subscription.Registration{}, - orbital.Registration{}, streamanalytics.Registration{}, - search.Registration{}, - springcloud.Registration{}, - securitycenter.Registration{}, + subscription.Registration{}, systemcentervirtualmachinemanager.Registration{}, vmware.Registration{}, voiceservices.Registration{}, @@ -234,7 +235,6 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration { analysisservices.Registration{}, apimanagement.Registration{}, appconfiguration.Registration{}, - springcloud.Registration{}, applicationinsights.Registration{}, arckubernetes.Registration{}, attestation.Registration{}, @@ -250,16 +250,16 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration { compute.Registration{}, confidentialledger.Registration{}, connections.Registration{}, - containers.Registration{}, consumption.Registration{}, + containers.Registration{}, cosmos.Registration{}, customproviders.Registration{}, dashboard.Registration{}, + databasemigration.Registration{}, + databoxedge.Registration{}, databricks.Registration{}, datadog.Registration{}, datafactory.Registration{}, - databasemigration.Registration{}, - databoxedge.Registration{}, dataprotection.Registration{}, datashare.Registration{}, desktopvirtualization.Registration{}, @@ -272,15 +272,16 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration { eventhub.Registration{}, firewall.Registration{}, frontdoor.Registration{}, - storagecache.Registration{}, - hsm.Registration{}, hdinsight.Registration{}, healthcare.Registration{}, - iothub.Registration{}, + hsm.Registration{}, iotcentral.Registration{}, + iothub.Registration{}, + iottimeseriesinsights.Registration{}, keyvault.Registration{}, kusto.Registration{}, legacy.Registration{}, + lighthouse.Registration{}, loadbalancer.Registration{}, loganalytics.Registration{}, logic.Registration{}, @@ -288,15 +289,14 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration { machinelearning.Registration{}, maintenance.Registration{}, managedapplications.Registration{}, - lighthouse.Registration{}, - managementgroup.Registration{}, managedhsm.Registration{}, + managedidentity.Registration{}, + managementgroup.Registration{}, maps.Registration{}, mariadb.Registration{}, media.Registration{}, mixedreality.Registration{}, monitor.Registration{}, - managedidentity.Registration{}, mssql.Registration{}, mssqlmanagedinstance.Registration{}, mysql.Registration{}, @@ -320,12 +320,13 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration { servicebus.Registration{}, servicefabric.Registration{}, signalr.Registration{}, + springcloud.Registration{}, sql.Registration{}, storage.Registration{}, + storagecache.Registration{}, streamanalytics.Registration{}, subscription.Registration{}, synapse.Registration{}, - iottimeseriesinsights.Registration{}, trafficmanager.Registration{}, videoanalyzer.Registration{}, vmware.Registration{}, diff --git a/internal/services/postgres/client/client.go b/internal/services/postgres/client/client.go index af2e6813a56c..7de68d1e4572 100644 --- a/internal/services/postgres/client/client.go +++ b/internal/services/postgres/client/client.go @@ -21,6 +21,7 @@ import ( flexibleserverdatabases "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2022-12-01/databases" flexibleserverfirewallrules "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2022-12-01/firewallrules" flexibleservers "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/servers" + flexibleservervirtualendpoints "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints" "github.com/hashicorp/terraform-provider-azurerm/internal/common" ) @@ -40,6 +41,7 @@ type Client struct { VirtualNetworkRulesClient *virtualnetworkrules.VirtualNetworkRulesClient ServerAdministratorsClient *serveradministrators.ServerAdministratorsClient ReplicasClient *replicas.ReplicasClient + VirtualEndpointClient *flexibleservervirtualendpoints.VirtualEndpointsClient } func NewClient(o *common.ClientOptions) (*Client, error) { @@ -133,6 +135,12 @@ func NewClient(o *common.ClientOptions) (*Client, error) { } o.Configure(flexibleServerAdministratorsClient.Client, o.Authorizers.ResourceManager) + virtualEndpointClient, err := flexibleservervirtualendpoints.NewVirtualEndpointsClientWithBaseURI(o.Environment.ResourceManager) + if err != nil { + return nil, fmt.Errorf("building FlexibleServerVirtualEndpoint client: %+v", err) + } + o.Configure(virtualEndpointClient.Client, o.Authorizers.ResourceManager) + return &Client{ ConfigurationsClient: configurationsClient, DatabasesClient: databasesClient, @@ -149,5 +157,6 @@ func NewClient(o *common.ClientOptions) (*Client, error) { VirtualNetworkRulesClient: virtualNetworkRulesClient, ServerAdministratorsClient: serverAdministratorsClient, ReplicasClient: replicasClient, + VirtualEndpointClient: virtualEndpointClient, }, nil } diff --git a/internal/services/postgres/custompollers/postgresql_flexible_server_virtual_endpoint_resource_poller.go b/internal/services/postgres/custompollers/postgresql_flexible_server_virtual_endpoint_resource_poller.go new file mode 100644 index 000000000000..25315a3031eb --- /dev/null +++ b/internal/services/postgres/custompollers/postgresql_flexible_server_virtual_endpoint_resource_poller.go @@ -0,0 +1,71 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package custompollers + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" +) + +var _ pollers.PollerType = &postgresFlexibleServerVirtualEndpointPoller{} + +type postgresFlexibleServerVirtualEndpointPoller struct { + client *virtualendpoints.VirtualEndpointsClient + id virtualendpoints.VirtualEndpointId +} + +// Workaround due to Azure performing a pseudo-soft delete on virtual endpoints. +// +// - The `DELETE` endpoint does not fully delete the resource, it sets `properties.members` to nil +// +// - Subsequent `GET` operations for the endpoint will always return 200 with empty metadata, so Terraform will hang on `DELETE` +// +// - The only way to currently check for deletion is to check the `properties.members` property +func NewPostgresFlexibleServerVirtualEndpointDeletePoller(client *virtualendpoints.VirtualEndpointsClient, id virtualendpoints.VirtualEndpointId) *postgresFlexibleServerVirtualEndpointPoller { + return &postgresFlexibleServerVirtualEndpointPoller{ + client: client, + id: id, + } +} + +func (p postgresFlexibleServerVirtualEndpointPoller) Poll(ctx context.Context) (*pollers.PollResult, error) { + resp, err := p.client.Get(ctx, p.id) + if err != nil { + return nil, fmt.Errorf("retrieving %s: %+v", p.id, err) + } + + model := resp.Model + + if model != nil && model.Properties != nil { + if model.Properties.Members != nil { + return &pollers.PollResult{ + HttpResponse: &client.Response{ + Response: resp.HttpResponse, + }, + PollInterval: 5 * time.Second, + Status: pollers.PollingStatusInProgress, + }, nil + } + + return &pollers.PollResult{ + HttpResponse: &client.Response{ + Response: resp.HttpResponse, + }, + PollInterval: 5 * time.Second, + Status: pollers.PollingStatusSucceeded, + }, nil + } + + return nil, pollers.PollingFailedError{ + HttpResponse: &client.Response{ + Response: resp.HttpResponse, + }, + Message: fmt.Sprintf("failed to delete %s", p.id), + } +} diff --git a/internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go b/internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go new file mode 100644 index 000000000000..104bacb7fcbc --- /dev/null +++ b/internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource.go @@ -0,0 +1,244 @@ +package postgres + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/servers" + "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" + "github.com/hashicorp/terraform-provider-azurerm/internal/locks" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/postgres/custompollers" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" +) + +type PostgresqlFlexibleServerVirtualEndpointResource struct{} + +type PostgresqlFlexibleServerVirtualEndpointModel struct { + Name string `tfschema:"name"` + SourceServerId string `tfschema:"source_server_id"` + ReplicaServerId string `tfschema:"replica_server_id"` + Type string `tfschema:"type"` +} + +var _ sdk.ResourceWithUpdate = PostgresqlFlexibleServerVirtualEndpointResource{} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) ModelObject() interface{} { + return &PostgresqlFlexibleServerVirtualEndpointModel{} +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) ResourceType() string { + return "azurerm_postgresql_flexible_server_virtual_endpoint" +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return virtualendpoints.ValidateVirtualEndpointID +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Description: "The name of the Virtual Endpoint", + ForceNew: true, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "source_server_id": { + Type: pluginsdk.TypeString, + Description: "The Resource ID of the *Source* Postgres Flexible Server this should be associated with", + ForceNew: true, + Required: true, + ValidateFunc: servers.ValidateFlexibleServerID, + }, + "replica_server_id": { + Type: pluginsdk.TypeString, + Description: "The Resource ID of the *Replica* Postgres Flexible Server this should be associated with", + Required: true, + ValidateFunc: servers.ValidateFlexibleServerID, + }, + "type": { + Type: pluginsdk.TypeString, + Description: "The type of Virtual Endpoint", + ForceNew: true, + Required: true, + ValidateFunc: validation.StringInSlice(virtualendpoints.PossibleValuesForVirtualEndpointType(), true), + }, + } +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var virtualEndpoint PostgresqlFlexibleServerVirtualEndpointModel + + if err := metadata.Decode(&virtualEndpoint); err != nil { + return err + } + + client := metadata.Client.Postgres.VirtualEndpointClient + + sourceServerId, err := servers.ParseFlexibleServerID(virtualEndpoint.SourceServerId) + if err != nil { + return err + } + + replicaServerId, err := servers.ParseFlexibleServerID(virtualEndpoint.ReplicaServerId) + if err != nil { + return err + } + + id := virtualendpoints.NewVirtualEndpointID(sourceServerId.SubscriptionId, sourceServerId.ResourceGroupName, sourceServerId.FlexibleServerName, virtualEndpoint.Name) + + locks.ByName(id.FlexibleServerName, postgresqlFlexibleServerResourceName) + defer locks.UnlockByName(id.FlexibleServerName, postgresqlFlexibleServerResourceName) + + // This API can be a bit flaky if the same named resource is created/destroyed quickly + // usually waiting a minute or two before redeploying is enough to resolve the conflict + if err = client.CreateThenPoll(ctx, id, virtualendpoints.VirtualEndpointResource{ + Name: &virtualEndpoint.Name, + Properties: &virtualendpoints.VirtualEndpointResourceProperties{ + EndpointType: pointer.To(virtualendpoints.VirtualEndpointType(virtualEndpoint.Type)), + Members: &[]string{replicaServerId.FlexibleServerName}, + }, + }); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + + return nil + }, + } +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Postgres.VirtualEndpointClient + state := PostgresqlFlexibleServerVirtualEndpointModel{} + + id, err := virtualendpoints.ParseVirtualEndpointID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] %s does not exist - removing from state", metadata.ResourceData.Id()) + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + state.Name = id.VirtualEndpointName + + if model := resp.Model; model != nil { + if props := model.Properties; props != nil { + state.Type = string(pointer.From(props.EndpointType)) + + if props.Members == nil || len(*props.Members) != 2 { + // if members list is nil, this is an endpoint that was previously deleted + log.Printf("[INFO] Postgresql Flexible Server Endpoint %q was previously deleted - removing from state", id.ID()) + return metadata.MarkAsGone(id) + } + + // Model.Properties.Members should be a tuple => [source_server, replication_server] + state.SourceServerId = servers.NewFlexibleServerID(id.SubscriptionId, id.ResourceGroupName, (*resp.Model.Properties.Members)[0]).ID() + state.ReplicaServerId = servers.NewFlexibleServerID(id.SubscriptionId, id.ResourceGroupName, (*resp.Model.Properties.Members)[1]).ID() + } + } + + return metadata.Encode(&state) + }, + } +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Postgres.VirtualEndpointClient + + id, err := virtualendpoints.ParseVirtualEndpointID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + locks.ByName(id.FlexibleServerName, postgresqlFlexibleServerResourceName) + defer locks.UnlockByName(id.FlexibleServerName, postgresqlFlexibleServerResourceName) + + if err := DeletePostgresFlexibileServerVirtualEndpoint(ctx, client, id); err != nil { + return err + } + + return nil + }, + } +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var virtualEndpoint PostgresqlFlexibleServerVirtualEndpointModel + client := metadata.Client.Postgres.VirtualEndpointClient + + if err := metadata.Decode(&virtualEndpoint); err != nil { + return err + } + + id, err := virtualendpoints.ParseVirtualEndpointID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + replicaServerId, err := servers.ParseFlexibleServerID(virtualEndpoint.ReplicaServerId) + if err != nil { + return err + } + + locks.ByName(id.FlexibleServerName, postgresqlFlexibleServerResourceName) + defer locks.UnlockByName(id.FlexibleServerName, postgresqlFlexibleServerResourceName) + + if err := client.UpdateThenPoll(ctx, *id, virtualendpoints.VirtualEndpointResourceForPatch{ + Properties: &virtualendpoints.VirtualEndpointResourceProperties{ + EndpointType: pointer.To(virtualendpoints.VirtualEndpointType(virtualEndpoint.Type)), + Members: pointer.To([]string{replicaServerId.FlexibleServerName}), + }, + }); err != nil { + return fmt.Errorf("updating %q: %+v", id, err) + } + + return nil + }, + } +} + +// exposed so we can access from tests +func DeletePostgresFlexibileServerVirtualEndpoint(ctx context.Context, client *virtualendpoints.VirtualEndpointsClient, id *virtualendpoints.VirtualEndpointId) error { + deletePoller := custompollers.NewPostgresFlexibleServerVirtualEndpointDeletePoller(client, *id) + poller := pollers.NewPoller(deletePoller, 5*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow) + + if _, err := client.Delete(ctx, *id); err != nil { + return fmt.Errorf("deleting %s: %+v", *id, err) + } + + if err := poller.PollUntilDone(ctx); err != nil { + return err + } + return nil +} diff --git a/internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go b/internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go new file mode 100644 index 000000000000..9b48f7bc1d6e --- /dev/null +++ b/internal/services/postgres/postgresql_flexible_server_virtual_endpoint_resource_test.go @@ -0,0 +1,202 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package postgres_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints" + "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/postgres" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type PostgresqlFlexibleServerVirtualEndpointResource struct{} + +func TestAccPostgresqlFlexibleServerVirtualEndpoint_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server_virtual_endpoint", "test") + r := PostgresqlFlexibleServerVirtualEndpointResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + data.DisappearsStep(acceptance.DisappearsStepData{ + Config: r.basic, + TestResource: r, + }), + }) +} + +func TestAccPostgresqlFlexibleServerVirtualEndpoint_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_postgresql_flexible_server_virtual_endpoint", "test") + r := PostgresqlFlexibleServerVirtualEndpointResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.update(data, "azurerm_postgresql_flexible_server.test_replica_0.id"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.update(data, "azurerm_postgresql_flexible_server.test_replica_1.id"), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := virtualendpoints.ParseVirtualEndpointID(state.ID) + if err != nil { + return nil, err + } + + resp, err := clients.Postgres.VirtualEndpointClient.Get(ctx, *id) + if err != nil { + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + + return pointer.To(resp.Model != nil && resp.Model.Properties != nil && resp.Model.Properties.Members != nil), nil +} + +func (r PostgresqlFlexibleServerVirtualEndpointResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := virtualendpoints.ParseVirtualEndpointID(state.ID) + if err != nil { + return nil, err + } + + if err := postgres.DeletePostgresFlexibileServerVirtualEndpoint(ctx, client.Postgres.VirtualEndpointClient, id); err != nil { + return nil, fmt.Errorf("deleting %s: %+v", id, err) + } + + return utils.Bool(true), nil +} + +func (PostgresqlFlexibleServerVirtualEndpointResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctest-ve-rg-%[1]d" + location = "%[2]s" +} + +resource "azurerm_postgresql_flexible_server" "test" { + name = "acctest-ve-primary-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + version = "16" + public_network_access_enabled = false + administrator_login = "psqladmin" + administrator_password = "H@Sh1CoR3!" + zone = "1" + storage_mb = 32768 + storage_tier = "P30" + sku_name = "GP_Standard_D2ads_v5" +} + +resource "azurerm_postgresql_flexible_server" "test_replica" { + name = "acctest-ve-replica-%[1]d" + resource_group_name = azurerm_postgresql_flexible_server.test.resource_group_name + location = azurerm_postgresql_flexible_server.test.location + create_mode = "Replica" + source_server_id = azurerm_postgresql_flexible_server.test.id + version = "16" + public_network_access_enabled = false + zone = "1" + storage_mb = 32768 + storage_tier = "P30" +} + +resource "azurerm_postgresql_flexible_server_virtual_endpoint" "test" { + name = "acctest-ve-%[1]d" + source_server_id = azurerm_postgresql_flexible_server.test.id + replica_server_id = azurerm_postgresql_flexible_server.test_replica.id + type = "ReadWrite" +} +`, data.RandomInteger, "eastus") // force region due to SKU constraints +} + +func (PostgresqlFlexibleServerVirtualEndpointResource) update(data acceptance.TestData, replicaId string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctest-ve-rg-%[1]d" + location = "%[2]s" +} + +resource "azurerm_postgresql_flexible_server" "test" { + name = "acctest-ve-primary-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + version = "16" + public_network_access_enabled = false + administrator_login = "psqladmin" + administrator_password = "H@Sh1CoR3!" + zone = "1" + storage_mb = 32768 + storage_tier = "P30" + sku_name = "GP_Standard_D2ads_v5" +} + +resource "azurerm_postgresql_flexible_server" "test_replica_0" { + name = "${azurerm_postgresql_flexible_server.test.name}-replica-0" + resource_group_name = azurerm_postgresql_flexible_server.test.resource_group_name + location = azurerm_postgresql_flexible_server.test.location + create_mode = "Replica" + source_server_id = azurerm_postgresql_flexible_server.test.id + version = azurerm_postgresql_flexible_server.test.version + public_network_access_enabled = azurerm_postgresql_flexible_server.test.public_network_access_enabled + zone = azurerm_postgresql_flexible_server.test.zone + storage_mb = azurerm_postgresql_flexible_server.test.storage_mb + storage_tier = azurerm_postgresql_flexible_server.test.storage_tier +} + +resource "azurerm_postgresql_flexible_server" "test_replica_1" { + name = "${azurerm_postgresql_flexible_server.test.name}-replica-1" + resource_group_name = azurerm_postgresql_flexible_server.test.resource_group_name + location = azurerm_postgresql_flexible_server.test.location + create_mode = "Replica" + source_server_id = azurerm_postgresql_flexible_server.test.id + version = azurerm_postgresql_flexible_server.test.version + public_network_access_enabled = azurerm_postgresql_flexible_server.test.public_network_access_enabled + zone = azurerm_postgresql_flexible_server.test.zone + storage_mb = azurerm_postgresql_flexible_server.test.storage_mb + storage_tier = azurerm_postgresql_flexible_server.test.storage_tier + + ## this prevents a race condition that can occur when 2 replicas are created simultaneously + depends_on = [azurerm_postgresql_flexible_server.test_replica_0] +} + +resource "azurerm_postgresql_flexible_server_virtual_endpoint" "test" { + name = "acctest-ve-%[1]d" + source_server_id = azurerm_postgresql_flexible_server.test.id + replica_server_id = %[3]s + type = "ReadWrite" + + ## this prevents a race condition that can occur if the virtual endpoint is created while a replica is still initializing + depends_on = [azurerm_postgresql_flexible_server.test_replica_0, azurerm_postgresql_flexible_server.test_replica_1] +} +`, data.RandomInteger, "eastus", replicaId) // force region due to SKU constraints +} diff --git a/internal/services/postgres/registration.go b/internal/services/postgres/registration.go index 1ccf42b25673..cad8f4e49dcf 100644 --- a/internal/services/postgres/registration.go +++ b/internal/services/postgres/registration.go @@ -10,7 +10,10 @@ import ( type Registration struct{} -var _ sdk.UntypedServiceRegistrationWithAGitHubLabel = Registration{} +var ( + _ sdk.TypedServiceRegistrationWithAGitHubLabel = Registration{} + _ sdk.UntypedServiceRegistrationWithAGitHubLabel = Registration{} +) func (r Registration) AssociatedGitHubLabel() string { return "service/postgresql" @@ -53,3 +56,13 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { "azurerm_postgresql_flexible_server_active_directory_administrator": resourcePostgresqlFlexibleServerAdministrator(), } } + +func (r Registration) Resources() []sdk.Resource { + return []sdk.Resource{ + PostgresqlFlexibleServerVirtualEndpointResource{}, + } +} + +func (r Registration) DataSources() []sdk.DataSource { + return []sdk.DataSource{} +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/README.md new file mode 100644 index 000000000000..831488b367cd --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/README.md @@ -0,0 +1,99 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints` Documentation + +The `virtualendpoints` SDK allows for interaction with the Azure Resource Manager Service `postgresql` (API Version `2023-06-01-preview`). + +This readme covers example usages, but further information on [using this SDK can be found in the project root](https://github.com/hashicorp/go-azure-sdk/tree/main/docs). + +### Import Path + +```go +import "github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints" +``` + + +### Client Initialization + +```go +client := virtualendpoints.NewVirtualEndpointsClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `VirtualEndpointsClient.Create` + +```go +ctx := context.TODO() +id := virtualendpoints.NewVirtualEndpointID("12345678-1234-9876-4563-123456789012", "example-resource-group", "flexibleServerValue", "virtualEndpointValue") + +payload := virtualendpoints.VirtualEndpointResource{ + // ... +} + + +if err := client.CreateThenPoll(ctx, id, payload); err != nil { + // handle the error +} +``` + + +### Example Usage: `VirtualEndpointsClient.Delete` + +```go +ctx := context.TODO() +id := virtualendpoints.NewVirtualEndpointID("12345678-1234-9876-4563-123456789012", "example-resource-group", "flexibleServerValue", "virtualEndpointValue") + +if err := client.DeleteThenPoll(ctx, id); err != nil { + // handle the error +} +``` + + +### Example Usage: `VirtualEndpointsClient.Get` + +```go +ctx := context.TODO() +id := virtualendpoints.NewVirtualEndpointID("12345678-1234-9876-4563-123456789012", "example-resource-group", "flexibleServerValue", "virtualEndpointValue") + +read, err := client.Get(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `VirtualEndpointsClient.ListByServer` + +```go +ctx := context.TODO() +id := virtualendpoints.NewFlexibleServerID("12345678-1234-9876-4563-123456789012", "example-resource-group", "flexibleServerValue") + +// alternatively `client.ListByServer(ctx, id)` can be used to do batched pagination +items, err := client.ListByServerComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `VirtualEndpointsClient.Update` + +```go +ctx := context.TODO() +id := virtualendpoints.NewVirtualEndpointID("12345678-1234-9876-4563-123456789012", "example-resource-group", "flexibleServerValue", "virtualEndpointValue") + +payload := virtualendpoints.VirtualEndpointResourceForPatch{ + // ... +} + + +if err := client.UpdateThenPoll(ctx, id, payload); err != nil { + // handle the error +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/client.go new file mode 100644 index 000000000000..e4f12890b9e5 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/client.go @@ -0,0 +1,26 @@ +package virtualendpoints + +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + sdkEnv "github.com/hashicorp/go-azure-sdk/sdk/environments" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type VirtualEndpointsClient struct { + Client *resourcemanager.Client +} + +func NewVirtualEndpointsClientWithBaseURI(sdkApi sdkEnv.Api) (*VirtualEndpointsClient, error) { + client, err := resourcemanager.NewResourceManagerClient(sdkApi, "virtualendpoints", defaultApiVersion) + if err != nil { + return nil, fmt.Errorf("instantiating VirtualEndpointsClient: %+v", err) + } + + return &VirtualEndpointsClient{ + Client: client, + }, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/constants.go new file mode 100644 index 000000000000..751ffa8c4732 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/constants.go @@ -0,0 +1,48 @@ +package virtualendpoints + +import ( + "encoding/json" + "fmt" + "strings" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type VirtualEndpointType string + +const ( + VirtualEndpointTypeReadWrite VirtualEndpointType = "ReadWrite" +) + +func PossibleValuesForVirtualEndpointType() []string { + return []string{ + string(VirtualEndpointTypeReadWrite), + } +} + +func (s *VirtualEndpointType) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseVirtualEndpointType(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseVirtualEndpointType(input string) (*VirtualEndpointType, error) { + vals := map[string]VirtualEndpointType{ + "readwrite": VirtualEndpointTypeReadWrite, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := VirtualEndpointType(input) + return &out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_flexibleserver.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_flexibleserver.go new file mode 100644 index 000000000000..242239daf770 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_flexibleserver.go @@ -0,0 +1,130 @@ +package virtualendpoints + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/recaser" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +func init() { + recaser.RegisterResourceId(&FlexibleServerId{}) +} + +var _ resourceids.ResourceId = &FlexibleServerId{} + +// FlexibleServerId is a struct representing the Resource ID for a Flexible Server +type FlexibleServerId struct { + SubscriptionId string + ResourceGroupName string + FlexibleServerName string +} + +// NewFlexibleServerID returns a new FlexibleServerId struct +func NewFlexibleServerID(subscriptionId string, resourceGroupName string, flexibleServerName string) FlexibleServerId { + return FlexibleServerId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + FlexibleServerName: flexibleServerName, + } +} + +// ParseFlexibleServerID parses 'input' into a FlexibleServerId +func ParseFlexibleServerID(input string) (*FlexibleServerId, error) { + parser := resourceids.NewParserFromResourceIdType(&FlexibleServerId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := FlexibleServerId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +// ParseFlexibleServerIDInsensitively parses 'input' case-insensitively into a FlexibleServerId +// note: this method should only be used for API response data and not user input +func ParseFlexibleServerIDInsensitively(input string) (*FlexibleServerId, error) { + parser := resourceids.NewParserFromResourceIdType(&FlexibleServerId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := FlexibleServerId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +func (id *FlexibleServerId) FromParseResult(input resourceids.ParseResult) error { + var ok bool + + if id.SubscriptionId, ok = input.Parsed["subscriptionId"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", input) + } + + if id.ResourceGroupName, ok = input.Parsed["resourceGroupName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", input) + } + + if id.FlexibleServerName, ok = input.Parsed["flexibleServerName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "flexibleServerName", input) + } + + return nil +} + +// ValidateFlexibleServerID checks that 'input' can be parsed as a Flexible Server ID +func ValidateFlexibleServerID(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 := ParseFlexibleServerID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Flexible Server ID +func (id FlexibleServerId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.DBforPostgreSQL/flexibleServers/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.FlexibleServerName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Flexible Server ID +func (id FlexibleServerId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftDBforPostgreSQL", "Microsoft.DBforPostgreSQL", "Microsoft.DBforPostgreSQL"), + resourceids.StaticSegment("staticFlexibleServers", "flexibleServers", "flexibleServers"), + resourceids.UserSpecifiedSegment("flexibleServerName", "flexibleServerValue"), + } +} + +// String returns a human-readable description of this Flexible Server ID +func (id FlexibleServerId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Flexible Server Name: %q", id.FlexibleServerName), + } + return fmt.Sprintf("Flexible Server (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_virtualendpoint.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_virtualendpoint.go new file mode 100644 index 000000000000..10a8e52f1c3b --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/id_virtualendpoint.go @@ -0,0 +1,139 @@ +package virtualendpoints + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/recaser" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +func init() { + recaser.RegisterResourceId(&VirtualEndpointId{}) +} + +var _ resourceids.ResourceId = &VirtualEndpointId{} + +// VirtualEndpointId is a struct representing the Resource ID for a Virtual Endpoint +type VirtualEndpointId struct { + SubscriptionId string + ResourceGroupName string + FlexibleServerName string + VirtualEndpointName string +} + +// NewVirtualEndpointID returns a new VirtualEndpointId struct +func NewVirtualEndpointID(subscriptionId string, resourceGroupName string, flexibleServerName string, virtualEndpointName string) VirtualEndpointId { + return VirtualEndpointId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + FlexibleServerName: flexibleServerName, + VirtualEndpointName: virtualEndpointName, + } +} + +// ParseVirtualEndpointID parses 'input' into a VirtualEndpointId +func ParseVirtualEndpointID(input string) (*VirtualEndpointId, error) { + parser := resourceids.NewParserFromResourceIdType(&VirtualEndpointId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := VirtualEndpointId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +// ParseVirtualEndpointIDInsensitively parses 'input' case-insensitively into a VirtualEndpointId +// note: this method should only be used for API response data and not user input +func ParseVirtualEndpointIDInsensitively(input string) (*VirtualEndpointId, error) { + parser := resourceids.NewParserFromResourceIdType(&VirtualEndpointId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := VirtualEndpointId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +func (id *VirtualEndpointId) FromParseResult(input resourceids.ParseResult) error { + var ok bool + + if id.SubscriptionId, ok = input.Parsed["subscriptionId"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", input) + } + + if id.ResourceGroupName, ok = input.Parsed["resourceGroupName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", input) + } + + if id.FlexibleServerName, ok = input.Parsed["flexibleServerName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "flexibleServerName", input) + } + + if id.VirtualEndpointName, ok = input.Parsed["virtualEndpointName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "virtualEndpointName", input) + } + + return nil +} + +// ValidateVirtualEndpointID checks that 'input' can be parsed as a Virtual Endpoint ID +func ValidateVirtualEndpointID(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 := ParseVirtualEndpointID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Virtual Endpoint ID +func (id VirtualEndpointId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.DBforPostgreSQL/flexibleServers/%s/virtualEndpoints/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.FlexibleServerName, id.VirtualEndpointName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Virtual Endpoint ID +func (id VirtualEndpointId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftDBforPostgreSQL", "Microsoft.DBforPostgreSQL", "Microsoft.DBforPostgreSQL"), + resourceids.StaticSegment("staticFlexibleServers", "flexibleServers", "flexibleServers"), + resourceids.UserSpecifiedSegment("flexibleServerName", "flexibleServerValue"), + resourceids.StaticSegment("staticVirtualEndpoints", "virtualEndpoints", "virtualEndpoints"), + resourceids.UserSpecifiedSegment("virtualEndpointName", "virtualEndpointValue"), + } +} + +// String returns a human-readable description of this Virtual Endpoint ID +func (id VirtualEndpointId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Flexible Server Name: %q", id.FlexibleServerName), + fmt.Sprintf("Virtual Endpoint Name: %q", id.VirtualEndpointName), + } + return fmt.Sprintf("Virtual Endpoint (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_create.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_create.go new file mode 100644 index 000000000000..e1734310b6e1 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_create.go @@ -0,0 +1,76 @@ +package virtualendpoints + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type CreateOperationResponse struct { + Poller pollers.Poller + HttpResponse *http.Response + OData *odata.OData + Model *VirtualEndpointResource +} + +// Create ... +func (c VirtualEndpointsClient) Create(ctx context.Context, id VirtualEndpointId, input VirtualEndpointResource) (result CreateOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + http.StatusCreated, + http.StatusOK, + }, + HttpMethod: http.MethodPut, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + if err = req.Marshal(input); err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + result.Poller, err = resourcemanager.PollerFromResponse(resp, c.Client) + if err != nil { + return + } + + return +} + +// CreateThenPoll performs Create then polls until it's completed +func (c VirtualEndpointsClient) CreateThenPoll(ctx context.Context, id VirtualEndpointId, input VirtualEndpointResource) error { + result, err := c.Create(ctx, id, input) + if err != nil { + return fmt.Errorf("performing Create: %+v", err) + } + + if err := result.Poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("polling after Create: %+v", err) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_delete.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_delete.go new file mode 100644 index 000000000000..e465e5f8fa02 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_delete.go @@ -0,0 +1,70 @@ +package virtualendpoints + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type DeleteOperationResponse struct { + Poller pollers.Poller + HttpResponse *http.Response + OData *odata.OData +} + +// Delete ... +func (c VirtualEndpointsClient) Delete(ctx context.Context, id VirtualEndpointId) (result DeleteOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + http.StatusNoContent, + }, + HttpMethod: http.MethodDelete, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + result.Poller, err = resourcemanager.PollerFromResponse(resp, c.Client) + if err != nil { + return + } + + return +} + +// DeleteThenPoll performs Delete then polls until it's completed +func (c VirtualEndpointsClient) DeleteThenPoll(ctx context.Context, id VirtualEndpointId) error { + result, err := c.Delete(ctx, id) + if err != nil { + return fmt.Errorf("performing Delete: %+v", err) + } + + if err := result.Poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("polling after Delete: %+v", err) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_get.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_get.go new file mode 100644 index 000000000000..3d17967feac2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_get.go @@ -0,0 +1,54 @@ +package virtualendpoints + +import ( + "context" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GetOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *VirtualEndpointResource +} + +// Get ... +func (c VirtualEndpointsClient) Get(ctx context.Context, id VirtualEndpointId) (result GetOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var model VirtualEndpointResource + result.Model = &model + + if err = resp.Unmarshal(result.Model); err != nil { + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_listbyserver.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_listbyserver.go new file mode 100644 index 000000000000..fc8065183062 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_listbyserver.go @@ -0,0 +1,105 @@ +package virtualendpoints + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListByServerOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *[]VirtualEndpointResource +} + +type ListByServerCompleteResult struct { + LatestHttpResponse *http.Response + Items []VirtualEndpointResource +} + +type ListByServerCustomPager struct { + NextLink *odata.Link `json:"nextLink"` +} + +func (p *ListByServerCustomPager) NextPageLink() *odata.Link { + defer func() { + p.NextLink = nil + }() + + return p.NextLink +} + +// ListByServer ... +func (c VirtualEndpointsClient) ListByServer(ctx context.Context, id FlexibleServerId) (result ListByServerOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Pager: &ListByServerCustomPager{}, + Path: fmt.Sprintf("%s/virtualEndpoints", id.ID()), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.ExecutePaged(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var values struct { + Values *[]VirtualEndpointResource `json:"value"` + } + if err = resp.Unmarshal(&values); err != nil { + return + } + + result.Model = values.Values + + return +} + +// ListByServerComplete retrieves all the results into a single object +func (c VirtualEndpointsClient) ListByServerComplete(ctx context.Context, id FlexibleServerId) (ListByServerCompleteResult, error) { + return c.ListByServerCompleteMatchingPredicate(ctx, id, VirtualEndpointResourceOperationPredicate{}) +} + +// ListByServerCompleteMatchingPredicate retrieves all the results and then applies the predicate +func (c VirtualEndpointsClient) ListByServerCompleteMatchingPredicate(ctx context.Context, id FlexibleServerId, predicate VirtualEndpointResourceOperationPredicate) (result ListByServerCompleteResult, err error) { + items := make([]VirtualEndpointResource, 0) + + resp, err := c.ListByServer(ctx, id) + if err != nil { + result.LatestHttpResponse = resp.HttpResponse + err = fmt.Errorf("loading results: %+v", err) + return + } + if resp.Model != nil { + for _, v := range *resp.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + result = ListByServerCompleteResult{ + LatestHttpResponse: resp.HttpResponse, + Items: items, + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_update.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_update.go new file mode 100644 index 000000000000..3e6a71684d73 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/method_update.go @@ -0,0 +1,75 @@ +package virtualendpoints + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type UpdateOperationResponse struct { + Poller pollers.Poller + HttpResponse *http.Response + OData *odata.OData + Model *VirtualEndpointResource +} + +// Update ... +func (c VirtualEndpointsClient) Update(ctx context.Context, id VirtualEndpointId, input VirtualEndpointResourceForPatch) (result UpdateOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + http.StatusOK, + }, + HttpMethod: http.MethodPatch, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + if err = req.Marshal(input); err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + result.Poller, err = resourcemanager.PollerFromResponse(resp, c.Client) + if err != nil { + return + } + + return +} + +// UpdateThenPoll performs Update then polls until it's completed +func (c VirtualEndpointsClient) UpdateThenPoll(ctx context.Context, id VirtualEndpointId, input VirtualEndpointResourceForPatch) error { + result, err := c.Update(ctx, id, input) + if err != nil { + return fmt.Errorf("performing Update: %+v", err) + } + + if err := result.Poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("polling after Update: %+v", err) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresource.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresource.go new file mode 100644 index 000000000000..5924aefac2e1 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresource.go @@ -0,0 +1,16 @@ +package virtualendpoints + +import ( + "github.com/hashicorp/go-azure-helpers/resourcemanager/systemdata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type VirtualEndpointResource struct { + Id *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Properties *VirtualEndpointResourceProperties `json:"properties,omitempty"` + SystemData *systemdata.SystemData `json:"systemData,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceforpatch.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceforpatch.go new file mode 100644 index 000000000000..141027b0b639 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceforpatch.go @@ -0,0 +1,8 @@ +package virtualendpoints + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type VirtualEndpointResourceForPatch struct { + Properties *VirtualEndpointResourceProperties `json:"properties,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceproperties.go new file mode 100644 index 000000000000..8384fc61746e --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/model_virtualendpointresourceproperties.go @@ -0,0 +1,10 @@ +package virtualendpoints + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type VirtualEndpointResourceProperties struct { + EndpointType *VirtualEndpointType `json:"endpointType,omitempty"` + Members *[]string `json:"members,omitempty"` + VirtualEndpoints *[]string `json:"virtualEndpoints,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/predicates.go new file mode 100644 index 000000000000..dd12a082467a --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/predicates.go @@ -0,0 +1,27 @@ +package virtualendpoints + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type VirtualEndpointResourceOperationPredicate struct { + Id *string + Name *string + Type *string +} + +func (p VirtualEndpointResourceOperationPredicate) Matches(input VirtualEndpointResource) bool { + + if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { + return false + } + + if p.Name != nil && (input.Name == nil || *p.Name != *input.Name) { + return false + } + + if p.Type != nil && (input.Type == nil || *p.Type != *input.Type) { + return false + } + + return true +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/version.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/version.go new file mode 100644 index 000000000000..914c7c521ea6 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints/version.go @@ -0,0 +1,12 @@ +package virtualendpoints + +import "fmt" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +const defaultApiVersion = "2023-06-01-preview" + +func userAgent() string { + return fmt.Sprintf("hashicorp/go-azure-sdk/virtualendpoints/%s", defaultApiVersion) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index fd1e05885487..d86474ded01b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -919,6 +919,7 @@ github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2022-12-01/adminis github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2022-12-01/databases github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2022-12-01/firewallrules github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/servers +github.com/hashicorp/go-azure-sdk/resource-manager/postgresql/2023-06-01-preview/virtualendpoints github.com/hashicorp/go-azure-sdk/resource-manager/postgresqlhsc/2022-11-08/clusters github.com/hashicorp/go-azure-sdk/resource-manager/postgresqlhsc/2022-11-08/configurations github.com/hashicorp/go-azure-sdk/resource-manager/postgresqlhsc/2022-11-08/firewallrules diff --git a/website/docs/r/postgresql_flexible_server_virtual_endpoint.html.markdown b/website/docs/r/postgresql_flexible_server_virtual_endpoint.html.markdown new file mode 100644 index 000000000000..0b99bd2984ef --- /dev/null +++ b/website/docs/r/postgresql_flexible_server_virtual_endpoint.html.markdown @@ -0,0 +1,95 @@ +--- +subcategory: "Database" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_postgresql_flexible_server_virtual_endpoint" +description: |- + Manages a Virtual Endpoint on a PostgreSQL Flexible Server +--- + +# azurerm_postgresql_flexible_server_virtual_endpoint + +Allows you to create a Virtual Endpoint associated with a Postgres Flexible Replica. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "East US" +} + +resource "azurerm_postgresql_flexible_server" "example" { + name = "example" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + version = "16" + public_network_access_enabled = false + administrator_login = "psqladmin" + administrator_password = "H@Sh1CoR3!" + zone = "1" + + storage_mb = 32768 + storage_tier = "P30" + + sku_name = "GP_Standard_D2ads_v5" +} + +resource "azurerm_postgresql_flexible_server" "example_replica" { + name = "example-replica" + resource_group_name = azurerm_postgresql_flexible_server.example.resource_group_name + location = azurerm_postgresql_flexible_server.example.location + create_mode = "Replica" + source_server_id = azurerm_postgresql_flexible_server.example.id + version = "16" + public_network_access_enabled = false + zone = "1" + storage_mb = 32768 + storage_tier = "P30" + + sku_name = "GP_Standard_D2ads_v5" +} + +resource "azurerm_postgresql_flexible_server_virtual_endpoint" "example" { + name = "example-endpoint-1" + source_server_id = azurerm_postgresql_flexible_server.example.id + replica_server_id = azurerm_postgresql_flexible_server.example_replica.id + type = "ReadWrite" +} +``` + +-> **Note:** If creating multiple replicas, an error can occur if virtual endpoints are created before all replicas have been completed. To avoid this error, use a `depends_on` property on `azurerm_postgresql_flexible_server_virtual_endpoint` that references all Postgres Flexible Server Replicas. + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Virtual Endpoint + +* `source_server_id` - (Required) The Resource ID of the *Source* Postgres Flexible Server this should be associated with. + +* `replica_server_id` - (Required) The Resource ID of the *Replica* Postgres Flexible Server this should be associated with + +* `type` - (Required) The type of Virtual Endpoint. Currently only `ReadWrite` is supported. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the PostgreSQL Flexible Virtual Endpoint. + +## 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 PostgreSQL Flexible Virtual Endpoint. +* `update` - (Defaults to 30 minutes) Used when updating the PostgreSQL Flexible Virtual Endpoint. +* `read` - (Defaults to 5 minutes) Used when retrieving the PostgreSQL Flexible Virtual Endpoint. +* `delete` - (Defaults to 30 minutes) Used when deleting the PostgreSQL Flexible Virtual Endpoint. + +## Import + +A PostgreSQL Flexible Virtual Endpoint can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_postgresql_flexible_server_virtual_endpoint.example subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.DBForPostgreSql/flexibleServers/server1/virtualendpoints/endpoint1 +```