Diagnostic WIP
diff --git a/views/ngXosViews/diagnostic/.eslintrc b/views/ngXosViews/diagnostic/.eslintrc
index c852748..c6e1175 100644
--- a/views/ngXosViews/diagnostic/.eslintrc
+++ b/views/ngXosViews/diagnostic/.eslintrc
@@ -16,6 +16,7 @@
     ],
     "rules": {
         "quotes": [2, "single"],
+        "no-undef": 2,
         "camelcase": [1, {"properties": "always"}],
         "no-underscore-dangle": 1,
         "eqeqeq": [2, "smart"],
diff --git a/views/ngXosViews/diagnostic/src/js/config.js b/views/ngXosViews/diagnostic/src/js/config.js
index 7308995..99112b1 100644
--- a/views/ngXosViews/diagnostic/src/js/config.js
+++ b/views/ngXosViews/diagnostic/src/js/config.js
@@ -18,10 +18,22 @@
       y: -10
     },
     rack: {
-      width: 50,
+      width: 60,
       height: 50,
-      x: -25,
+      x: -30,
       y: -25
+    },
+    computeNode: {
+      width: 50,
+      height: 20,
+      x: -25,
+      y: -10
+    },
+    instance: {
+      width: 40,
+      height: 16,
+      x: -20,
+      y: -8
     }
   })
 
diff --git a/views/ngXosViews/diagnostic/src/js/nodeDrawer.js b/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
index 82349ea..67156d5 100644
--- a/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
+++ b/views/ngXosViews/diagnostic/src/js/nodeDrawer.js
@@ -5,8 +5,11 @@
     cloud: ' M 79.72 49.60 C 86.00 37.29 98.57 29.01 111.96 26.42 C 124.27 24.11 137.53 26.15 148.18 32.90 C 158.08 38.78 165.39 48.87 167.65 60.20 C 176.20 57.90 185.14 56.01 194.00 57.73 C 206.08 59.59 217.92 66.01 224.37 76.66 C 227.51 81.54 228.85 87.33 229.23 93.06 C 237.59 93.33 246.22 95.10 253.04 100.19 C 256.69 103.13 259.87 107.67 258.91 112.59 C 257.95 118.43 252.78 122.38 247.78 124.82 C 235.27 130.43 220.23 130.09 207.98 123.93 C 199.33 127.88 189.76 129.43 180.30 128.57 C 173.70 139.92 161.70 147.65 148.86 149.93 C 133.10 153.26 116.06 148.15 104.42 137.08 C 92.98 143.04 78.96 143.87 66.97 139.04 C 57.75 135.41 49.70 128.00 46.60 118.43 C 43.87 109.95 45.81 100.29 51.30 93.32 C 57.38 85.18 67.10 80.44 76.99 78.89 C 74.38 69.20 74.87 58.52 79.72 49.60 Z'
   }
 
+  var computeNodeId = 0;
+  var instanceId = 0;
+
   angular.module('xos.serviceTopology')
-  .service('NodeDrawer', function(serviceTopologyConfig){
+  .service('NodeDrawer', function(d3, serviceTopologyConfig, Node){
     this.addNetworks = (nodes) => {
       nodes.append('path')
       .attr({
@@ -23,6 +26,15 @@
     }
 
     this.addRack = (nodes) => {
+
+      // NOTE is good to request data here? Probably not.
+
+      Node.queryWithInstances().$promise
+      .then((computeNodes) => {
+        this.drawComputeNodes(nodes, computeNodes);
+      });
+
+      // NOTE should we draw the rack?
       nodes.append('rect')
       .attr(serviceTopologyConfig.rack);
 
@@ -31,8 +43,51 @@
         'text-anchor': 'middle',
         y: serviceTopologyConfig.rack.y - 10
       })
-      .text(d => d.name)
-    }
+      .text(d => d.name);
+    };
+
+    this.drawComputeNodes = (container, nodes) => {
+      console.log('drawComputeNodes');
+      let elements = container.selectAll('.compute-nodes')
+      .data(nodes, d => {
+        if(!angular.isString(d.d3Id)){
+          d.d3Id = `compute-node-${++computeNodeId}`;
+        }
+        return d.d3Id;
+      });
+
+      var nodeContainer = elements.enter().append('g')
+      .attr({
+        class: 'compute-node'
+      });
+
+      nodeContainer.append('rect')
+      .attr(serviceTopologyConfig.computeNode);
+
+      // if there are Compute Nodes
+      if(nodeContainer.length > 0){
+        angular.forEach(nodeContainer.data(), (computeNode) => {
+          this.drawInstances(nodeContainer, computeNode.instances);
+        });
+      }
+
+    };
+
+    this.drawInstances = (container, instances) => {
+      
+      // TODO position instances... How??
+
+      let elements = container.selectAll('.instances')
+      .data(instances, d => angular.isString(d.d3Id) ? d.d3Id : d.d3Id = `instance-${++instanceId}`)
+
+      var instanceContainer = elements.enter().append('g')
+      .attr({
+        class: 'instance'
+      });
+
+      instanceContainer.append('rect')
+      .attr(serviceTopologyConfig.instance);
+    };
 
     this.addPhisical = (nodes) => {
       nodes.append('rect')
diff --git a/views/ngXosViews/diagnostic/src/js/rest_services.js b/views/ngXosViews/diagnostic/src/js/rest_services.js
index 2673bfc..87db711 100644
--- a/views/ngXosViews/diagnostic/src/js/rest_services.js
+++ b/views/ngXosViews/diagnostic/src/js/rest_services.js
@@ -12,7 +12,42 @@
     return $resource('/xos/slices', {id: '@id'});
   })
   .service('Instances', function($resource){
-    return $resource('/xos/instances', {id: '@id'});
+    return $resource('/xos/instances', {id: '@id'}, {});
+  })
+  .service('Node', function($resource, $q, Instances){
+    return $resource('/xos/nodes', {id: '@id'}, {
+      queryWithInstances: {
+        method: 'GET',
+        isArray: true,
+        interceptor: {
+          response: function(res){
+
+            // TODO update the API to include instances in nodes
+            // http://stackoverflow.com/questions/14573102/how-do-i-include-related-model-fields-using-django-rest-framework
+
+            const deferred = $q.defer();
+
+            let requests = [];
+
+            angular.forEach(res.data, (node) => {
+              requests.push(Instances.query({node: node.id}).$promise);
+            })
+
+            $q.all(requests)
+            .then((list) => {
+              res.data.map((node, i) => {
+                node.instances = list[i];
+                return node;
+              });
+
+              deferred.resolve(res.data);
+            })
+
+            return deferred.promise;
+          }
+        }
+      }
+    });
   })
   .service('Subscribers', function($resource, $q, SubscriberDevice){
     return $resource('/xos/subscribers', {id: '@id'}, {