예제 #1
0
    def test_get_cloud_from_endpoint(self):

        public_azure_dict = {
            "galleryEndpoint": "https://gallery.azure.com",
            "graphEndpoint": "https://graph.windows.net/",
            "portalEndpoint": "https://portal.azure.com",
            "authentication": {
                "loginEndpoint":
                "https://login.windows.net",
                "audiences": [
                    "https://management.core.windows.net/",
                    "https://management.azure.com/"
                ]
            }
        }

        httpretty.register_uri(
            httpretty.GET,
            "https://management.azure.com/metadata/endpoints?api-version=1.0",
            body=json.dumps(public_azure_dict),
            content_type="application/json")

        cloud = azure_cloud.get_cloud_from_metadata_endpoint(
            "https://management.azure.com")
        self.assertEqual("https://management.azure.com", cloud.name)
        self.assertEqual("https://management.azure.com",
                         cloud.endpoints.management)
        self.assertEqual("https://management.azure.com",
                         cloud.endpoints.resource_manager)
        self.assertEqual("https://gallery.azure.com", cloud.endpoints.gallery)
        self.assertEqual("https://graph.windows.net/",
                         cloud.endpoints.active_directory_graph_resource_id)
        self.assertEqual("https://login.windows.net",
                         cloud.endpoints.active_directory)

        session = requests.Session()
        cloud = azure_cloud.get_cloud_from_metadata_endpoint(
            "https://management.azure.com", "Public Azure", session)
        self.assertEqual("Public Azure", cloud.name)
        self.assertEqual("https://management.azure.com",
                         cloud.endpoints.management)
        self.assertEqual("https://management.azure.com",
                         cloud.endpoints.resource_manager)
        self.assertEqual("https://gallery.azure.com", cloud.endpoints.gallery)
        self.assertEqual("https://graph.windows.net/",
                         cloud.endpoints.active_directory_graph_resource_id)
        self.assertEqual("https://login.windows.net",
                         cloud.endpoints.active_directory)

        with self.assertRaises(azure_cloud.MetadataEndpointError):
            azure_cloud.get_cloud_from_metadata_endpoint(
                "https://something.azure.com")

        with self.assertRaises(azure_cloud.CloudEndpointNotSetException):
            cloud.endpoints.batch_resource_id

        with self.assertRaises(azure_cloud.CloudSuffixNotSetException):
            cloud.suffixes.sql_server_hostname

        self.assertIsNotNone(str(cloud))
예제 #2
0
파일: azurearm.py 프로젝트: arminsama/bos
def _determine_auth(**kwargs):
    '''
    Acquire Azure ARM Credentials
    '''
    if 'profile' in kwargs:
        azure_credentials = __salt__['config.option'](kwargs['profile'])
        kwargs.update(azure_credentials)

    service_principal_creds_kwargs = ['client_id', 'secret', 'tenant']
    user_pass_creds_kwargs = ['username', 'password']

    try:
        if kwargs.get('cloud_environment') and kwargs.get(
                'cloud_environment').startswith('http'):
            cloud_env = get_cloud_from_metadata_endpoint(
                kwargs['cloud_environment'])
        else:
            cloud_env_module = importlib.import_module(
                'msrestazure.azure_cloud')
            cloud_env = getattr(
                cloud_env_module,
                kwargs.get('cloud_environment', 'AZURE_PUBLIC_CLOUD'))
    except (AttributeError, ImportError, MetadataEndpointError):
        raise sys.exit(
            'The Azure cloud environment {0} is not available.'.format(
                kwargs['cloud_environment']))

    if set(service_principal_creds_kwargs).issubset(kwargs):
        if not (kwargs['client_id'] and kwargs['secret'] and kwargs['tenant']):
            raise SaltInvocationError(
                'The client_id, secret, and tenant parameters must all be '
                'populated if using service principals.')
        else:
            credentials = ServicePrincipalCredentials(
                kwargs['client_id'],
                kwargs['secret'],
                tenant=kwargs['tenant'],
                cloud_environment=cloud_env)
    elif set(user_pass_creds_kwargs).issubset(kwargs):
        if not (kwargs['username'] and kwargs['password']):
            raise SaltInvocationError(
                'The username and password parameters must both be '
                'populated if using username/password authentication.')
        else:
            credentials = UserPassCredentials(kwargs['username'],
                                              kwargs['password'],
                                              cloud_environment=cloud_env)
    else:
        raise SaltInvocationError(
            'Unable to determine credentials. '
            'A subscription_id with username and password, '
            'or client_id, secret, and tenant or a profile with the '
            'required parameters populated')

    if 'subscription_id' not in kwargs:
        raise SaltInvocationError('A subscription_id must be specified')

    subscription_id = salt.utils.stringutils.to_str(kwargs['subscription_id'])

    return credentials, subscription_id, cloud_env
    def __init__(self,
                 subscription_id,
                 resource_group,
                 pub_ssh_key_path='~/id_rsa.pub'):
        mystack_cloud = get_cloud_from_metadata_endpoint(
            os.environ['ARM_ENDPOINT'])
        subscription_id = os.environ['AZURE_SUBSCRIPTION_ID']
        credentials = ServicePrincipalCredentials(
            client_id=os.environ['AZURE_CLIENT_ID'],
            secret=os.environ['AZURE_CLIENT_SECRET'],
            tenant=os.environ['AZURE_TENANT_ID'],
            cloud_environment=mystack_cloud)

        self.subscription_id = subscription_id
        self.resource_group = resource_group
        self.dns_label_prefix = self.name_generator.haikunate()

        pub_ssh_key_path = os.path.expanduser(pub_ssh_key_path)
        # Will raise if file not exists or not enough permission
        with open(pub_ssh_key_path, 'r') as pub_ssh_file_fd:
            self.pub_ssh_key = pub_ssh_file_fd.read()

        self.credentials = credentials
        self.client = ResourceManagementClient(
            self.credentials,
            self.subscription_id,
            base_url=mystack_cloud.endpoints.resource_manager)
    def __init__(self,
                 config,
                 resource_group,
                 pub_ssh_key_path='~/id_rsa.pub'):
        mystack_cloud = get_cloud_from_metadata_endpoint(
            config['resourceManagerUrl'])
        credentials = ClientSecretCredential(
            client_id=config['clientId'],
            client_secret=config['clientSecret'],
            tenant_id=config['tenantId'],
            authority=mystack_cloud.endpoints.active_directory)

        self.location = config['location']
        self.subscription_id = config['subscriptionId']
        self.resource_group = resource_group
        self.dns_label_prefix = self.name_generator.haikunate()

        pub_ssh_key_path = os.path.expanduser(pub_ssh_key_path)
        # Will raise if file not exists or not enough permission
        with open(pub_ssh_key_path, 'r') as pub_ssh_file_fd:
            self.pub_ssh_key = pub_ssh_file_fd.read()

        self.credentials = credentials
        scope = "openid profile offline_access" + " " + mystack_cloud.endpoints.active_directory_resource_id + "/.default"
        self.client = ResourceManagementClient(
            credentials,
            self.subscription_id,
            base_url=mystack_cloud.endpoints.resource_manager,
            profile=KnownProfiles.v2020_09_01_hybrid,
            credential_scopes=[scope])
