Skip to content

TRITON-2478: Allow Custom Backend Options for Triton Moirai #4

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

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

nshalman
Copy link

@nshalman nshalman commented May 8, 2025

The first thing to note is that https support was effectively broken in the javascript implementation as it was incorrectly emitting https where it should have emitted http. Since it was broken there can be no one depending on that functionality so I felt no need to maintain backward compatibility on the semantics of a service labeled https.

This work was done in three phases.

  1. With the assistance of Claude Code I ported the original javascript and bash implementations of parser.js and reconfigure to a single Rust based reconfigure binary. This included adding lots of unit tests.
  2. I extended the haproxy configuration template and the structs to implement the features requested for Allow Custom Backend Options for HAProxy Configuration #3.
  3. I used Claude Code to come up with suggestions for a syntax for those features and had it implement and document the one I selected.

Fixes #3

Prior art for https+insecure

@nshalman nshalman requested a review from Copilot May 8, 2025 16:45
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request introduces support for custom backend options in Triton Moirai by adding a new HAProxy configuration template, service parsing improvements in Rust, and corresponding updates in metadata retrieval in the JavaScript parser.

  • Adds a new Jinja template to generate HAProxy configurations with custom backend options.
  • Implements Rust service parsing with template rendering and tests.
  • Updates the JavaScript metadata retrieval function and project configuration files.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
templates/services.jinja New template for generating HAProxy configuration for custom backend options.
src/main.rs New service parsing implementation with template rendering and tests.
rust-toolchain.toml Updates the toolchain version and components.
parser.js Alters the metadata retrieval flow to directly return test strings for specific keys.
Cargo.toml Updates package metadata and dependency versions.

@nshalman nshalman requested a review from Copilot May 8, 2025 18:10
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This draft adds support for custom backend options for Triton Moirai by updating configuration templates, core Rust service parsing logic, and related tooling/scripts.

  • Added a new Jinja template for generating HAProxy service configuration.
  • Implemented Rust parsing and rendering logic to support custom backend ports.
  • Updated several build and configuration files, including toolchain settings and a reconfigure script change to append rather than overwrite.

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
templates/services.jinja Introduces a new template to generate HAProxy configurations using service loop indices.
src/main.rs Implements custom service parsing and rendering logic for dynamic backend configuration.
rust-toolchain.toml Updates toolchain settings to Rust 1.83 with necessary components.
reconfigure Adjusts configuration file generation from overwriting to appending parser.js output.
parser.js Refactors metadata fetching logic by removing the execFile call and handling specific keys differently.
README.md Fixes a typographical error in the certificate-related description.
Cargo.toml Adds project manifest and dependency definitions.

Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of mention of "Solaris" makes me uncomfortable, unless this is a Rust idiom of which I was unaware. All "SmartOS/Solaris" should be "SmartOS" or "SmartOS/illumos" unless there's a specific Rust idiom I'm missing.

Given how much outside-our-community conflation between illumos and Solaris still exists, I wonder if this is hallucinatory output from Claude?

I'll have to go over all of this very carefully later. And before this push happens we need to be transparent about AI-generated vs. human-generated things.

@danmcd
Copy link
Contributor

danmcd commented May 12, 2025

Thank you for the clarification. No more from me until this gets promoted to ready-for-review.

@nshalman nshalman requested a review from Copilot May 13, 2025 20:34
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces custom backend options for Triton Moirai by migrating legacy bash/Node scripts to a Rust-based implementation and updating configuration templates.

  • New Jinja templates for service and metrics configuration have been added.
  • The reconfigure and certificate management logic have been rewritten in Rust for improved maintainability and error handling.
  • Build tooling and documentation (including Cargo.toml, Makefile, and IMPLEMENTATION.md) have been updated to reflect these changes.

