Skip to content

Commit 3a856c9

Browse files
xuzhang3NotTheEvilOne
authored andcommitted
[New Resource] azurerm_machine_learning_workspace_network_outbound_rule_service_tag (hashicorp#27931)
* add support for MLW vnet outbound rule service tag * fix lint * remove local val * update document and refactor code * update documentation and nil check
1 parent d1bb300 commit 3a856c9

5 files changed

Lines changed: 670 additions & 2 deletions

internal/services/machinelearning/machine_learning_workspace_network_outbound_rule_fqdn_resource_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,12 @@ func TestAccMachineLearningWorkspaceNetworkOutboundRuleFqdn_requiresImport(t *te
7676
}
7777

7878
func (r WorkspaceNetworkOutboundRuleFqdnResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
79-
maangedNetworkClient := client.MachineLearning.ManagedNetwork
8079
id, err := managednetwork.ParseOutboundRuleID(state.ID)
8180
if err != nil {
8281
return nil, err
8382
}
8483

85-
resp, err := maangedNetworkClient.SettingsRuleGet(ctx, *id)
84+
resp, err := client.MachineLearning.ManagedNetwork.SettingsRuleGet(ctx, *id)
8685
if err != nil {
8786
if response.WasNotFound(resp.HttpResponse) {
8887
return utils.Bool(false), nil
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package machinelearning
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"time"
10+
11+
"github.com/hashicorp/go-azure-helpers/lang/pointer"
12+
"github.com/hashicorp/go-azure-helpers/lang/response"
13+
"github.com/hashicorp/go-azure-sdk/resource-manager/machinelearningservices/2024-04-01/managednetwork"
14+
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
15+
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
16+
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
17+
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
18+
)
19+
20+
var _ sdk.ResourceWithUpdate = WorkspaceNetworkOutboundRuleServiceTag{}
21+
22+
type MachineLearningWorkspaceServiceTagOutboundRuleModel struct {
23+
Name string `tfschema:"name"`
24+
WorkspaceId string `tfschema:"workspace_id"`
25+
ServiceTag string `tfschema:"service_tag"`
26+
Protocol string `tfschema:"protocol"`
27+
PortRanges string `tfschema:"port_ranges"`
28+
}
29+
30+
type WorkspaceNetworkOutboundRuleServiceTag struct{}
31+
32+
var _ sdk.Resource = WorkspaceNetworkOutboundRuleServiceTag{}
33+
34+
func (r WorkspaceNetworkOutboundRuleServiceTag) ResourceType() string {
35+
return "azurerm_machine_learning_workspace_network_outbound_rule_service_tag"
36+
}
37+
38+
func (r WorkspaceNetworkOutboundRuleServiceTag) ModelObject() interface{} {
39+
return &MachineLearningWorkspaceServiceTagOutboundRuleModel{}
40+
}
41+
42+
func (r WorkspaceNetworkOutboundRuleServiceTag) IDValidationFunc() pluginsdk.SchemaValidateFunc {
43+
return managednetwork.ValidateOutboundRuleID
44+
}
45+
46+
func (r WorkspaceNetworkOutboundRuleServiceTag) Arguments() map[string]*pluginsdk.Schema {
47+
arguments := map[string]*pluginsdk.Schema{
48+
"name": {
49+
Type: pluginsdk.TypeString,
50+
Required: true,
51+
ForceNew: true,
52+
ValidateFunc: validation.StringIsNotEmpty,
53+
},
54+
55+
"workspace_id": {
56+
Type: pluginsdk.TypeString,
57+
Required: true,
58+
ForceNew: true,
59+
ValidateFunc: managednetwork.ValidateWorkspaceID,
60+
},
61+
62+
"service_tag": {
63+
Type: pluginsdk.TypeString,
64+
Required: true,
65+
ValidateFunc: validation.StringInSlice([]string{
66+
"AppConfiguration",
67+
"AppService",
68+
"AzureActiveDirectory",
69+
"AzureAdvancedThreatProtection",
70+
"AzureArcInfrastructure",
71+
"AzureAttestation",
72+
"AzureBackup",
73+
"AzureBotService",
74+
"AzureContainerRegistry",
75+
"AzureCosmosDB",
76+
"AzureDataLake",
77+
"AzureDevSpaces",
78+
"AzureInformationProtection",
79+
"AzureIoTHub",
80+
"AzureKeyVault",
81+
"AzureManagedGrafana",
82+
"AzureMonitor",
83+
"AzureOpenDatasets",
84+
"AzurePlatformDNS",
85+
"AzurePlatformIMDS",
86+
"AzurePlatformLKM",
87+
"AzureResourceManager",
88+
"AzureSignalR",
89+
"AzureSiteRecovery",
90+
"AzureSpringCloud",
91+
"AzureStack",
92+
"AzureUpdateDelivery",
93+
"DataFactoryManagement",
94+
"EventHub",
95+
"GuestAndHybridManagement",
96+
"M365ManagementActivityApi",
97+
"M365ManagementActivityApi",
98+
"MicrosoftAzureFluidRelay",
99+
"MicrosoftCloudAppSecurity",
100+
"MicrosoftContainerRegistry",
101+
"PowerPlatformInfra",
102+
"ServiceBus",
103+
"Sql",
104+
"Storage",
105+
"WindowsAdminCenter",
106+
"AppServiceManagement",
107+
"AutonomousDevelopmentPlatform",
108+
"AzureActiveDirectoryDomainServices",
109+
"AzureCloud",
110+
"AzureConnectors",
111+
"AzureContainerAppsService",
112+
"AzureDatabricks",
113+
"AzureDeviceUpdate",
114+
"AzureEventGrid",
115+
"AzureFrontDoor.Frontend",
116+
"AzureFrontDoor.Backend",
117+
"AzureFrontDoor.FirstParty",
118+
"AzureHealthcareAPIs",
119+
"AzureLoadBalancer",
120+
"AzureMachineLearning",
121+
"AzureSphere",
122+
"AzureWebPubSub",
123+
"BatchNodeManagement",
124+
"ChaosStudio",
125+
"CognitiveServicesFrontend",
126+
"CognitiveServicesManagement",
127+
"DataFactory",
128+
"Dynamics365ForMarketingEmail",
129+
"Dynamics365BusinessCentral",
130+
"EOPExternalPublishedIPs",
131+
"Internet",
132+
"LogicApps",
133+
"Marketplace",
134+
"MicrosoftDefenderForEndpoint",
135+
"PowerBI",
136+
"PowerQueryOnline",
137+
"ServiceFabric",
138+
"SqlManagement",
139+
"StorageSyncService",
140+
"WindowsVirtualDesktop",
141+
"VirtualNetwork",
142+
}, false),
143+
},
144+
145+
"protocol": {
146+
Type: pluginsdk.TypeString,
147+
Required: true,
148+
ValidateFunc: validation.StringInSlice([]string{"*", "TCP", "UDP", "ICMP"}, false),
149+
},
150+
151+
"port_ranges": {
152+
Type: pluginsdk.TypeString,
153+
Required: true,
154+
ValidateFunc: validation.StringIsNotEmpty,
155+
},
156+
}
157+
return arguments
158+
}
159+
160+
func (r WorkspaceNetworkOutboundRuleServiceTag) Attributes() map[string]*pluginsdk.Schema {
161+
return map[string]*pluginsdk.Schema{}
162+
}
163+
164+
func (r WorkspaceNetworkOutboundRuleServiceTag) Create() sdk.ResourceFunc {
165+
return sdk.ResourceFunc{
166+
Timeout: 30 * time.Minute,
167+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
168+
client := metadata.Client.MachineLearning.ManagedNetwork
169+
subscriptionId := metadata.Client.Account.SubscriptionId
170+
171+
var model MachineLearningWorkspaceServiceTagOutboundRuleModel
172+
if err := metadata.Decode(&model); err != nil {
173+
return fmt.Errorf("decoding: %+v", err)
174+
}
175+
176+
workspaceId, err := managednetwork.ParseWorkspaceID(model.WorkspaceId)
177+
if err != nil {
178+
return err
179+
}
180+
id := managednetwork.NewOutboundRuleID(subscriptionId, workspaceId.ResourceGroupName, workspaceId.WorkspaceName, model.Name)
181+
existing, err := client.SettingsRuleGet(ctx, id)
182+
if err != nil {
183+
if !response.WasNotFound(existing.HttpResponse) {
184+
return fmt.Errorf("checking for presence of existing %s: %+v", id, err)
185+
}
186+
}
187+
if !response.WasNotFound(existing.HttpResponse) {
188+
return tf.ImportAsExistsError("azurerm_machine_learning_workspace_network_outbound_rule_service_tag", id.ID())
189+
}
190+
191+
outboundRule := managednetwork.OutboundRuleBasicResource{
192+
Name: pointer.To(model.Name),
193+
Type: pointer.To(string(managednetwork.RuleTypeServiceTag)),
194+
Properties: managednetwork.ServiceTagOutboundRule{
195+
Category: pointer.To(managednetwork.RuleCategoryUserDefined),
196+
Destination: &managednetwork.ServiceTagDestination{
197+
PortRanges: &model.PortRanges,
198+
Protocol: &model.Protocol,
199+
ServiceTag: &model.ServiceTag,
200+
},
201+
},
202+
}
203+
204+
if err = client.SettingsRuleCreateOrUpdateThenPoll(ctx, id, outboundRule); err != nil {
205+
return fmt.Errorf("creating %s: %+v", id, err)
206+
}
207+
208+
metadata.SetID(id)
209+
return nil
210+
},
211+
}
212+
}
213+
214+
func (r WorkspaceNetworkOutboundRuleServiceTag) Update() sdk.ResourceFunc {
215+
return sdk.ResourceFunc{
216+
Timeout: 30 * time.Minute,
217+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
218+
client := metadata.Client.MachineLearning.ManagedNetwork
219+
id, err := managednetwork.ParseOutboundRuleID(metadata.ResourceData.Id())
220+
221+
var model MachineLearningWorkspaceServiceTagOutboundRuleModel
222+
if err := metadata.Decode(&model); err != nil {
223+
return fmt.Errorf("decoding: %+v", err)
224+
}
225+
226+
if err != nil {
227+
return err
228+
}
229+
230+
existing, err := client.SettingsRuleGet(ctx, *id)
231+
if err != nil {
232+
return fmt.Errorf("retrieving %s: %+v", id, err)
233+
}
234+
235+
if existing.Model == nil {
236+
return fmt.Errorf("retrieving %s: `model` was nil", id)
237+
}
238+
239+
if existing.Model.Properties == nil {
240+
return fmt.Errorf("retrieving %s: `properties` was nil", id)
241+
}
242+
243+
payload := existing.Model
244+
serviceTagOutboundRule := payload.Properties.(managednetwork.ServiceTagOutboundRule)
245+
if metadata.ResourceData.HasChange("service_tag") {
246+
serviceTagOutboundRule.Destination.ServiceTag = pointer.To(model.ServiceTag)
247+
}
248+
249+
if metadata.ResourceData.HasChange("protocol") {
250+
serviceTagOutboundRule.Destination.Protocol = pointer.To(model.Protocol)
251+
}
252+
253+
if metadata.ResourceData.HasChange("port_ranges") {
254+
serviceTagOutboundRule.Destination.PortRanges = pointer.To(model.PortRanges)
255+
}
256+
257+
payload.Properties = serviceTagOutboundRule
258+
if err := client.SettingsRuleCreateOrUpdateThenPoll(ctx, *id, *payload); err != nil {
259+
return fmt.Errorf("updating %s: %+v", id, err)
260+
}
261+
return nil
262+
},
263+
}
264+
}
265+
266+
func (r WorkspaceNetworkOutboundRuleServiceTag) Read() sdk.ResourceFunc {
267+
return sdk.ResourceFunc{
268+
Timeout: 5 * time.Minute,
269+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
270+
client := metadata.Client.MachineLearning.ManagedNetwork
271+
272+
id, err := managednetwork.ParseOutboundRuleID(metadata.ResourceData.Id())
273+
if err != nil {
274+
return err
275+
}
276+
277+
resp, err := client.SettingsRuleGet(ctx, *id)
278+
if err != nil {
279+
if response.WasNotFound(resp.HttpResponse) {
280+
return metadata.MarkAsGone(id)
281+
}
282+
283+
return fmt.Errorf("retrieving %s: %+v", *id, err)
284+
}
285+
286+
state := MachineLearningWorkspaceServiceTagOutboundRuleModel{
287+
Name: id.OutboundRuleName,
288+
WorkspaceId: managednetwork.NewWorkspaceID(id.SubscriptionId, id.ResourceGroupName, id.WorkspaceName).ID(),
289+
}
290+
291+
if model := resp.Model; model != nil {
292+
if props := model.Properties; props != nil {
293+
if prop, ok := props.(managednetwork.ServiceTagOutboundRule); ok && prop.Destination != nil {
294+
state.ServiceTag = pointer.From(prop.Destination.ServiceTag)
295+
state.Protocol = pointer.From(prop.Destination.Protocol)
296+
state.PortRanges = pointer.From(prop.Destination.PortRanges)
297+
}
298+
}
299+
}
300+
return metadata.Encode(&state)
301+
},
302+
}
303+
}
304+
305+
func (r WorkspaceNetworkOutboundRuleServiceTag) Delete() sdk.ResourceFunc {
306+
return sdk.ResourceFunc{
307+
Timeout: 30 * time.Minute,
308+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
309+
client := metadata.Client.MachineLearning.ManagedNetwork
310+
311+
id, err := managednetwork.ParseOutboundRuleID(metadata.ResourceData.Id())
312+
if err != nil {
313+
return err
314+
}
315+
316+
if err := client.SettingsRuleDeleteThenPoll(ctx, *id); err != nil {
317+
return fmt.Errorf("deleting %s: %+v", id, err)
318+
}
319+
return nil
320+
},
321+
}
322+
}

0 commit comments

Comments
 (0)