-
Notifications
You must be signed in to change notification settings - Fork 0
Handle cert dir mounts; add Docker restart #51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -81,14 +81,14 @@ public bool Exists(string name, bool checkRunning = true) | |||||||||||||
| IList<ContainerListResponse> containers = _dockerClient.Containers.ListContainersAsync( | ||||||||||||||
| new ContainersListParameters() | ||||||||||||||
| { | ||||||||||||||
| Filters = new Dictionary<string, IDictionary<string, bool>> { { "label", new Dictionary<string, bool> { { "vega-component", true } } } }, | ||||||||||||||
| Limit = 10, | ||||||||||||||
| Filters = new Dictionary<string, IDictionary<string, bool>> { { "name", new Dictionary<string, bool> { { name, true } } } }, | ||||||||||||||
| All = true, | ||||||||||||||
| }).GetAwaiter().GetResult(); | ||||||||||||||
| var container = containers.FirstOrDefault(x => x.Labels["vega-component"].Contains(name)); | ||||||||||||||
| var container = containers.FirstOrDefault(x => x.Names.Any(n => n.TrimStart('/') == name)); | ||||||||||||||
|
|
||||||||||||||
| if (container == null) return false; | ||||||||||||||
| if (checkRunning == false) return true; | ||||||||||||||
|
|
||||||||||||||
| return container.State == "running" || | ||||||||||||||
| // this should be started, lets do it | ||||||||||||||
| _dockerClient.Containers.StartContainerAsync(container.ID, new ContainerStartParameters() { }).GetAwaiter().GetResult(); | ||||||||||||||
|
Comment on lines
92
to
94
|
||||||||||||||
| return container.State == "running" || | |
| // this should be started, lets do it | |
| _dockerClient.Containers.StartContainerAsync(container.ID, new ContainerStartParameters() { }).GetAwaiter().GetResult(); | |
| // When checkRunning is true, only report whether the container is running; | |
| // do not start or otherwise modify container state. | |
| return container.State == "running"; |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new Restart method lacks test coverage. Consider adding tests for this new functionality, especially since the codebase has tests for other IDockerEngine implementations (e.g., FallbackDockerEngineTests.cs tests Run, Exists, Delete, Stop, and Exec operations).
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -34,60 +34,103 @@ public ReverseProxyClient(IDockerEngine docker, Func<string, IKubernetesClient> | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| public void Create() | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| var proxyExists = Exists(); | ||||||||||||||||||||||||||||||||||||||||||
| if (!proxyExists) | ||||||||||||||||||||||||||||||||||||||||||
| // Check if the container exists (running or stopped) | ||||||||||||||||||||||||||||||||||||||||||
| if (_docker.Exists(Containers.ProxyName)) | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine("Creating Vega VDK Proxy"); | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine(" - This may take a few minutes..."); | ||||||||||||||||||||||||||||||||||||||||||
| var conf = new FileInfo(NginxConf); | ||||||||||||||||||||||||||||||||||||||||||
| if (!conf.Exists) | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine("Vega VDK Proxy is running."); | ||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Container exists but is stopped - restart it | ||||||||||||||||||||||||||||||||||||||||||
| if (_docker.Exists(Containers.ProxyName, false)) | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine("Vega VDK Proxy exists but is not running. Restarting..."); | ||||||||||||||||||||||||||||||||||||||||||
| _docker.Restart(Containers.ProxyName); | ||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // Container does not exist at all - create it | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine("Creating Vega VDK Proxy"); | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine(" - This may take a few minutes..."); | ||||||||||||||||||||||||||||||||||||||||||
| var conf = new FileInfo(NginxConf); | ||||||||||||||||||||||||||||||||||||||||||
| if (!conf.Exists) | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| if (!conf.Directory!.Exists) | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| if (!conf.Directory!.Exists) | ||||||||||||||||||||||||||||||||||||||||||
| conf.Directory.Create(); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| InitConfFile(conf); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine($" - Reverse proxy configuration for {conf.FullName} exists, running a quick validation..."); | ||||||||||||||||||||||||||||||||||||||||||
| conf.Delete(); | ||||||||||||||||||||||||||||||||||||||||||
| InitConfFile(conf); | ||||||||||||||||||||||||||||||||||||||||||
| // iterate the clusters and create the endpoints for each | ||||||||||||||||||||||||||||||||||||||||||
| _kind.ListClusters().ForEach(tuple => | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| if (tuple is { isVdk: true, master: not null } && tuple.master.HttpsHostPort.HasValue) | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| conf.Directory.Create(); | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine($" - Adding cluster {tuple.name} to reverse proxy configuration"); | ||||||||||||||||||||||||||||||||||||||||||
| UpsertCluster(tuple.name, tuple.master.HttpsHostPort.Value, tuple.master.HttpHostPort.Value, false); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| var fullChain = new FileInfo(Path.Combine("Certs", "fullchain.pem")); | ||||||||||||||||||||||||||||||||||||||||||
| var privKey = new FileInfo(Path.Combine("Certs", "privkey.pem")); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| InitConfFile(conf); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteLine($" - Reverse proxy configuration for {conf.FullName} exists, running a quick validation..."); | ||||||||||||||||||||||||||||||||||||||||||
| conf.Delete(); | ||||||||||||||||||||||||||||||||||||||||||
| InitConfFile(conf); | ||||||||||||||||||||||||||||||||||||||||||
| // iterate the clusters and create the endpoints for each | ||||||||||||||||||||||||||||||||||||||||||
| _kind.ListClusters().ForEach(tuple => | ||||||||||||||||||||||||||||||||||||||||||
| // Check for and fix certificate paths that were incorrectly created as directories | ||||||||||||||||||||||||||||||||||||||||||
| if (!ValidateAndFixCertificatePath(fullChain.FullName) || | ||||||||||||||||||||||||||||||||||||||||||
| !ValidateAndFixCertificatePath(privKey.FullName)) | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| _console.WriteError("Certificate files are missing. Please ensure Certs/fullchain.pem and Certs/privkey.pem exist."); | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
| _console.WriteError("Certificate files are missing. Please ensure Certs/fullchain.pem and Certs/privkey.pem exist."); | |
| _console.WriteError("Certificate files are missing. The reverse proxy cannot be started without TLS certificates."); | |
| _console.WriteError("Expected files: Certs/fullchain.pem and Certs/privkey.pem"); | |
| _console.WriteError("For local development, you can create self-signed certificates with:"); | |
| _console.WriteError(" mkdir -p Certs && openssl req -x509 -nodes -newkey rsa:2048 -keyout Certs/privkey.pem -out Certs/fullchain.pem -days 365"); | |
| _console.WriteError("For production, use certificates issued by a trusted CA and refer to the Vega VDK documentation on TLS certificates."); |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The certificate validation logic is duplicated between ValidateAndFixCertificatePath() in ReverseProxyClient.cs and FixCertificatePathIfDirectory() in UpdateClustersCommand.cs. Both methods perform the same task: checking if a path exists as a directory and removing it.
Consider extracting this logic into a shared utility method or service to avoid duplication and ensure consistency. This would make maintenance easier and reduce the risk of the two implementations diverging over time.
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new ValidateAndFixCertificatePath method lacks test coverage. This is an important utility function that modifies the filesystem by detecting and removing incorrectly-created certificate directories.
The codebase has extensive tests for ReverseProxyClient in ReverseProxyClientTests.cs (testing methods like PatchCoreDns, InitConfFile, etc.), so adding tests for this new method would align with the existing testing patterns. Consider adding tests that verify:
- The method returns false when the path is a directory and can be removed
- The method returns true when the path is a valid file
- The method handles errors gracefully when directory removal fails
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message "Certificate files are missing. Cannot create TLS secret." could be more specific about which certificate file(s) are missing. Since the validation checks two separate files (fullchain.pem and privkey.pem), indicating which one failed would help users troubleshoot the issue more efficiently.
Consider updating the error message to specify which file(s) are missing or failed validation, for example: "Certificate file is missing or invalid: {path}"
| if (!ValidateAndFixCertificatePath(fullChainPath) || | |
| !ValidateAndFixCertificatePath(privKeyPath)) | |
| { | |
| _console.WriteError("Certificate files are missing. Cannot create TLS secret."); | |
| var invalidCertificatePaths = new List<string>(); | |
| if (!ValidateAndFixCertificatePath(fullChainPath)) | |
| { | |
| invalidCertificatePaths.Add(fullChainPath); | |
| } | |
| if (!ValidateAndFixCertificatePath(privKeyPath)) | |
| { | |
| invalidCertificatePaths.Add(privKeyPath); | |
| } | |
| if (invalidCertificatePaths.Count > 0) | |
| { | |
| _console.WriteError( | |
| $"Certificate file(s) are missing or invalid: {string.Join(", ", invalidCertificatePaths)}. Cannot create TLS secret."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
Restartmethod lacks test coverage. The existing test fileFallbackDockerEngineTests.cshas tests for other Docker operations (Run, Exists, Delete, Stop, Exec), but doesn't include tests for the newly added Restart functionality.Consider adding a test that verifies the Restart method works correctly, similar to the existing tests for other Docker operations.