diff --git a/app.py b/app.py index d4ed844..d2976b3 100755 --- a/app.py +++ b/app.py @@ -11,6 +11,7 @@ import logging import os import requests import datetime +import time import tokens from flask import Flask, redirect @@ -99,6 +100,9 @@ def index(): for entry in os.listdir('static/build'): if entry.startswith('app'): app_js = entry + if app.debug: + # cache busting for local development + app_js += '?_={}'.format(time.time()) break return flask.render_template('index.html', app_js=app_js) @@ -133,7 +137,7 @@ def generate_mock_pod(index, i, j): status['containerStatuses'] = [{'ready': False, 'state': {'waiting': {'reason': 'CrashLoopBackOff'}}}] elif j % 7 == 0: status['containerStatuses'] = [{'ready': True, 'state': {'running': {}}, 'restartCount': 3}] - pod = {'name': '{}-{}'.format(names[hash_int((i + 1) * (j + 1)) % len(names)], j), 'namespace': 'kube-system' if j < 3 else 'default', 'labels': labels, 'status': status, 'containers': containers} + pod = {'name': '{}-{}-{}'.format(names[hash_int((i + 1) * (j + 1)) % len(names)], i, j), 'namespace': 'kube-system' if j < 3 else 'default', 'labels': labels, 'status': status, 'containers': containers} return pod @@ -146,9 +150,12 @@ def generate_mock_cluster_data(index: int): labels['master'] = 'true' pods = [] for j in range(hash_int((index + 1) * (i + 1)) % 32): - pods.append(generate_mock_pod(index, i, j)) + if j % 17 == 0 and int(time.time() / 10) % 2 == 0: + pass + else: + pods.append(generate_mock_pod(index, i, j)) nodes.append({'name': 'node-{}'.format(i), 'labels': labels, 'status': {'capacity': {'cpu': '4', 'memory': '32Gi', 'pods': '110'}}, 'pods': pods}) - unassigned_pods = [generate_mock_pod(index, 0, index)] + unassigned_pods = [generate_mock_pod(index, 11, index)] return { 'api_server_url': 'https://kube-{}.example.org'.format(index), 'nodes': nodes, diff --git a/app/src/app.js b/app/src/app.js index 12e10bc..148b917 100644 --- a/app/src/app.js +++ b/app/src/app.js @@ -13,7 +13,7 @@ export default class App { } else { this.filterString = '' } - this.seenPods = {} + this.seenPods = new Set() this.desaturationFilter = new PIXI.filters.ColorMatrixFilter() this.desaturationFilter.desaturate() } @@ -122,7 +122,7 @@ export default class App { } animatePodCreation(originalPod, globalX, globalY) { - const pod = new Pod(originalPod.pod, this.tooltip, null) + const pod = new Pod(originalPod.pod, null, this.tooltip) pod.draw() const targetPosition = new PIXI.Point(globalX, globalY) const angle = Math.random()*Math.PI*2 @@ -160,10 +160,19 @@ export default class App { this.stage.addChild(pod) } update(clusters) { + const podKeys = new Set() this.viewContainer.removeChildren() - var y = 0 - for (var cluster of clusters) { - var clusterBox = new Cluster(cluster, this.tooltip) + let y = 0 + for (const cluster of clusters) { + for (const node of cluster.nodes) { + for (const pod of node.pods) { + podKeys.add(cluster.api_server_url + '/' + pod.namespace + '/' + pod.name) + } + } + for (const pod of cluster.unassigned_pods) { + podKeys.add(cluster.api_server_url + '/' + pod.namespace + '/' + pod.name) + } + const clusterBox = new Cluster(cluster, this.tooltip) clusterBox.draw() clusterBox.x = 0 clusterBox.y = y @@ -174,11 +183,16 @@ export default class App { let i = 0 const that = this - const firstTime = Object.keys(this.seenPods).length == 0 + const firstTime = this.seenPods.size == 0 for (const key of Object.keys(ALL_PODS)) { - if (!this.seenPods[key]) { + if (!podKeys.has(key)) { + // pod was deleted + delete ALL_PODS[key] + this.seenPods.delete(key) + } else if (!this.seenPods.has(key)) { + // pod was created + this.seenPods.add(key) const pod = ALL_PODS[key] - this.seenPods[key] = pod const globalPos = pod.toGlobal({x: 0, y: 0}) if (!firstTime && i < 10) { window.setTimeout(function() { diff --git a/app/src/node.js b/app/src/node.js index 03572ac..cc88708 100644 --- a/app/src/node.js +++ b/app/src/node.js @@ -83,7 +83,7 @@ export default class Node extends PIXI.Graphics { var py = 20 for (const pod of this.node.pods) { if (pod.namespace != 'kube-system') { - const podBox = Pod.getOrCreate(pod, this.cluster, this.tooltip) //new Pod(pod, this.tooltip) + const podBox = Pod.getOrCreate(pod, this.cluster, this.tooltip) podBox.x = px podBox.y = py nodeBox.addChild(podBox.draw()) @@ -99,7 +99,7 @@ export default class Node extends PIXI.Graphics { py = 100 for (const pod of this.node.pods) { if (pod.namespace == 'kube-system') { - const podBox = Pod.getOrCreate(pod, this.cluster, this.tooltip) //new Pod(pod, this.tooltip) + const podBox = Pod.getOrCreate(pod, this.cluster, this.tooltip) podBox.x = px podBox.y = py nodeBox.addChild(podBox.draw()) diff --git a/app/src/pod.js b/app/src/pod.js index 4ab1386..e9f07bd 100644 --- a/app/src/pod.js +++ b/app/src/pod.js @@ -5,9 +5,10 @@ export const ALL_PODS = {} export class Pod extends PIXI.Graphics { - constructor(pod, tooltip, cluster) { + constructor(pod, cluster, tooltip) { super() this.pod = pod + this.cluster = cluster this.tooltip = tooltip this.tick = null this._progress = 1 @@ -58,7 +59,7 @@ export class Pod extends PIXI.Graphics { existingPod.clear() return existingPod } else { - return new Pod(pod, tooltip) + return new Pod(pod, cluster, tooltip) } }