예제 #5
0
    def __init__(self, args):
        self._args = args
        self._cloud_environment = None
        self._compute_client = None
        self._resource_client = None
        self._network_client = None

        self.debug = False
        if args.debug:
            self.debug = True

        self.credentials = self._get_credentials(args)
        if not self.credentials:
            self.fail("Failed to get credentials. Either pass as parameters, set environment variables, "
                      "or define a profile in ~/.azure/credentials.")

        # if cloud_environment specified, look up/build Cloud object
        raw_cloud_env = self.credentials.get('cloud_environment')
        if not raw_cloud_env:
            self._cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD  # SDK default
        else:
            # try to look up "well-known" values via the name attribute on azure_cloud members
            all_clouds = [x[1] for x in inspect.getmembers(azure_cloud) if isinstance(x[1], azure_cloud.Cloud)]
            matched_clouds = [x for x in all_clouds if x.name == raw_cloud_env]
            if len(matched_clouds) == 1:
                self._cloud_environment = matched_clouds[0]
            elif len(matched_clouds) > 1:
                self.fail("Azure SDK failure: more than one cloud matched for cloud_environment name '{0}'".format(raw_cloud_env))
            else:
                if not urlparse.urlparse(raw_cloud_env).scheme:
                    self.fail("cloud_environment must be an endpoint discovery URL or one of {0}".format([x.name for x in all_clouds]))
                try:
                    self._cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(raw_cloud_env)
                except Exception as e:
                    self.fail("cloud_environment {0} could not be resolved: {1}".format(raw_cloud_env, e.message))

        if self.credentials.get('subscription_id', None) is None:
            self.fail("Credentials did not include a subscription_id value.")
        self.log("setting subscription_id")
        self.subscription_id = self.credentials['subscription_id']

        if self.credentials.get('credentials'):
            self.azure_credentials = self.credentials.get('credentials')
        elif self.credentials.get('client_id') and self.credentials.get('secret') and self.credentials.get('tenant'):
            self.azure_credentials = ServicePrincipalCredentials(client_id=self.credentials['client_id'],
                                                                 secret=self.credentials['secret'],
                                                                 tenant=self.credentials['tenant'],
                                                                 cloud_environment=self._cloud_environment)
        elif self.credentials.get('ad_user') is not None and self.credentials.get('password') is not None:
            tenant = self.credentials.get('tenant')
            if not tenant:
                tenant = 'common'
            self.azure_credentials = UserPassCredentials(self.credentials['ad_user'],
                                                         self.credentials['password'],
                                                         tenant=tenant,
                                                         cloud_environment=self._cloud_environment)
        else:
            self.fail("Failed to authenticate with provided credentials. Some attributes were missing. "
                      "Credentials must include client_id, secret and tenant or ad_user and password.")
예제 #6
0
    def __init__(self, args):
        self._args = args
        self._cloud_environment = None
        self._compute_client = None
        self._resource_client = None
        self._network_client = None

        self.debug = False
        if args.debug:
            self.debug = True

        self.credentials = self._get_credentials(args)
        if not self.credentials:
            self.fail("Failed to get credentials. Either pass as parameters, set environment variables, "
                      "or define a profile in ~/.azure/credentials.")

        # if cloud_environment specified, look up/build Cloud object
        raw_cloud_env = self.credentials.get('cloud_environment')
        if not raw_cloud_env:
            self._cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD  # SDK default
        else:
            # try to look up "well-known" values via the name attribute on azure_cloud members
            all_clouds = [x[1] for x in inspect.getmembers(azure_cloud) if isinstance(x[1], azure_cloud.Cloud)]
            matched_clouds = [x for x in all_clouds if x.name == raw_cloud_env]
            if len(matched_clouds) == 1:
                self._cloud_environment = matched_clouds[0]
            elif len(matched_clouds) > 1:
                self.fail("Azure SDK failure: more than one cloud matched for cloud_environment name '{0}'".format(raw_cloud_env))
            else:
                if not urlparse.urlparse(raw_cloud_env).scheme:
                    self.fail("cloud_environment must be an endpoint discovery URL or one of {0}".format([x.name for x in all_clouds]))
                try:
                    self._cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(raw_cloud_env)
                except Exception as e:
                    self.fail("cloud_environment {0} could not be resolved: {1}".format(raw_cloud_env, e.message))

        if self.credentials.get('subscription_id', None) is None:
            self.fail("Credentials did not include a subscription_id value.")
        self.log("setting subscription_id")
        self.subscription_id = self.credentials['subscription_id']

        if self.credentials.get('client_id') is not None and \
           self.credentials.get('secret') is not None and \
           self.credentials.get('tenant') is not None:
            self.azure_credentials = ServicePrincipalCredentials(client_id=self.credentials['client_id'],
                                                                 secret=self.credentials['secret'],
                                                                 tenant=self.credentials['tenant'],
                                                                 cloud_environment=self._cloud_environment)
        elif self.credentials.get('ad_user') is not None and self.credentials.get('password') is not None:
            tenant = self.credentials.get('tenant')
            if not tenant:
                tenant = 'common'
            self.azure_credentials = UserPassCredentials(self.credentials['ad_user'],
                                                         self.credentials['password'],
                                                         tenant=tenant,
                                                         cloud_environment=self._cloud_environment)
        else:
            self.fail("Failed to authenticate with provided credentials. Some attributes were missing. "
                      "Credentials must include client_id, secret and tenant or ad_user and password.")
def get_credentials(config):
    mystack_cloud = get_cloud_from_metadata_endpoint(config['resourceManagerEndpointUrl'])
    subscription_id = config['subscriptionId']
    credentials = ClientSecretCredential(
        client_id = config['clientId'],
        client_secret = config['clientSecret'],
        tenant_id = config['tenantId'],
        authority = mystack_cloud.endpoints.active_directory)

    return credentials, subscription_id, mystack_cloud
예제 #8
0
def get_credentials():
    mystack_cloud = get_cloud_from_metadata_endpoint(
        os.environ['ARM_ENDPOINT'])
    subscription_id = os.environ['AZURE_SUBSCRIPTION_ID']
    credentials = ServicePrincipalCredentials(
        client_id=os.environ['AZURE_CLIENT_ID'],
        secret=os.environ['AZURE_CLIENT_SECRET'],
        tenant=os.environ['AZURE_TENANT_ID'],
        cloud_environment=mystack_cloud)
    return credentials, subscription_id, mystack_cloud
def authenticate_cli():
    #
    # Create all clients with Azure CLI's active subscription
    #

    global mystack_cloud, resource_client, compute_client, storage_client, network_client

    mystack_cloud = get_cloud_from_metadata_endpoint(
        os.environ['ARM_ENDPOINT'])

    resource_client = get_client_from_cli_profile(ResourceManagementClient)
    compute_client = get_client_from_cli_profile(ComputeManagementClient)
    storage_client = get_client_from_cli_profile(StorageManagementClient)
    network_client = get_client_from_cli_profile(NetworkManagementClient)
    def run(self, terms, variables, **kwargs):

        self.set_options(direct=kwargs)

        credentials = {}
        credentials['azure_client_id'] = self.get_option(
            'azure_client_id', None)
        credentials['azure_secret'] = self.get_option('azure_secret', None)
        credentials['azure_tenant'] = self.get_option('azure_tenant', 'common')

        if credentials['azure_client_id'] is None or credentials[
                'azure_secret'] is None:
            raise AnsibleError("Must specify azure_client_id and azure_secret")

        _cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD
        if self.get_option('azure_cloud_environment', None) is not None:
            cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(
                credentials['azure_cloud_environment'])

        try:
            azure_credentials = ServicePrincipalCredentials(
                client_id=credentials['azure_client_id'],
                secret=credentials['azure_secret'],
                tenant=credentials['azure_tenant'],
                resource=_cloud_environment.endpoints.
                active_directory_graph_resource_id)

            client = GraphRbacManagementClient(
                azure_credentials,
                credentials['azure_tenant'],
                base_url=_cloud_environment.endpoints.
                active_directory_graph_resource_id)

            response = list(
                client.service_principals.list(filter="appId eq '{0}'".format(
                    credentials['azure_client_id'])))
            sp = response[0]

            return sp.object_id.split(',')
        except CloudError as ex:
            raise AnsibleError(
                "Failed to get service principal object id: %s" %
                to_native(ex))
        return False
