move tosca custom_types and hpcview from xos repo

Change-Id: Ia9ad16b43a3e966bcc2876deb9a9b2f881758789
diff --git a/xos/api/service/hpc/hpcview.py b/xos/api/service/hpc/hpcview.py
new file mode 100644
index 0000000..199bc09
--- /dev/null
+++ b/xos/api/service/hpc/hpcview.py
@@ -0,0 +1,219 @@
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
+from rest_framework.reverse import reverse
+from rest_framework import serializers
+from rest_framework import generics
+from rest_framework.views import APIView
+from core.models import *
+from services.hpc.models import *
+from services.requestrouter.models import *
+from django.forms import widgets
+from django.core.exceptions import PermissionDenied
+from django.contrib.contenttypes.models import ContentType
+import json
+import socket
+import time
+
+# This REST API endpoint contains a bunch of misc information that the
+# tenant view needs to display
+
+def get_service_slices(service):
+    try:
+        return service.slices.all()
+    except:
+        return service.service.all()
+
+def lookup_tag(service, instance, name, default=None):
+    instance_type = ContentType.objects.get_for_model(instance)
+    t = Tag.objects.filter(service=service, name=name, content_type__pk=instance_type.id, object_id=instance.id)
+    if t:
+        return t[0].value
+    else:
+        return default
+
+def lookup_time(service, instance, name):
+    v = lookup_tag(service, instance, name)
+    if v:
+        return str(time.time() - float(v))
+    else:
+        return None
+
+def json_default(d, default):
+    if not d:
+        return default
+    return json.loads(d)
+
+def compute_config_run(d):
+    if not d:
+        return "null"
+
+    try:
+        d = json.loads(d)
+    except:
+        return "error decoding json '%s'" % str(d)
+
+    status = d.get("status", "null")
+    if status!="success":
+        return status
+
+    config_run = d.get("config.run")
+    if not config_run:
+        return "null"
+
+    try:
+        config_run = max(0, int(time.time()) - int(float(config_run)))
+    except:
+        pass
+
+    return config_run
+
+# from hpc_watcher.py
+def get_public_ip(service, instance):
+    network_name = None
+    if "hpc" in instance.slice.name:
+        network_name = getattr(service, "watcher_hpc_network", None)
+    elif "demux" in instance.slice.name:
+        network_name = getattr(service, "watcher_dnsdemux_network", None)
+    elif "redir" in instance.slice.name:
+        network_name = getattr(service, "watcher_dnsredir_network", None)
+
+    if network_name and network_name.lower()=="nat":
+        return None
+
+    if (network_name is None) or (network_name=="") or (network_name.lower()=="public"):
+        return instance.get_public_ip()
+
+    for ns in instance.ports.all():
+        if (ns.ip) and (ns.network.name==network_name):
+            return ns.ip
+
+    raise ValueError("Couldn't find network %s" % str(network_name))
+
+def getHpcDict(user, pk):
+    hpc = HpcService.objects.get(pk=pk)
+    slices = get_service_slices(hpc)
+
+    dnsdemux_slice = None
+    dnsredir_slice = None
+    hpc_slice = None
+    for slice in slices:
+        if "dnsdemux" in slice.name:
+            dnsdemux_service = hpc
+            dnsdemux_slice = slice
+        if "dnsredir" in slice.name:
+            dnsredir_service = hpc
+            dnsredir_slice = slice
+        if "hpc" in slice.name:
+            hpc_service = hpc
+            hpc_slice = slice
+
+    if not dnsdemux_slice:
+        rr = RequestRouterService.objects.all()
+        if rr:
+            rr=rr[0]
+            slices = get_service_slices(rr)
+            for slice in slices:
+                if "dnsdemux" in slice.name:
+                    dnsdemux_service = rr
+                    dnsdemux_slice = slice
+                if "dnsredir" in slice.name:
+                    dnsredir_service = rr
+                    dnsredir_slice = slice
+
+    if not dnsredir_slice:
+        print "no dnsredir slice"
+        return
+
+    if not dnsdemux_slice:
+        print "no dnsdemux slice"
+        return
+
+    #dnsdemux_has_public_network = False
+    #for network in dnsdemux_slice.networks.all():
+    #    if (network.template) and (network.template.visibility=="public") and (network.template.translation=="none"):
+    #        dnsdemux_has_public_network = True
+
+    nameservers = {}
+    for nshc in hpc.hpchealthcheck_set.filter(kind="nameserver"):
+        nameserver = nshc.resource_name
+        try:
+            nameservers[nameserver] = {"name": nameserver, "ip": socket.gethostbyname(nameserver), "hit": False}
+        except:
+            nameservers[nameserver] = {"name": nameserver, "ip": "exception", "hit": False}
+
+    dnsdemux=[]
+    for instance in dnsdemux_slice.instances.all():
+        ip=None
+        try:
+            ip = get_public_ip(dnsdemux_service, instance)
+        except Exception, e:
+            ip = "Exception: " + str(e)
+        if not ip:
+            try:
+                ip = socket.gethostbyname(instance.node.name)
+            except:
+                ip = "??? " + instance.node.name
+
+        instance_nameservers = []
+        for ns in nameservers.values():
+            if ns["ip"]==ip:
+                instance_nameservers.append(ns["name"])
+                ns["hit"]=True
+
+        # now find the dnsredir instance that is also on this node
+        watcherd_dnsredir = "no-redir-instance"
+        for dnsredir_instance in dnsredir_slice.instances.all():
+            if dnsredir_instance.node == instance.node:
+                watcherd_dnsredir = lookup_tag(dnsredir_service, dnsredir_instance, "watcher.watcher.msg")
+
+        watcherd_dnsdemux = lookup_tag(dnsdemux_service, instance, "watcher.watcher.msg")
+
+        dnsdemux.append( {"name": instance.node.name,
+                       "watcher.DNS.msg": lookup_tag(dnsdemux_service, instance, "watcher.DNS.msg"),
+                       "watcher.DNS.time": lookup_time(dnsdemux_service, instance, "watcher.DNS.time"),
+                       "ip": ip,
+                       "nameservers": instance_nameservers,
+                       "dnsdemux_config_age": compute_config_run(watcherd_dnsdemux),
+                       "dnsredir_config_age": compute_config_run(watcherd_dnsredir) })
+
+    hpc=[]
+    for instance in hpc_slice.instances.all():
+        watcherd_hpc = lookup_tag(hpc_service, instance, "watcher.watcher.msg")
+
+        hpc.append( {"name": instance.node.name,
+                     "watcher.HPC-hb.msg": lookup_tag(hpc_service, instance, "watcher.HPC-hb.msg"),
+                     "watcher.HPC-hb.time": lookup_time(hpc_service, instance, "watcher.HPC-hb.time"),
+                     "watcher.HPC-fetch.msg": lookup_tag(hpc_service, instance, "watcher.HPC-fetch.msg"),
+                     "watcher.HPC-fetch.time": lookup_time(hpc_service, instance, "watcher.HPC-fetch.time"),
+                     "watcher.HPC-fetch.urls": json_default(lookup_tag(hpc_service, instance, "watcher.HPC-fetch-urls.msg"), []),
+                     "config_age": compute_config_run(watcherd_hpc),
+
+        })
+
+    return { "id": pk,
+             "dnsdemux": dnsdemux,
+             "hpc": hpc,
+             "nameservers": nameservers,}
+
+
+class HpcList(APIView):
+    method_kind = "list"
+    method_name = "hpcview"
+
+    def get(self, request, format=None):
+        if (not request.user.is_authenticated()):
+            raise PermissionDenied("You must be authenticated in order to use this API")
+        results = []
+        for hpc in HpcService.objects.all():
+            results.append(getHpcDict(request.user, hpc.pk))
+        return Response( results )
+
+class HpcDetail(APIView):
+    method_kind = "detail"
+    method_name = "hpcview"
+
+    def get(self, request, format=None, pk=0):
+        if (not request.user.is_authenticated()):
+            raise PermissionDenied("You must be authenticated in order to use this API")
+        return Response( [getHpcDict(request.user, pk)] )
+
diff --git a/xos/hpc-onboard.yaml b/xos/hpc-onboard.yaml
index 07a1745..30d6147 100644
--- a/xos/hpc-onboard.yaml
+++ b/xos/hpc-onboard.yaml
@@ -16,7 +16,7 @@
           admin_template: templates/hpcadmin.html  templates/hpctools.html
           synchronizer: synchronizer/manifest
           synchronizer_run: hpc-synchronizer.py
