mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-07 12:11:43 +00:00
Merge pull request #5763 from smarterclayton/get_input_parameters_versioned
Expose versioned query parameters and make watch an operation on List
This commit is contained in:
@@ -19,6 +19,8 @@ package api
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
)
|
||||
@@ -28,12 +30,48 @@ import (
|
||||
var Codec = runtime.CodecFor(Scheme, "")
|
||||
|
||||
func init() {
|
||||
Scheme.AddDefaultingFuncs(
|
||||
func(obj *ListOptions) {
|
||||
obj.LabelSelector = labels.Everything()
|
||||
obj.FieldSelector = fields.Everything()
|
||||
},
|
||||
)
|
||||
Scheme.AddConversionFuncs(
|
||||
func(in *util.Time, out *util.Time, s conversion.Scope) error {
|
||||
// Cannot deep copy these, because time.Time has unexported fields.
|
||||
*out = *in
|
||||
return nil
|
||||
},
|
||||
func(in *string, out *labels.Selector, s conversion.Scope) error {
|
||||
selector, err := labels.Parse(*in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*out = selector
|
||||
return nil
|
||||
},
|
||||
func(in *string, out *fields.Selector, s conversion.Scope) error {
|
||||
selector, err := fields.ParseSelector(*in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*out = selector
|
||||
return nil
|
||||
},
|
||||
func(in *labels.Selector, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
*out = (*in).String()
|
||||
return nil
|
||||
},
|
||||
func(in *fields.Selector, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
*out = (*in).String()
|
||||
return nil
|
||||
},
|
||||
func(in *resource.Quantity, out *resource.Quantity, s conversion.Scope) error {
|
||||
// Cannot deep copy these, because inf.Dec has unexported fields.
|
||||
*out = *in.Copy()
|
||||
|
@@ -21,6 +21,8 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
@@ -63,6 +65,12 @@ var Semantic = conversion.EqualitiesOrDie(
|
||||
func(a, b util.Time) bool {
|
||||
return a.UTC() == b.UTC()
|
||||
},
|
||||
func(a, b labels.Selector) bool {
|
||||
return a.String() == b.String()
|
||||
},
|
||||
func(a, b fields.Selector) bool {
|
||||
return a.String() == b.String()
|
||||
},
|
||||
)
|
||||
|
||||
var standardResources = util.NewStringSet(
|
||||
|
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO: move everything in this file to pkg/api/rest
|
||||
package meta
|
||||
|
||||
import (
|
||||
|
@@ -38,10 +38,18 @@ func (fakeCodec) DecodeInto([]byte, runtime.Object) error {
|
||||
|
||||
type fakeConvertor struct{}
|
||||
|
||||
func (fakeConvertor) Convert(in, out interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fakeConvertor) ConvertToVersion(in runtime.Object, _ string) (runtime.Object, error) {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
func (fakeConvertor) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
|
||||
return label, value, nil
|
||||
}
|
||||
|
||||
var validCodec = fakeCodec{}
|
||||
var validAccessor = resourceAccessor{}
|
||||
var validConvertor = fakeConvertor{}
|
||||
|
@@ -52,11 +52,12 @@ func init() {
|
||||
&NamespaceList{},
|
||||
&Secret{},
|
||||
&SecretList{},
|
||||
&DeleteOptions{},
|
||||
&PersistentVolume{},
|
||||
&PersistentVolumeList{},
|
||||
&PersistentVolumeClaim{},
|
||||
&PersistentVolumeClaimList{},
|
||||
&DeleteOptions{},
|
||||
&ListOptions{},
|
||||
)
|
||||
// Legacy names are supported
|
||||
Scheme.AddKnownTypeWithName("", "Minion", &Node{})
|
||||
@@ -90,8 +91,9 @@ func (*Namespace) IsAnAPIObject() {}
|
||||
func (*NamespaceList) IsAnAPIObject() {}
|
||||
func (*Secret) IsAnAPIObject() {}
|
||||
func (*SecretList) IsAnAPIObject() {}
|
||||
func (*DeleteOptions) IsAnAPIObject() {}
|
||||
func (*PersistentVolume) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeList) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaim) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
||||
func (*DeleteOptions) IsAnAPIObject() {}
|
||||
func (*ListOptions) IsAnAPIObject() {}
|
||||
|
@@ -129,7 +129,7 @@ func TestList(t *testing.T) {
|
||||
}
|
||||
|
||||
var nonRoundTrippableTypes = util.NewStringSet("ContainerManifest", "ContainerManifestList")
|
||||
var nonInternalRoundTrippableTypes = util.NewStringSet("List")
|
||||
var nonInternalRoundTrippableTypes = util.NewStringSet("List", "ListOptions")
|
||||
|
||||
func TestRoundTripTypes(t *testing.T) {
|
||||
// api.Scheme.Log(t)
|
||||
|
@@ -23,6 +23,8 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
@@ -87,6 +89,11 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
|
||||
j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10)
|
||||
j.SelfLink = c.RandString()
|
||||
},
|
||||
func(j *api.ListOptions, c fuzz.Continue) {
|
||||
// TODO: add some parsing
|
||||
j.LabelSelector, _ = labels.Parse("a=b")
|
||||
j.FieldSelector, _ = fields.ParseSelector("a=b")
|
||||
},
|
||||
func(j *api.PodPhase, c fuzz.Continue) {
|
||||
statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown}
|
||||
*j = statuses[c.Rand.Intn(len(statuses))]
|
||||
|
@@ -18,6 +18,8 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
@@ -1201,6 +1203,21 @@ type DeleteOptions struct {
|
||||
GracePeriodSeconds *int64 `json:"gracePeriodSeconds"`
|
||||
}
|
||||
|
||||
// ListOptions is the query options to a standard REST list call, and has future support for
|
||||
// watch calls.
|
||||
type ListOptions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
|
||||
// A selector based on labels
|
||||
LabelSelector labels.Selector
|
||||
// A selector based on fields
|
||||
FieldSelector fields.Selector
|
||||
// If true, watch for changes to this list
|
||||
Watch bool
|
||||
// The resource version to watch (no effect on list yet)
|
||||
ResourceVersion string
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
// TODO: this could go in apiserver, but I'm including it here so clients needn't
|
||||
// import both.
|
||||
|
@@ -40,18 +40,20 @@ func PreV1Beta3(version string) bool {
|
||||
return version == "v1beta1" || version == "v1beta2"
|
||||
}
|
||||
|
||||
// TODO: remove me when watch is refactored
|
||||
func LabelSelectorQueryParam(version string) string {
|
||||
if PreV1Beta3(version) {
|
||||
return "labels"
|
||||
}
|
||||
return "label-selector"
|
||||
return "labelSelector"
|
||||
}
|
||||
|
||||
// TODO: remove me when watch is refactored
|
||||
func FieldSelectorQueryParam(version string) string {
|
||||
if PreV1Beta3(version) {
|
||||
return "fields"
|
||||
}
|
||||
return "field-selector"
|
||||
return "fieldSelector"
|
||||
}
|
||||
|
||||
// String returns available api versions as a human-friendly version string.
|
||||
|
@@ -1493,7 +1493,7 @@ func init() {
|
||||
}
|
||||
|
||||
// Add field conversion funcs.
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "pods",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Pod",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "name":
|
||||
@@ -1513,7 +1513,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "replicationControllers",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "ReplicationController",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "name":
|
||||
@@ -1528,7 +1528,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "events",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Event",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "involvedObject.kind",
|
||||
@@ -1550,7 +1550,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "namespaces",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Namespace",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "status.phase":
|
||||
|
@@ -59,11 +59,12 @@ func init() {
|
||||
&NamespaceList{},
|
||||
&Secret{},
|
||||
&SecretList{},
|
||||
&DeleteOptions{},
|
||||
&PersistentVolume{},
|
||||
&PersistentVolumeList{},
|
||||
&PersistentVolumeClaim{},
|
||||
&PersistentVolumeClaimList{},
|
||||
&DeleteOptions{},
|
||||
&ListOptions{},
|
||||
)
|
||||
// Future names are supported
|
||||
api.Scheme.AddKnownTypeWithName("v1beta1", "Node", &Minion{})
|
||||
@@ -97,8 +98,9 @@ func (*Namespace) IsAnAPIObject() {}
|
||||
func (*NamespaceList) IsAnAPIObject() {}
|
||||
func (*Secret) IsAnAPIObject() {}
|
||||
func (*SecretList) IsAnAPIObject() {}
|
||||
func (*DeleteOptions) IsAnAPIObject() {}
|
||||
func (*PersistentVolume) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeList) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaim) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
||||
func (*DeleteOptions) IsAnAPIObject() {}
|
||||
func (*ListOptions) IsAnAPIObject() {}
|
||||
|
@@ -1034,6 +1034,20 @@ type DeleteOptions struct {
|
||||
GracePeriodSeconds *int64 `json:"gracePeriodSeconds" description:"the duration in seconds to wait before deleting this object; defaults to a per object value if not specified; zero means delete immediately"`
|
||||
}
|
||||
|
||||
// ListOptions is the query options to a standard REST list call
|
||||
type ListOptions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
|
||||
// A selector based on labels
|
||||
LabelSelector string `json:"labels" description:"a selector to restrict the list of returned objects by their labels; defaults to everything"`
|
||||
// A selector based on fields
|
||||
FieldSelector string `json:"fields" description:"a selector to restrict the list of returned objects by their fields; defaults to everything"`
|
||||
// If true, watch for changes to the selected resources
|
||||
Watch bool `json:"watch" description:"watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion"`
|
||||
// The desired resource version to watch
|
||||
ResourceVersion string `json:"resourceVersion" description:"when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history"`
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
// TODO: this could go in apiserver, but I'm including it here so clients needn't
|
||||
// import both.
|
||||
|
@@ -1419,7 +1419,7 @@ func init() {
|
||||
}
|
||||
|
||||
// Add field conversion funcs.
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "pods",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "Pod",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "name":
|
||||
@@ -1439,7 +1439,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "replicationControllers",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "ReplicationController",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "name":
|
||||
@@ -1454,7 +1454,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "events",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "Event",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "involvedObject.kind",
|
||||
@@ -1476,7 +1476,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "namespaces",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Namespace",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "status.phase":
|
||||
|
@@ -59,11 +59,12 @@ func init() {
|
||||
&NamespaceList{},
|
||||
&Secret{},
|
||||
&SecretList{},
|
||||
&DeleteOptions{},
|
||||
&PersistentVolume{},
|
||||
&PersistentVolumeList{},
|
||||
&PersistentVolumeClaim{},
|
||||
&PersistentVolumeClaimList{},
|
||||
&DeleteOptions{},
|
||||
&ListOptions{},
|
||||
)
|
||||
// Future names are supported
|
||||
api.Scheme.AddKnownTypeWithName("v1beta2", "Node", &Minion{})
|
||||
@@ -102,3 +103,4 @@ func (*PersistentVolumeList) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaim) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
||||
func (*DeleteOptions) IsAnAPIObject() {}
|
||||
func (*ListOptions) IsAnAPIObject() {}
|
||||
|
@@ -1048,6 +1048,20 @@ type DeleteOptions struct {
|
||||
GracePeriodSeconds *int64 `json:"gracePeriodSeconds" description:"the duration in seconds to wait before deleting this object; defaults to a per object value if not specified; zero means delete immediately"`
|
||||
}
|
||||
|
||||
// ListOptions is the query options to a standard REST list call
|
||||
type ListOptions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
|
||||
// A selector based on labels
|
||||
LabelSelector string `json:"labels" description:"a selector to restrict the list of returned objects by their labels; defaults to everything"`
|
||||
// A selector based on fields
|
||||
FieldSelector string `json:"fields" description:"a selector to restrict the list of returned objects by their fields; defaults to everything"`
|
||||
// If true, watch for changes to the selected resources
|
||||
Watch bool `json:"watch" description:"watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion"`
|
||||
// The desired resource version to watch
|
||||
ResourceVersion string `json:"resourceVersion" description:"when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history"`
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
// TODO: this could go in apiserver, but I'm including it here so clients needn't
|
||||
// import both.
|
||||
|
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
func init() {
|
||||
// Add field conversion funcs.
|
||||
err := newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "pods",
|
||||
err := newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "Pod",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "name",
|
||||
@@ -39,7 +39,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "replicationControllers",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "ReplicationController",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "name":
|
||||
@@ -54,7 +54,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "events",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "Event",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "involvedObject.kind",
|
||||
@@ -75,7 +75,7 @@ func init() {
|
||||
// If one of the conversion functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "namespaces",
|
||||
err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Namespace",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "status.phase":
|
||||
|
@@ -53,11 +53,12 @@ func init() {
|
||||
&NamespaceList{},
|
||||
&Secret{},
|
||||
&SecretList{},
|
||||
&DeleteOptions{},
|
||||
&PersistentVolume{},
|
||||
&PersistentVolumeList{},
|
||||
&PersistentVolumeClaim{},
|
||||
&PersistentVolumeClaimList{},
|
||||
&DeleteOptions{},
|
||||
&ListOptions{},
|
||||
)
|
||||
// Legacy names are supported
|
||||
api.Scheme.AddKnownTypeWithName("v1beta3", "Minion", &Node{})
|
||||
@@ -96,3 +97,4 @@ func (*PersistentVolumeList) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaim) IsAnAPIObject() {}
|
||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
|
||||
func (*DeleteOptions) IsAnAPIObject() {}
|
||||
func (*ListOptions) IsAnAPIObject() {}
|
||||
|
@@ -1190,6 +1190,20 @@ type DeleteOptions struct {
|
||||
GracePeriodSeconds *int64 `json:"gracePeriodSeconds" description:"the duration in seconds to wait before deleting this object; defaults to a per object value if not specified; zero means delete immediately"`
|
||||
}
|
||||
|
||||
// ListOptions is the query options to a standard REST list call
|
||||
type ListOptions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
|
||||
// A selector based on labels
|
||||
LabelSelector string `json:"labelSelector" description:"a selector to restrict the list of returned objects by their labels; defaults to everything"`
|
||||
// A selector based on fields
|
||||
FieldSelector string `json:"fieldSelector" description:"a selector to restrict the list of returned objects by their fields; defaults to everything"`
|
||||
// If true, watch for changes to the selected resources
|
||||
Watch bool `json:"watch" description:"watch for changes to the described resources and return them as a stream of add, update, and remove notifications; specify resourceVersion"`
|
||||
// The desired resource version to watch
|
||||
ResourceVersion string `json:"resourceVersion" description:"when specified with a watch call, shows changes that occur after that particular version of a resource; defaults to changes from the beginning of history"`
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
type Status struct {
|
||||
TypeMeta `json:",inline"`
|
||||
|
Reference in New Issue
Block a user