def authenticate_service_principal_token():
    #
    # Create all clients with an Application (service principal) token provider
    #

    global mystack_cloud, resource_client, compute_client, storage_client, network_client

    mystack_cloud = get_cloud_from_metadata_endpoint(
        os.environ['ARM_ENDPOINT'])

    subscription_id = os.environ['AZURE_SUBSCRIPTION_ID']
    credentials = ServicePrincipalCredentials(
        client_id=os.environ['AZURE_CLIENT_ID'],
        secret=os.environ['AZURE_CLIENT_SECRET'],
        tenant=os.environ['AZURE_TENANT_ID'],
        cloud_environment=mystack_cloud)

    # By Default, use AzureStack supported profile
    KnownProfiles.default.use(KnownProfiles.v2019_03_01_hybrid)

    resource_client = ResourceManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    compute_client = ComputeManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    storage_client = StorageManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    network_client = NetworkManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
예제 #12
0
    def run(self, terms, variables, **kwargs):

        #self.set_options(var_options=variables, direct=kwargs)
        self.set_options(direct=kwargs)
        #credentials = _get_credentials(self._options)

        #if len(self._options) > 0:
        #    #raise AnsibleError("self._options is: {0} {1}".format(self._options['azure_client_id'], self._options['azure_secret']))
        #else:
        #    raise AnsibleError("options is null: {0}, {1}".format(kwargs, variables))
        credentials = {}
        credentials['azure_client_id'] = self.get_option('azure_client_id')
        credentials['azure_secret'] = self.get_option('azure_secret')
        credentials['azure_tenant'] = self.get_option('azure_tenant', 'common')

        _cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD
        if self.get_option('azure_cloud_environment', None) is not None:
            cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(
                credentials['azure_cloud_environment'])

        azure_credentials = ServicePrincipalCredentials(
            client_id=credentials['azure_client_id'],
            secret=credentials['azure_secret'],
            tenant=credentials['azure_tenant'],
            #cloud_environment=_cloud_environment,
            resource=_cloud_environment.endpoints.
            active_directory_graph_resource_id)

        #auth_context = AuthenticationContext(_cloud_environment.endpoints.active_directory + '/' + credentials['azure_tenant'])

        # get on behalf of token
        #creds = auth_context.acquire_token_with_client_credentials(_cloud_environment.endpoints.active_directory_graph_resource_id, credentials['azure_client_id'], credentials['azure_secret'])
        #if creds is None:
        #    raise AnsibleError('invalid token')

        #creds = auth_context.acquire_token_with_client_credentials('00000002-0000-0000-c000-000000000000', credentials['azure_client_id'], credentials['azure_secret'])
        #copy_aad_cred = copy.deepcopy(azure_credentials)
        #copy_aad_cred.token['access_token'] = creds['accessToken']
        #        if auth_token is not None:
        #            raise AnsibleError("auth_token is null {0} {1}");
        #        else:
        #            raise AnsibleError("auth_token is: {0}".format(auth_token))

        client = GraphRbacManagementClient(
            azure_credentials,
            credentials['azure_tenant'],
            base_url=_cloud_environment.endpoints.
            active_directory_graph_resource_id)

        if not client:
            raise AnsibleError('invalid client')
        #else:
        #    raise AnsibleError('valid client!')

        try:
            response = list(
                client.service_principals.list(filter="appId eq '{}'".format(
                    credentials['azure_client_id'])))
            sp = response[0]

            #return ''.join(map(str, sp.object_id.split(',')))
            return sp.object_id.split(',')
        except CloudError as ex:
            raise AnsibleError(
                "Failed to get service principal object id: %s" %
                to_native(ex))
        return False
예제 #13
0
def run_example():
    """Resource Group management example."""
    #
    # Create all clients with an Application (service principal) token provider
    #
    mystack_cloud = get_cloud_from_metadata_endpoint(
        os.environ['ARM_ENDPOINT'])

    # Set Storage Endpoint suffix
    arm_url = mystack_cloud.endpoints.resource_manager
    storage_endpoint_suffix = arm_url.replace(arm_url.split(".")[0],
                                              "").strip('./')

    subscription_id = os.environ.get(
        'AZURE_SUBSCRIPTION_ID',
        '11111111-1111-1111-1111-111111111111')  # your Azure Subscription Id
    credentials = ServicePrincipalCredentials(
        client_id=os.environ['AZURE_CLIENT_ID'],
        secret=os.environ['AZURE_CLIENT_SECRET'],
        tenant=os.environ['AZURE_TENANT_ID'],
        cloud_environment=mystack_cloud)

    # By Default, use AzureStack supported profile
    KnownProfiles.default.use(KnownProfiles.v2017_03_09_profile)

    resource_client = ResourceManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    compute_client = ComputeManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    storage_client = StorageManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    network_client = NetworkManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)

    ###########
    # Prepare #
    ###########

    # Create Resource group
    print('\nCreate Resource Group')
    resource_client.resource_groups.create_or_update(GROUP_NAME,
                                                     {'location': LOCATION})

    # Create a storage account
    print('\nCreate a storage account')
    storage_async_operation = storage_client.storage_accounts.create(
        GROUP_NAME, STORAGE_ACCOUNT_NAME, {
            'sku': {
                'name': 'standard_lrs'
            },
            'kind': 'storage',
            'location': LOCATION
        })
    storage_async_operation.wait()

    # Create a NIC
    nic = create_nic(network_client)

    #############
    # VM Sample #
    #############

    # Create Linux VM
    print('\nCreating Linux Virtual Machine')
    vm_parameters = create_vm_parameters(nic.id, VM_REFERENCE['linux'],
                                         storage_endpoint_suffix)
    async_vm_creation = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, vm_parameters)
    async_vm_creation.wait()

    # Tag the VM
    print('\nTag Virtual Machine')
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, {
            'location': LOCATION,
            'tags': {
                'who-rocks': 'python',
                'where': 'on azure'
            }
        })
    async_vm_update.wait()

    # Attach data disk
    print('\nAttach Data Disk')
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, {
            'location': LOCATION,
            'storage_profile': {
                'data_disks': [{
                    'name': 'mydatadisk1',
                    'disk_size_gb': 1,
                    'lun': 0,
                    'vhd': {
                        'uri':
                        "https://{}.blob.{}/vhds/mydatadisk1.vhd".format(
                            STORAGE_ACCOUNT_NAME, storage_endpoint_suffix)
                    },
                    'create_option': 'Empty'
                }]
            }
        })
    async_vm_update.wait()

    # Get the virtual machine by name
    print('\nGet Virtual Machine by Name')
    virtual_machine = compute_client.virtual_machines.get(GROUP_NAME, VM_NAME)

    # Detach data disk
    print('\nDetach Data Disk')
    data_disks = virtual_machine.storage_profile.data_disks
    data_disks[:] = [disk for disk in data_disks if disk.name != 'mydatadisk1']
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, virtual_machine)
    virtual_machine = async_vm_update.result()

    # Deallocating the VM (resize prepare)
    print('\nDeallocating the VM (resize prepare)')
    async_vm_deallocate = compute_client.virtual_machines.deallocate(
        GROUP_NAME, VM_NAME)
    async_vm_deallocate.wait()

    # Update OS disk size by 10Gb
    print('\nUpdate OS disk size')
    # Server is not returning the OS Disk size (None), possible bug in server
    if not virtual_machine.storage_profile.os_disk.disk_size_gb:
        print(
            "\tServer is not returning the OS disk size, possible bug in the server?"
        )
        print("\tAssuming that the OS disk size is 256 GB")
        virtual_machine.storage_profile.os_disk.disk_size_gb = 256

    virtual_machine.storage_profile.os_disk.disk_size_gb += 10
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, virtual_machine)
    virtual_machine = async_vm_update.result()

    # Start the VM
    print('\nStart VM')
    async_vm_start = compute_client.virtual_machines.start(GROUP_NAME, VM_NAME)
    async_vm_start.wait()

    # Restart the VM
    print('\nRestart VM')
    async_vm_restart = compute_client.virtual_machines.restart(
        GROUP_NAME, VM_NAME)
    async_vm_restart.wait()

    # Stop the VM
    print('\nStop VM')
    async_vm_stop = compute_client.virtual_machines.power_off(
        GROUP_NAME, VM_NAME)
    async_vm_stop.wait()

    # List VMs in subscription
    print('\nList VMs in subscription')
    for vm in compute_client.virtual_machines.list_all():
        print("\tVM: {}".format(vm.name))

    # List VM in resource group
    print('\nList VMs in resource group')
    for vm in compute_client.virtual_machines.list(GROUP_NAME):
        print("\tVM: {}".format(vm.name))

    # Delete VM
    print('\nDelete VM')
    async_vm_delete = compute_client.virtual_machines.delete(
        GROUP_NAME, VM_NAME)
    async_vm_delete.wait()

    # Create Windows VM
    print('\nCreating Windows Virtual Machine')
    # Recycling NIC of previous VM
    vm_parameters = create_vm_parameters(nic.id, VM_REFERENCE['windows'],
                                         storage_endpoint_suffix)
    async_vm_creation = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, vm_parameters)
    async_vm_creation.wait()

    input("Press enter to delete this Resource Group.")

    # Delete Resource group and everything in it
    print('\nDelete Resource Group')
    delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME)
    delete_async_operation.wait()
    print("\nDeleted: {}".format(GROUP_NAME))
