Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dataprotection] Onboard Custom Tags for Backup Instances #5314

Merged
merged 2 commits into from
Sep 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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