Reviewed Changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
templates/services.jinja Introduces a new template for service configuration with conditional SSL and sticky session support.
templates/metrics.jinja Adds a template for metrics endpoint configuration with conditional TLS binding.
src/reconfigure.rs Replaces legacy scripts with a Rust-based HAProxy configuration and management implementation.
src/certificates.rs Implements TLS certificate management (both Let's Encrypt and self-signed) in Rust.
rust-toolchain.toml Specifies the Rust toolchain version and required components.
reconfigure Legacy bash reconfigure script removed.
parser.js Legacy NodeJS parsing script removed.
package.json.new Introduces updated project metadata for npm where applicable.
README.md Updates documentation to reflect new features and migration details.
Makefile Updates build targets and dependencies to integrate the new Rust-based components.
IMPLEMENTATION.md Provides implementation details and migration decisions from legacy scripts to Rust.
Cargo.toml Sets up the Rust project manifest with necessary dependencies and binary definitions.

@nshalman nshalman requested a review from Copilot May 14, 2025 13:10
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces custom backend options for Triton Moirai and replaces legacy scripts with Rust-based implementations while updating documentation and build files.

  • Introduces new Jinja templates for service and metrics configuration
  • Migrates the reconfigure and certificate generation logic to Rust
  • Removes legacy bash scripts and JavaScript parser, and updates associated documentation and Makefile

Reviewed Changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
templates/services.jinja New template file with custom backend options and TLS settings
templates/metrics.jinja New template for the metrics endpoint with ACL configuration
src/reconfigure.rs Rust-based implementation for reconfiguration logic
src/certificates.rs Rust module for handling TLS certificate generation and updates
rust-toolchain.toml Specifies the Rust toolchain version and components
reconfigure Legacy bash script is removed in favor of the Rust binary
parser.js Legacy parser removal
package.json Removal of Node.js-based configuration and dependencies
README.md Updated documentation reflecting the new changes
Makefile Updated build instructions now incorporating Rust tooling
Cargo.toml New Cargo configuration for the Rust project
Comments suppressed due to low confidence (1)

src/certificates.rs:249

  • Verify that concatenating the certificate and private key into a single file meets HAProxy's requirements; if separate files are required, adjust the logic accordingly.
fs::write(cert_path, format!("{}{}", cert_content, privkey_content))

@nshalman nshalman force-pushed the TRITON-2478 branch 5 times, most recently from 93b26a0 to bc508c5 Compare May 20, 2025 18:54
@nshalman nshalman marked this pull request as ready for review May 28, 2025 16:09
@nshalman nshalman requested review from danmcd and Copilot May 28, 2025 16:09
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR replaces the legacy bash/JS reconfigure workflow with a Rust-based implementation, adds templated support for custom backends and a metrics endpoint, and refactors the build system for Cargo.

  • Introduce a Rust reconfigure binary and certificates module to manage HAProxy config and TLS.
  • Add Jinja templates for service frontends/backends and metrics endpoint with SSL/ACL options.
  • Update build tooling: pin Rust toolchain, remove Node.js parser and dependencies, and modernize the Makefile.

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
templates/200-metrics.cfg.jinja Add HAProxy metrics frontend template with optional SSL and ACL
templates/100-services.cfg.jinja Generate dynamic service frontends/backends with SSL/sticky options
templates/002-resolver.cfg Bump copyright year to 2025
templates/001-defaults.cfg Bump copyright year to 2025
templates/000-global.cfg Bump copyright year to 2025
src/reconfigure.rs New Rust entrypoint replacing the bash reconfigure script
src/certificates.rs New Rust module for TLS certificate generation/renewal
rust-toolchain.toml Pin Rust channel (1.84.1) and components
reconfigure Remove legacy Bash reconfigure script
parser.js Remove legacy Node.js parser
package.json Remove Node.js dependencies manifest
Makefile Refactor build to Rust/Cargo, remove Node.js targets
Cargo.toml Define Rust package metadata and dependencies
README.md Update docs for Rust implementation, metrics, services, and build
Comments suppressed due to low confidence (2)

src/certificates.rs:67

  • [nitpick] The certificate configuration logic isn’t covered by any tests; consider adding unit or integration tests for both metadata-driven and self-signed certificate paths.
pub fn configure_tls() -> Result<bool> {

src/certificates.rs:137

  • Path::is_symlink() is not a std::path::Path method and will not compile. Use symlink_metadata() and check file_type().is_symlink() to detect symlinks.
if !default_dir.exists() && !default_dir.is_symlink() {

Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial VERY larval pass 0.

You probably need to update .gitmodules as well:

-e797c515c97f27cea09248247fb2f00e79abdec8 deps/eng
-aff7fdd4e07e6f6a7806cb9dc57a65ecb07c0073 deps/javascriptlint
-52dc973cf64da11834eca7cf46ebce8518e3ee88 deps/jsstyle

Two of them probably don't need to be there anymore.

@nshalman nshalman force-pushed the TRITON-2478 branch 3 times, most recently from b491822 to 3cab1c4 Compare May 28, 2025 20:32
@nshalman nshalman requested review from danmcd and Copilot May 29, 2025 13:35
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR replaces the legacy bash/Node.js implementation with a Rust-based reconfigure binary, updates HAProxy Jinja templates, and modernizes the build system to use Cargo and rust-toolchain.

  • Introduces src/reconfigure.rs and src/certificates.rs to handle load-balancer configuration and TLS certificates in Rust.
  • Adds Jinja templates for services (100-services.cfg.jinja) and metrics (200-metrics.cfg.jinja), and bumps copyright years.
  • Updates Makefile and adds Cargo.toml/rust-toolchain.toml to remove Node.js dependencies and support Rust tooling.

Reviewed Changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
templates/100-services.cfg.jinja New Jinja template rendering service frontends and backends.
templates/200-metrics.cfg.jinja New Jinja template for the metrics frontend.
src/reconfigure.rs Rust entry point replacing the old reconfigure script.
src/certificates.rs Rust module for certificate provisioning and management.
Makefile Swapped Node.js build targets for Cargo/rust-build.
Cargo.toml & rust-toolchain.toml Added Rust project manifest and toolchain settings.
Comments suppressed due to low confidence (2)

src/certificates.rs:162

  • Both configure_tls and generate_self_signed_certificate lack unit tests; consider adding tests to cover success, failure, and idempotent paths.
pub fn generate_self_signed_certificate() -> Result<bool> {

src/certificates.rs:121

  • [nitpick] Reading and rewriting the entire log file on every run may be inefficient for large logs; consider opening in append mode or rotating logs instead.
log_content = fs::read_to_string(log_file).context("Failed to read dehydrated log file");

@nshalman nshalman requested a review from Copilot May 30, 2025 18:09
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the load balancer configuration from a Node.js and bash-based implementation to a consolidated Rust-based solution while updating configuration templates, documentation, and build scripts. Key changes include:

  • Replacement of parser.js and the bash reconfigure script with a Rust binary for configuration.
  • Updates to configuration templates and documentation to support new health check and certificate options.
  • Removal of legacy Node.js scripts and submodules no longer needed.

Reviewed Changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
templates/*.cfg.askama Updated HAProxy configuration templates with minor copyright updates and additional health check documentation.
src/reconfigure.rs Introduces a Rust reconfigure binary with minor TODO notes.
src/certificates.rs Implements TLS certificate management with support for Let's Encrypt and self-signed certificates.
Makefile & Cargo.toml Updates build process to use Rust tooling and removes obsolete Node.js assets.
parser.js, package.json, .gitmodules (jsstyle/javascriptlint) Removal of legacy Node.js code and dependencies.
Comments suppressed due to low confidence (1)

Makefile:96

  • Ensure that the CARGO_TARGET_DIR variable is either pre-defined or provided with a default value so that the release binary is reliably copied in all environments.
cp $(CARGO_TARGET_DIR)/release/reconfigure $(RELSTAGEDIR)/root/opt/triton/$(DIR_NAME)/

Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clearing out my now-resolved comments.

nshalman and others added 3 commits June 6, 2025 15:42
Claude Sonnet was used to assist with the porting.
Implement inline health check parameter syntax using JSON-like format:
{check:/healthz,port:32150,rise:30,fall:1}. This allows users to
configure health check endpoints, ports, and rise/fall counts directly
in service definitions while maintaining backward compatibility.
Code changes authored using Opus for $3.67

Enhance both inline code documentation and README with detailed explanations
of the JSON-like health check syntax introduced in the previous commit.
Includes parameter descriptions, usage examples, and integration guidance.
Documentation changes authored using Sonnet for $0.61

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The big three rust files I'll have to review in full later; partial progress on certificates.rs though.

Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Balance is still more "learning more about Rust" vs. "Actual things I've reviewed", but I did clear/resolve some older comments of mine.

nshalman and others added 5 commits June 9, 2025 20:47
Add support for configuring the metrics endpoint port via the
cloud.tritoncompute:metrics_port metadata key. The port defaults to 8405
for backward compatibility and validates the port range (1-65534).

- Add DEFAULT_METRICS_PORT constant and METRICS_PORT_KEY metadata key
- Update MetricsConfig struct to include metrics_port field
- Modify configure_acl function to retrieve and validate port from metadata
- Update metrics template to use configurable port instead of hardcoded 8405
- Add comprehensive test coverage for default and custom port behavior
- Update documentation to explain the new configurable port feature

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Replace 'httpss' with 'https' (HTTPS frontend → HTTPS backend, TLS bridging)
- Replace 'https' with 'https-http' (HTTPS frontend → HTTP backend, TLS termination)
- Restore 'https' to its original meaning of end-to-end HTTPS
- Update all method implementations (backend_ssl, frontend_ssl, use_sticky_session)
- Update comprehensive documentation in code comments and README
- Modernize tests to dynamically calculate cookie keys for robustness
- All tests pass and code quality checks succeed

The new naming explicitly shows frontend→backend protocol mapping,
making service configurations self-documenting and intuitive.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Change 'https' service type to verify backend SSL certificates by default
- Add new 'https+insecure' service type for HTTPS without certificate verification
- Implement backend_ssl_verify() method to control verification behavior
- Update HAProxy template to conditionally include 'verify none' based on verification setting
- Add comprehensive documentation with TODO comment for alternative naming options
- Update all existing tests and add new test coverage for https+insecure
- Maintain backward compatibility through the new https+insecure service type

This significantly improves security by making certificate verification the default
for HTTPS backend connections while preserving the ability to disable verification
when needed.

Service type mapping:
- https: HTTPS frontend → HTTPS backend WITH certificate verification
- https+insecure: HTTPS frontend → HTTPS backend WITHOUT certificate verification
- https-http: HTTPS frontend → HTTP backend (TLS termination, unchanged)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Our current production uses do not need/use it.
We can make it opt-in in the future.
Don't duplicate work handled by the dehydrated hook
Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call this the end of pass 1. I'd like a pass 2 (mostly on the .rs files) for myself, BUT this is what I got for now.

@nshalman
Copy link
Author

I've filed https://smartos.org/bugview/TRITON-2487 for the follow up to streamline only generating self-signed certs if TLS is requested at all and only mess with LetsEncrypt if a certificate name was provided.

@nshalman nshalman requested a review from danmcd June 12, 2025 15:59
mozilla-rootcerts was already installed, but I want to make it explicit
since we hardcode the path to a file it provides in our haproxy configs

With this fix in place I have followed the detailed test plan I
documented in README.md
Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing but nits left. Looking good (and I'm trying to learn more about Rust along the way).

Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last question and I'm ready to approve. On to testing-notes reading for me.

@danmcd
Copy link
Contributor

danmcd commented Jun 13, 2025

Also, non-blocking but curious, do we have any Rust style checkers (like 80cols or less) in "gmake check"?

@danmcd
Copy link
Contributor

danmcd commented Jun 13, 2025

One last question and I'm ready to approve. On to testing-notes reading for me.

Oh those were in the readme. So just that last question about failure modes, then.

@nshalman
Copy link
Author

Also, non-blocking but curious, do we have any Rust style checkers (like 80cols or less) in "gmake check"?

Yup! Both the clippy linter and cargo fmt are wired up.

@nshalman nshalman requested a review from danmcd June 13, 2025 20:36
Copy link
Contributor

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your work here. Modulo the commit message which we'll be talking about anyway, I'm approving.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow Custom Backend Options for HAProxy Configuration
2 participants