1# ------------------------------------
2# Copyright (c) Microsoft Corporation.
3# Licensed under the MIT License.
4# ------------------------------------
5import asyncio
6import os
7from azure.keyvault.certificates.aio import CertificateClient
8from azure.keyvault.certificates import CertificatePolicy
9from azure.identity.aio import DefaultAzureCredential
10from azure.core.exceptions import HttpResponseError
11
12# ----------------------------------------------------------------------------------------------------------
13# Prerequisites:
14# 1. An Azure Key Vault (https://docs.microsoft.com/en-us/azure/key-vault/quick-create-cli)
15#
16# 2. azure-keyvault-certificates and azure-identity packages (pip install these)
17#
18# 3. Set Environment variables AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, VAULT_URL
19#    (See https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/keyvault/azure-keyvault-keys#authenticate-the-client)
20#
21# ----------------------------------------------------------------------------------------------------------
22# Sample - demonstrates the basic backup and restore operations on a vault(certificates) resource for Azure Key Vault
23#
24# 1. Create a certificate (create_certificate)
25#
26# 2. Backup a certificate (backup_certificate)
27#
28# 3. Delete a certificate (delete_certificate)
29#
30# 4. Purge a certificate (purge_deleted_certificate)
31#
32# 5. Restore a certificate (restore_certificate_backup)
33# ----------------------------------------------------------------------------------------------------------
34
35
36async def run_sample():
37    # Instantiate a certificate client that will be used to call the service.
38    # Notice that the client is using default Azure credentials.
39    # To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
40    # 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials.
41    vault_url = os.environ["VAULT_URL"]
42    credential = DefaultAzureCredential()
43    client = CertificateClient(vault_url=vault_url, credential=credential)
44    try:
45
46        print("\n.. Create Certificate")
47        cert_name = "BackupRestoreCertificate"
48
49        # Let's create a certificate for your key vault.
50        # if the certificate already exists in the Key Vault, then a new version of the certificate is created.
51        # Awaiting the call returns a KeyVaultCertificate if creation is successful, and a CertificateOperation if not.
52        certificate = await client.create_certificate(
53            certificate_name=cert_name, policy=CertificatePolicy.get_default()
54        )
55
56        print("Certificate with name '{0}' created.".format(certificate.name))
57
58        # Backups are good to have, if in case certificates gets deleted accidentally.
59        # For long term storage, it is ideal to write the backup to a file.
60        print("\n.. Create a backup for an existing certificate")
61        certificate_backup = await client.backup_certificate(cert_name)
62        print("Backup created for certificate with name '{0}'.".format(cert_name))
63
64        # The storage account certificate is no longer in use, so you can delete it.
65        print("\n.. Delete the certificate")
66        await client.delete_certificate(cert_name)
67        print("Deleted certificate with name '{0}'".format(cert_name))
68
69        # Purge the deleted certificate.
70        # The purge will take some time, so wait before restoring the backup to avoid a conflict.
71        print("\n.. Purge the certificate")
72        await client.purge_deleted_certificate(cert_name)
73        await asyncio.sleep(60)
74        print("Purged certificate with name '{0}'".format(cert_name))
75
76        # In the future, if the certificate is required again, we can use the backup value to restore it in the Key Vault.
77        print("\n.. Restore the certificate using the backed up certificate bytes")
78        certificate = await client.restore_certificate_backup(certificate_backup)
79        print("Restored certificate with name '{0}'".format(certificate.name))
80
81    except HttpResponseError as e:
82        print("\nrun_sample has caught an error. {0}".format(e.message))
83
84    finally:
85        print("\nrun_sample done")
86        await credential.close()
87        await client.close()
88
89
90if __name__ == "__main__":
91    try:
92        loop = asyncio.get_event_loop()
93        loop.run_until_complete(run_sample())
94        loop.close()
95
96    except Exception as e:
97        print("Top level Error: {0}".format(str(e)))
98