Example #1
0
    def __call__(self, environ, response):
        token = environ.get('HTTP_X_AUTH_TOKEN', '')

        if token == '':
            LOG.error('No X-Auth-Token header supplied.')
            raise HTTPError(400, 'No X-Auth-Token header supplied.')

        tenant = environ.get('HTTP_X_TENANT_NAME', '')

        if tenant == '':
            LOG.error('No X-Tenant-Name header supplied.')
            raise HTTPError(400, 'No X-Tenant-Name header supplied.')

        design_uri = CONFIG.get('service_manager', 'design_uri', '')
        if design_uri == '':
            LOG.fatal('No design_uri parameter supplied in sm.cfg')
            raise Exception('No design_uri parameter supplied in sm.cfg')

        auth = KeyStoneAuthService(design_uri)
        if not auth.verify(token=token, tenant_name=tenant):
            raise HTTPError(
                401, 'Token is not valid. You likely need an updated token.')

        return self._call_occi(environ,
                               response,
                               token=token,
                               tenant_name=tenant,
                               registry=self.registry)
def get_resource_openstack_ids(pop_url,
                               pop_id,
                               resource_type,
                               query_params=list()):
    """
    Retrive list of nodes uuid of a given type
    :param pop_url: Url of PoP DB
    :param pop_id: PoP ID
    :param resource_type: type of nodes that should be retrieved
    :param query_params: optional list of (key, value)s used as query parameters
    :return list: list of nodes uuids
    """
    graph_url, pop = _get_graph_url(pop_url, pop_id)

    query = 'match node where node.type="{}" and node.pop="{}" '.format(
        resource_type, pop)

    for q in query_params:
        if len(q[0]) > 0 and len(q[1]) > 0:
            val = '(?i).*%s.*' % (q[1])
            query += 'and node.attributes=~"{}"'.format(val)

    query += ' return node.openstack_uuid'
    graph_db = neo4j.Graph(graph_url)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)
    results = []
    for record in data.records:
        if record['node.openstack_uuid']:
            results.append(record['node.openstack_uuid'])

    query = 'match node where node.type=~"(?i){}" and node.pop="{}" '.format(
        resource_type, pop)

    for q in query_params:
        if len(q[0]) > 0 and len(q[1]) > 0:
            val = '(?i).*%s.*' % (q[1])
            query += 'and node.attributes=~"{}"'.format(val)

    query += ' return node.physical_name'

    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)

    for record in data.records:
        if record['node.physical_name']:
            results.append(record['node.physical_name'])

    return results
def get_pop_links_target_uuid(pop_url, source_uuid):
    """
    Return a list of tuple containing (target uuid, target type, link uuid)
    for a given source uuid node in the PoP DB
    :param pop_url: Url of the PoP DB
    :param source_uuid: source uuid of the links to be retrieved
    :return List: List of links information
    """
    graph_db = neo4j.Graph(pop_url)
    query = 'match n-[r]->m where n.type = "pop" and n.uuid="{}" ' \
            ' return r,m'.format(source_uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + pop_url)

    results = []
    for record in data.records:
        m_properties = dict(record.m.properties)
        r_properties = dict(record.r.properties)
        if 'uuid' in m_properties and 'uuid' in r_properties:
            results.append((m_properties['uuid'], m_properties['type'].lower(),
                            r_properties['uuid']))

    return results
def get_pop_ids(pop_url, query_params=list()):
    """
    Retrieve list of PoPs uuids
    :param pop_url: Url of the PoP DB
    :param query_params:  optional list of (key, value)s used as query parameters
    :return list: List of PoPs uuids
    """
    query = 'match node where node.type="{}" return node'.format('pop')

    graph_db = neo4j.Graph(pop_url)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + pop_url)
    results = []
    for record in data.records:
        prop = dict(record.node.properties)
        filtered = False
        for q in query_params:
            if len(q[0]) > 0 and len(q[1]) > 0:
                if q[0] == 'name' or q[0] == 'occi.epa.pop.name':
                    if prop['occi.epa.pop.name'].lower() != q[1].lower():
                        filtered = True
                else:
                    tmp = repr(prop[q[0]]).lower()
                    if tmp != q[1].lower():
                        filtered = True
        if not filtered:
            results.append(prop['uuid'])
    return results
