Merge pull request #39797 from fraenkel/portforward_ws_api

Automatic merge from submit-queue

Port forward over websockets API

The API changes for port forwarding over websockets
This commit is contained in:
Kubernetes Submit Queue 2017-01-20 15:05:33 -08:00 committed by GitHub
commit 88257cfb19
15 changed files with 1288 additions and 690 deletions

View File

@ -18,6 +18,8 @@ package api
import (
"fmt"
"strconv"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
@ -67,6 +69,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
Convert_map_to_unversioned_LabelSelector,
Convert_unversioned_LabelSelector_to_map,
Convert_Slice_string_To_Slice_int32,
)
}
@ -248,3 +252,19 @@ func Convert_unversioned_LabelSelector_to_map(in *metav1.LabelSelector, out *map
}
return err
}
// Convert_Slice_string_To_Slice_int32 converts multiple query parameters or
// a single query parameter with a comma delimited value to multiple int32.
// This is used for port forwarding which needs the ports as int32.
func Convert_Slice_string_To_Slice_int32(in *[]string, out *[]int32, s conversion.Scope) error {
for _, s := range *in {
for _, v := range strings.Split(s, ",") {
x, err := strconv.ParseUint(v, 10, 16)
if err != nil {
return fmt.Errorf("cannot convert to []int32: %v", err)
}
*out = append(*out, int32(x))
}
}
return nil
}

View File

@ -102,6 +102,7 @@ func newRESTMapper(externalVersions []schema.GroupVersion) meta.RESTMapper {
"PodLogOptions",
"PodExecOptions",
"PodAttachOptions",
"PodPortForwardOptions",
"PodProxyOptions",
"NodeProxyOptions",
"ServiceProxyOptions",

View File

@ -125,6 +125,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&PodAttachOptions{},
&PodLogOptions{},
&PodExecOptions{},
&PodPortForwardOptions{},
&PodProxyOptions{},
&ComponentStatus{},
&ComponentStatusList{},

View File

@ -117,6 +117,14 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
j.Stdout = true
j.Stderr = true
},
func(j *api.PodPortForwardOptions, c fuzz.Continue) {
if c.RandBool() {
j.Ports = make([]int32, c.Intn(10))
for i := range j.Ports {
j.Ports[i] = c.Int31n(65535)
}
}
},
func(s *api.PodSpec, c fuzz.Continue) {
c.FuzzNoCustom(s)
// has a default value

View File

@ -2953,6 +2953,15 @@ type PodExecOptions struct {
Command []string
}
// PodPortForwardOptions is the query options to a Pod's port forward call
type PodPortForwardOptions struct {
metav1.TypeMeta
// The list of ports to forward
// +optional
Ports []int32
}
// PodProxyOptions is the query options to a Pod's proxy call
type PodProxyOptions struct {
metav1.TypeMeta

File diff suppressed because it is too large Load Diff

View File

@ -2384,6 +2384,19 @@ message PodLogOptions {
optional int64 limitBytes = 8;
}
// PodPortForwardOptions is the query options to a Pod's port forward call
// when using WebSockets.
// The `port` query parameter must specify the port or
// ports (comma separated) to forward over.
// Port forwarding over SPDY does not use these options. It requires the port
// to be passed in the `port` header as part of request.
message PodPortForwardOptions {
// List of ports to forward
// Required when using WebSockets
// +optional
repeated int32 ports = 1;
}
// PodProxyOptions is the query options to a Pod's proxy call.
message PodProxyOptions {
// Path is the URL path to use for the current proxy request to pod.

View File

@ -81,6 +81,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&PodAttachOptions{},
&PodLogOptions{},
&PodExecOptions{},
&PodPortForwardOptions{},
&PodProxyOptions{},
&ComponentStatus{},
&ComponentStatusList{},

View File

@ -51083,6 +51083,315 @@ func (x *PodExecOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *PodPortForwardOptions) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yym1 := z.EncBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.EncExt(x) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [3]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.Kind != ""
yyq2[1] = x.APIVersion != ""
yyq2[2] = len(x.Ports) != 0
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(3)
} else {
yynn2 = 0
for _, b := range yyq2 {
if b {
yynn2++
}
}
r.EncodeMapStart(yynn2)
yynn2 = 0
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[0] {
yym4 := z.EncBinary()
_ = yym4
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[0] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("kind"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym5 := z.EncBinary()
_ = yym5
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.Kind))
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[1] {
yym7 := z.EncBinary()
_ = yym7
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
}
} else {
r.EncodeString(codecSelferC_UTF81234, "")
}
} else {
if yyq2[1] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("apiVersion"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym8 := z.EncBinary()
_ = yym8
if false {
} else {
r.EncodeString(codecSelferC_UTF81234, string(x.APIVersion))
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[2] {
if x.Ports == nil {
r.EncodeNil()
} else {
yym10 := z.EncBinary()
_ = yym10
if false {
} else {
z.F.EncSliceInt32V(x.Ports, false, e)
}
}
} else {
r.EncodeNil()
}
} else {
if yyq2[2] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("ports"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
if x.Ports == nil {
r.EncodeNil()
} else {
yym11 := z.EncBinary()
_ = yym11
if false {
} else {
z.F.EncSliceInt32V(x.Ports, false, e)
}
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
z.EncSendContainerState(codecSelfer_containerMapEnd1234)
}
}
}
}
func (x *PodPortForwardOptions) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
yym1 := z.DecBinary()
_ = yym1
if false {
} else if z.HasExtensions() && z.DecExt(x) {
} else {
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeMap1234 {
yyl2 := r.ReadMapStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
} else if yyct2 == codecSelferValueTypeArray1234 {
yyl2 := r.ReadArrayStart()
if yyl2 == 0 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
x.codecDecodeSelfFromArray(yyl2, d)
}
} else {
panic(codecSelferOnlyMapOrArrayEncodeToStructErr1234)
}
}
}
func (x *PodPortForwardOptions) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yys3Slc = z.DecScratchBuffer() // default slice to decode into
_ = yys3Slc
var yyhl3 bool = l >= 0
for yyj3 := 0; ; yyj3++ {
if yyhl3 {
if yyj3 >= l {
break
}
} else {
if r.CheckBreak() {
break
}
}
z.DecSendContainerState(codecSelfer_containerMapKey1234)
yys3Slc = r.DecodeBytes(yys3Slc, true, true)
yys3 := string(yys3Slc)
z.DecSendContainerState(codecSelfer_containerMapValue1234)
switch yys3 {
case "kind":
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
yyv4 := &x.Kind
yym5 := z.DecBinary()
_ = yym5
if false {
} else {
*((*string)(yyv4)) = r.DecodeString()
}
}
case "apiVersion":
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
yyv6 := &x.APIVersion
yym7 := z.DecBinary()
_ = yym7
if false {
} else {
*((*string)(yyv6)) = r.DecodeString()
}
}
case "ports":
if r.TryDecodeAsNil() {
x.Ports = nil
} else {
yyv8 := &x.Ports
yym9 := z.DecBinary()
_ = yym9
if false {
} else {
z.F.DecSliceInt32X(yyv8, false, d)
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
z.DecSendContainerState(codecSelfer_containerMapEnd1234)
}
func (x *PodPortForwardOptions) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj10 int
var yyb10 bool
var yyhl10 bool = l >= 0
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
yyv11 := &x.Kind
yym12 := z.DecBinary()
_ = yym12
if false {
} else {
*((*string)(yyv11)) = r.DecodeString()
}
}
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
yyv13 := &x.APIVersion
yym14 := z.DecBinary()
_ = yym14
if false {
} else {
*((*string)(yyv13)) = r.DecodeString()
}
}
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.Ports = nil
} else {
yyv15 := &x.Ports
yym16 := z.DecBinary()
_ = yym16
if false {
} else {
z.F.DecSliceInt32X(yyv15, false, d)
}
}
for {
yyj10++
if yyhl10 {
yyb10 = yyj10 > l
} else {
yyb10 = r.CheckBreak()
}
if yyb10 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj10-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}
func (x *PodProxyOptions) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1234
z, r := codec1978.GenHelperEncoder(e)

