Skip to content

Commit 462e521

Browse files
authored
new resource "azurerm_data_factory_managed_private_endpoint" (#12618)
fix #12364
1 parent e00dcac commit 462e521

12 files changed

+817
-14
lines changed

azurerm/internal/services/datafactory/client/client.go

+19-14
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import (
66
)
77

88
type Client struct {
9-
DatasetClient *datafactory.DatasetsClient
10-
FactoriesClient *datafactory.FactoriesClient
11-
IntegrationRuntimesClient *datafactory.IntegrationRuntimesClient
12-
LinkedServiceClient *datafactory.LinkedServicesClient
13-
ManagedVirtualNetworksClient *datafactory.ManagedVirtualNetworksClient
14-
PipelinesClient *datafactory.PipelinesClient
15-
TriggersClient *datafactory.TriggersClient
9+
DatasetClient *datafactory.DatasetsClient
10+
FactoriesClient *datafactory.FactoriesClient
11+
IntegrationRuntimesClient *datafactory.IntegrationRuntimesClient
12+
LinkedServiceClient *datafactory.LinkedServicesClient
13+
ManagedPrivateEndpointsClient *datafactory.ManagedPrivateEndpointsClient
14+
ManagedVirtualNetworksClient *datafactory.ManagedVirtualNetworksClient
15+
PipelinesClient *datafactory.PipelinesClient
16+
TriggersClient *datafactory.TriggersClient
1617
}
1718

1819
func NewClient(o *common.ClientOptions) *Client {
@@ -28,6 +29,9 @@ func NewClient(o *common.ClientOptions) *Client {
2829
LinkedServiceClient := datafactory.NewLinkedServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
2930
o.ConfigureClient(&LinkedServiceClient.Client, o.ResourceManagerAuthorizer)
3031

32+
ManagedPrivateEndpointsClient := datafactory.NewManagedPrivateEndpointsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
33+
o.ConfigureClient(&ManagedPrivateEndpointsClient.Client, o.ResourceManagerAuthorizer)
34+
3135
ManagedVirtualNetworksClient := datafactory.NewManagedVirtualNetworksClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
3236
o.ConfigureClient(&ManagedVirtualNetworksClient.Client, o.ResourceManagerAuthorizer)
3337

@@ -38,12 +42,13 @@ func NewClient(o *common.ClientOptions) *Client {
3842
o.ConfigureClient(&TriggersClient.Client, o.ResourceManagerAuthorizer)
3943

4044
return &Client{
41-
DatasetClient: &DatasetClient,
42-
FactoriesClient: &FactoriesClient,
43-
IntegrationRuntimesClient: &IntegrationRuntimesClient,
44-
LinkedServiceClient: &LinkedServiceClient,
45-
ManagedVirtualNetworksClient: &ManagedVirtualNetworksClient,
46-
PipelinesClient: &PipelinesClient,
47-
TriggersClient: &TriggersClient,
45+
DatasetClient: &DatasetClient,
46+
FactoriesClient: &FactoriesClient,
47+
IntegrationRuntimesClient: &IntegrationRuntimesClient,
48+
LinkedServiceClient: &LinkedServiceClient,
49+
ManagedPrivateEndpointsClient: &ManagedPrivateEndpointsClient,
50+
ManagedVirtualNetworksClient: &ManagedVirtualNetworksClient,
51+
PipelinesClient: &PipelinesClient,
52+
TriggersClient: &TriggersClient,
4853
}
4954
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package datafactory
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory"
9+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
10+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
11+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
12+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/datafactory/parse"
13+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/datafactory/validate"
14+
networkValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/network/validate"
15+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/pluginsdk"
16+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
17+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
18+
)
19+
20+
func resourceDataFactoryManagedPrivateEndpoint() *pluginsdk.Resource {
21+
return &pluginsdk.Resource{
22+
Create: resourceDataFactoryManagedPrivateEndpointCreate,
23+
Read: resourceDataFactoryManagedPrivateEndpointRead,
24+
Delete: resourceDataFactoryManagedPrivateEndpointDelete,
25+
26+
Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error {
27+
_, err := parse.ManagedPrivateEndpointID(id)
28+
return err
29+
}),
30+
31+
Timeouts: &pluginsdk.ResourceTimeout{
32+
Create: pluginsdk.DefaultTimeout(30 * time.Minute),
33+
Read: pluginsdk.DefaultTimeout(5 * time.Minute),
34+
Delete: pluginsdk.DefaultTimeout(30 * time.Minute),
35+
},
36+
37+
Schema: map[string]*pluginsdk.Schema{
38+
"name": {
39+
Type: pluginsdk.TypeString,
40+
Required: true,
41+
ForceNew: true,
42+
ValidateFunc: validate.DataFactoryManagedPrivateEndpointName(),
43+
},
44+
45+
"data_factory_id": {
46+
Type: pluginsdk.TypeString,
47+
Required: true,
48+
ForceNew: true,
49+
ValidateFunc: validate.DataFactoryID,
50+
},
51+
52+
"target_resource_id": {
53+
Type: pluginsdk.TypeString,
54+
Required: true,
55+
ForceNew: true,
56+
ValidateFunc: azure.ValidateResourceID,
57+
},
58+
59+
"subresource_name": {
60+
Type: pluginsdk.TypeString,
61+
Required: true,
62+
ForceNew: true,
63+
ValidateFunc: networkValidate.PrivateLinkSubResourceName,
64+
},
65+
},
66+
}
67+
}
68+
69+
func resourceDataFactoryManagedPrivateEndpointCreate(d *pluginsdk.ResourceData, meta interface{}) error {
70+
client := meta.(*clients.Client).DataFactory.ManagedPrivateEndpointsClient
71+
managedVirtualNetworksClient := meta.(*clients.Client).DataFactory.ManagedVirtualNetworksClient
72+
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
73+
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
74+
defer cancel()
75+
76+
dataFactoryId, err := parse.DataFactoryID(d.Get("data_factory_id").(string))
77+
if err != nil {
78+
return err
79+
}
80+
81+
managedVirtualNetworkName, err := getManagedVirtualNetworkName(ctx, managedVirtualNetworksClient, dataFactoryId.ResourceGroup, dataFactoryId.FactoryName)
82+
if err != nil {
83+
return err
84+
}
85+
if managedVirtualNetworkName == nil {
86+
return fmt.Errorf("managed Private endpoints are only available after managed virtual network for %s is enabled", dataFactoryId)
87+
}
88+
89+
id := parse.NewManagedPrivateEndpointID(subscriptionId, dataFactoryId.ResourceGroup, dataFactoryId.FactoryName, *managedVirtualNetworkName, d.Get("name").(string))
90+
existing, err := getManagedPrivateEndpoint(ctx, client, id.ResourceGroup, id.FactoryName, *managedVirtualNetworkName, id.Name)
91+
if err != nil {
92+
return fmt.Errorf("checking for presence of existing %s: %+v", id, err)
93+
}
94+
if existing != nil {
95+
return tf.ImportAsExistsError("azurerm_data_factory_managed_private_endpoint", id.ID())
96+
}
97+
98+
managedPrivateEndpoint := datafactory.ManagedPrivateEndpointResource{
99+
Properties: &datafactory.ManagedPrivateEndpoint{
100+
PrivateLinkResourceID: utils.String(d.Get("target_resource_id").(string)),
101+
GroupID: utils.String(d.Get("subresource_name").(string)),
102+
},
103+
}
104+
105+
if _, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.FactoryName, id.ManagedVirtualNetworkName, id.Name, managedPrivateEndpoint, ""); err != nil {
106+
return fmt.Errorf("creating %s: %+v", id, err)
107+
}
108+
109+
d.SetId(id.ID())
110+
111+
return resourceDataFactoryManagedPrivateEndpointRead(d, meta)
112+
}
113+
114+
func resourceDataFactoryManagedPrivateEndpointRead(d *pluginsdk.ResourceData, meta interface{}) error {
115+
client := meta.(*clients.Client).DataFactory.ManagedPrivateEndpointsClient
116+
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
117+
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
118+
defer cancel()
119+
120+
id, err := parse.ManagedPrivateEndpointID(d.Id())
121+
if err != nil {
122+
return err
123+
}
124+
125+
resp, err := client.Get(ctx, id.ResourceGroup, id.FactoryName, id.ManagedVirtualNetworkName, id.Name, "")
126+
if err != nil {
127+
if utils.ResponseWasNotFound(resp.Response) {
128+
d.SetId("")
129+
return nil
130+
}
131+
132+
return fmt.Errorf("retrieving %s: %+v", id, err)
133+
}
134+
135+
d.Set("name", id.Name)
136+
d.Set("data_factory_id", parse.NewDataFactoryID(subscriptionId, id.ResourceGroup, id.FactoryName).ID())
137+
138+
if props := resp.Properties; props != nil {
139+
d.Set("target_resource_id", props.PrivateLinkResourceID)
140+
d.Set("subresource_name", props.GroupID)
141+
}
142+
143+
return nil
144+
}
145+
146+
func resourceDataFactoryManagedPrivateEndpointDelete(d *pluginsdk.ResourceData, meta interface{}) error {
147+
client := meta.(*clients.Client).DataFactory.ManagedPrivateEndpointsClient
148+
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
149+
defer cancel()
150+
151+
id, err := parse.ManagedPrivateEndpointID(d.Id())
152+
if err != nil {
153+
return err
154+
}
155+
156+
if _, err := client.Delete(ctx, id.ResourceGroup, id.FactoryName, id.ManagedVirtualNetworkName, id.Name); err != nil {
157+
return fmt.Errorf("deleting %s: %+v", id, err)
158+
}
159+
160+
return nil
161+
}
162+
163+
// if ManagedPrivateEndpoint not exist, get rest api will return 400 bad request
164+
// invoke list rets api and then filter by name
165+
func getManagedPrivateEndpoint(ctx context.Context, client *datafactory.ManagedPrivateEndpointsClient, resourceGroupName, factoryName, managedVirtualNetworkName, name string) (*datafactory.ManagedPrivateEndpointResource, error) {
166+
iter, err := client.ListByFactoryComplete(ctx, resourceGroupName, factoryName, managedVirtualNetworkName)
167+
if err != nil {
168+
return nil, err
169+
}
170+
for iter.NotDone() {
171+
managedPrivateEndpoint := iter.Value()
172+
if managedPrivateEndpoint.Name != nil && *managedPrivateEndpoint.Name == name {
173+
return &managedPrivateEndpoint, nil
174+
}
175+
176+
if err := iter.NextWithContext(ctx); err != nil {
177+
return nil, err
178+
}
179+
}
180+
return nil, nil
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package datafactory_test
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"testing"
7+
8+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
9+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance/check"
10+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
11+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/datafactory/parse"
12+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/pluginsdk"
13+
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
14+
)
15+
16+
type ManagedPrivateEndpointResource struct{}
17+
18+
func TestAccDataFactoryManagedPrivateEndpoint_basic(t *testing.T) {
19+
data := acceptance.BuildTestData(t, "azurerm_data_factory_managed_private_endpoint", "test")
20+
r := ManagedPrivateEndpointResource{}
21+
22+
data.ResourceTest(t, r, []acceptance.TestStep{
23+
{
24+
Config: r.basic(data),
25+
Check: acceptance.ComposeTestCheckFunc(
26+
check.That(data.ResourceName).ExistsInAzure(r),
27+
),
28+
},
29+
data.ImportStep(),
30+
})
31+
}
32+
33+
func TestAccDataFactoryManagedPrivateEndpoint_requiresImport(t *testing.T) {
34+
data := acceptance.BuildTestData(t, "azurerm_data_factory_managed_private_endpoint", "test")
35+
r := ManagedPrivateEndpointResource{}
36+
37+
data.ResourceTest(t, r, []acceptance.TestStep{
38+
{
39+
Config: r.basic(data),
40+
Check: acceptance.ComposeTestCheckFunc(
41+
check.That(data.ResourceName).ExistsInAzure(r),
42+
),
43+
},
44+
data.RequiresImportErrorStep(r.requiresImport),
45+
})
46+
}
47+
48+
func (r ManagedPrivateEndpointResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
49+
id, err := parse.ManagedPrivateEndpointID(state.ID)
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
iter, err := client.DataFactory.ManagedPrivateEndpointsClient.ListByFactoryComplete(ctx, id.ResourceGroup, id.FactoryName, id.ManagedVirtualNetworkName)
55+
if err != nil {
56+
return nil, fmt.Errorf("listing %s: %+v", id, err)
57+
}
58+
for iter.NotDone() {
59+
managedPrivateEndpoint := iter.Value()
60+
if managedPrivateEndpoint.Name != nil && *managedPrivateEndpoint.Name == id.Name {
61+
return utils.Bool(true), nil
62+
}
63+
64+
if err := iter.NextWithContext(ctx); err != nil {
65+
return nil, err
66+
}
67+
}
68+
return utils.Bool(false), nil
69+
}
70+
71+
func (r ManagedPrivateEndpointResource) basic(data acceptance.TestData) string {
72+
template := r.template(data)
73+
return fmt.Sprintf(`
74+
%s
75+
76+
resource "azurerm_data_factory_managed_private_endpoint" "test" {
77+
name = "acctestEndpoint%d"
78+
data_factory_id = azurerm_data_factory.test.id
79+
target_resource_id = azurerm_storage_account.test.id
80+
subresource_name = "blob"
81+
}
82+
`, template, data.RandomInteger)
83+
}
84+
85+
func (r ManagedPrivateEndpointResource) requiresImport(data acceptance.TestData) string {
86+
config := r.basic(data)
87+
return fmt.Sprintf(`
88+
%s
89+
90+
resource "azurerm_data_factory_managed_private_endpoint" "import" {
91+
name = azurerm_data_factory_managed_private_endpoint.test.name
92+
data_factory_id = azurerm_data_factory_managed_private_endpoint.test.data_factory_id
93+
target_resource_id = azurerm_data_factory_managed_private_endpoint.test.target_resource_id
94+
subresource_name = azurerm_data_factory_managed_private_endpoint.test.subresource_name
95+
}
96+
`, config)
97+
}
98+
99+
func (r ManagedPrivateEndpointResource) template(data acceptance.TestData) string {
100+
return fmt.Sprintf(`
101+
provider "azurerm" {
102+
features {}
103+
}
104+
105+
resource "azurerm_resource_group" "test" {
106+
name = "acctestRG-adf-%d"
107+
location = "%s"
108+
}
109+
110+
resource "azurerm_data_factory" "test" {
111+
name = "acctestdf%d"
112+
location = azurerm_resource_group.test.location
113+
resource_group_name = azurerm_resource_group.test.name
114+
managed_virtual_network_enabled = true
115+
}
116+
117+
resource "azurerm_storage_account" "test" {
118+
name = "acctestacc%s"
119+
resource_group_name = azurerm_resource_group.test.name
120+
location = azurerm_resource_group.test.location
121+
account_kind = "BlobStorage"
122+
account_tier = "Standard"
123+
account_replication_type = "LRS"
124+
}
125+
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomString)
126+
}

0 commit comments

Comments
 (0)