Example #5
0
def call_odl_api(user, password, url):
    """
    Fecth the OpenDaylight response and
    put it in a dictionary.

    :param user: OpenDaylight Username
    :param password: OpenDaylight Password
    :param url: URL OpenDaylight endpoint
    :return dict: OpenDaylight response
    """
    buf = StringIO()
    try:
        c = pycurl.Curl()
        c.setopt(pycurl.USERPWD, str(user + ':' + password))
        c.setopt(c.URL, url)
        c.setopt(pycurl.HTTPHEADER, ["Content-type: application/json"])
        c.setopt(c.WRITEDATA, buf)
        c.perform()
        c.close()
    except Exception:
        raise HTTPError(400, "Error connecting to OpenDaylight {}".format(url))
    response = ''

    for string_buf in buf.buflist:
        response += string_buf

    body_json = {}

    if response.strip() != '':
        body_json = json.loads(response)

    return body_json
def get_links_target_uuid(pop_url, pop_id, source_uuid):
    """
    Retrieve Link target uuids given link's source uuid
    :param pop_url: Url of PoP DB
    :param pop_id: PoP ID
    :param source_uuid: link's source uuid
    :return list: List of link's targets UUIDs
    """
    graph_url, pop = _get_graph_url(pop_url, pop_id)

    graph_db = neo4j.Graph(graph_url)
    query = 'match n-[r]->m where n.openstack_uuid="{}" ' \
            ' return m'.format(source_uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)
    results = []
    for record in data.records:
        m_properties = dict(record.m.properties)
        if 'openstack_uuid' in m_properties:
            results.append(
                (m_properties['openstack_uuid'], m_properties['type'].lower()))

        if 'physical_name' in m_properties:
            results.append(
                (m_properties['physical_name'], m_properties['type'].lower()))

    query = 'match n-[r]->m where n.physical_name="{}" ' \
            ' return m'.format(source_uuid)

    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)

    for record in data.records:
        m_properties = dict(record.m.properties)
        if 'openstack_uuid' in m_properties:
            results.append(
                (m_properties['openstack_uuid'], m_properties['type'].lower()))

        if 'physical_name' in m_properties:
            results.append(
                (m_properties['physical_name'], m_properties['type'].lower()))

    return results
def _get_graph_url(pop_url, pop_id):
    """
    Retrieve EPA db url and PoP name for a given
    pop_id
    :param pop_url: Url of the PoP DB
    :param pop_id: PoP ID
    :return tuple: (EPA url, PoP name)
    """
    try:
        graph_db = neo4j.Graph(pop_url)
        index = ('pop', 'uuid', pop_id)
        pop = neo_resource.get_node(graph_db, index)
        if pop:
            properties = dict(pop.properties)
            if 'occi.epa.pop.graph_db_url' in properties and 'occi.epa.pop.name' in properties:
                return properties['occi.epa.pop.graph_db_url'], properties[
                    'occi.epa.pop.name']
    except Exception:
        raise HTTPError(404, 'Error connecting to graph_url: ' + str(pop_url))
    raise HTTPError(404, 'Resource not found: Epa-Pop-Id: ' + str(pop_id))
def _get_odl_info(pop_url, pop_id):
    """
    Retrieve OpenDaylight Url, username and password from the PoP DB

    :param pop_url: Url of Neo4j PoP DB
    :param pop_id: PoP ID
    :return tuple: (ODL url, ODL username, ODL password
    """
    try:
        graph_db = neo4j.Graph(pop_url)
        index = ('pop', 'uuid', pop_id)
        pop = neo_resource.get_node(graph_db, index)
        if pop:
            properties = dict(pop.properties)
            if 'occi.epa.pop.odl_url' in properties and 'occi.epa.pop.odl_name' in properties \
                    and 'occi.epa.pop.odl_password' in properties:
                return properties['occi.epa.pop.odl_url'], properties['occi.epa.pop.odl_name'],\
                    properties['occi.epa.pop.odl_password']

    except Exception:
        raise HTTPError(404, 'Error connecting to graph_url: ' + str(pop_url))
    raise HTTPError(404, 'Resource not found: Epa-Pop-Id: ' + str(pop_id))
