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
# under the License.
import json
from oslo_log import log as logging
from gluon.backends import backend_base
from gluon.common import exception as exc
from gluon.particleGenerator import generator
LOG = logging.getLogger(__name__)
@ -26,39 +28,71 @@ logger = LOG
class MyData(object):
pass
DriverData = MyData()
DriverData.service = u'net-l3vpn'
DriverData.version = 'v1.0'
DriverData.proton_base = 'proton'
DriverData.ports_name = 'ports'
DriverData.binding_name = 'vpnbindings'
def createDriverData():
service_list = generator.get_service_list()
drivers = dict()
for service in service_list:
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):
def driver_for(self, backend, dummy_net, dummy_subnet):
if backend['service'] == DriverData.service:
return Driver(backend, dummy_net, dummy_subnet)
service = backend['service']
if service in DriverData:
driverData = DriverData[service]
return Driver(backend, dummy_net, dummy_subnet, driverData)
else:
return None
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)
self.driverData = driverData
self._port_url = \
"{0:s}/{1:s}/{2:s}/{3:s}/{4:s}".format(backend["url"],
DriverData.proton_base,
DriverData.service,
DriverData.version,
DriverData.ports_name)
self._binding_url = \
"{0:s}/{1:s}/{2:s}/{3:s}/{4:s}".format(backend["url"],
DriverData.proton_base,
DriverData.service,
DriverData.version,
DriverData.binding_name)
driverData.proton_base,
driverData.service,
driverData.version,
driverData.ports_name)
self._base_url = \
"{0:s}/{1:s}/{2:s}/{3:s}".format(backend["url"],
driverData.proton_base,
driverData.service,
driverData.version)
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):
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
# 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
try:
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)
ret_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
try:
svc_bind_data = self._client.json_get(url)

View File

@ -1,7 +1,7 @@
file_version: "1.0"
imports: base/base.yaml
info:
name: test_api
name: test
version: 1.0
description: "Test API Specification"
author:
@ -64,4 +64,9 @@ objects:
values:
- one
- 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():
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