1
0
Fork 0

Vendor main dependencies.

This commit is contained in:
Timo Reimann 2017-02-07 22:33:23 +01:00
parent 49a09ab7dd
commit dd5e3fba01
2738 changed files with 1045689 additions and 0 deletions

152
vendor/k8s.io/client-go/1.5/pkg/api/context.go generated vendored Normal file
View file

@ -0,0 +1,152 @@
/*
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.5/pkg/auth/user"
"k8s.io/client-go/1.5/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
// userAgentKey is the context key for the request user agent.
userAgentKey
)
// 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
}
// WithUserAgent returns a copy of parent in which the user value is set
func WithUserAgent(parent Context, userAgent string) Context {
return WithValue(parent, userAgentKey, userAgent)
}
// UserAgentFrom returns the value of the userAgent key on the ctx
func UserAgentFrom(ctx Context) (string, bool) {
userAgent, ok := ctx.Value(userAgentKey).(string)
return userAgent, ok
}

245
vendor/k8s.io/client-go/1.5/pkg/api/conversion.go generated vendored Normal file
View file

@ -0,0 +1,245 @@
/*
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.5/pkg/api/resource"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/conversion"
"k8s.io/client-go/1.5/pkg/fields"
"k8s.io/client-go/1.5/pkg/labels"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/pkg/util/intstr"
utillabels "k8s.io/client-go/1.5/pkg/util/labels"
"k8s.io/client-go/1.5/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
}

36
vendor/k8s.io/client-go/1.5/pkg/api/defaults.go generated vendored Normal file
View file

@ -0,0 +1,36 @@
/*
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
import (
"k8s.io/client-go/1.5/pkg/fields"
"k8s.io/client-go/1.5/pkg/labels"
"k8s.io/client-go/1.5/pkg/runtime"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
return scheme.AddDefaultingFuncs(
func(obj *ListOptions) {
if obj.LabelSelector == nil {
obj.LabelSelector = labels.Everything()
}
if obj.FieldSelector == nil {
obj.FieldSelector = fields.Everything()
}
},
)
}

24
vendor/k8s.io/client-go/1.5/pkg/api/doc.go generated vendored Normal file
View file

@ -0,0 +1,24 @@
/*
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

18
vendor/k8s.io/client-go/1.5/pkg/api/errors/doc.go generated vendored Normal file
View file

@ -0,0 +1,18 @@
/*
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 provides detailed error types for api field validation.
package errors

461
vendor/k8s.io/client-go/1.5/pkg/api/errors/errors.go generated vendored Normal file
View file

@ -0,0 +1,461 @@
/*
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.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/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
}
// IsInternalError determines if err is an error which indicates an internal server error.
func IsInternalError(err error) bool {
return reasonForError(err) == unversioned.StatusReasonInternalError
}
// 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.5/pkg/api/field_constants.go generated vendored Normal file
View file

@ -0,0 +1,38 @@
/*
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.5/pkg/api/generate.go generated vendored Normal file
View file

@ -0,0 +1,64 @@
/*
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.5/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))
}

600
vendor/k8s.io/client-go/1.5/pkg/api/helpers.go generated vendored Normal file
View file

@ -0,0 +1,600 @@
/*
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.5/pkg/api/resource"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/conversion"
"k8s.io/client-go/1.5/pkg/fields"
"k8s.io/client-go/1.5/pkg/labels"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/pkg/selection"
"k8s.io/client-go/1.5/pkg/types"
"k8s.io/client-go/1.5/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
}
// MatchTaint checks if the taint matches taintToMatch. Taints are unique by key:effect,
// if the two taints have same key:effect, regard as they match.
func (t *Taint) MatchTaint(taintToMatch Taint) bool {
return t.Key == taintToMatch.Key && t.Effect == taintToMatch.Effect
}
// taint.ToString() converts taint struct to string in format key=value:effect or key:effect.
func (t *Taint) ToString() string {
if len(t.Value) == 0 {
return fmt.Sprintf("%v:%v", t.Key, t.Effect)
}
return fmt.Sprintf("%v=%v:%v", t.Key, t.Value, t.Effect)
}
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, ",")
}

153
vendor/k8s.io/client-go/1.5/pkg/api/install/install.go generated vendored Normal file
View file

@ -0,0 +1,153 @@
/*
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 install installs the v1 monolithic api, making it available as an
// option to all of the API encoding/decoding machinery.
package install
import (
"fmt"
"github.com/golang/glog"
"k8s.io/client-go/1.5/pkg/api"
"k8s.io/client-go/1.5/pkg/api/meta"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/api/v1"
"k8s.io/client-go/1.5/pkg/apimachinery"
"k8s.io/client-go/1.5/pkg/apimachinery/registered"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/pkg/util/sets"
)
const importPrefix = "k8s.io/client-go/1.5/pkg/api"
var accessor = meta.NewAccessor()
// availableVersions lists all known external versions for this group from most preferred to least preferred
var availableVersions = []unversioned.GroupVersion{v1.SchemeGroupVersion}
func init() {
registered.RegisterVersions(availableVersions)
externalVersions := []unversioned.GroupVersion{}
for _, v := range availableVersions {
if registered.IsAllowedVersion(v) {
externalVersions = append(externalVersions, v)
}
}
if len(externalVersions) == 0 {
glog.V(4).Infof("No version is registered for group %v", api.GroupName)
return
}
if err := registered.EnableVersions(externalVersions...); err != nil {
glog.V(4).Infof("%v", err)
return
}
if err := enableVersions(externalVersions); err != nil {
glog.V(4).Infof("%v", err)
return
}
}
// TODO: enableVersions should be centralized rather than spread in each API
// group.
// We can combine registered.RegisterVersions, registered.EnableVersions and
// registered.RegisterGroup once we have moved enableVersions there.
func enableVersions(externalVersions []unversioned.GroupVersion) error {
addVersionsToScheme(externalVersions...)
preferredExternalVersion := externalVersions[0]
groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions,
RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor,
}
if err := registered.RegisterGroup(groupMeta); err != nil {
return err
}
return nil
}
func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper {
// the list of kinds that are scoped at the root of the api hierarchy
// if a kind is not enumerated here, it is assumed to have a namespace scope
rootScoped := sets.NewString(
"Node",
"Namespace",
"PersistentVolume",
"ComponentStatus",
)
// these kinds should be excluded from the list of resources
ignoredKinds := sets.NewString(
"ListOptions",
"DeleteOptions",
"Status",
"PodLogOptions",
"PodExecOptions",
"PodAttachOptions",
"PodProxyOptions",
"NodeProxyOptions",
"ServiceProxyOptions",
"ThirdPartyResource",
"ThirdPartyResourceData",
"ThirdPartyResourceList")
mapper := api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped)
return mapper
}
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
// string, or an error if the version is not known.
func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
switch version {
case v1.SchemeGroupVersion:
return &meta.VersionInterfaces{
ObjectConvertor: api.Scheme,
MetadataAccessor: accessor,
}, nil
default:
g, _ := registered.Group(api.GroupName)
return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions)
}
}
func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) {
// add the internal version to Scheme
if err := api.AddToScheme(api.Scheme); err != nil {
// Programmer error, detect immediately
panic(err)
}
// add the enabled external versions to Scheme
for _, v := range externalVersions {
if !registered.IsEnabledVersion(v) {
glog.Errorf("Version %s is not enabled, so it will not be added to the Scheme.", v)
continue
}
switch v {
case v1.SchemeGroupVersion:
if err := v1.AddToScheme(api.Scheme); err != nil {
// Programmer error, detect immediately
panic(err)
}
}
}
}

58
vendor/k8s.io/client-go/1.5/pkg/api/mapper.go generated vendored Normal file
View file

@ -0,0 +1,58 @@
/*
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.5/pkg/api/meta"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/pkg/util/sets"
)
// 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.5/pkg/api/meta.go generated vendored Normal file
View file

@ -0,0 +1,140 @@
/*
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.5/pkg/api/meta"
"k8s.io/client-go/1.5/pkg/api/meta/metatypes"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/conversion"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/pkg/types"
"k8s.io/client-go/1.5/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.5/pkg/api/meta/doc.go generated vendored Normal file
View file

@ -0,0 +1,19 @@
/*
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.5/pkg/api/meta/errors.go generated vendored Normal file
View file

@ -0,0 +1,105 @@
/*
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.5/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
}
}

View file

@ -0,0 +1,97 @@
/*
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.5/pkg/api/unversioned"
utilerrors "k8s.io/client-go/1.5/pkg/util/errors"
)
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
// first successful result for the singular requests
type FirstHitRESTMapper struct {
MultiRESTMapper
}
func (m FirstHitRESTMapper) String() string {
return fmt.Sprintf("FirstHitRESTMapper{\n\t%v\n}", m.MultiRESTMapper)
}
func (m FirstHitRESTMapper) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
errors := []error{}
for _, t := range m.MultiRESTMapper {
ret, err := t.ResourceFor(resource)
if err == nil {
return ret, nil
}
errors = append(errors, err)
}
return unversioned.GroupVersionResource{}, collapseAggregateErrors(errors)
}
func (m FirstHitRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
errors := []error{}
for _, t := range m.MultiRESTMapper {
ret, err := t.KindFor(resource)
if err == nil {
return ret, nil
}
errors = append(errors, err)
}
return unversioned.GroupVersionKind{}, collapseAggregateErrors(errors)
}
// 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 FirstHitRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) {
errors := []error{}
for _, t := range m.MultiRESTMapper {
ret, err := t.RESTMapping(gk, versions...)
if err == nil {
return ret, nil
}
errors = append(errors, err)
}
return nil, collapseAggregateErrors(errors)
}
// collapseAggregateErrors returns the minimal errors. it handles empty as nil, handles one item in a list
// by returning the item, and collapses all NoMatchErrors to a single one (since they should all be the same)
func collapseAggregateErrors(errors []error) error {
if len(errors) == 0 {
return nil
}
if len(errors) == 1 {
return errors[0]
}
allNoMatchErrors := true
for _, err := range errors {
allNoMatchErrors = allNoMatchErrors && IsNoMatchError(err)
}
if allNoMatchErrors {
return errors[0]
}
return utilerrors.NewAggregate(errors)
}

134
vendor/k8s.io/client-go/1.5/pkg/api/meta/help.go generated vendored Normal file
View file

@ -0,0 +1,134 @@
/*
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.5/pkg/conversion"
"k8s.io/client-go/1.5/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
}

184
vendor/k8s.io/client-go/1.5/pkg/api/meta/interfaces.go generated vendored Normal file
View file

@ -0,0 +1,184 @@
/*
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.5/pkg/api/meta/metatypes"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/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: split into sub-interfaces
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.5/pkg/api/meta/meta.go generated vendored Normal file
View file

@ -0,0 +1,567 @@
/*
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.5/pkg/api/meta/metatypes"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/conversion"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/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
}

View file

@ -0,0 +1,30 @@
/*
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.5/pkg/types"
type OwnerReference struct {
APIVersion string
Kind string
UID types.UID
Name string
Controller *bool
}

View file

@ -0,0 +1,231 @@
/*
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.5/pkg/api/unversioned"
utilerrors "k8s.io/client-go/1.5/pkg/util/errors"
"k8s.io/client-go/1.5/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.5/pkg/api/meta/priority.go generated vendored Normal file
View file

@ -0,0 +1,226 @@
/*
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.5/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)
}

601
vendor/k8s.io/client-go/1.5/pkg/api/meta/restmapper.go generated vendored Normal file
View file

@ -0,0 +1,601 @@
/*
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.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/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 {
case hasGroup && hasVersion:
// fully qualified. Find the exact match
for plural, singular := range m.pluralToSingular {
if singular == resource {
ret = append(ret, plural)
break
}
if plural == resource {
ret = append(ret, plural)
break
}
}
case hasGroup:
// given a group, prefer an exact match. If you don't find one, resort to a prefix match on group
foundExactMatch := false
requestedGroupResource := resource.GroupResource()
for plural, singular := range m.pluralToSingular {
if singular.GroupResource() == requestedGroupResource {
foundExactMatch = true
ret = append(ret, plural)
}
if plural.GroupResource() == requestedGroupResource {
foundExactMatch = true
ret = append(ret, plural)
}
}
// if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match
// storageclass.storage.k8s.io
if !foundExactMatch {
for plural, singular := range m.pluralToSingular {
if !strings.HasPrefix(plural.Group, requestedGroupResource.Group) {
continue
}
if singular.Resource == requestedGroupResource.Resource {
ret = append(ret, plural)
}
if plural.Resource == requestedGroupResource.Resource {
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:
foundExactMatch := false
requestedGroupResource := resource.GroupResource()
for currResource, currKind := range m.resourceToKind {
if currResource.GroupResource() == requestedGroupResource {
foundExactMatch = true
ret = append(ret, currKind)
}
}
// if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match
// storageclass.storage.k8s.io
if !foundExactMatch {
for currResource, currKind := range m.resourceToKind {
if !strings.HasPrefix(currResource.Group, requestedGroupResource.Group) {
continue
}
if currResource.Resource == requestedGroupResource.Resource {
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: %v", gvk.GroupVersion().String(), err)
}
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: %v", gvk.GroupVersion().String(), err)
}
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
}

View file

@ -0,0 +1,31 @@
/*
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 (
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/runtime"
)
// InterfacesForUnstructured returns VersionInterfaces suitable for
// dealing with runtime.Unstructured objects.
func InterfacesForUnstructured(unversioned.GroupVersion) (*VersionInterfaces, error) {
return &VersionInterfaces{
ObjectConvertor: &runtime.UnstructuredObjectConverter{},
MetadataAccessor: NewAccessor(),
}, nil
}

132
vendor/k8s.io/client-go/1.5/pkg/api/ref.go generated vendored Normal file
View file

@ -0,0 +1,132 @@
/*
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.5/pkg/api/meta"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/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.5/pkg/api/register.go generated vendored Normal file
View file

@ -0,0 +1,139 @@
/*
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.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/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
}

117
vendor/k8s.io/client-go/1.5/pkg/api/requestcontext.go generated vendored Normal file
View file

@ -0,0 +1,117 @@
/*
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"
"github.com/golang/glog"
)
// 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)
}
// WithRequestContext 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 WithRequestContext(handler http.Handler, mapper RequestContextMapper) http.Handler {
rcMap, ok := mapper.(*requestContextMap)
if !ok {
glog.Fatal("Unknown RequestContextMapper implementation.")
}
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if rcMap.init(req, NewContext()) {
// If we were the ones to successfully initialize, pair with a remove
defer rcMap.remove(req)
}
handler.ServeHTTP(w, req)
})
}
// 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")
}

299
vendor/k8s.io/client-go/1.5/pkg/api/resource/amount.go generated vendored Normal file
View file

@ -0,0 +1,299 @@
/*
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.
// +k8s:openapi-gen=true
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
}

View file

@ -0,0 +1,69 @@
/*
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.5.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,
}

327
vendor/k8s.io/client-go/1.5/pkg/api/resource/math.go generated vendored Normal file
View file

@ -0,0 +1,327 @@
/*
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
}

View file

@ -0,0 +1,792 @@
/*
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"
"github.com/go-openapi/spec"
inf "gopkg.in/inf.v0"
"k8s.io/client-go/1.5/pkg/genericapiserver/openapi/common"
)
// 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
// +k8s:openapi-gen=true
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
}
// OpenAPIDefinition returns openAPI definition for this type.
func (_ Quantity) OpenAPIDefinition() common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
}
}
// 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}
}

View file

@ -0,0 +1,284 @@
/*
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")
)

View file

@ -0,0 +1,95 @@
/*
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.5/pkg/api/resource/suffix.go generated vendored Normal file
View file

@ -0,0 +1,198 @@
/*
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.5/pkg/api/resource_helpers.go generated vendored Normal file
View file

@ -0,0 +1,209 @@
/*
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.5/pkg/api/resource"
"k8s.io/client-go/1.5/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
}

62430
vendor/k8s.io/client-go/1.5/pkg/api/types.generated.go generated vendored Normal file

File diff suppressed because it is too large Load diff

3068
vendor/k8s.io/client-go/1.5/pkg/api/types.go generated vendored Normal file

File diff suppressed because it is too large Load diff

20
vendor/k8s.io/client-go/1.5/pkg/api/unversioned/doc.go generated vendored Normal file
View file

@ -0,0 +1,20 @@
/*
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.
*/
// +k8s:deepcopy-gen=package
// +k8s:openapi-gen=true
package unversioned

