fix(crud): read generated outputs in the apply that creates them - #47
Merged
Aleksei Sviridkin (lexfrei) merged 4 commits intoSep 21, 2026
Merged
Conversation
golangci-lint v2.13 renamed exhaustruct and wsl to exhaustruct_v5 and wsl_v5 while keeping the originals as deprecated aliases. With `default: all` both spellings are enabled, so disabling only the old names silently turned the two linters back on and the run failed on code that was never meant to satisfy them. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <f@lex.la>
Credentials, kubeconfigs, endpoints, and VM addresses live in Secrets, Services, and KubeVirt status that controllers materialise after the object itself exists. Create read them once, immediately after the write, so the attributes landed in state as null and only appeared on the next refresh: a bucket's S3 credentials were readable one apply late. The outputsReader contract gained outputsPending, so a model says when its outputs are still missing, and the apply re-reads them until they appear. The polling shares the wait_timeout budget with the readiness wait and runs only when wait_for_ready is set, so the default stays non-blocking. Outputs that never materialise leave a warning instead of failing an apply whose object was created successfully. Update polls as well, which is what surfaces a bucket user's credentials when the user is added to an existing bucket. A plan that changes the object marks Computed attributes with a null config value unknown, so outputs that grew during the apply are a legal result. A read that keeps failing is still reported, but a single failing one is retried: on a converging cluster an apiserver hiccup should not fail an apply whose object already exists. The credentials, kubeconfig, and endpoints attributes also name the Secrets and Services the charts actually create, which carry a release prefix, and the shared wait attributes move out of the tenant resource file they had no business living in. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <f@lex.la>
A create with wait_for_ready that outlasts wait_timeout returned before the state was written, so the object existed in Cozystack while Terraform knew nothing about it: the next apply tried to create it again and got AlreadyExists, leaving the practitioner to import or delete it by hand. The readiness wait now reports the last observation along with the timeout error, so the object is recorded and the error is still raised. Only a failed write reports nothing to record. Assisted-by: LLM Signed-off-by: Aleksei Sviridkin <f@lex.la>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
IvanHunters
approved these changes
Sep 21, 2026
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.
Summary
Bucket credentials, cluster kubeconfig, postgres endpoints and VM addresses live in Secrets, Services and KubeVirt status that controllers create after the object itself. The provider read them once, right after the write, so they landed in state as null and only appeared on the next refresh. A bucket's S3 credentials were readable one apply late.
With
wait_for_readyset, the apply now re-reads them until they show up, inside the samewait_timeoutbudget as the readiness wait. Default behaviour is unchanged.Second fix in the same path: when the readiness wait timed out, the created object never reached state, so the next apply got AlreadyExists and someone had to import or delete it by hand.
Changes
outputsReadergotoutputsPending, so a model says when its outputs are still missing, and create/update poll until they appear or the deadline passes. Outputs that never appear leave a warning instead of failing an apply whose object exists. A couple of failing reads in a row are retried, the cluster is converging at that point.wait_timeoutis parsed before the write, so a malformed duration no longer creates anything.bucket-<name>-<user>,kubernetes-<name>-admin-kubeconfig,postgres-<name>-rw/-ro. The shared wait attributes moved out of the tenant resource file, which is why every resource's docs said "until the tenant's Ready condition".default: allboth spellings are on, so both have to be listed in disable. Without that the lint job fails on any PR.Testing
make test)make lint)make docsproduces no diff)make testacc), if applicableNo cluster at hand for
make testacc. The new paths are covered by unit tests against a fake dynamic client, and I checked each one by breaking the code it guards and watching it fail.Documentation
examples/(bucket, kubernetes, postgres and vminstance showwait_for_ready = trueand say why)make docs)Checklist
type(scope): description)No breaking changes. With
wait_for_readyunset the behaviour is the same as before.Additional Notes
Update polls as well. A plan that changes the object marks Computed attributes with a null config value as unknown, prior state does not matter, so a grown credentials map is a legal result. Checked in terraform-plugin-framework v1.19.0,
MarkComputedNilsAsUnknown.VM addresses are waited for under Always, RerunOnFailure and Once, the strategies that start a guest themselves. A guest that exits before its address is read leaves no VirtualMachineInstance, and the wait then runs to the timeout and warns.
Left out on purpose:
client.WaitForReadygives up on the first failing Get and calls every failure a timeout, and CI does not pin the golangci-lint version.