Skip to content

Commit

Permalink
Add Diagram to display workload links
Browse files Browse the repository at this point in the history
  • Loading branch information
weibaohui committed May 7, 2024
1 parent 0f9279a commit ae10034
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 55 deletions.
33 changes: 33 additions & 0 deletions BlazorApp/Diagrams/KubeNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Blazor.Diagrams;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models;
using k8s;
using k8s.Models;

namespace BlazorApp.Diagrams;

public class KubeNode<T> : NodeModel where T : IKubernetesObject<V1ObjectMeta>
{
public KubeNode(BlazorDiagram diagram, T item, Point position = null) : base(position)
{
Item = item;
Name = Item.Name();
Title = Name;
Diagram = diagram;

AddPort(PortAlignment.Left);
AddPort(PortAlignment.Right);
AddNode(item);
}

public T Item { get; set; }
public string Name { get; set; }
private BlazorDiagram Diagram { get; set; }

private void AddNode(T item)
{
var key = $"{item.Namespace()}/{item.Name()}";
KubeNodeContainer.Instance.AddNode(key, this);
Diagram.Nodes.Add(this);
}
}
45 changes: 45 additions & 0 deletions BlazorApp/Diagrams/KubeNodeContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Collections.Generic;
using Blazor.Diagrams.Core.Models;
using BlazorApp.Utils;
using Microsoft.Extensions.Logging;

namespace BlazorApp.Diagrams;

public class KubeNodeContainer
{
private static readonly ILogger<KubeNodeContainer> Logger = LoggingHelper<KubeNodeContainer>.Logger();
private static readonly IDictionary<string, NodeModel> Map = new Dictionary<string, NodeModel>();

public static KubeNodeContainer Instance => KubeNodeContainer.Nested.Instance;

public void Clear()
{
Map.Clear();
}

public IDictionary<string, NodeModel> AddNode(string key, NodeModel node)
{
if (!Map.ContainsKey(key))
{
Map.Add(key, node);
}

return Map;
}

public NodeModel Get(string key)
{
return Map.TryGetValue(key, out var nodeModel) ? nodeModel : null;
}

private class Nested
{
internal static readonly KubeNodeContainer Instance = new KubeNodeContainer();

// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
}
}
22 changes: 22 additions & 0 deletions BlazorApp/Diagrams/KubeNodeWidget.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@typeparam T
@using k8s.Models
@inherits BlazorApp.Pages.Common.PageBase

<div class="default-node container">


@foreach (var port in Node.Ports.Where(x => x.Alignment == PortAlignment.Left))
{
<PortRenderer @key="port" Port="port" Class="default"/>
}


@foreach (var port in Node.Ports.Where(x => x.Alignment == PortAlignment.Right))
{
<PortRenderer @key="port" Port="port" Class="default"/>
}

<div>
@Node.Item.Name()
</div>
</div>
11 changes: 11 additions & 0 deletions BlazorApp/Diagrams/KubeNodeWidget.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using BlazorApp.Pages.Common;
using k8s;
using k8s.Models;
using Microsoft.AspNetCore.Components;

namespace BlazorApp.Diagrams;

public partial class KubeNodeWidget<T> : PageBase where T : IKubernetesObject<V1ObjectMeta>
{
[Parameter] public KubeNode<T> Node { get; set; }
}
101 changes: 48 additions & 53 deletions BlazorApp/Diagrams/MyDiagram.razor.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
using System.Threading.Tasks;
using Blazor.Diagrams;
using Blazor.Diagrams.Core.Anchors;
using Blazor.Diagrams.Core.Geometry;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.PathGenerators;
using Blazor.Diagrams.Core.Routers;
using Blazor.Diagrams.Options;
using BlazorApp.Service.k8s;
using k8s.Models;
using Microsoft.AspNetCore.Components;

namespace BlazorApp.Diagrams;

public partial class MyDiagram : ComponentBase
{
[Inject] private IDeploymentService DeploymentService { get; set; }
[Inject] private IReplicaSetService ReplicaSetService { get; set; }
[Inject] private IPodService PodService { get; set; }

private BlazorDiagram Diagram { get; set; }

protected override async Task OnInitializedAsync()
Expand All @@ -25,70 +30,60 @@ protected override async Task OnInitializedAsync()
};

Diagram = new BlazorDiagram(options);
var firstNode = Diagram.Nodes.Add(new NodeModel(new Point(50, 50))
{
Title = "Node x"
});
var secondNode = Diagram.Nodes.Add(new NodeModel(new Point(200, 100))
{
Title = "Node y"
});
var firstNodeRightPort = firstNode.AddPort(PortAlignment.Right);