예제 #14
0
def run_example():
    """Virtual Machine management example."""
    #
    # Create all clients with an Application (service principal) token provider
    #
    mystack_cloud = get_cloud_from_metadata_endpoint(
        os.environ['ARM_ENDPOINT'])

    subscription_id = os.environ['AZURE_SUBSCRIPTION_ID']

    credentials = ClientSecretCredential(
        client_id=os.environ['AZURE_CLIENT_ID'],
        client_secret=os.environ['AZURE_CLIENT_SECRET'],
        tenant_id=os.environ['AZURE_TENANT_ID'],
        authority=mystack_cloud.endpoints.active_directory)

    logging.basicConfig(level=logging.ERROR)
    scope = "openid profile offline_access" + " " + mystack_cloud.endpoints.active_directory_resource_id + "/.default"

    resource_client = ResourceManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager,
        profile=KnownProfiles.v2020_09_01_hybrid,
        credential_scopes=[scope])

    compute_client = ComputeManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager,
        profile=KnownProfiles.v2020_09_01_hybrid,
        credential_scopes=[scope])

    storage_client = StorageManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager,
        profile=KnownProfiles.v2020_09_01_hybrid,
        credential_scopes=[scope])

    network_client = NetworkManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager,
        profile=KnownProfiles.v2020_09_01_hybrid,
        credential_scopes=[scope])

    ###########
    # Prepare #
    ###########

    # Create Resource group
    print('\nCreate Resource Group')
    resource_client.resource_groups.create_or_update(GROUP_NAME,
                                                     {'location': LOCATION})

    try:
        # Create a storage account
        print('\nCreate a storage account')
        storage_async_operation = storage_client.storage_accounts.begin_create(
            GROUP_NAME, STORAGE_ACCOUNT_NAME, {
                'sku': {
                    'name': 'standard_lrs'
                },
                'kind': 'storage',
                'location': LOCATION
            })
        storage_async_operation.result()

        # Create a NIC
        nic = create_nic(network_client)

        #############
        # VM Sample #
        #############

        # Create Linux VM
        print('\nCreating Linux Virtual Machine')
        vm_parameters = create_vm_parameters(nic.id, VM_REFERENCE['linux'])
        async_vm_creation = compute_client.virtual_machines.begin_create_or_update(
            GROUP_NAME, VM_NAME, vm_parameters)
        async_vm_creation.result()

        # Tag the VM
        print('\nTag Virtual Machine')
        async_vm_update = compute_client.virtual_machines.begin_create_or_update(
            GROUP_NAME, VM_NAME, {
                'location': LOCATION,
                'tags': {
                    'who-rocks': 'python',
                    'where': 'on azure'
                }
            })
        async_vm_update.result()

        # Create managed data disk
        print('\nCreate (empty) managed Data Disk')
        async_disk_creation = compute_client.disks.begin_create_or_update(
            GROUP_NAME, 'mydatadisk1', {
                'location': LOCATION,
                'disk_size_gb': 1,
                'creation_data': {
                    'create_option': DiskCreateOption.empty
                }
            })
        data_disk = async_disk_creation.result()

        # Get the virtual machine by name
        print('\nGet Virtual Machine by Name')
        virtual_machine = compute_client.virtual_machines.get(
            GROUP_NAME, VM_NAME)

        # Attach data disk
        print('\nAttach Data Disk')
        virtual_machine.storage_profile.data_disks.append({
            'lun':
            12,
            'name':
            'mydatadisk1',
            'create_option':
            DiskCreateOption.attach,
            'managed_disk': {
                'id': data_disk.id
            }
        })
        async_disk_attach = compute_client.virtual_machines.begin_create_or_update(
            GROUP_NAME, virtual_machine.name, virtual_machine)
        async_disk_attach.result()

        # Detach data disk
        print('\nDetach Data Disk')
        data_disks = virtual_machine.storage_profile.data_disks
        data_disks[:] = [
            disk for disk in data_disks if disk.name != 'mydatadisk1'
        ]
        async_vm_update = compute_client.virtual_machines.begin_create_or_update(
            GROUP_NAME, VM_NAME, virtual_machine)
        virtual_machine = async_vm_update.result()

        # Deallocating the VM (in preparation for a disk resize)
        print('\nDeallocating the VM (to prepare for a disk resize)')
        async_vm_deallocate = compute_client.virtual_machines.begin_deallocate(
            GROUP_NAME, VM_NAME)
        async_vm_deallocate.result()

        # Increase OS disk size by 10 GB
        print('\nUpdate OS disk size')
        os_disk_name = virtual_machine.storage_profile.os_disk.name
        os_disk = compute_client.disks.get(GROUP_NAME, os_disk_name)
        if not os_disk.disk_size_gb:
            print(
                "\tServer is not returning the OS disk size, possible bug in the server?"
            )
            print("\tAssuming that the OS disk size is 30 GB")
            os_disk.disk_size_gb = 30

        os_disk.disk_size_gb += 10

        async_disk_update = compute_client.disks.begin_create_or_update(
            GROUP_NAME, os_disk.name, os_disk)
        async_disk_update.result()

        # Start the VM
        print('\nStart VM')
        async_vm_start = compute_client.virtual_machines.begin_start(
            GROUP_NAME, VM_NAME)
        async_vm_start.result()

        # Restart the VM
        print('\nRestart VM')
        async_vm_restart = compute_client.virtual_machines.begin_restart(
            GROUP_NAME, VM_NAME)
        async_vm_restart.result()

        # Stop the VM
        print('\nStop VM')
        async_vm_stop = compute_client.virtual_machines.begin_power_off(
            GROUP_NAME, VM_NAME)
        async_vm_stop.result()

        # List VMs in subscription
        print('\nList VMs in subscription')
        for vm in compute_client.virtual_machines.list_all():
            print("\tVM: {}".format(vm.name))

        # List VM in resource group
        print('\nList VMs in resource group')
        for vm in compute_client.virtual_machines.list(GROUP_NAME):
            print("\tVM: {}".format(vm.name))

        # Delete VM
        print('\nDelete VM')
        async_vm_delete = compute_client.virtual_machines.begin_delete(
            GROUP_NAME, VM_NAME)
        async_vm_delete.result()

        # Create Windows VM
        print('\nCreating Windows Virtual Machine')
        # Recycling NIC of previous VM
        vm_parameters = create_vm_parameters(nic.id, VM_REFERENCE['windows'])
        async_vm_creation = compute_client.virtual_machines.begin_create_or_update(
            GROUP_NAME, VM_NAME, vm_parameters)
        async_vm_creation.result()
    except CloudError:
        print('A VM operation failed:', traceback.format_exc(), sep='\n')
    else:
        print('All example operations completed successfully!')
    finally:
        # Delete Resource group and everything in it
        print('\nDelete Resource Group')
        delete_async_operation = resource_client.resource_groups.begin_delete(
            GROUP_NAME)
        delete_async_operation.result()
        print("\nDeleted: {}".format(GROUP_NAME))
