In [ ]:


In [1]:
import json

with open('./salt-grains.json') as json_data:
    grains_incoming = json.load(json_data)
    json_data.close()

grains_staged = {}
for key, value in grains_incoming.items():
    retval = {}
    retval['id'] = value['ret']['id']
    retval['kernel'] = value['ret']['kernel']
    retval['os'] = value['ret']['os']
    retval['os_family'] = value['ret']['os_family']
    retval['oscodename'] = value['ret']['oscodename']
    retval['osrelease'] = value['ret']['osrelease']
    retval['osfinger'] = value['ret']['osfinger']
    tmp = []
    for key2, value2 in value['ret']['ip4_interfaces'].items():
        if key2 not in ['lo']:
            tmp.append(value2[0])
    retval['ip4_interfaces'] = ", ".join(tmp)
    grains_staged[key] = retval

#grains_staged

In [2]:
import json

with open('./salt-keys.json') as json_data:
    keys_incoming = json.load(json_data)
    json_data.close()

keys_staged={}
for k, col in keys_incoming.items():
    #print(col)
    for m in map(str, col):
        keys_staged[m] = k

#keys_staged

In [3]:
from pprint import pprint

minions = {}
minionslist = []
for k, v in keys_staged.items():
    tmp = {}
    tmp['keystatus'] = v
    if k in grains_staged:
        tmp['grains'] = grains_staged[k]
    else:
        tmp['grains'] = {}
    tmp['minionid'] = k
    minions[k] = tmp
    minionslist.append(tmp)
pprint(minionslist)


[{'grains': {'id': 'saltminion02',
             'ip4_interfaces': '172.76.4.4',
             'kernel': 'Linux',
             'os': 'Debian',
             'os_family': 'Debian',
             'oscodename': 'jessie',
             'osfinger': 'Debian-8',
             'osrelease': '8.6'},
  'keystatus': 'minions',
  'minionid': 'saltminion02'},
 {'grains': {}, 'keystatus': 'minions_pre', 'minionid': 'T500-2017'},
 {'grains': {'id': 'saltminion01',
             'ip4_interfaces': '172.76.4.3',
             'kernel': 'Linux',
             'os': 'Ubuntu',
             'os_family': 'Debian',
             'oscodename': 'xenial',
             'osfinger': 'Ubuntu-16.04',
             'osrelease': '16.04'},
  'keystatus': 'minions',
  'minionid': 'saltminion01'},
 {'grains': {}, 'keystatus': 'minions_pre', 'minionid': 'W7-minion'},
 {'grains': {'id': 'minion-on-saltmaster',
             'ip4_interfaces': '172.76.4.2, 172.17.0.2',
             'kernel': 'Linux',
             'os': 'Ubuntu',
             'os_family': 'Debian',
             'oscodename': 'xenial',
             'osfinger': 'Ubuntu-16.04',
             'osrelease': '16.04'},
  'keystatus': 'minions',
  'minionid': 'minion-on-saltmaster'}]

In [6]:
from IPython.core.display import display, HTML
from string import Template
import json

js_text_template = Template('''

var data = $python_data;
//console.log(data)
var w = 640, h = 240;
var slice = (2 * Math.PI / data.length * .2 );

var svg = d3.select("#chart").insert("svg")
.attr("width", w).attr("height", h)
  .style("fill", "#fdf6e3");

var rectangle = svg.append("rect")
  .attr("x", 0)
  .attr("y", 0)
  .attr("width", w)
  .attr("height", h)
  .style("fill", "#fdf6e3");

var container = svg.append("g")
.attr("transform", "translate(" + 32 + "," + 8 + ")")
//.attr("transform", "translate(" + w/2 + "," + h/2 + ")")


var saltmaster = container.append("g").attr("id", "saltmaster");
var saltminions = container.append("g").attr("id", "saltminions");

saltmaster.append("circle").attr("r", 220)
  .attr("cx", 0)
  .attr("cy", 0)
  .style("fill", "#fdf6e3")
  .style("stroke-width", "3")
  .style("stroke", "#2aa198");

saltminions.selectAll("g.saltminion")
  .data(data)
  .enter()
  .append("g")
  .attr("class", "saltminion")
  .each(function(d, i) {
    d3.select(this).append("circle")
      .attr("r", 10)
      .attr("cx",(220 * Math.cos((slice*i)+0.1)))
      .attr("cy",(220 * Math.sin((slice*i)+0.1)))
      .style("fill", "#93a1a1")
      .style("stroke-width", "3")
      .style("stroke-dasharray", d.keystatus != "minions" ? "2, 1" : "10, ")
      .style("stroke", "#2aa198");
    d3.select(this).append("text")
      .attr("dx",(220 * Math.cos((slice*i)+0.1))+16)
      .attr("dy",(220 * Math.sin((slice*i)+0.1))+4)
      .style("fill", "#002b36")
      .style("font-weight", d.keystatus != "minions" ? "300" : "900")
      .text(d.minionid);
    d3.select(this).append("text")
      .attr("dx",(220 * Math.cos((slice*i)+0.1))+16)
      .attr("dy",(220 * Math.sin((slice*i)+0.1))+20)
      .style("fill", "#002b36")
      .text($$.grep([d.grains.kernel, d.grains.osfinger, d.grains.ip4_interfaces], Boolean).join('; '));
/*
    d3.select(this).selectAll("g.saltminion.legend")
      .data($$.grep([d.grains.kernel, d.grains.osfinger, d.grains.ip4_interfaces], Boolean).join('; '))
      .enter()
      .append("g")
      .attr("transform", "translate(" + (220 * Math.cos((slice*i)+0.1)) + "," + (220 * Math.sin((slice*i)+0.1)) + ")")
      .attr("class", "saltminionlegend")
      .each(function(d2, i2) {
        d3.select(this)
        .append("text").text(d2)
        .attr("dx", 120)
        .attr("dy", (i2*16)+12)
        .style("fill", "#002b36")
        .style("font-size", "12");
      })
      ;
*/
  });


svg.append("circle").attr("r", 120)
  .attr("cx", 24)
  .attr("cy", 24)
  .style("fill", "#eee8d5");
svg.append("circle").attr("r", 20)
  .attr("cx", 24)
  .attr("cy", 24)
  .style("fill", "#002b36")
  .style("stroke", "#073642");

svg.append("text")
  .attr("dx",48)
  .attr("dy",24)
  .style("fill", "#002b36")
  .style("font-weight", "900")
  .text('saltmaster');

''')

html_template = Template('''
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="chart"></div>
<script> $js_text </script>
''')

js_text = js_text_template.substitute({'python_data': json.dumps(minionslist),
                                       'alert': 'Test.'})

html = HTML(html_template.substitute({'js_text': js_text}))
html


Out[6]: