*: initial update to kube 1.8

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2017-09-26 16:23:09 +02:00
parent 2453222695
commit d6e819133d
No known key found for this signature in database
GPG key ID: B2BEAD150DE936B9
1237 changed files with 84117 additions and 564982 deletions

View file

@ -34,6 +34,9 @@ var Semantic = conversion.EqualitiesOrDie(
// Uninitialized quantities are equivalent to 0 quantities.
return a.Cmp(b) == 0
},
func(a, b metav1.MicroTime) bool {
return a.UTC() == b.UTC()
},
func(a, b metav1.Time) bool {
return a.UTC() == b.UTC()
},

View file

@ -28,14 +28,10 @@ import (
"k8s.io/apimachinery/pkg/util/validation/field"
)
// HTTP Status codes not in the golang http package.
const (
StatusUnprocessableEntity = 422
StatusTooManyRequests = 429
// StatusServerTimeout 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
// StatusTooManyRequests means the server experienced too many requests within a
// given window and that the client must wait to perform the action again.
StatusTooManyRequests = 429
)
// StatusError is an error intended for consumption by a REST API server; it can also be
@ -138,6 +134,14 @@ func NewUnauthorized(reason string) *StatusError {
// NewForbidden returns an error indicating the requested action was forbidden
func NewForbidden(qualifiedResource schema.GroupResource, name string, err error) *StatusError {
var message string
if qualifiedResource.Empty() {
message = fmt.Sprintf("forbidden: %v", err)
} else if name == "" {
message = fmt.Sprintf("%s is forbidden: %v", qualifiedResource.String(), err)
} else {
message = fmt.Sprintf("%s %q is forbidden: %v", qualifiedResource.String(), name, err)
}
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusForbidden,
@ -147,7 +151,7 @@ func NewForbidden(qualifiedResource schema.GroupResource, name string, err error
Kind: qualifiedResource.Resource,
Name: name,
},
Message: fmt.Sprintf("%s %q is forbidden: %v", qualifiedResource.String(), name, err),
Message: message,
}}
}
@ -176,6 +180,17 @@ func NewGone(message string) *StatusError {
}}
}
// NewResourceExpired creates an error that indicates that the requested resource content has expired from
// the server (usually due to a resourceVersion that is too old).
func NewResourceExpired(message string) *StatusError {
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusGone,
Reason: metav1.StatusReasonExpired,
Message: message,
}}
}
// NewInvalid returns an error indicating the item is invalid and cannot be processed.
func NewInvalid(qualifiedKind schema.GroupKind, name string, errs field.ErrorList) *StatusError {
causes := make([]metav1.StatusCause, 0, len(errs))
@ -189,7 +204,7 @@ func NewInvalid(qualifiedKind schema.GroupKind, name string, errs field.ErrorLis
}
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity
Code: http.StatusUnprocessableEntity,
Reason: metav1.StatusReasonInvalid,
Details: &metav1.StatusDetails{
Group: qualifiedKind.Group,
@ -211,6 +226,21 @@ func NewBadRequest(reason string) *StatusError {
}}
}
// NewTooManyRequests creates an error that indicates that the client must try again later because
// the specified endpoint is not accepting requests. More specific details should be provided
// if client should know why the failure was limited4.
func NewTooManyRequests(message string, retryAfterSeconds int) *StatusError {
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusTooManyRequests,
Reason: metav1.StatusReasonTooManyRequests,
Message: message,
Details: &metav1.StatusDetails{
RetryAfterSeconds: int32(retryAfterSeconds),
},
}}
}
// NewServiceUnavailable creates an error that indicates that the requested service is unavailable.
func NewServiceUnavailable(reason string) *StatusError {
return &StatusError{metav1.Status{
@ -276,7 +306,7 @@ func NewInternalError(err error) *StatusError {
func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: StatusServerTimeout,
Code: http.StatusGatewayTimeout,
Reason: metav1.StatusReasonTimeout,
Message: fmt.Sprintf("Timeout: %s", message),
Details: &metav1.StatusDetails{
@ -285,6 +315,18 @@ func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
}}
}
// NewTooManyRequestsError returns an error indicating that the request was rejected because
// the server has received too many requests. Client should wait and retry. But if the request
// is perishable, then the client should not retry the request.
func NewTooManyRequestsError(message string) *StatusError {
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: StatusTooManyRequests,
Reason: metav1.StatusReasonTooManyRequests,
Message: fmt.Sprintf("Too many requests: %s", message),
}}
}
// NewGenericServerResponse returns a new error for server responses that are not in a recognizable form.
func NewGenericServerResponse(code int, verb string, qualifiedResource schema.GroupResource, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) *StatusError {
reason := metav1.StatusReasonUnknown
@ -313,14 +355,14 @@ func NewGenericServerResponse(code int, verb string, qualifiedResource schema.Gr
case http.StatusMethodNotAllowed:
reason = metav1.StatusReasonMethodNotAllowed
message = "the server does not allow this method on the requested resource"
case StatusUnprocessableEntity:
case http.StatusUnprocessableEntity:
reason = metav1.StatusReasonInvalid
message = "the server rejected our request due to an error in our request"
case StatusServerTimeout:
reason = metav1.StatusReasonServerTimeout
message = "the server cannot complete the requested operation at this time, try again later"
case StatusTooManyRequests:
case http.StatusGatewayTimeout:
reason = metav1.StatusReasonTimeout
message = "the server was unable to return a response in the time allotted, but may still be processing the request"
case http.StatusTooManyRequests:
reason = metav1.StatusReasonTooManyRequests
message = "the server has received too many requests and has asked us to try again later"
default:
if code >= 500 {
@ -381,12 +423,28 @@ func IsInvalid(err error) bool {
return reasonForError(err) == metav1.StatusReasonInvalid
}
// IsGone is true if the error indicates the requested resource is no longer available.
func IsGone(err error) bool {
return reasonForError(err) == metav1.StatusReasonGone
}
// IsResourceExpired is true if the error indicates the resource has expired and the current action is
// no longer possible.
func IsResourceExpired(err error) bool {
return reasonForError(err) == metav1.StatusReasonExpired
}
// 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) == metav1.StatusReasonMethodNotAllowed
}
// IsServiceUnavailable is true if the error indicates the underlying service is no longer available.
func IsServiceUnavailable(err error) bool {
return reasonForError(err) == metav1.StatusReasonServiceUnavailable
}
// IsBadRequest determines if err is an error which indicates that the request is invalid.
func IsBadRequest(err error) bool {
return reasonForError(err) == metav1.StatusReasonBadRequest
@ -423,11 +481,13 @@ func IsInternalError(err error) bool {
// IsTooManyRequests determines if err is an error which indicates that there are too many requests
// that the server cannot handle.
// TODO: update IsTooManyRequests() when the TooManyRequests(429) error returned from the API server has a non-empty Reason field
func IsTooManyRequests(err error) bool {
if reasonForError(err) == metav1.StatusReasonTooManyRequests {
return true
}
switch t := err.(type) {
case APIStatus:
return t.Status().Code == StatusTooManyRequests
return t.Status().Code == http.StatusTooManyRequests
}
return false
}
@ -455,13 +515,20 @@ func IsUnexpectedObjectError(err error) bool {
}
// 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.
// suggested seconds to wait, or false if the error does not imply a wait. It does not
// address whether the error *should* be retried, since some errors (like a 3xx) may
// request delay without retry.
func SuggestsClientDelay(err error) (int, bool) {
switch t := err.(type) {
case APIStatus:
if t.Status().Details != nil {
switch t.Status().Reason {
case metav1.StatusReasonServerTimeout, metav1.StatusReasonTimeout:
// this StatusReason explicitly requests the caller to delay the action
case metav1.StatusReasonServerTimeout:
return int(t.Status().Details.RetryAfterSeconds), true
}
// If the client requests that we retry after a certain number of seconds
if t.Status().Details.RetryAfterSeconds > 0 {
return int(t.Status().Details.RetryAfterSeconds), true
}
}

View file

@ -1,51 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package meta
import (
"strings"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
)
// NewDefaultRESTMapperFromScheme instantiates a DefaultRESTMapper based on types registered in the given scheme.
func NewDefaultRESTMapperFromScheme(defaultGroupVersions []schema.GroupVersion, interfacesFunc VersionInterfacesFunc,
importPathPrefix string, ignoredKinds, rootScoped sets.String, scheme *runtime.Scheme) *DefaultRESTMapper {
mapper := 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 := RESTScopeNamespace
if rootScoped.Has(kind) {
scope = RESTScopeRoot
}
mapper.Add(gvk, scope)
}
}
return mapper
}

View file

@ -67,6 +67,9 @@ func GetItemsPtr(list runtime.Object) (interface{}, error) {
// EachListItem invokes fn on each runtime.Object in the list. Any error immediately terminates
// the loop.
func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
if unstructured, ok := obj.(runtime.Unstructured); ok {
return unstructured.EachListItem(fn)
}
// TODO: Change to an interface call?
itemsPtr, err := GetItemsPtr(obj)
if err != nil {

View file

@ -36,7 +36,7 @@ type ListMetaAccessor interface {
// 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 metav1.List
type List metav1.ListInterface
// Type exposes the type and APIVersion of versioned or internal API objects.
type Type metav1.Type

View file

@ -34,16 +34,49 @@ import (
// interfaces.
var errNotList = fmt.Errorf("object does not implement the List interfaces")
var errNotCommon = fmt.Errorf("object does not implement the common interface for accessing the SelfLink")
// CommonAccessor returns a Common interface for the provided object or an error if the object does
// not provide List.
// TODO: return bool instead of error
func CommonAccessor(obj interface{}) (metav1.Common, error) {
switch t := obj.(type) {
case List:
return t, nil
case metav1.ListInterface:
return t, nil
case ListMetaAccessor:
if m := t.GetListMeta(); m != nil {
return m, nil
}
return nil, errNotCommon
case metav1.ListMetaAccessor:
if m := t.GetListMeta(); m != nil {
return m, nil
}
return nil, errNotCommon
case metav1.Object:
return t, nil
case metav1.ObjectMetaAccessor:
if m := t.GetObjectMeta(); m != nil {
return m, nil
}
return nil, errNotCommon
default:
return nil, errNotCommon
}
}
// 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.
// IMPORTANT: Objects are NOT a superset of lists. 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 metav1.List:
case metav1.ListInterface:
return t, nil
case ListMetaAccessor:
if m := t.GetListMeta(); m != nil {
@ -55,15 +88,8 @@ func ListAccessor(obj interface{}) (List, error) {
return m, nil
}
return nil, errNotList
case metav1.Object:
return t, nil
case metav1.ObjectMetaAccessor:
if m := t.GetObjectMeta(); m != nil {
return m, nil
}
return nil, errNotList
default:
return nil, errNotList
panic(fmt.Errorf("%T does not implement the List interface", obj))
}
}
@ -274,7 +300,7 @@ func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
}
func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return "", err
}
@ -282,7 +308,7 @@ func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
}
func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return err
}
@ -325,7 +351,7 @@ func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[strin
}
func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return "", err
}
@ -333,7 +359,7 @@ func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
}
func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return err
}

View file

@ -117,7 +117,10 @@ func NewDefaultRESTMapper(defaultGroupVersions []schema.GroupVersion, f VersionI
func (m *DefaultRESTMapper) Add(kind schema.GroupVersionKind, scope RESTScope) {
plural, singular := UnsafeGuessKindToResource(kind)
m.AddSpecific(kind, plural, singular, scope)
}
func (m *DefaultRESTMapper) AddSpecific(kind schema.GroupVersionKind, plural, singular schema.GroupVersionResource, scope RESTScope) {
m.singularToPlural[singular] = plural
m.pluralToSingular[plural] = singular

View file

@ -29,7 +29,7 @@ import (
"github.com/go-openapi/spec"
inf "gopkg.in/inf.v0"
"k8s.io/apimachinery/pkg/openapi"
openapi "k8s.io/kube-openapi/pkg/common"
)
// Quantity is a fixed-point representation of a number.

View file

@ -195,14 +195,9 @@ func ValidateInitializers(initializers *metav1.Initializers, fldPath *field.Path
return allErrs
}
for i, initializer := range initializers.Pending {
for _, msg := range validation.IsQualifiedName(initializer.Name) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("pending").Index(i), initializer.Name, msg))
}
allErrs = append(allErrs, validation.IsFullyQualifiedName(fldPath.Child("pending").Index(i).Child("name"), initializer.Name)...)
}
allErrs = append(allErrs, validateInitializersResult(initializers.Result, fldPath.Child("result"))...)
if len(initializers.Pending) == 0 && initializers.Result == nil {
allErrs = append(allErrs, field.Invalid(fldPath.Child("pending"), nil, "must be non-empty when result is not set"))
}
return allErrs
}
@ -288,7 +283,7 @@ func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *f
if newMeta.GetDeletionGracePeriodSeconds() != nil && (oldMeta.GetDeletionGracePeriodSeconds() == nil || *newMeta.GetDeletionGracePeriodSeconds() != *oldMeta.GetDeletionGracePeriodSeconds()) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionGracePeriodSeconds"), newMeta.GetDeletionGracePeriodSeconds(), "field is immutable; may only be changed via deletion"))
}
if newMeta.GetDeletionTimestamp() != nil && (oldMeta.GetDeletionTimestamp() == nil || !newMeta.GetDeletionTimestamp().Equal(*oldMeta.GetDeletionTimestamp())) {
if newMeta.GetDeletionTimestamp() != nil && (oldMeta.GetDeletionTimestamp() == nil || !newMeta.GetDeletionTimestamp().Equal(oldMeta.GetDeletionTimestamp())) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionTimestamp"), newMeta.GetDeletionTimestamp(), "field is immutable; may only be changed via deletion"))
}

View file

@ -47,10 +47,6 @@ type GroupMetaFactoryArgs struct {
// example: 'servicecatalog.k8s.io'
GroupName string
VersionPreferenceOrder []string
// ImportPrefix is the base go package of the API-Group
//
// example: 'k8s.io/kubernetes/pkg/apis/autoscaling'
ImportPrefix string
// RootScopedKinds are resources that are not namespaced.
RootScopedKinds sets.String // nil is allowed
IgnoredKinds sets.String // nil is allowed
@ -176,14 +172,21 @@ func (gmf *GroupMetaFactory) newRESTMapper(scheme *runtime.Scheme, externalVersi
ignoredKinds = gmf.GroupArgs.IgnoredKinds
}
return meta.NewDefaultRESTMapperFromScheme(
externalVersions,
groupMeta.InterfacesFor,
gmf.GroupArgs.ImportPrefix,
ignoredKinds,
rootScoped,
scheme,
)
mapper := meta.NewDefaultRESTMapper(externalVersions, groupMeta.InterfacesFor)
for _, gv := range externalVersions {
for kind := range scheme.KnownTypes(gv) {
if ignoredKinds.Has(kind) {
continue
}
scope := meta.RESTScopeNamespace
if rootScoped.Has(kind) {
scope = meta.RESTScopeRoot
}
mapper.Add(gv.WithKind(kind), scope)
}
}
return mapper
}
// Enable enables group versions that are allowed, adds methods to the scheme, etc.

View file

