- def cloud_init(self, vapp, cloud_config):
- """
- Method to inject ssh-key
- vapp - vapp object
- cloud_config a dictionary with:
- 'key-pairs': (optional) list of strings with the public key to be inserted to the default user
- 'users': (optional) list of users to be inserted, each item is a dict with:
- 'name': (mandatory) user name,
- 'key-pairs': (optional) list of strings with the public key to be inserted to the user
- 'user-data': (optional) can be a string with the text script to be passed directly to cloud-init,
- or a list of strings, each one contains a script to be passed, usually with a MIMEmultipart file
- 'config-files': (optional). List of files to be transferred. Each item is a dict with:
- 'dest': (mandatory) string with the destination absolute path
- 'encoding': (optional, by default text). Can be one of:
- 'b64', 'base64', 'gz', 'gz+b64', 'gz+base64', 'gzip+b64', 'gzip+base64'
- 'content' (mandatory): string with the content of the file
- 'permissions': (optional) string with file permissions, typically octal notation '0644'
- 'owner': (optional) file owner, string with the format 'owner:group'
- 'boot-data-drive': boolean to indicate if user-data must be passed using a boot drive (hard disk
- """
- try:
- if not isinstance(cloud_config, dict):
- raise Exception(
- "cloud_init : parameter cloud_config is not a dictionary"
- )
- else:
- key_pairs = []
- userdata = []
-
- if "key-pairs" in cloud_config:
- key_pairs = cloud_config["key-pairs"]
-
- if "users" in cloud_config:
- userdata = cloud_config["users"]
-
- self.logger.debug("cloud_init : Guest os customization started..")
- customize_script = self.format_script(
- key_pairs=key_pairs, users_list=userdata
- )
- customize_script = customize_script.replace("&", "&")
- self.guest_customization(vapp, customize_script)
- except Exception as exp:
- self.logger.error(
- "cloud_init : exception occurred while injecting " "ssh-key"
- )
-
- raise vimconn.VimConnException(
- "cloud_init : Error {} failed to inject " "ssh-key".format(exp)
- )
-
- def format_script(self, key_pairs=[], users_list=[]):
- bash_script = """#!/bin/sh
-echo performing customization tasks with param $1 at `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"`>> /root/customization.log
-if [ "$1" = "precustomization" ];then
- echo performing precustomization tasks on `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log
-"""
-
- keys = "\n".join(key_pairs)
- if keys:
- keys_data = """
- if [ ! -d /root/.ssh ];then
- mkdir /root/.ssh
- chown root:root /root/.ssh
- chmod 700 /root/.ssh
- touch /root/.ssh/authorized_keys
- chown root:root /root/.ssh/authorized_keys
- chmod 600 /root/.ssh/authorized_keys
- # make centos with selinux happy
- which restorecon && restorecon -Rv /root/.ssh
- else
- touch /root/.ssh/authorized_keys
- chown root:root /root/.ssh/authorized_keys
- chmod 600 /root/.ssh/authorized_keys
- fi
- echo '{key}' >> /root/.ssh/authorized_keys
- """.format(
- key=keys
- )
-
- bash_script += keys_data
-
- for user in users_list:
- if "name" in user:
- user_name = user["name"]
-
- if "key-pairs" in user:
- user_keys = "\n".join(user["key-pairs"])
- else:
- user_keys = None
-
- add_user_name = """
- useradd -d /home/{user_name} -m -g users -s /bin/bash {user_name}
- """.format(
- user_name=user_name
- )
-
- bash_script += add_user_name
-
- if user_keys:
- user_keys_data = """
- mkdir /home/{user_name}/.ssh
- chown {user_name}:{user_name} /home/{user_name}/.ssh
- chmod 700 /home/{user_name}/.ssh
- touch /home/{user_name}/.ssh/authorized_keys
- chown {user_name}:{user_name} /home/{user_name}/.ssh/authorized_keys
- chmod 600 /home/{user_name}/.ssh/authorized_keys
- # make centos with selinux happy
- which restorecon && restorecon -Rv /home/{user_name}/.ssh
- echo '{user_key}' >> /home/{user_name}/.ssh/authorized_keys
- """.format(
- user_name=user_name, user_key=user_keys
- )
- bash_script += user_keys_data
-
- return bash_script + "\n\tfi"
-
- def guest_customization(self, vapp, customize_script):
- """
- Method to customize guest os
- vapp - Vapp object
- customize_script - Customize script to be run at first boot of VM.
- """
- for vm in vapp.get_all_vms():
- vm_id = vm.get("id").split(":")[-1]
- vm_name = vm.get("name")
- vm_name = vm_name.replace("_", "-")
-
- vm_customization_url = (
- "{}/api/vApp/vm-{}/guestCustomizationSection/".format(self.url, vm_id)
- )
- headers = {
- "Accept": "application/*+xml;version=" + API_VERSION,
- "x-vcloud-authorization": self.client._session.headers[
- "x-vcloud-authorization"
- ],
- }
-
- headers[
- "Content-Type"
- ] = "application/vnd.vmware.vcloud.guestCustomizationSection+xml"
-
- data = """<GuestCustomizationSection
- xmlns="http://www.vmware.com/vcloud/v1.5"
- xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
- ovf:required="false" href="{}"
- type="application/vnd.vmware.vcloud.guestCustomizationSection+xml">
- <ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
- <Enabled>true</Enabled>
- <ChangeSid>false</ChangeSid>
- <VirtualMachineId>{}</VirtualMachineId>
- <JoinDomainEnabled>false</JoinDomainEnabled>
- <UseOrgSettings>false</UseOrgSettings>
- <AdminPasswordEnabled>false</AdminPasswordEnabled>
- <AdminPasswordAuto>true</AdminPasswordAuto>
- <AdminAutoLogonEnabled>false</AdminAutoLogonEnabled>
- <AdminAutoLogonCount>0</AdminAutoLogonCount>
- <ResetPasswordRequired>false</ResetPasswordRequired>
- <CustomizationScript>{}</CustomizationScript>
- <ComputerName>{}</ComputerName>
- <Link href="{}"
- type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" rel="edit"/>
- </GuestCustomizationSection>
- """.format(
- vm_customization_url,
- vm_id,
- customize_script,
- vm_name,
- vm_customization_url,
- )
-
- response = self.perform_request(
- req_type="PUT", url=vm_customization_url, headers=headers, data=data
- )
- if response.status_code == 202:
- guest_task = self.get_task_from_response(response.text)
- self.client.get_task_monitor().wait_for_success(task=guest_task)
- self.logger.info(
- "guest_customization : customized guest os task "
- "completed for VM {}".format(vm_name)
- )
- else:
- self.logger.error(
- "guest_customization : task for customized guest os"
- "failed for VM {}".format(vm_name)
- )
-
- raise vimconn.VimConnException(
- "guest_customization : failed to perform"
- "guest os customization on VM {}".format(vm_name)
- )
-