support generic tenant in yaml
diff --git a/xos/tosca/custom_types/xos.m4 b/xos/tosca/custom_types/xos.m4
index 907d54c..9202ff4 100644
--- a/xos/tosca/custom_types/xos.m4
+++ b/xos/tosca/custom_types/xos.m4
@@ -93,6 +93,17 @@
         properties:
             xos_base_service_props
 
+    tosca.nodes.Tenant:
+        derived_from: tosca.nodes.Root
+        description: >
+            An ONOS Tenant.
+        properties:
+            xos_base_tenant_props
+            service_specific_attribute:
+                type: string
+                required: false
+                description: Service-specific attribute, usually a string containing a json structure
+
     tosca.nodes.ONOSService:
         derived_from: tosca.nodes.Root
         description: >
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
index 60968a5..83ec418 100644
--- a/xos/tosca/custom_types/xos.yaml
+++ b/xos/tosca/custom_types/xos.yaml
@@ -61,6 +61,24 @@
                 required: false
                 description: Version number of Service.
 
+    tosca.nodes.Tenant:
+        derived_from: tosca.nodes.Root
+        description: >
+            An ONOS Tenant.
+        properties:
+            kind:
+                type: string
+                default: generic
+                description: Kind of tenant
+            service_specific_id:
+                type: string
+                required: false
+                description: Service specific ID opaque to XOS but meaningful to service
+            service_specific_attribute:
+                type: string
+                required: false
+                description: Service-specific attribute, usually a string containing a json structure
+
     tosca.nodes.ONOSService:
         derived_from: tosca.nodes.Root
         description: >
diff --git a/xos/tosca/resources/tenant.py b/xos/tosca/resources/tenant.py
new file mode 100644
index 0000000..8821ae2
--- /dev/null
+++ b/xos/tosca/resources/tenant.py
@@ -0,0 +1,40 @@
+import os
+import pdb
+import sys
+import tempfile
+sys.path.append("/opt/tosca")
+from translator.toscalib.tosca_template import ToscaTemplate
+import pdb
+
+from ceilometer.models import Tenant, Service
+
+from xosresource import XOSResource
+
+class XOSTenant(XOSResource):
+    provides = "tosca.nodes.Tenant"
+    xos_model = Tenant
+    name_field = None
+    copyin_props = ("kind", "service_specific_attribute")
+
+    def get_xos_args(self, throw_exception=True):
+        args = super(XOSTenant, self).get_xos_args()
+
+        provider_name = self.get_requirement("tosca.relationships.MemberOfService", throw_exception=throw_exception)
+        if provider_name:
+            args["provider_service"] = self.get_xos_object(Service, throw_exception=throw_exception, name=provider_name)
+
+        return args
+
+    def get_existing_objs(self):
+        args = self.get_xos_args(throw_exception=False)
+        provider_service = args.get("provider", None)
+        if provider_service:
+            return [ self.get_xos_object(provider_service=provider_service) ]
+        return []
+
+    def postprocess(self, obj):
+        pass
+
+    def can_delete(self, obj):
+        return super(XOSTenant, self).can_delete(obj)
+
diff --git a/xos/tosca/samples/helloworld-chain.yaml b/xos/tosca/samples/helloworld-chain.yaml
index e4ccb11..9a00ddf 100644
--- a/xos/tosca/samples/helloworld-chain.yaml
+++ b/xos/tosca/samples/helloworld-chain.yaml
@@ -29,6 +29,17 @@
           kind: helloworldservice_complete
           view_url: /admin/helloworldservice_complete/helloworldservicecomplete/$id$/
 
+    tenant_helloworld:
+       type: tosca.nodes.Tenant
+       properties:
+           kind: helloworldservice_complete
+           service_specific_attribute: "{\"display_message\": \"Hello World from Tosca\"}"
+       requirements:
+           - provider_service:
+               node: service_helloworld
+               relationship: tosca.relationships.MemberOfService
+
+
     mysite_helloworld:
       type: tosca.nodes.Slice
       requirements: