Skip to content

Commit

Permalink
Merge pull request #52 from Vuader/development
Browse files Browse the repository at this point in the history
Added Contrail Southbound Interface #5
  • Loading branch information
Vuader committed Aug 3, 2018
2 parents ce1272d + 0e55b84 commit f04dcc0
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 5 deletions.
2 changes: 2 additions & 0 deletions netrino/interfaces/contrail/__init__.py
@@ -0,0 +1,2 @@
from netrino.interfaces.openstack import element
from netrino.interfaces.openstack import interface
43 changes: 43 additions & 0 deletions netrino/interfaces/contrail/element.py
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Christiaan Frans Rademan, David Kruger.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
from uuid import uuid4

from luxon import Model


class Element(Model):
id = Model.Uuid(default=uuid4, internal=True)
keystone_url = Model.String(null=False)
contrail_url = Model.String(null=False)
username = Model.String(null=False)
password = Model.String(null=False)
region = Model.String(null=True)
interface = Model.Enum('admin', 'public', 'internal', null=True)
primary_key = id
99 changes: 99 additions & 0 deletions netrino/interfaces/contrail/interface.py
@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018 Christiaan Frans Rademan, David Kruger.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.

from netrino.interfaces.interface import Interface as BaseInterface
from netrino.utils.interface import getScope

from psychokinetic import Openstack
from psychokinetic import Contrail

from luxon.exceptions import FieldMissing


class Interface(BaseInterface):
"""Contrail Interface/driver.
Wrapper around psychokinetic.Contrail obj
.. code:: python
with Interface('element-uuid') as ct:
networks = ct.execute(req)
Element credentials obtained from metadata in database.
req body must contain "uri", "data", "method" and either "project_name"
or "project_id". domain is obtained from req.context_domain.
execute methods are overwritten to return json.
Args:
uuid (str): UUID of element
"""

def __init__(self, uuid):
super().__init__(uuid, "contrail")

if not 'keystone_url' in self.metadata:
raise FieldMissing(field="keystone_url",
label="Keystone URL",
description="No Keystone URL for element '%s'" %
self.uuid)


self.os = Openstack(self.metadata['keystone_url'],
self.metadata['region'],
self.metadata['interface'])
self.contrail = Contrail(self.os, self.metadata['contrail_url'])

def __enter__(self):
self.contrail.authenticate(self.metadata['username'],
self.metadata['password'],
self.metadata['domain'])
return self

def __exit__(self, *args, **kwargs):
self.os.identity.revoke(self.os._login_token)

def __getattr__(self, name):
return getattr(self.contrail, name)

def execute(self, req, *args, **kwargs):
# Since we are wrapping around psychokinetic's contrail
# client, we have to modify the execute method to:
# * take req as first arg, and
# * return json instead of the default reponse object.
method = req.json['method']
uri = req.json['uri']
if 'data' in req.json:
kwargs['data'] = req.json['data']
self.contrail.scope(
**getScope(req, infinitystone=['domain'],
one_of=['project_id', 'project_name']))
result = self.contrail.execute(method, uri, *args, **kwargs)
return result.json
Empty file added netrino/utils/__init__.py
Empty file.
11 changes: 8 additions & 3 deletions netrino/views/interface.py
Expand Up @@ -31,6 +31,8 @@
from luxon import register

from luxon.utils.pkg import EntryPoints
from luxon.exceptions import NotFoundError


METHODS = ('GET','POST','PUT','DELETE','PATCH',
'OPTIONS','HEAD','TRACE','CONNECT')
Expand Down Expand Up @@ -58,9 +60,12 @@ def interface(self, req, resp, id, interface, property):
"""
netrino_interface = EntryPoints('netrino_interfaces')

with netrino_interface[interface](id) as obj:
method = getattr(obj, property)
return method(req)
try:
with netrino_interface[interface](id) as obj:
method = getattr(obj, property)
return method(req)
except KeyError:
raise NotFoundError("Interface '%s' not registered" % interface)

def property(self, req, resp, id, interface, property, method):
""" Interact with element via given interface, with property method.
Expand Down
6 changes: 4 additions & 2 deletions setup.py
Expand Up @@ -287,11 +287,13 @@ def run(self):
],
'netrino_interfaces': [
'netconf = netrino.interfaces.netconf.interface:Interface',
'openstack = netrino.interfaces.openstack.interface:Interface'
'openstack = netrino.interfaces.openstack.interface:Interface',
'contrail = netrino.interfaces.contrail.interface:Interface'
],
'netrino_elements': [
'netconf = netrino.interfaces.netconf.element:Element',
'openstack = netrino.interfaces.openstack.element:Element'
'openstack = netrino.interfaces.openstack.element:Element',
'contrail = netrino.interfaces.contrail.element:Element'
],
}
# 'console_scripts': [
Expand Down

0 comments on commit f04dcc0

Please sign in to comment.