def _create_vm(ova_file, machine_name, template, username, vm_kind, logger): with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: ova = Ova(ova_file) try: net_map = _get_network_mapping(vcenter, ova, vm_kind, username) the_vm = virtual_machine.deploy_from_ova(vcenter=vcenter, ova=ova, network_map=net_map, username=username, machine_name=machine_name, logger=logger) finally: ova.close() meta_data = {'component' : template, 'created' : time.time(), 'deployment': True, 'version' : 'n/a', 'configured' : True, 'generation' : 1} virtual_machine.set_meta(the_vm, meta_data) if vm_kind.lower() == 'onefs': info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=False) else: info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}
def test_set_meta_raises(self): """``virtual_machine`` set_meta raises ValueError if supplied with a bad object""" fake_task = MagicMock() fake_task.info.error = None fake_vm = MagicMock() fake_vm.ReconfigVM_Task.return_value = fake_task new_meta = {} with self.assertRaises(ValueError): virtual_machine.set_meta(fake_vm, new_meta)
def create_windows(username, machine_name, image, network, logger): """Deploy a new instance of Windows :Returns: Dictionary :param username: The name of the user who wants to create a new Windows :type username: String :param machine_name: The name of the new instance of Windows :type machine_name: String :param image: The image/version of Windows to create :type image: String :param network: The name of the network to connect the new Windows instance up to :type network: String :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image) logger.info(image_name) try: ova = Ova(os.path.join(const.VLAB_WINDOWS_IMAGES_DIR, image_name)) except FileNotFoundError: error = "Invalid verison of Windows supplied: {}".format(image) raise ValueError(error) try: network_map = vim.OvfManager.NetworkMapping() network_map.name = ova.networks[0] try: network_map.network = vcenter.networks[network] except KeyError: raise ValueError('No such network named {}'.format(network)) the_vm = virtual_machine.deploy_from_ova(vcenter, ova, [network_map], username, machine_name, logger) finally: ova.close() meta_data = { 'component': "Windows", 'created': time.time(), 'version': image, 'configured': False, 'generation': 1, } virtual_machine.set_meta(the_vm, meta_data) info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}
def create_esxi(username, machine_name, image, network, logger): """Deploy a new instance of ESXi :Returns: Dictionary :param username: The name of the user who wants to create a new ESXi :type username: String :param machine_name: The name of the new instance of ESXi :type machine_name: String :param image: The image/version of ESXi to create :type image: String :param network: The name of the network to connect the new ESXi instance up to :type network: String :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image) logger.info(image_name) ova = Ova(os.path.join(const.VLAB_ESXI_IMAGES_DIR, image_name)) try: network_map = vim.OvfManager.NetworkMapping() network_map.name = ova.networks[0] try: network_map.network = vcenter.networks[network] except KeyError: raise ValueError('No such network named {}'.format(network)) the_vm = virtual_machine.deploy_from_ova(vcenter=vcenter, ova=ova, network_map=[network_map], username=username, machine_name=machine_name, logger=logger, power_on=False) finally: ova.close() config_vm(the_vm) virtual_machine.power(the_vm, state='on') meta_data = {'component' : "ESXi", 'created': time.time(), 'version': image, 'configured': False, 'generation': 1, } virtual_machine.set_meta(the_vm, meta_data) info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}
def create_router(username, machine_name, image, requested_networks, logger): """Deploy a new instance of Router :Returns: Dictionary :param username: The name of the user who wants to create a new Router :type username: String :param machine_name: The name of the new instance of Router :type machine_name: String :param image: The image/version of Router to create :type image: String :param requested_networks: The name of the networks to connect the new Router instance up to :type requested_networks: List :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image) logger.info(image_name) try: ova = Ova(os.path.join(const.VLAB_ROUTER_IMAGES_DIR, image_name)) except FileNotFoundError: error = "Invalid version of Router supplied: {}".format(image) raise ValueError(error) try: networks = map_networks(ova.networks, requested_networks, vcenter.networks) the_vm = virtual_machine.deploy_from_ova(vcenter, ova, networks, username, machine_name, logger) finally: ova.close() meta_data = { 'component': "Router", 'created': time.time(), 'version': image, 'configured': False, 'generation': 1, } virtual_machine.set_meta(the_vm, meta_data) info = virtual_machine.get_info(vcenter, the_vm, username) return {the_vm.name: info}
def create_kemp(username, machine_name, image, network, logger): """Deploy a new instance of Kemp :Returns: Dictionary :param username: The name of the user who wants to create a new Kemp :type username: String :param machine_name: The name of the new instance of Kemp :type machine_name: String :param image: The image/version of Kemp to create :type image: String :param network: The name of the network to connect the new Kemp instance up to :type network: String :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image) logger.info(image_name) ova = Ova(os.path.join(const.VLAB_KEMP_IMAGES_DIR, image_name)) network_map = _get_nic_network_map(network, vcenter.networks, ova.networks) try: the_vm = virtual_machine.deploy_from_ova(vcenter, ova, network_map, username, machine_name, logger) finally: ova.close() meta_data = { 'component': "Kemp", 'created': time.time(), 'version': image, 'configured': False, 'generation': 1 } virtual_machine.set_meta(the_vm, meta_data) info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}
def test_set_meta(self): """``virtual_machine`` set_meta stores a JSON object as a VM annotation""" fake_task = MagicMock() fake_task.info.error = None fake_vm = MagicMock() fake_vm.ReconfigVM_Task.return_value = fake_task new_meta = { 'component': 'Windows', 'version': "10", 'generation': 1, 'configured': False, 'created': 1234, } virtual_machine.set_meta(fake_vm, new_meta) meta_obj = json.loads( fake_vm.ReconfigVM_Task.call_args[0][0].annotation) self.assertEqual(new_meta, meta_obj)
def update_meta(username, vm_name, new_meta): """Connect to vSphere and update the VM meta data :Returns: None :param username: The user who owns the OneFS node :type username: String :param vm_name: The name of the VM to update the meta data on :type vm_name: String :param new_meta: The new meta data to overwrite the old meta data with :type new_meta: Dictionary """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, \ password=const.INF_VCENTER_PASSWORD) as vcenter: folder = vcenter.get_by_name(name=username, vimtype=vim.Folder) for vm in folder.childEntity: if vm.name == vm_name: virtual_machine.set_meta(vm, new_meta)
def create_centos(username, machine_name, image, network, desktop, ram, cpu_count, logger): """Deploy a new instance of CentOS :Returns: Dictionary :param username: The name of the user who wants to create a new CentOS :type username: String :param machine_name: The name of the new instance of CentOS :type machine_name: String :param image: The image/version of CentOS to create :type image: String :param network: The name of the network to connect the new CentOS instance up to :type network: String :param network: The name of the network to connect the new CentOS instance up to :type network: String :param desktop: Deploy the VM with a GUI :type desktop: Boolean :param ram: The number of GB of RAM to allocate for the VM :type ram: Integer :param cpu_count: The number of CPU cores to allocate for the VM :type cpu_count: Integer :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image, desktop=desktop) logger.info(image_name) try: ova = Ova(os.path.join(const.VLAB_CENTOS_IMAGES_DIR, image_name)) except FileNotFoundError: error = "Invalid version of CentOS supplied: {}".format(image) raise ValueError(error) try: network_map = vim.OvfManager.NetworkMapping() network_map.name = ova.networks[0] try: network_map.network = vcenter.networks[network] except KeyError: raise ValueError('No such network named {}'.format(network)) the_vm = virtual_machine.deploy_from_ova(vcenter, ova, [network_map], username, machine_name, logger, power_on=False) finally: ova.close() mb_of_ram = ram * 1024 virtual_machine.adjust_ram(the_vm, mb_of_ram) virtual_machine.adjust_cpu(the_vm, cpu_count) virtual_machine.power(the_vm, state='on') meta_data = {'component' : "CentOS", 'created': time.time(), 'version': image, 'configured': False, 'generation': 1, } virtual_machine.set_meta(the_vm, meta_data) info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}
def create_onefs(username, machine_name, image, front_end, back_end, ram, cpu_count, logger): """Deploy a OneFS node :Returns: Dictionary :param username: The user who wants to delete a OneFS node :type username: String :param machine_name: The name of the OneFS node :type machine_name: String :param image: The version/image of the OneFS node to create :type image: String :param front_end: The network to hook up the external network to :type front_end: String :param back_end: The network to hook the internal network to :type back_end: String :param ram: The number of GB of memory to provision the node with :type ram: Integer :param cpu_count: The number of CPU cores to allocate to the vOneFS node :type cpu_count: Integer :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, \ password=const.INF_VCENTER_PASSWORD) as vcenter: ova_name = convert_name(image) try: ova = Ova(os.path.join(const.VLAB_ONEFS_IMAGES_DIR, ova_name)) except FileNotFoundError: error = 'Invalid version of OneFS: {}'.format(image) raise ValueError(error) try: network_map = make_network_map(vcenter.networks, front_end, back_end) the_vm = virtual_machine.deploy_from_ova(vcenter=vcenter, ova=ova, network_map=network_map, username=username, machine_name=machine_name, logger=logger, power_on=False) finally: ova.close() # ram is supplied in GB mb_of_ram = ram * 1024 virtual_machine.adjust_ram(the_vm, mb_of_ram=mb_of_ram) virtual_machine.adjust_cpu(the_vm, cpu_count) virtual_machine.power(the_vm, state='on') meta_data = { 'component': 'OneFS', 'created': time.time(), 'version': image, 'configured': False, 'generation': 1 } # Versioning of the VM itself virtual_machine.set_meta(the_vm, meta_data) info = virtual_machine.get_info(vcenter, the_vm, username) return {the_vm.name: info}
def _setup_gateway(vcenter, the_vm, username, gateway_version, logger): """Initialize the new gateway for the user :Returns: None :param vcenter: The instantiated connection to vCenter :type vcenter: vlab_inf_common.vmware.vCenter :param the_vm: The new gateway :type the_vm: vim.VirtualMachine """ time.sleep(120) # Let the VM fully boot vlab_ip = resolve_name( const.VLAB_URL.replace('https://', '').replace('http://', '')) cmd1 = '/usr/bin/sudo' args1 = '/usr/bin/hostnamectl set-hostname {}'.format(username) result1 = virtual_machine.run_command(vcenter, the_vm, cmd1, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args1) if result1.exitCode: logger.error('Failed to set hostname to {}'.format(username)) # Updating hostname fixes SPAM when SSH into box about "failure to resolve <host>" cmd2 = '/usr/bin/sudo' args2 = "/bin/sed -i -e 's/ipam/{}/g' /etc/hosts".format(username) result2 = virtual_machine.run_command(vcenter, the_vm, cmd2, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args2) if result2.exitCode: logger.error('Failed to fix hostname SPAM') # Fix the env var for the log_sender cmd3 = '/usr/bin/sudo' args3 = "/bin/sed -i -e 's/VLAB_LOG_TARGET=localhost:9092/VLAB_LOG_TARGET={}/g' /etc/environment".format( const.VLAB_IPAM_BROKER) result3 = virtual_machine.run_command(vcenter, the_vm, cmd3, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args3) if result3.exitCode: logger.error('Failed to set IPAM log-sender address') # Set the encryption key for log_sender cmd4 = '/usr/bin/sudo' args4 = "/bin/sed -i -e 's/changeME/{}/g' /etc/vlab/log_sender.key".format( const.VLAB_IPAM_KEY) result4 = virtual_machine.run_command(vcenter, the_vm, cmd4, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args4) if result4.exitCode: logger.error('Failed to set IPAM encryption key') logger.error('CMD: {} {}'.format(cmd4, args4)) logger.error('Result: \n{}'.format(result4)) cmd5 = '/usr/bin/sudo' args5 = "/bin/sed -i -e 's/VLAB_URL=https:\/\/localhost/VLAB_URL={}/g' /etc/environment".format( const.VLAB_URL.replace('/', '\/')) result5 = virtual_machine.run_command(vcenter, the_vm, cmd5, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args5) if result5.exitCode: logger.error('Failed to set VLAB_URL environment variable') cmd6 = '/usr/bin/sudo' args6 = "/bin/sed -i -e 's/PRODUCTION=false/PRODUCTION=beta/g' /etc/environment" result6 = virtual_machine.run_command(vcenter, the_vm, cmd6, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args6) if result6.exitCode: logger.error('Failed to set PRODUCTION environment variable') cmd7 = '/usr/bin/sudo' args7 = "/bin/sed -i -e 's/1.us.pool.ntp.org/{}/g' /etc/chrony/chrony.conf".format( vlab_ip) result7 = virtual_machine.run_command(vcenter, the_vm, cmd7, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args7) if result7.exitCode: logger.error('Failed to set NTP server') cmd8 = '/usr/bin/sudo' args8 = "/bin/sed -i -e 's/VLAB_DDNS_KEY=aabbcc/VLAB_DDNS_KEY={}/g' /etc/environment".format( const.VLAB_DDNS_KEY) result8 = virtual_machine.run_command(vcenter, the_vm, cmd8, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args8) if result8.exitCode: logger.error('Failed to configure DDNS settings') cmd9 = '/usr/bin/sudo' args9 = "sed -i -e 's/8.8.8.8/{}/g' /etc/bind/named.conf".format(vlab_ip) result9 = virtual_machine.run_command(vcenter, the_vm, cmd9, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args9) if result9.exitCode: logger.error('Failed to configure DNS forwarder') # *MUST* happen after setting up the hostname otherwise the salt-minion will # use the default hostname when registering with the salt-master cmd10 = '/usr/bin/sudo' args10 = "/bin/systemctl enable salt-minion.service" result10 = virtual_machine.run_command(vcenter, the_vm, cmd10, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args10) if result10.exitCode: logger.error('Failed to enable Config Mgmt Software') cmd11 = '/usr/bin/sudo' args11 = "/bin/sed -i -e 's/#master: salt/master: {}/g' /etc/salt/minion".format( vlab_ip) result11 = virtual_machine.run_command(vcenter, the_vm, cmd11, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args11) if result11.exitCode: logger.error('Failed to configure Config Mgmt Software') cmd12 = '/usr/bin/sudo' args12 = "/bin/sed -i -e 's/$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat/#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat/g' /etc/rsyslog.conf" result12 = virtual_machine.run_command(vcenter, the_vm, cmd12, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args12) if result12.exitCode: logger.error('Failed to set kern.log timestamp format') cmd13 = '/usr/bin/sudo' args13 = '/sbin/reboot' result13 = virtual_machine.run_command(vcenter, the_vm, cmd13, user=const.VLAB_IPAM_ADMIN, password=const.VLAB_IPAM_ADMIN_PW, arguments=args13, one_shot=True) if result13.exitCode: logger.error('Failed to reboot IPAM server') meta_data = { 'component': 'defaultGateway', 'created': time.time(), 'version': gateway_version, 'configured': True, 'generation': 1 } virtual_machine.set_meta(the_vm, meta_data) time.sleep(60) # Give the box time to power cycles
def create_winserver(username, machine_name, image, network, ip_config, logger): """Deploy a new instance of WinServer :Returns: Dictionary :param username: The name of the user who wants to create a new WinServer :type username: String :param machine_name: The name of the new instance of WinServer :type machine_name: String :param image: The image/version of WinServer to create :type image: String :param network: The name of the network to connect the new WinServer instance up to :type network: String :param ip_config: The IPv4 network configuration for the WinServer instance :type ip_config: Dictionary :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image) logger.info(image_name) try: ova = Ova(os.path.join(const.VLAB_WINSERVER_IMAGES_DIR, image_name)) except FileNotFoundError: error = 'Invalid version of Windows Server supplied: {}'.format(image) raise ValueError(error) try: network_map = vim.OvfManager.NetworkMapping() network_map.name = ova.networks[0] try: network_map.network = vcenter.networks[network] except KeyError: raise ValueError('No such network named {}'.format(network)) the_vm = virtual_machine.deploy_from_ova(vcenter, ova, [network_map], username, machine_name, logger) finally: ova.close() if ip_config['static-ip']: # Hack - The VM will walk through the C:\unattend.xml answer file # and then reboot. We wont have valid login creds until after the # reboot. Trying to *notice* the reboot is a race condition nightmare time.sleep(300) virtual_machine.config_static_ip(vcenter, the_vm, ip_config['static-ip'], ip_config['default-gateway'], ip_config['netmask'], ip_config['dns'], user='******', password='******', logger=logger, os='windows') meta_data = {'component' : "WinServer", 'created': time.time(), 'version': image, 'configured': False, 'generation': 1, } virtual_machine.set_meta(the_vm, meta_data) info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}
def create_dataiq(username, machine_name, image, network, static_ip, default_gateway, netmask, dns, disk_size, cpu_count, ram, logger): """Deploy a new instance of DataIQ :Returns: Dictionary :param username: The name of the user who wants to create a new DataIQ :type username: String :param machine_name: The name of the new instance of DataIQ :type machine_name: String :param image: The image/version of DataIQ to create :type image: String :param network: The name of the network to connect the new DataIQ instance up to :type network: String :param static_ip: The IPv4 address to assign to the VM :type static_ip: String :param default_gateway: The IPv4 address of the network gateway :type default_gateway: String :param netmask: The subnet mask of the network, i.e. 255.255.255.0 :type netmask: String :param dns: A list of DNS servers to use. :type dns: List :param disk_size: The number of GB to allocate for the DataIQ database :type disk_size: Integer :param cpu_count: Thenumber of CPU cores to allocate to the DataIQ machine :type cpu_count: Integer :param ram: The number of GB of RAM to allocate to the VM :type ram: Integer :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image) logger.info(image) ova = Ova(os.path.join(const.VLAB_DATAIQ_IMAGES_DIR, image_name)) try: network_map = vim.OvfManager.NetworkMapping() network_map.name = ova.networks[0] try: network_map.network = vcenter.networks[network] except KeyError: raise ValueError('No such network named {}'.format(network)) the_vm = virtual_machine.deploy_from_ova(vcenter=vcenter, ova=ova, network_map=[network_map], username=username, machine_name=machine_name, logger=logger, power_on=False) finally: ova.close() mb_of_ram = ram * 1024 virtual_machine.adjust_ram(the_vm, mb_of_ram) virtual_machine.adjust_cpu(the_vm, cpu_count) virtual_machine.power(the_vm, state='on') meta_data = {'component' : "DataIQ", 'created' : time.time(), 'version' : image, 'configured' : False, 'generation' : 1} virtual_machine.set_meta(the_vm, meta_data) logger.info("Adding DB VMDK") _add_database_disk(the_vm, disk_size) logger.info("Configuring network") _config_network(vcenter, the_vm, static_ip, default_gateway, netmask, dns, logger) logger.info("Adding GUI") _add_gui(vcenter, the_vm, logger) logger.info("Acquiring machine info") info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}
def create_dns(username, machine_name, image, network, static_ip, default_gateway, netmask, dns, logger): """Deploy a new instance of Dns :Returns: Dictionary :param username: The name of the user who wants to create a new Dns :type username: String :param machine_name: The name of the new instance of Dns :type machine_name: String :param image: The image/version of Dns to create :type image: String :param network: The name of the network to connect the new Dns instance up to :type network: String :param static_ip: The IPv4 address to assign to the VM :type static_ip: String :param default_gateway: The IPv4 address of the network gateway :type default_gateway: String :param netmask: The subnet mask of the network, i.e. 255.255.255.0 :type netmask: String :param dns: A list of DNS servers to use. :type dns: List :param logger: An object for logging messages :type logger: logging.LoggerAdapter """ with vCenter(host=const.INF_VCENTER_SERVER, user=const.INF_VCENTER_USER, password=const.INF_VCENTER_PASSWORD) as vcenter: image_name = convert_name(image) logger.info(image_name) ova = Ova(os.path.join(const.VLAB_DNS_IMAGES_DIR, image_name)) try: network_map = vim.OvfManager.NetworkMapping() network_map.name = ova.networks[0] try: network_map.network = vcenter.networks[network] except KeyError: raise ValueError('No such network named {}'.format(network)) the_vm = virtual_machine.deploy_from_ova(vcenter, ova, [network_map], username, machine_name, logger) finally: ova.close() meta_data = { 'component': "Dns", 'created': time.time(), 'version': image, 'configured': False, 'generation': 1 } virtual_machine.set_meta(the_vm, meta_data) if image.lower().startswith('windows'): vm_user, vm_password, the_os = const.VLAB_DNS_WINDOWS_ADMIN, const.VLAB_DNS_WINDOWS_PW, 'windows' else: vm_user, vm_password, the_os = const.VLAB_DNS_BIND9_ADMIN, const.VLAB_DNS_BIND9_PW, 'centos8' virtual_machine.config_static_ip(vcenter, the_vm, static_ip, default_gateway, netmask, dns, vm_user, vm_password, logger, os=the_os) if the_os == 'centos8': _finish_bind_config(vcenter, the_vm, static_ip, logger) info = virtual_machine.get_info(vcenter, the_vm, username, ensure_ip=True) return {the_vm.name: info}