Merge "Auto generate backend for core plug_in"

This commit is contained in:
Zuul 2018-01-08 23:35:22 +00:00 committed by Gerrit Code Review
commit a2ef179412
3 changed files with 87 additions and 21 deletions

View File

@ -13,10 +13,12 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import json
from oslo_log import log as logging from oslo_log import log as logging
from gluon.backends import backend_base from gluon.backends import backend_base
from gluon.common import exception as exc from gluon.common import exception as exc
from gluon.particleGenerator import generator
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -26,39 +28,71 @@ logger = LOG
class MyData(object): class MyData(object):
pass pass
DriverData = MyData()
DriverData.service = u'net-l3vpn' def createDriverData():
DriverData.version = 'v1.0' service_list = generator.get_service_list()
DriverData.proton_base = 'proton' drivers = dict()
DriverData.ports_name = 'ports' for service in service_list:
DriverData.binding_name = 'vpnbindings' model = generator.load_model_for_service(service)
generator.verify_model(model)
driverData = MyData()
driverData.service = str(model['info']['name'])
driverData.version = 'v' + str(model['info']['version'])
driverData.proton_base = 'proton'
driverData.ports_name = 'ports'
driverData.binding_names = \
generator.get_service_binding(driverData.service)
drivers[service] = driverData
return drivers
DriverData = createDriverData()
class Provider(backend_base.ProviderBase): class Provider(backend_base.ProviderBase):
def driver_for(self, backend, dummy_net, dummy_subnet): def driver_for(self, backend, dummy_net, dummy_subnet):
if backend['service'] == DriverData.service: service = backend['service']
return Driver(backend, dummy_net, dummy_subnet) if service in DriverData:
driverData = DriverData[service]
return Driver(backend, dummy_net, dummy_subnet, driverData)
else: else:
return None return None
class Driver(backend_base.Driver): class Driver(backend_base.Driver):
def __init__(self, backend, dummy_net, dummy_subnet): def __init__(self, backend, dummy_net, dummy_subnet, driverData):
super(Driver, self).__init__(backend, dummy_net, dummy_subnet) super(Driver, self).__init__(backend, dummy_net, dummy_subnet)
self.driverData = driverData
self._port_url = \ self._port_url = \
"{0:s}/{1:s}/{2:s}/{3:s}/{4:s}".format(backend["url"], "{0:s}/{1:s}/{2:s}/{3:s}/{4:s}".format(backend["url"],
DriverData.proton_base, driverData.proton_base,
DriverData.service, driverData.service,
DriverData.version, driverData.version,
DriverData.ports_name) driverData.ports_name)
self._binding_url = \ self._base_url = \
"{0:s}/{1:s}/{2:s}/{3:s}/{4:s}".format(backend["url"], "{0:s}/{1:s}/{2:s}/{3:s}".format(backend["url"],
DriverData.proton_base, driverData.proton_base,
DriverData.service, driverData.service,
DriverData.version, driverData.version)
DriverData.binding_name) self._binding_url = None
def get_binding_url(self, port_id):
for binding_name in self.driverData.binding_names:
binding_url = "{0:s}/{1:s}".format(self._base_url, binding_name)
url = binding_url + "/" + port_id
try:
svc_bind_data = self._client.json_get(url)
except exc.GluonClientException:
svc_bind_data = None
if svc_bind_data:
self._binding_url = binding_url
break
if self._binding_url is None:
self._binding_url = \
"{0:s}/{1:s}".format(self._base_url,
self.driverData.binding_names[0])
def port(self, port_id): def port(self, port_id):
url = self._port_url + "/" + port_id url = self._port_url + "/" + port_id
@ -67,6 +101,8 @@ class Driver(backend_base.Driver):
# The untagged interface has the same UUID as the port # The untagged interface has the same UUID as the port
# First we get the service binding to retrive the ipaddress # First we get the service binding to retrive the ipaddress
# #
if self._binding_url is None:
self.get_binding_url(port_id)
url = self._binding_url + "/" + port_id url = self._binding_url + "/" + port_id
try: try:
svc_bind_data = self._client.json_get(url) svc_bind_data = self._client.json_get(url)
@ -80,6 +116,9 @@ class Driver(backend_base.Driver):
port_list = self._client.json_get(self._port_url) port_list = self._client.json_get(self._port_url)
ret_port_list = [] ret_port_list = []
for port in port_list: for port in port_list:
if self._binding_url is None:
self.get_binding_url(port.id)
url = self._binding_url + "/" + port.id url = self._binding_url + "/" + port.id
try: try:
svc_bind_data = self._client.json_get(url) svc_bind_data = self._client.json_get(url)

View File

@ -1,7 +1,7 @@
file_version: "1.0" file_version: "1.0"
imports: base/base.yaml imports: base/base.yaml
info: info:
name: test_api name: test
version: 1.0 version: 1.0
description: "Test API Specification" description: "Test API Specification"
author: author:
@ -64,4 +64,9 @@ objects:
values: values:
- one - one
- two - two
- three - three
TestBinding:
api:
name: TestBinding
plural_name: TestBindings
extends: BaseServiceBinding

View File

@ -409,3 +409,25 @@ def build_api(root, service_list):
def get_db_gen(): def get_db_gen():
return GenData.DBGeneratorInstance return GenData.DBGeneratorInstance
# Get the binding name for a serivce. For example the binding for net_l3vpn
# would be VpnBinding, and the binding for ietf-sfc would be both
# SfDataPlaneLocator and SffDataPlaneLocator.
# One reason for getting the binding name is to get the port's ipaddress stored
# in binding. One example of using the binding name is when building the
# binding_url in the core plug_in backend in gluon.backends.models.net_l3vpn.py
# param service: service name
# return list of binding names, could be more than one binding per service
def get_service_binding(service):
binding_names = []
model = load_model_for_service(service)
for obj_name, obj_val in model['api_objects'].items():
if 'extends' in obj_val and \
obj_val.get('extends') == 'BaseServiceBinding':
binding_names.append(obj_val['api']['plural_name'])
if not binding_names:
raise_obj_error(service,
'Service %s does not have binding defined',
(service))
return binding_names