Update godeps
This commit is contained in:
parent
1c8773fc98
commit
1bc383f9c5
1723 changed files with 287976 additions and 411028 deletions
6
vendor/k8s.io/client-go/1.4/pkg/api/OWNERS
generated
vendored
6
vendor/k8s.io/client-go/1.4/pkg/api/OWNERS
generated
vendored
|
|
@ -1,6 +0,0 @@
|
|||
assignees:
|
||||
- bgrant0607
|
||||
- erictune
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- thockin
|
||||
138
vendor/k8s.io/client-go/1.4/pkg/api/context.go
generated
vendored
138
vendor/k8s.io/client-go/1.4/pkg/api/context.go
generated
vendored
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
stderrs "errors"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/client-go/1.4/pkg/auth/user"
|
||||
"k8s.io/client-go/1.4/pkg/types"
|
||||
)
|
||||
|
||||
// Context carries values across API boundaries.
|
||||
// This context matches the context.Context interface
|
||||
// (https://blog.golang.org/context), for the purposes
|
||||
// of passing the api.Context through to the storage tier.
|
||||
// TODO: Determine the extent that this abstraction+interface
|
||||
// is used by the api, and whether we can remove.
|
||||
type Context interface {
|
||||
// Value returns the value associated with key or nil if none.
|
||||
Value(key interface{}) interface{}
|
||||
|
||||
// Deadline returns the time when this Context will be canceled, if any.
|
||||
Deadline() (deadline time.Time, ok bool)
|
||||
|
||||
// Done returns a channel that is closed when this Context is canceled
|
||||
// or times out.
|
||||
Done() <-chan struct{}
|
||||
|
||||
// Err indicates why this context was canceled, after the Done channel
|
||||
// is closed.
|
||||
Err() error
|
||||
}
|
||||
|
||||
// The key type is unexported to prevent collisions
|
||||
type key int
|
||||
|
||||
const (
|
||||
// namespaceKey is the context key for the request namespace.
|
||||
namespaceKey key = iota
|
||||
|
||||
// userKey is the context key for the request user.
|
||||
userKey
|
||||
|
||||
// uidKey is the context key for the uid to assign to an object on create.
|
||||
uidKey
|
||||
)
|
||||
|
||||
// NewContext instantiates a base context object for request flows.
|
||||
func NewContext() Context {
|
||||
return context.TODO()
|
||||
}
|
||||
|
||||
// NewDefaultContext instantiates a base context object for request flows in the default namespace
|
||||
func NewDefaultContext() Context {
|
||||
return WithNamespace(NewContext(), NamespaceDefault)
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is val.
|
||||
func WithValue(parent Context, key interface{}, val interface{}) Context {
|
||||
internalCtx, ok := parent.(context.Context)
|
||||
if !ok {
|
||||
panic(stderrs.New("Invalid context type"))
|
||||
}
|
||||
return context.WithValue(internalCtx, key, val)
|
||||
}
|
||||
|
||||
// WithNamespace returns a copy of parent in which the namespace value is set
|
||||
func WithNamespace(parent Context, namespace string) Context {
|
||||
return WithValue(parent, namespaceKey, namespace)
|
||||
}
|
||||
|
||||
// NamespaceFrom returns the value of the namespace key on the ctx
|
||||
func NamespaceFrom(ctx Context) (string, bool) {
|
||||
namespace, ok := ctx.Value(namespaceKey).(string)
|
||||
return namespace, ok
|
||||
}
|
||||
|
||||
// NamespaceValue returns the value of the namespace key on the ctx, or the empty string if none
|
||||
func NamespaceValue(ctx Context) string {
|
||||
namespace, _ := NamespaceFrom(ctx)
|
||||
return namespace
|
||||
}
|
||||
|
||||
// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context.
|
||||
func ValidNamespace(ctx Context, resource *ObjectMeta) bool {
|
||||
ns, ok := NamespaceFrom(ctx)
|
||||
if len(resource.Namespace) == 0 {
|
||||
resource.Namespace = ns
|
||||
}
|
||||
return ns == resource.Namespace && ok
|
||||
}
|
||||
|
||||
// WithNamespaceDefaultIfNone returns a context whose namespace is the default if and only if the parent context has no namespace value
|
||||
func WithNamespaceDefaultIfNone(parent Context) Context {
|
||||
namespace, ok := NamespaceFrom(parent)
|
||||
if !ok || len(namespace) == 0 {
|
||||
return WithNamespace(parent, NamespaceDefault)
|
||||
}
|
||||
return parent
|
||||
}
|
||||
|
||||
// WithUser returns a copy of parent in which the user value is set
|
||||
func WithUser(parent Context, user user.Info) Context {
|
||||
return WithValue(parent, userKey, user)
|
||||
}
|
||||
|
||||
// UserFrom returns the value of the user key on the ctx
|
||||
func UserFrom(ctx Context) (user.Info, bool) {
|
||||
user, ok := ctx.Value(userKey).(user.Info)
|
||||
return user, ok
|
||||
}
|
||||
|
||||
// WithUID returns a copy of parent in which the uid value is set
|
||||
func WithUID(parent Context, uid types.UID) Context {
|
||||
return WithValue(parent, uidKey, uid)
|
||||
}
|
||||
|
||||
// UIDFrom returns the value of the uid key on the ctx
|
||||
func UIDFrom(ctx Context) (types.UID, bool) {
|
||||
uid, ok := ctx.Value(uidKey).(types.UID)
|
||||
return uid, ok
|
||||
}
|
||||
245
vendor/k8s.io/client-go/1.4/pkg/api/conversion.go
generated
vendored
245
vendor/k8s.io/client-go/1.4/pkg/api/conversion.go
generated
vendored
|
|
@ -1,245 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/resource"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/conversion"
|
||||
"k8s.io/client-go/1.4/pkg/fields"
|
||||
"k8s.io/client-go/1.4/pkg/labels"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/util/intstr"
|
||||
utillabels "k8s.io/client-go/1.4/pkg/util/labels"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
return scheme.AddConversionFuncs(
|
||||
Convert_unversioned_TypeMeta_To_unversioned_TypeMeta,
|
||||
|
||||
Convert_unversioned_ListMeta_To_unversioned_ListMeta,
|
||||
|
||||
Convert_intstr_IntOrString_To_intstr_IntOrString,
|
||||
|
||||
Convert_unversioned_Time_To_unversioned_Time,
|
||||
|
||||
Convert_Slice_string_To_unversioned_Time,
|
||||
|
||||
Convert_resource_Quantity_To_resource_Quantity,
|
||||
|
||||
Convert_string_To_labels_Selector,
|
||||
Convert_labels_Selector_To_string,
|
||||
|
||||
Convert_string_To_fields_Selector,
|
||||
Convert_fields_Selector_To_string,
|
||||
|
||||
Convert_Pointer_bool_To_bool,
|
||||
Convert_bool_To_Pointer_bool,
|
||||
|
||||
Convert_Pointer_string_To_string,
|
||||
Convert_string_To_Pointer_string,
|
||||
|
||||
Convert_Pointer_int64_To_int,
|
||||
Convert_int_To_Pointer_int64,
|
||||
|
||||
Convert_Pointer_int32_To_int32,
|
||||
Convert_int32_To_Pointer_int32,
|
||||
|
||||
Convert_Pointer_float64_To_float64,
|
||||
Convert_float64_To_Pointer_float64,
|
||||
|
||||
Convert_map_to_unversioned_LabelSelector,
|
||||
Convert_unversioned_LabelSelector_to_map,
|
||||
)
|
||||
}
|
||||
|
||||
func Convert_Pointer_float64_To_float64(in **float64, out *float64, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = 0
|
||||
return nil
|
||||
}
|
||||
*out = float64(**in)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_float64_To_Pointer_float64(in *float64, out **float64, s conversion.Scope) error {
|
||||
temp := float64(*in)
|
||||
*out = &temp
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_int32_To_int32(in **int32, out *int32, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = 0
|
||||
return nil
|
||||
}
|
||||
*out = int32(**in)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_int32_To_Pointer_int32(in *int32, out **int32, s conversion.Scope) error {
|
||||
temp := int32(*in)
|
||||
*out = &temp
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_int64_To_int(in **int64, out *int, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = 0
|
||||
return nil
|
||||
}
|
||||
*out = int(**in)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_int_To_Pointer_int64(in *int, out **int64, s conversion.Scope) error {
|
||||
temp := int64(*in)
|
||||
*out = &temp
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_string_To_string(in **string, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = ""
|
||||
return nil
|
||||
}
|
||||
*out = **in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_string_To_Pointer_string(in *string, out **string, s conversion.Scope) error {
|
||||
if in == nil {
|
||||
stringVar := ""
|
||||
*out = &stringVar
|
||||
return nil
|
||||
}
|
||||
*out = in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_bool_To_bool(in **bool, out *bool, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = false
|
||||
return nil
|
||||
}
|
||||
*out = **in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_bool_To_Pointer_bool(in *bool, out **bool, s conversion.Scope) error {
|
||||
if in == nil {
|
||||
boolVar := false
|
||||
*out = &boolVar
|
||||
return nil
|
||||
}
|
||||
*out = in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(in, out *unversioned.TypeMeta, s conversion.Scope) error {
|
||||
// These values are explicitly not copied
|
||||
//out.APIVersion = in.APIVersion
|
||||
//out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_ListMeta_To_unversioned_ListMeta(in, out *unversioned.ListMeta, s conversion.Scope) error {
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_intstr_IntOrString_To_intstr_IntOrString(in, out *intstr.IntOrString, s conversion.Scope) error {
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_Time_To_unversioned_Time(in *unversioned.Time, out *unversioned.Time, s conversion.Scope) error {
|
||||
// Cannot deep copy these, because time.Time has unexported fields.
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_Slice_string_To_unversioned_Time allows converting a URL query parameter value
|
||||
func Convert_Slice_string_To_unversioned_Time(input *[]string, out *unversioned.Time, s conversion.Scope) error {
|
||||
str := ""
|
||||
if len(*input) > 0 {
|
||||
str = (*input)[0]
|
||||
}
|
||||
return out.UnmarshalQueryParameter(str)
|
||||
}
|
||||
|
||||
func Convert_string_To_labels_Selector(in *string, out *labels.Selector, s conversion.Scope) error {
|
||||
selector, err := labels.Parse(*in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*out = selector
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_string_To_fields_Selector(in *string, out *fields.Selector, s conversion.Scope) error {
|
||||
selector, err := fields.ParseSelector(*in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*out = selector
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_labels_Selector_To_string(in *labels.Selector, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
*out = (*in).String()
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_fields_Selector_To_string(in *fields.Selector, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
*out = (*in).String()
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_resource_Quantity_To_resource_Quantity(in *resource.Quantity, out *resource.Quantity, s conversion.Scope) error {
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_map_to_unversioned_LabelSelector(in *map[string]string, out *unversioned.LabelSelector, s conversion.Scope) error {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out = new(unversioned.LabelSelector)
|
||||
for labelKey, labelValue := range *in {
|
||||
utillabels.AddLabelToSelector(out, labelKey, labelValue)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_LabelSelector_to_map(in *unversioned.LabelSelector, out *map[string]string, s conversion.Scope) error {
|
||||
var err error
|
||||
*out, err = unversioned.LabelSelectorAsMap(in)
|
||||
if err != nil {
|
||||
err = field.Invalid(field.NewPath("labelSelector"), *in, fmt.Sprintf("cannot convert to old selector: %v", err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
24
vendor/k8s.io/client-go/1.4/pkg/api/doc.go
generated
vendored
24
vendor/k8s.io/client-go/1.4/pkg/api/doc.go
generated
vendored
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
|
||||
// Package api contains the latest (or "internal") version of the
|
||||
// Kubernetes API objects. This is the API objects as represented in memory.
|
||||
// The contract presented to clients is located in the versioned packages,
|
||||
// which are sub-directories. The first one is "v1". Those packages
|
||||
// describe how a particular version is serialized to storage/network.
|
||||
package api
|
||||
238
vendor/k8s.io/client-go/1.4/pkg/api/endpoints/util.go
generated
vendored
238
vendor/k8s.io/client-go/1.4/pkg/api/endpoints/util.go
generated
vendored
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package endpoints
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"hash"
|
||||
"sort"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/types"
|
||||
hashutil "k8s.io/client-go/1.4/pkg/util/hash"
|
||||
)
|
||||
|
||||
const (
|
||||
// TODO: to be deleted after v1.3 is released
|
||||
// Its value is the json representation of map[string(IP)][HostRecord]
|
||||
// example: '{"10.245.1.6":{"HostName":"my-webserver"}}'
|
||||
PodHostnamesAnnotation = "endpoints.beta.kubernetes.io/hostnames-map"
|
||||
)
|
||||
|
||||
// TODO: to be deleted after v1.3 is released
|
||||
type HostRecord struct {
|
||||
HostName string
|
||||
}
|
||||
|
||||
// RepackSubsets takes a slice of EndpointSubset objects, expands it to the full
|
||||
// representation, and then repacks that into the canonical layout. This
|
||||
// ensures that code which operates on these objects can rely on the common
|
||||
// form for things like comparison. The result is a newly allocated slice.
|
||||
func RepackSubsets(subsets []api.EndpointSubset) []api.EndpointSubset {
|
||||
// First map each unique port definition to the sets of hosts that
|
||||
// offer it.
|
||||
allAddrs := map[addressKey]*api.EndpointAddress{}
|
||||
portToAddrReadyMap := map[api.EndpointPort]addressSet{}
|
||||
for i := range subsets {
|
||||
for _, port := range subsets[i].Ports {
|
||||
for k := range subsets[i].Addresses {
|
||||
mapAddressByPort(&subsets[i].Addresses[k], port, true, allAddrs, portToAddrReadyMap)
|
||||
}
|
||||
for k := range subsets[i].NotReadyAddresses {
|
||||
mapAddressByPort(&subsets[i].NotReadyAddresses[k], port, false, allAddrs, portToAddrReadyMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Next, map the sets of hosts to the sets of ports they offer.
|
||||
// Go does not allow maps or slices as keys to maps, so we have
|
||||
// to synthesize an artificial key and do a sort of 2-part
|
||||
// associative entity.
|
||||
type keyString string
|
||||
keyToAddrReadyMap := map[keyString]addressSet{}
|
||||
addrReadyMapKeyToPorts := map[keyString][]api.EndpointPort{}
|
||||
for port, addrs := range portToAddrReadyMap {
|
||||
key := keyString(hashAddresses(addrs))
|
||||
keyToAddrReadyMap[key] = addrs
|
||||
addrReadyMapKeyToPorts[key] = append(addrReadyMapKeyToPorts[key], port)
|
||||
}
|
||||
|
||||
// Next, build the N-to-M association the API wants.
|
||||
final := []api.EndpointSubset{}
|
||||
for key, ports := range addrReadyMapKeyToPorts {
|
||||
var readyAddrs, notReadyAddrs []api.EndpointAddress
|
||||
for addr, ready := range keyToAddrReadyMap[key] {
|
||||
if ready {
|
||||
readyAddrs = append(readyAddrs, *addr)
|
||||
} else {
|
||||
notReadyAddrs = append(notReadyAddrs, *addr)
|
||||
}
|
||||
}
|
||||
final = append(final, api.EndpointSubset{Addresses: readyAddrs, NotReadyAddresses: notReadyAddrs, Ports: ports})
|
||||
}
|
||||
|
||||
// Finally, sort it.
|
||||
return SortSubsets(final)
|
||||
}
|
||||
|
||||
// The sets of hosts must be de-duped, using IP+UID as the key.
|
||||
type addressKey struct {
|
||||
ip string
|
||||
uid types.UID
|
||||
}
|
||||
|
||||
// mapAddressByPort adds an address into a map by its ports, registering the address with a unique pointer, and preserving
|
||||
// any existing ready state.
|
||||
func mapAddressByPort(addr *api.EndpointAddress, port api.EndpointPort, ready bool, allAddrs map[addressKey]*api.EndpointAddress, portToAddrReadyMap map[api.EndpointPort]addressSet) *api.EndpointAddress {
|
||||
// use addressKey to distinguish between two endpoints that are identical addresses
|
||||
// but may have come from different hosts, for attribution. For instance, Mesos
|
||||
// assigns pods the node IP, but the pods are distinct.
|
||||
key := addressKey{ip: addr.IP}
|
||||
if addr.TargetRef != nil {
|
||||
key.uid = addr.TargetRef.UID
|
||||
}
|
||||
|
||||
// Accumulate the address. The full EndpointAddress structure is preserved for use when
|
||||
// we rebuild the subsets so that the final TargetRef has all of the necessary data.
|
||||
existingAddress := allAddrs[key]
|
||||
if existingAddress == nil {
|
||||
// Make a copy so we don't write to the
|
||||
// input args of this function.
|
||||
existingAddress = &api.EndpointAddress{}
|
||||
*existingAddress = *addr
|
||||
allAddrs[key] = existingAddress
|
||||
}
|
||||
|
||||
// Remember that this port maps to this address.
|
||||
if _, found := portToAddrReadyMap[port]; !found {
|
||||
portToAddrReadyMap[port] = addressSet{}
|
||||
}
|
||||
// if we have not yet recorded this port for this address, or if the previous
|
||||
// state was ready, write the current ready state. not ready always trumps
|
||||
// ready.
|
||||
if wasReady, found := portToAddrReadyMap[port][existingAddress]; !found || wasReady {
|
||||
portToAddrReadyMap[port][existingAddress] = ready
|
||||
}
|
||||
return existingAddress
|
||||
}
|
||||
|
||||
type addressSet map[*api.EndpointAddress]bool
|
||||
|
||||
type addrReady struct {
|
||||
addr *api.EndpointAddress
|
||||
ready bool
|
||||
}
|
||||
|
||||
func hashAddresses(addrs addressSet) string {
|
||||
// Flatten the list of addresses into a string so it can be used as a
|
||||
// map key. Unfortunately, DeepHashObject is implemented in terms of
|
||||
// spew, and spew does not handle non-primitive map keys well. So
|
||||
// first we collapse it into a slice, sort the slice, then hash that.
|
||||
slice := make([]addrReady, 0, len(addrs))
|
||||
for k, ready := range addrs {
|
||||
slice = append(slice, addrReady{k, ready})
|
||||
}
|
||||
sort.Sort(addrsReady(slice))
|
||||
hasher := md5.New()
|
||||
hashutil.DeepHashObject(hasher, slice)
|
||||
return hex.EncodeToString(hasher.Sum(nil)[0:])
|
||||
}
|
||||
|
||||
func lessAddrReady(a, b addrReady) bool {
|
||||
// ready is not significant to hashing since we can't have duplicate addresses
|
||||
return LessEndpointAddress(a.addr, b.addr)
|
||||
}
|
||||
|
||||
type addrsReady []addrReady
|
||||
|
||||
func (sl addrsReady) Len() int { return len(sl) }
|
||||
func (sl addrsReady) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
|
||||
func (sl addrsReady) Less(i, j int) bool {
|
||||
return lessAddrReady(sl[i], sl[j])
|
||||
}
|
||||
|
||||
func LessEndpointAddress(a, b *api.EndpointAddress) bool {
|
||||
ipComparison := bytes.Compare([]byte(a.IP), []byte(b.IP))
|
||||
if ipComparison != 0 {
|
||||
return ipComparison < 0
|
||||
}
|
||||
if b.TargetRef == nil {
|
||||
return false
|
||||
}
|
||||
if a.TargetRef == nil {
|
||||
return true
|
||||
}
|
||||
return a.TargetRef.UID < b.TargetRef.UID
|
||||
}
|
||||
|
||||
type addrPtrsByIpAndUID []*api.EndpointAddress
|
||||
|
||||
func (sl addrPtrsByIpAndUID) Len() int { return len(sl) }
|
||||
func (sl addrPtrsByIpAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
|
||||
func (sl addrPtrsByIpAndUID) Less(i, j int) bool {
|
||||
return LessEndpointAddress(sl[i], sl[j])
|
||||
}
|
||||
|
||||
// SortSubsets sorts an array of EndpointSubset objects in place. For ease of
|
||||
// use it returns the input slice.
|
||||
func SortSubsets(subsets []api.EndpointSubset) []api.EndpointSubset {
|
||||
for i := range subsets {
|
||||
ss := &subsets[i]
|
||||
sort.Sort(addrsByIpAndUID(ss.Addresses))
|
||||
sort.Sort(addrsByIpAndUID(ss.NotReadyAddresses))
|
||||
sort.Sort(portsByHash(ss.Ports))
|
||||
}
|
||||
sort.Sort(subsetsByHash(subsets))
|
||||
return subsets
|
||||
}
|
||||
|
||||
func hashObject(hasher hash.Hash, obj interface{}) []byte {
|
||||
hashutil.DeepHashObject(hasher, obj)
|
||||
return hasher.Sum(nil)
|
||||
}
|
||||
|
||||
type subsetsByHash []api.EndpointSubset
|
||||
|
||||
func (sl subsetsByHash) Len() int { return len(sl) }
|
||||
func (sl subsetsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
|
||||
func (sl subsetsByHash) Less(i, j int) bool {
|
||||
hasher := md5.New()
|
||||
h1 := hashObject(hasher, sl[i])
|
||||
h2 := hashObject(hasher, sl[j])
|
||||
return bytes.Compare(h1, h2) < 0
|
||||
}
|
||||
|
||||
type addrsByIpAndUID []api.EndpointAddress
|
||||
|
||||
func (sl addrsByIpAndUID) Len() int { return len(sl) }
|
||||
func (sl addrsByIpAndUID) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
|
||||
func (sl addrsByIpAndUID) Less(i, j int) bool {
|
||||
return LessEndpointAddress(&sl[i], &sl[j])
|
||||
}
|
||||
|
||||
type portsByHash []api.EndpointPort
|
||||
|
||||
func (sl portsByHash) Len() int { return len(sl) }
|
||||
func (sl portsByHash) Swap(i, j int) { sl[i], sl[j] = sl[j], sl[i] }
|
||||
func (sl portsByHash) Less(i, j int) bool {
|
||||
hasher := md5.New()
|
||||
h1 := hashObject(hasher, sl[i])
|
||||
h2 := hashObject(hasher, sl[j])
|
||||
return bytes.Compare(h1, h2) < 0
|
||||
}
|
||||
456
vendor/k8s.io/client-go/1.4/pkg/api/errors/errors.go
generated
vendored
456
vendor/k8s.io/client-go/1.4/pkg/api/errors/errors.go
generated
vendored
|
|
@ -1,456 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// HTTP Status codes not in the golang http package.
|
||||
const (
|
||||
StatusUnprocessableEntity = 422
|
||||
StatusTooManyRequests = 429
|
||||
// HTTP recommendations are for servers to define 5xx error codes
|
||||
// for scenarios not covered by behavior. In this case, ServerTimeout
|
||||
// is an indication that a transient server error has occurred and the
|
||||
// client *should* retry, with an optional Retry-After header to specify
|
||||
// the back off window.
|
||||
StatusServerTimeout = 504
|
||||
)
|
||||
|
||||
// StatusError is an error intended for consumption by a REST API server; it can also be
|
||||
// reconstructed by clients from a REST response. Public to allow easy type switches.
|
||||
type StatusError struct {
|
||||
ErrStatus unversioned.Status
|
||||
}
|
||||
|
||||
// APIStatus is exposed by errors that can be converted to an api.Status object
|
||||
// for finer grained details.
|
||||
type APIStatus interface {
|
||||
Status() unversioned.Status
|
||||
}
|
||||
|
||||
var _ error = &StatusError{}
|
||||
|
||||
// Error implements the Error interface.
|
||||
func (e *StatusError) Error() string {
|
||||
return e.ErrStatus.Message
|
||||
}
|
||||
|
||||
// Status allows access to e's status without having to know the detailed workings
|
||||
// of StatusError. Used by pkg/apiserver.
|
||||
func (e *StatusError) Status() unversioned.Status {
|
||||
return e.ErrStatus
|
||||
}
|
||||
|
||||
// DebugError reports extended info about the error to debug output.
|
||||
func (e *StatusError) DebugError() (string, []interface{}) {
|
||||
if out, err := json.MarshalIndent(e.ErrStatus, "", " "); err == nil {
|
||||
return "server response object: %s", []interface{}{string(out)}
|
||||
}
|
||||
return "server response object: %#v", []interface{}{e.ErrStatus}
|
||||
}
|
||||
|
||||
// UnexpectedObjectError can be returned by FromObject if it's passed a non-status object.
|
||||
type UnexpectedObjectError struct {
|
||||
Object runtime.Object
|
||||
}
|
||||
|
||||
// Error returns an error message describing 'u'.
|
||||
func (u *UnexpectedObjectError) Error() string {
|
||||
return fmt.Sprintf("unexpected object: %v", u.Object)
|
||||
}
|
||||
|
||||
// FromObject generates an StatusError from an unversioned.Status, if that is the type of obj; otherwise,
|
||||
// returns an UnexpecteObjectError.
|
||||
func FromObject(obj runtime.Object) error {
|
||||
switch t := obj.(type) {
|
||||
case *unversioned.Status:
|
||||
return &StatusError{*t}
|
||||
}
|
||||
return &UnexpectedObjectError{obj}
|
||||
}
|
||||
|
||||
// NewNotFound returns a new error which indicates that the resource of the kind and the name was not found.
|
||||
func NewNotFound(qualifiedResource unversioned.GroupResource, name string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusNotFound,
|
||||
Reason: unversioned.StatusReasonNotFound,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q not found", qualifiedResource.String(), name),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewAlreadyExists returns an error indicating the item requested exists by that identifier.
|
||||
func NewAlreadyExists(qualifiedResource unversioned.GroupResource, name string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusConflict,
|
||||
Reason: unversioned.StatusReasonAlreadyExists,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q already exists", qualifiedResource.String(), name),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewUnauthorized returns an error indicating the client is not authorized to perform the requested
|
||||
// action.
|
||||
func NewUnauthorized(reason string) *StatusError {
|
||||
message := reason
|
||||
if len(message) == 0 {
|
||||
message = "not authorized"
|
||||
}
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusUnauthorized,
|
||||
Reason: unversioned.StatusReasonUnauthorized,
|
||||
Message: message,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewForbidden returns an error indicating the requested action was forbidden
|
||||
func NewForbidden(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusForbidden,
|
||||
Reason: unversioned.StatusReasonForbidden,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q is forbidden: %v", qualifiedResource.String(), name, err),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewConflict returns an error indicating the item can't be updated as provided.
|
||||
func NewConflict(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusConflict,
|
||||
Reason: unversioned.StatusReasonConflict,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("Operation cannot be fulfilled on %s %q: %v", qualifiedResource.String(), name, err),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewGone returns an error indicating the item no longer available at the server and no forwarding address is known.
|
||||
func NewGone(message string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusGone,
|
||||
Reason: unversioned.StatusReasonGone,
|
||||
Message: message,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewInvalid returns an error indicating the item is invalid and cannot be processed.
|
||||
func NewInvalid(qualifiedKind unversioned.GroupKind, name string, errs field.ErrorList) *StatusError {
|
||||
causes := make([]unversioned.StatusCause, 0, len(errs))
|
||||
for i := range errs {
|
||||
err := errs[i]
|
||||
causes = append(causes, unversioned.StatusCause{
|
||||
Type: unversioned.CauseType(err.Type),
|
||||
Message: err.ErrorBody(),
|
||||
Field: err.Field,
|
||||
})
|
||||
}
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity
|
||||
Reason: unversioned.StatusReasonInvalid,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedKind.Group,
|
||||
Kind: qualifiedKind.Kind,
|
||||
Name: name,
|
||||
Causes: causes,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q is invalid: %v", qualifiedKind.String(), name, errs.ToAggregate()),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewBadRequest creates an error that indicates that the request is invalid and can not be processed.
|
||||
func NewBadRequest(reason string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusBadRequest,
|
||||
Reason: unversioned.StatusReasonBadRequest,
|
||||
Message: reason,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewServiceUnavailable creates an error that indicates that the requested service is unavailable.
|
||||
func NewServiceUnavailable(reason string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusServiceUnavailable,
|
||||
Reason: unversioned.StatusReasonServiceUnavailable,
|
||||
Message: reason,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewMethodNotSupported returns an error indicating the requested action is not supported on this kind.
|
||||
func NewMethodNotSupported(qualifiedResource unversioned.GroupResource, action string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusMethodNotAllowed,
|
||||
Reason: unversioned.StatusReasonMethodNotAllowed,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
},
|
||||
Message: fmt.Sprintf("%s is not supported on resources of kind %q", action, qualifiedResource.String()),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewServerTimeout returns an error indicating the requested action could not be completed due to a
|
||||
// transient error, and the client should try again.
|
||||
func NewServerTimeout(qualifiedResource unversioned.GroupResource, operation string, retryAfterSeconds int) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusInternalServerError,
|
||||
Reason: unversioned.StatusReasonServerTimeout,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: operation,
|
||||
RetryAfterSeconds: int32(retryAfterSeconds),
|
||||
},
|
||||
Message: fmt.Sprintf("The %s operation against %s could not be completed at this time, please try again.", operation, qualifiedResource.String()),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewServerTimeoutForKind should not exist. Server timeouts happen when accessing resources, the Kind is just what we
|
||||
// happened to be looking at when the request failed. This delegates to keep code sane, but we should work towards removing this.
|
||||
func NewServerTimeoutForKind(qualifiedKind unversioned.GroupKind, operation string, retryAfterSeconds int) *StatusError {
|
||||
return NewServerTimeout(unversioned.GroupResource{Group: qualifiedKind.Group, Resource: qualifiedKind.Kind}, operation, retryAfterSeconds)
|
||||
}
|
||||
|
||||
// NewInternalError returns an error indicating the item is invalid and cannot be processed.
|
||||
func NewInternalError(err error) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusInternalServerError,
|
||||
Reason: unversioned.StatusReasonInternalError,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Causes: []unversioned.StatusCause{{Message: err.Error()}},
|
||||
},
|
||||
Message: fmt.Sprintf("Internal error occurred: %v", err),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewTimeoutError returns an error indicating that a timeout occurred before the request
|
||||
// could be completed. Clients may retry, but the operation may still complete.
|
||||
func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: StatusServerTimeout,
|
||||
Reason: unversioned.StatusReasonTimeout,
|
||||
Message: fmt.Sprintf("Timeout: %s", message),
|
||||
Details: &unversioned.StatusDetails{
|
||||
RetryAfterSeconds: int32(retryAfterSeconds),
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
// NewGenericServerResponse returns a new error for server responses that are not in a recognizable form.
|
||||
func NewGenericServerResponse(code int, verb string, qualifiedResource unversioned.GroupResource, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) *StatusError {
|
||||
reason := unversioned.StatusReasonUnknown
|
||||
message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code)
|
||||
switch code {
|
||||
case http.StatusConflict:
|
||||
if verb == "POST" {
|
||||
reason = unversioned.StatusReasonAlreadyExists
|
||||
} else {
|
||||
reason = unversioned.StatusReasonConflict
|
||||
}
|
||||
message = "the server reported a conflict"
|
||||
case http.StatusNotFound:
|
||||
reason = unversioned.StatusReasonNotFound
|
||||
message = "the server could not find the requested resource"
|
||||
case http.StatusBadRequest:
|
||||
reason = unversioned.StatusReasonBadRequest
|
||||
message = "the server rejected our request for an unknown reason"
|
||||
case http.StatusUnauthorized:
|
||||
reason = unversioned.StatusReasonUnauthorized
|
||||
message = "the server has asked for the client to provide credentials"
|
||||
case http.StatusForbidden:
|
||||
reason = unversioned.StatusReasonForbidden
|
||||
message = "the server does not allow access to the requested resource"
|
||||
case http.StatusMethodNotAllowed:
|
||||
reason = unversioned.StatusReasonMethodNotAllowed
|
||||
message = "the server does not allow this method on the requested resource"
|
||||
case StatusUnprocessableEntity:
|
||||
reason = unversioned.StatusReasonInvalid
|
||||
message = "the server rejected our request due to an error in our request"
|
||||
case StatusServerTimeout:
|
||||
reason = unversioned.StatusReasonServerTimeout
|
||||
message = "the server cannot complete the requested operation at this time, try again later"
|
||||
case StatusTooManyRequests:
|
||||
reason = unversioned.StatusReasonTimeout
|
||||
message = "the server has received too many requests and has asked us to try again later"
|
||||
default:
|
||||
if code >= 500 {
|
||||
reason = unversioned.StatusReasonInternalError
|
||||
message = fmt.Sprintf("an error on the server (%q) has prevented the request from succeeding", serverMessage)
|
||||
}
|
||||
}
|
||||
switch {
|
||||
case !qualifiedResource.Empty() && len(name) > 0:
|
||||
message = fmt.Sprintf("%s (%s %s %s)", message, strings.ToLower(verb), qualifiedResource.String(), name)
|
||||
case !qualifiedResource.Empty():
|
||||
message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), qualifiedResource.String())
|
||||
}
|
||||
var causes []unversioned.StatusCause
|
||||
if isUnexpectedResponse {
|
||||
causes = []unversioned.StatusCause{
|
||||
{
|
||||
Type: unversioned.CauseTypeUnexpectedServerResponse,
|
||||
Message: serverMessage,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
causes = nil
|
||||
}
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: int32(code),
|
||||
Reason: reason,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
|
||||
Causes: causes,
|
||||
RetryAfterSeconds: int32(retryAfterSeconds),
|
||||
},
|
||||
Message: message,
|
||||
}}
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the specified error was created by NewNotFound.
|
||||
func IsNotFound(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonNotFound
|
||||
}
|
||||
|
||||
// IsAlreadyExists determines if the err is an error which indicates that a specified resource already exists.
|
||||
func IsAlreadyExists(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonAlreadyExists
|
||||
}
|
||||
|
||||
// IsConflict determines if the err is an error which indicates the provided update conflicts.
|
||||
func IsConflict(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonConflict
|
||||
}
|
||||
|
||||
// IsInvalid determines if the err is an error which indicates the provided resource is not valid.
|
||||
func IsInvalid(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonInvalid
|
||||
}
|
||||
|
||||
// IsMethodNotSupported determines if the err is an error which indicates the provided action could not
|
||||
// be performed because it is not supported by the server.
|
||||
func IsMethodNotSupported(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonMethodNotAllowed
|
||||
}
|
||||
|
||||
// IsBadRequest determines if err is an error which indicates that the request is invalid.
|
||||
func IsBadRequest(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonBadRequest
|
||||
}
|
||||
|
||||
// IsUnauthorized determines if err is an error which indicates that the request is unauthorized and
|
||||
// requires authentication by the user.
|
||||
func IsUnauthorized(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonUnauthorized
|
||||
}
|
||||
|
||||
// IsForbidden determines if err is an error which indicates that the request is forbidden and cannot
|
||||
// be completed as requested.
|
||||
func IsForbidden(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonForbidden
|
||||
}
|
||||
|
||||
// IsServerTimeout determines if err is an error which indicates that the request needs to be retried
|
||||
// by the client.
|
||||
func IsServerTimeout(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonServerTimeout
|
||||
}
|
||||
|
||||
// IsUnexpectedServerError returns true if the server response was not in the expected API format,
|
||||
// and may be the result of another HTTP actor.
|
||||
func IsUnexpectedServerError(err error) bool {
|
||||
switch t := err.(type) {
|
||||
case APIStatus:
|
||||
if d := t.Status().Details; d != nil {
|
||||
for _, cause := range d.Causes {
|
||||
if cause.Type == unversioned.CauseTypeUnexpectedServerResponse {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsUnexpectedObjectError determines if err is due to an unexpected object from the master.
|
||||
func IsUnexpectedObjectError(err error) bool {
|
||||
_, ok := err.(*UnexpectedObjectError)
|
||||
return err != nil && ok
|
||||
}
|
||||
|
||||
// SuggestsClientDelay returns true if this error suggests a client delay as well as the
|
||||
// suggested seconds to wait, or false if the error does not imply a wait.
|
||||
func SuggestsClientDelay(err error) (int, bool) {
|
||||
switch t := err.(type) {
|
||||
case APIStatus:
|
||||
if t.Status().Details != nil {
|
||||
switch t.Status().Reason {
|
||||
case unversioned.StatusReasonServerTimeout, unversioned.StatusReasonTimeout:
|
||||
return int(t.Status().Details.RetryAfterSeconds), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func reasonForError(err error) unversioned.StatusReason {
|
||||
switch t := err.(type) {
|
||||
case APIStatus:
|
||||
return t.Status().Reason
|
||||
}
|
||||
return unversioned.StatusReasonUnknown
|
||||
}
|
||||
38
vendor/k8s.io/client-go/1.4/pkg/api/field_constants.go
generated
vendored
38
vendor/k8s.io/client-go/1.4/pkg/api/field_constants.go
generated
vendored
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
// Field path constants that are specific to the internal API
|
||||
// representation.
|
||||
const (
|
||||
NodeUnschedulableField = "spec.unschedulable"
|
||||
ObjectNameField = "metadata.name"
|
||||
PodHostField = "spec.nodeName"
|
||||
PodStatusField = "status.phase"
|
||||
SecretTypeField = "type"
|
||||
|
||||
EventReasonField = "reason"
|
||||
EventSourceField = "source"
|
||||
EventTypeField = "type"
|
||||
EventInvolvedKindField = "involvedObject.kind"
|
||||
EventInvolvedNamespaceField = "involvedObject.namespace"
|
||||
EventInvolvedNameField = "involvedObject.name"
|
||||
EventInvolvedUIDField = "involvedObject.uid"
|
||||
EventInvolvedAPIVersionField = "involvedObject.apiVersion"
|
||||
EventInvolvedResourceVersionField = "involvedObject.resourceVersion"
|
||||
EventInvolvedFieldPathField = "involvedObject.fieldPath"
|
||||
)
|
||||
64
vendor/k8s.io/client-go/1.4/pkg/api/generate.go
generated
vendored
64
vendor/k8s.io/client-go/1.4/pkg/api/generate.go
generated
vendored
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
utilrand "k8s.io/client-go/1.4/pkg/util/rand"
|
||||
)
|
||||
|
||||
// NameGenerator generates names for objects. Some backends may have more information
|
||||
// available to guide selection of new names and this interface hides those details.
|
||||
type NameGenerator interface {
|
||||
// GenerateName generates a valid name from the base name, adding a random suffix to the
|
||||
// the base. If base is valid, the returned name must also be valid. The generator is
|
||||
// responsible for knowing the maximum valid name length.
|
||||
GenerateName(base string) string
|
||||
}
|
||||
|
||||
// GenerateName will resolve the object name of the provided ObjectMeta to a generated version if
|
||||
// necessary. It expects that validation for ObjectMeta has already completed (that Base is a
|
||||
// valid name) and that the NameGenerator generates a name that is also valid.
|
||||
func GenerateName(u NameGenerator, meta *ObjectMeta) {
|
||||
if len(meta.GenerateName) == 0 || len(meta.Name) != 0 {
|
||||
return
|
||||
}
|
||||
meta.Name = u.GenerateName(meta.GenerateName)
|
||||
}
|
||||
|
||||
// simpleNameGenerator generates random names.
|
||||
type simpleNameGenerator struct{}
|
||||
|
||||
// SimpleNameGenerator is a generator that returns the name plus a random suffix of five alphanumerics
|
||||
// when a name is requested. The string is guaranteed to not exceed the length of a standard Kubernetes
|
||||
// name (63 characters)
|
||||
var SimpleNameGenerator NameGenerator = simpleNameGenerator{}
|
||||
|
||||
const (
|
||||
// TODO: make this flexible for non-core resources with alternate naming rules.
|
||||
maxNameLength = 63
|
||||
randomLength = 5
|
||||
maxGeneratedNameLength = maxNameLength - randomLength
|
||||
)
|
||||
|
||||
func (simpleNameGenerator) GenerateName(base string) string {
|
||||
if len(base) > maxGeneratedNameLength {
|
||||
base = base[:maxGeneratedNameLength]
|
||||
}
|
||||
return fmt.Sprintf("%s%s", base, utilrand.String(randomLength))
|
||||
}
|
||||
586
vendor/k8s.io/client-go/1.4/pkg/api/helpers.go
generated
vendored
586
vendor/k8s.io/client-go/1.4/pkg/api/helpers.go
generated
vendored
|
|
@ -1,586 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/resource"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/conversion"
|
||||
"k8s.io/client-go/1.4/pkg/fields"
|
||||
"k8s.io/client-go/1.4/pkg/labels"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/selection"
|
||||
"k8s.io/client-go/1.4/pkg/types"
|
||||
"k8s.io/client-go/1.4/pkg/util/sets"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// Conversion error conveniently packages up errors in conversions.
|
||||
type ConversionError struct {
|
||||
In, Out interface{}
|
||||
Message string
|
||||
}
|
||||
|
||||
// Return a helpful string about the error
|
||||
func (c *ConversionError) Error() string {
|
||||
return spew.Sprintf(
|
||||
"Conversion error: %s. (in: %v(%+v) out: %v)",
|
||||
c.Message, reflect.TypeOf(c.In), c.In, reflect.TypeOf(c.Out),
|
||||
)
|
||||
}
|
||||
|
||||
// Semantic can do semantic deep equality checks for api objects.
|
||||
// Example: api.Semantic.DeepEqual(aPod, aPodWithNonNilButEmptyMaps) == true
|
||||
var Semantic = conversion.EqualitiesOrDie(
|
||||
func(a, b resource.Quantity) bool {
|
||||
// Ignore formatting, only care that numeric value stayed the same.
|
||||
// TODO: if we decide it's important, it should be safe to start comparing the format.
|
||||
//
|
||||
// Uninitialized quantities are equivalent to 0 quantities.
|
||||
return a.Cmp(b) == 0
|
||||
},
|
||||
func(a, b unversioned.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 standardResourceQuotaScopes = sets.NewString(
|
||||
string(ResourceQuotaScopeTerminating),
|
||||
string(ResourceQuotaScopeNotTerminating),
|
||||
string(ResourceQuotaScopeBestEffort),
|
||||
string(ResourceQuotaScopeNotBestEffort),
|
||||
)
|
||||
|
||||
// IsStandardResourceQuotaScope returns true if the scope is a standard value
|
||||
func IsStandardResourceQuotaScope(str string) bool {
|
||||
return standardResourceQuotaScopes.Has(str)
|
||||
}
|
||||
|
||||
var podObjectCountQuotaResources = sets.NewString(
|
||||
string(ResourcePods),
|
||||
)
|
||||
|
||||
var podComputeQuotaResources = sets.NewString(
|
||||
string(ResourceCPU),
|
||||
string(ResourceMemory),
|
||||
string(ResourceLimitsCPU),
|
||||
string(ResourceLimitsMemory),
|
||||
string(ResourceRequestsCPU),
|
||||
string(ResourceRequestsMemory),
|
||||
)
|
||||
|
||||
// IsResourceQuotaScopeValidForResource returns true if the resource applies to the specified scope
|
||||
func IsResourceQuotaScopeValidForResource(scope ResourceQuotaScope, resource string) bool {
|
||||
switch scope {
|
||||
case ResourceQuotaScopeTerminating, ResourceQuotaScopeNotTerminating, ResourceQuotaScopeNotBestEffort:
|
||||
return podObjectCountQuotaResources.Has(resource) || podComputeQuotaResources.Has(resource)
|
||||
case ResourceQuotaScopeBestEffort:
|
||||
return podObjectCountQuotaResources.Has(resource)
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
var standardContainerResources = sets.NewString(
|
||||
string(ResourceCPU),
|
||||
string(ResourceMemory),
|
||||
)
|
||||
|
||||
// IsStandardContainerResourceName returns true if the container can make a resource request
|
||||
// for the specified resource
|
||||
func IsStandardContainerResourceName(str string) bool {
|
||||
return standardContainerResources.Has(str)
|
||||
}
|
||||
|
||||
var standardLimitRangeTypes = sets.NewString(
|
||||
string(LimitTypePod),
|
||||
string(LimitTypeContainer),
|
||||
)
|
||||
|
||||
// IsStandardLimitRangeType returns true if the type is Pod or Container
|
||||
func IsStandardLimitRangeType(str string) bool {
|
||||
return standardLimitRangeTypes.Has(str)
|
||||
}
|
||||
|
||||
var standardQuotaResources = sets.NewString(
|
||||
string(ResourceCPU),
|
||||
string(ResourceMemory),
|
||||
string(ResourceRequestsCPU),
|
||||
string(ResourceRequestsMemory),
|
||||
string(ResourceRequestsStorage),
|
||||
string(ResourceLimitsCPU),
|
||||
string(ResourceLimitsMemory),
|
||||
string(ResourcePods),
|
||||
string(ResourceQuotas),
|
||||
string(ResourceServices),
|
||||
string(ResourceReplicationControllers),
|
||||
string(ResourceSecrets),
|
||||
string(ResourcePersistentVolumeClaims),
|
||||
string(ResourceConfigMaps),
|
||||
string(ResourceServicesNodePorts),
|
||||
string(ResourceServicesLoadBalancers),
|
||||
)
|
||||
|
||||
// IsStandardQuotaResourceName returns true if the resource is known to
|
||||
// the quota tracking system
|
||||
func IsStandardQuotaResourceName(str string) bool {
|
||||
return standardQuotaResources.Has(str)
|
||||
}
|
||||
|
||||
var standardResources = sets.NewString(
|
||||
string(ResourceCPU),
|
||||
string(ResourceMemory),
|
||||
string(ResourceRequestsCPU),
|
||||
string(ResourceRequestsMemory),
|
||||
string(ResourceLimitsCPU),
|
||||
string(ResourceLimitsMemory),
|
||||
string(ResourcePods),
|
||||
string(ResourceQuotas),
|
||||
string(ResourceServices),
|
||||
string(ResourceReplicationControllers),
|
||||
string(ResourceSecrets),
|
||||
string(ResourceConfigMaps),
|
||||
string(ResourcePersistentVolumeClaims),
|
||||
string(ResourceStorage),
|
||||
)
|
||||
|
||||
// IsStandardResourceName returns true if the resource is known to the system
|
||||
func IsStandardResourceName(str string) bool {
|
||||
return standardResources.Has(str)
|
||||
}
|
||||
|
||||
var integerResources = sets.NewString(
|
||||
string(ResourcePods),
|
||||
string(ResourceQuotas),
|
||||
string(ResourceServices),
|
||||
string(ResourceReplicationControllers),
|
||||
string(ResourceSecrets),
|
||||
string(ResourceConfigMaps),
|
||||
string(ResourcePersistentVolumeClaims),
|
||||
string(ResourceServicesNodePorts),
|
||||
string(ResourceServicesLoadBalancers),
|
||||
)
|
||||
|
||||
// IsIntegerResourceName returns true if the resource is measured in integer values
|
||||
func IsIntegerResourceName(str string) bool {
|
||||
return integerResources.Has(str)
|
||||
}
|
||||
|
||||
// NewDeleteOptions returns a DeleteOptions indicating the resource should
|
||||
// be deleted within the specified grace period. Use zero to indicate
|
||||
// immediate deletion. If you would prefer to use the default grace period,
|
||||
// use &api.DeleteOptions{} directly.
|
||||
func NewDeleteOptions(grace int64) *DeleteOptions {
|
||||
return &DeleteOptions{GracePeriodSeconds: &grace}
|
||||
}
|
||||
|
||||
// NewPreconditionDeleteOptions returns a DeleteOptions with a UID precondition set.
|
||||
func NewPreconditionDeleteOptions(uid string) *DeleteOptions {
|
||||
u := types.UID(uid)
|
||||
p := Preconditions{UID: &u}
|
||||
return &DeleteOptions{Preconditions: &p}
|
||||
}
|
||||
|
||||
// NewUIDPreconditions returns a Preconditions with UID set.
|
||||
func NewUIDPreconditions(uid string) *Preconditions {
|
||||
u := types.UID(uid)
|
||||
return &Preconditions{UID: &u}
|
||||
}
|
||||
|
||||
// this function aims to check if the service's ClusterIP is set or not
|
||||
// the objective is not to perform validation here
|
||||
func IsServiceIPSet(service *Service) bool {
|
||||
return service.Spec.ClusterIP != ClusterIPNone && service.Spec.ClusterIP != ""
|
||||
}
|
||||
|
||||
// this function aims to check if the service's cluster IP is requested or not
|
||||
func IsServiceIPRequested(service *Service) bool {
|
||||
// ExternalName services are CNAME aliases to external ones. Ignore the IP.
|
||||
if service.Spec.Type == ServiceTypeExternalName {
|
||||
return false
|
||||
}
|
||||
return service.Spec.ClusterIP == ""
|
||||
}
|
||||
|
||||
var standardFinalizers = sets.NewString(
|
||||
string(FinalizerKubernetes),
|
||||
FinalizerOrphan,
|
||||
)
|
||||
|
||||
func IsStandardFinalizerName(str string) bool {
|
||||
return standardFinalizers.Has(str)
|
||||
}
|
||||
|
||||
// SingleObject returns a ListOptions for watching a single object.
|
||||
func SingleObject(meta ObjectMeta) ListOptions {
|
||||
return ListOptions{
|
||||
FieldSelector: fields.OneTermEqualSelector("metadata.name", meta.Name),
|
||||
ResourceVersion: meta.ResourceVersion,
|
||||
}
|
||||
}
|
||||
|
||||
// AddToNodeAddresses appends the NodeAddresses to the passed-by-pointer slice,
|
||||
// only if they do not already exist
|
||||
func AddToNodeAddresses(addresses *[]NodeAddress, addAddresses ...NodeAddress) {
|
||||
for _, add := range addAddresses {
|
||||
exists := false
|
||||
for _, existing := range *addresses {
|
||||
if existing.Address == add.Address && existing.Type == add.Type {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
*addresses = append(*addresses, add)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func HashObject(obj runtime.Object, codec runtime.Codec) (string, error) {
|
||||
data, err := runtime.Encode(codec, obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%x", md5.Sum(data)), nil
|
||||
}
|
||||
|
||||
// TODO: make method on LoadBalancerStatus?
|
||||
func LoadBalancerStatusEqual(l, r *LoadBalancerStatus) bool {
|
||||
return ingressSliceEqual(l.Ingress, r.Ingress)
|
||||
}
|
||||
|
||||
func ingressSliceEqual(lhs, rhs []LoadBalancerIngress) bool {
|
||||
if len(lhs) != len(rhs) {
|
||||
return false
|
||||
}
|
||||
for i := range lhs {
|
||||
if !ingressEqual(&lhs[i], &rhs[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func ingressEqual(lhs, rhs *LoadBalancerIngress) bool {
|
||||
if lhs.IP != rhs.IP {
|
||||
return false
|
||||
}
|
||||
if lhs.Hostname != rhs.Hostname {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO: make method on LoadBalancerStatus?
|
||||
func LoadBalancerStatusDeepCopy(lb *LoadBalancerStatus) *LoadBalancerStatus {
|
||||
c := &LoadBalancerStatus{}
|
||||
c.Ingress = make([]LoadBalancerIngress, len(lb.Ingress))
|
||||
for i := range lb.Ingress {
|
||||
c.Ingress[i] = lb.Ingress[i]
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||
func GetAccessModesAsString(modes []PersistentVolumeAccessMode) string {
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
modesStr := []string{}
|
||||
if containsAccessMode(modes, ReadWriteOnce) {
|
||||
modesStr = append(modesStr, "RWO")
|
||||
}
|
||||
if containsAccessMode(modes, ReadOnlyMany) {
|
||||
modesStr = append(modesStr, "ROX")
|
||||
}
|
||||
if containsAccessMode(modes, ReadWriteMany) {
|
||||
modesStr = append(modesStr, "RWX")
|
||||
}
|
||||
return strings.Join(modesStr, ",")
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns an array of AccessModes from a string created by GetAccessModesAsString
|
||||
func GetAccessModesFromString(modes string) []PersistentVolumeAccessMode {
|
||||
strmodes := strings.Split(modes, ",")
|
||||
accessModes := []PersistentVolumeAccessMode{}
|
||||
for _, s := range strmodes {
|
||||
s = strings.Trim(s, " ")
|
||||
switch {
|
||||
case s == "RWO":
|
||||
accessModes = append(accessModes, ReadWriteOnce)
|
||||
case s == "ROX":
|
||||
accessModes = append(accessModes, ReadOnlyMany)
|
||||
case s == "RWX":
|
||||
accessModes = append(accessModes, ReadWriteMany)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
||||
func removeDuplicateAccessModes(modes []PersistentVolumeAccessMode) []PersistentVolumeAccessMode {
|
||||
accessModes := []PersistentVolumeAccessMode{}
|
||||
for _, m := range modes {
|
||||
if !containsAccessMode(accessModes, m) {
|
||||
accessModes = append(accessModes, m)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
func containsAccessMode(modes []PersistentVolumeAccessMode, mode PersistentVolumeAccessMode) bool {
|
||||
for _, m := range modes {
|
||||
if m == mode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ParseRFC3339 parses an RFC3339 date in either RFC3339Nano or RFC3339 format.
|
||||
func ParseRFC3339(s string, nowFn func() unversioned.Time) (unversioned.Time, error) {
|
||||
if t, timeErr := time.Parse(time.RFC3339Nano, s); timeErr == nil {
|
||||
return unversioned.Time{Time: t}, nil
|
||||
}
|
||||
t, err := time.Parse(time.RFC3339, s)
|
||||
if err != nil {
|
||||
return unversioned.Time{}, err
|
||||
}
|
||||
return unversioned.Time{Time: t}, nil
|
||||
}
|
||||
|
||||
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements
|
||||
// labels.Selector.
|
||||
func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) {
|
||||
if len(nsm) == 0 {
|
||||
return labels.Nothing(), nil
|
||||
}
|
||||
selector := labels.NewSelector()
|
||||
for _, expr := range nsm {
|
||||
var op selection.Operator
|
||||
switch expr.Operator {
|
||||
case NodeSelectorOpIn:
|
||||
op = selection.In
|
||||
case NodeSelectorOpNotIn:
|
||||
op = selection.NotIn
|
||||
case NodeSelectorOpExists:
|
||||
op = selection.Exists
|
||||
case NodeSelectorOpDoesNotExist:
|
||||
op = selection.DoesNotExist
|
||||
case NodeSelectorOpGt:
|
||||
op = selection.GreaterThan
|
||||
case NodeSelectorOpLt:
|
||||
op = selection.LessThan
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
|
||||
}
|
||||
r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
const (
|
||||
// AffinityAnnotationKey represents the key of affinity data (json serialized)
|
||||
// in the Annotations of a Pod.
|
||||
AffinityAnnotationKey string = "scheduler.alpha.kubernetes.io/affinity"
|
||||
|
||||
// TolerationsAnnotationKey represents the key of tolerations data (json serialized)
|
||||
// in the Annotations of a Pod.
|
||||
TolerationsAnnotationKey string = "scheduler.alpha.kubernetes.io/tolerations"
|
||||
|
||||
// TaintsAnnotationKey represents the key of taints data (json serialized)
|
||||
// in the Annotations of a Node.
|
||||
TaintsAnnotationKey string = "scheduler.alpha.kubernetes.io/taints"
|
||||
|
||||
// SeccompPodAnnotationKey represents the key of a seccomp profile applied
|
||||
// to all containers of a pod.
|
||||
SeccompPodAnnotationKey string = "seccomp.security.alpha.kubernetes.io/pod"
|
||||
|
||||
// SeccompContainerAnnotationKeyPrefix represents the key of a seccomp profile applied
|
||||
// to one container of a pod.
|
||||
SeccompContainerAnnotationKeyPrefix string = "container.seccomp.security.alpha.kubernetes.io/"
|
||||
|
||||
// CreatedByAnnotation represents the key used to store the spec(json)
|
||||
// used to create the resource.
|
||||
CreatedByAnnotation = "kubernetes.io/created-by"
|
||||
|
||||
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
|
||||
// in the Annotations of a Node.
|
||||
PreferAvoidPodsAnnotationKey string = "scheduler.alpha.kubernetes.io/preferAvoidPods"
|
||||
|
||||
// SysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
|
||||
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
|
||||
// key-value pairs. Only a limited set of whitelisted and isolated sysctls is supported by
|
||||
// the kubelet. Pods with other sysctls will fail to launch.
|
||||
SysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/sysctls"
|
||||
|
||||
// UnsafeSysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
|
||||
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
|
||||
// key-value pairs. Unsafe sysctls must be explicitly enabled for a kubelet. They are properly
|
||||
// namespaced to a pod or a container, but their isolation is usually unclear or weak. Their use
|
||||
// is at-your-own-risk. Pods that attempt to set an unsafe sysctl that is not enabled for a kubelet
|
||||
// will fail to launch.
|
||||
UnsafeSysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/unsafe-sysctls"
|
||||
)
|
||||
|
||||
// GetAffinityFromPod gets the json serialized affinity data from Pod.Annotations
|
||||
// and converts it to the Affinity type in api.
|
||||
func GetAffinityFromPodAnnotations(annotations map[string]string) (*Affinity, error) {
|
||||
if len(annotations) > 0 && annotations[AffinityAnnotationKey] != "" {
|
||||
var affinity Affinity
|
||||
err := json.Unmarshal([]byte(annotations[AffinityAnnotationKey]), &affinity)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &affinity, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetTolerationsFromPodAnnotations gets the json serialized tolerations data from Pod.Annotations
|
||||
// and converts it to the []Toleration type in api.
|
||||
func GetTolerationsFromPodAnnotations(annotations map[string]string) ([]Toleration, error) {
|
||||
var tolerations []Toleration
|
||||
if len(annotations) > 0 && annotations[TolerationsAnnotationKey] != "" {
|
||||
err := json.Unmarshal([]byte(annotations[TolerationsAnnotationKey]), &tolerations)
|
||||
if err != nil {
|
||||
return tolerations, err
|
||||
}
|
||||
}
|
||||
return tolerations, nil
|
||||
}
|
||||
|
||||
// GetTaintsFromNodeAnnotations gets the json serialized taints data from Pod.Annotations
|
||||
// and converts it to the []Taint type in api.
|
||||
func GetTaintsFromNodeAnnotations(annotations map[string]string) ([]Taint, error) {
|
||||
var taints []Taint
|
||||
if len(annotations) > 0 && annotations[TaintsAnnotationKey] != "" {
|
||||
err := json.Unmarshal([]byte(annotations[TaintsAnnotationKey]), &taints)
|
||||
if err != nil {
|
||||
return []Taint{}, err
|
||||
}
|
||||
}
|
||||
return taints, nil
|
||||
}
|
||||
|
||||
// TolerationToleratesTaint checks if the toleration tolerates the taint.
|
||||
func TolerationToleratesTaint(toleration *Toleration, taint *Taint) bool {
|
||||
if len(toleration.Effect) != 0 && toleration.Effect != taint.Effect {
|
||||
return false
|
||||
}
|
||||
|
||||
if toleration.Key != taint.Key {
|
||||
return false
|
||||
}
|
||||
// TODO: Use proper defaulting when Toleration becomes a field of PodSpec
|
||||
if (len(toleration.Operator) == 0 || toleration.Operator == TolerationOpEqual) && toleration.Value == taint.Value {
|
||||
return true
|
||||
}
|
||||
if toleration.Operator == TolerationOpExists {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
// TaintToleratedByTolerations checks if taint is tolerated by any of the tolerations.
|
||||
func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool {
|
||||
tolerated := false
|
||||
for i := range tolerations {
|
||||
if TolerationToleratesTaint(&tolerations[i], taint) {
|
||||
tolerated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return tolerated
|
||||
}
|
||||
|
||||
func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (AvoidPods, error) {
|
||||
var avoidPods AvoidPods
|
||||
if len(annotations) > 0 && annotations[PreferAvoidPodsAnnotationKey] != "" {
|
||||
err := json.Unmarshal([]byte(annotations[PreferAvoidPodsAnnotationKey]), &avoidPods)
|
||||
if err != nil {
|
||||
return avoidPods, err
|
||||
}
|
||||
}
|
||||
return avoidPods, nil
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
||||
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
||||
// SysctlsFromPodAnnotation.
|
||||
func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) {
|
||||
safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return safe, unsafe, nil
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
||||
func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
|
||||
if len(annotation) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
kvs := strings.Split(annotation, ",")
|
||||
sysctls := make([]Sysctl, len(kvs))
|
||||
for i, kv := range kvs {
|
||||
cs := strings.Split(kv, "=")
|
||||
if len(cs) != 2 {
|
||||
return nil, fmt.Errorf("sysctl %q not of the format sysctl_name=value", kv)
|
||||
}
|
||||
sysctls[i].Name = cs[0]
|
||||
sysctls[i].Value = cs[1]
|
||||
}
|
||||
return sysctls, nil
|
||||
}
|
||||
|
||||
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
||||
func PodAnnotationsFromSysctls(sysctls []Sysctl) string {
|
||||
if len(sysctls) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
kvs := make([]string, len(sysctls))
|
||||
for i := range sysctls {
|
||||
kvs[i] = fmt.Sprintf("%s=%s", sysctls[i].Name, sysctls[i].Value)
|
||||
}
|
||||
return strings.Join(kvs, ",")
|
||||
}
|
||||
68
vendor/k8s.io/client-go/1.4/pkg/api/mapper.go
generated
vendored
68
vendor/k8s.io/client-go/1.4/pkg/api/mapper.go
generated
vendored
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/util/sets"
|
||||
)
|
||||
|
||||
var RESTMapper meta.RESTMapper
|
||||
|
||||
func init() {
|
||||
RESTMapper = meta.MultiRESTMapper{}
|
||||
}
|
||||
|
||||
func RegisterRESTMapper(m meta.RESTMapper) {
|
||||
RESTMapper = append(RESTMapper.(meta.MultiRESTMapper), m)
|
||||
}
|
||||
|
||||
// Instantiates a DefaultRESTMapper based on types registered in api.Scheme
|
||||
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
|
||||
importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper {
|
||||
return NewDefaultRESTMapperFromScheme(defaultGroupVersions, interfacesFunc, importPathPrefix, ignoredKinds, rootScoped, Scheme)
|
||||
}
|
||||
|
||||
// Instantiates a DefaultRESTMapper based on types registered in the given scheme.
|
||||
func NewDefaultRESTMapperFromScheme(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
|
||||
importPathPrefix string, ignoredKinds, rootScoped sets.String, scheme *runtime.Scheme) *meta.DefaultRESTMapper {
|
||||
|
||||
mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc)
|
||||
// enumerate all supported versions, get the kinds, and register with the mapper how to address
|
||||
// our resources.
|
||||
for _, gv := range defaultGroupVersions {
|
||||
for kind, oType := range scheme.KnownTypes(gv) {
|
||||
gvk := gv.WithKind(kind)
|
||||
// TODO: Remove import path check.
|
||||
// We check the import path because we currently stuff both "api" and "extensions" objects
|
||||
// into the same group within Scheme since Scheme has no notion of groups yet.
|
||||
if !strings.Contains(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) {
|
||||
continue
|
||||
}
|
||||
scope := meta.RESTScopeNamespace
|
||||
if rootScoped.Has(kind) {
|
||||
scope = meta.RESTScopeRoot
|
||||
}
|
||||
mapper.Add(gvk, scope)
|
||||
}
|
||||
}
|
||||
return mapper
|
||||
}
|
||||
140
vendor/k8s.io/client-go/1.4/pkg/api/meta.go
generated
vendored
140
vendor/k8s.io/client-go/1.4/pkg/api/meta.go
generated
vendored
|
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/meta/metatypes"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/conversion"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/types"
|
||||
"k8s.io/client-go/1.4/pkg/util/uuid"
|
||||
)
|
||||
|
||||
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
|
||||
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
|
||||
meta.CreationTimestamp = unversioned.Now()
|
||||
// allows admission controllers to assign a UID earlier in the request processing
|
||||
// to support tracking resources pending creation.
|
||||
uid, found := UIDFrom(ctx)
|
||||
if !found {
|
||||
uid = uuid.NewUUID()
|
||||
}
|
||||
meta.UID = uid
|
||||
meta.SelfLink = ""
|
||||
}
|
||||
|
||||
// HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values.
|
||||
func HasObjectMetaSystemFieldValues(meta *ObjectMeta) bool {
|
||||
return !meta.CreationTimestamp.Time.IsZero() ||
|
||||
len(meta.UID) != 0
|
||||
}
|
||||
|
||||
// ObjectMetaFor returns a pointer to a provided object's ObjectMeta.
|
||||
// TODO: allow runtime.Unknown to extract this object
|
||||
// TODO: Remove this function and use meta.Accessor() instead.
|
||||
func ObjectMetaFor(obj runtime.Object) (*ObjectMeta, error) {
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var meta *ObjectMeta
|
||||
err = runtime.FieldPtr(v, "ObjectMeta", &meta)
|
||||
return meta, err
|
||||
}
|
||||
|
||||
// ListMetaFor returns a pointer to a provided object's ListMeta,
|
||||
// or an error if the object does not have that pointer.
|
||||
// TODO: allow runtime.Unknown to extract this object
|
||||
func ListMetaFor(obj runtime.Object) (*unversioned.ListMeta, error) {
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var meta *unversioned.ListMeta
|
||||
err = runtime.FieldPtr(v, "ListMeta", &meta)
|
||||
return meta, err
|
||||
}
|
||||
|
||||
func (obj *ObjectMeta) GetObjectMeta() meta.Object { return obj }
|
||||
|
||||
// Namespace implements meta.Object for any object with an ObjectMeta typed field. Allows
|
||||
// fast, direct access to metadata fields for API objects.
|
||||
func (meta *ObjectMeta) GetNamespace() string { return meta.Namespace }
|
||||
func (meta *ObjectMeta) SetNamespace(namespace string) { meta.Namespace = namespace }
|
||||
func (meta *ObjectMeta) GetName() string { return meta.Name }
|
||||
func (meta *ObjectMeta) SetName(name string) { meta.Name = name }
|
||||
func (meta *ObjectMeta) GetGenerateName() string { return meta.GenerateName }
|
||||
func (meta *ObjectMeta) SetGenerateName(generateName string) { meta.GenerateName = generateName }
|
||||
func (meta *ObjectMeta) GetUID() types.UID { return meta.UID }
|
||||
func (meta *ObjectMeta) SetUID(uid types.UID) { meta.UID = uid }
|
||||
func (meta *ObjectMeta) GetResourceVersion() string { return meta.ResourceVersion }
|
||||
func (meta *ObjectMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
|
||||
func (meta *ObjectMeta) GetSelfLink() string { return meta.SelfLink }
|
||||
func (meta *ObjectMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
|
||||
func (meta *ObjectMeta) GetCreationTimestamp() unversioned.Time { return meta.CreationTimestamp }
|
||||
func (meta *ObjectMeta) SetCreationTimestamp(creationTimestamp unversioned.Time) {
|
||||
meta.CreationTimestamp = creationTimestamp
|
||||
}
|
||||
func (meta *ObjectMeta) GetDeletionTimestamp() *unversioned.Time { return meta.DeletionTimestamp }
|
||||
func (meta *ObjectMeta) SetDeletionTimestamp(deletionTimestamp *unversioned.Time) {
|
||||
meta.DeletionTimestamp = deletionTimestamp
|
||||
}
|
||||
func (meta *ObjectMeta) GetLabels() map[string]string { return meta.Labels }
|
||||
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
|
||||
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
|
||||
func (meta *ObjectMeta) SetAnnotations(annotations map[string]string) { meta.Annotations = annotations }
|
||||
func (meta *ObjectMeta) GetFinalizers() []string { return meta.Finalizers }
|
||||
func (meta *ObjectMeta) SetFinalizers(finalizers []string) { meta.Finalizers = finalizers }
|
||||
|
||||
func (meta *ObjectMeta) GetOwnerReferences() []metatypes.OwnerReference {
|
||||
ret := make([]metatypes.OwnerReference, len(meta.OwnerReferences))
|
||||
for i := 0; i < len(meta.OwnerReferences); i++ {
|
||||
ret[i].Kind = meta.OwnerReferences[i].Kind
|
||||
ret[i].Name = meta.OwnerReferences[i].Name
|
||||
ret[i].UID = meta.OwnerReferences[i].UID
|
||||
ret[i].APIVersion = meta.OwnerReferences[i].APIVersion
|
||||
if meta.OwnerReferences[i].Controller != nil {
|
||||
value := *meta.OwnerReferences[i].Controller
|
||||
ret[i].Controller = &value
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (meta *ObjectMeta) SetOwnerReferences(references []metatypes.OwnerReference) {
|
||||
newReferences := make([]OwnerReference, len(references))
|
||||
for i := 0; i < len(references); i++ {
|
||||
newReferences[i].Kind = references[i].Kind
|
||||
newReferences[i].Name = references[i].Name
|
||||
newReferences[i].UID = references[i].UID
|
||||
newReferences[i].APIVersion = references[i].APIVersion
|
||||
if references[i].Controller != nil {
|
||||
value := *references[i].Controller
|
||||
newReferences[i].Controller = &value
|
||||
}
|
||||
}
|
||||
meta.OwnerReferences = newReferences
|
||||
}
|
||||
|
||||
func (meta *ObjectMeta) GetClusterName() string {
|
||||
return meta.ClusterName
|
||||
}
|
||||
func (meta *ObjectMeta) SetClusterName(clusterName string) {
|
||||
meta.ClusterName = clusterName
|
||||
}
|
||||
19
vendor/k8s.io/client-go/1.4/pkg/api/meta/doc.go
generated
vendored
19
vendor/k8s.io/client-go/1.4/pkg/api/meta/doc.go
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package meta provides functions for retrieving API metadata from objects
|
||||
// belonging to the Kubernetes API
|
||||
package meta
|
||||
105
vendor/k8s.io/client-go/1.4/pkg/api/meta/errors.go
generated
vendored
105
vendor/k8s.io/client-go/1.4/pkg/api/meta/errors.go
generated
vendored
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// AmbiguousResourceError is returned if the RESTMapper finds multiple matches for a resource
|
||||
type AmbiguousResourceError struct {
|
||||
PartialResource unversioned.GroupVersionResource
|
||||
|
||||
MatchingResources []unversioned.GroupVersionResource
|
||||
MatchingKinds []unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *AmbiguousResourceError) Error() string {
|
||||
switch {
|
||||
case len(e.MatchingKinds) > 0 && len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v and kinds %v", e.PartialResource, e.MatchingResources, e.MatchingKinds)
|
||||
case len(e.MatchingKinds) > 0:
|
||||
return fmt.Sprintf("%v matches multiple kinds %v", e.PartialResource, e.MatchingKinds)
|
||||
case len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v", e.PartialResource, e.MatchingResources)
|
||||
}
|
||||
return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialResource)
|
||||
}
|
||||
|
||||
// AmbiguousKindError is returned if the RESTMapper finds multiple matches for a kind
|
||||
type AmbiguousKindError struct {
|
||||
PartialKind unversioned.GroupVersionKind
|
||||
|
||||
MatchingResources []unversioned.GroupVersionResource
|
||||
MatchingKinds []unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *AmbiguousKindError) Error() string {
|
||||
switch {
|
||||
case len(e.MatchingKinds) > 0 && len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v and kinds %v", e.PartialKind, e.MatchingResources, e.MatchingKinds)
|
||||
case len(e.MatchingKinds) > 0:
|
||||
return fmt.Sprintf("%v matches multiple kinds %v", e.PartialKind, e.MatchingKinds)
|
||||
case len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v", e.PartialKind, e.MatchingResources)
|
||||
}
|
||||
return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialKind)
|
||||
}
|
||||
|
||||
func IsAmbiguousError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
switch err.(type) {
|
||||
case *AmbiguousResourceError, *AmbiguousKindError:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// NoResourceMatchError is returned if the RESTMapper can't find any match for a resource
|
||||
type NoResourceMatchError struct {
|
||||
PartialResource unversioned.GroupVersionResource
|
||||
}
|
||||
|
||||
func (e *NoResourceMatchError) Error() string {
|
||||
return fmt.Sprintf("no matches for %v", e.PartialResource)
|
||||
}
|
||||
|
||||
// NoKindMatchError is returned if the RESTMapper can't find any match for a kind
|
||||
type NoKindMatchError struct {
|
||||
PartialKind unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *NoKindMatchError) Error() string {
|
||||
return fmt.Sprintf("no matches for %v", e.PartialKind)
|
||||
}
|
||||
|
||||
func IsNoMatchError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
switch err.(type) {
|
||||
case *NoResourceMatchError, *NoKindMatchError:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
134
vendor/k8s.io/client-go/1.4/pkg/api/meta/help.go
generated
vendored
134
vendor/k8s.io/client-go/1.4/pkg/api/meta/help.go
generated
vendored
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/conversion"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
)
|
||||
|
||||
// IsListType returns true if the provided Object has a slice called Items
|
||||
func IsListType(obj runtime.Object) bool {
|
||||
_, err := GetItemsPtr(obj)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// GetItemsPtr returns a pointer to the list object's Items member.
|
||||
// If 'list' doesn't have an Items member, it's not really a list type
|
||||
// and an error will be returned.
|
||||
// This function will either return a pointer to a slice, or an error, but not both.
|
||||
func GetItemsPtr(list runtime.Object) (interface{}, error) {
|
||||
v, err := conversion.EnforcePtr(list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items := v.FieldByName("Items")
|
||||
if !items.IsValid() {
|
||||
return nil, fmt.Errorf("no Items field in %#v", list)
|
||||
}
|
||||
switch items.Kind() {
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
target := reflect.TypeOf(items.Interface()).Elem()
|
||||
if target.Kind() != reflect.Slice {
|
||||
return nil, fmt.Errorf("items: Expected slice, got %s", target.Kind())
|
||||
}
|
||||
return items.Interface(), nil
|
||||
case reflect.Slice:
|
||||
return items.Addr().Interface(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("items: Expected slice, got %s", items.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
// ExtractList returns obj's Items element as an array of runtime.Objects.
|
||||
// Returns an error if obj is not a List type (does not have an Items member).
|
||||
func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
|
||||
itemsPtr, err := GetItemsPtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items, err := conversion.EnforcePtr(itemsPtr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list := make([]runtime.Object, items.Len())
|
||||
for i := range list {
|
||||
raw := items.Index(i)
|
||||
switch item := raw.Interface().(type) {
|
||||
case runtime.RawExtension:
|
||||
switch {
|
||||
case item.Object != nil:
|
||||
list[i] = item.Object
|
||||
case item.Raw != nil:
|
||||
// TODO: Set ContentEncoding and ContentType correctly.
|
||||
list[i] = &runtime.Unknown{Raw: item.Raw}
|
||||
default:
|
||||
list[i] = nil
|
||||
}
|
||||
case runtime.Object:
|
||||
list[i] = item
|
||||
default:
|
||||
var found bool
|
||||
if list[i], found = raw.Addr().Interface().(runtime.Object); !found {
|
||||
return nil, fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
|
||||
}
|
||||
}
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// objectSliceType is the type of a slice of Objects
|
||||
var objectSliceType = reflect.TypeOf([]runtime.Object{})
|
||||
|
||||
// SetList sets the given list object's Items member have the elements given in
|
||||
// objects.
|
||||
// Returns an error if list is not a List type (does not have an Items member),
|
||||
// or if any of the objects are not of the right type.
|
||||
func SetList(list runtime.Object, objects []runtime.Object) error {
|
||||
itemsPtr, err := GetItemsPtr(list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items, err := conversion.EnforcePtr(itemsPtr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if items.Type() == objectSliceType {
|
||||
items.Set(reflect.ValueOf(objects))
|
||||
return nil
|
||||
}
|
||||
slice := reflect.MakeSlice(items.Type(), len(objects), len(objects))
|
||||
for i := range objects {
|
||||
dest := slice.Index(i)
|
||||
src, err := conversion.EnforcePtr(objects[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if src.Type().AssignableTo(dest.Type()) {
|
||||
dest.Set(src)
|
||||
} else if src.Type().ConvertibleTo(dest.Type()) {
|
||||
dest.Set(src.Convert(dest.Type()))
|
||||
} else {
|
||||
return fmt.Errorf("item[%d]: can't assign or convert %v into %v", i, src.Type(), dest.Type())
|
||||
}
|
||||
}
|
||||
items.Set(slice)
|
||||
return nil
|
||||
}
|
||||
185
vendor/k8s.io/client-go/1.4/pkg/api/meta/interfaces.go
generated
vendored
185
vendor/k8s.io/client-go/1.4/pkg/api/meta/interfaces.go
generated
vendored
|
|
@ -1,185 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/meta/metatypes"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/types"
|
||||
)
|
||||
|
||||
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
||||
type VersionInterfaces struct {
|
||||
runtime.ObjectConvertor
|
||||
MetadataAccessor
|
||||
}
|
||||
|
||||
type ObjectMetaAccessor interface {
|
||||
GetObjectMeta() Object
|
||||
}
|
||||
|
||||
// Object lets you work with object metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field (Name, UID, Namespace on lists) will be a no-op and return
|
||||
// a default value.
|
||||
type Object interface {
|
||||
GetNamespace() string
|
||||
SetNamespace(namespace string)
|
||||
GetName() string
|
||||
SetName(name string)
|
||||
GetGenerateName() string
|
||||
SetGenerateName(name string)
|
||||
GetUID() types.UID
|
||||
SetUID(uid types.UID)
|
||||
GetResourceVersion() string
|
||||
SetResourceVersion(version string)
|
||||
GetSelfLink() string
|
||||
SetSelfLink(selfLink string)
|
||||
GetCreationTimestamp() unversioned.Time
|
||||
SetCreationTimestamp(timestamp unversioned.Time)
|
||||
GetDeletionTimestamp() *unversioned.Time
|
||||
SetDeletionTimestamp(timestamp *unversioned.Time)
|
||||
GetLabels() map[string]string
|
||||
SetLabels(labels map[string]string)
|
||||
GetAnnotations() map[string]string
|
||||
SetAnnotations(annotations map[string]string)
|
||||
GetFinalizers() []string
|
||||
SetFinalizers(finalizers []string)
|
||||
GetOwnerReferences() []metatypes.OwnerReference
|
||||
SetOwnerReferences([]metatypes.OwnerReference)
|
||||
GetClusterName() string
|
||||
SetClusterName(clusterName string)
|
||||
}
|
||||
|
||||
var _ Object = &runtime.Unstructured{}
|
||||
|
||||
type ListMetaAccessor interface {
|
||||
GetListMeta() List
|
||||
}
|
||||
|
||||
// List lets you work with list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field will be a no-op and return a default value.
|
||||
type List unversioned.List
|
||||
|
||||
// Type exposes the type and APIVersion of versioned or internal API objects.
|
||||
type Type unversioned.Type
|
||||
|
||||
// MetadataAccessor lets you work with object and list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field (Name, UID, Namespace on lists) will be a no-op and return
|
||||
// a default value.
|
||||
//
|
||||
// MetadataAccessor exposes Interface in a way that can be used with multiple objects.
|
||||
type MetadataAccessor interface {
|
||||
APIVersion(obj runtime.Object) (string, error)
|
||||
SetAPIVersion(obj runtime.Object, version string) error
|
||||
|
||||
Kind(obj runtime.Object) (string, error)
|
||||
SetKind(obj runtime.Object, kind string) error
|
||||
|
||||
Namespace(obj runtime.Object) (string, error)
|
||||
SetNamespace(obj runtime.Object, namespace string) error
|
||||
|
||||
Name(obj runtime.Object) (string, error)
|
||||
SetName(obj runtime.Object, name string) error
|
||||
|
||||
GenerateName(obj runtime.Object) (string, error)
|
||||
SetGenerateName(obj runtime.Object, name string) error
|
||||
|
||||
UID(obj runtime.Object) (types.UID, error)
|
||||
SetUID(obj runtime.Object, uid types.UID) error
|
||||
|
||||
SelfLink(obj runtime.Object) (string, error)
|
||||
SetSelfLink(obj runtime.Object, selfLink string) error
|
||||
|
||||
Labels(obj runtime.Object) (map[string]string, error)
|
||||
SetLabels(obj runtime.Object, labels map[string]string) error
|
||||
|
||||
Annotations(obj runtime.Object) (map[string]string, error)
|
||||
SetAnnotations(obj runtime.Object, annotations map[string]string) error
|
||||
|
||||
runtime.ResourceVersioner
|
||||
}
|
||||
|
||||
type RESTScopeName string
|
||||
|
||||
const (
|
||||
RESTScopeNameNamespace RESTScopeName = "namespace"
|
||||
RESTScopeNameRoot RESTScopeName = "root"
|
||||
)
|
||||
|
||||
// RESTScope contains the information needed to deal with REST resources that are in a resource hierarchy
|
||||
type RESTScope interface {
|
||||
// Name of the scope
|
||||
Name() RESTScopeName
|
||||
// ParamName is the optional name of the parameter that should be inserted in the resource url
|
||||
// If empty, no param will be inserted
|
||||
ParamName() string
|
||||
// ArgumentName is the optional name that should be used for the variable holding the value.
|
||||
ArgumentName() string
|
||||
// ParamDescription is the optional description to use to document the parameter in api documentation
|
||||
ParamDescription() string
|
||||
}
|
||||
|
||||
// RESTMapping contains the information needed to deal with objects of a specific
|
||||
// resource and kind in a RESTful manner.
|
||||
type RESTMapping struct {
|
||||
// Resource is a string representing the name of this resource as a REST client would see it
|
||||
Resource string
|
||||
|
||||
GroupVersionKind unversioned.GroupVersionKind
|
||||
|
||||
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
||||
Scope RESTScope
|
||||
|
||||
runtime.ObjectConvertor
|
||||
MetadataAccessor
|
||||
}
|
||||
|
||||
// RESTMapper allows clients to map resources to kind, and map kind and version
|
||||
// to interfaces for manipulating those objects. It is primarily intended for
|
||||
// consumers of Kubernetes compatible REST APIs as defined in docs/devel/api-conventions.md.
|
||||
//
|
||||
// The Kubernetes API provides versioned resources and object kinds which are scoped
|
||||
// to API groups. In other words, kinds and resources should not be assumed to be
|
||||
// unique across groups.
|
||||
//
|
||||
// TODO(caesarxuchao): Add proper multi-group support so that kinds & resources are
|
||||
// scoped to groups. See http://issues.k8s.io/12413 and http://issues.k8s.io/10009.
|
||||
type RESTMapper interface {
|
||||
// KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||
KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error)
|
||||
|
||||
// KindsFor takes a partial resource and returns the list of potential kinds in priority order
|
||||
KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error)
|
||||
|
||||
// ResourceFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||
ResourceFor(input unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error)
|
||||
|
||||
// ResourcesFor takes a partial resource and returns the list of potential resource in priority order
|
||||
ResourcesFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error)
|
||||
|
||||
// RESTMapping identifies a preferred resource mapping for the provided group kind.
|
||||
RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error)
|
||||
// RESTMappings returns all resource mappings for the provided group kind.
|
||||
RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error)
|
||||
|
||||
AliasesForResource(resource string) ([]string, bool)
|
||||
ResourceSingularizer(resource string) (singular string, err error)
|
||||
}
|
||||
567
vendor/k8s.io/client-go/1.4/pkg/api/meta/meta.go
generated
vendored
567
vendor/k8s.io/client-go/1.4/pkg/api/meta/meta.go
generated
vendored
|
|
@ -1,567 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/meta/metatypes"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/conversion"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/types"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// errNotList is returned when an object implements the Object style interfaces but not the List style
|
||||
// interfaces.
|
||||
var errNotList = fmt.Errorf("object does not implement the List interfaces")
|
||||
|
||||
// ListAccessor returns a List interface for the provided object or an error if the object does
|
||||
// not provide List.
|
||||
// IMPORTANT: Objects are a superset of lists, so all Objects return List metadata. Do not use this
|
||||
// check to determine whether an object *is* a List.
|
||||
// TODO: return bool instead of error
|
||||
func ListAccessor(obj interface{}) (List, error) {
|
||||
switch t := obj.(type) {
|
||||
case List:
|
||||
return t, nil
|
||||
case unversioned.List:
|
||||
return t, nil
|
||||
case ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
case unversioned.ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
case Object:
|
||||
return t, nil
|
||||
case ObjectMetaAccessor:
|
||||
if m := t.GetObjectMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
default:
|
||||
return nil, errNotList
|
||||
}
|
||||
}
|
||||
|
||||
// errNotObject is returned when an object implements the List style interfaces but not the Object style
|
||||
// interfaces.
|
||||
var errNotObject = fmt.Errorf("object does not implement the Object interfaces")
|
||||
|
||||
// Accessor takes an arbitrary object pointer and returns meta.Interface.
|
||||
// obj must be a pointer to an API type. An error is returned if the minimum
|
||||
// required fields are missing. Fields that are not required return the default
|
||||
// value and are a no-op if set.
|
||||
// TODO: return bool instead of error
|
||||
func Accessor(obj interface{}) (Object, error) {
|
||||
switch t := obj.(type) {
|
||||
case Object:
|
||||
return t, nil
|
||||
case ObjectMetaAccessor:
|
||||
if m := t.GetObjectMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotObject
|
||||
case List, unversioned.List, ListMetaAccessor, unversioned.ListMetaAccessor:
|
||||
return nil, errNotObject
|
||||
default:
|
||||
return nil, errNotObject
|
||||
}
|
||||
}
|
||||
|
||||
// TypeAccessor returns an interface that allows retrieving and modifying the APIVersion
|
||||
// and Kind of an in-memory internal object.
|
||||
// TODO: this interface is used to test code that does not have ObjectMeta or ListMeta
|
||||
// in round tripping (objects which can use apiVersion/kind, but do not fit the Kube
|
||||
// api conventions).
|
||||
func TypeAccessor(obj interface{}) (Type, error) {
|
||||
if typed, ok := obj.(runtime.Object); ok {
|
||||
return objectAccessor{typed}, nil
|
||||
}
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := v.Type()
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface())
|
||||
}
|
||||
|
||||
typeMeta := v.FieldByName("TypeMeta")
|
||||
if !typeMeta.IsValid() {
|
||||
return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t)
|
||||
}
|
||||
a := &genericAccessor{}
|
||||
if err := extractFromTypeMeta(typeMeta, a); err != nil {
|
||||
return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err)
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
type objectAccessor struct {
|
||||
runtime.Object
|
||||
}
|
||||
|
||||
func (obj objectAccessor) GetKind() string {
|
||||
return obj.GetObjectKind().GroupVersionKind().Kind
|
||||
}
|
||||
|
||||
func (obj objectAccessor) SetKind(kind string) {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
gvk.Kind = kind
|
||||
obj.GetObjectKind().SetGroupVersionKind(gvk)
|
||||
}
|
||||
|
||||
func (obj objectAccessor) GetAPIVersion() string {
|
||||
return obj.GetObjectKind().GroupVersionKind().GroupVersion().String()
|
||||
}
|
||||
|
||||
func (obj objectAccessor) SetAPIVersion(version string) {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
gv, err := unversioned.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
gv = unversioned.GroupVersion{Version: version}
|
||||
}
|
||||
gvk.Group, gvk.Version = gv.Group, gv.Version
|
||||
obj.GetObjectKind().SetGroupVersionKind(gvk)
|
||||
}
|
||||
|
||||
// NewAccessor returns a MetadataAccessor that can retrieve
|
||||
// or manipulate resource version on objects derived from core API
|
||||
// metadata concepts.
|
||||
func NewAccessor() MetadataAccessor {
|
||||
return resourceAccessor{}
|
||||
}
|
||||
|
||||
// resourceAccessor implements ResourceVersioner and SelfLinker.
|
||||
type resourceAccessor struct{}
|
||||
|
||||
func (resourceAccessor) Kind(obj runtime.Object) (string, error) {
|
||||
return objectAccessor{obj}.GetKind(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetKind(obj runtime.Object, kind string) error {
|
||||
objectAccessor{obj}.SetKind(kind)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) {
|
||||
return objectAccessor{obj}.GetAPIVersion(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error {
|
||||
objectAccessor{obj}.SetAPIVersion(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Namespace(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetNamespace(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetNamespace(namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Name(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetName(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetName(obj runtime.Object, name string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetName(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetGenerateName(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetGenerateName(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetUID(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetUID(uid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetSelfLink(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetSelfLink(selfLink)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return accessor.GetLabels(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetLabels(labels)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return accessor.GetAnnotations(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetAnnotations(annotations)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetResourceVersion(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetResourceVersion(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractFromOwnerReference extracts v to o. v is the OwnerReferences field of an object.
|
||||
func extractFromOwnerReference(v reflect.Value, o *metatypes.OwnerReference) error {
|
||||
if err := runtime.Field(v, "APIVersion", &o.APIVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "Kind", &o.Kind); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "Name", &o.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "UID", &o.UID); err != nil {
|
||||
return err
|
||||
}
|
||||
var controllerPtr *bool
|
||||
if err := runtime.Field(v, "Controller", &controllerPtr); err != nil {
|
||||
return err
|
||||
}
|
||||
if controllerPtr != nil {
|
||||
controller := *controllerPtr
|
||||
o.Controller = &controller
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setOwnerReference sets v to o. v is the OwnerReferences field of an object.
|
||||
func setOwnerReference(v reflect.Value, o *metatypes.OwnerReference) error {
|
||||
if err := runtime.SetField(o.APIVersion, v, "APIVersion"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.Kind, v, "Kind"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.Name, v, "Name"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.UID, v, "UID"); err != nil {
|
||||
return err
|
||||
}
|
||||
if o.Controller != nil {
|
||||
controller := *(o.Controller)
|
||||
if err := runtime.SetField(&controller, v, "Controller"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// genericAccessor contains pointers to strings that can modify an arbitrary
|
||||
// struct and implements the Accessor interface.
|
||||
type genericAccessor struct {
|
||||
namespace *string
|
||||
name *string
|
||||
generateName *string
|
||||
uid *types.UID
|
||||
apiVersion *string
|
||||
kind *string
|
||||
resourceVersion *string
|
||||
selfLink *string
|
||||
creationTimestamp *unversioned.Time
|
||||
deletionTimestamp **unversioned.Time
|
||||
labels *map[string]string
|
||||
annotations *map[string]string
|
||||
ownerReferences reflect.Value
|
||||
finalizers *[]string
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetNamespace() string {
|
||||
if a.namespace == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.namespace
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetNamespace(namespace string) {
|
||||
if a.namespace == nil {
|
||||
return
|
||||
}
|
||||
*a.namespace = namespace
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetName() string {
|
||||
if a.name == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.name
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetName(name string) {
|
||||
if a.name == nil {
|
||||
return
|
||||
}
|
||||
*a.name = name
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetGenerateName() string {
|
||||
if a.generateName == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.generateName
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetGenerateName(generateName string) {
|
||||
if a.generateName == nil {
|
||||
return
|
||||
}
|
||||
*a.generateName = generateName
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetUID() types.UID {
|
||||
if a.uid == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.uid
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetUID(uid types.UID) {
|
||||
if a.uid == nil {
|
||||
return
|
||||
}
|
||||
*a.uid = uid
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetAPIVersion() string {
|
||||
return *a.apiVersion
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetAPIVersion(version string) {
|
||||
*a.apiVersion = version
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetKind() string {
|
||||
return *a.kind
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetKind(kind string) {
|
||||
*a.kind = kind
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetResourceVersion() string {
|
||||
return *a.resourceVersion
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetResourceVersion(version string) {
|
||||
*a.resourceVersion = version
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetSelfLink() string {
|
||||
return *a.selfLink
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetSelfLink(selfLink string) {
|
||||
*a.selfLink = selfLink
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetCreationTimestamp() unversioned.Time {
|
||||
return *a.creationTimestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetCreationTimestamp(timestamp unversioned.Time) {
|
||||
*a.creationTimestamp = timestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetDeletionTimestamp() *unversioned.Time {
|
||||
return *a.deletionTimestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetDeletionTimestamp(timestamp *unversioned.Time) {
|
||||
*a.deletionTimestamp = timestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetLabels() map[string]string {
|
||||
if a.labels == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.labels
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetLabels(labels map[string]string) {
|
||||
*a.labels = labels
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetAnnotations() map[string]string {
|
||||
if a.annotations == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.annotations
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetAnnotations(annotations map[string]string) {
|
||||
if a.annotations == nil {
|
||||
emptyAnnotations := make(map[string]string)
|
||||
a.annotations = &emptyAnnotations
|
||||
}
|
||||
*a.annotations = annotations
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetFinalizers() []string {
|
||||
if a.finalizers == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.finalizers
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetFinalizers(finalizers []string) {
|
||||
*a.finalizers = finalizers
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetOwnerReferences() []metatypes.OwnerReference {
|
||||
var ret []metatypes.OwnerReference
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
return ret
|
||||
}
|
||||
s = s.Elem()
|
||||
// Set the capacity to one element greater to avoid copy if the caller later append an element.
|
||||
ret = make([]metatypes.OwnerReference, s.Len(), s.Len()+1)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil {
|
||||
glog.Errorf("extractFromOwnerReference failed: %v", err)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetOwnerReferences(references []metatypes.OwnerReference) {
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
}
|
||||
s = s.Elem()
|
||||
newReferences := reflect.MakeSlice(s.Type(), len(references), len(references))
|
||||
for i := 0; i < len(references); i++ {
|
||||
if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil {
|
||||
glog.Errorf("setOwnerReference failed: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
s.Set(newReferences)
|
||||
}
|
||||
|
||||
// extractFromTypeMeta extracts pointers to version and kind fields from an object
|
||||
func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error {
|
||||
if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.FieldPtr(v, "Kind", &a.kind); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
30
vendor/k8s.io/client-go/1.4/pkg/api/meta/metatypes/types.go
generated
vendored
30
vendor/k8s.io/client-go/1.4/pkg/api/meta/metatypes/types.go
generated
vendored
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// The types defined in this package are used by the meta package to represent
|
||||
// the in-memory version of objects. We cannot reuse the __internal version of
|
||||
// API objects because it causes import cycle.
|
||||
package metatypes
|
||||
|
||||
import "k8s.io/client-go/1.4/pkg/types"
|
||||
|
||||
type OwnerReference struct {
|
||||
APIVersion string
|
||||
Kind string
|
||||
UID types.UID
|
||||
Name string
|
||||
Controller *bool
|
||||
}
|
||||
231
vendor/k8s.io/client-go/1.4/pkg/api/meta/multirestmapper.go
generated
vendored
231
vendor/k8s.io/client-go/1.4/pkg/api/meta/multirestmapper.go
generated
vendored
|
|
@ -1,231 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
utilerrors "k8s.io/client-go/1.4/pkg/util/errors"
|
||||
"k8s.io/client-go/1.4/pkg/util/sets"
|
||||
)
|
||||
|
||||
// MultiRESTMapper is a wrapper for multiple RESTMappers.
|
||||
type MultiRESTMapper []RESTMapper
|
||||
|
||||
func (m MultiRESTMapper) String() string {
|
||||
nested := []string{}
|
||||
for _, t := range m {
|
||||
currString := fmt.Sprintf("%v", t)
|
||||
splitStrings := strings.Split(currString, "\n")
|
||||
nested = append(nested, strings.Join(splitStrings, "\n\t"))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("MultiRESTMapper{\n\t%s\n}", strings.Join(nested, "\n\t"))
|
||||
}
|
||||
|
||||
// ResourceSingularizer converts a REST resource name from plural to singular (e.g., from pods to pod)
|
||||
// This implementation supports multiple REST schemas and return the first match.
|
||||
func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
for _, t := range m {
|
||||
singular, err = t.ResourceSingularizer(resource)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) ResourcesFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
allGVRs := []unversioned.GroupVersionResource{}
|
||||
for _, t := range m {
|
||||
gvrs, err := t.ResourcesFor(resource)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// walk the existing values to de-dup
|
||||
for _, curr := range gvrs {
|
||||
found := false
|
||||
for _, existing := range allGVRs {
|
||||
if curr == existing {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
allGVRs = append(allGVRs, curr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allGVRs) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
return allGVRs, nil
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) KindsFor(resource unversioned.GroupVersionResource) (gvk []unversioned.GroupVersionKind, err error) {
|
||||
allGVKs := []unversioned.GroupVersionKind{}
|
||||
for _, t := range m {
|
||||
gvks, err := t.KindsFor(resource)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// walk the existing values to de-dup
|
||||
for _, curr := range gvks {
|
||||
found := false
|
||||
for _, existing := range allGVKs {
|
||||
if curr == existing {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
allGVKs = append(allGVKs, curr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allGVKs) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
return allGVKs, nil
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
resources, err := m.ResourcesFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionResource{}, err
|
||||
}
|
||||
if len(resources) == 1 {
|
||||
return resources[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources}
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
kinds, err := m.KindsFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
if len(kinds) == 1 {
|
||||
return kinds[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
// RESTMapping provides the REST mapping for the resource based on the
|
||||
// kind and version. This implementation supports multiple REST schemas and
|
||||
// return the first match.
|
||||
func (m MultiRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
allMappings := []*RESTMapping{}
|
||||
errors := []error{}
|
||||
|
||||
for _, t := range m {
|
||||
currMapping, err := t.RESTMapping(gk, versions...)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
allMappings = append(allMappings, currMapping)
|
||||
}
|
||||
|
||||
// if we got exactly one mapping, then use it even if other requested failed
|
||||
if len(allMappings) == 1 {
|
||||
return allMappings[0], nil
|
||||
}
|
||||
if len(allMappings) > 1 {
|
||||
var kinds []unversioned.GroupVersionKind
|
||||
for _, m := range allMappings {
|
||||
kinds = append(kinds, m.GroupVersionKind)
|
||||
}
|
||||
return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds}
|
||||
}
|
||||
if len(errors) > 0 {
|
||||
return nil, utilerrors.NewAggregate(errors)
|
||||
}
|
||||
return nil, &NoKindMatchError{PartialKind: gk.WithVersion("")}
|
||||
}
|
||||
|
||||
// RESTMappings returns all possible RESTMappings for the provided group kind, or an error
|
||||
// if the type is not recognized.
|
||||
func (m MultiRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error) {
|
||||
var allMappings []*RESTMapping
|
||||
var errors []error
|
||||
|
||||
for _, t := range m {
|
||||
currMappings, err := t.RESTMappings(gk)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
allMappings = append(allMappings, currMappings...)
|
||||
}
|
||||
if len(errors) > 0 {
|
||||
return nil, utilerrors.NewAggregate(errors)
|
||||
}
|
||||
if len(allMappings) == 0 {
|
||||
return nil, &NoKindMatchError{PartialKind: gk.WithVersion("")}
|
||||
}
|
||||
return allMappings, nil
|
||||
}
|
||||
|
||||
// AliasesForResource finds the first alias response for the provided mappers.
|
||||
func (m MultiRESTMapper) AliasesForResource(alias string) ([]string, bool) {
|
||||
seenAliases := sets.NewString()
|
||||
allAliases := []string{}
|
||||
handled := false
|
||||
|
||||
for _, t := range m {
|
||||
if currAliases, currOk := t.AliasesForResource(alias); currOk {
|
||||
for _, currAlias := range currAliases {
|
||||
if !seenAliases.Has(currAlias) {
|
||||
allAliases = append(allAliases, currAlias)
|
||||
seenAliases.Insert(currAlias)
|
||||
}
|
||||
}
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
return allAliases, handled
|
||||
}
|
||||
226
vendor/k8s.io/client-go/1.4/pkg/api/meta/priority.go
generated
vendored
226
vendor/k8s.io/client-go/1.4/pkg/api/meta/priority.go
generated
vendored
|
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
const (
|
||||
AnyGroup = "*"
|
||||
AnyVersion = "*"
|
||||
AnyResource = "*"
|
||||
AnyKind = "*"
|
||||
)
|
||||
|
||||
// PriorityRESTMapper is a wrapper for automatically choosing a particular Resource or Kind
|
||||
// when multiple matches are possible
|
||||
type PriorityRESTMapper struct {
|
||||
// Delegate is the RESTMapper to use to locate all the Kind and Resource matches
|
||||
Delegate RESTMapper
|
||||
|
||||
// ResourcePriority is a list of priority patterns to apply to matching resources.
|
||||
// The list of all matching resources is narrowed based on the patterns until only one remains.
|
||||
// A pattern with no matches is skipped. A pattern with more than one match uses its
|
||||
// matches as the list to continue matching against.
|
||||
ResourcePriority []unversioned.GroupVersionResource
|
||||
|
||||
// KindPriority is a list of priority patterns to apply to matching kinds.
|
||||
// The list of all matching kinds is narrowed based on the patterns until only one remains.
|
||||
// A pattern with no matches is skipped. A pattern with more than one match uses its
|
||||
// matches as the list to continue matching against.
|
||||
KindPriority []unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) String() string {
|
||||
return fmt.Sprintf("PriorityRESTMapper{\n\t%v\n\t%v\n\t%v\n}", m.ResourcePriority, m.KindPriority, m.Delegate)
|
||||
}
|
||||
|
||||
// ResourceFor finds all resources, then passes them through the ResourcePriority patterns to find a single matching hit.
|
||||
func (m PriorityRESTMapper) ResourceFor(partiallySpecifiedResource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
originalGVRs, err := m.Delegate.ResourcesFor(partiallySpecifiedResource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionResource{}, err
|
||||
}
|
||||
if len(originalGVRs) == 1 {
|
||||
return originalGVRs[0], nil
|
||||
}
|
||||
|
||||
remainingGVRs := append([]unversioned.GroupVersionResource{}, originalGVRs...)
|
||||
for _, pattern := range m.ResourcePriority {
|
||||
matchedGVRs := []unversioned.GroupVersionResource{}
|
||||
for _, gvr := range remainingGVRs {
|
||||
if resourceMatches(pattern, gvr) {
|
||||
matchedGVRs = append(matchedGVRs, gvr)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(matchedGVRs) {
|
||||
case 0:
|
||||
// if you have no matches, then nothing matched this pattern just move to the next
|
||||
continue
|
||||
case 1:
|
||||
// one match, return
|
||||
return matchedGVRs[0], nil
|
||||
default:
|
||||
// more than one match, use the matched hits as the list moving to the next pattern.
|
||||
// this way you can have a series of selection criteria
|
||||
remainingGVRs = matchedGVRs
|
||||
}
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: partiallySpecifiedResource, MatchingResources: originalGVRs}
|
||||
}
|
||||
|
||||
// KindFor finds all kinds, then passes them through the KindPriority patterns to find a single matching hit.
|
||||
func (m PriorityRESTMapper) KindFor(partiallySpecifiedResource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
originalGVKs, err := m.Delegate.KindsFor(partiallySpecifiedResource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
if len(originalGVKs) == 1 {
|
||||
return originalGVKs[0], nil
|
||||
}
|
||||
|
||||
remainingGVKs := append([]unversioned.GroupVersionKind{}, originalGVKs...)
|
||||
for _, pattern := range m.KindPriority {
|
||||
matchedGVKs := []unversioned.GroupVersionKind{}
|
||||
for _, gvr := range remainingGVKs {
|
||||
if kindMatches(pattern, gvr) {
|
||||
matchedGVKs = append(matchedGVKs, gvr)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(matchedGVKs) {
|
||||
case 0:
|
||||
// if you have no matches, then nothing matched this pattern just move to the next
|
||||
continue
|
||||
case 1:
|
||||
// one match, return
|
||||
return matchedGVKs[0], nil
|
||||
default:
|
||||
// more than one match, use the matched hits as the list moving to the next pattern.
|
||||
// this way you can have a series of selection criteria
|
||||
remainingGVKs = matchedGVKs
|
||||
}
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: partiallySpecifiedResource, MatchingKinds: originalGVKs}
|
||||
}
|
||||
|
||||
func resourceMatches(pattern unversioned.GroupVersionResource, resource unversioned.GroupVersionResource) bool {
|
||||
if pattern.Group != AnyGroup && pattern.Group != resource.Group {
|
||||
return false
|
||||
}
|
||||
if pattern.Version != AnyVersion && pattern.Version != resource.Version {
|
||||
return false
|
||||
}
|
||||
if pattern.Resource != AnyResource && pattern.Resource != resource.Resource {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func kindMatches(pattern unversioned.GroupVersionKind, kind unversioned.GroupVersionKind) bool {
|
||||
if pattern.Group != AnyGroup && pattern.Group != kind.Group {
|
||||
return false
|
||||
}
|
||||
if pattern.Version != AnyVersion && pattern.Version != kind.Version {
|
||||
return false
|
||||
}
|
||||
if pattern.Kind != AnyKind && pattern.Kind != kind.Kind {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (mapping *RESTMapping, err error) {
|
||||
mappings, err := m.Delegate.RESTMappings(gk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// any versions the user provides take priority
|
||||
priorities := m.KindPriority
|
||||
if len(versions) > 0 {
|
||||
priorities = make([]unversioned.GroupVersionKind, 0, len(m.KindPriority)+len(versions))
|
||||
for _, version := range versions {
|
||||
gv, err := unversioned.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priorities = append(priorities, gv.WithKind(AnyKind))
|
||||
}
|
||||
priorities = append(priorities, m.KindPriority...)
|
||||
}
|
||||
|
||||
remaining := append([]*RESTMapping{}, mappings...)
|
||||
for _, pattern := range priorities {
|
||||
var matching []*RESTMapping
|
||||
for _, m := range remaining {
|
||||
if kindMatches(pattern, m.GroupVersionKind) {
|
||||
matching = append(matching, m)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(matching) {
|
||||
case 0:
|
||||
// if you have no matches, then nothing matched this pattern just move to the next
|
||||
continue
|
||||
case 1:
|
||||
// one match, return
|
||||
return matching[0], nil
|
||||
default:
|
||||
// more than one match, use the matched hits as the list moving to the next pattern.
|
||||
// this way you can have a series of selection criteria
|
||||
remaining = matching
|
||||
}
|
||||
}
|
||||
if len(remaining) == 1 {
|
||||
return remaining[0], nil
|
||||
}
|
||||
|
||||
var kinds []unversioned.GroupVersionKind
|
||||
for _, m := range mappings {
|
||||
kinds = append(kinds, m.GroupVersionKind)
|
||||
}
|
||||
return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error) {
|
||||
return m.Delegate.RESTMappings(gk)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) AliasesForResource(alias string) (aliases []string, ok bool) {
|
||||
return m.Delegate.AliasesForResource(alias)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
return m.Delegate.ResourceSingularizer(resource)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) ResourcesFor(partiallySpecifiedResource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
return m.Delegate.ResourcesFor(partiallySpecifiedResource)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) KindsFor(partiallySpecifiedResource unversioned.GroupVersionResource) (gvk []unversioned.GroupVersionKind, err error) {
|
||||
return m.Delegate.KindsFor(partiallySpecifiedResource)
|
||||
}
|
||||
564
vendor/k8s.io/client-go/1.4/pkg/api/meta/restmapper.go
generated
vendored
564
vendor/k8s.io/client-go/1.4/pkg/api/meta/restmapper.go
generated
vendored
|
|
@ -1,564 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
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 (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
)
|
||||
|
||||
// Implements RESTScope interface
|
||||
type restScope struct {
|
||||
name RESTScopeName
|
||||
paramName string
|
||||
argumentName string
|
||||
paramDescription string
|
||||
}
|
||||
|
||||
func (r *restScope) Name() RESTScopeName {
|
||||
return r.name
|
||||
}
|
||||
func (r *restScope) ParamName() string {
|
||||
return r.paramName
|
||||
}
|
||||
func (r *restScope) ArgumentName() string {
|
||||
return r.argumentName
|
||||
}
|
||||
func (r *restScope) ParamDescription() string {
|
||||
return r.paramDescription
|
||||
}
|
||||
|
||||
var RESTScopeNamespace = &restScope{
|
||||
name: RESTScopeNameNamespace,
|
||||
paramName: "namespaces",
|
||||
argumentName: "namespace",
|
||||
paramDescription: "object name and auth scope, such as for teams and projects",
|
||||
}
|
||||
|
||||
var RESTScopeRoot = &restScope{
|
||||
name: RESTScopeNameRoot,
|
||||
}
|
||||
|
||||
// DefaultRESTMapper exposes mappings between the types defined in a
|
||||
// runtime.Scheme. It assumes that all types defined the provided scheme
|
||||
// can be mapped with the provided MetadataAccessor and Codec interfaces.
|
||||
//
|
||||
// The resource name of a Kind is defined as the lowercase,
|
||||
// English-plural version of the Kind string.
|
||||
// When converting from resource to Kind, the singular version of the
|
||||
// resource name is also accepted for convenience.
|
||||
//
|
||||
// TODO: Only accept plural for some operations for increased control?
|
||||
// (`get pod bar` vs `get pods bar`)
|
||||
type DefaultRESTMapper struct {
|
||||
defaultGroupVersions []unversioned.GroupVersion
|
||||
|
||||
resourceToKind map[unversioned.GroupVersionResource]unversioned.GroupVersionKind
|
||||
kindToPluralResource map[unversioned.GroupVersionKind]unversioned.GroupVersionResource
|
||||
kindToScope map[unversioned.GroupVersionKind]RESTScope
|
||||
singularToPlural map[unversioned.GroupVersionResource]unversioned.GroupVersionResource
|
||||
pluralToSingular map[unversioned.GroupVersionResource]unversioned.GroupVersionResource
|
||||
|
||||
interfacesFunc VersionInterfacesFunc
|
||||
|
||||
// aliasToResource is used for mapping aliases to resources
|
||||
aliasToResource map[string][]string
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) String() string {
|
||||
return fmt.Sprintf("DefaultRESTMapper{kindToPluralResource=%v}", m.kindToPluralResource)
|
||||
}
|
||||
|
||||
var _ RESTMapper = &DefaultRESTMapper{}
|
||||
|
||||
// VersionInterfacesFunc returns the appropriate typer, and metadata accessor for a
|
||||
// given api version, or an error if no such api version exists.
|
||||
type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInterfaces, error)
|
||||
|
||||
// NewDefaultRESTMapper initializes a mapping between Kind and APIVersion
|
||||
// to a resource name and back based on the objects in a runtime.Scheme
|
||||
// and the Kubernetes API conventions. Takes a group name, a priority list of the versions
|
||||
// to search when an object has no default version (set empty to return an error),
|
||||
// and a function that retrieves the correct metadata for a given version.
|
||||
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f VersionInterfacesFunc) *DefaultRESTMapper {
|
||||
resourceToKind := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionKind)
|
||||
kindToPluralResource := make(map[unversioned.GroupVersionKind]unversioned.GroupVersionResource)
|
||||
kindToScope := make(map[unversioned.GroupVersionKind]RESTScope)
|
||||
singularToPlural := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionResource)
|
||||
pluralToSingular := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionResource)
|
||||
aliasToResource := make(map[string][]string)
|
||||
// TODO: verify name mappings work correctly when versions differ
|
||||
|
||||
return &DefaultRESTMapper{
|
||||
resourceToKind: resourceToKind,
|
||||
kindToPluralResource: kindToPluralResource,
|
||||
kindToScope: kindToScope,
|
||||
defaultGroupVersions: defaultGroupVersions,
|
||||
singularToPlural: singularToPlural,
|
||||
pluralToSingular: pluralToSingular,
|
||||
aliasToResource: aliasToResource,
|
||||
interfacesFunc: f,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) Add(kind unversioned.GroupVersionKind, scope RESTScope) {
|
||||
plural, singular := KindToResource(kind)
|
||||
|
||||
m.singularToPlural[singular] = plural
|
||||
m.pluralToSingular[plural] = singular
|
||||
|
||||
m.resourceToKind[singular] = kind
|
||||
m.resourceToKind[plural] = kind
|
||||
|
||||
m.kindToPluralResource[kind] = plural
|
||||
m.kindToScope[kind] = scope
|
||||
}
|
||||
|
||||
// unpluralizedSuffixes is a list of resource suffixes that are the same plural and singular
|
||||
// This is only is only necessary because some bits of code are lazy and don't actually use the RESTMapper like they should.
|
||||
// TODO eliminate this so that different callers can correctly map to resources. This probably means updating all
|
||||
// callers to use the RESTMapper they mean.
|
||||
var unpluralizedSuffixes = []string{
|
||||
"endpoints",
|
||||
}
|
||||
|
||||
// KindToResource converts Kind to a resource name.
|
||||
// Broken. This method only "sort of" works when used outside of this package. It assumes that Kinds and Resources match
|
||||
// and they aren't guaranteed to do so.
|
||||
func KindToResource(kind unversioned.GroupVersionKind) ( /*plural*/ unversioned.GroupVersionResource /*singular*/, unversioned.GroupVersionResource) {
|
||||
kindName := kind.Kind
|
||||
if len(kindName) == 0 {
|
||||
return unversioned.GroupVersionResource{}, unversioned.GroupVersionResource{}
|
||||
}
|
||||
singularName := strings.ToLower(kindName)
|
||||
singular := kind.GroupVersion().WithResource(singularName)
|
||||
|
||||
for _, skip := range unpluralizedSuffixes {
|
||||
if strings.HasSuffix(singularName, skip) {
|
||||
return singular, singular
|
||||
}
|
||||
}
|
||||
|
||||
switch string(singularName[len(singularName)-1]) {
|
||||
case "s":
|
||||
return kind.GroupVersion().WithResource(singularName + "es"), singular
|
||||
case "y":
|
||||
return kind.GroupVersion().WithResource(strings.TrimSuffix(singularName, "y") + "ies"), singular
|
||||
}
|
||||
|
||||
return kind.GroupVersion().WithResource(singularName + "s"), singular
|
||||
}
|
||||
|
||||
// ResourceSingularizer implements RESTMapper
|
||||
// It converts a resource name from plural to singular (e.g., from pods to pod)
|
||||
func (m *DefaultRESTMapper) ResourceSingularizer(resourceType string) (string, error) {
|
||||
partialResource := unversioned.GroupVersionResource{Resource: resourceType}
|
||||
resources, err := m.ResourcesFor(partialResource)
|
||||
if err != nil {
|
||||
return resourceType, err
|
||||
}
|
||||
|
||||
singular := unversioned.GroupVersionResource{}
|
||||
for _, curr := range resources {
|
||||
currSingular, ok := m.pluralToSingular[curr]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if singular.Empty() {
|
||||
singular = currSingular
|
||||
continue
|
||||
}
|
||||
|
||||
if currSingular.Resource != singular.Resource {
|
||||
return resourceType, fmt.Errorf("multiple possible singular resources (%v) found for %v", resources, resourceType)
|
||||
}
|
||||
}
|
||||
|
||||
if singular.Empty() {
|
||||
return resourceType, fmt.Errorf("no singular of resource %v has been defined", resourceType)
|
||||
}
|
||||
|
||||
return singular.Resource, nil
|
||||
}
|
||||
|
||||
// coerceResourceForMatching makes the resource lower case and converts internal versions to unspecified (legacy behavior)
|
||||
func coerceResourceForMatching(resource unversioned.GroupVersionResource) unversioned.GroupVersionResource {
|
||||
resource.Resource = strings.ToLower(resource.Resource)
|
||||
if resource.Version == runtime.APIVersionInternal {
|
||||
resource.Version = ""
|
||||
}
|
||||
|
||||
return resource
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) ResourcesFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
resource := coerceResourceForMatching(input)
|
||||
|
||||
hasResource := len(resource.Resource) > 0
|
||||
hasGroup := len(resource.Group) > 0
|
||||
hasVersion := len(resource.Version) > 0
|
||||
|
||||
if !hasResource {
|
||||
return nil, fmt.Errorf("a resource must be present, got: %v", resource)
|
||||
}
|
||||
|
||||
ret := []unversioned.GroupVersionResource{}
|
||||
switch {
|
||||
// fully qualified. Find the exact match
|
||||
case hasGroup && hasVersion:
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular == resource {
|
||||
ret = append(ret, plural)
|
||||
break
|
||||
}
|
||||
if plural == resource {
|
||||
ret = append(ret, plural)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case hasGroup:
|
||||
requestedGroupResource := resource.GroupResource()
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.GroupResource() == requestedGroupResource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.GroupResource() == requestedGroupResource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
case hasVersion:
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.Version == resource.Version && singular.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Version == resource.Version && plural.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
sort.Sort(resourceByPreferredGroupVersion{ret, m.defaultGroupVersions})
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
resources, err := m.ResourcesFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionResource{}, err
|
||||
}
|
||||
if len(resources) == 1 {
|
||||
return resources[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources}
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) KindsFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
|
||||
resource := coerceResourceForMatching(input)
|
||||
|
||||
hasResource := len(resource.Resource) > 0
|
||||
hasGroup := len(resource.Group) > 0
|
||||
hasVersion := len(resource.Version) > 0
|
||||
|
||||
if !hasResource {
|
||||
return nil, fmt.Errorf("a resource must be present, got: %v", resource)
|
||||
}
|
||||
|
||||
ret := []unversioned.GroupVersionKind{}
|
||||
switch {
|
||||
// fully qualified. Find the exact match
|
||||
case hasGroup && hasVersion:
|
||||
kind, exists := m.resourceToKind[resource]
|
||||
if exists {
|
||||
ret = append(ret, kind)
|
||||
}
|
||||
|
||||
case hasGroup:
|
||||
requestedGroupResource := resource.GroupResource()
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.GroupResource() == requestedGroupResource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
case hasVersion:
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.Version == resource.Version && currResource.Resource == resource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.Resource == resource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: input}
|
||||
}
|
||||
|
||||
sort.Sort(kindByPreferredGroupVersion{ret, m.defaultGroupVersions})
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
kinds, err := m.KindsFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
if len(kinds) == 1 {
|
||||
return kinds[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
type kindByPreferredGroupVersion struct {
|
||||
list []unversioned.GroupVersionKind
|
||||
sortOrder []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
func (o kindByPreferredGroupVersion) Len() int { return len(o.list) }
|
||||
func (o kindByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] }
|
||||
func (o kindByPreferredGroupVersion) Less(i, j int) bool {
|
||||
lhs := o.list[i]
|
||||
rhs := o.list[j]
|
||||
if lhs == rhs {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.GroupVersion() == rhs.GroupVersion() {
|
||||
return lhs.Kind < rhs.Kind
|
||||
}
|
||||
|
||||
// otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order
|
||||
lhsIndex := -1
|
||||
rhsIndex := -1
|
||||
|
||||
for i := range o.sortOrder {
|
||||
if o.sortOrder[i] == lhs.GroupVersion() {
|
||||
lhsIndex = i
|
||||
}
|
||||
if o.sortOrder[i] == rhs.GroupVersion() {
|
||||
rhsIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if rhsIndex == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return lhsIndex < rhsIndex
|
||||
}
|
||||
|
||||
type resourceByPreferredGroupVersion struct {
|
||||
list []unversioned.GroupVersionResource
|
||||
sortOrder []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
func (o resourceByPreferredGroupVersion) Len() int { return len(o.list) }
|
||||
func (o resourceByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] }
|
||||
func (o resourceByPreferredGroupVersion) Less(i, j int) bool {
|
||||
lhs := o.list[i]
|
||||
rhs := o.list[j]
|
||||
if lhs == rhs {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.GroupVersion() == rhs.GroupVersion() {
|
||||
return lhs.Resource < rhs.Resource
|
||||
}
|
||||
|
||||
// otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order
|
||||
lhsIndex := -1
|
||||
rhsIndex := -1
|
||||
|
||||
for i := range o.sortOrder {
|
||||
if o.sortOrder[i] == lhs.GroupVersion() {
|
||||
lhsIndex = i
|
||||
}
|
||||
if o.sortOrder[i] == rhs.GroupVersion() {
|
||||
rhsIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if rhsIndex == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return lhsIndex < rhsIndex
|
||||
}
|
||||
|
||||
// RESTMapping returns a struct representing the resource path and conversion interfaces a
|
||||
// RESTClient should use to operate on the provided group/kind in order of versions. If a version search
|
||||
// order is not provided, the search order provided to DefaultRESTMapper will be used to resolve which
|
||||
// version should be used to access the named group/kind.
|
||||
// TODO: consider refactoring to use RESTMappings in a way that preserves version ordering and preference
|
||||
func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
// Pick an appropriate version
|
||||
var gvk *unversioned.GroupVersionKind
|
||||
hadVersion := false
|
||||
for _, version := range versions {
|
||||
if len(version) == 0 || version == runtime.APIVersionInternal {
|
||||
continue
|
||||
}
|
||||
|
||||
currGVK := gk.WithVersion(version)
|
||||
hadVersion = true
|
||||
if _, ok := m.kindToPluralResource[currGVK]; ok {
|
||||
gvk = &currGVK
|
||||
break
|
||||
}
|
||||
}
|
||||
// Use the default preferred versions
|
||||
if !hadVersion && (gvk == nil) {
|
||||
for _, gv := range m.defaultGroupVersions {
|
||||
if gv.Group != gk.Group {
|
||||
continue
|
||||
}
|
||||
|
||||
currGVK := gk.WithVersion(gv.Version)
|
||||
if _, ok := m.kindToPluralResource[currGVK]; ok {
|
||||
gvk = &currGVK
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if gvk == nil {
|
||||
return nil, &NoKindMatchError{PartialKind: gk.WithVersion("")}
|
||||
}
|
||||
|
||||
// Ensure we have a REST mapping
|
||||
resource, ok := m.kindToPluralResource[*gvk]
|
||||
if !ok {
|
||||
found := []unversioned.GroupVersion{}
|
||||
for _, gv := range m.defaultGroupVersions {
|
||||
if _, ok := m.kindToPluralResource[*gvk]; ok {
|
||||
found = append(found, gv)
|
||||
}
|
||||
}
|
||||
if len(found) > 0 {
|
||||
return nil, fmt.Errorf("object with kind %q exists in versions %v, not %v", gvk.Kind, found, gvk.GroupVersion().String())
|
||||
}
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported object", gvk.GroupVersion().String(), gvk.Kind)
|
||||
}
|
||||
|
||||
// Ensure we have a REST scope
|
||||
scope, ok := m.kindToScope[*gvk]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion().String(), gvk.Kind)
|
||||
}
|
||||
|
||||
interfaces, err := m.interfacesFunc(gvk.GroupVersion())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the provided version %q has no relevant versions", gvk.GroupVersion().String())
|
||||
}
|
||||
|
||||
retVal := &RESTMapping{
|
||||
Resource: resource.Resource,
|
||||
GroupVersionKind: *gvk,
|
||||
Scope: scope,
|
||||
|
||||
ObjectConvertor: interfaces.ObjectConvertor,
|
||||
MetadataAccessor: interfaces.MetadataAccessor,
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
// RESTMappings returns the RESTMappings for the provided group kind in a rough internal preferred order. If no
|
||||
// kind is found it will return a NoResourceMatchError.
|
||||
func (m *DefaultRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error) {
|
||||
// Use the default preferred versions
|
||||
var mappings []*RESTMapping
|
||||
for _, gv := range m.defaultGroupVersions {
|
||||
if gv.Group != gk.Group {
|
||||
continue
|
||||
}
|
||||
|
||||
gvk := gk.WithVersion(gv.Version)
|
||||
gvr, ok := m.kindToPluralResource[gvk]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Ensure we have a REST scope
|
||||
scope, ok := m.kindToScope[gvk]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion(), gvk.Kind)
|
||||
}
|
||||
|
||||
interfaces, err := m.interfacesFunc(gvk.GroupVersion())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the provided version %q has no relevant versions", gvk.GroupVersion().String())
|
||||
}
|
||||
|
||||
mappings = append(mappings, &RESTMapping{
|
||||
Resource: gvr.Resource,
|
||||
GroupVersionKind: gvk,
|
||||
Scope: scope,
|
||||
|
||||
ObjectConvertor: interfaces.ObjectConvertor,
|
||||
MetadataAccessor: interfaces.MetadataAccessor,
|
||||
})
|
||||
}
|
||||
|
||||
if len(mappings) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: unversioned.GroupVersionResource{Group: gk.Group, Resource: gk.Kind}}
|
||||
}
|
||||
return mappings, nil
|
||||
}
|
||||
|
||||
// AddResourceAlias maps aliases to resources
|
||||
func (m *DefaultRESTMapper) AddResourceAlias(alias string, resources ...string) {
|
||||
if len(resources) == 0 {
|
||||
return
|
||||
}
|
||||
m.aliasToResource[alias] = resources
|
||||
}
|
||||
|
||||
// AliasesForResource returns whether a resource has an alias or not
|
||||
func (m *DefaultRESTMapper) AliasesForResource(alias string) ([]string, bool) {
|
||||
if res, ok := m.aliasToResource[alias]; ok {
|
||||
return res, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
49
vendor/k8s.io/client-go/1.4/pkg/api/node_example.json
generated
vendored
49
vendor/k8s.io/client-go/1.4/pkg/api/node_example.json
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
{
|
||||
"kind": "Node",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "e2e-test-wojtekt-minion-etd6",
|
||||
"selfLink": "/api/v1/nodes/e2e-test-wojtekt-minion-etd6",
|
||||
"uid": "a7e89222-e8e5-11e4-8fde-42010af09327",
|
||||
"resourceVersion": "379",
|
||||
"creationTimestamp": "2015-04-22T11:49:39Z"
|
||||
},
|
||||
"spec": {
|
||||
"externalID": "15488322946290398375"
|
||||
},
|
||||
"status": {
|
||||
"capacity": {
|
||||
"cpu": "1",
|
||||
"memory": "1745152Ki"
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"type": "Ready",
|
||||
"status": "True",
|
||||
"lastHeartbeatTime": "2015-04-22T11:58:17Z",
|
||||
"lastTransitionTime": "2015-04-22T11:49:52Z",
|
||||
"reason": "kubelet is posting ready status"
|
||||
}
|
||||
],
|
||||
"addresses": [
|
||||
{
|
||||
"type": "ExternalIP",
|
||||
"address": "104.197.49.213"
|
||||
},
|
||||
{
|
||||
"type": "LegacyHostIP",
|
||||
"address": "104.197.20.11"
|
||||
}
|
||||
],
|
||||
"nodeInfo": {
|
||||
"machineID": "",
|
||||
"systemUUID": "D59FA3FA-7B5B-7287-5E1A-1D79F13CB577",
|
||||
"bootID": "44a832f3-8cfb-4de5-b7d2-d66030b6cd95",
|
||||
"kernelVersion": "3.16.0-0.bpo.4-amd64",
|
||||
"osImage": "Debian GNU/Linux 7 (wheezy)",
|
||||
"containerRuntimeVersion": "docker://1.5.0",
|
||||
"kubeletVersion": "v0.15.0-484-g0c8ee980d705a3-dirty",
|
||||
"kubeProxyVersion": "v0.15.0-484-g0c8ee980d705a3-dirty"
|
||||
}
|
||||
}
|
||||
}
|
||||
61
vendor/k8s.io/client-go/1.4/pkg/api/pod/util.go
generated
vendored
61
vendor/k8s.io/client-go/1.4/pkg/api/pod/util.go
generated
vendored
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pod
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/util/intstr"
|
||||
)
|
||||
|
||||
const (
|
||||
// TODO: to be de!eted after v1.3 is released. PodSpec has a dedicated Hostname field.
|
||||
// The annotation value is a string specifying the hostname to be used for the pod e.g 'my-webserver-1'
|
||||
PodHostnameAnnotation = "pod.beta.kubernetes.io/hostname"
|
||||
|
||||
// TODO: to be de!eted after v1.3 is released. PodSpec has a dedicated Subdomain field.
|
||||
// The annotation value is a string specifying the subdomain e.g. "my-web-service"
|
||||
// If specified, on the pod itself, "<hostname>.my-web-service.<namespace>.svc.<cluster domain>" would resolve to
|
||||
// the pod's IP.
|
||||
// If there is a headless service named "my-web-service" in the same namespace as the pod, then,
|
||||
// <hostname>.my-web-service.<namespace>.svc.<cluster domain>" would be resolved by the cluster DNS Server.
|
||||
PodSubdomainAnnotation = "pod.beta.kubernetes.io/subdomain"
|
||||
)
|
||||
|
||||
// FindPort locates the container port for the given pod and portName. If the
|
||||
// targetPort is a number, use that. If the targetPort is a string, look that
|
||||
// string up in all named ports in all containers in the target pod. If no
|
||||
// match is found, fail.
|
||||
func FindPort(pod *api.Pod, svcPort *api.ServicePort) (int, error) {
|
||||
portName := svcPort.TargetPort
|
||||
switch portName.Type {
|
||||
case intstr.String:
|
||||
name := portName.StrVal
|
||||
for _, container := range pod.Spec.Containers {
|
||||
for _, port := range container.Ports {
|
||||
if port.Name == name && port.Protocol == svcPort.Protocol {
|
||||
return int(port.ContainerPort), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
case intstr.Int:
|
||||
return portName.IntValue(), nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
|
||||
}
|
||||
132
vendor/k8s.io/client-go/1.4/pkg/api/ref.go
generated
vendored
132
vendor/k8s.io/client-go/1.4/pkg/api/ref.go
generated
vendored
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
// Errors that could be returned by GetReference.
|
||||
ErrNilObject = errors.New("can't reference a nil object")
|
||||
ErrNoSelfLink = errors.New("selfLink was empty, can't make reference")
|
||||
)
|
||||
|
||||
// GetReference returns an ObjectReference which refers to the given
|
||||
// object, or an error if the object doesn't follow the conventions
|
||||
// that would allow this.
|
||||
// TODO: should take a meta.Interface see http://issue.k8s.io/7127
|
||||
func GetReference(obj runtime.Object) (*ObjectReference, error) {
|
||||
if obj == nil {
|
||||
return nil, ErrNilObject
|
||||
}
|
||||
if ref, ok := obj.(*ObjectReference); ok {
|
||||
// Don't make a reference to a reference.
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
|
||||
// if the object referenced is actually persisted, we can just get kind from meta
|
||||
// if we are building an object reference to something not yet persisted, we should fallback to scheme
|
||||
kind := gvk.Kind
|
||||
if len(kind) == 0 {
|
||||
// TODO: this is wrong
|
||||
gvks, _, err := Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kind = gvks[0].Kind
|
||||
}
|
||||
|
||||
// An object that implements only List has enough metadata to build a reference
|
||||
var listMeta meta.List
|
||||
objectMeta, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
listMeta, err = meta.ListAccessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
listMeta = objectMeta
|
||||
}
|
||||
|
||||
// if the object referenced is actually persisted, we can also get version from meta
|
||||
version := gvk.GroupVersion().String()
|
||||
if len(version) == 0 {
|
||||
selfLink := listMeta.GetSelfLink()
|
||||
if len(selfLink) == 0 {
|
||||
return nil, ErrNoSelfLink
|
||||
}
|
||||
selfLinkUrl, err := url.Parse(selfLink)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// example paths: /<prefix>/<version>/*
|
||||
parts := strings.Split(selfLinkUrl.Path, "/")
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("unexpected self link format: '%v'; got version '%v'", selfLink, version)
|
||||
}
|
||||
version = parts[2]
|
||||
}
|
||||
|
||||
// only has list metadata
|
||||
if objectMeta == nil {
|
||||
return &ObjectReference{
|
||||
Kind: kind,
|
||||
APIVersion: version,
|
||||
ResourceVersion: listMeta.GetResourceVersion(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &ObjectReference{
|
||||
Kind: kind,
|
||||
APIVersion: version,
|
||||
Name: objectMeta.GetName(),
|
||||
Namespace: objectMeta.GetNamespace(),
|
||||
UID: objectMeta.GetUID(),
|
||||
ResourceVersion: objectMeta.GetResourceVersion(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetPartialReference is exactly like GetReference, but allows you to set the FieldPath.
|
||||
func GetPartialReference(obj runtime.Object, fieldPath string) (*ObjectReference, error) {
|
||||
ref, err := GetReference(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ref.FieldPath = fieldPath
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
// IsAnAPIObject allows clients to preemptively get a reference to an API object and pass it to places that
|
||||
// intend only to get a reference to that object. This simplifies the event recording interface.
|
||||
func (obj *ObjectReference) SetGroupVersionKind(gvk unversioned.GroupVersionKind) {
|
||||
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *ObjectReference) GroupVersionKind() unversioned.GroupVersionKind {
|
||||
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
|
||||
}
|
||||
|
||||
func (obj *ObjectReference) GetObjectKind() unversioned.ObjectKind { return obj }
|
||||
139
vendor/k8s.io/client-go/1.4/pkg/api/register.go
generated
vendored
139
vendor/k8s.io/client-go/1.4/pkg/api/register.go
generated
vendored
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/runtime/serializer"
|
||||
)
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
// NOTE: If you are copying this file to start a new api group, STOP! Copy the
|
||||
// extensions group instead. This Scheme is special and should appear ONLY in
|
||||
// the api group, unless you really know what you're doing.
|
||||
// TODO(lavalamp): make the above error impossible.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
// Codecs provides access to encoding and decoding for the scheme
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = ""
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Unversioned is group version for unversioned API objects
|
||||
// TODO: this should be v1 probably
|
||||
var Unversioned = unversioned.GroupVersion{Group: "", Version: "v1"}
|
||||
|
||||
// ParameterCodec handles versioning of objects that are converted to query parameters.
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) unversioned.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) unversioned.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO(lavalamp): move this call to scheme builder above. Can't
|
||||
// remove it from here because lots of people inappropriately rely on it
|
||||
// (specifically the unversioned time conversion). Can't have it in
|
||||
// both places because then it gets double registered. Consequence of
|
||||
// current state is that it only ever gets registered in the main
|
||||
// api.Scheme, even though everyone that uses anything from unversioned
|
||||
// needs these.
|
||||
if err := addConversionFuncs(Scheme); err != nil {
|
||||
// Programmer error.
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
if err := scheme.AddIgnoredConversionType(&unversioned.TypeMeta{}, &unversioned.TypeMeta{}); err != nil {
|
||||
return err
|
||||
}
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Pod{},
|
||||
&PodList{},
|
||||
&PodStatusResult{},
|
||||
&PodTemplate{},
|
||||
&PodTemplateList{},
|
||||
&ReplicationControllerList{},
|
||||
&ReplicationController{},
|
||||
&ServiceList{},
|
||||
&Service{},
|
||||
&ServiceProxyOptions{},
|
||||
&NodeList{},
|
||||
&Node{},
|
||||
&NodeProxyOptions{},
|
||||
&Endpoints{},
|
||||
&EndpointsList{},
|
||||
&Binding{},
|
||||
&Event{},
|
||||
&EventList{},
|
||||
&List{},
|
||||
&LimitRange{},
|
||||
&LimitRangeList{},
|
||||
&ResourceQuota{},
|
||||
&ResourceQuotaList{},
|
||||
&Namespace{},
|
||||
&NamespaceList{},
|
||||
&ServiceAccount{},
|
||||
&ServiceAccountList{},
|
||||
&Secret{},
|
||||
&SecretList{},
|
||||
&PersistentVolume{},
|
||||
&PersistentVolumeList{},
|
||||
&PersistentVolumeClaim{},
|
||||
&PersistentVolumeClaimList{},
|
||||
&DeleteOptions{},
|
||||
&ListOptions{},
|
||||
&PodAttachOptions{},
|
||||
&PodLogOptions{},
|
||||
&PodExecOptions{},
|
||||
&PodProxyOptions{},
|
||||
&ComponentStatus{},
|
||||
&ComponentStatusList{},
|
||||
&SerializedReference{},
|
||||
&RangeAllocation{},
|
||||
&ConfigMap{},
|
||||
&ConfigMapList{},
|
||||
)
|
||||
|
||||
// Register Unversioned types under their own special group
|
||||
scheme.AddUnversionedTypes(Unversioned,
|
||||
&unversioned.ExportOptions{},
|
||||
&unversioned.Status{},
|
||||
&unversioned.APIVersions{},
|
||||
&unversioned.APIGroupList{},
|
||||
&unversioned.APIGroup{},
|
||||
&unversioned.APIResourceList{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
83
vendor/k8s.io/client-go/1.4/pkg/api/replication_controller_example.json
generated
vendored
83
vendor/k8s.io/client-go/1.4/pkg/api/replication_controller_example.json
generated
vendored
|
|
@ -1,83 +0,0 @@
|
|||
{
|
||||
"kind": "ReplicationController",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "elasticsearch-logging-controller",
|
||||
"namespace": "default",
|
||||
"selfLink": "/api/v1/namespaces/default/replicationcontrollers/elasticsearch-logging-controller",
|
||||
"uid": "aa76f162-e8e5-11e4-8fde-42010af09327",
|
||||
"resourceVersion": "98",
|
||||
"creationTimestamp": "2015-04-22T11:49:43Z",
|
||||
"labels": {
|
||||
"kubernetes.io/cluster-service": "true",
|
||||
"name": "elasticsearch-logging"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"name": "elasticsearch-logging"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"creationTimestamp": null,
|
||||
"labels": {
|
||||
"kubernetes.io/cluster-service": "true",
|
||||
"name": "elasticsearch-logging"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"name": "es-persistent-storage",
|
||||
"hostPath": null,
|
||||
"emptyDir": {
|
||||
"medium": ""
|
||||
},
|
||||
"gcePersistentDisk": null,
|
||||
"awsElasticBlockStore": null,
|
||||
"gitRepo": null,
|
||||
"secret": null,
|
||||
"nfs": null,
|
||||
"iscsi": null,
|
||||
"glusterfs": null,
|
||||
"quobyte": null
|
||||
}
|
||||
],
|
||||
"containers": [
|
||||
{
|
||||
"name": "elasticsearch-logging",
|
||||
"image": "gcr.io/google_containers/elasticsearch:1.0",
|
||||
"ports": [
|
||||
{
|
||||
"name": "db",
|
||||
"containerPort": 9200,
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"name": "transport",
|
||||
"containerPort": 9300,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"resources": {},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "es-persistent-storage",
|
||||
"mountPath": "/data"
|
||||
}
|
||||
],
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"capabilities": {}
|
||||
}
|
||||
],
|
||||
"restartPolicy": "Always",
|
||||
"dnsPolicy": "ClusterFirst"
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"replicas": 1
|
||||
}
|
||||
}
|
||||
115
vendor/k8s.io/client-go/1.4/pkg/api/requestcontext.go
generated
vendored
115
vendor/k8s.io/client-go/1.4/pkg/api/requestcontext.go
generated
vendored
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// RequestContextMapper keeps track of the context associated with a particular request
|
||||
type RequestContextMapper interface {
|
||||
// Get returns the context associated with the given request (if any), and true if the request has an associated context, and false if it does not.
|
||||
Get(req *http.Request) (Context, bool)
|
||||
// Update maps the request to the given context. If no context was previously associated with the request, an error is returned.
|
||||
// Update should only be called with a descendant context of the previously associated context.
|
||||
// Updating to an unrelated context may return an error in the future.
|
||||
// The context associated with a request should only be updated by a limited set of callers.
|
||||
// Valid examples include the authentication layer, or an audit/tracing layer.
|
||||
Update(req *http.Request, context Context) error
|
||||
}
|
||||
|
||||
type requestContextMap struct {
|
||||
contexts map[*http.Request]Context
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// NewRequestContextMapper returns a new RequestContextMapper.
|
||||
// The returned mapper must be added as a request filter using NewRequestContextFilter.
|
||||
func NewRequestContextMapper() RequestContextMapper {
|
||||
return &requestContextMap{
|
||||
contexts: make(map[*http.Request]Context),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the context associated with the given request (if any), and true if the request has an associated context, and false if it does not.
|
||||
// Get will only return a valid context when called from inside the filter chain set up by NewRequestContextFilter()
|
||||
func (c *requestContextMap) Get(req *http.Request) (Context, bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
context, ok := c.contexts[req]
|
||||
return context, ok
|
||||
}
|
||||
|
||||
// Update maps the request to the given context.
|
||||
// If no context was previously associated with the request, an error is returned and the context is ignored.
|
||||
func (c *requestContextMap) Update(req *http.Request, context Context) error {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if _, ok := c.contexts[req]; !ok {
|
||||
return errors.New("No context associated")
|
||||
}
|
||||
// TODO: ensure the new context is a descendant of the existing one
|
||||
c.contexts[req] = context
|
||||
return nil
|
||||
}
|
||||
|
||||
// init maps the request to the given context and returns true if there was no context associated with the request already.
|
||||
// if a context was already associated with the request, it ignores the given context and returns false.
|
||||
// init is intentionally unexported to ensure that all init calls are paired with a remove after a request is handled
|
||||
func (c *requestContextMap) init(req *http.Request, context Context) bool {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if _, exists := c.contexts[req]; exists {
|
||||
return false
|
||||
}
|
||||
c.contexts[req] = context
|
||||
return true
|
||||
}
|
||||
|
||||
// remove is intentionally unexported to ensure that the context is not removed until a request is handled
|
||||
func (c *requestContextMap) remove(req *http.Request) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
delete(c.contexts, req)
|
||||
}
|
||||
|
||||
// NewRequestContextFilter ensures there is a Context object associated with the request before calling the passed handler.
|
||||
// After the passed handler runs, the context is cleaned up.
|
||||
func NewRequestContextFilter(mapper RequestContextMapper, handler http.Handler) (http.Handler, error) {
|
||||
if mapper, ok := mapper.(*requestContextMap); ok {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if mapper.init(req, NewContext()) {
|
||||
// If we were the ones to successfully initialize, pair with a remove
|
||||
defer mapper.remove(req)
|
||||
}
|
||||
handler.ServeHTTP(w, req)
|
||||
}), nil
|
||||
} else {
|
||||
return handler, errors.New("Unknown RequestContextMapper implementation.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IsEmpty returns true if there are no contexts registered, or an error if it could not be determined. Intended for use by tests.
|
||||
func IsEmpty(requestsToContexts RequestContextMapper) (bool, error) {
|
||||
if requestsToContexts, ok := requestsToContexts.(*requestContextMap); ok {
|
||||
return len(requestsToContexts.contexts) == 0, nil
|
||||
}
|
||||
return true, errors.New("Unknown RequestContextMapper implementation")
|
||||
}
|
||||
298
vendor/k8s.io/client-go/1.4/pkg/api/resource/amount.go
generated
vendored
298
vendor/k8s.io/client-go/1.4/pkg/api/resource/amount.go
generated
vendored
|
|
@ -1,298 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
inf "gopkg.in/inf.v0"
|
||||
)
|
||||
|
||||
// Scale is used for getting and setting the base-10 scaled value.
|
||||
// Base-2 scales are omitted for mathematical simplicity.
|
||||
// See Quantity.ScaledValue for more details.
|
||||
type Scale int32
|
||||
|
||||
// infScale adapts a Scale value to an inf.Scale value.
|
||||
func (s Scale) infScale() inf.Scale {
|
||||
return inf.Scale(-s) // inf.Scale is upside-down
|
||||
}
|
||||
|
||||
const (
|
||||
Nano Scale = -9
|
||||
Micro Scale = -6
|
||||
Milli Scale = -3
|
||||
Kilo Scale = 3
|
||||
Mega Scale = 6
|
||||
Giga Scale = 9
|
||||
Tera Scale = 12
|
||||
Peta Scale = 15
|
||||
Exa Scale = 18
|
||||
)
|
||||
|
||||
var (
|
||||
Zero = int64Amount{}
|
||||
|
||||
// Used by quantity strings - treat as read only
|
||||
zeroBytes = []byte("0")
|
||||
)
|
||||
|
||||
// int64Amount represents a fixed precision numerator and arbitrary scale exponent. It is faster
|
||||
// than operations on inf.Dec for values that can be represented as int64.
|
||||
type int64Amount struct {
|
||||
value int64
|
||||
scale Scale
|
||||
}
|
||||
|
||||
// Sign returns 0 if the value is zero, -1 if it is less than 0, or 1 if it is greater than 0.
|
||||
func (a int64Amount) Sign() int {
|
||||
switch {
|
||||
case a.value == 0:
|
||||
return 0
|
||||
case a.value > 0:
|
||||
return 1
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// AsInt64 returns the current amount as an int64 at scale 0, or false if the value cannot be
|
||||
// represented in an int64 OR would result in a loss of precision. This method is intended as
|
||||
// an optimization to avoid calling AsDec.
|
||||
func (a int64Amount) AsInt64() (int64, bool) {
|
||||
if a.scale == 0 {
|
||||
return a.value, true
|
||||
}
|
||||
if a.scale < 0 {
|
||||
// TODO: attempt to reduce factors, although it is assumed that factors are reduced prior
|
||||
// to the int64Amount being created.
|
||||
return 0, false
|
||||
}
|
||||
return positiveScaleInt64(a.value, a.scale)
|
||||
}
|
||||
|
||||
// AsScaledInt64 returns an int64 representing the value of this amount at the specified scale,
|
||||
// rounding up, or false if that would result in overflow. (1e20).AsScaledInt64(1) would result
|
||||
// in overflow because 1e19 is not representable as an int64. Note that setting a scale larger
|
||||
// than the current value may result in loss of precision - i.e. (1e-6).AsScaledInt64(0) would
|
||||
// return 1, because 0.000001 is rounded up to 1.
|
||||
func (a int64Amount) AsScaledInt64(scale Scale) (result int64, ok bool) {
|
||||
if a.scale < scale {
|
||||
result, _ = negativeScaleInt64(a.value, scale-a.scale)
|
||||
return result, true
|
||||
}
|
||||
return positiveScaleInt64(a.value, a.scale-scale)
|
||||
}
|
||||
|
||||
// AsDec returns an inf.Dec representation of this value.
|
||||
func (a int64Amount) AsDec() *inf.Dec {
|
||||
var base inf.Dec
|
||||
base.SetUnscaled(a.value)
|
||||
base.SetScale(inf.Scale(-a.scale))
|
||||
return &base
|
||||
}
|
||||
|
||||
// Cmp returns 0 if a and b are equal, 1 if a is greater than b, or -1 if a is less than b.
|
||||
func (a int64Amount) Cmp(b int64Amount) int {
|
||||
switch {
|
||||
case a.scale == b.scale:
|
||||
// compare only the unscaled portion
|
||||
case a.scale > b.scale:
|
||||
result, remainder, exact := divideByScaleInt64(b.value, a.scale-b.scale)
|
||||
if !exact {
|
||||
return a.AsDec().Cmp(b.AsDec())
|
||||
}
|
||||
if result == a.value {
|
||||
switch {
|
||||
case remainder == 0:
|
||||
return 0
|
||||
case remainder > 0:
|
||||
return -1
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
b.value = result
|
||||
default:
|
||||
result, remainder, exact := divideByScaleInt64(a.value, b.scale-a.scale)
|
||||
if !exact {
|
||||
return a.AsDec().Cmp(b.AsDec())
|
||||
}
|
||||
if result == b.value {
|
||||
switch {
|
||||
case remainder == 0:
|
||||
return 0
|
||||
case remainder > 0:
|
||||
return 1
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
a.value = result
|
||||
}
|
||||
|
||||
switch {
|
||||
case a.value == b.value:
|
||||
return 0
|
||||
case a.value < b.value:
|
||||
return -1
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds two int64Amounts together, matching scales. It will return false and not mutate
|
||||
// a if overflow or underflow would result.
|
||||
func (a *int64Amount) Add(b int64Amount) bool {
|
||||
switch {
|
||||
case b.value == 0:
|
||||
return true
|
||||
case a.value == 0:
|
||||
a.value = b.value
|
||||
a.scale = b.scale
|
||||
return true
|
||||
case a.scale == b.scale:
|
||||
c, ok := int64Add(a.value, b.value)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
a.value = c
|
||||
case a.scale > b.scale:
|
||||
c, ok := positiveScaleInt64(a.value, a.scale-b.scale)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c, ok = int64Add(c, b.value)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
a.scale = b.scale
|
||||
a.value = c
|
||||
default:
|
||||
c, ok := positiveScaleInt64(b.value, b.scale-a.scale)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c, ok = int64Add(a.value, c)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
a.value = c
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Sub removes the value of b from the current amount, or returns false if underflow would result.
|
||||
func (a *int64Amount) Sub(b int64Amount) bool {
|
||||
return a.Add(int64Amount{value: -b.value, scale: b.scale})
|
||||
}
|
||||
|
||||
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
|
||||
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
|
||||
func (a int64Amount) AsScale(scale Scale) (int64Amount, bool) {
|
||||
if a.scale >= scale {
|
||||
return a, true
|
||||
}
|
||||
result, exact := negativeScaleInt64(a.value, scale-a.scale)
|
||||
return int64Amount{value: result, scale: scale}, exact
|
||||
}
|
||||
|
||||
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
|
||||
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
|
||||
func (a int64Amount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||
mantissa := a.value
|
||||
exponent = int32(a.scale)
|
||||
|
||||
amount, times := removeInt64Factors(mantissa, 10)
|
||||
exponent += int32(times)
|
||||
|
||||
// make sure exponent is a multiple of 3
|
||||
var ok bool
|
||||
switch exponent % 3 {
|
||||
case 1, -2:
|
||||
amount, ok = int64MultiplyScale10(amount)
|
||||
if !ok {
|
||||
return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
|
||||
}
|
||||
exponent = exponent - 1
|
||||
case 2, -1:
|
||||
amount, ok = int64MultiplyScale100(amount)
|
||||
if !ok {
|
||||
return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
|
||||
}
|
||||
exponent = exponent - 2
|
||||
}
|
||||
return strconv.AppendInt(out, amount, 10), exponent
|
||||
}
|
||||
|
||||
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
|
||||
// return []byte("2048"), 1.
|
||||
func (a int64Amount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
|
||||
value, ok := a.AsScaledInt64(0)
|
||||
if !ok {
|
||||
return infDecAmount{a.AsDec()}.AsCanonicalBase1024Bytes(out)
|
||||
}
|
||||
amount, exponent := removeInt64Factors(value, 1024)
|
||||
return strconv.AppendInt(out, amount, 10), exponent
|
||||
}
|
||||
|
||||
// infDecAmount implements common operations over an inf.Dec that are specific to the quantity
|
||||
// representation.
|
||||
type infDecAmount struct {
|
||||
*inf.Dec
|
||||
}
|
||||
|
||||
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
|
||||
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
|
||||
func (a infDecAmount) AsScale(scale Scale) (infDecAmount, bool) {
|
||||
tmp := &inf.Dec{}
|
||||
tmp.Round(a.Dec, scale.infScale(), inf.RoundUp)
|
||||
return infDecAmount{tmp}, tmp.Cmp(a.Dec) == 0
|
||||
}
|
||||
|
||||
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
|
||||
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
|
||||
func (a infDecAmount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||
mantissa := a.Dec.UnscaledBig()
|
||||
exponent = int32(-a.Dec.Scale())
|
||||
amount := big.NewInt(0).Set(mantissa)
|
||||
// move all factors of 10 into the exponent for easy reasoning
|
||||
amount, times := removeBigIntFactors(amount, bigTen)
|
||||
exponent += times
|
||||
|
||||
// make sure exponent is a multiple of 3
|
||||
for exponent%3 != 0 {
|
||||
amount.Mul(amount, bigTen)
|
||||
exponent--
|
||||
}
|
||||
|
||||
return append(out, amount.String()...), exponent
|
||||
}
|
||||
|
||||
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
|
||||
// return []byte("2048"), 1.
|
||||
func (a infDecAmount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
|
||||
tmp := &inf.Dec{}
|
||||
tmp.Round(a.Dec, 0, inf.RoundUp)
|
||||
amount, exponent := removeBigIntFactors(tmp.UnscaledBig(), big1024)
|
||||
return append(out, amount.String()...), exponent
|
||||
}
|
||||
69
vendor/k8s.io/client-go/1.4/pkg/api/resource/generated.pb.go
generated
vendored
69
vendor/k8s.io/client-go/1.4/pkg/api/resource/generated.pb.go
generated
vendored
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo.
|
||||
// source: k8s.io/kubernetes/pkg/api/resource/generated.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package resource is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
k8s.io/kubernetes/pkg/api/resource/generated.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Quantity
|
||||
*/
|
||||
package resource
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
const _ = proto.GoGoProtoPackageIsVersion1
|
||||
|
||||
func (m *Quantity) Reset() { *m = Quantity{} }
|
||||
func (*Quantity) ProtoMessage() {}
|
||||
func (*Quantity) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Quantity)(nil), "k8s.io.client-go.1.4.pkg.api.resource.Quantity")
|
||||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 222 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x32, 0xca, 0xb6, 0x28, 0xd6,
|
||||
0xcb, 0xcc, 0xd7, 0xcf, 0x2e, 0x4d, 0x4a, 0x2d, 0xca, 0x4b, 0x2d, 0x49, 0x2d, 0xd6, 0x2f, 0xc8,
|
||||
0x4e, 0xd7, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0x4a, 0x2d, 0xce, 0x2f, 0x2d, 0x4a, 0x4e, 0xd5, 0x4f,
|
||||
0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52,
|
||||
0x82, 0xe8, 0xd1, 0x43, 0xe8, 0xd1, 0x03, 0xea, 0xd1, 0x03, 0xea, 0xd1, 0x83, 0xe9, 0x91, 0xd2,
|
||||
0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, 0xcf, 0xd7,
|
||||
0x07, 0x6b, 0x4d, 0x2a, 0x4d, 0x03, 0xf3, 0xc0, 0x1c, 0x30, 0x0b, 0x62, 0xa4, 0x94, 0x21, 0x76,
|
||||
0x67, 0x94, 0x96, 0x64, 0xe6, 0xe8, 0x67, 0xe6, 0x95, 0x14, 0x97, 0x14, 0xa1, 0xbb, 0x42, 0xc9,
|
||||
0x82, 0x8b, 0x23, 0xb0, 0x34, 0x31, 0xaf, 0x24, 0xb3, 0xa4, 0x52, 0x48, 0x8c, 0x8b, 0x0d, 0xa8,
|
||||
0x24, 0x33, 0x2f, 0x5d, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0xca, 0xb3, 0x12, 0x99, 0xb1,
|
||||
0x40, 0x9e, 0xa1, 0x63, 0xa1, 0x3c, 0xc3, 0x04, 0x20, 0x5e, 0x00, 0xc4, 0x0d, 0x77, 0x14, 0x18,
|
||||
0x9c, 0xb4, 0x4e, 0x3c, 0x94, 0x63, 0xb8, 0x00, 0xc4, 0x37, 0x80, 0xb8, 0xe1, 0x91, 0x1c, 0xe3,
|
||||
0x09, 0x20, 0xbe, 0x00, 0xc4, 0x0f, 0x80, 0x78, 0xc2, 0x63, 0x39, 0x86, 0x28, 0x0e, 0x98, 0x3f,
|
||||
0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0x90, 0x1c, 0x7f, 0xff, 0x20, 0x01, 0x00, 0x00,
|
||||
}
|
||||
93
vendor/k8s.io/client-go/1.4/pkg/api/resource/generated.proto
generated
vendored
93
vendor/k8s.io/client-go/1.4/pkg/api/resource/generated.proto
generated
vendored
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
|
||||
|
||||
syntax = 'proto2';
|
||||
|
||||
package k8s.io.kubernetes.pkg.api.resource;
|
||||
|
||||
import "k8s.io/kubernetes/pkg/util/intstr/generated.proto";
|
||||
|
||||
// Package-wide variables from generator "generated".
|
||||
option go_package = "resource";
|
||||
|
||||
// Quantity is a fixed-point representation of a number.
|
||||
// It provides convenient marshaling/unmarshaling in JSON and YAML,
|
||||
// in addition to String() and Int64() accessors.
|
||||
//
|
||||
// The serialization format is:
|
||||
//
|
||||
// <quantity> ::= <signedNumber><suffix>
|
||||
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
|
||||
// <digit> ::= 0 | 1 | ... | 9
|
||||
// <digits> ::= <digit> | <digit><digits>
|
||||
// <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
|
||||
// <sign> ::= "+" | "-"
|
||||
// <signedNumber> ::= <number> | <sign><number>
|
||||
// <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI>
|
||||
// <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
|
||||
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
|
||||
// <decimalSI> ::= m | "" | k | M | G | T | P | E
|
||||
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
|
||||
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
|
||||
//
|
||||
// No matter which of the three exponent forms is used, no quantity may represent
|
||||
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
|
||||
// places. Numbers larger or more precise will be capped or rounded up.
|
||||
// (E.g.: 0.1m will rounded up to 1m.)
|
||||
// This may be extended in the future if we require larger or smaller quantities.
|
||||
//
|
||||
// When a Quantity is parsed from a string, it will remember the type of suffix
|
||||
// it had, and will use the same type again when it is serialized.
|
||||
//
|
||||
// Before serializing, Quantity will be put in "canonical form".
|
||||
// This means that Exponent/suffix will be adjusted up or down (with a
|
||||
// corresponding increase or decrease in Mantissa) such that:
|
||||
// a. No precision is lost
|
||||
// b. No fractional digits will be emitted
|
||||
// c. The exponent (or suffix) is as large as possible.
|
||||
// The sign will be omitted unless the number is negative.
|
||||
//
|
||||
// Examples:
|
||||
// 1.5 will be serialized as "1500m"
|
||||
// 1.5Gi will be serialized as "1536Mi"
|
||||
//
|
||||
// NOTE: We reserve the right to amend this canonical format, perhaps to
|
||||
// allow 1.5 to be canonical.
|
||||
// TODO: Remove above disclaimer after all bikeshedding about format is over,
|
||||
// or after March 2015.
|
||||
//
|
||||
// Note that the quantity will NEVER be internally represented by a
|
||||
// floating point number. That is the whole point of this exercise.
|
||||
//
|
||||
// Non-canonical values will still parse as long as they are well formed,
|
||||
// but will be re-emitted in their canonical form. (So always use canonical
|
||||
// form, or don't diff.)
|
||||
//
|
||||
// This format is intended to make it difficult to use these numbers without
|
||||
// writing some sort of special handling code in the hopes that that will
|
||||
// cause implementors to also use a fixed point implementation.
|
||||
//
|
||||
// +protobuf=true
|
||||
// +protobuf.embed=string
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message Quantity {
|
||||
optional string string = 1;
|
||||
}
|
||||
|
||||
327
vendor/k8s.io/client-go/1.4/pkg/api/resource/math.go
generated
vendored
327
vendor/k8s.io/client-go/1.4/pkg/api/resource/math.go
generated
vendored
|
|
@ -1,327 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
inf "gopkg.in/inf.v0"
|
||||
)
|
||||
|
||||
const (
|
||||
// maxInt64Factors is the highest value that will be checked when removing factors of 10 from an int64.
|
||||
// It is also the maximum decimal digits that can be represented with an int64.
|
||||
maxInt64Factors = 18
|
||||
)
|
||||
|
||||
var (
|
||||
// Commonly needed big.Int values-- treat as read only!
|
||||
bigTen = big.NewInt(10)
|
||||
bigZero = big.NewInt(0)
|
||||
bigOne = big.NewInt(1)
|
||||
bigThousand = big.NewInt(1000)
|
||||
big1024 = big.NewInt(1024)
|
||||
|
||||
// Commonly needed inf.Dec values-- treat as read only!
|
||||
decZero = inf.NewDec(0, 0)
|
||||
decOne = inf.NewDec(1, 0)
|
||||
decMinusOne = inf.NewDec(-1, 0)
|
||||
decThousand = inf.NewDec(1000, 0)
|
||||
dec1024 = inf.NewDec(1024, 0)
|
||||
decMinus1024 = inf.NewDec(-1024, 0)
|
||||
|
||||
// Largest (in magnitude) number allowed.
|
||||
maxAllowed = infDecAmount{inf.NewDec((1<<63)-1, 0)} // == max int64
|
||||
|
||||
// The maximum value we can represent milli-units for.
|
||||
// Compare with the return value of Quantity.Value() to
|
||||
// see if it's safe to use Quantity.MilliValue().
|
||||
MaxMilliValue = int64(((1 << 63) - 1) / 1000)
|
||||
)
|
||||
|
||||
const mostNegative = -(mostPositive + 1)
|
||||
const mostPositive = 1<<63 - 1
|
||||
|
||||
// int64Add returns a+b, or false if that would overflow int64.
|
||||
func int64Add(a, b int64) (int64, bool) {
|
||||
c := a + b
|
||||
switch {
|
||||
case a > 0 && b > 0:
|
||||
if c < 0 {
|
||||
return 0, false
|
||||
}
|
||||
case a < 0 && b < 0:
|
||||
if c > 0 {
|
||||
return 0, false
|
||||
}
|
||||
if a == mostNegative && b == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
return c, true
|
||||
}
|
||||
|
||||
// int64Multiply returns a*b, or false if that would overflow or underflow int64.
|
||||
func int64Multiply(a, b int64) (int64, bool) {
|
||||
if a == 0 || b == 0 || a == 1 || b == 1 {
|
||||
return a * b, true
|
||||
}
|
||||
if a == mostNegative || b == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * b
|
||||
return c, c/b == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale returns a*b, assuming b is greater than one, or false if that would overflow or underflow int64.
|
||||
// Use when b is known to be greater than one.
|
||||
func int64MultiplyScale(a int64, b int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * b, true
|
||||
}
|
||||
if a == mostNegative && b != 1 {
|
||||
return 0, false
|
||||
}
|
||||
c := a * b
|
||||
return c, c/b == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale10 multiplies a by 10, or returns false if that would overflow. This method is faster than
|
||||
// int64Multiply(a, 10) because the compiler can optimize constant factor multiplication.
|
||||
func int64MultiplyScale10(a int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * 10, true
|
||||
}
|
||||
if a == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * 10
|
||||
return c, c/10 == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale100 multiplies a by 100, or returns false if that would overflow. This method is faster than
|
||||
// int64Multiply(a, 100) because the compiler can optimize constant factor multiplication.
|
||||
func int64MultiplyScale100(a int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * 100, true
|
||||
}
|
||||
if a == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * 100
|
||||
return c, c/100 == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale1000 multiplies a by 1000, or returns false if that would overflow. This method is faster than
|
||||
// int64Multiply(a, 1000) because the compiler can optimize constant factor multiplication.
|
||||
func int64MultiplyScale1000(a int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * 1000, true
|
||||
}
|
||||
if a == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * 1000
|
||||
return c, c/1000 == a
|
||||
}
|
||||
|
||||
// positiveScaleInt64 multiplies base by 10^scale, returning false if the
|
||||
// value overflows. Passing a negative scale is undefined.
|
||||
func positiveScaleInt64(base int64, scale Scale) (int64, bool) {
|
||||
switch scale {
|
||||
case 0:
|
||||
return base, true
|
||||
case 1:
|
||||
return int64MultiplyScale10(base)
|
||||
case 2:
|
||||
return int64MultiplyScale100(base)
|
||||
case 3:
|
||||
return int64MultiplyScale1000(base)
|
||||
case 6:
|
||||
return int64MultiplyScale(base, 1000000)
|
||||
case 9:
|
||||
return int64MultiplyScale(base, 1000000000)
|
||||
default:
|
||||
value := base
|
||||
var ok bool
|
||||
for i := Scale(0); i < scale; i++ {
|
||||
if value, ok = int64MultiplyScale(value, 10); !ok {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
return value, true
|
||||
}
|
||||
}
|
||||
|
||||
// negativeScaleInt64 reduces base by the provided scale, rounding up, until the
|
||||
// value is zero or the scale is reached. Passing a negative scale is undefined.
|
||||
// The value returned, if not exact, is rounded away from zero.
|
||||
func negativeScaleInt64(base int64, scale Scale) (result int64, exact bool) {
|
||||
if scale == 0 {
|
||||
return base, true
|
||||
}
|
||||
|
||||
value := base
|
||||
var fraction bool
|
||||
for i := Scale(0); i < scale; i++ {
|
||||
if !fraction && value%10 != 0 {
|
||||
fraction = true
|
||||
}
|
||||
value = value / 10
|
||||
if value == 0 {
|
||||
if fraction {
|
||||
if base > 0 {
|
||||
return 1, false
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
return 0, true
|
||||
}
|
||||
}
|
||||
if fraction {
|
||||
if base > 0 {
|
||||
value += 1
|
||||
} else {
|
||||
value += -1
|
||||
}
|
||||
}
|
||||
return value, !fraction
|
||||
}
|
||||
|
||||
func pow10Int64(b int64) int64 {
|
||||
switch b {
|
||||
case 0:
|
||||
return 1
|
||||
case 1:
|
||||
return 10
|
||||
case 2:
|
||||
return 100
|
||||
case 3:
|
||||
return 1000
|
||||
case 4:
|
||||
return 10000
|
||||
case 5:
|
||||
return 100000
|
||||
case 6:
|
||||
return 1000000
|
||||
case 7:
|
||||
return 10000000
|
||||
case 8:
|
||||
return 100000000
|
||||
case 9:
|
||||
return 1000000000
|
||||
case 10:
|
||||
return 10000000000
|
||||
case 11:
|
||||
return 100000000000
|
||||
case 12:
|
||||
return 1000000000000
|
||||
case 13:
|
||||
return 10000000000000
|
||||
case 14:
|
||||
return 100000000000000
|
||||
case 15:
|
||||
return 1000000000000000
|
||||
case 16:
|
||||
return 10000000000000000
|
||||
case 17:
|
||||
return 100000000000000000
|
||||
case 18:
|
||||
return 1000000000000000000
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// powInt64 raises a to the bth power. Is not overflow aware.
|
||||
func powInt64(a, b int64) int64 {
|
||||
p := int64(1)
|
||||
for b > 0 {
|
||||
if b&1 != 0 {
|
||||
p *= a
|
||||
}
|
||||
b >>= 1
|
||||
a *= a
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// negativeScaleInt64 returns the result of dividing base by scale * 10 and the remainder, or
|
||||
// false if no such division is possible. Dividing by negative scales is undefined.
|
||||
func divideByScaleInt64(base int64, scale Scale) (result, remainder int64, exact bool) {
|
||||
if scale == 0 {
|
||||
return base, 0, true
|
||||
}
|
||||
// the max scale representable in base 10 in an int64 is 18 decimal places
|
||||
if scale >= 18 {
|
||||
return 0, base, false
|
||||
}
|
||||
divisor := pow10Int64(int64(scale))
|
||||
return base / divisor, base % divisor, true
|
||||
}
|
||||
|
||||
// removeInt64Factors divides in a loop; the return values have the property that
|
||||
// value == result * base ^ scale
|
||||
func removeInt64Factors(value int64, base int64) (result int64, times int32) {
|
||||
times = 0
|
||||
result = value
|
||||
negative := result < 0
|
||||
if negative {
|
||||
result = -result
|
||||
}
|
||||
switch base {
|
||||
// allow the compiler to optimize the common cases
|
||||
case 10:
|
||||
for result >= 10 && result%10 == 0 {
|
||||
times++
|
||||
result = result / 10
|
||||
}
|
||||
// allow the compiler to optimize the common cases
|
||||
case 1024:
|
||||
for result >= 1024 && result%1024 == 0 {
|
||||
times++
|
||||
result = result / 1024
|
||||
}
|
||||
default:
|
||||
for result >= base && result%base == 0 {
|
||||
times++
|
||||
result = result / base
|
||||
}
|
||||
}
|
||||
if negative {
|
||||
result = -result
|
||||
}
|
||||
return result, times
|
||||
}
|
||||
|
||||
// removeBigIntFactors divides in a loop; the return values have the property that
|
||||
// d == result * factor ^ times
|
||||
// d may be modified in place.
|
||||
// If d == 0, then the return values will be (0, 0)
|
||||
func removeBigIntFactors(d, factor *big.Int) (result *big.Int, times int32) {
|
||||
q := big.NewInt(0)
|
||||
m := big.NewInt(0)
|
||||
for d.Cmp(bigZero) != 0 {
|
||||
q.DivMod(d, factor, m)
|
||||
if m.Cmp(bigZero) != 0 {
|
||||
break
|
||||
}
|
||||
times++
|
||||
d, q = q, d
|
||||
}
|
||||
return d, times
|
||||
}
|
||||
777
vendor/k8s.io/client-go/1.4/pkg/api/resource/quantity.go
generated
vendored
777
vendor/k8s.io/client-go/1.4/pkg/api/resource/quantity.go
generated
vendored
|
|
@ -1,777 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
inf "gopkg.in/inf.v0"
|
||||
)
|
||||
|
||||
// Quantity is a fixed-point representation of a number.
|
||||
// It provides convenient marshaling/unmarshaling in JSON and YAML,
|
||||
// in addition to String() and Int64() accessors.
|
||||
//
|
||||
// The serialization format is:
|
||||
//
|
||||
// <quantity> ::= <signedNumber><suffix>
|
||||
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
|
||||
// <digit> ::= 0 | 1 | ... | 9
|
||||
// <digits> ::= <digit> | <digit><digits>
|
||||
// <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
|
||||
// <sign> ::= "+" | "-"
|
||||
// <signedNumber> ::= <number> | <sign><number>
|
||||
// <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI>
|
||||
// <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
|
||||
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
|
||||
// <decimalSI> ::= m | "" | k | M | G | T | P | E
|
||||
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
|
||||
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
|
||||
//
|
||||
// No matter which of the three exponent forms is used, no quantity may represent
|
||||
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
|
||||
// places. Numbers larger or more precise will be capped or rounded up.
|
||||
// (E.g.: 0.1m will rounded up to 1m.)
|
||||
// This may be extended in the future if we require larger or smaller quantities.
|
||||
//
|
||||
// When a Quantity is parsed from a string, it will remember the type of suffix
|
||||
// it had, and will use the same type again when it is serialized.
|
||||
//
|
||||
// Before serializing, Quantity will be put in "canonical form".
|
||||
// This means that Exponent/suffix will be adjusted up or down (with a
|
||||
// corresponding increase or decrease in Mantissa) such that:
|
||||
// a. No precision is lost
|
||||
// b. No fractional digits will be emitted
|
||||
// c. The exponent (or suffix) is as large as possible.
|
||||
// The sign will be omitted unless the number is negative.
|
||||
//
|
||||
// Examples:
|
||||
// 1.5 will be serialized as "1500m"
|
||||
// 1.5Gi will be serialized as "1536Mi"
|
||||
//
|
||||
// NOTE: We reserve the right to amend this canonical format, perhaps to
|
||||
// allow 1.5 to be canonical.
|
||||
// TODO: Remove above disclaimer after all bikeshedding about format is over,
|
||||
// or after March 2015.
|
||||
//
|
||||
// Note that the quantity will NEVER be internally represented by a
|
||||
// floating point number. That is the whole point of this exercise.
|
||||
//
|
||||
// Non-canonical values will still parse as long as they are well formed,
|
||||
// but will be re-emitted in their canonical form. (So always use canonical
|
||||
// form, or don't diff.)
|
||||
//
|
||||
// This format is intended to make it difficult to use these numbers without
|
||||
// writing some sort of special handling code in the hopes that that will
|
||||
// cause implementors to also use a fixed point implementation.
|
||||
//
|
||||
// +protobuf=true
|
||||
// +protobuf.embed=string
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type Quantity struct {
|
||||
// i is the quantity in int64 scaled form, if d.Dec == nil
|
||||
i int64Amount
|
||||
// d is the quantity in inf.Dec form if d.Dec != nil
|
||||
d infDecAmount
|
||||
// s is the generated value of this quantity to avoid recalculation
|
||||
s string
|
||||
|
||||
// Change Format at will. See the comment for Canonicalize for
|
||||
// more details.
|
||||
Format
|
||||
}
|
||||
|
||||
// CanonicalValue allows a quantity amount to be converted to a string.
|
||||
type CanonicalValue interface {
|
||||
// AsCanonicalBytes returns a byte array representing the string representation
|
||||
// of the value mantissa and an int32 representing its exponent in base-10. Callers may
|
||||
// pass a byte slice to the method to avoid allocations.
|
||||
AsCanonicalBytes(out []byte) ([]byte, int32)
|
||||
// AsCanonicalBase1024Bytes returns a byte array representing the string representation
|
||||
// of the value mantissa and an int32 representing its exponent in base-1024. Callers
|
||||
// may pass a byte slice to the method to avoid allocations.
|
||||
AsCanonicalBase1024Bytes(out []byte) ([]byte, int32)
|
||||
}
|
||||
|
||||
// Format lists the three possible formattings of a quantity.
|
||||
type Format string
|
||||
|
||||
const (
|
||||
DecimalExponent = Format("DecimalExponent") // e.g., 12e6
|
||||
BinarySI = Format("BinarySI") // e.g., 12Mi (12 * 2^20)
|
||||
DecimalSI = Format("DecimalSI") // e.g., 12M (12 * 10^6)
|
||||
)
|
||||
|
||||
// MustParse turns the given string into a quantity or panics; for tests
|
||||
// or others cases where you know the string is valid.
|
||||
func MustParse(str string) Quantity {
|
||||
q, err := ParseQuantity(str)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot parse '%v': %v", str, err))
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
const (
|
||||
// splitREString is used to separate a number from its suffix; as such,
|
||||
// this is overly permissive, but that's OK-- it will be checked later.
|
||||
splitREString = "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"
|
||||
)
|
||||
|
||||
var (
|
||||
// splitRE is used to get the various parts of a number.
|
||||
splitRE = regexp.MustCompile(splitREString)
|
||||
|
||||
// Errors that could happen while parsing a string.
|
||||
ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'")
|
||||
ErrNumeric = errors.New("unable to parse numeric part of quantity")
|
||||
ErrSuffix = errors.New("unable to parse quantity's suffix")
|
||||
)
|
||||
|
||||
// parseQuantityString is a fast scanner for quantity values.
|
||||
func parseQuantityString(str string) (positive bool, value, num, denom, suffix string, err error) {
|
||||
positive = true
|
||||
pos := 0
|
||||
end := len(str)
|
||||
|
||||
// handle leading sign
|
||||
if pos < end {
|
||||
switch str[0] {
|
||||
case '-':
|
||||
positive = false
|
||||
pos++
|
||||
case '+':
|
||||
pos++
|
||||
}
|
||||
}
|
||||
|
||||
// strip leading zeros
|
||||
Zeroes:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
num = "0"
|
||||
value = num
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0':
|
||||
pos++
|
||||
default:
|
||||
break Zeroes
|
||||
}
|
||||
}
|
||||
|
||||
// extract the numerator
|
||||
Num:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
num = str[pos:end]
|
||||
value = str[0:end]
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
default:
|
||||
num = str[pos:i]
|
||||
pos = i
|
||||
break Num
|
||||
}
|
||||
}
|
||||
|
||||
// if we stripped all numerator positions, always return 0
|
||||
if len(num) == 0 {
|
||||
num = "0"
|
||||
}
|
||||
|
||||
// handle a denominator
|
||||
if pos < end && str[pos] == '.' {
|
||||
pos++
|
||||
Denom:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
denom = str[pos:end]
|
||||
value = str[0:end]
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
default:
|
||||
denom = str[pos:i]
|
||||
pos = i
|
||||
break Denom
|
||||
}
|
||||
}
|
||||
// TODO: we currently allow 1.G, but we may not want to in the future.
|
||||
// if len(denom) == 0 {
|
||||
// err = ErrFormatWrong
|
||||
// return
|
||||
// }
|
||||
}
|
||||
value = str[0:pos]
|
||||
|
||||
// grab the elements of the suffix
|
||||
suffixStart := pos
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
suffix = str[suffixStart:end]
|
||||
return
|
||||
}
|
||||
if !strings.ContainsAny(str[i:i+1], "eEinumkKMGTP") {
|
||||
pos = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if pos < end {
|
||||
switch str[pos] {
|
||||
case '-', '+':
|
||||
pos++
|
||||
}
|
||||
}
|
||||
Suffix:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
suffix = str[suffixStart:end]
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
default:
|
||||
break Suffix
|
||||
}
|
||||
}
|
||||
// we encountered a non decimal in the Suffix loop, but the last character
|
||||
// was not a valid exponent
|
||||
err = ErrFormatWrong
|
||||
return
|
||||
}
|
||||
|
||||
// ParseQuantity turns str into a Quantity, or returns an error.
|
||||
func ParseQuantity(str string) (Quantity, error) {
|
||||
if len(str) == 0 {
|
||||
return Quantity{}, ErrFormatWrong
|
||||
}
|
||||
if str == "0" {
|
||||
return Quantity{Format: DecimalSI, s: str}, nil
|
||||
}
|
||||
|
||||
positive, value, num, denom, suf, err := parseQuantityString(str)
|
||||
if err != nil {
|
||||
return Quantity{}, err
|
||||
}
|
||||
|
||||
base, exponent, format, ok := quantitySuffixer.interpret(suffix(suf))
|
||||
if !ok {
|
||||
return Quantity{}, ErrSuffix
|
||||
}
|
||||
|
||||
precision := int32(0)
|
||||
scale := int32(0)
|
||||
mantissa := int64(1)
|
||||
switch format {
|
||||
case DecimalExponent, DecimalSI:
|
||||
scale = exponent
|
||||
precision = maxInt64Factors - int32(len(num)+len(denom))
|
||||
case BinarySI:
|
||||
scale = 0
|
||||
switch {
|
||||
case exponent >= 0 && len(denom) == 0:
|
||||
// only handle positive binary numbers with the fast path
|
||||
mantissa = int64(int64(mantissa) << uint64(exponent))
|
||||
// 1Mi (2^20) has ~6 digits of decimal precision, so exponent*3/10 -1 is roughly the precision
|
||||
precision = 15 - int32(len(num)) - int32(float32(exponent)*3/10) - 1
|
||||
default:
|
||||
precision = -1
|
||||
}
|
||||
}
|
||||
|
||||
if precision >= 0 {
|
||||
// if we have a denominator, shift the entire value to the left by the number of places in the
|
||||
// denominator
|
||||
scale -= int32(len(denom))
|
||||
if scale >= int32(Nano) {
|
||||
shifted := num + denom
|
||||
|
||||
var value int64
|
||||
value, err := strconv.ParseInt(shifted, 10, 64)
|
||||
if err != nil {
|
||||
return Quantity{}, ErrNumeric
|
||||
}
|
||||
if result, ok := int64Multiply(value, int64(mantissa)); ok {
|
||||
if !positive {
|
||||
result = -result
|
||||
}
|
||||
// if the number is in canonical form, reuse the string
|
||||
switch format {
|
||||
case BinarySI:
|
||||
if exponent%10 == 0 && (value&0x07 != 0) {
|
||||
return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil
|
||||
}
|
||||
default:
|
||||
if scale%3 == 0 && !strings.HasSuffix(shifted, "000") && shifted[0] != '0' {
|
||||
return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil
|
||||
}
|
||||
}
|
||||
return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amount := new(inf.Dec)
|
||||
if _, ok := amount.SetString(value); !ok {
|
||||
return Quantity{}, ErrNumeric
|
||||
}
|
||||
|
||||
// So that no one but us has to think about suffixes, remove it.
|
||||
if base == 10 {
|
||||
amount.SetScale(amount.Scale() + Scale(exponent).infScale())
|
||||
} else if base == 2 {
|
||||
// numericSuffix = 2 ** exponent
|
||||
numericSuffix := big.NewInt(1).Lsh(bigOne, uint(exponent))
|
||||
ub := amount.UnscaledBig()
|
||||
amount.SetUnscaledBig(ub.Mul(ub, numericSuffix))
|
||||
}
|
||||
|
||||
// Cap at min/max bounds.
|
||||
sign := amount.Sign()
|
||||
if sign == -1 {
|
||||
amount.Neg(amount)
|
||||
}
|
||||
|
||||
// This rounds non-zero values up to the minimum representable value, under the theory that
|
||||
// if you want some resources, you should get some resources, even if you asked for way too small
|
||||
// of an amount. Arguably, this should be inf.RoundHalfUp (normal rounding), but that would have
|
||||
// the side effect of rounding values < .5n to zero.
|
||||
if v, ok := amount.Unscaled(); v != int64(0) || !ok {
|
||||
amount.Round(amount, Nano.infScale(), inf.RoundUp)
|
||||
}
|
||||
|
||||
// The max is just a simple cap.
|
||||
// TODO: this prevents accumulating quantities greater than int64, for instance quota across a cluster
|
||||
if format == BinarySI && amount.Cmp(maxAllowed.Dec) > 0 {
|
||||
amount.Set(maxAllowed.Dec)
|
||||
}
|
||||
|
||||
if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 {
|
||||
// This avoids rounding and hopefully confusion, too.
|
||||
format = DecimalSI
|
||||
}
|
||||
if sign == -1 {
|
||||
amount.Neg(amount)
|
||||
}
|
||||
|
||||
return Quantity{d: infDecAmount{amount}, Format: format}, nil
|
||||
}
|
||||
|
||||
// DeepCopy returns a deep-copy of the Quantity value. Note that the method
|
||||
// receiver is a value, so we can mutate it in-place and return it.
|
||||
func (q Quantity) DeepCopy() Quantity {
|
||||
if q.d.Dec != nil {
|
||||
tmp := &inf.Dec{}
|
||||
q.d.Dec = tmp.Set(q.d.Dec)
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity).
|
||||
//
|
||||
// Note about BinarySI:
|
||||
// * If q.Format is set to BinarySI and q.Amount represents a non-zero value between
|
||||
// -1 and +1, it will be emitted as if q.Format were DecimalSI.
|
||||
// * Otherwise, if q.Format is set to BinarySI, frational parts of q.Amount will be
|
||||
// rounded up. (1.1i becomes 2i.)
|
||||
func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) {
|
||||
if q.IsZero() {
|
||||
return zeroBytes, nil
|
||||
}
|
||||
|
||||
var rounded CanonicalValue
|
||||
format := q.Format
|
||||
switch format {
|
||||
case DecimalExponent, DecimalSI:
|
||||
case BinarySI:
|
||||
if q.CmpInt64(-1024) > 0 && q.CmpInt64(1024) < 0 {
|
||||
// This avoids rounding and hopefully confusion, too.
|
||||
format = DecimalSI
|
||||
} else {
|
||||
var exact bool
|
||||
if rounded, exact = q.AsScale(0); !exact {
|
||||
// Don't lose precision-- show as DecimalSI
|
||||
format = DecimalSI
|
||||
}
|
||||
}
|
||||
default:
|
||||
format = DecimalExponent
|
||||
}
|
||||
|
||||
// TODO: If BinarySI formatting is requested but would cause rounding, upgrade to
|
||||
// one of the other formats.
|
||||
switch format {
|
||||
case DecimalExponent, DecimalSI:
|
||||
number, exponent := q.AsCanonicalBytes(out)
|
||||
suffix, _ := quantitySuffixer.constructBytes(10, exponent, format)
|
||||
return number, suffix
|
||||
default:
|
||||
// format must be BinarySI
|
||||
number, exponent := rounded.AsCanonicalBase1024Bytes(out)
|
||||
suffix, _ := quantitySuffixer.constructBytes(2, exponent*10, format)
|
||||
return number, suffix
|
||||
}
|
||||
}
|
||||
|
||||
// AsInt64 returns a representation of the current value as an int64 if a fast conversion
|
||||
// is possible. If false is returned, callers must use the inf.Dec form of this quantity.
|
||||
func (q *Quantity) AsInt64() (int64, bool) {
|
||||
if q.d.Dec != nil {
|
||||
return 0, false
|
||||
}
|
||||
return q.i.AsInt64()
|
||||
}
|
||||
|
||||
// ToDec promotes the quantity in place to use an inf.Dec representation and returns itself.
|
||||
func (q *Quantity) ToDec() *Quantity {
|
||||
if q.d.Dec == nil {
|
||||
q.d.Dec = q.i.AsDec()
|
||||
q.i = int64Amount{}
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// AsDec returns the quantity as represented by a scaled inf.Dec.
|
||||
func (q *Quantity) AsDec() *inf.Dec {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec
|
||||
}
|
||||
q.d.Dec = q.i.AsDec()
|
||||
q.i = int64Amount{}
|
||||
return q.d.Dec
|
||||
}
|
||||
|
||||
// AsCanonicalBytes returns the canonical byte representation of this quantity as a mantissa
|
||||
// and base 10 exponent. The out byte slice may be passed to the method to avoid an extra
|
||||
// allocation.
|
||||
func (q *Quantity) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.AsCanonicalBytes(out)
|
||||
}
|
||||
return q.i.AsCanonicalBytes(out)
|
||||
}
|
||||
|
||||
// IsZero returns true if the quantity is equal to zero.
|
||||
func (q *Quantity) IsZero() bool {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec.Sign() == 0
|
||||
}
|
||||
return q.i.value == 0
|
||||
}
|
||||
|
||||
// Sign returns 0 if the quantity is zero, -1 if the quantity is less than zero, or 1 if the
|
||||
// quantity is greater than zero.
|
||||
func (q *Quantity) Sign() int {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec.Sign()
|
||||
}
|
||||
return q.i.Sign()
|
||||
}
|
||||
|
||||
// AsScaled returns the current value, rounded up to the provided scale, and returns
|
||||
// false if the scale resulted in a loss of precision.
|
||||
func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool) {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.AsScale(scale)
|
||||
}
|
||||
return q.i.AsScale(scale)
|
||||
}
|
||||
|
||||
// RoundUp updates the quantity to the provided scale, ensuring that the value is at
|
||||
// least 1. False is returned if the rounding operation resulted in a loss of precision.
|
||||
// Negative numbers are rounded away from zero (-9 scale 1 rounds to -10).
|
||||
func (q *Quantity) RoundUp(scale Scale) bool {
|
||||
if q.d.Dec != nil {
|
||||
q.s = ""
|
||||
d, exact := q.d.AsScale(scale)
|
||||
q.d = d
|
||||
return exact
|
||||
}
|
||||
// avoid clearing the string value if we have already calculated it
|
||||
if q.i.scale >= scale {
|
||||
return true
|
||||
}
|
||||
q.s = ""
|
||||
i, exact := q.i.AsScale(scale)
|
||||
q.i = i
|
||||
return exact
|
||||
}
|
||||
|
||||
// Add adds the provide y quantity to the current value. If the current value is zero,
|
||||
// the format of the quantity will be updated to the format of y.
|
||||
func (q *Quantity) Add(y Quantity) {
|
||||
q.s = ""
|
||||
if q.d.Dec == nil && y.d.Dec == nil {
|
||||
if q.i.value == 0 {
|
||||
q.Format = y.Format
|
||||
}
|
||||
if q.i.Add(y.i) {
|
||||
return
|
||||
}
|
||||
} else if q.IsZero() {
|
||||
q.Format = y.Format
|
||||
}
|
||||
q.ToDec().d.Dec.Add(q.d.Dec, y.AsDec())
|
||||
}
|
||||
|
||||
// Sub subtracts the provided quantity from the current value in place. If the current
|
||||
// value is zero, the format of the quantity will be updated to the format of y.
|
||||
func (q *Quantity) Sub(y Quantity) {
|
||||
q.s = ""
|
||||
if q.IsZero() {
|
||||
q.Format = y.Format
|
||||
}
|
||||
if q.d.Dec == nil && y.d.Dec == nil && q.i.Sub(y.i) {
|
||||
return
|
||||
}
|
||||
q.ToDec().d.Dec.Sub(q.d.Dec, y.AsDec())
|
||||
}
|
||||
|
||||
// Cmp returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
|
||||
// quantity is greater than y.
|
||||
func (q *Quantity) Cmp(y Quantity) int {
|
||||
if q.d.Dec == nil && y.d.Dec == nil {
|
||||
return q.i.Cmp(y.i)
|
||||
}
|
||||
return q.AsDec().Cmp(y.AsDec())
|
||||
}
|
||||
|
||||
// CmpInt64 returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
|
||||
// quantity is greater than y.
|
||||
func (q *Quantity) CmpInt64(y int64) int {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec.Cmp(inf.NewDec(y, inf.Scale(0)))
|
||||
}
|
||||
return q.i.Cmp(int64Amount{value: y})
|
||||
}
|
||||
|
||||
// Neg sets quantity to be the negative value of itself.
|
||||
func (q *Quantity) Neg() {
|
||||
q.s = ""
|
||||
if q.d.Dec == nil {
|
||||
q.i.value = -q.i.value
|
||||
return
|
||||
}
|
||||
q.d.Dec.Neg(q.d.Dec)
|
||||
}
|
||||
|
||||
// int64QuantityExpectedBytes is the expected width in bytes of the canonical string representation
|
||||
// of most Quantity values.
|
||||
const int64QuantityExpectedBytes = 18
|
||||
|
||||
// String formats the Quantity as a string, caching the result if not calculated.
|
||||
// String is an expensive operation and caching this result significantly reduces the cost of
|
||||
// normal parse / marshal operations on Quantity.
|
||||
func (q *Quantity) String() string {
|
||||
if len(q.s) == 0 {
|
||||
result := make([]byte, 0, int64QuantityExpectedBytes)
|
||||
number, suffix := q.CanonicalizeBytes(result)
|
||||
number = append(number, suffix...)
|
||||
q.s = string(number)
|
||||
}
|
||||
return q.s
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface.
|
||||
func (q Quantity) MarshalJSON() ([]byte, error) {
|
||||
if len(q.s) > 0 {
|
||||
out := make([]byte, len(q.s)+2)
|
||||
out[0], out[len(out)-1] = '"', '"'
|
||||
copy(out[1:], q.s)
|
||||
return out, nil
|
||||
}
|
||||
result := make([]byte, int64QuantityExpectedBytes, int64QuantityExpectedBytes)
|
||||
result[0] = '"'
|
||||
number, suffix := q.CanonicalizeBytes(result[1:1])
|
||||
// if the same slice was returned to us that we passed in, avoid another allocation by copying number into
|
||||
// the source slice and returning that
|
||||
if len(number) > 0 && &number[0] == &result[1] && (len(number)+len(suffix)+2) <= int64QuantityExpectedBytes {
|
||||
number = append(number, suffix...)
|
||||
number = append(number, '"')
|
||||
return result[:1+len(number)], nil
|
||||
}
|
||||
// if CanonicalizeBytes needed more space than our slice provided, we may need to allocate again so use
|
||||
// append
|
||||
result = result[:1]
|
||||
result = append(result, number...)
|
||||
result = append(result, suffix...)
|
||||
result = append(result, '"')
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
// TODO: Remove support for leading/trailing whitespace
|
||||
func (q *Quantity) UnmarshalJSON(value []byte) error {
|
||||
l := len(value)
|
||||
if l == 4 && bytes.Equal(value, []byte("null")) {
|
||||
q.d.Dec = nil
|
||||
q.i = int64Amount{}
|
||||
return nil
|
||||
}
|
||||
if l >= 2 && value[0] == '"' && value[l-1] == '"' {
|
||||
value = value[1 : l-1]
|
||||
}
|
||||
|
||||
parsed, err := ParseQuantity(strings.TrimSpace(string(value)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This copy is safe because parsed will not be referred to again.
|
||||
*q = parsed
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewQuantity returns a new Quantity representing the given
|
||||
// value in the given format.
|
||||
func NewQuantity(value int64, format Format) *Quantity {
|
||||
return &Quantity{
|
||||
i: int64Amount{value: value},
|
||||
Format: format,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMilliQuantity returns a new Quantity representing the given
|
||||
// value * 1/1000 in the given format. Note that BinarySI formatting
|
||||
// will round fractional values, and will be changed to DecimalSI for
|
||||
// values x where (-1 < x < 1) && (x != 0).
|
||||
func NewMilliQuantity(value int64, format Format) *Quantity {
|
||||
return &Quantity{
|
||||
i: int64Amount{value: value, scale: -3},
|
||||
Format: format,
|
||||
}
|
||||
}
|
||||
|
||||
// NewScaledQuantity returns a new Quantity representing the given
|
||||
// value * 10^scale in DecimalSI format.
|
||||
func NewScaledQuantity(value int64, scale Scale) *Quantity {
|
||||
return &Quantity{
|
||||
i: int64Amount{value: value, scale: scale},
|
||||
Format: DecimalSI,
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the value of q; any fractional part will be lost.
|
||||
func (q *Quantity) Value() int64 {
|
||||
return q.ScaledValue(0)
|
||||
}
|
||||
|
||||
// MilliValue returns the value of ceil(q * 1000); this could overflow an int64;
|
||||
// if that's a concern, call Value() first to verify the number is small enough.
|
||||
func (q *Quantity) MilliValue() int64 {
|
||||
return q.ScaledValue(Milli)
|
||||
}
|
||||
|
||||
// ScaledValue returns the value of ceil(q * 10^scale); this could overflow an int64.
|
||||
// To detect overflow, call Value() first and verify the expected magnitude.
|
||||
func (q *Quantity) ScaledValue(scale Scale) int64 {
|
||||
if q.d.Dec == nil {
|
||||
i, _ := q.i.AsScaledInt64(scale)
|
||||
return i
|
||||
}
|
||||
dec := q.d.Dec
|
||||
return scaledValue(dec.UnscaledBig(), int(dec.Scale()), int(scale.infScale()))
|
||||
}
|
||||
|
||||
// Set sets q's value to be value.
|
||||
func (q *Quantity) Set(value int64) {
|
||||
q.SetScaled(value, 0)
|
||||
}
|
||||
|
||||
// SetMilli sets q's value to be value * 1/1000.
|
||||
func (q *Quantity) SetMilli(value int64) {
|
||||
q.SetScaled(value, Milli)
|
||||
}
|
||||
|
||||
// SetScaled sets q's value to be value * 10^scale
|
||||
func (q *Quantity) SetScaled(value int64, scale Scale) {
|
||||
q.s = ""
|
||||
q.d.Dec = nil
|
||||
q.i = int64Amount{value: value, scale: scale}
|
||||
}
|
||||
|
||||
// Copy is a convenience function that makes a deep copy for you. Non-deep
|
||||
// copies of quantities share pointers and you will regret that.
|
||||
func (q *Quantity) Copy() *Quantity {
|
||||
if q.d.Dec == nil {
|
||||
return &Quantity{
|
||||
s: q.s,
|
||||
i: q.i,
|
||||
Format: q.Format,
|
||||
}
|
||||
}
|
||||
tmp := &inf.Dec{}
|
||||
return &Quantity{
|
||||
s: q.s,
|
||||
d: infDecAmount{tmp.Set(q.d.Dec)},
|
||||
Format: q.Format,
|
||||
}
|
||||
}
|
||||
|
||||
// qFlag is a helper type for the Flag function
|
||||
type qFlag struct {
|
||||
dest *Quantity
|
||||
}
|
||||
|
||||
// Sets the value of the internal Quantity. (used by flag & pflag)
|
||||
func (qf qFlag) Set(val string) error {
|
||||
q, err := ParseQuantity(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// This copy is OK because q will not be referenced again.
|
||||
*qf.dest = q
|
||||
return nil
|
||||
}
|
||||
|
||||
// Converts the value of the internal Quantity to a string. (used by flag & pflag)
|
||||
func (qf qFlag) String() string {
|
||||
return qf.dest.String()
|
||||
}
|
||||
|
||||
// States the type of flag this is (Quantity). (used by pflag)
|
||||
func (qf qFlag) Type() string {
|
||||
return "quantity"
|
||||
}
|
||||
|
||||
// QuantityFlag is a helper that makes a quantity flag (using standard flag package).
|
||||
// Will panic if defaultValue is not a valid quantity.
|
||||
func QuantityFlag(flagName, defaultValue, description string) *Quantity {
|
||||
q := MustParse(defaultValue)
|
||||
flag.Var(NewQuantityFlagValue(&q), flagName, description)
|
||||
return &q
|
||||
}
|
||||
|
||||
// NewQuantityFlagValue returns an object that can be used to back a flag,
|
||||
// pointing at the given Quantity variable.
|
||||
func NewQuantityFlagValue(q *Quantity) flag.Value {
|
||||
return qFlag{q}
|
||||
}
|
||||
284
vendor/k8s.io/client-go/1.4/pkg/api/resource/quantity_proto.go
generated
vendored
284
vendor/k8s.io/client-go/1.4/pkg/api/resource/quantity_proto.go
generated
vendored
|
|
@ -1,284 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
var _ proto.Sizer = &Quantity{}
|
||||
|
||||
func (m *Quantity) Marshal() (data []byte, err error) {
|
||||
size := m.Size()
|
||||
data = make([]byte, size)
|
||||
n, err := m.MarshalTo(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data[:n], nil
|
||||
}
|
||||
|
||||
// MarshalTo is a customized version of the generated Protobuf unmarshaler for a struct
|
||||
// with a single string field.
|
||||
func (m *Quantity) MarshalTo(data []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
|
||||
data[i] = 0xa
|
||||
i++
|
||||
// BEGIN CUSTOM MARSHAL
|
||||
out := m.String()
|
||||
i = encodeVarintGenerated(data, i, uint64(len(out)))
|
||||
i += copy(data[i:], out)
|
||||
// END CUSTOM MARSHAL
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeVarintGenerated(data []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
data[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
data[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
|
||||
func (m *Quantity) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
|
||||
// BEGIN CUSTOM SIZE
|
||||
l = len(m.String())
|
||||
// END CUSTOM SIZE
|
||||
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenerated(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Unmarshal is a customized version of the generated Protobuf unmarshaler for a struct
|
||||
// with a single string field.
|
||||
func (m *Quantity) Unmarshal(data []byte) error {
|
||||
l := len(data)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Quantity: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Quantity: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field String_", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
s := string(data[iNdEx:postIndex])
|
||||
|
||||
// BEGIN CUSTOM DECODE
|
||||
p, err := ParseQuantity(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = p
|
||||
// END CUSTOM DECODE
|
||||
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(data[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func skipGenerated(data []byte) (n int, err error) {
|
||||
l := len(data)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if data[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
iNdEx += length
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenerated
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipGenerated(data[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
95
vendor/k8s.io/client-go/1.4/pkg/api/resource/scale_int.go
generated
vendored
95
vendor/k8s.io/client-go/1.4/pkg/api/resource/scale_int.go
generated
vendored
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// A sync pool to reduce allocation.
|
||||
intPool sync.Pool
|
||||
maxInt64 = big.NewInt(math.MaxInt64)
|
||||
)
|
||||
|
||||
func init() {
|
||||
intPool.New = func() interface{} {
|
||||
return &big.Int{}
|
||||
}
|
||||
}
|
||||
|
||||
// scaledValue scales given unscaled value from scale to new Scale and returns
|
||||
// an int64. It ALWAYS rounds up the result when scale down. The final result might
|
||||
// overflow.
|
||||
//
|
||||
// scale, newScale represents the scale of the unscaled decimal.
|
||||
// The mathematical value of the decimal is unscaled * 10**(-scale).
|
||||
func scaledValue(unscaled *big.Int, scale, newScale int) int64 {
|
||||
dif := scale - newScale
|
||||
if dif == 0 {
|
||||
return unscaled.Int64()
|
||||
}
|
||||
|
||||
// Handle scale up
|
||||
// This is an easy case, we do not need to care about rounding and overflow.
|
||||
// If any intermediate operation causes overflow, the result will overflow.
|
||||
if dif < 0 {
|
||||
return unscaled.Int64() * int64(math.Pow10(-dif))
|
||||
}
|
||||
|
||||
// Handle scale down
|
||||
// We have to be careful about the intermediate operations.
|
||||
|
||||
// fast path when unscaled < max.Int64 and exp(10,dif) < max.Int64
|
||||
const log10MaxInt64 = 19
|
||||
if unscaled.Cmp(maxInt64) < 0 && dif < log10MaxInt64 {
|
||||
divide := int64(math.Pow10(dif))
|
||||
result := unscaled.Int64() / divide
|
||||
mod := unscaled.Int64() % divide
|
||||
if mod != 0 {
|
||||
return result + 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// We should only convert back to int64 when getting the result.
|
||||
divisor := intPool.Get().(*big.Int)
|
||||
exp := intPool.Get().(*big.Int)
|
||||
result := intPool.Get().(*big.Int)
|
||||
defer func() {
|
||||
intPool.Put(divisor)
|
||||
intPool.Put(exp)
|
||||
intPool.Put(result)
|
||||
}()
|
||||
|
||||
// divisor = 10^(dif)
|
||||
// TODO: create loop up table if exp costs too much.
|
||||
divisor.Exp(bigTen, exp.SetInt64(int64(dif)), nil)
|
||||
// reuse exp
|
||||
remainder := exp
|
||||
|
||||
// result = unscaled / divisor
|
||||
// remainder = unscaled % divisor
|
||||
result.DivMod(unscaled, divisor, remainder)
|
||||
if remainder.Sign() != 0 {
|
||||
return result.Int64() + 1
|
||||
}
|
||||
|
||||
return result.Int64()
|
||||
}
|
||||
198
vendor/k8s.io/client-go/1.4/pkg/api/resource/suffix.go
generated
vendored
198
vendor/k8s.io/client-go/1.4/pkg/api/resource/suffix.go
generated
vendored
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type suffix string
|
||||
|
||||
// suffixer can interpret and construct suffixes.
|
||||
type suffixer interface {
|
||||
interpret(suffix) (base, exponent int32, fmt Format, ok bool)
|
||||
construct(base, exponent int32, fmt Format) (s suffix, ok bool)
|
||||
constructBytes(base, exponent int32, fmt Format) (s []byte, ok bool)
|
||||
}
|
||||
|
||||
// quantitySuffixer handles suffixes for all three formats that quantity
|
||||
// can handle.
|
||||
var quantitySuffixer = newSuffixer()
|
||||
|
||||
type bePair struct {
|
||||
base, exponent int32
|
||||
}
|
||||
|
||||
type listSuffixer struct {
|
||||
suffixToBE map[suffix]bePair
|
||||
beToSuffix map[bePair]suffix
|
||||
beToSuffixBytes map[bePair][]byte
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) addSuffix(s suffix, pair bePair) {
|
||||
if ls.suffixToBE == nil {
|
||||
ls.suffixToBE = map[suffix]bePair{}
|
||||
}
|
||||
if ls.beToSuffix == nil {
|
||||
ls.beToSuffix = map[bePair]suffix{}
|
||||
}
|
||||
if ls.beToSuffixBytes == nil {
|
||||
ls.beToSuffixBytes = map[bePair][]byte{}
|
||||
}
|
||||
ls.suffixToBE[s] = pair
|
||||
ls.beToSuffix[pair] = s
|
||||
ls.beToSuffixBytes[pair] = []byte(s)
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) lookup(s suffix) (base, exponent int32, ok bool) {
|
||||
pair, ok := ls.suffixToBE[s]
|
||||
if !ok {
|
||||
return 0, 0, false
|
||||
}
|
||||
return pair.base, pair.exponent, true
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) construct(base, exponent int32) (s suffix, ok bool) {
|
||||
s, ok = ls.beToSuffix[bePair{base, exponent}]
|
||||
return
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) constructBytes(base, exponent int32) (s []byte, ok bool) {
|
||||
s, ok = ls.beToSuffixBytes[bePair{base, exponent}]
|
||||
return
|
||||
}
|
||||
|
||||
type suffixHandler struct {
|
||||
decSuffixes listSuffixer
|
||||
binSuffixes listSuffixer
|
||||
}
|
||||
|
||||
type fastLookup struct {
|
||||
*suffixHandler
|
||||
}
|
||||
|
||||
func (l fastLookup) interpret(s suffix) (base, exponent int32, format Format, ok bool) {
|
||||
switch s {
|
||||
case "":
|
||||
return 10, 0, DecimalSI, true
|
||||
case "n":
|
||||
return 10, -9, DecimalSI, true
|
||||
case "u":
|
||||
return 10, -6, DecimalSI, true
|
||||
case "m":
|
||||
return 10, -3, DecimalSI, true
|
||||
case "k":
|
||||
return 10, 3, DecimalSI, true
|
||||
case "M":
|
||||
return 10, 6, DecimalSI, true
|
||||
case "G":
|
||||
return 10, 9, DecimalSI, true
|
||||
}
|
||||
return l.suffixHandler.interpret(s)
|
||||
}
|
||||
|
||||
func newSuffixer() suffixer {
|
||||
sh := &suffixHandler{}
|
||||
|
||||
// IMPORTANT: if you change this section you must change fastLookup
|
||||
|
||||
sh.binSuffixes.addSuffix("Ki", bePair{2, 10})
|
||||
sh.binSuffixes.addSuffix("Mi", bePair{2, 20})
|
||||
sh.binSuffixes.addSuffix("Gi", bePair{2, 30})
|
||||
sh.binSuffixes.addSuffix("Ti", bePair{2, 40})
|
||||
sh.binSuffixes.addSuffix("Pi", bePair{2, 50})
|
||||
sh.binSuffixes.addSuffix("Ei", bePair{2, 60})
|
||||
// Don't emit an error when trying to produce
|
||||
// a suffix for 2^0.
|
||||
sh.decSuffixes.addSuffix("", bePair{2, 0})
|
||||
|
||||
sh.decSuffixes.addSuffix("n", bePair{10, -9})
|
||||
sh.decSuffixes.addSuffix("u", bePair{10, -6})
|
||||
sh.decSuffixes.addSuffix("m", bePair{10, -3})
|
||||
sh.decSuffixes.addSuffix("", bePair{10, 0})
|
||||
sh.decSuffixes.addSuffix("k", bePair{10, 3})
|
||||
sh.decSuffixes.addSuffix("M", bePair{10, 6})
|
||||
sh.decSuffixes.addSuffix("G", bePair{10, 9})
|
||||
sh.decSuffixes.addSuffix("T", bePair{10, 12})
|
||||
sh.decSuffixes.addSuffix("P", bePair{10, 15})
|
||||
sh.decSuffixes.addSuffix("E", bePair{10, 18})
|
||||
|
||||
return fastLookup{sh}
|
||||
}
|
||||
|
||||
func (sh *suffixHandler) construct(base, exponent int32, fmt Format) (s suffix, ok bool) {
|
||||
switch fmt {
|
||||
case DecimalSI:
|
||||
return sh.decSuffixes.construct(base, exponent)
|
||||
case BinarySI:
|
||||
return sh.binSuffixes.construct(base, exponent)
|
||||
case DecimalExponent:
|
||||
if base != 10 {
|
||||
return "", false
|
||||
}
|
||||
if exponent == 0 {
|
||||
return "", true
|
||||
}
|
||||
return suffix("e" + strconv.FormatInt(int64(exponent), 10)), true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (sh *suffixHandler) constructBytes(base, exponent int32, format Format) (s []byte, ok bool) {
|
||||
switch format {
|
||||
case DecimalSI:
|
||||
return sh.decSuffixes.constructBytes(base, exponent)
|
||||
case BinarySI:
|
||||
return sh.binSuffixes.constructBytes(base, exponent)
|
||||
case DecimalExponent:
|
||||
if base != 10 {
|
||||
return nil, false
|
||||
}
|
||||
if exponent == 0 {
|
||||
return nil, true
|
||||
}
|
||||
result := make([]byte, 8, 8)
|
||||
result[0] = 'e'
|
||||
number := strconv.AppendInt(result[1:1], int64(exponent), 10)
|
||||
if &result[1] == &number[0] {
|
||||
return result[:1+len(number)], true
|
||||
}
|
||||
result = append(result[:1], number...)
|
||||
return result, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int32, fmt Format, ok bool) {
|
||||
// Try lookup tables first
|
||||
if b, e, ok := sh.decSuffixes.lookup(suffix); ok {
|
||||
return b, e, DecimalSI, true
|
||||
}
|
||||
if b, e, ok := sh.binSuffixes.lookup(suffix); ok {
|
||||
return b, e, BinarySI, true
|
||||
}
|
||||
|
||||
if len(suffix) > 1 && (suffix[0] == 'E' || suffix[0] == 'e') {
|
||||
parsed, err := strconv.ParseInt(string(suffix[1:]), 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, DecimalExponent, false
|
||||
}
|
||||
return 10, int32(parsed), DecimalExponent, true
|
||||
}
|
||||
|
||||
return 0, 0, DecimalExponent, false
|
||||
}
|
||||
209
vendor/k8s.io/client-go/1.4/pkg/api/resource_helpers.go
generated
vendored
209
vendor/k8s.io/client-go/1.4/pkg/api/resource_helpers.go
generated
vendored
|
|
@ -1,209 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/resource"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// Returns string version of ResourceName.
|
||||
func (self ResourceName) String() string {
|
||||
return string(self)
|
||||
}
|
||||
|
||||
// Returns the CPU limit if specified.
|
||||
func (self *ResourceList) Cpu() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourceCPU]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{Format: resource.DecimalSI}
|
||||
}
|
||||
|
||||
// Returns the Memory limit if specified.
|
||||
func (self *ResourceList) Memory() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourceMemory]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{Format: resource.BinarySI}
|
||||
}
|
||||
|
||||
func (self *ResourceList) Pods() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourcePods]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{}
|
||||
}
|
||||
|
||||
func (self *ResourceList) NvidiaGPU() *resource.Quantity {
|
||||
if val, ok := (*self)[ResourceNvidiaGPU]; ok {
|
||||
return &val
|
||||
}
|
||||
return &resource.Quantity{}
|
||||
}
|
||||
|
||||
func GetContainerStatus(statuses []ContainerStatus, name string) (ContainerStatus, bool) {
|
||||
for i := range statuses {
|
||||
if statuses[i].Name == name {
|
||||
return statuses[i], true
|
||||
}
|
||||
}
|
||||
return ContainerStatus{}, false
|
||||
}
|
||||
|
||||
func GetExistingContainerStatus(statuses []ContainerStatus, name string) ContainerStatus {
|
||||
for i := range statuses {
|
||||
if statuses[i].Name == name {
|
||||
return statuses[i]
|
||||
}
|
||||
}
|
||||
return ContainerStatus{}
|
||||
}
|
||||
|
||||
// IsPodReady returns true if a pod is ready; false otherwise.
|
||||
func IsPodReady(pod *Pod) bool {
|
||||
return IsPodReadyConditionTrue(pod.Status)
|
||||
}
|
||||
|
||||
// IsPodReady retruns true if a pod is ready; false otherwise.
|
||||
func IsPodReadyConditionTrue(status PodStatus) bool {
|
||||
condition := GetPodReadyCondition(status)
|
||||
return condition != nil && condition.Status == ConditionTrue
|
||||
}
|
||||
|
||||
// Extracts the pod ready condition from the given status and returns that.
|
||||
// Returns nil if the condition is not present.
|
||||
func GetPodReadyCondition(status PodStatus) *PodCondition {
|
||||
_, condition := GetPodCondition(&status, PodReady)
|
||||
return condition
|
||||
}
|
||||
|
||||
// GetPodCondition extracts the provided condition from the given status and returns that.
|
||||
// Returns nil and -1 if the condition is not present, and the index of the located condition.
|
||||
func GetPodCondition(status *PodStatus, conditionType PodConditionType) (int, *PodCondition) {
|
||||
if status == nil {
|
||||
return -1, nil
|
||||
}
|
||||
for i := range status.Conditions {
|
||||
if status.Conditions[i].Type == conditionType {
|
||||
return i, &status.Conditions[i]
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// GetNodeCondition extracts the provided condition from the given status and returns that.
|
||||
// Returns nil and -1 if the condition is not present, and the index of the located condition.
|
||||
func GetNodeCondition(status *NodeStatus, conditionType NodeConditionType) (int, *NodeCondition) {
|
||||
if status == nil {
|
||||
return -1, nil
|
||||
}
|
||||
for i := range status.Conditions {
|
||||
if status.Conditions[i].Type == conditionType {
|
||||
return i, &status.Conditions[i]
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// Updates existing pod condition or creates a new one. Sets LastTransitionTime to now if the
|
||||
// status has changed.
|
||||
// Returns true if pod condition has changed or has been added.
|
||||
func UpdatePodCondition(status *PodStatus, condition *PodCondition) bool {
|
||||
condition.LastTransitionTime = unversioned.Now()
|
||||
// Try to find this pod condition.
|
||||
conditionIndex, oldCondition := GetPodCondition(status, condition.Type)
|
||||
|
||||
if oldCondition == nil {
|
||||
// We are adding new pod condition.
|
||||
status.Conditions = append(status.Conditions, *condition)
|
||||
return true
|
||||
} else {
|
||||
// We are updating an existing condition, so we need to check if it has changed.
|
||||
if condition.Status == oldCondition.Status {
|
||||
condition.LastTransitionTime = oldCondition.LastTransitionTime
|
||||
}
|
||||
|
||||
isEqual := condition.Status == oldCondition.Status &&
|
||||
condition.Reason == oldCondition.Reason &&
|
||||
condition.Message == oldCondition.Message &&
|
||||
condition.LastProbeTime.Equal(oldCondition.LastProbeTime) &&
|
||||
condition.LastTransitionTime.Equal(oldCondition.LastTransitionTime)
|
||||
|
||||
status.Conditions[conditionIndex] = *condition
|
||||
// Return true if one of the fields have changed.
|
||||
return !isEqual
|
||||
}
|
||||
}
|
||||
|
||||
// IsNodeReady returns true if a node is ready; false otherwise.
|
||||
func IsNodeReady(node *Node) bool {
|
||||
for _, c := range node.Status.Conditions {
|
||||
if c.Type == NodeReady {
|
||||
return c.Status == ConditionTrue
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all
|
||||
// containers of the pod.
|
||||
func PodRequestsAndLimits(pod *Pod) (reqs map[ResourceName]resource.Quantity, limits map[ResourceName]resource.Quantity, err error) {
|
||||
reqs, limits = map[ResourceName]resource.Quantity{}, map[ResourceName]resource.Quantity{}
|
||||
for _, container := range pod.Spec.Containers {
|
||||
for name, quantity := range container.Resources.Requests {
|
||||
if value, ok := reqs[name]; !ok {
|
||||
reqs[name] = *quantity.Copy()
|
||||
} else {
|
||||
value.Add(quantity)
|
||||
reqs[name] = value
|
||||
}
|
||||
}
|
||||
for name, quantity := range container.Resources.Limits {
|
||||
if value, ok := limits[name]; !ok {
|
||||
limits[name] = *quantity.Copy()
|
||||
} else {
|
||||
value.Add(quantity)
|
||||
limits[name] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
// init containers define the minimum of any resource
|
||||
for _, container := range pod.Spec.InitContainers {
|
||||
for name, quantity := range container.Resources.Requests {
|
||||
value, ok := reqs[name]
|
||||
if !ok {
|
||||
reqs[name] = *quantity.Copy()
|
||||
continue
|
||||
}
|
||||
if quantity.Cmp(value) > 0 {
|
||||
reqs[name] = *quantity.Copy()
|
||||
}
|
||||
}
|
||||
for name, quantity := range container.Resources.Limits {
|
||||
value, ok := limits[name]
|
||||
if !ok {
|
||||
limits[name] = *quantity.Copy()
|
||||
continue
|
||||
}
|
||||
if quantity.Cmp(value) > 0 {
|
||||
limits[name] = *quantity.Copy()
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
89
vendor/k8s.io/client-go/1.4/pkg/api/service/annotations.go
generated
vendored
89
vendor/k8s.io/client-go/1.4/pkg/api/service/annotations.go
generated
vendored
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
)
|
||||
|
||||
const (
|
||||
// AnnotationLoadBalancerSourceRangesKey is the key of the annotation on a service to set allowed ingress ranges on their LoadBalancers
|
||||
//
|
||||
// It should be a comma-separated list of CIDRs, e.g. `0.0.0.0/0` to
|
||||
// allow full access (the default) or `18.0.0.0/8,56.0.0.0/8` to allow
|
||||
// access only from the CIDRs currently allocated to MIT & the USPS.
|
||||
//
|
||||
// Not all cloud providers support this annotation, though AWS & GCE do.
|
||||
AnnotationLoadBalancerSourceRangesKey = "service.beta.kubernetes.io/load-balancer-source-ranges"
|
||||
|
||||
// AnnotationExternalTraffic An annotation that denotes if this Service desires to route external traffic to local
|
||||
// endpoints only. This preserves Source IP and avoids a second hop.
|
||||
AnnotationExternalTraffic = "service.alpha.kubernetes.io/external-traffic"
|
||||
// AnnotationValueExternalTrafficLocal Value of annotation to specify local endpoints behaviour
|
||||
AnnotationValueExternalTrafficLocal = "OnlyLocal"
|
||||
// AnnotationValueExternalTrafficGlobal Value of annotation to specify global (legacy) behaviour
|
||||
AnnotationValueExternalTrafficGlobal = "Global"
|
||||
// AnnotationHealthCheckNodePort Annotation specifying the healthcheck nodePort for the service
|
||||
// If not specified, annotation is created by the service api backend with the allocated nodePort
|
||||
// Will use user-specified nodePort value if specified by the client
|
||||
AnnotationHealthCheckNodePort = "service.alpha.kubernetes.io/healthcheck-nodeport"
|
||||
)
|
||||
|
||||
// NeedsHealthCheck Check service for health check annotations
|
||||
func NeedsHealthCheck(service *api.Service) bool {
|
||||
if l, ok := service.Annotations[AnnotationExternalTraffic]; ok {
|
||||
if l == AnnotationValueExternalTrafficLocal {
|
||||
return true
|
||||
} else if l == AnnotationValueExternalTrafficGlobal {
|
||||
return false
|
||||
} else {
|
||||
glog.Errorf("Invalid value for annotation %v", AnnotationExternalTraffic)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetServiceHealthCheckNodePort Return health check node port annotation for service, if one exists
|
||||
func GetServiceHealthCheckNodePort(service *api.Service) int32 {
|
||||
if NeedsHealthCheck(service) {
|
||||
if l, ok := service.Annotations[AnnotationHealthCheckNodePort]; ok {
|
||||
p, err := strconv.Atoi(l)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to parse annotation %v: %v", AnnotationHealthCheckNodePort, err)
|
||||
return 0
|
||||
}
|
||||
return int32(p)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetServiceHealthCheckPathPort Return the path and nodePort programmed into the Cloud LB Health Check
|
||||
func GetServiceHealthCheckPathPort(service *api.Service) (string, int32) {
|
||||
if !NeedsHealthCheck(service) {
|
||||
return "", 0
|
||||
}
|
||||
port := GetServiceHealthCheckNodePort(service)
|
||||
if port == 0 {
|
||||
return "", 0
|
||||
}
|
||||
return "/healthz", port
|
||||
}
|
||||
68
vendor/k8s.io/client-go/1.4/pkg/api/service/util.go
generated
vendored
68
vendor/k8s.io/client-go/1.4/pkg/api/service/util.go
generated
vendored
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
netsets "k8s.io/client-go/1.4/pkg/util/net/sets"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultLoadBalancerSourceRanges = "0.0.0.0/0"
|
||||
)
|
||||
|
||||
// IsAllowAll checks whether the netsets.IPNet allows traffic from 0.0.0.0/0
|
||||
func IsAllowAll(ipnets netsets.IPNet) bool {
|
||||
for _, s := range ipnets.StringSlice() {
|
||||
if s == "0.0.0.0/0" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetLoadBalancerSourceRanges first try to parse and verify LoadBalancerSourceRanges field from a service.
|
||||
// If the field is not specified, turn to parse and verify the AnnotationLoadBalancerSourceRangesKey annotation from a service,
|
||||
// extracting the source ranges to allow, and if not present returns a default (allow-all) value.
|
||||
func GetLoadBalancerSourceRanges(service *api.Service) (netsets.IPNet, error) {
|
||||
var ipnets netsets.IPNet
|
||||
var err error
|
||||
// if SourceRange field is specified, ignore sourceRange annotation
|
||||
if len(service.Spec.LoadBalancerSourceRanges) > 0 {
|
||||
specs := service.Spec.LoadBalancerSourceRanges
|
||||
ipnets, err = netsets.ParseIPNets(specs...)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("service.Spec.LoadBalancerSourceRanges: %v is not valid. Expecting a list of IP ranges. For example, 10.0.0.0/24. Error msg: %v", specs, err)
|
||||
}
|
||||
} else {
|
||||
val := service.Annotations[AnnotationLoadBalancerSourceRangesKey]
|
||||
val = strings.TrimSpace(val)
|
||||
if val == "" {
|
||||
val = defaultLoadBalancerSourceRanges
|
||||
}
|
||||
specs := strings.Split(val, ",")
|
||||
ipnets, err = netsets.ParseIPNets(specs...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: %s is not valid. Expecting a comma-separated list of source IP ranges. For example, 10.0.0.0/24,192.168.2.0/24", AnnotationLoadBalancerSourceRangesKey, val)
|
||||
}
|
||||
}
|
||||
return ipnets, nil
|
||||
}
|
||||
62430
vendor/k8s.io/client-go/1.4/pkg/api/types.generated.go
generated
vendored
62430
vendor/k8s.io/client-go/1.4/pkg/api/types.generated.go
generated
vendored
File diff suppressed because it is too large
Load diff
3064
vendor/k8s.io/client-go/1.4/pkg/api/types.go
generated
vendored
3064
vendor/k8s.io/client-go/1.4/pkg/api/types.go
generated
vendored
File diff suppressed because it is too large
Load diff
47
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/duration.go
generated
vendored
47
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/duration.go
generated
vendored
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Duration is a wrapper around time.Duration which supports correct
|
||||
// marshaling to YAML and JSON. In particular, it marshals into strings, which
|
||||
// can be used as map keys in json.
|
||||
type Duration struct {
|
||||
time.Duration `protobuf:"varint,1,opt,name=duration,casttype=time.Duration"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||
var str string
|
||||
json.Unmarshal(b, &str)
|
||||
|
||||
pd, err := time.ParseDuration(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Duration = pd
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (d Duration) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(d.Duration.String())
|
||||
}
|
||||
4536
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/generated.pb.go
generated
vendored
4536
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/generated.pb.go
generated
vendored
File diff suppressed because it is too large
Load diff
378
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/generated.proto
generated
vendored
378
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/generated.proto
generated
vendored
|
|
@ -1,378 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
|
||||
|
||||
syntax = 'proto2';
|
||||
|
||||
package k8s.io.kubernetes.pkg.api.unversioned;
|
||||
|
||||
import "k8s.io/kubernetes/pkg/runtime/generated.proto";
|
||||
import "k8s.io/kubernetes/pkg/util/intstr/generated.proto";
|
||||
|
||||
// Package-wide variables from generator "generated".
|
||||
option go_package = "unversioned";
|
||||
|
||||
// APIGroup contains the name, the supported versions, and the preferred version
|
||||
// of a group.
|
||||
message APIGroup {
|
||||
// name is the name of the group.
|
||||
optional string name = 1;
|
||||
|
||||
// versions are the versions supported in this group.
|
||||
repeated GroupVersionForDiscovery versions = 2;
|
||||
|
||||
// preferredVersion is the version preferred by the API server, which
|
||||
// probably is the storage version.
|
||||
optional GroupVersionForDiscovery preferredVersion = 3;
|
||||
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 4;
|
||||
}
|
||||
|
||||
// APIGroupList is a list of APIGroup, to allow clients to discover the API at
|
||||
// /apis.
|
||||
message APIGroupList {
|
||||
// groups is a list of APIGroup.
|
||||
repeated APIGroup groups = 1;
|
||||
}
|
||||
|
||||
// APIResource specifies the name of a resource and whether it is namespaced.
|
||||
message APIResource {
|
||||
// name is the name of the resource.
|
||||
optional string name = 1;
|
||||
|
||||
// namespaced indicates if a resource is namespaced or not.
|
||||
optional bool namespaced = 2;
|
||||
|
||||
// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
|
||||
optional string kind = 3;
|
||||
}
|
||||
|
||||
// APIResourceList is a list of APIResource, it is used to expose the name of the
|
||||
// resources supported in a specific group and version, and if the resource
|
||||
// is namespaced.
|
||||
message APIResourceList {
|
||||
// groupVersion is the group and version this APIResourceList is for.
|
||||
optional string groupVersion = 1;
|
||||
|
||||
// resources contains the name of the resources and if they are namespaced.
|
||||
repeated APIResource resources = 2;
|
||||
}
|
||||
|
||||
// APIVersions lists the versions that are available, to allow clients to
|
||||
// discover the API at /api, which is the root path of the legacy v1 API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message APIVersions {
|
||||
// versions are the api versions that are available.
|
||||
repeated string versions = 1;
|
||||
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 2;
|
||||
}
|
||||
|
||||
// Duration is a wrapper around time.Duration which supports correct
|
||||
// marshaling to YAML and JSON. In particular, it marshals into strings, which
|
||||
// can be used as map keys in json.
|
||||
message Duration {
|
||||
optional int64 duration = 1;
|
||||
}
|
||||
|
||||
// ExportOptions is the query options to the standard REST get call.
|
||||
message ExportOptions {
|
||||
// Should this value be exported. Export strips fields that a user can not specify.`
|
||||
optional bool export = 1;
|
||||
|
||||
// Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'
|
||||
optional bool exact = 2;
|
||||
}
|
||||
|
||||
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupKind {
|
||||
optional string group = 1;
|
||||
|
||||
optional string kind = 2;
|
||||
}
|
||||
|
||||
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupResource {
|
||||
optional string group = 1;
|
||||
|
||||
optional string resource = 2;
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupVersion {
|
||||
optional string group = 1;
|
||||
|
||||
optional string version = 2;
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group/version" and "version" string of a version.
|
||||
// It is made a struct to keep extensibility.
|
||||
message GroupVersionForDiscovery {
|
||||
// groupVersion specifies the API group and version in the form "group/version"
|
||||
optional string groupVersion = 1;
|
||||
|
||||
// version specifies the version in the form of "version". This is to save
|
||||
// the clients the trouble of splitting the GroupVersion.
|
||||
optional string version = 2;
|
||||
}
|
||||
|
||||
// GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupVersionKind {
|
||||
optional string group = 1;
|
||||
|
||||
optional string version = 2;
|
||||
|
||||
optional string kind = 3;
|
||||
}
|
||||
|
||||
// GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupVersionResource {
|
||||
optional string group = 1;
|
||||
|
||||
optional string version = 2;
|
||||
|
||||
optional string resource = 3;
|
||||
}
|
||||
|
||||
// A label selector is a label query over a set of resources. The result of matchLabels and
|
||||
// matchExpressions are ANDed. An empty label selector matches all objects. A null
|
||||
// label selector matches no objects.
|
||||
message LabelSelector {
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
// operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
map<string, string> matchLabels = 1;
|
||||
|
||||
// matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
repeated LabelSelectorRequirement matchExpressions = 2;
|
||||
}
|
||||
|
||||
// A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
// relates the key and values.
|
||||
message LabelSelectorRequirement {
|
||||
// key is the label key that the selector applies to.
|
||||
optional string key = 1;
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators ard In, NotIn, Exists and DoesNotExist.
|
||||
optional string operator = 2;
|
||||
|
||||
// values is an array of string values. If the operator is In or NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a strategic
|
||||
// merge patch.
|
||||
repeated string values = 3;
|
||||
}
|
||||
|
||||
// ListMeta describes metadata that synthetic resources must have, including lists and
|
||||
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
|
||||
message ListMeta {
|
||||
// SelfLink is a URL representing this object.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
optional string selfLink = 1;
|
||||
|
||||
// String that identifies the server's internal version of this object that
|
||||
// can be used by clients to determine when objects have changed.
|
||||
// Value must be treated as opaque by clients and passed unmodified back to the server.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency
|
||||
optional string resourceVersion = 2;
|
||||
}
|
||||
|
||||
// RootPaths lists the paths available at root.
|
||||
// For example: "/healthz", "/apis".
|
||||
message RootPaths {
|
||||
// paths are the paths available at root.
|
||||
repeated string paths = 1;
|
||||
}
|
||||
|
||||
// ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.
|
||||
message ServerAddressByClientCIDR {
|
||||
// The CIDR with which clients can match their IP to figure out the server address that they should use.
|
||||
optional string clientCIDR = 1;
|
||||
|
||||
// Address of this server, suitable for a client that matches the above CIDR.
|
||||
// This can be a hostname, hostname:port, IP or IP:port.
|
||||
optional string serverAddress = 2;
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
message Status {
|
||||
// Standard list metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
optional ListMeta metadata = 1;
|
||||
|
||||
// Status of the operation.
|
||||
// One of: "Success" or "Failure".
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
optional string status = 2;
|
||||
|
||||
// A human-readable description of the status of this operation.
|
||||
optional string message = 3;
|
||||
|
||||
// A machine-readable description of why this operation is in the
|
||||
// "Failure" status. If this value is empty there
|
||||
// is no information available. A Reason clarifies an HTTP status
|
||||
// code but does not override it.
|
||||
optional string reason = 4;
|
||||
|
||||
// Extended data associated with the reason. Each reason may define its
|
||||
// own extended details. This field is optional and the data returned
|
||||
// is not guaranteed to conform to any schema except that defined by
|
||||
// the reason type.
|
||||
optional StatusDetails details = 5;
|
||||
|
||||
// Suggested HTTP return code for this status, 0 if not set.
|
||||
optional int32 code = 6;
|
||||
}
|
||||
|
||||
// StatusCause provides more information about an api.Status failure, including
|
||||
// cases when multiple errors are encountered.
|
||||
message StatusCause {
|
||||
// A machine-readable description of the cause of the error. If this value is
|
||||
// empty there is no information available.
|
||||
optional string reason = 1;
|
||||
|
||||
// A human-readable description of the cause of the error. This field may be
|
||||
// presented as-is to a reader.
|
||||
optional string message = 2;
|
||||
|
||||
// The field of the resource that has caused this error, as named by its JSON
|
||||
// serialization. May include dot and postfix notation for nested attributes.
|
||||
// Arrays are zero-indexed. Fields may appear more than once in an array of
|
||||
// causes due to fields having multiple errors.
|
||||
// Optional.
|
||||
//
|
||||
// Examples:
|
||||
// "name" - the field "name" on the current resource
|
||||
// "items[0].name" - the field "name" on the first array entry in "items"
|
||||
optional string field = 3;
|
||||
}
|
||||
|
||||
// StatusDetails is a set of additional properties that MAY be set by the
|
||||
// server to provide additional information about a response. The Reason
|
||||
// field of a Status object defines what attributes will be set. Clients
|
||||
// must ignore fields that do not match the defined type of each attribute,
|
||||
// and should assume that any attribute may be empty, invalid, or under
|
||||
// defined.
|
||||
message StatusDetails {
|
||||
// The name attribute of the resource associated with the status StatusReason
|
||||
// (when there is a single name which can be described).
|
||||
optional string name = 1;
|
||||
|
||||
// The group attribute of the resource associated with the status StatusReason.
|
||||
optional string group = 2;
|
||||
|
||||
// The kind attribute of the resource associated with the status StatusReason.
|
||||
// On some operations may differ from the requested resource Kind.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
optional string kind = 3;
|
||||
|
||||
// The Causes array includes more details associated with the StatusReason
|
||||
// failure. Not all StatusReasons may provide detailed causes.
|
||||
repeated StatusCause causes = 4;
|
||||
|
||||
// If specified, the time in seconds before the operation should be retried.
|
||||
optional int32 retryAfterSeconds = 5;
|
||||
}
|
||||
|
||||
// Time is a wrapper around time.Time which supports correct
|
||||
// marshaling to YAML and JSON. Wrappers are provided for many
|
||||
// of the factory methods that the time package offers.
|
||||
//
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.as=Timestamp
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message Time {
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
optional int64 seconds = 1;
|
||||
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive. This field may be limited in precision depending on context.
|
||||
optional int32 nanos = 2;
|
||||
}
|
||||
|
||||
// Timestamp is a struct that is equivalent to Time, but intended for
|
||||
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
||||
// that matches Time. Do not use in Go structs.
|
||||
message Timestamp {
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
optional int64 seconds = 1;
|
||||
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive. This field may be limited in precision depending on context.
|
||||
optional int32 nanos = 2;
|
||||
}
|
||||
|
||||
// TypeMeta describes an individual object in an API response or request
|
||||
// with strings representing the type of the object and its API schema version.
|
||||
// Structures that are versioned or persisted should inline TypeMeta.
|
||||
message TypeMeta {
|
||||
// Kind is a string value representing the REST resource this object represents.
|
||||
// Servers may infer this from the endpoint the client submits requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
optional string kind = 1;
|
||||
|
||||
// APIVersion defines the versioned schema of this representation of an object.
|
||||
// Servers should convert recognized schemas to the latest internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources
|
||||
optional string apiVersion = 2;
|
||||
}
|
||||
|
||||
325
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/group_version.go
generated
vendored
325
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/group_version.go
generated
vendored
|
|
@ -1,325 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseResourceArg takes the common style of string which may be either `resource.group.com` or `resource.version.group.com`
|
||||
// and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended
|
||||
// but with a knowledge of all GroupVersions, calling code can take a very good guess. If there are only two segments, then
|
||||
// `*GroupVersionResource` is nil.
|
||||
// `resource.group.com` -> `group=com, version=group, resource=resource` and `group=group.com, resource=resource`
|
||||
func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) {
|
||||
var gvr *GroupVersionResource
|
||||
if strings.Count(arg, ".") >= 2 {
|
||||
s := strings.SplitN(arg, ".", 3)
|
||||
gvr = &GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]}
|
||||
}
|
||||
|
||||
return gvr, ParseGroupResource(arg)
|
||||
}
|
||||
|
||||
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupResource struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Resource string `protobuf:"bytes,2,opt,name=resource"`
|
||||
}
|
||||
|
||||
func (gr GroupResource) WithVersion(version string) GroupVersionResource {
|
||||
return GroupVersionResource{Group: gr.Group, Version: version, Resource: gr.Resource}
|
||||
}
|
||||
|
||||
func (gr GroupResource) Empty() bool {
|
||||
return len(gr.Group) == 0 && len(gr.Resource) == 0
|
||||
}
|
||||
|
||||
func (gr *GroupResource) String() string {
|
||||
if len(gr.Group) == 0 {
|
||||
return gr.Resource
|
||||
}
|
||||
return gr.Resource + "." + gr.Group
|
||||
}
|
||||
|
||||
// ParseGroupResource turns "resource.group" string into a GroupResource struct. Empty strings are allowed
|
||||
// for each field.
|
||||
func ParseGroupResource(gr string) GroupResource {
|
||||
if i := strings.Index(gr, "."); i == -1 {
|
||||
return GroupResource{Resource: gr}
|
||||
} else {
|
||||
return GroupResource{Group: gr[i+1:], Resource: gr[:i]}
|
||||
}
|
||||
}
|
||||
|
||||
// GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupVersionResource struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Version string `protobuf:"bytes,2,opt,name=version"`
|
||||
Resource string `protobuf:"bytes,3,opt,name=resource"`
|
||||
}
|
||||
|
||||
func (gvr GroupVersionResource) Empty() bool {
|
||||
return len(gvr.Group) == 0 && len(gvr.Version) == 0 && len(gvr.Resource) == 0
|
||||
}
|
||||
|
||||
func (gvr GroupVersionResource) GroupResource() GroupResource {
|
||||
return GroupResource{Group: gvr.Group, Resource: gvr.Resource}
|
||||
}
|
||||
|
||||
func (gvr GroupVersionResource) GroupVersion() GroupVersion {
|
||||
return GroupVersion{Group: gvr.Group, Version: gvr.Version}
|
||||
}
|
||||
|
||||
func (gvr *GroupVersionResource) String() string {
|
||||
return strings.Join([]string{gvr.Group, "/", gvr.Version, ", Resource=", gvr.Resource}, "")
|
||||
}
|
||||
|
||||
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupKind struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Kind string `protobuf:"bytes,2,opt,name=kind"`
|
||||
}
|
||||
|
||||
func (gk GroupKind) Empty() bool {
|
||||
return len(gk.Group) == 0 && len(gk.Kind) == 0
|
||||
}
|
||||
|
||||
func (gk GroupKind) WithVersion(version string) GroupVersionKind {
|
||||
return GroupVersionKind{Group: gk.Group, Version: version, Kind: gk.Kind}
|
||||
}
|
||||
|
||||
func (gk *GroupKind) String() string {
|
||||
if len(gk.Group) == 0 {
|
||||
return gk.Kind
|
||||
}
|
||||
return gk.Kind + "." + gk.Group
|
||||
}
|
||||
|
||||
// GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupVersionKind struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Version string `protobuf:"bytes,2,opt,name=version"`
|
||||
Kind string `protobuf:"bytes,3,opt,name=kind"`
|
||||
}
|
||||
|
||||
// Empty returns true if group, version, and kind are empty
|
||||
func (gvk GroupVersionKind) Empty() bool {
|
||||
return len(gvk.Group) == 0 && len(gvk.Version) == 0 && len(gvk.Kind) == 0
|
||||
}
|
||||
|
||||
func (gvk GroupVersionKind) GroupKind() GroupKind {
|
||||
return GroupKind{Group: gvk.Group, Kind: gvk.Kind}
|
||||
}
|
||||
|
||||
func (gvk GroupVersionKind) GroupVersion() GroupVersion {
|
||||
return GroupVersion{Group: gvk.Group, Version: gvk.Version}
|
||||
}
|
||||
|
||||
func (gvk GroupVersionKind) String() string {
|
||||
return gvk.Group + "/" + gvk.Version + ", Kind=" + gvk.Kind
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupVersion struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Version string `protobuf:"bytes,2,opt,name=version"`
|
||||
}
|
||||
|
||||
// Empty returns true if group and version are empty
|
||||
func (gv GroupVersion) Empty() bool {
|
||||
return len(gv.Group) == 0 && len(gv.Version) == 0
|
||||
}
|
||||
|
||||
// String puts "group" and "version" into a single "group/version" string. For the legacy v1
|
||||
// it returns "v1".
|
||||
func (gv GroupVersion) String() string {
|
||||
// special case the internal apiVersion for the legacy kube types
|
||||
if gv.Empty() {
|
||||
return ""
|
||||
}
|
||||
|
||||
// special case of "v1" for backward compatibility
|
||||
if len(gv.Group) == 0 && gv.Version == "v1" {
|
||||
return gv.Version
|
||||
}
|
||||
if len(gv.Group) > 0 {
|
||||
return gv.Group + "/" + gv.Version
|
||||
}
|
||||
return gv.Version
|
||||
}
|
||||
|
||||
// KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false
|
||||
// if none of the options match the group. It prefers a match to group and version over just group.
|
||||
// TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme.
|
||||
// TODO: Introduce an adapter type between GroupVersion and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
|
||||
// in fewer places.
|
||||
func (gv GroupVersion) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) {
|
||||
for _, gvk := range kinds {
|
||||
if gvk.Group == gv.Group && gvk.Version == gv.Version {
|
||||
return gvk, true
|
||||
}
|
||||
}
|
||||
for _, gvk := range kinds {
|
||||
if gvk.Group == gv.Group {
|
||||
return gv.WithKind(gvk.Kind), true
|
||||
}
|
||||
}
|
||||
return GroupVersionKind{}, false
|
||||
}
|
||||
|
||||
// ParseGroupVersion turns "group/version" string into a GroupVersion struct. It reports error
|
||||
// if it cannot parse the string.
|
||||
func ParseGroupVersion(gv string) (GroupVersion, error) {
|
||||
// this can be the internal version for the legacy kube types
|
||||
// TODO once we've cleared the last uses as strings, this special case should be removed.
|
||||
if (len(gv) == 0) || (gv == "/") {
|
||||
return GroupVersion{}, nil
|
||||
}
|
||||
|
||||
switch strings.Count(gv, "/") {
|
||||
case 0:
|
||||
return GroupVersion{"", gv}, nil
|
||||
case 1:
|
||||
i := strings.Index(gv, "/")
|
||||
return GroupVersion{gv[:i], gv[i+1:]}, nil
|
||||
default:
|
||||
return GroupVersion{}, fmt.Errorf("unexpected GroupVersion string: %v", gv)
|
||||
}
|
||||
}
|
||||
|
||||
// WithKind creates a GroupVersionKind based on the method receiver's GroupVersion and the passed Kind.
|
||||
func (gv GroupVersion) WithKind(kind string) GroupVersionKind {
|
||||
return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind}
|
||||
}
|
||||
|
||||
// WithResource creates a GroupVersionResource based on the method receiver's GroupVersion and the passed Resource.
|
||||
func (gv GroupVersion) WithResource(resource string) GroupVersionResource {
|
||||
return GroupVersionResource{Group: gv.Group, Version: gv.Version, Resource: resource}
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface.
|
||||
func (gv GroupVersion) MarshalJSON() ([]byte, error) {
|
||||
s := gv.String()
|
||||
if strings.Count(s, "/") > 1 {
|
||||
return []byte{}, fmt.Errorf("illegal GroupVersion %v: contains more than one /", s)
|
||||
}
|
||||
return json.Marshal(s)
|
||||
}
|
||||
|
||||
func (gv *GroupVersion) unmarshal(value []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(value, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
parsed, err := ParseGroupVersion(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*gv = parsed
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (gv *GroupVersion) UnmarshalJSON(value []byte) error {
|
||||
return gv.unmarshal(value)
|
||||
}
|
||||
|
||||
// UnmarshalTEXT implements the Ugorji's encoding.TextUnmarshaler interface.
|
||||
func (gv *GroupVersion) UnmarshalText(value []byte) error {
|
||||
return gv.unmarshal(value)
|
||||
}
|
||||
|
||||
// GroupVersions can be used to represent a set of desired group versions.
|
||||
// TODO: Move GroupVersions to a package under pkg/runtime, since it's used by scheme.
|
||||
// TODO: Introduce an adapter type between GroupVersions and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
|
||||
// in fewer places.
|
||||
type GroupVersions []GroupVersion
|
||||
|
||||
// KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false
|
||||
// if none of the options match the group.
|
||||
func (gvs GroupVersions) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) {
|
||||
for _, gv := range gvs {
|
||||
target, ok := gv.KindForGroupVersionKinds(kinds)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
return target, true
|
||||
}
|
||||
return GroupVersionKind{}, false
|
||||
}
|
||||
|
||||
// ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that
|
||||
// do not use TypeMeta.
|
||||
func (gvk *GroupVersionKind) ToAPIVersionAndKind() (string, string) {
|
||||
if gvk == nil {
|
||||
return "", ""
|
||||
}
|
||||
return gvk.GroupVersion().String(), gvk.Kind
|
||||
}
|
||||
|
||||
// FromAPIVersionAndKind returns a GVK representing the provided fields for types that
|
||||
// do not use TypeMeta. This method exists to support test types and legacy serializations
|
||||
// that have a distinct group and kind.
|
||||
// TODO: further reduce usage of this method.
|
||||
func FromAPIVersionAndKind(apiVersion, kind string) GroupVersionKind {
|
||||
if gv, err := ParseGroupVersion(apiVersion); err == nil {
|
||||
return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind}
|
||||
}
|
||||
return GroupVersionKind{Kind: kind}
|
||||
}
|
||||
|
||||
// All objects that are serialized from a Scheme encode their type information. This interface is used
|
||||
// by serialization to set type information from the Scheme onto the serialized version of an object.
|
||||
// For objects that cannot be serialized or have unique requirements, this interface may be a no-op.
|
||||
// TODO: this belongs in pkg/runtime, move unversioned.GVK into runtime.
|
||||
type ObjectKind interface {
|
||||
// SetGroupVersionKind sets or clears the intended serialized kind of an object. Passing kind nil
|
||||
// should clear the current setting.
|
||||
SetGroupVersionKind(kind GroupVersionKind)
|
||||
// GroupVersionKind returns the stored group, version, and kind of an object, or nil if the object does
|
||||
// not expose or provide these fields.
|
||||
GroupVersionKind() GroupVersionKind
|
||||
}
|
||||
|
||||
// EmptyObjectKind implements the ObjectKind interface as a noop
|
||||
// TODO: this belongs in pkg/runtime, move unversioned.GVK into runtime.
|
||||
var EmptyObjectKind = emptyObjectKind{}
|
||||
|
||||
type emptyObjectKind struct{}
|
||||
|
||||
// SetGroupVersionKind implements the ObjectKind interface
|
||||
func (emptyObjectKind) SetGroupVersionKind(gvk GroupVersionKind) {}
|
||||
|
||||
// GroupVersionKind implements the ObjectKind interface
|
||||
func (emptyObjectKind) GroupVersionKind() GroupVersionKind { return GroupVersionKind{} }
|
||||
184
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/helpers.go
generated
vendored
184
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/helpers.go
generated
vendored
|
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/labels"
|
||||
"k8s.io/client-go/1.4/pkg/selection"
|
||||
"k8s.io/client-go/1.4/pkg/util/sets"
|
||||
)
|
||||
|
||||
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
|
||||
// labels.Selector
|
||||
// Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go
|
||||
func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
|
||||
if ps == nil {
|
||||
return labels.Nothing(), nil
|
||||
}
|
||||
if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
|
||||
return labels.Everything(), nil
|
||||
}
|
||||
selector := labels.NewSelector()
|
||||
for k, v := range ps.MatchLabels {
|
||||
r, err := labels.NewRequirement(k, selection.Equals, sets.NewString(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
for _, expr := range ps.MatchExpressions {
|
||||
var op selection.Operator
|
||||
switch expr.Operator {
|
||||
case LabelSelectorOpIn:
|
||||
op = selection.In
|
||||
case LabelSelectorOpNotIn:
|
||||
op = selection.NotIn
|
||||
case LabelSelectorOpExists:
|
||||
op = selection.Exists
|
||||
case LabelSelectorOpDoesNotExist:
|
||||
op = selection.DoesNotExist
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
|
||||
}
|
||||
r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// LabelSelectorAsMap converts the LabelSelector api type into a map of strings, ie. the
|
||||
// original structure of a label selector. Operators that cannot be converted into plain
|
||||
// labels (Exists, DoesNotExist, NotIn, and In with more than one value) will result in
|
||||
// an error.
|
||||
func LabelSelectorAsMap(ps *LabelSelector) (map[string]string, error) {
|
||||
if ps == nil {
|
||||
return nil, nil
|
||||
}
|
||||
selector := map[string]string{}
|
||||
for k, v := range ps.MatchLabels {
|
||||
selector[k] = v
|
||||
}
|
||||
for _, expr := range ps.MatchExpressions {
|
||||
switch expr.Operator {
|
||||
case LabelSelectorOpIn:
|
||||
if len(expr.Values) != 1 {
|
||||
return selector, fmt.Errorf("operator %q without a single value cannot be converted into the old label selector format", expr.Operator)
|
||||
}
|
||||
// Should we do anything in case this will override a previous key-value pair?
|
||||
selector[expr.Key] = expr.Values[0]
|
||||
case LabelSelectorOpNotIn, LabelSelectorOpExists, LabelSelectorOpDoesNotExist:
|
||||
return selector, fmt.Errorf("operator %q cannot be converted into the old label selector format", expr.Operator)
|
||||
default:
|
||||
return selector, fmt.Errorf("%q is not a valid selector operator", expr.Operator)
|
||||
}
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// ParseToLabelSelector parses a string representing a selector into a LabelSelector object.
|
||||
// Note: This function should be kept in sync with the parser in pkg/labels/selector.go
|
||||
func ParseToLabelSelector(selector string) (*LabelSelector, error) {
|
||||
reqs, err := labels.ParseToRequirements(selector)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't parse the selector string \"%s\": %v", selector, err)
|
||||
}
|
||||
|
||||
labelSelector := &LabelSelector{
|
||||
MatchLabels: map[string]string{},
|
||||
MatchExpressions: []LabelSelectorRequirement{},
|
||||
}
|
||||
for _, req := range reqs {
|
||||
var op LabelSelectorOperator
|
||||
switch req.Operator() {
|
||||
case selection.Equals, selection.DoubleEquals:
|
||||
vals := req.Values()
|
||||
if vals.Len() != 1 {
|
||||
return nil, fmt.Errorf("equals operator must have exactly one value")
|
||||
}
|
||||
val, ok := vals.PopAny()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("equals operator has exactly one value but it cannot be retrieved")
|
||||
}
|
||||
labelSelector.MatchLabels[req.Key()] = val
|
||||
continue
|
||||
case selection.In:
|
||||
op = LabelSelectorOpIn
|
||||
case selection.NotIn:
|
||||
op = LabelSelectorOpNotIn
|
||||
case selection.Exists:
|
||||
op = LabelSelectorOpExists
|
||||
case selection.DoesNotExist:
|
||||
op = LabelSelectorOpDoesNotExist
|
||||
case selection.GreaterThan, selection.LessThan:
|
||||
// Adding a separate case for these operators to indicate that this is deliberate
|
||||
return nil, fmt.Errorf("%q isn't supported in label selectors", req.Operator())
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid label selector operator", req.Operator())
|
||||
}
|
||||
labelSelector.MatchExpressions = append(labelSelector.MatchExpressions, LabelSelectorRequirement{
|
||||
Key: req.Key(),
|
||||
Operator: op,
|
||||
Values: req.Values().List(),
|
||||
})
|
||||
}
|
||||
return labelSelector, nil
|
||||
}
|
||||
|
||||
// SetAsLabelSelector converts the labels.Set object into a LabelSelector api object.
|
||||
func SetAsLabelSelector(ls labels.Set) *LabelSelector {
|
||||
if ls == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
selector := &LabelSelector{
|
||||
MatchLabels: make(map[string]string),
|
||||
}
|
||||
for label, value := range ls {
|
||||
selector.MatchLabels[label] = value
|
||||
}
|
||||
|
||||
return selector
|
||||
}
|
||||
|
||||
// FormatLabelSelector convert labelSelector into plain string
|
||||
func FormatLabelSelector(labelSelector *LabelSelector) string {
|
||||
selector, err := LabelSelectorAsSelector(labelSelector)
|
||||
if err != nil {
|
||||
return "<error>"
|
||||
}
|
||||
|
||||
l := selector.String()
|
||||
if len(l) == 0 {
|
||||
l = "<none>"
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func ExtractGroupVersions(l *APIGroupList) []string {
|
||||
var groupVersions []string
|
||||
for _, g := range l.Groups {
|
||||
for _, gv := range g.Versions {
|
||||
groupVersions = append(groupVersions, gv.GroupVersion)
|
||||
}
|
||||
}
|
||||
return groupVersions
|
||||
}
|
||||
62
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/meta.go
generated
vendored
62
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/meta.go
generated
vendored
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
// ListMetaAccessor retrieves the list interface from an object
|
||||
// TODO: move this, and TypeMeta and ListMeta, to a different package
|
||||
type ListMetaAccessor interface {
|
||||
GetListMeta() List
|
||||
}
|
||||
|
||||
// List lets you work with list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field will be a no-op and return a default value.
|
||||
// TODO: move this, and TypeMeta and ListMeta, to a different package
|
||||
type List interface {
|
||||
GetResourceVersion() string
|
||||
SetResourceVersion(version string)
|
||||
GetSelfLink() string
|
||||
SetSelfLink(selfLink string)
|
||||
}
|
||||
|
||||
// Type exposes the type and APIVersion of versioned or internal API objects.
|
||||
// TODO: move this, and TypeMeta and ListMeta, to a different package
|
||||
type Type interface {
|
||||
GetAPIVersion() string
|
||||
SetAPIVersion(version string)
|
||||
GetKind() string
|
||||
SetKind(kind string)
|
||||
}
|
||||
|
||||
func (meta *ListMeta) GetResourceVersion() string { return meta.ResourceVersion }
|
||||
func (meta *ListMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
|
||||
func (meta *ListMeta) GetSelfLink() string { return meta.SelfLink }
|
||||
func (meta *ListMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
|
||||
|
||||
func (obj *TypeMeta) GetObjectKind() ObjectKind { return obj }
|
||||
|
||||
// SetGroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
|
||||
func (obj *TypeMeta) SetGroupVersionKind(gvk GroupVersionKind) {
|
||||
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
|
||||
// GroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
|
||||
func (obj *TypeMeta) GroupVersionKind() GroupVersionKind {
|
||||
return FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
|
||||
}
|
||||
|
||||
func (obj *ListMeta) GetListMeta() List { return obj }
|
||||
166
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/time.go
generated
vendored
166
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/time.go
generated
vendored
|
|
@ -1,166 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
// Time is a wrapper around time.Time which supports correct
|
||||
// marshaling to YAML and JSON. Wrappers are provided for many
|
||||
// of the factory methods that the time package offers.
|
||||
//
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.as=Timestamp
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type Time struct {
|
||||
time.Time `protobuf:"-"`
|
||||
}
|
||||
|
||||
// DeepCopy returns a deep-copy of the Time value. The underlying time.Time
|
||||
// type is effectively immutable in the time API, so it is safe to
|
||||
// copy-by-assign, despite the presence of (unexported) Pointer fields.
|
||||
func (t Time) DeepCopy() Time {
|
||||
return t
|
||||
}
|
||||
|
||||
// String returns the representation of the time.
|
||||
func (t Time) String() string {
|
||||
return t.Time.String()
|
||||
}
|
||||
|
||||
// NewTime returns a wrapped instance of the provided time
|
||||
func NewTime(time time.Time) Time {
|
||||
return Time{time}
|
||||
}
|
||||
|
||||
// Date returns the Time corresponding to the supplied parameters
|
||||
// by wrapping time.Date.
|
||||
func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Time {
|
||||
return Time{time.Date(year, month, day, hour, min, sec, nsec, loc)}
|
||||
}
|
||||
|
||||
// Now returns the current local time.
|
||||
func Now() Time {
|
||||
return Time{time.Now()}
|
||||
}
|
||||
|
||||
// IsZero returns true if the value is nil or time is zero.
|
||||
func (t *Time) IsZero() bool {
|
||||
if t == nil {
|
||||
return true
|
||||
}
|
||||
return t.Time.IsZero()
|
||||
}
|
||||
|
||||
// Before reports whether the time instant t is before u.
|
||||
func (t Time) Before(u Time) bool {
|
||||
return t.Time.Before(u.Time)
|
||||
}
|
||||
|
||||
// Equal reports whether the time instant t is equal to u.
|
||||
func (t Time) Equal(u Time) bool {
|
||||
return t.Time.Equal(u.Time)
|
||||
}
|
||||
|
||||
// Unix returns the local time corresponding to the given Unix time
|
||||
// by wrapping time.Unix.
|
||||
func Unix(sec int64, nsec int64) Time {
|
||||
return Time{time.Unix(sec, nsec)}
|
||||
}
|
||||
|
||||
// Rfc3339Copy returns a copy of the Time at second-level precision.
|
||||
func (t Time) Rfc3339Copy() Time {
|
||||
copied, _ := time.Parse(time.RFC3339, t.Format(time.RFC3339))
|
||||
return Time{copied}
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (t *Time) UnmarshalJSON(b []byte) error {
|
||||
if len(b) == 4 && string(b) == "null" {
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
|
||||
var str string
|
||||
json.Unmarshal(b, &str)
|
||||
|
||||
pt, err := time.Parse(time.RFC3339, str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Time = pt.Local()
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalQueryParameter converts from a URL query parameter value to an object
|
||||
func (t *Time) UnmarshalQueryParameter(str string) error {
|
||||
if len(str) == 0 {
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
// Tolerate requests from older clients that used JSON serialization to build query params
|
||||
if len(str) == 4 && str == "null" {
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
|
||||
pt, err := time.Parse(time.RFC3339, str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Time = pt.Local()
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
if t.IsZero() {
|
||||
// Encode unset/nil objects as JSON's "null".
|
||||
return []byte("null"), nil
|
||||
}
|
||||
|
||||
return json.Marshal(t.UTC().Format(time.RFC3339))
|
||||
}
|
||||
|
||||
// MarshalQueryParameter converts to a URL query parameter value
|
||||
func (t Time) MarshalQueryParameter() (string, error) {
|
||||
if t.IsZero() {
|
||||
// Encode unset/nil objects as an empty string
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return t.UTC().Format(time.RFC3339), nil
|
||||
}
|
||||
|
||||
// Fuzz satisfies fuzz.Interface.
|
||||
func (t *Time) Fuzz(c fuzz.Continue) {
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
// Allow for about 1000 years of randomness. Leave off nanoseconds
|
||||
// because JSON doesn't represent them so they can't round-trip
|
||||
// properly.
|
||||
t.Time = time.Unix(c.Rand.Int63n(1000*365*24*60*60), 0)
|
||||
}
|
||||
|
||||
var _ fuzz.Interface = &Time{}
|
||||
85
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/time_proto.go
generated
vendored
85
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/time_proto.go
generated
vendored
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Timestamp is a struct that is equivalent to Time, but intended for
|
||||
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
||||
// that matches Time. Do not use in Go structs.
|
||||
type Timestamp struct {
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
Seconds int64 `json:"seconds" protobuf:"varint,1,opt,name=seconds"`
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive. This field may be limited in precision depending on context.
|
||||
Nanos int32 `json:"nanos" protobuf:"varint,2,opt,name=nanos"`
|
||||
}
|
||||
|
||||
// Timestamp returns the Time as a new Timestamp value.
|
||||
func (m *Time) ProtoTime() *Timestamp {
|
||||
if m == nil {
|
||||
return &Timestamp{}
|
||||
}
|
||||
return &Timestamp{
|
||||
Seconds: m.Time.Unix(),
|
||||
Nanos: int32(m.Time.Nanosecond()),
|
||||
}
|
||||
}
|
||||
|
||||
// Size implements the protobuf marshalling interface.
|
||||
func (m *Time) Size() (n int) {
|
||||
if m == nil || m.Time.IsZero() {
|
||||
return 0
|
||||
}
|
||||
return m.ProtoTime().Size()
|
||||
}
|
||||
|
||||
// Reset implements the protobuf marshalling interface.
|
||||
func (m *Time) Unmarshal(data []byte) error {
|
||||
if len(data) == 0 {
|
||||
m.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
p := Timestamp{}
|
||||
if err := p.Unmarshal(data); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Time = time.Unix(p.Seconds, int64(p.Nanos)).Local()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshal implements the protobuf marshalling interface.
|
||||
func (m *Time) Marshal() (data []byte, err error) {
|
||||
if m == nil || m.Time.IsZero() {
|
||||
return nil, nil
|
||||
}
|
||||
return m.ProtoTime().Marshal()
|
||||
}
|
||||
|
||||
// MarshalTo implements the protobuf marshalling interface.
|
||||
func (m *Time) MarshalTo(data []byte) (int, error) {
|
||||
if m == nil || m.Time.IsZero() {
|
||||
return 0, nil
|
||||
}
|
||||
return m.ProtoTime().MarshalTo(data)
|
||||
}
|
||||
460
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/types.go
generated
vendored
460
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/types.go
generated
vendored
|
|
@ -1,460 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package unversioned contains API types that are common to all versions.
|
||||
//
|
||||
// The package contains two categories of types:
|
||||
// - external (serialized) types that lack their own version (e.g TypeMeta)
|
||||
// - internal (never-serialized) types that are needed by several different
|
||||
// api groups, and so live here, to avoid duplication and/or import loops
|
||||
// (e.g. LabelSelector).
|
||||
// In the future, we will probably move these categories of objects into
|
||||
// separate packages.
|
||||
package unversioned
|
||||
|
||||
import "strings"
|
||||
|
||||
// TypeMeta describes an individual object in an API response or request
|
||||
// with strings representing the type of the object and its API schema version.
|
||||
// Structures that are versioned or persisted should inline TypeMeta.
|
||||
type TypeMeta struct {
|
||||
// Kind is a string value representing the REST resource this object represents.
|
||||
// Servers may infer this from the endpoint the client submits requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
|
||||
|
||||
// APIVersion defines the versioned schema of this representation of an object.
|
||||
// Servers should convert recognized schemas to the latest internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources
|
||||
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
|
||||
}
|
||||
|
||||
// ListMeta describes metadata that synthetic resources must have, including lists and
|
||||
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
|
||||
type ListMeta struct {
|
||||
// SelfLink is a URL representing this object.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,1,opt,name=selfLink"`
|
||||
|
||||
// String that identifies the server's internal version of this object that
|
||||
// can be used by clients to determine when objects have changed.
|
||||
// Value must be treated as opaque by clients and passed unmodified back to the server.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency
|
||||
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,2,opt,name=resourceVersion"`
|
||||
}
|
||||
|
||||
// ExportOptions is the query options to the standard REST get call.
|
||||
type ExportOptions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Should this value be exported. Export strips fields that a user can not specify.`
|
||||
Export bool `json:"export" protobuf:"varint,1,opt,name=export"`
|
||||
// Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'
|
||||
Exact bool `json:"exact" protobuf:"varint,2,opt,name=exact"`
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
type Status struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Standard list metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// Status of the operation.
|
||||
// One of: "Success" or "Failure".
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status string `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"`
|
||||
// A human-readable description of the status of this operation.
|
||||
Message string `json:"message,omitempty" protobuf:"bytes,3,opt,name=message"`
|
||||
// A machine-readable description of why this operation is in the
|
||||
// "Failure" status. If this value is empty there
|
||||
// is no information available. A Reason clarifies an HTTP status
|
||||
// code but does not override it.
|
||||
Reason StatusReason `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason,casttype=StatusReason"`
|
||||
// Extended data associated with the reason. Each reason may define its
|
||||
// own extended details. This field is optional and the data returned
|
||||
// is not guaranteed to conform to any schema except that defined by
|
||||
// the reason type.
|
||||
Details *StatusDetails `json:"details,omitempty" protobuf:"bytes,5,opt,name=details"`
|
||||
// Suggested HTTP return code for this status, 0 if not set.
|
||||
Code int32 `json:"code,omitempty" protobuf:"varint,6,opt,name=code"`
|
||||
}
|
||||
|
||||
// StatusDetails is a set of additional properties that MAY be set by the
|
||||
// server to provide additional information about a response. The Reason
|
||||
// field of a Status object defines what attributes will be set. Clients
|
||||
// must ignore fields that do not match the defined type of each attribute,
|
||||
// and should assume that any attribute may be empty, invalid, or under
|
||||
// defined.
|
||||
type StatusDetails struct {
|
||||
// The name attribute of the resource associated with the status StatusReason
|
||||
// (when there is a single name which can be described).
|
||||
Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
|
||||
// The group attribute of the resource associated with the status StatusReason.
|
||||
Group string `json:"group,omitempty" protobuf:"bytes,2,opt,name=group"`
|
||||
// The kind attribute of the resource associated with the status StatusReason.
|
||||
// On some operations may differ from the requested resource Kind.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"`
|
||||
// The Causes array includes more details associated with the StatusReason
|
||||
// failure. Not all StatusReasons may provide detailed causes.
|
||||
Causes []StatusCause `json:"causes,omitempty" protobuf:"bytes,4,rep,name=causes"`
|
||||
// If specified, the time in seconds before the operation should be retried.
|
||||
RetryAfterSeconds int32 `json:"retryAfterSeconds,omitempty" protobuf:"varint,5,opt,name=retryAfterSeconds"`
|
||||
}
|
||||
|
||||
// Values of Status.Status
|
||||
const (
|
||||
StatusSuccess = "Success"
|
||||
StatusFailure = "Failure"
|
||||
)
|
||||
|
||||
// StatusReason is an enumeration of possible failure causes. Each StatusReason
|
||||
// must map to a single HTTP status code, but multiple reasons may map
|
||||
// to the same HTTP status code.
|
||||
// TODO: move to apiserver
|
||||
type StatusReason string
|
||||
|
||||
const (
|
||||
// StatusReasonUnknown means the server has declined to indicate a specific reason.
|
||||
// The details field may contain other information about this error.
|
||||
// Status code 500.
|
||||
StatusReasonUnknown StatusReason = ""
|
||||
|
||||
// StatusReasonUnauthorized means the server can be reached and understood the request, but requires
|
||||
// the user to present appropriate authorization credentials (identified by the WWW-Authenticate header)
|
||||
// in order for the action to be completed. If the user has specified credentials on the request, the
|
||||
// server considers them insufficient.
|
||||
// Status code 401
|
||||
StatusReasonUnauthorized StatusReason = "Unauthorized"
|
||||
|
||||
// StatusReasonForbidden means the server can be reached and understood the request, but refuses
|
||||
// to take any further action. It is the result of the server being configured to deny access for some reason
|
||||
// to the requested resource by the client.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the forbidden resource
|
||||
// on some operations may differ from the requested
|
||||
// resource.
|
||||
// "id" string - the identifier of the forbidden resource
|
||||
// Status code 403
|
||||
StatusReasonForbidden StatusReason = "Forbidden"
|
||||
|
||||
// StatusReasonNotFound means one or more resources required for this operation
|
||||
// could not be found.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the missing resource
|
||||
// on some operations may differ from the requested
|
||||
// resource.
|
||||
// "id" string - the identifier of the missing resource
|
||||
// Status code 404
|
||||
StatusReasonNotFound StatusReason = "NotFound"
|
||||
|
||||
// StatusReasonAlreadyExists means the resource you are creating already exists.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the conflicting resource
|
||||
// "id" string - the identifier of the conflicting resource
|
||||
// Status code 409
|
||||
StatusReasonAlreadyExists StatusReason = "AlreadyExists"
|
||||
|
||||
// StatusReasonConflict means the requested operation cannot be completed
|
||||
// due to a conflict in the operation. The client may need to alter the
|
||||
// request. Each resource may define custom details that indicate the
|
||||
// nature of the conflict.
|
||||
// Status code 409
|
||||
StatusReasonConflict StatusReason = "Conflict"
|
||||
|
||||
// StatusReasonGone means the item is no longer available at the server and no
|
||||
// forwarding address is known.
|
||||
// Status code 410
|
||||
StatusReasonGone StatusReason = "Gone"
|
||||
|
||||
// StatusReasonInvalid means the requested create or update operation cannot be
|
||||
// completed due to invalid data provided as part of the request. The client may
|
||||
// need to alter the request. When set, the client may use the StatusDetails
|
||||
// message field as a summary of the issues encountered.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the invalid resource
|
||||
// "id" string - the identifier of the invalid resource
|
||||
// "causes" - one or more StatusCause entries indicating the data in the
|
||||
// provided resource that was invalid. The code, message, and
|
||||
// field attributes will be set.
|
||||
// Status code 422
|
||||
StatusReasonInvalid StatusReason = "Invalid"
|
||||
|
||||
// StatusReasonServerTimeout means the server can be reached and understood the request,
|
||||
// but cannot complete the action in a reasonable time. The client should retry the request.
|
||||
// This is may be due to temporary server load or a transient communication issue with
|
||||
// another server. Status code 500 is used because the HTTP spec provides no suitable
|
||||
// server-requested client retry and the 5xx class represents actionable errors.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the resource being acted on.
|
||||
// "id" string - the operation that is being attempted.
|
||||
// "retryAfterSeconds" int32 - the number of seconds before the operation should be retried
|
||||
// Status code 500
|
||||
StatusReasonServerTimeout StatusReason = "ServerTimeout"
|
||||
|
||||
// StatusReasonTimeout means that the request could not be completed within the given time.
|
||||
// Clients can get this response only when they specified a timeout param in the request,
|
||||
// or if the server cannot complete the operation within a reasonable amount of time.
|
||||
// The request might succeed with an increased value of timeout param. The client *should*
|
||||
// wait at least the number of seconds specified by the retryAfterSeconds field.
|
||||
// Details (optional):
|
||||
// "retryAfterSeconds" int32 - the number of seconds before the operation should be retried
|
||||
// Status code 504
|
||||
StatusReasonTimeout StatusReason = "Timeout"
|
||||
|
||||
// StatusReasonBadRequest means that the request itself was invalid, because the request
|
||||
// doesn't make any sense, for example deleting a read-only object. This is different than
|
||||
// StatusReasonInvalid above which indicates that the API call could possibly succeed, but the
|
||||
// data was invalid. API calls that return BadRequest can never succeed.
|
||||
StatusReasonBadRequest StatusReason = "BadRequest"
|
||||
|
||||
// StatusReasonMethodNotAllowed means that the action the client attempted to perform on the
|
||||
// resource was not supported by the code - for instance, attempting to delete a resource that
|
||||
// can only be created. API calls that return MethodNotAllowed can never succeed.
|
||||
StatusReasonMethodNotAllowed StatusReason = "MethodNotAllowed"
|
||||
|
||||
// StatusReasonInternalError indicates that an internal error occurred, it is unexpected
|
||||
// and the outcome of the call is unknown.
|
||||
// Details (optional):
|
||||
// "causes" - The original error
|
||||
// Status code 500
|
||||
StatusReasonInternalError StatusReason = "InternalError"
|
||||
|
||||
// StatusReasonExpired indicates that the request is invalid because the content you are requesting
|
||||
// has expired and is no longer available. It is typically associated with watches that can't be
|
||||
// serviced.
|
||||
// Status code 410 (gone)
|
||||
StatusReasonExpired StatusReason = "Expired"
|
||||
|
||||
// StatusReasonServiceUnavailable means that the request itself was valid,
|
||||
// but the requested service is unavailable at this time.
|
||||
// Retrying the request after some time might succeed.
|
||||
// Status code 503
|
||||
StatusReasonServiceUnavailable StatusReason = "ServiceUnavailable"
|
||||
)
|
||||
|
||||
// StatusCause provides more information about an api.Status failure, including
|
||||
// cases when multiple errors are encountered.
|
||||
type StatusCause struct {
|
||||
// A machine-readable description of the cause of the error. If this value is
|
||||
// empty there is no information available.
|
||||
Type CauseType `json:"reason,omitempty" protobuf:"bytes,1,opt,name=reason,casttype=CauseType"`
|
||||
// A human-readable description of the cause of the error. This field may be
|
||||
// presented as-is to a reader.
|
||||
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
|
||||
// The field of the resource that has caused this error, as named by its JSON
|
||||
// serialization. May include dot and postfix notation for nested attributes.
|
||||
// Arrays are zero-indexed. Fields may appear more than once in an array of
|
||||
// causes due to fields having multiple errors.
|
||||
// Optional.
|
||||
//
|
||||
// Examples:
|
||||
// "name" - the field "name" on the current resource
|
||||
// "items[0].name" - the field "name" on the first array entry in "items"
|
||||
Field string `json:"field,omitempty" protobuf:"bytes,3,opt,name=field"`
|
||||
}
|
||||
|
||||
// CauseType is a machine readable value providing more detail about what
|
||||
// occurred in a status response. An operation may have multiple causes for a
|
||||
// status (whether Failure or Success).
|
||||
type CauseType string
|
||||
|
||||
const (
|
||||
// CauseTypeFieldValueNotFound is used to report failure to find a requested value
|
||||
// (e.g. looking up an ID).
|
||||
CauseTypeFieldValueNotFound CauseType = "FieldValueNotFound"
|
||||
// CauseTypeFieldValueRequired is used to report required values that are not
|
||||
// provided (e.g. empty strings, null values, or empty arrays).
|
||||
CauseTypeFieldValueRequired CauseType = "FieldValueRequired"
|
||||
// CauseTypeFieldValueDuplicate is used to report collisions of values that must be
|
||||
// unique (e.g. unique IDs).
|
||||
CauseTypeFieldValueDuplicate CauseType = "FieldValueDuplicate"
|
||||
// CauseTypeFieldValueInvalid is used to report malformed values (e.g. failed regex
|
||||
// match).
|
||||
CauseTypeFieldValueInvalid CauseType = "FieldValueInvalid"
|
||||
// CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules)
|
||||
// values that can not be handled (e.g. an enumerated string).
|
||||
CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported"
|
||||
// CauseTypeUnexpectedServerResponse is used to report when the server responded to the client
|
||||
// without the expected return type. The presence of this cause indicates the error may be
|
||||
// due to an intervening proxy or the server software malfunctioning.
|
||||
CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse"
|
||||
)
|
||||
|
||||
// APIVersions lists the versions that are available, to allow clients to
|
||||
// discover the API at /api, which is the root path of the legacy v1 API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type APIVersions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// versions are the api versions that are available.
|
||||
Versions []string `json:"versions" protobuf:"bytes,1,rep,name=versions"`
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" protobuf:"bytes,2,rep,name=serverAddressByClientCIDRs"`
|
||||
}
|
||||
|
||||
// APIGroupList is a list of APIGroup, to allow clients to discover the API at
|
||||
// /apis.
|
||||
type APIGroupList struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// groups is a list of APIGroup.
|
||||
Groups []APIGroup `json:"groups" protobuf:"bytes,1,rep,name=groups"`
|
||||
}
|
||||
|
||||
// APIGroup contains the name, the supported versions, and the preferred version
|
||||
// of a group.
|
||||
type APIGroup struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// name is the name of the group.
|
||||
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
|
||||
// versions are the versions supported in this group.
|
||||
Versions []GroupVersionForDiscovery `json:"versions" protobuf:"bytes,2,rep,name=versions"`
|
||||
// preferredVersion is the version preferred by the API server, which
|
||||
// probably is the storage version.
|
||||
PreferredVersion GroupVersionForDiscovery `json:"preferredVersion,omitempty" protobuf:"bytes,3,opt,name=preferredVersion"`
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" protobuf:"bytes,4,rep,name=serverAddressByClientCIDRs"`
|
||||
}
|
||||
|
||||
// ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.
|
||||
type ServerAddressByClientCIDR struct {
|
||||
// The CIDR with which clients can match their IP to figure out the server address that they should use.
|
||||
ClientCIDR string `json:"clientCIDR" protobuf:"bytes,1,opt,name=clientCIDR"`
|
||||
// Address of this server, suitable for a client that matches the above CIDR.
|
||||
// This can be a hostname, hostname:port, IP or IP:port.
|
||||
ServerAddress string `json:"serverAddress" protobuf:"bytes,2,opt,name=serverAddress"`
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group/version" and "version" string of a version.
|
||||
// It is made a struct to keep extensibility.
|
||||
type GroupVersionForDiscovery struct {
|
||||
// groupVersion specifies the API group and version in the form "group/version"
|
||||
GroupVersion string `json:"groupVersion" protobuf:"bytes,1,opt,name=groupVersion"`
|
||||
// version specifies the version in the form of "version". This is to save
|
||||
// the clients the trouble of splitting the GroupVersion.
|
||||
Version string `json:"version" protobuf:"bytes,2,opt,name=version"`
|
||||
}
|
||||
|
||||
// APIResource specifies the name of a resource and whether it is namespaced.
|
||||
type APIResource struct {
|
||||
// name is the name of the resource.
|
||||
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
|
||||
// namespaced indicates if a resource is namespaced or not.
|
||||
Namespaced bool `json:"namespaced" protobuf:"varint,2,opt,name=namespaced"`
|
||||
// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
|
||||
Kind string `json:"kind" protobuf:"bytes,3,opt,name=kind"`
|
||||
}
|
||||
|
||||
// APIResourceList is a list of APIResource, it is used to expose the name of the
|
||||
// resources supported in a specific group and version, and if the resource
|
||||
// is namespaced.
|
||||
type APIResourceList struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// groupVersion is the group and version this APIResourceList is for.
|
||||
GroupVersion string `json:"groupVersion" protobuf:"bytes,1,opt,name=groupVersion"`
|
||||
// resources contains the name of the resources and if they are namespaced.
|
||||
APIResources []APIResource `json:"resources" protobuf:"bytes,2,rep,name=resources"`
|
||||
}
|
||||
|
||||
// RootPaths lists the paths available at root.
|
||||
// For example: "/healthz", "/apis".
|
||||
type RootPaths struct {
|
||||
// paths are the paths available at root.
|
||||
Paths []string `json:"paths" protobuf:"bytes,1,rep,name=paths"`
|
||||
}
|
||||
|
||||
// TODO: remove me when watch is refactored
|
||||
func LabelSelectorQueryParam(version string) string {
|
||||
return "labelSelector"
|
||||
}
|
||||
|
||||
// TODO: remove me when watch is refactored
|
||||
func FieldSelectorQueryParam(version string) string {
|
||||
return "fieldSelector"
|
||||
}
|
||||
|
||||
// String returns available api versions as a human-friendly version string.
|
||||
func (apiVersions APIVersions) String() string {
|
||||
return strings.Join(apiVersions.Versions, ",")
|
||||
}
|
||||
|
||||
func (apiVersions APIVersions) GoString() string {
|
||||
return apiVersions.String()
|
||||
}
|
||||
|
||||
// Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.
|
||||
type Patch struct{}
|
||||
|
||||
// Note:
|
||||
// There are two different styles of label selectors used in versioned types:
|
||||
// an older style which is represented as just a string in versioned types, and a
|
||||
// newer style that is structured. LabelSelector is an internal representation for the
|
||||
// latter style.
|
||||
|
||||
// A label selector is a label query over a set of resources. The result of matchLabels and
|
||||
// matchExpressions are ANDed. An empty label selector matches all objects. A null
|
||||
// label selector matches no objects.
|
||||
type LabelSelector struct {
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
// operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
MatchLabels map[string]string `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"`
|
||||
// matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" protobuf:"bytes,2,rep,name=matchExpressions"`
|
||||
}
|
||||
|
||||
// A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
// relates the key and values.
|
||||
type LabelSelectorRequirement struct {
|
||||
// key is the label key that the selector applies to.
|
||||
Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"`
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators ard In, NotIn, Exists and DoesNotExist.
|
||||
Operator LabelSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=LabelSelectorOperator"`
|
||||
// values is an array of string values. If the operator is In or NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a strategic
|
||||
// merge patch.
|
||||
Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values"`
|
||||
}
|
||||
|
||||
// A label selector operator is the set of operators that can be used in a selector requirement.
|
||||
type LabelSelectorOperator string
|
||||
|
||||
const (
|
||||
LabelSelectorOpIn LabelSelectorOperator = "In"
|
||||
LabelSelectorOpNotIn LabelSelectorOperator = "NotIn"
|
||||
LabelSelectorOpExists LabelSelectorOperator = "Exists"
|
||||
LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist"
|
||||
)
|
||||
208
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/types_swagger_doc_generated.go
generated
vendored
208
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/types_swagger_doc_generated.go
generated
vendored
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
// This file contains a collection of methods that can be used from go-restful to
|
||||
// generate Swagger API documentation for its models. Please read this PR for more
|
||||
// information on the implementation: https://github.com/emicklei/go-restful/pull/215
|
||||
//
|
||||
// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if
|
||||
// they are on one line! For multiple line or blocks that you want to ignore use ---.
|
||||
// Any context after a --- is ignored.
|
||||
//
|
||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS START HERE
|
||||
var map_APIGroup = map[string]string{
|
||||
"": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"name": "name is the name of the group.",
|
||||
"versions": "versions are the versions supported in this group.",
|
||||
"preferredVersion": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"serverAddressByClientCIDRs": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
}
|
||||
|
||||
func (APIGroup) SwaggerDoc() map[string]string {
|
||||
return map_APIGroup
|
||||
}
|
||||
|
||||
var map_APIGroupList = map[string]string{
|
||||
"": "APIGroupList is a list of APIGroup, to allow clients to discover the API at /apis.",
|
||||
"groups": "groups is a list of APIGroup.",
|
||||
}
|
||||
|
||||
func (APIGroupList) SwaggerDoc() map[string]string {
|
||||
return map_APIGroupList
|
||||
}
|
||||
|
||||
var map_APIResource = map[string]string{
|
||||
"": "APIResource specifies the name of a resource and whether it is namespaced.",
|
||||
"name": "name is the name of the resource.",
|
||||
"namespaced": "namespaced indicates if a resource is namespaced or not.",
|
||||
"kind": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')",
|
||||
}
|
||||
|
||||
func (APIResource) SwaggerDoc() map[string]string {
|
||||
return map_APIResource
|
||||
}
|
||||
|
||||
var map_APIResourceList = map[string]string{
|
||||
"": "APIResourceList is a list of APIResource, it is used to expose the name of the resources supported in a specific group and version, and if the resource is namespaced.",
|
||||
"groupVersion": "groupVersion is the group and version this APIResourceList is for.",
|
||||
"resources": "resources contains the name of the resources and if they are namespaced.",
|
||||
}
|
||||
|
||||
func (APIResourceList) SwaggerDoc() map[string]string {
|
||||
return map_APIResourceList
|
||||
}
|
||||
|
||||
var map_APIVersions = map[string]string{
|
||||
"": "APIVersions lists the versions that are available, to allow clients to discover the API at /api, which is the root path of the legacy v1 API.",
|
||||
"versions": "versions are the api versions that are available.",
|
||||
"serverAddressByClientCIDRs": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
}
|
||||
|
||||
func (APIVersions) SwaggerDoc() map[string]string {
|
||||
return map_APIVersions
|
||||
}
|
||||
|
||||
var map_ExportOptions = map[string]string{
|
||||
"": "ExportOptions is the query options to the standard REST get call.",
|
||||
"export": "Should this value be exported. Export strips fields that a user can not specify.`",
|
||||
"exact": "Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'",
|
||||
}
|
||||
|
||||
func (ExportOptions) SwaggerDoc() map[string]string {
|
||||
return map_ExportOptions
|
||||
}
|
||||
|
||||
var map_GroupVersionForDiscovery = map[string]string{
|
||||
"": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"groupVersion": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"version": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
}
|
||||
|
||||
func (GroupVersionForDiscovery) SwaggerDoc() map[string]string {
|
||||
return map_GroupVersionForDiscovery
|
||||
}
|
||||
|
||||
var map_LabelSelector = map[string]string{
|
||||
"": "A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.",
|
||||
"matchLabels": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is \"key\", the operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
|
||||
"matchExpressions": "matchExpressions is a list of label selector requirements. The requirements are ANDed.",
|
||||
}
|
||||
|
||||
func (LabelSelector) SwaggerDoc() map[string]string {
|
||||
return map_LabelSelector
|
||||
}
|
||||
|
||||
var map_LabelSelectorRequirement = map[string]string{
|
||||
"": "A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.",
|
||||
"key": "key is the label key that the selector applies to.",
|
||||
"operator": "operator represents a key's relationship to a set of values. Valid operators ard In, NotIn, Exists and DoesNotExist.",
|
||||
"values": "values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.",
|
||||
}
|
||||
|
||||
func (LabelSelectorRequirement) SwaggerDoc() map[string]string {
|
||||
return map_LabelSelectorRequirement
|
||||
}
|
||||
|
||||
var map_ListMeta = map[string]string{
|
||||
"": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.",
|
||||
"selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.",
|
||||
"resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency",
|
||||
}
|
||||
|
||||
func (ListMeta) SwaggerDoc() map[string]string {
|
||||
return map_ListMeta
|
||||
}
|
||||
|
||||
var map_Patch = map[string]string{
|
||||
"": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.",
|
||||
}
|
||||
|
||||
func (Patch) SwaggerDoc() map[string]string {
|
||||
return map_Patch
|
||||
}
|
||||
|
||||
var map_RootPaths = map[string]string{
|
||||
"": "RootPaths lists the paths available at root. For example: \"/healthz\", \"/apis\".",
|
||||
"paths": "paths are the paths available at root.",
|
||||
}
|
||||
|
||||
func (RootPaths) SwaggerDoc() map[string]string {
|
||||
return map_RootPaths
|
||||
}
|
||||
|
||||
var map_ServerAddressByClientCIDR = map[string]string{
|
||||
"": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"clientCIDR": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"serverAddress": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
}
|
||||
|
||||
func (ServerAddressByClientCIDR) SwaggerDoc() map[string]string {
|
||||
return map_ServerAddressByClientCIDR
|
||||
}
|
||||
|
||||
var map_Status = map[string]string{
|
||||
"": "Status is a return value for calls that don't return other objects.",
|
||||
"metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
|
||||
"status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status",
|
||||
"message": "A human-readable description of the status of this operation.",
|
||||
"reason": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.",
|
||||
"details": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.",
|
||||
"code": "Suggested HTTP return code for this status, 0 if not set.",
|
||||
}
|
||||
|
||||
func (Status) SwaggerDoc() map[string]string {
|
||||
return map_Status
|
||||
}
|
||||
|
||||
var map_StatusCause = map[string]string{
|
||||
"": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.",
|
||||
"reason": "A machine-readable description of the cause of the error. If this value is empty there is no information available.",
|
||||
"message": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.",
|
||||
"field": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"",
|
||||
}
|
||||
|
||||
func (StatusCause) SwaggerDoc() map[string]string {
|
||||
return map_StatusCause
|
||||
}
|
||||
|
||||
var map_StatusDetails = map[string]string{
|
||||
"": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.",
|
||||
"name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).",
|
||||
"group": "The group attribute of the resource associated with the status StatusReason.",
|
||||
"kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
|
||||
"causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.",
|
||||
"retryAfterSeconds": "If specified, the time in seconds before the operation should be retried.",
|
||||
}
|
||||
|
||||
func (StatusDetails) SwaggerDoc() map[string]string {
|
||||
return map_StatusDetails
|
||||
}
|
||||
|
||||
var map_TypeMeta = map[string]string{
|
||||
"": "TypeMeta describes an individual object in an API response or request with strings representing the type of the object and its API schema version. Structures that are versioned or persisted should inline TypeMeta.",
|
||||
"kind": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
|
||||
"apiVersion": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources",
|
||||
}
|
||||
|
||||
func (TypeMeta) SwaggerDoc() map[string]string {
|
||||
return map_TypeMeta
|
||||
}
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS END HERE
|
||||
74
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/validation/validation.go
generated
vendored
74
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/validation/validation.go
generated
vendored
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func ValidateLabelSelector(ps *unversioned.LabelSelector, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if ps == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, ValidateLabels(ps.MatchLabels, fldPath.Child("matchLabels"))...)
|
||||
for i, expr := range ps.MatchExpressions {
|
||||
allErrs = append(allErrs, ValidateLabelSelectorRequirement(expr, fldPath.Child("matchExpressions").Index(i))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateLabelSelectorRequirement(sr unversioned.LabelSelectorRequirement, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
switch sr.Operator {
|
||||
case unversioned.LabelSelectorOpIn, unversioned.LabelSelectorOpNotIn:
|
||||
if len(sr.Values) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("values"), "must be specified when `operator` is 'In' or 'NotIn'"))
|
||||
}
|
||||
case unversioned.LabelSelectorOpExists, unversioned.LabelSelectorOpDoesNotExist:
|
||||
if len(sr.Values) > 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("values"), "may not be specified when `operator` is 'Exists' or 'DoesNotExist'"))
|
||||
}
|
||||
default:
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("operator"), sr.Operator, "not a valid selector operator"))
|
||||
}
|
||||
allErrs = append(allErrs, ValidateLabelName(sr.Key, fldPath.Child("key"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateLabelName validates that the label name is correctly defined.
|
||||
func ValidateLabelName(labelName string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, msg := range validation.IsQualifiedName(labelName) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, labelName, msg))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateLabels validates that a set of labels are correctly defined.
|
||||
func ValidateLabels(labels map[string]string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for k, v := range labels {
|
||||
allErrs = append(allErrs, ValidateLabelName(k, fldPath)...)
|
||||
for _, msg := range validation.IsValidLabelValue(v) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, v, msg))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
30
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/well_known_labels.go
generated
vendored
30
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/well_known_labels.go
generated
vendored
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
const (
|
||||
// If you add a new topology domain here, also consider adding it to the set of default values
|
||||
// for the scheduler's --failure-domain command-line argument.
|
||||
LabelHostname = "kubernetes.io/hostname"
|
||||
LabelZoneFailureDomain = "failure-domain.beta.kubernetes.io/zone"
|
||||
LabelZoneRegion = "failure-domain.beta.kubernetes.io/region"
|
||||
|
||||
LabelInstanceType = "beta.kubernetes.io/instance-type"
|
||||
|
||||
LabelOS = "beta.kubernetes.io/os"
|
||||
LabelArch = "beta.kubernetes.io/arch"
|
||||
)
|
||||
390
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/zz_generated.deepcopy.go
generated
vendored
390
vendor/k8s.io/client-go/1.4/pkg/api/unversioned/zz_generated.deepcopy.go
generated
vendored
|
|
@ -1,390 +0,0 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
conversion "k8s.io/client-go/1.4/pkg/conversion"
|
||||
time "time"
|
||||
)
|
||||
|
||||
func DeepCopy_unversioned_APIGroup(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIGroup)
|
||||
out := out.(*APIGroup)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.Name = in.Name
|
||||
if in.Versions != nil {
|
||||
in, out := &in.Versions, &out.Versions
|
||||
*out = make([]GroupVersionForDiscovery, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.Versions = nil
|
||||
}
|
||||
out.PreferredVersion = in.PreferredVersion
|
||||
if in.ServerAddressByClientCIDRs != nil {
|
||||
in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
|
||||
*out = make([]ServerAddressByClientCIDR, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.ServerAddressByClientCIDRs = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIGroupList(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIGroupList)
|
||||
out := out.(*APIGroupList)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Groups != nil {
|
||||
in, out := &in.Groups, &out.Groups
|
||||
*out = make([]APIGroup, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_unversioned_APIGroup(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Groups = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIResource(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIResource)
|
||||
out := out.(*APIResource)
|
||||
out.Name = in.Name
|
||||
out.Namespaced = in.Namespaced
|
||||
out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIResourceList(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIResourceList)
|
||||
out := out.(*APIResourceList)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.GroupVersion = in.GroupVersion
|
||||
if in.APIResources != nil {
|
||||
in, out := &in.APIResources, &out.APIResources
|
||||
*out = make([]APIResource, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.APIResources = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIVersions(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIVersions)
|
||||
out := out.(*APIVersions)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Versions != nil {
|
||||
in, out := &in.Versions, &out.Versions
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
} else {
|
||||
out.Versions = nil
|
||||
}
|
||||
if in.ServerAddressByClientCIDRs != nil {
|
||||
in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
|
||||
*out = make([]ServerAddressByClientCIDR, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.ServerAddressByClientCIDRs = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Duration(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Duration)
|
||||
out := out.(*Duration)
|
||||
out.Duration = in.Duration
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_ExportOptions(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ExportOptions)
|
||||
out := out.(*ExportOptions)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.Export = in.Export
|
||||
out.Exact = in.Exact
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupKind(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupKind)
|
||||
out := out.(*GroupKind)
|
||||
out.Group = in.Group
|
||||
out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupResource(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupResource)
|
||||
out := out.(*GroupResource)
|
||||
out.Group = in.Group
|
||||
out.Resource = in.Resource
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersion(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersion)
|
||||
out := out.(*GroupVersion)
|
||||
out.Group = in.Group
|
||||
out.Version = in.Version
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersionForDiscovery(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersionForDiscovery)
|
||||
out := out.(*GroupVersionForDiscovery)
|
||||
out.GroupVersion = in.GroupVersion
|
||||
out.Version = in.Version
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersionKind(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersionKind)
|
||||
out := out.(*GroupVersionKind)
|
||||
out.Group = in.Group
|
||||
out.Version = in.Version
|
||||
out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersionResource(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersionResource)
|
||||
out := out.(*GroupVersionResource)
|
||||
out.Group = in.Group
|
||||
out.Version = in.Version
|
||||
out.Resource = in.Resource
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_LabelSelector(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*LabelSelector)
|
||||
out := out.(*LabelSelector)
|
||||
if in.MatchLabels != nil {
|
||||
in, out := &in.MatchLabels, &out.MatchLabels
|
||||
*out = make(map[string]string)
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
} else {
|
||||
out.MatchLabels = nil
|
||||
}
|
||||
if in.MatchExpressions != nil {
|
||||
in, out := &in.MatchExpressions, &out.MatchExpressions
|
||||
*out = make([]LabelSelectorRequirement, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_unversioned_LabelSelectorRequirement(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.MatchExpressions = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_LabelSelectorRequirement(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*LabelSelectorRequirement)
|
||||
out := out.(*LabelSelectorRequirement)
|
||||
out.Key = in.Key
|
||||
out.Operator = in.Operator
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
} else {
|
||||
out.Values = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_ListMeta(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ListMeta)
|
||||
out := out.(*ListMeta)
|
||||
out.SelfLink = in.SelfLink
|
||||
out.ResourceVersion = in.ResourceVersion
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Patch(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Patch)
|
||||
out := out.(*Patch)
|
||||
_ = in
|
||||
_ = out
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_RootPaths(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*RootPaths)
|
||||
out := out.(*RootPaths)
|
||||
if in.Paths != nil {
|
||||
in, out := &in.Paths, &out.Paths
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
} else {
|
||||
out.Paths = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_ServerAddressByClientCIDR(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ServerAddressByClientCIDR)
|
||||
out := out.(*ServerAddressByClientCIDR)
|
||||
out.ClientCIDR = in.ClientCIDR
|
||||
out.ServerAddress = in.ServerAddress
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Status(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Status)
|
||||
out := out.(*Status)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Status = in.Status
|
||||
out.Message = in.Message
|
||||
out.Reason = in.Reason
|
||||
if in.Details != nil {
|
||||
in, out := &in.Details, &out.Details
|
||||
*out = new(StatusDetails)
|
||||
if err := DeepCopy_unversioned_StatusDetails(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Details = nil
|
||||
}
|
||||
out.Code = in.Code
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_StatusCause(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatusCause)
|
||||
out := out.(*StatusCause)
|
||||
out.Type = in.Type
|
||||
out.Message = in.Message
|
||||
out.Field = in.Field
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_StatusDetails(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatusDetails)
|
||||
out := out.(*StatusDetails)
|
||||
out.Name = in.Name
|
||||
out.Group = in.Group
|
||||
out.Kind = in.Kind
|
||||
if in.Causes != nil {
|
||||
in, out := &in.Causes, &out.Causes
|
||||
*out = make([]StatusCause, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.Causes = nil
|
||||
}
|
||||
out.RetryAfterSeconds = in.RetryAfterSeconds
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Time(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Time)
|
||||
out := out.(*Time)
|
||||
if newVal, err := c.DeepCopy(&in.Time); err != nil {
|
||||
return err
|
||||
} else {
|
||||
out.Time = *newVal.(*time.Time)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Timestamp(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Timestamp)
|
||||
out := out.(*Timestamp)
|
||||
out.Seconds = in.Seconds
|
||||
out.Nanos = in.Nanos
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_TypeMeta(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*TypeMeta)
|
||||
out := out.(*TypeMeta)
|
||||
out.Kind = in.Kind
|
||||
out.APIVersion = in.APIVersion
|
||||
return nil
|
||||
}
|
||||
}
|
||||
48
vendor/k8s.io/client-go/1.4/pkg/api/util/group_version.go
generated
vendored
48
vendor/k8s.io/client-go/1.4/pkg/api/util/group_version.go
generated
vendored
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO: This GetVersion/GetGroup arrangement is temporary and will be replaced
|
||||
// with a GroupAndVersion type.
|
||||
package util
|
||||
|
||||
import "strings"
|
||||
|
||||
func GetVersion(groupVersion string) string {
|
||||
s := strings.Split(groupVersion, "/")
|
||||
if len(s) != 2 {
|
||||
// e.g. return "v1" for groupVersion="v1"
|
||||
return s[len(s)-1]
|
||||
}
|
||||
return s[1]
|
||||
}
|
||||
|
||||
func GetGroup(groupVersion string) string {
|
||||
s := strings.Split(groupVersion, "/")
|
||||
if len(s) == 1 {
|
||||
// e.g. return "" for groupVersion="v1"
|
||||
return ""
|
||||
}
|
||||
return s[0]
|
||||
}
|
||||
|
||||
// GetGroupVersion returns the "group/version". It returns "version" is if group
|
||||
// is empty. It returns "group/" if version is empty.
|
||||
func GetGroupVersion(group, version string) string {
|
||||
if len(group) == 0 {
|
||||
return version
|
||||
}
|
||||
return group + "/" + version
|
||||
}
|
||||
797
vendor/k8s.io/client-go/1.4/pkg/api/v1/conversion.go
generated
vendored
797
vendor/k8s.io/client-go/1.4/pkg/api/v1/conversion.go
generated
vendored
|
|
@ -1,797 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/apis/extensions"
|
||||
"k8s.io/client-go/1.4/pkg/conversion"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation/field"
|
||||
"k8s.io/client-go/1.4/pkg/watch/versioned"
|
||||
)
|
||||
|
||||
const (
|
||||
// Annotation key used to identify mirror pods.
|
||||
mirrorAnnotationKey = "kubernetes.io/config.mirror"
|
||||
|
||||
// Value used to identify mirror pods from pre-v1.1 kubelet.
|
||||
mirrorAnnotationValue_1_0 = "mirror"
|
||||
|
||||
// annotation key prefix used to identify non-convertible json paths.
|
||||
NonConvertibleAnnotationPrefix = "kubernetes.io/non-convertible"
|
||||
)
|
||||
|
||||
// This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are
|
||||
// converted the most in the cluster.
|
||||
// TODO: generate one of these for every external API group - this is to prove the impact
|
||||
func addFastPathConversionFuncs(scheme *runtime.Scheme) error {
|
||||
scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) {
|
||||
switch a := objA.(type) {
|
||||
case *Pod:
|
||||
switch b := objB.(type) {
|
||||
case *api.Pod:
|
||||
return true, Convert_v1_Pod_To_api_Pod(a, b, s)
|
||||
}
|
||||
case *api.Pod:
|
||||
switch b := objB.(type) {
|
||||
case *Pod:
|
||||
return true, Convert_api_Pod_To_v1_Pod(a, b, s)
|
||||
}
|
||||
|
||||
case *Event:
|
||||
switch b := objB.(type) {
|
||||
case *api.Event:
|
||||
return true, Convert_v1_Event_To_api_Event(a, b, s)
|
||||
}
|
||||
case *api.Event:
|
||||
switch b := objB.(type) {
|
||||
case *Event:
|
||||
return true, Convert_api_Event_To_v1_Event(a, b, s)
|
||||
}
|
||||
|
||||
case *ReplicationController:
|
||||
switch b := objB.(type) {
|
||||
case *api.ReplicationController:
|
||||
return true, Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s)
|
||||
}
|
||||
case *api.ReplicationController:
|
||||
switch b := objB.(type) {
|
||||
case *ReplicationController:
|
||||
return true, Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s)
|
||||
}
|
||||
|
||||
case *Node:
|
||||
switch b := objB.(type) {
|
||||
case *api.Node:
|
||||
return true, Convert_v1_Node_To_api_Node(a, b, s)
|
||||
}
|
||||
case *api.Node:
|
||||
switch b := objB.(type) {
|
||||
case *Node:
|
||||
return true, Convert_api_Node_To_v1_Node(a, b, s)
|
||||
}
|
||||
|
||||
case *Namespace:
|
||||
switch b := objB.(type) {
|
||||
case *api.Namespace:
|
||||
return true, Convert_v1_Namespace_To_api_Namespace(a, b, s)
|
||||
}
|
||||
case *api.Namespace:
|
||||
switch b := objB.(type) {
|
||||
case *Namespace:
|
||||
return true, Convert_api_Namespace_To_v1_Namespace(a, b, s)
|
||||
}
|
||||
|
||||
case *Service:
|
||||
switch b := objB.(type) {
|
||||
case *api.Service:
|
||||
return true, Convert_v1_Service_To_api_Service(a, b, s)
|
||||
}
|
||||
case *api.Service:
|
||||
switch b := objB.(type) {
|
||||
case *Service:
|
||||
return true, Convert_api_Service_To_v1_Service(a, b, s)
|
||||
}
|
||||
|
||||
case *Endpoints:
|
||||
switch b := objB.(type) {
|
||||
case *api.Endpoints:
|
||||
return true, Convert_v1_Endpoints_To_api_Endpoints(a, b, s)
|
||||
}
|
||||
case *api.Endpoints:
|
||||
switch b := objB.(type) {
|
||||
case *Endpoints:
|
||||
return true, Convert_api_Endpoints_To_v1_Endpoints(a, b, s)
|
||||
}
|
||||
|
||||
case *versioned.Event:
|
||||
switch b := objB.(type) {
|
||||
case *versioned.InternalEvent:
|
||||
return true, versioned.Convert_versioned_Event_to_versioned_InternalEvent(a, b, s)
|
||||
}
|
||||
case *versioned.InternalEvent:
|
||||
switch b := objB.(type) {
|
||||
case *versioned.Event:
|
||||
return true, versioned.Convert_versioned_InternalEvent_to_versioned_Event(a, b, s)
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
// Add non-generated conversion functions
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_api_Pod_To_v1_Pod,
|
||||
Convert_api_PodSpec_To_v1_PodSpec,
|
||||
Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec,
|
||||
Convert_api_ServiceSpec_To_v1_ServiceSpec,
|
||||
Convert_v1_Pod_To_api_Pod,
|
||||
Convert_v1_PodSpec_To_api_PodSpec,
|
||||
Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec,
|
||||
Convert_v1_Secret_To_api_Secret,
|
||||
Convert_v1_ServiceSpec_To_api_ServiceSpec,
|
||||
Convert_v1_ResourceList_To_api_ResourceList,
|
||||
Convert_v1_ReplicationController_to_extensions_ReplicaSet,
|
||||
Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec,
|
||||
Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus,
|
||||
Convert_extensions_ReplicaSet_to_v1_ReplicationController,
|
||||
Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec,
|
||||
Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Add field label conversions for kinds having selectable nothing but ObjectMeta fields.
|
||||
for _, k := range []string{
|
||||
"Endpoints",
|
||||
"ResourceQuota",
|
||||
"PersistentVolumeClaim",
|
||||
"Service",
|
||||
"ServiceAccount",
|
||||
"ConfigMap",
|
||||
} {
|
||||
kind := k // don't close over range variables
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", kind,
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.namespace",
|
||||
"metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label %q not supported for %q", label, kind)
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Add field conversion funcs.
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "Pod",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.annotations",
|
||||
"metadata.labels",
|
||||
"metadata.name",
|
||||
"metadata.namespace",
|
||||
"spec.nodeName",
|
||||
"spec.restartPolicy",
|
||||
"spec.serviceAccountName",
|
||||
"status.phase",
|
||||
"status.podIP":
|
||||
return label, value, nil
|
||||
// This is for backwards compatibility with old v1 clients which send spec.host
|
||||
case "spec.host":
|
||||
return "spec.nodeName", value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "Node",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.name":
|
||||
return label, value, nil
|
||||
case "spec.unschedulable":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "ReplicationController",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.name",
|
||||
"metadata.namespace",
|
||||
"status.replicas":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "PersistentVolume",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AddFieldLabelConversionsForEvent(scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AddFieldLabelConversionsForNamespace(scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := AddFieldLabelConversionsForSecret(scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicationController_to_extensions_ReplicaSet(in *ReplicationController, out *extensions.ReplicaSet, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*ReplicationController))(in)
|
||||
}
|
||||
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_ObjectMeta_To_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicationControllerSpec_to_extensions_ReplicaSetSpec(in *ReplicationControllerSpec, out *extensions.ReplicaSetSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*ReplicationControllerSpec))(in)
|
||||
}
|
||||
out.Replicas = *in.Replicas
|
||||
if in.Selector != nil {
|
||||
api.Convert_map_to_unversioned_LabelSelector(&in.Selector, out.Selector, s)
|
||||
}
|
||||
if in.Template != nil {
|
||||
if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, &out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicationControllerStatus_to_extensions_ReplicaSetStatus(in *ReplicationControllerStatus, out *extensions.ReplicaSetStatus, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*ReplicationControllerStatus))(in)
|
||||
}
|
||||
out.Replicas = in.Replicas
|
||||
out.FullyLabeledReplicas = in.FullyLabeledReplicas
|
||||
out.ObservedGeneration = in.ObservedGeneration
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_ReplicaSet_to_v1_ReplicationController(in *extensions.ReplicaSet, out *ReplicationController, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.ReplicaSet))(in)
|
||||
}
|
||||
if err := api.Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(&in.TypeMeta, &out.TypeMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_api_ObjectMeta_To_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
fieldErr, ok := err.(*field.Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
if out.Annotations == nil {
|
||||
out.Annotations = make(map[string]string)
|
||||
}
|
||||
out.Annotations[NonConvertibleAnnotationPrefix+"/"+fieldErr.Field] = reflect.ValueOf(fieldErr.BadValue).String()
|
||||
}
|
||||
if err := Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_extensions_ReplicaSetSpec_to_v1_ReplicationControllerSpec(in *extensions.ReplicaSetSpec, out *ReplicationControllerSpec, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.ReplicaSetSpec))(in)
|
||||
}
|
||||
out.Replicas = new(int32)
|
||||
*out.Replicas = in.Replicas
|
||||
var invalidErr error
|
||||
if in.Selector != nil {
|
||||
invalidErr = api.Convert_unversioned_LabelSelector_to_map(in.Selector, &out.Selector, s)
|
||||
}
|
||||
out.Template = new(PodTemplateSpec)
|
||||
if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(&in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return invalidErr
|
||||
}
|
||||
|
||||
func Convert_extensions_ReplicaSetStatus_to_v1_ReplicationControllerStatus(in *extensions.ReplicaSetStatus, out *ReplicationControllerStatus, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*extensions.ReplicaSetStatus))(in)
|
||||
}
|
||||
out.Replicas = in.Replicas
|
||||
out.FullyLabeledReplicas = in.FullyLabeledReplicas
|
||||
out.ObservedGeneration = in.ObservedGeneration
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_ReplicationControllerSpec_To_v1_ReplicationControllerSpec(in *api.ReplicationControllerSpec, out *ReplicationControllerSpec, s conversion.Scope) error {
|
||||
out.Replicas = &in.Replicas
|
||||
out.Selector = in.Selector
|
||||
if in.Template != nil {
|
||||
out.Template = new(PodTemplateSpec)
|
||||
if err := Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ReplicationControllerSpec_To_api_ReplicationControllerSpec(in *ReplicationControllerSpec, out *api.ReplicationControllerSpec, s conversion.Scope) error {
|
||||
out.Replicas = *in.Replicas
|
||||
out.Selector = in.Selector
|
||||
if in.Template != nil {
|
||||
out.Template = new(api.PodTemplateSpec)
|
||||
if err := Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in.Template, out.Template, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Template = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_PodStatusResult_To_v1_PodStatusResult(in *api.PodStatusResult, out *PodStatusResult, s conversion.Scope) error {
|
||||
if err := autoConvert_api_PodStatusResult_To_v1_PodStatusResult(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if old := out.Annotations; old != nil {
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
}
|
||||
if len(out.Status.InitContainerStatuses) > 0 {
|
||||
if out.Annotations == nil {
|
||||
out.Annotations = make(map[string]string)
|
||||
}
|
||||
value, err := json.Marshal(out.Status.InitContainerStatuses)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value)
|
||||
} else {
|
||||
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_PodStatusResult_To_api_PodStatusResult(in *PodStatusResult, out *api.PodStatusResult, s conversion.Scope) error {
|
||||
// TODO: sometime after we move init container to stable, remove these conversions
|
||||
if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok {
|
||||
var values []ContainerStatus
|
||||
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
||||
return err
|
||||
}
|
||||
// Conversion from external to internal version exists more to
|
||||
// satisfy the needs of the decoder than it does to be a general
|
||||
// purpose tool. And Decode always creates an intermediate object
|
||||
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
||||
// taking responsibility to ensure mutation of in is not exposed
|
||||
// back to the caller.
|
||||
in.Status.InitContainerStatuses = values
|
||||
}
|
||||
|
||||
if err := autoConvert_v1_PodStatusResult_To_api_PodStatusResult(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(out.Annotations) > 0 {
|
||||
old := out.Annotations
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in *api.PodTemplateSpec, out *PodTemplateSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_api_PodTemplateSpec_To_v1_PodTemplateSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: sometime after we move init container to stable, remove these conversions.
|
||||
if old := out.Annotations; old != nil {
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
}
|
||||
if len(out.Spec.InitContainers) > 0 {
|
||||
if out.Annotations == nil {
|
||||
out.Annotations = make(map[string]string)
|
||||
}
|
||||
value, err := json.Marshal(out.Spec.InitContainers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.Annotations[PodInitContainersAnnotationKey] = string(value)
|
||||
out.Annotations[PodInitContainersBetaAnnotationKey] = string(value)
|
||||
} else {
|
||||
delete(out.Annotations, PodInitContainersAnnotationKey)
|
||||
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out *api.PodTemplateSpec, s conversion.Scope) error {
|
||||
// TODO: sometime after we move init container to stable, remove these conversions
|
||||
// If there is a beta annotation, copy to alpha key.
|
||||
// See commit log for PR #31026 for why we do this.
|
||||
if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta {
|
||||
in.Annotations[PodInitContainersAnnotationKey] = valueBeta
|
||||
}
|
||||
// Move the annotation to the internal repr. field
|
||||
if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok {
|
||||
var values []Container
|
||||
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
||||
return err
|
||||
}
|
||||
// Conversion from external to internal version exists more to
|
||||
// satisfy the needs of the decoder than it does to be a general
|
||||
// purpose tool. And Decode always creates an intermediate object
|
||||
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
||||
// taking responsibility to ensure mutation of in is not exposed
|
||||
// back to the caller.
|
||||
in.Spec.InitContainers = values
|
||||
}
|
||||
|
||||
if err := autoConvert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(out.Annotations) > 0 {
|
||||
old := out.Annotations
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
delete(out.Annotations, PodInitContainersAnnotationKey)
|
||||
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// The following two PodSpec conversions are done here to support ServiceAccount
|
||||
// as an alias for ServiceAccountName.
|
||||
func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_api_PodSpec_To_v1_PodSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// DeprecatedServiceAccount is an alias for ServiceAccountName.
|
||||
out.DeprecatedServiceAccount = in.ServiceAccountName
|
||||
|
||||
if in.SecurityContext != nil {
|
||||
// the host namespace fields have to be handled here for backward compatibility
|
||||
// with v1.0.0
|
||||
out.HostPID = in.SecurityContext.HostPID
|
||||
out.HostNetwork = in.SecurityContext.HostNetwork
|
||||
out.HostIPC = in.SecurityContext.HostIPC
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_v1_PodSpec_To_api_PodSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We support DeprecatedServiceAccount as an alias for ServiceAccountName.
|
||||
// If both are specified, ServiceAccountName (the new field) wins.
|
||||
if in.ServiceAccountName == "" {
|
||||
out.ServiceAccountName = in.DeprecatedServiceAccount
|
||||
}
|
||||
|
||||
// the host namespace fields have to be handled specially for backward compatibility
|
||||
// with v1.0.0
|
||||
if out.SecurityContext == nil {
|
||||
out.SecurityContext = new(api.PodSecurityContext)
|
||||
}
|
||||
out.SecurityContext.HostNetwork = in.HostNetwork
|
||||
out.SecurityContext.HostPID = in.HostPID
|
||||
out.SecurityContext.HostIPC = in.HostIPC
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_Pod_To_v1_Pod(in *api.Pod, out *Pod, s conversion.Scope) error {
|
||||
if err := autoConvert_api_Pod_To_v1_Pod(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: sometime after we move init container to stable, remove these conversions
|
||||
if len(out.Spec.InitContainers) > 0 || len(out.Status.InitContainerStatuses) > 0 {
|
||||
old := out.Annotations
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
delete(out.Annotations, PodInitContainersAnnotationKey)
|
||||
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
|
||||
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
|
||||
}
|
||||
if len(out.Spec.InitContainers) > 0 {
|
||||
value, err := json.Marshal(out.Spec.InitContainers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.Annotations[PodInitContainersAnnotationKey] = string(value)
|
||||
out.Annotations[PodInitContainersBetaAnnotationKey] = string(value)
|
||||
}
|
||||
if len(out.Status.InitContainerStatuses) > 0 {
|
||||
value, err := json.Marshal(out.Status.InitContainerStatuses)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out.Annotations[PodInitContainerStatusesAnnotationKey] = string(value)
|
||||
}
|
||||
|
||||
// We need to reset certain fields for mirror pods from pre-v1.1 kubelet
|
||||
// (#15960).
|
||||
// TODO: Remove this code after we drop support for v1.0 kubelets.
|
||||
if value, ok := in.Annotations[mirrorAnnotationKey]; ok && value == mirrorAnnotationValue_1_0 {
|
||||
// Reset the TerminationGracePeriodSeconds.
|
||||
out.Spec.TerminationGracePeriodSeconds = nil
|
||||
// Reset the resource requests.
|
||||
for i := range out.Spec.Containers {
|
||||
out.Spec.Containers[i].Resources.Requests = nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_Pod_To_api_Pod(in *Pod, out *api.Pod, s conversion.Scope) error {
|
||||
// If there is a beta annotation, copy to alpha key.
|
||||
// See commit log for PR #31026 for why we do this.
|
||||
if valueBeta, okBeta := in.Annotations[PodInitContainersBetaAnnotationKey]; okBeta {
|
||||
in.Annotations[PodInitContainersAnnotationKey] = valueBeta
|
||||
}
|
||||
// TODO: sometime after we move init container to stable, remove these conversions
|
||||
// Move the annotation to the internal repr. field
|
||||
if value, ok := in.Annotations[PodInitContainersAnnotationKey]; ok {
|
||||
var values []Container
|
||||
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
||||
return err
|
||||
}
|
||||
// Conversion from external to internal version exists more to
|
||||
// satisfy the needs of the decoder than it does to be a general
|
||||
// purpose tool. And Decode always creates an intermediate object
|
||||
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
||||
// taking responsibility to ensure mutation of in is not exposed
|
||||
// back to the caller.
|
||||
in.Spec.InitContainers = values
|
||||
}
|
||||
if value, ok := in.Annotations[PodInitContainerStatusesAnnotationKey]; ok {
|
||||
var values []ContainerStatus
|
||||
if err := json.Unmarshal([]byte(value), &values); err != nil {
|
||||
return err
|
||||
}
|
||||
// Conversion from external to internal version exists more to
|
||||
// satisfy the needs of the decoder than it does to be a general
|
||||
// purpose tool. And Decode always creates an intermediate object
|
||||
// to decode to. Thus the caller of UnsafeConvertToVersion is
|
||||
// taking responsibility to ensure mutation of in is not exposed
|
||||
// back to the caller.
|
||||
in.Status.InitContainerStatuses = values
|
||||
}
|
||||
|
||||
if err := autoConvert_v1_Pod_To_api_Pod(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(out.Annotations) > 0 {
|
||||
old := out.Annotations
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
delete(out.Annotations, PodInitContainersAnnotationKey)
|
||||
delete(out.Annotations, PodInitContainersBetaAnnotationKey)
|
||||
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *ServiceSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_api_ServiceSpec_To_v1_ServiceSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
// Publish both externalIPs and deprecatedPublicIPs fields in v1.
|
||||
out.DeprecatedPublicIPs = in.ExternalIPs
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_Secret_To_api_Secret(in *Secret, out *api.Secret, s conversion.Scope) error {
|
||||
if err := autoConvert_v1_Secret_To_api_Secret(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// StringData overwrites Data
|
||||
if len(in.StringData) > 0 {
|
||||
if out.Data == nil {
|
||||
out.Data = map[string][]byte{}
|
||||
}
|
||||
for k, v := range in.StringData {
|
||||
out.Data[k] = []byte(v)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.ServiceSpec, s conversion.Scope) error {
|
||||
if err := autoConvert_v1_ServiceSpec_To_api_ServiceSpec(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
// Prefer the legacy deprecatedPublicIPs field, if provided.
|
||||
if len(in.DeprecatedPublicIPs) > 0 {
|
||||
out.ExternalIPs = in.DeprecatedPublicIPs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error {
|
||||
out.SupplementalGroups = in.SupplementalGroups
|
||||
if in.SELinuxOptions != nil {
|
||||
out.SELinuxOptions = new(SELinuxOptions)
|
||||
if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SELinuxOptions = nil
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.FSGroup = in.FSGroup
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
|
||||
out.SupplementalGroups = in.SupplementalGroups
|
||||
if in.SELinuxOptions != nil {
|
||||
out.SELinuxOptions = new(api.SELinuxOptions)
|
||||
if err := Convert_v1_SELinuxOptions_To_api_SELinuxOptions(in.SELinuxOptions, out.SELinuxOptions, s); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SELinuxOptions = nil
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.FSGroup = in.FSGroup
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ResourceList_To_api_ResourceList(in *ResourceList, out *api.ResourceList, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if *out == nil {
|
||||
*out = make(api.ResourceList, len(*in))
|
||||
}
|
||||
for key, val := range *in {
|
||||
// TODO(#18538): We round up resource values to milli scale to maintain API compatibility.
|
||||
// In the future, we should instead reject values that need rounding.
|
||||
const milliScale = -3
|
||||
val.RoundUp(milliScale)
|
||||
|
||||
(*out)[api.ResourceName(key)] = val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddFieldLabelConversionsForEvent(scheme *runtime.Scheme) error {
|
||||
return scheme.AddFieldLabelConversionFunc("v1", "Event",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "involvedObject.kind",
|
||||
"involvedObject.namespace",
|
||||
"involvedObject.name",
|
||||
"involvedObject.uid",
|
||||
"involvedObject.apiVersion",
|
||||
"involvedObject.resourceVersion",
|
||||
"involvedObject.fieldPath",
|
||||
"reason",
|
||||
"source",
|
||||
"type",
|
||||
"metadata.namespace",
|
||||
"metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func AddFieldLabelConversionsForNamespace(scheme *runtime.Scheme) error {
|
||||
return scheme.AddFieldLabelConversionFunc("v1", "Namespace",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "status.phase",
|
||||
"metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error {
|
||||
return scheme.AddFieldLabelConversionFunc("v1", "Secret",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "type",
|
||||
"metadata.namespace",
|
||||
"metadata.name":
|
||||
return label, value, nil
|
||||
default:
|
||||
return "", "", fmt.Errorf("field label not supported: %s", label)
|
||||
}
|
||||
})
|
||||
}
|
||||
336
vendor/k8s.io/client-go/1.4/pkg/api/v1/defaults.go
generated
vendored
336
vendor/k8s.io/client-go/1.4/pkg/api/v1/defaults.go
generated
vendored
|
|
@ -1,336 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
"k8s.io/client-go/1.4/pkg/util"
|
||||
"k8s.io/client-go/1.4/pkg/util/intstr"
|
||||
"k8s.io/client-go/1.4/pkg/util/parsers"
|
||||
)
|
||||
|
||||
func addDefaultingFuncs(scheme *runtime.Scheme) error {
|
||||
return scheme.AddDefaultingFuncs(
|
||||
SetDefaults_PodExecOptions,
|
||||
SetDefaults_PodAttachOptions,
|
||||
SetDefaults_ReplicationController,
|
||||
SetDefaults_Volume,
|
||||
SetDefaults_ContainerPort,
|
||||
SetDefaults_Container,
|
||||
SetDefaults_ServiceSpec,
|
||||
SetDefaults_Pod,
|
||||
SetDefaults_PodSpec,
|
||||
SetDefaults_Probe,
|
||||
SetDefaults_SecretVolumeSource,
|
||||
SetDefaults_ConfigMapVolumeSource,
|
||||
SetDefaults_DownwardAPIVolumeSource,
|
||||
SetDefaults_Secret,
|
||||
SetDefaults_PersistentVolume,
|
||||
SetDefaults_PersistentVolumeClaim,
|
||||
SetDefaults_ISCSIVolumeSource,
|
||||
SetDefaults_Endpoints,
|
||||
SetDefaults_HTTPGetAction,
|
||||
SetDefaults_NamespaceStatus,
|
||||
SetDefaults_Node,
|
||||
SetDefaults_NodeStatus,
|
||||
SetDefaults_ObjectFieldSelector,
|
||||
SetDefaults_LimitRangeItem,
|
||||
SetDefaults_ConfigMap,
|
||||
SetDefaults_RBDVolumeSource,
|
||||
)
|
||||
}
|
||||
|
||||
func SetDefaults_PodExecOptions(obj *PodExecOptions) {
|
||||
obj.Stdout = true
|
||||
obj.Stderr = true
|
||||
}
|
||||
func SetDefaults_PodAttachOptions(obj *PodAttachOptions) {
|
||||
obj.Stdout = true
|
||||
obj.Stderr = true
|
||||
}
|
||||
func SetDefaults_ReplicationController(obj *ReplicationController) {
|
||||
var labels map[string]string
|
||||
if obj.Spec.Template != nil {
|
||||
labels = obj.Spec.Template.Labels
|
||||
}
|
||||
// TODO: support templates defined elsewhere when we support them in the API
|
||||
if labels != nil {
|
||||
if len(obj.Spec.Selector) == 0 {
|
||||
obj.Spec.Selector = labels
|
||||
}
|
||||
if len(obj.Labels) == 0 {
|
||||
obj.Labels = labels
|
||||
}
|
||||
}
|
||||
if obj.Spec.Replicas == nil {
|
||||
obj.Spec.Replicas = new(int32)
|
||||
*obj.Spec.Replicas = 1
|
||||
}
|
||||
}
|
||||
func SetDefaults_Volume(obj *Volume) {
|
||||
if util.AllPtrFieldsNil(&obj.VolumeSource) {
|
||||
obj.VolumeSource = VolumeSource{
|
||||
EmptyDir: &EmptyDirVolumeSource{},
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_ContainerPort(obj *ContainerPort) {
|
||||
if obj.Protocol == "" {
|
||||
obj.Protocol = ProtocolTCP
|
||||
}
|
||||
}
|
||||
func SetDefaults_Container(obj *Container) {
|
||||
if obj.ImagePullPolicy == "" {
|
||||
// Ignore error and assume it has been validated elsewhere
|
||||
_, tag, _, _ := parsers.ParseImageName(obj.Image)
|
||||
|
||||
// Check image tag
|
||||
|
||||
if tag == "latest" {
|
||||
obj.ImagePullPolicy = PullAlways
|
||||
} else {
|
||||
obj.ImagePullPolicy = PullIfNotPresent
|
||||
}
|
||||
}
|
||||
if obj.TerminationMessagePath == "" {
|
||||
obj.TerminationMessagePath = TerminationMessagePathDefault
|
||||
}
|
||||
}
|
||||
func SetDefaults_ServiceSpec(obj *ServiceSpec) {
|
||||
if obj.SessionAffinity == "" {
|
||||
obj.SessionAffinity = ServiceAffinityNone
|
||||
}
|
||||
if obj.Type == "" {
|
||||
obj.Type = ServiceTypeClusterIP
|
||||
}
|
||||
for i := range obj.Ports {
|
||||
sp := &obj.Ports[i]
|
||||
if sp.Protocol == "" {
|
||||
sp.Protocol = ProtocolTCP
|
||||
}
|
||||
if sp.TargetPort == intstr.FromInt(0) || sp.TargetPort == intstr.FromString("") {
|
||||
sp.TargetPort = intstr.FromInt(int(sp.Port))
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_Pod(obj *Pod) {
|
||||
// If limits are specified, but requests are not, default requests to limits
|
||||
// This is done here rather than a more specific defaulting pass on ResourceRequirements
|
||||
// because we only want this defaulting semantic to take place on a Pod and not a PodTemplate
|
||||
for i := range obj.Spec.Containers {
|
||||
// set requests to limits if requests are not specified, but limits are
|
||||
if obj.Spec.Containers[i].Resources.Limits != nil {
|
||||
if obj.Spec.Containers[i].Resources.Requests == nil {
|
||||
obj.Spec.Containers[i].Resources.Requests = make(ResourceList)
|
||||
}
|
||||
for key, value := range obj.Spec.Containers[i].Resources.Limits {
|
||||
if _, exists := obj.Spec.Containers[i].Resources.Requests[key]; !exists {
|
||||
obj.Spec.Containers[i].Resources.Requests[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_PodSpec(obj *PodSpec) {
|
||||
if obj.DNSPolicy == "" {
|
||||
obj.DNSPolicy = DNSClusterFirst
|
||||
}
|
||||
if obj.RestartPolicy == "" {
|
||||
obj.RestartPolicy = RestartPolicyAlways
|
||||
}
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
}
|
||||
if obj.SecurityContext == nil {
|
||||
obj.SecurityContext = &PodSecurityContext{}
|
||||
}
|
||||
if obj.TerminationGracePeriodSeconds == nil {
|
||||
period := int64(DefaultTerminationGracePeriodSeconds)
|
||||
obj.TerminationGracePeriodSeconds = &period
|
||||
}
|
||||
}
|
||||
func SetDefaults_Probe(obj *Probe) {
|
||||
if obj.TimeoutSeconds == 0 {
|
||||
obj.TimeoutSeconds = 1
|
||||
}
|
||||
if obj.PeriodSeconds == 0 {
|
||||
obj.PeriodSeconds = 10
|
||||
}
|
||||
if obj.SuccessThreshold == 0 {
|
||||
obj.SuccessThreshold = 1
|
||||
}
|
||||
if obj.FailureThreshold == 0 {
|
||||
obj.FailureThreshold = 3
|
||||
}
|
||||
}
|
||||
func SetDefaults_SecretVolumeSource(obj *SecretVolumeSource) {
|
||||
if obj.DefaultMode == nil {
|
||||
perm := int32(SecretVolumeSourceDefaultMode)
|
||||
obj.DefaultMode = &perm
|
||||
}
|
||||
}
|
||||
func SetDefaults_ConfigMapVolumeSource(obj *ConfigMapVolumeSource) {
|
||||
if obj.DefaultMode == nil {
|
||||
perm := int32(ConfigMapVolumeSourceDefaultMode)
|
||||
obj.DefaultMode = &perm
|
||||
}
|
||||
}
|
||||
func SetDefaults_DownwardAPIVolumeSource(obj *DownwardAPIVolumeSource) {
|
||||
if obj.DefaultMode == nil {
|
||||
perm := int32(DownwardAPIVolumeSourceDefaultMode)
|
||||
obj.DefaultMode = &perm
|
||||
}
|
||||
}
|
||||
func SetDefaults_Secret(obj *Secret) {
|
||||
if obj.Type == "" {
|
||||
obj.Type = SecretTypeOpaque
|
||||
}
|
||||
}
|
||||
func SetDefaults_PersistentVolume(obj *PersistentVolume) {
|
||||
if obj.Status.Phase == "" {
|
||||
obj.Status.Phase = VolumePending
|
||||
}
|
||||
if obj.Spec.PersistentVolumeReclaimPolicy == "" {
|
||||
obj.Spec.PersistentVolumeReclaimPolicy = PersistentVolumeReclaimRetain
|
||||
}
|
||||
}
|
||||
func SetDefaults_PersistentVolumeClaim(obj *PersistentVolumeClaim) {
|
||||
if obj.Status.Phase == "" {
|
||||
obj.Status.Phase = ClaimPending
|
||||
}
|
||||
}
|
||||
func SetDefaults_ISCSIVolumeSource(obj *ISCSIVolumeSource) {
|
||||
if obj.ISCSIInterface == "" {
|
||||
obj.ISCSIInterface = "default"
|
||||
}
|
||||
}
|
||||
func SetDefaults_AzureDiskVolumeSource(obj *AzureDiskVolumeSource) {
|
||||
if obj.CachingMode == nil {
|
||||
obj.CachingMode = new(AzureDataDiskCachingMode)
|
||||
*obj.CachingMode = AzureDataDiskCachingNone
|
||||
}
|
||||
if obj.FSType == nil {
|
||||
obj.FSType = new(string)
|
||||
*obj.FSType = "ext4"
|
||||
}
|
||||
if obj.ReadOnly == nil {
|
||||
obj.ReadOnly = new(bool)
|
||||
*obj.ReadOnly = false
|
||||
}
|
||||
}
|
||||
func SetDefaults_Endpoints(obj *Endpoints) {
|
||||
for i := range obj.Subsets {
|
||||
ss := &obj.Subsets[i]
|
||||
for i := range ss.Ports {
|
||||
ep := &ss.Ports[i]
|
||||
if ep.Protocol == "" {
|
||||
ep.Protocol = ProtocolTCP
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_HTTPGetAction(obj *HTTPGetAction) {
|
||||
if obj.Path == "" {
|
||||
obj.Path = "/"
|
||||
}
|
||||
if obj.Scheme == "" {
|
||||
obj.Scheme = URISchemeHTTP
|
||||
}
|
||||
}
|
||||
func SetDefaults_NamespaceStatus(obj *NamespaceStatus) {
|
||||
if obj.Phase == "" {
|
||||
obj.Phase = NamespaceActive
|
||||
}
|
||||
}
|
||||
func SetDefaults_Node(obj *Node) {
|
||||
if obj.Spec.ExternalID == "" {
|
||||
obj.Spec.ExternalID = obj.Name
|
||||
}
|
||||
}
|
||||
func SetDefaults_NodeStatus(obj *NodeStatus) {
|
||||
if obj.Allocatable == nil && obj.Capacity != nil {
|
||||
obj.Allocatable = make(ResourceList, len(obj.Capacity))
|
||||
for key, value := range obj.Capacity {
|
||||
obj.Allocatable[key] = *(value.Copy())
|
||||
}
|
||||
obj.Allocatable = obj.Capacity
|
||||
}
|
||||
}
|
||||
func SetDefaults_ObjectFieldSelector(obj *ObjectFieldSelector) {
|
||||
if obj.APIVersion == "" {
|
||||
obj.APIVersion = "v1"
|
||||
}
|
||||
}
|
||||
func SetDefaults_LimitRangeItem(obj *LimitRangeItem) {
|
||||
// for container limits, we apply default values
|
||||
if obj.Type == LimitTypeContainer {
|
||||
|
||||
if obj.Default == nil {
|
||||
obj.Default = make(ResourceList)
|
||||
}
|
||||
if obj.DefaultRequest == nil {
|
||||
obj.DefaultRequest = make(ResourceList)
|
||||
}
|
||||
|
||||
// If a default limit is unspecified, but the max is specified, default the limit to the max
|
||||
for key, value := range obj.Max {
|
||||
if _, exists := obj.Default[key]; !exists {
|
||||
obj.Default[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
// If a default limit is specified, but the default request is not, default request to limit
|
||||
for key, value := range obj.Default {
|
||||
if _, exists := obj.DefaultRequest[key]; !exists {
|
||||
obj.DefaultRequest[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
// If a default request is not specified, but the min is provided, default request to the min
|
||||
for key, value := range obj.Min {
|
||||
if _, exists := obj.DefaultRequest[key]; !exists {
|
||||
obj.DefaultRequest[key] = *(value.Copy())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func SetDefaults_ConfigMap(obj *ConfigMap) {
|
||||
if obj.Data == nil {
|
||||
obj.Data = make(map[string]string)
|
||||
}
|
||||
}
|
||||
|
||||
// With host networking default all container ports to host ports.
|
||||
func defaultHostNetworkPorts(containers *[]Container) {
|
||||
for i := range *containers {
|
||||
for j := range (*containers)[i].Ports {
|
||||
if (*containers)[i].Ports[j].HostPort == 0 {
|
||||
(*containers)[i].Ports[j].HostPort = (*containers)[i].Ports[j].ContainerPort
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_RBDVolumeSource(obj *RBDVolumeSource) {
|
||||
if obj.RBDPool == "" {
|
||||
obj.RBDPool = "rbd"
|
||||
}
|
||||
if obj.RadosUser == "" {
|
||||
obj.RadosUser = "admin"
|
||||
}
|
||||
if obj.Keyring == "" {
|
||||
obj.Keyring = "/etc/ceph/keyring"
|
||||
}
|
||||
}
|
||||
21
vendor/k8s.io/client-go/1.4/pkg/api/v1/doc.go
generated
vendored
21
vendor/k8s.io/client-go/1.4/pkg/api/v1/doc.go
generated
vendored
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/pkg/api
|
||||
|
||||
// Package v1 is the v1 version of the API.
|
||||
package v1
|
||||
39094
vendor/k8s.io/client-go/1.4/pkg/api/v1/generated.pb.go
generated
vendored
39094
vendor/k8s.io/client-go/1.4/pkg/api/v1/generated.pb.go
generated
vendored
File diff suppressed because it is too large
Load diff
3088
vendor/k8s.io/client-go/1.4/pkg/api/v1/generated.proto
generated
vendored
3088
vendor/k8s.io/client-go/1.4/pkg/api/v1/generated.proto
generated
vendored
File diff suppressed because it is too large
Load diff
92
vendor/k8s.io/client-go/1.4/pkg/api/v1/meta.go
generated
vendored
92
vendor/k8s.io/client-go/1.4/pkg/api/v1/meta.go
generated
vendored
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/meta/metatypes"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/types"
|
||||
)
|
||||
|
||||
func (obj *ObjectMeta) GetObjectMeta() meta.Object { return obj }
|
||||
|
||||
// Namespace implements meta.Object for any object with an ObjectMeta typed field. Allows
|
||||
// fast, direct access to metadata fields for API objects.
|
||||
func (meta *ObjectMeta) GetNamespace() string { return meta.Namespace }
|
||||
func (meta *ObjectMeta) SetNamespace(namespace string) { meta.Namespace = namespace }
|
||||
func (meta *ObjectMeta) GetName() string { return meta.Name }
|
||||
func (meta *ObjectMeta) SetName(name string) { meta.Name = name }
|
||||
func (meta *ObjectMeta) GetGenerateName() string { return meta.GenerateName }
|
||||
func (meta *ObjectMeta) SetGenerateName(generateName string) { meta.GenerateName = generateName }
|
||||
func (meta *ObjectMeta) GetUID() types.UID { return meta.UID }
|
||||
func (meta *ObjectMeta) SetUID(uid types.UID) { meta.UID = uid }
|
||||
func (meta *ObjectMeta) GetResourceVersion() string { return meta.ResourceVersion }
|
||||
func (meta *ObjectMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
|
||||
func (meta *ObjectMeta) GetSelfLink() string { return meta.SelfLink }
|
||||
func (meta *ObjectMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
|
||||
func (meta *ObjectMeta) GetCreationTimestamp() unversioned.Time { return meta.CreationTimestamp }
|
||||
func (meta *ObjectMeta) SetCreationTimestamp(creationTimestamp unversioned.Time) {
|
||||
meta.CreationTimestamp = creationTimestamp
|
||||
}
|
||||
func (meta *ObjectMeta) GetDeletionTimestamp() *unversioned.Time { return meta.DeletionTimestamp }
|
||||
func (meta *ObjectMeta) SetDeletionTimestamp(deletionTimestamp *unversioned.Time) {
|
||||
meta.DeletionTimestamp = deletionTimestamp
|
||||
}
|
||||
func (meta *ObjectMeta) GetLabels() map[string]string { return meta.Labels }
|
||||
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
|
||||
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
|
||||
func (meta *ObjectMeta) SetAnnotations(annotations map[string]string) { meta.Annotations = annotations }
|
||||
func (meta *ObjectMeta) GetFinalizers() []string { return meta.Finalizers }
|
||||
func (meta *ObjectMeta) SetFinalizers(finalizers []string) { meta.Finalizers = finalizers }
|
||||
|
||||
func (meta *ObjectMeta) GetOwnerReferences() []metatypes.OwnerReference {
|
||||
ret := make([]metatypes.OwnerReference, len(meta.OwnerReferences))
|
||||
for i := 0; i < len(meta.OwnerReferences); i++ {
|
||||
ret[i].Kind = meta.OwnerReferences[i].Kind
|
||||
ret[i].Name = meta.OwnerReferences[i].Name
|
||||
ret[i].UID = meta.OwnerReferences[i].UID
|
||||
ret[i].APIVersion = meta.OwnerReferences[i].APIVersion
|
||||
if meta.OwnerReferences[i].Controller != nil {
|
||||
value := *meta.OwnerReferences[i].Controller
|
||||
ret[i].Controller = &value
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (meta *ObjectMeta) SetOwnerReferences(references []metatypes.OwnerReference) {
|
||||
newReferences := make([]OwnerReference, len(references))
|
||||
for i := 0; i < len(references); i++ {
|
||||
newReferences[i].Kind = references[i].Kind
|
||||
newReferences[i].Name = references[i].Name
|
||||
newReferences[i].UID = references[i].UID
|
||||
newReferences[i].APIVersion = references[i].APIVersion
|
||||
if references[i].Controller != nil {
|
||||
value := *references[i].Controller
|
||||
newReferences[i].Controller = &value
|
||||
}
|
||||
}
|
||||
meta.OwnerReferences = newReferences
|
||||
}
|
||||
|
||||
func (meta *ObjectMeta) GetClusterName() string {
|
||||
return meta.ClusterName
|
||||
}
|
||||
func (meta *ObjectMeta) SetClusterName(clusterName string) {
|
||||
meta.ClusterName = clusterName
|
||||
}
|
||||
133
vendor/k8s.io/client-go/1.4/pkg/api/v1/ref.go
generated
vendored
133
vendor/k8s.io/client-go/1.4/pkg/api/v1/ref.go
generated
vendored
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
// Errors that could be returned by GetReference.
|
||||
ErrNilObject = errors.New("can't reference a nil object")
|
||||
ErrNoSelfLink = errors.New("selfLink was empty, can't make reference")
|
||||
)
|
||||
|
||||
// GetReference returns an ObjectReference which refers to the given
|
||||
// object, or an error if the object doesn't follow the conventions
|
||||
// that would allow this.
|
||||
// TODO: should take a meta.Interface see http://issue.k8s.io/7127
|
||||
func GetReference(obj runtime.Object) (*ObjectReference, error) {
|
||||
if obj == nil {
|
||||
return nil, ErrNilObject
|
||||
}
|
||||
if ref, ok := obj.(*ObjectReference); ok {
|
||||
// Don't make a reference to a reference.
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
|
||||
// if the object referenced is actually persisted, we can just get kind from meta
|
||||
// if we are building an object reference to something not yet persisted, we should fallback to scheme
|
||||
kind := gvk.Kind
|
||||
if len(kind) == 0 {
|
||||
// TODO: this is wrong
|
||||
gvks, _, err := api.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kind = gvks[0].Kind
|
||||
}
|
||||
|
||||
// An object that implements only List has enough metadata to build a reference
|
||||
var listMeta meta.List
|
||||
objectMeta, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
listMeta, err = meta.ListAccessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
listMeta = objectMeta
|
||||
}
|
||||
|
||||
// if the object referenced is actually persisted, we can also get version from meta
|
||||
version := gvk.GroupVersion().String()
|
||||
if len(version) == 0 {
|
||||
selfLink := listMeta.GetSelfLink()
|
||||
if len(selfLink) == 0 {
|
||||
return nil, ErrNoSelfLink
|
||||
}
|
||||
selfLinkUrl, err := url.Parse(selfLink)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// example paths: /<prefix>/<version>/*
|
||||
parts := strings.Split(selfLinkUrl.Path, "/")
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("unexpected self link format: '%v'; got version '%v'", selfLink, version)
|
||||
}
|
||||
version = parts[2]
|
||||
}
|
||||
|
||||
// only has list metadata
|
||||
if objectMeta == nil {
|
||||
return &ObjectReference{
|
||||
Kind: kind,
|
||||
APIVersion: version,
|
||||
ResourceVersion: listMeta.GetResourceVersion(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &ObjectReference{
|
||||
Kind: kind,
|
||||
APIVersion: version,
|
||||
Name: objectMeta.GetName(),
|
||||
Namespace: objectMeta.GetNamespace(),
|
||||
UID: objectMeta.GetUID(),
|
||||
ResourceVersion: objectMeta.GetResourceVersion(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetPartialReference is exactly like GetReference, but allows you to set the FieldPath.
|
||||
func GetPartialReference(obj runtime.Object, fieldPath string) (*ObjectReference, error) {
|
||||
ref, err := GetReference(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ref.FieldPath = fieldPath
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
// IsAnAPIObject allows clients to preemptively get a reference to an API object and pass it to places that
|
||||
// intend only to get a reference to that object. This simplifies the event recording interface.
|
||||
func (obj *ObjectReference) SetGroupVersionKind(gvk unversioned.GroupVersionKind) {
|
||||
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
func (obj *ObjectReference) GroupVersionKind() unversioned.GroupVersionKind {
|
||||
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
|
||||
}
|
||||
|
||||
func (obj *ObjectReference) GetObjectKind() unversioned.ObjectKind { return obj }
|
||||
93
vendor/k8s.io/client-go/1.4/pkg/api/v1/register.go
generated
vendored
93
vendor/k8s.io/client-go/1.4/pkg/api/v1/register.go
generated
vendored
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
versionedwatch "k8s.io/client-go/1.4/pkg/watch/versioned"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = ""
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs, addConversionFuncs, addFastPathConversionFuncs)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Pod{},
|
||||
&PodList{},
|
||||
&PodStatusResult{},
|
||||
&PodTemplate{},
|
||||
&PodTemplateList{},
|
||||
&ReplicationController{},
|
||||
&ReplicationControllerList{},
|
||||
&Service{},
|
||||
&ServiceProxyOptions{},
|
||||
&ServiceList{},
|
||||
&Endpoints{},
|
||||
&EndpointsList{},
|
||||
&Node{},
|
||||
&NodeList{},
|
||||
&NodeProxyOptions{},
|
||||
&Binding{},
|
||||
&Event{},
|
||||
&EventList{},
|
||||
&List{},
|
||||
&LimitRange{},
|
||||
&LimitRangeList{},
|
||||
&ResourceQuota{},
|
||||
&ResourceQuotaList{},
|
||||
&Namespace{},
|
||||
&NamespaceList{},
|
||||
&Secret{},
|
||||
&SecretList{},
|
||||
&ServiceAccount{},
|
||||
&ServiceAccountList{},
|
||||
&PersistentVolume{},
|
||||
&PersistentVolumeList{},
|
||||
&PersistentVolumeClaim{},
|
||||
&PersistentVolumeClaimList{},
|
||||
&DeleteOptions{},
|
||||
&ExportOptions{},
|
||||
&ListOptions{},
|
||||
&PodAttachOptions{},
|
||||
&PodLogOptions{},
|
||||
&PodExecOptions{},
|
||||
&PodProxyOptions{},
|
||||
&ComponentStatus{},
|
||||
&ComponentStatusList{},
|
||||
&SerializedReference{},
|
||||
&RangeAllocation{},
|
||||
&ConfigMap{},
|
||||
&ConfigMapList{},
|
||||
)
|
||||
|
||||
// Add common types
|
||||
scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.Status{})
|
||||
|
||||
// Add the watch version that applies
|
||||
versionedwatch.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
62479
vendor/k8s.io/client-go/1.4/pkg/api/v1/types.generated.go
generated
vendored
62479
vendor/k8s.io/client-go/1.4/pkg/api/v1/types.generated.go
generated
vendored
File diff suppressed because it is too large
Load diff
3498
vendor/k8s.io/client-go/1.4/pkg/api/v1/types.go
generated
vendored
3498
vendor/k8s.io/client-go/1.4/pkg/api/v1/types.go
generated
vendored
File diff suppressed because it is too large
Load diff
1811
vendor/k8s.io/client-go/1.4/pkg/api/v1/types_swagger_doc_generated.go
generated
vendored
1811
vendor/k8s.io/client-go/1.4/pkg/api/v1/types_swagger_doc_generated.go
generated
vendored
File diff suppressed because it is too large
Load diff
7129
vendor/k8s.io/client-go/1.4/pkg/api/v1/zz_generated.conversion.go
generated
vendored
7129
vendor/k8s.io/client-go/1.4/pkg/api/v1/zz_generated.conversion.go
generated
vendored
File diff suppressed because it is too large
Load diff
3703
vendor/k8s.io/client-go/1.4/pkg/api/v1/zz_generated.deepcopy.go
generated
vendored
3703
vendor/k8s.io/client-go/1.4/pkg/api/v1/zz_generated.deepcopy.go
generated
vendored
File diff suppressed because it is too large
Load diff
80
vendor/k8s.io/client-go/1.4/pkg/api/validation/events.go
generated
vendored
80
vendor/k8s.io/client-go/1.4/pkg/api/validation/events.go
generated
vendored
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
apiutil "k8s.io/client-go/1.4/pkg/api/util"
|
||||
"k8s.io/client-go/1.4/pkg/apimachinery/registered"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// ValidateEvent makes sure that the event makes sense.
|
||||
func ValidateEvent(event *api.Event) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// Make sure event.Namespace and the involvedObject.Namespace agree
|
||||
if len(event.InvolvedObject.Namespace) == 0 {
|
||||
// event.Namespace must also be empty (or "default", for compatibility with old clients)
|
||||
if event.Namespace != api.NamespaceNone && event.Namespace != api.NamespaceDefault {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
|
||||
}
|
||||
} else {
|
||||
// event namespace must match
|
||||
if event.Namespace != event.InvolvedObject.Namespace {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
|
||||
}
|
||||
}
|
||||
|
||||
// For kinds we recognize, make sure involvedObject.Namespace is set for namespaced kinds
|
||||
if namespaced, err := isNamespacedKind(event.InvolvedObject.Kind, event.InvolvedObject.APIVersion); err == nil {
|
||||
if namespaced && len(event.InvolvedObject.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(field.NewPath("involvedObject", "namespace"), fmt.Sprintf("required for kind %s", event.InvolvedObject.Kind)))
|
||||
}
|
||||
if !namespaced && len(event.InvolvedObject.Namespace) > 0 {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, fmt.Sprintf("not allowed for kind %s", event.InvolvedObject.Kind)))
|
||||
}
|
||||
}
|
||||
|
||||
for _, msg := range validation.IsDNS1123Subdomain(event.Namespace) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("namespace"), event.Namespace, msg))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// Check whether the kind in groupVersion is scoped at the root of the api hierarchy
|
||||
func isNamespacedKind(kind, groupVersion string) (bool, error) {
|
||||
group := apiutil.GetGroup(groupVersion)
|
||||
g, err := registered.Group(group)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
restMapping, err := g.RESTMapper.RESTMapping(unversioned.GroupKind{Group: group, Kind: kind}, apiutil.GetVersion(groupVersion))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
scopeName := restMapping.Scope.Name()
|
||||
if scopeName == meta.RESTScopeNameNamespace {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
370
vendor/k8s.io/client-go/1.4/pkg/api/validation/schema.go
generated
vendored
370
vendor/k8s.io/client-go/1.4/pkg/api/validation/schema.go
generated
vendored
|
|
@ -1,370 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
"github.com/golang/glog"
|
||||
apiutil "k8s.io/client-go/1.4/pkg/api/util"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
utilerrors "k8s.io/client-go/1.4/pkg/util/errors"
|
||||
"k8s.io/client-go/1.4/pkg/util/yaml"
|
||||
)
|
||||
|
||||
type InvalidTypeError struct {
|
||||
ExpectedKind reflect.Kind
|
||||
ObservedKind reflect.Kind
|
||||
FieldName string
|
||||
}
|
||||
|
||||
func (i *InvalidTypeError) Error() string {
|
||||
return fmt.Sprintf("expected type %s, for field %s, got %s", i.ExpectedKind.String(), i.FieldName, i.ObservedKind.String())
|
||||
}
|
||||
|
||||
func NewInvalidTypeError(expected reflect.Kind, observed reflect.Kind, fieldName string) error {
|
||||
return &InvalidTypeError{expected, observed, fieldName}
|
||||
}
|
||||
|
||||
// TypeNotFoundError is returned when specified type
|
||||
// can not found in schema
|
||||
type TypeNotFoundError string
|
||||
|
||||
func (tnfe TypeNotFoundError) Error() string {
|
||||
return fmt.Sprintf("couldn't find type: %s", string(tnfe))
|
||||
}
|
||||
|
||||
// Schema is an interface that knows how to validate an API object serialized to a byte array.
|
||||
type Schema interface {
|
||||
ValidateBytes(data []byte) error
|
||||
}
|
||||
|
||||
type NullSchema struct{}
|
||||
|
||||
func (NullSchema) ValidateBytes(data []byte) error { return nil }
|
||||
|
||||
type SwaggerSchema struct {
|
||||
api swagger.ApiDeclaration
|
||||
delegate Schema // For delegating to other api groups
|
||||
}
|
||||
|
||||
func NewSwaggerSchemaFromBytes(data []byte, factory Schema) (Schema, error) {
|
||||
schema := &SwaggerSchema{}
|
||||
err := json.Unmarshal(data, &schema.api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
schema.delegate = factory
|
||||
return schema, nil
|
||||
}
|
||||
|
||||
// validateList unpacks a list and validate every item in the list.
|
||||
// It return nil if every item is ok.
|
||||
// Otherwise it return an error list contain errors of every item.
|
||||
func (s *SwaggerSchema) validateList(obj map[string]interface{}) []error {
|
||||
items, exists := obj["items"]
|
||||
if !exists {
|
||||
return []error{fmt.Errorf("no items field in %#v", obj)}
|
||||
}
|
||||
return s.validateItems(items)
|
||||
}
|
||||
|
||||
func (s *SwaggerSchema) validateItems(items interface{}) []error {
|
||||
allErrs := []error{}
|
||||
itemList, ok := items.([]interface{})
|
||||
if !ok {
|
||||
return append(allErrs, fmt.Errorf("items isn't a slice"))
|
||||
}
|
||||
for i, item := range itemList {
|
||||
fields, ok := item.(map[string]interface{})
|
||||
if !ok {
|
||||
allErrs = append(allErrs, fmt.Errorf("items[%d] isn't a map[string]interface{}", i))
|
||||
continue
|
||||
}
|
||||
groupVersion := fields["apiVersion"]
|
||||
if groupVersion == nil {
|
||||
allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion not set", i))
|
||||
continue
|
||||
}
|
||||
itemVersion, ok := groupVersion.(string)
|
||||
if !ok {
|
||||
allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion isn't string type", i))
|
||||
continue
|
||||
}
|
||||
if len(itemVersion) == 0 {
|
||||
allErrs = append(allErrs, fmt.Errorf("items[%d].apiVersion is empty", i))
|
||||
}
|
||||
kind := fields["kind"]
|
||||
if kind == nil {
|
||||
allErrs = append(allErrs, fmt.Errorf("items[%d].kind not set", i))
|
||||
continue
|
||||
}
|
||||
itemKind, ok := kind.(string)
|
||||
if !ok {
|
||||
allErrs = append(allErrs, fmt.Errorf("items[%d].kind isn't string type", i))
|
||||
continue
|
||||
}
|
||||
if len(itemKind) == 0 {
|
||||
allErrs = append(allErrs, fmt.Errorf("items[%d].kind is empty", i))
|
||||
}
|
||||
version := apiutil.GetVersion(itemVersion)
|
||||
errs := s.ValidateObject(item, "", version+"."+itemKind)
|
||||
if len(errs) >= 1 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func (s *SwaggerSchema) ValidateBytes(data []byte) error {
|
||||
var obj interface{}
|
||||
out, err := yaml.ToJSON(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data = out
|
||||
if err := json.Unmarshal(data, &obj); err != nil {
|
||||
return err
|
||||
}
|
||||
fields, ok := obj.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("error in unmarshaling data %s", string(data))
|
||||
}
|
||||
groupVersion := fields["apiVersion"]
|
||||
if groupVersion == nil {
|
||||
return fmt.Errorf("apiVersion not set")
|
||||
}
|
||||
if _, ok := groupVersion.(string); !ok {
|
||||
return fmt.Errorf("apiVersion isn't string type")
|
||||
}
|
||||
kind := fields["kind"]
|
||||
if kind == nil {
|
||||
return fmt.Errorf("kind not set")
|
||||
}
|
||||
if _, ok := kind.(string); !ok {
|
||||
return fmt.Errorf("kind isn't string type")
|
||||
}
|
||||
if strings.HasSuffix(kind.(string), "List") {
|
||||
return utilerrors.NewAggregate(s.validateList(fields))
|
||||
}
|
||||
version := apiutil.GetVersion(groupVersion.(string))
|
||||
allErrs := s.ValidateObject(obj, "", version+"."+kind.(string))
|
||||
if len(allErrs) == 1 {
|
||||
return allErrs[0]
|
||||
}
|
||||
return utilerrors.NewAggregate(allErrs)
|
||||
}
|
||||
|
||||
func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName string) []error {
|
||||
allErrs := []error{}
|
||||
models := s.api.Models
|
||||
model, ok := models.At(typeName)
|
||||
|
||||
// Verify the api version matches. This is required for nested types with differing api versions because
|
||||
// s.api only has schema for 1 api version (the parent object type's version).
|
||||
// e.g. an extensions/v1beta1 Template embedding a /v1 Service requires the schema for the extensions/v1beta1
|
||||
// api to delegate to the schema for the /v1 api.
|
||||
// Only do this for !ok objects so that cross ApiVersion vendored types take precedence.
|
||||
if !ok && s.delegate != nil {
|
||||
fields, mapOk := obj.(map[string]interface{})
|
||||
if !mapOk {
|
||||
return append(allErrs, fmt.Errorf("field %s: expected object of type map[string]interface{}, but the actual type is %T", fieldName, obj))
|
||||
}
|
||||
if delegated, err := s.delegateIfDifferentApiVersion(runtime.Unstructured{Object: fields}); delegated {
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return append(allErrs, TypeNotFoundError(typeName))
|
||||
}
|
||||
properties := model.Properties
|
||||
if len(properties.List) == 0 {
|
||||
// The object does not have any sub-fields.
|
||||
return nil
|
||||
}
|
||||
fields, ok := obj.(map[string]interface{})
|
||||
if !ok {
|
||||
return append(allErrs, fmt.Errorf("field %s: expected object of type map[string]interface{}, but the actual type is %T", fieldName, obj))
|
||||
}
|
||||
if len(fieldName) > 0 {
|
||||
fieldName = fieldName + "."
|
||||
}
|
||||
// handle required fields
|
||||
for _, requiredKey := range model.Required {
|
||||
if _, ok := fields[requiredKey]; !ok {
|
||||
allErrs = append(allErrs, fmt.Errorf("field %s: is required", requiredKey))
|
||||
}
|
||||
}
|
||||
for key, value := range fields {
|
||||
details, ok := properties.At(key)
|
||||
|
||||
// Special case for runtime.RawExtension and runtime.Objects because they always fail to validate
|
||||
// This is because the actual values will be of some sub-type (e.g. Deployment) not the expected
|
||||
// super-type (RawExtension)
|
||||
if s.isGenericArray(details) {
|
||||
errs := s.validateItems(value)
|
||||
if len(errs) > 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !ok {
|
||||
allErrs = append(allErrs, fmt.Errorf("found invalid field %s for %s", key, typeName))
|
||||
continue
|
||||
}
|
||||
if details.Type == nil && details.Ref == nil {
|
||||
allErrs = append(allErrs, fmt.Errorf("could not find the type of %s from object: %v", key, details))
|
||||
}
|
||||
var fieldType string
|
||||
if details.Type != nil {
|
||||
fieldType = *details.Type
|
||||
} else {
|
||||
fieldType = *details.Ref
|
||||
}
|
||||
if value == nil {
|
||||
glog.V(2).Infof("Skipping nil field: %s", key)
|
||||
continue
|
||||
}
|
||||
errs := s.validateField(value, fieldName+key, fieldType, &details)
|
||||
if len(errs) > 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// delegateIfDifferentApiVersion delegates the validation of an object if its ApiGroup does not match the
|
||||
// current SwaggerSchema.
|
||||
// First return value is true if the validation was delegated (by a different ApiGroup SwaggerSchema)
|
||||
// Second return value is the result of the delegated validation if performed.
|
||||
func (s *SwaggerSchema) delegateIfDifferentApiVersion(obj runtime.Unstructured) (bool, error) {
|
||||
// Never delegate objects in the same ApiVersion or we will get infinite recursion
|
||||
if !s.isDifferentApiVersion(obj) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Convert the object back into bytes so that we can pass it to the ValidateBytes function
|
||||
m, err := json.Marshal(obj.Object)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
// Delegate validation of this object to the correct SwaggerSchema for its ApiGroup
|
||||
return true, s.delegate.ValidateBytes(m)
|
||||
}
|
||||
|
||||
// isDifferentApiVersion Returns true if obj lives in a different ApiVersion than the SwaggerSchema does.
|
||||
// The SwaggerSchema will not be able to process objects in different ApiVersions unless they are vendored.
|
||||
func (s *SwaggerSchema) isDifferentApiVersion(obj runtime.Unstructured) bool {
|
||||
groupVersion := obj.GetAPIVersion()
|
||||
return len(groupVersion) > 0 && s.api.ApiVersion != groupVersion
|
||||
}
|
||||
|
||||
// isGenericArray Returns true if p is an array of generic Objects - either RawExtension or Object.
|
||||
func (s *SwaggerSchema) isGenericArray(p swagger.ModelProperty) bool {
|
||||
return p.DataTypeFields.Type != nil &&
|
||||
*p.DataTypeFields.Type == "array" &&
|
||||
p.Items != nil &&
|
||||
p.Items.Ref != nil &&
|
||||
(*p.Items.Ref == "runtime.RawExtension" || *p.Items.Ref == "runtime.Object")
|
||||
}
|
||||
|
||||
// This matches type name in the swagger spec, such as "v1.Binding".
|
||||
var versionRegexp = regexp.MustCompile(`^(v.+|unversioned)\..*`)
|
||||
|
||||
func (s *SwaggerSchema) validateField(value interface{}, fieldName, fieldType string, fieldDetails *swagger.ModelProperty) []error {
|
||||
allErrs := []error{}
|
||||
if reflect.TypeOf(value) == nil {
|
||||
return append(allErrs, fmt.Errorf("unexpected nil value for field %v", fieldName))
|
||||
}
|
||||
// TODO: caesarxuchao: because we have multiple group/versions and objects
|
||||
// may reference objects in other group, the commented out way of checking
|
||||
// if a filedType is a type defined by us is outdated. We use a hacky way
|
||||
// for now.
|
||||
// TODO: the type name in the swagger spec is something like "v1.Binding",
|
||||
// and the "v1" is generated from the package name, not the groupVersion of
|
||||
// the type. We need to fix go-restful to embed the group name in the type
|
||||
// name, otherwise we couldn't handle identically named types in different
|
||||
// groups correctly.
|
||||
if versionRegexp.MatchString(fieldType) {
|
||||
// if strings.HasPrefix(fieldType, apiVersion) {
|
||||
return s.ValidateObject(value, fieldName, fieldType)
|
||||
}
|
||||
switch fieldType {
|
||||
case "string":
|
||||
// Be loose about what we accept for 'string' since we use IntOrString in a couple of places
|
||||
_, isString := value.(string)
|
||||
_, isNumber := value.(float64)
|
||||
_, isInteger := value.(int)
|
||||
if !isString && !isNumber && !isInteger {
|
||||
return append(allErrs, NewInvalidTypeError(reflect.String, reflect.TypeOf(value).Kind(), fieldName))
|
||||
}
|
||||
case "array":
|
||||
arr, ok := value.([]interface{})
|
||||
if !ok {
|
||||
return append(allErrs, NewInvalidTypeError(reflect.Array, reflect.TypeOf(value).Kind(), fieldName))
|
||||
}
|
||||
var arrType string
|
||||
if fieldDetails.Items.Ref == nil && fieldDetails.Items.Type == nil {
|
||||
return append(allErrs, NewInvalidTypeError(reflect.Array, reflect.TypeOf(value).Kind(), fieldName))
|
||||
}
|
||||
if fieldDetails.Items.Ref != nil {
|
||||
arrType = *fieldDetails.Items.Ref
|
||||
} else {
|
||||
arrType = *fieldDetails.Items.Type
|
||||
}
|
||||
for ix := range arr {
|
||||
errs := s.validateField(arr[ix], fmt.Sprintf("%s[%d]", fieldName, ix), arrType, nil)
|
||||
if len(errs) > 0 {
|
||||
allErrs = append(allErrs, errs...)
|
||||
}
|
||||
}
|
||||
case "uint64":
|
||||
case "int64":
|
||||
case "integer":
|
||||
_, isNumber := value.(float64)
|
||||
_, isInteger := value.(int)
|
||||
if !isNumber && !isInteger {
|
||||
return append(allErrs, NewInvalidTypeError(reflect.Int, reflect.TypeOf(value).Kind(), fieldName))
|
||||
}
|
||||
case "float64":
|
||||
if _, ok := value.(float64); !ok {
|
||||
return append(allErrs, NewInvalidTypeError(reflect.Float64, reflect.TypeOf(value).Kind(), fieldName))
|
||||
}
|
||||
case "boolean":
|
||||
if _, ok := value.(bool); !ok {
|
||||
return append(allErrs, NewInvalidTypeError(reflect.Bool, reflect.TypeOf(value).Kind(), fieldName))
|
||||
}
|
||||
// API servers before release 1.3 produce swagger spec with `type: "any"` as the fallback type, while newer servers produce spec with `type: "object"`.
|
||||
// We have both here so that kubectl can work with both old and new api servers.
|
||||
case "object":
|
||||
case "any":
|
||||
default:
|
||||
return append(allErrs, fmt.Errorf("unexpected type: %v", fieldType))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
3601
vendor/k8s.io/client-go/1.4/pkg/api/validation/validation.go
generated
vendored
3601
vendor/k8s.io/client-go/1.4/pkg/api/validation/validation.go
generated
vendored
File diff suppressed because it is too large
Load diff
3749
vendor/k8s.io/client-go/1.4/pkg/api/zz_generated.deepcopy.go
generated
vendored
3749
vendor/k8s.io/client-go/1.4/pkg/api/zz_generated.deepcopy.go
generated
vendored
File diff suppressed because it is too large
Load diff
20
vendor/k8s.io/client-go/1.4/pkg/apimachinery/doc.go
generated
vendored
20
vendor/k8s.io/client-go/1.4/pkg/apimachinery/doc.go
generated
vendored
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package apimachinery contains the generic API machinery code that
|
||||
// is common to both server and clients.
|
||||
// This package should never import specific API objects.
|
||||
package apimachinery
|
||||
376
vendor/k8s.io/client-go/1.4/pkg/apimachinery/registered/registered.go
generated
vendored
376
vendor/k8s.io/client-go/1.4/pkg/apimachinery/registered/registered.go
generated
vendored
|
|
@ -1,376 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package to keep track of API Versions that can be registered and are enabled in api.Scheme.
|
||||
package registered
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/apimachinery"
|
||||
"k8s.io/client-go/1.4/pkg/util/sets"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultAPIRegistrationManager = NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
|
||||
)
|
||||
|
||||
// APIRegistrationManager
|
||||
type APIRegistrationManager struct {
|
||||
// registeredGroupVersions stores all API group versions for which RegisterGroup is called.
|
||||
registeredVersions map[unversioned.GroupVersion]struct{}
|
||||
|
||||
// thirdPartyGroupVersions are API versions which are dynamically
|
||||
// registered (and unregistered) via API calls to the apiserver
|
||||
thirdPartyGroupVersions []unversioned.GroupVersion
|
||||
|
||||
// enabledVersions represents all enabled API versions. It should be a
|
||||
// subset of registeredVersions. Please call EnableVersions() to add
|
||||
// enabled versions.
|
||||
enabledVersions map[unversioned.GroupVersion]struct{}
|
||||
|
||||
// map of group meta for all groups.
|
||||
groupMetaMap map[string]*apimachinery.GroupMeta
|
||||
|
||||
// envRequestedVersions represents the versions requested via the
|
||||
// KUBE_API_VERSIONS environment variable. The install package of each group
|
||||
// checks this list before add their versions to the latest package and
|
||||
// Scheme. This list is small and order matters, so represent as a slice
|
||||
envRequestedVersions []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
// NewAPIRegistrationManager constructs a new manager. The argument ought to be
|
||||
// the value of the KUBE_API_VERSIONS env var, or a value of this which you
|
||||
// wish to test.
|
||||
func NewAPIRegistrationManager(kubeAPIVersions string) (*APIRegistrationManager, error) {
|
||||
m := &APIRegistrationManager{
|
||||
registeredVersions: map[unversioned.GroupVersion]struct{}{},
|
||||
thirdPartyGroupVersions: []unversioned.GroupVersion{},
|
||||
enabledVersions: map[unversioned.GroupVersion]struct{}{},
|
||||
groupMetaMap: map[string]*apimachinery.GroupMeta{},
|
||||
envRequestedVersions: []unversioned.GroupVersion{},
|
||||
}
|
||||
|
||||
if len(kubeAPIVersions) != 0 {
|
||||
for _, version := range strings.Split(kubeAPIVersions, ",") {
|
||||
gv, err := unversioned.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid api version: %s in KUBE_API_VERSIONS: %s.",
|
||||
version, kubeAPIVersions)
|
||||
}
|
||||
m.envRequestedVersions = append(m.envRequestedVersions, gv)
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func NewOrDie(kubeAPIVersions string) *APIRegistrationManager {
|
||||
m, err := NewAPIRegistrationManager(kubeAPIVersions)
|
||||
if err != nil {
|
||||
glog.Fatalf("Could not construct version manager: %v (KUBE_API_VERSIONS=%q)", err, kubeAPIVersions)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// People are calling global functions. Let them continue to do that (for now).
|
||||
var (
|
||||
ValidateEnvRequestedVersions = DefaultAPIRegistrationManager.ValidateEnvRequestedVersions
|
||||
AllPreferredGroupVersions = DefaultAPIRegistrationManager.AllPreferredGroupVersions
|
||||
RESTMapper = DefaultAPIRegistrationManager.RESTMapper
|
||||
GroupOrDie = DefaultAPIRegistrationManager.GroupOrDie
|
||||
AddThirdPartyAPIGroupVersions = DefaultAPIRegistrationManager.AddThirdPartyAPIGroupVersions
|
||||
IsThirdPartyAPIGroupVersion = DefaultAPIRegistrationManager.IsThirdPartyAPIGroupVersion
|
||||
RegisteredGroupVersions = DefaultAPIRegistrationManager.RegisteredGroupVersions
|
||||
IsRegisteredVersion = DefaultAPIRegistrationManager.IsRegisteredVersion
|
||||
IsRegistered = DefaultAPIRegistrationManager.IsRegistered
|
||||
Group = DefaultAPIRegistrationManager.Group
|
||||
EnabledVersionsForGroup = DefaultAPIRegistrationManager.EnabledVersionsForGroup
|
||||
EnabledVersions = DefaultAPIRegistrationManager.EnabledVersions
|
||||
IsEnabledVersion = DefaultAPIRegistrationManager.IsEnabledVersion
|
||||
IsAllowedVersion = DefaultAPIRegistrationManager.IsAllowedVersion
|
||||
EnableVersions = DefaultAPIRegistrationManager.EnableVersions
|
||||
RegisterGroup = DefaultAPIRegistrationManager.RegisterGroup
|
||||
RegisterVersions = DefaultAPIRegistrationManager.RegisterVersions
|
||||
)
|
||||
|
||||
// RegisterVersions adds the given group versions to the list of registered group versions.
|
||||
func (m *APIRegistrationManager) RegisterVersions(availableVersions []unversioned.GroupVersion) {
|
||||
for _, v := range availableVersions {
|
||||
m.registeredVersions[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterGroup adds the given group to the list of registered groups.
|
||||
func (m *APIRegistrationManager) RegisterGroup(groupMeta apimachinery.GroupMeta) error {
|
||||
groupName := groupMeta.GroupVersion.Group
|
||||
if _, found := m.groupMetaMap[groupName]; found {
|
||||
return fmt.Errorf("group %v is already registered", m.groupMetaMap)
|
||||
}
|
||||
m.groupMetaMap[groupName] = &groupMeta
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableVersions adds the versions for the given group to the list of enabled versions.
|
||||
// Note that the caller should call RegisterGroup before calling this method.
|
||||
// The caller of this function is responsible to add the versions to scheme and RESTMapper.
|
||||
func (m *APIRegistrationManager) EnableVersions(versions ...unversioned.GroupVersion) error {
|
||||
var unregisteredVersions []unversioned.GroupVersion
|
||||
for _, v := range versions {
|
||||
if _, found := m.registeredVersions[v]; !found {
|
||||
unregisteredVersions = append(unregisteredVersions, v)
|
||||
}
|
||||
m.enabledVersions[v] = struct{}{}
|
||||
}
|
||||
if len(unregisteredVersions) != 0 {
|
||||
return fmt.Errorf("Please register versions before enabling them: %v", unregisteredVersions)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsAllowedVersion returns if the version is allowed by the KUBE_API_VERSIONS
|
||||
// environment variable. If the environment variable is empty, then it always
|
||||
// returns true.
|
||||
func (m *APIRegistrationManager) IsAllowedVersion(v unversioned.GroupVersion) bool {
|
||||
if len(m.envRequestedVersions) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, envGV := range m.envRequestedVersions {
|
||||
if v == envGV {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsEnabledVersion returns if a version is enabled.
|
||||
func (m *APIRegistrationManager) IsEnabledVersion(v unversioned.GroupVersion) bool {
|
||||
_, found := m.enabledVersions[v]
|
||||
return found
|
||||
}
|
||||
|
||||
// EnabledVersions returns all enabled versions. Groups are randomly ordered, but versions within groups
|
||||
// are priority order from best to worst
|
||||
func (m *APIRegistrationManager) EnabledVersions() []unversioned.GroupVersion {
|
||||
ret := []unversioned.GroupVersion{}
|
||||
for _, groupMeta := range m.groupMetaMap {
|
||||
ret = append(ret, groupMeta.GroupVersions...)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// EnabledVersionsForGroup returns all enabled versions for a group in order of best to worst
|
||||
func (m *APIRegistrationManager) EnabledVersionsForGroup(group string) []unversioned.GroupVersion {
|
||||
groupMeta, ok := m.groupMetaMap[group]
|
||||
if !ok {
|
||||
return []unversioned.GroupVersion{}
|
||||
}
|
||||
|
||||
return append([]unversioned.GroupVersion{}, groupMeta.GroupVersions...)
|
||||
}
|
||||
|
||||
// Group returns the metadata of a group if the group is registered, otherwise
|
||||
// an error is returned.
|
||||
func (m *APIRegistrationManager) Group(group string) (*apimachinery.GroupMeta, error) {
|
||||
groupMeta, found := m.groupMetaMap[group]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("group %v has not been registered", group)
|
||||
}
|
||||
groupMetaCopy := *groupMeta
|
||||
return &groupMetaCopy, nil
|
||||
}
|
||||
|
||||
// IsRegistered takes a string and determines if it's one of the registered groups
|
||||
func (m *APIRegistrationManager) IsRegistered(group string) bool {
|
||||
_, found := m.groupMetaMap[group]
|
||||
return found
|
||||
}
|
||||
|
||||
// IsRegisteredVersion returns if a version is registered.
|
||||
func (m *APIRegistrationManager) IsRegisteredVersion(v unversioned.GroupVersion) bool {
|
||||
_, found := m.registeredVersions[v]
|
||||
return found
|
||||
}
|
||||
|
||||
// RegisteredGroupVersions returns all registered group versions.
|
||||
func (m *APIRegistrationManager) RegisteredGroupVersions() []unversioned.GroupVersion {
|
||||
ret := []unversioned.GroupVersion{}
|
||||
for groupVersion := range m.registeredVersions {
|
||||
ret = append(ret, groupVersion)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// IsThirdPartyAPIGroupVersion returns true if the api version is a user-registered group/version.
|
||||
func (m *APIRegistrationManager) IsThirdPartyAPIGroupVersion(gv unversioned.GroupVersion) bool {
|
||||
for ix := range m.thirdPartyGroupVersions {
|
||||
if m.thirdPartyGroupVersions[ix] == gv {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddThirdPartyAPIGroupVersions sets the list of third party versions,
|
||||
// registers them in the API machinery and enables them.
|
||||
// Skips GroupVersions that are already registered.
|
||||
// Returns the list of GroupVersions that were skipped.
|
||||
func (m *APIRegistrationManager) AddThirdPartyAPIGroupVersions(gvs ...unversioned.GroupVersion) []unversioned.GroupVersion {
|
||||
filteredGVs := []unversioned.GroupVersion{}
|
||||
skippedGVs := []unversioned.GroupVersion{}
|
||||
for ix := range gvs {
|
||||
if !m.IsRegisteredVersion(gvs[ix]) {
|
||||
filteredGVs = append(filteredGVs, gvs[ix])
|
||||
} else {
|
||||
glog.V(3).Infof("Skipping %s, because its already registered", gvs[ix].String())
|
||||
skippedGVs = append(skippedGVs, gvs[ix])
|
||||
}
|
||||
}
|
||||
if len(filteredGVs) == 0 {
|
||||
return skippedGVs
|
||||
}
|
||||
m.RegisterVersions(filteredGVs)
|
||||
m.EnableVersions(filteredGVs...)
|
||||
m.thirdPartyGroupVersions = append(m.thirdPartyGroupVersions, filteredGVs...)
|
||||
|
||||
return skippedGVs
|
||||
}
|
||||
|
||||
// TODO: This is an expedient function, because we don't check if a Group is
|
||||
// supported throughout the code base. We will abandon this function and
|
||||
// checking the error returned by the Group() function.
|
||||
func (m *APIRegistrationManager) GroupOrDie(group string) *apimachinery.GroupMeta {
|
||||
groupMeta, found := m.groupMetaMap[group]
|
||||
if !found {
|
||||
if group == "" {
|
||||
panic("The legacy v1 API is not registered.")
|
||||
} else {
|
||||
panic(fmt.Sprintf("Group %s is not registered.", group))
|
||||
}
|
||||
}
|
||||
groupMetaCopy := *groupMeta
|
||||
return &groupMetaCopy
|
||||
}
|
||||
|
||||
// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
|
||||
// 1. if KUBE_API_VERSIONS is specified, then KUBE_API_VERSIONS in order, OR
|
||||
// 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
|
||||
// kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
|
||||
// all other groups alphabetical.
|
||||
func (m *APIRegistrationManager) RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper {
|
||||
unionMapper := meta.MultiRESTMapper{}
|
||||
unionedGroups := sets.NewString()
|
||||
for enabledVersion := range m.enabledVersions {
|
||||
if !unionedGroups.Has(enabledVersion.Group) {
|
||||
unionedGroups.Insert(enabledVersion.Group)
|
||||
groupMeta := m.groupMetaMap[enabledVersion.Group]
|
||||
unionMapper = append(unionMapper, groupMeta.RESTMapper)
|
||||
}
|
||||
}
|
||||
|
||||
if len(versionPatterns) != 0 {
|
||||
resourcePriority := []unversioned.GroupVersionResource{}
|
||||
kindPriority := []unversioned.GroupVersionKind{}
|
||||
for _, versionPriority := range versionPatterns {
|
||||
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
|
||||
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
|
||||
}
|
||||
|
||||
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
|
||||
}
|
||||
|
||||
if len(m.envRequestedVersions) != 0 {
|
||||
resourcePriority := []unversioned.GroupVersionResource{}
|
||||
kindPriority := []unversioned.GroupVersionKind{}
|
||||
|
||||
for _, versionPriority := range m.envRequestedVersions {
|
||||
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
|
||||
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
|
||||
}
|
||||
|
||||
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
|
||||
}
|
||||
|
||||
prioritizedGroups := []string{"", "extensions", "metrics"}
|
||||
resourcePriority, kindPriority := m.prioritiesForGroups(prioritizedGroups...)
|
||||
|
||||
prioritizedGroupsSet := sets.NewString(prioritizedGroups...)
|
||||
remainingGroups := sets.String{}
|
||||
for enabledVersion := range m.enabledVersions {
|
||||
if !prioritizedGroupsSet.Has(enabledVersion.Group) {
|
||||
remainingGroups.Insert(enabledVersion.Group)
|
||||
}
|
||||
}
|
||||
|
||||
remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...)
|
||||
resourcePriority = append(resourcePriority, remainingResourcePriority...)
|
||||
kindPriority = append(kindPriority, remainingKindPriority...)
|
||||
|
||||
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
|
||||
}
|
||||
|
||||
// prioritiesForGroups returns the resource and kind priorities for a PriorityRESTMapper, preferring the preferred version of each group first,
|
||||
// then any non-preferred version of the group second.
|
||||
func (m *APIRegistrationManager) prioritiesForGroups(groups ...string) ([]unversioned.GroupVersionResource, []unversioned.GroupVersionKind) {
|
||||
resourcePriority := []unversioned.GroupVersionResource{}
|
||||
kindPriority := []unversioned.GroupVersionKind{}
|
||||
|
||||
for _, group := range groups {
|
||||
availableVersions := m.EnabledVersionsForGroup(group)
|
||||
if len(availableVersions) > 0 {
|
||||
resourcePriority = append(resourcePriority, availableVersions[0].WithResource(meta.AnyResource))
|
||||
kindPriority = append(kindPriority, availableVersions[0].WithKind(meta.AnyKind))
|
||||
}
|
||||
}
|
||||
for _, group := range groups {
|
||||
resourcePriority = append(resourcePriority, unversioned.GroupVersionResource{Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource})
|
||||
kindPriority = append(kindPriority, unversioned.GroupVersionKind{Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind})
|
||||
}
|
||||
|
||||
return resourcePriority, kindPriority
|
||||
}
|
||||
|
||||
// AllPreferredGroupVersions returns the preferred versions of all registered
|
||||
// groups in the form of "group1/version1,group2/version2,..."
|
||||
func (m *APIRegistrationManager) AllPreferredGroupVersions() string {
|
||||
if len(m.groupMetaMap) == 0 {
|
||||
return ""
|
||||
}
|
||||
var defaults []string
|
||||
for _, groupMeta := range m.groupMetaMap {
|
||||
defaults = append(defaults, groupMeta.GroupVersion.String())
|
||||
}
|
||||
sort.Strings(defaults)
|
||||
return strings.Join(defaults, ",")
|
||||
}
|
||||
|
||||
// ValidateEnvRequestedVersions returns a list of versions that are requested in
|
||||
// the KUBE_API_VERSIONS environment variable, but not enabled.
|
||||
func (m *APIRegistrationManager) ValidateEnvRequestedVersions() []unversioned.GroupVersion {
|
||||
var missingVersions []unversioned.GroupVersion
|
||||
for _, v := range m.envRequestedVersions {
|
||||
if _, found := m.enabledVersions[v]; !found {
|
||||
missingVersions = append(missingVersions, v)
|
||||
}
|
||||
}
|
||||
return missingVersions
|
||||
}
|
||||
52
vendor/k8s.io/client-go/1.4/pkg/apimachinery/types.go
generated
vendored
52
vendor/k8s.io/client-go/1.4/pkg/apimachinery/types.go
generated
vendored
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package apimachinery
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api/meta"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
)
|
||||
|
||||
// GroupMeta stores the metadata of a group.
|
||||
type GroupMeta struct {
|
||||
// GroupVersion represents the preferred version of the group.
|
||||
GroupVersion unversioned.GroupVersion
|
||||
|
||||
// GroupVersions is Group + all versions in that group.
|
||||
GroupVersions []unversioned.GroupVersion
|
||||
|
||||
// Codec is the default codec for serializing output that should use
|
||||
// the preferred version. Use this Codec when writing to
|
||||
// disk, a data store that is not dynamically versioned, or in tests.
|
||||
// This codec can decode any object that the schema is aware of.
|
||||
Codec runtime.Codec
|
||||
|
||||
// SelfLinker can set or get the SelfLink field of all API types.
|
||||
// TODO: when versioning changes, make this part of each API definition.
|
||||
// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
|
||||
// to go through the InterfacesFor method below.
|
||||
SelfLinker runtime.SelfLinker
|
||||
|
||||
// RESTMapper provides the default mapping between REST paths and the objects declared in api.Scheme and all known
|
||||
// versions.
|
||||
RESTMapper meta.RESTMapper
|
||||
|
||||
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
|
||||
// or an error if the version is not known.
|
||||
InterfacesFor func(version unversioned.GroupVersion) (*meta.VersionInterfaces, error)
|
||||
}
|
||||
2656
vendor/k8s.io/client-go/1.4/pkg/apis/autoscaling/types.generated.go
generated
vendored
2656
vendor/k8s.io/client-go/1.4/pkg/apis/autoscaling/types.generated.go
generated
vendored
File diff suppressed because it is too large
Load diff
120
vendor/k8s.io/client-go/1.4/pkg/apis/autoscaling/types.go
generated
vendored
120
vendor/k8s.io/client-go/1.4/pkg/apis/autoscaling/types.go
generated
vendored
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package autoscaling
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// Scale represents a scaling request for a resource.
|
||||
type Scale struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata.
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.
|
||||
Spec ScaleSpec `json:"spec,omitempty"`
|
||||
|
||||
// current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only.
|
||||
Status ScaleStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// ScaleSpec describes the attributes of a scale subresource.
|
||||
type ScaleSpec struct {
|
||||
// desired number of instances for the scaled object.
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
}
|
||||
|
||||
// ScaleStatus represents the current status of a scale subresource.
|
||||
type ScaleStatus struct {
|
||||
// actual number of observed instances of the scaled object.
|
||||
Replicas int32 `json:"replicas"`
|
||||
|
||||
// label query over pods that should match the replicas count. This is same
|
||||
// as the label selector but in the string format to avoid introspection
|
||||
// by clients. The string will be in the same format as the query-param syntax.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
|
||||
Selector string `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
// CrossVersionObjectReference contains enough information to let you identify the referred resource.
|
||||
type CrossVersionObjectReference struct {
|
||||
// Kind of the referent; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds"
|
||||
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
|
||||
// Name of the referent; More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names
|
||||
Name string `json:"name" protobuf:"bytes,2,opt,name=name"`
|
||||
// API version of the referent
|
||||
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"`
|
||||
}
|
||||
|
||||
// specification of a horizontal pod autoscaler.
|
||||
type HorizontalPodAutoscalerSpec struct {
|
||||
// reference to scaled resource; horizontal pod autoscaler will learn the current resource consumption
|
||||
// and will set the desired number of pods by using its Scale subresource.
|
||||
ScaleTargetRef CrossVersionObjectReference `json:"scaleTargetRef"`
|
||||
// lower limit for the number of pods that can be set by the autoscaler, default 1.
|
||||
MinReplicas *int32 `json:"minReplicas,omitempty"`
|
||||
// upper limit for the number of pods that can be set by the autoscaler. It cannot be smaller than MinReplicas.
|
||||
MaxReplicas int32 `json:"maxReplicas"`
|
||||
// target average CPU utilization (represented as a percentage of requested CPU) over all the pods;
|
||||
// if not specified the default autoscaling policy will be used.
|
||||
TargetCPUUtilizationPercentage *int32 `json:"targetCPUUtilizationPercentage,omitempty"`
|
||||
}
|
||||
|
||||
// current status of a horizontal pod autoscaler
|
||||
type HorizontalPodAutoscalerStatus struct {
|
||||
// most recent generation observed by this autoscaler.
|
||||
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// last time the HorizontalPodAutoscaler scaled the number of pods;
|
||||
// used by the autoscaler to control how often the number of pods is changed.
|
||||
LastScaleTime *unversioned.Time `json:"lastScaleTime,omitempty"`
|
||||
|
||||
// current number of replicas of pods managed by this autoscaler.
|
||||
CurrentReplicas int32 `json:"currentReplicas"`
|
||||
|
||||
// desired number of replicas of pods managed by this autoscaler.
|
||||
DesiredReplicas int32 `json:"desiredReplicas"`
|
||||
|
||||
// current average CPU utilization over all pods, represented as a percentage of requested CPU,
|
||||
// e.g. 70 means that an average pod is using now 70% of its requested CPU.
|
||||
CurrentCPUUtilizationPercentage *int32 `json:"currentCPUUtilizationPercentage,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// configuration of a horizontal pod autoscaler.
|
||||
type HorizontalPodAutoscaler struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// behaviour of autoscaler. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.
|
||||
Spec HorizontalPodAutoscalerSpec `json:"spec,omitempty"`
|
||||
|
||||
// current information about the autoscaler.
|
||||
Status HorizontalPodAutoscalerStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// list of horizontal pod autoscaler objects.
|
||||
type HorizontalPodAutoscalerList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// list of horizontal pod autoscaler objects.
|
||||
Items []HorizontalPodAutoscaler `json:"items"`
|
||||
}
|
||||
186
vendor/k8s.io/client-go/1.4/pkg/apis/autoscaling/zz_generated.deepcopy.go
generated
vendored
186
vendor/k8s.io/client-go/1.4/pkg/apis/autoscaling/zz_generated.deepcopy.go
generated
vendored
|
|
@ -1,186 +0,0 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package autoscaling
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.4/pkg/api"
|
||||
unversioned "k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
conversion "k8s.io/client-go/1.4/pkg/conversion"
|
||||
runtime "k8s.io/client-go/1.4/pkg/runtime"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(RegisterDeepCopies)
|
||||
}
|
||||
|
||||
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
|
||||
// to allow building arbitrary schemes.
|
||||
func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedDeepCopyFuncs(
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_CrossVersionObjectReference, InType: reflect.TypeOf(&CrossVersionObjectReference{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_HorizontalPodAutoscaler, InType: reflect.TypeOf(&HorizontalPodAutoscaler{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_HorizontalPodAutoscalerList, InType: reflect.TypeOf(&HorizontalPodAutoscalerList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_HorizontalPodAutoscalerSpec, InType: reflect.TypeOf(&HorizontalPodAutoscalerSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_HorizontalPodAutoscalerStatus, InType: reflect.TypeOf(&HorizontalPodAutoscalerStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_Scale, InType: reflect.TypeOf(&Scale{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_ScaleSpec, InType: reflect.TypeOf(&ScaleSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_autoscaling_ScaleStatus, InType: reflect.TypeOf(&ScaleStatus{})},
|
||||
)
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_CrossVersionObjectReference(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*CrossVersionObjectReference)
|
||||
out := out.(*CrossVersionObjectReference)
|
||||
out.Kind = in.Kind
|
||||
out.Name = in.Name
|
||||
out.APIVersion = in.APIVersion
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_HorizontalPodAutoscaler(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*HorizontalPodAutoscaler)
|
||||
out := out.(*HorizontalPodAutoscaler)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_autoscaling_HorizontalPodAutoscalerSpec(&in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_autoscaling_HorizontalPodAutoscalerStatus(&in.Status, &out.Status, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_HorizontalPodAutoscalerList(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*HorizontalPodAutoscalerList)
|
||||
out := out.(*HorizontalPodAutoscalerList)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]HorizontalPodAutoscaler, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_autoscaling_HorizontalPodAutoscaler(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_HorizontalPodAutoscalerSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*HorizontalPodAutoscalerSpec)
|
||||
out := out.(*HorizontalPodAutoscalerSpec)
|
||||
out.ScaleTargetRef = in.ScaleTargetRef
|
||||
if in.MinReplicas != nil {
|
||||
in, out := &in.MinReplicas, &out.MinReplicas
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
} else {
|
||||
out.MinReplicas = nil
|
||||
}
|
||||
out.MaxReplicas = in.MaxReplicas
|
||||
if in.TargetCPUUtilizationPercentage != nil {
|
||||
in, out := &in.TargetCPUUtilizationPercentage, &out.TargetCPUUtilizationPercentage
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
} else {
|
||||
out.TargetCPUUtilizationPercentage = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_HorizontalPodAutoscalerStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*HorizontalPodAutoscalerStatus)
|
||||
out := out.(*HorizontalPodAutoscalerStatus)
|
||||
if in.ObservedGeneration != nil {
|
||||
in, out := &in.ObservedGeneration, &out.ObservedGeneration
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
} else {
|
||||
out.ObservedGeneration = nil
|
||||
}
|
||||
if in.LastScaleTime != nil {
|
||||
in, out := &in.LastScaleTime, &out.LastScaleTime
|
||||
*out = new(unversioned.Time)
|
||||
**out = (*in).DeepCopy()
|
||||
} else {
|
||||
out.LastScaleTime = nil
|
||||
}
|
||||
out.CurrentReplicas = in.CurrentReplicas
|
||||
out.DesiredReplicas = in.DesiredReplicas
|
||||
if in.CurrentCPUUtilizationPercentage != nil {
|
||||
in, out := &in.CurrentCPUUtilizationPercentage, &out.CurrentCPUUtilizationPercentage
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
} else {
|
||||
out.CurrentCPUUtilizationPercentage = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_Scale(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Scale)
|
||||
out := out.(*Scale)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Spec = in.Spec
|
||||
out.Status = in.Status
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_ScaleSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ScaleSpec)
|
||||
out := out.(*ScaleSpec)
|
||||
out.Replicas = in.Replicas
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_autoscaling_ScaleStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ScaleStatus)
|
||||
out := out.(*ScaleStatus)
|
||||
out.Replicas = in.Replicas
|
||||
out.Selector = in.Selector
|
||||
return nil
|
||||
}
|
||||
}
|
||||
4676
vendor/k8s.io/client-go/1.4/pkg/apis/batch/types.generated.go
generated
vendored
4676
vendor/k8s.io/client-go/1.4/pkg/apis/batch/types.generated.go
generated
vendored
File diff suppressed because it is too large
Load diff
244
vendor/k8s.io/client-go/1.4/pkg/apis/batch/types.go
generated
vendored
244
vendor/k8s.io/client-go/1.4/pkg/apis/batch/types.go
generated
vendored
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package batch
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// Job represents the configuration of a single job.
|
||||
type Job struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec is a structure defining the expected behavior of a job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec JobSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is a structure describing current status of a job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status JobStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// JobList is a collection of jobs.
|
||||
type JobList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of Job.
|
||||
Items []Job `json:"items"`
|
||||
}
|
||||
|
||||
// JobTemplate describes a template for creating copies of a predefined pod.
|
||||
type JobTemplate struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Template defines jobs that will be created from this template
|
||||
// http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Template JobTemplateSpec `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// JobTemplateSpec describes the data a Job should have when created from a template
|
||||
type JobTemplateSpec struct {
|
||||
// Standard object's metadata of the jobs created from this template.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Specification of the desired behavior of the job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec JobSpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// JobSpec describes how the job execution will look like.
|
||||
type JobSpec struct {
|
||||
|
||||
// Parallelism specifies the maximum desired number of pods the job should
|
||||
// run at any given time. The actual number of pods running in steady state will
|
||||
// be less than this number when ((.spec.completions - .status.successful) < .spec.parallelism),
|
||||
// i.e. when the work left to do is less than max parallelism.
|
||||
Parallelism *int32 `json:"parallelism,omitempty"`
|
||||
|
||||
// Completions specifies the desired number of successfully finished pods the
|
||||
// job should be run with. Setting to nil means that the success of any
|
||||
// pod signals the success of all pods, and allows parallelism to have any positive
|
||||
// value. Setting to 1 means that parallelism is limited to 1 and the success of that
|
||||
// pod signals the success of the job.
|
||||
Completions *int32 `json:"completions,omitempty"`
|
||||
|
||||
// Optional duration in seconds relative to the startTime that the job may be active
|
||||
// before the system tries to terminate it; value must be positive integer
|
||||
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
|
||||
|
||||
// Selector is a label query over pods that should match the pod count.
|
||||
// Normally, the system sets this field for you.
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// ManualSelector controls generation of pod labels and pod selectors.
|
||||
// Leave `manualSelector` unset unless you are certain what you are doing.
|
||||
// When false or unset, the system pick labels unique to this job
|
||||
// and appends those labels to the pod template. When true,
|
||||
// the user is responsible for picking unique labels and specifying
|
||||
// the selector. Failure to pick a unique label may cause this
|
||||
// and other jobs to not function correctly. However, You may see
|
||||
// `manualSelector=true` in jobs that were created with the old `extensions/v1beta1`
|
||||
// API.
|
||||
ManualSelector *bool `json:"manualSelector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created when
|
||||
// executing a job.
|
||||
Template api.PodTemplateSpec `json:"template"`
|
||||
}
|
||||
|
||||
// JobStatus represents the current state of a Job.
|
||||
type JobStatus struct {
|
||||
|
||||
// Conditions represent the latest available observations of an object's current state.
|
||||
Conditions []JobCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
|
||||
|
||||
// StartTime represents time when the job was acknowledged by the Job Manager.
|
||||
// It is not guaranteed to be set in happens-before order across separate operations.
|
||||
// It is represented in RFC3339 form and is in UTC.
|
||||
StartTime *unversioned.Time `json:"startTime,omitempty"`
|
||||
|
||||
// CompletionTime represents time when the job was completed. It is not guaranteed to
|
||||
// be set in happens-before order across separate operations.
|
||||
// It is represented in RFC3339 form and is in UTC.
|
||||
CompletionTime *unversioned.Time `json:"completionTime,omitempty"`
|
||||
|
||||
// Active is the number of actively running pods.
|
||||
Active int32 `json:"active,omitempty"`
|
||||
|
||||
// Succeeded is the number of pods which reached Phase Succeeded.
|
||||
Succeeded int32 `json:"succeeded,omitempty"`
|
||||
|
||||
// Failed is the number of pods which reached Phase Failed.
|
||||
Failed int32 `json:"failed,omitempty"`
|
||||
}
|
||||
|
||||
type JobConditionType string
|
||||
|
||||
// These are valid conditions of a job.
|
||||
const (
|
||||
// JobComplete means the job has completed its execution.
|
||||
JobComplete JobConditionType = "Complete"
|
||||
// JobFailed means the job has failed its execution.
|
||||
JobFailed JobConditionType = "Failed"
|
||||
)
|
||||
|
||||
// JobCondition describes current state of a job.
|
||||
type JobCondition struct {
|
||||
// Type of job condition, Complete or Failed.
|
||||
Type JobConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status api.ConditionStatus `json:"status"`
|
||||
// Last time the condition was checked.
|
||||
LastProbeTime unversioned.Time `json:"lastProbeTime,omitempty"`
|
||||
// Last time the condition transit from one status to another.
|
||||
LastTransitionTime unversioned.Time `json:"lastTransitionTime,omitempty"`
|
||||
// (brief) reason for the condition's last transition.
|
||||
Reason string `json:"reason,omitempty"`
|
||||
// Human readable message indicating details about last transition.
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// ScheduledJob represents the configuration of a single scheduled job.
|
||||
type ScheduledJob struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec is a structure defining the expected behavior of a job, including the schedule.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec ScheduledJobSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is a structure describing current status of a job.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status ScheduledJobStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// ScheduledJobList is a collection of scheduled jobs.
|
||||
type ScheduledJobList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of ScheduledJob.
|
||||
Items []ScheduledJob `json:"items"`
|
||||
}
|
||||
|
||||
// ScheduledJobSpec describes how the job execution will look like and when it will actually run.
|
||||
type ScheduledJobSpec struct {
|
||||
|
||||
// Schedule contains the schedule in Cron format, see https://en.wikipedia.org/wiki/Cron.
|
||||
Schedule string `json:"schedule"`
|
||||
|
||||
// Optional deadline in seconds for starting the job if it misses scheduled
|
||||
// time for any reason. Missed jobs executions will be counted as failed ones.
|
||||
StartingDeadlineSeconds *int64 `json:"startingDeadlineSeconds,omitempty"`
|
||||
|
||||
// ConcurrencyPolicy specifies how to treat concurrent executions of a Job.
|
||||
ConcurrencyPolicy ConcurrencyPolicy `json:"concurrencyPolicy,omitempty"`
|
||||
|
||||
// Suspend flag tells the controller to suspend subsequent executions, it does
|
||||
// not apply to already started executions. Defaults to false.
|
||||
Suspend *bool `json:"suspend,omitempty"`
|
||||
|
||||
// JobTemplate is the object that describes the job that will be created when
|
||||
// executing a ScheduledJob.
|
||||
JobTemplate JobTemplateSpec `json:"jobTemplate"`
|
||||
}
|
||||
|
||||
// ConcurrencyPolicy describes how the job will be handled.
|
||||
// Only one of the following concurrent policies may be specified.
|
||||
// If none of the following policies is specified, the default one
|
||||
// is AllowConcurrent.
|
||||
type ConcurrencyPolicy string
|
||||
|
||||
const (
|
||||
// AllowConcurrent allows ScheduledJobs to run concurrently.
|
||||
AllowConcurrent ConcurrencyPolicy = "Allow"
|
||||
|
||||
// ForbidConcurrent forbids concurrent runs, skipping next run if previous
|
||||
// hasn't finished yet.
|
||||
ForbidConcurrent ConcurrencyPolicy = "Forbid"
|
||||
|
||||
// ReplaceConcurrent cancels currently running job and replaces it with a new one.
|
||||
ReplaceConcurrent ConcurrencyPolicy = "Replace"
|
||||
)
|
||||
|
||||
// ScheduledJobStatus represents the current state of a Job.
|
||||
type ScheduledJobStatus struct {
|
||||
// Active holds pointers to currently running jobs.
|
||||
Active []api.ObjectReference `json:"active,omitempty"`
|
||||
|
||||
// LastScheduleTime keeps information of when was the last time the job was successfully scheduled.
|
||||
LastScheduleTime *unversioned.Time `json:"lastScheduleTime,omitempty"`
|
||||
}
|
||||
307
vendor/k8s.io/client-go/1.4/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
307
vendor/k8s.io/client-go/1.4/pkg/apis/batch/zz_generated.deepcopy.go
generated
vendored
|
|
@ -1,307 +0,0 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package batch
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.4/pkg/api"
|
||||
unversioned "k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
conversion "k8s.io/client-go/1.4/pkg/conversion"
|
||||
runtime "k8s.io/client-go/1.4/pkg/runtime"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(RegisterDeepCopies)
|
||||
}
|
||||
|
||||
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
|
||||
// to allow building arbitrary schemes.
|
||||
func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedDeepCopyFuncs(
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_Job, InType: reflect.TypeOf(&Job{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_JobCondition, InType: reflect.TypeOf(&JobCondition{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_JobList, InType: reflect.TypeOf(&JobList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_JobSpec, InType: reflect.TypeOf(&JobSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_JobStatus, InType: reflect.TypeOf(&JobStatus{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_JobTemplate, InType: reflect.TypeOf(&JobTemplate{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_JobTemplateSpec, InType: reflect.TypeOf(&JobTemplateSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_ScheduledJob, InType: reflect.TypeOf(&ScheduledJob{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_ScheduledJobList, InType: reflect.TypeOf(&ScheduledJobList{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_ScheduledJobSpec, InType: reflect.TypeOf(&ScheduledJobSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_batch_ScheduledJobStatus, InType: reflect.TypeOf(&ScheduledJobStatus{})},
|
||||
)
|
||||
}
|
||||
|
||||
func DeepCopy_batch_Job(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Job)
|
||||
out := out.(*Job)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_batch_JobSpec(&in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_batch_JobStatus(&in.Status, &out.Status, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_JobCondition(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*JobCondition)
|
||||
out := out.(*JobCondition)
|
||||
out.Type = in.Type
|
||||
out.Status = in.Status
|
||||
out.LastProbeTime = in.LastProbeTime.DeepCopy()
|
||||
out.LastTransitionTime = in.LastTransitionTime.DeepCopy()
|
||||
out.Reason = in.Reason
|
||||
out.Message = in.Message
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_JobList(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*JobList)
|
||||
out := out.(*JobList)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Job, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_batch_Job(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_JobSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*JobSpec)
|
||||
out := out.(*JobSpec)
|
||||
if in.Parallelism != nil {
|
||||
in, out := &in.Parallelism, &out.Parallelism
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
} else {
|
||||
out.Parallelism = nil
|
||||
}
|
||||
if in.Completions != nil {
|
||||
in, out := &in.Completions, &out.Completions
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
} else {
|
||||
out.Completions = nil
|
||||
}
|
||||
if in.ActiveDeadlineSeconds != nil {
|
||||
in, out := &in.ActiveDeadlineSeconds, &out.ActiveDeadlineSeconds
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
} else {
|
||||
out.ActiveDeadlineSeconds = nil
|
||||
}
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
*out = new(unversioned.LabelSelector)
|
||||
if err := unversioned.DeepCopy_unversioned_LabelSelector(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
if in.ManualSelector != nil {
|
||||
in, out := &in.ManualSelector, &out.ManualSelector
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
} else {
|
||||
out.ManualSelector = nil
|
||||
}
|
||||
if err := api.DeepCopy_api_PodTemplateSpec(&in.Template, &out.Template, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_JobStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*JobStatus)
|
||||
out := out.(*JobStatus)
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]JobCondition, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_batch_JobCondition(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Conditions = nil
|
||||
}
|
||||
if in.StartTime != nil {
|
||||
in, out := &in.StartTime, &out.StartTime
|
||||
*out = new(unversioned.Time)
|
||||
**out = (*in).DeepCopy()
|
||||
} else {
|
||||
out.StartTime = nil
|
||||
}
|
||||
if in.CompletionTime != nil {
|
||||
in, out := &in.CompletionTime, &out.CompletionTime
|
||||
*out = new(unversioned.Time)
|
||||
**out = (*in).DeepCopy()
|
||||
} else {
|
||||
out.CompletionTime = nil
|
||||
}
|
||||
out.Active = in.Active
|
||||
out.Succeeded = in.Succeeded
|
||||
out.Failed = in.Failed
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_JobTemplate(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*JobTemplate)
|
||||
out := out.(*JobTemplate)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_batch_JobTemplateSpec(&in.Template, &out.Template, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_JobTemplateSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*JobTemplateSpec)
|
||||
out := out.(*JobTemplateSpec)
|
||||
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_batch_JobSpec(&in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_ScheduledJob(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ScheduledJob)
|
||||
out := out.(*ScheduledJob)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_batch_ScheduledJobSpec(&in.Spec, &out.Spec, c); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := DeepCopy_batch_ScheduledJobStatus(&in.Status, &out.Status, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_ScheduledJobList(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ScheduledJobList)
|
||||
out := out.(*ScheduledJobList)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]ScheduledJob, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_batch_ScheduledJob(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_ScheduledJobSpec(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ScheduledJobSpec)
|
||||
out := out.(*ScheduledJobSpec)
|
||||
out.Schedule = in.Schedule
|
||||
if in.StartingDeadlineSeconds != nil {
|
||||
in, out := &in.StartingDeadlineSeconds, &out.StartingDeadlineSeconds
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
} else {
|
||||
out.StartingDeadlineSeconds = nil
|
||||
}
|
||||
out.ConcurrencyPolicy = in.ConcurrencyPolicy
|
||||
if in.Suspend != nil {
|
||||
in, out := &in.Suspend, &out.Suspend
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
} else {
|
||||
out.Suspend = nil
|
||||
}
|
||||
if err := DeepCopy_batch_JobTemplateSpec(&in.JobTemplate, &out.JobTemplate, c); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_batch_ScheduledJobStatus(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ScheduledJobStatus)
|
||||
out := out.(*ScheduledJobStatus)
|
||||
if in.Active != nil {
|
||||
in, out := &in.Active, &out.Active
|
||||
*out = make([]api.ObjectReference, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.Active = nil
|
||||
}
|
||||
if in.LastScheduleTime != nil {
|
||||
in, out := &in.LastScheduleTime, &out.LastScheduleTime
|
||||
*out = new(unversioned.Time)
|
||||
**out = (*in).DeepCopy()
|
||||
} else {
|
||||
out.LastScheduleTime = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
37
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/helpers.go
generated
vendored
37
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/helpers.go
generated
vendored
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SysctlsFromPodSecurityPolicyAnnotation parses an annotation value of the key
|
||||
// SysctlsSecurityPolocyAnnotationKey into a slice of sysctls. An empty slice
|
||||
// is returned if annotation is the empty string.
|
||||
func SysctlsFromPodSecurityPolicyAnnotation(annotation string) ([]string, error) {
|
||||
if len(annotation) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
return strings.Split(annotation, ","), nil
|
||||
}
|
||||
|
||||
// PodAnnotationsFromSysctls creates an annotation value for a slice of Sysctls.
|
||||
func PodAnnotationsFromSysctls(sysctls []string) string {
|
||||
return strings.Join(sysctls, ",")
|
||||
}
|
||||
83
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/register.go
generated
vendored
83
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/register.go
generated
vendored
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/apis/autoscaling"
|
||||
"k8s.io/client-go/1.4/pkg/apis/batch"
|
||||
"k8s.io/client-go/1.4/pkg/runtime"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = "extensions"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) unversioned.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) unversioned.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
// TODO this gets cleaned up when the types are fixed
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Deployment{},
|
||||
&DeploymentList{},
|
||||
&DeploymentRollback{},
|
||||
&autoscaling.HorizontalPodAutoscaler{},
|
||||
&autoscaling.HorizontalPodAutoscalerList{},
|
||||
&batch.Job{},
|
||||
&batch.JobList{},
|
||||
&batch.JobTemplate{},
|
||||
&ReplicationControllerDummy{},
|
||||
&Scale{},
|
||||
&ThirdPartyResource{},
|
||||
&ThirdPartyResourceList{},
|
||||
&DaemonSetList{},
|
||||
&DaemonSet{},
|
||||
&ThirdPartyResourceData{},
|
||||
&ThirdPartyResourceDataList{},
|
||||
&Ingress{},
|
||||
&IngressList{},
|
||||
&api.ListOptions{},
|
||||
&api.DeleteOptions{},
|
||||
&ReplicaSet{},
|
||||
&ReplicaSetList{},
|
||||
&api.ExportOptions{},
|
||||
&PodSecurityPolicy{},
|
||||
&PodSecurityPolicyList{},
|
||||
&NetworkPolicy{},
|
||||
&NetworkPolicyList{},
|
||||
&StorageClass{},
|
||||
&StorageClassList{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
18819
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/types.generated.go
generated
vendored
18819
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/types.generated.go
generated
vendored
File diff suppressed because it is too large
Load diff
951
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/types.go
generated
vendored
951
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/types.go
generated
vendored
|
|
@ -1,951 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file (together with pkg/apis/extensions/v1beta1/types.go) contain the experimental
|
||||
types in kubernetes. These API objects are experimental, meaning that the
|
||||
APIs may be broken at any time by the kubernetes team.
|
||||
|
||||
DISCLAIMER: The implementation of the experimental API group itself is
|
||||
a temporary one meant as a stopgap solution until kubernetes has proper
|
||||
support for multiple API groups. The transition may require changes
|
||||
beyond registration differences. In other words, experimental API group
|
||||
support is experimental.
|
||||
*/
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.4/pkg/api"
|
||||
"k8s.io/client-go/1.4/pkg/api/resource"
|
||||
"k8s.io/client-go/1.4/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.4/pkg/util/intstr"
|
||||
)
|
||||
|
||||
const (
|
||||
// SysctlsPodSecurityPolicyAnnotationKey represents the key of a whitelist of
|
||||
// allowed safe and unsafe sysctls in a pod spec. It's a comma-separated list of plain sysctl
|
||||
// names or sysctl patterns (which end in *). The string "*" matches all sysctls.
|
||||
SysctlsPodSecurityPolicyAnnotationKey string = "security.alpha.kubernetes.io/sysctls"
|
||||
)
|
||||
|
||||
// describes the attributes of a scale subresource
|
||||
type ScaleSpec struct {
|
||||
// desired number of instances for the scaled object.
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
}
|
||||
|
||||
// represents the current status of a scale subresource.
|
||||
type ScaleStatus struct {
|
||||
// actual number of observed instances of the scaled object.
|
||||
Replicas int32 `json:"replicas"`
|
||||
|
||||
// label query over pods that should match the replicas count.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
// +noMethods=true
|
||||
|
||||
// represents a scaling request for a resource.
|
||||
type Scale struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object metadata; More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata.
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// defines the behavior of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status.
|
||||
Spec ScaleSpec `json:"spec,omitempty"`
|
||||
|
||||
// current status of the scale. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status. Read-only.
|
||||
Status ScaleStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Dummy definition
|
||||
type ReplicationControllerDummy struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
}
|
||||
|
||||
// Alpha-level support for Custom Metrics in HPA (as annotations).
|
||||
type CustomMetricTarget struct {
|
||||
// Custom Metric name.
|
||||
Name string `json:"name"`
|
||||
// Custom Metric value (average).
|
||||
TargetValue resource.Quantity `json:"value"`
|
||||
}
|
||||
|
||||
type CustomMetricTargetList struct {
|
||||
Items []CustomMetricTarget `json:"items"`
|
||||
}
|
||||
|
||||
type CustomMetricCurrentStatus struct {
|
||||
// Custom Metric name.
|
||||
Name string `json:"name"`
|
||||
// Custom Metric value (average).
|
||||
CurrentValue resource.Quantity `json:"value"`
|
||||
}
|
||||
|
||||
type CustomMetricCurrentStatusList struct {
|
||||
Items []CustomMetricCurrentStatus `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
// +nonNamespaced=true
|
||||
|
||||
// A ThirdPartyResource is a generic representation of a resource, it is used by add-ons and plugins to add new resource
|
||||
// types to the API. It consists of one or more Versions of the api.
|
||||
type ThirdPartyResource struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
|
||||
// Standard object metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Description is the description of this object.
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// Versions are versions for this third party object
|
||||
Versions []APIVersion `json:"versions,omitempty"`
|
||||
}
|
||||
|
||||
type ThirdPartyResourceList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
|
||||
// Standard list metadata.
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of horizontal pod autoscalers.
|
||||
Items []ThirdPartyResource `json:"items"`
|
||||
}
|
||||
|
||||
// An APIVersion represents a single concrete version of an object model.
|
||||
// TODO: we should consider merge this struct with GroupVersion in unversioned.go
|
||||
type APIVersion struct {
|
||||
// Name of this version (e.g. 'v1').
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// An internal object, used for versioned storage in etcd. Not exposed to the end user.
|
||||
type ThirdPartyResourceData struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object metadata.
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Data is the raw JSON data for this data.
|
||||
Data []byte `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
|
||||
type Deployment struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Specification of the desired behavior of the Deployment.
|
||||
Spec DeploymentSpec `json:"spec,omitempty"`
|
||||
|
||||
// Most recently observed status of the Deployment.
|
||||
Status DeploymentStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type DeploymentSpec struct {
|
||||
// Number of desired pods. This is a pointer to distinguish between explicit
|
||||
// zero and not specified. Defaults to 1.
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
|
||||
// Label selector for pods. Existing ReplicaSets whose pods are
|
||||
// selected by this will be the ones affected by this deployment.
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// Template describes the pods that will be created.
|
||||
Template api.PodTemplateSpec `json:"template"`
|
||||
|
||||
// The deployment strategy to use to replace existing pods with new ones.
|
||||
Strategy DeploymentStrategy `json:"strategy,omitempty"`
|
||||
|
||||
// Minimum number of seconds for which a newly created pod should be ready
|
||||
// without any of its container crashing, for it to be considered available.
|
||||
// Defaults to 0 (pod will be considered available as soon as it is ready)
|
||||
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
|
||||
|
||||
// The number of old ReplicaSets to retain to allow rollback.
|
||||
// This is a pointer to distinguish between explicit zero and not specified.
|
||||
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
|
||||
|
||||
// Indicates that the deployment is paused and will not be processed by the
|
||||
// deployment controller.
|
||||
Paused bool `json:"paused,omitempty"`
|
||||
// The config this deployment is rolling back to. Will be cleared after rollback is done.
|
||||
RollbackTo *RollbackConfig `json:"rollbackTo,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentRollback stores the information required to rollback a deployment.
|
||||
type DeploymentRollback struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Required: This must match the Name of a deployment.
|
||||
Name string `json:"name"`
|
||||
// The annotations to be updated to a deployment
|
||||
UpdatedAnnotations map[string]string `json:"updatedAnnotations,omitempty"`
|
||||
// The config of this deployment rollback.
|
||||
RollbackTo RollbackConfig `json:"rollbackTo"`
|
||||
}
|
||||
|
||||
type RollbackConfig struct {
|
||||
// The revision to rollback to. If set to 0, rollbck to the last revision.
|
||||
Revision int64 `json:"revision,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
// DefaultDeploymentUniqueLabelKey is the default key of the selector that is added
|
||||
// to existing RCs (and label key that is added to its pods) to prevent the existing RCs
|
||||
// to select new pods (and old pods being select by new RC).
|
||||
DefaultDeploymentUniqueLabelKey string = "pod-template-hash"
|
||||
)
|
||||
|
||||
type DeploymentStrategy struct {
|
||||
// Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate.
|
||||
Type DeploymentStrategyType `json:"type,omitempty"`
|
||||
|
||||
// Rolling update config params. Present only if DeploymentStrategyType =
|
||||
// RollingUpdate.
|
||||
//---
|
||||
// TODO: Update this to follow our convention for oneOf, whatever we decide it
|
||||
// to be.
|
||||
RollingUpdate *RollingUpdateDeployment `json:"rollingUpdate,omitempty"`
|
||||
}
|
||||
|
||||
type DeploymentStrategyType string
|
||||
|
||||
const (
|
||||
// Kill all existing pods before creating new ones.
|
||||
RecreateDeploymentStrategyType DeploymentStrategyType = "Recreate"
|
||||
|
||||
// Replace the old RCs by new one using rolling update i.e gradually scale down the old RCs and scale up the new one.
|
||||
RollingUpdateDeploymentStrategyType DeploymentStrategyType = "RollingUpdate"
|
||||
)
|
||||
|
||||
// Spec to control the desired behavior of rolling update.
|
||||
type RollingUpdateDeployment struct {
|
||||
// The maximum number of pods that can be unavailable during the update.
|
||||
// Value can be an absolute number (ex: 5) or a percentage of total pods at the start of update (ex: 10%).
|
||||
// Absolute number is calculated from percentage by rounding up.
|
||||
// This can not be 0 if MaxSurge is 0.
|
||||
// By default, a fixed value of 1 is used.
|
||||
// Example: when this is set to 30%, the old RC can be scaled down by 30%
|
||||
// immediately when the rolling update starts. Once new pods are ready, old RC
|
||||
// can be scaled down further, followed by scaling up the new RC, ensuring
|
||||
// that at least 70% of original number of pods are available at all times
|
||||
// during the update.
|
||||
MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty"`
|
||||
|
||||
// The maximum number of pods that can be scheduled above the original number of
|
||||
// pods.
|
||||
// Value can be an absolute number (ex: 5) or a percentage of total pods at
|
||||
// the start of the update (ex: 10%). This can not be 0 if MaxUnavailable is 0.
|
||||
// Absolute number is calculated from percentage by rounding up.
|
||||
// By default, a value of 1 is used.
|
||||
// Example: when this is set to 30%, the new RC can be scaled up by 30%
|
||||
// immediately when the rolling update starts. Once old pods have been killed,
|
||||
// new RC can be scaled up further, ensuring that total number of pods running
|
||||
// at any time during the update is atmost 130% of original pods.
|
||||
MaxSurge intstr.IntOrString `json:"maxSurge,omitempty"`
|
||||
}
|
||||
|
||||
type DeploymentStatus struct {
|
||||
// The generation observed by the deployment controller.
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// Total number of non-terminated pods targeted by this deployment (their labels match the selector).
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
|
||||
// Total number of non-terminated pods targeted by this deployment that have the desired template spec.
|
||||
UpdatedReplicas int32 `json:"updatedReplicas,omitempty"`
|
||||
|
||||
// Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.
|
||||
AvailableReplicas int32 `json:"availableReplicas,omitempty"`
|
||||
|
||||
// Total number of unavailable pods targeted by this deployment.
|
||||
UnavailableReplicas int32 `json:"unavailableReplicas,omitempty"`
|
||||
}
|
||||
|
||||
type DeploymentList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of deployments.
|
||||
Items []Deployment `json:"items"`
|
||||
}
|
||||
|
||||
// TODO(madhusudancs): Uncomment while implementing DaemonSet updates.
|
||||
/* Commenting out for v1.2. We are planning to bring these types back with a more robust DaemonSet update implementation in v1.3, hence not deleting but just commenting the types out.
|
||||
type DaemonSetUpdateStrategy struct {
|
||||
// Type of daemon set update. Only "RollingUpdate" is supported at this time. Default is RollingUpdate.
|
||||
Type DaemonSetUpdateStrategyType `json:"type,omitempty"`
|
||||
|
||||
// Rolling update config params. Present only if DaemonSetUpdateStrategy =
|
||||
// RollingUpdate.
|
||||
//---
|
||||
// TODO: Update this to follow our convention for oneOf, whatever we decide it
|
||||
// to be. Same as DeploymentStrategy.RollingUpdate.
|
||||
RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty"`
|
||||
}
|
||||
|
||||
type DaemonSetUpdateStrategyType string
|
||||
|
||||
const (
|
||||
// Replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
|
||||
RollingUpdateDaemonSetStrategyType DaemonSetUpdateStrategyType = "RollingUpdate"
|
||||
)
|
||||
|
||||
// Spec to control the desired behavior of daemon set rolling update.
|
||||
type RollingUpdateDaemonSet struct {
|
||||
// The maximum number of DaemonSet pods that can be unavailable during the
|
||||
// update. Value can be an absolute number (ex: 5) or a percentage of total
|
||||
// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
|
||||
// number is calculated from percentage by rounding up.
|
||||
// This cannot be 0.
|
||||
// Default value is 1.
|
||||
// Example: when this is set to 30%, 30% of the currently running DaemonSet
|
||||
// pods can be stopped for an update at any given time. The update starts
|
||||
// by stopping at most 30% of the currently running DaemonSet pods and then
|
||||
// brings up new DaemonSet pods in their place. Once the new pods are ready,
|
||||
// it then proceeds onto other DaemonSet pods, thus ensuring that at least
|
||||
// 70% of original number of DaemonSet pods are available at all times
|
||||
// during the update.
|
||||
MaxUnavailable intstr.IntOrString `json:"maxUnavailable,omitempty"`
|
||||
|
||||
// Minimum number of seconds for which a newly created DaemonSet pod should
|
||||
// be ready without any of its container crashing, for it to be considered
|
||||
// available. Defaults to 0 (pod will be considered available as soon as it
|
||||
// is ready).
|
||||
MinReadySeconds int `json:"minReadySeconds,omitempty"`
|
||||
}
|
||||
*/
|
||||
|
||||
// DaemonSetSpec is the specification of a daemon set.
|
||||
type DaemonSetSpec struct {
|
||||
// Selector is a label query over pods that are managed by the daemon set.
|
||||
// Must match in order to be controlled.
|
||||
// If empty, defaulted to labels on Pod template.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created.
|
||||
// The DaemonSet will create exactly one copy of this pod on every node
|
||||
// that matches the template's node selector (or on every node if no node
|
||||
// selector is specified).
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/replication-controller.md#pod-template
|
||||
Template api.PodTemplateSpec `json:"template"`
|
||||
|
||||
// TODO(madhusudancs): Uncomment while implementing DaemonSet updates.
|
||||
/* Commenting out for v1.2. We are planning to bring these fields back with a more robust DaemonSet update implementation in v1.3, hence not deleting but just commenting these fields out.
|
||||
// Update strategy to replace existing DaemonSet pods with new pods.
|
||||
UpdateStrategy DaemonSetUpdateStrategy `json:"updateStrategy,omitempty"`
|
||||
|
||||
// Label key that is added to DaemonSet pods to distinguish between old and
|
||||
// new pod templates during DaemonSet update.
|
||||
// Users can set this to an empty string to indicate that the system should
|
||||
// not add any label. If unspecified, system uses
|
||||
// DefaultDaemonSetUniqueLabelKey("daemonset.kubernetes.io/podTemplateHash").
|
||||
// Value of this key is hash of DaemonSetSpec.PodTemplateSpec.
|
||||
// No label is added if this is set to empty string.
|
||||
UniqueLabelKey string `json:"uniqueLabelKey,omitempty"`
|
||||
*/
|
||||
}
|
||||
|
||||
const (
|
||||
// DefaultDaemonSetUniqueLabelKey is the default key of the labels that is added
|
||||
// to daemon set pods to distinguish between old and new pod templates during
|
||||
// DaemonSet update. See DaemonSetSpec's UniqueLabelKey field for more information.
|
||||
DefaultDaemonSetUniqueLabelKey string = "daemonset.kubernetes.io/podTemplateHash"
|
||||
)
|
||||
|
||||
// DaemonSetStatus represents the current status of a daemon set.
|
||||
type DaemonSetStatus struct {
|
||||
// CurrentNumberScheduled is the number of nodes that are running at least 1
|
||||
// daemon pod and are supposed to run the daemon pod.
|
||||
CurrentNumberScheduled int32 `json:"currentNumberScheduled"`
|
||||
|
||||
// NumberMisscheduled is the number of nodes that are running the daemon pod, but are
|
||||
// not supposed to run the daemon pod.
|
||||
NumberMisscheduled int32 `json:"numberMisscheduled"`
|
||||
|
||||
// DesiredNumberScheduled is the total number of nodes that should be running the daemon
|
||||
// pod (including nodes correctly running the daemon pod).
|
||||
DesiredNumberScheduled int32 `json:"desiredNumberScheduled"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// DaemonSet represents the configuration of a daemon set.
|
||||
type DaemonSet struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the desired behavior of this daemon set.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec DaemonSetSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current status of this daemon set. This data may be
|
||||
// out of date by some window of time.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status DaemonSetStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// DaemonSetList is a collection of daemon sets.
|
||||
type DaemonSetList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is a list of daemon sets.
|
||||
Items []DaemonSet `json:"items"`
|
||||
}
|
||||
|
||||
type ThirdPartyResourceDataList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
// Items is a list of third party objects
|
||||
Items []ThirdPartyResourceData `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// Ingress is a collection of rules that allow inbound connections to reach the
|
||||
// endpoints defined by a backend. An Ingress can be configured to give services
|
||||
// externally-reachable urls, load balance traffic, terminate SSL, offer name
|
||||
// based virtual hosting etc.
|
||||
type Ingress struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec is the desired state of the Ingress.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Spec IngressSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current state of the Ingress.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status IngressStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// IngressList is a collection of Ingress.
|
||||
type IngressList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of Ingress.
|
||||
Items []Ingress `json:"items"`
|
||||
}
|
||||
|
||||
// IngressSpec describes the Ingress the user wishes to exist.
|
||||
type IngressSpec struct {
|
||||
// A default backend capable of servicing requests that don't match any
|
||||
// rule. At least one of 'backend' or 'rules' must be specified. This field
|
||||
// is optional to allow the loadbalancer controller or defaulting logic to
|
||||
// specify a global default.
|
||||
Backend *IngressBackend `json:"backend,omitempty"`
|
||||
|
||||
// TLS configuration. Currently the Ingress only supports a single TLS
|
||||
// port, 443. If multiple members of this list specify different hosts, they
|
||||
// will be multiplexed on the same port according to the hostname specified
|
||||
// through the SNI TLS extension, if the ingress controller fulfilling the
|
||||
// ingress supports SNI.
|
||||
TLS []IngressTLS `json:"tls,omitempty"`
|
||||
|
||||
// A list of host rules used to configure the Ingress. If unspecified, or
|
||||
// no rule matches, all traffic is sent to the default backend.
|
||||
Rules []IngressRule `json:"rules,omitempty"`
|
||||
// TODO: Add the ability to specify load-balancer IP through claims
|
||||
}
|
||||
|
||||
// IngressTLS describes the transport layer security associated with an Ingress.
|
||||
type IngressTLS struct {
|
||||
// Hosts are a list of hosts included in the TLS certificate. The values in
|
||||
// this list must match the name/s used in the tlsSecret. Defaults to the
|
||||
// wildcard host setting for the loadbalancer controller fulfilling this
|
||||
// Ingress, if left unspecified.
|
||||
Hosts []string `json:"hosts,omitempty"`
|
||||
// SecretName is the name of the secret used to terminate SSL traffic on 443.
|
||||
// Field is left optional to allow SSL routing based on SNI hostname alone.
|
||||
// If the SNI host in a listener conflicts with the "Host" header field used
|
||||
// by an IngressRule, the SNI host is used for termination and value of the
|
||||
// Host header is used for routing.
|
||||
SecretName string `json:"secretName,omitempty"`
|
||||
// TODO: Consider specifying different modes of termination, protocols etc.
|
||||
}
|
||||
|
||||
// IngressStatus describe the current state of the Ingress.
|
||||
type IngressStatus struct {
|
||||
// LoadBalancer contains the current status of the load-balancer.
|
||||
LoadBalancer api.LoadBalancerStatus `json:"loadBalancer,omitempty"`
|
||||
}
|
||||
|
||||
// IngressRule represents the rules mapping the paths under a specified host to
|
||||
// the related backend services. Incoming requests are first evaluated for a host
|
||||
// match, then routed to the backend associated with the matching IngressRuleValue.
|
||||
type IngressRule struct {
|
||||
// Host is the fully qualified domain name of a network host, as defined
|
||||
// by RFC 3986. Note the following deviations from the "host" part of the
|
||||
// URI as defined in the RFC:
|
||||
// 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the
|
||||
// IP in the Spec of the parent Ingress.
|
||||
// 2. The `:` delimiter is not respected because ports are not allowed.
|
||||
// Currently the port of an Ingress is implicitly :80 for http and
|
||||
// :443 for https.
|
||||
// Both these may change in the future.
|
||||
// Incoming requests are matched against the host before the IngressRuleValue.
|
||||
// If the host is unspecified, the Ingress routes all traffic based on the
|
||||
// specified IngressRuleValue.
|
||||
Host string `json:"host,omitempty"`
|
||||
// IngressRuleValue represents a rule to route requests for this IngressRule.
|
||||
// If unspecified, the rule defaults to a http catch-all. Whether that sends
|
||||
// just traffic matching the host to the default backend or all traffic to the
|
||||
// default backend, is left to the controller fulfilling the Ingress. Http is
|
||||
// currently the only supported IngressRuleValue.
|
||||
IngressRuleValue `json:",inline,omitempty"`
|
||||
}
|
||||
|
||||
// IngressRuleValue represents a rule to apply against incoming requests. If the
|
||||
// rule is satisfied, the request is routed to the specified backend. Currently
|
||||
// mixing different types of rules in a single Ingress is disallowed, so exactly
|
||||
// one of the following must be set.
|
||||
type IngressRuleValue struct {
|
||||
//TODO:
|
||||
// 1. Consider renaming this resource and the associated rules so they
|
||||
// aren't tied to Ingress. They can be used to route intra-cluster traffic.
|
||||
// 2. Consider adding fields for ingress-type specific global options
|
||||
// usable by a loadbalancer, like http keep-alive.
|
||||
|
||||
HTTP *HTTPIngressRuleValue `json:"http,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPIngressRuleValue is a list of http selectors pointing to backends.
|
||||
// In the example: http://<host>/<path>?<searchpart> -> backend where
|
||||
// where parts of the url correspond to RFC 3986, this resource will be used
|
||||
// to match against everything after the last '/' and before the first '?'
|
||||
// or '#'.
|
||||
type HTTPIngressRuleValue struct {
|
||||
// A collection of paths that map requests to backends.
|
||||
Paths []HTTPIngressPath `json:"paths"`
|
||||
// TODO: Consider adding fields for ingress-type specific global
|
||||
// options usable by a loadbalancer, like http keep-alive.
|
||||
}
|
||||
|
||||
// HTTPIngressPath associates a path regex with a backend. Incoming urls matching
|
||||
// the path are forwarded to the backend.
|
||||
type HTTPIngressPath struct {
|
||||
// Path is an extended POSIX regex as defined by IEEE Std 1003.1,
|
||||
// (i.e this follows the egrep/unix syntax, not the perl syntax)
|
||||
// matched against the path of an incoming request. Currently it can
|
||||
// contain characters disallowed from the conventional "path"
|
||||
// part of a URL as defined by RFC 3986. Paths must begin with
|
||||
// a '/'. If unspecified, the path defaults to a catch all sending
|
||||
// traffic to the backend.
|
||||
Path string `json:"path,omitempty"`
|
||||
|
||||
// Backend defines the referenced service endpoint to which the traffic
|
||||
// will be forwarded to.
|
||||
Backend IngressBackend `json:"backend"`
|
||||
}
|
||||
|
||||
// IngressBackend describes all endpoints for a given service and port.
|
||||
type IngressBackend struct {
|
||||
// Specifies the name of the referenced service.
|
||||
ServiceName string `json:"serviceName"`
|
||||
|
||||
// Specifies the port of the referenced service.
|
||||
ServicePort intstr.IntOrString `json:"servicePort"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// ReplicaSet represents the configuration of a replica set.
|
||||
type ReplicaSet struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the desired behavior of this ReplicaSet.
|
||||
Spec ReplicaSetSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current status of this ReplicaSet. This data may be
|
||||
// out of date by some window of time.
|
||||
Status ReplicaSetStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// ReplicaSetList is a collection of ReplicaSets.
|
||||
type ReplicaSetList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []ReplicaSet `json:"items"`
|
||||
}
|
||||
|
||||
// ReplicaSetSpec is the specification of a ReplicaSet.
|
||||
// As the internal representation of a ReplicaSet, it must have
|
||||
// a Template set.
|
||||
type ReplicaSetSpec struct {
|
||||
// Replicas is the number of desired replicas.
|
||||
Replicas int32 `json:"replicas"`
|
||||
|
||||
// Selector is a label query over pods that should match the replica count.
|
||||
// Must match in order to be controlled.
|
||||
// If empty, defaulted to labels on pod template.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created if
|
||||
// insufficient replicas are detected.
|
||||
Template api.PodTemplateSpec `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// ReplicaSetStatus represents the current status of a ReplicaSet.
|
||||
type ReplicaSetStatus struct {
|
||||
// Replicas is the number of actual replicas.
|
||||
Replicas int32 `json:"replicas"`
|
||||
|
||||
// The number of pods that have labels matching the labels of the pod template of the replicaset.
|
||||
FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty"`
|
||||
|
||||
// The number of ready replicas for this replica set.
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
|
||||
|
||||
// ObservedGeneration is the most recent generation observed by the controller.
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
// +nonNamespaced=true
|
||||
|
||||
// PodSecurityPolicy governs the ability to make requests that affect the SecurityContext
|
||||
// that will be applied to a pod and container.
|
||||
type PodSecurityPolicy struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the policy enforced.
|
||||
Spec PodSecurityPolicySpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
// PodSecurityPolicySpec defines the policy enforced.
|
||||
type PodSecurityPolicySpec struct {
|
||||
// Privileged determines if a pod can request to be run as privileged.
|
||||
Privileged bool `json:"privileged,omitempty"`
|
||||
// DefaultAddCapabilities is the default set of capabilities that will be added to the container
|
||||
// unless the pod spec specifically drops the capability. You may not list a capability in both
|
||||
// DefaultAddCapabilities and RequiredDropCapabilities.
|
||||
DefaultAddCapabilities []api.Capability `json:"defaultAddCapabilities,omitempty"`
|
||||
// RequiredDropCapabilities are the capabilities that will be dropped from the container. These
|
||||
// are required to be dropped and cannot be added.
|
||||
RequiredDropCapabilities []api.Capability `json:"requiredDropCapabilities,omitempty"`
|
||||
// AllowedCapabilities is a list of capabilities that can be requested to add to the container.
|
||||
// Capabilities in this field may be added at the pod author's discretion.
|
||||
// You must not list a capability in both AllowedCapabilities and RequiredDropCapabilities.
|
||||
AllowedCapabilities []api.Capability `json:"allowedCapabilities,omitempty"`
|
||||
// Volumes is a white list of allowed volume plugins. Empty indicates that all plugins
|
||||
// may be used.
|
||||
Volumes []FSType `json:"volumes,omitempty"`
|
||||
// HostNetwork determines if the policy allows the use of HostNetwork in the pod spec.
|
||||
HostNetwork bool `json:"hostNetwork,omitempty"`
|
||||
// HostPorts determines which host port ranges are allowed to be exposed.
|
||||
HostPorts []HostPortRange `json:"hostPorts,omitempty"`
|
||||
// HostPID determines if the policy allows the use of HostPID in the pod spec.
|
||||
HostPID bool `json:"hostPID,omitempty"`
|
||||
// HostIPC determines if the policy allows the use of HostIPC in the pod spec.
|
||||
HostIPC bool `json:"hostIPC,omitempty"`
|
||||
// SELinux is the strategy that will dictate the allowable labels that may be set.
|
||||
SELinux SELinuxStrategyOptions `json:"seLinux"`
|
||||
// RunAsUser is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
RunAsUser RunAsUserStrategyOptions `json:"runAsUser"`
|
||||
// SupplementalGroups is the strategy that will dictate what supplemental groups are used by the SecurityContext.
|
||||
SupplementalGroups SupplementalGroupsStrategyOptions `json:"supplementalGroups"`
|
||||
// FSGroup is the strategy that will dictate what fs group is used by the SecurityContext.
|
||||
FSGroup FSGroupStrategyOptions `json:"fsGroup"`
|
||||
// ReadOnlyRootFilesystem when set to true will force containers to run with a read only root file
|
||||
// system. If the container specifically requests to run with a non-read only root file system
|
||||
// the PSP should deny the pod.
|
||||
// If set to false the container may run with a read only root file system if it wishes but it
|
||||
// will not be forced to.
|
||||
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem,omitempty"`
|
||||
}
|
||||
|
||||
// HostPortRange defines a range of host ports that will be enabled by a policy
|
||||
// for pods to use. It requires both the start and end to be defined.
|
||||
type HostPortRange struct {
|
||||
// Min is the start of the range, inclusive.
|
||||
Min int `json:"min"`
|
||||
// Max is the end of the range, inclusive.
|
||||
Max int `json:"max"`
|
||||
}
|
||||
|
||||
// FSType gives strong typing to different file systems that are used by volumes.
|
||||
type FSType string
|
||||
|
||||
var (
|
||||
AzureFile FSType = "azureFile"
|
||||
Flocker FSType = "flocker"
|
||||
FlexVolume FSType = "flexVolume"
|
||||
HostPath FSType = "hostPath"
|
||||
EmptyDir FSType = "emptyDir"
|
||||
GCEPersistentDisk FSType = "gcePersistentDisk"
|
||||
AWSElasticBlockStore FSType = "awsElasticBlockStore"
|
||||
GitRepo FSType = "gitRepo"
|
||||
Secret FSType = "secret"
|
||||
NFS FSType = "nfs"
|
||||
ISCSI FSType = "iscsi"
|
||||
Glusterfs FSType = "glusterfs"
|
||||
PersistentVolumeClaim FSType = "persistentVolumeClaim"
|
||||
RBD FSType = "rbd"
|
||||
Cinder FSType = "cinder"
|
||||
CephFS FSType = "cephFS"
|
||||
DownwardAPI FSType = "downwardAPI"
|
||||
FC FSType = "fc"
|
||||
ConfigMap FSType = "configMap"
|
||||
VsphereVolume FSType = "vsphereVolume"
|
||||
Quobyte FSType = "quobyte"
|
||||
AzureDisk FSType = "azureDisk"
|
||||
All FSType = "*"
|
||||
)
|
||||
|
||||
// SELinuxStrategyOptions defines the strategy type and any options used to create the strategy.
|
||||
type SELinuxStrategyOptions struct {
|
||||
// Rule is the strategy that will dictate the allowable labels that may be set.
|
||||
Rule SELinuxStrategy `json:"rule"`
|
||||
// seLinuxOptions required to run as; required for MustRunAs
|
||||
// More info: http://releases.k8s.io/HEAD/docs/design/security_context.md#security-context
|
||||
SELinuxOptions *api.SELinuxOptions `json:"seLinuxOptions,omitempty"`
|
||||
}
|
||||
|
||||
// SELinuxStrategy denotes strategy types for generating SELinux options for a
|
||||
// Security.
|
||||
type SELinuxStrategy string
|
||||
|
||||
const (
|
||||
// container must have SELinux labels of X applied.
|
||||
SELinuxStrategyMustRunAs SELinuxStrategy = "MustRunAs"
|
||||
// container may make requests for any SELinux context labels.
|
||||
SELinuxStrategyRunAsAny SELinuxStrategy = "RunAsAny"
|
||||
)
|
||||
|
||||
// RunAsUserStrategyOptions defines the strategy type and any options used to create the strategy.
|
||||
type RunAsUserStrategyOptions struct {
|
||||
// Rule is the strategy that will dictate the allowable RunAsUser values that may be set.
|
||||
Rule RunAsUserStrategy `json:"rule"`
|
||||
// Ranges are the allowed ranges of uids that may be used.
|
||||
Ranges []IDRange `json:"ranges,omitempty"`
|
||||
}
|
||||
|
||||
// IDRange provides a min/max of an allowed range of IDs.
|
||||
type IDRange struct {
|
||||
// Min is the start of the range, inclusive.
|
||||
Min int64 `json:"min"`
|
||||
// Max is the end of the range, inclusive.
|
||||
Max int64 `json:"max"`
|
||||
}
|
||||
|
||||
// RunAsUserStrategy denotes strategy types for generating RunAsUser values for a
|
||||
// SecurityContext.
|
||||
type RunAsUserStrategy string
|
||||
|
||||
const (
|
||||
// container must run as a particular uid.
|
||||
RunAsUserStrategyMustRunAs RunAsUserStrategy = "MustRunAs"
|
||||
// container must run as a non-root uid
|
||||
RunAsUserStrategyMustRunAsNonRoot RunAsUserStrategy = "MustRunAsNonRoot"
|
||||
// container may make requests for any uid.
|
||||
RunAsUserStrategyRunAsAny RunAsUserStrategy = "RunAsAny"
|
||||
)
|
||||
|
||||
// FSGroupStrategyOptions defines the strategy type and options used to create the strategy.
|
||||
type FSGroupStrategyOptions struct {
|
||||
// Rule is the strategy that will dictate what FSGroup is used in the SecurityContext.
|
||||
Rule FSGroupStrategyType `json:"rule,omitempty"`
|
||||
// Ranges are the allowed ranges of fs groups. If you would like to force a single
|
||||
// fs group then supply a single range with the same start and end.
|
||||
Ranges []IDRange `json:"ranges,omitempty"`
|
||||
}
|
||||
|
||||
// FSGroupStrategyType denotes strategy types for generating FSGroup values for a
|
||||
// SecurityContext
|
||||
type FSGroupStrategyType string
|
||||
|
||||
const (
|
||||
// container must have FSGroup of X applied.
|
||||
FSGroupStrategyMustRunAs FSGroupStrategyType = "MustRunAs"
|
||||
// container may make requests for any FSGroup labels.
|
||||
FSGroupStrategyRunAsAny FSGroupStrategyType = "RunAsAny"
|
||||
)
|
||||
|
||||
// SupplementalGroupsStrategyOptions defines the strategy type and options used to create the strategy.
|
||||
type SupplementalGroupsStrategyOptions struct {
|
||||
// Rule is the strategy that will dictate what supplemental groups is used in the SecurityContext.
|
||||
Rule SupplementalGroupsStrategyType `json:"rule,omitempty"`
|
||||
// Ranges are the allowed ranges of supplemental groups. If you would like to force a single
|
||||
// supplemental group then supply a single range with the same start and end.
|
||||
Ranges []IDRange `json:"ranges,omitempty"`
|
||||
}
|
||||
|
||||
// SupplementalGroupsStrategyType denotes strategy types for determining valid supplemental
|
||||
// groups for a SecurityContext.
|
||||
type SupplementalGroupsStrategyType string
|
||||
|
||||
const (
|
||||
// container must run as a particular gid.
|
||||
SupplementalGroupsStrategyMustRunAs SupplementalGroupsStrategyType = "MustRunAs"
|
||||
// container may make requests for any gid.
|
||||
SupplementalGroupsStrategyRunAsAny SupplementalGroupsStrategyType = "RunAsAny"
|
||||
)
|
||||
|
||||
// PodSecurityPolicyList is a list of PodSecurityPolicy objects.
|
||||
type PodSecurityPolicyList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []PodSecurityPolicy `json:"items"`
|
||||
}
|
||||
|
||||
type NetworkPolicy struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Specification of the desired behavior for this NetworkPolicy.
|
||||
Spec NetworkPolicySpec `json:"spec,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkPolicySpec struct {
|
||||
// Selects the pods to which this NetworkPolicy object applies. The array of ingress rules
|
||||
// is applied to any pods selected by this field. Multiple network policies can select the
|
||||
// same set of pods. In this case, the ingress rules for each are combined additively.
|
||||
// This field is NOT optional and follows standard label selector semantics.
|
||||
// An empty podSelector matches all pods in this namespace.
|
||||
PodSelector unversioned.LabelSelector `json:"podSelector"`
|
||||
|
||||
// List of ingress rules to be applied to the selected pods.
|
||||
// Traffic is allowed to a pod if namespace.networkPolicy.ingress.isolation is undefined and cluster policy allows it,
|
||||
// OR if the traffic source is the pod's local node,
|
||||
// OR if the traffic matches at least one ingress rule across all of the NetworkPolicy
|
||||
// objects whose podSelector matches the pod.
|
||||
// If this field is empty then this NetworkPolicy does not affect ingress isolation.
|
||||
// If this field is present and contains at least one rule, this policy allows any traffic
|
||||
// which matches at least one of the ingress rules in this list.
|
||||
Ingress []NetworkPolicyIngressRule `json:"ingress,omitempty"`
|
||||
}
|
||||
|
||||
// This NetworkPolicyIngressRule matches traffic if and only if the traffic matches both ports AND from.
|
||||
type NetworkPolicyIngressRule struct {
|
||||
// List of ports which should be made accessible on the pods selected for this rule.
|
||||
// Each item in this list is combined using a logical OR.
|
||||
// If this field is not provided, this rule matches all ports (traffic not restricted by port).
|
||||
// If this field is empty, this rule matches no ports (no traffic matches).
|
||||
// If this field is present and contains at least one item, then this rule allows traffic
|
||||
// only if the traffic matches at least one port in the list.
|
||||
// TODO: Update this to be a pointer to slice as soon as auto-generation supports it.
|
||||
Ports []NetworkPolicyPort `json:"ports,omitempty"`
|
||||
|
||||
// List of sources which should be able to access the pods selected for this rule.
|
||||
// Items in this list are combined using a logical OR operation.
|
||||
// If this field is not provided, this rule matches all sources (traffic not restricted by source).
|
||||
// If this field is empty, this rule matches no sources (no traffic matches).
|
||||
// If this field is present and contains at least on item, this rule allows traffic only if the
|
||||
// traffic matches at least one item in the from list.
|
||||
// TODO: Update this to be a pointer to slice as soon as auto-generation supports it.
|
||||
From []NetworkPolicyPeer `json:"from,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkPolicyPort struct {
|
||||
// Optional. The protocol (TCP or UDP) which traffic must match.
|
||||
// If not specified, this field defaults to TCP.
|
||||
Protocol *api.Protocol `json:"protocol,omitempty"`
|
||||
|
||||
// If specified, the port on the given protocol. This can
|
||||
// either be a numerical or named port on a pod. If this field is not provided,
|
||||
// this matches all port names and numbers.
|
||||
// If present, only traffic on the specified protocol AND port
|
||||
// will be matched.
|
||||
Port *intstr.IntOrString `json:"port,omitempty"`
|
||||
}
|
||||
|
||||
type NetworkPolicyPeer struct {
|
||||
// Exactly one of the following must be specified.
|
||||
|
||||
// This is a label selector which selects Pods in this namespace.
|
||||
// This field follows standard label selector semantics.
|
||||
// If not provided, this selector selects no pods.
|
||||
// If present but empty, this selector selects all pods in this namespace.
|
||||
PodSelector *unversioned.LabelSelector `json:"podSelector,omitempty"`
|
||||
|
||||
// Selects Namespaces using cluster scoped-labels. This
|
||||
// matches all pods in all namespaces selected by this label selector.
|
||||
// This field follows standard label selector semantics.
|
||||
// If omitted, this selector selects no namespaces.
|
||||
// If present but empty, this selector selects all namespaces.
|
||||
NamespaceSelector *unversioned.LabelSelector `json:"namespaceSelector,omitempty"`
|
||||
}
|
||||
|
||||
// NetworkPolicyList is a list of NetworkPolicy objects.
|
||||
type NetworkPolicyList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []NetworkPolicy `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient=true
|
||||
// +nonNamespaced=true
|
||||
|
||||
// StorageClass describes a named "class" of storage offered in a cluster.
|
||||
// Different classes might map to quality-of-service levels, or to backup policies,
|
||||
// or to arbitrary policies determined by the cluster administrators. Kubernetes
|
||||
// itself is unopinionated about what classes represent. This concept is sometimes
|
||||
// called "profiles" in other storage systems.
|
||||
// The name of a StorageClass object is significant, and is how users can request a particular class.
|
||||
type StorageClass struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// provisioner is the driver expected to handle this StorageClass.
|
||||
// This is an optionally-prefixed name, like a label key.
|
||||
// For example: "kubernetes.io/gce-pd" or "kubernetes.io/aws-ebs".
|
||||
// This value may not be empty.
|
||||
Provisioner string `json:"provisioner"`
|
||||
|
||||
// parameters holds parameters for the provisioner.
|
||||
// These values are opaque to the system and are passed directly
|
||||
// to the provisioner. The only validation done on keys is that they are
|
||||
// not empty. The maximum number of parameters is
|
||||
// 512, with a cumulative max size of 256K
|
||||
Parameters map[string]string `json:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
// StorageClassList is a collection of storage classes.
|
||||
type StorageClassList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
// Standard list metadata
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of StorageClasses
|
||||
Items []StorageClass `json:"items"`
|
||||
}
|
||||
1126
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/zz_generated.deepcopy.go
generated
vendored
1126
vendor/k8s.io/client-go/1.4/pkg/apis/extensions/zz_generated.deepcopy.go
generated
vendored
File diff suppressed because it is too large
Load diff
19
vendor/k8s.io/client-go/1.4/pkg/auth/user/doc.go
generated
vendored
19
vendor/k8s.io/client-go/1.4/pkg/auth/user/doc.go
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package user contains utilities for dealing with simple user exchange in the auth
|
||||
// packages. The user.Info interface defines an interface for exchanging that info.
|
||||
package user
|
||||
67
vendor/k8s.io/client-go/1.4/pkg/auth/user/user.go
generated
vendored
67
vendor/k8s.io/client-go/1.4/pkg/auth/user/user.go
generated
vendored
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package user
|
||||
|
||||
// Info describes a user that has been authenticated to the system.
|
||||
type Info interface {
|
||||
// GetName returns the name that uniquely identifies this user among all
|
||||
// other active users.
|
||||
GetName() string
|
||||
// GetUID returns a unique value for a particular user that will change
|
||||
// if the user is removed from the system and another user is added with
|
||||
// the same name.
|
||||
GetUID() string
|
||||
// GetGroups returns the names of the groups the user is a member of
|
||||
GetGroups() []string
|
||||
|
||||
// GetExtra can contain any additional information that the authenticator
|
||||
// thought was interesting. One example would be scopes on a token.
|
||||
// Keys in this map should be namespaced to the authenticator or
|
||||
// authenticator/authorizer pair making use of them.
|
||||
// For instance: "example.org/foo" instead of "foo"
|
||||
// This is a map[string][]string because it needs to be serializeable into
|
||||
// a SubjectAccessReviewSpec.authorization.k8s.io for proper authorization
|
||||
// delegation flows
|
||||
// In order to faithfully round-trip through an impersonation flow, these keys
|
||||
// MUST be lowercase.
|
||||
GetExtra() map[string][]string
|
||||
}
|
||||
|
||||
// DefaultInfo provides a simple user information exchange object
|
||||
// for components that implement the UserInfo interface.
|
||||
type DefaultInfo struct {
|
||||
Name string
|
||||
UID string
|
||||
Groups []string
|
||||
Extra map[string][]string
|
||||
}
|
||||
|
||||
func (i *DefaultInfo) GetName() string {
|
||||
return i.Name
|
||||
}
|
||||
|
||||
func (i *DefaultInfo) GetUID() string {
|
||||
return i.UID
|
||||
}
|
||||
|
||||
func (i *DefaultInfo) GetGroups() []string {
|
||||
return i.Groups
|
||||
}
|
||||
|
||||
func (i *DefaultInfo) GetExtra() map[string][]string {
|
||||
return i.Extra
|
||||
}
|
||||
94
vendor/k8s.io/client-go/1.4/pkg/capabilities/capabilities.go
generated
vendored
94
vendor/k8s.io/client-go/1.4/pkg/capabilities/capabilities.go
generated
vendored
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package capabilities
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Capabilities defines the set of capabilities available within the system.
|
||||
// For now these are global. Eventually they may be per-user
|
||||
type Capabilities struct {
|
||||
AllowPrivileged bool
|
||||
|
||||
// Pod sources from which to allow privileged capabilities like host networking, sharing the host
|
||||
// IPC namespace, and sharing the host PID namespace.
|
||||
PrivilegedSources PrivilegedSources
|
||||
|
||||
// PerConnectionBandwidthLimitBytesPerSec limits the throughput of each connection (currently only used for proxy, exec, attach)
|
||||
PerConnectionBandwidthLimitBytesPerSec int64
|
||||
}
|
||||
|
||||
// PrivilegedSources defines the pod sources allowed to make privileged requests for certain types
|
||||
// of capabilities like host networking, sharing the host IPC namespace, and sharing the host PID namespace.
|
||||
type PrivilegedSources struct {
|
||||
// List of pod sources for which using host network is allowed.
|
||||
HostNetworkSources []string
|
||||
|
||||
// List of pod sources for which using host pid namespace is allowed.
|
||||
HostPIDSources []string
|
||||
|
||||
// List of pod sources for which using host ipc is allowed.
|
||||
HostIPCSources []string
|
||||
}
|
||||
|
||||
// TODO: Clean these up into a singleton
|
||||
var once sync.Once
|
||||
var lock sync.Mutex
|
||||
var capabilities *Capabilities
|
||||
|
||||
// Initialize the capability set. This can only be done once per binary, subsequent calls are ignored.
|
||||
func Initialize(c Capabilities) {
|
||||
// Only do this once
|
||||
once.Do(func() {
|
||||
capabilities = &c
|
||||
})
|
||||
}
|
||||
|
||||
// Setup the capability set. It wraps Initialize for improving usability.
|
||||
func Setup(allowPrivileged bool, privilegedSources PrivilegedSources, perConnectionBytesPerSec int64) {
|
||||
Initialize(Capabilities{
|
||||
AllowPrivileged: allowPrivileged,
|
||||
PrivilegedSources: privilegedSources,
|
||||
PerConnectionBandwidthLimitBytesPerSec: perConnectionBytesPerSec,
|
||||
})
|
||||
}
|
||||
|
||||
// SetCapabilitiesForTests. Convenience method for testing. This should only be called from tests.
|
||||
func SetForTests(c Capabilities) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
capabilities = &c
|
||||
}
|
||||
|
||||
// Returns a read-only copy of the system capabilities.
|
||||
func Get() Capabilities {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
// This check prevents clobbering of capabilities that might've been set via SetForTests
|
||||
if capabilities == nil {
|
||||
Initialize(Capabilities{
|
||||
AllowPrivileged: false,
|
||||
PrivilegedSources: PrivilegedSources{
|
||||
HostNetworkSources: []string{},
|
||||
HostPIDSources: []string{},
|
||||
HostIPCSources: []string{},
|
||||
},
|
||||
})
|
||||
}
|
||||
return *capabilities
|
||||
}
|
||||
5
vendor/k8s.io/client-go/1.4/pkg/conversion/OWNERS
generated
vendored
5
vendor/k8s.io/client-go/1.4/pkg/conversion/OWNERS
generated
vendored
|
|
@ -1,5 +0,0 @@
|
|||
assignees:
|
||||
- derekwaynecarr
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
249
vendor/k8s.io/client-go/1.4/pkg/conversion/cloner.go
generated
vendored
249
vendor/k8s.io/client-go/1.4/pkg/conversion/cloner.go
generated
vendored
|
|
@ -1,249 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package conversion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Cloner knows how to copy one type to another.
|
||||
type Cloner struct {
|
||||
// Map from the type to a function which can do the deep copy.
|
||||
deepCopyFuncs map[reflect.Type]reflect.Value
|
||||
generatedDeepCopyFuncs map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error
|
||||
}
|
||||
|
||||
// NewCloner creates a new Cloner object.
|
||||
func NewCloner() *Cloner {
|
||||
c := &Cloner{
|
||||
deepCopyFuncs: map[reflect.Type]reflect.Value{},
|
||||
generatedDeepCopyFuncs: map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error{},
|
||||
}
|
||||
if err := c.RegisterDeepCopyFunc(byteSliceDeepCopy); err != nil {
|
||||
// If one of the deep-copy functions is malformed, detect it immediately.
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Prevent recursing into every byte...
|
||||
func byteSliceDeepCopy(in *[]byte, out *[]byte, c *Cloner) error {
|
||||
if *in != nil {
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
} else {
|
||||
*out = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verifies whether a deep-copy function has a correct signature.
|
||||
func verifyDeepCopyFunctionSignature(ft reflect.Type) error {
|
||||
if ft.Kind() != reflect.Func {
|
||||
return fmt.Errorf("expected func, got: %v", ft)
|
||||
}
|
||||
if ft.NumIn() != 3 {
|
||||
return fmt.Errorf("expected three 'in' params, got %v", ft)
|
||||
}
|
||||
if ft.NumOut() != 1 {
|
||||
return fmt.Errorf("expected one 'out' param, got %v", ft)
|
||||
}
|
||||
if ft.In(0).Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
|
||||
}
|
||||
if ft.In(1) != ft.In(0) {
|
||||
return fmt.Errorf("expected 'in' param 0 the same as param 1, got: %v", ft)
|
||||
}
|
||||
var forClonerType Cloner
|
||||
if expected := reflect.TypeOf(&forClonerType); ft.In(2) != expected {
|
||||
return fmt.Errorf("expected '%v' arg for 'in' param 2, got: '%v'", expected, ft.In(2))
|
||||
}
|
||||
var forErrorType error
|
||||
// This convolution is necessary, otherwise TypeOf picks up on the fact
|
||||
// that forErrorType is nil
|
||||
errorType := reflect.TypeOf(&forErrorType).Elem()
|
||||
if ft.Out(0) != errorType {
|
||||
return fmt.Errorf("expected error return, got: %v", ft)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterGeneratedDeepCopyFunc registers a copying func with the Cloner.
|
||||
// deepCopyFunc must take three parameters: a type input, a pointer to a
|
||||
// type output, and a pointer to Cloner. It should return an error.
|
||||
//
|
||||
// Example:
|
||||
// c.RegisterGeneratedDeepCopyFunc(
|
||||
// func(in Pod, out *Pod, c *Cloner) error {
|
||||
// // deep copy logic...
|
||||
// return nil
|
||||
// })
|
||||
func (c *Cloner) RegisterDeepCopyFunc(deepCopyFunc interface{}) error {
|
||||
fv := reflect.ValueOf(deepCopyFunc)
|
||||
ft := fv.Type()
|
||||
if err := verifyDeepCopyFunctionSignature(ft); err != nil {
|
||||
return err
|
||||
}
|
||||
c.deepCopyFuncs[ft.In(0)] = fv
|
||||
return nil
|
||||
}
|
||||
|
||||
// GeneratedDeepCopyFunc bundles an untyped generated deep-copy function of a type
|
||||
// with a reflection type object used as a key to lookup the deep-copy function.
|
||||
type GeneratedDeepCopyFunc struct {
|
||||
Fn func(in interface{}, out interface{}, c *Cloner) error
|
||||
InType reflect.Type
|
||||
}
|
||||
|
||||
// Similar to RegisterDeepCopyFunc, but registers deep copy function that were
|
||||
// automatically generated.
|
||||
func (c *Cloner) RegisterGeneratedDeepCopyFunc(fn GeneratedDeepCopyFunc) error {
|
||||
c.generatedDeepCopyFuncs[fn.InType] = fn.Fn
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy will perform a deep copy of a given object.
|
||||
func (c *Cloner) DeepCopy(in interface{}) (interface{}, error) {
|
||||
// Can be invalid if we run DeepCopy(X) where X is a nil interface type.
|
||||
// For example, we get an invalid value when someone tries to deep-copy
|
||||
// a nil labels.Selector.
|
||||
// This does not occur if X is nil and is a pointer to a concrete type.
|
||||
if in == nil {
|
||||
return nil, nil
|
||||
}
|
||||
inValue := reflect.ValueOf(in)
|
||||
outValue, err := c.deepCopy(inValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return outValue.Interface(), nil
|
||||
}
|
||||
|
||||
func (c *Cloner) deepCopy(src reflect.Value) (reflect.Value, error) {
|
||||
inType := src.Type()
|
||||
|
||||
switch src.Kind() {
|
||||
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
|
||||
if src.IsNil() {
|
||||
return src, nil
|
||||
}
|
||||
}
|
||||
|
||||
if fv, ok := c.deepCopyFuncs[inType]; ok {
|
||||
return c.customDeepCopy(src, fv)
|
||||
}
|
||||
if fv, ok := c.generatedDeepCopyFuncs[inType]; ok {
|
||||
var outValue reflect.Value
|
||||
outValue = reflect.New(inType.Elem())
|
||||
err := fv(src.Interface(), outValue.Interface(), c)
|
||||
return outValue, err
|
||||
}
|
||||
return c.defaultDeepCopy(src)
|
||||
}
|
||||
|
||||
func (c *Cloner) customDeepCopy(src, fv reflect.Value) (reflect.Value, error) {
|
||||
outValue := reflect.New(src.Type().Elem())
|
||||
args := []reflect.Value{src, outValue, reflect.ValueOf(c)}
|
||||
result := fv.Call(args)[0].Interface()
|
||||
// This convolution is necessary because nil interfaces won't convert
|
||||
// to error.
|
||||
if result == nil {
|
||||
return outValue, nil
|
||||
}
|
||||
return outValue, result.(error)
|
||||
}
|
||||
|
||||
func (c *Cloner) defaultDeepCopy(src reflect.Value) (reflect.Value, error) {
|
||||
switch src.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Uintptr:
|
||||
return src, fmt.Errorf("cannot deep copy kind: %s", src.Kind())
|
||||
case reflect.Array:
|
||||
dst := reflect.New(src.Type())
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
copyVal, err := c.deepCopy(src.Index(i))
|
||||
if err != nil {
|
||||
return src, err
|
||||
}
|
||||
dst.Elem().Index(i).Set(copyVal)
|
||||
}
|
||||
return dst.Elem(), nil
|
||||
case reflect.Interface:
|
||||
if src.IsNil() {
|
||||
return src, nil
|
||||
}
|
||||
return c.deepCopy(src.Elem())
|
||||
case reflect.Map:
|
||||
if src.IsNil() {
|
||||
return src, nil
|
||||
}
|
||||
dst := reflect.MakeMap(src.Type())
|
||||
for _, k := range src.MapKeys() {
|
||||
copyVal, err := c.deepCopy(src.MapIndex(k))
|
||||
if err != nil {
|
||||
return src, err
|
||||
}
|
||||
dst.SetMapIndex(k, copyVal)
|
||||
}
|
||||
return dst, nil
|
||||
case reflect.Ptr:
|
||||
if src.IsNil() {
|
||||
return src, nil
|
||||
}
|
||||
dst := reflect.New(src.Type().Elem())
|
||||
copyVal, err := c.deepCopy(src.Elem())
|
||||
if err != nil {
|
||||
return src, err
|
||||
}
|
||||
dst.Elem().Set(copyVal)
|
||||
return dst, nil
|
||||
case reflect.Slice:
|
||||
if src.IsNil() {
|
||||
return src, nil
|
||||
}
|
||||
dst := reflect.MakeSlice(src.Type(), 0, src.Len())
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
copyVal, err := c.deepCopy(src.Index(i))
|
||||
if err != nil {
|
||||
return src, err
|
||||
}
|
||||
dst = reflect.Append(dst, copyVal)
|
||||
}
|
||||
return dst, nil
|
||||
case reflect.Struct:
|
||||
dst := reflect.New(src.Type())
|
||||
for i := 0; i < src.NumField(); i++ {
|
||||
if !dst.Elem().Field(i).CanSet() {
|
||||
// Can't set private fields. At this point, the
|
||||
// best we can do is a shallow copy. For
|
||||
// example, time.Time is a value type with
|
||||
// private members that can be shallow copied.
|
||||
return src, nil
|
||||
}
|
||||
copyVal, err := c.deepCopy(src.Field(i))
|
||||
if err != nil {
|
||||
return src, err
|
||||
}
|
||||
dst.Elem().Field(i).Set(copyVal)
|
||||
}
|
||||
return dst.Elem(), nil
|
||||
|
||||
default:
|
||||
// Value types like numbers, booleans, and strings.
|
||||
return src, nil
|
||||
}
|
||||
}
|
||||
953
vendor/k8s.io/client-go/1.4/pkg/conversion/converter.go
generated
vendored
953
vendor/k8s.io/client-go/1.4/pkg/conversion/converter.go
generated
vendored
|
|
@ -1,953 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package conversion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type typePair struct {
|
||||
source reflect.Type
|
||||
dest reflect.Type
|
||||
}
|
||||
|
||||
type typeNamePair struct {
|
||||
fieldType reflect.Type
|
||||
fieldName string
|
||||
}
|
||||
|
||||
// DebugLogger allows you to get debugging messages if necessary.
|
||||
type DebugLogger interface {
|
||||
Logf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
type NameFunc func(t reflect.Type) string
|
||||
|
||||
var DefaultNameFunc = func(t reflect.Type) string { return t.Name() }
|
||||
|
||||
type GenericConversionFunc func(a, b interface{}, scope Scope) (bool, error)
|
||||
|
||||
// Converter knows how to convert one type to another.
|
||||
type Converter struct {
|
||||
// Map from the conversion pair to a function which can
|
||||
// do the conversion.
|
||||
conversionFuncs ConversionFuncs
|
||||
generatedConversionFuncs ConversionFuncs
|
||||
|
||||
// genericConversions are called during normal conversion to offer a "fast-path"
|
||||
// that avoids all reflection. These methods are not called outside of the .Convert()
|
||||
// method.
|
||||
genericConversions []GenericConversionFunc
|
||||
|
||||
// Set of conversions that should be treated as a no-op
|
||||
ignoredConversions map[typePair]struct{}
|
||||
|
||||
// This is a map from a source field type and name, to a list of destination
|
||||
// field type and name.
|
||||
structFieldDests map[typeNamePair][]typeNamePair
|
||||
|
||||
// Allows for the opposite lookup of structFieldDests. So that SourceFromDest
|
||||
// copy flag also works. So this is a map of destination field name, to potential
|
||||
// source field name and type to look for.
|
||||
structFieldSources map[typeNamePair][]typeNamePair
|
||||
|
||||
// Map from a type to a function which applies defaults.
|
||||
defaultingFuncs map[reflect.Type]reflect.Value
|
||||
|
||||
// Similar to above, but function is stored as interface{}.
|
||||
defaultingInterfaces map[reflect.Type]interface{}
|
||||
|
||||
// Map from an input type to a function which can apply a key name mapping
|
||||
inputFieldMappingFuncs map[reflect.Type]FieldMappingFunc
|
||||
|
||||
// Map from an input type to a set of default conversion flags.
|
||||
inputDefaultFlags map[reflect.Type]FieldMatchingFlags
|
||||
|
||||
// If non-nil, will be called to print helpful debugging info. Quite verbose.
|
||||
Debug DebugLogger
|
||||
|
||||
// nameFunc is called to retrieve the name of a type; this name is used for the
|
||||
// purpose of deciding whether two types match or not (i.e., will we attempt to
|
||||
// do a conversion). The default returns the go type name.
|
||||
nameFunc func(t reflect.Type) string
|
||||
}
|
||||
|
||||
// NewConverter creates a new Converter object.
|
||||
func NewConverter(nameFn NameFunc) *Converter {
|
||||
c := &Converter{
|
||||
conversionFuncs: NewConversionFuncs(),
|
||||
generatedConversionFuncs: NewConversionFuncs(),
|
||||
ignoredConversions: make(map[typePair]struct{}),
|
||||
defaultingFuncs: make(map[reflect.Type]reflect.Value),
|
||||
defaultingInterfaces: make(map[reflect.Type]interface{}),
|
||||
nameFunc: nameFn,
|
||||
structFieldDests: make(map[typeNamePair][]typeNamePair),
|
||||
structFieldSources: make(map[typeNamePair][]typeNamePair),
|
||||
|
||||
inputFieldMappingFuncs: make(map[reflect.Type]FieldMappingFunc),
|
||||
inputDefaultFlags: make(map[reflect.Type]FieldMatchingFlags),
|
||||
}
|
||||
c.RegisterConversionFunc(Convert_Slice_byte_To_Slice_byte)
|
||||
return c
|
||||
}
|
||||
|
||||
// AddGenericConversionFunc adds a function that accepts the ConversionFunc call pattern
|
||||
// (for two conversion types) to the converter. These functions are checked first during
|
||||
// a normal conversion, but are otherwise not called. Use AddConversionFuncs when registering
|
||||
// typed conversions.
|
||||
func (c *Converter) AddGenericConversionFunc(fn GenericConversionFunc) {
|
||||
c.genericConversions = append(c.genericConversions, fn)
|
||||
}
|
||||
|
||||
// WithConversions returns a Converter that is a copy of c but with the additional
|
||||
// fns merged on top.
|
||||
func (c *Converter) WithConversions(fns ConversionFuncs) *Converter {
|
||||
copied := *c
|
||||
copied.conversionFuncs = c.conversionFuncs.Merge(fns)
|
||||
return &copied
|
||||
}
|
||||
|
||||
// DefaultMeta returns the conversion FieldMappingFunc and meta for a given type.
|
||||
func (c *Converter) DefaultMeta(t reflect.Type) (FieldMatchingFlags, *Meta) {
|
||||
return c.inputDefaultFlags[t], &Meta{
|
||||
KeyNameMapping: c.inputFieldMappingFuncs[t],
|
||||
}
|
||||
}
|
||||
|
||||
// Convert_Slice_byte_To_Slice_byte prevents recursing into every byte
|
||||
func Convert_Slice_byte_To_Slice_byte(in *[]byte, out *[]byte, s Scope) error {
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
return nil
|
||||
}
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Scope is passed to conversion funcs to allow them to continue an ongoing conversion.
|
||||
// If multiple converters exist in the system, Scope will allow you to use the correct one
|
||||
// from a conversion function--that is, the one your conversion function was called by.
|
||||
type Scope interface {
|
||||
// Call Convert to convert sub-objects. Note that if you call it with your own exact
|
||||
// parameters, you'll run out of stack space before anything useful happens.
|
||||
Convert(src, dest interface{}, flags FieldMatchingFlags) error
|
||||
|
||||
// DefaultConvert performs the default conversion, without calling a conversion func
|
||||
// on the current stack frame. This makes it safe to call from a conversion func.
|
||||
DefaultConvert(src, dest interface{}, flags FieldMatchingFlags) error
|
||||
|
||||
// If registered, returns a function applying defaults for objects of a given type.
|
||||
// Used for automatically generating conversion functions.
|
||||
DefaultingInterface(inType reflect.Type) (interface{}, bool)
|
||||
|
||||
// SrcTags and DestTags contain the struct tags that src and dest had, respectively.
|
||||
// If the enclosing object was not a struct, then these will contain no tags, of course.
|
||||
SrcTag() reflect.StructTag
|
||||
DestTag() reflect.StructTag
|
||||
|
||||
// Flags returns the flags with which the conversion was started.
|
||||
Flags() FieldMatchingFlags
|
||||
|
||||
// Meta returns any information originally passed to Convert.
|
||||
Meta() *Meta
|
||||
}
|
||||
|
||||
// FieldMappingFunc can convert an input field value into different values, depending on
|
||||
// the value of the source or destination struct tags.
|
||||
type FieldMappingFunc func(key string, sourceTag, destTag reflect.StructTag) (source string, dest string)
|
||||
|
||||
func NewConversionFuncs() ConversionFuncs {
|
||||
return ConversionFuncs{fns: make(map[typePair]reflect.Value)}
|
||||
}
|
||||
|
||||
type ConversionFuncs struct {
|
||||
fns map[typePair]reflect.Value
|
||||
}
|
||||
|
||||
// Add adds the provided conversion functions to the lookup table - they must have the signature
|
||||
// `func(type1, type2, Scope) error`. Functions are added in the order passed and will override
|
||||
// previously registered pairs.
|
||||
func (c ConversionFuncs) Add(fns ...interface{}) error {
|
||||
for _, fn := range fns {
|
||||
fv := reflect.ValueOf(fn)
|
||||
ft := fv.Type()
|
||||
if err := verifyConversionFunctionSignature(ft); err != nil {
|
||||
return err
|
||||
}
|
||||
c.fns[typePair{ft.In(0).Elem(), ft.In(1).Elem()}] = fv
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Merge returns a new ConversionFuncs that contains all conversions from
|
||||
// both other and c, with other conversions taking precedence.
|
||||
func (c ConversionFuncs) Merge(other ConversionFuncs) ConversionFuncs {
|
||||
merged := NewConversionFuncs()
|
||||
for k, v := range c.fns {
|
||||
merged.fns[k] = v
|
||||
}
|
||||
for k, v := range other.fns {
|
||||
merged.fns[k] = v
|
||||
}
|
||||
return merged
|
||||
}
|
||||
|
||||
// Meta is supplied by Scheme, when it calls Convert.
|
||||
type Meta struct {
|
||||
// KeyNameMapping is an optional function which may map the listed key (field name)
|
||||
// into a source and destination value.
|
||||
KeyNameMapping FieldMappingFunc
|
||||
// Context is an optional field that callers may use to pass info to conversion functions.
|
||||
Context interface{}
|
||||
}
|
||||
|
||||
// scope contains information about an ongoing conversion.
|
||||
type scope struct {
|
||||
converter *Converter
|
||||
meta *Meta
|
||||
flags FieldMatchingFlags
|
||||
|
||||
// srcStack & destStack are separate because they may not have a 1:1
|
||||
// relationship.
|
||||
srcStack scopeStack
|
||||
destStack scopeStack
|
||||
}
|
||||
|
||||
type scopeStackElem struct {
|
||||
tag reflect.StructTag
|
||||
value reflect.Value
|
||||
key string
|
||||
}
|
||||
|
||||
type scopeStack []scopeStackElem
|
||||
|
||||
func (s *scopeStack) pop() {
|
||||
n := len(*s)
|
||||
*s = (*s)[:n-1]
|
||||
}
|
||||
|
||||
func (s *scopeStack) push(e scopeStackElem) {
|
||||
*s = append(*s, e)
|
||||
}
|
||||
|
||||
func (s *scopeStack) top() *scopeStackElem {
|
||||
return &(*s)[len(*s)-1]
|
||||
}
|
||||
|
||||
func (s scopeStack) describe() string {
|
||||
desc := ""
|
||||
if len(s) > 1 {
|
||||
desc = "(" + s[1].value.Type().String() + ")"
|
||||
}
|
||||
for i, v := range s {
|
||||
if i < 2 {
|
||||
// First layer on stack is not real; second is handled specially above.
|
||||
continue
|
||||
}
|
||||
if v.key == "" {
|
||||
desc += fmt.Sprintf(".%v", v.value.Type())
|
||||
} else {
|
||||
desc += fmt.Sprintf(".%v", v.key)
|
||||
}
|
||||
}
|
||||
return desc
|
||||
}
|
||||
|
||||
func (s *scope) DefaultingInterface(inType reflect.Type) (interface{}, bool) {
|
||||
value, found := s.converter.defaultingInterfaces[inType]
|
||||
return value, found
|
||||
}
|
||||
|
||||
// Formats src & dest as indices for printing.
|
||||
func (s *scope) setIndices(src, dest int) {
|
||||
s.srcStack.top().key = fmt.Sprintf("[%v]", src)
|
||||
s.destStack.top().key = fmt.Sprintf("[%v]", dest)
|
||||
}
|
||||
|
||||
// Formats src & dest as map keys for printing.
|
||||
func (s *scope) setKeys(src, dest interface{}) {
|
||||
s.srcStack.top().key = fmt.Sprintf(`["%v"]`, src)
|
||||
s.destStack.top().key = fmt.Sprintf(`["%v"]`, dest)
|
||||
}
|
||||
|
||||
// Convert continues a conversion.
|
||||
func (s *scope) Convert(src, dest interface{}, flags FieldMatchingFlags) error {
|
||||
return s.converter.Convert(src, dest, flags, s.meta)
|
||||
}
|
||||
|
||||
// DefaultConvert continues a conversion, performing a default conversion (no conversion func)
|
||||
// for the current stack frame.
|
||||
func (s *scope) DefaultConvert(src, dest interface{}, flags FieldMatchingFlags) error {
|
||||
return s.converter.DefaultConvert(src, dest, flags, s.meta)
|
||||
}
|
||||
|
||||
// SrcTag returns the tag of the struct containing the current source item, if any.
|
||||
func (s *scope) SrcTag() reflect.StructTag {
|
||||
return s.srcStack.top().tag
|
||||
}
|
||||
|
||||
// DestTag returns the tag of the struct containing the current dest item, if any.
|
||||
func (s *scope) DestTag() reflect.StructTag {
|
||||
return s.destStack.top().tag
|
||||
}
|
||||
|
||||
// Flags returns the flags with which the current conversion was started.
|
||||
func (s *scope) Flags() FieldMatchingFlags {
|
||||
return s.flags
|
||||
}
|
||||
|
||||
// Meta returns the meta object that was originally passed to Convert.
|
||||
func (s *scope) Meta() *Meta {
|
||||
return s.meta
|
||||
}
|
||||
|
||||
// describe prints the path to get to the current (source, dest) values.
|
||||
func (s *scope) describe() (src, dest string) {
|
||||
return s.srcStack.describe(), s.destStack.describe()
|
||||
}
|
||||
|
||||
// error makes an error that includes information about where we were in the objects
|
||||
// we were asked to convert.
|
||||
func (s *scope) errorf(message string, args ...interface{}) error {
|
||||
srcPath, destPath := s.describe()
|
||||
where := fmt.Sprintf("converting %v to %v: ", srcPath, destPath)
|
||||
return fmt.Errorf(where+message, args...)
|
||||
}
|
||||
|
||||
// Verifies whether a conversion function has a correct signature.
|
||||
func verifyConversionFunctionSignature(ft reflect.Type) error {
|
||||
if ft.Kind() != reflect.Func {
|
||||
return fmt.Errorf("expected func, got: %v", ft)
|
||||
}
|
||||
if ft.NumIn() != 3 {
|
||||
return fmt.Errorf("expected three 'in' params, got: %v", ft)
|
||||
}
|
||||
if ft.NumOut() != 1 {
|
||||
return fmt.Errorf("expected one 'out' param, got: %v", ft)
|
||||
}
|
||||
if ft.In(0).Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
|
||||
}
|
||||
if ft.In(1).Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("expected pointer arg for 'in' param 1, got: %v", ft)
|
||||
}
|
||||
scopeType := Scope(nil)
|
||||
if e, a := reflect.TypeOf(&scopeType).Elem(), ft.In(2); e != a {
|
||||
return fmt.Errorf("expected '%v' arg for 'in' param 2, got '%v' (%v)", e, a, ft)
|
||||
}
|
||||
var forErrorType error
|
||||
// This convolution is necessary, otherwise TypeOf picks up on the fact
|
||||
// that forErrorType is nil.
|
||||
errorType := reflect.TypeOf(&forErrorType).Elem()
|
||||
if ft.Out(0) != errorType {
|
||||
return fmt.Errorf("expected error return, got: %v", ft)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterConversionFunc registers a conversion func with the
|
||||
// Converter. conversionFunc must take three parameters: a pointer to the input
|
||||
// type, a pointer to the output type, and a conversion.Scope (which should be
|
||||
// used if recursive conversion calls are desired). It must return an error.
|
||||
//
|
||||
// Example:
|
||||
// c.RegisterConversionFunc(
|
||||
// func(in *Pod, out *v1.Pod, s Scope) error {
|
||||
// // conversion logic...
|
||||
// return nil
|
||||
// })
|
||||
func (c *Converter) RegisterConversionFunc(conversionFunc interface{}) error {
|
||||
return c.conversionFuncs.Add(conversionFunc)
|
||||
}
|
||||
|
||||
// Similar to RegisterConversionFunc, but registers conversion function that were
|
||||
// automatically generated.
|
||||
func (c *Converter) RegisterGeneratedConversionFunc(conversionFunc interface{}) error {
|
||||
return c.generatedConversionFuncs.Add(conversionFunc)
|
||||
}
|
||||
|
||||
// RegisterIgnoredConversion registers a "no-op" for conversion, where any requested
|
||||
// conversion between from and to is ignored.
|
||||
func (c *Converter) RegisterIgnoredConversion(from, to interface{}) error {
|
||||
typeFrom := reflect.TypeOf(from)
|
||||
typeTo := reflect.TypeOf(to)
|
||||
if reflect.TypeOf(from).Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("expected pointer arg for 'from' param 0, got: %v", typeFrom)
|
||||
}
|
||||
if typeTo.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("expected pointer arg for 'to' param 1, got: %v", typeTo)
|
||||
}
|
||||
c.ignoredConversions[typePair{typeFrom.Elem(), typeTo.Elem()}] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsConversionIgnored returns true if the specified objects should be dropped during
|
||||
// conversion.
|
||||
func (c *Converter) IsConversionIgnored(inType, outType reflect.Type) bool {
|
||||
_, found := c.ignoredConversions[typePair{inType, outType}]
|
||||
return found
|
||||
}
|
||||
|
||||
func (c *Converter) HasConversionFunc(inType, outType reflect.Type) bool {
|
||||
_, found := c.conversionFuncs.fns[typePair{inType, outType}]
|
||||
return found
|
||||
}
|
||||
|
||||
func (c *Converter) ConversionFuncValue(inType, outType reflect.Type) (reflect.Value, bool) {
|
||||
value, found := c.conversionFuncs.fns[typePair{inType, outType}]
|
||||
return value, found
|
||||
}
|
||||
|
||||
// SetStructFieldCopy registers a correspondence. Whenever a struct field is encountered
|
||||
// which has a type and name matching srcFieldType and srcFieldName, it wil be copied
|
||||
// into the field in the destination struct matching destFieldType & Name, if such a
|
||||
// field exists.
|
||||
// May be called multiple times, even for the same source field & type--all applicable
|
||||
// copies will be performed.
|
||||
func (c *Converter) SetStructFieldCopy(srcFieldType interface{}, srcFieldName string, destFieldType interface{}, destFieldName string) error {
|
||||
st := reflect.TypeOf(srcFieldType)
|
||||
dt := reflect.TypeOf(destFieldType)
|
||||
srcKey := typeNamePair{st, srcFieldName}
|
||||
destKey := typeNamePair{dt, destFieldName}
|
||||
c.structFieldDests[srcKey] = append(c.structFieldDests[srcKey], destKey)
|
||||
c.structFieldSources[destKey] = append(c.structFieldSources[destKey], srcKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterDefaultingFunc registers a value-defaulting func with the Converter.
|
||||
// defaultingFunc must take one parameters: a pointer to the input type.
|
||||
//
|
||||
// Example:
|
||||
// c.RegisteDefaultingFunc(
|
||||
// func(in *v1.Pod) {
|
||||
// // defaulting logic...
|
||||
// })
|
||||
func (c *Converter) RegisterDefaultingFunc(defaultingFunc interface{}) error {
|
||||
fv := reflect.ValueOf(defaultingFunc)
|
||||
ft := fv.Type()
|
||||
if ft.Kind() != reflect.Func {
|
||||
return fmt.Errorf("expected func, got: %v", ft)
|
||||
}
|
||||
if ft.NumIn() != 1 {
|
||||
return fmt.Errorf("expected one 'in' param, got: %v", ft)
|
||||
}
|
||||
if ft.NumOut() != 0 {
|
||||
return fmt.Errorf("expected zero 'out' params, got: %v", ft)
|
||||
}
|
||||
if ft.In(0).Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("expected pointer arg for 'in' param 0, got: %v", ft)
|
||||
}
|
||||
inType := ft.In(0).Elem()
|
||||
c.defaultingFuncs[inType] = fv
|
||||
c.defaultingInterfaces[inType] = defaultingFunc
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterInputDefaults registers a field name mapping function, used when converting
|
||||
// from maps to structs. Inputs to the conversion methods are checked for this type and a mapping
|
||||
// applied automatically if the input matches in. A set of default flags for the input conversion
|
||||
// may also be provided, which will be used when no explicit flags are requested.
|
||||
func (c *Converter) RegisterInputDefaults(in interface{}, fn FieldMappingFunc, defaultFlags FieldMatchingFlags) error {
|
||||
fv := reflect.ValueOf(in)
|
||||
ft := fv.Type()
|
||||
if ft.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("expected pointer 'in' argument, got: %v", ft)
|
||||
}
|
||||
c.inputFieldMappingFuncs[ft] = fn
|
||||
c.inputDefaultFlags[ft] = defaultFlags
|
||||
return nil
|
||||
}
|
||||
|
||||
// FieldMatchingFlags contains a list of ways in which struct fields could be
|
||||
// copied. These constants may be | combined.
|
||||
type FieldMatchingFlags int
|
||||
|
||||
const (
|
||||
// Loop through destination fields, search for matching source
|
||||
// field to copy it from. Source fields with no corresponding
|
||||
// destination field will be ignored. If SourceToDest is
|
||||
// specified, this flag is ignored. If neither is specified,
|
||||
// or no flags are passed, this flag is the default.
|
||||
DestFromSource FieldMatchingFlags = 0
|
||||
// Loop through source fields, search for matching dest field
|
||||
// to copy it into. Destination fields with no corresponding
|
||||
// source field will be ignored.
|
||||
SourceToDest FieldMatchingFlags = 1 << iota
|
||||
// Don't treat it as an error if the corresponding source or
|
||||
// dest field can't be found.
|
||||
IgnoreMissingFields
|
||||
// Don't require type names to match.
|
||||
AllowDifferentFieldTypeNames
|
||||
)
|
||||
|
||||
// IsSet returns true if the given flag or combination of flags is set.
|
||||
func (f FieldMatchingFlags) IsSet(flag FieldMatchingFlags) bool {
|
||||
if flag == DestFromSource {
|
||||
// The bit logic doesn't work on the default value.
|
||||
return f&SourceToDest != SourceToDest
|
||||
}
|
||||
return f&flag == flag
|
||||
}
|
||||
|
||||
// Convert will translate src to dest if it knows how. Both must be pointers.
|
||||
// If no conversion func is registered and the default copying mechanism
|
||||
// doesn't work on this type pair, an error will be returned.
|
||||
// Read the comments on the various FieldMatchingFlags constants to understand
|
||||
// what the 'flags' parameter does.
|
||||
// 'meta' is given to allow you to pass information to conversion functions,
|
||||
// it is not used by Convert() other than storing it in the scope.
|
||||
// Not safe for objects with cyclic references!
|
||||
func (c *Converter) Convert(src, dest interface{}, flags FieldMatchingFlags, meta *Meta) error {
|
||||
if len(c.genericConversions) > 0 {
|
||||
// TODO: avoid scope allocation
|
||||
s := &scope{converter: c, flags: flags, meta: meta}
|
||||
for _, fn := range c.genericConversions {
|
||||
if ok, err := fn(src, dest, s); ok {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return c.doConversion(src, dest, flags, meta, c.convert)
|
||||
}
|
||||
|
||||
// DefaultConvert will translate src to dest if it knows how. Both must be pointers.
|
||||
// No conversion func is used. If the default copying mechanism
|
||||
// doesn't work on this type pair, an error will be returned.
|
||||
// Read the comments on the various FieldMatchingFlags constants to understand
|
||||
// what the 'flags' parameter does.
|
||||
// 'meta' is given to allow you to pass information to conversion functions,
|
||||
// it is not used by DefaultConvert() other than storing it in the scope.
|
||||
// Not safe for objects with cyclic references!
|
||||
func (c *Converter) DefaultConvert(src, dest interface{}, flags FieldMatchingFlags, meta *Meta) error {
|
||||
return c.doConversion(src, dest, flags, meta, c.defaultConvert)
|
||||
}
|
||||
|
||||
type conversionFunc func(sv, dv reflect.Value, scope *scope) error
|
||||
|
||||
func (c *Converter) doConversion(src, dest interface{}, flags FieldMatchingFlags, meta *Meta, f conversionFunc) error {
|
||||
dv, err := EnforcePtr(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !dv.CanAddr() && !dv.CanSet() {
|
||||
return fmt.Errorf("can't write to dest")
|
||||
}
|
||||
sv, err := EnforcePtr(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := &scope{
|
||||
converter: c,
|
||||
flags: flags,
|
||||
meta: meta,
|
||||
}
|
||||
// Leave something on the stack, so that calls to struct tag getters never fail.
|
||||
s.srcStack.push(scopeStackElem{})
|
||||
s.destStack.push(scopeStackElem{})
|
||||
return f(sv, dv, s)
|
||||
}
|
||||
|
||||
// callCustom calls 'custom' with sv & dv. custom must be a conversion function.
|
||||
func (c *Converter) callCustom(sv, dv, custom reflect.Value, scope *scope) error {
|
||||
if !sv.CanAddr() {
|
||||
sv2 := reflect.New(sv.Type())
|
||||
sv2.Elem().Set(sv)
|
||||
sv = sv2
|
||||
} else {
|
||||
sv = sv.Addr()
|
||||
}
|
||||
if !dv.CanAddr() {
|
||||
if !dv.CanSet() {
|
||||
return scope.errorf("can't addr or set dest.")
|
||||
}
|
||||
dvOrig := dv
|
||||
dv := reflect.New(dvOrig.Type())
|
||||
defer func() { dvOrig.Set(dv) }()
|
||||
} else {
|
||||
dv = dv.Addr()
|
||||
}
|
||||
args := []reflect.Value{sv, dv, reflect.ValueOf(scope)}
|
||||
ret := custom.Call(args)[0].Interface()
|
||||
// This convolution is necessary because nil interfaces won't convert
|
||||
// to errors.
|
||||
if ret == nil {
|
||||
return nil
|
||||
}
|
||||
return ret.(error)
|
||||
}
|
||||
|
||||
// convert recursively copies sv into dv, calling an appropriate conversion function if
|
||||
// one is registered.
|
||||
func (c *Converter) convert(sv, dv reflect.Value, scope *scope) error {
|
||||
dt, st := dv.Type(), sv.Type()
|
||||
// Apply default values.
|
||||
if fv, ok := c.defaultingFuncs[st]; ok {
|
||||
if c.Debug != nil {
|
||||
c.Debug.Logf("Applying defaults for '%v'", st)
|
||||
}
|
||||
args := []reflect.Value{sv.Addr()}
|
||||
fv.Call(args)
|
||||
}
|
||||
|
||||
pair := typePair{st, dt}
|
||||
|
||||
// ignore conversions of this type
|
||||
if _, ok := c.ignoredConversions[pair]; ok {
|
||||
if c.Debug != nil {
|
||||
c.Debug.Logf("Ignoring conversion of '%v' to '%v'", st, dt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert sv to dv.
|
||||
if fv, ok := c.conversionFuncs.fns[pair]; ok {
|
||||
if c.Debug != nil {
|
||||
c.Debug.Logf("Calling custom conversion of '%v' to '%v'", st, dt)
|
||||
}
|
||||
return c.callCustom(sv, dv, fv, scope)
|
||||
}
|
||||
if fv, ok := c.generatedConversionFuncs.fns[pair]; ok {
|
||||
if c.Debug != nil {
|
||||
c.Debug.Logf("Calling generated conversion of '%v' to '%v'", st, dt)
|
||||
}
|
||||
return c.callCustom(sv, dv, fv, scope)
|
||||
}
|
||||
|
||||
return c.defaultConvert(sv, dv, scope)
|
||||
}
|
||||
|
||||
// defaultConvert recursively copies sv into dv. no conversion function is called
|
||||
// for the current stack frame (but conversion functions may be called for nested objects)
|
||||
func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error {
|
||||
dt, st := dv.Type(), sv.Type()
|
||||
|
||||
if !dv.CanSet() {
|
||||
return scope.errorf("Cannot set dest. (Tried to deep copy something with unexported fields?)")
|
||||
}
|
||||
|
||||
if !scope.flags.IsSet(AllowDifferentFieldTypeNames) && c.nameFunc(dt) != c.nameFunc(st) {
|
||||
return scope.errorf(
|
||||
"type names don't match (%v, %v), and no conversion 'func (%v, %v) error' registered.",
|
||||
c.nameFunc(st), c.nameFunc(dt), st, dt)
|
||||
}
|
||||
|
||||
switch st.Kind() {
|
||||
case reflect.Map, reflect.Ptr, reflect.Slice, reflect.Interface, reflect.Struct:
|
||||
// Don't copy these via assignment/conversion!
|
||||
default:
|
||||
// This should handle all simple types.
|
||||
if st.AssignableTo(dt) {
|
||||
dv.Set(sv)
|
||||
return nil
|
||||
}
|
||||
if st.ConvertibleTo(dt) {
|
||||
dv.Set(sv.Convert(dt))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if c.Debug != nil {
|
||||
c.Debug.Logf("Trying to convert '%v' to '%v'", st, dt)
|
||||
}
|
||||
|
||||
scope.srcStack.push(scopeStackElem{value: sv})
|
||||
scope.destStack.push(scopeStackElem{value: dv})
|
||||
defer scope.srcStack.pop()
|
||||
defer scope.destStack.pop()
|
||||
|
||||
switch dv.Kind() {
|
||||
case reflect.Struct:
|
||||
return c.convertKV(toKVValue(sv), toKVValue(dv), scope)
|
||||
case reflect.Slice:
|
||||
if sv.IsNil() {
|
||||
// Don't make a zero-length slice.
|
||||
dv.Set(reflect.Zero(dt))
|
||||
return nil
|
||||
}
|
||||
dv.Set(reflect.MakeSlice(dt, sv.Len(), sv.Cap()))
|
||||
for i := 0; i < sv.Len(); i++ {
|
||||
scope.setIndices(i, i)
|
||||
if err := c.convert(sv.Index(i), dv.Index(i), scope); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if sv.IsNil() {
|
||||
// Don't copy a nil ptr!
|
||||
dv.Set(reflect.Zero(dt))
|
||||
return nil
|
||||
}
|
||||
dv.Set(reflect.New(dt.Elem()))
|
||||
switch st.Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
return c.convert(sv.Elem(), dv.Elem(), scope)
|
||||
default:
|
||||
return c.convert(sv, dv.Elem(), scope)
|
||||
}
|
||||
case reflect.Map:
|
||||
if sv.IsNil() {
|
||||
// Don't copy a nil ptr!
|
||||
dv.Set(reflect.Zero(dt))
|
||||
return nil
|
||||
}
|
||||
dv.Set(reflect.MakeMap(dt))
|
||||
for _, sk := range sv.MapKeys() {
|
||||
dk := reflect.New(dt.Key()).Elem()
|
||||
if err := c.convert(sk, dk, scope); err != nil {
|
||||
return err
|
||||
}
|
||||
dkv := reflect.New(dt.Elem()).Elem()
|
||||
scope.setKeys(sk.Interface(), dk.Interface())
|
||||
// TODO: sv.MapIndex(sk) may return a value with CanAddr() == false,
|
||||
// because a map[string]struct{} does not allow a pointer reference.
|
||||
// Calling a custom conversion function defined for the map value
|
||||
// will panic. Example is PodInfo map[string]ContainerStatus.
|
||||
if err := c.convert(sv.MapIndex(sk), dkv, scope); err != nil {
|
||||
return err
|
||||
}
|
||||
dv.SetMapIndex(dk, dkv)
|
||||
}
|
||||
case reflect.Interface:
|
||||
if sv.IsNil() {
|
||||
// Don't copy a nil interface!
|
||||
dv.Set(reflect.Zero(dt))
|
||||
return nil
|
||||
}
|
||||
tmpdv := reflect.New(sv.Elem().Type()).Elem()
|
||||
if err := c.convert(sv.Elem(), tmpdv, scope); err != nil {
|
||||
return err
|
||||
}
|
||||
dv.Set(reflect.ValueOf(tmpdv.Interface()))
|
||||
return nil
|
||||
default:
|
||||
return scope.errorf("couldn't copy '%v' into '%v'; didn't understand types", st, dt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var stringType = reflect.TypeOf("")
|
||||
|
||||
func toKVValue(v reflect.Value) kvValue {
|
||||
switch v.Kind() {
|
||||
case reflect.Struct:
|
||||
return structAdaptor(v)
|
||||
case reflect.Map:
|
||||
if v.Type().Key().AssignableTo(stringType) {
|
||||
return stringMapAdaptor(v)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// kvValue lets us write the same conversion logic to work with both maps
|
||||
// and structs. Only maps with string keys make sense for this.
|
||||
type kvValue interface {
|
||||
// returns all keys, as a []string.
|
||||
keys() []string
|
||||
// Will just return "" for maps.
|
||||
tagOf(key string) reflect.StructTag
|
||||
// Will return the zero Value if the key doesn't exist.
|
||||
value(key string) reflect.Value
|
||||
// Maps require explicit setting-- will do nothing for structs.
|
||||
// Returns false on failure.
|
||||
confirmSet(key string, v reflect.Value) bool
|
||||
}
|
||||
|
||||
type stringMapAdaptor reflect.Value
|
||||
|
||||
func (a stringMapAdaptor) len() int {
|
||||
return reflect.Value(a).Len()
|
||||
}
|
||||
|
||||
func (a stringMapAdaptor) keys() []string {
|
||||
v := reflect.Value(a)
|
||||
keys := make([]string, v.Len())
|
||||
for i, v := range v.MapKeys() {
|
||||
if v.IsNil() {
|
||||
continue
|
||||
}
|
||||
switch t := v.Interface().(type) {
|
||||
case string:
|
||||
keys[i] = t
|
||||
}
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func (a stringMapAdaptor) tagOf(key string) reflect.StructTag {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a stringMapAdaptor) value(key string) reflect.Value {
|
||||
return reflect.Value(a).MapIndex(reflect.ValueOf(key))
|
||||
}
|
||||
|
||||
func (a stringMapAdaptor) confirmSet(key string, v reflect.Value) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type structAdaptor reflect.Value
|
||||
|
||||
func (a structAdaptor) len() int {
|
||||
v := reflect.Value(a)
|
||||
return v.Type().NumField()
|
||||
}
|
||||
|
||||
func (a structAdaptor) keys() []string {
|
||||
v := reflect.Value(a)
|
||||
t := v.Type()
|
||||
keys := make([]string, t.NumField())
|
||||
for i := range keys {
|
||||
keys[i] = t.Field(i).Name
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func (a structAdaptor) tagOf(key string) reflect.StructTag {
|
||||
v := reflect.Value(a)
|
||||
field, ok := v.Type().FieldByName(key)
|
||||
if ok {
|
||||
return field.Tag
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a structAdaptor) value(key string) reflect.Value {
|
||||
v := reflect.Value(a)
|
||||
return v.FieldByName(key)
|
||||
}
|
||||
|
||||
func (a structAdaptor) confirmSet(key string, v reflect.Value) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// convertKV can convert things that consist of key/value pairs, like structs
|
||||
// and some maps.
|
||||
func (c *Converter) convertKV(skv, dkv kvValue, scope *scope) error {
|
||||
if skv == nil || dkv == nil {
|
||||
// TODO: add keys to stack to support really understandable error messages.
|
||||
return fmt.Errorf("Unable to convert %#v to %#v", skv, dkv)
|
||||
}
|
||||
|
||||
lister := dkv
|
||||
if scope.flags.IsSet(SourceToDest) {
|
||||
lister = skv
|
||||
}
|
||||
|
||||
var mapping FieldMappingFunc
|
||||
if scope.meta != nil && scope.meta.KeyNameMapping != nil {
|
||||
mapping = scope.meta.KeyNameMapping
|
||||
}
|
||||
|
||||
for _, key := range lister.keys() {
|
||||
if found, err := c.checkField(key, skv, dkv, scope); found {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
stag := skv.tagOf(key)
|
||||
dtag := dkv.tagOf(key)
|
||||
skey := key
|
||||
dkey := key
|
||||
if mapping != nil {
|
||||
skey, dkey = scope.meta.KeyNameMapping(key, stag, dtag)
|
||||
}
|
||||
|
||||
df := dkv.value(dkey)
|
||||
sf := skv.value(skey)
|
||||
if !df.IsValid() || !sf.IsValid() {
|
||||
switch {
|
||||
case scope.flags.IsSet(IgnoreMissingFields):
|
||||
// No error.
|
||||
case scope.flags.IsSet(SourceToDest):
|
||||
return scope.errorf("%v not present in dest", dkey)
|
||||
default:
|
||||
return scope.errorf("%v not present in src", skey)
|
||||
}
|
||||
continue
|
||||
}
|
||||
scope.srcStack.top().key = skey
|
||||
scope.srcStack.top().tag = stag
|
||||
scope.destStack.top().key = dkey
|
||||
scope.destStack.top().tag = dtag
|
||||
if err := c.convert(sf, df, scope); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkField returns true if the field name matches any of the struct
|
||||
// field copying rules. The error should be ignored if it returns false.
|
||||
func (c *Converter) checkField(fieldName string, skv, dkv kvValue, scope *scope) (bool, error) {
|
||||
replacementMade := false
|
||||
if scope.flags.IsSet(DestFromSource) {
|
||||
df := dkv.value(fieldName)
|
||||
if !df.IsValid() {
|
||||
return false, nil
|
||||
}
|
||||
destKey := typeNamePair{df.Type(), fieldName}
|
||||
// Check each of the potential source (type, name) pairs to see if they're
|
||||
// present in sv.
|
||||
for _, potentialSourceKey := range c.structFieldSources[destKey] {
|
||||
sf := skv.value(potentialSourceKey.fieldName)
|
||||
if !sf.IsValid() {
|
||||
continue
|
||||
}
|
||||
if sf.Type() == potentialSourceKey.fieldType {
|
||||
// Both the source's name and type matched, so copy.
|
||||
scope.srcStack.top().key = potentialSourceKey.fieldName
|
||||
scope.destStack.top().key = fieldName
|
||||
if err := c.convert(sf, df, scope); err != nil {
|
||||
return true, err
|
||||
}
|
||||
dkv.confirmSet(fieldName, df)
|
||||
replacementMade = true
|
||||
}
|
||||
}
|
||||
return replacementMade, nil
|
||||
}
|
||||
|
||||
sf := skv.value(fieldName)
|
||||
if !sf.IsValid() {
|
||||
return false, nil
|
||||
}
|
||||
srcKey := typeNamePair{sf.Type(), fieldName}
|
||||
// Check each of the potential dest (type, name) pairs to see if they're
|
||||
// present in dv.
|
||||
for _, potentialDestKey := range c.structFieldDests[srcKey] {
|
||||
df := dkv.value(potentialDestKey.fieldName)
|
||||
if !df.IsValid() {
|
||||
continue
|
||||
}
|
||||
if df.Type() == potentialDestKey.fieldType {
|
||||
// Both the dest's name and type matched, so copy.
|
||||
scope.srcStack.top().key = fieldName
|
||||
scope.destStack.top().key = potentialDestKey.fieldName
|
||||
if err := c.convert(sf, df, scope); err != nil {
|
||||
return true, err
|
||||
}
|
||||
dkv.confirmSet(potentialDestKey.fieldName, df)
|
||||
replacementMade = true
|
||||
}
|
||||
}
|
||||
return replacementMade, nil
|
||||
}
|
||||
24
vendor/k8s.io/client-go/1.4/pkg/conversion/doc.go
generated
vendored
24
vendor/k8s.io/client-go/1.4/pkg/conversion/doc.go
generated
vendored
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package conversion provides go object versioning.
|
||||
//
|
||||
// Specifically, conversion provides a way for you to define multiple versions
|
||||
// of the same object. You may write functions which implement conversion logic,
|
||||
// but for the fields which did not change, copying is automated. This makes it
|
||||
// easy to modify the structures you use in memory without affecting the format
|
||||
// you store on disk or respond to in your external API calls.
|
||||
package conversion
|
||||
39
vendor/k8s.io/client-go/1.4/pkg/conversion/helper.go
generated
vendored
39
vendor/k8s.io/client-go/1.4/pkg/conversion/helper.go
generated
vendored
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package conversion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// EnforcePtr ensures that obj is a pointer of some sort. Returns a reflect.Value
|
||||
// of the dereferenced pointer, ensuring that it is settable/addressable.
|
||||
// Returns an error if this is not possible.
|
||||
func EnforcePtr(obj interface{}) (reflect.Value, error) {
|
||||
v := reflect.ValueOf(obj)
|
||||
if v.Kind() != reflect.Ptr {
|
||||
if v.Kind() == reflect.Invalid {
|
||||
return reflect.Value{}, fmt.Errorf("expected pointer, but got invalid kind")
|
||||
}
|
||||
return reflect.Value{}, fmt.Errorf("expected pointer, but got %v type", v.Type())
|
||||
}
|
||||
if v.IsNil() {
|
||||
return reflect.Value{}, fmt.Errorf("expected pointer, but got nil")
|
||||
}
|
||||
return v.Elem(), nil
|
||||
}
|
||||
188
vendor/k8s.io/client-go/1.4/pkg/conversion/queryparams/convert.go
generated
vendored
188
vendor/k8s.io/client-go/1.4/pkg/conversion/queryparams/convert.go
generated
vendored
|
|
@ -1,188 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package queryparams
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Marshaler converts an object to a query parameter string representation
|
||||
type Marshaler interface {
|
||||
MarshalQueryParameter() (string, error)
|
||||
}
|
||||
|
||||
// Unmarshaler converts a string representation to an object
|
||||
type Unmarshaler interface {
|
||||
UnmarshalQueryParameter(string) error
|
||||
}
|
||||
|
||||
func jsonTag(field reflect.StructField) (string, bool) {
|
||||
structTag := field.Tag.Get("json")
|
||||
if len(structTag) == 0 {
|
||||
return "", false
|
||||
}
|
||||
parts := strings.Split(structTag, ",")
|
||||
tag := parts[0]
|
||||
if tag == "-" {
|
||||
tag = ""
|
||||
}
|
||||
omitempty := false
|
||||
parts = parts[1:]
|
||||
for _, part := range parts {
|
||||
if part == "omitempty" {
|
||||
omitempty = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return tag, omitempty
|
||||
}
|
||||
|
||||
func formatValue(value interface{}) string {
|
||||
return fmt.Sprintf("%v", value)
|
||||
}
|
||||
|
||||
func isPointerKind(kind reflect.Kind) bool {
|
||||
return kind == reflect.Ptr
|
||||
}
|
||||
|
||||
func isStructKind(kind reflect.Kind) bool {
|
||||
return kind == reflect.Struct
|
||||
}
|
||||
|
||||
func isValueKind(kind reflect.Kind) bool {
|
||||
switch kind {
|
||||
case reflect.String, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16,
|
||||
reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8,
|
||||
reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32,
|
||||
reflect.Float64, reflect.Complex64, reflect.Complex128:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func zeroValue(value reflect.Value) bool {
|
||||
return reflect.DeepEqual(reflect.Zero(value.Type()).Interface(), value.Interface())
|
||||
}
|
||||
|
||||
func customMarshalValue(value reflect.Value) (reflect.Value, bool) {
|
||||
// Return unless we implement a custom query marshaler
|
||||
if !value.CanInterface() {
|
||||
return reflect.Value{}, false
|
||||
}
|
||||
|
||||
marshaler, ok := value.Interface().(Marshaler)
|
||||
if !ok {
|
||||
return reflect.Value{}, false
|
||||
}
|
||||
|
||||
// Don't invoke functions on nil pointers
|
||||
// If the type implements MarshalQueryParameter, AND the tag is not omitempty, AND the value is a nil pointer, "" seems like a reasonable response
|
||||
if isPointerKind(value.Kind()) && zeroValue(value) {
|
||||
return reflect.ValueOf(""), true
|
||||
}
|
||||
|
||||
// Get the custom marshalled value
|
||||
v, err := marshaler.MarshalQueryParameter()
|
||||
if err != nil {
|
||||
return reflect.Value{}, false
|
||||
}
|
||||
return reflect.ValueOf(v), true
|
||||
}
|
||||
|
||||
func addParam(values url.Values, tag string, omitempty bool, value reflect.Value) {
|
||||
if omitempty && zeroValue(value) {
|
||||
return
|
||||
}
|
||||
val := ""
|
||||
iValue := fmt.Sprintf("%v", value.Interface())
|
||||
|
||||
if iValue != "<nil>" {
|
||||
val = iValue
|
||||
}
|
||||
values.Add(tag, val)
|
||||
}
|
||||
|
||||
func addListOfParams(values url.Values, tag string, omitempty bool, list reflect.Value) {
|
||||
for i := 0; i < list.Len(); i++ {
|
||||
addParam(values, tag, omitempty, list.Index(i))
|
||||
}
|
||||
}
|
||||
|
||||
// Convert takes an object and converts it to a url.Values object using JSON tags as
|
||||
// parameter names. Only top-level simple values, arrays, and slices are serialized.
|
||||
// Embedded structs, maps, etc. will not be serialized.
|
||||
func Convert(obj interface{}) (url.Values, error) {
|
||||
result := url.Values{}
|
||||
if obj == nil {
|
||||
return result, nil
|
||||
}
|
||||
var sv reflect.Value
|
||||
switch reflect.TypeOf(obj).Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
sv = reflect.ValueOf(obj).Elem()
|
||||
default:
|
||||
return nil, fmt.Errorf("expecting a pointer or interface")
|
||||
}
|
||||
st := sv.Type()
|
||||
if !isStructKind(st.Kind()) {
|
||||
return nil, fmt.Errorf("expecting a pointer to a struct")
|
||||
}
|
||||
|
||||
// Check all object fields
|
||||
convertStruct(result, st, sv)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func convertStruct(result url.Values, st reflect.Type, sv reflect.Value) {
|
||||
for i := 0; i < st.NumField(); i++ {
|
||||
field := sv.Field(i)
|
||||
tag, omitempty := jsonTag(st.Field(i))
|
||||
if len(tag) == 0 {
|
||||
continue
|
||||
}
|
||||
ft := field.Type()
|
||||
|
||||
kind := ft.Kind()
|
||||
if isPointerKind(kind) {
|
||||
ft = ft.Elem()
|
||||
kind = ft.Kind()
|
||||
if !field.IsNil() {
|
||||
field = reflect.Indirect(field)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case isValueKind(kind):
|
||||
addParam(result, tag, omitempty, field)
|
||||
case kind == reflect.Array || kind == reflect.Slice:
|
||||
if isValueKind(ft.Elem().Kind()) {
|
||||
addListOfParams(result, tag, omitempty, field)
|
||||
}
|
||||
case isStructKind(kind) && !(zeroValue(field) && omitempty):
|
||||
if marshalValue, ok := customMarshalValue(field); ok {
|
||||
addParam(result, tag, omitempty, marshalValue)
|
||||
} else {
|
||||
convertStruct(result, ft, field)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
vendor/k8s.io/client-go/1.4/pkg/conversion/queryparams/doc.go
generated
vendored
19
vendor/k8s.io/client-go/1.4/pkg/conversion/queryparams/doc.go
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package queryparams provides conversion from versioned
|
||||
// runtime objects to URL query values
|
||||
package queryparams
|
||||
19
vendor/k8s.io/client-go/1.4/pkg/fields/doc.go
generated
vendored
19
vendor/k8s.io/client-go/1.4/pkg/fields/doc.go
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package fields implements a simple field system, parsing and matching
|
||||
// selectors with sets of fields.
|
||||
package fields
|
||||
62
vendor/k8s.io/client-go/1.4/pkg/fields/fields.go
generated
vendored
62
vendor/k8s.io/client-go/1.4/pkg/fields/fields.go
generated
vendored
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fields
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Fields allows you to present fields independently from their storage.
|
||||
type Fields interface {
|
||||
// Has returns whether the provided field exists.
|
||||
Has(field string) (exists bool)
|
||||
|
||||
// Get returns the value for the provided field.
|
||||
Get(field string) (value string)
|
||||
}
|
||||
|
||||
// Set is a map of field:value. It implements Fields.
|
||||
type Set map[string]string
|
||||
|
||||
// String returns all fields listed as a human readable string.
|
||||
// Conveniently, exactly the format that ParseSelector takes.
|
||||
func (ls Set) String() string {
|
||||
selector := make([]string, 0, len(ls))
|
||||
for key, value := range ls {
|
||||
selector = append(selector, key+"="+value)
|
||||
}
|
||||
// Sort for determinism.
|
||||
sort.StringSlice(selector).Sort()
|
||||
return strings.Join(selector, ",")
|
||||
}
|
||||
|
||||
// Has returns whether the provided field exists in the map.
|
||||
func (ls Set) Has(field string) bool {
|
||||
_, exists := ls[field]
|
||||
return exists
|
||||
}
|
||||
|
||||
// Get returns the value in the map for the provided field.
|
||||
func (ls Set) Get(field string) string {
|
||||
return ls[field]
|
||||
}
|
||||
|
||||
// AsSelector converts fields into a selectors.
|
||||
func (ls Set) AsSelector() Selector {
|
||||
return SelectorFromSet(ls)
|
||||
}
|
||||
278
vendor/k8s.io/client-go/1.4/pkg/fields/selector.go
generated
vendored
278
vendor/k8s.io/client-go/1.4/pkg/fields/selector.go
generated
vendored
|
|
@ -1,278 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fields
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.4/pkg/selection"
|
||||
)
|
||||
|
||||
// Selector represents a field selector.
|
||||
type Selector interface {
|
||||
// Matches returns true if this selector matches the given set of fields.
|
||||
Matches(Fields) bool
|
||||
|
||||
// Empty returns true if this selector does not restrict the selection space.
|
||||
Empty() bool
|
||||
|
||||
// RequiresExactMatch allows a caller to introspect whether a given selector
|
||||
// requires a single specific field to be set, and if so returns the value it
|
||||
// requires.
|
||||
RequiresExactMatch(field string) (value string, found bool)
|
||||
|
||||
// Transform returns a new copy of the selector after TransformFunc has been
|
||||
// applied to the entire selector, or an error if fn returns an error.
|
||||
Transform(fn TransformFunc) (Selector, error)
|
||||
|
||||
// Requirements converts this interface to Requirements to expose
|
||||
// more detailed selection information.
|
||||
Requirements() Requirements
|
||||
|
||||
// String returns a human readable string that represents this selector.
|
||||
String() string
|
||||
}
|
||||
|
||||
// Everything returns a selector that matches all fields.
|
||||
func Everything() Selector {
|
||||
return andTerm{}
|
||||
}
|
||||
|
||||
type hasTerm struct {
|
||||
field, value string
|
||||
}
|
||||
|
||||
func (t *hasTerm) Matches(ls Fields) bool {
|
||||
return ls.Get(t.field) == t.value
|
||||
}
|
||||
|
||||
func (t *hasTerm) Empty() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *hasTerm) RequiresExactMatch(field string) (value string, found bool) {
|
||||
if t.field == field {
|
||||
return t.value, true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (t *hasTerm) Transform(fn TransformFunc) (Selector, error) {
|
||||
field, value, err := fn(t.field, t.value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &hasTerm{field, value}, nil
|
||||
}
|
||||
|
||||
func (t *hasTerm) Requirements() Requirements {
|
||||
return []Requirement{{
|
||||
Field: t.field,
|
||||
Operator: selection.Equals,
|
||||
Value: t.value,
|
||||
}}
|
||||
}
|
||||
|
||||
func (t *hasTerm) String() string {
|
||||
return fmt.Sprintf("%v=%v", t.field, t.value)
|
||||
}
|
||||
|
||||
type notHasTerm struct {
|
||||
field, value string
|
||||
}
|
||||
|
||||
func (t *notHasTerm) Matches(ls Fields) bool {
|
||||
return ls.Get(t.field) != t.value
|
||||
}
|
||||
|
||||
func (t *notHasTerm) Empty() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *notHasTerm) RequiresExactMatch(field string) (value string, found bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (t *notHasTerm) Transform(fn TransformFunc) (Selector, error) {
|
||||
field, value, err := fn(t.field, t.value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ¬HasTerm{field, value}, nil
|
||||
}
|
||||
|
||||
func (t *notHasTerm) Requirements() Requirements {
|
||||
return []Requirement{{
|
||||
Field: t.field,
|
||||
Operator: selection.NotEquals,
|
||||
Value: t.value,
|
||||
}}
|
||||
}
|
||||
|
||||
func (t *notHasTerm) String() string {
|
||||
return fmt.Sprintf("%v!=%v", t.field, t.value)
|
||||
}
|
||||
|
||||
type andTerm []Selector
|
||||
|
||||
func (t andTerm) Matches(ls Fields) bool {
|
||||
for _, q := range t {
|
||||
if !q.Matches(ls) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (t andTerm) Empty() bool {
|
||||
if t == nil {
|
||||
return true
|
||||
}
|
||||
if len([]Selector(t)) == 0 {
|
||||
return true
|
||||
}
|
||||
for i := range t {
|
||||
if !t[i].Empty() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (t andTerm) RequiresExactMatch(field string) (string, bool) {
|
||||
if t == nil || len([]Selector(t)) == 0 {
|
||||
return "", false
|
||||
}
|
||||
for i := range t {
|
||||
if value, found := t[i].RequiresExactMatch(field); found {
|
||||
return value, found
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (t andTerm) Transform(fn TransformFunc) (Selector, error) {
|
||||
next := make([]Selector, len([]Selector(t)))
|
||||
for i, s := range []Selector(t) {
|
||||
n, err := s.Transform(fn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
next[i] = n
|
||||
}
|
||||
return andTerm(next), nil
|
||||
}
|
||||
|
||||
func (t andTerm) Requirements() Requirements {
|
||||
reqs := make([]Requirement, 0, len(t))
|
||||
for _, s := range []Selector(t) {
|
||||
rs := s.Requirements()
|
||||
reqs = append(reqs, rs...)
|
||||
}
|
||||
return reqs
|
||||
}
|
||||
|
||||
func (t andTerm) String() string {
|
||||
var terms []string
|
||||
for _, q := range t {
|
||||
terms = append(terms, q.String())
|
||||
}
|
||||
return strings.Join(terms, ",")
|
||||
}
|
||||
|
||||
// SelectorFromSet returns a Selector which will match exactly the given Set. A
|
||||
// nil Set is considered equivalent to Everything().
|
||||
func SelectorFromSet(ls Set) Selector {
|
||||
if ls == nil {
|
||||
return Everything()
|
||||
}
|
||||
items := make([]Selector, 0, len(ls))
|
||||
for field, value := range ls {
|
||||
items = append(items, &hasTerm{field: field, value: value})
|
||||
}
|
||||
if len(items) == 1 {
|
||||
return items[0]
|
||||
}
|
||||
return andTerm(items)
|
||||
}
|
||||
|
||||
// ParseSelectorOrDie takes a string representing a selector and returns an
|
||||
// object suitable for matching, or panic when an error occur.
|
||||
func ParseSelectorOrDie(s string) Selector {
|
||||
selector, err := ParseSelector(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// ParseSelector takes a string representing a selector and returns an
|
||||
// object suitable for matching, or an error.
|
||||
func ParseSelector(selector string) (Selector, error) {
|
||||
return parseSelector(selector,
|
||||
func(lhs, rhs string) (newLhs, newRhs string, err error) {
|
||||
return lhs, rhs, nil
|
||||
})
|
||||
}
|
||||
|
||||
// Parses the selector and runs them through the given TransformFunc.
|
||||
func ParseAndTransformSelector(selector string, fn TransformFunc) (Selector, error) {
|
||||
return parseSelector(selector, fn)
|
||||
}
|
||||
|
||||
// Function to transform selectors.
|
||||
type TransformFunc func(field, value string) (newField, newValue string, err error)
|
||||
|
||||
func try(selectorPiece, op string) (lhs, rhs string, ok bool) {
|
||||
pieces := strings.Split(selectorPiece, op)
|
||||
if len(pieces) == 2 {
|
||||
return pieces[0], pieces[1], true
|
||||
}
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
func parseSelector(selector string, fn TransformFunc) (Selector, error) {
|
||||
parts := strings.Split(selector, ",")
|
||||
sort.StringSlice(parts).Sort()
|
||||
var items []Selector
|
||||
for _, part := range parts {
|
||||
if part == "" {
|
||||
continue
|
||||
}
|
||||
if lhs, rhs, ok := try(part, "!="); ok {
|
||||
items = append(items, ¬HasTerm{field: lhs, value: rhs})
|
||||
} else if lhs, rhs, ok := try(part, "=="); ok {
|
||||
items = append(items, &hasTerm{field: lhs, value: rhs})
|
||||
} else if lhs, rhs, ok := try(part, "="); ok {
|
||||
items = append(items, &hasTerm{field: lhs, value: rhs})
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
|
||||
}
|
||||
}
|
||||
if len(items) == 1 {
|
||||
return items[0].Transform(fn)
|
||||
}
|
||||
return andTerm(items).Transform(fn)
|
||||
}
|
||||
|
||||
// OneTermEqualSelector returns an object that matches objects where one field/field equals one value.
|
||||
// Cannot return an error.
|
||||
func OneTermEqualSelector(k, v string) Selector {
|
||||
return &hasTerm{field: k, value: v}
|
||||
}
|
||||
19
vendor/k8s.io/client-go/1.4/pkg/labels/doc.go
generated
vendored
19
vendor/k8s.io/client-go/1.4/pkg/labels/doc.go
generated
vendored
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package labels implements a simple label system, parsing and matching
|
||||
// selectors with sets of labels.
|
||||
package labels
|
||||
80
vendor/k8s.io/client-go/1.4/pkg/labels/labels.go
generated
vendored
80
vendor/k8s.io/client-go/1.4/pkg/labels/labels.go
generated
vendored
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package labels
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Labels allows you to present labels independently from their storage.
|
||||
type Labels interface {
|
||||
// Has returns whether the provided label exists.
|
||||
Has(label string) (exists bool)
|
||||
|
||||
// Get returns the value for the provided label.
|
||||
Get(label string) (value string)
|
||||
}
|
||||
|
||||
// Set is a map of label:value. It implements Labels.
|
||||
type Set map[string]string
|
||||
|
||||
// String returns all labels listed as a human readable string.
|
||||
// Conveniently, exactly the format that ParseSelector takes.
|
||||
func (ls Set) String() string {
|
||||
selector := make([]string, 0, len(ls))
|
||||
for key, value := range ls {
|
||||
selector = append(selector, key+"="+value)
|
||||
}
|
||||
// Sort for determinism.
|
||||
sort.StringSlice(selector).Sort()
|
||||
return strings.Join(selector, ",")
|
||||
}
|
||||
|
||||
// Has returns whether the provided label exists in the map.
|
||||
func (ls Set) Has(label string) bool {
|
||||
_, exists := ls[label]
|
||||
return exists
|
||||
}
|
||||
|
||||
// Get returns the value in the map for the provided label.
|
||||
func (ls Set) Get(label string) string {
|
||||
return ls[label]
|
||||
}
|
||||
|
||||
// AsSelector converts labels into a selectors.
|
||||
func (ls Set) AsSelector() Selector {
|
||||
return SelectorFromSet(ls)
|
||||
}
|
||||
|
||||
// AsSelectorPreValidated converts labels into a selector, but
|
||||
// assumes that labels are already validated and thus don't
|
||||
// preform any validation.
|
||||
// According to our measurements this is significantly faster
|
||||
// in codepaths that matter at high sccale.
|
||||
func (ls Set) AsSelectorPreValidated() Selector {
|
||||
return SelectorFromValidatedSet(ls)
|
||||
}
|
||||
|
||||
// FormatLables convert label map into plain string
|
||||
func FormatLabels(labelMap map[string]string) string {
|
||||
l := Set(labelMap).String()
|
||||
if l == "" {
|
||||
l = "<none>"
|
||||
}
|
||||
return l
|
||||
}
|
||||
822
vendor/k8s.io/client-go/1.4/pkg/labels/selector.go
generated
vendored
822
vendor/k8s.io/client-go/1.4/pkg/labels/selector.go
generated
vendored
|
|
@ -1,822 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package labels
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/client-go/1.4/pkg/selection"
|
||||
"k8s.io/client-go/1.4/pkg/util/sets"
|
||||
"k8s.io/client-go/1.4/pkg/util/validation"
|
||||
)
|
||||
|
||||
// Requirements is AND of all requirements.
|
||||
type Requirements []Requirement
|
||||
|
||||
// Selector represents a label selector.
|
||||
type Selector interface {
|
||||
// Matches returns true if this selector matches the given set of labels.
|
||||
Matches(Labels) bool
|
||||
|
||||
// Empty returns true if this selector does not restrict the selection space.
|
||||
Empty() bool
|
||||
|
||||
// String returns a human readable string that represents this selector.
|
||||
String() string
|
||||
|
||||
// Add adds requirements to the Selector
|
||||
Add(r ...Requirement) Selector
|
||||
|
||||
// Requirements converts this interface into Requirements to expose
|
||||
// more detailed selection information.
|
||||
// If there are querying parameters, it will return converted requirements and selectable=true.
|
||||
// If this selector doesn't want to select anything, it will return selectable=false.
|
||||
Requirements() (requirements Requirements, selectable bool)
|
||||
}
|
||||
|
||||
// Everything returns a selector that matches all labels.
|
||||
func Everything() Selector {
|
||||
return internalSelector{}
|
||||
}
|
||||
|
||||
type nothingSelector struct{}
|
||||
|
||||
func (n nothingSelector) Matches(_ Labels) bool { return false }
|
||||
func (n nothingSelector) Empty() bool { return false }
|
||||
func (n nothingSelector) String() string { return "<null>" }
|
||||
func (n nothingSelector) Add(_ ...Requirement) Selector { return n }
|
||||
func (n nothingSelector) Requirements() (Requirements, bool) { return nil, false }
|
||||
|
||||
// Nothing returns a selector that matches no labels
|
||||
func Nothing() Selector {
|
||||
return nothingSelector{}
|
||||
}
|
||||
|
||||
func NewSelector() Selector {
|
||||
return internalSelector(nil)
|
||||
}
|
||||
|
||||
type internalSelector []Requirement
|
||||
|
||||
// Sort by key to obtain determisitic parser
|
||||
type ByKey []Requirement
|
||||
|
||||
func (a ByKey) Len() int { return len(a) }
|
||||
|
||||
func (a ByKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
|
||||
func (a ByKey) Less(i, j int) bool { return a[i].key < a[j].key }
|
||||
|
||||
// Requirement contains values, a key, and an operator that relates the key and values.
|
||||
// The zero value of Requirement is invalid.
|
||||
// Requirement implements both set based match and exact match
|
||||
// Requirement should be initialized via NewRequirement constructor for creating a valid Requirement.
|
||||
type Requirement struct {
|
||||
key string
|
||||
operator selection.Operator
|
||||
strValues sets.String
|
||||
}
|
||||
|
||||
// NewRequirement is the constructor for a Requirement.
|
||||
// If any of these rules is violated, an error is returned:
|
||||
// (1) The operator can only be In, NotIn, Equals, DoubleEquals, NotEquals, Exists, or DoesNotExist.
|
||||
// (2) If the operator is In or NotIn, the values set must be non-empty.
|
||||
// (3) If the operator is Equals, DoubleEquals, or NotEquals, the values set must contain one value.
|
||||
// (4) If the operator is Exists or DoesNotExist, the value set must be empty.
|
||||
// (5) If the operator is Gt or Lt, the values set must contain only one value, which will be interpreted as an integer.
|
||||
// (6) The key is invalid due to its length, or sequence
|
||||
// of characters. See validateLabelKey for more details.
|
||||
//
|
||||
// The empty string is a valid value in the input values set.
|
||||
func NewRequirement(key string, op selection.Operator, vals sets.String) (*Requirement, error) {
|
||||
if err := validateLabelKey(key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch op {
|
||||
case selection.In, selection.NotIn:
|
||||
if len(vals) == 0 {
|
||||
return nil, fmt.Errorf("for 'in', 'notin' operators, values set can't be empty")
|
||||
}
|
||||
case selection.Equals, selection.DoubleEquals, selection.NotEquals:
|
||||
if len(vals) != 1 {
|
||||
return nil, fmt.Errorf("exact-match compatibility requires one single value")
|
||||
}
|
||||
case selection.Exists, selection.DoesNotExist:
|
||||
if len(vals) != 0 {
|
||||
return nil, fmt.Errorf("values set must be empty for exists and does not exist")
|
||||
}
|
||||
case selection.GreaterThan, selection.LessThan:
|
||||
if len(vals) != 1 {
|
||||
return nil, fmt.Errorf("for 'Gt', 'Lt' operators, exactly one value is required")
|
||||
}
|
||||
for val := range vals {
|
||||
if _, err := strconv.ParseInt(val, 10, 64); err != nil {
|
||||
return nil, fmt.Errorf("for 'Gt', 'Lt' operators, the value must be an integer")
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("operator '%v' is not recognized", op)
|
||||
}
|
||||
|
||||
for v := range vals {
|
||||
if err := validateLabelValue(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &Requirement{key: key, operator: op, strValues: vals}, nil
|
||||
}
|
||||
|
||||
// Matches returns true if the Requirement matches the input Labels.
|
||||
// There is a match in the following cases:
|
||||
// (1) The operator is Exists and Labels has the Requirement's key.
|
||||
// (2) The operator is In, Labels has the Requirement's key and Labels'
|
||||
// value for that key is in Requirement's value set.
|
||||
// (3) The operator is NotIn, Labels has the Requirement's key and
|
||||
// Labels' value for that key is not in Requirement's value set.
|
||||
// (4) The operator is DoesNotExist or NotIn and Labels does not have the
|
||||
// Requirement's key.
|
||||
// (5) The operator is GreaterThanOperator or LessThanOperator, and Labels has
|
||||
// the Requirement's key and the corresponding value satisfies mathematical inequality.
|
||||
func (r *Requirement) Matches(ls Labels) bool {
|
||||
switch r.operator {
|
||||
case selection.In, selection.Equals, selection.DoubleEquals:
|
||||
if !ls.Has(r.key) {
|
||||
return false
|
||||
}
|
||||
return r.strValues.Has(ls.Get(r.key))
|
||||
case selection.NotIn, selection.NotEquals:
|
||||
if !ls.Has(r.key) {
|
||||
return true
|
||||
}
|
||||
return !r.strValues.Has(ls.Get(r.key))
|
||||
case selection.Exists:
|
||||
return ls.Has(r.key)
|
||||
case selection.DoesNotExist:
|
||||
return !ls.Has(r.key)
|
||||
case selection.GreaterThan, selection.LessThan:
|
||||
if !ls.Has(r.key) {
|
||||
return false
|
||||
}
|
||||
lsValue, err := strconv.ParseInt(ls.Get(r.key), 10, 64)
|
||||
if err != nil {
|
||||
glog.V(10).Infof("ParseInt failed for value %+v in label %+v, %+v", ls.Get(r.key), ls, err)
|
||||
return false
|
||||
}
|
||||
|
||||
// There should be only one strValue in r.strValues, and can be converted to a integer.
|
||||
if len(r.strValues) != 1 {
|
||||
glog.V(10).Infof("Invalid values count %+v of requirement %#v, for 'Gt', 'Lt' operators, exactly one value is required", len(r.strValues), r)
|
||||
return false
|
||||
}
|
||||
|
||||
var rValue int64
|
||||
for strValue := range r.strValues {
|
||||
rValue, err = strconv.ParseInt(strValue, 10, 64)
|
||||
if err != nil {
|
||||
glog.V(10).Infof("ParseInt failed for value %+v in requirement %#v, for 'Gt', 'Lt' operators, the value must be an integer", strValue, r)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return (r.operator == selection.GreaterThan && lsValue > rValue) || (r.operator == selection.LessThan && lsValue < rValue)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Requirement) Key() string {
|
||||
return r.key
|
||||
}
|
||||
func (r *Requirement) Operator() selection.Operator {
|
||||
return r.operator
|
||||
}
|
||||
func (r *Requirement) Values() sets.String {
|
||||
ret := sets.String{}
|
||||
for k := range r.strValues {
|
||||
ret.Insert(k)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Return true if the internalSelector doesn't restrict selection space
|
||||
func (lsel internalSelector) Empty() bool {
|
||||
if lsel == nil {
|
||||
return true
|
||||
}
|
||||
return len(lsel) == 0
|
||||
}
|
||||
|
||||
// String returns a human-readable string that represents this
|
||||
// Requirement. If called on an invalid Requirement, an error is
|
||||
// returned. See NewRequirement for creating a valid Requirement.
|
||||
func (r *Requirement) String() string {
|
||||
var buffer bytes.Buffer
|
||||
if r.operator == selection.DoesNotExist {
|
||||
buffer.WriteString("!")
|
||||
}
|
||||
buffer.WriteString(r.key)
|
||||
|
||||
switch r.operator {
|
||||
case selection.Equals:
|
||||
buffer.WriteString("=")
|
||||
case selection.DoubleEquals:
|
||||
buffer.WriteString("==")
|
||||
case selection.NotEquals:
|
||||
buffer.WriteString("!=")
|
||||
case selection.In:
|
||||
buffer.WriteString(" in ")
|
||||
case selection.NotIn:
|
||||
buffer.WriteString(" notin ")
|
||||
case selection.GreaterThan:
|
||||
buffer.WriteString(">")
|
||||
case selection.LessThan:
|
||||
buffer.WriteString("<")
|
||||
case selection.Exists, selection.DoesNotExist:
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
switch r.operator {
|
||||
case selection.In, selection.NotIn:
|
||||
buffer.WriteString("(")
|
||||
}
|
||||
if len(r.strValues) == 1 {
|
||||
buffer.WriteString(r.strValues.List()[0])
|
||||
} else { // only > 1 since == 0 prohibited by NewRequirement
|
||||
buffer.WriteString(strings.Join(r.strValues.List(), ","))
|
||||
}
|
||||
|
||||
switch r.operator {
|
||||
case selection.In, selection.NotIn:
|
||||
buffer.WriteString(")")
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// Add adds requirements to the selector. It copies the current selector returning a new one
|
||||
func (lsel internalSelector) Add(reqs ...Requirement) Selector {
|
||||
var sel internalSelector
|
||||
for ix := range lsel {
|
||||
sel = append(sel, lsel[ix])
|
||||
}
|
||||
for _, r := range reqs {
|
||||
sel = append(sel, r)
|
||||
}
|
||||
sort.Sort(ByKey(sel))
|
||||
return sel
|
||||
}
|
||||
|
||||
// Matches for a internalSelector returns true if all
|
||||
// its Requirements match the input Labels. If any
|
||||
// Requirement does not match, false is returned.
|
||||
func (lsel internalSelector) Matches(l Labels) bool {
|
||||
for ix := range lsel {
|
||||
if matches := lsel[ix].Matches(l); !matches {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (lsel internalSelector) Requirements() (Requirements, bool) { return Requirements(lsel), true }
|
||||
|
||||
// String returns a comma-separated string of all
|
||||
// the internalSelector Requirements' human-readable strings.
|
||||
func (lsel internalSelector) String() string {
|
||||
var reqs []string
|
||||
for ix := range lsel {
|
||||
reqs = append(reqs, lsel[ix].String())
|
||||
}
|
||||
return strings.Join(reqs, ",")
|
||||
}
|
||||
|
||||
// constants definition for lexer token
|
||||
type Token int
|
||||
|
||||
const (
|
||||
ErrorToken Token = iota
|
||||
EndOfStringToken
|
||||
ClosedParToken
|
||||
CommaToken
|
||||
DoesNotExistToken
|
||||
DoubleEqualsToken
|
||||
EqualsToken
|
||||
GreaterThanToken
|
||||
IdentifierToken // to represent keys and values
|
||||
InToken
|
||||
LessThanToken
|
||||
NotEqualsToken
|
||||
NotInToken
|
||||
OpenParToken
|
||||
)
|
||||
|
||||
// string2token contains the mapping between lexer Token and token literal
|
||||
// (except IdentifierToken, EndOfStringToken and ErrorToken since it makes no sense)
|
||||
var string2token = map[string]Token{
|
||||
")": ClosedParToken,
|
||||
",": CommaToken,
|
||||
"!": DoesNotExistToken,
|
||||
"==": DoubleEqualsToken,
|
||||
"=": EqualsToken,
|
||||
">": GreaterThanToken,
|
||||
"in": InToken,
|
||||
"<": LessThanToken,
|
||||
"!=": NotEqualsToken,
|
||||
"notin": NotInToken,
|
||||
"(": OpenParToken,
|
||||
}
|
||||
|
||||
// The item produced by the lexer. It contains the Token and the literal.
|
||||
type ScannedItem struct {
|
||||
tok Token
|
||||
literal string
|
||||
}
|
||||
|
||||
// isWhitespace returns true if the rune is a space, tab, or newline.
|
||||
func isWhitespace(ch byte) bool {
|
||||
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'
|
||||
}
|
||||
|
||||
// isSpecialSymbol detect if the character ch can be an operator
|
||||
func isSpecialSymbol(ch byte) bool {
|
||||
switch ch {
|
||||
case '=', '!', '(', ')', ',', '>', '<':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Lexer represents the Lexer struct for label selector.
|
||||
// It contains necessary informationt to tokenize the input string
|
||||
type Lexer struct {
|
||||
// s stores the string to be tokenized
|
||||
s string
|
||||
// pos is the position currently tokenized
|
||||
pos int
|
||||
}
|
||||
|
||||
// read return the character currently lexed
|
||||
// increment the position and check the buffer overflow
|
||||
func (l *Lexer) read() (b byte) {
|
||||
b = 0
|
||||
if l.pos < len(l.s) {
|
||||
b = l.s[l.pos]
|
||||
l.pos++
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// unread 'undoes' the last read character
|
||||
func (l *Lexer) unread() {
|
||||
l.pos--
|
||||
}
|
||||
|
||||
// scanIdOrKeyword scans string to recognize literal token (for example 'in') or an identifier.
|
||||
func (l *Lexer) scanIdOrKeyword() (tok Token, lit string) {
|
||||
var buffer []byte
|
||||
IdentifierLoop:
|
||||
for {
|
||||
switch ch := l.read(); {
|
||||
case ch == 0:
|
||||
break IdentifierLoop
|
||||
case isSpecialSymbol(ch) || isWhitespace(ch):
|
||||
l.unread()
|
||||
break IdentifierLoop
|
||||
default:
|
||||
buffer = append(buffer, ch)
|
||||
}
|
||||
}
|
||||
s := string(buffer)
|
||||
if val, ok := string2token[s]; ok { // is a literal token?
|
||||
return val, s
|
||||
}
|
||||
return IdentifierToken, s // otherwise is an identifier
|
||||
}
|
||||
|
||||
// scanSpecialSymbol scans string starting with special symbol.
|
||||
// special symbol identify non literal operators. "!=", "==", "="
|
||||
func (l *Lexer) scanSpecialSymbol() (Token, string) {
|
||||
lastScannedItem := ScannedItem{}
|
||||
var buffer []byte
|
||||
SpecialSymbolLoop:
|
||||
for {
|
||||
switch ch := l.read(); {
|
||||
case ch == 0:
|
||||
break SpecialSymbolLoop
|
||||
case isSpecialSymbol(ch):
|
||||
buffer = append(buffer, ch)
|
||||
if token, ok := string2token[string(buffer)]; ok {
|
||||
lastScannedItem = ScannedItem{tok: token, literal: string(buffer)}
|
||||
} else if lastScannedItem.tok != 0 {
|
||||
l.unread()
|
||||
break SpecialSymbolLoop
|
||||
}
|
||||
default:
|
||||
l.unread()
|
||||
break SpecialSymbolLoop
|
||||
}
|
||||
}
|
||||
if lastScannedItem.tok == 0 {
|
||||
return ErrorToken, fmt.Sprintf("error expected: keyword found '%s'", buffer)
|
||||
}
|
||||
return lastScannedItem.tok, lastScannedItem.literal
|
||||
}
|
||||
|
||||
// skipWhiteSpaces consumes all blank characters
|
||||
// returning the first non blank character
|
||||
func (l *Lexer) skipWhiteSpaces(ch byte) byte {
|
||||
for {
|
||||
if !isWhitespace(ch) {
|
||||
return ch
|
||||
}
|
||||
ch = l.read()
|
||||
}
|
||||
}
|
||||
|
||||
// Lex returns a pair of Token and the literal
|
||||
// literal is meaningfull only for IdentifierToken token
|
||||
func (l *Lexer) Lex() (tok Token, lit string) {
|
||||
switch ch := l.skipWhiteSpaces(l.read()); {
|
||||
case ch == 0:
|
||||
return EndOfStringToken, ""
|
||||
case isSpecialSymbol(ch):
|
||||
l.unread()
|
||||
return l.scanSpecialSymbol()
|
||||
default:
|
||||
l.unread()
|
||||
return l.scanIdOrKeyword()
|
||||
}
|
||||
}
|
||||
|
||||
// Parser data structure contains the label selector parser data structure
|
||||
type Parser struct {
|
||||
l *Lexer
|
||||
scannedItems []ScannedItem
|
||||
position int
|
||||
}
|
||||
|
||||
// Parser context represents context during parsing:
|
||||
// some literal for example 'in' and 'notin' can be
|
||||
// recognized as operator for example 'x in (a)' but
|
||||
// it can be recognized as value for example 'value in (in)'
|
||||
type ParserContext int
|
||||
|
||||
const (
|
||||
KeyAndOperator ParserContext = iota
|
||||
Values
|
||||
)
|
||||
|
||||
// lookahead func returns the current token and string. No increment of current position
|
||||
func (p *Parser) lookahead(context ParserContext) (Token, string) {
|
||||
tok, lit := p.scannedItems[p.position].tok, p.scannedItems[p.position].literal
|
||||
if context == Values {
|
||||
switch tok {
|
||||
case InToken, NotInToken:
|
||||
tok = IdentifierToken
|
||||
}
|
||||
}
|
||||
return tok, lit
|
||||
}
|
||||
|
||||
// consume returns current token and string. Increments the the position
|
||||
func (p *Parser) consume(context ParserContext) (Token, string) {
|
||||
p.position++
|
||||
tok, lit := p.scannedItems[p.position-1].tok, p.scannedItems[p.position-1].literal
|
||||
if context == Values {
|
||||
switch tok {
|
||||
case InToken, NotInToken:
|
||||
tok = IdentifierToken
|
||||
}
|
||||
}
|
||||
return tok, lit
|
||||
}
|
||||
|
||||
// scan runs through the input string and stores the ScannedItem in an array
|
||||
// Parser can now lookahead and consume the tokens
|
||||
func (p *Parser) scan() {
|
||||
for {
|
||||
token, literal := p.l.Lex()
|
||||
p.scannedItems = append(p.scannedItems, ScannedItem{token, literal})
|
||||
if token == EndOfStringToken {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse runs the left recursive descending algorithm
|
||||
// on input string. It returns a list of Requirement objects.
|
||||
func (p *Parser) parse() (internalSelector, error) {
|
||||
p.scan() // init scannedItems
|
||||
|
||||
var requirements internalSelector
|
||||
for {
|
||||
tok, lit := p.lookahead(Values)
|
||||
switch tok {
|
||||
case IdentifierToken, DoesNotExistToken:
|
||||
r, err := p.parseRequirement()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse requirement: %v", err)
|
||||
}
|
||||
requirements = append(requirements, *r)
|
||||
t, l := p.consume(Values)
|
||||
switch t {
|
||||
case EndOfStringToken:
|
||||
return requirements, nil
|
||||
case CommaToken:
|
||||
t2, l2 := p.lookahead(Values)
|
||||
if t2 != IdentifierToken && t2 != DoesNotExistToken {
|
||||
return nil, fmt.Errorf("found '%s', expected: identifier after ','", l2)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("found '%s', expected: ',' or 'end of string'", l)
|
||||
}
|
||||
case EndOfStringToken:
|
||||
return requirements, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("found '%s', expected: !, identifier, or 'end of string'", lit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseRequirement() (*Requirement, error) {
|
||||
key, operator, err := p.parseKeyAndInferOperator()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if operator == selection.Exists || operator == selection.DoesNotExist { // operator found lookahead set checked
|
||||
return NewRequirement(key, operator, nil)
|
||||
}
|
||||
operator, err = p.parseOperator()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var values sets.String
|
||||
switch operator {
|
||||
case selection.In, selection.NotIn:
|
||||
values, err = p.parseValues()
|
||||
case selection.Equals, selection.DoubleEquals, selection.NotEquals, selection.GreaterThan, selection.LessThan:
|
||||
values, err = p.parseExactValue()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRequirement(key, operator, values)
|
||||
|
||||
}
|
||||
|
||||
// parseKeyAndInferOperator parse literals.
|
||||
// in case of no operator '!, in, notin, ==, =, !=' are found
|
||||
// the 'exists' operator is inferred
|
||||
func (p *Parser) parseKeyAndInferOperator() (string, selection.Operator, error) {
|
||||
var operator selection.Operator
|
||||
tok, literal := p.consume(Values)
|
||||
if tok == DoesNotExistToken {
|
||||
operator = selection.DoesNotExist
|
||||
tok, literal = p.consume(Values)
|
||||
}
|
||||
if tok != IdentifierToken {
|
||||
err := fmt.Errorf("found '%s', expected: identifier", literal)
|
||||
return "", "", err
|
||||
}
|
||||
if err := validateLabelKey(literal); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if t, _ := p.lookahead(Values); t == EndOfStringToken || t == CommaToken {
|
||||
if operator != selection.DoesNotExist {
|
||||
operator = selection.Exists
|
||||
}
|
||||
}
|
||||
return literal, operator, nil
|
||||
}
|
||||
|
||||
// parseOperator return operator and eventually matchType
|
||||
// matchType can be exact
|
||||
func (p *Parser) parseOperator() (op selection.Operator, err error) {
|
||||
tok, lit := p.consume(KeyAndOperator)
|
||||
switch tok {
|
||||
// DoesNotExistToken shouldn't be here because it's a unary operator, not a binary operator
|
||||
case InToken:
|
||||
op = selection.In
|
||||
case EqualsToken:
|
||||
op = selection.Equals
|
||||
case DoubleEqualsToken:
|
||||
op = selection.DoubleEquals
|
||||
case GreaterThanToken:
|
||||
op = selection.GreaterThan
|
||||
case LessThanToken:
|
||||
op = selection.LessThan
|
||||
case NotInToken:
|
||||
op = selection.NotIn
|
||||
case NotEqualsToken:
|
||||
op = selection.NotEquals
|
||||
default:
|
||||
return "", fmt.Errorf("found '%s', expected: '=', '!=', '==', 'in', notin'", lit)
|
||||
}
|
||||
return op, nil
|
||||
}
|
||||
|
||||
// parseValues parses the values for set based matching (x,y,z)
|
||||
func (p *Parser) parseValues() (sets.String, error) {
|
||||
tok, lit := p.consume(Values)
|
||||
if tok != OpenParToken {
|
||||
return nil, fmt.Errorf("found '%s' expected: '('", lit)
|
||||
}
|
||||
tok, lit = p.lookahead(Values)
|
||||
switch tok {
|
||||
case IdentifierToken, CommaToken:
|
||||
s, err := p.parseIdentifiersList() // handles general cases
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
if tok, _ = p.consume(Values); tok != ClosedParToken {
|
||||
return nil, fmt.Errorf("found '%s', expected: ')'", lit)
|
||||
}
|
||||
return s, nil
|
||||
case ClosedParToken: // handles "()"
|
||||
p.consume(Values)
|
||||
return sets.NewString(""), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("found '%s', expected: ',', ')' or identifier", lit)
|
||||
}
|
||||
}
|
||||
|
||||
// parseIdentifiersList parses a (possibly empty) list of
|
||||
// of comma separated (possibly empty) identifiers
|
||||
func (p *Parser) parseIdentifiersList() (sets.String, error) {
|
||||
s := sets.NewString()
|
||||
for {
|
||||
tok, lit := p.consume(Values)
|
||||
switch tok {
|
||||
case IdentifierToken:
|
||||
s.Insert(lit)
|
||||
tok2, lit2 := p.lookahead(Values)
|
||||
switch tok2 {
|
||||
case CommaToken:
|
||||
continue
|
||||
case ClosedParToken:
|
||||
return s, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("found '%s', expected: ',' or ')'", lit2)
|
||||
}
|
||||
case CommaToken: // handled here since we can have "(,"
|
||||
if s.Len() == 0 {
|
||||
s.Insert("") // to handle (,
|
||||
}
|
||||
tok2, _ := p.lookahead(Values)
|
||||
if tok2 == ClosedParToken {
|
||||
s.Insert("") // to handle ,) Double "" removed by StringSet
|
||||
return s, nil
|
||||
}
|
||||
if tok2 == CommaToken {
|
||||
p.consume(Values)
|
||||
s.Insert("") // to handle ,, Double "" removed by StringSet
|
||||
}
|
||||
default: // it can be operator
|
||||
return s, fmt.Errorf("found '%s', expected: ',', or identifier", lit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parseExactValue parses the only value for exact match style
|
||||
func (p *Parser) parseExactValue() (sets.String, error) {
|
||||
s := sets.NewString()
|
||||
tok, lit := p.lookahead(Values)
|
||||
if tok == EndOfStringToken || tok == CommaToken {
|
||||
s.Insert("")
|
||||
return s, nil
|
||||
}
|
||||
tok, lit = p.consume(Values)
|
||||
if tok == IdentifierToken {
|
||||
s.Insert(lit)
|
||||
return s, nil
|
||||
}
|
||||
return nil, fmt.Errorf("found '%s', expected: identifier", lit)
|
||||
}
|
||||
|
||||
// Parse takes a string representing a selector and returns a selector
|
||||
// object, or an error. This parsing function differs from ParseSelector
|
||||
// as they parse different selectors with different syntaxes.
|
||||
// The input will cause an error if it does not follow this form:
|
||||
//
|
||||
// <selector-syntax> ::= <requirement> | <requirement> "," <selector-syntax> ]
|
||||
// <requirement> ::= [!] KEY [ <set-based-restriction> | <exact-match-restriction> ]
|
||||
// <set-based-restriction> ::= "" | <inclusion-exclusion> <value-set>
|
||||
// <inclusion-exclusion> ::= <inclusion> | <exclusion>
|
||||
// <exclusion> ::= "notin"
|
||||
// <inclusion> ::= "in"
|
||||
// <value-set> ::= "(" <values> ")"
|
||||
// <values> ::= VALUE | VALUE "," <values>
|
||||
// <exact-match-restriction> ::= ["="|"=="|"!="] VALUE
|
||||
// KEY is a sequence of one or more characters following [ DNS_SUBDOMAIN "/" ] DNS_LABEL. Max length is 63 characters.
|
||||
// VALUE is a sequence of zero or more characters "([A-Za-z0-9_-\.])". Max length is 63 characters.
|
||||
// Delimiter is white space: (' ', '\t')
|
||||
// Example of valid syntax:
|
||||
// "x in (foo,,baz),y,z notin ()"
|
||||
//
|
||||
// Note:
|
||||
// (1) Inclusion - " in " - denotes that the KEY exists and is equal to any of the
|
||||
// VALUEs in its requirement
|
||||
// (2) Exclusion - " notin " - denotes that the KEY is not equal to any
|
||||
// of the VALUEs in its requirement or does not exist
|
||||
// (3) The empty string is a valid VALUE
|
||||
// (4) A requirement with just a KEY - as in "y" above - denotes that
|
||||
// the KEY exists and can be any VALUE.
|
||||
// (5) A requirement with just !KEY requires that the KEY not exist.
|
||||
//
|
||||
func Parse(selector string) (Selector, error) {
|
||||
parsedSelector, err := parse(selector)
|
||||
if err == nil {
|
||||
return parsedSelector, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse parses the string representation of the selector and returns the internalSelector struct.
|
||||
// The callers of this method can then decide how to return the internalSelector struct to their
|
||||
// callers. This function has two callers now, one returns a Selector interface and the other
|
||||
// returns a list of requirements.
|
||||
func parse(selector string) (internalSelector, error) {
|
||||
p := &Parser{l: &Lexer{s: selector, pos: 0}}
|
||||
items, err := p.parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sort.Sort(ByKey(items)) // sort to grant determistic parsing
|
||||
return internalSelector(items), err
|
||||
}
|
||||
|
||||
func validateLabelKey(k string) error {
|
||||
if errs := validation.IsQualifiedName(k); len(errs) != 0 {
|
||||
return fmt.Errorf("invalid label key %q: %s", k, strings.Join(errs, "; "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateLabelValue(v string) error {
|
||||
if errs := validation.IsValidLabelValue(v); len(errs) != 0 {
|
||||
return fmt.Errorf("invalid label value: %q: %s", v, strings.Join(errs, "; "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectorFromSet returns a Selector which will match exactly the given Set. A
|
||||
// nil and empty Sets are considered equivalent to Everything().
|
||||
func SelectorFromSet(ls Set) Selector {
|
||||
if ls == nil {
|
||||
return internalSelector{}
|
||||
}
|
||||
var requirements internalSelector
|
||||
for label, value := range ls {
|
||||
if r, err := NewRequirement(label, selection.Equals, sets.NewString(value)); err != nil {
|
||||
//TODO: double check errors when input comes from serialization?
|
||||
return internalSelector{}
|
||||
} else {
|
||||
requirements = append(requirements, *r)
|
||||
}
|
||||
}
|
||||
// sort to have deterministic string representation
|
||||
sort.Sort(ByKey(requirements))
|
||||
return internalSelector(requirements)
|
||||
}
|
||||
|
||||
// SelectorFromValidatedSet returns a Selector which will match exactly the given Set.
|
||||
// A nil and empty Sets are considered equivalent to Everything().
|
||||
// It assumes that Set is already validated and doesn't do any validation.
|
||||
func SelectorFromValidatedSet(ls Set) Selector {
|
||||
if ls == nil {
|
||||
return internalSelector{}
|
||||
}
|
||||
var requirements internalSelector
|
||||
for label, value := range ls {
|
||||
requirements = append(requirements, Requirement{key: label, operator: selection.Equals, strValues: sets.NewString(value)})
|
||||
}
|
||||
// sort to have deterministic string representation
|
||||
sort.Sort(ByKey(requirements))
|
||||
return internalSelector(requirements)
|
||||
}
|
||||
|
||||
// ParseToRequirements takes a string representing a selector and returns a list of
|
||||
// requirements. This function is suitable for those callers that perform additional
|
||||
// processing on selector requirements.
|
||||
// See the documentation for Parse() function for more details.
|
||||
// TODO: Consider exporting the internalSelector type instead.
|
||||
func ParseToRequirements(selector string) ([]Requirement, error) {
|
||||
return parse(selector)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue