2021-01-08 13:41:50 +01:00
|
|
|
From bb2070d4f4e8fbb5a963c521d61feb7419abdec1 Mon Sep 17 00:00:00 2001
|
2018-09-17 16:18:45 +02:00
|
|
|
From: ed lane <ed.lane.0@gmail.com>
|
|
|
|
Date: Thu, 30 Aug 2018 06:07:08 -0600
|
|
|
|
Subject: [PATCH] Integration of MSI authentication with azurearm cloud
|
|
|
|
driver (#105)
|
|
|
|
|
|
|
|
---
|
2021-01-08 13:41:50 +01:00
|
|
|
salt/cloud/clouds/azurearm.py | 98 +++++++++++++++--------------------
|
|
|
|
1 file changed, 43 insertions(+), 55 deletions(-)
|
2018-09-17 16:18:45 +02:00
|
|
|
|
|
|
|
diff --git a/salt/cloud/clouds/azurearm.py b/salt/cloud/clouds/azurearm.py
|
2021-01-08 13:41:50 +01:00
|
|
|
index 54fc7b497b..8b9254cecb 100644
|
2018-09-17 16:18:45 +02:00
|
|
|
--- a/salt/cloud/clouds/azurearm.py
|
|
|
|
+++ b/salt/cloud/clouds/azurearm.py
|
2021-01-08 13:41:50 +01:00
|
|
|
@@ -1,4 +1,3 @@
|
|
|
|
-# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
Azure ARM Cloud Module
|
|
|
|
======================
|
|
|
|
@@ -61,6 +60,9 @@ The Azure ARM cloud module is used to control access to Microsoft Azure Resource
|
2019-04-12 11:57:21 +02:00
|
|
|
virtual machine type will be "Windows". Only set this parameter on profiles which install Windows operating systems.
|
|
|
|
|
2018-09-17 16:18:45 +02:00
|
|
|
|
|
|
|
+ if using MSI-style authentication:
|
|
|
|
+ * ``subscription_id``
|
|
|
|
+
|
|
|
|
Example ``/etc/salt/cloud.providers`` or
|
|
|
|
``/etc/salt/cloud.providers.d/azure.conf`` configuration:
|
|
|
|
|
2021-01-08 13:41:50 +01:00
|
|
|
@@ -91,7 +93,6 @@ Example ``/etc/salt/cloud.providers`` or
|
|
|
|
|
|
|
|
|
|
|
|
# pylint: disable=wrong-import-position,wrong-import-order
|
|
|
|
-from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
|
|
|
|
import importlib
|
|
|
|
import logging
|
|
|
|
@@ -121,7 +122,6 @@ from salt.exceptions import (
|
|
|
|
# Salt libs
|
|
|
|
from salt.ext import six
|
|
|
|
|
|
|
|
-# Import 3rd-party libs
|
|
|
|
HAS_LIBS = False
|
|
|
|
try:
|
|
|
|
import azure.mgmt.compute.models as compute_models
|
|
|
|
@@ -179,7 +179,7 @@ def get_api_versions(call=None, kwargs=None): # pylint: disable=unused-argument
|
2018-09-17 16:18:45 +02:00
|
|
|
)
|
|
|
|
|
2021-01-08 13:41:50 +01:00
|
|
|
for resource in provider_query.resource_types:
|
|
|
|
- if six.text_type(resource.resource_type) == kwargs["resource_type"]:
|
|
|
|
+ if str(resource.resource_type) == kwargs["resource_type"]:
|
|
|
|
resource_dict = resource.as_dict()
|
|
|
|
api_versions = resource_dict["api_versions"]
|
|
|
|
except CloudError as exc:
|
|
|
|
@@ -263,6 +263,7 @@ def get_conn(client_type):
|
2018-09-17 16:18:45 +02:00
|
|
|
)
|
2019-04-12 11:57:21 +02:00
|
|
|
|
2018-09-17 16:18:45 +02:00
|
|
|
if tenant is not None:
|
|
|
|
+ # using Service Principle style authentication...
|
|
|
|
client_id = config.get_cloud_config_value(
|
2021-01-08 13:41:50 +01:00
|
|
|
"client_id", get_configured_provider(), __opts__, search_global=False
|
|
|
|
)
|
|
|
|
@@ -319,7 +320,7 @@ def avail_locations(call=None):
|
|
|
|
)
|
|
|
|
locations = []
|
|
|
|
for resource in provider_query.resource_types:
|
|
|
|
- if six.text_type(resource.resource_type) == "virtualMachines":
|
|
|
|
+ if str(resource.resource_type) == "virtualMachines":
|
|
|
|
resource_dict = resource.as_dict()
|
|
|
|
locations = resource_dict["locations"]
|
|
|
|
for location in locations:
|
|
|
|
@@ -399,7 +400,7 @@ def avail_images(call=None):
|
|
|
|
results = pool.map_async(_get_publisher_images, publishers)
|
|
|
|
results.wait()
|
|
|
|
|
|
|
|
- ret = {k: v for result in results.get() for k, v in six.iteritems(result)}
|
|
|
|
+ ret = {k: v for result in results.get() for k, v in result.items()}
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
@@ -529,7 +530,7 @@ def list_nodes_full(call=None):
|
|
|
|
results = pool.map_async(_get_node_info, nodes)
|
|
|
|
results.wait()
|
|
|
|
|
|
|
|
- group_ret = {k: v for result in results.get() for k, v in six.iteritems(result)}
|
|
|
|
+ group_ret = {k: v for result in results.get() for k, v in result.items()}
|
|
|
|
ret.update(group_ret)
|
|
|
|
|
|
|
|
return ret
|
|
|
|
@@ -707,7 +708,7 @@ def create_network_interface(call=None, kwargs=None):
|
|
|
|
)
|
|
|
|
|
|
|
|
if kwargs.get("iface_name") is None:
|
|
|
|
- kwargs["iface_name"] = "{0}-iface0".format(vm_["name"])
|
|
|
|
+ kwargs["iface_name"] = "{}-iface0".format(vm_["name"])
|
|
|
|
|
|
|
|
try:
|
|
|
|
subnet_obj = netconn.subnets.get(
|
|
|
|
@@ -717,7 +718,7 @@ def create_network_interface(call=None, kwargs=None):
|
|
|
|
)
|
|
|
|
except CloudError as exc:
|
|
|
|
raise SaltCloudSystemExit(
|
|
|
|
- '{0} (Resource Group: "{1}", VNET: "{2}", Subnet: "{3}")'.format(
|
|
|
|
+ '{} (Resource Group: "{}", VNET: "{}", Subnet: "{}")'.format(
|
|
|
|
exc.message,
|
|
|
|
kwargs["network_resource_group"],
|
|
|
|
kwargs["network"],
|
|
|
|
@@ -740,11 +741,11 @@ def create_network_interface(call=None, kwargs=None):
|
|
|
|
)
|
|
|
|
pool_ids.append({"id": lbbep_data.as_dict()["id"]})
|
|
|
|
except CloudError as exc:
|
|
|
|
- log.error("There was a cloud error: %s", six.text_type(exc))
|
|
|
|
+ log.error("There was a cloud error: %s", str(exc))
|
|
|
|
except KeyError as exc:
|
|
|
|
log.error(
|
|
|
|
"There was an error getting the Backend Pool ID: %s",
|
|
|
|
- six.text_type(exc),
|
|
|
|
+ str(exc),
|
|
|
|
)
|
|
|
|
ip_kwargs["load_balancer_backend_address_pools"] = pool_ids
|
|
|
|
|
|
|
|
@@ -755,7 +756,7 @@ def create_network_interface(call=None, kwargs=None):
|
|
|
|
ip_kwargs["private_ip_allocation_method"] = IPAllocationMethod.dynamic
|
|
|
|
|
|
|
|
if kwargs.get("allocate_public_ip") is True:
|
|
|
|
- pub_ip_name = "{0}-ip".format(kwargs["iface_name"])
|
|
|
|
+ pub_ip_name = "{}-ip".format(kwargs["iface_name"])
|
|
|
|
poller = netconn.public_ip_addresses.create_or_update(
|
|
|
|
resource_group_name=kwargs["resource_group"],
|
|
|
|
public_ip_address_name=pub_ip_name,
|
|
|
|
@@ -773,11 +774,11 @@ def create_network_interface(call=None, kwargs=None):
|
|
|
|
)
|
|
|
|
if pub_ip_data.ip_address: # pylint: disable=no-member
|
|
|
|
ip_kwargs["public_ip_address"] = PublicIPAddress(
|
|
|
|
- id=six.text_type(pub_ip_data.id), # pylint: disable=no-member
|
|
|
|
+ id=str(pub_ip_data.id), # pylint: disable=no-member
|
|
|
|
)
|
|
|
|
ip_configurations = [
|
|
|
|
NetworkInterfaceIPConfiguration(
|
|
|
|
- name="{0}-ip".format(kwargs["iface_name"]),
|
|
|
|
+ name="{}-ip".format(kwargs["iface_name"]),
|
|
|
|
subnet=subnet_obj,
|
|
|
|
**ip_kwargs
|
|
|
|
)
|
|
|
|
@@ -790,7 +791,7 @@ def create_network_interface(call=None, kwargs=None):
|
|
|
|
raise ValueError("Timed out waiting for public IP Address.")
|
|
|
|
time.sleep(5)
|
|
|
|
else:
|
|
|
|
- priv_ip_name = "{0}-ip".format(kwargs["iface_name"])
|
|
|
|
+ priv_ip_name = "{}-ip".format(kwargs["iface_name"])
|
|
|
|
ip_configurations = [
|
|
|
|
NetworkInterfaceIPConfiguration(
|
|
|
|
name=priv_ip_name, subnet=subnet_obj, **ip_kwargs
|
|
|
|
@@ -900,7 +901,7 @@ def request_instance(vm_):
|
|
|
|
)
|
|
|
|
vm_["iface_id"] = iface_data["id"]
|
|
|
|
|
|
|
|
- disk_name = "{0}-vol0".format(vm_["name"])
|
|
|
|
+ disk_name = "{}-vol0".format(vm_["name"])
|
|
|
|
|
|
|
|
vm_username = config.get_cloud_config_value(
|
|
|
|
"ssh_username",
|
|
|
|
@@ -922,8 +923,8 @@ def request_instance(vm_):
|
|
|
|
ssh_publickeyfile_contents = spkc_.read()
|
|
|
|
except Exception as exc: # pylint: disable=broad-except
|
|
|
|
raise SaltCloudConfigError(
|
|
|
|
- "Failed to read ssh publickey file '{0}': "
|
|
|
|
- "{1}".format(ssh_publickeyfile, exc.args[-1])
|
|
|
|
+ "Failed to read ssh publickey file '{}': "
|
|
|
|
+ "{}".format(ssh_publickeyfile, exc.args[-1])
|
|
|
|
)
|
|
|
|
|
|
|
|
disable_password_authentication = config.get_cloud_config_value(
|
|
|
|
@@ -941,7 +942,7 @@ def request_instance(vm_):
|
|
|
|
if not win_installer and ssh_publickeyfile_contents is not None:
|
|
|
|
sshpublickey = SshPublicKey(
|
|
|
|
key_data=ssh_publickeyfile_contents,
|
|
|
|
- path="/home/{0}/.ssh/authorized_keys".format(vm_username),
|
|
|
|
+ path="/home/{}/.ssh/authorized_keys".format(vm_username),
|
|
|
|
)
|
|
|
|
sshconfiguration = SshConfiguration(public_keys=[sshpublickey],)
|
|
|
|
linuxconfiguration = LinuxConfiguration(
|
|
|
|
@@ -991,9 +992,9 @@ def request_instance(vm_):
|
|
|
|
availability_set = config.get_cloud_config_value(
|
|
|
|
"availability_set", vm_, __opts__, search_global=False, default=None
|
|
|
|
)
|
|
|
|
- if availability_set is not None and isinstance(availability_set, six.string_types):
|
|
|
|
+ if availability_set is not None and isinstance(availability_set, str):
|
|
|
|
availability_set = {
|
|
|
|
- "id": "/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Compute/availabilitySets/{2}".format(
|
|
|
|
+ "id": "/subscriptions/{}/resourceGroups/{}/providers/Microsoft.Compute/availabilitySets/{}".format(
|
|
|
|
subscription_id, vm_["resource_group"], availability_set
|
|
|
|
)
|
|
|
|
}
|
|
|
|
@@ -1004,7 +1005,7 @@ def request_instance(vm_):
|
|
|
|
|
|
|
|
storage_endpoint_suffix = cloud_env.suffixes.storage_endpoint
|
|
|
|
|
|
|
|
- if isinstance(vm_.get("volumes"), six.string_types):
|
|
|
|
+ if isinstance(vm_.get("volumes"), str):
|
|
|
|
volumes = salt.utils.yaml.safe_load(vm_["volumes"])
|
|
|
|
else:
|
|
|
|
volumes = vm_.get("volumes")
|
|
|
|
@@ -1018,16 +1019,14 @@ def request_instance(vm_):
|
|
|
|
lun = 0
|
|
|
|
luns = []
|
|
|
|
for volume in volumes:
|
|
|
|
- if isinstance(volume, six.string_types):
|
|
|
|
+ if isinstance(volume, str):
|
|
|
|
volume = {"name": volume}
|
|
|
|
|
|
|
|
volume.setdefault(
|
|
|
|
"name",
|
|
|
|
volume.get(
|
|
|
|
"name",
|
|
|
|
- volume.get(
|
|
|
|
- "name", "{0}-datadisk{1}".format(vm_["name"], six.text_type(lun))
|
|
|
|
- ),
|
|
|
|
+ volume.get("name", "{}-datadisk{}".format(vm_["name"], str(lun))),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
@@ -1050,7 +1049,7 @@ def request_instance(vm_):
|
|
|
|
del volume["media_link"]
|
|
|
|
elif volume.get("vhd") == "unmanaged":
|
|
|
|
volume["vhd"] = VirtualHardDisk(
|
|
|
|
- uri="https://{0}.blob.{1}/vhds/{2}-datadisk{3}.vhd".format(
|
|
|
|
+ uri="https://{}.blob.{}/vhds/{}-datadisk{}.vhd".format(
|
|
|
|
vm_["storage_account"],
|
|
|
|
storage_endpoint_suffix,
|
|
|
|
vm_["name"],
|
|
|
|
@@ -1090,7 +1089,7 @@ def request_instance(vm_):
|
|
|
|
create_option=DiskCreateOptionTypes.from_image,
|
|
|
|
name=disk_name,
|
|
|
|
vhd=VirtualHardDisk(
|
|
|
|
- uri="https://{0}.blob.{1}/vhds/{2}.vhd".format(
|
|
|
|
+ uri="https://{}.blob.{}/vhds/{}.vhd".format(
|
|
|
|
vm_["storage_account"], storage_endpoint_suffix, disk_name,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
@@ -1209,7 +1208,7 @@ def request_instance(vm_):
|
|
|
|
__utils__["cloud.fire_event"](
|
|
|
|
"event",
|
|
|
|
"requesting instance",
|
|
|
|
- "salt/cloud/{0}/requesting".format(vm_["name"]),
|
|
|
|
+ "salt/cloud/{}/requesting".format(vm_["name"]),
|
|
|
|
args=__utils__["cloud.filter_event"](
|
|
|
|
"requesting", vm_, ["name", "profile", "provider", "driver"]
|
|
|
|
),
|
|
|
|
@@ -1260,7 +1259,7 @@ def create(vm_):
|
|
|
|
__utils__["cloud.fire_event"](
|
|
|
|
"event",
|
|
|
|
"starting create",
|
|
|
|
- "salt/cloud/{0}/creating".format(vm_["name"]),
|
|
|
|
+ "salt/cloud/{}/creating".format(vm_["name"]),
|
|
|
|
args=__utils__["cloud.filter_event"](
|
|
|
|
"creating", vm_, ["name", "profile", "provider", "driver"]
|
|
|
|
),
|
|
|
|
@@ -1278,9 +1277,7 @@ def create(vm_):
|
|
|
|
vm_request = request_instance(vm_=vm_)
|
|
|
|
|
|
|
|
if not vm_request or "error" in vm_request:
|
|
|
|
- err_message = "Error creating VM {0}! ({1})".format(
|
|
|
|
- vm_["name"], six.text_type(vm_request)
|
|
|
|
- )
|
|
|
|
+ err_message = "Error creating VM {}! ({})".format(vm_["name"], str(vm_request))
|
|
|
|
log.error(err_message)
|
|
|
|
raise SaltCloudSystemExit(err_message)
|
|
|
|
|
|
|
|
@@ -1322,7 +1319,7 @@ def create(vm_):
|
|
|
|
try:
|
|
|
|
log.warning(exc)
|
|
|
|
finally:
|
|
|
|
- raise SaltCloudSystemExit(six.text_type(exc))
|
|
|
|
+ raise SaltCloudSystemExit(str(exc))
|
|
|
|
|
|
|
|
vm_["ssh_host"] = data
|
|
|
|
if not vm_.get("ssh_username"):
|
|
|
|
@@ -1341,7 +1338,7 @@ def create(vm_):
|
|
|
|
__utils__["cloud.fire_event"](
|
|
|
|
"event",
|
|
|
|
"created instance",
|
|
|
|
- "salt/cloud/{0}/created".format(vm_["name"]),
|
|
|
|
+ "salt/cloud/{}/created".format(vm_["name"]),
|
|
|
|
args=__utils__["cloud.filter_event"](
|
|
|
|
"created", vm_, ["name", "profile", "provider", "driver"]
|
|
|
|
),
|
|
|
|
@@ -1548,9 +1545,7 @@ def _get_cloud_environment():
|
|
|
|
cloud_env = getattr(cloud_env_module, cloud_environment or "AZURE_PUBLIC_CLOUD")
|
|
|
|
except (AttributeError, ImportError):
|
|
|
|
raise SaltCloudSystemExit(
|
|
|
|
- "The azure {0} cloud environment is not available.".format(
|
|
|
|
- cloud_environment
|
|
|
|
- )
|
|
|
|
+ "The azure {} cloud environment is not available.".format(cloud_environment)
|
|
|
|
)
|
|
|
|
|
|
|
|
return cloud_env
|
|
|
|
@@ -1585,7 +1580,7 @@ def _get_block_blob_service(kwargs=None):
|
|
|
|
resource_group, storage_account
|
|
|
|
)
|
|
|
|
storage_keys = {v.key_name: v.value for v in storage_keys.keys}
|
|
|
|
- storage_key = next(six.itervalues(storage_keys))
|
|
|
|
+ storage_key = next(iter(storage_keys.values()))
|
|
|
|
|
|
|
|
cloud_env = _get_cloud_environment()
|
|
|
|
|
|
|
|
@@ -1620,7 +1615,7 @@ def list_blobs(call=None, kwargs=None): # pylint: disable=unused-argument
|
|
|
|
"server_encrypted": blob.properties.server_encrypted,
|
|
|
|
}
|
|
|
|
except Exception as exc: # pylint: disable=broad-except
|
|
|
|
- log.warning(six.text_type(exc))
|
|
|
|
+ log.warning(str(exc))
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
@@ -1655,9 +1650,7 @@ def delete_managed_disk(call=None, kwargs=None): # pylint: disable=unused-argum
|
|
|
|
compconn.disks.delete(kwargs["resource_group"], kwargs["blob"])
|
|
|
|
except Exception as exc: # pylint: disable=broad-except
|
|
|
|
log.error(
|
|
|
|
- "Error deleting managed disk %s - %s",
|
|
|
|
- kwargs.get("blob"),
|
|
|
|
- six.text_type(exc),
|
|
|
|
+ "Error deleting managed disk %s - %s", kwargs.get("blob"), str(exc),
|
|
|
|
)
|
|
|
|
return False
|
|
|
|
|
|
|
|
@@ -1834,7 +1827,7 @@ def create_or_update_vmextension(
|
|
|
|
except CloudError as exc:
|
|
|
|
__utils__["azurearm.log_cloud_error"](
|
|
|
|
"compute",
|
|
|
|
- "Error attempting to create the VM extension: {0}".format(exc.message),
|
|
|
|
+ "Error attempting to create the VM extension: {}".format(exc.message),
|
|
|
|
)
|
|
|
|
ret = {"error": exc.message}
|
|
|
|
|
|
|
|
@@ -1881,11 +1874,9 @@ def stop(name, call=None):
|
|
|
|
ret = {"error": exc.message}
|
|
|
|
if not ret:
|
|
|
|
__utils__["azurearm.log_cloud_error"](
|
|
|
|
- "compute", "Unable to find virtual machine with name: {0}".format(name)
|
|
|
|
+ "compute", "Unable to find virtual machine with name: {}".format(name)
|
|
|
|
)
|
|
|
|
- ret = {
|
|
|
|
- "error": "Unable to find virtual machine with name: {0}".format(name)
|
|
|
|
- }
|
|
|
|
+ ret = {"error": "Unable to find virtual machine with name: {}".format(name)}
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
instance = compconn.virtual_machines.deallocate(
|
|
|
|
@@ -1896,7 +1887,7 @@ def stop(name, call=None):
|
|
|
|
ret = vm_result.as_dict()
|
|
|
|
except CloudError as exc:
|
|
|
|
__utils__["azurearm.log_cloud_error"](
|
|
|
|
- "compute", "Error attempting to stop {0}: {1}".format(name, exc.message)
|
|
|
|
+ "compute", "Error attempting to stop {}: {}".format(name, exc.message)
|
|
|
|
)
|
|
|
|
ret = {"error": exc.message}
|
|
|
|
|
|
|
|
@@ -1945,11 +1936,9 @@ def start(name, call=None):
|
|
|
|
ret = {"error": exc.message}
|
|
|
|
if not ret:
|
|
|
|
__utils__["azurearm.log_cloud_error"](
|
|
|
|
- "compute", "Unable to find virtual machine with name: {0}".format(name)
|
|
|
|
+ "compute", "Unable to find virtual machine with name: {}".format(name)
|
|
|
|
)
|
|
|
|
- ret = {
|
|
|
|
- "error": "Unable to find virtual machine with name: {0}".format(name)
|
|
|
|
- }
|
|
|
|
+ ret = {"error": "Unable to find virtual machine with name: {}".format(name)}
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
instance = compconn.virtual_machines.start(
|
|
|
|
@@ -1960,8 +1949,7 @@ def start(name, call=None):
|
|
|
|
ret = vm_result.as_dict()
|
|
|
|
except CloudError as exc:
|
|
|
|
__utils__["azurearm.log_cloud_error"](
|
|
|
|
- "compute",
|
|
|
|
- "Error attempting to start {0}: {1}".format(name, exc.message),
|
|
|
|
+ "compute", "Error attempting to start {}: {}".format(name, exc.message),
|
|
|
|
)
|
|
|
|
ret = {"error": exc.message}
|
|
|
|
|
2018-09-17 16:18:45 +02:00
|
|
|
--
|
2021-01-08 13:41:50 +01:00
|
|
|
2.29.2
|
2018-09-17 16:18:45 +02:00
|
|
|
|
|
|
|
|