Skip to content

Commit

Permalink
Feat: regenerate network maps on new scans
Browse files Browse the repository at this point in the history
Signed-off-by: deggja <danieldagfinrud@gmail.com>
  • Loading branch information
deggja committed Dec 2, 2023
1 parent fb144fd commit e7a6819
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 35 deletions.
88 changes: 56 additions & 32 deletions frontend/dash/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,34 +80,35 @@
<!-- Message for No Missing Policies -->
<h2 v-else class="no-policies-message">No network policies missing. You are good to go!</h2>
</div>

<!-- Loading visualization message -->
<div v-if="isLoadingVisualization" class="loading-message">
Loading visualization data...
</div>
{{ loadingMessage }}
</div>

<!-- Conditional rendering based on isShowClusterMap -->
<!-- Visualization components based on isShowClusterMap -->
<div v-if="isShowClusterMap">
<!-- Render loading message or network map for the entire cluster -->
<div v-if="isLoadingVisualization" class="loading-message">Loading visualization data...</div>
<div v-else>
<div v-for="(vizData, namespace) in namespaceVisualizationData" :key="namespace">
<network-policy-visualization
v-if="vizData.length > 0"
:policies="vizData">
</network-policy-visualization>
</div>
<div v-if="clusterVisualizationData && clusterVisualizationData.length > 0">
<network-policy-visualization
v-if="isShowClusterMap && clusterVisualizationData.length > 0"
:key="`cluster-map-${clusterMapGenerationCount}`"
:clusterData="clusterVisualizationData"
visualizationType="cluster">
</network-policy-visualization>
</div>
</div>

<!-- Visualization components -->
<div v-else>
<div v-for="(vizData, namespace) in namespaceVisualizationData" :key="namespace">
<network-policy-visualization
v-if="vizData.length > 0"
:policies="vizData">
</network-policy-visualization>
</div>
<!-- Visualization components for namespace -->
<div v-if="!isShowClusterMap">
<div v-for="(vizData, namespace) in namespaceVisualizationData" :key="namespace">
<network-policy-visualization
v-if="vizData && vizData.length > 0"
:policies="vizData"
visualizationType="namespace">
</network-policy-visualization>

</div>
</div>
</main>
</div>
</template>
Expand All @@ -131,13 +132,15 @@ export default {
menuVisible: false,
currentPage: 1,
pageSize: 10,
clusterMapGenerationCount: 0,
expandedNamespaces: {},
selectedNamespace: '',
allNamespaces: [],
lastScanType: 'cluster',
namespaceVisualizationData: {},
isLoadingVisualization: false,
isShowClusterMap: false,
isClusterMapLoading: false,
clusterVisualizationData: [],
};
},
Expand Down Expand Up @@ -204,6 +207,15 @@ export default {
}
return 0;
},
loadingMessage() {
if (this.isClusterMapLoading) {
return 'Loading cluster visualization data...';
}
if (this.isLoadingVisualization) {
return 'Loading visualization data...';
}
return '';
}
},
methods: {
toggleMenu() {
Expand Down Expand Up @@ -319,8 +331,13 @@ export default {
return;
}
this.isShowClusterMap = false;
this.namespaceVisualizationData = {};
this.clusterVisualizationData = [];
this.lastScanType = 'namespace';
this.scanInitiated = true;
this.isLoadingVisualization = true;
try {
const scanResponse = await axios.get(`http://localhost:8080/scan?namespace=${namespace}`);
this.scanResults = scanResponse.data;
Expand All @@ -329,7 +346,7 @@ export default {
this.netfetchScore = scanResponse.data.Score || null;
} else {
this.unprotectedPods = [];
this.netfetchScore = 42; // Default score for no missing policies
this.netfetchScore = 42;
}
this.updateExpandedNamespaces();
Expand All @@ -338,6 +355,8 @@ export default {
} catch (error) {
console.error('Error scanning namespace:', namespace, error);
this.message = { type: 'error', text: `Failed to scan namespace: ${namespace}. Error: ${error.message}` };
} finally {
this.isLoadingVisualization = false;
}
},
// Fetch and update visualization data for multiple namespaces
Expand All @@ -362,6 +381,22 @@ export default {
}
this.isLoadingVisualization = false;
},
async generateClusterNetworkMap() {
this.isShowClusterMap = true;
this.isLoadingVisualization = true;
this.namespaceVisualizationData = {};
this.clusterMapGenerationCount++;
try {
const response = await axios.get('http://localhost:8080/visualization/cluster');
this.clusterVisualizationData = response.data;
} catch (error) {
console.error('Error fetching cluster visualization data:', error);
} finally {
this.isLoadingVisualization = false;
}
},
// Viz
async fetchVisualizationData(namespace) {
if (!namespace) return;
Expand All @@ -376,17 +411,6 @@ export default {
console.error('Error fetching visualization data:', error);
}
},
async generateClusterNetworkMap() {
this.isShowClusterMap = true;
this.isLoadingVisualization = true;
try {
const response = await axios.get('http://localhost:8080/visualization/cluster');
this.clusterVisualizationData = response.data;
} catch (error) {
console.error('Error fetching cluster visualization data:', error);
}
this.isLoadingVisualization = false;
}
},
mounted() {
this.updateExpandedNamespaces();
Expand Down
32 changes: 29 additions & 3 deletions frontend/dash/src/Viz.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,48 @@
name: 'NetworkPolicyVisualization',
props: {
policies: Array,
clusterData: {
type: Array,
default: () => [],
},
visualizationType: {
type: String,
default: 'namespace' // Possible values: 'namespace', 'cluster'
},
},
mounted() {
this.createNetworkMap();
},
methods: {
createNetworkMap() {
console.log("Policies data:", this.policies)
let data;
if (this.visualizationType === 'cluster') {
// Flatten the policies array from the nested structure
data = this.clusterVisualizationData.reduce((acc, item) => {
if (item.policies && Array.isArray(item.policies)) {
return [...acc, ...item.policies];
}
return acc;
}, []);
} else {
data = this.policies;
}
console.log("Visualization data:", data);
const container = d3.select(this.$refs.vizContainer);
const width = 800;
const height = 600;
// Transform policies into nodes and links
const nodes = [];
const links = [];
this.policies.forEach(policy => {
// Iterate over flattened policies
data.forEach(policy => {
if (!policy.targetPods || !Array.isArray(policy.targetPods)) {
console.warn(`Skipping policy ${policy.name} as it has no targetPods or targetPods is not an array`);
return;
}
const policyNode = { id: policy.name, type: 'policy' };
nodes.push(policyNode);
Expand Down

0 comments on commit e7a6819

Please sign in to comment.