Skip to content

Conversation

@pro-wh
Copy link
Member

@pro-wh pro-wh commented Jan 22, 2026

  • new --kubernetes <output dir> writes a directory of kubernetes config files and a kustomization.yaml. use kubectl apply -k <ouptut_dir> to put up the scenario
  • adds serde_yaml crate, although that's said to be unmaintained. for comparison, docker compose reporter does its own yaml stunts using string operations
  • adds a 'resources.rs' file with structures divined by LLM knowledge of kubernetes 😬
  • for "runtime" values in top level config, it gives you a root-config.env file, e.g.
    # Root config values - fill in values before deploying
    AMBER_CONFIG_API_KEY=
    and kustomize generates an amber-root-config ConfigMap out of it
  • deployments put those amber-root-config values into places OR use the amber-compose-helper to exec a program with string interpolations using those values
  • amber-helper mounted into containers similar to docker-compose, an initContainer copies it from an image to a volume
  • now that amber-compose-helper is used in multiple reporters, it's renamed to amber-helper
  • bindings are encoded into NetworkPolicy objects, so other connections are not allowed
  • on startup, a special set of deployments + services + network policy check that NetworkPolicy can actually block
  • the actual scenario deployments use an initContainer to check if the network policy test succeeded

@pro-wh
Copy link
Member Author

pro-wh commented Jan 22, 2026

ERROR: failed to build: invalid tag "ghcr.io/RDI-Foundation/amber-cli:ca7393a147b96a61d9dd136b1892056fc4d7daf8-amd64": repository name must be lowercase

holy

// Clean and recreate the output directory.
if root.exists() {
if root.is_dir() {
std::fs::remove_dir_all(root)
Copy link
Member Author

Choose a reason for hiding this comment

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

not sure if want

Copy link
Member Author

Choose a reason for hiding this comment

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

like it's not too bad in theory, but the .env files kind of invite you to edit them so

Copy link
Member

Choose a reason for hiding this comment

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

yeah, maybe let's make people rm -rf <whatever> && amber --k8s <whatever>. not that bad compared to overwriting a .env, which can be really annoying

Copy link
Member

@nhynes nhynes left a comment

Choose a reason for hiding this comment

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

looks mostly reasonable. we should strongly consider whether it makes sense to include the cni checker which is more weighty than anticipated. an ignored rust test that exercises the new reporter in KinD and runs in CI would be cool. also a hoisting and cleanup pass. I'll run this through codex for completeness

Comment on lines +80 to +81
#[arg(long = "disable-networkpolicy-check", requires = "kubernetes")]
disable_networkpolicy_check: bool,
Copy link
Member

Choose a reason for hiding this comment

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

Interesting. So far I haven't had a good answer for how to add reporter-specific args. Thanks for making a movement on that.

// Clean and recreate the output directory.
if root.exists() {
if root.is_dir() {
std::fs::remove_dir_all(root)
Copy link
Member

Choose a reason for hiding this comment

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

yeah, maybe let's make people rm -rf <whatever> && amber --k8s <whatever>. not that bad compared to overwriting a .env, which can be really annoying

.collect::<Vec<_>>()
.join(" -> ");
return Err(ReporterError::new(format!(
"kubernetes reporter requires an acyclic dependency graph (ignoring weak bindings). \
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if this error shouldn't be some non-string error or something since the compose reporter also prefers acyclic. I also wonder if not all scenarios should be required to be acyclic, hoisting the check to scenario construction (linking) time.

Ok(endpoint.port)
}

fn compose_templates_dfs(
Copy link
Member

Choose a reason for hiding this comment

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

blatant plagiarism


/// Try to resolve a config query against a composed template.
/// Returns Static if the value is fully resolved, Runtime if it contains config refs.
fn resolve_config_query_for_program(
Copy link
Member

Choose a reason for hiding this comment

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

This PR could use a pass to collect all of the shared code into one place. I can nominate myself for that

/// - Phase 1: Try to connect to allowed server. If this fails, networking is broken - exit with error.
/// - Phase 2: Try to connect to blocked server. If this succeeds, NetworkPolicy isn't enforced - exit with error.
/// - Success: Both checks pass, stay alive.
fn generate_netpol_enforcement_check(
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we really care that much that we would add 300 lines of code for it. This should be replaced at some point by L7 enforcement, so maybe we don't bother

miette = { workspace = true, features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
serde_yaml = { workspace = true }
Copy link
Member

Choose a reason for hiding this comment

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

controversial opinion: yaml is a superset of json. write out json instead of bringing in yaml

- `linker`: schema validation, binding resolution, and export verification.
- `passes`: graph rewrites that must preserve scenario invariants.
- `reporter`: transforms `CompileOutput` into artifacts (e.g., scenario IR JSON, DOT, Docker Compose YAML).
- `reporter`: transforms `CompileOutput` into artifacts (e.g., scenario IR JSON, DOT, Docker Compose YAML, Kubernetes YAML).
Copy link
Member

Choose a reason for hiding this comment

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

and then leave it described as kubernetes YAML to mess with people

@nhynes
Copy link
Member

nhynes commented Jan 24, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da969e8784

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +747 to +749
// Add ingress rules for bound consumers.
if let Some(allowed) = inbound_allow.get(id) {
// Group by port.

Choose a reason for hiding this comment

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

P2 Badge Permit ingress for exported provides in NetworkPolicy

The NetworkPolicy here only adds ingress rules based on inbound_allow (bindings). If a component is only exported (no internal bindings), inbound_allow is empty so the generated policy has zero ingress rules, which is a default‑deny for all ingress to that pod. That makes scenario exports unreachable from any external client (other namespaces, ingress, or utility pods) despite the service being created. Consider adding rules for exported ports (or skipping the policy) so exported provides remain accessible.

Useful? React with 👍 / 👎.

@nhynes
Copy link
Member

nhynes commented Jan 25, 2026

Vague suggestion: docker-compose and k8s work in much the same way with programs and sidecars being turned into a "workload" and then rendered. There's a lot of duplicated code to prove this point. Would it be valuable to move the shared logic into one or more compose+k8s passes so that they can both be thin renderers on top of the same postprocessed IR? If you don't think that makes sense to put in this PR, I'm happy to try a refactoring pass after it's in.

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.

3 participants