View File

@ -3423,6 +3423,21 @@ type PodExecOptions struct {
Command []string `json:"command" protobuf:"bytes,6,rep,name=command"`
}
// PodPortForwardOptions is the query options to a Pod's port forward call
// when using WebSockets.
// The `port` query parameter must specify the port or
// ports (comma separated) to forward over.
// Port forwarding over SPDY does not use these options. It requires the port
// to be passed in the `port` header as part of request.
type PodPortForwardOptions struct {
metav1.TypeMeta `json:",inline"`
// List of ports to forward
// Required when using WebSockets
// +optional
Ports []int32 `json:"ports,omitempty" protobuf:"varint,1,rep,name=ports"`
}
// PodProxyOptions is the query options to a Pod's proxy call.
type PodProxyOptions struct {
metav1.TypeMeta `json:",inline"`

View File

@ -1244,6 +1244,15 @@ func (PodLogOptions) SwaggerDoc() map[string]string {
return map_PodLogOptions
}
var map_PodPortForwardOptions = map[string]string{
"": "PodPortForwardOptions is the query options to a Pod's port forward call when using WebSockets. The `port` query parameter must specify the port or ports (comma separated) to forward over. Port forwarding over SPDY does not use these options. It requires the port to be passed in the `port` header as part of request.",
"ports": "List of ports to forward Required when using WebSockets",
}
func (PodPortForwardOptions) SwaggerDoc() map[string]string {
return map_PodPortForwardOptions
}
var map_PodProxyOptions = map[string]string{
"": "PodProxyOptions is the query options to a Pod's proxy call.",
"path": "Path is the URL path to use for the current proxy request to pod.",

View File

@ -251,6 +251,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
Convert_api_PodList_To_v1_PodList,
Convert_v1_PodLogOptions_To_api_PodLogOptions,
Convert_api_PodLogOptions_To_v1_PodLogOptions,
Convert_v1_PodPortForwardOptions_To_api_PodPortForwardOptions,
Convert_api_PodPortForwardOptions_To_v1_PodPortForwardOptions,
Convert_v1_PodProxyOptions_To_api_PodProxyOptions,
Convert_api_PodProxyOptions_To_v1_PodProxyOptions,
Convert_v1_PodSecurityContext_To_api_PodSecurityContext,
@ -2978,6 +2980,24 @@ func Convert_api_PodLogOptions_To_v1_PodLogOptions(in *api.PodLogOptions, out *P
return autoConvert_api_PodLogOptions_To_v1_PodLogOptions(in, out, s)
}
func autoConvert_v1_PodPortForwardOptions_To_api_PodPortForwardOptions(in *PodPortForwardOptions, out *api.PodPortForwardOptions, s conversion.Scope) error {
out.Ports = *(*[]int32)(unsafe.Pointer(&in.Ports))
return nil
}
func Convert_v1_PodPortForwardOptions_To_api_PodPortForwardOptions(in *PodPortForwardOptions, out *api.PodPortForwardOptions, s conversion.Scope) error {
return autoConvert_v1_PodPortForwardOptions_To_api_PodPortForwardOptions(in, out, s)
}
func autoConvert_api_PodPortForwardOptions_To_v1_PodPortForwardOptions(in *api.PodPortForwardOptions, out *PodPortForwardOptions, s conversion.Scope) error {
out.Ports = *(*[]int32)(unsafe.Pointer(&in.Ports))
return nil
}
func Convert_api_PodPortForwardOptions_To_v1_PodPortForwardOptions(in *api.PodPortForwardOptions, out *PodPortForwardOptions, s conversion.Scope) error {
return autoConvert_api_PodPortForwardOptions_To_v1_PodPortForwardOptions(in, out, s)
}
func autoConvert_v1_PodProxyOptions_To_api_PodProxyOptions(in *PodProxyOptions, out *api.PodProxyOptions, s conversion.Scope) error {
out.Path = in.Path
return nil

View File

@ -143,6 +143,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PodExecOptions, InType: reflect.TypeOf(&PodExecOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PodList, InType: reflect.TypeOf(&PodList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PodLogOptions, InType: reflect.TypeOf(&PodLogOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PodPortForwardOptions, InType: reflect.TypeOf(&PodPortForwardOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PodProxyOptions, InType: reflect.TypeOf(&PodProxyOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PodSecurityContext, InType: reflect.TypeOf(&PodSecurityContext{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1_PodSignature, InType: reflect.TypeOf(&PodSignature{})},
@ -2179,6 +2180,20 @@ func DeepCopy_v1_PodLogOptions(in interface{}, out interface{}, c *conversion.Cl
}
}
func DeepCopy_v1_PodPortForwardOptions(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PodPortForwardOptions)
out := out.(*PodPortForwardOptions)
*out = *in
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
*out = make([]int32, len(*in))
copy(*out, *in)
}
return nil
}
}
func DeepCopy_v1_PodProxyOptions(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PodProxyOptions)

View File

@ -146,6 +146,7 @@ func RegisterDeepCopies(scheme *runtime.Scheme) error {
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PodExecOptions, InType: reflect.TypeOf(&PodExecOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PodList, InType: reflect.TypeOf(&PodList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PodLogOptions, InType: reflect.TypeOf(&PodLogOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PodPortForwardOptions, InType: reflect.TypeOf(&PodPortForwardOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PodProxyOptions, InType: reflect.TypeOf(&PodProxyOptions{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PodSecurityContext, InType: reflect.TypeOf(&PodSecurityContext{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_api_PodSignature, InType: reflect.TypeOf(&PodSignature{})},
@ -2223,6 +2224,20 @@ func DeepCopy_api_PodLogOptions(in interface{}, out interface{}, c *conversion.C
}
}
func DeepCopy_api_PodPortForwardOptions(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PodPortForwardOptions)
out := out.(*PodPortForwardOptions)
*out = *in
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
*out = make([]int32, len(*in))
copy(*out, *in)
}
return nil
}
}
func DeepCopy_api_PodProxyOptions(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PodProxyOptions)

View File

@ -5883,6 +5883,44 @@ var OpenAPIDefinitions *openapi.OpenAPIDefinitions = &openapi.OpenAPIDefinitions
Dependencies: []string{
"v1.Time"},
},
"v1.PodPortForwardOptions": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Description: "PodPortForwardOptions is the query options to a Pod's port forward call when using WebSockets. The `port` query parameter must specify the port or ports (comma separated) to forward over. Port forwarding over SPDY does not use these options. It requires the port to be passed in the `port` header as part of request.",
Properties: map[string]spec.Schema{
"kind": {
SchemaProps: spec.SchemaProps{
Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
Type: []string{"string"},
Format: "",
},
},
"apiVersion": {
SchemaProps: spec.SchemaProps{
Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources",
Type: []string{"string"},
Format: "",
},
},
"ports": {
SchemaProps: spec.SchemaProps{
Description: "List of ports to forward Required when using WebSockets",
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"integer"},
Format: "int32",
},
},
},
},
},
},
},
},
Dependencies: []string{},
},
"v1.PodProxyOptions": {
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{