Skip to content

Commit 406de0f

Browse files
committed
new resrouce azurerm_data_protection_backup_instance_data_lake_storage
1 parent 98c5ba6 commit 406de0f

File tree

5 files changed

+677
-0
lines changed

5 files changed

+677
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright IBM Corp. 2014, 2025
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package custompollers
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-sdk/resource-manager/dataprotection/2025-09-01/backupinstanceresources"
13+
"github.com/hashicorp/go-azure-sdk/sdk/client/pollers"
14+
)
15+
16+
var _ pollers.PollerType = &dataProtectionBackupInstancePoller{}
17+
18+
type dataProtectionBackupInstancePoller struct {
19+
client *backupinstanceresources.BackupInstanceResourcesClient
20+
id backupinstanceresources.BackupInstanceId
21+
}
22+
23+
var (
24+
backupInstancePollingSuccess = pollers.PollResult{
25+
PollInterval: 30 * time.Second,
26+
Status: pollers.PollingStatusSucceeded,
27+
}
28+
backupInstancePollingInProgress = pollers.PollResult{
29+
HttpResponse: nil,
30+
PollInterval: 30 * time.Second,
31+
Status: pollers.PollingStatusInProgress,
32+
}
33+
)
34+
35+
func NewDataProtectionBackupInstancePoller(client *backupinstanceresources.BackupInstanceResourcesClient, id backupinstanceresources.BackupInstanceId) *dataProtectionBackupInstancePoller {
36+
return &dataProtectionBackupInstancePoller{
37+
client: client,
38+
id: id,
39+
}
40+
}
41+
42+
func (p dataProtectionBackupInstancePoller) Poll(ctx context.Context) (*pollers.PollResult, error) {
43+
resp, err := p.client.BackupInstancesGet(ctx, p.id)
44+
if err != nil {
45+
return nil, fmt.Errorf("retrieving %s: %+v", p.id, err)
46+
}
47+
48+
if resp.Model == nil || resp.Model.Properties == nil {
49+
return nil, fmt.Errorf("polling for %s: `model` or `properties` was nil", p.id)
50+
}
51+
52+
protectionState := pointer.From(resp.Model.Properties.CurrentProtectionState)
53+
if protectionState == backupinstanceresources.CurrentProtectionStateProtectionConfigured {
54+
return &backupInstancePollingSuccess, nil
55+
}
56+
57+
return &backupInstancePollingInProgress, nil
58+
}
Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
// Copyright IBM Corp. 2014, 2025
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package dataprotection
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-helpers/resourcemanager/commonids"
14+
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
15+
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
16+
"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
17+
"github.com/hashicorp/go-azure-sdk/resource-manager/dataprotection/2025-09-01/backupinstanceresources"
18+
"github.com/hashicorp/go-azure-sdk/resource-manager/dataprotection/2025-09-01/backupvaultresources"
19+
"github.com/hashicorp/go-azure-sdk/resource-manager/dataprotection/2025-09-01/basebackuppolicyresources"
20+
"github.com/hashicorp/go-azure-sdk/sdk/client/pollers"
21+
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
22+
"github.com/hashicorp/terraform-provider-azurerm/internal/services/dataprotection/custompollers"
23+
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
24+
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
25+
)
26+
27+
//go:generate go run ../../tools/generator-tests resourceidentity -resource-name data_protection_backup_instance_data_lake_storage -service-package-name dataprotection -properties "name" -compare-values "subscription_id:vault_id,resource_group_name:vault_id,backup_vault_name:vault_id"
28+
29+
type BackupInstanceDataLakeStorageModel struct {
30+
Name string `tfschema:"name"`
31+
Location string `tfschema:"location"`
32+
VaultId string `tfschema:"vault_id"`
33+
BackupPolicyId string `tfschema:"backup_policy_id"`
34+
StorageAccountId string `tfschema:"storage_account_id"`
35+
ProtectionState string `tfschema:"protection_state"`
36+
}
37+
38+
type DataProtectionBackupInstanceDataLakeStorageResource struct{}
39+
40+
var (
41+
_ sdk.Resource = DataProtectionBackupInstanceDataLakeStorageResource{}
42+
_ sdk.ResourceWithIdentity = DataProtectionBackupInstanceDataLakeStorageResource{}
43+
)
44+
45+
func (r DataProtectionBackupInstanceDataLakeStorageResource) Identity() resourceids.ResourceId {
46+
return &backupinstanceresources.BackupInstanceId{}
47+
}
48+
49+
func (r DataProtectionBackupInstanceDataLakeStorageResource) ResourceType() string {
50+
return "azurerm_data_protection_backup_instance_data_lake_storage"
51+
}
52+
53+
func (r DataProtectionBackupInstanceDataLakeStorageResource) ModelObject() interface{} {
54+
return &BackupInstanceDataLakeStorageModel{}
55+
}
56+
57+
func (r DataProtectionBackupInstanceDataLakeStorageResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
58+
return backupinstanceresources.ValidateBackupInstanceID
59+
}
60+
61+
func (r DataProtectionBackupInstanceDataLakeStorageResource) Arguments() map[string]*pluginsdk.Schema {
62+
return map[string]*pluginsdk.Schema{
63+
"name": {
64+
Type: pluginsdk.TypeString,
65+
Required: true,
66+
ForceNew: true,
67+
ValidateFunc: validation.StringIsNotEmpty,
68+
},
69+
70+
"location": commonschema.Location(),
71+
72+
"vault_id": commonschema.ResourceIDReferenceRequiredForceNew(&basebackuppolicyresources.BackupVaultId{}),
73+
74+
"backup_policy_id": commonschema.ResourceIDReferenceRequired(&basebackuppolicyresources.BackupPolicyId{}),
75+
76+
"storage_account_id": commonschema.ResourceIDReferenceRequiredForceNew(&commonids.StorageAccountId{}),
77+
}
78+
}
79+
80+
func (r DataProtectionBackupInstanceDataLakeStorageResource) Attributes() map[string]*pluginsdk.Schema {
81+
return map[string]*pluginsdk.Schema{
82+
"protection_state": {
83+
Type: pluginsdk.TypeString,
84+
Computed: true,
85+
},
86+
}
87+
}
88+
89+
func (r DataProtectionBackupInstanceDataLakeStorageResource) Create() sdk.ResourceFunc {
90+
return sdk.ResourceFunc{
91+
Timeout: 60 * time.Minute,
92+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
93+
var model BackupInstanceDataLakeStorageModel
94+
if err := metadata.Decode(&model); err != nil {
95+
return fmt.Errorf("decoding: %+v", err)
96+
}
97+
98+
client := metadata.Client.DataProtection.BackupInstanceClient
99+
100+
vaultId, err := backupvaultresources.ParseBackupVaultID(model.VaultId)
101+
if err != nil {
102+
return err
103+
}
104+
105+
id := backupinstanceresources.NewBackupInstanceID(vaultId.SubscriptionId, vaultId.ResourceGroupName, vaultId.BackupVaultName, model.Name)
106+
107+
existing, err := client.BackupInstancesGet(ctx, id)
108+
if err != nil {
109+
if !response.WasNotFound(existing.HttpResponse) {
110+
return fmt.Errorf("checking for existing %s: %+v", id, err)
111+
}
112+
}
113+
114+
if !response.WasNotFound(existing.HttpResponse) {
115+
return metadata.ResourceRequiresImport(r.ResourceType(), id)
116+
}
117+
118+
storageAccountId, err := commonids.ParseStorageAccountID(model.StorageAccountId)
119+
if err != nil {
120+
return err
121+
}
122+
123+
policyId, err := basebackuppolicyresources.ParseBackupPolicyID(model.BackupPolicyId)
124+
if err != nil {
125+
return err
126+
}
127+
128+
parameters := backupinstanceresources.BackupInstanceResource{
129+
Properties: &backupinstanceresources.BackupInstance{
130+
DataSourceInfo: backupinstanceresources.Datasource{
131+
DatasourceType: pointer.To("Microsoft.Storage/storageAccounts/adlsBlobServices"),
132+
ObjectType: pointer.To("Datasource"),
133+
ResourceID: storageAccountId.ID(),
134+
ResourceLocation: pointer.To(location.Normalize(model.Location)),
135+
ResourceName: pointer.To(storageAccountId.StorageAccountName),
136+
ResourceType: pointer.To("Microsoft.Storage/storageAccounts"),
137+
ResourceUri: pointer.To(storageAccountId.ID()),
138+
},
139+
DataSourceSetInfo: &backupinstanceresources.DatasourceSet{
140+
DatasourceType: pointer.To("Microsoft.Storage/storageAccounts/adlsBlobServices"),
141+
ObjectType: pointer.To("DatasourceSet"),
142+
ResourceID: storageAccountId.ID(),
143+
ResourceLocation: pointer.To(location.Normalize(model.Location)),
144+
ResourceName: pointer.To(storageAccountId.StorageAccountName),
145+
ResourceType: pointer.To("Microsoft.Storage/storageAccounts"),
146+
ResourceUri: pointer.To(storageAccountId.ID()),
147+
},
148+
FriendlyName: pointer.To(id.BackupInstanceName),
149+
PolicyInfo: backupinstanceresources.PolicyInfo{
150+
PolicyId: policyId.ID(),
151+
},
152+
},
153+
}
154+
155+
if err := client.BackupInstancesCreateOrUpdateThenPoll(ctx, id, parameters, backupinstanceresources.DefaultBackupInstancesCreateOrUpdateOperationOptions()); err != nil {
156+
return fmt.Errorf("creating %s: %+v", id, err)
157+
}
158+
159+
pollerType := custompollers.NewDataProtectionBackupInstancePoller(client, id)
160+
poller := pollers.NewPoller(pollerType, 30*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow)
161+
if err := poller.PollUntilDone(ctx); err != nil {
162+
return err
163+
}
164+
165+
metadata.SetID(id)
166+
if err := pluginsdk.SetResourceIdentityData(metadata.ResourceData, &id); err != nil {
167+
return err
168+
}
169+
return nil
170+
},
171+
}
172+
}
173+
174+
func (r DataProtectionBackupInstanceDataLakeStorageResource) Read() sdk.ResourceFunc {
175+
return sdk.ResourceFunc{
176+
Timeout: 5 * time.Minute,
177+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
178+
client := metadata.Client.DataProtection.BackupInstanceClient
179+
180+
id, err := backupinstanceresources.ParseBackupInstanceID(metadata.ResourceData.Id())
181+
if err != nil {
182+
return err
183+
}
184+
185+
resp, err := client.BackupInstancesGet(ctx, *id)
186+
if err != nil {
187+
if response.WasNotFound(resp.HttpResponse) {
188+
return metadata.MarkAsGone(*id)
189+
}
190+
191+
return fmt.Errorf("retrieving %s: %+v", *id, err)
192+
}
193+
194+
vaultId := backupvaultresources.NewBackupVaultID(id.SubscriptionId, id.ResourceGroupName, id.BackupVaultName)
195+
196+
state := BackupInstanceDataLakeStorageModel{
197+
Name: id.BackupInstanceName,
198+
VaultId: vaultId.ID(),
199+
}
200+
201+
if model := resp.Model; model != nil {
202+
if props := model.Properties; props != nil {
203+
state.Location = location.NormalizeNilable(props.DataSourceInfo.ResourceLocation)
204+
205+
storageAccountId, err := commonids.ParseStorageAccountIDInsensitively(props.DataSourceInfo.ResourceID)
206+
if err != nil {
207+
return err
208+
}
209+
state.StorageAccountId = storageAccountId.ID()
210+
211+
backupPolicyId, err := basebackuppolicyresources.ParseBackupPolicyIDInsensitively(props.PolicyInfo.PolicyId)
212+
if err != nil {
213+
return err
214+
}
215+
state.BackupPolicyId = backupPolicyId.ID()
216+
217+
state.ProtectionState = pointer.FromEnum(props.CurrentProtectionState)
218+
}
219+
}
220+
221+
if err := pluginsdk.SetResourceIdentityData(metadata.ResourceData, id); err != nil {
222+
return err
223+
}
224+
return metadata.Encode(&state)
225+
},
226+
}
227+
}
228+
229+
func (r DataProtectionBackupInstanceDataLakeStorageResource) Update() sdk.ResourceFunc {
230+
return sdk.ResourceFunc{
231+
Timeout: 60 * time.Minute,
232+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
233+
client := metadata.Client.DataProtection.BackupInstanceClient
234+
235+
id, err := backupinstanceresources.ParseBackupInstanceID(metadata.ResourceData.Id())
236+
if err != nil {
237+
return err
238+
}
239+
240+
var model BackupInstanceDataLakeStorageModel
241+
if err := metadata.Decode(&model); err != nil {
242+
return fmt.Errorf("decoding: %+v", err)
243+
}
244+
245+
existing, err := client.BackupInstancesGet(ctx, *id)
246+
if err != nil {
247+
if response.WasNotFound(existing.HttpResponse) {
248+
return metadata.MarkAsGone(id)
249+
}
250+
251+
return fmt.Errorf("reading %s: %+v", *id, err)
252+
}
253+
254+
if existing.Model == nil {
255+
return fmt.Errorf("retrieving %s: `model` was nil", id)
256+
}
257+
258+
parameters := *existing.Model
259+
260+
if metadata.ResourceData.HasChange("backup_policy_id") {
261+
policyId, err := basebackuppolicyresources.ParseBackupPolicyID(model.BackupPolicyId)
262+
if err != nil {
263+
return err
264+
}
265+
parameters.Properties.PolicyInfo.PolicyId = policyId.ID()
266+
}
267+
268+
if err := client.BackupInstancesCreateOrUpdateThenPoll(ctx, *id, parameters, backupinstanceresources.DefaultBackupInstancesCreateOrUpdateOperationOptions()); err != nil {
269+
return fmt.Errorf("updating %s: %+v", id, err)
270+
}
271+
272+
pollerType := custompollers.NewDataProtectionBackupInstancePoller(client, *id)
273+
poller := pollers.NewPoller(pollerType, 30*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow)
274+
if err := poller.PollUntilDone(ctx); err != nil {
275+
return err
276+
}
277+
278+
return nil
279+
},
280+
}
281+
}
282+
283+
func (r DataProtectionBackupInstanceDataLakeStorageResource) Delete() sdk.ResourceFunc {
284+
return sdk.ResourceFunc{
285+
Timeout: 60 * time.Minute,
286+
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
287+
client := metadata.Client.DataProtection.BackupInstanceClient
288+
289+
id, err := backupinstanceresources.ParseBackupInstanceID(metadata.ResourceData.Id())
290+
if err != nil {
291+
return err
292+
}
293+
294+
err = client.BackupInstancesDeleteThenPoll(ctx, *id, backupinstanceresources.DefaultBackupInstancesDeleteOperationOptions())
295+
if err != nil {
296+
return fmt.Errorf("deleting %s: %+v", *id, err)
297+
}
298+
299+
return nil
300+
},
301+
}
302+
}

0 commit comments

Comments
 (0)