예제 #15
0
    def __init__(self,
                 derived_arg_spec,
                 bypass_checks=False,
                 no_log=False,
                 check_invalid_arguments=None,
                 mutually_exclusive=None,
                 required_together=None,
                 required_one_of=None,
                 add_file_common_args=False,
                 supports_check_mode=False,
                 required_if=None,
                 supports_tags=True,
                 facts_module=False,
                 skip_exec=False):

        merged_arg_spec = dict()
        merged_arg_spec.update(AZURE_COMMON_ARGS)
        if supports_tags:
            merged_arg_spec.update(AZURE_TAG_ARGS)

        if derived_arg_spec:
            merged_arg_spec.update(derived_arg_spec)

        merged_required_if = list(AZURE_COMMON_REQUIRED_IF)
        if required_if:
            merged_required_if += required_if

        self.module = AnsibleModule(
            argument_spec=merged_arg_spec,
            bypass_checks=bypass_checks,
            no_log=no_log,
            check_invalid_arguments=check_invalid_arguments,
            mutually_exclusive=mutually_exclusive,
            required_together=required_together,
            required_one_of=required_one_of,
            add_file_common_args=add_file_common_args,
            supports_check_mode=supports_check_mode,
            required_if=merged_required_if)

        if not HAS_PACKAGING_VERSION:
            self.fail(
                "Do you have packaging installed? Try `pip install packaging`"
                "- {0}".format(HAS_PACKAGING_VERSION_EXC))

        if not HAS_MSRESTAZURE:
            self.fail(
                "Do you have msrestazure installed? Try `pip install msrestazure`"
                "- {0}".format(HAS_MSRESTAZURE_EXC))

        if not HAS_AZURE:
            self.fail(
                "Do you have azure>={1} installed? Try `pip install ansible[azure]`"
                "- {0}".format(HAS_AZURE_EXC, AZURE_MIN_RELEASE))

        self._cloud_environment = None
        self._network_client = None
        self._storage_client = None
        self._resource_client = None
        self._compute_client = None
        self._dns_client = None
        self._web_client = None
        self._containerservice_client = None

        self.check_mode = self.module.check_mode
        self.api_profile = self.module.params.get('api_profile')
        self.facts_module = facts_module
        # self.debug = self.module.params.get('debug')

        # authenticate
        self.credentials = self._get_credentials(self.module.params)
        if not self.credentials:
            if HAS_AZURE_CLI_CORE:
                self.fail(
                    "Failed to get credentials. Either pass as parameters, set environment variables, "
                    "define a profile in ~/.azure/credentials, or log in with Azure CLI (`az login`)."
                )
            else:
                self.fail(
                    "Failed to get credentials. Either pass as parameters, set environment variables, "
                    "define a profile in ~/.azure/credentials, or install Azure CLI and log in (`az login`)."
                )

        # cert validation mode precedence: module-arg, credential profile, env, "validate"
        self._cert_validation_mode = self.module.params['cert_validation_mode'] or self.credentials.get('cert_validation_mode') or \
            os.environ.get('AZURE_CERT_VALIDATION_MODE') or 'validate'

        if self._cert_validation_mode not in ['validate', 'ignore']:
            self.fail('invalid cert_validation_mode: {0}'.format(
                self._cert_validation_mode))

        # if cloud_environment specified, look up/build Cloud object
        raw_cloud_env = self.credentials.get('cloud_environment')
        if self.credentials.get(
                'credentials') is not None and raw_cloud_env is not None:
            self._cloud_environment = raw_cloud_env
        elif not raw_cloud_env:
            self._cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD  # SDK default
        else:
            # try to look up "well-known" values via the name attribute on azure_cloud members
            all_clouds = [
                x[1] for x in inspect.getmembers(azure_cloud)
                if isinstance(x[1], azure_cloud.Cloud)
            ]
            matched_clouds = [x for x in all_clouds if x.name == raw_cloud_env]
            if len(matched_clouds) == 1:
                self._cloud_environment = matched_clouds[0]
            elif len(matched_clouds) > 1:
                self.fail(
                    "Azure SDK failure: more than one cloud matched for cloud_environment name '{0}'"
                    .format(raw_cloud_env))
            else:
                if not urlparse.urlparse(raw_cloud_env).scheme:
                    self.fail(
                        "cloud_environment must be an endpoint discovery URL or one of {0}"
                        .format([x.name for x in all_clouds]))
                try:
                    self._cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(
                        raw_cloud_env)
                except Exception as e:
                    self.fail(
                        "cloud_environment {0} could not be resolved: {1}".
                        format(raw_cloud_env, e.message),
                        exception=traceback.format_exc(e))

        if self.credentials.get(
                'subscription_id',
                None) is None and self.credentials.get('credentials') is None:
            self.fail("Credentials did not include a subscription_id value.")
        self.log("setting subscription_id")
        self.subscription_id = self.credentials['subscription_id']

        if self.credentials.get('credentials') is not None:
            # AzureCLI credentials
            self.azure_credentials = self.credentials['credentials']
        elif self.credentials.get('client_id') is not None and \
                self.credentials.get('secret') is not None and \
                self.credentials.get('tenant') is not None:
            self.azure_credentials = ServicePrincipalCredentials(
                client_id=self.credentials['client_id'],
                secret=self.credentials['secret'],
                tenant=self.credentials['tenant'],
                cloud_environment=self._cloud_environment,
                verify=self._cert_validation_mode == 'validate')

        elif self.credentials.get(
                'ad_user') is not None and self.credentials.get(
                    'password') is not None:
            tenant = self.credentials.get('tenant')
            if not tenant:
                tenant = 'common'  # SDK default

            self.azure_credentials = UserPassCredentials(
                self.credentials['ad_user'],
                self.credentials['password'],
                tenant=tenant,
                cloud_environment=self._cloud_environment,
                verify=self._cert_validation_mode == 'validate')
        else:
            self.fail(
                "Failed to authenticate with provided credentials. Some attributes were missing. "
                "Credentials must include client_id, secret and tenant or ad_user and password or "
                "be logged using AzureCLI.")

        # common parameter validation
        if self.module.params.get('tags'):
            self.validate_tags(self.module.params['tags'])

        if not skip_exec:
            res = self.exec_module(**self.module.params)
            self.module.exit_json(**res)
예제 #16
0
def _determine_auth(**kwargs):
    """
    Acquire Azure ARM Credentials
    """
    if "profile" in kwargs:
        azure_credentials = __salt__["config.option"](kwargs["profile"])
        kwargs.update(azure_credentials)

    service_principal_creds_kwargs = ["client_id", "secret", "tenant"]
    user_pass_creds_kwargs = ["username", "password"]

    try:
        if kwargs.get("cloud_environment") and kwargs.get(
                "cloud_environment").startswith("http"):
            cloud_env = get_cloud_from_metadata_endpoint(
                kwargs["cloud_environment"])
        else:
            cloud_env_module = importlib.import_module(
                "msrestazure.azure_cloud")
            cloud_env = getattr(
                cloud_env_module,
                kwargs.get("cloud_environment", "AZURE_PUBLIC_CLOUD"))
    except (AttributeError, ImportError, MetadataEndpointError):
        raise sys.exit(
            "The Azure cloud environment {} is not available.".format(
                kwargs["cloud_environment"]))

    if set(service_principal_creds_kwargs).issubset(kwargs):
        if not (kwargs["client_id"] and kwargs["secret"] and kwargs["tenant"]):
            raise SaltInvocationError(
                "The client_id, secret, and tenant parameters must all be "
                "populated if using service principals.")
        else:
            credentials = ServicePrincipalCredentials(
                kwargs["client_id"],
                kwargs["secret"],
                tenant=kwargs["tenant"],
                cloud_environment=cloud_env,
            )
    elif set(user_pass_creds_kwargs).issubset(kwargs):
        if not (kwargs["username"] and kwargs["password"]):
            raise SaltInvocationError(
                "The username and password parameters must both be "
                "populated if using username/password authentication.")
        else:
            credentials = UserPassCredentials(kwargs["username"],
                                              kwargs["password"],
                                              cloud_environment=cloud_env)
    elif "subscription_id" in kwargs:
        try:
            from msrestazure.azure_active_directory import MSIAuthentication

            credentials = MSIAuthentication(cloud_environment=cloud_env)
        except ImportError:
            raise SaltSystemExit(msg=(
                "MSI authentication support not availabe (requires msrestazure >="
                " 0.4.14)"))

    else:
        raise SaltInvocationError(
            "Unable to determine credentials. "
            "A subscription_id with username and password, "
            "or client_id, secret, and tenant or a profile with the "
            "required parameters populated")

    if "subscription_id" not in kwargs:
        raise SaltInvocationError("A subscription_id must be specified")

    subscription_id = salt.utils.stringutils.to_str(kwargs["subscription_id"])

    return credentials, subscription_id, cloud_env
