Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmd/podman/common/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -2006,6 +2006,11 @@ func AutocompleteHealthOnFailure(_ *cobra.Command, _ []string, _ string) ([]stri
return define.SupportedHealthCheckOnFailureActions, cobra.ShellCompDirectiveNoFileComp
}

// AutocompleteKubePlayValidate - autocomplete the values for the kube play --validate flag.
func AutocompleteKubePlayValidate(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) {
return entities.KubeValidateModeNames(), cobra.ShellCompDirectiveNoFileComp
}

// AutocompleteSysctl - autocomplete list all sysctl names
func AutocompleteSysctl(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
var completions []string
Expand Down
15 changes: 15 additions & 0 deletions cmd/podman/kube/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"go.podman.io/podman/v6/cmd/podman/parse"
"go.podman.io/podman/v6/cmd/podman/registry"
"go.podman.io/podman/v6/cmd/podman/utils"
"go.podman.io/podman/v6/cmd/podman/validate"
"go.podman.io/podman/v6/libpod/define"
"go.podman.io/podman/v6/libpod/shutdown"
"go.podman.io/podman/v6/pkg/annotations"
Expand All @@ -38,6 +39,7 @@ type playKubeOptionsWrapper struct {
CredentialsCLI string
StartCLI bool
BuildCLI bool
ValidateCLI string
annotations []string
macs []string
}
Expand Down Expand Up @@ -142,6 +144,12 @@ func playFlags(cmd *cobra.Command) {
)
_ = cmd.RegisterFlagCompletionFunc(usernsFlagName, common.AutocompleteUserNamespace)

playOptions.ValidateCLI = string(entities.KubeValidateIgnore)
validateChoice := validate.Value(&playOptions.ValidateCLI, entities.KubeValidateModeNames()...)
validateFlagName := "validate"
flags.Var(validateChoice, validateFlagName, "How to handle unrecognized YAML fields and objects: "+validateChoice.Choices())
_ = cmd.RegisterFlagCompletionFunc(validateFlagName, common.AutocompleteKubePlayValidate)

flags.BoolVar(&playOptions.NoHostname, "no-hostname", false, "Do not create /etc/hostname within the container, instead use the version from the image")
flags.BoolVar(&playOptions.NoHosts, "no-hosts", podmanConfig.ContainersConfDefaultsRO.Containers.NoHosts, "Do not create /etc/hosts within the pod's containers, instead use the version from the image")
flags.BoolVarP(&playOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images")
Expand Down Expand Up @@ -217,6 +225,8 @@ func play(cmd *cobra.Command, args []string) error {
if playOptions.ServiceContainer && !playOptions.StartCLI { // Sanity check to be future proof
return fmt.Errorf("--service-container does not work with --start=stop")
}
// The --validate value is enforced at flag-parse time by validate.Value.
playOptions.Validate = entities.KubeValidateMode(playOptions.ValidateCLI)
// TLS verification in c/image is controlled via a `types.OptionalBool`
// which allows for distinguishing among set-true, set-false, unspecified
// which is important to implement a sane way of dealing with defaults of
Expand Down Expand Up @@ -517,6 +527,11 @@ func kubeplay(body io.Reader) error {
// printPlayReport goes through the report returned by KubePlay and prints it out in a human
// friendly format.
func printPlayReport(report *entities.PlayKubeReport) error {
// Print any validation warnings (for example --validate=warn) to stderr.
for _, warning := range report.ValidationWarnings {
fmt.Fprintln(os.Stderr, "Warning:", warning)
}

// Print volumes report
for i, volume := range report.Volumes {
if i == 0 {
Expand Down
13 changes: 13 additions & 0 deletions docs/source/markdown/podman-kube-play.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,19 @@ Start the pod after creating it, set to false to only create it.

@@option userns.container

#### **--validate**=*mode*

Control how unrecognized YAML fields and unsupported objects are handled. Supported modes are:

- **ignore**: silently skip them (default).
- **warn**: report a warning and continue. Warnings are printed to stderr and, when using the API, returned in the play report.
- **strict**: fail with an error.

Comment thread
danishprakash marked this conversation as resolved.
When **strict** is used, any object that fails validation halts the processing of
further objects, but prior objects will still exist and will not be rolled back.
For example, in a YAML file containing a Pod followed by an unsupported object, the
Pod is created and then the command fails.

#### **--wait**, **-w**

Run pods and containers in the foreground. Default is false.
Expand Down
9 changes: 9 additions & 0 deletions pkg/api/handlers/libpod/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
StaticMACs []string `schema:"staticMACs"`
TLSVerify bool `schema:"tlsVerify"`
Userns string `schema:"userns"`
Validate string `schema:"validate"`
Comment thread
danishprakash marked this conversation as resolved.
Wait bool `schema:"wait"`
Build bool `schema:"build"`
NoPodPrefix bool `schema:"noPodPrefix"`
Expand All @@ -133,6 +134,13 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
return
}

// An empty value is allowed for backward compatibility with older clients
// that do not send the parameter; it is treated as the default (ignore).
if query.Validate != "" && !entities.KubeValidateMode(query.Validate).IsValid() {
Comment thread
danishprakash marked this conversation as resolved.
utils.Error(w, http.StatusBadRequest, fmt.Errorf("invalid validate value %q", query.Validate))
return
}

staticIPs := make([]net.IP, 0, len(query.StaticIPs))
for _, ipString := range query.StaticIPs {
ip := net.ParseIP(ipString)
Expand Down Expand Up @@ -196,6 +204,7 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
UseLongAnnotations: query.NoTrunc,
Username: username,
Userns: query.Userns,
Validate: entities.KubeValidateMode(query.Validate),
Wait: query.Wait,
ContextDir: contextDirectory,
NoPodPrefix: query.NoPodPrefix,
Expand Down
11 changes: 11 additions & 0 deletions pkg/api/server/register_kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,15 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error {
// type: string
// description: Set the user namespace mode for the pods.
// - in: query
// name: validate
// type: string
// default: ignore
// enum: [ignore, warn, strict]
// description: |
// How to handle unrecognized YAML fields and unsupported objects. "ignore" skips them,
// "warn" returns them in the ValidationWarnings field of the response, and "strict"
// fails the request. An empty value is treated as "ignore".
// - in: query
// name: wait
// type: boolean
// default: false
Expand All @@ -153,6 +162,8 @@ func (s *APIServer) registerKubeHandlers(r *mux.Router) error {
// responses:
// 200:
// $ref: "#/responses/playKubeResponseLibpod"
// 400:
// $ref: "#/responses/badParamError"
// 500:
// $ref: "#/responses/internalError"
r.HandleFunc(VersionedPath("/libpod/play/kube"), s.APIHandler(libpod.PlayKube)).Methods(http.MethodPost)
Expand Down
3 changes: 3 additions & 0 deletions pkg/bindings/kube/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ type PlayOptions struct {
NoTrunc *bool
// Userns - define the user namespace to use.
Userns *string
// Validate - how to handle unrecognized YAML fields and kinds:
// "ignore", "warn", or "strict".
Validate *string
// Force - remove volumes on --down
Force *bool
// PublishPorts - configure how to expose ports configured inside the K8S YAML file
Expand Down
15 changes: 15 additions & 0 deletions pkg/bindings/kube/types_play_options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 37 additions & 0 deletions pkg/domain/entities/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,41 @@ import (
entitiesTypes "go.podman.io/podman/v6/pkg/domain/entities/types"
)

// KubeValidateMode controls how `podman kube play` handles unrecognized YAML
// fields and unsupported kinds.
type KubeValidateMode string

const (
// KubeValidateIgnore silently skips unrecognized fields and kinds.
KubeValidateIgnore KubeValidateMode = "ignore"
// KubeValidateWarn logs a warning for unrecognized fields and kinds.
KubeValidateWarn KubeValidateMode = "warn"
// KubeValidateStrict fails on unrecognized fields and kinds.
KubeValidateStrict KubeValidateMode = "strict"
)

// 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]
}
Comment thread
danishprakash marked this conversation as resolved.

// KubeValidateModeNames returns the supported --validate values as strings, in
// order of increasing strictness, for use in shell completion and error messages.
func KubeValidateModeNames() []string {
return []string{
string(KubeValidateIgnore),
string(KubeValidateWarn),
string(KubeValidateStrict),
}
}

// PlayKubeOptions controls playing kube YAML files.
type PlayKubeOptions struct {
// Annotations - Annotations to add to Pods
Expand Down Expand Up @@ -83,6 +118,8 @@ type PlayKubeOptions struct {
SystemContext *types.SystemContext
// Do not prefix container name with pod name
NoPodPrefix bool
// Validate controls how unrecognized YAML fields and kinds are handled.
Validate KubeValidateMode
}

// PlayKubePod represents a single pod and associated containers created by play kube
Expand Down
3 changes: 3 additions & 0 deletions pkg/domain/entities/types/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ type PlayKubeReport struct {
Secrets []PlaySecret
// ServiceContainerID - ID of the service container if one is created
ServiceContainerID string
// ValidationWarnings - non-fatal messages produced by --validate=warn, for
// example unrecognized YAML fields or unsupported kinds.
ValidationWarnings []string
// If set, exit with the specified exit code.
ExitCode *int32
}
Expand Down
Loading