From a5fddc45cc8ddfc510f0b78f3db2d68f4691c0dc Mon Sep 17 00:00:00 2001 From: Eduardo Alonso Garcia Date: Sun, 15 Jun 2025 16:16:40 +0200 Subject: [PATCH 1/2] fix: add command to create cloud provider kind --- .../CreateCloudProviderKindCommand.cs | 24 +++++++++++ cli/src/Vdk/Commands/CreateClusterCommand.cs | 4 +- cli/src/Vdk/Commands/CreateCommand.cs | 3 +- cli/src/Vdk/Commands/CreateRegistryCommand.cs | 2 +- .../RemoveCloudProviderKindCommand.cs | 24 +++++++++++ cli/src/Vdk/Commands/RemoveCommand.cs | 3 +- cli/src/Vdk/Commands/RemoveRegistryCommand.cs | 2 +- cli/src/Vdk/Constants/Containers.cs | 2 + cli/src/Vdk/Properties/launchSettings.json | 2 +- cli/src/Vdk/ServiceProviderBuilder.cs | 2 + cli/src/Vdk/Services/DockerHubClient.cs | 41 ++++++++++++++++--- cli/src/Vdk/Services/IDockerEngine.cs | 2 +- cli/src/Vdk/Services/IHubClient.cs | 12 ++++-- cli/src/Vdk/Services/LocalDockerClient.cs | 33 ++++++++++++++- docs/usage/command-reference.md | 7 ++++ 15 files changed, 145 insertions(+), 18 deletions(-) create mode 100644 cli/src/Vdk/Commands/CreateCloudProviderKindCommand.cs create mode 100644 cli/src/Vdk/Commands/RemoveCloudProviderKindCommand.cs diff --git a/cli/src/Vdk/Commands/CreateCloudProviderKindCommand.cs b/cli/src/Vdk/Commands/CreateCloudProviderKindCommand.cs new file mode 100644 index 0000000..fe4e743 --- /dev/null +++ b/cli/src/Vdk/Commands/CreateCloudProviderKindCommand.cs @@ -0,0 +1,24 @@ +using System.CommandLine; +using Vdk.Services; +using IConsole = Vdk.Services.IConsole; + +namespace Vdk.Commands; + +public class CreateCloudProviderKindCommand: Command +{ + private readonly IConsole _console; + private readonly IHubClient _client; + + public CreateCloudProviderKindCommand(IConsole console, IHubClient client): base("cloud-provider-kind", "Create Vega VDK Cloud Provider kind container registry") + { + _console = console; + _client = client; + this.SetHandler(InvokeAsync); + } + + public Task InvokeAsync() + { + _client.CreateCloudProviderKind(); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/cli/src/Vdk/Commands/CreateClusterCommand.cs b/cli/src/Vdk/Commands/CreateClusterCommand.cs index 5d0b860..52f8b36 100644 --- a/cli/src/Vdk/Commands/CreateClusterCommand.cs +++ b/cli/src/Vdk/Commands/CreateClusterCommand.cs @@ -61,8 +61,8 @@ public async Task InvokeAsync(string name = Defaults.ClusterName, int controlPla // check if the hub and proxy are there if (!_reverseProxy.Exists()) _reverseProxy.Create(); - if (!_hub.Exists()) - _hub.Create(); + if (!_hub.ExistRegistry()) + _hub.CreateRegistry(); var map = await _kindVersionInfo.GetVersionInfoAsync(); string? kindVersion = null; diff --git a/cli/src/Vdk/Commands/CreateCommand.cs b/cli/src/Vdk/Commands/CreateCommand.cs index 2445aea..c1ac013 100644 --- a/cli/src/Vdk/Commands/CreateCommand.cs +++ b/cli/src/Vdk/Commands/CreateCommand.cs @@ -4,11 +4,12 @@ namespace Vdk.Commands; public class CreateCommand: Command { - public CreateCommand(CreateClusterCommand createCluster, CreateRegistryCommand createRegistry, CreateProxyCommand createProxy) + public CreateCommand(CreateClusterCommand createCluster, CreateRegistryCommand createRegistry, CreateProxyCommand createProxy, CreateCloudProviderKindCommand createCloudProviderKindCommand) : base("create", "Create vega development resources") { AddCommand(createCluster); AddCommand(createRegistry); AddCommand(createProxy); + AddCommand(createCloudProviderKindCommand); } } \ No newline at end of file diff --git a/cli/src/Vdk/Commands/CreateRegistryCommand.cs b/cli/src/Vdk/Commands/CreateRegistryCommand.cs index 7bafd9d..b6483b0 100644 --- a/cli/src/Vdk/Commands/CreateRegistryCommand.cs +++ b/cli/src/Vdk/Commands/CreateRegistryCommand.cs @@ -18,7 +18,7 @@ public CreateRegistryCommand(IConsole console, IHubClient client): base("registr public Task InvokeAsync() { - _client.Create(); + _client.CreateRegistry(); return Task.CompletedTask; } } \ No newline at end of file diff --git a/cli/src/Vdk/Commands/RemoveCloudProviderKindCommand.cs b/cli/src/Vdk/Commands/RemoveCloudProviderKindCommand.cs new file mode 100644 index 0000000..298a97e --- /dev/null +++ b/cli/src/Vdk/Commands/RemoveCloudProviderKindCommand.cs @@ -0,0 +1,24 @@ +using System.CommandLine; +using Vdk.Services; +using IConsole = Vdk.Services.IConsole; + +namespace Vdk.Commands; + +public class RemoveCloudProviderKindCommand: Command +{ + private readonly IConsole _console; + private readonly IHubClient _client; + + public RemoveCloudProviderKindCommand(IConsole console, IHubClient client) : base("cloud-provider-kind", "Remove Vega VDK Cloud Provider Kind") + { + _console = console; + _client = client; + this.SetHandler(InvokeAsync); + } + + public Task InvokeAsync() + { + _client.DestroyCloudProviderKind(); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/cli/src/Vdk/Commands/RemoveCommand.cs b/cli/src/Vdk/Commands/RemoveCommand.cs index d41396f..194d130 100644 --- a/cli/src/Vdk/Commands/RemoveCommand.cs +++ b/cli/src/Vdk/Commands/RemoveCommand.cs @@ -4,11 +4,12 @@ namespace Vdk.Commands; public class RemoveCommand: Command { - public RemoveCommand(RemoveClusterCommand removeCluster, RemoveRegistryCommand removeRegistry, RemoveProxyCommand removeProxy) + public RemoveCommand(RemoveClusterCommand removeCluster, RemoveRegistryCommand removeRegistry, RemoveProxyCommand removeProxy, RemoveCloudProviderKindCommand removeCloudProviderKindCommand) : base("remove", "Remove Vega development resources") { AddCommand(removeCluster); AddCommand(removeRegistry); AddCommand(removeProxy); + AddCommand(removeCloudProviderKindCommand); } } \ No newline at end of file diff --git a/cli/src/Vdk/Commands/RemoveRegistryCommand.cs b/cli/src/Vdk/Commands/RemoveRegistryCommand.cs index 3f98ecd..65dee3e 100644 --- a/cli/src/Vdk/Commands/RemoveRegistryCommand.cs +++ b/cli/src/Vdk/Commands/RemoveRegistryCommand.cs @@ -18,7 +18,7 @@ public RemoveRegistryCommand(IConsole console, IHubClient client) : base("regist public Task InvokeAsync() { - _client.Destroy(); + _client.DestroyRegistry(); return Task.CompletedTask; } } \ No newline at end of file diff --git a/cli/src/Vdk/Constants/Containers.cs b/cli/src/Vdk/Constants/Containers.cs index 56fa32a..e71a420 100644 --- a/cli/src/Vdk/Constants/Containers.cs +++ b/cli/src/Vdk/Constants/Containers.cs @@ -8,4 +8,6 @@ public static class Containers public const int RegistryHostPort = 5000; public const string ProxyName = "vega-proxy"; public const string ProxyImage = "nginx:latest"; + public const string CloudProviderKindName = "cloud-provider-kind"; + public const string CloudProviderKindImage = "registry.k8s.io/cloud-provider-kind/cloud-controller-manager:v0.6.0"; } \ No newline at end of file diff --git a/cli/src/Vdk/Properties/launchSettings.json b/cli/src/Vdk/Properties/launchSettings.json index 462db42..1b73d7f 100644 --- a/cli/src/Vdk/Properties/launchSettings.json +++ b/cli/src/Vdk/Properties/launchSettings.json @@ -14,7 +14,7 @@ }, "create-clutser": { "commandName": "Project", - "commandLineArgs": "create cluster" + "commandLineArgs": "create cloud-provider-kind" }, "WSL": { "commandName": "WSL2", diff --git a/cli/src/Vdk/ServiceProviderBuilder.cs b/cli/src/Vdk/ServiceProviderBuilder.cs index 3e73b4c..95c8de4 100644 --- a/cli/src/Vdk/ServiceProviderBuilder.cs +++ b/cli/src/Vdk/ServiceProviderBuilder.cs @@ -44,7 +44,9 @@ public static IServiceProvider Build() .AddSingleton() .AddSingleton() .AddSingleton() + .AddSingleton() .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton() .AddSingleton() diff --git a/cli/src/Vdk/Services/DockerHubClient.cs b/cli/src/Vdk/Services/DockerHubClient.cs index 856c426..2f536de 100644 --- a/cli/src/Vdk/Services/DockerHubClient.cs +++ b/cli/src/Vdk/Services/DockerHubClient.cs @@ -5,9 +5,9 @@ namespace Vdk.Services; public class DockerHubClient(IDockerEngine docker, IConsole console) : IHubClient { - public void Create() + public void CreateRegistry() { - if (Exists()) return; + if (ExistRegistry()) return; console.WriteLine("Creating Vega VDK Registry"); console.WriteLine(" - This may take a few minutes..."); docker.Run(Containers.RegistryImage, @@ -18,16 +18,47 @@ public void Create() null); } - public void Destroy() + public void CreateCloudProviderKind() { - if (!Exists()) return; + if (ExistCloudProviderKind()) return; + console.WriteLine("Creating Cloud Provider Kind"); + // docker run -d --name cloud-provider-kind --network kind -v /var/run/docker.sock:/var/run/docker.sock registry.k8s.io/cloud-provider-kind/cloud-controller-manager:v0.6.0 + var volumes = new List() + { + new() + { + Source = "/var/run/docker.sock", + Destination = "/var/run/docker.sock" + } + }; + docker.Run(Containers.CloudProviderKindImage, + Containers.CloudProviderKindName, + null, null, volumes.ToArray(), null, "kind"); + } + + + public void DestroyRegistry() + { + if (!ExistRegistry()) return; console.WriteWarning("Deleting Vega VDK Registry from Docker"); console.WriteLine("You can recreate the registry using command 'vega create registry'"); docker.Delete(Containers.RegistryName); } - public bool Exists() + public void DestroyCloudProviderKind() + { + if (!ExistCloudProviderKind()) return; + console.WriteWarning("Deleting Cloud Provider Kind from Docker"); + docker.Delete(Containers.CloudProviderKindName); + } + + public bool ExistRegistry() { return docker.Exists(Containers.RegistryName); } + + public bool ExistCloudProviderKind() + { + return docker.Exists(Containers.CloudProviderKindName); + } } \ No newline at end of file diff --git a/cli/src/Vdk/Services/IDockerEngine.cs b/cli/src/Vdk/Services/IDockerEngine.cs index 672b27a..4867973 100644 --- a/cli/src/Vdk/Services/IDockerEngine.cs +++ b/cli/src/Vdk/Services/IDockerEngine.cs @@ -4,7 +4,7 @@ namespace Vdk.Services; public interface IDockerEngine { - bool Run(string image, string name, PortMapping[]? ports, Dictionary? envs, FileMapping[]? volumes, string[]? commands); + bool Run(string image, string name, PortMapping[]? ports, Dictionary? envs, FileMapping[]? volumes, string[]? commands, string? network = null); bool Exists(string name,bool checkRunning = true); diff --git a/cli/src/Vdk/Services/IHubClient.cs b/cli/src/Vdk/Services/IHubClient.cs index 68a0839..c54d5b4 100644 --- a/cli/src/Vdk/Services/IHubClient.cs +++ b/cli/src/Vdk/Services/IHubClient.cs @@ -2,9 +2,15 @@ namespace Vdk.Services; public interface IHubClient { - void Create(); + void CreateRegistry(); - void Destroy(); + void CreateCloudProviderKind(); - bool Exists(); + void DestroyRegistry(); + + void DestroyCloudProviderKind(); + + bool ExistRegistry(); + + bool ExistCloudProviderKind(); } \ No newline at end of file diff --git a/cli/src/Vdk/Services/LocalDockerClient.cs b/cli/src/Vdk/Services/LocalDockerClient.cs index e1f3b84..fe1f6c4 100644 --- a/cli/src/Vdk/Services/LocalDockerClient.cs +++ b/cli/src/Vdk/Services/LocalDockerClient.cs @@ -12,7 +12,7 @@ public LocalDockerClient(Docker.DotNet.IDockerClient dockerClient) _dockerClient = dockerClient; } - public bool Run(string image, string name, PortMapping[]? ports, Dictionary? envs, FileMapping[]? volumes, string[]? commands) + public bool Run(string image, string name, PortMapping[]? ports, Dictionary? envs, FileMapping[]? volumes, string[]? commands, string? network = null) { _dockerClient.Images.CreateImageAsync( new ImagesCreateParameters @@ -27,7 +27,8 @@ public bool Run(string image, string name, PortMapping[]? ports, Dictionary { { "vega-component", name } }, ExposedPorts = ports?.ToDictionary(x => $"{x.ContainerPort}/tcp", y => default(EmptyStruct)), Volumes = volumes?.ToDictionary(x => x.Destination, y => new EmptyStruct()), @@ -43,6 +44,34 @@ public bool Run(string image, string name, PortMapping[]? ports, Dictionary> + { + { "name", new Dictionary { { network, true } } } + } + }) + .GetAwaiter() + .GetResult(); + + var dockerNetwork = networkList?.FirstOrDefault(); + if (dockerNetwork == null) + { + throw new Exception($"Docker network '{network}' not found."); + } + + _dockerClient.Networks + .ConnectNetworkAsync(dockerNetwork.ID, new NetworkConnectParameters + { + Container = response.ID + }) + .GetAwaiter() + .GetResult(); + } return _dockerClient.Containers.StartContainerAsync(response.ID, new ContainerStartParameters() { }).GetAwaiter().GetResult(); } diff --git a/docs/usage/command-reference.md b/docs/usage/command-reference.md index 4dcb919..c726284 100644 --- a/docs/usage/command-reference.md +++ b/docs/usage/command-reference.md @@ -39,3 +39,10 @@ Gets the kubeconfig path for a cluster. **Flags:** * `--name string`: Name of the cluster (default: `kind`) + +# `vdk create cloud-provider-kind` + +Creates a cloud Provider KIND docker image wich runs as a standalone binary in the local machine +and will connect to the Kind cluster and provision new Load balancer containers for the services. + + From d8b431d12f27b752b43f83e2650089989c0c4e05 Mon Sep 17 00:00:00 2001 From: Eddie Date: Tue, 17 Jun 2025 16:06:51 -0500 Subject: [PATCH 2/2] Update docs/usage/command-reference.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Eddie --- docs/usage/command-reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage/command-reference.md b/docs/usage/command-reference.md index c726284..8c62b0c 100644 --- a/docs/usage/command-reference.md +++ b/docs/usage/command-reference.md @@ -42,7 +42,7 @@ Gets the kubeconfig path for a cluster. # `vdk create cloud-provider-kind` -Creates a cloud Provider KIND docker image wich runs as a standalone binary in the local machine +Creates a cloud Provider KIND docker image which runs as a standalone binary in the local machine and will connect to the Kind cluster and provision new Load balancer containers for the services.