예제 #17
0
    def __init__(self, derived_arg_spec, bypass_checks=False, no_log=False,
                 check_invalid_arguments=True, mutually_exclusive=None, required_together=None,
                 required_one_of=None, add_file_common_args=False, supports_check_mode=False,
                 required_if=None, supports_tags=True, facts_module=False, skip_exec=False):

        merged_arg_spec = dict()
        merged_arg_spec.update(AZURE_COMMON_ARGS)
        if supports_tags:
            merged_arg_spec.update(AZURE_TAG_ARGS)

        if derived_arg_spec:
            merged_arg_spec.update(derived_arg_spec)

        merged_required_if = list(AZURE_COMMON_REQUIRED_IF)
        if required_if:
            merged_required_if += required_if

        self.module = AnsibleModule(argument_spec=merged_arg_spec,
                                    bypass_checks=bypass_checks,
                                    no_log=no_log,
                                    check_invalid_arguments=check_invalid_arguments,
                                    mutually_exclusive=mutually_exclusive,
                                    required_together=required_together,
                                    required_one_of=required_one_of,
                                    add_file_common_args=add_file_common_args,
                                    supports_check_mode=supports_check_mode,
                                    required_if=merged_required_if)

        if not HAS_PACKAGING_VERSION:
            self.fail("Do you have packaging installed? Try `pip install packaging`"
                      "- {0}".format(HAS_PACKAGING_VERSION_EXC))

        if not HAS_MSRESTAZURE:
            self.fail("Do you have msrestazure installed? Try `pip install msrestazure`"
                      "- {0}".format(HAS_MSRESTAZURE_EXC))

        if not HAS_AZURE:
            self.fail("Do you have azure>={1} installed? Try `pip install 'azure>={1}' --upgrade`"
                      "- {0}".format(HAS_AZURE_EXC, AZURE_MIN_RELEASE))

        self._cloud_environment = None
        self._network_client = None
        self._storage_client = None
        self._resource_client = None
        self._compute_client = None
        self._dns_client = None
        self._web_client = None
        self._containerservice_client = None

        self.check_mode = self.module.check_mode
        self.facts_module = facts_module
        # self.debug = self.module.params.get('debug')

        # authenticate
        self.credentials = self._get_credentials(self.module.params)
        if not self.credentials:
            self.fail("Failed to get credentials. Either pass as parameters, set environment variables, "
                      "or define a profile in ~/.azure/credentials or be logged using AzureCLI.")

        # if cloud_environment specified, look up/build Cloud object
        raw_cloud_env = self.credentials.get('cloud_environment')
        if not raw_cloud_env:
            self._cloud_environment = azure_cloud.AZURE_PUBLIC_CLOUD  # SDK default
        else:
            # try to look up "well-known" values via the name attribute on azure_cloud members
            all_clouds = [x[1] for x in inspect.getmembers(azure_cloud) if isinstance(x[1], azure_cloud.Cloud)]
            matched_clouds = [x for x in all_clouds if x.name == raw_cloud_env]
            if len(matched_clouds) == 1:
                self._cloud_environment = matched_clouds[0]
            elif len(matched_clouds) > 1:
                self.fail("Azure SDK failure: more than one cloud matched for cloud_environment name '{0}'".format(raw_cloud_env))
            else:
                if not urlparse.urlparse(raw_cloud_env).scheme:
                    self.fail("cloud_environment must be an endpoint discovery URL or one of {0}".format([x.name for x in all_clouds]))
                try:
                    self._cloud_environment = azure_cloud.get_cloud_from_metadata_endpoint(raw_cloud_env)
                except Exception as e:
                    self.fail("cloud_environment {0} could not be resolved: {1}".format(raw_cloud_env, e.message), exception=traceback.format_exc(e))

        if self.credentials.get('subscription_id', None) is None:
            self.fail("Credentials did not include a subscription_id value.")
        self.log("setting subscription_id")
        self.subscription_id = self.credentials['subscription_id']

        if self.credentials.get('client_id') is not None and \
           self.credentials.get('secret') is not None and \
           self.credentials.get('tenant') is not None:
            self.azure_credentials = ServicePrincipalCredentials(client_id=self.credentials['client_id'],
                                                                 secret=self.credentials['secret'],
                                                                 tenant=self.credentials['tenant'],
                                                                 cloud_environment=self._cloud_environment)

        elif self.credentials.get('ad_user') is not None and self.credentials.get('password') is not None:
            tenant = self.credentials.get('tenant')
            if not tenant:
                tenant = 'common'  # SDK default

            self.azure_credentials = UserPassCredentials(self.credentials['ad_user'],
                                                         self.credentials['password'],
                                                         tenant=tenant,
                                                         cloud_environment=self._cloud_environment)
        else:
            self.fail("Failed to authenticate with provided credentials. Some attributes were missing. "
                      "Credentials must include client_id, secret and tenant or ad_user and password or "
                      "be logged using AzureCLI.")

        # common parameter validation
        if self.module.params.get('tags'):
            self.validate_tags(self.module.params['tags'])

        if not skip_exec:
            res = self.exec_module(**self.module.params)
            self.module.exit_json(**res)
예제 #18
0
def run_example(config):
    """Resource Group management example."""
    try:
        logging.basicConfig(level=logging.ERROR)

        mystack_cloud = get_cloud_from_metadata_endpoint(
            config['resourceManagerUrl'])

        subscription_id = config['subscriptionId']
        # Azure stack location
        location = config['location']

        credentials = ClientSecretCredential(
            client_id = config['clientId'],
            client_secret = config['clientSecret'],
            tenant_id = config['tenantId'],
            authority = mystack_cloud.endpoints.active_directory
        )

        KnownProfiles.default.use(KnownProfiles.v2020_09_01_hybrid)
        scope = "openid profile offline_access" + " " + mystack_cloud.endpoints.active_directory_resource_id + "/.default"
        
        client = ResourceManagementClient(
            credentials , subscription_id,
            base_url=mystack_cloud.endpoints.resource_manager,
            credential_scopes=[scope])

        #
        # Managing resource groups
        #
        resource_group_params = {'location': location}

        # List Resource Groups
        print('List Resource Groups')
        for item in client.resource_groups.list():
            print_item(item)

        # Create Resource group
        print('Create Resource Group')
        print_item(client.resource_groups.create_or_update(GROUP_NAME, resource_group_params))

        # Modify the Resource group
        print('Modify Resource Group')
        resource_group_params.update(tags={'hello': 'world'})
        print_item(client.resource_groups.create_or_update(GROUP_NAME, resource_group_params))

        # Create a Key Vault in the Resource Group
        print('Create a Key Vault via a Generic Resource Put')
        key_vault_params = {
            'location': location,
            'properties': {
                'sku': {'family': 'A', 'name': 'standard'},
                'tenantId': config['tenantId'],
                'accessPolicies': [],
                'enabledForDeployment': True,
                'enabledForTemplateDeployment': True,
                'enabledForDiskEncryption': True
            }
        }

        client.resources.begin_create_or_update(
            resource_group_name=GROUP_NAME,
            resource_provider_namespace="Microsoft.KeyVault",
            parent_resource_path="",
            resource_type="vaults",
            resource_name='azureSampleVault' + datetime.utcnow().strftime("-%H%M%S"),
            parameters = key_vault_params,
            api_version="2016-10-01"
        ).result()

        # List Resources within the group
        print('List all of the resources within the group')
        for item in client.resources.list_by_resource_group(GROUP_NAME):
            print_item(item)

        # Export the Resource group template
        print('Export Resource Group Template')
        BODY = {
            'resources': ['*']
        }
        rgTemplate = client.resource_groups.begin_export_template(GROUP_NAME, BODY).result()
        print(rgTemplate.template)
        print('\n\n')
    finally:
        # Delete Resource group and everything in it
        print('Delete Resource Group')
        client.resource_groups.begin_delete(GROUP_NAME).result()
        print("\nDeleted: {}".format(GROUP_NAME))
