Skip to content

Commit

Permalink
Merge pull request #16880 from ygalblum/kube-publish-ports
Browse files Browse the repository at this point in the history
Kube Play - allow setting and overriding published host ports
  • Loading branch information
openshift-merge-robot authored Jan 10, 2023
2 parents 5b9e068 + 07cc49e commit 6ba308f
Show file tree
Hide file tree
Showing 9 changed files with 395 additions and 21 deletions.
4 changes: 4 additions & 0 deletions cmd/podman/kube/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ func playFlags(cmd *cobra.Command) {
replaceFlagName := "replace"
flags.BoolVar(&playOptions.Replace, replaceFlagName, false, "Delete and recreate pods defined in the YAML file")

publishPortsFlagName := "publish"
flags.StringSliceVar(&playOptions.PublishPorts, publishPortsFlagName, []string{}, "Publish a container's port, or a range of ports, to the host")
_ = cmd.RegisterFlagCompletionFunc(publishPortsFlagName, completion.AutocompleteNone)

if !registry.IsRemote() {
certDirFlagName := "cert-dir"
flags.StringVar(&playOptions.CertDir, certDirFlagName, "", "`Pathname` of a directory containing TLS certificates and keys")
Expand Down
7 changes: 7 additions & 0 deletions docs/source/markdown/podman-kube-play.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ When no network option is specified and *host* network mode is not configured in

This option conflicts with host added in the Kubernetes YAML.

#### **--publish**=*[[ip:][hostPort]:]containerPort[/protocol]*

Define or override a port definition in the YAML file.

The lists of ports in the YAML file and the command line are merged. Matching is done by using the **containerPort** field.
If **containerPort** exists in both the YAML file and the option, the latter takes precedence.

#### **--quiet**, **-q**

Suppress output information when pulling images
Expand Down
44 changes: 23 additions & 21 deletions pkg/api/handlers/libpod/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
query := struct {
Annotations map[string]string `schema:"annotations"`
Network []string `schema:"network"`
TLSVerify bool `schema:"tlsVerify"`
LogDriver string `schema:"logDriver"`
LogOptions []string `schema:"logOptions"`
Start bool `schema:"start"`
StaticIPs []string `schema:"staticIPs"`
StaticMACs []string `schema:"staticMACs"`
NoHosts bool `schema:"noHosts"`
Annotations map[string]string `schema:"annotations"`
Network []string `schema:"network"`
TLSVerify bool `schema:"tlsVerify"`
LogDriver string `schema:"logDriver"`
LogOptions []string `schema:"logOptions"`
Start bool `schema:"start"`
StaticIPs []string `schema:"staticIPs"`
StaticMACs []string `schema:"staticMACs"`
NoHosts bool `schema:"noHosts"`
PublishPorts []string `schema:"publishPorts"`
}{
TLSVerify: true,
Start: true,
Expand Down Expand Up @@ -82,18 +83,19 @@ func KubePlay(w http.ResponseWriter, r *http.Request) {

containerEngine := abi.ContainerEngine{Libpod: runtime}
options := entities.PlayKubeOptions{
Annotations: query.Annotations,
Authfile: authfile,
Username: username,
Password: password,
Networks: query.Network,
NoHosts: query.NoHosts,
Quiet: true,
LogDriver: logDriver,
LogOptions: query.LogOptions,
StaticIPs: staticIPs,
StaticMACs: staticMACs,
IsRemote: true,
Annotations: query.Annotations,
Authfile: authfile,
Username: username,
Password: password,
Networks: query.Network,
NoHosts: query.NoHosts,
Quiet: true,
LogDriver: logDriver,
LogOptions: query.LogOptions,
StaticIPs: staticIPs,
StaticMACs: staticMACs,
IsRemote: true,
PublishPorts: query.PublishPorts,
}
if _, found := r.URL.Query()["tlsVerify"]; found {
options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
Expand Down
2 changes: 2 additions & 0 deletions pkg/bindings/kube/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ type PlayOptions struct {
Userns *string
// Force - remove volumes on --down
Force *bool
// PublishPorts - configure how to expose ports configured inside the K8S YAML file
PublishPorts []string
}

// ApplyOptions are optional options for applying kube YAML files to a k8s cluster
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.

2 changes: 2 additions & 0 deletions pkg/domain/entities/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ type PlayKubeOptions struct {
IsRemote bool
// Force - remove volumes on --down
Force bool
// PublishPorts - configure how to expose ports configured inside the K8S YAML file
PublishPorts []string
}

// PlayKubePod represents a single pod and associated containers created by play kube
Expand Down
40 changes: 40 additions & 0 deletions pkg/domain/infra/abi/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,14 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
*ipIndex++

if len(options.PublishPorts) > 0 {
publishPorts, err := specgenutil.CreatePortBindings(options.PublishPorts)
if err != nil {
return nil, nil, err
}
mergePublishPorts(&podOpt, publishPorts)
}

p := specgen.NewPodSpecGenerator()
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -1001,6 +1009,38 @@ func (ic *ContainerEngine) playKubePVC(ctx context.Context, pvcYAML *v1.Persiste
return &report, nil
}

func mergePublishPorts(p *entities.PodCreateOptions, publishPortsOption []nettypes.PortMapping) {
for _, publishPortSpec := range p.Net.PublishPorts {
if !portAlreadyPublished(publishPortSpec, publishPortsOption) {
publishPortsOption = append(publishPortsOption, publishPortSpec)
}
}
p.Net.PublishPorts = publishPortsOption
}

func portAlreadyPublished(port nettypes.PortMapping, publishedPorts []nettypes.PortMapping) bool {
for _, publishedPort := range publishedPorts {
if port.ContainerPort >= publishedPort.ContainerPort &&
port.ContainerPort < publishedPort.ContainerPort+publishedPort.Range &&
isSamePortProtocol(port.Protocol, publishedPort.Protocol) {
return true
}
}
return false
}

func isSamePortProtocol(a, b string) bool {
if len(a) == 0 {
a = string(v1.ProtocolTCP)
}
if len(b) == 0 {
b = string(v1.ProtocolTCP)
}

ret := strings.EqualFold(a, b)
return ret
}

func (ic *ContainerEngine) importVolume(ctx context.Context, vol *libpod.Volume, tarFile *os.File) error {
volumeConfig, err := vol.Config()
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions pkg/domain/infra/tunnel/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, opts en
if start := opts.Start; start != types.OptionalBoolUndefined {
options.WithStart(start == types.OptionalBoolTrue)
}
options.WithPublishPorts(opts.PublishPorts)
return play.KubeWithBody(ic.ClientCtx, body, options)
}

Expand Down
Loading

0 comments on commit 6ba308f

Please sign in to comment.