Skip to content

podman kube play: add --validate=ignore|warn|strict flag#29145

Open
ROKUMATE wants to merge 1 commit into
podman-container-tools:mainfrom
ROKUMATE:feat-playkube-warn-unknown-keys
Open

podman kube play: add --validate=ignore|warn|strict flag#29145
ROKUMATE wants to merge 1 commit into
podman-container-tools:mainfrom
ROKUMATE:feat-playkube-warn-unknown-keys

Conversation

@ROKUMATE

@ROKUMATE ROKUMATE commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Fixes: #18332

podman kube play silently ignored unrecognized YAML keys (e.g. a typo likeworkdir instead of workingDir). This logs them at debug level for Pod/DaemonSet/Deployment/Job — the pod still runs unchanged, but ignored keys are visible with --log-level=debug.

Note: the strict decode reports the first unrecognized key per document, not all.

Checklist

Ensure you have completed the following checklist for your pull request to be reviewed:

  • Certify you wrote the patch or otherwise have the right to pass it on as an open-source patch by signing all
    commits. (git commit -s). (If needed, use git commit -s --amend). The author email must match
    the sign-off email address. See CONTRIBUTING.md
    for more information.
  • Referenced issues using Fixes: #00000 in commit message (if applicable)
  • Tests have been added/updated (or no tests are needed)
  • Documentation has been updated (or no documentation changes are needed)
  • All commits pass make validatepr (format/lint checks)
  • Release note entered in the section below (or None if no user-facing changes)

Does this PR introduce a user-facing change?

podman kube play now logs unrecognized YAML fields at debug level.

@TomSweeneyRedHat

Copy link
Copy Markdown
Contributor

Changes look OK from a high level, high speed review. Tests, however, aren't having it @ROKUMATE

@danishprakash danishprakash left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's still unclear how we want to approach this problem at least going by the discussion in the linked issue.