예제 #19
0
def run_example():
    """Resource Group management example."""
    #
    # Create the Resource Manager Client with an Application (service principal) token provider
    #
    mystack_cloud = get_cloud_from_metadata_endpoint(
        os.environ['ARM_ENDPOINT'])
    subscription_id = os.environ['AZURE_SUBSCRIPTION_ID']
    credentials = ServicePrincipalCredentials(
        client_id=os.environ['AZURE_CLIENT_ID'],
        secret=os.environ['AZURE_CLIENT_SECRET'],
        tenant=os.environ['AZURE_TENANT_ID'],
        cloud_environment=mystack_cloud)

    # By Default, use AzureStack supported profile
    KnownProfiles.default.use(KnownProfiles.v2018_03_01_hybrid)
    logging.basicConfig(level=logging.ERROR)

    client = ResourceManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)

    #
    # Managing resource groups
    #
    resource_group_params = {'location': LOCATION}

    # List Resource Groups
    print('List Resource Groups')
    for item in client.resource_groups.list():
        print_item(item)

    # Create Resource group
    print('Create Resource Group')
    print_item(
        client.resource_groups.create_or_update(GROUP_NAME,
                                                resource_group_params))

    # Modify the Resource group
    print('Modify Resource Group')
    resource_group_params.update(tags={'hello': 'world'})
    print_item(
        client.resource_groups.create_or_update(GROUP_NAME,
                                                resource_group_params))

    # Create a Key Vault in the Resource Group
    print('Create a Key Vault via a Generic Resource Put')
    key_vault_params = {
        'location': LOCATION,
        'properties': {
            'sku': {
                'family': 'A',
                'name': 'standard'
            },
            'tenantId': os.environ['AZURE_TENANT_ID'],
            'accessPolicies': [],
            'enabledForDeployment': True,
            'enabledForTemplateDeployment': True,
            'enabledForDiskEncryption': True
        }
    }
    client.resources.create_or_update(
        GROUP_NAME,
        'Microsoft.KeyVault',
        '',
        'vaults',
        # Suffix random string to make vault name unique
        'azureSampleVault' + datetime.utcnow().strftime("-%H%M%S"),
        '2015-06-01',
        key_vault_params)

    # List Resources within the group
    print('List all of the resources within the group')
    for item in client.resources.list_by_resource_group(GROUP_NAME):
        print_item(item)

    # Export the Resource group template
    print('Export Resource Group Template')
    print(
        json.dumps(client.resource_groups.export_template(GROUP_NAME,
                                                          ['*']).template,
                   indent=4))
    print('\n\n')

    # Delete Resource group and everything in it
    print('Delete Resource Group')
    delete_async_operation = client.resource_groups.delete(GROUP_NAME)
    delete_async_operation.wait()
    print("\nDeleted: {}".format(GROUP_NAME))
def run_example():
    """Virtual Machine management example."""
    #
    # Create all clients with an Application (service principal) token provider
    #
    mystack_cloud = get_cloud_from_metadata_endpoint(
        os.environ['ARM_ENDPOINT'])

    # Set Storage Endpoint suffix
    arm_url = mystack_cloud.endpoints.resource_manager
    storage_endpoint_suffix = arm_url.replace(arm_url.split(".")[0],
                                              "").strip('./')

    # By Default, use AzureStack supported profile
    KnownProfiles.default.use(KnownProfiles.v2017_03_09_profile)
    """
    Authenticate using service principal w/ cert.
    """
    subscription_id = os.environ['AZURE_SUBSCRIPTION_ID']
    cert_file = os.environ['AZURE_CERT_PATH']
    tenant = os.environ['AZURE_TENANT_ID']
    client_id = os.environ['AZURE_CLIENT_ID']

    from OpenSSL.crypto import load_certificate, FILETYPE_PEM
    with open(cert_file, 'r') as file_reader:
        cert_file_string = file_reader.read()
        cert = load_certificate(FILETYPE_PEM, cert_file_string)
        thumbprint = cert.digest("sha1").decode()

    authority_uri, is_adfs = _get_authority_url(mystack_cloud, tenant)
    resource_uri = mystack_cloud.endpoints.active_directory_resource_id

    context = adal.AuthenticationContext(authority_uri,
                                         api_version=None,
                                         validate_authority=(not is_adfs))

    mgmt_token = context.acquire_token_with_client_certificate(
        resource_uri, client_id, cert_file_string, thumbprint)
    credentials = AADTokenCredentials(mgmt_token, client_id)

    # By Default, use AzureStack supported profile
    KnownProfiles.default.use(KnownProfiles.v2017_03_09_profile)

    resource_client = ResourceManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    compute_client = ComputeManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    storage_client = StorageManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)
    network_client = NetworkManagementClient(
        credentials,
        subscription_id,
        base_url=mystack_cloud.endpoints.resource_manager)

    ###########
    # Prepare #
    ###########

    # Create Resource group
    print('\nCreate Resource Group')
    resource_client.resource_groups.create_or_update(GROUP_NAME,
                                                     {'location': LOCATION})

    # Create a storage account
    print('\nCreate a storage account')
    storage_async_operation = storage_client.storage_accounts.create(
        GROUP_NAME, STORAGE_ACCOUNT_NAME, {
            'sku': {
                'name': 'standard_lrs'
            },
            'kind': 'storage',
            'location': LOCATION
        })
    storage_async_operation.wait()

    # Create a NIC
    nic = create_nic(network_client)

    #############
    # VM Sample #
    #############

    # Create Linux VM
    print('\nCreating Linux Virtual Machine')
    vm_parameters = create_vm_parameters(nic.id, VM_REFERENCE['linux'],
                                         storage_endpoint_suffix)
    async_vm_creation = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, vm_parameters)
    async_vm_creation.wait()

    # Tag the VM
    print('\nTag Virtual Machine')
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, {
            'location': LOCATION,
            'tags': {
                'who-rocks': 'python',
                'where': 'on azure'
            }
        })
    async_vm_update.wait()

    # Attach data disk
    print('\nAttach Data Disk')
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, {
            'location': LOCATION,
            'storage_profile': {
                'data_disks': [{
                    'name': 'mydatadisk1',
                    'disk_size_gb': 1,
                    'lun': 0,
                    'vhd': {
                        'uri':
                        "https://{}.blob.{}/vhds/mydatadisk1.vhd".format(
                            STORAGE_ACCOUNT_NAME, storage_endpoint_suffix)
                    },
                    'create_option': 'Empty'
                }]
            }
        })
    async_vm_update.wait()

    # Get the virtual machine by name
    print('\nGet Virtual Machine by Name')
    virtual_machine = compute_client.virtual_machines.get(GROUP_NAME, VM_NAME)

    # Detach data disk
    print('\nDetach Data Disk')
    data_disks = virtual_machine.storage_profile.data_disks
    data_disks[:] = [disk for disk in data_disks if disk.name != 'mydatadisk1']
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, virtual_machine)
    virtual_machine = async_vm_update.result()

    # Deallocating the VM (resize prepare)
    print('\nDeallocating the VM (resize prepare)')
    async_vm_deallocate = compute_client.virtual_machines.deallocate(
        GROUP_NAME, VM_NAME)
    async_vm_deallocate.wait()

    # Update OS disk size by 10Gb
    print('\nUpdate OS disk size')

    # Server is not returning the OS Disk size (None), possible bug in server
    if not virtual_machine.storage_profile.os_disk.disk_size_gb:
        print(
            "\tServer is not returning the OS disk size, possible bug in the server?"
        )
        print("\tAssuming that the OS disk size is 256 GB")
        virtual_machine.storage_profile.os_disk.disk_size_gb = 256

    virtual_machine.storage_profile.os_disk.disk_size_gb += 10
    async_vm_update = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, virtual_machine)
    virtual_machine = async_vm_update.result()

    # Start the VM
    print('\nStart VM')
    async_vm_start = compute_client.virtual_machines.start(GROUP_NAME, VM_NAME)
    async_vm_start.wait()

    # Restart the VM
    print('\nRestart VM')
    async_vm_restart = compute_client.virtual_machines.restart(
        GROUP_NAME, VM_NAME)
    async_vm_restart.wait()

    # Stop the VM
    print('\nStop VM')
    async_vm_stop = compute_client.virtual_machines.power_off(
        GROUP_NAME, VM_NAME)
    async_vm_stop.wait()

    # List VMs in subscription
    print('\nList VMs in subscription')
    for vm in compute_client.virtual_machines.list_all():
        print("\tVM: {}".format(vm.name))

    # List VM in resource group
    print('\nList VMs in resource group')
    for vm in compute_client.virtual_machines.list(GROUP_NAME):
        print("\tVM: {}".format(vm.name))

    # Delete VM
    print('\nDelete VM')
    async_vm_delete = compute_client.virtual_machines.delete(
        GROUP_NAME, VM_NAME)
    async_vm_delete.wait()

    # Create Windows VM
    print('\nCreating Windows Virtual Machine')
    # Recycling NIC of previous VM
    vm_parameters = create_vm_parameters(nic.id, VM_REFERENCE['windows'],
                                         storage_endpoint_suffix)
    async_vm_creation = compute_client.virtual_machines.create_or_update(
        GROUP_NAME, VM_NAME, vm_parameters)
    async_vm_creation.wait()

    input("Press enter to delete this Resource Group.")

    # Delete Resource group and everything in it
    print('\nDelete Resource Group')
    delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME)
    delete_async_operation.wait()
    print("\nDeleted: {}".format(GROUP_NAME))
