feat(secret): add secret get and secret set, and show key names in ls - #11
Merged
Conversation
…n `ls` There was no way to see what a Secret holds. `secret ls` reported a key count and nothing else — not even the key names — and there was no `secret get`. `orcinus config --show-secrets` does not fill the gap either: it selects on managed-by AND the project label, and a Secret made by `secret create` carries no project label, so it never appears there. Reading a value meant dropping to `orcinus kubectl get secret ... -o jsonpath` and decoding base64 by hand. Updating was worse. `secret create` on an existing name replaces the whole object, so changing one key silently dropped every key not passed with it — and since the keys could not be listed, there was no way to know what to pass. - `secret get <name>` lists the keys, with values withheld unless --show-values, so it is safe to run in a shared terminal. - `secret set <name> --from-literal K=V` merges: keys not named are kept, and the Secret is created if absent. It keeps the Secret's existing type, so merging into a TLS or dockerconfigjson Secret does not retype it to Opaque and break its consumers. - `secret ls` shows key names instead of a bare count, truncated to three with "+N more" to keep rows scannable. - `secret create` keeps replace semantics — that is what it means — but now names the keys it dropped and points at `set`. Both writers reject an empty --from-literal set rather than clearing a Secret. Help text carries the two things that bite: that `create` REPLACES, and that a changed Secret does not reach running pods, since env vars are injected at container start (`orcinus restart <service>`). Secrets mounted as files are the exception — the kubelet refreshes those in place. GET /api/v1/secrets gains a KeyNames field from the shared ListSecrets type. The API's POST keeps replace semantics; only the CLI grew a merge path.
…uster TestLiveSecret only exercised create/ls/rm, so nothing checked the new commands against a real API server — the unit tests use a fake clientset, which cannot catch how the values actually round-trip. Extends it with: ls naming the keys, get withholding values until --show-values, set changing one key while leaving the other intact (verified through kubectl, against the base64 the API actually stores), set creating a Secret that does not exist yet, and create reporting the key it dropped. Adds TestLiveSecretEnvFromSecret, which deploys a service with x-orcinus-env-from-secret and reads the value back out of the running pod's environment — the one thing no offline test can assert. Both stay behind ORCINUS_E2E_LIVE, like the rest of the live suite.
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.
Problem
Two gaps, and they made each other worse.
You could not see what a Secret holds.
secret lsshowed a key count and nothing else — not even the names — and there was nosecret get.orcinus config --show-secretsdoes not cover it either: it selects onmanaged-byandorcinus.io/project, and a Secret made bysecret createhas no project label, so it never appears there. Reading a value meant:Updating one key destroyed the others.
secret createon an existing name replaces the whole object:orcinus secret create app-secret --from-literal DB_PASS=xxx --from-literal API_KEY=yyy orcinus secret create app-secret --from-literal DB_PASS=new # → API_KEY gone, no warningAnd since the keys could not be listed, there was no way to know what to re-pass.
Change
secret get— keys listed, values withheld unless--show-values, so it is safe in a shared terminal.secret set— merges; keys not named are kept, and the Secret is created if absent. It preserves the Secret's existing type, so merging into a TLS or dockerconfigjson Secret does not retype it to Opaque and break every consumer (tested).secret ls— key names instead of a bare count, truncated to three with+N more.secret create— keeps replace semantics, since that is what it means, but now names the keys it dropped and points atset.Both writers reject an empty
--from-literalset rather than clearing a Secret.The two things that bite, now in
--helpcreateREPLACES — stated in its long helporcinus restart <service>is needed. Secrets consumed as a mounted file (external: true) are the exception — the kubelet refreshes those in place.Tests
10 new, 147 total.
pkg/deployagainst a fake clientset: merge keeps untouched keys; merge creates when absent; merge preserves an existing TLS type;GetSecretsorts keys and reportsManagedBy;ListSecretsreturns names. PlusTestApplySecretReplaces, which pins the destructive behavioursetexists to avoid, so it cannot drift silently.pkg/cli: subcommands resolve with the expected flag defaults,--show-valuesdefaults to false, the help text keeps its two warnings,parseLiteralsedge cases (K=,WITH=a=b, rejectsNOEQUALSand=novalue), andsummarizeKeystruncation.Note for reviewers
GET /api/v1/secretsgains aKeyNamesfield, since it serializes the sharedListSecretstype — names only, no values. The API'sPOSTkeeps replace semantics; only the CLI grew a merge path. Say the word if the API should getsettoo.