[CORD-2938] Moving convenience methods in the synchronizer containers
Change-Id: I3b189006f43e3aae89e50b7802306da86b339a22
diff --git a/xos/coreapi/dynamicbuild.py b/xos/coreapi/dynamicbuild.py
index 96e4d39..b35fcab 100644
--- a/xos/coreapi/dynamicbuild.py
+++ b/xos/coreapi/dynamicbuild.py
@@ -36,6 +36,7 @@
self.coreapi_dir = os.path.join(base_dir, "coreapi")
self.protos_dir = os.path.join(base_dir, "coreapi/protos")
self.app_metadata_dir = os.path.join(base_dir, "xos")
+ self.convenience_methods_dir = os.path.join(base_dir, "xos_client/xosapi/convenience")
def pre_validate_file(self, item):
# someone might be trying to trick us into writing files outside the designated directory
@@ -174,7 +175,8 @@
"dest_dir": os.path.join(self.services_dest_dir, request.name),
"xprotos": [],
"decls": [],
- "attics": []}
+ "attics": [],
+ "convenience_methods": []}
if (state == "load"):
for item in request.xprotos:
@@ -194,6 +196,14 @@
file(os.path.join(attic_dir, item.filename), "w").write(item.contents)
service_manifest["attics"].append({"filename": item.filename})
+ for item in request.convenience_methods:
+ save_path = os.path.join(self.convenience_methods_dir, item.filename)
+ file(save_path, "w").write(item.contents)
+ service_manifest["convenience_methods"].append({
+ "filename": item.filename,
+ "path": save_path
+ })
+
return service_manifest
def run_xosgenx_service(self, manifest):
diff --git a/xos/coreapi/protos/dynamicload.proto b/xos/coreapi/protos/dynamicload.proto
index 353804f..0279f71 100644
--- a/xos/coreapi/protos/dynamicload.proto
+++ b/xos/coreapi/protos/dynamicload.proto
@@ -20,14 +20,24 @@
string contents = 2;
};
+message APIConvenienceFile {
+ string filename = 1;
+ string contents = 2;
+};
+
message LoadModelsRequest {
string name = 1;
string version = 2;
repeated Xproto xprotos = 3;
repeated DeclFile decls = 4;
repeated AtticFile attics = 5;
+ repeated APIConvenienceFile convenience_methods = 6;
};
+message ListConvenienceMethodsReply {
+ repeated APIConvenienceFile convenience_methods = 1;
+}
+
message LoadModelsReply {
enum LoadModelsStatus {
SUCCESS = 0;
@@ -71,4 +81,10 @@
get: "/xosapi/v1/dynamicload/load_status"
};
}
+ rpc GetConvenienceMethods(google.protobuf.Empty) returns (ListConvenienceMethodsReply) {
+ option (googleapi.http) = {
+ // NOTE do we need to expose this via rest? maybe for debug...
+ get: "/xosapi/v1/dynamicload/convenience_methods"
+ };
+ }
};
diff --git a/xos/coreapi/xos_dynamicload_api.py b/xos/coreapi/xos_dynamicload_api.py
index 2d775dc..30ef79b 100644
--- a/xos/coreapi/xos_dynamicload_api.py
+++ b/xos/coreapi/xos_dynamicload_api.py
@@ -28,6 +28,8 @@
from xosutil.autodiscover_version import autodiscover_version_of_main
from dynamicbuild import DynamicBuilder
+# NOTE/FIXME this file is loaded before Django, we can't import apihelper
+# from apihelper import XOSAPIHelperMixin, translate_exceptions
class DynamicLoadService(dynamicload_pb2_grpc.dynamicloadServicer):
def __init__(self, thread_pool, server):
@@ -115,3 +117,24 @@
except Exception, e:
import traceback; traceback.print_exc()
raise e
+
+ def GetConvenienceMethods(self, request, context):
+ # self.authenticate(context, required=True)
+ try:
+ builder = DynamicBuilder()
+ manifests = builder.get_manifests()
+
+ response = dynamicload_pb2.ListConvenienceMethodsReply()
+
+ for manifest in manifests:
+ for cm in manifest["convenience_methods"]:
+ item = response.convenience_methods.add()
+ item.filename = cm["filename"]
+ item.contents = open(cm["path"]).read()
+ return response
+
+ except Exception, e:
+ import traceback; traceback.print_exc()
+ raise e
+
+
diff --git a/xos/synchronizers/new_base/loadmodels.py b/xos/synchronizers/new_base/loadmodels.py
index b9cb1f9..dc8be4b 100644
--- a/xos/synchronizers/new_base/loadmodels.py
+++ b/xos/synchronizers/new_base/loadmodels.py
@@ -14,6 +14,10 @@
# limitations under the License.
import os
+from xosconfig import Config
+from multistructlog import create_logger
+
+log = create_logger(Config().get('logging'))
class ModelLoadClient(object):
def __init__(self, api):
@@ -36,11 +40,20 @@
attic_dir = os.path.join(dir, "attic")
if os.path.exists(attic_dir):
+ log.warn("Attics are deprecated, please use the legacy=True option in xProto")
for fn in os.listdir(attic_dir):
if fn.endswith(".py"):
item = request.attics.add()
item.filename = fn
item.contents = open(os.path.join(attic_dir, fn)).read()
+ api_convenience_dir = os.path.join(dir, "convenience")
+ if os.path.exists(api_convenience_dir):
+ for fn in os.listdir(api_convenience_dir):
+ if fn.endswith(".py") and not "test" in fn:
+ item = request.convenience_methods.add()
+ item.filename = fn
+ item.contents = open(os.path.join(api_convenience_dir, fn)).read()
+
result = self.api.dynamicload.LoadModels(request)
diff --git a/xos/synchronizers/new_base/modelaccessor.py b/xos/synchronizers/new_base/modelaccessor.py
index 6730879..2167ca5 100644
--- a/xos/synchronizers/new_base/modelaccessor.py
+++ b/xos/synchronizers/new_base/modelaccessor.py
@@ -30,7 +30,6 @@
import signal
import sys
import time
-from xosconfig import Config
from diag import update_diag
from loadmodels import ModelLoadClient
@@ -231,7 +230,6 @@
# Restore the sigint handler
signal.signal(signal.SIGINT, orig_sigint)
-
def config_accessor_grpcapi():
global orig_sigint
diff --git a/xos/xos_client/xosapi/convenience/addressmanagerservice.py b/xos/xos_client/xosapi/convenience/addressmanagerservice.py
deleted file mode 100644
index 6c59bec..0000000
--- a/xos/xos_client/xosapi/convenience/addressmanagerservice.py
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import json
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-from xosapi.convenience.service import ORMWrapperService
-
-class ORMWrapperAddressManagerService(ORMWrapperService):
- def get_gateways(self):
- gateways = []
-
- aps = self.addresspools.all()
- for ap in aps:
- gateways.append({"gateway_ip": ap.gateway_ip, "gateway_mac": ap.gateway_mac})
-
- return gateways
-
-register_convenience_wrapper("AddressManagerService", ORMWrapperAddressManagerService)
diff --git a/xos/xos_client/xosapi/convenience/addressmanagerserviceinstance.py b/xos/xos_client/xosapi/convenience/addressmanagerserviceinstance.py
deleted file mode 100644
index cfb7f69..0000000
--- a/xos/xos_client/xosapi/convenience/addressmanagerserviceinstance.py
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import json
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-
-class ORMWrapperAddressManagerServiceInstance(ORMWrapper):
- @property
- def gateway_ip(self):
- if not self.address_pool:
- return None
- return self.address_pool.gateway_ip
-
- @property
- def gateway_mac(self):
- if not self.address_pool:
- return None
- return self.address_pool.gateway_mac
-
- @property
- def cidr(self):
- if not self.address_pool:
- return None
- return self.address_pool.cidr
-
- @property
- def netbits(self):
- # return number of bits in the network portion of the cidr
- if self.cidr:
- parts = self.cidr.split("/")
- if len(parts) == 2:
- return int(parts[1].strip())
- return None
-
- # Use for tenant_for_instance_id
- # TODO: These should be reimplemented using real database models
-
- def get_attribute(self, name, default=None):
- if self.service_specific_attribute:
- attributes = json.loads(self.service_specific_attribute)
- else:
- attributes = {}
- return attributes.get(name, default)
-
- def set_attribute(self, name, value):
- if self.service_specific_attribute:
- attributes = json.loads(self.service_specific_attribute)
- else:
- attributes = {}
- attributes[name] = value
- self.service_specific_attribute = json.dumps(attributes)
-
-
-register_convenience_wrapper("AddressManagerServiceInstance", ORMWrapperAddressManagerServiceInstance)
diff --git a/xos/xos_client/xosapi/convenience/cordsubscriberroot.py b/xos/xos_client/xosapi/convenience/cordsubscriberroot.py
deleted file mode 100644
index 5af889c..0000000
--- a/xos/xos_client/xosapi/convenience/cordsubscriberroot.py
+++ /dev/null
@@ -1,55 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import json
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-
-class ORMWrapperCordSubscriberRoot(ORMWrapper):
- @property
- def volt(self):
- links = self.subscribed_links.all()
- for link in links:
- # TODO: hardcoded service dependency
- # cast from ServiceInstance to VOLTServiceInstance
- volts = self.stub.VOLTServiceInstance.objects.filter(id = link.provider_service_instance.id)
- if volts:
- return volts[0]
- return None
-
- sync_attributes = ("firewall_enable",
- "firewall_rules",
- "url_filter_enable",
- "url_filter_rules",
- "cdn_enable",
- "uplink_speed",
- "downlink_speed",
- "enable_uverse",
- "status")
-
- # figure out what to do about "devices"... is it still needed?
-
- def get_attribute(self, name, default=None):
- if self.service_specific_attribute:
- attributes = json.loads(self.service_specific_attribute)
- else:
- attributes = {}
- return attributes.get(name, default)
-
- @property
- def devices(self):
- return self.get_attribute("devices", [])
-
-register_convenience_wrapper("CordSubscriberRoot", ORMWrapperCordSubscriberRoot)
diff --git a/xos/xos_client/xosapi/convenience/voltserviceinstance.py b/xos/xos_client/xosapi/convenience/voltserviceinstance.py
deleted file mode 100644
index 158d1ce..0000000
--- a/xos/xos_client/xosapi/convenience/voltserviceinstance.py
+++ /dev/null
@@ -1,121 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-
-import logging as log
-
-class ORMWrapperVOLTServiceInstance(ORMWrapper):
-
- @property
- def vsg(self):
- log.warning('VOLTServiceInstance.vsg is DEPRECATED, use get_westbound_service_instance_properties instead')
- links = self.stub.ServiceInstanceLink.objects.filter(subscriber_service_instance_id = self.id)
- for link in links:
- # cast from ServiceInstance to VSGTenant
- vsgs = self.stub.VSGServiceInstance.objects.filter(id = link.provider_service_instance.id)
- if vsgs:
- return vsgs[0]
- return None
-
- # DEPRECATED
- @property
- def vcpe(self):
- log.warning('VOLTServiceInstance.vcpe is DEPRECATED, use VOLTServiceInstance.vsg instead')
- return self.vsg
-
- @property
- def subscriber(self):
- log.warning(
- 'VOLTServiceInstance.subscriber is DEPRECATED, use get_westbound_service_instance_properties instead')
- # NOTE this assume that each VOLT has just 1 subscriber, is that right?
- links = self.stub.ServiceInstanceLink.objects.filter(provider_service_instance_id = self.id)
- for link in links:
- subs = self.stub.CordSubscriberRoot.objects.filter(id=link.subscriber_service_instance_id)
- if subs:
- return subs[0]
- return None
-
- @property
- def c_tag(self):
- log.warning(
- 'VOLTServiceInstance.c_tag is DEPRECATED, use get_westbound_service_instance_properties instead')
- return self.subscriber.c_tag
-
- def get_olt_device_by_subscriber(self):
- si = self.stub.ServiceInstance.objects.get(id=self.id)
-
- olt_device_name = si.get_westbound_service_instance_properties("olt_device")
-
- olt_device = self.stub.OLTDevice.objects.get(name=olt_device_name)
- return olt_device
-
- def get_olt_port_by_subscriber(self):
- si = self.stub.ServiceInstance.objects.get(id=self.id)
-
- olt_port_name = si.get_westbound_service_instance_properties("olt_port")
-
- olt_device = self.get_olt_device_by_subscriber()
- olt_port = self.stub.PONPort.objects.get(name=olt_port_name, olt_device_id=olt_device.id)
- return olt_port
-
- @property
- def s_tag(self):
- try:
- olt_port = self.get_olt_port_by_subscriber()
-
- if olt_port:
- return olt_port.s_tag
- return None
- except Exception, e:
- log.warning('Error while reading s_tag: %s' % e.message)
- return None
-
- @property
- def switch_datapath_id(self):
- try:
- olt_device = self.get_olt_device_by_subscriber()
- if olt_device:
- return olt_device.switch_datapath_id
- return None
- except Exception, e:
- log.warning('Error while reading switch_datapath_id: %s' % e.message)
- return None
-
- @property
- def switch_port(self):
- try:
- olt_device = self.get_olt_device_by_subscriber()
- if olt_device:
- return olt_device.switch_port
- return None
- except Exception, e:
- log.warning('Error while reading switch_port: %s' % e.message)
- return None
-
- @property
- def outer_tpid(self):
- try:
- olt_device = self.get_olt_device_by_subscriber()
- if olt_device:
- return olt_device.outer_tpid
- return None
- except Exception, e:
- log.warning('Error while reading outer_tpid: %s' % e.message)
- return None
-
-
-register_convenience_wrapper("VOLTServiceInstance", ORMWrapperVOLTServiceInstance)
diff --git a/xos/xos_client/xosapi/convenience/vrouterapp.py b/xos/xos_client/xosapi/convenience/vrouterapp.py
deleted file mode 100644
index 3dafde2..0000000
--- a/xos/xos_client/xosapi/convenience/vrouterapp.py
+++ /dev/null
@@ -1,33 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import json
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-
-class ORMWrapperVRouterApp(ORMWrapper):
- @property
- def interfaces(self):
- app_interfaces = []
- devices = self.stub.VRouterDevice.objects.filter(vrouter_service_id=self.vrouter_service.id)
- for device in devices:
- ports = self.stub.VRouterPort.objects.filter(vrouter_device_id=device.id)
- for port in ports:
- interfaces = self.stub.VRouterInterface.objects.filter(vrouter_port_id=port.id)
- for iface in interfaces:
- app_interfaces.append(iface.name)
- return app_interfaces
-
-register_convenience_wrapper("VRouterApp", ORMWrapperVRouterApp)
diff --git a/xos/xos_client/xosapi/convenience/vrouterservice.py b/xos/xos_client/xosapi/convenience/vrouterservice.py
deleted file mode 100644
index 28f1421..0000000
--- a/xos/xos_client/xosapi/convenience/vrouterservice.py
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import json
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-from xosapi.convenience.service import ORMWrapperService
-
-class ORMWrapperVRouterService(ORMWrapperService):
- def get_gateways(self):
- gateways = []
-
- aps = self.addresspools.all()
- for ap in aps:
- gateways.append({"gateway_ip": ap.gateway_ip, "gateway_mac": ap.gateway_mac})
-
- return gateways
-
-register_convenience_wrapper("VRouterService", ORMWrapperVRouterService)
diff --git a/xos/xos_client/xosapi/convenience/vroutertenant.py b/xos/xos_client/xosapi/convenience/vroutertenant.py
deleted file mode 100644
index f9b76c2..0000000
--- a/xos/xos_client/xosapi/convenience/vroutertenant.py
+++ /dev/null
@@ -1,67 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import json
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-
-class ORMWrapperVRouterTenant(ORMWrapper):
- @property
- def gateway_ip(self):
- if not self.address_pool:
- return None
- return self.address_pool.gateway_ip
-
- @property
- def gateway_mac(self):
- if not self.address_pool:
- return None
- return self.address_pool.gateway_mac
-
- @property
- def cidr(self):
- if not self.address_pool:
- return None
- return self.address_pool.cidr
-
- @property
- def netbits(self):
- # return number of bits in the network portion of the cidr
- if self.cidr:
- parts = self.cidr.split("/")
- if len(parts) == 2:
- return int(parts[1].strip())
- return None
-
- # Use for tenant_for_instance_id
- # TODO: These should be reimplemented using real database models
-
- def get_attribute(self, name, default=None):
- if self.service_specific_attribute:
- attributes = json.loads(self.service_specific_attribute)
- else:
- attributes = {}
- return attributes.get(name, default)
-
- def set_attribute(self, name, value):
- if self.service_specific_attribute:
- attributes = json.loads(self.service_specific_attribute)
- else:
- attributes = {}
- attributes[name] = value
- self.service_specific_attribute = json.dumps(attributes)
-
-
-register_convenience_wrapper("VRouterTenant", ORMWrapperVRouterTenant)
diff --git a/xos/xos_client/xosapi/convenience/vsgserviceinstance.py b/xos/xos_client/xosapi/convenience/vsgserviceinstance.py
deleted file mode 100644
index 800ad53..0000000
--- a/xos/xos_client/xosapi/convenience/vsgserviceinstance.py
+++ /dev/null
@@ -1,108 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-
-class ORMWrapperVSGServiceInstance(ORMWrapper):
- sync_attributes = ("wan_container_ip", "wan_container_mac", "wan_container_netbits",
- "wan_container_gateway_ip", "wan_container_gateway_mac",
- "wan_vm_ip", "wan_vm_mac")
-
- @property
- def ingress_service_instance(self):
- links = self.provided_links.all()
- for link in links:
- subscriber_service_instance = link.subscriber_service_instance.leaf_model
- # Look for something that has an s_tag attribute
- if (hasattr(subscriber_service_instance, "s_tag")):
- return subscriber_service_instance
- return None
-
- @property
- def volt(self):
- return self.ingress_service_instance
-
- def is_address_manager_service_instance(self, si):
- # TODO: hardcoded dependency
- # TODO: VRouterTenant is deprecated
- return si.leaf_model_name in ["AddressManagerServiceInstance", "VRouterTenant"]
-
- # DEPRECATED
- @property
- def vrouter(self):
- return self.address_service_instance
-
- @property
- def address_service_instance(self):
- links = self.subscribed_links.all()
- for link in links:
- if not self.is_address_manager_service_instance(link.provider_service_instance):
- continue
- # cast from ServiceInstance to AddressManagerServiceInstance or similar
- return link.provider_service_instance.leaf_model
- return None
-
- def get_address_service_instance_field(self, name, default=None):
- if self.address_service_instance:
- return getattr(self.address_service_instance, name, default)
- else:
- return default
-
- @property
- def wan_container_ip(self):
- return self.get_address_service_instance_field("public_ip", None)
-
- @property
- def wan_container_mac(self):
- return self.get_address_service_instance_field("public_mac", None)
-
- @property
- def wan_container_netbits(self):
- return self.get_address_service_instance_field("netbits", None)
-
- @property
- def wan_container_gateway_ip(self):
- return self.get_address_service_instance_field("gateway_ip", None)
-
- @property
- def wan_container_gateway_mac(self):
- return self.get_address_service_instance_field("gateway_mac", None)
-
- @property
- def wan_vm_ip(self):
- tags = self.stub.Tag.objects.filter(name="vm_vrouter_tenant", object_id=self.instance.id, content_type=self.instance.self_content_type_id)
- if tags:
- service_instances = self.stub.ServiceInstance.objects.filter(id=int(tags[0].value))
- if not service_instances:
- raise Exception("ServiceInstance %d linked to vsg %s does not exist" % (int(tags[0].value), self))
- return service_instances[0].leaf_model.public_ip
- else:
- raise Exception("no vm_vrouter_tenant tag for instance %s" % self.instance)
-
- @property
- def wan_vm_mac(self):
- tags = self.stub.Tag.objects.filter(name="vm_vrouter_tenant", object_id=self.instance.id, content_type=self.instance.self_content_type_id)
- if tags:
- service_instances = self.stub.ServiceInstance.objects.filter(id=int(tags[0].value))
- if not service_instances:
- raise Exception("ServiceInstance %d linked to vsg %s does not exist" % (int(tags[0].value), self))
- return service_instances[0].leaf_model.public_mac
- else:
- raise Exception("no vm_vrouter_tenant tag for instance %s" % self.instance)
-
-
-register_convenience_wrapper("VSGTenant", ORMWrapperVSGServiceInstance) # DEPRECATED
-register_convenience_wrapper("VSGServiceInstance", ORMWrapperVSGServiceInstance)
diff --git a/xos/xos_client/xosapi/convenience/vtrtenant.py b/xos/xos_client/xosapi/convenience/vtrtenant.py
deleted file mode 100644
index ddc64ae..0000000
--- a/xos/xos_client/xosapi/convenience/vtrtenant.py
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from xosapi.orm import ORMWrapper, register_convenience_wrapper
-
-class ORMWrapperVTRTenant(ORMWrapper):
- def get_generic_foreignkeys(self):
- return [{"name": "target", "content_type": "target_type", "id": "target_id"}]
-
-register_convenience_wrapper("VTRTenant", ORMWrapperVTRTenant)
diff --git a/xos/xos_client/xosapi/orm.py b/xos/xos_client/xosapi/orm.py
index a50b7ee..7869184 100644
--- a/xos/xos_client/xosapi/orm.py
+++ b/xos/xos_client/xosapi/orm.py
@@ -38,6 +38,8 @@
import os
import sys
import time
+import imp
+import logging as log
convenience_wrappers = {}
@@ -618,25 +620,40 @@
return cls(wrapped_class, *args, **kwargs)
-import convenience.addresspool
-import convenience.privilege
-import convenience.instance
-import convenience.network
-import convenience.cordsubscriberroot
-import convenience.voltserviceinstance
-import convenience.vsgserviceinstance
-import convenience.serviceinstance
-import convenience.vrouterservice
-import convenience.vroutertenant
-import convenience.vrouterapp
-import convenience.service
-import convenience.onosapp
-import convenience.controller
-import convenience.user
-import convenience.slice
-import convenience.port
-import convenience.tag
-import convenience.vtrtenant
-import convenience.addressmanagerservice
-import convenience.addressmanagerserviceinstance
+def import_convenience_methods():
+
+ log.info("Loading convenience methods")
+
+ cwd = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
+ api_convenience_dir = os.path.join(cwd, "convenience")
+ for file in os.listdir(api_convenience_dir):
+ if file.endswith(".py") and not "test" in file:
+ pathname = os.path.join(api_convenience_dir, file)
+ try:
+ log.debug("Loading: %s" % file)
+ imp.load_source(file[:-3], pathname)
+ except Exception, e:
+ log.error("Cannot import api convenience method for: %s, %s", (file[:-3], pathname))
+
+
+# import convenience.addresspool
+# import convenience.privilege
+# import convenience.instance
+# import convenience.network
+# import convenience.cordsubscriberroot
+# import convenience.vsgserviceinstance
+# import convenience.serviceinstance
+# import convenience.vrouterservice
+# import convenience.vroutertenant
+# import convenience.vrouterapp
+# import convenience.service
+# import convenience.onosapp
+# import convenience.controller
+# import convenience.user
+# import convenience.slice
+# import convenience.port
+# import convenience.tag
+# import convenience.vtrtenant
+# import convenience.addressmanagerservice
+# import convenience.addressmanagerserviceinstance
diff --git a/xos/xos_client/xosapi/xos_grpc_client.py b/xos/xos_client/xosapi/xos_grpc_client.py
index 46fb829..62b9a4a 100644
--- a/xos/xos_client/xosapi/xos_grpc_client.py
+++ b/xos/xos_client/xosapi/xos_grpc_client.py
@@ -33,7 +33,7 @@
import chameleon.grpc_client.grpc_client as chameleon_client
from twisted.internet import reactor
-
+from google.protobuf.empty_pb2 import Empty
SERVER_CA="/usr/local/share/ca-certificates/local_certs.crt"
@@ -61,9 +61,30 @@
def set_reconnect_callback(self, reconnect_callback):
self.reconnect_callback2 = reconnect_callback
+
return self
+ def load_convenience_methods(self):
+
+ convenience_methods_dir = "/usr/local/lib/python2.7/dist-packages/xosapi/convenience/"
+
+ try:
+ cms = self.dynamicload.GetConvenienceMethods(Empty())
+ except grpc._channel._Rendezvous, e:
+ code = e.code()
+ if code == grpc.StatusCode.UNAVAILABLE:
+ # NOTE if the core is not available, restart the synchronizer
+ os.execv(sys.executable, ['python'] + sys.argv)
+ print "Loading convenience methods: %s" % [m.filename for m in cms.convenience_methods]
+
+ for cm in cms.convenience_methods:
+ print "Saving %s" % cm.filename
+ save_path = os.path.join(convenience_methods_dir, cm.filename)
+ file(save_path, "w").write(cm.contents)
+
+
def reconnected(self):
+
for api in ['modeldefs', 'utility', 'xos', 'dynamicload']:
pb2_file_name = os.path.join(self.work_dir, api + "_pb2.py")
pb2_grpc_file_name = os.path.join(self.work_dir, api + "_pb2_grpc.py")
@@ -89,6 +110,12 @@
if hasattr(self, "xos"):
self.xos_orm = orm.ORMStub(self.xos, self.xos_pb2, "xos")
+ # ask the core for the convenience methods
+ self.load_convenience_methods()
+
+ # Load convenience methods after reconnect
+ orm.import_convenience_methods()
+
if self.reconnect_callback2:
self.reconnect_callback2()
@@ -122,19 +149,16 @@
defs = {"grpc_insecure_endpoint": "xos-core.cord.lab:50055",
"grpc_secure_endpoint": "xos-core.cord.lab:50051",
- "consul": None}
+ "config": '/opt/xos/config.yml'}
- _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
+ _help = 'Path to the config file (default: %s)' % defs['config']
parser.add_argument(
- '-C', '--consul', dest='consul', action='store',
- default=defs['consul'],
+ '-C', '--config', dest='config', action='store',
+ default=defs['config'],
help=_help)
- _help = ('gRPC insecure end-point to connect to. It can either be a direct'
- 'definition in the form of <hostname>:<port>, or it can be an'
- 'indirect definition in the form of @<service-name> where'
- '<service-name> is the name of the grpc service as registered'
- 'in consul (example: @voltha-grpc). (default: %s'
+ _help = ('gRPC insecure end-point to connect to. It is a direct',
+ '. (default: %s'
% defs['grpc_insecure_endpoint'])
parser.add_argument('-G', '--grpc-insecure-endpoint',
dest='grpc_insecure_endpoint',
@@ -142,11 +166,8 @@
default=defs["grpc_insecure_endpoint"],
help=_help)
- _help = ('gRPC secure end-point to connect to. It can either be a direct'
- 'definition in the form of <hostname>:<port>, or it can be an'
- 'indirect definition in the form of @<service-name> where'
- '<service-name> is the name of the grpc service as registered'
- 'in consul (example: @voltha-grpc). (default: %s'
+ _help = ('gRPC secure end-point to connect to. It is a direct',
+ '. (default: %s'
% defs["grpc_secure_endpoint"])
parser.add_argument('-S', '--grpc-secure-endpoint',
dest='grpc_secure_endpoint',
@@ -190,18 +211,27 @@
return args
def setup_logging(args):
- import logging
- import structlog
+ import os
- verbosity_adjust = (args.verbose or 0) - (args.quiet or 0)
- logging.basicConfig()
- logger = logging.getLogger()
- logger.setLevel(logging.DEBUG - 10*verbosity_adjust)
+ if os.path.isfile(args.config):
+ from xosconfig import Config
+ from multistructlog import create_logger
+ Config.init(args.config, 'synchronizer-config-schema.yaml')
+ log = create_logger(Config().get('logging'))
+ else:
+ import logging
+ import structlog
- def logger_factory():
- return logger
+ verbosity_adjust = (args.verbose or 0) - (args.quiet or 0)
+ logging.basicConfig()
+ logger = logging.getLogger()
+ logger.setLevel(logging.DEBUG - 10 * verbosity_adjust)
- structlog.configure(logger_factory=logger_factory)
+ def logger_factory():
+ return logger
+
+ structlog.configure(logger_factory=logger_factory)
+
def coreclient_reconnect(client, reconnect_callback, *args, **kwargs):
global coreapi
diff --git a/xos/xos_client/xossh b/xos/xos_client/xossh
index 02bab8a..61bc651 100644
--- a/xos/xos_client/xossh
+++ b/xos/xos_client/xossh
@@ -19,21 +19,18 @@
def parse_args():
parser = argparse.ArgumentParser()
- defs = {"grpc_insecure_endpoint": "xos-core.cord.lab:50055",
- "grpc_secure_endpoint": "xos-core.cord.lab:50051",
- "consul": None}
+ defs = {"grpc_insecure_endpoint": "xos-core:50055",
+ "grpc_secure_endpoint": "xos-core:50051",
+ "config": '/opt/xos/config.yml'}
- _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
+ _help = 'Path to the config file (default: %s)' % defs['config']
parser.add_argument(
- '-C', '--consul', dest='consul', action='store',
- default=defs['consul'],
+ '-C', '--config', dest='config', action='store',
+ default=defs['config'],
help=_help)
- _help = ('gRPC insecure end-point to connect to. It can either be a direct'
- 'definition in the form of <hostname>:<port>, or it can be an'
- 'indirect definition in the form of @<service-name> where'
- '<service-name> is the name of the grpc service as registered'
- 'in consul (example: @voltha-grpc). (default: %s'
+ _help = ('gRPC insecure end-point to connect to. It is a direct',
+ '. (default: %s'
% defs['grpc_insecure_endpoint'])
parser.add_argument('-G', '--grpc-insecure-endpoint',
dest='grpc_insecure_endpoint',
@@ -41,11 +38,8 @@
default=defs["grpc_insecure_endpoint"],
help=_help)
- _help = ('gRPC secure end-point to connect to. It can either be a direct'
- 'definition in the form of <hostname>:<port>, or it can be an'
- 'indirect definition in the form of @<service-name> where'
- '<service-name> is the name of the grpc service as registered'
- 'in consul (example: @voltha-grpc). (default: %s'
+ _help = ('gRPC secure end-point to connect to. It is a direct',
+ '. (default: %s'
% defs["grpc_secure_endpoint"])
parser.add_argument('-S', '--grpc-secure-endpoint',
dest='grpc_secure_endpoint',