def get_pop(pop_url, uuid):
    """
    Retrieve PoP given the uuid
    :param pop_url: Url of PoP DB
    :param uuid: PoP uuid
    :return dict: Dictionary containing PoP properties
    """
    graph_db = neo4j.Graph(pop_url)
    index = ('pop', 'uuid', uuid)
    pop = neo_resource.get_node(graph_db, index)
    if pop:
        results = dict(pop.properties)
        return results
    raise HTTPError(404, 'Resource not found: /pop/' + uuid)
def _get_resource_by_type_and_uuid(graph_db, pop, resource_type, uuid):
    """
    Retrieve properties of a given virtual node, given its type and
    its unique ID
    :param graph_db: Graph instance pointing to the EPA DB
    :param pop: PoP Name
    :param resource_type: Type of the resource
    :param uuid: Node uuid
    :return dict: Node properties
    """
    query = 'match node where node.type="{}" and node.pop="{}" ' \
            'and node.openstack_uuid = "{}" return node'.format(resource_type, pop, uuid)

    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url ")
    for record in data.records:
        node_properties = dict(record.node.properties)
        return node_properties

    raise HTTPError(404,
                    'Resource not found: /' + str(resource_type) + '/' + uuid)
Example #11
0
    def get_resources(self, extras):
        """
        Get list of resources
        :param extras: any extras parameter to the call
        :return: list of resources
        """
        results = []
        query = extras['query']
        if extras['kind'] != 'pop':
            if 'pop_id' not in extras:
                raise HTTPError(400, "Pop-Id missing")
            results = self.get_resource_entities(extras['pop_url'], extras['pop_id'], [extras['kind']], query)

        elif extras['kind'] == 'pop':
            results = self.get_pops(extras['pop_url'], query)
        return results
def get_pop_link_source_target(pop_url, uuid):
    """
    Return the source and the target uuid for a link
    specified with it uuid
    :param pop_url: Url of the PoP DB
    :param uuid: Link uuid
    :return tuple: (source uuid, target uuid)
    """
    graph_db = neo4j.Graph(pop_url)
    query = 'match n-[r]-m where r.uuid = "{}" return n.uuid, m.uuid'.format(
        uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + pop_url)
    for record in data.records:
        return record['n.uuid'], record['m.uuid']
def get_pop_link(pop_url, uuid):
    """
    Return link properites and link label

    :param pop_url: Url of the PoP DB
    :param uuid: Link uuid
    :return tuple: (link properties, link label)
    """
    graph_db = neo4j.Graph(pop_url)
    query = 'match n-[r]-m where r.uuid = "{}" return r'.format(uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + pop_url)
    for record in data.records:
        r_properties = dict(record.r.properties)
        return r_properties, record.r.type
def get_os_dev_by_mac(pop_url, pop_id, mac):
    """
    Retrieve the osdev id with the given MAC address
    :param pop_url: Url of the PoP DB
    :param pop_id: PoP ID
    :param mac: MAC address
    :return string: osdev uuid
    """
    graph_url, pop = _get_graph_url(pop_url, pop_id)
    graph_db = neo4j.Graph(graph_url)
    query = 'match n where n.attributes=~"(?i).*{}.*" return n.physical_name'.format(
        mac)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + pop_url)
    for record in data.records:
        return record['n.physical_name']
def get_mac_by_osdev_uuid(pop_url, pop_id, uuid):
    """
    Retrieve mac address of the osdev with the give uuid
    :param pop_url: Url of the PoP DB
    :param pop_id: PoP ID
    :param uuid: OS device uuid
    :return string: MAC address
    """
    graph_url, pop = _get_graph_url(pop_url, pop_id)
    graph_db = neo4j.Graph(graph_url)
    query = 'match n where n.physical_name="{}" return n.attributes'.format(
        uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + pop_url)
    for record in data.records:
        json_attr = json.loads(record['n.attributes'])
        return json_attr.get('Address', None)
