Stop the reconciler wedging private networks as failed - #12
Merged
Conversation
A sandbox workload matches no existing principal type. It carries no agent-<id> attribute -- there is no agent class behind it -- and it cannot be a group member, because groups collect users, agents, and apps. Nothing in the access model could name the engineer at a sandbox shell. An environment principal resolves to every workload running that environment, agent workloads and sandboxes alike. Its dial policy names environment-<id>, which the Orchestrator already stamps on every workload identity it creates and which egress rule attachments already target -- so no new OpenZiti mechanism is involved and nothing about the topology changes. The two per-principal steps that assume an identity now branch. An environment is a configuration resource and is not in the Identity registry, so existence and organization resolve through Agents.GetEnvironment; the call forwards the caller for the same reason the group lookup does. AGENTS_GRPC_TARGET joins the dependency set, and WithAgentsClient keeps the existing constructors' shapes since every other principal resolves without it. Authorization is can_edit_config on the environment, matching what an egress rule attachment to an environment already requires and what the agent principal uses on its agent. Not organization owner: a grant here reaches anyone holding can_use, because they can start a sandbox and a sandbox is a shell -- it adds a destination to what a shell there already reaches rather than widening who stands in front of it. The enum gains its value by ALTER TYPE. The runner applies pending migrations in one transaction and PostgreSQL forbids using an enum value in the transaction that added it, so the file says as much for whoever adds the next one.
Three faults compounded into a network that reported failed forever while OpenZiti was healthy. OpenZiti resolves a "@" service role by id only, never by name, so the dial policy for a resource access could never match its service. Services now carry a private-resource-<id> role attribute and the policy selects on that, which also survives the service being recreated as an id would not. A reconcile that failed wrote an empty id over the one already recorded, stranding the live OpenZiti object and guaranteeing every later attempt hit the unique-name constraint. Provisioning failures were also swallowed unlogged, so both services looked idle while this ran. Creates now set return_existing so a reconcile after a lost response adopts what is already there. Adds a devspace.yaml so the service can run from sources against the VM.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A private network sat at
failedin the console for an hour while OpenZiti was perfectly healthy — the bind policy existed, the tunnel was enrolled and online. Three faults compounded.@resolves by id, not name.createResourceAccessDialPolicyRequestselected its service with@private-<resourceId>— the service name. OpenZiti answersno services found with the given ids; probing the controller with both forms against the same live service gives 400 for@nameand 201 for@id. Every other@reference in the platform already uses an id.Rather than switch to the id, services now carry a
private-resource-<id>role attribute and the dial policy selects#private-resource-<id>. An id goes stale the moment a service is recreated, and the access reconciler only checks that its policy exists — it would never notice the policy pointed at a dead service. A role attribute is derived from the resource id, so it survives recreation.A failed re-provision erased the id it already had.
UpdateNetworkProvisioning(ctx, id, failed, "")wrote an emptyopenziti_bind_policy_idover a good one, stranding the live OpenZiti object. Every later reconcile then conflicted on the unique name, permanently.keepIDnow preserves the recorded id when provisioning fails.Nothing was logged. Provisioning errors were discarded, so both services looked idle. They are logged now — that is how the config-level conflict behind this was found at all.
Creates set
return_existing, so a reconcile after a lost response adopts the existing object instead of conflicting forever. The private-resource guard also re-provisions a service missing its role attribute, so one predating this change converges instead of being skipped as "exists".Needs ziti-management with the matching tag-filter and adopt fixes — without those the managed-object listing comes back empty and orphan cleanup never runs.
Verified end to end on the bundle VM: network, resource and access all reach
active, the dial policy resolves to exactly 1 service and 1 identity, and two consecutive reconcile ticks write nothing.Also adds
devspace.yaml(the repo had none) and gitignores.devspace/and vendored subcharts.