I personally would prefer going the k8s way with a --validate=strict|warn|ignore flag and unlike k8s that defaults to strict, we can start with ignore. This has the added benefit of validating both fields and kind (#27712). This allows the user to either ignore, warn, or fail on any unsupported type.

cc/ @ygalblum

@ROKUMATE

ROKUMATE commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

i didnt thought on the way to add a flag initally ...
sounds good to me as well ... to work on the approach u pointed out
will work on it once the approach is agreed then with the design ....
if there are any more points you would like to come with for the solution i am happy to implement that as well ... side by side 👍🏼

@Honny1

Honny1 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

I personally would prefer going the k8s way with a --validate=strict|warn|ignore flag and unlike k8s that defaults to strict, we can start with ignore. This has the added benefit of validating both fields and kind (#27712). This allows the user to either ignore, warn, or fail on any unsupported type.

I think the flag is a good idea.

PTAL @podman-container-tools/podman-maintainers

@ROKUMATE

Copy link
Copy Markdown
Contributor Author

will implement it 👍🏼

@ygalblum

Copy link
Copy Markdown
Contributor

I personally would prefer going the k8s way with a --validate=strict|warn|ignore flag and unlike k8s that defaults to strict, we can start with ignore

I like the idea of this flag. I think defaulting to ignore is a must to avoid breaking existing usages that just work

@ROKUMATE
ROKUMATE force-pushed the feat-playkube-warn-unknown-keys branch from 5d84aeb to 214ab53 Compare July 13, 2026 20:48
@github-actions github-actions Bot added the kind/api-change Change to remote API; merits scrutiny label Jul 13, 2026
@ROKUMATE

Copy link
Copy Markdown
Contributor Author

Added the flag option suggested 👍🏼

Comment thread cmd/podman/kube/play.go Outdated
validateFlagName := "validate"
flags.StringVar(&playOptions.Validate, validateFlagName, "ignore", "How to handle unrecognized YAML fields and kinds: `ignore`, `warn`, or `strict`")
_ = cmd.RegisterFlagCompletionFunc(validateFlagName, func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
return []string{"ignore", "warn", "strict"}, cobra.ShellCompDirectiveNoFileComp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can these values be typed? The hard coded values keep repeating in the code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it got slipped from my mind regarding that
any more reviews from this ??

as will implement all at once then if there are any more changes required 👍🏼

Comment thread pkg/domain/infra/abi/play.go Outdated
@@ -358,6 +358,9 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
if err := yaml.Unmarshal(document, &podYAML); err != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if there's a way to combine the Unmarshal with the validation below. They seem to do similar things. (in all the cases)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will look a way to combine it 👍🏼

Comment thread pkg/domain/infra/abi/play.go Outdated
logrus.Infof("Kube kind %s not supported", kind)
switch options.Validate {
case "strict":
return nil, fmt.Errorf("kube kind %q is not supported", kind)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we use %q in the new cases, but keep %s in the default case? Also since the same string is used in all cases, does it make sense to create it once?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

did it by mistake will fix it 👍🏼

Comment thread test/e2e/play_kube_test.go
@danishprakash
danishprakash self-requested a review July 14, 2026 07:32
@ROKUMATE
ROKUMATE force-pushed the feat-playkube-warn-unknown-keys branch from 214ab53 to 390d1ba Compare July 14, 2026 11:21
@ROKUMATE
ROKUMATE requested a review from ygalblum July 14, 2026 12:16
Comment thread pkg/domain/entities/play.go Outdated
Comment on lines +25 to +34
var SupportedKubeValidateModes = []KubeValidateMode{
KubeValidateIgnore,
KubeValidateWarn,
KubeValidateStrict,
}

// IsValid reports whether m is a supported validate mode.
func (m KubeValidateMode) IsValid() bool {
return slices.Contains(SupportedKubeValidateModes, m)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Using a map[KubeValidateMode]bool instead of a list will simplify IsValid as it will be a simple map check

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

did the changes 👍🏼

@ROKUMATE
ROKUMATE force-pushed the feat-playkube-warn-unknown-keys branch from 390d1ba to 10f8d4d Compare July 14, 2026 19:54
@danishprakash danishprakash changed the title pkg/domain: log unrecognized kube play YAML keys at debug level podman kube play: add --validate=ignore|warn|strict flag Jul 15, 2026
Comment thread cmd/podman/kube/play.go Outdated
return fmt.Errorf("--service-container does not work with --start=stop")
}
playOptions.Validate = entities.KubeValidateMode(playOptions.ValidateCLI)
if !playOptions.Validate.IsValid() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should also do this check in the API handler

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ohkk 👍🏼

if err := yaml.Unmarshal(document, &jobYAML); err != nil {
return nil, fmt.Errorf("unable to read YAML as Kube Job: %w", err)
if err := unmarshalKubeObject("Job", options.Validate, document, &jobYAML); err != nil {
return nil, err

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are we skipping PVCs, ConfigMaps, and Secrets deliberately?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

nahh i forgot to add that check over here
will add that as well

Comment thread pkg/domain/infra/abi/play.go Outdated
Comment on lines +557 to +572
func unmarshalKubeObject(kind string, mode entities.KubeValidateMode, document []byte, obj any) error {
if mode != entities.KubeValidateWarn && mode != entities.KubeValidateStrict {
return decodeKubeObject(kind, document, obj)
}

err := yaml.UnmarshalStrict(document, obj)
switch {
case err == nil:
return nil
case mode == entities.KubeValidateStrict:
return fmt.Errorf("validating kube %s: %w", kind, err)
default: // warn
logrus.Warnf("kube %s: %v", kind, err)
return decodeKubeObject(kind, document, obj)
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: but this is not the easiest to read; you could simply fall through from strict, warn and to ignore.

Suggested change
func unmarshalKubeObject(kind string, mode entities.KubeValidateMode, document []byte, obj any) error {
if mode != entities.KubeValidateWarn && mode != entities.KubeValidateStrict {
return decodeKubeObject(kind, document, obj)
}
err := yaml.UnmarshalStrict(document, obj)
switch {
case err == nil:
return nil
case mode == entities.KubeValidateStrict:
return fmt.Errorf("validating kube %s: %w", kind, err)
default: // warn
logrus.Warnf("kube %s: %v", kind, err)
return decodeKubeObject(kind, document, obj)
}
}
func unmarshalKubeObject(kind string, mode entities.KubeValidateMode, document []byte, obj any) error {
switch mode {
case entities.KubeValidateStrict:
if err := yaml.UnmarshalStrict(document, obj); err != nil {
return fmt.Errorf("validating kube %s: %w", kind, err)
}
case entities.KubeValidateWarn:
if err := yaml.UnmarshalStrict(document, obj); err != nil {
logrus.Warnf("kube %s: %v", kind, err)
return decodeKubeObject(kind, document, obj)
}
default: // ignore, and any invalid value
return decodeKubeObject(kind, document, obj)
}
return nil
}

Comment on lines +23 to +33
// supportedKubeValidateModes is the set of accepted --validate values.
var supportedKubeValidateModes = map[KubeValidateMode]bool{
KubeValidateIgnore: true,
KubeValidateWarn: true,
KubeValidateStrict: true,
}

// IsValid reports whether m is a supported validate mode.
func (m KubeValidateMode) IsValid() bool {
return supportedKubeValidateModes[m]
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This feels unnecessary; I believe we do similar validation for other commands, can you check:

sort := validate.Value(&listOpts.Sort, "command", "created", "id", "image", "names", "runningfor", "size", "status")
sortFlagName := "sort"
flags.Var(sort, sortFlagName, "Sort output by: "+sort.Choices())
_ = cmd.RegisterFlagCompletionFunc(sortFlagName, common.AutocompletePsSort)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ohkk will implement that 👍🏼

Comment thread pkg/domain/infra/abi/play.go Outdated
// decoded leniently. In "warn" and "strict" mode it is decoded strictly:
// "strict" returns an error on an unknown field, while "warn" logs a warning
// and falls back to a lenient decode so playback still succeeds.
func unmarshalKubeObject(kind string, mode entities.KubeValidateMode, document []byte, obj any) error {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you please add unit tests for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yupp 👍🏼

Comment thread test/e2e/play_kube_test.go Outdated
Comment on lines +2701 to +2703
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
kube := podmanTest.PodmanExitCleanly([]string{"kube", "play", kubeYaml})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should also ensure stderr is empty ie no warnings.

Comment thread test/e2e/play_kube_test.go Outdated
Comment on lines +2732 to +2734
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
kube := podmanTest.PodmanExitCleanly([]string{"kube", "play", kubeYaml})

Comment thread test/e2e/play_kube_test.go Outdated
Comment on lines +2760 to +2761
err := writeYaml(yamlWithUnknownField, kubeYaml)
Expect(err).ToNot(HaveOccurred())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I guess we can drop this unwanted I/O, worth a check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

will drop it in the next commit and will ping then

Expect(kube.ErrorToString()).To(ContainSubstring("BogusKind"))
})

It("--validate=strict fails on unsupported kube kinds", func() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you also add a test that ensure --validate=strict doesn't reject legitimate manifests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

👍🏼

@danishprakash

Copy link
Copy Markdown
Member

Let's also not prematurely close #27712; @mheon @axel7083 can you confirm if this works for you folks for unsupported Kinds?

@axel7083

axel7083 commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Let's also not prematurely close #27712; @mheon @axel7083 can you confirm if this works for you folks for unsupported Kinds?

Thanks @danishprakash for tagging me!

I gave it a try with the following markdown

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    name: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

podman cli

$:  ./bin/podman kube play --validate strict ./demo.yaml 
Error: kube kind "Service" is not supported

However, reading podman kube play -h I can see

      --validate ignore               How to handle unrecognized YAML fields and kinds: ignore, `warn`, or `strict` (default "ignore")

Can't we have warn as default?

podman service

Using ./bin/podman system service --time=0 tcp://localhost:8888 and calling POST http://localhost:8888/v5.6.2/libpod/play/kube?replace=true&validate=warn is not showing me any warnings.

It will fail nicely if validate is set to strict, but warn is doing nothing using the libpod api. From Podman Desktop side, we use the libpod api, so we need the warnings to be in the response.

We may need to add a custom field (Wanings?) in the PlayKubeReport.

type PlayKubeReport struct {
// Pods - pods created by play kube.
Pods []PlayKubePod
// Volumes - volumes created by play kube.
Volumes []PlayKubeVolume
PlayKubeTeardown
// Secrets - secrets created by play kube
Secrets []PlaySecret
// ServiceContainerID - ID of the service container if one is created
ServiceContainerID string
// If set, exit with the specified exit code.
ExitCode *int32
}

Moreover, if I have several unsupported resources, I only see the first one in the error / warn. Maybe we should see them all?

@danishprakash

Copy link
Copy Markdown
Member

Can't we have warn as default?

We discussed this previously and concluded that it's not desirable since it could potentially break existing workflows especially programmatic uses where an empty stderr is suddenly now populated when running with the same (even though broken) manifests. But assuming we surface the warnings in the API response (discussed below), then you could choose to show/suppress the warnings on the client end. Would that work for you?

It will fail nicely if validate is set to strict, but warn is doing nothing using the libpod api. From Podman Desktop side, we use the libpod api, so we need the warnings to be in the response.

We may need to add a custom field (Wanings?) in the PlayKubeReport.

Agree with both the points; API check was flagged earlier, I'm guessing it's still WIP but surfacing warnings in the API response is a good suggestion, we should certainly support that.

Moreover, if I have several unsupported resources, I only see the first one in the error / warn. Maybe we should see them all?

Yes, by design, it's an early return on any failure but if we have to aggregate all the validation issues at once like how k8s does it, it might be a bigger change than the scope of this PR imo. I suggest we track that in a separate issue.

@axel7083

Copy link
Copy Markdown
Contributor

But assuming we surface the warnings in the API response (discussed below), then you could choose to show/suppress the warnings on the client end. Would that work for you?

Yes, if the warnings is returned as part of the libpod/play/kube response, in Podman Desktop we will probably enable warn or strict by default, will see !

Agree with both the points; API check was flagged earlier, I'm guessing it's still WIP but surfacing warnings in the API response is a good suggestion, we should certainly support that.

To show the flag on the Podman Destkop side this is a requirement for us!

Yes, by design, it's an early return on any failure but if we have to aggregate all the validation issues at once like how k8s does

I'm fine with it, I just wanted to be sure this has been considered.

Thanks @danishprakash !

@ROKUMATE
ROKUMATE force-pushed the feat-playkube-warn-unknown-keys branch from 10f8d4d to a5dd5b1 Compare July 17, 2026 08:42
ignore warn and strict modes for unknown yaml fields and kinds
ignore is the default and skips them warn reports them strict fails
warnings are returned in the play report so they show up in the cli and over the api for tools like podman desktop

Closes podman-container-tools#18332

Signed-off-by: ROKUMATE <rohitkumawat0110@gmail.com>
@ROKUMATE
ROKUMATE force-pushed the feat-playkube-warn-unknown-keys branch from a5dd5b1 to 54fab1e Compare July 17, 2026 10:43
@ROKUMATE

Copy link
Copy Markdown
Contributor Author

@danishprakash I have done the requested changes the understood the discussion as well

the first force push was the changes you requested earlier while the second one is more on the side of the warning feature

if any more review changes are there do tell 👍🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/api-change Change to remote API; merits scrutiny kube

Projects

None yet

Development

Successfully merging this pull request may close these issues.

podman play kube doesn't warn for unrecognised keys in YAML

6 participants