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()
示例#2
0
def opencenter_endpoint(chef, name='test', os='ubuntu'):
    validate_environment(chef, name=name, os=os)
    env = env_format % (name, os)
    query = "in_use:\"server\" AND chef_environment:%s" % env
    server = next(Node(node['name']) for node in Search('node').query(query))
    ep_url = "https://%s:8443" % server['ipaddress']
    return OpenCenterEndpoint(ep_url, user="******", password="******")
 def _update_task(self, result, input_data):
     task_id = input_data['id']
     endpoint_url = global_config['endpoints']['admin']
     ep = OpenCenterEndpoint(endpoint_url)
     task = ep.tasks[task_id]
     task._request_get()
     task.state = 'done'
     task.result = result
     task.save()
示例#4
0
    def __init__(self,
                 endpoint='http://localhost:8080',
                 logger=None,
                 parent_task_id=None,
                 adventure_globals=None):
        self.endpoint = OpenCenterEndpoint(endpoint)
        self.logger = logger
        self.parent_task_id = parent_task_id

        self.api = db_api.api_from_endpoint(endpoint)

        self.adventure_globals = adventure_globals
        if not adventure_globals:
            self.adventure_globals = {}

        if not logger:
            self.logger = logging.getLogger()

        opencenter.backends.load()
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))
示例#6
0
    def _maybe_init(self):
        if self.endpoint:
            return True
        else:
            LOG.info('Connecting to endpoint')
            try:
                self.endpoint = OpenCenterEndpoint(self.endpoint_uri)
            except ConnectionError:
                return False
            except KeyboardInterrupt:
                raise

        if not self.host_id:
            # try to find our host ID from the endpoint
            LOG.info('Initial connection: fetching host ID')
            #TODO: Fix up client to support whoami in a more
            #reasonable manner and fix this code up
            root = self.endpoint.nodes.filter(
                'facts.parent_id = None and name = "workspace"').first()
            resp = root.whoami(hostname=self.name).json
            try:
                host_id = resp['node_id']
            except KeyError:
                LOG.error('Unable to get node ID: %s' % resp['message'])
                return False
            reg_file = '.'.join((self.hostidfile, 'registering'))
            dirs = reg_file.rpartition(os.sep)[0]
            try:
                os.makedirs(dirs)
            except OSError:
                pass

            with open(reg_file, 'wb') as f:
                f.write(str(host_id))
            resp = root.whoami(node_id=host_id).json
            try:
                node = resp['node']
            except KeyError:
                LOG.error('Unable to get node ID: %s' % resp['message'])
                return False
            if node['id'] == host_id:
                os.rename(reg_file, self.hostidfile)
                self.host_id = node['id']
            else:
                LOG.error('Node ID mismatch.')
                return False

        # update the module list
        self.producer_lock.acquire()
        task = {'action': 'modules.list',
                'payload': {},
                'id': -1}
        self.pending_tasks.append(task)
        self.producer_condition.notify()
        LOG.debug('added module_list task to work queue')
        self.producer_lock.release()
        self.producer_lock.acquire()
        task = {'action': 'modules.actions',
                'payload': {},
                'id': -1}
        self.pending_tasks.append(task)
        self.producer_condition.notify()
        LOG.debug('added module_list task to work queue')
        self.producer_lock.release()

        return True