import logging
import netaddr
import time
+import yaml
-from novaclient import client as nClient_v2, exceptions as nvExceptions, api_versions as APIVersion
+from novaclient import client as nClient_v2, exceptions as nvExceptions
+from novaclient import api_versions
import keystoneclient.v2_0.client as ksClient_v2
from novaclient.v2.client import Client as nClient
import keystoneclient.v3.client as ksClient
class vimconnector(vimconn.vimconnector):
def __init__(self, uuid, name, tenant_id, tenant_name, url, url_admin=None, user=None, passwd=None, log_level=None, config={}):
- '''using common constructor parameters. In this case
+ '''using common constructor parameters. In this case
'url' is the keystone authorization url,
'url_admin' is not use
'''
if len(self.n_creds) <4:
raise ksExceptions.ClientException("Not enough parameters to connect to openstack")
if self.osc_api_version == 'v3.3':
- self.nova = nClient(APIVersion(version_str='2'), **self.n_creds)
+ self.nova = nClient(api_version=api_versions.APIVersion(version_str='2.0'), **self.n_creds)
#TODO To be updated for v3
#self.cinder = cClient.Client(**self.n_creds)
self.keystone = ksClient.Client(**self.k_creds)
self.ne_endpoint=self.keystone.service_catalog.url_for(service_type='network', endpoint_type='publicURL')
- self.neutron = neClient.Client(APIVersion(version_str='2'), endpoint_url=self.ne_endpoint, token=self.keystone.auth_token, **self.k_creds)
+ self.neutron = neClient.Client(api_version=api_versions.APIVersion(version_str='2.0'), endpoint_url=self.ne_endpoint, token=self.keystone.auth_token, **self.k_creds)
else:
- self.nova = nClient_v2.Client('2', **self.n_creds)
+ self.nova = nClient_v2.Client(version='2', **self.n_creds)
self.cinder = cClient_v2.Client(**self.n_creds)
self.keystone = ksClient_v2.Client(**self.k_creds)
self.ne_endpoint=self.keystone.service_catalog.url_for(service_type='network', endpoint_type='publicURL')
#determine format http://docs.openstack.org/developer/glance/formats.html
if "disk_format" in image_dict:
disk_format=image_dict["disk_format"]
- else: #autodiscover base on extention
+ else: #autodiscover based on extension
if image_dict['location'][-6:]==".qcow2":
disk_format="qcow2"
elif image_dict['location'][-4:]==".vhd":
filtered_list = []
for image in image_list:
image_dict=self.glance.images.get(image.id)
- if image_dict['checksum']==filter_dict.get('checksum'):
- filtered_list.append(image)
+ if 'checksum' not in filter_dict or image_dict['checksum']==filter_dict.get('checksum'):
+ filtered_list.append(image_dict)
return filtered_list
except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e:
self._format_exception(e)
security_groups = self.config.get('security_groups')
if type(security_groups) is str:
security_groups = ( security_groups, )
+ #cloud config
+ userdata=None
+ config_drive = None
if isinstance(cloud_config, dict):
- userdata="#cloud-config\nusers:\n"
- #default user
- if "key-pairs" in cloud_config:
- userdata += " - default:\n ssh-authorized-keys:\n"
- for key in cloud_config["key-pairs"]:
- userdata += " - '{key}'\n".format(key=key)
- for user in cloud_config.get("users",[]):
- userdata += " - name: {name}\n sudo: ALL=(ALL) NOPASSWD:ALL\n".format(name=user["name"])
- if "user-info" in user:
- userdata += " gecos: {}'\n".format(user["user-info"])
- if user.get("key-pairs"):
- userdata += " ssh-authorized-keys:\n"
- for key in user["key-pairs"]:
- userdata += " - '{key}'\n".format(key=key)
+ if cloud_config.get("user-data"):
+ userdata=cloud_config["user-data"]
+ if cloud_config.get("boot-data-drive") != None:
+ config_drive = cloud_config["boot-data-drive"]
+ if cloud_config.get("config-files") or cloud_config.get("users") or cloud_config.get("key-pairs"):
+ if userdata:
+ raise vimconn.vimconnConflictException("Cloud-config cannot contain both 'userdata' and 'config-files'/'users'/'key-pairs'")
+ userdata_dict={}
+ #default user
+ if cloud_config.get("key-pairs"):
+ userdata_dict["ssh-authorized-keys"] = cloud_config["key-pairs"]
+ userdata_dict["users"] = [{"default": None, "ssh-authorized-keys": cloud_config["key-pairs"] }]
+ if cloud_config.get("users"):
+ if "users" not in cloud_config:
+ userdata_dict["users"] = [ "default" ]
+ for user in cloud_config["users"]:
+ user_info = {
+ "name" : user["name"],
+ "sudo": "ALL = (ALL)NOPASSWD:ALL"
+ }
+ if "user-info" in user:
+ user_info["gecos"] = user["user-info"]
+ if user.get("key-pairs"):
+ user_info["ssh-authorized-keys"] = user["key-pairs"]
+ userdata_dict["users"].append(user_info)
+
+ if cloud_config.get("config-files"):
+ userdata_dict["write_files"] = []
+ for file in cloud_config["config-files"]:
+ file_info = {
+ "path" : file["dest"],
+ "content": file["content"]
+ }
+ if file.get("encoding"):
+ file_info["encoding"] = file["encoding"]
+ if file.get("permissions"):
+ file_info["permissions"] = file["permissions"]
+ if file.get("owner"):
+ file_info["owner"] = file["owner"]
+ userdata_dict["write_files"].append(file_info)
+ userdata = "#cloud-config\n"
+ userdata += yaml.safe_dump(userdata_dict, indent=4, default_flow_style=False)
self.logger.debug("userdata: %s", userdata)
elif isinstance(cloud_config, str):
userdata = cloud_config
- else:
- userdata=None
#Create additional volumes in case these are present in disk_list
block_device_mapping = None
availability_zone=self.config.get('availability_zone'),
key_name=self.config.get('keypair'),
userdata=userdata,
+ config_drive = config_drive,
block_device_mapping = block_device_mapping
) # , description=description)
#print "DONE :-)", server