Repository navigation
ate-setup: add a render subcommand for kustomize generation - #3411
Steven Shriver (stshrive) wants to merge 2 commits into
Conversation
90dd378 to
ae8359e
Compare
|
Hi Steven Shriver (@stshrive) ,
Separately, --component compatibility remains dependent on #3179. |
Release artifacts, Helm charts and provider CI need the manifests that deploy ate-system applies, without access to a cluster. render ate-system writes them to --output-dir, one file per apply step, numbered in apply order. It requires --image-repo and --image-tag and pins every image to a digest. It also writes the settings ConfigMaps that deploy creates through the API, and ate-api-server-secret-envvars for the bundled database. An external database's connection strings are not written. It leaves out the CA and JWT pool Secrets, which each hold a private key generated for one cluster: rendering them would put the keys wherever the output goes, and every apply would replace the pools and invalidate the certificates and tokens issued from them. deploy creates each pool only when it is absent, and actor-id-ca-certs is copied from the actor-id-ca-pool Secret in the cluster. It also leaves out the credential provider's namespace policy, the bundled PostgreSQL identities and the CSI drivers. deploy ate-system now builds the podcertificate-controller manifest, the ate-api-server settings and the service account issuer through the same helpers as render. Signed-off-by: Steven Shriver <6007067+stshrive@users.noreply.github.com>
ae8359e to
4282ded
Compare
Signed-off-by: Steven Shriver <6007067+stshrive@users.noreply.github.com>
d3d0aad to
cbbe58e
Compare
This is intentional. I updated the commit message and the PR description to make this a bit more clear. Additional comments in the code were also added.
this is a known, interim gap. #3399 closes it by rejecting ATE_API_POSTGRES_CLOUDSQL_* for every command.
This is true and documented in the code. A rotated external Secret won't change the hash or trigger a rollout. Worth a tracking issue? Ultimately the bootstrap work (#3175) owns this Secret.
This is dependent on a few things, also added to the PR description to clarify a bit, but some other PRs are removing a bunch of content that impacts render directly. The Cited PRs are generally higher priority and this will land after a few of the others and will need a rebase for a few things. Any lingering provider-neutral issues will be addressed then. Additionally, I have made a few tweaks to documentation to address this issue. |
| issuer := e.configuredJWTIssuer() | ||
| if issuer == "" { | ||
| issuer = inClusterIssuer | ||
| } |
There was a problem hiding this comment.
🤖 blocking 🔴 – With --kind this writes https://kubernetes.default.svc, but kind (kubeadm) issues tokens as https://kubernetes.default.svc.cluster.local. deploy reads the real issuer from the cluster, and buildAuthenticationConfig already handles both values. The output of the documented --kind example would make ate-api-server reject every service account token, including the ate-client one kubectl ate uses. Please use the .cluster.local issuer when Kind is set, and have the kind test row assert it.
| // renderCredentialProvider is the configured credential provider, or the | ||
| // bundled Kubernetes Secrets provider when none is set. The bundled provider | ||
| // runs in the install namespace and needs nothing outside the cluster, which | ||
| // is why kind installs use it too. | ||
| func (e *Env) renderCredentialProvider() (config.CredentialProvider, error) { | ||
| if e.Cfg.CredentialProviderJSON == "" { | ||
| log.Infof("no credential provider set; rendering the bundled %s provider", config.K8sCredentialProviderName) | ||
| return config.CredentialProvider{ | ||
| Name: config.K8sCredentialProviderName, | ||
| Address: config.K8sCredentialProviderAddress, | ||
| }, nil | ||
| } | ||
| return e.Cfg.CredentialProvider() |
There was a problem hiding this comment.
🤖 should-fix 🟡 – deploy ate-system refuses to run without --credential-provider, on kind too. Kind installs pass {"name":"k8s.io"} explicitly, so the comment's "which is why kind installs use it too" and the help text's "as kind installs do" (internal/cmd/render.go:72) are misleading. Here render quietly picks the bundled provider, which gets cluster-wide Secret read, and it does so for production renders as well. I'd call e.Cfg.CredentialProvider() directly, the way deploy does, and drop this helper, its test row, and the help text bullet.
|
|
||
| // apiServerConfigVars is the ate-api-server-envvars ConfigMap payload without | ||
| // the Cloud SQL settings, which only CreateAPIServerEnvVars adds. render ate-system | ||
| // writes this payload, and Cloud SQL is not part of the core install. |
| ate-setup create podcertificate-controller-cas | ||
| kubectl apply -f DIR/01-crds.yaml | ||
| kubectl wait --for=condition=Established crd --all | ||
| kubectl apply -f DIR |
There was a problem hiding this comment.
🤖 nit 🟢 – The bundled provider needs k8s-credential-provider-namespace-policy to start, but this block leaves it out, so following these steps as written leaves the provider unable to start. Could you add the kubectl apply -f manifests/egress-credential-injection/namespace-policy.yaml step here, before the last apply? Then the prose below would not need to repeat it.
| var renderAteSystemCmd = &cobra.Command{ | ||
| Use: "ate-system", | ||
| Short: "Write the manifests deploy ate-system applies into a directory", | ||
| Long: `Write the manifests "deploy ate-system" applies to a fresh cluster into |
There was a problem hiding this comment.
a fresh cluster -> a cluster, since this cluster may already have Substrate installed.
| ate-setup render ate-system --kind --image-repo REPO --image-tag TAG \ | ||
| --output-dir DIR | ||
|
|
||
| Other clusters store snapshots on GCS today, so they also need the snapshot |
There was a problem hiding this comment.
Other clusters means non-KIND clusters?
| Key: "render.outputDir", Env: "ATE_RENDER_OUTPUT_DIR", Flag: "output-dir", | ||
| Kind: config.KindString, | ||
| Commands: []string{renderAteSystemPath}, | ||
| Usage: "Directory the rendered manifests are written to; it must be new or empty", |
There was a problem hiding this comment.
Requiring the directory to be new or empty is safe, but may make it difficult to diff the config change.
| resource below on the way, so those subcommands are only needed to redo one on | ||
| a running cluster. | ||
|
|
||
| ## Render |
There was a problem hiding this comment.
🤖 nit 🟢 – This section repeats the Long help of render ate-system almost word for word, and the RenderAteSystem doc comment in steps/render.go lists the same exclusions a third time. The copies have already drifted, for example in how they describe the --gcp-* issuer settings. Other sections in this file are mapping tables with short notes. Could this keep the table row with a pointer to ate-setup render ate-system --help, and could the Go doc comment shrink to what the function writes?
| if err != nil { | ||
| return nil, err | ||
| } | ||
| out.WriteString("---\n") |
There was a problem hiding this comment.
🤖 nit 🟢 – kube.ReadPath already prepends "---\n" and guarantees a trailing newline for each file, so out.WriteString("---\n") here produces duplicate ---\n---\n separators in 03-sandboxconfig.yaml.
| // default gVisor SandboxConfig, the order DeploySandboxConfig applies them in. | ||
| func (e *Env) sandboxConfigManifest() ([]byte, error) { | ||
| var out bytes.Buffer | ||
| for _, name := range []string{"sandboxconfig-validation.yaml", "sandboxconfig-gvisor.yaml"} { |
There was a problem hiding this comment.
#3254 is replacing sandboxconfig-gvisor.yaml with sandboxconfig-gvisor.yaml.tmpl, which deploy fills in with a substrate-<hash>-gvisor name, a created-by-version label a the class-default annotation.
Zoe Zhao (@zoez7) for vis, either PR merge later need to be careful on this.
| ate-setup create podcertificate-controller-cas | ||
| kubectl apply -f DIR/01-crds.yaml | ||
| kubectl wait --for=condition=Established crd --all | ||
| kubectl apply -f DIR |
There was a problem hiding this comment.
This one from Claude: Same gap as the namespace policy, for the bundled database: ate-api-server logs in as substrate_readwrite_user, which only the SQL in setupBundledPostgres creates, so ate-api-server can't connect after this block. Could the block end with ate-setup deploy postgres when the database is bundled?
| later file holds a SandboxConfig: | ||
|
|
||
| ```bash | ||
| kubectl apply -f DIR/00-namespace.yaml |
There was a problem hiding this comment.
On a cluster installed with these commands, a field that a later release removes (an env var, a volume, a sidecar) is still there after the runbook's ate-setup deploy steps.
Client-side kubectl apply records kubectl-client-side-apply as the owner of every field, and server-side apply only removes a field no other manager owns.
Asked claude to rerpo this on kind with a ConfigMap key. Could these commands use kubectl apply --server-side --field-manager=ate-setup, so the upgrade steps own the same fields?
Release artifacts, Helm charts and provider CI need the manifests that deploy ate-system applies, without access to a cluster. render ate-system writes them to --output-dir, one file per apply step, numbered in apply order. It requires --image-repo and --image-tag and pins every image to a digest.
It also writes the settings ConfigMaps that deploy creates through the API, and ate-api-server-secret-envvars for the bundled database. An external database's connection strings are not written.
It leaves out the CA and JWT pool Secrets, which each hold a private key generated for one cluster: rendering them would put the keys wherever the output goes, and every apply would replace the pools and invalidate the certificates and tokens issued from them. deploy creates each pool only when it is absent, and actor-id-ca-certs is copied from the actor-id-ca-pool Secret in the cluster. It also leaves out the credential provider's namespace policy, the bundled PostgreSQL identities and the CSI drivers.
deploy ate-system now builds the podcertificate-controller manifest, the ate-api-server settings and the service account issuer through the same helpers as render.
Part of #3240.
Related provider-neutral core work:
ate-setup's Cloud SQL support and the GKE content inmanifests/ate-install/base.renderrelies on its config-load rejection ofATE_API_POSTGRES_CLOUDSQL_*, and its output has no GKE content once it lands.tools/setup-gcpandhack/teardown.sh.--componentfor render follows ate-setup deploy accepts --component, and control plane sizing moves into kustomize Components #3179.Outside kind, render still needs the GCS snapshot location and transfer service account, because the object store defaults to GCS. A later core change makes the backend explicit.