class OpenCenterTestCase(unittest2.TestCase): """ This test case assumes a opencenter-server has been successfully created, and at least 3 nodes have opencenter-agent installed. """ @classmethod def setUpClass(self): pass @classmethod def tearDownClass(self): pass def setUp(self): # Gather configuration data config = OpenCenterConfiguration() opencenter_config = config.opencenter_config cluster_data = config.cluster_data vip_data = config.vip_data self.endpoint_url = opencenter_config.endpoint_url self.server_name = opencenter_config.instance_server_hostname self.chef_name = opencenter_config.instance_chef_hostname self.compute_name = opencenter_config.instance_compute_hostname self.controller_name = opencenter_config.instance_controller_hostname self.user = opencenter_config.user self.password = opencenter_config.password self.cluster_data = { 'osops_public': cluster_data.osops_public, 'osops_mgmt': cluster_data.osops_mgmt, 'osops_nova': cluster_data.osops_nova, 'nova_public_if': cluster_data.nova_public_if, 'nova_vm_bridge': cluster_data.nova_vm_bridge, 'nova_dmz_cidr': cluster_data.nova_dmz_cidr, 'cluster_name': cluster_data.cluster_name, 'keystone_admin_pw': cluster_data.keystone_admin_pw, 'nova_vm_fixed_if': cluster_data.nova_vm_fixed_if, 'nova_vm_fixed_range': cluster_data.nova_vm_fixed_range, 'libvirt_type': cluster_data.libvirt_type } self.vip_data = { 'nova_rabbitmq_vip': vip_data.nova_rabbitmq_vip, 'nova_api_vip': vip_data.nova_api_vip, 'nova_mysql_vip': vip_data.nova_mysql_vip } # Establish connections with endpoints if self.user: self.ep = OpenCenterEndpoint(self.endpoint_url, user=self.user, password=self.password) else: self.ep = OpenCenterEndpoint(self.endpoint_url) self.admin_ep = OpenCenterEndpoint(self.endpoint_url + '/admin', user=self.user, password=self.password) # Collect all the nodes we need self.workspace = self.find_node("workspace") self.unprovisioned = self.find_node('unprovisioned') # Collect all the adventures we are going to run self.chef_svr = self.ep.adventures.filter('name = "Install Chef Server"').first() self.chef_cli = self.ep.adventures.filter('name = "Install Chef Client"').first() self.nova_clus = self.ep.adventures.filter('name = "Create Nova Cluster"').first() self.n_api = self.ep.adventures.filter('name = "Install Nova Controller"').first() self.n_cpu = self.ep.adventures.filter('name = "Install Nova Compute"').first() self.download_cookbooks = self.ep.adventures.filter('name = "Download Chef Cookbooks"').first() self.upload_glance_images = self.ep.adventures.filter('name = "Upload Initial Glance Images"').first() self.enable_ha = self.ep.adventures.filter('name = "Enable HA Infrastructure"').first() def tearDown(self): pass def find_node(self, partial_name): """find a node by partial name match. Useful for unpredictable jenkins node names.""" self.ep._refresh('nodes', 'before_find_node') matches = [n for n in self.ep.nodes if re.search(partial_name.strip(), n.name)] if matches: return matches[0] else: raise ValueError('No nodes found for pattern %s' % partial_name) def test_opencenter_happy_path(self): """Happy path creates a chef server and lays down an openstack cluster. If there's enough controllers in the configuration a second controller is created for HA""" # Run the install-chef-server adventure on the node chef_server = self.find_node(self.chef_name) resp = self.ep.adventures[self.chef_svr.id].execute( node=chef_server.id) self.assertEquals(resp.status_code, 202) # adventure is running, go poll task = resp.task task.wait_for_complete() # refresh the server object chef_server._request('get') self._validate_chef_server(chef_server) # Lets check if the root workspace now has the correct adventure self.assertTrue(self.nova_clus.id in self.workspace.adventures.keys()) # Create an OpenStack cluster resp = self.ep.adventures[self.nova_clus.id].execute( node=self.workspace.id, plan_args=self.cluster_data) self.assertEquals(resp.status_code, 202) self.assertFalse(resp.requires_input) task = resp.task task.wait_for_complete() # make sure test_cluster got created test_cluster = self.find_node(self.cluster_data['cluster_name']) self.assertIsNotNone(test_cluster) self.assertEquals(test_cluster.facts['parent_id'], self.workspace.id) infra_container = self.find_node("Infrastructure") self.assertIsNotNone(infra_container) self.assertEquals(infra_container.facts['parent_id'], test_cluster.id) compute_container = self.find_node("Compute") self.assertIsNotNone(compute_container) self.assertEquals(compute_container.facts['parent_id'], test_cluster.id) az_container = self.find_node("AZ nova") self.assertIsNotNone(az_container) self.assertEquals(az_container.facts['parent_id'], compute_container.id) controllers = [] for controller_name in self.controller_name.split(","): controllers.append(self.find_node(controller_name)) computes = [] for compute_name in self.compute_name.split(","): computes.append(self.find_node(compute_name)) print "computes", computes print "controllers", controllers # Reparent self.controller_name under the new infra container ha_enabled = False for new_controller in controllers: self._reparent(new_controller, infra_container) new_controller._request('get') self.assertEquals(new_controller.facts['parent_id'], infra_container.id) #Upload initial glance images resp = self.ep.adventures[self.upload_glance_images.id].execute( node=new_controller.id, plan_args=self.cluster_data) self.assertEquals(resp.status_code, 202) self.assertFalse(resp.requires_input) task = resp.task task.wait_for_complete() # Enable HA if possible if not ha_enabled and len(controllers) > 1: resp = self.ep.adventures[self.enable_ha.id].execute( node=infra_container.id, plan_args=self.vip_data) self.assertEquals(resp.status_code, 202) self.assertFalse(resp.requires_input) task = resp.task task.wait_for_complete() infra_container._request('get') self.assertTrue(infra_container.facts['ha_infra']) ha_enabled = True # Reparent self.controller_name under the new infra container for new_compute in computes: self._reparent(new_compute, az_container) new_compute._request('get') self.assertEquals(new_compute.facts['parent_id'], az_container.id) def _reparent(self, child_node, parent_node): new_fact = self.ep.facts.create(node_id=child_node.id, key='parent_id', value=parent_node.id) resp = new_fact.save() self.assertEquals(resp.status_code, 202) task = resp.task task.wait_for_complete() time.sleep(10) #Wait for the chain of adventures that follow to finish tasks = self.ep.nodes[child_node.id].tasks for task in tasks: task.wait_for_complete() if (tasks != self.ep.nodes[child_node.id].tasks): tasks = self.ep.nodes[child_node.id].tasks def _validate_chef_server(self, node): self.assertTrue('chef-server' in node.facts['backends']) fact_keys = ['chef_server_client_name', 'chef_server_client_pem', 'chef_server_pem', 'chef_server_uri'] for key in fact_keys: self.assertIsNotNone(node.facts.get(key, None))