var secondNodeLeftPort = secondNode.AddPort(PortAlignment.Left);
var secondNodeRightPort = secondNode.AddPort(PortAlignment.Right);
var sourceAnchor1 = new SinglePortAnchor(firstNodeRightPort);
var targetAnchor1 = new SinglePortAnchor(secondNodeLeftPort);
var link = Diagram.Links.Add(new LinkModel(sourceAnchor1, targetAnchor1));

Diagram.RegisterComponent<AddTwoNumbersNode, AddTwoNumbersWidget>();
var node = Diagram.Nodes.Add(new AddTwoNumbersNode(new Point(400, 150)));
node.AddPort(PortAlignment.Left);
node.AddPort(PortAlignment.Right);
Diagram.RegisterComponent<KubeNode<V1Deployment>, KubeNodeWidget<V1Deployment>>();
KubeNodeContainer.Instance.Clear();
var list = DeploymentService.List();
var x = 50;
var offset = 30;
var column2XBase = 250;
var column3XBase = 450;
var y = 0;

Diagram.Links.Add(new LinkModel(secondNode.GetPort(PortAlignment.Right), node.GetPort(PortAlignment.Left))
foreach (var deploy in list)
{
SourceMarker = LinkMarker.Arrow,
TargetMarker = LinkMarker.Arrow,
PathGenerator = new SmoothPathGenerator()
});
y += offset;
_ = new KubeNode<V1Deployment>(Diagram, deploy, new Point(x, y));
var key = $"{deploy.Namespace()}/{deploy.Name()}";
var deployNode = KubeNodeContainer.Instance.Get(key);

var replicaSets = ReplicaSetService.ListByOwnerUid(deploy.Metadata.Uid);

foreach (var rs in replicaSets)
{
_ = new KubeNode<V1ReplicaSet>(Diagram, rs, new Point(column2XBase, y));
var rkey = $"{rs.Namespace()}/{rs.Name()}";
var rsNode = KubeNodeContainer.Instance.Get(rkey);
LinkNodes(deployNode, rsNode);

var pods = PodService.ListByOwnerUid(rs.Metadata.Uid);
foreach (var pod in pods)
{
_ = new KubeNode<V1Pod>(Diagram, pod, new Point(column3XBase, y));
var pkey = $"{pod.Namespace()}/{pod.Name()}";
var podNode = KubeNodeContainer.Instance.Get(pkey);
LinkNodes(rsNode, podNode);
y += offset * 2;
}

y += offset * 2;
}
}

var node1 = NewNode(50, 50, "node1");
var node2 = NewNode(300, 300, "node2");
var node3 = NewNode(300, 50, "node3");
Diagram.Nodes.Add(new[] { node1, node2, node3 });

Diagram.Links.Add(new LinkModel(node1.GetPort(PortAlignment.Right), node2.GetPort(PortAlignment.Left))
{
SourceMarker = LinkMarker.Arrow,
TargetMarker = LinkMarker.Arrow,
PathGenerator = new SmoothPathGenerator()
});
Diagram.Links.Add(new LinkModel(node2.GetPort(PortAlignment.Right), node3.GetPort(PortAlignment.Right))
{
Router = new OrthogonalRouter(),
PathGenerator = new StraightPathGenerator(),
SourceMarker = LinkMarker.Arrow,
TargetMarker = LinkMarker.Arrow
});
await base.OnInitializedAsync();
}

protected override void OnInitialized()
{
}

private NodeModel NewNode(double x, double y, string title)
private void LinkNodes(NodeModel source, NodeModel target)
{
var node = new NodeModel(new Point(x, y))
Diagram.Links.Add(new LinkModel(source.GetPort(PortAlignment.Right), target.GetPort(PortAlignment.Left))
{
Title = title
};
node.AddPort();
node.AddPort(PortAlignment.Top);
node.AddPort(PortAlignment.Left);
node.AddPort(PortAlignment.Right);
return node;
Router = new OrthogonalRouter(),
PathGenerator = new StraightPathGenerator(),
// SourceMarker = LinkMarker.Square,
TargetMarker = LinkMarker.Arrow
});
}
}
4 changes: 2 additions & 2 deletions BlazorApp/Service/k8s/IDeploymentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ namespace BlazorApp.Service.k8s
{
public interface IDeploymentService : ICommonAction<V1Deployment>
{
Task UpdateReplicas(V1Deployment item, int? replicas);
Task Restart(V1Deployment item);
Task UpdateReplicas(V1Deployment item, int? replicas);
Task Restart(V1Deployment item);
Task<List<Result>> Analyze();
}
}

0 comments on commit ae10034

Please sign in to comment.