@ -42,10 +42,6 @@ type APIRegistrationManager struct {
// registeredGroupVersions stores all API group versions for which RegisterGroup is called.
registeredVersions map[schema.GroupVersion]struct{}
// thirdPartyGroupVersions are API versions which are dynamically
// registered (and unregistered) via API calls to the apiserver
thirdPartyGroupVersions []schema.GroupVersion
// enabledVersions represents all enabled API versions. It should be a
// subset of registeredVersions. Please call EnableVersions() to add
// enabled versions.
@ -66,11 +62,10 @@ type APIRegistrationManager struct {
// wish to test.
func NewAPIRegistrationManager(kubeAPIVersions string) (*APIRegistrationManager, error) {
m := &APIRegistrationManager{
registeredVersions: map[schema.GroupVersion]struct{}{},
thirdPartyGroupVersions: []schema.GroupVersion{},
enabledVersions: map[schema.GroupVersion]struct{}{},
groupMetaMap: map[string]*apimachinery.GroupMeta{},
envRequestedVersions: []schema.GroupVersion{},
registeredVersions: map[schema.GroupVersion]struct{}{},
enabledVersions: map[schema.GroupVersion]struct{}{},
groupMetaMap: map[string]*apimachinery.GroupMeta{},
envRequestedVersions: []schema.GroupVersion{},
}
if len(kubeAPIVersions) != 0 {
@ -211,41 +206,6 @@ func (m *APIRegistrationManager) RegisteredGroupVersions() []schema.GroupVersion
return ret
}
// IsThirdPartyAPIGroupVersion returns true if the api version is a user-registered group/version.
func (m *APIRegistrationManager) IsThirdPartyAPIGroupVersion(gv schema.GroupVersion) bool {
for ix := range m.thirdPartyGroupVersions {
if m.thirdPartyGroupVersions[ix] == gv {
return true
}
}
return false
}
// AddThirdPartyAPIGroupVersions sets the list of third party versions,
// registers them in the API machinery and enables them.
// Skips GroupVersions that are already registered.
// Returns the list of GroupVersions that were skipped.
func (m *APIRegistrationManager) AddThirdPartyAPIGroupVersions(gvs ...schema.GroupVersion) []schema.GroupVersion {
filteredGVs := []schema.GroupVersion{}
skippedGVs := []schema.GroupVersion{}
for ix := range gvs {
if !m.IsRegisteredVersion(gvs[ix]) {
filteredGVs = append(filteredGVs, gvs[ix])
} else {
glog.V(3).Infof("Skipping %s, because its already registered", gvs[ix].String())
skippedGVs = append(skippedGVs, gvs[ix])
}
}
if len(filteredGVs) == 0 {
return skippedGVs
}
m.RegisterVersions(filteredGVs)
m.EnableVersions(filteredGVs...)
m.thirdPartyGroupVersions = append(m.thirdPartyGroupVersions, filteredGVs...)
return skippedGVs
}
// InterfacesFor is a union meta.VersionInterfacesFunc func for all registered types
func (m *APIRegistrationManager) InterfacesFor(version schema.GroupVersion) (*meta.VersionInterfaces, error) {
groupMeta, err := m.Group(version.Group)

View file

@ -0,0 +1,77 @@
/*
Copyright 2017 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 internalversion
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/util/validation/field"
)
func Convert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out *metav1.ListOptions, s conversion.Scope) error {
if err := metav1.Convert_fields_Selector_To_string(&in.FieldSelector, &out.FieldSelector, s); err != nil {
return err
}
if err := metav1.Convert_labels_Selector_To_string(&in.LabelSelector, &out.LabelSelector, s); err != nil {
return err
}
out.IncludeUninitialized = in.IncludeUninitialized
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = in.TimeoutSeconds
out.Watch = in.Watch
out.Limit = in.Limit
out.Continue = in.Continue
return nil
}
func Convert_v1_ListOptions_To_internalversion_ListOptions(in *metav1.ListOptions, out *ListOptions, s conversion.Scope) error {
if err := metav1.Convert_string_To_fields_Selector(&in.FieldSelector, &out.FieldSelector, s); err != nil {
return err
}
if err := metav1.Convert_string_To_labels_Selector(&in.LabelSelector, &out.LabelSelector, s); err != nil {
return err
}
out.IncludeUninitialized = in.IncludeUninitialized
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = in.TimeoutSeconds
out.Watch = in.Watch
out.Limit = in.Limit
out.Continue = in.Continue
return nil
}
func Convert_map_to_v1_LabelSelector(in *map[string]string, out *metav1.LabelSelector, s conversion.Scope) error {
if in == nil {
return nil
}
out = new(metav1.LabelSelector)
for labelKey, labelValue := range *in {
metav1.AddLabelToSelector(out, labelKey, labelValue)
}
return nil
}
func Convert_v1_LabelSelector_to_map(in *metav1.LabelSelector, out *map[string]string, s conversion.Scope) error {
var err error
*out, err = metav1.LabelSelectorAsMap(in)
if err != nil {
err = field.Invalid(field.NewPath("labelSelector"), *in, fmt.Sprintf("cannot convert to old selector: %v", err))
}
return err
}

View file

@ -14,5 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// package openapi holds shared codes and types between open API code generator and spec generator.
package openapi
// +k8s:deepcopy-gen=package
package internalversion

View file

@ -0,0 +1,108 @@
/*
Copyright 2017 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 internalversion
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
)
// GroupName is the group name for this API.
const GroupName = "meta.k8s.io"
// Scheme is the registry for any type that adheres to the meta API spec.
var scheme = runtime.NewScheme()
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
// Copier exposes copying on this scheme.
var Copier runtime.ObjectCopier = scheme
// Codecs provides access to encoding and decoding for the scheme.
var Codecs = serializer.NewCodecFactory(scheme)
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// 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) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// addToGroupVersion registers common meta types into schemas.
func addToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) error {
if err := scheme.AddIgnoredConversionType(&metav1.TypeMeta{}, &metav1.TypeMeta{}); err != nil {
return err
}
scheme.AddConversionFuncs(
metav1.Convert_string_To_labels_Selector,
metav1.Convert_labels_Selector_To_string,
metav1.Convert_string_To_fields_Selector,
metav1.Convert_fields_Selector_To_string,
Convert_map_to_v1_LabelSelector,
Convert_v1_LabelSelector_to_map,
Convert_internalversion_ListOptions_To_v1_ListOptions,
Convert_v1_ListOptions_To_internalversion_ListOptions,
)
// ListOptions is the only options struct which needs conversion (it exposes labels and fields
// as selectors for convenience). The other types have only a single representation today.
scheme.AddKnownTypes(SchemeGroupVersion,
&ListOptions{},
&metav1.GetOptions{},
&metav1.ExportOptions{},
&metav1.DeleteOptions{},
)
scheme.AddKnownTypes(SchemeGroupVersion,
&metav1alpha1.Table{},
&metav1alpha1.TableOptions{},
&metav1alpha1.PartialObjectMetadata{},
&metav1alpha1.PartialObjectMetadataList{},
)
scheme.AddKnownTypes(metav1alpha1.SchemeGroupVersion,
&metav1alpha1.Table{},
&metav1alpha1.TableOptions{},
&metav1alpha1.PartialObjectMetadata{},
&metav1alpha1.PartialObjectMetadataList{},
)
// Allow delete options to be decoded across all version in this scheme (we may want to be more clever than this)
scheme.AddUnversionedTypes(SchemeGroupVersion, &metav1.DeleteOptions{})
metav1.AddToGroupVersion(scheme, metav1.SchemeGroupVersion)
return nil
}
// Unlike other API groups, meta internal knows about all meta external versions, but keeps
// the logic for conversion private.
func init() {
if err := addToGroupVersion(scheme, SchemeGroupVersion); err != nil {
panic(err)
}
}

View file

@ -0,0 +1,70 @@
/*
Copyright 2017 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 internalversion
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ListOptions is the query options to a standard REST list call.
type ListOptions struct {
metav1.TypeMeta
// A selector based on labels
LabelSelector labels.Selector
// A selector based on fields
FieldSelector fields.Selector
// If true, partially initialized resources are included in the response.
// +optional
IncludeUninitialized bool
// If true, watch for changes to this list
Watch bool
// When specified with a watch call, shows changes that occur after that particular version of a resource.
// Defaults to changes from the beginning of history.
// When specified for list:
// - if unset, then the result is returned from remote storage based on quorum-read flag;
// - if it's 0, then we simply return what we currently have in cache, no guarantee;
// - if set to non zero, then the result is at least as fresh as given rv.
ResourceVersion string
// Timeout for the list/watch call.
TimeoutSeconds *int64
// Limit specifies the maximum number of results to return from the server. The server may
// not support this field on all resource types, but if it does and more results remain it
// will set the continue field on the returned list object.
Limit int64
// Continue is a token returned by the server that lets a client retrieve chunks of results
// from the server by specifying limit. The server may reject requests for continuation tokens
// it does not recognize and will return a 410 error if the token can no longer be used because
// it has expired.
Continue string
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// List holds a list of objects, which may not be known by the server.
type List struct {
metav1.TypeMeta
// +optional
metav1.ListMeta
Items []runtime.Object
}

View file

@ -0,0 +1,113 @@
// +build !ignore_autogenerated
/*
Copyright 2017 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 conversion-gen. Do not edit it manually!
package internalversion
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
unsafe "unsafe"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
return scheme.AddGeneratedConversionFuncs(
Convert_internalversion_List_To_v1_List,
Convert_v1_List_To_internalversion_List,
Convert_internalversion_ListOptions_To_v1_ListOptions,
Convert_v1_ListOptions_To_internalversion_ListOptions,
)
}
func autoConvert_internalversion_List_To_v1_List(in *List, out *v1.List, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.RawExtension, len(*in))
for i := range *in {
if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = make([]runtime.RawExtension, 0)
}
return nil
}
// Convert_internalversion_List_To_v1_List is an autogenerated conversion function.
func Convert_internalversion_List_To_v1_List(in *List, out *v1.List, s conversion.Scope) error {
return autoConvert_internalversion_List_To_v1_List(in, out, s)
}
func autoConvert_v1_List_To_internalversion_List(in *v1.List, out *List, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.Object, len(*in))
for i := range *in {
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
// Convert_v1_List_To_internalversion_List is an autogenerated conversion function.
func Convert_v1_List_To_internalversion_List(in *v1.List, out *List, s conversion.Scope) error {
return autoConvert_v1_List_To_internalversion_List(in, out, s)
}
func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out *v1.ListOptions, s conversion.Scope) error {
if err := v1.Convert_labels_Selector_To_string(&in.LabelSelector, &out.LabelSelector, s); err != nil {
return err
}
if err := v1.Convert_fields_Selector_To_string(&in.FieldSelector, &out.FieldSelector, s); err != nil {
return err
}
out.IncludeUninitialized = in.IncludeUninitialized
out.Watch = in.Watch
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
return nil
}
func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOptions, out *ListOptions, s conversion.Scope) error {
if err := v1.Convert_string_To_labels_Selector(&in.LabelSelector, &out.LabelSelector, s); err != nil {
return err
}
if err := v1.Convert_string_To_fields_Selector(&in.FieldSelector, &out.FieldSelector, s); err != nil {
return err
}
out.IncludeUninitialized = in.IncludeUninitialized
out.Watch = in.Watch
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
return nil
}

View file

@ -0,0 +1,126 @@
// +build !ignore_autogenerated
/*
Copyright 2017 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 internalversion
import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
reflect "reflect"
)
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
//
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*List).DeepCopyInto(out.(*List))
return nil
}, InType: reflect.TypeOf(&List{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*ListOptions).DeepCopyInto(out.(*ListOptions))
return nil
}, InType: reflect.TypeOf(&ListOptions{})},
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *List) DeepCopyInto(out *List) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.Object, len(*in))
for i := range *in {
if (*in)[i] == nil {
(*out)[i] = nil
} else {
(*out)[i] = (*in)[i].DeepCopyObject()
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new List.
func (in *List) DeepCopy() *List {
if in == nil {
return nil
}
out := new(List)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *List) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ListOptions) DeepCopyInto(out *ListOptions) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.LabelSelector == nil {
out.LabelSelector = nil
} else {
out.LabelSelector = in.LabelSelector.DeepCopySelector()
}
if in.FieldSelector == nil {
out.FieldSelector = nil
} else {
out.FieldSelector = in.FieldSelector.DeepCopySelector()
}
if in.TimeoutSeconds != nil {
in, out := &in.TimeoutSeconds, &out.TimeoutSeconds
if *in == nil {
*out = nil
} else {
*out = new(int64)
**out = **in
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListOptions.
func (in *ListOptions) DeepCopy() *ListOptions {
if in == nil {
return nil
}
out := new(ListOptions)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ListOptions) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}

View file

@ -0,0 +1,54 @@
/*
Copyright 2017 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/apimachinery/pkg/runtime/schema"
)
// IsControlledBy checks if the object has a controllerRef set to the given owner
func IsControlledBy(obj Object, owner Object) bool {
ref := GetControllerOf(obj)
if ref == nil {
return false
}
return ref.UID == owner.GetUID()
}
// GetControllerOf returns a pointer to a copy of the controllerRef if controllee has a controller
func GetControllerOf(controllee Object) *OwnerReference {
for _, ref := range controllee.GetOwnerReferences() {
if ref.Controller != nil && *ref.Controller {
return &ref
}
}
return nil
}
// NewControllerRef creates an OwnerReference pointing to the given owner.
func NewControllerRef(owner Object, gvk schema.GroupVersionKind) *OwnerReference {
blockOwnerDeletion := true
isController := true
return &OwnerReference{
APIVersion: gvk.GroupVersion().String(),
Kind: gvk.Kind,
Name: owner.GetName(),
UID: owner.GetUID(),
BlockOwnerDeletion: &blockOwnerDeletion,
Controller: &isController,
}
}

View file

@ -39,6 +39,9 @@ func AddConversionFuncs(scheme *runtime.Scheme) error {
Convert_unversioned_Time_To_unversioned_Time,
Convert_Pointer_v1_Duration_To_v1_Duration,
Convert_v1_Duration_To_Pointer_v1_Duration,
Convert_Slice_string_To_unversioned_Time,
Convert_resource_Quantity_To_resource_Quantity,
@ -181,6 +184,21 @@ func Convert_unversioned_Time_To_unversioned_Time(in *Time, out *Time, s convers
return nil
}
func Convert_Pointer_v1_Duration_To_v1_Duration(in **Duration, out *Duration, s conversion.Scope) error {
if *in == nil {
*out = Duration{} // zero duration
return nil
}
*out = **in // copy
return nil
}
func Convert_v1_Duration_To_Pointer_v1_Duration(in *Duration, out **Duration, s conversion.Scope) error {
temp := *in //copy
*out = &temp
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 *Time, s conversion.Scope) error {
str := ""

View file

@ -19,4 +19,4 @@ limitations under the License.
// +k8s:defaulter-gen=TypeMeta
// +groupName=meta.k8s.io
package v1
package v1 // import "k8s.io/apimachinery/pkg/apis/meta/v1"

View file

@ -44,6 +44,7 @@ limitations under the License.
Initializers
LabelSelector
LabelSelectorRequirement
List
ListMeta
ListOptions
MicroTime
@ -67,6 +68,8 @@ import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import k8s_io_apimachinery_pkg_runtime "k8s.io/apimachinery/pkg/runtime"
import time "time"
import k8s_io_apimachinery_pkg_types "k8s.io/apimachinery/pkg/types"
@ -169,71 +172,75 @@ func (*LabelSelectorRequirement) Descriptor() ([]byte, []int) {
return fileDescriptorGenerated, []int{18}
}
func (m *List) Reset() { *m = List{} }
func (*List) ProtoMessage() {}
func (*List) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{19} }
func (m *ListMeta) Reset() { *m = ListMeta{} }
func (*ListMeta) ProtoMessage() {}
func (*ListMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{19} }
func (*ListMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{20} }
func (m *ListOptions) Reset() { *m = ListOptions{} }
func (*ListOptions) ProtoMessage() {}
func (*ListOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{20} }
func (*ListOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{21} }
func (m *MicroTime) Reset() { *m = MicroTime{} }
func (*MicroTime) ProtoMessage() {}
func (*MicroTime) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{21} }
func (*MicroTime) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{22} }
func (m *ObjectMeta) Reset() { *m = ObjectMeta{} }
func (*ObjectMeta) ProtoMessage() {}
func (*ObjectMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{22} }
func (*ObjectMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{23} }
func (m *OwnerReference) Reset() { *m = OwnerReference{} }
func (*OwnerReference) ProtoMessage() {}
func (*OwnerReference) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{23} }
func (*OwnerReference) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{24} }
func (m *Preconditions) Reset() { *m = Preconditions{} }
func (*Preconditions) ProtoMessage() {}
func (*Preconditions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{24} }
func (*Preconditions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{25} }
func (m *RootPaths) Reset() { *m = RootPaths{} }
func (*RootPaths) ProtoMessage() {}
func (*RootPaths) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{25} }
func (*RootPaths) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{26} }
func (m *ServerAddressByClientCIDR) Reset() { *m = ServerAddressByClientCIDR{} }
func (*ServerAddressByClientCIDR) ProtoMessage() {}
func (*ServerAddressByClientCIDR) Descriptor() ([]byte, []int) {
return fileDescriptorGenerated, []int{26}
return fileDescriptorGenerated, []int{27}
}
func (m *Status) Reset() { *m = Status{} }
func (*Status) ProtoMessage() {}
func (*Status) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{27} }
func (*Status) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{28} }
func (m *StatusCause) Reset() { *m = StatusCause{} }
func (*StatusCause) ProtoMessage() {}
func (*StatusCause) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{28} }
func (*StatusCause) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{29} }
func (m *StatusDetails) Reset() { *m = StatusDetails{} }
func (*StatusDetails) ProtoMessage() {}
func (*StatusDetails) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{29} }
func (*StatusDetails) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{30} }
func (m *Time) Reset() { *m = Time{} }
func (*Time) ProtoMessage() {}
func (*Time) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{30} }
func (*Time) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{31} }
func (m *Timestamp) Reset() { *m = Timestamp{} }
func (*Timestamp) ProtoMessage() {}
func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{31} }
func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{32} }
func (m *TypeMeta) Reset() { *m = TypeMeta{} }
func (*TypeMeta) ProtoMessage() {}
func (*TypeMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{32} }
func (*TypeMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{33} }
func (m *Verbs) Reset() { *m = Verbs{} }
func (*Verbs) ProtoMessage() {}
func (*Verbs) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{33} }
func (*Verbs) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{34} }
func (m *WatchEvent) Reset() { *m = WatchEvent{} }
func (*WatchEvent) ProtoMessage() {}
func (*WatchEvent) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{34} }
func (*WatchEvent) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{35} }
func init() {
proto.RegisterType((*APIGroup)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.APIGroup")
@ -255,6 +262,7 @@ func init() {
proto.RegisterType((*Initializers)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.Initializers")
proto.RegisterType((*LabelSelector)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector")
proto.RegisterType((*LabelSelectorRequirement)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement")
proto.RegisterType((*List)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.List")
proto.RegisterType((*ListMeta)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta")
proto.RegisterType((*ListOptions)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.ListOptions")
proto.RegisterType((*MicroTime)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1.MicroTime")
@ -431,6 +439,14 @@ func (m *APIResource) MarshalTo(dAtA []byte) (int, error) {
i += copy(dAtA[i:], s)
}
}
dAtA[i] = 0x42
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Group)))
i += copy(dAtA[i:], m.Group)
dAtA[i] = 0x4a
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Version)))
i += copy(dAtA[i:], m.Version)
return i, nil
}
@ -966,6 +982,44 @@ func (m *LabelSelectorRequirement) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *List) 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
}
func (m *List) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size()))
n5, err := m.ListMeta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n5
if len(m.Items) > 0 {
for _, msg := range m.Items {
dAtA[i] = 0x12
i++
i = encodeVarintGenerated(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n
}
}
return i, nil
}
func (m *ListMeta) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -989,6 +1043,10 @@ func (m *ListMeta) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.ResourceVersion)))
i += copy(dAtA[i:], m.ResourceVersion)
dAtA[i] = 0x1a
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Continue)))
i += copy(dAtA[i:], m.Continue)
return i, nil
}
@ -1040,6 +1098,13 @@ func (m *ListOptions) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0
}
i++
dAtA[i] = 0x38
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.Limit))
dAtA[i] = 0x42
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Continue)))
i += copy(dAtA[i:], m.Continue)
return i, nil
}
@ -1088,20 +1153,20 @@ func (m *ObjectMeta) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x42
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.CreationTimestamp.Size()))
n5, err := m.CreationTimestamp.MarshalTo(dAtA[i:])
n6, err := m.CreationTimestamp.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n5
i += n6
if m.DeletionTimestamp != nil {
dAtA[i] = 0x4a
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.DeletionTimestamp.Size()))
n6, err := m.DeletionTimestamp.MarshalTo(dAtA[i:])
n7, err := m.DeletionTimestamp.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n6
i += n7
}
if m.DeletionGracePeriodSeconds != nil {
dAtA[i] = 0x50
@ -1189,11 +1254,11 @@ func (m *ObjectMeta) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x1
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.Initializers.Size()))
n7, err := m.Initializers.MarshalTo(dAtA[i:])
n8, err := m.Initializers.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n7
i += n8
}
return i, nil
}
@ -1353,11 +1418,11 @@ func (m *Status) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.ListMeta.Size()))
n8, err := m.ListMeta.MarshalTo(dAtA[i:])
n9, err := m.ListMeta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n8
i += n9
dAtA[i] = 0x12
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Status)))
@ -1374,11 +1439,11 @@ func (m *Status) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2a
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.Details.Size()))
n9, err := m.Details.MarshalTo(dAtA[i:])
n10, err := m.Details.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n9
i += n10
}
dAtA[i] = 0x30
i++
@ -1570,11 +1635,11 @@ func (m *WatchEvent) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.Object.Size()))
n10, err := m.Object.MarshalTo(dAtA[i:])
n11, err := m.Object.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n10
i += n11
return i, nil
}
@ -1665,6 +1730,10 @@ func (m *APIResource) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
}
}
l = len(m.Group)
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Version)
n += 1 + l + sovGenerated(uint64(l))
return n
}
@ -1868,6 +1937,20 @@ func (m *LabelSelectorRequirement) Size() (n int) {
return n
}
func (m *List) Size() (n int) {
var l int
_ = l
l = m.ListMeta.Size()
n += 1 + l + sovGenerated(uint64(l))
if len(m.Items) > 0 {
for _, e := range m.Items {
l = e.Size()
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
func (m *ListMeta) Size() (n int) {
var l int
_ = l
@ -1875,6 +1958,8 @@ func (m *ListMeta) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = len(m.ResourceVersion)
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Continue)
n += 1 + l + sovGenerated(uint64(l))
return n
}
@ -1892,6 +1977,9 @@ func (m *ListOptions) Size() (n int) {
n += 1 + sovGenerated(uint64(*m.TimeoutSeconds))
}
n += 2
n += 1 + sovGenerated(uint64(m.Limit))
l = len(m.Continue)
n += 1 + l + sovGenerated(uint64(l))
return n
}
@ -2149,6 +2237,8 @@ func (this *APIResource) String() string {
`ShortNames:` + fmt.Sprintf("%v", this.ShortNames) + `,`,
`SingularName:` + fmt.Sprintf("%v", this.SingularName) + `,`,
`Categories:` + fmt.Sprintf("%v", this.Categories) + `,`,
`Group:` + fmt.Sprintf("%v", this.Group) + `,`,
`Version:` + fmt.Sprintf("%v", this.Version) + `,`,
`}`,
}, "")
return s
@ -2274,6 +2364,17 @@ func (this *LabelSelectorRequirement) String() string {
}, "")
return s
}
func (this *List) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&List{`,
`ListMeta:` + strings.Replace(strings.Replace(this.ListMeta.String(), "ListMeta", "ListMeta", 1), `&`, ``, 1) + `,`,
`Items:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.Items), "RawExtension", "k8s_io_apimachinery_pkg_runtime.RawExtension", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
}
func (this *ListMeta) String() string {
if this == nil {
return "nil"
@ -2281,6 +2382,7 @@ func (this *ListMeta) String() string {
s := strings.Join([]string{`&ListMeta{`,
`SelfLink:` + fmt.Sprintf("%v", this.SelfLink) + `,`,
`ResourceVersion:` + fmt.Sprintf("%v", this.ResourceVersion) + `,`,
`Continue:` + fmt.Sprintf("%v", this.Continue) + `,`,
`}`,
}, "")
return s
@ -2296,6 +2398,8 @@ func (this *ListOptions) String() string {
`ResourceVersion:` + fmt.Sprintf("%v", this.ResourceVersion) + `,`,
`TimeoutSeconds:` + valueToStringGenerated(this.TimeoutSeconds) + `,`,
`IncludeUninitialized:` + fmt.Sprintf("%v", this.IncludeUninitialized) + `,`,
`Limit:` + fmt.Sprintf("%v", this.Limit) + `,`,
`Continue:` + fmt.Sprintf("%v", this.Continue) + `,`,
`}`,
}, "")
return s
@ -2953,6 +3057,64 @@ func (m *APIResource) Unmarshal(dAtA []byte) error {
}
m.Categories = append(m.Categories, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Group", 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
}
m.Group = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 9:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Version", 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
}
m.Version = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@ -4839,6 +5001,117 @@ func (m *LabelSelectorRequirement) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *List) 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: List: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: List: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Items = append(m.Items, k8s_io_apimachinery_pkg_runtime.RawExtension{})
if err := m.Items[len(m.Items)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
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 (m *ListMeta) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -4926,6 +5199,35 @@ func (m *ListMeta) Unmarshal(dAtA []byte) error {
}
m.ResourceVersion = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Continue", 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
}
m.Continue = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@ -5123,6 +5425,54 @@ func (m *ListOptions) Unmarshal(dAtA []byte) error {
}
}
m.IncludeUninitialized = bool(v != 0)
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType)
}
m.Limit = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Limit |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Continue", 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
}
m.Continue = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@ -7365,152 +7715,157 @@ func init() {
}
var fileDescriptorGenerated = []byte{
// 2351 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0xcd, 0x6f, 0x1b, 0xc7,
0x15, 0xd7, 0x52, 0x22, 0x45, 0x3e, 0x8a, 0xfa, 0x98, 0xc8, 0x2d, 0x23, 0xb4, 0xa4, 0xb2, 0x29,
0x02, 0xa5, 0x75, 0xc8, 0x4a, 0x69, 0x03, 0xd7, 0x6d, 0xdd, 0x6a, 0x45, 0xd9, 0x10, 0x62, 0xd9,
0xc4, 0x28, 0x76, 0x51, 0xd7, 0x28, 0xba, 0x5a, 0x8e, 0xa8, 0xad, 0x96, 0xbb, 0x9b, 0x99, 0xa1,
0x6c, 0x35, 0x87, 0xe6, 0xd0, 0x02, 0x3d, 0x14, 0x85, 0x8f, 0x3d, 0x15, 0x31, 0xda, 0xbf, 0xa0,
0x7f, 0x40, 0x4f, 0x05, 0xea, 0x63, 0x80, 0x5e, 0x72, 0x28, 0x88, 0x98, 0x39, 0xf4, 0x14, 0xf4,
0x2e, 0xa0, 0x40, 0x31, 0xb3, 0xb3, 0x5f, 0xa4, 0x18, 0x2d, 0xe3, 0xa0, 0xc8, 0x49, 0xdc, 0xf7,
0xf1, 0x7b, 0x6f, 0x66, 0xde, 0xbc, 0xf7, 0xe6, 0x09, 0xf6, 0x4f, 0xae, 0xb1, 0x86, 0xed, 0x35,
0x4f, 0xfa, 0x87, 0x84, 0xba, 0x84, 0x13, 0xd6, 0x3c, 0x25, 0x6e, 0xc7, 0xa3, 0x4d, 0xc5, 0x30,
0x7d, 0xbb, 0x67, 0x5a, 0xc7, 0xb6, 0x4b, 0xe8, 0x59, 0xd3, 0x3f, 0xe9, 0x0a, 0x02, 0x6b, 0xf6,
0x08, 0x37, 0x9b, 0xa7, 0x9b, 0xcd, 0x2e, 0x71, 0x09, 0x35, 0x39, 0xe9, 0x34, 0x7c, 0xea, 0x71,
0x0f, 0x7d, 0x23, 0xd0, 0x6a, 0x24, 0xb5, 0x1a, 0xfe, 0x49, 0x57, 0x10, 0x58, 0x43, 0x68, 0x35,
0x4e, 0x37, 0xd7, 0xde, 0xe8, 0xda, 0xfc, 0xb8, 0x7f, 0xd8, 0xb0, 0xbc, 0x5e, 0xb3, 0xeb, 0x75,
0xbd, 0xa6, 0x54, 0x3e, 0xec, 0x1f, 0xc9, 0x2f, 0xf9, 0x21, 0x7f, 0x05, 0xa0, 0x6b, 0x13, 0x5d,
0xa1, 0x7d, 0x97, 0xdb, 0x3d, 0x32, 0xea, 0xc5, 0xda, 0x5b, 0x97, 0x29, 0x30, 0xeb, 0x98, 0xf4,
0xcc, 0x31, 0xbd, 0x37, 0x27, 0xe9, 0xf5, 0xb9, 0xed, 0x34, 0x6d, 0x97, 0x33, 0x4e, 0x47, 0x95,
0xf4, 0x7f, 0xcc, 0x42, 0x71, 0xbb, 0xbd, 0x77, 0x8b, 0x7a, 0x7d, 0x1f, 0xad, 0xc3, 0x9c, 0x6b,
0xf6, 0x48, 0x55, 0x5b, 0xd7, 0x36, 0x4a, 0xc6, 0xc2, 0xb3, 0x41, 0x7d, 0x66, 0x38, 0xa8, 0xcf,
0xdd, 0x31, 0x7b, 0x04, 0x4b, 0x0e, 0x72, 0xa0, 0x78, 0x4a, 0x28, 0xb3, 0x3d, 0x97, 0x55, 0x73,
0xeb, 0xb3, 0x1b, 0xe5, 0xad, 0x1b, 0x8d, 0x2c, 0x9b, 0xd6, 0x90, 0x06, 0xee, 0x07, 0xaa, 0x37,
0x3d, 0xda, 0xb2, 0x99, 0xe5, 0x9d, 0x12, 0x7a, 0x66, 0x2c, 0x2b, 0x2b, 0x45, 0xc5, 0x64, 0x38,
0xb2, 0x80, 0x7e, 0xa3, 0xc1, 0xb2, 0x4f, 0xc9, 0x11, 0xa1, 0x94, 0x74, 0x14, 0xbf, 0x3a, 0xbb,
0xae, 0x7d, 0x01, 0x66, 0xab, 0xca, 0xec, 0x72, 0x7b, 0x04, 0x1f, 0x8f, 0x59, 0x44, 0x7f, 0xd6,
0x60, 0x8d, 0x11, 0x7a, 0x4a, 0xe8, 0x76, 0xa7, 0x43, 0x09, 0x63, 0xc6, 0xd9, 0x8e, 0x63, 0x13,
0x97, 0xef, 0xec, 0xb5, 0x30, 0xab, 0xce, 0xc9, 0x7d, 0xf8, 0x51, 0x36, 0x87, 0x0e, 0x26, 0xe1,
0x18, 0xba, 0xf2, 0x68, 0x6d, 0xa2, 0x08, 0xc3, 0x9f, 0xe1, 0x86, 0x7e, 0x04, 0x0b, 0xe1, 0x41,
0xde, 0xb6, 0x19, 0x47, 0xf7, 0xa1, 0xd0, 0x15, 0x1f, 0xac, 0xaa, 0x49, 0x07, 0x1b, 0xd9, 0x1c,
0x0c, 0x31, 0x8c, 0x45, 0xe5, 0x4f, 0x41, 0x7e, 0x32, 0xac, 0xd0, 0xf4, 0x4f, 0x73, 0x50, 0xde,
0x6e, 0xef, 0x61, 0xc2, 0xbc, 0x3e, 0xb5, 0x48, 0x86, 0xa0, 0xd9, 0x02, 0x10, 0x7f, 0x99, 0x6f,
0x5a, 0xa4, 0x53, 0xcd, 0xad, 0x6b, 0x1b, 0x45, 0x03, 0x29, 0x39, 0xb8, 0x13, 0x71, 0x70, 0x42,
0x4a, 0xa0, 0x9e, 0xd8, 0x6e, 0x47, 0x9e, 0x76, 0x02, 0xf5, 0x6d, 0xdb, 0xed, 0x60, 0xc9, 0x41,
0xb7, 0x21, 0x7f, 0x4a, 0xe8, 0xa1, 0xd8, 0x7f, 0x11, 0x10, 0xdf, 0xca, 0xb6, 0xbc, 0xfb, 0x42,
0xc5, 0x28, 0x0d, 0x07, 0xf5, 0xbc, 0xfc, 0x89, 0x03, 0x10, 0xd4, 0x00, 0x60, 0xc7, 0x1e, 0xe5,
0xd2, 0x9d, 0x6a, 0x7e, 0x7d, 0x76, 0xa3, 0x64, 0x2c, 0x0a, 0xff, 0x0e, 0x22, 0x2a, 0x4e, 0x48,
0xa0, 0x6b, 0xb0, 0xc0, 0x6c, 0xb7, 0xdb, 0x77, 0x4c, 0x2a, 0x08, 0xd5, 0x82, 0xf4, 0x73, 0x55,
0xf9, 0xb9, 0x70, 0x90, 0xe0, 0xe1, 0x94, 0xa4, 0xb0, 0x64, 0x99, 0x9c, 0x74, 0x3d, 0x6a, 0x13,
0x56, 0x9d, 0x8f, 0x2d, 0xed, 0x44, 0x54, 0x9c, 0x90, 0xd0, 0xff, 0xaa, 0xc1, 0x52, 0x62, 0xbf,
0xe5, 0xd9, 0x5e, 0x83, 0x85, 0x6e, 0x22, 0xb2, 0xd5, 0xde, 0x47, 0xd6, 0x93, 0x51, 0x8f, 0x53,
0x92, 0x88, 0x40, 0x89, 0x2a, 0xa4, 0xf0, 0x06, 0x6f, 0x66, 0x0e, 0x8c, 0xd0, 0x87, 0xd8, 0x52,
0x82, 0xc8, 0x70, 0x8c, 0xac, 0xff, 0x5b, 0x93, 0x41, 0x12, 0xde, 0x69, 0xb4, 0x91, 0xc8, 0x1b,
0x9a, 0x5c, 0xf2, 0xc2, 0x84, 0x3b, 0x7f, 0xc9, 0x65, 0xcb, 0x7d, 0x29, 0x2e, 0xdb, 0xf5, 0xe2,
0x1f, 0x3f, 0xa8, 0xcf, 0xbc, 0xff, 0xaf, 0xf5, 0x19, 0xfd, 0x93, 0x1c, 0x54, 0x5a, 0xc4, 0x21,
0x9c, 0xdc, 0xf5, 0xb9, 0x5c, 0xc1, 0x4d, 0x40, 0x5d, 0x6a, 0x5a, 0xa4, 0x4d, 0xa8, 0xed, 0x75,
0x0e, 0x88, 0xe5, 0xb9, 0x1d, 0x26, 0x8f, 0x68, 0xd6, 0xf8, 0xca, 0x70, 0x50, 0x47, 0xb7, 0xc6,
0xb8, 0xf8, 0x02, 0x0d, 0xe4, 0x40, 0xc5, 0xa7, 0xf2, 0xb7, 0xcd, 0x55, 0xc2, 0x15, 0x81, 0xfe,
0x66, 0xb6, 0xb5, 0xb7, 0x93, 0xaa, 0xc6, 0xca, 0x70, 0x50, 0xaf, 0xa4, 0x48, 0x38, 0x0d, 0x8e,
0x7e, 0x0c, 0xcb, 0x1e, 0xf5, 0x8f, 0x4d, 0xb7, 0x45, 0x7c, 0xe2, 0x76, 0x88, 0xcb, 0x99, 0xbc,
0x7c, 0x45, 0x63, 0x55, 0xa4, 0xc9, 0xbb, 0x23, 0x3c, 0x3c, 0x26, 0x8d, 0x1e, 0xc0, 0x8a, 0x4f,
0x3d, 0xdf, 0xec, 0x9a, 0x02, 0xb1, 0xed, 0x39, 0xb6, 0x75, 0x26, 0x2f, 0x67, 0xc9, 0xb8, 0x3a,
0x1c, 0xd4, 0x57, 0xda, 0xa3, 0xcc, 0xf3, 0x41, 0xfd, 0x25, 0xb9, 0x75, 0x82, 0x12, 0x33, 0xf1,
0x38, 0x8c, 0xbe, 0x07, 0xc5, 0x56, 0x9f, 0x4a, 0x0a, 0xfa, 0x21, 0x14, 0x3b, 0xea, 0xb7, 0xda,
0xd5, 0x57, 0xc2, 0x1a, 0x12, 0xca, 0x9c, 0x0f, 0xea, 0x15, 0x51, 0x2a, 0x1b, 0x21, 0x01, 0x47,
0x2a, 0xfa, 0x43, 0xa8, 0xec, 0x3e, 0xf6, 0x3d, 0xca, 0xc3, 0xf3, 0x7a, 0x0d, 0x0a, 0x44, 0x12,
0x24, 0x5a, 0x31, 0x4e, 0x7c, 0x81, 0x18, 0x56, 0x5c, 0xf4, 0x2a, 0xe4, 0xc9, 0x63, 0xd3, 0xe2,
0x2a, 0x83, 0x55, 0x94, 0x58, 0x7e, 0x57, 0x10, 0x71, 0xc0, 0xd3, 0x9f, 0x6a, 0x00, 0xb7, 0x48,
0x84, 0xbd, 0x0d, 0x4b, 0xe1, 0xa5, 0x48, 0xdf, 0xd5, 0xaf, 0x2a, 0xed, 0x25, 0x9c, 0x66, 0xe3,
0x51, 0x79, 0xd4, 0x86, 0x55, 0xdb, 0xb5, 0x9c, 0x7e, 0x87, 0xdc, 0x73, 0x6d, 0xd7, 0xe6, 0xb6,
0xe9, 0xd8, 0xbf, 0x8a, 0xf2, 0xe8, 0xd7, 0x14, 0xce, 0xea, 0xde, 0x05, 0x32, 0xf8, 0x42, 0x4d,
0xfd, 0x21, 0x94, 0x64, 0x86, 0x10, 0xc9, 0x54, 0xac, 0x4a, 0x26, 0x08, 0xe5, 0x57, 0xb4, 0x2a,
0x29, 0x81, 0x03, 0x5e, 0x94, 0x8d, 0x73, 0x93, 0xb2, 0x71, 0xe2, 0x42, 0x38, 0x50, 0x09, 0x74,
0xc3, 0x02, 0x91, 0xc9, 0xc2, 0x55, 0x28, 0x86, 0x0b, 0x57, 0x56, 0xa2, 0xc6, 0x20, 0x04, 0xc2,
0x91, 0x44, 0xc2, 0xda, 0x31, 0xa4, 0xb2, 0x5d, 0x36, 0x63, 0xaf, 0xc3, 0xbc, 0xca, 0x37, 0xca,
0xd6, 0x92, 0x12, 0x9b, 0x0f, 0x4f, 0x21, 0xe4, 0x27, 0x2c, 0xfd, 0x1a, 0xaa, 0x93, 0xba, 0x89,
0x17, 0xc8, 0xc7, 0xd9, 0x5d, 0xd1, 0xff, 0xa0, 0xc1, 0x72, 0x12, 0x29, 0xfb, 0xf1, 0x65, 0x37,
0x72, 0x79, 0xdd, 0x4d, 0xec, 0xc8, 0x9f, 0x34, 0x58, 0x4d, 0x2d, 0x6d, 0xaa, 0x13, 0x9f, 0xc2,
0xa9, 0x64, 0x70, 0xcc, 0x4e, 0x11, 0x1c, 0x4d, 0x28, 0xef, 0x45, 0x71, 0x4f, 0x2f, 0xef, 0x54,
0xf4, 0xbf, 0x69, 0xb0, 0x90, 0xd0, 0x60, 0xe8, 0x21, 0xcc, 0x8b, 0xfc, 0x66, 0xbb, 0x5d, 0xd5,
0x45, 0x65, 0x2c, 0x96, 0x09, 0x90, 0x78, 0x5d, 0xed, 0x00, 0x09, 0x87, 0x90, 0xa8, 0x0d, 0x05,
0x4a, 0x58, 0xdf, 0xe1, 0x2a, 0xb5, 0x5f, 0xcd, 0x58, 0xd6, 0xb8, 0xc9, 0xfb, 0xcc, 0x00, 0x91,
0xa3, 0xb0, 0xd4, 0xc7, 0x0a, 0x47, 0xff, 0x67, 0x0e, 0x2a, 0xb7, 0xcd, 0x43, 0xe2, 0x1c, 0x10,
0x87, 0x58, 0xdc, 0xa3, 0xe8, 0x3d, 0x28, 0xf7, 0x4c, 0x6e, 0x1d, 0x4b, 0x6a, 0xd8, 0x0b, 0xb6,
0xb2, 0x19, 0x4a, 0x21, 0x35, 0xf6, 0x63, 0x98, 0x5d, 0x97, 0xd3, 0x33, 0xe3, 0x25, 0xb5, 0xb0,
0x72, 0x82, 0x83, 0x93, 0xd6, 0x64, 0x03, 0x2f, 0xbf, 0x77, 0x1f, 0xfb, 0xa2, 0x88, 0x4e, 0xff,
0x6e, 0x48, 0xb9, 0x80, 0xc9, 0xbb, 0x7d, 0x9b, 0x92, 0x1e, 0x71, 0x79, 0xdc, 0xc0, 0xef, 0x8f,
0xe0, 0xe3, 0x31, 0x8b, 0x6b, 0x37, 0x60, 0x79, 0xd4, 0x79, 0xb4, 0x0c, 0xb3, 0x27, 0xe4, 0x2c,
0x88, 0x05, 0x2c, 0x7e, 0xa2, 0x55, 0xc8, 0x9f, 0x9a, 0x4e, 0x5f, 0xe5, 0x1f, 0x1c, 0x7c, 0x5c,
0xcf, 0x5d, 0xd3, 0xf4, 0xbf, 0x68, 0x50, 0x9d, 0xe4, 0x08, 0xfa, 0x7a, 0x02, 0xc8, 0x28, 0x2b,
0xaf, 0x66, 0xdf, 0x26, 0x67, 0x01, 0xea, 0x2e, 0x14, 0x3d, 0x5f, 0x3c, 0xb9, 0x3c, 0xaa, 0xe2,
0xfc, 0xf5, 0x30, 0x76, 0xef, 0x2a, 0xfa, 0xf9, 0xa0, 0x7e, 0x25, 0x05, 0x1f, 0x32, 0x70, 0xa4,
0x8a, 0x74, 0x28, 0x48, 0x7f, 0x44, 0x51, 0x16, 0xed, 0x93, 0x3c, 0xfc, 0xfb, 0x92, 0x82, 0x15,
0x47, 0x7f, 0x0f, 0x8a, 0xa2, 0x3b, 0xdc, 0x27, 0xdc, 0x14, 0x57, 0x86, 0x11, 0xe7, 0xe8, 0xb6,
0xed, 0x9e, 0x28, 0xd7, 0xa2, 0x2b, 0x73, 0xa0, 0xe8, 0x38, 0x92, 0xb8, 0xa8, 0x4c, 0xe5, 0xa6,
0x2b, 0x53, 0xfa, 0x7f, 0x73, 0x50, 0x16, 0xd6, 0xc3, 0xca, 0xf7, 0x7d, 0xa8, 0x38, 0xc9, 0x35,
0x29, 0x2f, 0xae, 0x28, 0xc0, 0x74, 0x94, 0xe2, 0xb4, 0xac, 0x50, 0x3e, 0xb2, 0x89, 0xd3, 0x89,
0x94, 0x73, 0x69, 0xe5, 0x9b, 0x49, 0x26, 0x4e, 0xcb, 0x8a, 0xec, 0xf3, 0x48, 0x9c, 0xb6, 0x6a,
0x5f, 0xa2, 0xec, 0xf3, 0x13, 0x41, 0xc4, 0x01, 0xef, 0xa2, 0x15, 0xcf, 0x4d, 0x59, 0x98, 0xaf,
0xc3, 0xa2, 0xe8, 0x31, 0xbc, 0x3e, 0x0f, 0x7b, 0xbc, 0xbc, 0xec, 0x46, 0xd0, 0x70, 0x50, 0x5f,
0x7c, 0x27, 0xc5, 0xc1, 0x23, 0x92, 0x13, 0x8b, 0x7a, 0xe1, 0x73, 0x17, 0xf5, 0x77, 0xa1, 0xb4,
0x6f, 0x5b, 0xd4, 0x13, 0x86, 0x45, 0x6e, 0x65, 0xa9, 0xbe, 0x33, 0xca, 0x41, 0xa1, 0x43, 0x21,
0x5f, 0xec, 0x96, 0x6b, 0xba, 0x5e, 0xd0, 0x5d, 0xe6, 0xe3, 0xdd, 0xba, 0x23, 0x88, 0x38, 0xe0,
0x5d, 0x5f, 0x15, 0x29, 0xf5, 0x77, 0x4f, 0xeb, 0x33, 0x4f, 0x9e, 0xd6, 0x67, 0x3e, 0x78, 0xaa,
0xd2, 0xeb, 0xa7, 0x00, 0x70, 0xf7, 0xf0, 0x97, 0xc4, 0x0a, 0x42, 0xee, 0xf2, 0x87, 0xa0, 0x28,
0x93, 0x6a, 0xfe, 0x20, 0x1f, 0x4d, 0xb9, 0x91, 0x32, 0x99, 0xe0, 0xe1, 0x94, 0x24, 0x6a, 0x42,
0x29, 0x7a, 0x1c, 0xaa, 0x12, 0xb0, 0xa2, 0xd4, 0x4a, 0xd1, 0x0b, 0x12, 0xc7, 0x32, 0xa9, 0xf8,
0x9f, 0xbb, 0x34, 0xfe, 0x0d, 0x98, 0xed, 0xdb, 0x1d, 0x79, 0x7e, 0x25, 0xe3, 0xdb, 0xe1, 0x1d,
0xbe, 0xb7, 0xd7, 0x3a, 0x1f, 0xd4, 0x5f, 0x99, 0x34, 0x56, 0xe1, 0x67, 0x3e, 0x61, 0x8d, 0x7b,
0x7b, 0x2d, 0x2c, 0x94, 0x2f, 0x8a, 0xa8, 0xc2, 0x94, 0x11, 0xb5, 0x05, 0xa0, 0x56, 0x2d, 0xb4,
0xe7, 0x83, 0x68, 0x0a, 0x1f, 0xca, 0xb7, 0x22, 0x0e, 0x4e, 0x48, 0x21, 0x06, 0x2b, 0x16, 0x25,
0xf2, 0xb7, 0x38, 0x7a, 0xc6, 0xcd, 0x9e, 0x5f, 0x2d, 0xca, 0x72, 0xf2, 0xcd, 0x6c, 0x29, 0x56,
0xa8, 0x19, 0x2f, 0x2b, 0x33, 0x2b, 0x3b, 0xa3, 0x60, 0x78, 0x1c, 0x1f, 0x79, 0xb0, 0xd2, 0x51,
0x8d, 0x7b, 0x6c, 0xb4, 0x34, 0xb5, 0xd1, 0x2b, 0xc2, 0x60, 0x6b, 0x14, 0x08, 0x8f, 0x63, 0xa3,
0x9f, 0xc3, 0x5a, 0x48, 0x1c, 0x7f, 0x3d, 0x55, 0x41, 0xee, 0x54, 0x4d, 0xbc, 0xe7, 0x5a, 0x13,
0xa5, 0xf0, 0x67, 0x20, 0xa0, 0x0e, 0x14, 0x9c, 0xa0, 0x40, 0x96, 0x65, 0x75, 0xfa, 0x41, 0xb6,
0x55, 0xc4, 0xd1, 0xdf, 0x48, 0x16, 0xc6, 0xe8, 0x05, 0xa1, 0x6a, 0xa2, 0xc2, 0x46, 0x8f, 0xa1,
0x6c, 0xba, 0xae, 0xc7, 0xcd, 0xe0, 0x3d, 0xb7, 0x20, 0x4d, 0x6d, 0x4f, 0x6d, 0x6a, 0x3b, 0xc6,
0x18, 0x29, 0xc4, 0x09, 0x0e, 0x4e, 0x9a, 0x42, 0x8f, 0x60, 0xc9, 0x7b, 0xe4, 0x12, 0x8a, 0xc9,
0x11, 0xa1, 0xc4, 0x15, 0x8f, 0xff, 0x8a, 0xb4, 0xfe, 0x9d, 0x8c, 0xd6, 0x53, 0xca, 0x71, 0x48,
0xa7, 0xe9, 0x0c, 0x8f, 0x5a, 0x41, 0x0d, 0x80, 0x23, 0xdb, 0x55, 0xed, 0x54, 0x75, 0x31, 0x9e,
0x76, 0xdc, 0x8c, 0xa8, 0x38, 0x21, 0x81, 0xbe, 0x0b, 0x65, 0xcb, 0xe9, 0x33, 0x4e, 0x82, 0xb1,
0xca, 0x92, 0xbc, 0x41, 0xd1, 0xfa, 0x76, 0x62, 0x16, 0x4e, 0xca, 0xa1, 0x63, 0x58, 0xb0, 0x13,
0x7d, 0x5b, 0x75, 0x59, 0xc6, 0xe2, 0xd6, 0xd4, 0xcd, 0x1a, 0x33, 0x96, 0x45, 0x26, 0x4a, 0x52,
0x70, 0x0a, 0x79, 0xed, 0x7b, 0x50, 0xfe, 0x9c, 0x6d, 0x84, 0x68, 0x43, 0x46, 0x8f, 0x6e, 0xaa,
0x36, 0xe4, 0xef, 0x39, 0x58, 0x4c, 0x6f, 0x78, 0xd4, 0xae, 0x6b, 0x13, 0xc7, 0x64, 0x61, 0x56,
0x9e, 0x9d, 0x98, 0x95, 0x55, 0xf2, 0x9b, 0x7b, 0x91, 0xe4, 0xb7, 0x05, 0x60, 0xfa, 0x76, 0x98,
0xf7, 0x82, 0x3c, 0x1a, 0x65, 0xae, 0x78, 0x10, 0x84, 0x13, 0x52, 0x72, 0x10, 0xe6, 0xb9, 0x9c,
0x7a, 0x8e, 0x43, 0xa8, 0xaa, 0x7c, 0xc1, 0x20, 0x2c, 0xa2, 0xe2, 0x84, 0x04, 0xba, 0x09, 0xe8,
0xd0, 0xf1, 0xac, 0x13, 0xb9, 0x05, 0xe1, 0x3d, 0x97, 0x59, 0xb2, 0x18, 0xcc, 0x55, 0x8c, 0x31,
0x2e, 0xbe, 0x40, 0x43, 0xbf, 0x0b, 0xe9, 0x49, 0x08, 0xba, 0x11, 0x6c, 0x80, 0x16, 0x8d, 0x2a,
0xa6, 0x5b, 0xbc, 0x7e, 0x15, 0x4a, 0xd8, 0xf3, 0x78, 0xdb, 0xe4, 0xc7, 0x0c, 0xd5, 0x21, 0xef,
0x8b, 0x1f, 0x6a, 0xcc, 0x25, 0x27, 0x8d, 0x92, 0x83, 0x03, 0xba, 0xfe, 0x7b, 0x0d, 0x5e, 0x9e,
0x38, 0x75, 0x12, 0x1b, 0x69, 0x45, 0x5f, 0xca, 0xa5, 0x68, 0x23, 0x63, 0x39, 0x9c, 0x90, 0x12,
0xdd, 0x52, 0x6a, 0x54, 0x35, 0xda, 0x2d, 0xa5, 0xac, 0xe1, 0xb4, 0xac, 0xfe, 0x9f, 0x1c, 0x14,
0x82, 0x07, 0x05, 0x7a, 0x08, 0x45, 0x71, 0x25, 0x3a, 0x26, 0x37, 0xa5, 0xe5, 0xcc, 0x33, 0xe3,
0xb0, 0xeb, 0x8c, 0x6b, 0x6c, 0x48, 0xc1, 0x11, 0x22, 0x7a, 0x0d, 0x0a, 0x4c, 0xda, 0x51, 0xee,
0x45, 0x49, 0x32, 0xb0, 0x8e, 0x15, 0x57, 0xf4, 0x2e, 0x3d, 0xc2, 0x98, 0xd9, 0x0d, 0x63, 0x36,
0xea, 0x5d, 0xf6, 0x03, 0x32, 0x0e, 0xf9, 0xe8, 0x2d, 0xf1, 0x7e, 0x32, 0x59, 0xd4, 0xbb, 0xd5,
0x42, 0x48, 0x2c, 0xa9, 0xe7, 0x83, 0xfa, 0x82, 0x02, 0x97, 0xdf, 0x58, 0x49, 0xa3, 0x07, 0x30,
0xdf, 0x21, 0xdc, 0xb4, 0x9d, 0xa0, 0x65, 0xcb, 0x3c, 0x53, 0x0b, 0xc0, 0x5a, 0x81, 0xaa, 0x51,
0x16, 0x3e, 0xa9, 0x0f, 0x1c, 0x02, 0x8a, 0xfb, 0x66, 0x79, 0x9d, 0x60, 0x20, 0x9c, 0x8f, 0xef,
0xdb, 0x8e, 0xd7, 0x21, 0x58, 0x72, 0xf4, 0x27, 0x1a, 0x94, 0x03, 0xa4, 0x1d, 0xb3, 0xcf, 0x08,
0xda, 0x8c, 0x56, 0x11, 0x1c, 0x77, 0x58, 0x8a, 0xe7, 0xde, 0x39, 0xf3, 0xc9, 0xf9, 0xa0, 0x5e,
0x92, 0x62, 0xe2, 0x23, 0x5a, 0x40, 0x62, 0x8f, 0x72, 0x97, 0xec, 0xd1, 0xab, 0x90, 0x97, 0xed,
0xb1, 0xda, 0xcc, 0xa8, 0xbf, 0x93, 0x2d, 0x34, 0x0e, 0x78, 0xfa, 0xc7, 0x39, 0xa8, 0xa4, 0x16,
0x97, 0xa1, 0x99, 0x8b, 0x1e, 0xf9, 0xb9, 0x0c, 0x83, 0xa3, 0xc9, 0x63, 0xfc, 0x9f, 0x42, 0xc1,
0x12, 0xeb, 0x0b, 0xff, 0x8f, 0xb2, 0x39, 0xcd, 0x51, 0xc8, 0x9d, 0x89, 0x23, 0x49, 0x7e, 0x32,
0xac, 0x00, 0xd1, 0x2d, 0x58, 0xa1, 0x84, 0xd3, 0xb3, 0xed, 0x23, 0x4e, 0x68, 0xb2, 0x47, 0xcf,
0xc7, 0xed, 0x0e, 0x1e, 0x15, 0xc0, 0xe3, 0x3a, 0x61, 0x86, 0x2c, 0xbc, 0x40, 0x86, 0xd4, 0x1d,
0x98, 0xfb, 0x3f, 0xb6, 0xe6, 0x3f, 0x83, 0x52, 0xdc, 0x3c, 0x7d, 0xc1, 0x26, 0xf5, 0x5f, 0x40,
0x51, 0x44, 0x63, 0xd8, 0xf4, 0x5f, 0x52, 0x80, 0xd2, 0xa5, 0x21, 0x97, 0xa5, 0x34, 0xe8, 0x5b,
0x10, 0xfc, 0x77, 0x46, 0x64, 0x53, 0x9b, 0x93, 0x5e, 0x2a, 0x9b, 0xee, 0x09, 0x02, 0x0e, 0xe8,
0x89, 0x61, 0xcf, 0x6f, 0x35, 0x00, 0xf9, 0xc4, 0xdb, 0x3d, 0x15, 0xcf, 0xf2, 0x75, 0x98, 0x13,
0x27, 0x30, 0xea, 0x98, 0xbc, 0x46, 0x92, 0x83, 0xee, 0x41, 0xc1, 0x93, 0x4d, 0x95, 0x9a, 0xbe,
0xbc, 0x31, 0x31, 0xf2, 0xd4, 0x3f, 0x5e, 0x1b, 0xd8, 0x7c, 0xb4, 0xfb, 0x98, 0x13, 0x57, 0xf8,
0x18, 0x47, 0x5d, 0xd0, 0x99, 0x61, 0x05, 0x66, 0x6c, 0x3c, 0x7b, 0x5e, 0x9b, 0xf9, 0xf0, 0x79,
0x6d, 0xe6, 0xa3, 0xe7, 0xb5, 0x99, 0xf7, 0x87, 0x35, 0xed, 0xd9, 0xb0, 0xa6, 0x7d, 0x38, 0xac,
0x69, 0x1f, 0x0d, 0x6b, 0xda, 0xc7, 0xc3, 0x9a, 0xf6, 0xe4, 0x93, 0xda, 0xcc, 0x83, 0xdc, 0xe9,
0xe6, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x80, 0x43, 0x11, 0x41, 0xbe, 0x1e, 0x00, 0x00,
// 2428 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x59, 0x4d, 0x6c, 0x23, 0x49,
0x15, 0x4e, 0xdb, 0xb1, 0x63, 0x3f, 0xc7, 0xf9, 0xa9, 0xcd, 0x80, 0x37, 0x02, 0x3b, 0xdb, 0x8b,
0x56, 0x59, 0x98, 0xb5, 0x49, 0x16, 0x56, 0xc3, 0x00, 0x03, 0xe9, 0x38, 0x33, 0x8a, 0x76, 0x32,
0x63, 0x55, 0x76, 0x06, 0x31, 0x8c, 0x10, 0x9d, 0x76, 0xc5, 0x69, 0xd2, 0xee, 0xf6, 0x56, 0x95,
0x33, 0x09, 0x1c, 0xd8, 0x03, 0x48, 0x1c, 0x10, 0x9a, 0x23, 0x27, 0xb4, 0x23, 0xb8, 0x70, 0xe5,
0xc4, 0x05, 0x4e, 0x48, 0xcc, 0x71, 0x24, 0x2e, 0x7b, 0x40, 0xd6, 0x8e, 0xf7, 0xc0, 0x09, 0x71,
0xcf, 0x09, 0x55, 0x75, 0xf5, 0x9f, 0x1d, 0x4f, 0xda, 0x3b, 0x0b, 0xe2, 0x14, 0xf7, 0xfb, 0xf9,
0xde, 0xab, 0xaa, 0xf7, 0x5e, 0xbd, 0x7a, 0x81, 0xbd, 0xe3, 0x6b, 0xac, 0x6e, 0x7b, 0x8d, 0xe3,
0xfe, 0x01, 0xa1, 0x2e, 0xe1, 0x84, 0x35, 0x4e, 0x88, 0xdb, 0xf6, 0x68, 0x43, 0x31, 0xcc, 0x9e,
0xdd, 0x35, 0xad, 0x23, 0xdb, 0x25, 0xf4, 0xac, 0xd1, 0x3b, 0xee, 0x08, 0x02, 0x6b, 0x74, 0x09,
0x37, 0x1b, 0x27, 0x1b, 0x8d, 0x0e, 0x71, 0x09, 0x35, 0x39, 0x69, 0xd7, 0x7b, 0xd4, 0xe3, 0x1e,
0xfa, 0x92, 0xaf, 0x55, 0x8f, 0x6b, 0xd5, 0x7b, 0xc7, 0x1d, 0x41, 0x60, 0x75, 0xa1, 0x55, 0x3f,
0xd9, 0x58, 0x7d, 0xab, 0x63, 0xf3, 0xa3, 0xfe, 0x41, 0xdd, 0xf2, 0xba, 0x8d, 0x8e, 0xd7, 0xf1,
0x1a, 0x52, 0xf9, 0xa0, 0x7f, 0x28, 0xbf, 0xe4, 0x87, 0xfc, 0xe5, 0x83, 0xae, 0x4e, 0x74, 0x85,
0xf6, 0x5d, 0x6e, 0x77, 0xc9, 0xa8, 0x17, 0xab, 0xef, 0x5c, 0xa6, 0xc0, 0xac, 0x23, 0xd2, 0x35,
0xc7, 0xf4, 0xde, 0x9e, 0xa4, 0xd7, 0xe7, 0xb6, 0xd3, 0xb0, 0x5d, 0xce, 0x38, 0x1d, 0x55, 0xd2,
0xff, 0x96, 0x85, 0xc2, 0x56, 0x6b, 0xf7, 0x16, 0xf5, 0xfa, 0x3d, 0xb4, 0x06, 0xb3, 0xae, 0xd9,
0x25, 0x15, 0x6d, 0x4d, 0x5b, 0x2f, 0x1a, 0xf3, 0x4f, 0x07, 0xb5, 0x99, 0xe1, 0xa0, 0x36, 0x7b,
0xc7, 0xec, 0x12, 0x2c, 0x39, 0xc8, 0x81, 0xc2, 0x09, 0xa1, 0xcc, 0xf6, 0x5c, 0x56, 0xc9, 0xac,
0x65, 0xd7, 0x4b, 0x9b, 0x37, 0xea, 0x69, 0x36, 0xad, 0x2e, 0x0d, 0xdc, 0xf7, 0x55, 0x6f, 0x7a,
0xb4, 0x69, 0x33, 0xcb, 0x3b, 0x21, 0xf4, 0xcc, 0x58, 0x52, 0x56, 0x0a, 0x8a, 0xc9, 0x70, 0x68,
0x01, 0xfd, 0x5c, 0x83, 0xa5, 0x1e, 0x25, 0x87, 0x84, 0x52, 0xd2, 0x56, 0xfc, 0x4a, 0x76, 0x4d,
0xfb, 0x0c, 0xcc, 0x56, 0x94, 0xd9, 0xa5, 0xd6, 0x08, 0x3e, 0x1e, 0xb3, 0x88, 0x7e, 0xa7, 0xc1,
0x2a, 0x23, 0xf4, 0x84, 0xd0, 0xad, 0x76, 0x9b, 0x12, 0xc6, 0x8c, 0xb3, 0x6d, 0xc7, 0x26, 0x2e,
0xdf, 0xde, 0x6d, 0x62, 0x56, 0x99, 0x95, 0xfb, 0xf0, 0x9d, 0x74, 0x0e, 0xed, 0x4f, 0xc2, 0x31,
0x74, 0xe5, 0xd1, 0xea, 0x44, 0x11, 0x86, 0x5f, 0xe0, 0x86, 0x7e, 0x08, 0xf3, 0xc1, 0x41, 0xde,
0xb6, 0x19, 0x47, 0xf7, 0x21, 0xdf, 0x11, 0x1f, 0xac, 0xa2, 0x49, 0x07, 0xeb, 0xe9, 0x1c, 0x0c,
0x30, 0x8c, 0x05, 0xe5, 0x4f, 0x5e, 0x7e, 0x32, 0xac, 0xd0, 0xf4, 0x3f, 0x67, 0xa1, 0xb4, 0xd5,
0xda, 0xc5, 0x84, 0x79, 0x7d, 0x6a, 0x91, 0x14, 0x41, 0xb3, 0x09, 0x20, 0xfe, 0xb2, 0x9e, 0x69,
0x91, 0x76, 0x25, 0xb3, 0xa6, 0xad, 0x17, 0x0c, 0xa4, 0xe4, 0xe0, 0x4e, 0xc8, 0xc1, 0x31, 0x29,
0x81, 0x7a, 0x6c, 0xbb, 0x6d, 0x79, 0xda, 0x31, 0xd4, 0x77, 0x6d, 0xb7, 0x8d, 0x25, 0x07, 0xdd,
0x86, 0xdc, 0x09, 0xa1, 0x07, 0x62, 0xff, 0x45, 0x40, 0x7c, 0x25, 0xdd, 0xf2, 0xee, 0x0b, 0x15,
0xa3, 0x38, 0x1c, 0xd4, 0x72, 0xf2, 0x27, 0xf6, 0x41, 0x50, 0x1d, 0x80, 0x1d, 0x79, 0x94, 0x4b,
0x77, 0x2a, 0xb9, 0xb5, 0xec, 0x7a, 0xd1, 0x58, 0x10, 0xfe, 0xed, 0x87, 0x54, 0x1c, 0x93, 0x40,
0xd7, 0x60, 0x9e, 0xd9, 0x6e, 0xa7, 0xef, 0x98, 0x54, 0x10, 0x2a, 0x79, 0xe9, 0xe7, 0x8a, 0xf2,
0x73, 0x7e, 0x3f, 0xc6, 0xc3, 0x09, 0x49, 0x61, 0xc9, 0x32, 0x39, 0xe9, 0x78, 0xd4, 0x26, 0xac,
0x32, 0x17, 0x59, 0xda, 0x0e, 0xa9, 0x38, 0x26, 0x81, 0x5e, 0x87, 0x9c, 0xdc, 0xf9, 0x4a, 0x41,
0x9a, 0x28, 0x2b, 0x13, 0x39, 0x79, 0x2c, 0xd8, 0xe7, 0xa1, 0x37, 0x61, 0x4e, 0x65, 0x4d, 0xa5,
0x28, 0xc5, 0x16, 0x95, 0xd8, 0x5c, 0x10, 0xd6, 0x01, 0x5f, 0xff, 0xa3, 0x06, 0x8b, 0xb1, 0xf3,
0x93, 0xb1, 0x72, 0x0d, 0xe6, 0x3b, 0xb1, 0x4c, 0x51, 0x67, 0x19, 0xae, 0x26, 0x9e, 0x45, 0x38,
0x21, 0x89, 0x08, 0x14, 0xa9, 0x42, 0x0a, 0x2a, 0xc2, 0x46, 0xea, 0x40, 0x0b, 0x7c, 0x88, 0x2c,
0xc5, 0x88, 0x0c, 0x47, 0xc8, 0xfa, 0x3f, 0x35, 0x19, 0x74, 0x41, 0x8d, 0x40, 0xeb, 0xb1, 0x3a,
0xa4, 0xc9, 0x2d, 0x9c, 0x9f, 0x50, 0x43, 0x2e, 0x49, 0xde, 0xcc, 0xff, 0x45, 0xf2, 0x5e, 0x2f,
0xfc, 0xe6, 0xc3, 0xda, 0xcc, 0x07, 0xff, 0x58, 0x9b, 0xd1, 0x3f, 0xc9, 0x40, 0xb9, 0x49, 0x1c,
0xc2, 0xc9, 0xdd, 0x1e, 0x97, 0x2b, 0xb8, 0x09, 0xa8, 0x43, 0x4d, 0x8b, 0xb4, 0x08, 0xb5, 0xbd,
0xf6, 0x3e, 0xb1, 0x3c, 0xb7, 0xcd, 0xe4, 0x11, 0x65, 0x8d, 0xcf, 0x0d, 0x07, 0x35, 0x74, 0x6b,
0x8c, 0x8b, 0x2f, 0xd0, 0x40, 0x0e, 0x94, 0x7b, 0x54, 0xfe, 0xb6, 0xb9, 0x2a, 0xe0, 0x22, 0x71,
0xde, 0x4e, 0xb7, 0xf6, 0x56, 0x5c, 0xd5, 0x58, 0x1e, 0x0e, 0x6a, 0xe5, 0x04, 0x09, 0x27, 0xc1,
0xd1, 0x77, 0x61, 0xc9, 0xa3, 0xbd, 0x23, 0xd3, 0x6d, 0x92, 0x1e, 0x71, 0xdb, 0xc4, 0xe5, 0x4c,
0x26, 0x73, 0xc1, 0x58, 0x11, 0x65, 0xf7, 0xee, 0x08, 0x0f, 0x8f, 0x49, 0xa3, 0x07, 0xb0, 0xdc,
0xa3, 0x5e, 0xcf, 0xec, 0x98, 0x02, 0xb1, 0xe5, 0x39, 0xb6, 0x75, 0x26, 0x93, 0xbd, 0x68, 0x5c,
0x1d, 0x0e, 0x6a, 0xcb, 0xad, 0x51, 0xe6, 0xf9, 0xa0, 0xf6, 0x8a, 0xdc, 0x3a, 0x41, 0x89, 0x98,
0x78, 0x1c, 0x46, 0xdf, 0x85, 0x42, 0xb3, 0x4f, 0x25, 0x05, 0x7d, 0x1b, 0x0a, 0x6d, 0xf5, 0x5b,
0xed, 0xea, 0x6b, 0xc1, 0x9d, 0x14, 0xc8, 0x9c, 0x0f, 0x6a, 0x65, 0x71, 0xf5, 0xd6, 0x03, 0x02,
0x0e, 0x55, 0xf4, 0x87, 0x50, 0xde, 0x39, 0xed, 0x79, 0x94, 0x07, 0xe7, 0xf5, 0x06, 0xe4, 0x89,
0x24, 0x48, 0xb4, 0x42, 0x54, 0x48, 0x7d, 0x31, 0xac, 0xb8, 0x22, 0xb1, 0xc9, 0xa9, 0x69, 0x71,
0x55, 0x11, 0xc3, 0xc4, 0xde, 0x11, 0x44, 0xec, 0xf3, 0xf4, 0x27, 0x1a, 0xc0, 0x2d, 0x12, 0x62,
0x6f, 0xc1, 0x62, 0x90, 0x14, 0xc9, 0x5c, 0xfd, 0xbc, 0xd2, 0x5e, 0xc4, 0x49, 0x36, 0x1e, 0x95,
0x47, 0x2d, 0x58, 0xb1, 0x5d, 0xcb, 0xe9, 0xb7, 0xc9, 0x3d, 0xd7, 0x76, 0x6d, 0x6e, 0x9b, 0x8e,
0xfd, 0x93, 0xb0, 0x2e, 0x7f, 0x41, 0xe1, 0xac, 0xec, 0x5e, 0x20, 0x83, 0x2f, 0xd4, 0xd4, 0x1f,
0x42, 0x51, 0x56, 0x08, 0x51, 0x9c, 0xa3, 0x72, 0xa5, 0xbd, 0xa0, 0x5c, 0x05, 0xd5, 0x3d, 0x33,
0xa9, 0xba, 0xc7, 0x12, 0xc2, 0x81, 0xb2, 0xaf, 0x1b, 0x5c, 0x38, 0xa9, 0x2c, 0x5c, 0x85, 0x42,
0xb0, 0x70, 0x65, 0x25, 0x6c, 0x34, 0x02, 0x20, 0x1c, 0x4a, 0xc4, 0xac, 0x1d, 0x41, 0xa2, 0xda,
0xa5, 0x33, 0x16, 0xab, 0xbe, 0x99, 0x17, 0x57, 0xdf, 0x98, 0xa5, 0x9f, 0x41, 0x65, 0x52, 0x77,
0xf2, 0x12, 0xf5, 0x38, 0xbd, 0x2b, 0xfa, 0xaf, 0x35, 0x58, 0x8a, 0x23, 0xa5, 0x3f, 0xbe, 0xf4,
0x46, 0x2e, 0xbf, 0xc7, 0x63, 0x3b, 0xf2, 0x5b, 0x0d, 0x56, 0x12, 0x4b, 0x9b, 0xea, 0xc4, 0xa7,
0x70, 0x2a, 0x1e, 0x1c, 0xd9, 0x29, 0x82, 0xa3, 0x01, 0xa5, 0xdd, 0x30, 0xee, 0xe9, 0xe5, 0x9d,
0x8f, 0xfe, 0x17, 0x0d, 0xe6, 0x63, 0x1a, 0x0c, 0x3d, 0x84, 0x39, 0x51, 0xdf, 0x6c, 0xb7, 0xa3,
0xba, 0xb2, 0x94, 0x97, 0x65, 0x0c, 0x24, 0x5a, 0x57, 0xcb, 0x47, 0xc2, 0x01, 0x24, 0x6a, 0x41,
0x9e, 0x12, 0xd6, 0x77, 0xb8, 0x2a, 0xed, 0x57, 0x53, 0x5e, 0x6b, 0xdc, 0xe4, 0x7d, 0x66, 0x80,
0xa8, 0x51, 0x58, 0xea, 0x63, 0x85, 0xa3, 0xff, 0x3d, 0x03, 0xe5, 0xdb, 0xe6, 0x01, 0x71, 0xf6,
0x89, 0x43, 0x2c, 0xee, 0x51, 0xf4, 0x53, 0x28, 0x75, 0x4d, 0x6e, 0x1d, 0x49, 0x6a, 0xd0, 0x5b,
0x36, 0xd3, 0x19, 0x4a, 0x20, 0xd5, 0xf7, 0x22, 0x98, 0x1d, 0x97, 0xd3, 0x33, 0xe3, 0x15, 0xb5,
0xb0, 0x52, 0x8c, 0x83, 0xe3, 0xd6, 0xe4, 0x83, 0x40, 0x7e, 0xef, 0x9c, 0xf6, 0xc4, 0x25, 0x3a,
0xfd, 0x3b, 0x24, 0xe1, 0x02, 0x26, 0xef, 0xf7, 0x6d, 0x4a, 0xba, 0xc4, 0xe5, 0xd1, 0x83, 0x60,
0x6f, 0x04, 0x1f, 0x8f, 0x59, 0x5c, 0xbd, 0x01, 0x4b, 0xa3, 0xce, 0xa3, 0x25, 0xc8, 0x1e, 0x93,
0x33, 0x3f, 0x16, 0xb0, 0xf8, 0x89, 0x56, 0x20, 0x77, 0x62, 0x3a, 0x7d, 0x55, 0x7f, 0xb0, 0xff,
0x71, 0x3d, 0x73, 0x4d, 0xd3, 0x7f, 0xaf, 0x41, 0x65, 0x92, 0x23, 0xe8, 0x8b, 0x31, 0x20, 0xa3,
0xa4, 0xbc, 0xca, 0xbe, 0x4b, 0xce, 0x7c, 0xd4, 0x1d, 0x28, 0x78, 0x3d, 0xf1, 0x84, 0xf3, 0xa8,
0x8a, 0xf3, 0x37, 0x83, 0xd8, 0xbd, 0xab, 0xe8, 0xe7, 0x83, 0xda, 0x95, 0x04, 0x7c, 0xc0, 0xc0,
0xa1, 0x2a, 0xd2, 0x21, 0x2f, 0xfd, 0x11, 0x97, 0xb2, 0x68, 0x9f, 0xe4, 0xe1, 0xdf, 0x97, 0x14,
0xac, 0x38, 0xfa, 0x9f, 0x34, 0x98, 0x95, 0xed, 0xe1, 0x43, 0x28, 0x88, 0xfd, 0x6b, 0x9b, 0xdc,
0x94, 0x7e, 0xa5, 0x7e, 0x4c, 0x08, 0xed, 0x3d, 0xc2, 0xcd, 0x28, 0xbf, 0x02, 0x0a, 0x0e, 0x11,
0x11, 0x86, 0x9c, 0xcd, 0x49, 0x37, 0x38, 0xc8, 0xb7, 0x26, 0x42, 0xab, 0xf7, 0x6f, 0x1d, 0x9b,
0x8f, 0x76, 0x4e, 0x39, 0x71, 0xc5, 0x61, 0x44, 0xc5, 0x60, 0x57, 0x60, 0x60, 0x1f, 0x4a, 0xff,
0x83, 0x06, 0xa1, 0x29, 0x91, 0xee, 0x8c, 0x38, 0x87, 0xb7, 0x6d, 0xf7, 0x58, 0x6d, 0x6b, 0xe8,
0xce, 0xbe, 0xa2, 0xe3, 0x50, 0xe2, 0xa2, 0x2b, 0x36, 0x33, 0xe5, 0x15, 0x7b, 0x15, 0x0a, 0x96,
0xe7, 0x72, 0xdb, 0xed, 0x8f, 0xd5, 0x97, 0x6d, 0x45, 0xc7, 0xa1, 0x84, 0xfe, 0x2c, 0x0b, 0x25,
0xe1, 0x6b, 0x70, 0xc7, 0x7f, 0x13, 0xca, 0x4e, 0xfc, 0xf4, 0x94, 0xcf, 0x57, 0x14, 0x44, 0x32,
0x1f, 0x71, 0x52, 0x56, 0x28, 0x1f, 0xda, 0xc4, 0x69, 0x87, 0xca, 0x99, 0xa4, 0xf2, 0xcd, 0x38,
0x13, 0x27, 0x65, 0x45, 0x9d, 0x7d, 0x24, 0xe2, 0x5a, 0x35, 0x6a, 0xe1, 0xd6, 0x7e, 0x4f, 0x10,
0xb1, 0xcf, 0xbb, 0x68, 0x7f, 0x66, 0xa7, 0xdc, 0x9f, 0xeb, 0xb0, 0x20, 0x0e, 0xd2, 0xeb, 0xf3,
0xa0, 0x9b, 0xcd, 0xc9, 0xbe, 0x0b, 0x0d, 0x07, 0xb5, 0x85, 0xf7, 0x12, 0x1c, 0x3c, 0x22, 0x39,
0xb1, 0x7d, 0xc9, 0x7f, 0xda, 0xf6, 0x45, 0xac, 0xda, 0xb1, 0xbb, 0x36, 0xaf, 0xcc, 0x49, 0x27,
0xc2, 0x55, 0xdf, 0x16, 0x44, 0xec, 0xf3, 0x12, 0x47, 0x5a, 0xb8, 0xf4, 0x48, 0xdf, 0x87, 0xe2,
0x9e, 0x6d, 0x51, 0x4f, 0xac, 0x45, 0x5c, 0x4c, 0x2c, 0xd1, 0xb4, 0x87, 0x05, 0x3c, 0x58, 0x63,
0xc0, 0x17, 0xae, 0xb8, 0xa6, 0xeb, 0xf9, 0xad, 0x79, 0x2e, 0x72, 0xe5, 0x8e, 0x20, 0x62, 0x9f,
0x77, 0x7d, 0x45, 0xdc, 0x47, 0xbf, 0x7c, 0x52, 0x9b, 0x79, 0xfc, 0xa4, 0x36, 0xf3, 0xe1, 0x13,
0x75, 0x37, 0xfd, 0x0b, 0x00, 0xee, 0x1e, 0xfc, 0x98, 0x58, 0x7e, 0xcc, 0x5f, 0xfe, 0x2a, 0x17,
0x3d, 0x86, 0x1a, 0x06, 0xc9, 0x17, 0x6c, 0x66, 0xa4, 0xc7, 0x88, 0xf1, 0x70, 0x42, 0x12, 0x35,
0xa0, 0x18, 0xbe, 0xd4, 0x55, 0x7c, 0x2f, 0x2b, 0xb5, 0x62, 0xf8, 0x9c, 0xc7, 0x91, 0x4c, 0x22,
0x01, 0x67, 0x2f, 0x4d, 0x40, 0x03, 0xb2, 0x7d, 0xbb, 0x2d, 0x43, 0xa2, 0x68, 0x7c, 0x35, 0x28,
0x80, 0xf7, 0x76, 0x9b, 0xe7, 0x83, 0xda, 0x6b, 0x93, 0x66, 0x5c, 0xfc, 0xac, 0x47, 0x58, 0xfd,
0xde, 0x6e, 0x13, 0x0b, 0xe5, 0x8b, 0x82, 0x34, 0x3f, 0x65, 0x90, 0x6e, 0x02, 0xa8, 0x55, 0x0b,
0x6d, 0x3f, 0x36, 0xc2, 0xa9, 0xc5, 0xad, 0x90, 0x83, 0x63, 0x52, 0x88, 0xc1, 0xb2, 0x45, 0x89,
0xfc, 0x2d, 0x8e, 0x9e, 0x71, 0xb3, 0xeb, 0xbf, 0xdb, 0x4b, 0x9b, 0x5f, 0x4e, 0x57, 0x31, 0x85,
0x9a, 0xf1, 0xaa, 0x32, 0xb3, 0xbc, 0x3d, 0x0a, 0x86, 0xc7, 0xf1, 0x91, 0x07, 0xcb, 0x6d, 0xf5,
0xea, 0x89, 0x8c, 0x16, 0xa7, 0x36, 0x7a, 0x45, 0x18, 0x6c, 0x8e, 0x02, 0xe1, 0x71, 0x6c, 0xf4,
0x43, 0x58, 0x0d, 0x88, 0xe3, 0x4f, 0xcf, 0x0a, 0xc8, 0x9d, 0xaa, 0x8a, 0xc7, 0x70, 0x73, 0xa2,
0x14, 0x7e, 0x01, 0x02, 0x6a, 0x43, 0xde, 0xf1, 0xbb, 0x8b, 0x92, 0xbc, 0x11, 0xbe, 0x95, 0x6e,
0x15, 0x51, 0xf4, 0xd7, 0xe3, 0x5d, 0x45, 0xf8, 0xfc, 0x52, 0x0d, 0x85, 0xc2, 0x46, 0xa7, 0x50,
0x32, 0x5d, 0xd7, 0xe3, 0xa6, 0xff, 0x18, 0x9e, 0x97, 0xa6, 0xb6, 0xa6, 0x36, 0xb5, 0x15, 0x61,
0x8c, 0x74, 0x31, 0x31, 0x0e, 0x8e, 0x9b, 0x42, 0x8f, 0x60, 0xd1, 0x7b, 0xe4, 0x12, 0x8a, 0xc9,
0x21, 0xa1, 0xc4, 0xb5, 0x08, 0xab, 0x94, 0xa5, 0xf5, 0xaf, 0xa5, 0xb4, 0x9e, 0x50, 0x8e, 0x42,
0x3a, 0x49, 0x67, 0x78, 0xd4, 0x0a, 0xaa, 0x03, 0x1c, 0xda, 0xae, 0xea, 0x45, 0x2b, 0x0b, 0xd1,
0xe8, 0xe9, 0x66, 0x48, 0xc5, 0x31, 0x09, 0xf4, 0x75, 0x28, 0x59, 0x4e, 0x9f, 0x71, 0xe2, 0xcf,
0xb8, 0x16, 0x65, 0x06, 0x85, 0xeb, 0xdb, 0x8e, 0x58, 0x38, 0x2e, 0x87, 0x8e, 0x60, 0xde, 0x8e,
0x35, 0xbd, 0x95, 0x25, 0x19, 0x8b, 0x9b, 0x53, 0x77, 0xba, 0xcc, 0x58, 0x12, 0x95, 0x28, 0x4e,
0xc1, 0x09, 0xe4, 0xd5, 0x6f, 0x40, 0xe9, 0x53, 0xf6, 0x60, 0xa2, 0x87, 0x1b, 0x3d, 0xba, 0xa9,
0x7a, 0xb8, 0xbf, 0x66, 0x60, 0x21, 0xb9, 0xe1, 0xe1, 0x5b, 0x47, 0x9b, 0x38, 0xb3, 0x0c, 0xaa,
0x72, 0x76, 0x62, 0x55, 0x56, 0xc5, 0x6f, 0xf6, 0x65, 0x8a, 0xdf, 0x26, 0x80, 0xd9, 0xb3, 0x83,
0xba, 0xe7, 0xd7, 0xd1, 0xb0, 0x72, 0x45, 0x53, 0x34, 0x1c, 0x93, 0x92, 0x53, 0x49, 0xcf, 0xe5,
0xd4, 0x73, 0x1c, 0x42, 0xd5, 0x65, 0xea, 0x4f, 0x25, 0x43, 0x2a, 0x8e, 0x49, 0xa0, 0x9b, 0x80,
0x0e, 0x1c, 0xcf, 0x3a, 0x96, 0x5b, 0x10, 0xe4, 0xb9, 0xac, 0x92, 0x05, 0x7f, 0x28, 0x65, 0x8c,
0x71, 0xf1, 0x05, 0x1a, 0xfa, 0x5d, 0x48, 0x8e, 0x91, 0xd0, 0x0d, 0x7f, 0x03, 0xb4, 0x70, 0xce,
0x33, 0xdd, 0xe2, 0xf5, 0xab, 0x50, 0xc4, 0x9e, 0xc7, 0x5b, 0x26, 0x3f, 0x62, 0xa8, 0x06, 0xb9,
0x9e, 0xf8, 0xa1, 0x66, 0x84, 0x72, 0xec, 0x2b, 0x39, 0xd8, 0xa7, 0xeb, 0xbf, 0xd2, 0xe0, 0xd5,
0x89, 0x23, 0x3b, 0xb1, 0x91, 0x56, 0xf8, 0xa5, 0x5c, 0x0a, 0x37, 0x32, 0x92, 0xc3, 0x31, 0x29,
0xd1, 0x80, 0x25, 0xe6, 0x7c, 0xa3, 0x0d, 0x58, 0xc2, 0x1a, 0x4e, 0xca, 0xea, 0xff, 0xce, 0x40,
0xde, 0x7f, 0x8d, 0xfd, 0x97, 0x7b, 0xee, 0x37, 0x20, 0xcf, 0xa4, 0x1d, 0xe5, 0x5e, 0x58, 0x24,
0x7d, 0xeb, 0x58, 0x71, 0x45, 0xef, 0xd2, 0x25, 0x8c, 0x99, 0x9d, 0x20, 0x66, 0xc3, 0xde, 0x65,
0xcf, 0x27, 0xe3, 0x80, 0x8f, 0xde, 0x11, 0x8f, 0x4f, 0x93, 0x85, 0xed, 0x60, 0x35, 0x80, 0xc4,
0x92, 0x7a, 0x3e, 0xa8, 0xcd, 0x2b, 0x70, 0xf9, 0x8d, 0x95, 0x34, 0x7a, 0x00, 0x73, 0x6d, 0xc2,
0x4d, 0xdb, 0xf1, 0xbb, 0xc0, 0xd4, 0x03, 0x49, 0x1f, 0xac, 0xe9, 0xab, 0x1a, 0x25, 0xe1, 0x93,
0xfa, 0xc0, 0x01, 0xa0, 0xc8, 0x37, 0xcb, 0x6b, 0xfb, 0xd3, 0xf9, 0x5c, 0x94, 0x6f, 0xdb, 0x5e,
0x9b, 0x60, 0xc9, 0xd1, 0x1f, 0x6b, 0x50, 0xf2, 0x91, 0xb6, 0xcd, 0x3e, 0x23, 0x68, 0x23, 0x5c,
0x85, 0x7f, 0xdc, 0xc1, 0x55, 0x3c, 0xfb, 0xde, 0x59, 0x8f, 0x9c, 0x0f, 0x6a, 0x45, 0x29, 0x26,
0x3e, 0xc2, 0x05, 0xc4, 0xf6, 0x28, 0x73, 0xc9, 0x1e, 0xbd, 0x0e, 0x39, 0xd9, 0x71, 0xab, 0xcd,
0x0c, 0xfb, 0x3b, 0xd9, 0x95, 0x63, 0x9f, 0xa7, 0x7f, 0x9c, 0x81, 0x72, 0x62, 0x71, 0x29, 0x9a,
0xb9, 0x70, 0x42, 0x92, 0x49, 0x31, 0x75, 0x9b, 0xfc, 0x3f, 0x95, 0xef, 0x43, 0xde, 0x12, 0xeb,
0x0b, 0xfe, 0xa9, 0xb5, 0x31, 0xcd, 0x51, 0xc8, 0x9d, 0x89, 0x22, 0x49, 0x7e, 0x32, 0xac, 0x00,
0xd1, 0x2d, 0x58, 0xa6, 0x84, 0xd3, 0xb3, 0xad, 0x43, 0x4e, 0x68, 0xbc, 0xed, 0xcf, 0x45, 0xed,
0x0e, 0x1e, 0x15, 0xc0, 0xe3, 0x3a, 0x41, 0x85, 0xcc, 0xbf, 0x44, 0x85, 0xd4, 0x1d, 0x98, 0xfd,
0x1f, 0xb6, 0xe6, 0x3f, 0x80, 0x62, 0xd4, 0x3c, 0x7d, 0xc6, 0x26, 0xf5, 0x1f, 0x41, 0x41, 0x44,
0x63, 0xd0, 0xf4, 0x5f, 0x72, 0x01, 0x25, 0xaf, 0x86, 0x4c, 0x9a, 0xab, 0x41, 0xdf, 0x04, 0xff,
0x5f, 0x65, 0xa2, 0x9a, 0xfa, 0x0f, 0xf5, 0x58, 0x35, 0x8d, 0xbf, 0xba, 0x63, 0x93, 0xb2, 0x5f,
0x68, 0x00, 0xf2, 0xd5, 0xb8, 0x73, 0x42, 0x5c, 0x2e, 0x1c, 0x13, 0x27, 0x30, 0xea, 0x98, 0x4c,
0x23, 0xc9, 0x41, 0xf7, 0x20, 0xef, 0xc9, 0xa6, 0x4a, 0x8d, 0xae, 0xa6, 0x9c, 0x02, 0x84, 0x51,
0xe7, 0x77, 0x66, 0x58, 0x81, 0x19, 0xeb, 0x4f, 0x9f, 0x57, 0x67, 0x9e, 0x3d, 0xaf, 0xce, 0x7c,
0xf4, 0xbc, 0x3a, 0xf3, 0xc1, 0xb0, 0xaa, 0x3d, 0x1d, 0x56, 0xb5, 0x67, 0xc3, 0xaa, 0xf6, 0xd1,
0xb0, 0xaa, 0x7d, 0x3c, 0xac, 0x6a, 0x8f, 0x3f, 0xa9, 0xce, 0x3c, 0xc8, 0x9c, 0x6c, 0xfc, 0x27,
0x00, 0x00, 0xff, 0xff, 0x66, 0xe7, 0x2a, 0x84, 0x4b, 0x20, 0x00, 0x00,
}

View file

@ -72,6 +72,14 @@ message APIResource {
// namespaced indicates if a resource is namespaced or not.
optional bool namespaced = 2;
// group is the preferred group of the resource. Empty implies the group of the containing resource list.
// For subresources, this may have a different value, for example: Scale".
optional string group = 8;
// version is the preferred version of the resource. Empty implies the version of the containing resource list
// For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)".
optional string version = 9;
// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
optional string kind = 3;
@ -101,6 +109,7 @@ message APIResourceList {
// discover the API at /api, which is the root path of the legacy v1 API.
//
// +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message APIVersions {
// versions are the api versions that are available.
repeated string versions = 1;
@ -249,6 +258,8 @@ message Initializers {
// When the last pending initializer is removed, and no failing result is set, the initializers
// struct will be set to nil and the object is considered as initialized and visible to all
// clients.
// +patchMergeKey=name
// +patchStrategy=merge
repeated Initializer pending = 1;
// If result is set with the Failure field, the object will be persisted to storage and then deleted,
@ -280,7 +291,7 @@ message LabelSelectorRequirement {
optional string key = 1;
// operator represents a key's relationship to a set of values.
// Valid operators ard In, NotIn, Exists and DoesNotExist.
// Valid operators are In, NotIn, Exists and DoesNotExist.
optional string operator = 2;
// values is an array of string values. If the operator is In or NotIn,
@ -291,10 +302,21 @@ message LabelSelectorRequirement {
repeated string values = 3;
}
// List holds a list of objects, which may not be known by the server.
message List {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// +optional
optional ListMeta metadata = 1;
// List of objects
repeated k8s.io.apimachinery.pkg.runtime.RawExtension items = 2;
}
// ListMeta describes metadata that synthetic resources must have, including lists and
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
message ListMeta {
// SelfLink is a URL representing this object.
// selfLink is a URL representing this object.
// Populated by the system.
// Read-only.
// +optional
@ -308,6 +330,14 @@ message ListMeta {
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency
// +optional
optional string resourceVersion = 2;
// continue may be set if the user set a limit on the number of items returned, and indicates that
// the server has more data available. The value is opaque and may be used to issue another request
// to the endpoint that served this list to retrieve the next set of available objects. Continuing a
// list may not be possible if the server configuration has changed or more than a few minutes have
// passed. The resourceVersion field returned when using this continue value will be identical to
// the value in the first response.
optional string continue = 3;
}
// ListOptions is the query options to a standard REST list call.
@ -343,6 +373,34 @@ message ListOptions {
// Timeout for the list/watch call.
// +optional
optional int64 timeoutSeconds = 5;
// limit is a maximum number of responses to return for a list call. If more items exist, the
// server will set the `continue` field on the list metadata to a value that can be used with the
// same initial query to retrieve the next set of results. Setting a limit may return fewer than
// the requested amount of items (up to zero items) in the event all requested objects are
// filtered out and clients should only use the presence of the continue field to determine whether
// more results are available. Servers may choose not to support the limit argument and will return
// all of the available results. If limit is specified and the continue field is empty, clients may
// assume that no more results are available. This field is not supported if watch is true.
//
// The server guarantees that the objects returned when using continue will be identical to issuing
// a single list call without a limit - that is, no objects created, modified, or deleted after the
// first request is issued will be included in any subsequent continued requests. This is sometimes
// referred to as a consistent snapshot, and ensures that a client that is using limit to receive
// smaller chunks of a very large result can ensure they see all possible objects. If objects are
// updated during a chunked list the version of the object that was present at the time the first list
// result was calculated is returned.
optional int64 limit = 7;
// The continue option should be set when retrieving more results from the server. Since this value
// is server defined, clients may only use the continue value from a previous query result with
// identical query parameters (except for the value of continue) and the server may reject a continue
// value it does not recognize. If the specified continue value is no longer valid whether due to
// expiration (generally five to fifteen minutes) or a configuration change on the server the server
// will respond with a 410 ResourceExpired error indicating the client must restart their list without
// the continue field. This field is not supported when watch is true. Clients may start a watch from
// the last resourceVersion value returned by the server and not miss any modifications.
optional string continue = 8;
}
// MicroTime is version of Time with microsecond level precision.
@ -677,7 +735,9 @@ message StatusDetails {
// +optional
repeated StatusCause causes = 4;
// If specified, the time in seconds before the operation should be retried.
// If specified, the time in seconds before the operation should be retried. Some errors may indicate
// the client must take an alternate action - for those errors this field may indicate how long to wait
// before taking the alternate action.
// +optional
optional int32 retryAfterSeconds = 5;
}
@ -721,6 +781,8 @@ message Timestamp {
// 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.
//
// +k8s:deepcopy-gen=false
message TypeMeta {
// Kind is a string value representing the REST resource this object represents.
// Servers may infer this from the endpoint the client submits requests to.
@ -751,6 +813,8 @@ message Verbs {
// Event represents a single event to a watched resource.
//
// +protobuf=true
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message WatchEvent {
optional string type = 1;

View file

@ -67,20 +67,33 @@ type Object interface {
// ListMetaAccessor retrieves the list interface from an object
type ListMetaAccessor interface {
GetListMeta() List
GetListMeta() ListInterface
}
// List lets you work with list metadata from any of the versioned or
// Common lets you work with core 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 {
type Common interface {
GetResourceVersion() string
SetResourceVersion(version string)
GetSelfLink() string
SetSelfLink(selfLink string)
}
// ListInterface 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 ListInterface interface {
GetResourceVersion() string
SetResourceVersion(version string)
GetSelfLink() string
SetSelfLink(selfLink string)
GetContinue() string
SetContinue(c 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 {
@ -94,6 +107,8 @@ func (meta *ListMeta) GetResourceVersion() string { return meta.ResourceV
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 (meta *ListMeta) GetContinue() string { return meta.Continue }
func (meta *ListMeta) SetContinue(c string) { meta.Continue = c }
func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj }
@ -107,7 +122,7 @@ func (obj *TypeMeta) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *ListMeta) GetListMeta() List { return obj }
func (obj *ListMeta) GetListMeta() ListInterface { return obj }
func (obj *ObjectMeta) GetObjectMeta() Object { return obj }

View file

@ -20,7 +20,7 @@ import (
"encoding/json"
"time"
"k8s.io/apimachinery/pkg/openapi"
openapi "k8s.io/kube-openapi/pkg/common"
"github.com/go-openapi/spec"
"github.com/google/gofuzz"
@ -40,8 +40,8 @@ type MicroTime struct {
// DeepCopy returns a deep-copy of the MicroTime 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 MicroTime) DeepCopy() MicroTime {
return t
func (t *MicroTime) DeepCopyInto(out *MicroTime) {
*out = *t
}
// String returns the representation of the time.
@ -74,22 +74,22 @@ func (t *MicroTime) IsZero() bool {
}
// Before reports whether the time instant t is before u.
func (t MicroTime) Before(u MicroTime) bool {
func (t *MicroTime) Before(u *MicroTime) bool {
return t.Time.Before(u.Time)
}
// Equal reports whether the time instant t is equal to u.
func (t MicroTime) Equal(u MicroTime) bool {
func (t *MicroTime) Equal(u *MicroTime) bool {
return t.Time.Equal(u.Time)
}
// BeforeTime reports whether the time instant t is before second-lever precision u.
func (t MicroTime) BeforeTime(u Time) bool {
func (t *MicroTime) BeforeTime(u *Time) bool {
return t.Time.Before(u.Time)
}
// EqualTime reports whether the time instant t is equal to second-lever precision u.
func (t MicroTime) EqualTime(u Time) bool {
func (t *MicroTime) EqualTime(u *Time) bool {
return t.Time.Equal(u.Time)
}

View file

@ -20,7 +20,7 @@ import (
"encoding/json"
"time"
"k8s.io/apimachinery/pkg/openapi"
openapi "k8s.io/kube-openapi/pkg/common"
"github.com/go-openapi/spec"
"github.com/google/gofuzz"
@ -37,11 +37,11 @@ type Time struct {
time.Time `protobuf:"-"`
}
// DeepCopy returns a deep-copy of the Time value. The underlying time.Time
// DeepCopyInto creates 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
func (t *Time) DeepCopyInto(out *Time) {
*out = *t
}
// String returns the representation of the time.
@ -74,12 +74,12 @@ func (t *Time) IsZero() bool {
}
// Before reports whether the time instant t is before u.
func (t Time) Before(u Time) bool {
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 {
func (t *Time) Equal(u *Time) bool {
return t.Time.Equal(u.Time)
}

View file

@ -42,7 +42,10 @@ func (m *Time) ProtoTime() *Timestamp {
}
return &Timestamp{
Seconds: m.Time.Unix(),
Nanos: int32(m.Time.Nanosecond()),
// leaving this here for the record. our JSON only handled seconds, so this results in writes by
// protobuf clients storing values that aren't read by json clients, which results in unexpected
// field mutation, which fails various validation and equality code.
// Nanos: int32(m.Time.Nanosecond()),
}
}
@ -64,7 +67,11 @@ func (m *Time) Unmarshal(data []byte) error {
if err := p.Unmarshal(data); err != nil {
return err
}
m.Time = time.Unix(p.Seconds, int64(p.Nanos)).Local()
// leaving this here for the record. our JSON only handled seconds, so this results in writes by
// protobuf clients storing values that aren't read by json clients, which results in unexpected
// field mutation, which fails various validation and equality code.
// m.Time = time.Unix(p.Seconds, int64(p.Nanos)).Local()
m.Time = time.Unix(p.Seconds, int64(0)).Local()
return nil
}

View file

@ -14,7 +14,7 @@ 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.
// Package v1 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)
@ -29,12 +29,15 @@ import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
)
// 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.
//
// +k8s:deepcopy-gen=false
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.
@ -55,7 +58,7 @@ type TypeMeta struct {
// 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.
// selfLink is a URL representing this object.
// Populated by the system.
// Read-only.
// +optional
@ -69,6 +72,14 @@ type ListMeta struct {
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency
// +optional
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,2,opt,name=resourceVersion"`
// continue may be set if the user set a limit on the number of items returned, and indicates that
// the server has more data available. The value is opaque and may be used to issue another request
// to the endpoint that served this list to retrieve the next set of available objects. Continuing a
// list may not be possible if the server configuration has changed or more than a few minutes have
// passed. The resourceVersion field returned when using this continue value will be identical to
// the value in the first response.
Continue string `json:"continue,omitempty" protobuf:"bytes,3,opt,name=continue"`
}
// These are internal finalizer values for Kubernetes-like APIs, must be qualified name unless defined here
@ -245,7 +256,9 @@ type Initializers struct {
// When the last pending initializer is removed, and no failing result is set, the initializers
// struct will be set to nil and the object is considered as initialized and visible to all
// clients.
Pending []Initializer `json:"pending" protobuf:"bytes,1,rep,name=pending"`
// +patchMergeKey=name
// +patchStrategy=merge
Pending []Initializer `json:"pending" protobuf:"bytes,1,rep,name=pending" patchStrategy:"merge" patchMergeKey:"name"`
// If result is set with the Failure field, the object will be persisted to storage and then deleted,
// ensuring that other clients can observe the deletion.
Result *Status `json:"result,omitempty" protobuf:"bytes,2,opt,name=result"`
@ -298,6 +311,8 @@ type OwnerReference struct {
BlockOwnerDeletion *bool `json:"blockOwnerDeletion,omitempty" protobuf:"varint,7,opt,name=blockOwnerDeletion"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ListOptions is the query options to a standard REST list call.
type ListOptions struct {
TypeMeta `json:",inline"`
@ -328,8 +343,37 @@ type ListOptions struct {
// Timeout for the list/watch call.
// +optional
TimeoutSeconds *int64 `json:"timeoutSeconds,omitempty" protobuf:"varint,5,opt,name=timeoutSeconds"`
// limit is a maximum number of responses to return for a list call. If more items exist, the
// server will set the `continue` field on the list metadata to a value that can be used with the
// same initial query to retrieve the next set of results. Setting a limit may return fewer than
// the requested amount of items (up to zero items) in the event all requested objects are
// filtered out and clients should only use the presence of the continue field to determine whether
// more results are available. Servers may choose not to support the limit argument and will return
// all of the available results. If limit is specified and the continue field is empty, clients may
// assume that no more results are available. This field is not supported if watch is true.
//
// The server guarantees that the objects returned when using continue will be identical to issuing
// a single list call without a limit - that is, no objects created, modified, or deleted after the
// first request is issued will be included in any subsequent continued requests. This is sometimes
// referred to as a consistent snapshot, and ensures that a client that is using limit to receive
// smaller chunks of a very large result can ensure they see all possible objects. If objects are
// updated during a chunked list the version of the object that was present at the time the first list
// result was calculated is returned.
Limit int64 `json:"limit,omitempty" protobuf:"varint,7,opt,name=limit"`
// The continue option should be set when retrieving more results from the server. Since this value
// is server defined, clients may only use the continue value from a previous query result with
// identical query parameters (except for the value of continue) and the server may reject a continue
// value it does not recognize. If the specified continue value is no longer valid whether due to
// expiration (generally five to fifteen minutes) or a configuration change on the server the server
// will respond with a 410 ResourceExpired error indicating the client must restart their list without
// the continue field. This field is not supported when watch is true. Clients may start a watch from
// the last resourceVersion value returned by the server and not miss any modifications.
Continue string `json:"continue,omitempty" protobuf:"bytes,8,opt,name=continue"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ExportOptions is the query options to the standard REST get call.
type ExportOptions struct {
TypeMeta `json:",inline"`
@ -339,6 +383,8 @@ type ExportOptions struct {
Exact bool `json:"exact" protobuf:"varint,2,opt,name=exact"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// GetOptions is the standard query options to the standard REST get call.
type GetOptions struct {
TypeMeta `json:",inline"`
@ -370,6 +416,8 @@ const (
DeletePropagationForeground DeletionPropagation = "Foreground"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// DeleteOptions may be provided when deleting an API object.
type DeleteOptions struct {
TypeMeta `json:",inline"`
@ -408,6 +456,8 @@ type Preconditions struct {
UID *types.UID `json:"uid,omitempty" protobuf:"bytes,1,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Status is a return value for calls that don't return other objects.
type Status struct {
TypeMeta `json:",inline"`
@ -469,7 +519,9 @@ type StatusDetails struct {
// failure. Not all StatusReasons may provide detailed causes.
// +optional
Causes []StatusCause `json:"causes,omitempty" protobuf:"bytes,4,rep,name=causes"`
// If specified, the time in seconds before the operation should be retried.
// If specified, the time in seconds before the operation should be retried. Some errors may indicate
// the client must take an alternate action - for those errors this field may indicate how long to wait
// before taking the alternate action.
// +optional
RetryAfterSeconds int32 `json:"retryAfterSeconds,omitempty" protobuf:"varint,5,opt,name=retryAfterSeconds"`
}
@ -574,6 +626,15 @@ const (
// Status code 504
StatusReasonTimeout StatusReason = "Timeout"
// StatusReasonTooManyRequests means the server experienced too many requests within a
// given window and that the client must wait to perform the action again. A client may
// always retry the request that led to this error, although 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 429
StatusReasonTooManyRequests StatusReason = "TooManyRequests"
// 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
@ -656,10 +717,25 @@ const (
CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// List holds a list of objects, which may not be known by the server.
type List struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// +optional
ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of objects
Items []runtime.RawExtension `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// 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
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type APIVersions struct {
TypeMeta `json:",inline"`
// versions are the api versions that are available.
@ -674,6 +750,8 @@ type APIVersions struct {
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" protobuf:"bytes,2,rep,name=serverAddressByClientCIDRs"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// APIGroupList is a list of APIGroup, to allow clients to discover the API at
// /apis.
type APIGroupList struct {
@ -682,6 +760,8 @@ type APIGroupList struct {
Groups []APIGroup `json:"groups" protobuf:"bytes,1,rep,name=groups"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// APIGroup contains the name, the supported versions, and the preferred version
// of a group.
type APIGroup struct {
@ -733,6 +813,12 @@ type APIResource struct {
SingularName string `json:"singularName" protobuf:"bytes,6,opt,name=singularName"`
// namespaced indicates if a resource is namespaced or not.
Namespaced bool `json:"namespaced" protobuf:"varint,2,opt,name=namespaced"`
// group is the preferred group of the resource. Empty implies the group of the containing resource list.
// For subresources, this may have a different value, for example: Scale".
Group string `json:"group,omitempty" protobuf:"bytes,8,opt,name=group"`
// version is the preferred version of the resource. Empty implies the version of the containing resource list
// For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)".
Version string `json:"version,omitempty" protobuf:"bytes,9,opt,name=version"`
// 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"`
// verbs is a list of supported kube verbs (this includes get, list, watch, create,
@ -754,6 +840,8 @@ func (vs Verbs) String() string {
return fmt.Sprintf("%v", []string(vs))
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// 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.
@ -822,7 +910,7 @@ type LabelSelectorRequirement struct {
// +patchStrategy=merge
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.
// Valid operators are 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,

View file

@ -53,6 +53,8 @@ var map_APIResource = map[string]string{
"name": "name is the plural name of the resource.",
"singularName": "singularName is the singular name of the resource. This allows clients to handle plural and singular opaquely. The singularName is more correct for reporting status on a single item and both singular and plural are allowed from the kubectl CLI interface.",
"namespaced": "namespaced indicates if a resource is namespaced or not.",
"group": "group is the preferred group of the resource. Empty implies the group of the containing resource list. For subresources, this may have a different value, for example: Scale\".",
"version": "version is the preferred version of the resource. Empty implies the version of the containing resource list For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)\".",
"kind": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')",
"verbs": "verbs is a list of supported kube verbs (this includes get, list, watch, create, update, patch, delete, deletecollection, and proxy)",
"shortNames": "shortNames is a list of suggested short names of the resource.",
@ -157,7 +159,7 @@ func (LabelSelector) SwaggerDoc() map[string]string {
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.",
"operator": "operator represents a key's relationship to a set of values. Valid operators are 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.",
}
@ -165,10 +167,21 @@ func (LabelSelectorRequirement) SwaggerDoc() map[string]string {
return map_LabelSelectorRequirement
}
var map_List = map[string]string{
"": "List holds a list of objects, which may not be known by the server.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"items": "List of objects",
}
func (List) SwaggerDoc() map[string]string {
return map_List
}
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.",
"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: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency",
"continue": "continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response.",
}
func (ListMeta) SwaggerDoc() map[string]string {
@ -183,6 +196,8 @@ var map_ListOptions = map[string]string{
"watch": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.",
"resourceVersion": "When specified with a watch call, shows changes that occur after that particular version of a resource. Defaults to changes from the beginning of history. When specified for list: - if unset, then the result is returned from remote storage based on quorum-read flag; - if it's 0, then we simply return what we currently have in cache, no guarantee; - if set to non zero, then the result is at least as fresh as given rv.",
"timeoutSeconds": "Timeout for the list/watch call.",
"limit": "limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true.\n\nThe server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned.",
"continue": "The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server the server will respond with a 410 ResourceExpired error indicating the client must restart their list without the continue field. This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications.",
}
func (ListOptions) SwaggerDoc() map[string]string {
@ -295,7 +310,7 @@ var map_StatusDetails = map[string]string{
"kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"uid": "UID of the resource. (when there is a single resource which can be described). More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
"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.",
"retryAfterSeconds": "If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action.",
}
func (StatusDetails) SwaggerDoc() map[string]string {

View file

@ -43,6 +43,8 @@ import (
// type if you are dealing with objects that are not in the server meta v1 schema.
//
// TODO: make the serialization part of this type distinct from the field accessors.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:deepcopy-gen=true
type Unstructured struct {
// Object is a JSON compatible map with string, float, int, bool, []interface{}, or
// map[string]interface{}
@ -69,6 +71,39 @@ func (obj *Unstructured) IsList() bool {
}
func (obj *UnstructuredList) IsList() bool { return true }
func (obj *Unstructured) EachListItem(fn func(runtime.Object) error) error {
if obj.Object == nil {
return fmt.Errorf("content is not a list")
}
field, ok := obj.Object["items"]
if !ok {
return fmt.Errorf("content is not a list")
}
items, ok := field.([]interface{})
if !ok {
return nil
}
for _, item := range items {
child, ok := item.(map[string]interface{})
if !ok {
return fmt.Errorf("items member is not an object")
}
if err := fn(&Unstructured{Object: child}); err != nil {
return err
}
}
return nil
}
func (obj *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
for i := range obj.Items {
if err := fn(&obj.Items[i]); err != nil {
return err
}
}
return nil
}
func (obj *Unstructured) UnstructuredContent() map[string]interface{} {
if obj.Object == nil {
obj.Object = make(map[string]interface{})
@ -110,6 +145,50 @@ func (u *Unstructured) UnmarshalJSON(b []byte) error {
return err
}
func deepCopyJSON(x interface{}) interface{} {
switch x := x.(type) {
case map[string]interface{}:
clone := make(map[string]interface{}, len(x))
for k, v := range x {
clone[k] = deepCopyJSON(v)
}
return clone
case []interface{}:
clone := make([]interface{}, len(x))
for i := range x {
clone[i] = deepCopyJSON(x[i])
}
return clone
default:
// only non-pointer values (float64, int64, bool, string) are left. These can be copied by-value.
return x
}
}
func (in *Unstructured) DeepCopy() *Unstructured {
if in == nil {
return nil
}
out := new(Unstructured)
*out = *in
out.Object = deepCopyJSON(in.Object).(map[string]interface{})
return out
}
func (in *UnstructuredList) DeepCopy() *UnstructuredList {
if in == nil {
return nil
}
out := new(UnstructuredList)
*out = *in
out.Object = deepCopyJSON(in.Object).(map[string]interface{})
out.Items = make([]Unstructured, len(in.Items))
for i := range in.Items {
in.Items[i].DeepCopyInto(&out.Items[i])
}
return out
}
func getNestedField(obj map[string]interface{}, fields ...string) interface{} {
var val interface{} = obj
for _, field := range fields {
@ -136,10 +215,15 @@ func getNestedInt64(obj map[string]interface{}, fields ...string) int64 {
}
func getNestedInt64Pointer(obj map[string]interface{}, fields ...string) *int64 {
if str, ok := getNestedField(obj, fields...).(*int64); ok {
return str
nested := getNestedField(obj, fields...)
switch n := nested.(type) {
case int64:
return &n
case *int64:
return n
default:
return nil
}
return nil
}
func getNestedSlice(obj map[string]interface{}, fields ...string) []string {
@ -384,6 +468,14 @@ func (u *Unstructured) SetSelfLink(selfLink string) {
u.setNestedField(selfLink, "metadata", "selfLink")
}
func (u *Unstructured) GetContinue() string {
return getNestedString(u.Object, "metadata", "continue")
}
func (u *Unstructured) SetContinue(c string) {
u.setNestedField(c, "metadata", "continue")
}
func (u *Unstructured) GetCreationTimestamp() metav1.Time {
var timestamp metav1.Time
timestamp.UnmarshalQueryParameter(getNestedString(u.Object, "metadata", "creationTimestamp"))
@ -470,12 +562,15 @@ func (u *Unstructured) GetInitializers() *metav1.Initializers {
}
func (u *Unstructured) SetInitializers(initializers *metav1.Initializers) {
if u.Object == nil {
u.Object = make(map[string]interface{})
}
if initializers == nil {
setNestedField(u.Object, nil, "metadata", "initializers")
return
}
out := make(map[string]interface{})
if err := converter.ToUnstructured(initializers, &out); err != nil {
out, err := converter.ToUnstructured(initializers)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to retrieve initializers for object: %v", err))
}
setNestedField(u.Object, out, "metadata", "initializers")
@ -500,6 +595,8 @@ func (u *Unstructured) SetClusterName(clusterName string) {
// UnstructuredList allows lists that do not have Golang structs
// registered to be manipulated generically. This can be used to deal
// with the API lists from a plug-in.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:deepcopy-gen=true
type UnstructuredList struct {
Object map[string]interface{}
@ -507,6 +604,8 @@ type UnstructuredList struct {
Items []Unstructured `json:"items"`
}
var _ metav1.ListInterface = &UnstructuredList{}
// MarshalJSON ensures that the unstructured list object produces proper
// JSON when passed to Go's standard JSON library.
func (u *UnstructuredList) MarshalJSON() ([]byte, error) {
@ -561,6 +660,14 @@ func (u *UnstructuredList) SetSelfLink(selfLink string) {
u.setNestedField(selfLink, "metadata", "selfLink")
}
func (u *UnstructuredList) GetContinue() string {
return getNestedString(u.Object, "metadata", "continue")
}
func (u *UnstructuredList) SetContinue(c string) {
u.setNestedField(c, "metadata", "continue")
}
func (u *UnstructuredList) SetGroupVersionKind(gvk schema.GroupVersionKind) {
u.SetAPIVersion(gvk.GroupVersion().String())
u.SetKind(gvk.Kind)
@ -611,9 +718,12 @@ func (unstructuredJSONScheme) Encode(obj runtime.Object, w io.Writer) error {
for _, i := range t.Items {
items = append(items, i.Object)
}
t.Object["items"] = items
defer func() { delete(t.Object, "items") }()
return json.NewEncoder(w).Encode(t.Object)
listObj := make(map[string]interface{}, len(t.Object)+1)
for k, v := range t.Object { // Make a shallow copy
listObj[k] = v
}
listObj["items"] = items
return json.NewEncoder(w).Encode(listObj)
case *runtime.Unknown:
// TODO: Unstructured needs to deal with ContentType.
_, err := w.Write(t.Raw)

View file

@ -0,0 +1,75 @@
// +build !ignore_autogenerated
/*
Copyright 2017 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 unstructured
import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
reflect "reflect"
)
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
//
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*Unstructured).DeepCopyInto(out.(*Unstructured))
return nil
}, InType: reflect.TypeOf(&Unstructured{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*UnstructuredList).DeepCopyInto(out.(*UnstructuredList))
return nil
}, InType: reflect.TypeOf(&UnstructuredList{})},
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Unstructured) DeepCopyInto(out *Unstructured) {
clone := in.DeepCopy()
*out = *clone
return
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Unstructured) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *UnstructuredList) DeepCopyInto(out *UnstructuredList) {
clone := in.DeepCopy()
*out = *clone
return
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *UnstructuredList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}

View file

@ -88,3 +88,5 @@ func ValidateDeleteOptions(options *metav1.DeleteOptions) field.ErrorList {
}
return allErrs
}
const UninitializedStatusUpdateErrorMsg string = `must not update status when the object is uninitialized`

View file

@ -26,6 +26,8 @@ import (
// Event represents a single event to a watched resource.
//
// +protobuf=true
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type WatchEvent struct {
Type string `json:"type" protobuf:"bytes,1,opt,name=type"`
@ -78,3 +80,10 @@ type InternalEvent watch.Event
func (e *InternalEvent) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
func (e *WatchEvent) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind }
func (e *InternalEvent) DeepCopyObject() runtime.Object {
if c := e.DeepCopy(); c != nil {
return c
} else {
return nil
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,27 @@
/*
Copyright 2017 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 v1alpha1
import "k8s.io/apimachinery/pkg/conversion"
// Convert_Slice_string_To_v1alpha1_IncludeObjectPolicy allows converting a URL query parameter value
func Convert_Slice_string_To_v1alpha1_IncludeObjectPolicy(input *[]string, out *IncludeObjectPolicy, s conversion.Scope) error {
if len(*input) > 0 {
*out = IncludeObjectPolicy((*input)[0])
}
return nil
}

View file

@ -0,0 +1,61 @@
/*
Copyright 2017 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 v1alpha1
func (in *TableRow) DeepCopy() *TableRow {
if in == nil {
return nil
}
out := new(TableRow)
if in.Cells != nil {
out.Cells = make([]interface{}, len(in.Cells))
for i := range in.Cells {
out.Cells[i] = deepCopyJSON(in.Cells[i])
}
}
if in.Conditions != nil {
out.Conditions = make([]TableRowCondition, len(in.Conditions))
for i := range in.Conditions {
in.Conditions[i].DeepCopyInto(&out.Conditions[i])
}
}
in.Object.DeepCopyInto(&out.Object)
return out
}
func deepCopyJSON(x interface{}) interface{} {
switch x := x.(type) {
case map[string]interface{}:
clone := make(map[string]interface{}, len(x))
for k, v := range x {
clone[k] = deepCopyJSON(v)
}
return clone
case []interface{}:
clone := make([]interface{}, len(x))
for i := range x {
clone[i] = deepCopyJSON(x[i])
}
return clone
default:
return x
}
}

View file

@ -31,6 +31,7 @@ option go_package = "v1alpha1";
// PartialObjectMetadata is a generic representation of any object with ObjectMeta. It allows clients
// to get access to a particular ObjectMeta schema without knowing the details of the version.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message PartialObjectMetadata {
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
@ -39,12 +40,14 @@ message PartialObjectMetadata {
}
// PartialObjectMetadataList contains a list of objects containing only their metadata
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message PartialObjectMetadataList {
// items contains each of the included items.
repeated PartialObjectMetadata items = 1;
}
// TableOptions are used when a Table is requested by the caller.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message TableOptions {
// includeObject decides whether to include each object along with its columnar information.
// Specifying "None" will return no object, specifying "Object" will return the full object contents, and

View file

@ -46,6 +46,12 @@ func init() {
&PartialObjectMetadataList{},
)
if err := scheme.AddConversionFuncs(
Convert_Slice_string_To_v1alpha1_IncludeObjectPolicy,
); err != nil {
panic(err)
}
// register manually. This usually goes through the SchemeBuilder, which we cannot use here.
//scheme.AddGeneratedDeepCopyFuncs(GetGeneratedDeepCopyFuncs()...)
}

View file

@ -28,6 +28,7 @@ import (
// Table is a tabular representation of a set of API resources. The server transforms the
// object into a set of preferred columns for quickly reviewing the objects.
// +protobuf=false
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Table struct {
v1.TypeMeta `json:",inline"`
// Standard list metadata.
@ -129,6 +130,7 @@ const (
)
// TableOptions are used when a Table is requested by the caller.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TableOptions struct {
v1.TypeMeta `json:",inline"`
// includeObject decides whether to include each object along with its columnar information.
@ -140,6 +142,7 @@ type TableOptions struct {
// PartialObjectMetadata is a generic representation of any object with ObjectMeta. It allows clients
// to get access to a particular ObjectMeta schema without knowing the details of the version.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PartialObjectMetadata struct {
v1.TypeMeta `json:",inline"`
// Standard object's metadata.
@ -149,6 +152,7 @@ type PartialObjectMetadata struct {
}
// PartialObjectMetadataList contains a list of objects containing only their metadata
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PartialObjectMetadataList struct {
v1.TypeMeta `json:",inline"`

View file

@ -21,144 +21,212 @@ limitations under the License.
package v1alpha1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
reflect "reflect"
)
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
//
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: DeepCopy_v1alpha1_PartialObjectMetadata, InType: reflect.TypeOf(&PartialObjectMetadata{})},
{Fn: DeepCopy_v1alpha1_PartialObjectMetadataList, InType: reflect.TypeOf(&PartialObjectMetadataList{})},
{Fn: DeepCopy_v1alpha1_Table, InType: reflect.TypeOf(&Table{})},
{Fn: DeepCopy_v1alpha1_TableColumnDefinition, InType: reflect.TypeOf(&TableColumnDefinition{})},
{Fn: DeepCopy_v1alpha1_TableOptions, InType: reflect.TypeOf(&TableOptions{})},
{Fn: DeepCopy_v1alpha1_TableRow, InType: reflect.TypeOf(&TableRow{})},
{Fn: DeepCopy_v1alpha1_TableRowCondition, InType: reflect.TypeOf(&TableRowCondition{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*PartialObjectMetadata).DeepCopyInto(out.(*PartialObjectMetadata))
return nil
}, InType: reflect.TypeOf(&PartialObjectMetadata{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*PartialObjectMetadataList).DeepCopyInto(out.(*PartialObjectMetadataList))
return nil
}, InType: reflect.TypeOf(&PartialObjectMetadataList{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*Table).DeepCopyInto(out.(*Table))
return nil
}, InType: reflect.TypeOf(&Table{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*TableColumnDefinition).DeepCopyInto(out.(*TableColumnDefinition))
return nil
}, InType: reflect.TypeOf(&TableColumnDefinition{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*TableOptions).DeepCopyInto(out.(*TableOptions))
return nil
}, InType: reflect.TypeOf(&TableOptions{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*TableRow).DeepCopyInto(out.(*TableRow))
return nil
}, InType: reflect.TypeOf(&TableRow{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*TableRowCondition).DeepCopyInto(out.(*TableRowCondition))
return nil
}, InType: reflect.TypeOf(&TableRowCondition{})},
}
}
// DeepCopy_v1alpha1_PartialObjectMetadata is an autogenerated deepcopy function.
func DeepCopy_v1alpha1_PartialObjectMetadata(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PartialObjectMetadata)
out := out.(*PartialObjectMetadata)
*out = *in
if newVal, err := c.DeepCopy(&in.ObjectMeta); err != nil {
return err
} else {
out.ObjectMeta = *newVal.(*v1.ObjectMeta)
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PartialObjectMetadata) DeepCopyInto(out *PartialObjectMetadata) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartialObjectMetadata.
func (in *PartialObjectMetadata) DeepCopy() *PartialObjectMetadata {
if in == nil {
return nil
}
out := new(PartialObjectMetadata)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PartialObjectMetadata) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopy_v1alpha1_PartialObjectMetadataList is an autogenerated deepcopy function.
func DeepCopy_v1alpha1_PartialObjectMetadataList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PartialObjectMetadataList)
out := out.(*PartialObjectMetadataList)
*out = *in
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]*PartialObjectMetadata, len(*in))
for i := range *in {
if newVal, err := c.DeepCopy(&(*in)[i]); err != nil {
return err
} else {
(*out)[i] = *newVal.(**PartialObjectMetadata)
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PartialObjectMetadataList) DeepCopyInto(out *PartialObjectMetadataList) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]*PartialObjectMetadata, len(*in))
for i := range *in {
if (*in)[i] == nil {
(*out)[i] = nil
} else {
(*out)[i] = new(PartialObjectMetadata)
(*in)[i].DeepCopyInto((*out)[i])
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartialObjectMetadataList.
func (in *PartialObjectMetadataList) DeepCopy() *PartialObjectMetadataList {
if in == nil {
return nil
}
out := new(PartialObjectMetadataList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PartialObjectMetadataList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopy_v1alpha1_Table is an autogenerated deepcopy function.
func DeepCopy_v1alpha1_Table(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Table)
out := out.(*Table)
*out = *in
if in.ColumnDefinitions != nil {
in, out := &in.ColumnDefinitions, &out.ColumnDefinitions
*out = make([]TableColumnDefinition, len(*in))
copy(*out, *in)
}
if in.Rows != nil {
in, out := &in.Rows, &out.Rows
*out = make([]TableRow, len(*in))
for i := range *in {
if newVal, err := c.DeepCopy(&(*in)[i]); err != nil {
return err
} else {
(*out)[i] = *newVal.(*TableRow)
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Table) DeepCopyInto(out *Table) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.ColumnDefinitions != nil {
in, out := &in.ColumnDefinitions, &out.ColumnDefinitions
*out = make([]TableColumnDefinition, len(*in))
copy(*out, *in)
}
if in.Rows != nil {
in, out := &in.Rows, &out.Rows
*out = make([]TableRow, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Table.
func (in *Table) DeepCopy() *Table {
if in == nil {
return nil
}
out := new(Table)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Table) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopy_v1alpha1_TableColumnDefinition is an autogenerated deepcopy function.
func DeepCopy_v1alpha1_TableColumnDefinition(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TableColumnDefinition)
out := out.(*TableColumnDefinition)
*out = *in
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TableColumnDefinition) DeepCopyInto(out *TableColumnDefinition) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TableColumnDefinition.
func (in *TableColumnDefinition) DeepCopy() *TableColumnDefinition {
if in == nil {
return nil
}
out := new(TableColumnDefinition)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TableOptions) DeepCopyInto(out *TableOptions) {
*out = *in
out.TypeMeta = in.TypeMeta
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TableOptions.
func (in *TableOptions) DeepCopy() *TableOptions {
if in == nil {
return nil
}
out := new(TableOptions)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *TableOptions) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopy_v1alpha1_TableOptions is an autogenerated deepcopy function.
func DeepCopy_v1alpha1_TableOptions(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TableOptions)
out := out.(*TableOptions)
*out = *in
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TableRow) DeepCopyInto(out *TableRow) {
clone := in.DeepCopy()
*out = *clone
return
}
// DeepCopy_v1alpha1_TableRow is an autogenerated deepcopy function.
func DeepCopy_v1alpha1_TableRow(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TableRow)
out := out.(*TableRow)
*out = *in
if in.Cells != nil {
in, out := &in.Cells, &out.Cells
*out = make([]interface{}, len(*in))
for i := range *in {
if newVal, err := c.DeepCopy(&(*in)[i]); err != nil {
return err
} else {
(*out)[i] = *newVal.(*interface{})
}
}
}
if in.Conditions != nil {
in, out := &in.Conditions, &out.Conditions
*out = make([]TableRowCondition, len(*in))
copy(*out, *in)
}
if newVal, err := c.DeepCopy(&in.Object); err != nil {
return err
} else {
out.Object = *newVal.(*runtime.RawExtension)
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TableRowCondition) DeepCopyInto(out *TableRowCondition) {
*out = *in
return
}
// DeepCopy_v1alpha1_TableRowCondition is an autogenerated deepcopy function.
func DeepCopy_v1alpha1_TableRowCondition(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TableRowCondition)
out := out.(*TableRowCondition)
*out = *in
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TableRowCondition.
func (in *TableRowCondition) DeepCopy() *TableRowCondition {
if in == nil {
return nil
}
out := new(TableRowCondition)
in.DeepCopyInto(out)
return out
}

View file

@ -39,7 +39,7 @@ import (
// Converter is an interface for converting between interface{}
// and map[string]interface representation.
type Converter interface {
ToUnstructured(obj interface{}, u *map[string]interface{}) error
ToUnstructured(obj interface{}) (map[string]interface{}, error)
FromUnstructured(u map[string]interface{}, obj interface{}) error
}
@ -388,12 +388,13 @@ func interfaceFromUnstructured(sv, dv reflect.Value) error {
return nil
}
func (c *converterImpl) ToUnstructured(obj interface{}, u *map[string]interface{}) error {
func (c *converterImpl) ToUnstructured(obj interface{}) (map[string]interface{}, error) {
t := reflect.TypeOf(obj)
value := reflect.ValueOf(obj)
if t.Kind() != reflect.Ptr || value.IsNil() {
return fmt.Errorf("ToUnstructured requires a non-nil pointer to an object, got %v", t)
return nil, fmt.Errorf("ToUnstructured requires a non-nil pointer to an object, got %v", t)
}
u := &map[string]interface{}{}
err := toUnstructured(value.Elem(), reflect.ValueOf(u).Elem())
if c.mismatchDetection {
newUnstr := &map[string]interface{}{}
@ -405,7 +406,10 @@ func (c *converterImpl) ToUnstructured(obj interface{}, u *map[string]interface{
glog.Fatalf("ToUnstructured mismatch for %#v, diff: %v", u, diff.ObjectReflectDiff(u, newUnstr))
}
}
return err
if err != nil {
return nil, err
}
return *u, nil
}
func toUnstructuredViaJSON(obj interface{}, u *map[string]interface{}) error {
@ -416,51 +420,95 @@ func toUnstructuredViaJSON(obj interface{}, u *map[string]interface{}) error {
return json.Unmarshal(data, u)
}
func toUnstructured(sv, dv reflect.Value) error {
st, dt := sv.Type(), dv.Type()
var (
nullBytes = []byte("null")
trueBytes = []byte("true")
falseBytes = []byte("false")
)
func getMarshaler(v reflect.Value) (encodingjson.Marshaler, bool) {
// Check value receivers if v is not a pointer and pointer receivers if v is a pointer
if v.Type().Implements(marshalerType) {
return v.Interface().(encodingjson.Marshaler), true
}
// Check pointer receivers if v is not a pointer
if v.Kind() != reflect.Ptr && v.CanAddr() {
v = v.Addr()
if v.Type().Implements(marshalerType) {
return v.Interface().(encodingjson.Marshaler), true
}
}
return nil, false
}
func toUnstructured(sv, dv reflect.Value) error {
// Check if the object has a custom JSON marshaller/unmarshaller.
if st.Implements(marshalerType) {
if marshaler, ok := getMarshaler(sv); ok {
if sv.Kind() == reflect.Ptr && sv.IsNil() {
// We're done - we don't need to store anything.
return nil
}
marshaler := sv.Interface().(encodingjson.Marshaler)
data, err := marshaler.MarshalJSON()
if err != nil {
return err
}
if bytes.Equal(data, []byte("null")) {
switch {
case len(data) == 0:
return fmt.Errorf("error decoding from json: empty value")
case bytes.Equal(data, nullBytes):
// We're done - we don't need to store anything.
} else {
switch {
case len(data) > 0 && data[0] == '"':
var result string
err := json.Unmarshal(data, &result)
if err != nil {
return fmt.Errorf("error decoding from json: %v", err)
}
dv.Set(reflect.ValueOf(result))
case len(data) > 0 && data[0] == '{':
result := make(map[string]interface{})
err := json.Unmarshal(data, &result)
if err != nil {
return fmt.Errorf("error decoding from json: %v", err)
}
dv.Set(reflect.ValueOf(result))
default:
var result int64
err := json.Unmarshal(data, &result)
if err != nil {
return fmt.Errorf("error decoding from json: %v", err)
}
dv.Set(reflect.ValueOf(result))
case bytes.Equal(data, trueBytes):
dv.Set(reflect.ValueOf(true))
case bytes.Equal(data, falseBytes):
dv.Set(reflect.ValueOf(false))
case data[0] == '"':
var result string
err := json.Unmarshal(data, &result)
if err != nil {
return fmt.Errorf("error decoding string from json: %v", err)
}
dv.Set(reflect.ValueOf(result))
case data[0] == '{':
result := make(map[string]interface{})
err := json.Unmarshal(data, &result)
if err != nil {
return fmt.Errorf("error decoding object from json: %v", err)
}
dv.Set(reflect.ValueOf(result))
case data[0] == '[':
result := make([]interface{}, 0)
err := json.Unmarshal(data, &result)
if err != nil {
return fmt.Errorf("error decoding array from json: %v", err)
}
dv.Set(reflect.ValueOf(result))
default:
var (
resultInt int64
resultFloat float64
err error
)
if err = json.Unmarshal(data, &resultInt); err == nil {
dv.Set(reflect.ValueOf(resultInt))
} else if err = json.Unmarshal(data, &resultFloat); err == nil {
dv.Set(reflect.ValueOf(resultFloat))
} else {
return fmt.Errorf("error decoding number from json: %v", err)
}
}
return nil
}
st, dt := sv.Type(), dv.Type()
switch st.Kind() {
case reflect.String:
if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {

View file

@ -50,6 +50,9 @@ type Selector interface {
// String returns a human readable string that represents this selector.
String() string
// Make a deep copy of the selector.
DeepCopySelector() Selector
}
// Everything returns a selector that matches all fields.
@ -99,6 +102,15 @@ func (t *hasTerm) String() string {
return fmt.Sprintf("%v=%v", t.field, EscapeValue(t.value))
}
func (t *hasTerm) DeepCopySelector() Selector {
if t == nil {
return nil
}
out := new(hasTerm)
*out = *t
return out
}
type notHasTerm struct {
field, value string
}
@ -138,6 +150,15 @@ func (t *notHasTerm) String() string {
return fmt.Sprintf("%v!=%v", t.field, EscapeValue(t.value))
}
func (t *notHasTerm) DeepCopySelector() Selector {
if t == nil {
return nil
}
out := new(notHasTerm)
*out = *t
return out
}
type andTerm []Selector
func (t andTerm) Matches(ls Fields) bool {
@ -207,6 +228,17 @@ func (t andTerm) String() string {
return strings.Join(terms, ",")
}
func (t andTerm) DeepCopySelector() Selector {
if t == nil {
return nil
}
out := make([]Selector, len(t))
for i := range t {
out[i] = t[i].DeepCopySelector()
}
return andTerm(out)
}
// SelectorFromSet returns a Selector which will match exactly the given Set. A
// nil Set is considered equivalent to Everything().
func SelectorFromSet(ls Set) Selector {

View file

@ -51,6 +51,9 @@ type Selector interface {
// If there are querying parameters, it will return converted requirements and selectable=true.
// If this selector doesn't want to select anything, it will return selectable=false.
Requirements() (requirements Requirements, selectable bool)
// Make a deep copy of the selector.
DeepCopySelector() Selector
}
// Everything returns a selector that matches all labels.
@ -65,6 +68,7 @@ func (n nothingSelector) Empty() bool { return false }
func (n nothingSelector) String() string { return "" }
func (n nothingSelector) Add(_ ...Requirement) Selector { return n }
func (n nothingSelector) Requirements() (Requirements, bool) { return nil, false }
func (n nothingSelector) DeepCopySelector() Selector { return n }
// Nothing returns a selector that matches no labels
func Nothing() Selector {
@ -78,6 +82,21 @@ func NewSelector() Selector {
type internalSelector []Requirement
func (s internalSelector) DeepCopy() internalSelector {
if s == nil {
return nil
}
result := make([]Requirement, len(s))
for i := range s {
s[i].DeepCopyInto(&result[i])
}
return result
}
func (s internalSelector) DeepCopySelector() Selector {
return s.DeepCopy()
}
// ByKey sorts requirements by key to obtain deterministic parser
type ByKey []Requirement
@ -91,6 +110,7 @@ func (a ByKey) Less(i, j int) bool { return a[i].key < a[j].key }
// The zero value of Requirement is invalid.
// Requirement implements both set based match and exact match
// Requirement should be initialized via NewRequirement constructor for creating a valid Requirement.
// +k8s:deepcopy-gen=true
type Requirement struct {
key string
operator selection.Operator

View file

@ -0,0 +1,59 @@
// +build !ignore_autogenerated
/*
Copyright 2017 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 labels
import (
conversion "k8s.io/apimachinery/pkg/conversion"
reflect "reflect"
)
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
//
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*Requirement).DeepCopyInto(out.(*Requirement))
return nil
}, InType: reflect.TypeOf(&Requirement{})},
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Requirement) DeepCopyInto(out *Requirement) {
*out = *in
if in.strValues != nil {
in, out := &in.strValues, &out.strValues
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Requirement.
func (in *Requirement) DeepCopy() *Requirement {
if in == nil {
return nil
}
out := new(Requirement)
in.DeepCopyInto(out)
return out
}

View file

@ -1,161 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package openapi
import (
"github.com/emicklei/go-restful"
"github.com/go-openapi/spec"
"strings"
)
// OpenAPIDefinition describes single type. Normally these definitions are auto-generated using gen-openapi.
type OpenAPIDefinition struct {
Schema spec.Schema
Dependencies []string
}
type ReferenceCallback func(path string) spec.Ref
// OpenAPIDefinitions is collection of all definitions.
type GetOpenAPIDefinitions func(ReferenceCallback) map[string]OpenAPIDefinition
// OpenAPIDefinitionGetter gets openAPI definitions for a given type. If a type implements this interface,
// the definition returned by it will be used, otherwise the auto-generated definitions will be used. See
// GetOpenAPITypeFormat for more information about trade-offs of using this interface or GetOpenAPITypeFormat method when
// possible.
type OpenAPIDefinitionGetter interface {
OpenAPIDefinition() *OpenAPIDefinition
}
// Config is set of configuration for openAPI spec generation.
type Config struct {
// List of supported protocols such as https, http, etc.
ProtocolList []string
// Info is general information about the API.
Info *spec.Info
// DefaultResponse will be used if an operation does not have any responses listed. It
// will show up as ... "responses" : {"default" : $DefaultResponse} in the spec.
DefaultResponse *spec.Response
// CommonResponses will be added as a response to all operation specs. This is a good place to add common
// responses such as authorization failed.
CommonResponses map[int]spec.Response
// List of webservice's path prefixes to ignore
IgnorePrefixes []string
// OpenAPIDefinitions should provide definition for all models used by routes. Failure to provide this map
// or any of the models will result in spec generation failure.
GetDefinitions GetOpenAPIDefinitions
// GetOperationIDAndTags returns operation id and tags for a restful route. It is an optional function to customize operation IDs.
GetOperationIDAndTags func(r *restful.Route) (string, []string, error)
// GetDefinitionName returns a friendly name for a definition base on the serving path. parameter `name` is the full name of the definition.
// It is an optional function to customize model names.
GetDefinitionName func(name string) (string, spec.Extensions)
// PostProcessSpec runs after the spec is ready to serve. It allows a final modification to the spec before serving.
PostProcessSpec func(*spec.Swagger) (*spec.Swagger, error)
// SecurityDefinitions is list of all security definitions for OpenAPI service. If this is not nil, the user of config
// is responsible to provide DefaultSecurity and (maybe) add unauthorized response to CommonResponses.
SecurityDefinitions *spec.SecurityDefinitions
// DefaultSecurity for all operations. This will pass as spec.SwaggerProps.Security to OpenAPI.
// For most cases, this will be list of acceptable definitions in SecurityDefinitions.
DefaultSecurity []map[string][]string
}
// This function is a reference for converting go (or any custom type) to a simple open API type,format pair. There are
// two ways to customize spec for a type. If you add it here, a type will be converted to a simple type and the type
// comment (the comment that is added before type definition) will be lost. The spec will still have the property
// comment. The second way is to implement OpenAPIDefinitionGetter interface. That function can customize the spec (so
// the spec does not need to be simple type,format) or can even return a simple type,format (e.g. IntOrString). For simple
// type formats, the benefit of adding OpenAPIDefinitionGetter interface is to keep both type and property documentation.
// Example:
// type Sample struct {
// ...
// // port of the server
// port IntOrString
// ...
// }
// // IntOrString documentation...
// type IntOrString { ... }
//
// Adding IntOrString to this function:
// "port" : {
// format: "string",
// type: "int-or-string",
// Description: "port of the server"
// }
//
// Implement OpenAPIDefinitionGetter for IntOrString:
//
// "port" : {
// $Ref: "#/definitions/IntOrString"
// Description: "port of the server"
// }
// ...
// definitions:
// {
// "IntOrString": {
// format: "string",
// type: "int-or-string",
// Description: "IntOrString documentation..." // new
// }
// }
//
func GetOpenAPITypeFormat(typeName string) (string, string) {
schemaTypeFormatMap := map[string][]string{
"uint": {"integer", "int32"},
"uint8": {"integer", "byte"},
"uint16": {"integer", "int32"},
"uint32": {"integer", "int64"},
"uint64": {"integer", "int64"},
"int": {"integer", "int32"},
"int8": {"integer", "byte"},
"int16": {"integer", "int32"},
"int32": {"integer", "int32"},
"int64": {"integer", "int64"},
"byte": {"integer", "byte"},
"float64": {"number", "double"},
"float32": {"number", "float"},
"bool": {"boolean", ""},
"time.Time": {"string", "date-time"},
"string": {"string", ""},
"integer": {"integer", ""},
"number": {"number", ""},
"boolean": {"boolean", ""},
"[]byte": {"string", "byte"}, // base64 encoded characters
"interface{}": {"object", ""},
}
mapped, ok := schemaTypeFormatMap[typeName]
if !ok {
return "", ""
}
return mapped[0], mapped[1]
}
func EscapeJsonPointer(p string) string {
// Escaping reference name using rfc6901
p = strings.Replace(p, "~", "~0", -1)
p = strings.Replace(p, "/", "~1", -1)
return p
}

View file

@ -19,6 +19,7 @@ limitations under the License.
package runtime
import (
"fmt"
"reflect"
"strconv"
"strings"
@ -26,6 +27,20 @@ import (
"k8s.io/apimachinery/pkg/conversion"
)
// DefaultFieldSelectorConversion auto-accepts metav1 values for name and namespace.
// A cluster scoped resource specifying namespace empty works fine and specifying a particular
// namespace will return no results, as expected.
func DefaultMetaV1FieldSelectorConversion(label, value string) (string, string, error) {
switch label {
case "metadata.name":
return label, value, nil
case "metadata.namespace":
return label, value, nil
default:
return "", "", fmt.Errorf("%q is not a known field selector: only %q, %q", label, "metadata.name", "metadata.namespace")
}
}
// JSONKeyMapper uses the struct tags on a conversion to determine the key value for
// the other side. Use when mapping from a map[string]* to a struct or vice versa.
func JSONKeyMapper(key string, sourceTag, destTag reflect.StructTag) (string, string) {

View file

@ -30,6 +30,12 @@ type encodable struct {
}
func (e encodable) GetObjectKind() schema.ObjectKind { return e.obj.GetObjectKind() }
func (e encodable) DeepCopyObject() Object {
var out encodable = e
out.obj = e.obj.DeepCopyObject()
copy(out.versions, e.versions)
return out
}
// NewEncodable creates an object that will be encoded with the provided codec on demand.
// Provided as a convenience for test cases dealing with internal objects.

View file

@ -17,6 +17,7 @@ limitations under the License.
package runtime
import (
"bytes"
"encoding/json"
"errors"
)
@ -25,7 +26,9 @@ func (re *RawExtension) UnmarshalJSON(in []byte) error {
if re == nil {
return errors.New("runtime.RawExtension: UnmarshalJSON on nil pointer")
}
re.Raw = append(re.Raw[0:0], in...)
if !bytes.Equal(in, []byte("null")) {
re.Raw = append(re.Raw[0:0], in...)
}
return nil
}

View file

@ -89,7 +89,7 @@ message RawExtension {
// TypeMeta is provided here for convenience. You may use it directly from this package or define
// your own with the same fields.
//
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen=false
// +protobuf=true
// +k8s:openapi-gen=true
message TypeMeta {
@ -107,6 +107,7 @@ message TypeMeta {
// metadata and field mutatation.
//
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +protobuf=true
// +k8s:openapi-gen=true
message Unknown {

View file

@ -234,6 +234,7 @@ type SelfLinker interface {
// to return a no-op ObjectKindAccessor in cases where it is not expected to be serialized.
type Object interface {
GetObjectKind() schema.ObjectKind
DeepCopyObject() Object
}
// Unstructured objects store values as map[string]interface{}, with only values that can be serialized
@ -242,10 +243,14 @@ type Unstructured interface {
// IsUnstructuredObject is a marker interface to allow objects that can be serialized but not introspected
// to bypass conversion.
IsUnstructuredObject()
// IsList returns true if this type is a list or matches the list convention - has an array called "items".
IsList() bool
// UnstructuredContent returns a non-nil, mutable map of the contents of this object. Values may be
// []interface{}, map[string]interface{}, or any primitive type. Contents are typically serialized to
// and from JSON.
UnstructuredContent() map[string]interface{}
// IsList returns true if this type is a list or matches the list convention - has an array called "items".
IsList() bool
// EachListItem should pass a single item out of the list as an Object to the provided function. Any
// error should terminate the iteration. If IsList() returns false, this method should return an error
// instead of calling the provided function.
EachListItem(func(Object) error) error
}

View file

@ -28,7 +28,7 @@ func (obj *TypeMeta) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *Unknown) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta }
func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj }
// GetObjectKind implements Object for VersionedObjects, returning an empty ObjectKind
// interface if no objects are provided, or the ObjectKind interface of the object in the

View file

@ -454,11 +454,11 @@ func (s *Scheme) Convert(in, out interface{}, context interface{}) error {
// versioned representation to an unversioned one.
func (s *Scheme) ConvertFieldLabel(version, kind, label, value string) (string, string, error) {
if s.fieldLabelConversionFuncs[version] == nil {
return "", "", fmt.Errorf("No field label conversion function found for version: %s", version)
return DefaultMetaV1FieldSelectorConversion(label, value)
}
conversionFunc, ok := s.fieldLabelConversionFuncs[version][kind]
if !ok {
return "", "", fmt.Errorf("No field label conversion function found for version %s and kind %s", version, kind)
return DefaultMetaV1FieldSelectorConversion(label, value)
}
return conversionFunc(label, value)
}
@ -530,11 +530,7 @@ func (s *Scheme) convertToVersion(copy bool, in Object, target GroupVersioner) (
}
if copy {
copied, err := s.Copy(in)
if err != nil {
return nil, err
}
in = copied
in = in.DeepCopyObject()
}
flags, meta := s.generateConvertMeta(in)
@ -555,11 +551,7 @@ func (s *Scheme) generateConvertMeta(in interface{}) (conversion.FieldMatchingFl
// copyAndSetTargetKind performs a conditional copy before returning the object, or an error if copy was not successful.
func copyAndSetTargetKind(copy bool, copier ObjectCopier, obj Object, kind schema.GroupVersionKind) (Object, error) {
if copy {
copied, err := copier.Copy(obj)
if err != nil {
return nil, err
}
obj = copied
obj = obj.DeepCopyObject()
}
setTargetKind(obj, kind)
return obj, nil

View file

@ -19,9 +19,11 @@ package json
import (
"encoding/json"
"io"
"strconv"
"unsafe"
"github.com/ghodss/yaml"
"github.com/ugorji/go/codec"
jsoniter "github.com/json-iterator/go"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -66,6 +68,36 @@ type Serializer struct {
var _ runtime.Serializer = &Serializer{}
var _ recognizer.RecognizingDecoder = &Serializer{}
func init() {
// Force jsoniter to decode number to interface{} via ints, if possible.
decodeNumberAsInt64IfPossible := func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
switch iter.WhatIsNext() {
case jsoniter.NumberValue:
var number json.Number
iter.ReadVal(&number)
u64, err := strconv.ParseUint(string(number), 10, 64)
if err == nil {
*(*interface{})(ptr) = u64
return
}
i64, err := strconv.ParseInt(string(number), 10, 64)
if err == nil {
*(*interface{})(ptr) = i64
return
}
f64, err := strconv.ParseFloat(string(number), 64)
if err == nil {
*(*interface{})(ptr) = f64
return
}
// Not much we can do here.
default:
*(*interface{})(ptr) = iter.Read()
}
}
jsoniter.RegisterTypeDecoderFunc("interface {}", decodeNumberAsInt64IfPossible)
}
// Decode attempts to convert the provided data into YAML or JSON, extract the stored schema kind, apply the provided default gvk, and then
// load that data into an object matching the desired schema kind or the provided into. If into is *runtime.Unknown, the raw data will be
// extracted and no decoding will be performed. If into is not registered with the typer, then the object will be straight decoded using
@ -121,7 +153,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
types, _, err := s.typer.ObjectKinds(into)
switch {
case runtime.IsNotRegisteredError(err):
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(into); err != nil {
if err := jsoniter.ConfigFastest.Unmarshal(data, into); err != nil {
return nil, actual, err
}
return into, actual, nil
@ -155,7 +187,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
return nil, actual, err
}
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil {
if err := jsoniter.ConfigFastest.Unmarshal(data, obj); err != nil {
return nil, actual, err
}
return obj, actual, nil
@ -164,7 +196,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
// Encode serializes the provided object to the given writer.
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
if s.yaml {
json, err := json.Marshal(obj)
json, err := jsoniter.ConfigFastest.Marshal(obj)
if err != nil {
return err
}
@ -177,7 +209,7 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
}
if s.pretty {
data, err := json.MarshalIndent(obj, "", " ")
data, err := jsoniter.ConfigFastest.MarshalIndent(obj, "", " ")
if err != nil {
return err
}

View file

@ -213,7 +213,7 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
}
if e, ok := out.(runtime.NestedObjectEncoder); ok {
if err := e.EncodeNestedObjects(DirectEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
if err := e.EncodeNestedObjects(DirectEncoder{Version: c.encodeVersion, Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
return err
}
}

View file

@ -71,7 +71,7 @@ func fmtRawDoc(rawDoc string) string {
delPrevChar()
buffer.WriteString("\n\n")
case strings.HasPrefix(leading, "TODO"): // Ignore one line TODOs
case strings.HasPrefix(leading, "+"): // Ignore instructions to go2idl
case strings.HasPrefix(leading, "+"): // Ignore instructions to the generators
default:
if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") {
delPrevChar()

View file

@ -30,7 +30,7 @@ package runtime
// TypeMeta is provided here for convenience. You may use it directly from this package or define
// your own with the same fields.
//
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen=false
// +protobuf=true
// +k8s:openapi-gen=true
type TypeMeta struct {
@ -106,6 +106,7 @@ type RawExtension struct {
// metadata and field mutatation.
//
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +protobuf=true
// +k8s:openapi-gen=true
type Unknown struct {
@ -124,6 +125,9 @@ type Unknown struct {
// VersionedObjects is used by Decoders to give callers a way to access all versions
// of an object during the decoding process.
//
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +k8s:deepcopy-gen=true
type VersionedObjects struct {
// Objects is the set of objects retrieved during decoding, in order of conversion.
// The 0 index is the object as serialized on the wire. If conversion has occurred,

View file

@ -26,58 +26,114 @@ import (
)
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
//
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: DeepCopy_runtime_RawExtension, InType: reflect.TypeOf(&RawExtension{})},
{Fn: DeepCopy_runtime_TypeMeta, InType: reflect.TypeOf(&TypeMeta{})},
{Fn: DeepCopy_runtime_Unknown, InType: reflect.TypeOf(&Unknown{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*RawExtension).DeepCopyInto(out.(*RawExtension))
return nil
}, InType: reflect.TypeOf(&RawExtension{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*Unknown).DeepCopyInto(out.(*Unknown))
return nil
}, InType: reflect.TypeOf(&Unknown{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*VersionedObjects).DeepCopyInto(out.(*VersionedObjects))
return nil
}, InType: reflect.TypeOf(&VersionedObjects{})},
}
}
// DeepCopy_runtime_RawExtension is an autogenerated deepcopy function.
func DeepCopy_runtime_RawExtension(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RawExtension)
out := out.(*RawExtension)
*out = *in
if in.Raw != nil {
in, out := &in.Raw, &out.Raw
*out = make([]byte, len(*in))
copy(*out, *in)
}
// in.Object is kind 'Interface'
if in.Object != nil {
if newVal, err := c.DeepCopy(&in.Object); err != nil {
return err
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RawExtension) DeepCopyInto(out *RawExtension) {
*out = *in
if in.Raw != nil {
in, out := &in.Raw, &out.Raw
*out = make([]byte, len(*in))
copy(*out, *in)
}
if in.Object == nil {
out.Object = nil
} else {
out.Object = in.Object.DeepCopyObject()
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RawExtension.
func (in *RawExtension) DeepCopy() *RawExtension {
if in == nil {
return nil
}
out := new(RawExtension)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Unknown) DeepCopyInto(out *Unknown) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.Raw != nil {
in, out := &in.Raw, &out.Raw
*out = make([]byte, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Unknown.
func (in *Unknown) DeepCopy() *Unknown {
if in == nil {
return nil
}
out := new(Unknown)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new Object.
func (in *Unknown) DeepCopyObject() Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VersionedObjects) DeepCopyInto(out *VersionedObjects) {
*out = *in
if in.Objects != nil {
in, out := &in.Objects, &out.Objects
*out = make([]Object, len(*in))
for i := range *in {
if (*in)[i] == nil {
(*out)[i] = nil
} else {
out.Object = *newVal.(*Object)
(*out)[i] = (*in)[i].DeepCopyObject()
}
}
return nil
}
return
}
// DeepCopy_runtime_TypeMeta is an autogenerated deepcopy function.
func DeepCopy_runtime_TypeMeta(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*TypeMeta)
out := out.(*TypeMeta)
*out = *in
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VersionedObjects.
func (in *VersionedObjects) DeepCopy() *VersionedObjects {
if in == nil {
return nil
}
out := new(VersionedObjects)
in.DeepCopyInto(out)
return out
}
// DeepCopy_runtime_Unknown is an autogenerated deepcopy function.
func DeepCopy_runtime_Unknown(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Unknown)
out := out.(*Unknown)
*out = *in
if in.Raw != nil {
in, out := &in.Raw, &out.Raw
*out = make([]byte, len(*in))
copy(*out, *in)
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new Object.
func (in *VersionedObjects) DeepCopyObject() Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}

View file

@ -21,7 +21,7 @@ import (
"fmt"
)
// MessagesgCountMap contains occurance for each error message.
// MessageCountMap contains occurance for each error message.
type MessageCountMap map[string]int
// Aggregate represents an object that contains multiple errors, but does not

View file

@ -24,7 +24,7 @@ import (
"strconv"
"strings"
"k8s.io/apimachinery/pkg/openapi"
openapi "k8s.io/kube-openapi/pkg/common"
"github.com/go-openapi/spec"
"github.com/golang/glog"

View file

@ -50,6 +50,18 @@ func Unmarshal(data []byte, v interface{}) error {
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
return convertMapNumbers(*v)
case *[]interface{}:
// Build a decoder from the given data
decoder := json.NewDecoder(bytes.NewBuffer(data))
// Preserve numbers, rather than casting to float64 automatically
decoder.UseNumber()
// Run the decode
if err := decoder.Decode(v); err != nil {
return err
}
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
return convertSliceNumbers(*v)
default:
return json.Unmarshal(data, v)
}

View file

@ -108,7 +108,7 @@ func DialerFor(transport http.RoundTripper) (DialFunc, error) {
case RoundTripperWrapper:
return DialerFor(transport.WrappedRoundTripper())
default:
return nil, fmt.Errorf("unknown transport type: %v", transport)
return nil, fmt.Errorf("unknown transport type: %T", transport)
}
}
@ -129,7 +129,7 @@ func TLSClientConfig(transport http.RoundTripper) (*tls.Config, error) {
case RoundTripperWrapper:
return TLSClientConfig(transport.WrappedRoundTripper())
default:
return nil, fmt.Errorf("unknown transport type: %v", transport)
return nil, fmt.Errorf("unknown transport type: %T", transport)
}
}
@ -277,6 +277,13 @@ func NewProxierWithNoProxyCIDR(delegate func(req *http.Request) (*url.URL, error
}
}
// DialerFunc implements Dialer for the provided function.
type DialerFunc func(req *http.Request) (net.Conn, error)
func (fn DialerFunc) Dial(req *http.Request) (net.Conn, error) {
return fn(req)
}
// Dialer dials a host and writes a request to it.
type Dialer interface {
// Dial connects to the host specified by req's URL, writes the request to the connection, and

View file

@ -29,18 +29,47 @@ import (
"github.com/golang/glog"
)
type AddressFamily uint
const (
familyIPv4 AddressFamily = 4
familyIPv6 AddressFamily = 6
)
const (
ipv4RouteFile = "/proc/net/route"
ipv6RouteFile = "/proc/net/ipv6_route"
)
type Route struct {
Interface string
Destination net.IP
Gateway net.IP
// TODO: add more fields here if needed
Family AddressFamily
}
func getRoutes(input io.Reader) ([]Route, error) {
routes := []Route{}
if input == nil {
return nil, fmt.Errorf("input is nil")
type RouteFile struct {
name string
parse func(input io.Reader) ([]Route, error)
}
var (
v4File = RouteFile{name: ipv4RouteFile, parse: getIPv4DefaultRoutes}
v6File = RouteFile{name: ipv6RouteFile, parse: getIPv6DefaultRoutes}
)
func (rf RouteFile) extract() ([]Route, error) {
file, err := os.Open(rf.name)
if err != nil {
return nil, err
}
defer file.Close()
return rf.parse(file)
}
// getIPv4DefaultRoutes obtains the IPv4 routes, and filters out non-default routes.
func getIPv4DefaultRoutes(input io.Reader) ([]Route, error) {
routes := []Route{}
scanner := bufio.NewReader(input)
for {
line, err := scanner.ReadString('\n')
@ -52,24 +81,71 @@ func getRoutes(input io.Reader) ([]Route, error) {
continue
}
fields := strings.Fields(line)
routes = append(routes, Route{})
route := &routes[len(routes)-1]
route.Interface = fields[0]
ip, err := parseIP(fields[1])
// Interested in fields:
// 0 - interface name
// 1 - destination address
// 2 - gateway
dest, err := parseIP(fields[1], familyIPv4)
if err != nil {
return nil, err
}
route.Destination = ip
ip, err = parseIP(fields[2])
gw, err := parseIP(fields[2], familyIPv4)
if err != nil {
return nil, err
}
route.Gateway = ip
if !dest.Equal(net.IPv4zero) {
continue
}
routes = append(routes, Route{
Interface: fields[0],
Destination: dest,
Gateway: gw,
Family: familyIPv4,
})
}
return routes, nil
}
func parseIP(str string) (net.IP, error) {
func getIPv6DefaultRoutes(input io.Reader) ([]Route, error) {
routes := []Route{}
scanner := bufio.NewReader(input)
for {
line, err := scanner.ReadString('\n')
if err == io.EOF {
break
}
fields := strings.Fields(line)
// Interested in fields:
// 0 - destination address
// 4 - gateway
// 9 - interface name
dest, err := parseIP(fields[0], familyIPv6)
if err != nil {
return nil, err
}
gw, err := parseIP(fields[4], familyIPv6)
if err != nil {
return nil, err
}
if !dest.Equal(net.IPv6zero) {
continue
}
if gw.Equal(net.IPv6zero) {
continue // loopback
}
routes = append(routes, Route{
Interface: fields[9],
Destination: dest,
Gateway: gw,
Family: familyIPv6,
})
}
return routes, nil
}
// parseIP takes the hex IP address string from route file and converts it
// to a net.IP address. For IPv4, the value must be converted to big endian.
func parseIP(str string, family AddressFamily) (net.IP, error) {
if str == "" {
return nil, fmt.Errorf("input is nil")
}
@ -77,11 +153,16 @@ func parseIP(str string) (net.IP, error) {
if err != nil {
return nil, err
}
//TODO add ipv6 support
if len(bytes) != net.IPv4len {
return nil, fmt.Errorf("only IPv4 is supported")
if family == familyIPv4 {
if len(bytes) != net.IPv4len {
return nil, fmt.Errorf("invalid IPv4 address in route")
}
return net.IP([]byte{bytes[3], bytes[2], bytes[1], bytes[0]}), nil
}
// Must be IPv6
if len(bytes) != net.IPv6len {
return nil, fmt.Errorf("invalid IPv6 address in route")
}
bytes[0], bytes[1], bytes[2], bytes[3] = bytes[3], bytes[2], bytes[1], bytes[0]
return net.IP(bytes), nil
}
@ -96,10 +177,13 @@ func isInterfaceUp(intf *net.Interface) bool {
return false
}
//getFinalIP method receives all the IP addrs of a Interface
//and returns a nil if the address is Loopback, Ipv6, link-local or nil.
//It returns a valid IPv4 if an Ipv4 address is found in the array.
func getFinalIP(addrs []net.Addr) (net.IP, error) {
func isLoopbackOrPointToPoint(intf *net.Interface) bool {
return intf.Flags&(net.FlagLoopback|net.FlagPointToPoint) != 0
}
// getMatchingGlobalIP returns the first valid global unicast address of the given
// 'family' from the list of 'addrs'.
func getMatchingGlobalIP(addrs []net.Addr, family AddressFamily) (net.IP, error) {
if len(addrs) > 0 {
for i := range addrs {
glog.V(4).Infof("Checking addr %s.", addrs[i].String())
@ -107,17 +191,15 @@ func getFinalIP(addrs []net.Addr) (net.IP, error) {
if err != nil {
return nil, err
}
//Only IPv4
//TODO : add IPv6 support
if ip.To4() != nil {
if !ip.IsLoopback() && !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
if memberOf(ip, family) {
if ip.IsGlobalUnicast() {
glog.V(4).Infof("IP found %v", ip)
return ip, nil
} else {
glog.V(4).Infof("Loopback/link-local found %v", ip)
glog.V(4).Infof("Non-global unicast address found %v", ip)
}
} else {
glog.V(4).Infof("%v is not a valid IPv4 address", ip)
glog.V(4).Infof("%v is not an IPv%d address", ip, int(family))
}
}
@ -125,7 +207,9 @@ func getFinalIP(addrs []net.Addr) (net.IP, error) {
return nil, nil
}
func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
// getIPFromInterface gets the IPs on an interface and returns a global unicast address, if any. The
// interface must be up, the IP must in the family requested, and the IP must be a global unicast address.
func getIPFromInterface(intfName string, forFamily AddressFamily, nw networkInterfacer) (net.IP, error) {
intf, err := nw.InterfaceByName(intfName)
if err != nil {
return nil, err
@ -136,131 +220,161 @@ func getIPFromInterface(intfName string, nw networkInterfacer) (net.IP, error) {
return nil, err
}
glog.V(4).Infof("Interface %q has %d addresses :%v.", intfName, len(addrs), addrs)
finalIP, err := getFinalIP(addrs)
matchingIP, err := getMatchingGlobalIP(addrs, forFamily)
if err != nil {
return nil, err
}
if finalIP != nil {
glog.V(4).Infof("valid IPv4 address for interface %q found as %v.", intfName, finalIP)
return finalIP, nil
if matchingIP != nil {
glog.V(4).Infof("Found valid IPv%d address %v for interface %q.", int(forFamily), matchingIP, intfName)
return matchingIP, nil
}
}
return nil, nil
}
func flagsSet(flags net.Flags, test net.Flags) bool {
return flags&test != 0
// memberOF tells if the IP is of the desired family. Used for checking interface addresses.
func memberOf(ip net.IP, family AddressFamily) bool {
if ip.To4() != nil {
return family == familyIPv4
} else {
return family == familyIPv6
}
}
func flagsClear(flags net.Flags, test net.Flags) bool {
return flags&test == 0
}
func chooseHostInterfaceNativeGo() (net.IP, error) {
intfs, err := net.Interfaces()
// chooseIPFromHostInterfaces looks at all system interfaces, trying to find one that is up that
// has a global unicast address (non-loopback, non-link local, non-point2point), and returns the IP.
// Searches for IPv4 addresses, and then IPv6 addresses.
func chooseIPFromHostInterfaces(nw networkInterfacer) (net.IP, error) {
intfs, err := nw.Interfaces()
if err != nil {
return nil, err
}
i := 0
var ip net.IP
for i = range intfs {
if flagsSet(intfs[i].Flags, net.FlagUp) && flagsClear(intfs[i].Flags, net.FlagLoopback|net.FlagPointToPoint) {
addrs, err := intfs[i].Addrs()
if len(intfs) == 0 {
return nil, fmt.Errorf("no interfaces found on host.")
}
for _, family := range []AddressFamily{familyIPv4, familyIPv6} {
glog.V(4).Infof("Looking for system interface with a global IPv%d address", uint(family))
for _, intf := range intfs {
if !isInterfaceUp(&intf) {
glog.V(4).Infof("Skipping: down interface %q", intf.Name)
continue
}
if isLoopbackOrPointToPoint(&intf) {
glog.V(4).Infof("Skipping: LB or P2P interface %q", intf.Name)
continue
}
addrs, err := nw.Addrs(&intf)
if err != nil {
return nil, err
}
if len(addrs) > 0 {
for _, addr := range addrs {
if addrIP, _, err := net.ParseCIDR(addr.String()); err == nil {
if addrIP.To4() != nil {
ip = addrIP.To4()
if !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() {
break
}
}
}
if len(addrs) == 0 {
glog.V(4).Infof("Skipping: no addresses on interface %q", intf.Name)
continue
}
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
if err != nil {
return nil, fmt.Errorf("Unable to parse CIDR for interface %q: %s", intf.Name, err)
}
if ip != nil {
// This interface should suffice.
break
if !memberOf(ip, family) {
glog.V(4).Infof("Skipping: no address family match for %q on interface %q.", ip, intf.Name)
continue
}
// TODO: Decide if should open up to allow IPv6 LLAs in future.
if !ip.IsGlobalUnicast() {
glog.V(4).Infof("Skipping: non-global address %q on interface %q.", ip, intf.Name)
continue
}
glog.V(4).Infof("Found global unicast address %q on interface %q.", ip, intf.Name)
return ip, nil
}
}
}
if ip == nil {
return nil, fmt.Errorf("no acceptable interface from host")
}
glog.V(4).Infof("Choosing interface %s (IP %v) as default", intfs[i].Name, ip)
return ip, nil
return nil, fmt.Errorf("no acceptable interface with global unicast address found on host")
}
//ChooseHostInterface is a method used fetch an IP for a daemon.
//It uses data from /proc/net/route file.
//For a node with no internet connection ,it returns error
//For a multi n/w interface node it returns the IP of the interface with gateway on it.
// ChooseHostInterface is a method used fetch an IP for a daemon.
// If there is no routing info file, it will choose a global IP from the system
// interfaces. Otherwise, it will use IPv4 and IPv6 route information to return the
// IP of the interface with a gateway on it (with priority given to IPv4). For a node
// with no internet connection, it returns error.
func ChooseHostInterface() (net.IP, error) {
inFile, err := os.Open("/proc/net/route")
var nw networkInterfacer = networkInterface{}
if _, err := os.Stat(ipv4RouteFile); os.IsNotExist(err) {
return chooseIPFromHostInterfaces(nw)
}
routes, err := getAllDefaultRoutes()
if err != nil {
if os.IsNotExist(err) {
return chooseHostInterfaceNativeGo()
}
return nil, err
}
defer inFile.Close()
var nw networkInterfacer = networkInterface{}
return chooseHostInterfaceFromRoute(inFile, nw)
return chooseHostInterfaceFromRoute(routes, nw)
}
// networkInterfacer defines an interface for several net library functions. Production
// code will forward to net library functions, and unit tests will override the methods
// for testing purposes.
type networkInterfacer interface {
InterfaceByName(intfName string) (*net.Interface, error)
Addrs(intf *net.Interface) ([]net.Addr, error)
Interfaces() ([]net.Interface, error)
}
// networkInterface implements the networkInterfacer interface for production code, just
// wrapping the underlying net library function calls.
type networkInterface struct{}
func (_ networkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
intf, err := net.InterfaceByName(intfName)
if err != nil {
return nil, err
}
return intf, nil
return net.InterfaceByName(intfName)
}
func (_ networkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
addrs, err := intf.Addrs()
if err != nil {
return nil, err
}
return addrs, nil
return intf.Addrs()
}
func chooseHostInterfaceFromRoute(inFile io.Reader, nw networkInterfacer) (net.IP, error) {
routes, err := getRoutes(inFile)
func (_ networkInterface) Interfaces() ([]net.Interface, error) {
return net.Interfaces()
}
// getAllDefaultRoutes obtains IPv4 and IPv6 default routes on the node. If unable
// to read the IPv4 routing info file, we return an error. If unable to read the IPv6
// routing info file (which is optional), we'll just use the IPv4 route information.
// Using all the routing info, if no default routes are found, an error is returned.
func getAllDefaultRoutes() ([]Route, error) {
routes, err := v4File.extract()
if err != nil {
return nil, err
}
zero := net.IP{0, 0, 0, 0}
var finalIP net.IP
for i := range routes {
//find interface with gateway
if routes[i].Destination.Equal(zero) {
glog.V(4).Infof("Default route transits interface %q", routes[i].Interface)
finalIP, err := getIPFromInterface(routes[i].Interface, nw)
v6Routes, _ := v6File.extract()
routes = append(routes, v6Routes...)
if len(routes) == 0 {
return nil, fmt.Errorf("No default routes.")
}
return routes, nil
}
// chooseHostInterfaceFromRoute cycles through each default route provided, looking for a
// global IP address from the interface for the route. Will first look all each IPv4 route for
// an IPv4 IP, and then will look at each IPv6 route for an IPv6 IP.
func chooseHostInterfaceFromRoute(routes []Route, nw networkInterfacer) (net.IP, error) {
for _, family := range []AddressFamily{familyIPv4, familyIPv6} {
glog.V(4).Infof("Looking for default routes with IPv%d addresses", uint(family))
for _, route := range routes {
if route.Family != family {
continue
}
glog.V(4).Infof("Default route transits interface %q", route.Interface)
finalIP, err := getIPFromInterface(route.Interface, family, nw)
if err != nil {
return nil, err
}
if finalIP != nil {
glog.V(4).Infof("Choosing IP %v ", finalIP)
glog.V(4).Infof("Found active IP %v ", finalIP)
return finalIP, nil
}
}
}
glog.V(4).Infof("No valid IP found")
if finalIP == nil {
return nil, fmt.Errorf("Unable to select an IP.")
}
return nil, nil
glog.V(4).Infof("No active IP found by looking at default routes")
return nil, fmt.Errorf("unable to select an IP from default routes.")
}
// If bind-address is usable, return it directly

View file

@ -72,7 +72,7 @@ func Perm(n int) []int {
// We omit vowels from the set of available characters to reduce the chances
// of "bad words" being formed.
var alphanums = []rune("bcdfghjklmnpqrstvwxz0123456789")
var alphanums = []rune("bcdfghjklmnpqrstvwxz2456789")
// String generates a random alphanumeric string, without vowels, which is n
// characters long. This will panic if n is less than zero.
@ -83,3 +83,13 @@ func String(length int) string {
}
return string(b)
}
// SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and
// ensures that strings generated from hash functions appear consistent throughout the API.
func SafeEncodeString(s string) string {
r := make([]rune, len(s))
for i, b := range []rune(s) {
r[i] = alphanums[(int(b) % len(alphanums))]
}
return string(r)
}

View file

@ -22,6 +22,8 @@ import (
"net"
"regexp"
"strings"
"k8s.io/apimachinery/pkg/util/validation/field"
)
const qnameCharFmt string = "[A-Za-z0-9]"
@ -67,6 +69,21 @@ func IsQualifiedName(value string) []string {
return errs
}
// IsFullyQualifiedName checks if the name is fully qualified.
func IsFullyQualifiedName(fldPath *field.Path, name string) field.ErrorList {
var allErrors field.ErrorList
if len(name) == 0 {
return append(allErrors, field.Required(fldPath, ""))
}
if errs := IsDNS1123Subdomain(name); len(errs) > 0 {
return append(allErrors, field.Invalid(fldPath, name, strings.Join(errs, ",")))
}
if len(strings.Split(name, ".")) < 3 {
return append(allErrors, field.Invalid(fldPath, name, "should be a domain with at least three segments separated by dots"))
}
return allErrors
}
const labelValueFmt string = "(" + qualifiedNameFmt + ")?"
const labelValueErrMsg string = "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character"
const LabelValueMaxLength int = 63
@ -126,7 +143,7 @@ func IsDNS1123Subdomain(value string) []string {
}
const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?"
const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character"
const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character"
const DNS1035LabelMaxLength int = 63
var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$")
@ -188,6 +205,14 @@ func IsValidPortNum(port int) []string {
return []string{InclusiveRangeError(1, 65535)}
}
// IsInRange tests that the argument is in an inclusive range.
func IsInRange(value int, min int, max int) []string {
if value >= min && value <= max {
return nil
}
return []string{InclusiveRangeError(min, max)}
}
// Now in libcontainer UID/GID limits is 0 ~ 1<<31 - 1
// TODO: once we have a type for UID/GID we should make these that type.
const (
@ -277,6 +302,22 @@ func IsHTTPHeaderName(value string) []string {
return nil
}
const envVarNameFmt = "[-._a-zA-Z][-._a-zA-Z0-9]*"
const envVarNameFmtErrMsg string = "a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit"
var envVarNameRegexp = regexp.MustCompile("^" + envVarNameFmt + "$")
// IsEnvVarName tests if a string is a valid environment variable name.
func IsEnvVarName(value string) []string {
var errs []string
if !envVarNameRegexp.MatchString(value) {
errs = append(errs, RegexError(envVarNameFmtErrMsg, envVarNameFmt, "my.env-name", "MY_ENV.NAME", "MyEnvName1"))
}
errs = append(errs, hasChDirPrefix(value)...)
return errs
}
const configMapKeyFmt = `[-._a-zA-Z0-9]+`
const configMapKeyErrMsg string = "a valid config key must consist of alphanumeric characters, '-', '_' or '.'"
@ -291,13 +332,7 @@ func IsConfigMapKey(value string) []string {
if !configMapKeyRegexp.MatchString(value) {
errs = append(errs, RegexError(configMapKeyErrMsg, configMapKeyFmt, "key.name", "KEY_NAME", "key-name"))
}
if value == "." {
errs = append(errs, `must not be '.'`)
} else if value == ".." {
errs = append(errs, `must not be '..'`)
} else if strings.HasPrefix(value, "..") {
errs = append(errs, `must not start with '..'`)
}
errs = append(errs, hasChDirPrefix(value)...)
return errs
}
@ -341,3 +376,16 @@ func prefixEach(msgs []string, prefix string) []string {
func InclusiveRangeError(lo, hi int) string {
return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi)
}
func hasChDirPrefix(value string) []string {
var errs []string
switch {
case value == ".":
errs = append(errs, `must not be '.'`)
case value == "..":
errs = append(errs, `must not be '..'`)
case strings.HasPrefix(value, ".."):
errs = append(errs, `must not start with '..'`)
}
return errs
}

View file

@ -17,8 +17,10 @@ limitations under the License.
package wait
import (
"context"
"errors"
"math/rand"
"sync"
"time"
"k8s.io/apimachinery/pkg/util/runtime"
@ -36,6 +38,40 @@ var ForeverTestTimeout = time.Second * 30
// NeverStop may be passed to Until to make it never stop.
var NeverStop <-chan struct{} = make(chan struct{})
// Group allows to start a group of goroutines and wait for their completion.
type Group struct {
wg sync.WaitGroup
}
func (g *Group) Wait() {
g.wg.Wait()
}
// StartWithChannel starts f in a new goroutine in the group.
// stopCh is passed to f as an argument. f should stop when stopCh is available.
func (g *Group) StartWithChannel(stopCh <-chan struct{}, f func(stopCh <-chan struct{})) {
g.Start(func() {
f(stopCh)
})
}
// StartWithContext starts f in a new goroutine in the group.
// ctx is passed to f as an argument. f should stop when ctx.Done() is available.
func (g *Group) StartWithContext(ctx context.Context, f func(context.Context)) {
g.Start(func() {
f(ctx)
})
}
// Start starts f in a new goroutine in the group.
func (g *Group) Start(f func()) {
g.wg.Add(1)
go func() {
defer g.wg.Done()
f()
}()
}
// Forever calls f every period for ever.
//
// Forever is syntactic sugar on top of Until.

View file

@ -84,6 +84,13 @@ type functionFakeRuntimeObject func()
func (obj functionFakeRuntimeObject) GetObjectKind() schema.ObjectKind {
return schema.EmptyObjectKind
}
func (obj functionFakeRuntimeObject) DeepCopyObject() runtime.Object {
if obj == nil {
return nil
}
// funcs are immutable. Hence, just return the original func.
return obj
}
// Execute f, blocking the incoming queue (and waiting for it to drain first).
// The purpose of this terrible hack is so that watchers added after an event

View file

@ -20,9 +20,9 @@ import (
"fmt"
"sync"
"k8s.io/apimachinery/pkg/runtime"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/runtime"
)
// Interface can be implemented by anything that knows how to watch and report changes.
@ -50,6 +50,7 @@ const (
)
// Event represents a single event to a watched resource.
// +k8s:deepcopy-gen=true
type Event struct {
Type EventType

View file

@ -0,0 +1,59 @@
// +build !ignore_autogenerated
/*
Copyright 2017 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 watch
import (
conversion "k8s.io/apimachinery/pkg/conversion"
reflect "reflect"
)
// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.
//
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*Event).DeepCopyInto(out.(*Event))
return nil
}, InType: reflect.TypeOf(&Event{})},
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Event) DeepCopyInto(out *Event) {
*out = *in
if in.Object == nil {
out.Object = nil
} else {
out.Object = in.Object.DeepCopyObject()
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Event.
func (in *Event) DeepCopy() *Event {
if in == nil {
return nil
}
out := new(Event)
in.DeepCopyInto(out)
return out
}