mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Convert List query parameters via object conversion
Convert url.Values -> an object, with appropriate versioning. ListOptions should also expose parameter names to swagger.
This commit is contained in:
		@@ -43,6 +43,16 @@ kube::util::wait_for_url() {
 | 
				
			|||||||
  return 1
 | 
					  return 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Create a temp dir that'll be deleted at the end of this bash session.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Vars set:
 | 
				
			||||||
 | 
					#   KUBE_TEMP
 | 
				
			||||||
 | 
					kube::util::ensure-temp-dir() {
 | 
				
			||||||
 | 
					  if [[ -z ${KUBE_TEMP-} ]]; then
 | 
				
			||||||
 | 
					    KUBE_TEMP=$(mktemp -d -t kubernetes.XXXXXX)
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This figures out the host platform without relying on golang.  We need this as
 | 
					# This figures out the host platform without relying on golang.  We need this as
 | 
				
			||||||
# we don't want a golang install to be a prerequisite to building yet we need
 | 
					# we don't want a golang install to be a prerequisite to building yet we need
 | 
				
			||||||
# this info to figure out where the final binaries are placed.
 | 
					# this info to figure out where the final binaries are placed.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,12 +33,14 @@ function cleanup()
 | 
				
			|||||||
    [[ -n ${PROXY_PID-} ]] && kill ${PROXY_PID} 1>&2 2>/dev/null
 | 
					    [[ -n ${PROXY_PID-} ]] && kill ${PROXY_PID} 1>&2 2>/dev/null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    kube::etcd::cleanup
 | 
					    kube::etcd::cleanup
 | 
				
			||||||
 | 
					    rm -rf "${KUBE_TEMP}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    kube::log::status "Clean up complete"
 | 
					    kube::log::status "Clean up complete"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
trap cleanup EXIT SIGINT
 | 
					trap cleanup EXIT SIGINT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					kube::util::ensure-temp-dir
 | 
				
			||||||
kube::etcd::start
 | 
					kube::etcd::start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ETCD_HOST=${ETCD_HOST:-127.0.0.1}
 | 
					ETCD_HOST=${ETCD_HOST:-127.0.0.1}
 | 
				
			||||||
@@ -533,6 +535,7 @@ __EOF__
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  kube::test::describe_object_assert nodes "127.0.0.1" "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
 | 
					  kube::test::describe_object_assert nodes "127.0.0.1" "Name:" "Labels:" "CreationTimestamp:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ###########
 | 
					  ###########
 | 
				
			||||||
  # Minions #
 | 
					  # Minions #
 | 
				
			||||||
  ###########
 | 
					  ###########
 | 
				
			||||||
@@ -548,6 +551,7 @@ __EOF__
 | 
				
			|||||||
    kube::test::describe_object_assert minions "127.0.0.1" "Name:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
 | 
					    kube::test::describe_object_assert minions "127.0.0.1" "Name:" "Conditions:" "Addresses:" "Capacity:" "Pods:"
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #####################
 | 
					  #####################
 | 
				
			||||||
  # Retrieve multiple #
 | 
					  # Retrieve multiple #
 | 
				
			||||||
  #####################
 | 
					  #####################
 | 
				
			||||||
@@ -555,6 +559,19 @@ __EOF__
 | 
				
			|||||||
  kube::log::status "Testing kubectl(${version}:multiget)"
 | 
					  kube::log::status "Testing kubectl(${version}:multiget)"
 | 
				
			||||||
  kube::test::get_object_assert 'nodes/127.0.0.1 service/kubernetes' "{{range.items}}{{.$id_field}}:{{end}}" '127.0.0.1:kubernetes:'
 | 
					  kube::test::get_object_assert 'nodes/127.0.0.1 service/kubernetes' "{{range.items}}{{.$id_field}}:{{end}}" '127.0.0.1:kubernetes:'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ###########
 | 
				
			||||||
 | 
					  # Swagger #
 | 
				
			||||||
 | 
					  ###########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if [[ -n "${version}" ]]; then
 | 
				
			||||||
 | 
					    # Verify schema
 | 
				
			||||||
 | 
					    file="${KUBE_TEMP}/schema-${version}.json"
 | 
				
			||||||
 | 
					    curl -s "http://127.0.0.1:${API_PORT}/swaggerapi/api/${version}" > "${file}"
 | 
				
			||||||
 | 
					    [[ "$(grep "list of returned" "${file}")" ]]
 | 
				
			||||||
 | 
					    [[ "$(grep "list of pods" "${file}")" ]]
 | 
				
			||||||
 | 
					  fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  kube::test::clear_all
 | 
					  kube::test::clear_all
 | 
				
			||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,8 @@ package api
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
						"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/runtime"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -28,12 +30,48 @@ import (
 | 
				
			|||||||
var Codec = runtime.CodecFor(Scheme, "")
 | 
					var Codec = runtime.CodecFor(Scheme, "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
 | 
						Scheme.AddDefaultingFuncs(
 | 
				
			||||||
 | 
							func(obj *ListOptions) {
 | 
				
			||||||
 | 
								obj.LabelSelector = labels.Everything()
 | 
				
			||||||
 | 
								obj.FieldSelector = fields.Everything()
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
	Scheme.AddConversionFuncs(
 | 
						Scheme.AddConversionFuncs(
 | 
				
			||||||
		func(in *util.Time, out *util.Time, s conversion.Scope) error {
 | 
							func(in *util.Time, out *util.Time, s conversion.Scope) error {
 | 
				
			||||||
			// Cannot deep copy these, because time.Time has unexported fields.
 | 
								// Cannot deep copy these, because time.Time has unexported fields.
 | 
				
			||||||
			*out = *in
 | 
								*out = *in
 | 
				
			||||||
			return nil
 | 
								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 {
 | 
							func(in *resource.Quantity, out *resource.Quantity, s conversion.Scope) error {
 | 
				
			||||||
			// Cannot deep copy these, because inf.Dec has unexported fields.
 | 
								// Cannot deep copy these, because inf.Dec has unexported fields.
 | 
				
			||||||
			*out = *in.Copy()
 | 
								*out = *in.Copy()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,8 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
						"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/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/davecgh/go-spew/spew"
 | 
						"github.com/davecgh/go-spew/spew"
 | 
				
			||||||
@@ -63,6 +65,12 @@ var Semantic = conversion.EqualitiesOrDie(
 | 
				
			|||||||
	func(a, b util.Time) bool {
 | 
						func(a, b util.Time) bool {
 | 
				
			||||||
		return a.UTC() == b.UTC()
 | 
							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(
 | 
					var standardResources = util.NewStringSet(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: move everything in this file to pkg/api/rest
 | 
				
			||||||
package meta
 | 
					package meta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,10 +38,18 @@ func (fakeCodec) DecodeInto([]byte, runtime.Object) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type fakeConvertor struct{}
 | 
					type fakeConvertor struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (fakeConvertor) Convert(in, out interface{}) error {
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (fakeConvertor) ConvertToVersion(in runtime.Object, _ string) (runtime.Object, error) {
 | 
					func (fakeConvertor) ConvertToVersion(in runtime.Object, _ string) (runtime.Object, error) {
 | 
				
			||||||
	return in, nil
 | 
						return in, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (fakeConvertor) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
 | 
				
			||||||
 | 
						return label, value, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var validCodec = fakeCodec{}
 | 
					var validCodec = fakeCodec{}
 | 
				
			||||||
var validAccessor = resourceAccessor{}
 | 
					var validAccessor = resourceAccessor{}
 | 
				
			||||||
var validConvertor = fakeConvertor{}
 | 
					var validConvertor = fakeConvertor{}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,11 +52,12 @@ func init() {
 | 
				
			|||||||
		&NamespaceList{},
 | 
							&NamespaceList{},
 | 
				
			||||||
		&Secret{},
 | 
							&Secret{},
 | 
				
			||||||
		&SecretList{},
 | 
							&SecretList{},
 | 
				
			||||||
		&DeleteOptions{},
 | 
					 | 
				
			||||||
		&PersistentVolume{},
 | 
							&PersistentVolume{},
 | 
				
			||||||
		&PersistentVolumeList{},
 | 
							&PersistentVolumeList{},
 | 
				
			||||||
		&PersistentVolumeClaim{},
 | 
							&PersistentVolumeClaim{},
 | 
				
			||||||
		&PersistentVolumeClaimList{},
 | 
							&PersistentVolumeClaimList{},
 | 
				
			||||||
 | 
							&DeleteOptions{},
 | 
				
			||||||
 | 
							&ListOptions{},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// Legacy names are supported
 | 
						// Legacy names are supported
 | 
				
			||||||
	Scheme.AddKnownTypeWithName("", "Minion", &Node{})
 | 
						Scheme.AddKnownTypeWithName("", "Minion", &Node{})
 | 
				
			||||||
@@ -90,8 +91,9 @@ func (*Namespace) IsAnAPIObject()                 {}
 | 
				
			|||||||
func (*NamespaceList) IsAnAPIObject()             {}
 | 
					func (*NamespaceList) IsAnAPIObject()             {}
 | 
				
			||||||
func (*Secret) IsAnAPIObject()                    {}
 | 
					func (*Secret) IsAnAPIObject()                    {}
 | 
				
			||||||
func (*SecretList) IsAnAPIObject()                {}
 | 
					func (*SecretList) IsAnAPIObject()                {}
 | 
				
			||||||
func (*DeleteOptions) IsAnAPIObject()             {}
 | 
					 | 
				
			||||||
func (*PersistentVolume) IsAnAPIObject()          {}
 | 
					func (*PersistentVolume) IsAnAPIObject()          {}
 | 
				
			||||||
func (*PersistentVolumeList) IsAnAPIObject()      {}
 | 
					func (*PersistentVolumeList) IsAnAPIObject()      {}
 | 
				
			||||||
func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
					func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
				
			||||||
func (*PersistentVolumeClaimList) 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 nonRoundTrippableTypes = util.NewStringSet("ContainerManifest", "ContainerManifestList")
 | 
				
			||||||
var nonInternalRoundTrippableTypes = util.NewStringSet("List")
 | 
					var nonInternalRoundTrippableTypes = util.NewStringSet("List", "ListOptions")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestRoundTripTypes(t *testing.T) {
 | 
					func TestRoundTripTypes(t *testing.T) {
 | 
				
			||||||
	// api.Scheme.Log(t)
 | 
						// api.Scheme.Log(t)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,8 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
						"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/runtime"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
@@ -88,6 +90,11 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
 | 
				
			|||||||
			j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10)
 | 
								j.ResourceVersion = strconv.FormatUint(c.RandUint64(), 10)
 | 
				
			||||||
			j.SelfLink = c.RandString()
 | 
								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) {
 | 
							func(j *api.PodPhase, c fuzz.Continue) {
 | 
				
			||||||
			statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown}
 | 
								statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown}
 | 
				
			||||||
			*j = statuses[c.Rand.Intn(len(statuses))]
 | 
								*j = statuses[c.Rand.Intn(len(statuses))]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,8 @@ package api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
 | 
						"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/runtime"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
 | 
				
			||||||
@@ -1168,6 +1170,16 @@ type DeleteOptions struct {
 | 
				
			|||||||
	GracePeriodSeconds *int64 `json:"gracePeriodSeconds"`
 | 
						GracePeriodSeconds *int64 `json:"gracePeriodSeconds"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ListOptions is the query options to a standard REST list call
 | 
				
			||||||
 | 
					type ListOptions struct {
 | 
				
			||||||
 | 
						TypeMeta `json:",inline"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// A selector based on labels
 | 
				
			||||||
 | 
						LabelSelector labels.Selector
 | 
				
			||||||
 | 
						// A selector based on fields
 | 
				
			||||||
 | 
						FieldSelector fields.Selector
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Status is a return value for calls that don't return other objects.
 | 
					// 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
 | 
					// TODO: this could go in apiserver, but I'm including it here so clients needn't
 | 
				
			||||||
// import both.
 | 
					// import both.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,18 +40,20 @@ func PreV1Beta3(version string) bool {
 | 
				
			|||||||
	return version == "v1beta1" || version == "v1beta2"
 | 
						return version == "v1beta1" || version == "v1beta2"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: remove me when watch is refactored
 | 
				
			||||||
func LabelSelectorQueryParam(version string) string {
 | 
					func LabelSelectorQueryParam(version string) string {
 | 
				
			||||||
	if PreV1Beta3(version) {
 | 
						if PreV1Beta3(version) {
 | 
				
			||||||
		return "labels"
 | 
							return "labels"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return "label-selector"
 | 
						return "labelSelector"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: remove me when watch is refactored
 | 
				
			||||||
func FieldSelectorQueryParam(version string) string {
 | 
					func FieldSelectorQueryParam(version string) string {
 | 
				
			||||||
	if PreV1Beta3(version) {
 | 
						if PreV1Beta3(version) {
 | 
				
			||||||
		return "fields"
 | 
							return "fields"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return "field-selector"
 | 
						return "fieldSelector"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// String returns available api versions as a human-friendly version string.
 | 
					// String returns available api versions as a human-friendly version string.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1494,7 +1494,7 @@ func init() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add field conversion funcs.
 | 
						// Add field conversion funcs.
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "pods",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Pod",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "name":
 | 
								case "name":
 | 
				
			||||||
@@ -1514,7 +1514,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "replicationControllers",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "ReplicationController",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "name":
 | 
								case "name":
 | 
				
			||||||
@@ -1529,7 +1529,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "events",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Event",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "involvedObject.kind",
 | 
								case "involvedObject.kind",
 | 
				
			||||||
@@ -1551,7 +1551,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "namespaces",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Namespace",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "status.phase":
 | 
								case "status.phase":
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,11 +59,12 @@ func init() {
 | 
				
			|||||||
		&NamespaceList{},
 | 
							&NamespaceList{},
 | 
				
			||||||
		&Secret{},
 | 
							&Secret{},
 | 
				
			||||||
		&SecretList{},
 | 
							&SecretList{},
 | 
				
			||||||
		&DeleteOptions{},
 | 
					 | 
				
			||||||
		&PersistentVolume{},
 | 
							&PersistentVolume{},
 | 
				
			||||||
		&PersistentVolumeList{},
 | 
							&PersistentVolumeList{},
 | 
				
			||||||
		&PersistentVolumeClaim{},
 | 
							&PersistentVolumeClaim{},
 | 
				
			||||||
		&PersistentVolumeClaimList{},
 | 
							&PersistentVolumeClaimList{},
 | 
				
			||||||
 | 
							&DeleteOptions{},
 | 
				
			||||||
 | 
							&ListOptions{},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// Future names are supported
 | 
						// Future names are supported
 | 
				
			||||||
	api.Scheme.AddKnownTypeWithName("v1beta1", "Node", &Minion{})
 | 
						api.Scheme.AddKnownTypeWithName("v1beta1", "Node", &Minion{})
 | 
				
			||||||
@@ -97,8 +98,9 @@ func (*Namespace) IsAnAPIObject()                 {}
 | 
				
			|||||||
func (*NamespaceList) IsAnAPIObject()             {}
 | 
					func (*NamespaceList) IsAnAPIObject()             {}
 | 
				
			||||||
func (*Secret) IsAnAPIObject()                    {}
 | 
					func (*Secret) IsAnAPIObject()                    {}
 | 
				
			||||||
func (*SecretList) IsAnAPIObject()                {}
 | 
					func (*SecretList) IsAnAPIObject()                {}
 | 
				
			||||||
func (*DeleteOptions) IsAnAPIObject()             {}
 | 
					 | 
				
			||||||
func (*PersistentVolume) IsAnAPIObject()          {}
 | 
					func (*PersistentVolume) IsAnAPIObject()          {}
 | 
				
			||||||
func (*PersistentVolumeList) IsAnAPIObject()      {}
 | 
					func (*PersistentVolumeList) IsAnAPIObject()      {}
 | 
				
			||||||
func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
					func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
				
			||||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
 | 
					func (*PersistentVolumeClaimList) IsAnAPIObject() {}
 | 
				
			||||||
 | 
					func (*DeleteOptions) IsAnAPIObject()             {}
 | 
				
			||||||
 | 
					func (*ListOptions) IsAnAPIObject()               {}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -985,6 +985,16 @@ 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"`
 | 
						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"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Status is a return value for calls that don't return other objects.
 | 
					// 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
 | 
					// TODO: this could go in apiserver, but I'm including it here so clients needn't
 | 
				
			||||||
// import both.
 | 
					// import both.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1420,7 +1420,7 @@ func init() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add field conversion funcs.
 | 
						// Add field conversion funcs.
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "pods",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "Pod",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "name":
 | 
								case "name":
 | 
				
			||||||
@@ -1440,7 +1440,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "replicationControllers",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "ReplicationController",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "name":
 | 
								case "name":
 | 
				
			||||||
@@ -1455,7 +1455,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "events",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta2", "Event",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "involvedObject.kind",
 | 
								case "involvedObject.kind",
 | 
				
			||||||
@@ -1477,7 +1477,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "namespaces",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Namespace",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "status.phase":
 | 
								case "status.phase":
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,11 +59,12 @@ func init() {
 | 
				
			|||||||
		&NamespaceList{},
 | 
							&NamespaceList{},
 | 
				
			||||||
		&Secret{},
 | 
							&Secret{},
 | 
				
			||||||
		&SecretList{},
 | 
							&SecretList{},
 | 
				
			||||||
		&DeleteOptions{},
 | 
					 | 
				
			||||||
		&PersistentVolume{},
 | 
							&PersistentVolume{},
 | 
				
			||||||
		&PersistentVolumeList{},
 | 
							&PersistentVolumeList{},
 | 
				
			||||||
		&PersistentVolumeClaim{},
 | 
							&PersistentVolumeClaim{},
 | 
				
			||||||
		&PersistentVolumeClaimList{},
 | 
							&PersistentVolumeClaimList{},
 | 
				
			||||||
 | 
							&DeleteOptions{},
 | 
				
			||||||
 | 
							&ListOptions{},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// Future names are supported
 | 
						// Future names are supported
 | 
				
			||||||
	api.Scheme.AddKnownTypeWithName("v1beta2", "Node", &Minion{})
 | 
						api.Scheme.AddKnownTypeWithName("v1beta2", "Node", &Minion{})
 | 
				
			||||||
@@ -102,3 +103,4 @@ func (*PersistentVolumeList) IsAnAPIObject()      {}
 | 
				
			|||||||
func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
					func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
				
			||||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
 | 
					func (*PersistentVolumeClaimList) IsAnAPIObject() {}
 | 
				
			||||||
func (*DeleteOptions) IsAnAPIObject()             {}
 | 
					func (*DeleteOptions) IsAnAPIObject()             {}
 | 
				
			||||||
 | 
					func (*ListOptions) IsAnAPIObject()               {}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -999,6 +999,16 @@ 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"`
 | 
						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"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Status is a return value for calls that don't return other objects.
 | 
					// 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
 | 
					// TODO: this could go in apiserver, but I'm including it here so clients needn't
 | 
				
			||||||
// import both.
 | 
					// import both.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	// Add field conversion funcs.
 | 
						// Add field conversion funcs.
 | 
				
			||||||
	err := newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "pods",
 | 
						err := newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "Pod",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "name",
 | 
								case "name",
 | 
				
			||||||
@@ -39,7 +39,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "replicationControllers",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "ReplicationController",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "name":
 | 
								case "name":
 | 
				
			||||||
@@ -54,7 +54,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "events",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta3", "Event",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "involvedObject.kind",
 | 
								case "involvedObject.kind",
 | 
				
			||||||
@@ -75,7 +75,7 @@ func init() {
 | 
				
			|||||||
		// If one of the conversion functions is malformed, detect it immediately.
 | 
							// If one of the conversion functions is malformed, detect it immediately.
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "namespaces",
 | 
						err = newer.Scheme.AddFieldLabelConversionFunc("v1beta1", "Namespace",
 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
			switch label {
 | 
								switch label {
 | 
				
			||||||
			case "status.phase":
 | 
								case "status.phase":
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,11 +53,12 @@ func init() {
 | 
				
			|||||||
		&NamespaceList{},
 | 
							&NamespaceList{},
 | 
				
			||||||
		&Secret{},
 | 
							&Secret{},
 | 
				
			||||||
		&SecretList{},
 | 
							&SecretList{},
 | 
				
			||||||
		&DeleteOptions{},
 | 
					 | 
				
			||||||
		&PersistentVolume{},
 | 
							&PersistentVolume{},
 | 
				
			||||||
		&PersistentVolumeList{},
 | 
							&PersistentVolumeList{},
 | 
				
			||||||
		&PersistentVolumeClaim{},
 | 
							&PersistentVolumeClaim{},
 | 
				
			||||||
		&PersistentVolumeClaimList{},
 | 
							&PersistentVolumeClaimList{},
 | 
				
			||||||
 | 
							&DeleteOptions{},
 | 
				
			||||||
 | 
							&ListOptions{},
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// Legacy names are supported
 | 
						// Legacy names are supported
 | 
				
			||||||
	api.Scheme.AddKnownTypeWithName("v1beta3", "Minion", &Node{})
 | 
						api.Scheme.AddKnownTypeWithName("v1beta3", "Minion", &Node{})
 | 
				
			||||||
@@ -96,3 +97,4 @@ func (*PersistentVolumeList) IsAnAPIObject()      {}
 | 
				
			|||||||
func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
					func (*PersistentVolumeClaim) IsAnAPIObject()     {}
 | 
				
			||||||
func (*PersistentVolumeClaimList) IsAnAPIObject() {}
 | 
					func (*PersistentVolumeClaimList) IsAnAPIObject() {}
 | 
				
			||||||
func (*DeleteOptions) IsAnAPIObject()             {}
 | 
					func (*DeleteOptions) IsAnAPIObject()             {}
 | 
				
			||||||
 | 
					func (*ListOptions) IsAnAPIObject()               {}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1158,6 +1158,16 @@ 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"`
 | 
						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"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Status is a return value for calls that don't return other objects.
 | 
					// Status is a return value for calls that don't return other objects.
 | 
				
			||||||
type Status struct {
 | 
					type Status struct {
 | 
				
			||||||
	TypeMeta `json:",inline"`
 | 
						TypeMeta `json:",inline"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,6 +29,7 @@ import (
 | 
				
			|||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/emicklei/go-restful"
 | 
						"github.com/emicklei/go-restful"
 | 
				
			||||||
@@ -60,10 +61,12 @@ func (a *APIInstaller) Install() (ws *restful.WebService, errors []error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Initialize the custom handlers.
 | 
						// Initialize the custom handlers.
 | 
				
			||||||
	watchHandler := (&WatchHandler{
 | 
						watchHandler := (&WatchHandler{
 | 
				
			||||||
		storage: a.group.Storage,
 | 
							storage:   a.group.Storage,
 | 
				
			||||||
		codec:   a.group.Codec,
 | 
							mapper:    a.group.Mapper,
 | 
				
			||||||
		linker:  a.group.Linker,
 | 
							convertor: a.group.Convertor,
 | 
				
			||||||
		info:    a.info,
 | 
							codec:     a.group.Codec,
 | 
				
			||||||
 | 
							linker:    a.group.Linker,
 | 
				
			||||||
 | 
							info:      a.info,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	redirectHandler := (&RedirectHandler{a.group.Storage, a.group.Codec, a.group.Context, a.info})
 | 
						redirectHandler := (&RedirectHandler{a.group.Storage, a.group.Codec, a.group.Context, a.info})
 | 
				
			||||||
	proxyHandler := (&ProxyHandler{a.prefix + "/proxy/", a.group.Storage, a.group.Codec, a.group.Context, a.info})
 | 
						proxyHandler := (&ProxyHandler{a.prefix + "/proxy/", a.group.Storage, a.group.Codec, a.group.Context, a.info})
 | 
				
			||||||
@@ -99,6 +102,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
 | 
				
			|||||||
	admit := a.group.Admit
 | 
						admit := a.group.Admit
 | 
				
			||||||
	context := a.group.Context
 | 
						context := a.group.Context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						serverVersion := a.group.ServerVersion
 | 
				
			||||||
 | 
						if len(serverVersion) == 0 {
 | 
				
			||||||
 | 
							serverVersion = a.group.Version
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var resource, subresource string
 | 
						var resource, subresource string
 | 
				
			||||||
	switch parts := strings.Split(path, "/"); len(parts) {
 | 
						switch parts := strings.Split(path, "/"); len(parts) {
 | 
				
			||||||
	case 2:
 | 
						case 2:
 | 
				
			||||||
@@ -152,10 +160,15 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
 | 
				
			|||||||
		storageMeta = defaultStorageMetadata{}
 | 
							storageMeta = defaultStorageMetadata{}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						versionedListOptions, err := a.group.Creater.New(serverVersion, "ListOptions")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var versionedDeleterObject runtime.Object
 | 
						var versionedDeleterObject runtime.Object
 | 
				
			||||||
	switch {
 | 
						switch {
 | 
				
			||||||
	case isGracefulDeleter:
 | 
						case isGracefulDeleter:
 | 
				
			||||||
		object, err := a.group.Creater.New(a.group.Version, "DeleteOptions")
 | 
							object, err := a.group.Creater.New(serverVersion, "DeleteOptions")
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -288,11 +301,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
 | 
				
			|||||||
	// test/integration/auth_test.go is currently the most comprehensive status code test
 | 
						// test/integration/auth_test.go is currently the most comprehensive status code test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reqScope := RequestScope{
 | 
						reqScope := RequestScope{
 | 
				
			||||||
		ContextFunc: ctxFn,
 | 
							ContextFunc:      ctxFn,
 | 
				
			||||||
		Codec:       mapping.Codec,
 | 
							Creater:          a.group.Creater,
 | 
				
			||||||
		APIVersion:  a.group.Version,
 | 
							Convertor:        a.group.Convertor,
 | 
				
			||||||
		Resource:    resource,
 | 
							Codec:            mapping.Codec,
 | 
				
			||||||
		Kind:        kind,
 | 
							APIVersion:       a.group.Version,
 | 
				
			||||||
 | 
							ServerAPIVersion: serverVersion,
 | 
				
			||||||
 | 
							Resource:         resource,
 | 
				
			||||||
 | 
							Kind:             kind,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, action := range actions {
 | 
						for _, action := range actions {
 | 
				
			||||||
		reqScope.Namer = action.Namer
 | 
							reqScope.Namer = action.Namer
 | 
				
			||||||
@@ -314,6 +330,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
 | 
				
			|||||||
				Operation("list" + kind).
 | 
									Operation("list" + kind).
 | 
				
			||||||
				Produces("application/json").
 | 
									Produces("application/json").
 | 
				
			||||||
				Writes(versionedList)
 | 
									Writes(versionedList)
 | 
				
			||||||
 | 
								if err := addObjectParams(ws, route, versionedListOptions); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			addParams(route, action.Params)
 | 
								addParams(route, action.Params)
 | 
				
			||||||
			ws.Route(route)
 | 
								ws.Route(route)
 | 
				
			||||||
		case "PUT": // Update a resource.
 | 
							case "PUT": // Update a resource.
 | 
				
			||||||
@@ -651,6 +670,39 @@ func addParams(route *restful.RouteBuilder, params []*restful.Parameter) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func addObjectParams(ws *restful.WebService, route *restful.RouteBuilder, obj runtime.Object) error {
 | 
				
			||||||
 | 
						sv, err := conversion.EnforcePtr(obj)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						st := sv.Type()
 | 
				
			||||||
 | 
						switch st.Kind() {
 | 
				
			||||||
 | 
						case reflect.Struct:
 | 
				
			||||||
 | 
							for i := 0; i < st.NumField(); i++ {
 | 
				
			||||||
 | 
								name := st.Field(i).Name
 | 
				
			||||||
 | 
								sf, ok := st.FieldByName(name)
 | 
				
			||||||
 | 
								if !ok {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								switch sf.Type.Kind() {
 | 
				
			||||||
 | 
								case reflect.Interface, reflect.Struct:
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									jsonTag := sf.Tag.Get("json")
 | 
				
			||||||
 | 
									if len(jsonTag) == 0 {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									jsonName := strings.SplitN(jsonTag, ",", 2)[0]
 | 
				
			||||||
 | 
									if len(jsonName) == 0 {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									desc := sf.Tag.Get("description")
 | 
				
			||||||
 | 
									route.Param(ws.QueryParameter(jsonName, desc).DataType(sf.Type.Name()))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// defaultStorageMetadata provides default answers to rest.StorageMetadata.
 | 
					// defaultStorageMetadata provides default answers to rest.StorageMetadata.
 | 
				
			||||||
type defaultStorageMetadata struct{}
 | 
					type defaultStorageMetadata struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,12 +102,19 @@ type APIGroupVersion struct {
 | 
				
			|||||||
	Root    string
 | 
						Root    string
 | 
				
			||||||
	Version string
 | 
						Version string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ServerVersion controls the Kubernetes APIVersion used for common objects in the apiserver
 | 
				
			||||||
 | 
						// schema like api.Status, api.DeleteOptions, and api.ListOptions. Other implementors may
 | 
				
			||||||
 | 
						// define a version "v1beta1" but want to use the Kubernetes "v1beta3" internal objects. If
 | 
				
			||||||
 | 
						// empty, defaults to Version.
 | 
				
			||||||
 | 
						ServerVersion string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Mapper meta.RESTMapper
 | 
						Mapper meta.RESTMapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Codec   runtime.Codec
 | 
						Codec     runtime.Codec
 | 
				
			||||||
	Typer   runtime.ObjectTyper
 | 
						Typer     runtime.ObjectTyper
 | 
				
			||||||
	Creater runtime.ObjectCreater
 | 
						Creater   runtime.ObjectCreater
 | 
				
			||||||
	Linker  runtime.SelfLinker
 | 
						Convertor runtime.ObjectConvertor
 | 
				
			||||||
 | 
						Linker    runtime.SelfLinker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Admit   admission.Interface
 | 
						Admit   admission.Interface
 | 
				
			||||||
	Context api.RequestContextMapper
 | 
						Context api.RequestContextMapper
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ import (
 | 
				
			|||||||
	apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
						apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
				
			||||||
@@ -96,11 +97,10 @@ func init() {
 | 
				
			|||||||
	// api.Status is returned in errors
 | 
						// api.Status is returned in errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// "internal" version
 | 
						// "internal" version
 | 
				
			||||||
	api.Scheme.AddKnownTypes("", &Simple{}, &SimpleList{},
 | 
						api.Scheme.AddKnownTypes("", &Simple{}, &SimpleList{}, &api.Status{}, &api.ListOptions{})
 | 
				
			||||||
		&api.Status{})
 | 
					 | 
				
			||||||
	// "version" version
 | 
						// "version" version
 | 
				
			||||||
	// TODO: Use versioned api objects?
 | 
						// TODO: Use versioned api objects?
 | 
				
			||||||
	api.Scheme.AddKnownTypes(testVersion, &Simple{}, &SimpleList{}, &api.DeleteOptions{}, &api.Status{})
 | 
						api.Scheme.AddKnownTypes(testVersion, &Simple{}, &SimpleList{}, &v1beta1.DeleteOptions{}, &v1beta1.Status{}, &v1beta1.ListOptions{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nsMapper := newMapper()
 | 
						nsMapper := newMapper()
 | 
				
			||||||
	legacyNsMapper := newMapper()
 | 
						legacyNsMapper := newMapper()
 | 
				
			||||||
@@ -156,10 +156,11 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
 | 
				
			|||||||
		Root:    "/api",
 | 
							Root:    "/api",
 | 
				
			||||||
		Version: testVersion,
 | 
							Version: testVersion,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Creater: api.Scheme,
 | 
							Creater:   api.Scheme,
 | 
				
			||||||
		Typer:   api.Scheme,
 | 
							Convertor: api.Scheme,
 | 
				
			||||||
		Codec:   codec,
 | 
							Typer:     api.Scheme,
 | 
				
			||||||
		Linker:  selfLinker,
 | 
							Codec:     codec,
 | 
				
			||||||
 | 
							Linker:    selfLinker,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Admit:   admissionControl,
 | 
							Admit:   admissionControl,
 | 
				
			||||||
		Context: requestContextMapper,
 | 
							Context: requestContextMapper,
 | 
				
			||||||
@@ -244,6 +245,8 @@ func (storage *SimpleRESTStorage) List(ctx api.Context, label labels.Selector, f
 | 
				
			|||||||
	result := &SimpleList{
 | 
						result := &SimpleList{
 | 
				
			||||||
		Items: storage.list,
 | 
							Items: storage.list,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						storage.requestedLabelSelector = label
 | 
				
			||||||
 | 
						storage.requestedFieldSelector = field
 | 
				
			||||||
	return result, storage.errors["list"]
 | 
						return result, storage.errors["list"]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -522,15 +525,60 @@ func TestList(t *testing.T) {
 | 
				
			|||||||
		namespace string
 | 
							namespace string
 | 
				
			||||||
		selfLink  string
 | 
							selfLink  string
 | 
				
			||||||
		legacy    bool
 | 
							legacy    bool
 | 
				
			||||||
 | 
							label     string
 | 
				
			||||||
 | 
							field     string
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{"/api/version/simple", "", "/api/version/simple?namespace=", true},
 | 
							{
 | 
				
			||||||
		{"/api/version/simple?namespace=other", "other", "/api/version/simple?namespace=other", true},
 | 
								url:       "/api/version/simple",
 | 
				
			||||||
 | 
								namespace: "",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/simple?namespace=",
 | 
				
			||||||
 | 
								legacy:    true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								url:       "/api/version/simple?namespace=other",
 | 
				
			||||||
 | 
								namespace: "other",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/simple?namespace=other",
 | 
				
			||||||
 | 
								legacy:    true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								url:       "/api/version/simple?namespace=other&labels=a%3Db&fields=c%3Dd",
 | 
				
			||||||
 | 
								namespace: "other",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/simple?namespace=other",
 | 
				
			||||||
 | 
								legacy:    true,
 | 
				
			||||||
 | 
								label:     "a=b",
 | 
				
			||||||
 | 
								field:     "c=d",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		// list items across all namespaces
 | 
							// list items across all namespaces
 | 
				
			||||||
		{"/api/version/simple?namespace=", "", "/api/version/simple?namespace=", true},
 | 
							{
 | 
				
			||||||
		{"/api/version/namespaces/default/simple", "default", "/api/version/namespaces/default/simple", false},
 | 
								url:       "/api/version/simple?namespace=",
 | 
				
			||||||
		{"/api/version/namespaces/other/simple", "other", "/api/version/namespaces/other/simple", false},
 | 
								namespace: "",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/simple?namespace=",
 | 
				
			||||||
 | 
								legacy:    true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							// list items in a namespace, v1beta3+
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								url:       "/api/version/namespaces/default/simple",
 | 
				
			||||||
 | 
								namespace: "default",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/namespaces/default/simple",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								url:       "/api/version/namespaces/other/simple",
 | 
				
			||||||
 | 
								namespace: "other",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/namespaces/other/simple",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								url:       "/api/version/namespaces/other/simple?labels=a%3Db&fields=c%3Dd",
 | 
				
			||||||
 | 
								namespace: "other",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/namespaces/other/simple",
 | 
				
			||||||
 | 
								label:     "a=b",
 | 
				
			||||||
 | 
								field:     "c=d",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		// list items across all namespaces
 | 
							// list items across all namespaces
 | 
				
			||||||
		{"/api/version/simple", "", "/api/version/simple", false},
 | 
							{
 | 
				
			||||||
 | 
								url:       "/api/version/simple",
 | 
				
			||||||
 | 
								namespace: "",
 | 
				
			||||||
 | 
								selfLink:  "/api/version/simple",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for i, testCase := range testCases {
 | 
						for i, testCase := range testCases {
 | 
				
			||||||
		storage := map[string]rest.Storage{}
 | 
							storage := map[string]rest.Storage{}
 | 
				
			||||||
@@ -567,6 +615,12 @@ func TestList(t *testing.T) {
 | 
				
			|||||||
		} else if simpleStorage.actualNamespace != testCase.namespace {
 | 
							} else if simpleStorage.actualNamespace != testCase.namespace {
 | 
				
			||||||
			t.Errorf("%d: unexpected resource namespace: %s", i, simpleStorage.actualNamespace)
 | 
								t.Errorf("%d: unexpected resource namespace: %s", i, simpleStorage.actualNamespace)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if simpleStorage.requestedLabelSelector == nil || simpleStorage.requestedLabelSelector.String() != testCase.label {
 | 
				
			||||||
 | 
								t.Errorf("%d: unexpected label selector: %v", i, simpleStorage.requestedLabelSelector)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if simpleStorage.requestedFieldSelector == nil || simpleStorage.requestedFieldSelector.String() != testCase.field {
 | 
				
			||||||
 | 
								t.Errorf("%d: unexpected field selector: %v", i, simpleStorage.requestedFieldSelector)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,6 @@ package apiserver
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
					 | 
				
			||||||
	gpath "path"
 | 
						gpath "path"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,8 +26,6 @@ import (
 | 
				
			|||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
					 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/emicklei/go-restful"
 | 
						"github.com/emicklei/go-restful"
 | 
				
			||||||
@@ -64,9 +61,15 @@ type RequestScope struct {
 | 
				
			|||||||
	Namer ScopeNamer
 | 
						Namer ScopeNamer
 | 
				
			||||||
	ContextFunc
 | 
						ContextFunc
 | 
				
			||||||
	runtime.Codec
 | 
						runtime.Codec
 | 
				
			||||||
 | 
						Creater   runtime.ObjectCreater
 | 
				
			||||||
 | 
						Convertor runtime.ObjectConvertor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Resource   string
 | 
						Resource   string
 | 
				
			||||||
	Kind       string
 | 
						Kind       string
 | 
				
			||||||
	APIVersion string
 | 
						APIVersion string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The version of apiserver resources to use
 | 
				
			||||||
 | 
						ServerAPIVersion string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetResource returns a function that handles retrieving a single resource from a rest.Storage object.
 | 
					// GetResource returns a function that handles retrieving a single resource from a rest.Storage object.
 | 
				
			||||||
@@ -94,24 +97,6 @@ func GetResource(r rest.Getter, scope RequestScope) restful.RouteFunction {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseSelectorQueryParams(query url.Values, version, apiResource string) (label labels.Selector, field fields.Selector, err error) {
 | 
					 | 
				
			||||||
	labelString := query.Get(api.LabelSelectorQueryParam(version))
 | 
					 | 
				
			||||||
	label, err = labels.Parse(labelString)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, errors.NewBadRequest(fmt.Sprintf("The 'labels' selector parameter (%s) could not be parsed: %v", labelString, err))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	convertToInternalVersionFunc := func(label, value string) (newLabel, newValue string, err error) {
 | 
					 | 
				
			||||||
		return api.Scheme.ConvertFieldLabel(version, apiResource, label, value)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fieldString := query.Get(api.FieldSelectorQueryParam(version))
 | 
					 | 
				
			||||||
	field, err = fields.ParseAndTransformSelector(fieldString, convertToInternalVersionFunc)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, nil, errors.NewBadRequest(fmt.Sprintf("The 'fields' selector parameter (%s) could not be parsed: %v", fieldString, err))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return label, field, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ListResource returns a function that handles retrieving a list of resources from a rest.Storage object.
 | 
					// ListResource returns a function that handles retrieving a list of resources from a rest.Storage object.
 | 
				
			||||||
func ListResource(r rest.Lister, scope RequestScope) restful.RouteFunction {
 | 
					func ListResource(r rest.Lister, scope RequestScope) restful.RouteFunction {
 | 
				
			||||||
	return func(req *restful.Request, res *restful.Response) {
 | 
						return func(req *restful.Request, res *restful.Response) {
 | 
				
			||||||
@@ -125,13 +110,38 @@ func ListResource(r rest.Lister, scope RequestScope) restful.RouteFunction {
 | 
				
			|||||||
		ctx := scope.ContextFunc(req)
 | 
							ctx := scope.ContextFunc(req)
 | 
				
			||||||
		ctx = api.WithNamespace(ctx, namespace)
 | 
							ctx = api.WithNamespace(ctx, namespace)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		label, field, err := parseSelectorQueryParams(req.Request.URL.Query(), scope.APIVersion, scope.Resource)
 | 
							// TODO: extract me into a method
 | 
				
			||||||
 | 
							query := req.Request.URL.Query()
 | 
				
			||||||
 | 
							versioned, err := scope.Creater.New(scope.ServerAPIVersion, "ListOptions")
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								// programmer error
 | 
				
			||||||
 | 
								errorJSON(err, scope.Codec, w)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := scope.Convertor.Convert(&query, versioned); err != nil {
 | 
				
			||||||
 | 
								// bad request
 | 
				
			||||||
 | 
								errorJSON(err, scope.Codec, w)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							out, err := scope.Convertor.ConvertToVersion(versioned, "")
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								// programmer error
 | 
				
			||||||
 | 
								errorJSON(err, scope.Codec, w)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							opts := *out.(*api.ListOptions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// transform fields
 | 
				
			||||||
 | 
							fn := func(label, value string) (newLabel, newValue string, err error) {
 | 
				
			||||||
 | 
								return scope.Convertor.ConvertFieldLabel(scope.APIVersion, scope.Kind, label, value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if opts.FieldSelector, err = opts.FieldSelector.Transform(fn); err != nil {
 | 
				
			||||||
 | 
								// invalid field
 | 
				
			||||||
			errorJSON(err, scope.Codec, w)
 | 
								errorJSON(err, scope.Codec, w)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		result, err := r.List(ctx, label, field)
 | 
							result, err := r.List(ctx, opts.LabelSelector, opts.FieldSelector)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			errorJSON(err, scope.Codec, w)
 | 
								errorJSON(err, scope.Codec, w)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ package apiserver
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@@ -26,8 +27,11 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
 | 
				
			||||||
	watchjson "github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json"
 | 
						watchjson "github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json"
 | 
				
			||||||
@@ -36,11 +40,14 @@ import (
 | 
				
			|||||||
	"golang.org/x/net/websocket"
 | 
						"golang.org/x/net/websocket"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: convert me to resthandler custom verb
 | 
				
			||||||
type WatchHandler struct {
 | 
					type WatchHandler struct {
 | 
				
			||||||
	storage map[string]rest.Storage
 | 
						storage   map[string]rest.Storage
 | 
				
			||||||
	codec   runtime.Codec
 | 
						mapper    meta.RESTMapper
 | 
				
			||||||
	linker  runtime.SelfLinker
 | 
						convertor runtime.ObjectConvertor
 | 
				
			||||||
	info    *APIRequestInfoResolver
 | 
						codec     runtime.Codec
 | 
				
			||||||
 | 
						linker    runtime.SelfLinker
 | 
				
			||||||
 | 
						info      *APIRequestInfoResolver
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// setSelfLinkAddName sets the self link, appending the object's name to the canonical path & type.
 | 
					// setSelfLinkAddName sets the self link, appending the object's name to the canonical path & type.
 | 
				
			||||||
@@ -96,8 +103,24 @@ func (h *WatchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 | 
				
			|||||||
		httpCode = errorJSON(errors.NewMethodNotSupported(requestInfo.Resource, "watch"), h.codec, w)
 | 
							httpCode = errorJSON(errors.NewMethodNotSupported(requestInfo.Resource, "watch"), h.codec, w)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						kind := requestInfo.Kind
 | 
				
			||||||
 | 
						if len(kind) == 0 {
 | 
				
			||||||
 | 
							if _, kind, err = h.mapper.VersionAndKindForResource(apiResource); err != nil {
 | 
				
			||||||
 | 
								glog.Errorf("No kind found for %s: %v", apiResource, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	label, field, err := parseSelectorQueryParams(req.URL.Query(), requestInfo.APIVersion, apiResource)
 | 
						scope := RequestScope{
 | 
				
			||||||
 | 
							Convertor:  h.convertor,
 | 
				
			||||||
 | 
							Kind:       kind,
 | 
				
			||||||
 | 
							Resource:   apiResource,
 | 
				
			||||||
 | 
							APIVersion: requestInfo.APIVersion,
 | 
				
			||||||
 | 
							// TODO: this must be parameterized per version, and is incorrect for implementors
 | 
				
			||||||
 | 
							// outside of Kubernetes. Fix by refactoring watch under resthandler as a custome
 | 
				
			||||||
 | 
							// resource.
 | 
				
			||||||
 | 
							ServerAPIVersion: requestInfo.APIVersion,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						label, field, err := parseSelectorQueryParams(req.URL.Query(), scope)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		httpCode = errorJSON(err, h.codec, w)
 | 
							httpCode = errorJSON(err, h.codec, w)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -125,6 +148,26 @@ func (h *WatchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: remove when watcher is refactored to fit under api_installer
 | 
				
			||||||
 | 
					func parseSelectorQueryParams(query url.Values, scope RequestScope) (label labels.Selector, field fields.Selector, err error) {
 | 
				
			||||||
 | 
						labelString := query.Get(api.LabelSelectorQueryParam(scope.ServerAPIVersion))
 | 
				
			||||||
 | 
						label, err = labels.Parse(labelString)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, errors.NewBadRequest(fmt.Sprintf("The 'labels' selector parameter (%s) could not be parsed: %v", labelString, err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn := func(label, value string) (newLabel, newValue string, err error) {
 | 
				
			||||||
 | 
							return scope.Convertor.ConvertFieldLabel(scope.APIVersion, scope.Kind, label, value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fieldString := query.Get(api.FieldSelectorQueryParam(scope.ServerAPIVersion))
 | 
				
			||||||
 | 
						field, err = fields.ParseAndTransformSelector(fieldString, fn)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, errors.NewBadRequest(fmt.Sprintf("The 'fields' selector parameter (%s) could not be parsed: %v", fieldString, err))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.Infof("Found %#v %#v from %v in scope %#v", label, field, query, scope)
 | 
				
			||||||
 | 
						return label, field, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
 | 
					// WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
 | 
				
			||||||
type WatchServer struct {
 | 
					type WatchServer struct {
 | 
				
			||||||
	watching watch.Interface
 | 
						watching watch.Interface
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
 | 
				
			||||||
@@ -48,16 +49,24 @@ var watchTestTable = []struct {
 | 
				
			|||||||
	{watch.Deleted, &Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}}},
 | 
						{watch.Deleted, &Simple{ObjectMeta: api.ObjectMeta{Name: "bar"}}},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						mapper.(*meta.DefaultRESTMapper).Add(meta.RESTScopeNamespaceLegacy, "Simple", testVersion, false)
 | 
				
			||||||
 | 
						api.Scheme.AddFieldLabelConversionFunc(testVersion, "Simple",
 | 
				
			||||||
 | 
							func(label, value string) (string, string, error) {
 | 
				
			||||||
 | 
								return label, value, nil
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestWatchWebsocket(t *testing.T) {
 | 
					func TestWatchWebsocket(t *testing.T) {
 | 
				
			||||||
	simpleStorage := &SimpleRESTStorage{}
 | 
						simpleStorage := &SimpleRESTStorage{}
 | 
				
			||||||
	_ = rest.Watcher(simpleStorage) // Give compile error if this doesn't work.
 | 
						_ = rest.Watcher(simpleStorage) // Give compile error if this doesn't work.
 | 
				
			||||||
	handler := handle(map[string]rest.Storage{"foo": simpleStorage})
 | 
						handler := handle(map[string]rest.Storage{"simples": simpleStorage})
 | 
				
			||||||
	server := httptest.NewServer(handler)
 | 
						server := httptest.NewServer(handler)
 | 
				
			||||||
	defer server.Close()
 | 
						defer server.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dest, _ := url.Parse(server.URL)
 | 
						dest, _ := url.Parse(server.URL)
 | 
				
			||||||
	dest.Scheme = "ws" // Required by websocket, though the server never sees it.
 | 
						dest.Scheme = "ws" // Required by websocket, though the server never sees it.
 | 
				
			||||||
	dest.Path = "/api/version/watch/foo"
 | 
						dest.Path = "/api/version/watch/simples"
 | 
				
			||||||
	dest.RawQuery = ""
 | 
						dest.RawQuery = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ws, err := websocket.Dial(dest.String(), "", "http://localhost")
 | 
						ws, err := websocket.Dial(dest.String(), "", "http://localhost")
 | 
				
			||||||
@@ -103,13 +112,13 @@ func TestWatchWebsocket(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestWatchHTTP(t *testing.T) {
 | 
					func TestWatchHTTP(t *testing.T) {
 | 
				
			||||||
	simpleStorage := &SimpleRESTStorage{}
 | 
						simpleStorage := &SimpleRESTStorage{}
 | 
				
			||||||
	handler := handle(map[string]rest.Storage{"foo": simpleStorage})
 | 
						handler := handle(map[string]rest.Storage{"simples": simpleStorage})
 | 
				
			||||||
	server := httptest.NewServer(handler)
 | 
						server := httptest.NewServer(handler)
 | 
				
			||||||
	defer server.Close()
 | 
						defer server.Close()
 | 
				
			||||||
	client := http.Client{}
 | 
						client := http.Client{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dest, _ := url.Parse(server.URL)
 | 
						dest, _ := url.Parse(server.URL)
 | 
				
			||||||
	dest.Path = "/api/version/watch/foo"
 | 
						dest.Path = "/api/version/watch/simples"
 | 
				
			||||||
	dest.RawQuery = ""
 | 
						dest.RawQuery = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	request, err := http.NewRequest("GET", dest.String(), nil)
 | 
						request, err := http.NewRequest("GET", dest.String(), nil)
 | 
				
			||||||
@@ -163,17 +172,13 @@ func TestWatchHTTP(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestWatchParamParsing(t *testing.T) {
 | 
					func TestWatchParamParsing(t *testing.T) {
 | 
				
			||||||
	api.Scheme.AddFieldLabelConversionFunc(testVersion, "foo",
 | 
					 | 
				
			||||||
		func(label, value string) (string, string, error) {
 | 
					 | 
				
			||||||
			return label, value, nil
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	simpleStorage := &SimpleRESTStorage{}
 | 
						simpleStorage := &SimpleRESTStorage{}
 | 
				
			||||||
	handler := handle(map[string]rest.Storage{"foo": simpleStorage})
 | 
						handler := handle(map[string]rest.Storage{"simples": simpleStorage})
 | 
				
			||||||
	server := httptest.NewServer(handler)
 | 
						server := httptest.NewServer(handler)
 | 
				
			||||||
	defer server.Close()
 | 
						defer server.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dest, _ := url.Parse(server.URL)
 | 
						dest, _ := url.Parse(server.URL)
 | 
				
			||||||
	dest.Path = "/api/" + testVersion + "/watch/foo"
 | 
						dest.Path = "/api/" + testVersion + "/watch/simples"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	table := []struct {
 | 
						table := []struct {
 | 
				
			||||||
		rawQuery        string
 | 
							rawQuery        string
 | 
				
			||||||
@@ -238,14 +243,14 @@ func TestWatchParamParsing(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestWatchProtocolSelection(t *testing.T) {
 | 
					func TestWatchProtocolSelection(t *testing.T) {
 | 
				
			||||||
	simpleStorage := &SimpleRESTStorage{}
 | 
						simpleStorage := &SimpleRESTStorage{}
 | 
				
			||||||
	handler := handle(map[string]rest.Storage{"foo": simpleStorage})
 | 
						handler := handle(map[string]rest.Storage{"simples": simpleStorage})
 | 
				
			||||||
	server := httptest.NewServer(handler)
 | 
						server := httptest.NewServer(handler)
 | 
				
			||||||
	defer server.Close()
 | 
						defer server.Close()
 | 
				
			||||||
	defer server.CloseClientConnections()
 | 
						defer server.CloseClientConnections()
 | 
				
			||||||
	client := http.Client{}
 | 
						client := http.Client{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dest, _ := url.Parse(server.URL)
 | 
						dest, _ := url.Parse(server.URL)
 | 
				
			||||||
	dest.Path = "/api/version/watch/foo"
 | 
						dest.Path = "/api/version/watch/simples"
 | 
				
			||||||
	dest.RawQuery = ""
 | 
						dest.RawQuery = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	table := []struct {
 | 
						table := []struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -572,9 +572,10 @@ func (m *Master) defaultAPIGroupVersion() *apiserver.APIGroupVersion {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		Mapper: latest.RESTMapper,
 | 
							Mapper: latest.RESTMapper,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Creater: api.Scheme,
 | 
							Creater:   api.Scheme,
 | 
				
			||||||
		Typer:   api.Scheme,
 | 
							Convertor: api.Scheme,
 | 
				
			||||||
		Linker:  latest.SelfLinker,
 | 
							Typer:     api.Scheme,
 | 
				
			||||||
 | 
							Linker:    latest.SelfLinker,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Admit:   m.admissionControl,
 | 
							Admit:   m.admissionControl,
 | 
				
			||||||
		Context: m.requestContextMapper,
 | 
							Context: m.requestContextMapper,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,9 @@ type Codec interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ObjectConvertor converts an object to a different version.
 | 
					// ObjectConvertor converts an object to a different version.
 | 
				
			||||||
type ObjectConvertor interface {
 | 
					type ObjectConvertor interface {
 | 
				
			||||||
 | 
						Convert(in, out interface{}) error
 | 
				
			||||||
	ConvertToVersion(in Object, outVersion string) (out Object, err error)
 | 
						ConvertToVersion(in Object, outVersion string) (out Object, err error)
 | 
				
			||||||
 | 
						ConvertFieldLabel(version, kind, label, value string) (string, string, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ObjectTyper contains methods for extracting the APIVersion and Kind
 | 
					// ObjectTyper contains methods for extracting the APIVersion and Kind
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ package runtime
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
						"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
 | 
				
			||||||
@@ -224,6 +225,9 @@ func NewScheme() *Scheme {
 | 
				
			|||||||
	if err := s.raw.RegisterInputDefaults(&map[string][]string{}, JSONKeyMapper, conversion.AllowDifferentFieldTypeNames|conversion.IgnoreMissingFields); err != nil {
 | 
						if err := s.raw.RegisterInputDefaults(&map[string][]string{}, JSONKeyMapper, conversion.AllowDifferentFieldTypeNames|conversion.IgnoreMissingFields); err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if err := s.raw.RegisterInputDefaults(&url.Values{}, JSONKeyMapper, conversion.AllowDifferentFieldTypeNames|conversion.IgnoreMissingFields); err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return s
 | 
						return s
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -294,13 +298,13 @@ func (s *Scheme) AddConversionFuncs(conversionFuncs ...interface{}) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddFieldLabelConversionFunc adds a conversion function to convert field selectors
 | 
					// AddFieldLabelConversionFunc adds a conversion function to convert field selectors
 | 
				
			||||||
// of the given api resource from the given version to internal version representation.
 | 
					// of the given kind from the given version to internal version representation.
 | 
				
			||||||
func (s *Scheme) AddFieldLabelConversionFunc(version, apiResource string, conversionFunc FieldLabelConversionFunc) error {
 | 
					func (s *Scheme) AddFieldLabelConversionFunc(version, kind string, conversionFunc FieldLabelConversionFunc) error {
 | 
				
			||||||
	if s.fieldLabelConversionFuncs[version] == nil {
 | 
						if s.fieldLabelConversionFuncs[version] == nil {
 | 
				
			||||||
		s.fieldLabelConversionFuncs[version] = map[string]FieldLabelConversionFunc{}
 | 
							s.fieldLabelConversionFuncs[version] = map[string]FieldLabelConversionFunc{}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s.fieldLabelConversionFuncs[version][apiResource] = conversionFunc
 | 
						s.fieldLabelConversionFuncs[version][kind] = conversionFunc
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -326,15 +330,15 @@ func (s *Scheme) Convert(in, out interface{}) error {
 | 
				
			|||||||
	return s.raw.Convert(in, out)
 | 
						return s.raw.Convert(in, out)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Converts the given field label and value for an apiResource field selector from
 | 
					// Converts the given field label and value for an kind field selector from
 | 
				
			||||||
// versioned representation to an unversioned one.
 | 
					// versioned representation to an unversioned one.
 | 
				
			||||||
func (s *Scheme) ConvertFieldLabel(version, apiResource, label, value string) (string, string, error) {
 | 
					func (s *Scheme) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
 | 
				
			||||||
	if s.fieldLabelConversionFuncs[version] == nil {
 | 
						if s.fieldLabelConversionFuncs[version] == nil {
 | 
				
			||||||
		return "", "", fmt.Errorf("No conversion function found for version: %s", version)
 | 
							return "", "", fmt.Errorf("No conversion function found for version: %s", version)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	conversionFunc, ok := s.fieldLabelConversionFuncs[version][apiResource]
 | 
						conversionFunc, ok := s.fieldLabelConversionFuncs[version][kind]
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return "", "", fmt.Errorf("No conversion function found for version %s and api resource %s", version, apiResource)
 | 
							return "", "", fmt.Errorf("No conversion function found for version %s and kind %s", version, kind)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return conversionFunc(label, value)
 | 
						return conversionFunc(label, value)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user