def delete_pop_link(pop_url, uuid):
    """
    Delete link with the given uuid
    :param pop_url: Url of the PoP DB
    :param uuid: Link uuid
    """
    graph_db = neo4j.Graph(pop_url)
    query = 'match n-[r]-m where r.uuid = "{}" return r'.format(uuid)
    edge = None
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + pop_url)

    for record in data.records:
        edge = record.r

    if edge:
        graph_db.delete(edge)
def get_link(pop_url, pop_id, source_uuid, target_uuid):
    """
    Retrieve Link information given source and target uuid
    :param pop_url: Url of PoP DB
    :param pop_id: PoP ID
    :param source_uuid: link's source uuid
    :param target_uuid: link's target uuid
    :return dict: It returns label and target type of the link
    """
    graph_url, pop = _get_graph_url(pop_url, pop_id)
    graph_db = neo4j.Graph(graph_url)
    query = 'match n-[r]->m where n.openstack_uuid="{}" and m.openstack_uuid="{}" ' \
            ' return r, m.type'.format(source_uuid, target_uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)

    for record in data.records:
        result = {
            'label': record.r.type.lower(),
            'target_type': record['m.type']
        }
        return result

    query = 'match n-[r]->m where n.openstack_uuid="{}" and m.physical_name="{}" ' \
            ' return r, m.type'.format(source_uuid, target_uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)

    for record in data.records:
        result = {
            'label': record.r.type.lower(),
            'target_type': record['m.type']
        }
        return result

    query = 'match n-[r]->m where n.physical_name="{}" and m.openstack_uuid="{}" ' \
            ' return r, m.type'.format(source_uuid, target_uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)

    for record in data.records:
        result = {
            'label': record.r.type.lower(),
            'target_type': record['m.type']
        }
        return result

    query = 'match n-[r]->m where n.physical_name="{}" and m.physical_name="{}" ' \
            ' return r, m.type'.format(source_uuid, target_uuid)
    try:
        data = graph_db.cypher.execute(query)
    except Exception:
        raise HTTPError(400, "Error connecting to graph url " + graph_url)

    for record in data.records:
        result = {
            'label': record.r.type.lower(),
            'target_type': record['m.type']
        }
        return result
