Merge remote-tracking branch 'upstream/2014.7' into merge-forward-2015.2

Conflicts:
	salt/modules/virt.py
This commit is contained in:
Colton Myers 2015-03-11 16:09:57 -06:00
commit bdfdd3f232
6 changed files with 120 additions and 12 deletions

View file

@ -386,6 +386,71 @@ def managedcloud(vm_):
)
def networks(vm_, kwargs=None):
conn = get_conn()
if kwargs is None:
kwargs = {}
networks = config.get_cloud_config_value(
'networks', vm_, __opts__, search_global=False
)
floating = []
if HAS014:
if networks is not None:
for net in networks:
if 'fixed' in net:
kwargs['networks'] = [
OpenStackNetwork(n, None, None, None)
for n in net['fixed']
]
elif 'floating' in net:
pool = OpenStack_1_1_FloatingIpPool(
net['floating'], conn.connection
)
for idx in pool.list_floating_ips():
if idx.node_id is None:
floating.append(idx)
if not floating:
# Note(pabelanger): We have no available floating IPs.
# For now, we raise an exception and exit.
# A future enhancement might be to allow salt-cloud
# to dynamically allocate new address but that might
raise SaltCloudSystemExit(
'Floating pool {0!r} does not have any more '
'please create some more or use a different '
'pool.'.format(net['floating'])
)
# otherwise, attempt to obtain list without specifying pool
# this is the same as 'nova floating-ip-list'
elif ssh_interface(vm_) != 'private_ips':
try:
# This try/except is here because it appears some
# *cough* Rackspace *cough*
# OpenStack providers return a 404 Not Found for the
# floating ip pool URL if there are no pools setup
pool = OpenStack_1_1_FloatingIpPool(
'', conn.connection
)
for idx in pool.list_floating_ips():
if idx.node_id is None:
floating.append(idx)
if not floating:
# Note(pabelanger): We have no available floating IPs.
# For now, we raise an exception and exit.
# A future enhancement might be to allow salt-cloud to
# dynamically allocate new address but that might be
# tricky to manage.
raise SaltCloudSystemExit(
'There are no more floating IP addresses '
'available, please create some more'
)
except Exception as e:
if not str(e).startswith('404'):
raise
vm_['floating'] = floating
def request_instance(vm_=None, call=None):
'''
Put together all of the information necessary to request an instance on Openstack
@ -620,9 +685,11 @@ def create(vm_):
__opts__
)
)
data = conn.ex_get_node_details(vm_['instance_id'])
if vm_['key_filename'] is None and 'change_password' in __opts__ and __opts__['change_password'] is True:
vm_['password'] = sup.secure_password()
conn.root_password(vm_['instance_id'], vm_['password'])
conn.ex_set_password(data, vm_['password'])
networks(vm_)
else:
# Put together all of the information required to request the instance,
# and then fire off the request for it

View file

@ -23,9 +23,9 @@ import jinja2
import jinja2.exceptions
import salt.ext.six as six
from salt.ext.six.moves import StringIO as _StringIO # pylint: disable=import-error
from xml.dom import minidom
try:
import libvirt # pylint: disable=import-error
from xml.dom import minidom
HAS_ALL_IMPORTS = True
except ImportError:
HAS_ALL_IMPORTS = False
@ -799,8 +799,8 @@ def get_nics(vm_):
# driver, source, and match can all have optional attributes
if re.match('(driver|source|address)', v_node.tagName):
temp = {}
for key in v_node.attributes:
temp[key] = v_node.getAttribute(key)
for key, value in v_node.attributes.items():
temp[key] = value
nic[str(v_node.tagName)] = temp
# virtualport needs to be handled separately, to pick up the
# type attribute of the virtualport itself
@ -857,8 +857,8 @@ def get_graphics(vm_):
for node in doc.getElementsByTagName('domain'):
g_nodes = node.getElementsByTagName('graphics')
for g_node in g_nodes:
for key in g_node.attributes:
out[key] = g_node.getAttribute(key)
for key, value in g_node.attributes.items():
out[key] = value
return out

View file

@ -122,7 +122,9 @@ def decrypt_object(o, gpg):
o[k] = decrypt_object(v, gpg)
return o
elif isinstance(o, list):
return [decrypt_object(e, gpg) for e in o]
for number, value in enumerate(o):
o[number] = decrypt_object(value, gpg)
return o
else:
return o

View file

@ -595,7 +595,7 @@ class SaltDistribution(distutils.dist.Distribution):
self.name = 'salt-ssh' if PACKAGED_FOR_SALT_SSH else 'salt'
self.version = __version__ # pylint: disable=undefined-variable
self.salt_version = __version__ # pylint: disable=undefined-variable
self.description = 'Portable, distributed, remote execution and configuration management system'
self.author = 'Thomas S Hatch'
self.author_email = 'thatch45@gmail.com'
@ -627,6 +627,8 @@ class SaltDistribution(distutils.dist.Distribution):
attrvalue = getattr(self, attrname, None)
if attrvalue == 0:
continue
if attrname == 'salt_version':
attrname = 'version'
if hasattr(self.metadata, 'set_{0}'.format(attrname)):
getattr(self.metadata, 'set_{0}'.format(attrname))(attrvalue)
elif hasattr(self.metadata, attrname):

View file

@ -23,8 +23,8 @@ class VirtTest(integration.ModuleCase):
'''
profiles = self.run_function('virt.get_profiles', ['kvm'])
nicp = profiles['nic']['default']
self.assertTrue(nicp['eth0'].get('model', '') == 'virtio')
self.assertTrue(nicp['eth0'].get('bridge', '') == 'br0')
self.assertTrue(nicp[0].get('model', '') == 'virtio')
self.assertTrue(nicp[0].get('source', '') == 'br0')
diskp = profiles['disk']['default']
self.assertTrue(diskp[0]['system'].get('model', '') == 'virtio')
self.assertTrue(diskp[0]['system'].get('format', '') == 'qcow2')
@ -36,8 +36,8 @@ class VirtTest(integration.ModuleCase):
'''
profiles = self.run_function('virt.get_profiles', ['esxi'])
nicp = profiles['nic']['default']
self.assertTrue(nicp['eth0'].get('model', '') == 'e1000')
self.assertTrue(nicp['eth0'].get('bridge', '') == 'DEFAULT')
self.assertTrue(nicp[0].get('model', '') == 'e1000')
self.assertTrue(nicp[0].get('source', '') == 'DEFAULT')
diskp = profiles['disk']['default']
self.assertTrue(diskp[0]['system'].get('model', '') == 'scsi')
self.assertTrue(diskp[0]['system'].get('format', '') == 'vmdk')

View file

@ -500,6 +500,43 @@ class VirtTestCase(TestCase):
re.match('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$',
interface_attrs['mac'], re.I))
@skipIf(sys.version_info < (2, 7), 'ElementTree version 1.3 required'
' which comes with Python 2.7')
def test_get_graphics(self):
virt.get_xml = MagicMock(return_value='''<domain type='kvm' id='7'>
<name>test-vm</name>
<devices>
<graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0'>
<listen type='address' address='0.0.0.0'/>
</graphics>
</devices>
</domain>
''')
graphics = virt.get_graphics('test-vm')
self.assertEqual('vnc', graphics['type'])
self.assertEqual('5900', graphics['port'])
self.assertEqual('0.0.0.0', graphics['listen'])
@skipIf(sys.version_info < (2, 7), 'ElementTree version 1.3 required'
' which comes with Python 2.7')
def test_get_nics(self):
virt.get_xml = MagicMock(return_value='''<domain type='kvm' id='7'>
<name>test-vm</name>
<devices>
<interface type='bridge'>
<mac address='ac:de:48:b6:8b:59'/>
<source bridge='br0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
</devices>
</domain>
''')
nics = virt.get_nics('test-vm')
nic = nics[nics.keys()[0]]
self.assertEqual('bridge', nic['type'])
self.assertEqual('ac:de:48:b6:8b:59', nic['mac'])
if __name__ == '__main__':
from integration import run_tests