%PDF- %PDF-
Direktori : /proc/thread-self/root/lib/python2.7/site-packages/salt/cloud/clouds/ |
Current File : //proc/thread-self/root/lib/python2.7/site-packages/salt/cloud/clouds/xen.py |
# -*- coding: utf-8 -*- ''' XenServer Cloud Driver ====================== The XenServer driver is designed to work with a Citrix XenServer. Requires XenServer SDK (can be downloaded from https://www.citrix.com/downloads/xenserver/product-software/ ) Place a copy of the XenAPI.py in the Python site-packages folder. :depends: XenAPI Example provider configuration: .. code-block:: yaml # /etc/salt/cloud.providers.d/myxen.conf myxen: driver: xen url: http://10.0.0.120 user: root password: p@ssw0rd Example profile configuration: .. code-block:: yaml # /etc/salt/cloud.profiles.d/myxen.conf suse: provider: myxen user: root password: p@ssw0rd image: opensuseleap42_2-template storage_repo: 'Local storage' resource_pool: default_pool clone: True minion: master: 10.0.0.18 sles: provider: myxen user: root clone: False image: sles12sp2-template deploy: False w2k12: provider: myxen image: w2k12svr-template clone: True userdata_file: /srv/salt/win/files/windows-firewall.ps1 win_installer: /srv/salt/win/files/Salt-Minion-2016.11.3-AMD64-Setup.exe win_username: Administrator win_password: p@ssw0rd use_winrm: False ipv4_cidr: 10.0.0.215/24 ipv4_gw: 10.0.0.1 ''' # Import python libs from __future__ import absolute_import, print_function, unicode_literals from datetime import datetime import logging import time # Import salt libs import salt.config as config from salt.ext import six # Import Salt-Cloud Libs import salt.utils.cloud from salt.exceptions import ( SaltCloudSystemExit, SaltCloudException ) # Get logging started log = logging.getLogger(__name__) try: import XenAPI HAS_XEN_API = True except ImportError: HAS_XEN_API = False __virtualname__ = 'xen' cache = None def __virtual__(): ''' Only load if Xen configuration and XEN SDK is found. ''' if get_configured_provider() is False: return False if _get_dependencies() is False: return False global cache # pylint: disable=global-statement,invalid-name cache = salt.cache.Cache(__opts__) return __virtualname__ def _get_dependencies(): ''' Warn if dependencies aren't met. Checks for the XenAPI.py module ''' return config.check_driver_dependencies( __virtualname__, {'XenAPI': HAS_XEN_API} ) def get_configured_provider(): ''' Return the first configured instance. ''' return config.is_provider_configured( __opts__, __active_provider_name__ or __virtualname__, ('url',) ) def _get_session(): ''' Get a connection to the XenServer host ''' api_version = '1.0' originator = 'salt_cloud_{}_driver'.format(__virtualname__) url = config.get_cloud_config_value( 'url', get_configured_provider(), __opts__, search_global=False ) user = config.get_cloud_config_value( 'user', get_configured_provider(), __opts__, search_global=False ) password = config.get_cloud_config_value( 'password', get_configured_provider(), __opts__, search_global=False ) ignore_ssl = config.get_cloud_config_value( 'ignore_ssl', get_configured_provider(), __opts__, default=False, search_global=False ) try: session = XenAPI.Session(url, ignore_ssl=ignore_ssl) log.debug( 'url: %s user: %s password: %s, originator: %s', url, user, 'XXX-pw-redacted-XXX', originator ) session.xenapi.login_with_password( user, password, api_version, originator) except XenAPI.Failure as ex: pool_master_addr = six.text_type(ex.__dict__['details'][1]) slash_parts = url.split('/') new_url = '/'.join(slash_parts[:2]) + '/' + pool_master_addr session = XenAPI.Session(new_url) log.debug( 'session is -> url: %s user: %s password: %s, originator:%s', new_url, user, 'XXX-pw-redacted-XXX', originator ) session.xenapi.login_with_password( user, password, api_version, originator) return session def list_nodes(): ''' List virtual machines .. code-block:: bash salt-cloud -Q ''' session = _get_session() vms = session.xenapi.VM.get_all_records() ret = {} for vm in vms: record = session.xenapi.VM.get_record(vm) if not record['is_a_template'] and not record['is_control_domain']: try: base_template_name = record['other_config']['base_template_name'] except Exception: base_template_name = None log.debug( 'VM %s, doesnt have base_template_name attribute', record['name_label'] ) ret[record['name_label']] = {'id': record['uuid'], 'image': base_template_name, 'name': record['name_label'], 'size': record['memory_dynamic_max'], 'state': record['power_state'], 'private_ips': get_vm_ip(record['name_label'], session), 'public_ips': None} return ret def get_vm_ip(name=None, session=None, call=None): ''' Get the IP address of the VM .. code-block:: bash salt-cloud -a get_vm_ip xenvm01 .. note:: Requires xen guest tools to be installed in VM ''' if call == 'function': raise SaltCloudException( 'This function must be called with -a or --action.' ) if session is None: log.debug('New session being created') session = _get_session() vm = _get_vm(name, session=session) ret = None # -- try to get ip from vif vifs = session.xenapi.VM.get_VIFs(vm) if vifs is not None: for vif in vifs: if session.xenapi.VIF.get_ipv4_addresses(vif): cidr = session.xenapi.VIF.get_ipv4_addresses(vif).pop() ret, subnet = cidr.split('/') log.debug( 'VM vif returned for instance: %s ip: %s', name, ret) return ret # -- try to get ip from get tools metrics vgm = session.xenapi.VM.get_guest_metrics(vm) try: net = session.xenapi.VM_guest_metrics.get_networks(vgm) if "0/ip" in net.keys(): log.debug( 'VM guest metrics returned for instance: %s 0/ip: %s', name, net["0/ip"] ) ret = net["0/ip"] # except Exception as ex: except XenAPI.Failure: log.info('Could not get vm metrics at this time') return ret def set_vm_ip(name=None, ipv4_cidr=None, ipv4_gw=None, session=None, call=None): ''' Set the IP address on a virtual interface (vif) ''' mode = 'static' # TODO: Need to add support for IPv6 if call == 'function': raise SaltCloudException( 'The function must be called with -a or --action.') log.debug( 'Setting name: %s ipv4_cidr: %s ipv4_gw: %s mode: %s', name, ipv4_cidr, ipv4_gw, mode ) if session is None: log.debug('New session being created') session = _get_session() vm = _get_vm(name, session) # -- try to get ip from vif # TODO: for now will take first interface # addition consideration needed for # multiple interface(vif) VMs vifs = session.xenapi.VM.get_VIFs(vm) if vifs is not None: log.debug('There are %s vifs.', len(vifs)) for vif in vifs: record = session.xenapi.VIF.get_record(vif) log.debug(record) try: session.xenapi.VIF.configure_ipv4( vif, mode, ipv4_cidr, ipv4_gw) except XenAPI.Failure: log.info('Static IP assignment could not be performed.') return True def list_nodes_full(session=None): ''' List full virtual machines .. code-block:: bash salt-cloud -F ''' if session is None: session = _get_session() ret = {} vms = session.xenapi.VM.get_all() for vm in vms: record = session.xenapi.VM.get_record(vm) if not record['is_a_template'] and not record['is_control_domain']: # deal with cases where the VM doesn't have 'base_template_name' attribute try: base_template_name = record['other_config']['base_template_name'] except Exception: base_template_name = None log.debug( 'VM %s, doesnt have base_template_name attribute', record['name_label'] ) vm_cfg = session.xenapi.VM.get_record(vm) vm_cfg['id'] = record['uuid'] vm_cfg['name'] = record['name_label'] vm_cfg['image'] = base_template_name vm_cfg['size'] = None vm_cfg['state'] = record['power_state'] vm_cfg['private_ips'] = get_vm_ip(record['name_label'], session) vm_cfg['public_ips'] = None if 'snapshot_time' in vm_cfg.keys(): del vm_cfg['snapshot_time'] ret[record['name_label']] = vm_cfg provider = __active_provider_name__ or 'xen' if ':' in provider: comps = provider.split(':') provider = comps[0] log.debug('ret: %s', ret) log.debug('provider: %s', provider) log.debug('__opts__: %s', __opts__) __utils__['cloud.cache_node_list'](ret, provider, __opts__) return ret def list_nodes_select(call=None): ''' Perform a select query on Xen VM instances .. code-block:: bash salt-cloud -S ''' return salt.utils.cloud.list_nodes_select( list_nodes_full(), __opts__['query.selection'], call, ) def vdi_list(call=None, kwargs=None): ''' Return available Xen VDI images If this function is called with the ``-f`` or ``--function`` then it can return a list with minimal deatil using the ``terse=True`` keyword argument. .. code-block:: bash salt-cloud -f vdi_list myxen terse=True ''' if call == 'action': raise SaltCloudException( 'This function must be called with -f or --function.') log.debug('kwargs is %s', kwargs) if kwargs is not None: if 'terse' in kwargs: if kwargs['terse'] == 'True': terse = True else: terse = False else: terse = False else: kwargs = {} terse = False session = _get_session() vdis = session.xenapi.VDI.get_all() ret = {} for vdi in vdis: data = session.xenapi.VDI.get_record(vdi) log.debug(type(terse)) if terse is True: ret[data.get('name_label')] = { 'uuid': data.get('uuid'), 'OpqueRef': vdi} else: data.update({'OpaqueRef': vdi}) ret[data.get('name_label')] = data return ret def avail_locations(session=None, call=None): ''' Return available Xen locations (not implemented) .. code-block:: bash salt-cloud --list-locations myxen ''' # TODO: need to figure out a good meaning of locations in Xen if call == 'action': raise SaltCloudException( 'The avail_locations function must be called with -f or --function.' ) return pool_list() def avail_sizes(session=None, call=None): ''' Return a list of Xen template definitions .. code-block:: bash salt-cloud --list-sizes myxen ''' if call == 'action': raise SaltCloudException( 'The avail_sizes function must be called with -f or --function.') return {'STATUS': 'Sizes are build into templates. Consider running --list-images to see sizes'} def template_list(call=None): ''' Return available Xen template information. This returns the details of each template to show number cores, memory sizes, etc.. .. code-block:: bash salt-cloud -f template_list myxen ''' templates = {} session = _get_session() vms = session.xenapi.VM.get_all() for vm in vms: record = session.xenapi.VM.get_record(vm) if record['is_a_template']: templates[record['name_label']] = record return templates def show_instance(name, session=None, call=None): ''' Show information about a specific VM or template .. code-block:: bash salt-cloud -a show_instance xenvm01 .. note:: memory is memory_dynamic_max ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) log.debug('show_instance-> name: %s session: %s', name, session) if session is None: session = _get_session() vm = _get_vm(name, session=session) record = session.xenapi.VM.get_record(vm) if not record['is_a_template'] and not record['is_control_domain']: try: base_template_name = record['other_config']['base_template_name'] except Exception: base_template_name = None log.debug( 'VM %s, doesnt have base_template_name attribute', record['name_label'] ) ret = {'id': record['uuid'], 'image': base_template_name, 'name': record['name_label'], 'size': record['memory_dynamic_max'], 'state': record['power_state'], 'private_ips': get_vm_ip(name, session), 'public_ips': None} __utils__['cloud.cache_node']( ret, __active_provider_name__, __opts__ ) return ret def _determine_resource_pool(session, vm_): ''' Called by create() used to determine resource pool ''' resource_pool = '' if 'resource_pool' in vm_.keys(): resource_pool = _get_pool(vm_['resource_pool'], session) else: pool = session.xenapi.pool.get_all() if not pool: resource_pool = None else: first_pool = session.xenapi.pool.get_all()[0] resource_pool = first_pool pool_record = session.xenapi.pool.get_record(resource_pool) log.debug('resource pool: %s', pool_record['name_label']) return resource_pool def _determine_storage_repo(session, resource_pool, vm_): ''' Called by create() used to determine storage repo for create ''' storage_repo = '' if 'storage_repo' in vm_.keys(): storage_repo = _get_sr(vm_['storage_repo'], session) else: storage_repo = None if resource_pool: default_sr = session.xenapi.pool.get_default_SR(resource_pool) sr_record = session.xenapi.SR.get_record(default_sr) log.debug('storage repository: %s', sr_record['name_label']) storage_repo = default_sr else: storage_repo = None log.debug('storage repository: %s', storage_repo) return storage_repo def create(vm_): ''' Create a VM in Xen The configuration for this function is read from the profile settings. .. code-block:: bash salt-cloud -p some_profile xenvm01 ''' name = vm_['name'] record = {} ret = {} # fire creating event __utils__['cloud.fire_event']( 'event', 'starting create', 'salt/cloud/{0}/creating'.format(name), args={ 'name': name, 'profile': vm_['profile'], 'provider': vm_['driver'], }, sock_dir=__opts__['sock_dir'], transport=__opts__['transport'] ) log.debug('Adding %s to cloud cache.', name) __utils__['cloud.cachedir_index_add']( vm_['name'], vm_['profile'], 'xen', vm_['driver'] ) # connect to xen session = _get_session() # determine resource pool resource_pool = _determine_resource_pool(session, vm_) # determine storage repo storage_repo = _determine_storage_repo(session, resource_pool, vm_) # build VM image = vm_.get('image') clone = vm_.get('clone') if clone is None: clone = True log.debug('Clone: %s ', clone) # fire event to read new vm properties (requesting) __utils__['cloud.fire_event']( 'event', 'requesting instance', 'salt/cloud/{0}/requesting'.format(name), sock_dir=__opts__['sock_dir'], transport=__opts__['transport'] ) # create by cloning template if clone: _clone_vm(image, name, session) else: _copy_vm(image, name, session, storage_repo) # provision template to vm _provision_vm(name, session) vm = _get_vm(name, session) # start vm start(name, None, session) # get new VM vm = _get_vm(name, session) # wait for vm to report IP via guest tools _wait_for_ip(name, session) # set static IP if configured _set_static_ip(name, session, vm_) # if not deploying salt then exit deploy = vm_.get('deploy', True) log.debug('delopy is set to %s', deploy) if deploy: record = session.xenapi.VM.get_record(vm) if record is not None: _deploy_salt_minion(name, session, vm_) else: log.debug( 'The Salt minion will not be installed, deploy: %s', vm_['deploy'] ) record = session.xenapi.VM.get_record(vm) ret = show_instance(name) ret.update({'extra': record}) __utils__['cloud.fire_event']( 'event', 'created instance', 'salt/cloud/{0}/created'.format(name), args={ 'name': name, 'profile': vm_['profile'], 'provider': vm_['driver'], }, sock_dir=__opts__['sock_dir'], transport=__opts__['transport'] ) return ret def _deploy_salt_minion(name, session, vm_): ''' Deploy salt minion during create() ''' # Get bootstrap values vm_['ssh_host'] = get_vm_ip(name, session) vm_['user'] = vm_.get('user', 'root') vm_['password'] = vm_.get('password', 'p@ssw0rd!') vm_['provider'] = vm_.get('provider', 'xen') log.debug('%s has IP of %s', name, vm_['ssh_host']) # Bootstrap Salt minion! if vm_['ssh_host'] is not None: log.info('Installing Salt minion on %s', name) boot_ret = __utils__['cloud.bootstrap'](vm_, __opts__) log.debug('boot return: %s', boot_ret) def _set_static_ip(name, session, vm_): ''' Set static IP during create() if defined ''' ipv4_cidr = '' ipv4_gw = '' if 'ipv4_gw' in vm_.keys(): log.debug('ipv4_gw is found in keys') ipv4_gw = vm_['ipv4_gw'] if 'ipv4_cidr' in vm_.keys(): log.debug('ipv4_cidr is found in keys') ipv4_cidr = vm_['ipv4_cidr'] log.debug('attempting to set IP in instance') set_vm_ip(name, ipv4_cidr, ipv4_gw, session, None) def _wait_for_ip(name, session): ''' Wait for IP to be available during create() ''' start_time = datetime.now() status = None while status is None: status = get_vm_ip(name, session) if status is not None: # ignore APIPA address if status.startswith('169'): status = None check_time = datetime.now() delta = check_time - start_time log.debug( 'Waited %s seconds for %s to report ip address...', delta.seconds, name ) if delta.seconds > 180: log.warning('Timeout getting IP address') break time.sleep(5) def _run_async_task(task=None, session=None): ''' Run XenAPI task in asynchronous mode to prevent timeouts ''' if task is None or session is None: return None task_name = session.xenapi.task.get_name_label(task) log.debug('Running %s', task_name) while session.xenapi.task.get_status(task) == 'pending': progress = round(session.xenapi.task.get_progress(task), 2) * 100 log.debug('Task progress %.2f%%', progress) time.sleep(1) log.debug('Cleaning up task %s', task_name) session.xenapi.task.destroy(task) def _clone_vm(image=None, name=None, session=None): ''' Create VM by cloning This is faster and should be used if source and target are in the same storage repository ''' if session is None: session = _get_session() log.debug('Creating VM %s by cloning %s', name, image) source = _get_vm(image, session) task = session.xenapi.Async.VM.clone(source, name) _run_async_task(task, session) def _copy_vm(template=None, name=None, session=None, sr=None): ''' Create VM by copy This is slower and should be used if source and target are NOT in the same storage repository template = object reference name = string name of new VM session = object reference sr = object reference ''' if session is None: session = _get_session() log.debug('Creating VM %s by copying %s', name, template) source = _get_vm(template, session) task = session.xenapi.Async.VM.copy(source, name, sr) _run_async_task(task, session) def _provision_vm(name=None, session=None): ''' Provision vm right after clone/copy ''' if session is None: session = _get_session() log.info('Provisioning VM %s', name) vm = _get_vm(name, session) task = session.xenapi.Async.VM.provision(vm) _run_async_task(task, session) def start(name, call=None, session=None): ''' Start a vm .. code-block:: bash salt-cloud -a start xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) if session is None: session = _get_session() log.info('Starting VM %s', name) vm = _get_vm(name, session) task = session.xenapi.Async.VM.start(vm, False, True) _run_async_task(task, session) return show_instance(name) def pause(name, call=None, session=None): ''' Pause a vm .. code-block:: bash salt-cloud -a pause xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) if session is None: session = _get_session() log.info('Pausing VM %s', name) vm = _get_vm(name, session) task = session.xenapi.Async.VM.pause(vm) _run_async_task(task, session) return show_instance(name) def unpause(name, call=None, session=None): ''' UnPause a vm .. code-block:: bash salt-cloud -a unpause xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) if session is None: session = _get_session() log.info('Unpausing VM %s', name) vm = _get_vm(name, session) task = session.xenapi.Async.VM.unpause(vm) _run_async_task(task, session) return show_instance(name) def suspend(name, call=None, session=None): ''' Suspend a vm to disk .. code-block:: bash salt-cloud -a suspend xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) if session is None: session = _get_session() log.info('Suspending VM %s', name) vm = _get_vm(name, session) task = session.xenapi.Async.VM.suspend(vm) _run_async_task(task, session) return show_instance(name) def resume(name, call=None, session=None): ''' Resume a vm from disk .. code-block:: bash salt-cloud -a resume xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) if session is None: session = _get_session() log.info('Resuming VM %s', name) vm = _get_vm(name, session) task = session.xenapi.Async.VM.resume(vm, False, True) _run_async_task(task, session) return show_instance(name) def stop(name, call=None, session=None): ''' Stop a vm .. code-block:: bash salt-cloud -a stop xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) return shutdown(name, call, session) def shutdown(name, call=None, session=None): ''' Shutdown a vm .. code-block:: bash salt-cloud -a shutdown xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) if session is None: session = _get_session() log.info('Starting VM %s', name) vm = _get_vm(name, session) task = session.xenapi.Async.VM.shutdown(vm) _run_async_task(task, session) return show_instance(name) def reboot(name, call=None, session=None): ''' Reboot a vm .. code-block:: bash salt-cloud -a reboot xenvm01 ''' if call == 'function': raise SaltCloudException( 'The show_instnce function must be called with -a or --action.' ) if session is None: session = _get_session() log.info('Starting VM %s', name) vm = _get_vm(name, session) power_state = session.xenapi.VM.get_power_state(vm) if power_state == 'Running': task = session.xenapi.Async.VM.clean_reboot(vm) _run_async_task(task, session) return show_instance(name) else: return '{} is not running to be rebooted'.format(name) def _get_vm(name=None, session=None): ''' Get XEN vm instance object reference ''' if session is None: session = _get_session() vms = session.xenapi.VM.get_by_name_label(name) if len(vms) == 1: return vms[0] return None def _get_sr(name=None, session=None): ''' Get XEN sr (storage repo) object reference ''' if session is None: session = _get_session() srs = session.xenapi.SR.get_by_name_label(name) if len(srs) == 1: return srs[0] return None def _get_pool(name=None, session=None): ''' Get XEN resource pool object reference ''' if session is None: session = _get_session() pools = session.xenapi.pool.get_all() for pool in pools: pool_record = session.xenapi.pool.get_record(pool) if name in pool_record.get('name_label'): return pool return None def destroy(name=None, call=None): ''' Destroy Xen VM or template instance .. code-block:: bash salt-cloud -d xenvm01 ''' if call == 'function': raise SaltCloudSystemExit( 'The destroy action must be called with -d, --destroy, ' '-a or --action.' ) ret = {} __utils__['cloud.fire_event']( 'event', 'destroying instance', 'salt/cloud/{0}/destroying'.format(name), args={'name': name}, sock_dir=__opts__['sock_dir'], transport=__opts__['transport'] ) session = _get_session() vm = _get_vm(name) if vm: # get vm record = session.xenapi.VM.get_record(vm) log.debug('power_state: %s', record['power_state']) # shut down if record['power_state'] != 'Halted': task = session.xenapi.Async.VM.hard_shutdown(vm) _run_async_task(task, session) # destroy disk (vdi) by reading vdb on vm ret['vbd'] = destroy_vm_vdis(name, session) # destroy vm task = session.xenapi.Async.VM.destroy(vm) _run_async_task(task, session) ret['destroyed'] = True __utils__['cloud.fire_event']( 'event', 'destroyed instance', 'salt/cloud/{0}/destroyed'.format(name), args={'name': name}, sock_dir=__opts__['sock_dir'], transport=__opts__['transport'] ) if __opts__.get('update_cachedir', False) is True: __utils__['cloud.delete_minion_cachedir']( name, __active_provider_name__.split(':')[0], __opts__ ) __utils__['cloud.cachedir_index_del'](name) return ret def sr_list(call=None): ''' Geta list of storage repositories .. code-block:: bash salt-cloud -f sr_list myxen ''' if call != 'function': raise SaltCloudSystemExit( 'This function must be called with -f, --function argument.' ) ret = {} session = _get_session() srs = session.xenapi.SR.get_all() for sr in srs: sr_record = session.xenapi.SR.get_record(sr) ret[sr_record['name_label']] = sr_record return ret def host_list(call=None): ''' Get a list of Xen Servers .. code-block:: bash salt-cloud -f host_list myxen ''' if call == 'action': raise SaltCloudSystemExit( 'This function must be called with -f, --function argument.' ) ret = {} session = _get_session() hosts = session.xenapi.host.get_all() for host in hosts: host_record = session.xenapi.host.get_record(host) ret[host_record['name_label']] = host_record return ret def pool_list(call=None): ''' Get a list of Resource Pools .. code-block:: bash salt-cloud -f pool_list myxen ''' if call == 'action': raise SaltCloudSystemExit( 'This function must be called with -f, --function argument.' ) ret = {} session = _get_session() pools = session.xenapi.pool.get_all() for pool in pools: pool_record = session.xenapi.pool.get_record(pool) ret[pool_record['name_label']] = pool_record return ret def pif_list(call=None): ''' Get a list of Resource Pools .. code-block:: bash salt-cloud -f pool_list myxen ''' if call != 'function': raise SaltCloudSystemExit( 'This function must be called with -f, --function argument.' ) ret = {} session = _get_session() pifs = session.xenapi.PIF.get_all() for pif in pifs: record = session.xenapi.PIF.get_record(pif) ret[record['uuid']] = record return ret def vif_list(name, call=None, kwargs=None): ''' Get a list of virtual network interfaces on a VM **requires**: the name of the vm with the vbd definition .. code-block:: bash salt-cloud -a vif_list xenvm01 ''' if call == 'function': raise SaltCloudSystemExit( 'This function must be called with -a, --action argument.' ) if name is None: return 'A name kwarg is rquired' ret = {} data = {} session = _get_session() vm = _get_vm(name) vifs = session.xenapi.VM.get_VIFs(vm) if vifs is not None: x = 0 for vif in vifs: vif_record = session.xenapi.VIF.get_record(vif) data['vif-{}'.format(x)] = vif_record x += 1 ret[name] = data return ret def vbd_list(name=None, call=None): ''' Get a list of VBDs on a VM **requires**: the name of the vm with the vbd definition .. code-block:: bash salt-cloud -a vbd_list xenvm01 ''' if call == 'function': raise SaltCloudSystemExit( 'This function must be called with -a, --action argument.' ) if name is None: return 'A name kwarg is rquired' ret = {} data = {} session = _get_session() vms = session.xenapi.VM.get_by_name_label(name) if len(vms) == 1: vm = vms[0] vbds = session.xenapi.VM.get_VBDs(vm) if vbds is not None: x = 0 for vbd in vbds: vbd_record = session.xenapi.VBD.get_record(vbd) data['vbd-{}'.format(x)] = vbd_record x += 1 ret = data return ret def avail_images(call=None): ''' Get a list of images from Xen If called with the `--list-images` then it returns images with all details. .. code-block:: bash salt-cloud --list-images myxen ''' if call == 'action': raise SaltCloudSystemExit( 'This function must be called with -f, --function argument.' ) return template_list() def destroy_vm_vdis(name=None, session=None, call=None): ''' Get virtual block devices on VM .. code-block:: bash salt-cloud -a destroy_vm_vdis xenvm01 ''' if session is None: session = _get_session() ret = {} # get vm object vms = session.xenapi.VM.get_by_name_label(name) if len(vms) == 1: # read virtual block device (vdb) vbds = session.xenapi.VM.get_VBDs(vms[0]) if vbds is not None: x = 0 for vbd in vbds: vbd_record = session.xenapi.VBD.get_record(vbd) if vbd_record['VDI'] != 'OpaqueRef:NULL': # read vdi on vdb vdi_record = session.xenapi.VDI.get_record( vbd_record['VDI']) if 'iso' not in vdi_record['name_label']: session.xenapi.VDI.destroy(vbd_record['VDI']) ret['vdi-{}'.format(x)] = vdi_record['name_label'] x += 1 return ret def destroy_template(name=None, call=None, kwargs=None): ''' Destroy Xen VM or template instance .. code-block:: bash salt-cloud -f destroy_template myxen name=testvm2 ''' if call == 'action': raise SaltCloudSystemExit( 'The destroy_template function must be called with -f.' ) if kwargs is None: kwargs = {} name = kwargs.get('name', None) session = _get_session() vms = session.xenapi.VM.get_all_records() ret = {} found = False for vm in vms: record = session.xenapi.VM.get_record(vm) if record['is_a_template']: if record['name_label'] == name: found = True # log.debug(record['name_label']) session.xenapi.VM.destroy(vm) ret[name] = {'status': 'destroyed'} if not found: ret[name] = {'status': 'not found'} return ret def get_pv_args(name, session=None, call=None): ''' Get PV arguments for a VM .. code-block:: bash salt-cloud -a get_pv_args xenvm01 ''' if call == 'function': raise SaltCloudException( 'This function must be called with -a or --action.' ) if session is None: log.debug('New session being created') session = _get_session() vm = _get_vm(name, session=session) pv_args = session.xenapi.VM.get_PV_args(vm) if pv_args: return pv_args return None def set_pv_args(name, kwargs=None, session=None, call=None): ''' Set PV arguments for a VM .. code-block:: bash salt-cloud -a set_pv_args xenvm01 pv_args="utf-8 graphical" ''' if call == 'function': raise SaltCloudException( 'This function must be called with -a or --action.' ) if session is None: log.debug('New session being created') session = _get_session() vm = _get_vm(name, session=session) try: log.debug('Setting PV Args: %s', kwargs['pv_args']) session.xenapi.VM.set_PV_args(vm, str(kwargs['pv_args'])) except KeyError: log.error('No pv_args parameter found.') return False except XenAPI.Failure: log.info('Setting PV Args failed.') return False return True