예제 #21
0
async def determine_auth(hub, ctx, resource=None, **kwargs):
    """
    Acquire Azure RM Credentials (mgmt modules)
    """
    service_principal_creds_kwargs = ["client_id", "secret", "tenant"]
    user_pass_creds_kwargs = ["username", "password"]

    if ctx["acct"]:
        for key, val in ctx["acct"].items():
            # explicit kwargs override acct
            kwargs.setdefault(key, val)

    cred_kwargs = {}

    if resource:
        cred_kwargs.update({"resource": resource})

    try:
        if kwargs.get("cloud_environment") and kwargs.get(
                "cloud_environment").startswith("http"):
            cloud_env = get_cloud_from_metadata_endpoint(
                kwargs["cloud_environment"])
        else:
            cloud_env_module = importlib.import_module(
                "msrestazure.azure_cloud")
            cloud_env = getattr(
                cloud_env_module,
                kwargs.get("cloud_environment", "AZURE_PUBLIC_CLOUD"))
    except (AttributeError, ImportError, MetadataEndpointError):
        raise sys.exit(
            "The Azure cloud environment {0} is not available.".format(
                kwargs["cloud_environment"]))

    if set(service_principal_creds_kwargs).issubset(kwargs):
        if not (kwargs["client_id"] and kwargs["secret"] and kwargs["tenant"]):
            raise Exception(
                "The client_id, secret, and tenant parameters must all be "
                "populated if using service principals.")
        credentials = ServicePrincipalCredentials(
            kwargs["client_id"],
            kwargs["secret"],
            tenant=kwargs["tenant"],
            cloud_environment=cloud_env,
            **cred_kwargs,
        )
    elif set(user_pass_creds_kwargs).issubset(kwargs):
        if not (kwargs["username"] and kwargs["password"]):
            raise Exception(
                "The username and password parameters must both be "
                "populated if using username/password authentication.")
        credentials = UserPassCredentials(
            kwargs["username"],
            kwargs["password"],
            cloud_environment=cloud_env,
            **cred_kwargs,
        )
    else:
        raise Exception(
            "Unable to determine credentials. "
            "A subscription_id with username and password, "
            "or client_id, secret, and tenant or a profile with the "
            "required parameters populated")

    if "subscription_id" not in kwargs:
        raise Exception("A subscription_id must be specified")

    subscription_id = str(kwargs["subscription_id"])

    return credentials, subscription_id, cloud_env
예제 #22
0
def load_secrets(experiment_secrets: Secrets):
    """Load secrets from experiments or azure credential file.

    :param experiment_secrets: Secrets provided in experiment file
    :returns: a secret object

    Load secrets from multiple sources that can contain different format
    such as azure credential file or experiment secrets section.
    The latter takes precedence over azure credential file.

    Function returns following dictionary object:
    ```python
    {
        # always available
        "cloud": "variable contains msrest cloud object"

        # optional - available if user authenticate with service principal
        "client_id": "variable contains client id",
        "client_secret": "variable contains client secret",
        "tenant_id": "variable contains tenant id",

        # optional - available if user authenticate with existing token
        "access_token": "variable contains access token",
    }
    ```

    :Loading secrets from experiment file:

    Function will try to load following secrets from the experiment file:
    ```json
    {
        "azure": {
            "client_id": "AZURE_CLIENT_ID",
            "client_secret": "AZURE_CLIENT_SECRET",
            "tenant_id": "AZURE_TENANT_ID",
            "access_token": "AZURE_ACCESS_TOKEN"
        }
    }
    ```

    :Loading secrets from azure credential file:

    If experiment file contains no secrets, function will try to load secrets
    from the azure credential file. Path to the file should be set under
    AZURE_AUTH_LOCATION environment variable.

    Function will try to load following secrets from azure credential file:
    ```json
    {
        "clientId": "AZURE_CLIENT_ID",
        "clientSecret": "AZURE_CLIENT_SECRET",
        "tenantId": "AZURE_TENANT_ID",
        "resourceManagerEndpointUrl": "AZURE_RESOURCE_MANAGER_ENDPOINT",
        ...
    }
    ```
    More info about azure credential file may be found:
    https://docs.microsoft.com/en-us/azure/developer/python/azure-sdk-authenticate

    """

    # 1: lookup for secrets in experiment  file
    if experiment_secrets:
        return {
            'client_id': experiment_secrets.get('client_id'),
            'client_secret': experiment_secrets.get('client_secret'),
            'tenant_id': experiment_secrets.get('tenant_id'),
            # load cloud object
            'cloud': cloud.get_or_raise(experiment_secrets.get('azure_cloud')),
            'access_token': experiment_secrets.get('access_token'),
        }

    # 2: lookup for credentials in azure auth file
    az_auth_file = _load_azure_auth_file()
    if az_auth_file:
        rm_endpoint = az_auth_file.get('resourceManagerEndpointUrl')
        return {
            'client_id': az_auth_file.get('clientId'),
            'client_secret': az_auth_file.get('clientSecret'),
            'tenant_id': az_auth_file.get('tenantId'),
            # load cloud object
            'cloud': azure_cloud.get_cloud_from_metadata_endpoint(rm_endpoint),
            # access token is not supported for credential files
            'access_token': None,
        }

    # no secretes
    logger.warn("Unable to load Azure credentials.")
    return {}