CORD-1253 Support AddressManager service

Change-Id: Ie9aab1ba1f48f87391d1cd786823b9218413bac7
diff --git a/xos/tosca/resources/network.py b/xos/tosca/resources/network.py
index 95923ea..6eba57d 100644
--- a/xos/tosca/resources/network.py
+++ b/xos/tosca/resources/network.py
@@ -83,15 +83,22 @@
                 # TODO: Break hardcoded dependencies
                 # TODO: Rethink relationship between networks and vrouter tenants
                 if provider_service.kind == "vROUTER":
+                    # DEPRECATED
                     from services.vrouter.models import VRouterService
                     si = VRouterService.objects.get(id=provider_service.id).get_tenant(address_pool_name="addresses_"+obj.name)
-                    si.save()
-                    link = ServiceInstanceLink(provider_service_instance=si, subscriber_network=obj)
-                    link.save()
-
-                    obj.subnet = si.cidr
+                elif provider_service.kind == "addressmanager":
+                    from services.addressmanager.models import AddressManagerService
+                    si = AddressManagerService.objects.get(id=provider_service.id).get_service_instance(address_pool_name="addresses_"+obj.name)
                 else:
-                    raise Exception("The only network tenancy relationships that are allowed are to vRouter services")
+                    # Hardcoded dependency, will be obsoleted by new Tosca engine
+                    raise Exception(
+                        "The only network tenancy relationships that are allowed are to vRouter and AddressManager services")
+
+                si.save()
+                link = ServiceInstanceLink(provider_service_instance=si, subscriber_network=obj)
+                link.save()
+
+                obj.subnet = si.cidr
 
                 self.info("Created Tenancy relationship from %s to %s" % (str(obj), str(provider_service)))
 
diff --git a/xos/xos_client/xosapi/convenience/addressmanagerservice.py b/xos/xos_client/xosapi/convenience/addressmanagerservice.py
new file mode 100644
index 0000000..6c59bec
--- /dev/null
+++ b/xos/xos_client/xosapi/convenience/addressmanagerservice.py
@@ -0,0 +1,31 @@
+
+# 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
new file mode 100644
index 0000000..cfb7f69
--- /dev/null
+++ b/xos/xos_client/xosapi/convenience/addressmanagerserviceinstance.py
@@ -0,0 +1,67 @@
+
+# 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/vsgtenant.py b/xos/xos_client/xosapi/convenience/vsgtenant.py
index ab3c477..2f91d14 100644
--- a/xos/xos_client/xosapi/convenience/vsgtenant.py
+++ b/xos/xos_client/xosapi/convenience/vsgtenant.py
@@ -30,51 +30,61 @@
             if volts:
                 return volts[0]
         return None
+    
+    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:
-            # cast from ServiceInstance to VRouterTenant
-            vrouters = self.stub.VRouterTenant.objects.filter(id = link.provider_service_instance.id)
-            if vrouters:
-                return vrouters[0]
+            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_vrouter_field(self, name, default=None):
-        if self.vrouter:
-            return getattr(self.vrouter, name, default)
+    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_vrouter_field("public_ip", None)
+        return self.get_address_service_instance_field("public_ip", None)
 
     @property
     def wan_container_mac(self):
-        return self.get_vrouter_field("public_mac", None)
+        return self.get_address_service_instance_field("public_mac", None)
 
     @property
     def wan_container_netbits(self):
-        return self.get_vrouter_field("netbits", None)
+        return self.get_address_service_instance_field("netbits", None)
 
     @property
     def wan_container_gateway_ip(self):
-        return self.get_vrouter_field("gateway_ip", None)
+        return self.get_address_service_instance_field("gateway_ip", None)
 
     @property
     def wan_container_gateway_mac(self):
-        return self.get_vrouter_field("gateway_mac", None)
+        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:
-            tenants = self.stub.VRouterTenant.objects.filter(id=int(tags[0].value))
-            if not tenants:
-                raise Exception("VRouterTenent %d linked to vsg %s does not exist" % (int(tags[0].value), self))
-            return tenants[0].public_ip
+            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)
 
@@ -82,10 +92,10 @@
     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:
-            tenants = self.stub.VRouterTenant.objects.filter(id=int(tags[0].value))
-            if not tenants:
-                raise Exception("VRouterTenent %d linked to vsg %s does not exist" % (int(tags[0].value), self))
-            return tenants[0].public_mac
+            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)
 
diff --git a/xos/xos_client/xosapi/orm.py b/xos/xos_client/xosapi/orm.py
index 119275c..0c28321 100644
--- a/xos/xos_client/xosapi/orm.py
+++ b/xos/xos_client/xosapi/orm.py
@@ -547,4 +547,6 @@
 import convenience.port
 import convenience.tag
 import convenience.vtrtenant
+import convenience.addressmanagerservice
+import convenience.addressmanagerserviceinstance