-          #tosca_custom_types: exampleservice.yaml
+          tosca_custom_types: tosca/resources/cdn.yaml
           #tosca_resource: tosca/resources/vcpeservice.py
           #rest_service: subdirectory:vsg api/service/vsg/vsgservice.py
           #rest_tenant: subdirectory:cord api/tenant/cord/vsg.py
diff --git a/xos/tosca/custom_types/cdn.m4 b/xos/tosca/custom_types/cdn.m4
new file mode 100644
index 0000000..0d33715
--- /dev/null
+++ b/xos/tosca/custom_types/cdn.m4
@@ -0,0 +1,83 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+# Note: Tosca derived_from isn't working the way I think it should, it's not
+#    inheriting from the parent template. Until we get that figured out, use
+#    m4 macros do our inheritance
+
+node_types:
+    tosca.nodes.ServiceProvider:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.ServiceProvider
+
+    tosca.nodes.ContentProvider:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.ContentProvider
+
+    tosca.nodes.OriginServer:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.OriginServer
+
+    tosca.nodes.CDNPrefix:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.CDNPrefix
+
+    tosca.nodes.HpcHealthCheck:
+        derived_from: tosca.nodes.Root
+
+        properties:
+            kind:
+                type: string
+                required: true
+                description: dns | http | nameserver
+            resource_name:
+                type: string
+                required: true
+                description: name of resource to query
+            result_contains:
+                type: string
+                required: false
+                description: soemthing to look for inside the result
+        capabilities:
+            healthcheck:
+                type: tosca.capabilities.xos.HpcHealthCheck
+
+    tosca.relationships.MemberOfServiceProvider:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.ServiceProvider ]
+
+    tosca.relationships.MemberOfContentProvider:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.ContentProvider ]
+
+    tosca.relationships.DefaultOriginServer:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.OriginServer ]
+
+    tosca.capabilities.xos.ServiceProvider:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.ContentProvider:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.CDNPrefix:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.OriginServer:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.HpcHealthCheck:
+        derived_from: tosca.capabilities.Root
+
+
diff --git a/xos/tosca/custom_types/cdn.yaml b/xos/tosca/custom_types/cdn.yaml
new file mode 100644
index 0000000..0d33715
--- /dev/null
+++ b/xos/tosca/custom_types/cdn.yaml
@@ -0,0 +1,83 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+# Note: Tosca derived_from isn't working the way I think it should, it's not
+#    inheriting from the parent template. Until we get that figured out, use
+#    m4 macros do our inheritance
+
+node_types:
+    tosca.nodes.ServiceProvider:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.ServiceProvider
+
+    tosca.nodes.ContentProvider:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.ContentProvider
+
+    tosca.nodes.OriginServer:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.OriginServer
+
+    tosca.nodes.CDNPrefix:
+        derived_from: tosca.nodes.Root
+
+        capabilities:
+            user:
+                type: tosca.capabilities.xos.CDNPrefix
+
+    tosca.nodes.HpcHealthCheck:
+        derived_from: tosca.nodes.Root
+
+        properties:
+            kind:
+                type: string
+                required: true
+                description: dns | http | nameserver
+            resource_name:
+                type: string
+                required: true
+                description: name of resource to query
+            result_contains:
+                type: string
+                required: false
+                description: soemthing to look for inside the result
+        capabilities:
+            healthcheck:
+                type: tosca.capabilities.xos.HpcHealthCheck
+
+    tosca.relationships.MemberOfServiceProvider:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.ServiceProvider ]
+
+    tosca.relationships.MemberOfContentProvider:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.ContentProvider ]
+
+    tosca.relationships.DefaultOriginServer:
+        derived_from: tosca.relationships.Root
+        valid_target_types: [ tosca.capabilities.xos.OriginServer ]
+
+    tosca.capabilities.xos.ServiceProvider:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.ContentProvider:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.CDNPrefix:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.OriginServer:
+        derived_from: tosca.capabilities.Root
+
+    tosca.capabilities.xos.HpcHealthCheck:
+        derived_from: tosca.capabilities.Root
+
+