View file

@ -0,0 +1,47 @@
/*
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())
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,325 @@
/*
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{} }

View file

@ -0,0 +1,184 @@
/*
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.5/pkg/labels"
"k8s.io/client-go/1.5/pkg/selection"
"k8s.io/client-go/1.5/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
}

View file

@ -0,0 +1,62 @@
/*
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 }

View file

@ -0,0 +1,25 @@
/*
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
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = GroupVersion{Group: "", Version: ""}
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

180
vendor/k8s.io/client-go/1.5/pkg/api/unversioned/time.go generated vendored Normal file
View file

@ -0,0 +1,180 @@
/*
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"
"k8s.io/client-go/1.5/pkg/genericapiserver/openapi/common"
"github.com/go-openapi/spec"
"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))
}
func (_ Time) OpenAPIDefinition() common.OpenAPIDefinition {
return common.OpenAPIDefinition{
Schema: spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "date-time",
},
},
}
}
// 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{}

View file

@ -0,0 +1,85 @@
/*
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)
}

View file

@ -0,0 +1,460 @@
/*
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"
)

View file

@ -0,0 +1,208 @@
/*
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

View file

@ -0,0 +1,30 @@
/*
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"
)

View file

@ -0,0 +1,390 @@
// +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.5/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
}
}

814
vendor/k8s.io/client-go/1.5/pkg/api/v1/conversion.go generated vendored Normal file
View file

@ -0,0 +1,814 @@
/*
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.5/pkg/api"
"k8s.io/client-go/1.5/pkg/apis/extensions"
"k8s.io/client-go/1.5/pkg/conversion"
"k8s.io/client-go/1.5/pkg/runtime"
"k8s.io/client-go/1.5/pkg/util/validation/field"
"k8s.io/client-go/1.5/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)
out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = string(value)
} else {
delete(out.Annotations, PodInitContainerStatusesAnnotationKey)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
}
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 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[PodInitContainerStatusesBetaAnnotationKey]; okBeta {
in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta
}
// Move the annotation to the internal repr. field
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)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
}
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)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
}
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)
out.Annotations[PodInitContainerStatusesBetaAnnotationKey] = 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 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[PodInitContainerStatusesBetaAnnotationKey]; okBeta {
in.Annotations[PodInitContainerStatusesAnnotationKey] = valueBeta
}
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)
delete(out.Annotations, PodInitContainerStatusesBetaAnnotationKey)
}
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.5/pkg/api/v1/defaults.go generated vendored Normal file
View file

@ -0,0 +1,336 @@
/*
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.5/pkg/runtime"
"k8s.io/client-go/1.5/pkg/util"
"k8s.io/client-go/1.5/pkg/util/intstr"
"k8s.io/client-go/1.5/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"
}
}

22
vendor/k8s.io/client-go/1.5/pkg/api/v1/doc.go generated vendored Normal file
View file

@ -0,0 +1,22 @@
/*
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
// +k8s:openapi-gen=true
// Package v1 is the v1 version of the API.
package v1

39094
vendor/k8s.io/client-go/1.5/pkg/api/v1/generated.pb.go generated vendored Normal file

File diff suppressed because it is too large Load diff

92
vendor/k8s.io/client-go/1.5/pkg/api/v1/meta.go generated vendored Normal file
View file

@ -0,0 +1,92 @@
/*
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.5/pkg/api/meta"
"k8s.io/client-go/1.5/pkg/api/meta/metatypes"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/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.5/pkg/api/v1/ref.go generated vendored Normal file
View file

@ -0,0 +1,133 @@
/*
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.5/pkg/api"
"net/url"
"strings"
"k8s.io/client-go/1.5/pkg/api/meta"
"k8s.io/client-go/1.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/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.5/pkg/api/v1/register.go generated vendored Normal file
View file

@ -0,0 +1,93 @@
/*
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.5/pkg/api/unversioned"
"k8s.io/client-go/1.5/pkg/runtime"
versionedwatch "k8s.io/client-go/1.5/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.5/pkg/api/v1/types.generated.go generated vendored Normal file

File diff suppressed because it is too large Load diff

3507
vendor/k8s.io/client-go/1.5/pkg/api/v1/types.go generated vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
/*
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 path
import (
"fmt"
"strings"
)
// NameMayNotBe specifies strings that cannot be used as names specified as path segments (like the REST API or etcd store)
var NameMayNotBe = []string{".", ".."}
// NameMayNotContain specifies substrings that cannot be used in names specified as path segments (like the REST API or etcd store)
var NameMayNotContain = []string{"/", "%"}
// IsValidPathSegmentName validates the name can be safely encoded as a path segment
func IsValidPathSegmentName(name string) []string {
for _, illegalName := range NameMayNotBe {
if name == illegalName {
return []string{fmt.Sprintf(`may not be '%s'`, illegalName)}
}
}
for _, illegalContent := range NameMayNotContain {
if strings.Contains(name, illegalContent) {
return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)}
}
}
return nil
}
// IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment
// It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid
func IsValidPathSegmentPrefix(name string) []string {
for _, illegalContent := range NameMayNotContain {
if strings.Contains(name, illegalContent) {
return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)}
}
}
return nil
}
// ValidatePathSegmentName validates the name can be safely encoded as a path segment
func ValidatePathSegmentName(name string, prefix bool) []string {
if prefix {
return IsValidPathSegmentPrefix(name)
} else {
return IsValidPathSegmentName(name)
}
}

File diff suppressed because it is too large Load diff