Skip to content

Instantly share code, notes, and snippets.

@schasi

schasi/ovirt.py Secret

Last active August 17, 2017 21:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schasi/7e0209e6c014f3a58b45722f510c5e94 to your computer and use it in GitHub Desktop.
Save schasi/7e0209e6c014f3a58b45722f510c5e94 to your computer and use it in GitHub Desktop.
ovirt provider for salt-cloud
# -*- coding: utf-8 -*-
'''
oVirt Cloud Module
=========================
The oVirt cloud module is used to control access to the oVirt system.
.. code-block:: yaml
# Note: This example is for /etc/salt/cloud.providers or any file in the
# /etc/salt/cloud.providers.d/ directory.
ovirt-config:
url: https://ovirt-engine-1.example.com/ovirt-engine/api
username: admin@internal
password: password
ca_file: /usr/local/etc/salt/pki/ovirt.pem
debug: True
driver: ovirt
:depends: ovirtsdk4
Example profile configuration:
.. code-block:: yaml
# /etc/salt/cloud.profiles.d/ovirt.conf
freebsd:
provider: ovirt-config
user: root
ssh_keyfile: /usr/local/etc/salt/pki/id_rsa
image: Default
memory: 4294967296
cores: 2
minion:
master: saltmaster-01.example.com
'''
# Import python libs
from __future__ import absolute_import
from datetime import datetime
import logging
import time
import socket
# Import salt libs
import salt.config as config
# Import Salt-Cloud Libs
import salt.utils.cloud
from salt.exceptions import (
SaltCloudSystemExit,
SaltCloudException,
SaltCloudExecutionFailure,
)
# Get logging started
log = logging.getLogger(__name__)
# Import Third Party Libs
try:
import ovirtsdk4 as osdk
import ovirtsdk4.types as types
HAS_OVIRTSDK = True
except ImportError:
HAS_OVIRTSDK = False
__virtualname__ = 'ovirt'
# Only load in this module if the oVirt configurations are in place
def __virtual__():
'''
Check for oVirt configurations
'''
if get_configured_provider() is False:
return False
if _get_dependencies() is False:
return False
return __virtualname__
def _get_dependencies():
'''
Warn if dependencies aren't met.
Checks for the ovirtsdk4 module
'''
return config.check_driver_dependencies(
__virtualname__,
{'ovirtsdk4': HAS_OVIRTSDK}
)
# Replaced by "_get_session()"
#def __get_connection(url, username, password, ca_file):
# try:
# connection = osdk.Connection(
# url=url,
# username=username,
# password=password,
# ca_file=ca_file,
# debug=True,
# )
# except Exception:
# raise SaltCloudExecutionFailure(
# 'Sorry, {0} failed to open a connection to the hypervisor '
# 'software at {1}'.format(
# __grains__['fqdn'], url
# )
# )
# return connection
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 oVirt 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
)
username = config.get_cloud_config_value(
'username',
get_configured_provider(),
__opts__,
search_global=False
)
password = config.get_cloud_config_value(
'password',
get_configured_provider(),
__opts__,
search_global=False
)
ca_file = config.get_cloud_config_value(
'ca_file',
get_configured_provider(),
__opts__,
search_global=False
)
insecure = config.get_cloud_config_value(
'insecure',
get_configured_provider(),
__opts__,
default=False,
search_global=False
)
debug = config.get_cloud_config_value(
'debug',
get_configured_provider(),
__opts__,
default=True,
search_global=False
)
try:
connection = osdk.Connection(
url=url,
username=username,
password=password,
ca_file=ca_file,
insecure=insecure,
debug=debug,
)
connection.test(raise_exception=True) # Needed that connection actually does something
except Exception as e:
raise SaltCloudExecutionFailure(
'Failed to open connection with {}: {}'.format(
url,
e
)
)
#session = XenAPI.Session(url, ignore_ssl=ignore_ssl)
log.debug('url: {} user: {} password: {}, ca_file: {}, originator: {}'.format(
url,
username,
'XXX-pw-redacted-XXX',
ca_file,
originator))
#session.xenapi.login_with_password(user, password, api_version, originator)
return connection
def test_connection(call=None, session=None):
'''
Test the connection to the oVirt host
.. code-block:: bash
salt-cloud -f
'''
if call == 'action':
raise SaltCloudException(
'The test_connection function must be called with -f or --function.'
)
url = config.get_cloud_config_value(
'url',
get_configured_provider(),
__opts__,
search_global=False
)
if session is None:
session = _get_session()
session.close()
return "Made new session with {}.".format(
url)
else:
return "Session to {} is already established.".format(
url)
def list_nodes():
'''
List virtual machines
.. code-block:: bash
salt-cloud -Q
'''
return list_nodes_full()
#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 {} seconds for {} to report ip address...'.format(
# delta.seconds, name))
# if delta.seconds > 300:
# log.warn('Timeout getting IP address')
# break
# time.sleep(5)
def _wait_for_ip_from_hostname(name, session):
'''
Wait to get an IP from hostname during create()
'''
hostname = name
ip = None
start_time = datetime.now()
while ip is None:
try:
check_time = datetime.now()
delta = check_time - start_time
ip = socket.gethostbyname(hostname)
log.debug('Waited {} seconds for {} to report ip address...'.format(
delta.seconds, name))
break
except:
if delta.seconds > 300:
log.warn('Timeout getting IP address')
break
time.sleep(1)
return ip
#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 len(session.xenapi.VIF.get_ipv4_addresses(vif)) != 0:
# cidr = session.xenapi.VIF.get_ipv4_addresses(vif).pop()
# ret, subnet = cidr.split('/')
# log.debug(
# 'VM vif returned for instance: {} ip: {}'.format(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: {} 0/ip: {}'.format(
# 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: {} ipv4_cidr: {} ipv4_gw: {} mode: {}'.format(
# 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:
# for vif in vifs:
# log.debug('There are {} vifs.'.format(len(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_service = session.system_service().vms_service()
templates_service = session.system_service().templates_service()
print("Getting VMs")
vms = vms_service.list()
#for vm in vms:
# print("%s: %s" % (vm.name, vm.id))
for vm in vms:
vm_cfg = {}
vm_cfg['id'] = vm.id
vm_cfg['name'] = vm.name
template = templates_service.template_service(vm.template.id).get()
vm_cfg['image'] = template.name
vm_cfg['size'] = None
vm_cfg['state'] = str(vm.status)
vm_cfg['private_ips'] = None
vm_cfg['public_ips'] = None
ret[vm.name] = vm_cfg
provider = __active_provider_name__ or 'ovirt'
if ':' in provider:
comps = provider.split(':')
provider = comps[0]
log.debug('ret: {}'.format(ret))
log.debug('provider: {}'.format(provider))
log.debug('__opts__: {}'.format(__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 {}'.format(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 templat 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 oVirt-1
'''
if call == 'function':
raise SaltCloudException(
'The show_instance function must be called with -a or --action.'
)
log.debug('show_instance-> name: {} session: {}'.format(name, session))
if session is None:
session = _get_session()
print("Getting VM")
vms_service = session.system_service().vms_service()
templates_service = session.system_service().templates_service()
vm = vms_service.list(search='name={}'.format(name))
if vm:
vm = vm[0]
vm_cfg = {}
vm_cfg['id'] = vm.id
vm_cfg['name'] = vm.name
template = templates_service.template_service(vm.template.id).get()
vm_cfg['image'] = template.name
vm_cfg['size'] = None
vm_cfg['state'] = str(vm.status)
vm_cfg['private_ips'] = None
vm_cfg['public_ips'] = None
__utils__['cloud.cache_node'](
vm_cfg,
__active_provider_name__,
__opts__
)
return vm_cfg
#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 len(pool) <= 0:
# 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: {}'.format(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: {}'.format(sr_record['name_label']))
# storage_repo = default_sr
# else:
# storage_repo = None
# log.debug('storage repository: {}'.format(storage_repo))
# return storage_repo
def create(vm_):
'''
Create a VM in oVirt
The configuration for this function is read from the profile settings.
.. code-block:: bash
salt-cloud -p some_profile oVirt-VM-1
'''
name = vm_['name']
ret = {}
# Since using "provider: <provider-engine>" is deprecated, alias provider
# to use driver: "driver: <provider-engine>"
if 'provider' in vm_:
vm_['driver'] = vm_.pop('provider')
# 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 {} to cloud cache.'.format(name))
__utils__['cloud.cachedir_index_add'](
vm_['name'], vm_['profile'], 'xen', vm_['driver']
)
# connect to ovirt
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
memory = vm_.get('memory')
if memory is None:
memory = 2147483648
cores = vm_.get('cores')
if cores is None:
cores = 2
template = vm_.get('template')
if template is None:
template = "Blank"
#clone = vm_.get('clone')
#if clone is None:
# clone = True
#log.debug('Clone: {} '.format(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']
)
log.debug('Starting vm with {} memory and {} cores '.format(
memory,
cores
)
)
# create by cloning template
vms_service = session.system_service().vms_service()
vm = vms_service.add(
types.Vm(
name=name,
memory=memory,
memory_policy=types.MemoryPolicy(
guaranteed=memory,
max=4 * memory
),
cpu=types.Cpu(
topology=types.CpuTopology(
cores=cores,
sockets=1,
threads=1,
),
),
cluster=types.Cluster(
name='Default',
),
template=types.Template(
name='Default',
),
),
)
# Find the service that manages the virtual machine. Why do we have to do
# this again? Because vm is just a container of data. We want the service.
vm_service = vms_service.vm_service(vm.id)
while True:
time.sleep(5)
vm = vm_service.get()
if vm.status == types.VmStatus.DOWN:
break
#if clone:
# _clone_vm(image, name, session)
#else:
# _copy_vm(image, name, session, storage_repo)
# Set cloud_init_script if there
cloud_init_script = config.get_cloud_config_value(
'cloud_init_script',
get_configured_provider(),
__opts__,
search_global=False
)
# start vm
vm_service.start(
use_cloud_init=True,
vm=types.Vm(
initialization=types.Initialization(
host_name=name,
custom_script=cloud_init_script,
)
)
)
## get new VM
#vm = _get_vm(name, session)
# wait for vm to report IP via guest tools
#_wait_for_ip(name, session)
_wait_for_ip_from_hostname(name, session)
# if not deploying salt then exit
deploy = vm_.get('deploy', True)
log.debug('deploy is set to {}'.format(deploy))
if deploy:
_deploy_salt_minion(name, session, vm_)
else:
log.debug(
'The Salt minion will not be installed, deploy: {}'.format(
vm_['deploy'])
)
ret = {"foo": "\o/"}#show_instance(name)
__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'] = _wait_for_ip_from_hostname(name, session)
vm_['user'] = vm_.get('user', 'root')
vm_['password'] = vm_.get('password', 'p@ssw0rd!')
log.debug('{} has IP of {}'.format(name, vm_['ssh_host']))
# Bootstrap Salt minion!
if vm_['ssh_host'] is not None:
log.info('Installing Salt minion on {0}'.format(name))
boot_ret = __utils__['cloud.bootstrap'](vm_, __opts__)
log.debug('boot return: {}'.format(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 {} seconds for {} to report ip address...'.format(
delta.seconds, name))
if delta.seconds > 300:
log.warn('Timeout getting IP address')
break
time.sleep(5)
#def _run_async_task(task=None, session=None):
# '''
# Run XenAPI task in async 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 {}'.format(task_name))
# while session.xenapi.task.get_status(task) == 'pending':
# progress = round(session.xenapi.task.get_progress(task), 2) * 100
# log.debug('Task progress {}%'.format(str(progress)))
# time.sleep(1)
# log.debug('Cleaning up task {}'.format(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 {0} by cloning {1}'.format(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 faster 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 {0} by copying {1}'.format(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 {0}'.format(name))
# vm = _get_vm(name, session)
# task = session.xenapi.Async.VM.provision(vm)
# _run_async_task(task, session)
#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
#'''
def list_tags(name=None, call=None, kwargs=None):
'''
List tags of a VM
.. code-block:: bash
salt-cloud -f list_tags ovirt name=ovirt-vm-1
'''
if call == 'action':
raise SaltCloudException(
'The list_tags function must be called with -f or --function.'
)
session = _get_session()
if kwargs is None:
kwargs = {}
name = kwargs.get('name', None)
#if kwargs:
# print(kwargs)
# Get the reference to the "vms" service:
vms_service = session.system_service().vms_service()
# Set name of vm to list tags for
vm_name = 'name={}'.format(name)
# Find the virtual machine:
vm = vms_service.list(search=vm_name)[0]
# Find the service that manages the vm:
vm_service = vms_service.vm_service(vm.id)
# Locate the service that manages the tags of the vm:
tags_service = vm_service.tags_service()
# Print all name and description of tags assigned to virtual machine:
for tag in tags_service.list():
print("%s: %s" % (tag.name, tag.description))
# Close the connection to the server:
session.close()
log.info('Listed tags for VM {0}'.format(name))
return str(tags_service)
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_instance function must be called with -a or --action.'
)
if session is None:
session = _get_session()
log.info('Starting VM {0}'.format(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 {0}'.format(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 {0}'.format(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 {0}'.format(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 {0}'.format(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 {0}'.format(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 {0}'.format(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 oVirt VM
.. code-block:: bash
salt-cloud -d oVirt-1
'''
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()
## Get service; then the VM
vms_service = session.system_service().vms_service()
vm = vms_service.list(search='name={}'.format(name))
if vm:
vm = vm[0]
# shut down
vm_service = vms_service.vm_service(vm.id)
vm_service.stop()
# destroy vm
while True:
time.sleep(1)
vm = vm_service.get()
if vm.status == types.VmStatus.DOWN:
break
vm_service.remove()
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
@johnkeates
Copy link

If it works, it works! ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment