+ def _generate_keys(self):
+ """Method used to generate a pair of private/public keys.
+ This method is used because to create a vm in Azure we always need a key or a password
+ In some cases we may have a password in a cloud-init file but it may not be available
+ """
+ key = rsa.generate_private_key(
+ backend=crypto_default_backend(), public_exponent=65537, key_size=2048
+ )
+ private_key = key.private_bytes(
+ crypto_serialization.Encoding.PEM,
+ crypto_serialization.PrivateFormat.PKCS8,
+ crypto_serialization.NoEncryption(),
+ )
+ public_key = key.public_key().public_bytes(
+ crypto_serialization.Encoding.OpenSSH,
+ crypto_serialization.PublicFormat.OpenSSH,
+ )
+ private_key = private_key.decode("utf8")
+ # Change first line because Paramiko needs a explicit start with 'BEGIN RSA PRIVATE KEY'
+ i = private_key.find("\n")
+ private_key = "-----BEGIN RSA PRIVATE KEY-----" + private_key[i:]
+ public_key = public_key.decode("utf8")
+
+ return private_key, public_key
+
+ def _get_unused_vm_name(self, vm_name):
+ """
+ Checks the vm name and in case it is used adds a suffix to the name to allow creation
+ :return:
+ """
+ all_vms = (
+ self.conn_compute.instances()
+ .list(project=self.project, zone=self.zone)
+ .execute()
+ )
+ # Filter to vms starting with the indicated name
+ vms = list(filter(lambda vm: (vm.name.startswith(vm_name)), all_vms))
+ vm_names = [str(vm.name) for vm in vms]
+
+ # get the name with the first not used suffix
+ name_suffix = 0
+ # name = subnet_name + "-" + str(name_suffix)
+ name = vm_name # first subnet created will have no prefix
+
+ while name in vm_names:
+ name_suffix += 1
+ name = vm_name + "-" + str(name_suffix)
+
+ return name
+