Example #18
0
    def get_resource(self, key, extras):
        """
        Get single resource kind and call the
        specific kind backend.

        :param key: UUID of the resource
        :param extras: any extras parameters of the call
        :return Resource: OCCI Resource
        """
        # Initialize PoP ID from extras
        if 'pop_id' in extras:
            pop_id = extras['pop_id']
        else:
            pop_id = None

        pop_url = extras['pop_url']
        result = None
        splitted_url = key[1:].split('/')

        # All resources, except PoPs and PoPs links
        # require a PoP ID
        if splitted_url[0] != 'pop' and not pop_id:
            raise HTTPError(400, "Pop-Id missing")

        # Get Resource
        if len(splitted_url) == 2:
            resource_type = splitted_url[0]
            uuid = splitted_url[1]
            uuids = EPARegistry.get_ids(resource_type, pop_url, pop_id)
            if uuid not in uuids:
                raise HTTPError(404, "Resource not found")

            result = self.get_occi_resource(resource_type, uuid)

            # Identify PoP Link
            if resource_type == 'pop':
                for target_link in epa_glue.get_pop_links_target_uuid(pop_url, uuid):
                    self.get_link(resource_type,
                                  result,
                                  target_link[0],
                                  target_link[1],
                                  target_link[2])

            # Identify switch link
            elif resource_type == 'switch':
                for target_uuid in odl_glue.get_switch_interfaces_by_switch_id(pop_url, pop_id, uuid):
                    link_uuid = uuid + '->' + target_uuid
                    self.get_link(resource_type,
                                  result,
                                  target_uuid,
                                  'switch-interface',
                                  link_uuid)

            # Identify switch interface link
            # A switch interface is connected to the switch
            # and can be connected to an osdev
            elif resource_type == 'switch-interface':
                switch_uuid = odl_glue.get_switch_by_interface(pop_url, pop_id, uuid)
                # Link to the switch
                if switch_uuid:
                    switch_link_uuid = uuid + '->' + switch_uuid
                    self.get_link(resource_type,
                                  result,
                                  switch_uuid,
                                  'switch',
                                  switch_link_uuid)

                osdev_uuid = odl_glue.get_os_dev_by_switch_interface(pop_url, pop_id, uuid)
                # Link to the osdev
                if osdev_uuid:
                    osdev_link_uuid = uuid + '->' + osdev_uuid
                    self.get_link(resource_type,
                                  result,
                                  osdev_uuid,
                                  'osdev',
                                  osdev_link_uuid)
            # Identify osdev link
            # An osdev can be connected to a switch interface
            elif resource_type == 'osdev':
                mac = epa_glue.get_mac_by_osdev_uuid(pop_url, pop_id, uuid)
                if mac:
                    switch_interface = odl_glue.get_switch_interface_by_mac(pop_url, pop_id, mac)
                    if switch_interface:
                        link_uuid = uuid + '->' + switch_interface
                        self.get_link(resource_type,
                                      result,
                                      switch_interface,
                                      'switch-interface',
                                      link_uuid)

            # Indentify link for all other resources
            else:
                for target_link in epa_glue.get_links_target_uuid(extras['pop_url'], pop_id, uuid):
                    link_uuid = uuid + '->' + target_link[0]
                    self.get_link(resource_type,
                                  result,
                                  target_link[0],
                                  target_link[1],
                                  link_uuid)

        # Get Link
        elif len(splitted_url) == 3 and splitted_url[1] == 'link':
            link_uuid = splitted_url[2]

            # Not PoP Link
            # Link UUID = source_uuid + '->' + target_uuid
            if '->' in link_uuid:
                source_type = splitted_url[0]
                source_uuid = splitted_url[2].split('->')[0]
                target_uuid = splitted_url[2].split('->')[1]

                # if source_type is switch
                # target type can be only switch interface
                if source_type == 'switch':
                    link_prop = dict()
                    link_prop['target_type'] = 'switch-interface'

                # if source_type is switch
                # target type can be switch and eventually osdev
                elif source_type == 'switch-interface':
                    link_prop = dict()
                    if target_uuid == odl_glue.get_switch_by_interface(pop_url, pop_id, source_uuid):
                        link_prop['target_type'] = 'switch'
                    elif target_uuid == odl_glue.get_os_dev_by_switch_interface(pop_url, pop_id, source_uuid):
                        link_prop['target_type'] = 'osdev'

                # if source_type is switch
                # and target_uuid is of openflow type
                # target_type is a switch
                elif source_type == 'osdev' and 'openflow' in target_uuid:
                    link_prop = dict()
                    link_prop['target_type'] = 'switch-interface'
                else:
                    link_prop = epa_glue.get_link(extras['pop_url'], pop_id, source_uuid, target_uuid)

                # if link_prop is not set
                # the required link does not exist
                if not link_prop:
                    raise HTTPError(404, "Resource Not Found")
                source_entity = self.get_occi_resource(source_type, source_uuid)
                result = self.get_link(source_type,
                                       source_entity,
                                       target_uuid,
                                       link_prop['target_type'],
                                       link_uuid)

            # PoP Link
            else:
                link_result = epa_glue.get_pop_link_source_target(pop_url, link_uuid)
                if link_result and len(link_result) == 2:
                    source = link_result[0]
                    target = link_result[1]
                    source_entity = self.get_occi_resource(splitted_url[0], source)
                    target_entity = self.get_occi_resource(splitted_url[0], target)
                    result = self.get_occi_link(splitted_url[0] + '_link', link_uuid, source_entity, target_entity)

        # If requested resource does not exist
        # raise Resource not found exception
        if result:
            if isinstance(result, Resource) and result.kind.term != 'pop':
                EPARegistry.add_pop_id_to_resource(result, pop_id)
                EPARegistry.add_pop_id_to_links(result.links, pop_id)
            if isinstance(result, Link) and result.kind.term != 'poplink':
                EPARegistry.add_pop_id_to_resource(result, pop_id)
                EPARegistry.add_pop_id_to_link_source(result, pop_id)
                EPARegistry.add_pop_id_to_link_target(result, pop_id)


            return result
        raise HTTPError(404, 'Resource not found: ' + str(key))