Skip to content

Commit

Permalink
[Dataprotection] Onboard Custom Tags for Backup Instances (#5314)
Browse files Browse the repository at this point in the history
* added tags to dpp BIs

* updated history.rst

Co-authored-by: Akshay Neema <[email protected]>
  • Loading branch information
akshayneema and Akshay Neema authored Sep 7, 2022
1 parent f423ab9 commit a86b501
Show file tree
Hide file tree
Showing 52 changed files with 5,178 additions and 3,331 deletions.
4 changes: 4 additions & 0 deletions src/dataprotection/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
Release History
===============
0.6.0
++++++
* `az dataprotection backup-instance initialize`: Add optional `--tags` parameter

0.5.0
++++++
* `az dataprotection backup-instance update-msi-permissions`: New command to grant missing permissions to backup vault MSI
Expand Down
4 changes: 2 additions & 2 deletions src/dataprotection/azext_dataprotection/generated/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,8 @@
-9f70-7708a3a2283b/resourceGroups/000pikumar/providers/Microsoft.DataProtection/Backupvaults/PratikPrivatePreviewVault1\
/backupPolicies/PratikPolicy1" --policy-parameters data-store-parameters-list={"dataStoreType":"OperationalStore","obje\
ctType":"AzureOperationalStoreParameters","resourceGroupId":"/subscriptions/f75d8d8b-6735-4697-82e1-1a7a3ff0d5d4/resour\
ceGroups/viveksipgtest"} --validation-type "ShallowValidation" --resource-group "000pikumar" --vault-name \
"PratikPrivatePreviewVault1"
ceGroups/viveksipgtest"} --validation-type "ShallowValidation" --tags key1="val1" --resource-group "000pikumar" \
--vault-name "PratikPrivatePreviewVault1"
"""

helps['dataprotection backup-instance delete'] = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def load_arguments(self, _):
c.argument('vault_name', type=str, help='The name of the backup vault.')
c.argument('backup_instance_name', options_list=['--name', '-n', '--backup-instance-name'], type=str,
help='The name of the backup instance')
c.argument('tags', tags_type)
c.argument('friendly_name', type=str, help='Gets or sets the Backup Instance friendly name.')
c.argument('data_source_info', action=AddDataSourceInfo, nargs='+', help='Gets or sets the data source '
'information.')
Expand Down
2 changes: 2 additions & 0 deletions src/dataprotection/azext_dataprotection/generated/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def dataprotection_backup_instance_create(client,
resource_group_name,
vault_name,
backup_instance_name,
tags=None,
friendly_name=None,
data_source_info=None,
data_source_set_info=None,
Expand All @@ -156,6 +157,7 @@ def dataprotection_backup_instance_create(client,
datasource_auth_credentials = all_datasource_auth_credentials[0] if len(all_datasource_auth_credentials) == 1 else \
None
parameters = {}
parameters['tags'] = tags
parameters['properties'] = {}
parameters['properties']['friendly_name'] = friendly_name
parameters['properties']['data_source_info'] = data_source_info
Expand Down
1 change: 1 addition & 0 deletions src/dataprotection/azext_dataprotection/manual/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def load_arguments(self, _):
c.argument('secret_store_type', arg_type=get_enum_type(get_secret_store_type_values()), help="Specify the secret store type to use for authentication")
c.argument('secret_store_uri', type=str, help="specify the secret store uri to use for authentication")
c.argument('snapshot_resource_group_name', options_list=['--snapshot-resource-group-name', '--snapshot-rg'], type=str, help="Name of the resource group in which the backup snapshots should be stored")
c.argument('tags', tags_type)

with self.argument_context('dataprotection backup-instance update-policy') as c:
c.argument('backup_instance_name', type=str, help="Backup instance name.")
Expand Down
5 changes: 3 additions & 2 deletions src/dataprotection/azext_dataprotection/manual/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def dataprotection_backup_instance_validate_for_backup(client, vault_name, resou

def dataprotection_backup_instance_initialize(datasource_type, datasource_id, datasource_location, policy_id,
secret_store_type=None, secret_store_uri=None,
snapshot_resource_group_name=None):
snapshot_resource_group_name=None, tags=None):
datasource_info = helper.get_datasource_info(datasource_type, datasource_id, datasource_location)
datasourceset_info = None
manifest = helper.load_manifest(datasource_type)
Expand Down Expand Up @@ -231,7 +231,8 @@ def dataprotection_backup_instance_initialize(datasource_type, datasource_id, da
"policy_info": policy_info,
"datasource_auth_credentials": datasource_auth_credentials_info,
"object_type": "BackupInstance"
}
},
"tags": tags
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ def setup(test):
"rgid": "/subscriptions/" + account_res["id"] + "/resourceGroups/sarath-rg"
})

# run the below commands only in record mode
time.sleep(10)
# test.cmd('az role assignment create --assignee "{principalId}" --role "Disk Backup Reader" --scope "{diskid}"')
# test.cmd('az role assignment create --assignee "{principalId}" --role "Disk Snapshot Contributor" --scope "{rgid}"')


def test_resource_guard(test):
test.cmd('az dataprotection resource-guard create -g "{rg}" -n "{resourceGuardName}"', checks=[
test.check('name', "{resourceGuardName}")
Expand Down Expand Up @@ -115,6 +109,73 @@ def create_policy(test):
test.cmd('az dataprotection backup-policy create -n diskhourlypolicy --policy "{policyjson}" -g "{rg}" --vault-name "{vaultName}"')


def initialize_backup_instance(test):
backup_instance_guid = "b7e6f082-b310-11eb-8f55-9cfce85d4fae"
backup_instance_json = test.cmd('az dataprotection backup-instance initialize --datasource-type AzureDisk'
' -l centraluseuap --policy-id "{policyid}" --datasource-id "{diskid}" --snapshot-rg "{rg}" --tags Owner=dppclitest').get_output_in_json()
backup_instance_json["backup_instance_name"] = test.kwargs['diskname'] + "-" + test.kwargs['diskname'] + "-" + backup_instance_guid
test.kwargs.update({
"backup_instance_json": backup_instance_json,
"backup_instance_name": backup_instance_json["backup_instance_name"]
})

backup_instance_json = test.cmd('az dataprotection backup-instance initialize --datasource-type AzureBlob'
' -l centraluseuap --policy-id "{storagepolicyid}" --datasource-id "{storageaccountid}"').get_output_in_json()
backup_instance_json["backup_instance_name"] = test.kwargs['storageaccountname'] + "-" + test.kwargs['storageaccountname'] + "-" + backup_instance_guid
test.kwargs.update({
"storage_backup_instance_json": backup_instance_json,
"storage_backup_instance_name": backup_instance_json["backup_instance_name"]
})

backup_instance_guid = "faec6818-0720-11ec-bd1b-c8f750f92764"
backup_instance_json = test.cmd('az dataprotection backup-instance initialize --datasource-type AzureDatabaseForPostgreSQL'
' -l centraluseuap --policy-id "{serverpolicyid}" --datasource-id "{ossdbid}" --secret-store-type AzureKeyVault --secret-store-uri "{secretstoreuri}"').get_output_in_json()
backup_instance_json["backup_instance_name"] = test.kwargs['ossserver'] + "-" + test.kwargs['ossdb'] + "-" + backup_instance_guid
test.kwargs.update({
"server_backup_instance_json": backup_instance_json,
"server_backup_instance_name": backup_instance_json["backup_instance_name"]
})


def assign_permissions_and_validate(test):
# run only in record mode - grant permission

# test.cmd('az dataprotection backup-instance update-msi-permissions --datasource-type AzureDisk --operation Backup --permissions-scope Resource -g "{rg}" --vault-name "{vaultName}" --backup-instance "{backup_instance_json}" --yes').get_output_in_json()
# test.cmd('az dataprotection backup-instance update-msi-permissions --datasource-type AzureBlob --operation Backup --permissions-scope Resource -g "{rg}" --vault-name "{vaultName}" --backup-instance "{storage_backup_instance_json}" --yes').get_output_in_json()
# test.cmd('az dataprotection backup-instance update-msi-permissions --datasource-type AzureDatabaseForPostgreSQL --permissions-scope Resource -g "{serverrgname}" --vault-name "{servervaultname}" --operation Backup --backup-instance "{server_backup_instance_json}" --keyvault-id "{keyvaultid}" --yes')
# test.cmd('az role assignment create --assignee "{principalId}" --role "Disk Restore Operator" --scope "{rgid}"')
# time.sleep(120) # Wait for permissions to propagate

test.cmd('az dataprotection backup-instance validate-for-backup -g "{rg}" --vault-name "{vaultName}" --backup-instance "{backup_instance_json}"', checks=[
test.check('objectType', 'OperationJobExtendedInfo')
])
test.cmd('az dataprotection backup-instance validate-for-backup -g "{rg}" --vault-name "{vaultName}" --backup-instance "{storage_backup_instance_json}"', checks=[
test.check('objectType', 'OperationJobExtendedInfo')
])
test.cmd('az dataprotection backup-instance validate-for-backup -g "{serverrgname}" --vault-name "{servervaultname}" --backup-instance "{server_backup_instance_json}"', checks=[
test.check('objectType', 'OperationJobExtendedInfo')
])

# run only in record mode - reset firewall rule

# test.cmd('az postgres server firewall-rule delete -g "{serverrgname}" -s "{ossserver}" -n AllowAllWindowsAzureIps --yes')


def configure_backup(test):
test.cmd('az dataprotection backup-instance create -g "{rg}" --vault-name "{vaultName}" --backup-instance "{backup_instance_json}"')

backup_instance_res = test.cmd('az dataprotection backup-instance list -g "{rg}" --vault-name "{vaultName}" --query "[0].properties.protectionStatus"').get_output_in_json()
protection_status = backup_instance_res["status"]
while protection_status != "ProtectionConfigured":
time.sleep(10)
backup_instance_res = test.cmd('az dataprotection backup-instance list -g "{rg}" --vault-name "{vaultName}" --query "[0].properties.protectionStatus"').get_output_in_json()
protection_status = backup_instance_res["status"]

test.cmd('az dataprotection backup-instance create -g "{rg}" --vault-name "{vaultName}" --backup-instance "{storage_backup_instance_json}"')

time.sleep(30)


def stop_resume_protection(test):
test.cmd('az dataprotection backup-instance stop-protection -n "{backup_instance_name}" -g "{rg}" --vault-name "{vaultName}"')

Expand Down Expand Up @@ -147,7 +208,6 @@ def trigger_disk_backup(test):
job_status = None
test.kwargs.update({"backup_job_id": response_json["jobId"]})
while job_status != "Completed":
# run the below code only in record mode
time.sleep(10)
job_response = test.cmd('az dataprotection job show --ids "{backup_job_id}"').get_output_in_json()
job_status = job_response["properties"]["status"]
Expand All @@ -174,82 +234,13 @@ def trigger_disk_restore(test):
job_status = None
test.kwargs.update({"backup_job_id": response_json["jobId"]})
while job_status != "Completed":
# run the below code only in record mode
time.sleep(10)
job_response = test.cmd('az dataprotection job show --ids "{backup_job_id}"').get_output_in_json()
job_status = job_response["properties"]["status"]
if job_status not in ["Completed", "InProgress"]:
raise Exception("Undefined job status received")


def initialize_backup_instance(test):
backup_instance_guid = "b7e6f082-b310-11eb-8f55-9cfce85d4fae"
backup_instance_json = test.cmd('az dataprotection backup-instance initialize --datasource-type AzureDisk'
' -l centraluseuap --policy-id "{policyid}" --datasource-id "{diskid}" --snapshot-rg "{rg}"').get_output_in_json()
backup_instance_json["backup_instance_name"] = test.kwargs['diskname'] + "-" + test.kwargs['diskname'] + "-" + backup_instance_guid
test.kwargs.update({
"backup_instance_json": backup_instance_json,
"backup_instance_name": backup_instance_json["backup_instance_name"]
})

backup_instance_json = test.cmd('az dataprotection backup-instance initialize --datasource-type AzureBlob'
' -l centraluseuap --policy-id "{storagepolicyid}" --datasource-id "{storageaccountid}"').get_output_in_json()
backup_instance_json["backup_instance_name"] = test.kwargs['storageaccountname'] + "-" + test.kwargs['storageaccountname'] + "-" + backup_instance_guid
test.kwargs.update({
"storage_backup_instance_json": backup_instance_json,
"storage_backup_instance_name": backup_instance_json["backup_instance_name"]
})

backup_instance_guid = "faec6818-0720-11ec-bd1b-c8f750f92764"
backup_instance_json = test.cmd('az dataprotection backup-instance initialize --datasource-type AzureDatabaseForPostgreSQL'
' -l centraluseuap --policy-id "{serverpolicyid}" --datasource-id "{ossdbid}" --secret-store-type AzureKeyVault --secret-store-uri "{secretstoreuri}"').get_output_in_json()
backup_instance_json["backup_instance_name"] = test.kwargs['ossserver'] + "-" + test.kwargs['ossdb'] + "-" + backup_instance_guid
test.kwargs.update({
"server_backup_instance_json": backup_instance_json,
"server_backup_instance_name": backup_instance_json["backup_instance_name"]
})


def assign_permissions_and_validate(test):
test.cmd('az dataprotection backup-instance validate-for-backup -g "{rg}" --vault-name "{vaultName}" --backup-instance "{backup_instance_json}"', expect_failure=True)
test.cmd('az dataprotection backup-instance validate-for-backup -g "{rg}" --vault-name "{vaultName}" --backup-instance "{storage_backup_instance_json}"', expect_failure=True)
test.cmd('az dataprotection backup-instance validate-for-backup -g "{serverrgname}" --vault-name "{servervaultname}" --backup-instance "{server_backup_instance_json}"', expect_failure=True)
# test.cmd('az dataprotection backup-instance update-msi-permissions --datasource-type AzureDisk --operation Backup --permissions-scope Resource -g "{rg}" --vault-name "{vaultName}" --backup-instance "{backup_instance_json}" --yes').get_output_in_json()
# test.cmd('az dataprotection backup-instance update-msi-permissions --datasource-type AzureBlob --operation Backup --permissions-scope Resource -g "{rg}" --vault-name "{vaultName}" --backup-instance "{storage_backup_instance_json}" --yes').get_output_in_json()
# test.cmd('az dataprotection backup-instance update-msi-permissions --datasource-type AzureDatabaseForPostgreSQL --permissions-scope Resource -g "{serverrgname}" --vault-name "{servervaultname}" --operation Backup --backup-instance "{server_backup_instance_json}" --keyvault-id "{keyvaultid}" --yes')
# test.cmd('az role assignment create --assignee "{principalId}" --role "Disk Restore Operator" --scope "{rgid}"')
# time.sleep(120) # Wait for permissions to propagate
test.cmd('az dataprotection backup-instance validate-for-backup -g "{rg}" --vault-name "{vaultName}" --backup-instance "{backup_instance_json}"', checks=[
test.check('objectType', 'OperationJobExtendedInfo')
])
test.cmd('az dataprotection backup-instance validate-for-backup -g "{rg}" --vault-name "{vaultName}" --backup-instance "{storage_backup_instance_json}"', checks=[
test.check('objectType', 'OperationJobExtendedInfo')
])
test.cmd('az dataprotection backup-instance validate-for-backup -g "{serverrgname}" --vault-name "{servervaultname}" --backup-instance "{server_backup_instance_json}"', checks=[
test.check('objectType', 'OperationJobExtendedInfo')
])
# test.cmd('az role assignment delete --assignee "{servervaultprincipalid}" --role Reader --scope "{serverid}"')
test.cmd('az postgres server firewall-rule delete -g "{serverrgname}" -s "{ossserver}" -n AllowAllWindowsAzureIps --yes')
# test.cmd('az keyvault delete-policy -g "{serverrgname}" -n "{keyvaultname}" --object-id "{servervaultprincipalid}"')


def configure_backup(test):
test.cmd('az dataprotection backup-instance create -g "{rg}" --vault-name "{vaultName}" --backup-instance "{backup_instance_json}"')

backup_instance_res = test.cmd('az dataprotection backup-instance list -g "{rg}" --vault-name "{vaultName}" --query "[0].properties.protectionStatus"').get_output_in_json()
protection_status = backup_instance_res["status"]
while protection_status != "ProtectionConfigured":
# run the below line only in record mode
time.sleep(10)
backup_instance_res = test.cmd('az dataprotection backup-instance list -g "{rg}" --vault-name "{vaultName}" --query "[0].properties.protectionStatus"').get_output_in_json()
protection_status = backup_instance_res["status"]

test.cmd('az dataprotection backup-instance create -g "{rg}" --vault-name "{vaultName}" --backup-instance "{storage_backup_instance_json}"')

# run the below line only in record mode
time.sleep(30)


def delete_backup(test):
test.cmd('az dataprotection backup-instance delete -g "{rg}" --vault-name "{vaultName}" -n "{backup_instance_name}" --yes')
test.cmd('az dataprotection backup-instance delete -g "{rg}" --vault-name "{vaultName}" -n "{storage_backup_instance_name}" --yes')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def step_backup_instance_create(test, checks=None):
'erationalStoreParameters","resourceGroupId":"/subscriptions/f75d8d8b-6735-4697-82e1-1a7a3ff0d5d4/resource'
'Groups/viveksipgtest"}} '
'--validation-type "ShallowValidation" '
'--tags key1="val1" '
'--resource-group "{rg_2}" '
'--vault-name "{myBackupVault}"',
checks=[])
Expand Down
Loading

0 comments on commit a86b501

Please sign in to comment.