aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--func/create_zones.py257
-rw-r--r--func/spawn_vm.py561
-rw-r--r--tests/create_zones_test.py89
-rw-r--r--tests/spawn_vm_test.py71
4 files changed, 569 insertions, 409 deletions
diff --git a/func/create_zones.py b/func/create_zones.py
index 44ba7568..e715dfd4 100644
--- a/func/create_zones.py
+++ b/func/create_zones.py
@@ -1,127 +1,130 @@
-##############################################################################
-# Copyright (c) 2015 Dell Inc and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-
-
-from keystoneclient.auth.identity import v2
-from keystoneclient import session
-from novaclient import client
-import os
-import re
-from collections import defaultdict
-
-
-class create_zones:
-
- def __init__(self):
- print 'Creating Zones'
- self._keystone_client = None
- self._nova_client = None
-
- def _get_keystone_client(self):
- '''returns a keystone client instance'''
-
- if self._keystone_client is None:
- '''
- self._keystone_client = keystoneclient.v2_0.client.Client(
- auth_url=os.environ.get('OS_AUTH_URL'),
- username=os.environ.get('OS_USERNAME'),
- password=os.environ.get('OS_PASSWORD'),
- tenant_name=os.environ.get('OS_TENANT_NAME'))
- '''
- auth = v2.Password(auth_url=os.environ.get('OS_AUTH_URL'),
- username=os.environ.get('OS_USERNAME'),
- password=os.environ.get('OS_PASSWORD'),
- tenant_name=os.environ.get('OS_TENANT_NAME'))
-
- sess = session.Session(auth=auth)
-
- return sess
-
- def _get_nova_client(self):
- if self._nova_client is None:
- keystone = self._get_keystone_client()
- self._nova_client = client.Client('2', session=keystone)
- return self._nova_client
-
- def check_aggregate(self, nova, agg_name):
- list1 = nova.aggregates.list()
-
- agg_name_exist = False
- for x in list1:
-
- if x.name == agg_name:
- agg_name_exist = True
- return agg_name_exist
-
- def get_aggregate_id(self, nova, agg_name):
- list1 = nova.aggregates.list()
- agg_id = 0
- agg_name_exist = False
- for x in list1:
- if x.name == agg_name:
- agg_id = x.id
- return agg_id
-
- def check_host_added_to_aggregate(self, nova, agg_id, hostname):
- host_added = False
- list1 = nova.aggregates.get_details(agg_id)
-
- nme = str(list1.hosts)
- if(hostname in nme):
- host_added = True
- return host_added
-
- def del_agg(self, nova, id, host):
-
- nova.aggregates.remove_host(id, host)
- nova.aggregates.delete(id)
-
- def get_compute_num(self, computeName):
-
- num = re.findall(r'\d+',computeName)
- return (int(num[0])-1)
-
- def create_agg(self, D):
- nova = self._get_nova_client()
- hyper_list = nova.hypervisors.list()
- hostnA = []
- zone_machine = defaultdict(list)
-
- x = 0
- for x in range(len(hyper_list)):
-
- hostnA.append(hyper_list[x].service['host'])
- hostnA[x] = str(hostnA[x])
-
- hostnA.sort()
- for k in D:
-
- zone_machine[k].append(' ')
-
- for x in range(len(zone_machine)):
- compute_index = self.get_compute_num(D[x])
- if compute_index > len(hyper_list):
- print '\n The specified compute node doesnt exist. using compute 1'
- compute_index = 1
- if not self.check_aggregate(nova, hostnA[compute_index]):
- agg_idA = nova.aggregates.create(hostnA[compute_index], D[x])
- nova.aggregates.add_host(aggregate=agg_idA, host=hostnA[compute_index])
-
- else:
-
- id1 = self.get_aggregate_id(nova, hostnA[compute_index])
- self.del_agg(nova, id1, hostnA[compute_index])
- agg_idA = nova.aggregates.create(hostnA[compute_index], D[x])
- id1 = self.get_aggregate_id(nova, hostnA[compute_index])
-
- if not self.check_host_added_to_aggregate(
- nova, id1, hostnA[compute_index]):
-
- nova.aggregates.add_host(aggregate=id1, host=hostnA[compute_index])
+##############################################################################
+# Copyright (c) 2015 Dell Inc and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+from keystoneclient.auth.identity import v2
+from keystoneclient import session
+from novaclient import client
+import os
+import re
+from collections import defaultdict
+
+
+class create_zones:
+
+ def __init__(self):
+ print 'Creating Zones'
+ self._keystone_client = None
+ self._nova_client = None
+
+ def _get_keystone_client(self):
+ """returns a keystone client instance"""
+
+ if self._keystone_client is None:
+ '''
+ self._keystone_client = keystoneclient.v2_0.client.Client(
+ auth_url=os.environ.get('OS_AUTH_URL'),
+ username=os.environ.get('OS_USERNAME'),
+ password=os.environ.get('OS_PASSWORD'),
+ tenant_name=os.environ.get('OS_TENANT_NAME'))
+ '''
+ auth = v2.Password(auth_url=os.environ.get('OS_AUTH_URL'),
+ username=os.environ.get('OS_USERNAME'),
+ password=os.environ.get('OS_PASSWORD'),
+ tenant_name=os.environ.get('OS_TENANT_NAME'))
+
+ sess = session.Session(auth=auth)
+ else:
+ return self._keystone_client
+
+ return sess
+
+ def _get_nova_client(self):
+ if self._nova_client is None:
+ keystone = self._get_keystone_client()
+ self._nova_client = client.Client('2', session=keystone)
+ return self._nova_client
+
+ @staticmethod
+ def check_aggregate(nova, agg_name):
+ list1 = nova.aggregates.list()
+ agg_name_exist = False
+ for x in list1:
+ if x.name == agg_name:
+ agg_name_exist = True
+ return agg_name_exist
+
+ @staticmethod
+ def get_aggregate_id(nova, agg_name):
+ list1 = nova.aggregates.list()
+ for x in list1:
+ if x.name == agg_name:
+ agg_id = x.id
+ return agg_id
+
+ @staticmethod
+ def check_host_added_to_aggregate(nova, agg_id, hostname):
+ host_added = False
+ list1 = nova.aggregates.get_details(agg_id)
+
+ nme = str(list1.hosts)
+ if hostname in nme:
+ host_added = True
+ return host_added
+
+ @staticmethod
+ def del_agg(nova, id, host):
+
+ nova.aggregates.remove_host(id, host)
+ nova.aggregates.delete(id)
+
+ @staticmethod
+ def get_compute_num(compute_name):
+
+ num = re.findall(r'\d+', compute_name)
+ return int(num[0]) - 1
+
+ def test(self):
+ nova = self._get_nova_client()
+ hyper_list = nova.hypervisors.list()
+ return hyper_list
+
+ def create_agg(self, d):
+ nova = self._get_nova_client()
+ hyper_list = nova.hypervisors.list()
+ host_a = []
+ zone_machine = defaultdict(list)
+
+ for x in range(len(hyper_list)):
+
+ host_a.append(hyper_list[x].service['host'])
+ host_a[x] = str(host_a[x])
+
+ host_a.sort()
+ for k in d:
+
+ zone_machine[k].append(' ')
+
+ for x in range(len(zone_machine)):
+ compute_index = self.get_compute_num(d[x])
+ if compute_index > len(hyper_list):
+ print '\n The specified compute node doesnt exist. using compute 1'
+ compute_index = 1
+ if not self.check_aggregate(nova, host_a[compute_index]):
+ agg_id_a = nova.aggregates.create(host_a[compute_index], d[x])
+ nova.aggregates.add_host(aggregate=agg_id_a, host=host_a[compute_index])
+
+ else:
+ id1 = self.get_aggregate_id(nova, host_a[compute_index])
+ self.del_agg(nova, id1, host_a[compute_index])
+ nova.aggregates.create(host_a[compute_index], d[x])
+ id1 = self.get_aggregate_id(nova, host_a[compute_index])
+
+ if not self.check_host_added_to_aggregate(
+ nova, id1, host_a[compute_index]):
+
+ nova.aggregates.add_host(aggregate=id1, host=host_a[compute_index])
diff --git a/func/spawn_vm.py b/func/spawn_vm.py
index 94aa424a..ec63230c 100644
--- a/func/spawn_vm.py
+++ b/func/spawn_vm.py
@@ -1,282 +1,279 @@
-##############################################################################
-# Copyright (c) 2015 Dell Inc and others.
-#
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Apache License, Version 2.0
-# which accompanies this distribution, and is available at
-# http://www.apache.org/licenses/LICENSE-2.0
-##############################################################################
-
-import os
-import sys
-from collections import defaultdict
-from func.env_setup import Env_setup
-from func.fetchimg import FetchImg
-import yaml
-import heatclient.client
-import keystoneclient
-import glanceclient
-from novaclient import client
-import time
-import json
-from func.create_zones import create_zones
-
-class SpawnVM(Env_setup):
- vm_role_ip_dict = defaultdict(list)
- installer = ''
-
- def __init__(self, vm_info):
- print 'SpawnVM Class initiated'
- vm_role_ip_dict = vm_info.copy()
- print 'Generating Heat Template\n'
- self._keystone_client = None
- self._heat_client = None
- self._glance_client = None
- self._nova_client = None
- nova =self. _get_nova_client()
- azoneobj = create_zones()
- azoneobj.create_agg(vm_info['availability_zone'])
- installer= self.get_installer_type()
- self.Heat_template1 = self.HeatTemplate_vm(vm_info,installer)
- self.create_stack(vm_role_ip_dict, self.Heat_template1)
-
- def get_installer_type(self):
- print 'Getting Installer Name'
- return os.environ['INSTALLER_TYPE']
-
- def get_public_network(self,installer_detected):
-
- '''
- TODO: GET THE NAMES OF THE PUBLIC NETWORKS for OTHER PROJECTS
- '''
- print 'Getting Public Network'
- if installer_detected.lower() == 'fuel':
- return 'admin_floating_net'
- if installer_detected.lower() == 'apex':
- return 'external'
- if installer_detected.lower() == 'compass':
- return 'ext-net'
- if installer_detected.lower() == 'joid':
- return 'ext-net'
-
- def HeatTemplate_vm(self, vm_params, installer):
- try:
- Heat_Dic=''
- with open('./heat/SampleHeat.yaml', 'r+') as H_temp:
- Heat_Dic = yaml.load(H_temp)
- except yaml.YAMLError as exc:
- if hasattr(exc, 'problem_mark'):
- mark = exc.problem_mark
- print 'Error in qtip/heat/SampleHeat.yaml at: (%s,%s)' % (mark.line + 1, mark.column + 1)
- print 'EXITING PROGRAM. Correct File and restart'
- sys.exit(0)
- fopen = open('./data/QtipKey.pub', 'r')
- fopenstr = fopen.read()
- fopenstr = fopenstr.rstrip()
- scriptcmd = '#!/bin/bash \n echo {0} >> foo.txt \n echo {1} >> /root/.ssh/authorized_keys'.format(
- fopenstr, fopenstr)
-
- netName = self.get_public_network(installer)
- print netName
- Heat_Dic['heat_template_version'] = '2014-10-16'
- Heat_Dic['resources']['KeyPairSavePrivate'] = {
- 'type': 'OS::Nova::KeyPair',
- 'properties': {
- 'save_private_key': 'true',
- 'name': 'my_key'
- }
- }
- Heat_Dic['parameters']['public_network'] = {
- 'type': 'string',
- #'default': vm_params['public_network'][0]
- 'default': netName
- }
- for x in range(1, len(vm_params['availability_zone']) + 1):
- avail_zone = vm_params['availability_zone'][x - 1]
- img = vm_params['OS_image'][x - 1]
- flavor = vm_params['flavor'][x - 1]
-
- Heat_Dic['parameters']['availability_zone_' +str(x)] = {
- 'description': 'Availability Zone of the instance',
- 'default': avail_zone,
- 'type': 'string'
-
- }
-
- Heat_Dic['resources']['public_port_' +str(x)] = {
- 'type': 'OS::Neutron::Port',
- 'properties': {
- 'network': {'get_resource': 'private_network'},
- 'security_groups': [{ 'get_resource': 'demo1_security_Group'}],
- 'fixed_ips': [
- {'subnet_id': {'get_resource': 'private_subnet'}}]}}
-
- Heat_Dic['resources']['floating_ip_' + str(x)] = {
- 'type': 'OS::Neutron::FloatingIP',
- 'properties': {
- 'floating_network': {'get_param': 'public_network'}}}
-
- Heat_Dic['resources']['floating_ip_assoc_' + str(x)] = {
- 'type': 'OS::Neutron::FloatingIPAssociation',
- 'properties': {
- 'floatingip_id': {'get_resource': 'floating_ip_' + str(x)},
- 'port_id': {'get_resource': 'public_port_' + str(x)}}}
-
- Heat_Dic['resources']['my_instance_' + str(x)] = {
- 'type': 'OS::Nova::Server',
- 'properties': {
- 'image': img,
- 'networks':[
- {'port': {'get_resource': 'public_port_' + str(x)}}],
- 'flavor': flavor,
- 'availability_zone': avail_zone,
- 'name': 'instance' + str(x),
- 'key_name': {'get_resource': 'KeyPairSavePrivate'},
- 'user_data_format': 'RAW',
- 'user_data': scriptcmd}}
-
- Heat_Dic['resources']['demo1_security_Group'] = {
- 'type': 'OS::Neutron::SecurityGroup',
- 'properties': {
- 'name': 'demo1_security_Group',
- 'rules': [{
- 'protocol': 'tcp',
- 'port_range_min': 22,
- 'port_range_max': 5201},
- {'protocol': 'udp',
- 'port_range_min': 22,
- 'port_range_max': 5201},
- {'protocol': 'icmp'}]}}
-
- Heat_Dic['outputs']['instance_PIP_' +str(x)] = {
- 'description': 'IP address of the instance',
- 'value': {'get_attr': ['my_instance_' + str(x), 'first_address']}}
- Heat_Dic['outputs']['instance_ip_' +str(x)] = {
- 'description': 'IP address of the instance',
- 'value': {'get_attr': ['floating_ip_' + str(x), 'floating_ip_address']}}
-
- Heat_Dic['outputs']['availability_instance_' + str(x)] = {
- 'description': 'Availability Zone of the Instance',
- 'value': { 'get_param': 'availability_zone_'+str(x)}}
-
-
- Heat_Dic['outputs']['KeyPair_PublicKey'] = {
- 'description': 'Private Key',
- 'value': {'get_attr': ['KeyPairSavePrivate', 'private_key']}
- }
- del Heat_Dic['outputs']['description']
- return Heat_Dic
-
- def _get_keystone_client(self):
- '''returns a keystone client instance'''
-
- if self._keystone_client is None:
- self._keystone_client = keystoneclient.v2_0.client.Client(
- auth_url=os.environ.get('OS_AUTH_URL'),
- username=os.environ.get('OS_USERNAME'),
- password=os.environ.get('OS_PASSWORD'),
- tenant_name=os.environ.get('OS_TENANT_NAME'))
- return self._keystone_client
-
- def _get_nova_client(self):
- if self._nova_client is None:
- keystone = self._get_keystone_client()
- self._nova_client = client.Client('2', token=keystone.auth_token)
- return self._nova_client
-
- def _get_heat_client(self):
- '''returns a heat client instance'''
- if self._heat_client is None:
- keystone = self._get_keystone_client()
- heat_endpoint = keystone.service_catalog.url_for(
- service_type='orchestration')
- self._heat_client = heatclient.client.Client(
- '1', endpoint=heat_endpoint, token=keystone.auth_token)
- return self._heat_client
-
- def _get_glance_client(self):
- if self._glance_client is None:
- keystone = self._get_keystone_client()
- glance_endpoint = keystone.service_catalog.url_for(
- service_type='image')
- self._glance_client = glanceclient.Client(
- '2', glance_endpoint, token=keystone.auth_token)
- return self._glance_client
-
- def create_stack(self, vm_role_ip_dict, Heat_template):
-
- stackname = 'QTIP'
- heat = self._get_heat_client()
- glance = self._get_glance_client()
-
- available_images = []
- for image_list in glance.images.list():
-
- available_images.append(image_list.name)
-
- if 'QTIP_CentOS' in available_images:
- print 'Image Present'
-
- elif 'QTIP_CentOS' not in available_images:
- fetchImage = FetchImg()
- fetchImage.download()
- print 'Uploading Image to Glance. Please wait'
- qtip_image = glance.images.create(
- name='QTIP_CentOS',
- visibility='public',
- disk_format='qcow2',
- container_format='bare')
- qtip_image = glance.images.upload(
- qtip_image.id, open('./Temp_Img/QTIP_CentOS.qcow2'))
- json_temp = json.dumps(Heat_template)
-
- for checks in range(3):
- for prev_stacks in heat.stacks.list():
-
- if prev_stacks.stack_name == 'QTIP':
- print 'QTIP Stacks exists.\nDeleting Existing Stack'
- heat.stacks.delete('QTIP')
- time.sleep(10)
-
- print '\nStack Creating Started\n'
-
- try:
- heat.stacks.create(stack_name=stackname, template=Heat_template)
- except:
- print 'Create Failed :( '
-
- cluster_detail = heat.stacks.get(stackname)
- while(cluster_detail.status != 'COMPLETE'):
- if cluster_detail.status == 'IN_PROGRESS':
- print 'Stack Creation in Progress'
- cluster_detail = heat.stacks.get(stackname)
- time.sleep(10)
- print 'Stack Created'
- print 'Getting Public IP(s)'
- zone = []
- s=0
- for vm in range(len(vm_role_ip_dict['OS_image'])):
-
- for I in cluster_detail.outputs:
- availabilityKey = 'availability_instance_'+str(vm+1)
-
- if I['output_key'] == availabilityKey:
- zone.insert(s,str(I['output_value']))
- s=s+1
- for i in cluster_detail.outputs:
- instanceKey = "instance_ip_" + str(vm + 1)
- privateIPkey = 'instance_PIP_' + str(vm +1)
- if i['output_key'] == instanceKey:
- Env_setup.roles_dict[vm_role_ip_dict['role'][vm]].append(
- str(i['output_value']))
- Env_setup.ip_pw_list.append((str(i['output_value']),''))
-
- if i['output_key'] == privateIPkey:
- Env_setup.ip_pw_dict[vm_role_ip_dict['role'][vm]]=str(i['output_value'])
- if i['output_key'] == 'KeyPair_PublicKey':
- sshkey = str(i['output_value'])
-
- with open('./data/my_key.pem', 'w') as fopen:
- fopen.write(sshkey)
- fopen.close()
- print Env_setup.ip_pw_list
+##############################################################################
+# Copyright (c) 2015 Dell Inc and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+import os
+import sys
+from collections import defaultdict
+from func.env_setup import Env_setup
+from func.fetchimg import FetchImg
+import yaml
+import heatclient.client
+import keystoneclient
+import glanceclient
+from novaclient import client
+import time
+from func.create_zones import create_zones
+
+
+class SpawnVM(Env_setup):
+ vm_role_ip_dict = defaultdict(list)
+ installer = ''
+
+ def __init__(self, vm_info):
+ Env_setup.__init__(self)
+ print 'SpawnVM Class initiated'
+ vm_role_ip_dict = vm_info.copy()
+ print 'Generating Heat Template\n'
+ self._keystone_client = None
+ self._heat_client = None
+ self._glance_client = None
+ self._nova_client = None
+ self. _get_nova_client()
+ azoneobj = create_zones()
+ azoneobj.create_agg(vm_info['availability_zone'])
+ installer = self.get_installer_type()
+ self.Heat_template1 = self.heat_template_vm(vm_info, installer)
+ self.create_stack(vm_role_ip_dict, self.Heat_template1)
+
+ @staticmethod
+ def get_installer_type():
+ print 'Getting Installer Name'
+ return os.environ['INSTALLER_TYPE']
+
+ @staticmethod
+ def get_public_network(installer_detected):
+
+ """
+ TODO: GET THE NAMES OF THE PUBLIC NETWORKS for OTHER PROJECTS
+ """
+ print 'Getting Public Network'
+ if installer_detected.lower() == 'fuel':
+ return 'admin_floating_net'
+ if installer_detected.lower() == 'apex':
+ return 'external'
+ if installer_detected.lower() == 'compass':
+ return 'ext-net'
+ if installer_detected.lower() == 'joid':
+ return 'ext-net'
+
+ def heat_template_vm(self, vm_params, installer):
+ Heat_Dic = {}
+ try:
+ with open('./heat/SampleHeat.yaml', 'r+') as H_temp:
+ Heat_Dic = yaml.load(H_temp)
+ except yaml.YAMLError as exc:
+ if hasattr(exc, 'problem_mark'):
+ mark = exc.problem_mark
+ print 'Error in qtip/heat/SampleHeat.yaml at: (%s,%s)' % (mark.line + 1, mark.column + 1)
+ print 'EXITING PROGRAM. Correct File and restart'
+ sys.exit(0)
+ fopen = open('./data/QtipKey.pub', 'r')
+ fopenstr = fopen.read()
+ fopenstr = fopenstr.rstrip()
+ scriptcmd = '#!/bin/bash \n echo {0} >> foo.txt \n echo {1} >> /root/.ssh/authorized_keys'.format(
+ fopenstr, fopenstr)
+
+ netName = self.get_public_network(installer)
+ print netName
+ Heat_Dic['heat_template_version'] = '2014-10-16'
+ Heat_Dic['resources']['KeyPairSavePrivate'] = {
+ 'type': 'OS::Nova::KeyPair',
+ 'properties': {
+ 'save_private_key': 'true',
+ 'name': 'my_key'
+ }
+ }
+ Heat_Dic['parameters']['public_network'] = {
+ 'type': 'string',
+ 'default': netName
+ }
+ for x in range(1, len(vm_params['availability_zone']) + 1):
+ avail_zone = vm_params['availability_zone'][x - 1]
+ img = vm_params['OS_image'][x - 1]
+ flavor = vm_params['flavor'][x - 1]
+
+ Heat_Dic['parameters']['availability_zone_' + str(x)] = \
+ {'description': 'Availability Zone of the instance',
+ 'default': avail_zone,
+ 'type': 'string'}
+
+ Heat_Dic['resources']['public_port_' + str(x)] = \
+ {'type': 'OS::Neutron::Port',
+ 'properties': {'network': {'get_resource': 'private_network'},
+ 'security_groups': [{'get_resource': 'demo1_security_Group'}],
+ 'fixed_ips': [{'subnet_id':
+ {'get_resource': 'private_subnet'}}]}}
+
+ Heat_Dic['resources']['floating_ip_' + str(x)] = {
+ 'type': 'OS::Neutron::FloatingIP',
+ 'properties': {
+ 'floating_network': {'get_param': 'public_network'}}}
+
+ Heat_Dic['resources']['floating_ip_assoc_' + str(x)] = {
+ 'type': 'OS::Neutron::FloatingIPAssociation',
+ 'properties': {
+ 'floatingip_id': {'get_resource': 'floating_ip_' + str(x)},
+ 'port_id': {'get_resource': 'public_port_' + str(x)}}}
+
+ Heat_Dic['resources']['my_instance_' + str(x)] = \
+ {'type': 'OS::Nova::Server',
+ 'properties': {'image': img,
+ 'networks':
+ [{'port': {'get_resource': 'public_port_' + str(x)}}],
+ 'flavor': flavor,
+ 'availability_zone': avail_zone,
+ 'name': 'instance' + str(x),
+ 'key_name': {'get_resource': 'KeyPairSavePrivate'},
+ 'user_data_format': 'RAW',
+ 'user_data': scriptcmd}}
+
+ Heat_Dic['resources']['demo1_security_Group'] = {
+ 'type': 'OS::Neutron::SecurityGroup',
+ 'properties': {
+ 'name': 'demo1_security_Group',
+ 'rules': [{
+ 'protocol': 'tcp',
+ 'port_range_min': 22,
+ 'port_range_max': 5201},
+ {'protocol': 'udp',
+ 'port_range_min': 22,
+ 'port_range_max': 5201},
+ {'protocol': 'icmp'}]}}
+
+ Heat_Dic['outputs']['instance_PIP_' + str(x)] = {
+ 'description': 'IP address of the instance',
+ 'value': {'get_attr': ['my_instance_' + str(x), 'first_address']}}
+ Heat_Dic['outputs']['instance_ip_' + str(x)] = {
+ 'description': 'IP address of the instance',
+ 'value': {'get_attr': ['floating_ip_' + str(x), 'floating_ip_address']}}
+
+ Heat_Dic['outputs']['availability_instance_' + str(x)] = {
+ 'description': 'Availability Zone of the Instance',
+ 'value': {'get_param': 'availability_zone_' + str(x)}}
+
+ Heat_Dic['outputs']['KeyPair_PublicKey'] = {
+ 'description': 'Private Key',
+ 'value': {'get_attr': ['KeyPairSavePrivate', 'private_key']}
+ }
+ del Heat_Dic['outputs']['description']
+ print Heat_Dic
+ return Heat_Dic
+
+ def _get_keystone_client(self):
+ """returns a keystone client instance"""
+
+ if self._keystone_client is None:
+ self._keystone_client = keystoneclient.v2_0.client.Client(
+ auth_url=os.environ.get('OS_AUTH_URL'),
+ username=os.environ.get('OS_USERNAME'),
+ password=os.environ.get('OS_PASSWORD'),
+ tenant_name=os.environ.get('OS_TENANT_NAME'))
+ return self._keystone_client
+
+ def _get_nova_client(self):
+ if self._nova_client is None:
+ keystone = self._get_keystone_client()
+ self._nova_client = client.Client('2', token=keystone.auth_token)
+ return self._nova_client
+
+ def _get_heat_client(self):
+ """returns a heat client instance"""
+ if self._heat_client is None:
+ keystone = self._get_keystone_client()
+ heat_endpoint = keystone.service_catalog.url_for(
+ service_type='orchestration')
+ self._heat_client = heatclient.client.Client(
+ '1', endpoint=heat_endpoint, token=keystone.auth_token)
+ return self._heat_client
+
+ def _get_glance_client(self):
+ if self._glance_client is None:
+ keystone = self._get_keystone_client()
+ glance_endpoint = keystone.service_catalog.url_for(
+ service_type='image')
+ self._glance_client = glanceclient.Client(
+ '2', glance_endpoint, token=keystone.auth_token)
+ return self._glance_client
+
+ def create_stack(self, vm_role_ip_dict, heat_template):
+
+ global sshkey
+ stackname = 'QTIP'
+ heat = self._get_heat_client()
+ glance = self._get_glance_client()
+
+ available_images = []
+ for image_list in glance.images.list():
+
+ available_images.append(image_list.name)
+
+ if 'QTIP_CentOS' in available_images:
+ print 'Image Present'
+
+ elif 'QTIP_CentOS' not in available_images:
+ fetchImage = FetchImg()
+ fetchImage.download()
+ print 'Uploading Image to Glance. Please wait'
+ qtip_image = glance.images.create(
+ name='QTIP_CentOS',
+ visibility='public',
+ disk_format='qcow2',
+ container_format='bare')
+ glance.images.upload(
+ qtip_image.id, open('./Temp_Img/QTIP_CentOS.qcow2'))
+ for checks in range(3):
+ print "Try to delete heats %s" % checks
+ for prev_stacks in heat.stacks.list():
+ if prev_stacks.stack_name == 'QTIP':
+ print 'QTIP Stacks exists.\nDeleting Existing Stack'
+ heat.stacks.delete('QTIP')
+ time.sleep(10)
+
+ print '\nStack Creating Started\n'
+
+ try:
+ heat.stacks.create(stack_name=stackname, template=heat_template)
+ except Exception:
+ print 'Create Failed :( '
+
+ cluster_detail = heat.stacks.get(stackname)
+ while cluster_detail.status != 'COMPLETE':
+ if cluster_detail.status == 'IN_PROGRESS':
+ print 'Stack Creation in Progress'
+ cluster_detail = heat.stacks.get(stackname)
+ time.sleep(10)
+ print 'Stack Created'
+ print 'Getting Public IP(s)'
+ zone = []
+ s = 0
+ for vm in range(len(vm_role_ip_dict['OS_image'])):
+
+ for I in cluster_detail.outputs:
+ availabilityKey = 'availability_instance_' + str(vm + 1)
+
+ if I['output_key'] == availabilityKey:
+ zone.insert(s, str(I['output_value']))
+ s = s + 1
+ for i in cluster_detail.outputs:
+ instanceKey = "instance_ip_" + str(vm + 1)
+ privateIPkey = 'instance_PIP_' + str(vm + 1)
+ if i['output_key'] == instanceKey:
+ Env_setup.roles_dict[vm_role_ip_dict['role'][vm]] \
+ .append(str(i['output_value']))
+ Env_setup.ip_pw_list.append((str(i['output_value']), ''))
+
+ if i['output_key'] == privateIPkey:
+ Env_setup.ip_pw_dict[vm_role_ip_dict['role'][vm]] = str(i['output_value'])
+ if i['output_key'] == 'KeyPair_PublicKey':
+ sshkey = str(i['output_value'])
+
+ with open('./data/my_key.pem', 'w') as fopen:
+ fopen.write(sshkey)
+ fopen.close()
+ print Env_setup.ip_pw_list
diff --git a/tests/create_zones_test.py b/tests/create_zones_test.py
new file mode 100644
index 00000000..e431a907
--- /dev/null
+++ b/tests/create_zones_test.py
@@ -0,0 +1,89 @@
+import pytest
+import mock
+from mock import Mock, MagicMock
+import os
+from func.create_zones import create_zones
+
+return_list = []
+
+
+def get_agg_mock(host):
+ agg = Mock()
+ agg.name = host
+ agg.id = host
+ return agg
+
+
+class HyperMock(MagicMock):
+ def list(self):
+ mock_hypervisor = [Mock(service={'host': '10.20.0.4'}), Mock(service={'host': '10.20.0.5'})]
+ return mock_hypervisor
+
+
+class AggMock(MagicMock):
+ def get_details(self, agg_id):
+ print "get_detail:{0}".format(agg_id)
+ return Mock(hosts=[])
+
+ def create(self, host, agg):
+ print "create:{0}:{1}".format(host, agg)
+ return agg
+
+ def list(self):
+ return return_list
+
+ def delete(self, agg_id):
+ print "delete:{0}".format(agg_id)
+ pass
+
+ def add_host(self, aggregate, host):
+ print "add_host:{0}:{1}".format(aggregate, host)
+ pass
+
+ def remove_host(self, agg_id, host):
+ pass
+
+
+class NovaMock(MagicMock):
+ hypervisors = HyperMock()
+ aggregates = AggMock()
+
+
+class TestClass:
+ @pytest.mark.parametrize("test_input, expected", [
+ ([[], ['compute1', 'compute2']],
+ ['create:10.20.0.4:compute1',
+ 'add_host:compute1:10.20.0.4',
+ 'create:10.20.0.5:compute2',
+ 'add_host:compute2:10.20.0.5']),
+ ([[get_agg_mock('10.20.0.4'), get_agg_mock('10.20.0.5')], ['compute1', 'compute2']],
+ ['delete:10.20.0.4',
+ 'create:10.20.0.4:compute1',
+ 'get_detail:10.20.0.4',
+ 'add_host:10.20.0.4:10.20.0.4',
+ 'delete:10.20.0.5',
+ 'create:10.20.0.5:compute2',
+ 'get_detail:10.20.0.5',
+ 'add_host:10.20.0.5:10.20.0.5']),
+ ([[], ['compute1', 'compute5']],
+ ['The specified compute node doesnt exist. using compute 1'])
+ ])
+ @mock.patch('func.create_zones.client', autospec=True)
+ @mock.patch('func.create_zones.v2', autospec=True)
+ @mock.patch('func.create_zones.session')
+ def test_create_zones_success(self, mock_keystone_session, mock_keystone_v2, mock_nova_client, test_input, expected, capfd):
+ global return_list
+ return_list = test_input[0]
+ nova_obj = NovaMock()
+ mock_nova_client.Client.return_value = nova_obj()
+ k = mock.patch.dict(os.environ, {'OS_AUTH_URL': 'http://172.10.0.5:5000',
+ 'OS_USERNAME': 'admin',
+ 'OS_PASSWORD': 'admin',
+ 'OS_TENANT_NAME': 'admin'})
+ k.start()
+ create = create_zones()
+ create.create_agg(test_input[1])
+ k.stop()
+ resout, reserr = capfd.readouterr()
+ for x in expected:
+ assert x in resout
diff --git a/tests/spawn_vm_test.py b/tests/spawn_vm_test.py
new file mode 100644
index 00000000..eb843ad9
--- /dev/null
+++ b/tests/spawn_vm_test.py
@@ -0,0 +1,71 @@
+import pytest
+import mock
+from mock import Mock, MagicMock
+import os
+from func.spawn_vm import SpawnVM
+
+
+class KeystoneMock(MagicMock):
+ auth_token = Mock()
+ v2_0 = Mock()
+
+
+class ImageMock(MagicMock):
+ name = 'QTIP_CentOS'
+
+
+class ImagesMock(MagicMock):
+ def list(self):
+ return [ImageMock()]
+
+
+class StackMock(MagicMock):
+ status = 'COMPLETE'
+ outputs = [{'output_key': 'availability_instance_1',
+ 'output_value': 'output_value_1'},
+ {'output_key': 'instance_ip_1',
+ "output_value": "172.10.0.154"},
+ {"output_key": "instance_PIP_1",
+ "output_value": "10.10.17.5"},
+ {'output_key': 'KeyPair_PublicKey',
+ "output_value": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpwIBAAKCAQEAqCiHcrLBXtxG0LhnKndU7VIVpYxORmv0d4tvujkWOkYuagiW\nU/MTRk0zhRvFQDVPEs0Jrj/BIecqm6fjjT6dZ/H7JLYGaqJitRkoupKgBsMSIqUz\nrR0ekOlfXZ6N+Ud8k6s+qjc7BO4b1ezz78jHisC5o0GCkUV0ECx64Re1fO+oKs1c\nfL9aaexahJUYN3J48pazQz+imc2x/G9nuqHX3cqEszmxnT4jwv//In1GjHy2AyXw\n1oA5F6wZoQCSrXc2BditU+1tlVhEkPFt5JgiHUpY8T8mYbroT7JH6xjcGSKUN+HG\nN8PXNUTD1VAQfwHpkfsGMfDyzjytCXsoTEOqnwIDAQABAoIBAAEL/4vfQQTuKiKy\ngzHofEbd8/SL4xDdKzBzVca7BEBon3FZjFYJdV1CrcduXNQBgPSFAkJrczBa2BEQ\nAoKmmSREhWO9Hl0blbG67l36+7QPEtXUYXX6cG5Ghal3izq6DzR8JG+62Es3kETM\nrNgZT+S1PnKdvcpZvFc9b6ZnF2InuTbrmNVBZKrhdWOJ5tCwRGKKUl6BHoJH3yu0\nT5hUW277e1LYHx+hZtoZ98ToC+LGe6/M8a8y6VLYpcQlX2AtVXeGDalomunF+p3f\nuY6din6s4lq1gSJz03PTpUbwiuhYCTe8Xkseu74Y+XYYJXPHopFju0Ewd6p0Db9Q\nJzzxCoECggCBAM2ox9zyrDc/Vlc0bb9SciFGUd/nEJF89+UHy98bAkpo22zNZIDg\nfacSgkg/6faZD+KrOU0I5W7m2B5t6w2fNHHik6NYGSLQ1JhgbXELGV7X/qECDL02\nctPaf+8o+dYoZja2LdJNASq2nmEmPI3LSHhzAt4dWY4W+geXiHt4iWVHAoIAgQDR\nUdN09xv4U+stWqNcSfgjtx6boEUE8Ky7pyj+LrZKG0L61Jy9cSDP0x0rCtkW9vVR\n6RjidWM/DHQ5cl6aq+7pPy20/OqtqttFYT4R+C3AoAnRSaNzPD9a80C2gjv7WEz0\nPPFstWkI1gsN71KKRx7e6NIa9CNn5x9iE+SGfjgb6QKCAIBXylzG7LCnRNpOj4rp\nyP//RE1fDvv7nyUTF6jnrFfl+6zvXR4yBaKd10DWJrJxGhW15PGo+Ms39EL9el6E\nihmRI+9yIwFX411dToxpXRuPaRTBFmbpvnx2Ayfpp8w+pzA62rnktApzeVFSl0fy\nH3zoLfBjcJPyG8zPwNf6HRJJsQKCAIAE2S5asTaWo+r4m/bYtmXm/eDZnfa7TI/T\nsOWELbTPNp5wjOgsgyhNaAhu7MtmesXn5cxLwohP94vhoMKMNptMD8iRPqJ471Iw\n4zW62NLGeW6AyIHes3CMPMIs+AtHoR33MkotSG5sY/jRk8+HoGoYo6/qK+l+CJ5z\neR579wR5sQKCAIAvPWq+bvcPTDKUU1Fe/Y/GyWoUA+uSqmCdORBkK38lALFGphxj\nfDz9dXskimqW+A9hOPOS8dm8YcVvi/TLXVE5Vsx9VkOg6z6AZBQpgNXGfOgpju4W\nbjER7bQaASatuWQyCxbA9oNlAUdSeOhGTxeFLkLj7hNMd6tLjfd8w7A/hA==\n-----END RSA PRIVATE KEY-----\n"}]
+
+
+class HeatMock(MagicMock):
+ def list(self):
+ return []
+
+ def get(self, stackname):
+ return StackMock()
+
+ def create(self, stack_name, template):
+ pass
+
+
+class TestClass:
+ @pytest.mark.parametrize("test_input, expected", [
+ ({'availability_zone': ['compute1', 'compute1'],
+ 'OS_image': ['QTIP_CentOS', 'QTIP_CentOS'],
+ 'public_network': ['admin-floating_net', 'admin-floating_net'],
+ 'flavor': ['m1.large', 'm1.large'],
+ 'role': ['1-server', '2-host']},
+ [('172.10.0.154', '')]),
+ ])
+ @mock.patch('func.spawn_vm.Env_setup')
+ @mock.patch('func.spawn_vm.FetchImg')
+ @mock.patch('func.spawn_vm.create_zones')
+ @mock.patch('func.spawn_vm.client', autospec=True)
+ @mock.patch('func.spawn_vm.glanceclient', autospec=True)
+ @mock.patch('func.spawn_vm.keystoneclient.v2_0', autospec=True)
+ @mock.patch('func.spawn_vm.heatclient.client', autospec=True)
+ def test_create_zones_success(self, mock_heat, mock_keystone, mock_glance,
+ mock_nova_client, mock_zone, mock_fetch,
+ mock_setup, test_input, expected):
+ mock_glance.Client.return_value = Mock(images=ImagesMock())
+ mock_nova_client.Client.return_value = Mock()
+ mock_heat.Client.return_value = Mock(stacks=HeatMock())
+ k = mock.patch.dict(os.environ, {'INSTALLER_TYPE': 'fuel'})
+ k.start()
+ SpawnVM(test_input)
+ k.stop()
+ mock_setup.ip_pw_list.append.assert_called_with(expected[0])