use istio client-go library instead of knative (#1661)

use istio client-go library instead of knative
bump kubernetes dependency version
change code coverage to codecov
This commit is contained in:
zryfish
2019-12-13 11:26:18 +08:00
committed by GitHub
parent f249a6e081
commit ea88c8803d
2071 changed files with 354531 additions and 108336 deletions

View File

@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- lavalamp

View File

@@ -32,7 +32,9 @@ import (
const (
// 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
// DEPRECATED: please use http.StatusTooManyRequests, this will be removed in
// the future version.
StatusTooManyRequests = http.StatusTooManyRequests
)
// StatusError is an error intended for consumption by a REST API server; it can also be
@@ -184,6 +186,20 @@ func NewConflict(qualifiedResource schema.GroupResource, name string, err error)
}}
}
// NewApplyConflict returns an error including details on the requests apply conflicts
func NewApplyConflict(causes []metav1.StatusCause, message string) *StatusError {
return &StatusError{ErrStatus: metav1.Status{
Status: metav1.StatusFailure,
Code: http.StatusConflict,
Reason: metav1.StatusReasonConflict,
Details: &metav1.StatusDetails{
// TODO: Get obj details here?
Causes: causes,
},
Message: message,
}}
}
// NewGone returns an error indicating the item no longer available at the server and no forwarding address is known.
func NewGone(message string) *StatusError {
return &StatusError{metav1.Status{
@@ -335,7 +351,7 @@ func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
func NewTooManyRequestsError(message string) *StatusError {
return &StatusError{metav1.Status{
Status: metav1.StatusFailure,
Code: StatusTooManyRequests,
Code: http.StatusTooManyRequests,
Reason: metav1.StatusReasonTooManyRequests,
Message: fmt.Sprintf("Too many requests: %s", message),
}}
@@ -380,7 +396,11 @@ func NewGenericServerResponse(code int, verb string, qualifiedResource schema.Gr
case http.StatusNotAcceptable:
reason = metav1.StatusReasonNotAcceptable
// the server message has details about what types are acceptable
message = serverMessage
if len(serverMessage) == 0 || serverMessage == "unknown" {
message = "the server was unable to respond with a content type that the client supports"
} else {
message = serverMessage
}
case http.StatusUnsupportedMediaType:
reason = metav1.StatusReasonUnsupportedMediaType
// the server message has details about what types are acceptable
@@ -603,3 +623,46 @@ func ReasonForError(err error) metav1.StatusReason {
}
return metav1.StatusReasonUnknown
}
// ErrorReporter converts generic errors into runtime.Object errors without
// requiring the caller to take a dependency on meta/v1 (where Status lives).
// This prevents circular dependencies in core watch code.
type ErrorReporter struct {
code int
verb string
reason string
}
// NewClientErrorReporter will respond with valid v1.Status objects that report
// unexpected server responses. Primarily used by watch to report errors when
// we attempt to decode a response from the server and it is not in the form
// we expect. Because watch is a dependency of the core api, we can't return
// meta/v1.Status in that package and so much inject this interface to convert a
// generic error as appropriate. The reason is passed as a unique status cause
// on the returned status, otherwise the generic "ClientError" is returned.
func NewClientErrorReporter(code int, verb string, reason string) *ErrorReporter {
return &ErrorReporter{
code: code,
verb: verb,
reason: reason,
}
}
// AsObject returns a valid error runtime.Object (a v1.Status) for the given
// error, using the code and verb of the reporter type. The error is set to
// indicate that this was an unexpected server response.
func (r *ErrorReporter) AsObject(err error) runtime.Object {
status := NewGenericServerResponse(r.code, r.verb, schema.GroupResource{}, "", err.Error(), 0, true)
if status.ErrStatus.Details == nil {
status.ErrStatus.Details = &metav1.StatusDetails{}
}
reason := r.reason
if len(reason) == 0 {
reason = "ClientError"
}
status.ErrStatus.Details.Causes = append(status.ErrStatus.Details.Causes, metav1.StatusCause{
Type: metav1.CauseType(reason),
Message: err.Error(),
})
return &status.ErrStatus
}

View File

@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- smarterclayton

View File

@@ -17,30 +17,76 @@ limitations under the License.
package meta
import (
"errors"
"fmt"
"reflect"
"sync"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
)
// IsListType returns true if the provided Object has a slice called Items
var (
// isListCache maintains a cache of types that are checked for lists
// which is used by IsListType.
// TODO: remove and replace with an interface check
isListCache = struct {
lock sync.RWMutex
byType map[reflect.Type]bool
}{
byType: make(map[reflect.Type]bool, 1024),
}
)
// IsListType returns true if the provided Object has a slice called Items.
// TODO: Replace the code in this check with an interface comparison by
// creating and enforcing that lists implement a list accessor.
func IsListType(obj runtime.Object) bool {
// if we're a runtime.Unstructured, check whether this is a list.
// TODO: refactor GetItemsPtr to use an interface that returns []runtime.Object
if unstructured, ok := obj.(runtime.Unstructured); ok {
return unstructured.IsList()
switch t := obj.(type) {
case runtime.Unstructured:
return t.IsList()
}
t := reflect.TypeOf(obj)
isListCache.lock.RLock()
ok, exists := isListCache.byType[t]
isListCache.lock.RUnlock()
if !exists {
_, err := getItemsPtr(obj)
ok = err == nil
// cache only the first 1024 types
isListCache.lock.Lock()
if len(isListCache.byType) < 1024 {
isListCache.byType[t] = ok
}
isListCache.lock.Unlock()
}
_, err := GetItemsPtr(obj)
return err == nil
return ok
}
var (
errExpectFieldItems = errors.New("no Items field in this object")
errExpectSliceItems = errors.New("Items field must be a slice of objects")
)
// GetItemsPtr returns a pointer to the list object's Items member.
// If 'list' doesn't have an Items member, it's not really a list type
// and an error will be returned.
// This function will either return a pointer to a slice, or an error, but not both.
// TODO: this will be replaced with an interface in the future
func GetItemsPtr(list runtime.Object) (interface{}, error) {
obj, err := getItemsPtr(list)
if err != nil {
return nil, fmt.Errorf("%T is not a list: %v", list, err)
}
return obj, nil
}
// getItemsPtr returns a pointer to the list object's Items member or an error.
func getItemsPtr(list runtime.Object) (interface{}, error) {
v, err := conversion.EnforcePtr(list)
if err != nil {
return nil, err
@@ -48,19 +94,19 @@ func GetItemsPtr(list runtime.Object) (interface{}, error) {
items := v.FieldByName("Items")
if !items.IsValid() {
return nil, fmt.Errorf("no Items field in %#v", list)
return nil, errExpectFieldItems
}
switch items.Kind() {
case reflect.Interface, reflect.Ptr:
target := reflect.TypeOf(items.Interface()).Elem()
if target.Kind() != reflect.Slice {
return nil, fmt.Errorf("items: Expected slice, got %s", target.Kind())
return nil, errExpectSliceItems
}
return items.Interface(), nil
case reflect.Slice:
return items.Addr().Interface(), nil
default:
return nil, fmt.Errorf("items: Expected slice, got %s", items.Kind())
return nil, errExpectSliceItems
}
}
@@ -158,6 +204,19 @@ func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
// objectSliceType is the type of a slice of Objects
var objectSliceType = reflect.TypeOf([]runtime.Object{})
// LenList returns the length of this list or 0 if it is not a list.
func LenList(list runtime.Object) int {
itemsPtr, err := GetItemsPtr(list)
if err != nil {
return 0
}
items, err := conversion.EnforcePtr(itemsPtr)
if err != nil {
return 0
}
return items.Len()
}
// SetList sets the given list object's Items member have the elements given in
// objects.
// Returns an error if list is not a List type (does not have an Items member),

View File

@@ -20,14 +20,12 @@ import (
"fmt"
"reflect"
"k8s.io/klog"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog"
)
// errNotList is returned when an object implements the Object style interfaces but not the List style
@@ -115,12 +113,12 @@ func Accessor(obj interface{}) (metav1.Object, error) {
// AsPartialObjectMetadata takes the metav1 interface and returns a partial object.
// TODO: consider making this solely a conversion action.
func AsPartialObjectMetadata(m metav1.Object) *metav1beta1.PartialObjectMetadata {
func AsPartialObjectMetadata(m metav1.Object) *metav1.PartialObjectMetadata {
switch t := m.(type) {
case *metav1.ObjectMeta:
return &metav1beta1.PartialObjectMetadata{ObjectMeta: *t}
return &metav1.PartialObjectMetadata{ObjectMeta: *t}
default:
return &metav1beta1.PartialObjectMetadata{
return &metav1.PartialObjectMetadata{
ObjectMeta: metav1.ObjectMeta{
Name: m.GetName(),
GenerateName: m.GetGenerateName(),
@@ -137,7 +135,7 @@ func AsPartialObjectMetadata(m metav1.Object) *metav1beta1.PartialObjectMetadata
OwnerReferences: m.GetOwnerReferences(),
Finalizers: m.GetFinalizers(),
ClusterName: m.GetClusterName(),
Initializers: m.GetInitializers(),
ManagedFields: m.GetManagedFields(),
},
}
}

View File

@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- lavalamp

View File

@@ -17,20 +17,15 @@ limitations under the License.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto
/*
Package resource is a generated protocol buffer package.
It is generated from these files:
k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto
It has these top-level messages:
Quantity
*/
package resource
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
math "math"
proto "github.com/gogo/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@@ -43,19 +38,38 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
func (m *Quantity) Reset() { *m = Quantity{} }
func (*Quantity) ProtoMessage() {}
func (*Quantity) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
func (m *Quantity) Reset() { *m = Quantity{} }
func (*Quantity) ProtoMessage() {}
func (*Quantity) Descriptor() ([]byte, []int) {
return fileDescriptor_612bba87bd70906c, []int{0}
}
func (m *Quantity) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Quantity.Unmarshal(m, b)
}
func (m *Quantity) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Quantity.Marshal(b, m, deterministic)
}
func (m *Quantity) XXX_Merge(src proto.Message) {
xxx_messageInfo_Quantity.Merge(m, src)
}
func (m *Quantity) XXX_Size() int {
return xxx_messageInfo_Quantity.Size(m)
}
func (m *Quantity) XXX_DiscardUnknown() {
xxx_messageInfo_Quantity.DiscardUnknown(m)
}
var xxx_messageInfo_Quantity proto.InternalMessageInfo
func init() {
proto.RegisterType((*Quantity)(nil), "k8s.io.apimachinery.pkg.api.resource.Quantity")
}
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto", fileDescriptorGenerated)
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto", fileDescriptor_612bba87bd70906c)
}
var fileDescriptorGenerated = []byte{
var fileDescriptor_612bba87bd70906c = []byte{
// 237 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8e, 0xb1, 0x4e, 0xc3, 0x30,
0x10, 0x40, 0xcf, 0x0b, 0x2a, 0x19, 0x2b, 0x84, 0x10, 0xc3, 0xa5, 0x42, 0x0c, 0x2c, 0xd8, 0x6b,

View File

@@ -26,7 +26,7 @@ option go_package = "resource";
// Quantity is a fixed-point representation of a number.
// It provides convenient marshaling/unmarshaling in JSON and YAML,
// in addition to String() and Int64() accessors.
// in addition to String() and AsInt64() accessors.
//
// The serialization format is:
//

View File

@@ -194,9 +194,9 @@ func negativeScaleInt64(base int64, scale Scale) (result int64, exact bool) {
}
if fraction {
if base > 0 {
value += 1
value++
} else {
value += -1
value--
}
}
return value, !fraction

View File

@@ -29,7 +29,7 @@ import (
// Quantity is a fixed-point representation of a number.
// It provides convenient marshaling/unmarshaling in JSON and YAML,
// in addition to String() and Int64() accessors.
// in addition to String() and AsInt64() accessors.
//
// The serialization format is:
//
@@ -584,6 +584,12 @@ func (q *Quantity) Neg() {
q.d.Dec.Neg(q.d.Dec)
}
// Equal checks equality of two Quantities. This is useful for testing with
// cmp.Equal.
func (q Quantity) Equal(v Quantity) bool {
return q.Cmp(v) == 0
}
// int64QuantityExpectedBytes is the expected width in bytes of the canonical string representation
// of most Quantity values.
const int64QuantityExpectedBytes = 18
@@ -680,7 +686,7 @@ func NewScaledQuantity(value int64, scale Scale) *Quantity {
}
}
// Value returns the value of q; any fractional part will be lost.
// Value returns the unscaled value of q rounded up to the nearest integer away from 0.
func (q *Quantity) Value() int64 {
return q.ScaledValue(0)
}
@@ -691,7 +697,9 @@ func (q *Quantity) MilliValue() int64 {
return q.ScaledValue(Milli)
}
// ScaledValue returns the value of ceil(q * 10^scale); this could overflow an int64.
// ScaledValue returns the value of ceil(q / 10^scale).
// For example, NewQuantity(1, DecimalSI).ScaledValue(Milli) returns 1000.
// This could overflow an int64.
// To detect overflow, call Value() first and verify the expected magnitude.
func (q *Quantity) ScaledValue(scale Scale) int64 {
if q.d.Dec == nil {
@@ -718,21 +726,3 @@ func (q *Quantity) SetScaled(value int64, scale Scale) {
q.d.Dec = nil
q.i = int64Amount{value: value, scale: scale}
}
// Copy is a convenience function that makes a deep copy for you. Non-deep
// copies of quantities share pointers and you will regret that.
func (q *Quantity) Copy() *Quantity {
if q.d.Dec == nil {
return &Quantity{
s: q.s,
i: q.i,
Format: q.Format,
}
}
tmp := &inf.Dec{}
return &Quantity{
s: q.s,
d: infDecAmount{tmp.Set(q.d.Dec)},
Format: q.Format,
}
}

View File

@@ -19,6 +19,7 @@ package resource
import (
"fmt"
"io"
"math/bits"
"github.com/gogo/protobuf/proto"
)
@@ -28,7 +29,7 @@ var _ proto.Sizer = &Quantity{}
func (m *Quantity) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
n, err := m.MarshalTo(data)
n, err := m.MarshalToSizedBuffer(data[:size])
if err != nil {
return nil, err
}
@@ -38,30 +39,40 @@ func (m *Quantity) Marshal() (data []byte, err error) {
// MarshalTo is a customized version of the generated Protobuf unmarshaler for a struct
// with a single string field.
func (m *Quantity) MarshalTo(data []byte) (int, error) {
var i int
size := m.Size()
return m.MarshalToSizedBuffer(data[:size])
}
// MarshalToSizedBuffer is a customized version of the generated
// Protobuf unmarshaler for a struct with a single string field.
func (m *Quantity) MarshalToSizedBuffer(data []byte) (int, error) {
i := len(data)
_ = i
var l int
_ = l
data[i] = 0xa
i++
// BEGIN CUSTOM MARSHAL
out := m.String()
i -= len(out)
copy(data[i:], out)
i = encodeVarintGenerated(data, i, uint64(len(out)))
i += copy(data[i:], out)
// END CUSTOM MARSHAL
i--
data[i] = 0xa
return i, nil
return len(data) - i, nil
}
func encodeVarintGenerated(data []byte, offset int, v uint64) int {
offset -= sovGenerated(v)
base := offset
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
return base
}
func (m *Quantity) Size() (n int) {
@@ -77,14 +88,7 @@ func (m *Quantity) Size() (n int) {
}
func sovGenerated(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
return (bits.Len64(x|1) + 6) / 7
}
// Unmarshal is a customized version of the generated Protobuf unmarshaler for a struct

View File

@@ -176,37 +176,15 @@ func ValidateObjectMetaAccessor(meta metav1.Object, requiresNamespace bool, name
allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterName"), meta.GetClusterName(), msg))
}
}
for _, entry := range meta.GetManagedFields() {
allErrs = append(allErrs, v1validation.ValidateFieldManager(entry.Manager, fldPath.Child("fieldManager"))...)
}
allErrs = append(allErrs, ValidateNonnegativeField(meta.GetGeneration(), fldPath.Child("generation"))...)
allErrs = append(allErrs, v1validation.ValidateLabels(meta.GetLabels(), fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(meta.GetAnnotations(), fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidateOwnerReferences(meta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)
allErrs = append(allErrs, ValidateInitializers(meta.GetInitializers(), fldPath.Child("initializers"))...)
allErrs = append(allErrs, ValidateFinalizers(meta.GetFinalizers(), fldPath.Child("finalizers"))...)
return allErrs
}
func ValidateInitializers(initializers *metav1.Initializers, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
if initializers == nil {
return allErrs
}
for i, initializer := range initializers.Pending {
allErrs = append(allErrs, validation.IsFullyQualifiedName(fldPath.Child("pending").Index(i).Child("name"), initializer.Name)...)
}
allErrs = append(allErrs, validateInitializersResult(initializers.Result, fldPath.Child("result"))...)
return allErrs
}
func validateInitializersResult(result *metav1.Status, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
if result == nil {
return allErrs
}
switch result.Status {
case metav1.StatusFailure:
default:
allErrs = append(allErrs, field.Invalid(fldPath.Child("status"), result.Status, "must be 'Failure'"))
}
allErrs = append(allErrs, v1validation.ValidateManagedFields(meta.GetManagedFields(), fldPath.Child("managedFields"))...)
return allErrs
}
@@ -265,8 +243,9 @@ func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *f
allErrs = append(allErrs, field.Invalid(fldPath.Child("generation"), newMeta.GetGeneration(), "must not be decremented"))
}
allErrs = append(allErrs, ValidateInitializersUpdate(newMeta.GetInitializers(), oldMeta.GetInitializers(), fldPath.Child("initializers"))...)
for _, entry := range newMeta.GetManagedFields() {
allErrs = append(allErrs, v1validation.ValidateFieldManager(entry.Manager, fldPath.Child("fieldManager"))...)
}
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetName(), oldMeta.GetName(), fldPath.Child("name"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetNamespace(), oldMeta.GetNamespace(), fldPath.Child("namespace"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetUID(), oldMeta.GetUID(), fldPath.Child("uid"))...)
@@ -278,31 +257,7 @@ func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *f
allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.GetLabels(), fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(newMeta.GetAnnotations(), fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidateOwnerReferences(newMeta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)
allErrs = append(allErrs, v1validation.ValidateManagedFields(newMeta.GetManagedFields(), fldPath.Child("managedFields"))...)
return allErrs
}
// ValidateInitializersUpdate checks the update of the metadata initializers field
func ValidateInitializersUpdate(newInit, oldInit *metav1.Initializers, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
switch {
case oldInit == nil && newInit != nil:
// Initializers may not be set on new objects
allErrs = append(allErrs, field.Invalid(fldPath, nil, "field is immutable once initialization has completed"))
case oldInit != nil && newInit == nil:
// this is a valid transition and means initialization was successful
case oldInit != nil && newInit != nil:
// validate changes to initializers
switch {
case oldInit.Result == nil && newInit.Result != nil:
// setting a result is allowed
allErrs = append(allErrs, validateInitializersResult(newInit.Result, fldPath.Child("result"))...)
case oldInit.Result != nil:
// setting Result implies permanent failure, and all future updates will be prevented
allErrs = append(allErrs, ValidateImmutableField(newInit.Result, oldInit.Result, fldPath.Child("result"))...)
default:
// leaving the result nil is allowed
}
}
return allErrs
}

View File

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

View File

@@ -17,4 +17,4 @@ limitations under the License.
// +k8s:deepcopy-gen=package
// +k8s:conversion-gen=k8s.io/apimachinery/pkg/apis/meta/v1
package internalversion
package internalversion // import "k8s.io/apimachinery/pkg/apis/meta/internalversion"

View File

@@ -66,9 +66,6 @@ func addToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion)
metav1.Convert_Map_string_To_string_To_v1_LabelSelector,
metav1.Convert_v1_LabelSelector_To_Map_string_To_string,
Convert_internalversion_ListOptions_To_v1_ListOptions,
Convert_v1_ListOptions_To_internalversion_ListOptions,
)
if err != nil {
return err
@@ -89,12 +86,12 @@ func addToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion)
&metav1beta1.PartialObjectMetadata{},
&metav1beta1.PartialObjectMetadataList{},
)
scheme.AddKnownTypes(metav1beta1.SchemeGroupVersion,
&metav1beta1.Table{},
&metav1beta1.TableOptions{},
&metav1beta1.PartialObjectMetadata{},
&metav1beta1.PartialObjectMetadataList{},
)
if err := metav1beta1.AddMetaToScheme(scheme); err != nil {
return err
}
if err := metav1.AddMetaToScheme(scheme); err != nil {
return err
}
// 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{},

View File

@@ -33,11 +33,17 @@ type ListOptions struct {
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
// allowWatchBookmarks requests watch events with type "BOOKMARK".
// Servers that do not implement bookmarks may ignore this flag and
// bookmarks are sent at the server's discretion. Clients should not
// assume bookmarks are returned at any specific interval, nor may they
// assume the server will send any BOOKMARK event during a session.
// If this is not a watch, this field is ignored.
// If the feature gate WatchBookmarks is not enabled in apiserver,
// this field is ignored.
AllowWatchBookmarks 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:

View File

@@ -55,16 +55,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
if err := s.AddConversionFunc((*ListOptions)(nil), (*v1.ListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_internalversion_ListOptions_To_v1_ListOptions(a.(*ListOptions), b.(*v1.ListOptions), scope)
}); err != nil {
return err
}
if err := s.AddConversionFunc((*v1.ListOptions)(nil), (*ListOptions)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1_ListOptions_To_internalversion_ListOptions(a.(*v1.ListOptions), b.(*ListOptions), scope)
}); err != nil {
return err
}
return nil
}
@@ -117,8 +107,8 @@ func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions,
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.AllowWatchBookmarks = in.AllowWatchBookmarks
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
out.Limit = in.Limit
@@ -126,6 +116,11 @@ func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions,
return nil
}
// Convert_internalversion_ListOptions_To_v1_ListOptions is an autogenerated conversion function.
func Convert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out *v1.ListOptions, s conversion.Scope) error {
return autoConvert_internalversion_ListOptions_To_v1_ListOptions(in, out, s)
}
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
@@ -133,11 +128,16 @@ func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOption
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.AllowWatchBookmarks = in.AllowWatchBookmarks
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
out.Limit = in.Limit
out.Continue = in.Continue
return nil
}
// Convert_v1_ListOptions_To_internalversion_ListOptions is an autogenerated conversion function.
func Convert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOptions, out *ListOptions, s conversion.Scope) error {
return autoConvert_v1_ListOptions_To_internalversion_ListOptions(in, out, s)
}

View File

@@ -28,7 +28,7 @@ import (
func (in *List) DeepCopyInto(out *List) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.Object, len(*in))

View File

@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
reviewers:
- thockin
- smarterclayton

View File

@@ -77,6 +77,8 @@ func AddConversionFuncs(scheme *runtime.Scheme) error {
Convert_Slice_string_To_Slice_int32,
Convert_Slice_string_To_v1_DeletionPropagation,
Convert_Slice_string_To_v1_IncludeObjectPolicy,
)
}
@@ -317,3 +319,11 @@ func Convert_Slice_string_To_v1_DeletionPropagation(input *[]string, out *Deleti
}
return nil
}
// Convert_Slice_string_To_v1_IncludeObjectPolicy allows converting a URL query parameter value
func Convert_Slice_string_To_v1_IncludeObjectPolicy(input *[]string, out *IncludeObjectPolicy, s conversion.Scope) error {
if len(*input) > 0 {
*out = IncludeObjectPolicy((*input)[0])
}
return nil
}

View File

@@ -0,0 +1,46 @@
/*
Copyright 2019 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"
)
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] = runtime.DeepCopyJSONValue(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
}

View File

@@ -48,3 +48,13 @@ func (d *Duration) UnmarshalJSON(b []byte) error {
func (d Duration) MarshalJSON() ([]byte, error) {
return json.Marshal(d.Duration.String())
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ Duration) OpenAPISchemaType() []string { return []string{"string"} }
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ Duration) OpenAPISchemaFormat() string { return "" }

File diff suppressed because it is too large Load Diff

View File

@@ -92,6 +92,16 @@ message APIResource {
// categories is a list of the grouped resources this resource belongs to (e.g. 'all')
repeated string categories = 7;
// The hash value of the storage version, the version this resource is
// converted to when written to the data store. Value must be treated
// as opaque by clients. Only equality comparison on the value is valid.
// This is an alpha feature and may change or be removed in the future.
// The field is populated by the apiserver only if the
// StorageVersionHash feature gate is enabled.
// This field will remain optional even if it graduates.
// +optional
optional string storageVersionHash = 10;
}
// APIResourceList is a list of APIResource, it is used to expose the name of the
@@ -134,9 +144,12 @@ message CreateOptions {
// +optional
repeated string dryRun = 1;
// If IncludeUninitialized is specified, the object may be
// returned without completing initialization.
optional bool includeUninitialized = 2;
// fieldManager is a name associated with the actor or entity
// that is making these changes. The value must be less than or
// 128 characters long, and only contain printable characters,
// as defined by https://golang.org/pkg/unicode/#IsPrint.
// +optional
optional string fieldManager = 3;
}
// DeleteOptions may be provided when deleting an API object.
@@ -188,14 +201,33 @@ message Duration {
}
// ExportOptions is the query options to the standard REST get call.
// Deprecated. Planned for removal in 1.18.
message ExportOptions {
// Should this value be exported. Export strips fields that a user can not specify.
// Deprecated. Planned for removal in 1.18.
optional bool export = 1;
// Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'.
// Deprecated. Planned for removal in 1.18.
optional bool exact = 2;
}
// FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.
//
// Each key is either a '.' representing the field itself, and will always map to an empty set,
// or a string representing a sub-field or item. The string will follow one of these four formats:
// 'f:<name>', where <name> is the name of a field in a struct, or key in a map
// 'v:<value>', where <value> is the exact json formatted value of a list item
// 'i:<index>', where <index> is position of a item in a list
// 'k:<keys>', where <keys> is a map of a list item's key fields to their unique values
// If a key maps to an empty Fields value, the field that key represents is part of the set.
//
// The exact format is defined in sigs.k8s.io/structured-merge-diff
message FieldsV1 {
// Raw is the underlying serialization of this object.
optional bytes Raw = 1;
}
// GetOptions is the standard query options to the standard REST get call.
message GetOptions {
// When specified:
@@ -203,10 +235,6 @@ message GetOptions {
// - 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.
optional string resourceVersion = 1;
// If true, partially initialized resources are included in the response.
// +optional
optional bool includeUninitialized = 2;
}
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
@@ -273,27 +301,6 @@ message GroupVersionResource {
optional string resource = 3;
}
// Initializer is information about an initializer that has not yet completed.
message Initializer {
// name of the process that is responsible for initializing this object.
optional string name = 1;
}
// Initializers tracks the progress of initialization.
message Initializers {
// Pending is a list of initializers that must execute in order before this object is visible.
// 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,
// ensuring that other clients can observe the deletion.
optional Status result = 2;
}
// A label selector is a label query over a set of resources. The result of matchLabels and
// matchExpressions are ANDed. An empty label selector matches all objects. A null
// label selector matches no objects.
@@ -332,7 +339,7 @@ message LabelSelectorRequirement {
// 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
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional ListMeta metadata = 1;
@@ -346,6 +353,10 @@ message ListMeta {
// selfLink is a URL representing this object.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional
optional string selfLink = 1;
@@ -354,7 +365,7 @@ message ListMeta {
// 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
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
// +optional
optional string resourceVersion = 2;
@@ -366,6 +377,18 @@ message ListMeta {
// identical to the value in the first response, unless you have received this token from an error
// message.
optional string continue = 3;
// remainingItemCount is the number of subsequent items in the list which are not included in this
// list response. If the list request contained label or field selectors, then the number of
// remaining items is unknown and the field will be left unset and omitted during serialization.
// If the list is complete (either because it is not chunking or because this is the last chunk),
// then there are no more remaining items and this field will be left unset and omitted during
// serialization.
// Servers older than v1.15 do not set this field.
// The intended use of the remainingItemCount is *estimating* the size of a collection. Clients
// should not rely on the remainingItemCount to be set or to be exact.
// +optional
optional int64 remainingItemCount = 4;
}
// ListOptions is the query options to a standard REST list call.
@@ -380,15 +403,25 @@ message ListOptions {
// +optional
optional string fieldSelector = 2;
// If true, partially initialized resources are included in the response.
// +optional
optional bool includeUninitialized = 6;
// Watch for changes to the described resources and return them as a stream of
// add, update, and remove notifications. Specify resourceVersion.
// +optional
optional bool watch = 3;
// allowWatchBookmarks requests watch events with type "BOOKMARK".
// Servers that do not implement bookmarks may ignore this flag and
// bookmarks are sent at the server's discretion. Clients should not
// assume bookmarks are returned at any specific interval, nor may they
// assume the server will send any BOOKMARK event during a session.
// If this is not a watch, this field is ignored.
// If the feature gate WatchBookmarks is not enabled in apiserver,
// this field is ignored.
//
// This field is beta.
//
// +optional
optional bool allowWatchBookmarks = 9;
// 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:
@@ -438,6 +471,35 @@ message ListOptions {
optional string continue = 8;
}
// ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource
// that the fieldset applies to.
message ManagedFieldsEntry {
// Manager is an identifier of the workflow managing these fields.
optional string manager = 1;
// Operation is the type of operation which lead to this ManagedFieldsEntry being created.
// The only valid values for this field are 'Apply' and 'Update'.
optional string operation = 2;
// APIVersion defines the version of this resource that this field set
// applies to. The format is "group/version" just like the top-level
// APIVersion field. It is necessary to track the version of a field
// set because it cannot be automatically converted.
optional string apiVersion = 3;
// Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'
// +optional
optional Time time = 4;
// FieldsType is the discriminator for the different fields format and version.
// There is currently only one possible value: "FieldsV1"
optional string fieldsType = 6;
// FieldsV1 holds the first JSON version format as described in the "FieldsV1" type.
// +optional
optional FieldsV1 fieldsV1 = 7;
}
// MicroTime is version of Time with microsecond level precision.
//
// +protobuf.options.marshal=false
@@ -482,7 +544,7 @@ message ObjectMeta {
// should retry (optionally after the time indicated in the Retry-After header).
//
// Applied only if Name is not specified.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
// +optional
optional string generateName = 2;
@@ -500,6 +562,10 @@ message ObjectMeta {
// SelfLink is a URL representing this object.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional
optional string selfLink = 4;
@@ -522,7 +588,7 @@ message ObjectMeta {
// Populated by the system.
// Read-only.
// Value must be treated as opaque by clients and .
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
// +optional
optional string resourceVersion = 6;
@@ -538,7 +604,7 @@ message ObjectMeta {
// Populated by the system.
// Read-only.
// Null for lists.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
optional Time creationTimestamp = 8;
@@ -559,7 +625,7 @@ message ObjectMeta {
//
// Populated by the system when a graceful deletion is requested.
// Read-only.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
optional Time deletionTimestamp = 9;
@@ -593,17 +659,6 @@ message ObjectMeta {
// +patchStrategy=merge
repeated OwnerReference ownerReferences = 13;
// An initializer is a controller which enforces some system invariant at object creation time.
// This field is a list of initializers that have not yet acted on this object. If nil or empty,
// this object has been completely initialized. Otherwise, the object is considered uninitialized
// and is hidden (in list/watch and get calls) from clients that haven't explicitly asked to
// observe uninitialized objects.
//
// When an object is created, the system will populate this list with the current set of initializers.
// Only privileged users may set or modify this list. Once it is empty, it may not be modified further
// by any user.
optional Initializers initializers = 16;
// Must be empty before the object is deleted from the registry. Each entry
// is an identifier for the responsible component that will remove the entry
// from the list. If the deletionTimestamp of the object is non-nil, entries
@@ -617,6 +672,17 @@ message ObjectMeta {
// This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
// +optional
optional string clusterName = 15;
// ManagedFields maps workflow-id and version to the set of fields
// that are managed by that workflow. This is mostly for internal
// housekeeping, and users typically shouldn't need to set or
// understand this field. A workflow can be the user's name, a
// controller's name, or the name of a specific apply path like
// "ci-cd". The set of fields is always in the version that the
// workflow used when modifying the object.
//
// +optional
repeated ManagedFieldsEntry managedFields = 17;
}
// OwnerReference contains enough information to let you identify an owning
@@ -627,7 +693,7 @@ message OwnerReference {
optional string apiVersion = 5;
// Kind of the referent.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
optional string kind = 1;
// Name of the referent.
@@ -652,15 +718,69 @@ message OwnerReference {
optional bool blockOwnerDeletion = 7;
}
// 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/sig-architecture/api-conventions.md#metadata
// +optional
optional ObjectMeta metadata = 1;
}
// PartialObjectMetadataList contains a list of objects containing only their metadata
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message PartialObjectMetadataList {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional ListMeta metadata = 1;
// items contains each of the included items.
repeated PartialObjectMetadata items = 2;
}
// Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.
message Patch {
}
// PatchOptions may be provided when patching an API object.
// PatchOptions is meant to be a superset of UpdateOptions.
message PatchOptions {
// When present, indicates that modifications should not be
// persisted. An invalid or unrecognized dryRun directive will
// result in an error response and no further processing of the
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
repeated string dryRun = 1;
// Force is going to "force" Apply requests. It means user will
// re-acquire conflicting fields owned by other people. Force
// flag must be unset for non-apply patch requests.
// +optional
optional bool force = 2;
// fieldManager is a name associated with the actor or entity
// that is making these changes. The value must be less than or
// 128 characters long, and only contain printable characters,
// as defined by https://golang.org/pkg/unicode/#IsPrint. This
// field is required for apply requests
// (application/apply-patch) but optional for non-apply patch
// types (JsonPatch, MergePatch, StrategicMergePatch).
// +optional
optional string fieldManager = 3;
}
// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
message Preconditions {
// Specifies the target UID.
// +optional
optional string uid = 1;
// Specifies the target ResourceVersion
// +optional
optional string resourceVersion = 2;
}
// RootPaths lists the paths available at root.
@@ -683,13 +803,13 @@ message ServerAddressByClientCIDR {
// Status is a return value for calls that don't return other objects.
message Status {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional ListMeta metadata = 1;
// Status of the operation.
// One of: "Success" or "Failure".
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
optional string status = 2;
@@ -760,7 +880,7 @@ message StatusDetails {
// 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
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional string kind = 3;
@@ -782,6 +902,16 @@ message StatusDetails {
optional int32 retryAfterSeconds = 5;
}
// 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
// specifying "Metadata" (the default) will return the object's metadata in the PartialObjectMetadata kind
// in version v1beta1 of the meta.k8s.io API group.
optional string includeObject = 1;
}
// Time is a wrapper around time.Time which supports correct
// marshaling to YAML and JSON. Wrappers are provided for many
// of the factory methods that the time package offers.
@@ -828,19 +958,20 @@ message TypeMeta {
// Servers may infer this from the endpoint the client submits requests to.
// Cannot be updated.
// In CamelCase.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional string kind = 1;
// APIVersion defines the versioned schema of this representation of an object.
// Servers should convert recognized schemas to the latest internal value, and
// may reject unrecognized values.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
// +optional
optional string apiVersion = 2;
}
// UpdateOptions may be provided when updating an API object.
// All fields in UpdateOptions should also be present in PatchOptions.
message UpdateOptions {
// When present, indicates that modifications should not be
// persisted. An invalid or unrecognized dryRun directive will
@@ -849,6 +980,13 @@ message UpdateOptions {
// - All: all dry run stages will be processed
// +optional
repeated string dryRun = 1;
// fieldManager is a name associated with the actor or entity
// that is making these changes. The value must be less than or
// 128 characters long, and only contain printable characters,
// as defined by https://golang.org/pkg/unicode/#IsPrint.
// +optional
optional string fieldManager = 2;
}
// Verbs masks the value so protobuf can generate

View File

@@ -17,6 +17,9 @@ limitations under the License.
package v1
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"k8s.io/apimachinery/pkg/fields"
@@ -227,8 +230,51 @@ func NewUIDPreconditions(uid string) *Preconditions {
return &Preconditions{UID: &u}
}
// NewRVDeletionPrecondition returns a DeleteOptions with a ResourceVersion precondition set.
func NewRVDeletionPrecondition(rv string) *DeleteOptions {
p := Preconditions{ResourceVersion: &rv}
return &DeleteOptions{Preconditions: &p}
}
// HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values.
func HasObjectMetaSystemFieldValues(meta Object) bool {
return !meta.GetCreationTimestamp().Time.IsZero() ||
len(meta.GetUID()) != 0
}
// ResetObjectMetaForStatus forces the meta fields for a status update to match the meta fields
// for a pre-existing object. This is opt-in for new objects with Status subresource.
func ResetObjectMetaForStatus(meta, existingMeta Object) {
meta.SetDeletionTimestamp(existingMeta.GetDeletionTimestamp())
meta.SetGeneration(existingMeta.GetGeneration())
meta.SetSelfLink(existingMeta.GetSelfLink())
meta.SetLabels(existingMeta.GetLabels())
meta.SetAnnotations(existingMeta.GetAnnotations())
meta.SetFinalizers(existingMeta.GetFinalizers())
meta.SetOwnerReferences(existingMeta.GetOwnerReferences())
meta.SetManagedFields(existingMeta.GetManagedFields())
}
// MarshalJSON implements json.Marshaler
// MarshalJSON may get called on pointers or values, so implement MarshalJSON on value.
// http://stackoverflow.com/questions/21390979/custom-marshaljson-never-gets-called-in-go
func (f FieldsV1) MarshalJSON() ([]byte, error) {
if f.Raw == nil {
return []byte("null"), nil
}
return f.Raw, nil
}
// UnmarshalJSON implements json.Unmarshaler
func (f *FieldsV1) UnmarshalJSON(b []byte) error {
if f == nil {
return errors.New("metav1.Fields: UnmarshalJSON on nil pointer")
}
if !bytes.Equal(b, []byte("null")) {
f.Raw = append(f.Raw[0:0], b...)
}
return nil
}
var _ json.Marshaler = FieldsV1{}
var _ json.Unmarshaler = &FieldsV1{}

View File

@@ -55,14 +55,14 @@ type Object interface {
SetLabels(labels map[string]string)
GetAnnotations() map[string]string
SetAnnotations(annotations map[string]string)
GetInitializers() *Initializers
SetInitializers(initializers *Initializers)
GetFinalizers() []string
SetFinalizers(finalizers []string)
GetOwnerReferences() []OwnerReference
SetOwnerReferences([]OwnerReference)
GetClusterName() string
SetClusterName(clusterName string)
GetManagedFields() []ManagedFieldsEntry
SetManagedFields(managedFields []ManagedFieldsEntry)
}
// ListMetaAccessor retrieves the list interface from an object
@@ -92,6 +92,8 @@ type ListInterface interface {
SetSelfLink(selfLink string)
GetContinue() string
SetContinue(c string)
GetRemainingItemCount() *int64
SetRemainingItemCount(c *int64)
}
// Type exposes the type and APIVersion of versioned or internal API objects.
@@ -103,12 +105,16 @@ type Type interface {
SetKind(kind string)
}
var _ ListInterface = &ListMeta{}
func (meta *ListMeta) GetResourceVersion() string { return meta.ResourceVersion }
func (meta *ListMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
func (meta *ListMeta) GetSelfLink() string { return meta.SelfLink }
func (meta *ListMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
func (meta *ListMeta) GetContinue() string { return meta.Continue }
func (meta *ListMeta) SetContinue(c string) { meta.Continue = c }
func (meta *ListMeta) GetRemainingItemCount() *int64 { return meta.RemainingItemCount }
func (meta *ListMeta) SetRemainingItemCount(c *int64) { meta.RemainingItemCount = c }
func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj }
@@ -158,13 +164,15 @@ func (meta *ObjectMeta) GetLabels() map[string]string { return m
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
func (meta *ObjectMeta) SetAnnotations(annotations map[string]string) { meta.Annotations = annotations }
func (meta *ObjectMeta) GetInitializers() *Initializers { return meta.Initializers }
func (meta *ObjectMeta) SetInitializers(initializers *Initializers) { meta.Initializers = initializers }
func (meta *ObjectMeta) GetFinalizers() []string { return meta.Finalizers }
func (meta *ObjectMeta) SetFinalizers(finalizers []string) { meta.Finalizers = finalizers }
func (meta *ObjectMeta) GetOwnerReferences() []OwnerReference { return meta.OwnerReferences }
func (meta *ObjectMeta) SetOwnerReferences(references []OwnerReference) {
meta.OwnerReferences = references
}
func (meta *ObjectMeta) GetClusterName() string { return meta.ClusterName }
func (meta *ObjectMeta) SetClusterName(clusterName string) { meta.ClusterName = clusterName }
func (meta *ObjectMeta) GetClusterName() string { return meta.ClusterName }
func (meta *ObjectMeta) SetClusterName(clusterName string) { meta.ClusterName = clusterName }
func (meta *ObjectMeta) GetManagedFields() []ManagedFieldsEntry { return meta.ManagedFields }
func (meta *ObjectMeta) SetManagedFields(managedFields []ManagedFieldsEntry) {
meta.ManagedFields = managedFields
}

View File

@@ -41,11 +41,6 @@ func (t *MicroTime) DeepCopyInto(out *MicroTime) {
*out = *t
}
// String returns the representation of the time.
func (t MicroTime) String() string {
return t.Time.String()
}
// NewMicroTime returns a wrapped instance of the provided time
func NewMicroTime(time time.Time) MicroTime {
return MicroTime{time}
@@ -72,22 +67,40 @@ func (t *MicroTime) IsZero() bool {
// Before reports whether the time instant t is before u.
func (t *MicroTime) Before(u *MicroTime) bool {
return t.Time.Before(u.Time)
if t != nil && u != nil {
return t.Time.Before(u.Time)
}
return false
}
// Equal reports whether the time instant t is equal to u.
func (t *MicroTime) Equal(u *MicroTime) bool {
return t.Time.Equal(u.Time)
if t == nil && u == nil {
return true
}
if t != nil && u != nil {
return t.Time.Equal(u.Time)
}
return false
}
// BeforeTime reports whether the time instant t is before second-lever precision u.
func (t *MicroTime) BeforeTime(u *Time) bool {
return t.Time.Before(u.Time)
if t != nil && u != nil {
return t.Time.Before(u.Time)
}
return false
}
// EqualTime reports whether the time instant t is equal to second-lever precision u.
func (t *MicroTime) EqualTime(u *Time) bool {
return t.Time.Equal(u.Time)
if t == nil && u == nil {
return true
}
if t != nil && u != nil {
return t.Time.Equal(u.Time)
}
return false
}
// UnixMicro returns the local time corresponding to the given Unix time

View File

@@ -70,3 +70,11 @@ func (m *MicroTime) MarshalTo(data []byte) (int, error) {
}
return m.ProtoMicroTime().MarshalTo(data)
}
// MarshalToSizedBuffer implements the protobuf marshalling interface.
func (m *MicroTime) MarshalToSizedBuffer(data []byte) (int, error) {
if m == nil || m.Time.IsZero() {
return 0, nil
}
return m.ProtoMicroTime().MarshalToSizedBuffer(data)
}

View File

@@ -55,6 +55,7 @@ func AddToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion)
&DeleteOptions{},
&CreateOptions{},
&UpdateOptions{},
&PatchOptions{},
)
utilruntime.Must(scheme.AddConversionFuncs(
Convert_v1_WatchEvent_To_watch_Event,
@@ -90,8 +91,26 @@ func init() {
&DeleteOptions{},
&CreateOptions{},
&UpdateOptions{},
&PatchOptions{},
)
if err := AddMetaToScheme(scheme); err != nil {
panic(err)
}
// register manually. This usually goes through the SchemeBuilder, which we cannot use here.
utilruntime.Must(RegisterDefaults(scheme))
}
func AddMetaToScheme(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Table{},
&TableOptions{},
&PartialObjectMetadata{},
&PartialObjectMetadataList{},
)
return scheme.AddConversionFuncs(
Convert_Slice_string_To_v1_IncludeObjectPolicy,
)
}

View File

@@ -20,7 +20,7 @@ import (
"encoding/json"
"time"
"github.com/google/gofuzz"
fuzz "github.com/google/gofuzz"
)
// Time is a wrapper around time.Time which supports correct
@@ -41,11 +41,6 @@ func (t *Time) DeepCopyInto(out *Time) {
*out = *t
}
// String returns the representation of the time.
func (t Time) String() string {
return t.Time.String()
}
// NewTime returns a wrapped instance of the provided time
func NewTime(time time.Time) Time {
return Time{time}
@@ -72,7 +67,10 @@ func (t *Time) IsZero() bool {
// Before reports whether the time instant t is before u.
func (t *Time) Before(u *Time) bool {
return t.Time.Before(u.Time)
if t != nil && u != nil {
return t.Time.Before(u.Time)
}
return false
}
// Equal reports whether the time instant t is equal to u.
@@ -147,8 +145,12 @@ func (t Time) MarshalJSON() ([]byte, error) {
// Encode unset/nil objects as JSON's "null".
return []byte("null"), nil
}
return json.Marshal(t.UTC().Format(time.RFC3339))
buf := make([]byte, 0, len(time.RFC3339)+2)
buf = append(buf, '"')
// time cannot contain non escapable JSON characters
buf = t.UTC().AppendFormat(buf, time.RFC3339)
buf = append(buf, '"')
return buf, nil
}
// OpenAPISchemaType is used by the kube-openapi generator when constructing

View File

@@ -75,7 +75,7 @@ func (m *Time) Unmarshal(data []byte) error {
return nil
}
// Marshal implements the protobuf marshalling interface.
// Marshal implements the protobuf marshaling interface.
func (m *Time) Marshal() (data []byte, err error) {
if m == nil || m.Time.IsZero() {
return nil, nil
@@ -83,10 +83,18 @@ func (m *Time) Marshal() (data []byte, err error) {
return m.ProtoTime().Marshal()
}
// MarshalTo implements the protobuf marshalling interface.
// MarshalTo implements the protobuf marshaling interface.
func (m *Time) MarshalTo(data []byte) (int, error) {
if m == nil || m.Time.IsZero() {
return 0, nil
}
return m.ProtoTime().MarshalTo(data)
}
// MarshalToSizedBuffer implements the protobuf reverse marshaling interface.
func (m *Time) MarshalToSizedBuffer(data []byte) (int, error) {
if m == nil || m.Time.IsZero() {
return 0, nil
}
return m.ProtoTime().MarshalToSizedBuffer(data)
}

View File

@@ -43,14 +43,14 @@ type TypeMeta struct {
// Servers may infer this from the endpoint the client submits requests to.
// Cannot be updated.
// In CamelCase.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
// APIVersion defines the versioned schema of this representation of an object.
// Servers should convert recognized schemas to the latest internal value, and
// may reject unrecognized values.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
// +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
}
@@ -61,6 +61,10 @@ type ListMeta struct {
// selfLink is a URL representing this object.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional
SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,1,opt,name=selfLink"`
@@ -69,7 +73,7 @@ type ListMeta struct {
// 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
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
// +optional
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,2,opt,name=resourceVersion"`
@@ -81,6 +85,18 @@ type ListMeta struct {
// identical to the value in the first response, unless you have received this token from an error
// message.
Continue string `json:"continue,omitempty" protobuf:"bytes,3,opt,name=continue"`
// remainingItemCount is the number of subsequent items in the list which are not included in this
// list response. If the list request contained label or field selectors, then the number of
// remaining items is unknown and the field will be left unset and omitted during serialization.
// If the list is complete (either because it is not chunking or because this is the last chunk),
// then there are no more remaining items and this field will be left unset and omitted during
// serialization.
// Servers older than v1.15 do not set this field.
// The intended use of the remainingItemCount is *estimating* the size of a collection. Clients
// should not rely on the remainingItemCount to be set or to be exact.
// +optional
RemainingItemCount *int64 `json:"remainingItemCount,omitempty" protobuf:"bytes,4,opt,name=remainingItemCount"`
}
// These are internal finalizer values for Kubernetes-like APIs, must be qualified name unless defined here
@@ -115,7 +131,7 @@ type ObjectMeta struct {
// should retry (optionally after the time indicated in the Retry-After header).
//
// Applied only if Name is not specified.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency
// +optional
GenerateName string `json:"generateName,omitempty" protobuf:"bytes,2,opt,name=generateName"`
@@ -133,6 +149,10 @@ type ObjectMeta struct {
// SelfLink is a URL representing this object.
// Populated by the system.
// Read-only.
//
// DEPRECATED
// Kubernetes will stop propagating this field in 1.20 release and the field is planned
// to be removed in 1.21 release.
// +optional
SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,4,opt,name=selfLink"`
@@ -155,7 +175,7 @@ type ObjectMeta struct {
// Populated by the system.
// Read-only.
// Value must be treated as opaque by clients and .
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
// +optional
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"`
@@ -171,7 +191,7 @@ type ObjectMeta struct {
// Populated by the system.
// Read-only.
// Null for lists.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
CreationTimestamp Time `json:"creationTimestamp,omitempty" protobuf:"bytes,8,opt,name=creationTimestamp"`
@@ -192,7 +212,7 @@ type ObjectMeta struct {
//
// Populated by the system when a graceful deletion is requested.
// Read-only.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"`
@@ -226,17 +246,6 @@ type ObjectMeta struct {
// +patchStrategy=merge
OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"`
// An initializer is a controller which enforces some system invariant at object creation time.
// This field is a list of initializers that have not yet acted on this object. If nil or empty,
// this object has been completely initialized. Otherwise, the object is considered uninitialized
// and is hidden (in list/watch and get calls) from clients that haven't explicitly asked to
// observe uninitialized objects.
//
// When an object is created, the system will populate this list with the current set of initializers.
// Only privileged users may set or modify this list. Once it is empty, it may not be modified further
// by any user.
Initializers *Initializers `json:"initializers,omitempty" protobuf:"bytes,16,opt,name=initializers"`
// Must be empty before the object is deleted from the registry. Each entry
// is an identifier for the responsible component that will remove the entry
// from the list. If the deletionTimestamp of the object is non-nil, entries
@@ -250,26 +259,17 @@ type ObjectMeta struct {
// This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.
// +optional
ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"`
}
// Initializers tracks the progress of initialization.
type Initializers struct {
// Pending is a list of initializers that must execute in order before this object is visible.
// 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
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"`
}
// Initializer is information about an initializer that has not yet completed.
type Initializer struct {
// name of the process that is responsible for initializing this object.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// ManagedFields maps workflow-id and version to the set of fields
// that are managed by that workflow. This is mostly for internal
// housekeeping, and users typically shouldn't need to set or
// understand this field. A workflow can be the user's name, a
// controller's name, or the name of a specific apply path like
// "ci-cd". The set of fields is always in the version that the
// workflow used when modifying the object.
//
// +optional
ManagedFields []ManagedFieldsEntry `json:"managedFields,omitempty" protobuf:"bytes,17,rep,name=managedFields"`
}
const (
@@ -292,7 +292,7 @@ type OwnerReference struct {
// API version of the referent.
APIVersion string `json:"apiVersion" protobuf:"bytes,5,opt,name=apiVersion"`
// Kind of the referent.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// Name of the referent.
// More info: http://kubernetes.io/docs/user-guide/identifiers#names
@@ -327,13 +327,27 @@ type ListOptions struct {
// Defaults to everything.
// +optional
FieldSelector string `json:"fieldSelector,omitempty" protobuf:"bytes,2,opt,name=fieldSelector"`
// If true, partially initialized resources are included in the response.
// +optional
IncludeUninitialized bool `json:"includeUninitialized,omitempty" protobuf:"varint,6,opt,name=includeUninitialized"`
// +k8s:deprecated=includeUninitialized,protobuf=6
// Watch for changes to the described resources and return them as a stream of
// add, update, and remove notifications. Specify resourceVersion.
// +optional
Watch bool `json:"watch,omitempty" protobuf:"varint,3,opt,name=watch"`
// allowWatchBookmarks requests watch events with type "BOOKMARK".
// Servers that do not implement bookmarks may ignore this flag and
// bookmarks are sent at the server's discretion. Clients should not
// assume bookmarks are returned at any specific interval, nor may they
// assume the server will send any BOOKMARK event during a session.
// If this is not a watch, this field is ignored.
// If the feature gate WatchBookmarks is not enabled in apiserver,
// this field is ignored.
//
// This field is beta.
//
// +optional
AllowWatchBookmarks bool `json:"allowWatchBookmarks,omitempty" protobuf:"varint,9,opt,name=allowWatchBookmarks"`
// 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:
@@ -384,11 +398,14 @@ type ListOptions struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// ExportOptions is the query options to the standard REST get call.
// Deprecated. Planned for removal in 1.18.
type ExportOptions struct {
TypeMeta `json:",inline"`
// Should this value be exported. Export strips fields that a user can not specify.
// Deprecated. Planned for removal in 1.18.
Export bool `json:"export" protobuf:"varint,1,opt,name=export"`
// Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'.
// Deprecated. Planned for removal in 1.18.
Exact bool `json:"exact" protobuf:"varint,2,opt,name=exact"`
}
@@ -402,9 +419,7 @@ type GetOptions struct {
// - 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 `json:"resourceVersion,omitempty" protobuf:"bytes,1,opt,name=resourceVersion"`
// If true, partially initialized resources are included in the response.
// +optional
IncludeUninitialized bool `json:"includeUninitialized,omitempty" protobuf:"varint,2,opt,name=includeUninitialized"`
// +k8s:deprecated=includeUninitialized,protobuf=2
}
// DeletionPropagation decides if a deletion will propagate to the dependents of
@@ -489,15 +504,52 @@ type CreateOptions struct {
// - All: all dry run stages will be processed
// +optional
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"`
// +k8s:deprecated=includeUninitialized,protobuf=2
// If IncludeUninitialized is specified, the object may be
// returned without completing initialization.
IncludeUninitialized bool `json:"includeUninitialized,omitempty" protobuf:"varint,2,opt,name=includeUninitialized"`
// fieldManager is a name associated with the actor or entity
// that is making these changes. The value must be less than or
// 128 characters long, and only contain printable characters,
// as defined by https://golang.org/pkg/unicode/#IsPrint.
// +optional
FieldManager string `json:"fieldManager,omitempty" protobuf:"bytes,3,name=fieldManager"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PatchOptions may be provided when patching an API object.
// PatchOptions is meant to be a superset of UpdateOptions.
type PatchOptions struct {
TypeMeta `json:",inline"`
// When present, indicates that modifications should not be
// persisted. An invalid or unrecognized dryRun directive will
// result in an error response and no further processing of the
// request. Valid values are:
// - All: all dry run stages will be processed
// +optional
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"`
// Force is going to "force" Apply requests. It means user will
// re-acquire conflicting fields owned by other people. Force
// flag must be unset for non-apply patch requests.
// +optional
Force *bool `json:"force,omitempty" protobuf:"varint,2,opt,name=force"`
// fieldManager is a name associated with the actor or entity
// that is making these changes. The value must be less than or
// 128 characters long, and only contain printable characters,
// as defined by https://golang.org/pkg/unicode/#IsPrint. This
// field is required for apply requests
// (application/apply-patch) but optional for non-apply patch
// types (JsonPatch, MergePatch, StrategicMergePatch).
// +optional
FieldManager string `json:"fieldManager,omitempty" protobuf:"bytes,3,name=fieldManager"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// UpdateOptions may be provided when updating an API object.
// All fields in UpdateOptions should also be present in PatchOptions.
type UpdateOptions struct {
TypeMeta `json:",inline"`
@@ -508,6 +560,13 @@ type UpdateOptions struct {
// - All: all dry run stages will be processed
// +optional
DryRun []string `json:"dryRun,omitempty" protobuf:"bytes,1,rep,name=dryRun"`
// fieldManager is a name associated with the actor or entity
// that is making these changes. The value must be less than or
// 128 characters long, and only contain printable characters,
// as defined by https://golang.org/pkg/unicode/#IsPrint.
// +optional
FieldManager string `json:"fieldManager,omitempty" protobuf:"bytes,2,name=fieldManager"`
}
// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
@@ -515,6 +574,9 @@ type Preconditions struct {
// Specifies the target UID.
// +optional
UID *types.UID `json:"uid,omitempty" protobuf:"bytes,1,opt,name=uid,casttype=k8s.io/apimachinery/pkg/types.UID"`
// Specifies the target ResourceVersion
// +optional
ResourceVersion *string `json:"resourceVersion,omitempty" protobuf:"bytes,2,opt,name=resourceVersion"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -523,13 +585,13 @@ type Preconditions struct {
type Status struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Status of the operation.
// One of: "Success" or "Failure".
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
// +optional
Status string `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"`
// A human-readable description of the status of this operation.
@@ -568,7 +630,7 @@ type StatusDetails struct {
Group string `json:"group,omitempty" protobuf:"bytes,2,opt,name=group"`
// The kind attribute of the resource associated with the status StatusReason.
// On some operations may differ from the requested resource Kind.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"`
// UID of the resource.
@@ -700,11 +762,13 @@ const (
// doesn't make any sense, for example deleting a read-only object. This is different than
// StatusReasonInvalid above which indicates that the API call could possibly succeed, but the
// data was invalid. API calls that return BadRequest can never succeed.
// Status code 400
StatusReasonBadRequest StatusReason = "BadRequest"
// StatusReasonMethodNotAllowed means that the action the client attempted to perform on the
// resource was not supported by the code - for instance, attempting to delete a resource that
// can only be created. API calls that return MethodNotAllowed can never succeed.
// Status code 405
StatusReasonMethodNotAllowed StatusReason = "MethodNotAllowed"
// StatusReasonNotAcceptable means that the accept types indicated by the client were not acceptable
@@ -792,6 +856,9 @@ const (
// without the expected return type. The presence of this cause indicates the error may be
// due to an intervening proxy or the server software malfunctioning.
CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse"
// FieldManagerConflict is used to report when another client claims to manage this field,
// It should only be returned for a request using server-side apply.
CauseTypeFieldManagerConflict CauseType = "FieldManagerConflict"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
@@ -800,7 +867,7 @@ const (
type List struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
@@ -906,6 +973,15 @@ type APIResource struct {
ShortNames []string `json:"shortNames,omitempty" protobuf:"bytes,5,rep,name=shortNames"`
// categories is a list of the grouped resources this resource belongs to (e.g. 'all')
Categories []string `json:"categories,omitempty" protobuf:"bytes,7,rep,name=categories"`
// The hash value of the storage version, the version this resource is
// converted to when written to the data store. Value must be treated
// as opaque by clients. Only equality comparison on the value is valid.
// This is an alpha feature and may change or be removed in the future.
// The field is populated by the apiserver only if the
// StorageVersionHash feature gate is enabled.
// This field will remain optional even if it graduates.
// +optional
StorageVersionHash string `json:"storageVersionHash,omitempty" protobuf:"bytes,10,opt,name=storageVersionHash"`
}
// Verbs masks the value so protobuf can generate
@@ -1007,3 +1083,216 @@ const (
LabelSelectorOpExists LabelSelectorOperator = "Exists"
LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist"
)
// ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource
// that the fieldset applies to.
type ManagedFieldsEntry struct {
// Manager is an identifier of the workflow managing these fields.
Manager string `json:"manager,omitempty" protobuf:"bytes,1,opt,name=manager"`
// Operation is the type of operation which lead to this ManagedFieldsEntry being created.
// The only valid values for this field are 'Apply' and 'Update'.
Operation ManagedFieldsOperationType `json:"operation,omitempty" protobuf:"bytes,2,opt,name=operation,casttype=ManagedFieldsOperationType"`
// APIVersion defines the version of this resource that this field set
// applies to. The format is "group/version" just like the top-level
// APIVersion field. It is necessary to track the version of a field
// set because it cannot be automatically converted.
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,3,opt,name=apiVersion"`
// Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'
// +optional
Time *Time `json:"time,omitempty" protobuf:"bytes,4,opt,name=time"`
// Fields is tombstoned to show why 5 is a reserved protobuf tag.
//Fields *Fields `json:"fields,omitempty" protobuf:"bytes,5,opt,name=fields,casttype=Fields"`
// FieldsType is the discriminator for the different fields format and version.
// There is currently only one possible value: "FieldsV1"
FieldsType string `json:"fieldsType,omitempty" protobuf:"bytes,6,opt,name=fieldsType"`
// FieldsV1 holds the first JSON version format as described in the "FieldsV1" type.
// +optional
FieldsV1 *FieldsV1 `json:"fieldsV1,omitempty" protobuf:"bytes,7,opt,name=fieldsV1"`
}
// ManagedFieldsOperationType is the type of operation which lead to a ManagedFieldsEntry being created.
type ManagedFieldsOperationType string
const (
ManagedFieldsOperationApply ManagedFieldsOperationType = "Apply"
ManagedFieldsOperationUpdate ManagedFieldsOperationType = "Update"
)
// FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.
//
// Each key is either a '.' representing the field itself, and will always map to an empty set,
// or a string representing a sub-field or item. The string will follow one of these four formats:
// 'f:<name>', where <name> is the name of a field in a struct, or key in a map
// 'v:<value>', where <value> is the exact json formatted value of a list item
// 'i:<index>', where <index> is position of a item in a list
// 'k:<keys>', where <keys> is a map of a list item's key fields to their unique values
// If a key maps to an empty Fields value, the field that key represents is part of the set.
//
// The exact format is defined in sigs.k8s.io/structured-merge-diff
type FieldsV1 struct {
// Raw is the underlying serialization of this object.
Raw []byte `json:"-" protobuf:"bytes,1,opt,name=Raw"`
}
// TODO: Table does not generate to protobuf because of the interface{} - fix protobuf
// generation to support a meta type that can accept any valid JSON. This can be introduced
// in a v1 because clients a) receive an error if they try to access proto today, and b)
// once introduced they would be able to gracefully switch over to using it.
// 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.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +protobuf=false
type Table struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
ListMeta `json:"metadata,omitempty"`
// columnDefinitions describes each column in the returned items array. The number of cells per row
// will always match the number of column definitions.
ColumnDefinitions []TableColumnDefinition `json:"columnDefinitions"`
// rows is the list of items in the table.
Rows []TableRow `json:"rows"`
}
// TableColumnDefinition contains information about a column returned in the Table.
// +protobuf=false
type TableColumnDefinition struct {
// name is a human readable name for the column.
Name string `json:"name"`
// type is an OpenAPI type definition for this column, such as number, integer, string, or
// array.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
Type string `json:"type"`
// format is an optional OpenAPI type modifier for this column. A format modifies the type and
// imposes additional rules, like date or time formatting for a string. The 'name' format is applied
// to the primary identifier column which has type 'string' to assist in clients identifying column
// is the resource name.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
Format string `json:"format"`
// description is a human readable description of this column.
Description string `json:"description"`
// priority is an integer defining the relative importance of this column compared to others. Lower
// numbers are considered higher priority. Columns that may be omitted in limited space scenarios
// should be given a higher priority.
Priority int32 `json:"priority"`
}
// TableRow is an individual row in a table.
// +protobuf=false
type TableRow struct {
// cells will be as wide as the column definitions array and may contain strings, numbers (float64 or
// int64), booleans, simple maps, lists, or null. See the type field of the column definition for a
// more detailed description.
Cells []interface{} `json:"cells"`
// conditions describe additional status of a row that are relevant for a human user. These conditions
// apply to the row, not to the object, and will be specific to table output. The only defined
// condition type is 'Completed', for a row that indicates a resource that has run to completion and
// can be given less visual priority.
// +optional
Conditions []TableRowCondition `json:"conditions,omitempty"`
// This field contains the requested additional information about each object based on the includeObject
// policy when requesting the Table. If "None", this field is empty, if "Object" this will be the
// default serialization of the object for the current API version, and if "Metadata" (the default) will
// contain the object metadata. Check the returned kind and apiVersion of the object before parsing.
// The media type of the object will always match the enclosing list - if this as a JSON table, these
// will be JSON encoded objects.
// +optional
Object runtime.RawExtension `json:"object,omitempty"`
}
// TableRowCondition allows a row to be marked with additional information.
// +protobuf=false
type TableRowCondition struct {
// Type of row condition. The only defined value is 'Completed' indicating that the
// object this row represents has reached a completed state and may be given less visual
// priority than other rows. Clients are not required to honor any conditions but should
// be consistent where possible about handling the conditions.
Type RowConditionType `json:"type"`
// Status of the condition, one of True, False, Unknown.
Status ConditionStatus `json:"status"`
// (brief) machine readable reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty"`
// Human readable message indicating details about last transition.
// +optional
Message string `json:"message,omitempty"`
}
type RowConditionType string
// These are valid conditions of a row. This list is not exhaustive and new conditions may be
// included by other resources.
const (
// RowCompleted means the underlying resource has reached completion and may be given less
// visual priority than other resources.
RowCompleted RowConditionType = "Completed"
)
type ConditionStatus string
// These are valid condition statuses. "ConditionTrue" means a resource is in the condition.
// "ConditionFalse" means a resource is not in the condition. "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionTrue ConditionStatus = "True"
ConditionFalse ConditionStatus = "False"
ConditionUnknown ConditionStatus = "Unknown"
)
// IncludeObjectPolicy controls which portion of the object is returned with a Table.
type IncludeObjectPolicy string
const (
// IncludeNone returns no object.
IncludeNone IncludeObjectPolicy = "None"
// IncludeMetadata serializes the object containing only its metadata field.
IncludeMetadata IncludeObjectPolicy = "Metadata"
// IncludeObject contains the full object.
IncludeObject IncludeObjectPolicy = "Object"
)
// TableOptions are used when a Table is requested by the caller.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TableOptions struct {
TypeMeta `json:",inline"`
// NoHeaders is only exposed for internal callers. It is not included in our OpenAPI definitions
// and may be removed as a field in a future release.
NoHeaders bool `json:"-"`
// 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
// specifying "Metadata" (the default) will return the object's metadata in the PartialObjectMetadata kind
// in version v1beta1 of the meta.k8s.io API group.
IncludeObject IncludeObjectPolicy `json:"includeObject,omitempty" protobuf:"bytes,1,opt,name=includeObject,casttype=IncludeObjectPolicy"`
}
// 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 {
TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
// +optional
ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
}
// PartialObjectMetadataList contains a list of objects containing only their metadata
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type PartialObjectMetadataList struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// items contains each of the included items.
Items []PartialObjectMetadata `json:"items" protobuf:"bytes,2,rep,name=items"`
}

View File

@@ -49,16 +49,17 @@ func (APIGroupList) SwaggerDoc() map[string]string {
}
var map_APIResource = map[string]string{
"": "APIResource specifies the name of a resource and whether it is namespaced.",
"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.",
"categories": "categories is a list of the grouped resources this resource belongs to (e.g. 'all')",
"": "APIResource specifies the name of a resource and whether it is namespaced.",
"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.",
"categories": "categories is a list of the grouped resources this resource belongs to (e.g. 'all')",
"storageVersionHash": "The hash value of the storage version, the version this resource is converted to when written to the data store. Value must be treated as opaque by clients. Only equality comparison on the value is valid. This is an alpha feature and may change or be removed in the future. The field is populated by the apiserver only if the StorageVersionHash feature gate is enabled. This field will remain optional even if it graduates.",
}
func (APIResource) SwaggerDoc() map[string]string {
@@ -86,9 +87,9 @@ func (APIVersions) SwaggerDoc() map[string]string {
}
var map_CreateOptions = map[string]string{
"": "CreateOptions may be provided when creating an API object.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"includeUninitialized": "If IncludeUninitialized is specified, the object may be returned without completing initialization.",
"": "CreateOptions may be provided when creating an API object.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.",
}
func (CreateOptions) SwaggerDoc() map[string]string {
@@ -109,19 +110,26 @@ func (DeleteOptions) SwaggerDoc() map[string]string {
}
var map_ExportOptions = map[string]string{
"": "ExportOptions is the query options to the standard REST get call.",
"export": "Should this value be exported. Export strips fields that a user can not specify.",
"exact": "Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'.",
"": "ExportOptions is the query options to the standard REST get call. Deprecated. Planned for removal in 1.18.",
"export": "Should this value be exported. Export strips fields that a user can not specify. Deprecated. Planned for removal in 1.18.",
"exact": "Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'. Deprecated. Planned for removal in 1.18.",
}
func (ExportOptions) SwaggerDoc() map[string]string {
return map_ExportOptions
}
var map_FieldsV1 = map[string]string{
"": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:<name>', where <name> is the name of a field in a struct, or key in a map 'v:<value>', where <value> is the exact json formatted value of a list item 'i:<index>', where <index> is position of a item in a list 'k:<keys>', where <keys> is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff",
}
func (FieldsV1) SwaggerDoc() map[string]string {
return map_FieldsV1
}
var map_GetOptions = map[string]string{
"": "GetOptions is the standard query options to the standard REST get call.",
"resourceVersion": "When specified: - 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.",
"includeUninitialized": "If true, partially initialized resources are included in the response.",
"": "GetOptions is the standard query options to the standard REST get call.",
"resourceVersion": "When specified: - 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.",
}
func (GetOptions) SwaggerDoc() map[string]string {
@@ -138,25 +146,6 @@ func (GroupVersionForDiscovery) SwaggerDoc() map[string]string {
return map_GroupVersionForDiscovery
}
var map_Initializer = map[string]string{
"": "Initializer is information about an initializer that has not yet completed.",
"name": "name of the process that is responsible for initializing this object.",
}
func (Initializer) SwaggerDoc() map[string]string {
return map_Initializer
}
var map_Initializers = map[string]string{
"": "Initializers tracks the progress of initialization.",
"pending": "Pending is a list of initializers that must execute in order before this object is visible. 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.",
"result": "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.",
}
func (Initializers) SwaggerDoc() map[string]string {
return map_Initializers
}
var map_LabelSelector = map[string]string{
"": "A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.",
"matchLabels": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is \"key\", the operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
@@ -180,7 +169,7 @@ func (LabelSelectorRequirement) SwaggerDoc() map[string]string {
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",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "List of objects",
}
@@ -189,10 +178,11 @@ func (List) SwaggerDoc() map[string]string {
}
var map_ListMeta = map[string]string{
"": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.",
"selfLink": "selfLink is a URL representing this object. Populated by the system. Read-only.",
"resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: 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 consistent 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, unless you have received this token from an error message.",
"": "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.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.",
"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/sig-architecture/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 consistent 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, unless you have received this token from an error message.",
"remainingItemCount": "remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact.",
}
func (ListMeta) SwaggerDoc() map[string]string {
@@ -200,39 +190,53 @@ func (ListMeta) SwaggerDoc() map[string]string {
}
var map_ListOptions = map[string]string{
"": "ListOptions is the query options to a standard REST list call.",
"labelSelector": "A selector to restrict the list of returned objects by their labels. Defaults to everything.",
"fieldSelector": "A selector to restrict the list of returned objects by their fields. Defaults to everything.",
"includeUninitialized": "If true, partially initialized resources are included in the response.",
"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. This limits the duration of the call, regardless of any activity or inactivity.",
"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 together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis 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.",
"": "ListOptions is the query options to a standard REST list call.",
"labelSelector": "A selector to restrict the list of returned objects by their labels. Defaults to everything.",
"fieldSelector": "A selector to restrict the list of returned objects by their fields. Defaults to everything.",
"watch": "Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion.",
"allowWatchBookmarks": "allowWatchBookmarks requests watch events with type \"BOOKMARK\". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. If the feature gate WatchBookmarks is not enabled in apiserver, this field is ignored.\n\nThis field is beta.",
"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. This limits the duration of the call, regardless of any activity or inactivity.",
"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 together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\".\n\nThis 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 {
return map_ListOptions
}
var map_ManagedFieldsEntry = map[string]string{
"": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.",
"manager": "Manager is an identifier of the workflow managing these fields.",
"operation": "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.",
"apiVersion": "APIVersion defines the version of this resource that this field set applies to. The format is \"group/version\" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.",
"time": "Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'",
"fieldsType": "FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: \"FieldsV1\"",
"fieldsV1": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type.",
}
func (ManagedFieldsEntry) SwaggerDoc() map[string]string {
return map_ManagedFieldsEntry
}
var map_ObjectMeta = map[string]string{
"": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.",
"name": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
"generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#idempotency",
"generateName": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency",
"namespace": "Namespace defines the space within each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces",
"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.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.",
"uid": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
"resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#concurrency-control-and-consistency",
"resourceVersion": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency",
"generation": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.",
"creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata",
"deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata",
"creationTimestamp": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
"deletionTimestamp": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
"deletionGracePeriodSeconds": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.",
"labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels",
"annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations",
"ownerReferences": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.",
"initializers": "An initializer is a controller which enforces some system invariant at object creation time. This field is a list of initializers that have not yet acted on this object. If nil or empty, this object has been completely initialized. Otherwise, the object is considered uninitialized and is hidden (in list/watch and get calls) from clients that haven't explicitly asked to observe uninitialized objects.\n\nWhen an object is created, the system will populate this list with the current set of initializers. Only privileged users may set or modify this list. Once it is empty, it may not be modified further by any user.",
"finalizers": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed.",
"clusterName": "The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.",
"managedFields": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.",
}
func (ObjectMeta) SwaggerDoc() map[string]string {
@@ -242,7 +246,7 @@ func (ObjectMeta) SwaggerDoc() map[string]string {
var map_OwnerReference = map[string]string{
"": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.",
"apiVersion": "API version of the referent.",
"kind": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"kind": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"name": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
"uid": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
"controller": "If true, this reference points to the managing controller.",
@@ -253,6 +257,25 @@ func (OwnerReference) SwaggerDoc() map[string]string {
return map_OwnerReference
}
var map_PartialObjectMetadata = map[string]string{
"": "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.",
"metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
}
func (PartialObjectMetadata) SwaggerDoc() map[string]string {
return map_PartialObjectMetadata
}
var map_PartialObjectMetadataList = map[string]string{
"": "PartialObjectMetadataList contains a list of objects containing only their metadata",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "items contains each of the included items.",
}
func (PartialObjectMetadataList) SwaggerDoc() map[string]string {
return map_PartialObjectMetadataList
}
var map_Patch = map[string]string{
"": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.",
}
@@ -261,9 +284,21 @@ func (Patch) SwaggerDoc() map[string]string {
return map_Patch
}
var map_PatchOptions = map[string]string{
"": "PatchOptions may be provided when patching an API object. PatchOptions is meant to be a superset of UpdateOptions.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"force": "Force is going to \"force\" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests.",
"fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch).",
}
func (PatchOptions) SwaggerDoc() map[string]string {
return map_PatchOptions
}
var map_Preconditions = map[string]string{
"": "Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.",
"uid": "Specifies the target UID.",
"": "Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.",
"uid": "Specifies the target UID.",
"resourceVersion": "Specifies the target ResourceVersion",
}
func (Preconditions) SwaggerDoc() map[string]string {
@@ -291,8 +326,8 @@ func (ServerAddressByClientCIDR) SwaggerDoc() map[string]string {
var map_Status = map[string]string{
"": "Status is a return value for calls that don't return other objects.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status",
"message": "A human-readable description of the status of this operation.",
"reason": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.",
"details": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.",
@@ -318,7 +353,7 @@ var map_StatusDetails = map[string]string{
"": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.",
"name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).",
"group": "The group attribute of the resource associated with the status StatusReason.",
"kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"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/sig-architecture/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. 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.",
@@ -328,10 +363,66 @@ func (StatusDetails) SwaggerDoc() map[string]string {
return map_StatusDetails
}
var map_Table = map[string]string{
"": "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.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"columnDefinitions": "columnDefinitions describes each column in the returned items array. The number of cells per row will always match the number of column definitions.",
"rows": "rows is the list of items in the table.",
}
func (Table) SwaggerDoc() map[string]string {
return map_Table
}
var map_TableColumnDefinition = map[string]string{
"": "TableColumnDefinition contains information about a column returned in the Table.",
"name": "name is a human readable name for the column.",
"type": "type is an OpenAPI type definition for this column, such as number, integer, string, or array. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.",
"format": "format is an optional OpenAPI type modifier for this column. A format modifies the type and imposes additional rules, like date or time formatting for a string. The 'name' format is applied to the primary identifier column which has type 'string' to assist in clients identifying column is the resource name. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.",
"description": "description is a human readable description of this column.",
"priority": "priority is an integer defining the relative importance of this column compared to others. Lower numbers are considered higher priority. Columns that may be omitted in limited space scenarios should be given a higher priority.",
}
func (TableColumnDefinition) SwaggerDoc() map[string]string {
return map_TableColumnDefinition
}
var map_TableOptions = map[string]string{
"": "TableOptions are used when a Table is requested by the caller.",
"includeObject": "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 specifying \"Metadata\" (the default) will return the object's metadata in the PartialObjectMetadata kind in version v1beta1 of the meta.k8s.io API group.",
}
func (TableOptions) SwaggerDoc() map[string]string {
return map_TableOptions
}
var map_TableRow = map[string]string{
"": "TableRow is an individual row in a table.",
"cells": "cells will be as wide as the column definitions array and may contain strings, numbers (float64 or int64), booleans, simple maps, lists, or null. See the type field of the column definition for a more detailed description.",
"conditions": "conditions describe additional status of a row that are relevant for a human user. These conditions apply to the row, not to the object, and will be specific to table output. The only defined condition type is 'Completed', for a row that indicates a resource that has run to completion and can be given less visual priority.",
"object": "This field contains the requested additional information about each object based on the includeObject policy when requesting the Table. If \"None\", this field is empty, if \"Object\" this will be the default serialization of the object for the current API version, and if \"Metadata\" (the default) will contain the object metadata. Check the returned kind and apiVersion of the object before parsing. The media type of the object will always match the enclosing list - if this as a JSON table, these will be JSON encoded objects.",
}
func (TableRow) SwaggerDoc() map[string]string {
return map_TableRow
}
var map_TableRowCondition = map[string]string{
"": "TableRowCondition allows a row to be marked with additional information.",
"type": "Type of row condition. The only defined value is 'Completed' indicating that the object this row represents has reached a completed state and may be given less visual priority than other rows. Clients are not required to honor any conditions but should be consistent where possible about handling the conditions.",
"status": "Status of the condition, one of True, False, Unknown.",
"reason": "(brief) machine readable reason for the condition's last transition.",
"message": "Human readable message indicating details about last transition.",
}
func (TableRowCondition) SwaggerDoc() map[string]string {
return map_TableRowCondition
}
var map_TypeMeta = map[string]string{
"": "TypeMeta describes an individual object in an API response or request with strings representing the type of the object and its API schema version. Structures that are versioned or persisted should inline TypeMeta.",
"kind": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"apiVersion": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources",
"kind": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"apiVersion": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
}
func (TypeMeta) SwaggerDoc() map[string]string {
@@ -339,8 +430,9 @@ func (TypeMeta) SwaggerDoc() map[string]string {
}
var map_UpdateOptions = map[string]string{
"": "UpdateOptions may be provided when updating an API object.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"": "UpdateOptions may be provided when updating an API object. All fields in UpdateOptions should also be present in PatchOptions.",
"dryRun": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
"fieldManager": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.",
}
func (UpdateOptions) SwaggerDoc() map[string]string {

View File

@@ -32,6 +32,9 @@ import (
// NestedFieldCopy returns a deep copy of the value of a nested field.
// Returns false if the value is missing.
// No error is returned for a nil field.
//
// Note: fields passed to this function are treated as keys within the passed
// object; no array/slice syntax is supported.
func NestedFieldCopy(obj map[string]interface{}, fields ...string) (interface{}, bool, error) {
val, found, err := NestedFieldNoCopy(obj, fields...)
if !found || err != nil {
@@ -43,10 +46,16 @@ func NestedFieldCopy(obj map[string]interface{}, fields ...string) (interface{},
// NestedFieldNoCopy returns a reference to a nested field.
// Returns false if value is not found and an error if unable
// to traverse obj.
//
// Note: fields passed to this function are treated as keys within the passed
// object; no array/slice syntax is supported.
func NestedFieldNoCopy(obj map[string]interface{}, fields ...string) (interface{}, bool, error) {
var val interface{} = obj
for i, field := range fields {
if val == nil {
return nil, false, nil
}
if m, ok := val.(map[string]interface{}); ok {
val, ok = m[field]
if !ok {
@@ -272,6 +281,22 @@ func getNestedString(obj map[string]interface{}, fields ...string) string {
return val
}
func getNestedInt64(obj map[string]interface{}, fields ...string) int64 {
val, found, err := NestedInt64(obj, fields...)
if !found || err != nil {
return 0
}
return val
}
func getNestedInt64Pointer(obj map[string]interface{}, fields ...string) *int64 {
val, found, err := NestedInt64(obj, fields...)
if !found || err != nil {
return nil
}
return &val
}
func jsonPath(fields []string) string {
return "." + strings.Join(fields, ".")
}

View File

@@ -47,6 +47,7 @@ type Unstructured struct {
var _ metav1.Object = &Unstructured{}
var _ runtime.Unstructured = &Unstructured{}
var _ metav1.ListInterface = &Unstructured{}
func (obj *Unstructured) GetObjectKind() schema.ObjectKind { return obj }
@@ -126,6 +127,16 @@ func (u *Unstructured) UnmarshalJSON(b []byte) error {
return err
}
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
func (in *Unstructured) NewEmptyInstance() runtime.Unstructured {
out := new(Unstructured)
if in != nil {
out.GetObjectKind().SetGroupVersionKind(in.GetObjectKind().GroupVersionKind())
}
return out
}
func (in *Unstructured) DeepCopy() *Unstructured {
if in == nil {
return nil
@@ -143,13 +154,20 @@ func (u *Unstructured) setNestedField(value interface{}, fields ...string) {
SetNestedField(u.Object, value, fields...)
}
func (u *Unstructured) setNestedSlice(value []string, fields ...string) {
func (u *Unstructured) setNestedStringSlice(value []string, fields ...string) {
if u.Object == nil {
u.Object = make(map[string]interface{})
}
SetNestedStringSlice(u.Object, value, fields...)
}
func (u *Unstructured) setNestedSlice(value []interface{}, fields ...string) {
if u.Object == nil {
u.Object = make(map[string]interface{})
}
SetNestedSlice(u.Object, value, fields...)
}
func (u *Unstructured) setNestedMap(value map[string]string, fields ...string) {
if u.Object == nil {
u.Object = make(map[string]interface{})
@@ -312,6 +330,18 @@ func (u *Unstructured) SetContinue(c string) {
u.setNestedField(c, "metadata", "continue")
}
func (u *Unstructured) GetRemainingItemCount() *int64 {
return getNestedInt64Pointer(u.Object, "metadata", "remainingItemCount")
}
func (u *Unstructured) SetRemainingItemCount(c *int64) {
if c == nil {
RemoveNestedField(u.Object, "metadata", "remainingItemCount")
} else {
u.setNestedField(*c, "metadata", "remainingItemCount")
}
}
func (u *Unstructured) GetCreationTimestamp() metav1.Time {
var timestamp metav1.Time
timestamp.UnmarshalQueryParameter(getNestedString(u.Object, "metadata", "creationTimestamp"))
@@ -401,31 +431,6 @@ func (u *Unstructured) GroupVersionKind() schema.GroupVersionKind {
return gvk
}
func (u *Unstructured) GetInitializers() *metav1.Initializers {
m, found, err := nestedMapNoCopy(u.Object, "metadata", "initializers")
if !found || err != nil {
return nil
}
out := &metav1.Initializers{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(m, out); err != nil {
utilruntime.HandleError(fmt.Errorf("unable to retrieve initializers for object: %v", err))
return nil
}
return out
}
func (u *Unstructured) SetInitializers(initializers *metav1.Initializers) {
if initializers == nil {
RemoveNestedField(u.Object, "metadata", "initializers")
return
}
out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(initializers)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to retrieve initializers for object: %v", err))
}
u.setNestedField(out, "metadata", "initializers")
}
func (u *Unstructured) GetFinalizers() []string {
val, _, _ := NestedStringSlice(u.Object, "metadata", "finalizers")
return val
@@ -436,7 +441,7 @@ func (u *Unstructured) SetFinalizers(finalizers []string) {
RemoveNestedField(u.Object, "metadata", "finalizers")
return
}
u.setNestedSlice(finalizers, "metadata", "finalizers")
u.setNestedStringSlice(finalizers, "metadata", "finalizers")
}
func (u *Unstructured) GetClusterName() string {
@@ -450,3 +455,42 @@ func (u *Unstructured) SetClusterName(clusterName string) {
}
u.setNestedField(clusterName, "metadata", "clusterName")
}
func (u *Unstructured) GetManagedFields() []metav1.ManagedFieldsEntry {
items, found, err := NestedSlice(u.Object, "metadata", "managedFields")
if !found || err != nil {
return nil
}
managedFields := []metav1.ManagedFieldsEntry{}
for _, item := range items {
m, ok := item.(map[string]interface{})
if !ok {
utilruntime.HandleError(fmt.Errorf("unable to retrieve managedFields for object, item %v is not a map", item))
return nil
}
out := metav1.ManagedFieldsEntry{}
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(m, &out); err != nil {
utilruntime.HandleError(fmt.Errorf("unable to retrieve managedFields for object: %v", err))
return nil
}
managedFields = append(managedFields, out)
}
return managedFields
}
func (u *Unstructured) SetManagedFields(managedFields []metav1.ManagedFieldsEntry) {
if managedFields == nil {
RemoveNestedField(u.Object, "metadata", "managedFields")
return
}
items := []interface{}{}
for _, managedFieldsEntry := range managedFields {
out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&managedFieldsEntry)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to set managedFields for object: %v", err))
return
}
items = append(items, out)
}
u.setNestedSlice(items, "metadata", "managedFields")
}

View File

@@ -52,6 +52,16 @@ func (u *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
return nil
}
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
func (u *UnstructuredList) NewEmptyInstance() runtime.Unstructured {
out := new(UnstructuredList)
if u != nil {
out.SetGroupVersionKind(u.GroupVersionKind())
}
return out
}
// UnstructuredContent returns a map contain an overlay of the Items field onto
// the Object field. Items always overwrites overlay.
func (u *UnstructuredList) UnstructuredContent() map[string]interface{} {
@@ -166,6 +176,18 @@ func (u *UnstructuredList) SetContinue(c string) {
u.setNestedField(c, "metadata", "continue")
}
func (u *UnstructuredList) GetRemainingItemCount() *int64 {
return getNestedInt64Pointer(u.Object, "metadata", "remainingItemCount")
}
func (u *UnstructuredList) SetRemainingItemCount(c *int64) {
if c == nil {
RemoveNestedField(u.Object, "metadata", "remainingItemCount")
} else {
u.setNestedField(*c, "metadata", "remainingItemCount")
}
}
func (u *UnstructuredList) SetGroupVersionKind(gvk schema.GroupVersionKind) {
u.SetAPIVersion(gvk.GroupVersion().String())
u.SetKind(gvk.Kind)

View File

@@ -17,7 +17,11 @@ limitations under the License.
package validation
import (
"fmt"
"unicode"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -85,21 +89,67 @@ func ValidateDeleteOptions(options *metav1.DeleteOptions) field.ErrorList {
*options.PropagationPolicy != metav1.DeletePropagationOrphan {
allErrs = append(allErrs, field.NotSupported(field.NewPath("propagationPolicy"), options.PropagationPolicy, []string{string(metav1.DeletePropagationForeground), string(metav1.DeletePropagationBackground), string(metav1.DeletePropagationOrphan), "nil"}))
}
allErrs = append(allErrs, validateDryRun(field.NewPath("dryRun"), options.DryRun)...)
allErrs = append(allErrs, ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...)
return allErrs
}
func ValidateCreateOptions(options *metav1.CreateOptions) field.ErrorList {
return validateDryRun(field.NewPath("dryRun"), options.DryRun)
return append(
ValidateFieldManager(options.FieldManager, field.NewPath("fieldManager")),
ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...,
)
}
func ValidateUpdateOptions(options *metav1.UpdateOptions) field.ErrorList {
return validateDryRun(field.NewPath("dryRun"), options.DryRun)
return append(
ValidateFieldManager(options.FieldManager, field.NewPath("fieldManager")),
ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...,
)
}
func ValidatePatchOptions(options *metav1.PatchOptions, patchType types.PatchType) field.ErrorList {
allErrs := field.ErrorList{}
if patchType != types.ApplyPatchType {
if options.Force != nil {
allErrs = append(allErrs, field.Forbidden(field.NewPath("force"), "may not be specified for non-apply patch"))
}
} else {
if options.FieldManager == "" {
// This field is defaulted to "kubectl" by kubectl, but HAS TO be explicitly set by controllers.
allErrs = append(allErrs, field.Required(field.NewPath("fieldManager"), "is required for apply patch"))
}
}
allErrs = append(allErrs, ValidateFieldManager(options.FieldManager, field.NewPath("fieldManager"))...)
allErrs = append(allErrs, ValidateDryRun(field.NewPath("dryRun"), options.DryRun)...)
return allErrs
}
var FieldManagerMaxLength = 128
// ValidateFieldManager valides that the fieldManager is the proper length and
// only has printable characters.
func ValidateFieldManager(fieldManager string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
// the field can not be set as a `*string`, so a empty string ("") is
// considered as not set and is defaulted by the rest of the process
// (unless apply is used, in which case it is required).
if len(fieldManager) > FieldManagerMaxLength {
allErrs = append(allErrs, field.TooLong(fldPath, fieldManager, FieldManagerMaxLength))
}
// Verify that all characters are printable.
for i, r := range fieldManager {
if !unicode.IsPrint(r) {
allErrs = append(allErrs, field.Invalid(fldPath, fieldManager, fmt.Sprintf("invalid character %#U (at position %d)", r, i)))
}
}
return allErrs
}
var allowedDryRunValues = sets.NewString(metav1.DryRunAll)
func validateDryRun(fldPath *field.Path, dryRun []string) field.ErrorList {
// ValidateDryRun validates that a dryRun query param only contains allowed values.
func ValidateDryRun(fldPath *field.Path, dryRun []string) field.ErrorList {
allErrs := field.ErrorList{}
if !allowedDryRunValues.HasAll(dryRun...) {
allErrs = append(allErrs, field.NotSupported(fldPath, dryRun, allowedDryRunValues.List()))
@@ -108,3 +158,29 @@ func validateDryRun(fldPath *field.Path, dryRun []string) field.ErrorList {
}
const UninitializedStatusUpdateErrorMsg string = `must not update status when the object is uninitialized`
// ValidateTableOptions returns any invalid flags on TableOptions.
func ValidateTableOptions(opts *metav1.TableOptions) field.ErrorList {
var allErrs field.ErrorList
switch opts.IncludeObject {
case metav1.IncludeMetadata, metav1.IncludeNone, metav1.IncludeObject, "":
default:
allErrs = append(allErrs, field.Invalid(field.NewPath("includeObject"), opts.IncludeObject, "must be 'Metadata', 'Object', 'None', or empty"))
}
return allErrs
}
func ValidateManagedFields(fieldsList []metav1.ManagedFieldsEntry, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
for _, fields := range fieldsList {
switch fields.Operation {
case metav1.ManagedFieldsOperationApply, metav1.ManagedFieldsOperationUpdate:
default:
allErrs = append(allErrs, field.Invalid(fldPath.Child("operation"), fields.Operation, "must be `Apply` or `Update`"))
}
if fields.FieldsType != "FieldsV1" {
allErrs = append(allErrs, field.Invalid(fldPath.Child("fieldsType"), fields.FieldsType, "must be `FieldsV1`"))
}
}
return allErrs
}

View File

@@ -312,6 +312,27 @@ func (in *ExportOptions) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *FieldsV1) DeepCopyInto(out *FieldsV1) {
*out = *in
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 FieldsV1.
func (in *FieldsV1) DeepCopy() *FieldsV1 {
if in == nil {
return nil
}
out := new(FieldsV1)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GetOptions) DeepCopyInto(out *GetOptions) {
*out = *in
@@ -433,48 +454,6 @@ func (in *GroupVersionResource) DeepCopy() *GroupVersionResource {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Initializer) DeepCopyInto(out *Initializer) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Initializer.
func (in *Initializer) DeepCopy() *Initializer {
if in == nil {
return nil
}
out := new(Initializer)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Initializers) DeepCopyInto(out *Initializers) {
*out = *in
if in.Pending != nil {
in, out := &in.Pending, &out.Pending
*out = make([]Initializer, len(*in))
copy(*out, *in)
}
if in.Result != nil {
in, out := &in.Result, &out.Result
*out = new(Status)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Initializers.
func (in *Initializers) DeepCopy() *Initializers {
if in == nil {
return nil
}
out := new(Initializers)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InternalEvent) DeepCopyInto(out *InternalEvent) {
*out = *in
@@ -549,7 +528,7 @@ func (in *LabelSelectorRequirement) DeepCopy() *LabelSelectorRequirement {
func (in *List) DeepCopyInto(out *List) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.RawExtension, len(*in))
@@ -581,6 +560,11 @@ func (in *List) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ListMeta) DeepCopyInto(out *ListMeta) {
*out = *in
if in.RemainingItemCount != nil {
in, out := &in.RemainingItemCount, &out.RemainingItemCount
*out = new(int64)
**out = **in
}
return
}
@@ -624,6 +608,31 @@ func (in *ListOptions) DeepCopyObject() runtime.Object {
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ManagedFieldsEntry) DeepCopyInto(out *ManagedFieldsEntry) {
*out = *in
if in.Time != nil {
in, out := &in.Time, &out.Time
*out = (*in).DeepCopy()
}
if in.FieldsV1 != nil {
in, out := &in.FieldsV1, &out.FieldsV1
*out = new(FieldsV1)
(*in).DeepCopyInto(*out)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedFieldsEntry.
func (in *ManagedFieldsEntry) DeepCopy() *ManagedFieldsEntry {
if in == nil {
return nil
}
out := new(ManagedFieldsEntry)
in.DeepCopyInto(out)
return out
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicroTime.
func (in *MicroTime) DeepCopy() *MicroTime {
if in == nil {
@@ -668,16 +677,18 @@ func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Initializers != nil {
in, out := &in.Initializers, &out.Initializers
*out = new(Initializers)
(*in).DeepCopyInto(*out)
}
if in.Finalizers != nil {
in, out := &in.Finalizers, &out.Finalizers
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ManagedFields != nil {
in, out := &in.ManagedFields, &out.ManagedFields
*out = make([]ManagedFieldsEntry, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
@@ -717,6 +728,65 @@ func (in *OwnerReference) DeepCopy() *OwnerReference {
return out
}
// 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
}
return nil
}
// 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
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]PartialObjectMetadata, len(*in))
for i := range *in {
(*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
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Patch) DeepCopyInto(out *Patch) {
*out = *in
@@ -733,6 +803,41 @@ func (in *Patch) DeepCopy() *Patch {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PatchOptions) DeepCopyInto(out *PatchOptions) {
*out = *in
out.TypeMeta = in.TypeMeta
if in.DryRun != nil {
in, out := &in.DryRun, &out.DryRun
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Force != nil {
in, out := &in.Force, &out.Force
*out = new(bool)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PatchOptions.
func (in *PatchOptions) DeepCopy() *PatchOptions {
if in == nil {
return nil
}
out := new(PatchOptions)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *PatchOptions) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Preconditions) DeepCopyInto(out *Preconditions) {
*out = *in
@@ -741,6 +846,11 @@ func (in *Preconditions) DeepCopyInto(out *Preconditions) {
*out = new(types.UID)
**out = **in
}
if in.ResourceVersion != nil {
in, out := &in.ResourceVersion, &out.ResourceVersion
*out = new(string)
**out = **in
}
return
}
@@ -795,7 +905,7 @@ func (in *ServerAddressByClientCIDR) DeepCopy() *ServerAddressByClientCIDR {
func (in *Status) DeepCopyInto(out *Status) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Details != nil {
in, out := &in.Details, &out.Details
*out = new(StatusDetails)
@@ -859,6 +969,108 @@ func (in *StatusDetails) DeepCopy() *StatusDetails {
return out
}
// 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
in.ListMeta.DeepCopyInto(&out.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
}
return nil
}
// 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
}
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
}
// 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 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
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Time.
func (in *Time) DeepCopy() *Time {
if in == nil {

View File

@@ -15,30 +15,3 @@ limitations under the License.
*/
package v1beta1
import "k8s.io/apimachinery/pkg/runtime"
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] = runtime.DeepCopyJSONValue(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
}

View File

@@ -20,4 +20,4 @@ limitations under the License.
// +groupName=meta.k8s.io
package v1beta1
package v1beta1 // import "k8s.io/apimachinery/pkg/apis/meta/v1beta1"

View File

@@ -17,27 +17,21 @@ limitations under the License.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
/*
Package v1beta1 is a generated protocol buffer package.
It is generated from these files:
k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
It has these top-level messages:
PartialObjectMetadata
PartialObjectMetadataList
TableOptions
*/
package v1beta1
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
import strings "strings"
import reflect "reflect"
io "io"
import io "io"
proto "github.com/gogo/protobuf/proto"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
math "math"
math_bits "math/bits"
reflect "reflect"
strings "strings"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@@ -50,55 +44,71 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
func (m *PartialObjectMetadata) Reset() { *m = PartialObjectMetadata{} }
func (*PartialObjectMetadata) ProtoMessage() {}
func (*PartialObjectMetadata) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
func (m *PartialObjectMetadataList) Reset() { *m = PartialObjectMetadataList{} }
func (*PartialObjectMetadataList) ProtoMessage() {}
func (*PartialObjectMetadataList) Descriptor() ([]byte, []int) {
return fileDescriptorGenerated, []int{1}
return fileDescriptor_90ec10f86b91f9a8, []int{0}
}
func (m *TableOptions) Reset() { *m = TableOptions{} }
func (*TableOptions) ProtoMessage() {}
func (*TableOptions) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} }
func init() {
proto.RegisterType((*PartialObjectMetadata)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1beta1.PartialObjectMetadata")
proto.RegisterType((*PartialObjectMetadataList)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1beta1.PartialObjectMetadataList")
proto.RegisterType((*TableOptions)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1beta1.TableOptions")
func (m *PartialObjectMetadataList) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PartialObjectMetadata) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
func (m *PartialObjectMetadataList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return dAtA[:n], nil
return b[:n], nil
}
func (m *PartialObjectMetadataList) XXX_Merge(src proto.Message) {
xxx_messageInfo_PartialObjectMetadataList.Merge(m, src)
}
func (m *PartialObjectMetadataList) XXX_Size() int {
return m.Size()
}
func (m *PartialObjectMetadataList) XXX_DiscardUnknown() {
xxx_messageInfo_PartialObjectMetadataList.DiscardUnknown(m)
}
func (m *PartialObjectMetadata) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.ObjectMeta.Size()))
n1, err := m.ObjectMeta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n1
return i, nil
var xxx_messageInfo_PartialObjectMetadataList proto.InternalMessageInfo
func init() {
proto.RegisterType((*PartialObjectMetadataList)(nil), "k8s.io.apimachinery.pkg.apis.meta.v1beta1.PartialObjectMetadataList")
}
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto", fileDescriptor_90ec10f86b91f9a8)
}
var fileDescriptor_90ec10f86b91f9a8 = []byte{
// 321 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0x41, 0x4b, 0xf3, 0x30,
0x18, 0xc7, 0x9b, 0xf7, 0x65, 0x38, 0x3a, 0x04, 0xd9, 0x69, 0xee, 0x90, 0x0d, 0x4f, 0xf3, 0xb0,
0x84, 0x0d, 0x11, 0xc1, 0xdb, 0x6e, 0x82, 0xa2, 0xec, 0x28, 0x1e, 0x4c, 0xbb, 0xc7, 0x2e, 0xd6,
0x34, 0x25, 0x79, 0x3a, 0xf0, 0xe6, 0x47, 0xf0, 0x63, 0xed, 0xb8, 0xe3, 0x40, 0x18, 0xae, 0x7e,
0x11, 0x49, 0x57, 0x45, 0xa6, 0x62, 0x6f, 0x79, 0xfe, 0xe1, 0xf7, 0xcb, 0x3f, 0x89, 0x3f, 0x8e,
0x4f, 0x2c, 0x93, 0x9a, 0xc7, 0x59, 0x00, 0x26, 0x01, 0x04, 0xcb, 0x67, 0x90, 0x4c, 0xb4, 0xe1,
0xe5, 0x86, 0x48, 0xa5, 0x12, 0xe1, 0x54, 0x26, 0x60, 0x1e, 0x79, 0x1a, 0x47, 0x2e, 0xb0, 0x5c,
0x01, 0x0a, 0x3e, 0x1b, 0x04, 0x80, 0x62, 0xc0, 0x23, 0x48, 0xc0, 0x08, 0x84, 0x09, 0x4b, 0x8d,
0x46, 0xdd, 0x3c, 0xdc, 0xa0, 0xec, 0x2b, 0xca, 0xd2, 0x38, 0x72, 0x81, 0x65, 0x0e, 0x65, 0x25,
0xda, 0xee, 0x47, 0x12, 0xa7, 0x59, 0xc0, 0x42, 0xad, 0x78, 0xa4, 0x23, 0xcd, 0x0b, 0x43, 0x90,
0xdd, 0x15, 0x53, 0x31, 0x14, 0xab, 0x8d, 0xb9, 0x7d, 0x54, 0xa5, 0xd4, 0x76, 0x9f, 0xf6, 0xaf,
0x57, 0x31, 0x59, 0x82, 0x52, 0xc1, 0x37, 0xe0, 0xf8, 0x2f, 0xc0, 0x86, 0x53, 0x50, 0x62, 0x9b,
0x3b, 0x78, 0x21, 0xfe, 0xfe, 0x95, 0x30, 0x28, 0xc5, 0xc3, 0x65, 0x70, 0x0f, 0x21, 0x5e, 0x00,
0x8a, 0x89, 0x40, 0x71, 0x2e, 0x2d, 0x36, 0x6f, 0xfc, 0xba, 0x2a, 0xe7, 0xd6, 0xbf, 0x2e, 0xe9,
0x35, 0x86, 0x8c, 0x55, 0x79, 0x29, 0xe6, 0x68, 0x67, 0x1a, 0xed, 0xcd, 0x57, 0x1d, 0x2f, 0x5f,
0x75, 0xea, 0x1f, 0xc9, 0xf8, 0xd3, 0xd8, 0xbc, 0xf5, 0x6b, 0x12, 0x41, 0xd9, 0x16, 0xe9, 0xfe,
0xef, 0x35, 0x86, 0xa7, 0xd5, 0xd4, 0x3f, 0xb6, 0x1d, 0xed, 0x96, 0xe7, 0xd4, 0xce, 0x9c, 0x71,
0xbc, 0x11, 0x8f, 0xfa, 0xf3, 0x35, 0xf5, 0x16, 0x6b, 0xea, 0x2d, 0xd7, 0xd4, 0x7b, 0xca, 0x29,
0x99, 0xe7, 0x94, 0x2c, 0x72, 0x4a, 0x96, 0x39, 0x25, 0xaf, 0x39, 0x25, 0xcf, 0x6f, 0xd4, 0xbb,
0xde, 0x29, 0xbf, 0xf6, 0x3d, 0x00, 0x00, 0xff, 0xff, 0xc6, 0x7e, 0x00, 0x08, 0x5a, 0x02, 0x00,
0x00,
}
func (m *PartialObjectMetadataList) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
@@ -106,65 +116,57 @@ func (m *PartialObjectMetadataList) Marshal() (dAtA []byte, err error) {
}
func (m *PartialObjectMetadataList) MarshalTo(dAtA []byte) (int, error) {
var i int
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PartialObjectMetadataList) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size, err := m.ListMeta.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
if len(m.Items) > 0 {
for _, msg := range m.Items {
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(msg.Size()))
n, err := msg.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
for iNdEx := len(m.Items) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Items[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i += n
i--
dAtA[i] = 0xa
}
}
return i, nil
}
func (m *TableOptions) 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 *TableOptions) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.IncludeObject)))
i += copy(dAtA[i:], m.IncludeObject)
return i, nil
return len(dAtA) - i, nil
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
offset -= sovGenerated(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
return base
}
func (m *PartialObjectMetadata) Size() (n int) {
var l int
_ = l
l = m.ObjectMeta.Size()
n += 1 + l + sovGenerated(uint64(l))
return n
}
func (m *PartialObjectMetadataList) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Items) > 0 {
@@ -173,56 +175,29 @@ func (m *PartialObjectMetadataList) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
func (m *TableOptions) Size() (n int) {
var l int
_ = l
l = len(m.IncludeObject)
l = m.ListMeta.Size()
n += 1 + l + sovGenerated(uint64(l))
return n
}
func sovGenerated(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenerated(x uint64) (n int) {
return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (this *PartialObjectMetadata) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&PartialObjectMetadata{`,
`ObjectMeta:` + strings.Replace(strings.Replace(this.ObjectMeta.String(), "ObjectMeta", "k8s_io_apimachinery_pkg_apis_meta_v1.ObjectMeta", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
}
func (this *PartialObjectMetadataList) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&PartialObjectMetadataList{`,
`Items:` + strings.Replace(fmt.Sprintf("%v", this.Items), "PartialObjectMetadata", "PartialObjectMetadata", 1) + `,`,
`}`,
}, "")
return s
}
func (this *TableOptions) String() string {
if this == nil {
return "nil"
repeatedStringForItems := "[]PartialObjectMetadata{"
for _, f := range this.Items {
repeatedStringForItems += fmt.Sprintf("%v", f) + ","
}
s := strings.Join([]string{`&TableOptions{`,
`IncludeObject:` + fmt.Sprintf("%v", this.IncludeObject) + `,`,
repeatedStringForItems += "}"
s := strings.Join([]string{`&PartialObjectMetadataList{`,
`Items:` + repeatedStringForItems + `,`,
`ListMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ListMeta), "ListMeta", "v1.ListMeta", 1), `&`, ``, 1) + `,`,
`}`,
}, "")
return s
@@ -235,86 +210,6 @@ func valueToStringGenerated(v interface{}) string {
pv := reflect.Indirect(rv).Interface()
return fmt.Sprintf("*%v", pv)
}
func (m *PartialObjectMetadata) 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: PartialObjectMetadata: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PartialObjectMetadata: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", 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.ObjectMeta.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 *PartialObjectMetadataList) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@@ -330,7 +225,7 @@ func (m *PartialObjectMetadataList) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -358,7 +253,7 @@ func (m *PartialObjectMetadataList) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -367,69 +262,22 @@ func (m *PartialObjectMetadataList) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Items = append(m.Items, &PartialObjectMetadata{})
m.Items = append(m.Items, v1.PartialObjectMetadata{})
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 *TableOptions) 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: TableOptions: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TableOptions: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field IncludeObject", wireType)
return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType)
}
var stringLen uint64
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
@@ -439,20 +287,24 @@ func (m *TableOptions) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
if msglen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.IncludeObject = IncludeObjectPolicy(dAtA[iNdEx:postIndex])
if err := m.ListMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
@@ -463,6 +315,9 @@ func (m *TableOptions) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@@ -529,10 +384,13 @@ func skipGenerated(dAtA []byte) (n int, err error) {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthGenerated
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthGenerated
}
return iNdEx, nil
case 3:
for {
@@ -561,6 +419,9 @@ func skipGenerated(dAtA []byte) (n int, err error) {
return 0, err
}
iNdEx = start + next
if iNdEx < 0 {
return 0, ErrInvalidLengthGenerated
}
}
return iNdEx, nil
case 4:
@@ -579,35 +440,3 @@ var (
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto", fileDescriptorGenerated)
}
var fileDescriptorGenerated = []byte{
// 375 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xcd, 0x0a, 0xd3, 0x40,
0x10, 0xc7, 0xb3, 0x48, 0xd1, 0x6e, 0xed, 0x25, 0x22, 0xd4, 0x1e, 0x36, 0xa5, 0xa7, 0x0a, 0x76,
0xd7, 0x16, 0x11, 0x8f, 0x92, 0x5b, 0x41, 0x69, 0x09, 0x9e, 0x3c, 0xb9, 0x49, 0xc6, 0x74, 0xcd,
0xc7, 0x86, 0xec, 0xa6, 0xd0, 0x8b, 0xf8, 0x08, 0x3e, 0x56, 0x8f, 0x3d, 0xf6, 0x14, 0x6c, 0x7c,
0x0b, 0x4f, 0x92, 0x0f, 0xec, 0x87, 0x15, 0x7b, 0x9b, 0xf9, 0x0f, 0xbf, 0x5f, 0x66, 0xb2, 0xd8,
0x09, 0xdf, 0x28, 0x2a, 0x24, 0x0b, 0x73, 0x17, 0xb2, 0x04, 0x34, 0x28, 0xb6, 0x81, 0xc4, 0x97,
0x19, 0x6b, 0x07, 0x3c, 0x15, 0x31, 0xf7, 0xd6, 0x22, 0x81, 0x6c, 0xcb, 0xd2, 0x30, 0xa8, 0x02,
0xc5, 0x62, 0xd0, 0x9c, 0x6d, 0x66, 0x2e, 0x68, 0x3e, 0x63, 0x01, 0x24, 0x90, 0x71, 0x0d, 0x3e,
0x4d, 0x33, 0xa9, 0xa5, 0xf9, 0xbc, 0x41, 0xe9, 0x39, 0x4a, 0xd3, 0x30, 0xa8, 0x02, 0x45, 0x2b,
0x94, 0xb6, 0xe8, 0x70, 0x1a, 0x08, 0xbd, 0xce, 0x5d, 0xea, 0xc9, 0x98, 0x05, 0x32, 0x90, 0xac,
0x36, 0xb8, 0xf9, 0xe7, 0xba, 0xab, 0x9b, 0xba, 0x6a, 0xcc, 0xc3, 0x57, 0xf7, 0x2c, 0x75, 0xbd,
0xcf, 0xf0, 0x9f, 0xa7, 0x64, 0x79, 0xa2, 0x45, 0x0c, 0x7f, 0x01, 0xaf, 0xff, 0x07, 0x28, 0x6f,
0x0d, 0x31, 0xbf, 0xe6, 0xc6, 0x5b, 0xfc, 0x74, 0xc5, 0x33, 0x2d, 0x78, 0xb4, 0x74, 0xbf, 0x80,
0xa7, 0xdf, 0x83, 0xe6, 0x3e, 0xd7, 0xdc, 0xfc, 0x84, 0x1f, 0xc5, 0x6d, 0x3d, 0x40, 0x23, 0x34,
0xe9, 0xcd, 0x5f, 0xd2, 0x7b, 0x7e, 0x12, 0x3d, 0x79, 0x6c, 0x73, 0x57, 0x58, 0x46, 0x59, 0x58,
0xf8, 0x94, 0x39, 0x7f, 0xac, 0xe3, 0xaf, 0xf8, 0xd9, 0xcd, 0x4f, 0xbf, 0x13, 0x4a, 0x9b, 0x1c,
0x77, 0x84, 0x86, 0x58, 0x0d, 0xd0, 0xe8, 0xc1, 0xa4, 0x37, 0x7f, 0x4b, 0xef, 0x7e, 0x20, 0x7a,
0x53, 0x6a, 0x77, 0xcb, 0xc2, 0xea, 0x2c, 0x2a, 0xa5, 0xd3, 0x98, 0xc7, 0x2e, 0x7e, 0xfc, 0x81,
0xbb, 0x11, 0x2c, 0x53, 0x2d, 0x64, 0xa2, 0x4c, 0x07, 0xf7, 0x45, 0xe2, 0x45, 0xb9, 0x0f, 0x0d,
0x5a, 0x9f, 0xdd, 0xb5, 0x5f, 0xb4, 0x47, 0xf4, 0x17, 0xe7, 0xc3, 0x5f, 0x85, 0xf5, 0xe4, 0x22,
0x58, 0xc9, 0x48, 0x78, 0x5b, 0xe7, 0x52, 0x61, 0x4f, 0x77, 0x47, 0x62, 0xec, 0x8f, 0xc4, 0x38,
0x1c, 0x89, 0xf1, 0xad, 0x24, 0x68, 0x57, 0x12, 0xb4, 0x2f, 0x09, 0x3a, 0x94, 0x04, 0xfd, 0x28,
0x09, 0xfa, 0xfe, 0x93, 0x18, 0x1f, 0x1f, 0xb6, 0xab, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xf3,
0xe1, 0xde, 0x86, 0xdb, 0x02, 0x00, 0x00,
}

View File

@@ -28,30 +28,15 @@ import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
// Package-wide variables from generator "generated".
option go_package = "v1beta1";
// 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
// +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
}
// PartialObjectMetadataList contains a list of objects containing only their metadata
// PartialObjectMetadataList contains a list of objects containing only their metadata.
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
message PartialObjectMetadataList {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
optional k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 2;
// 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
// specifying "Metadata" (the default) will return the object's metadata in the PartialObjectMetadata kind
// in version v1beta1 of the meta.k8s.io API group.
optional string includeObject = 1;
repeated k8s.io.apimachinery.pkg.apis.meta.v1.PartialObjectMetadata items = 1;
}

View File

@@ -39,6 +39,12 @@ var scheme = runtime.NewScheme()
var ParameterCodec = runtime.NewParameterCodec(scheme)
func init() {
if err := AddMetaToScheme(scheme); err != nil {
panic(err)
}
}
func AddMetaToScheme(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Table{},
&TableOptions{},
@@ -46,11 +52,9 @@ func init() {
&PartialObjectMetadataList{},
)
if err := scheme.AddConversionFuncs(
return scheme.AddConversionFuncs(
Convert_Slice_string_To_v1beta1_IncludeObjectPolicy,
); err != nil {
panic(err)
}
)
// register manually. This usually goes through the SchemeBuilder, which we cannot use here.
//scheme.AddGeneratedDeepCopyFuncs(GetGeneratedDeepCopyFuncs()...)

View File

@@ -18,144 +18,67 @@ limitations under the License.
package v1beta1
import (
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// TODO: Table does not generate to protobuf because of the interface{} - fix protobuf
// generation to support a meta type that can accept any valid JSON.
// 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.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// +optional
v1.ListMeta `json:"metadata,omitempty"`
// columnDefinitions describes each column in the returned items array. The number of cells per row
// will always match the number of column definitions.
ColumnDefinitions []TableColumnDefinition `json:"columnDefinitions"`
// rows is the list of items in the table.
Rows []TableRow `json:"rows"`
}
// +protobuf=false
type Table = v1.Table
// TableColumnDefinition contains information about a column returned in the Table.
// +protobuf=false
type TableColumnDefinition struct {
// name is a human readable name for the column.
Name string `json:"name"`
// type is an OpenAPI type definition for this column.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
Type string `json:"type"`
// format is an optional OpenAPI type definition for this column. The 'name' format is applied
// to the primary identifier column to assist in clients identifying column is the resource name.
// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
Format string `json:"format"`
// description is a human readable description of this column.
Description string `json:"description"`
// priority is an integer defining the relative importance of this column compared to others. Lower
// numbers are considered higher priority. Columns that may be omitted in limited space scenarios
// should be given a higher priority.
Priority int32 `json:"priority"`
}
type TableColumnDefinition = v1.TableColumnDefinition
// TableRow is an individual row in a table.
// +protobuf=false
type TableRow struct {
// cells will be as wide as headers and may contain strings, numbers (float64 or int64), booleans, simple
// maps, or lists, or null. See the type field of the column definition for a more detailed description.
Cells []interface{} `json:"cells"`
// conditions describe additional status of a row that are relevant for a human user.
// +optional
Conditions []TableRowCondition `json:"conditions,omitempty"`
// This field contains the requested additional information about each object based on the includeObject
// policy when requesting the Table. If "None", this field is empty, if "Object" this will be the
// default serialization of the object for the current API version, and if "Metadata" (the default) will
// contain the object metadata. Check the returned kind and apiVersion of the object before parsing.
// +optional
Object runtime.RawExtension `json:"object,omitempty"`
}
type TableRow = v1.TableRow
// TableRowCondition allows a row to be marked with additional information.
// +protobuf=false
type TableRowCondition struct {
// Type of row condition.
Type RowConditionType `json:"type"`
// Status of the condition, one of True, False, Unknown.
Status ConditionStatus `json:"status"`
// (brief) machine readable reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty"`
// Human readable message indicating details about last transition.
// +optional
Message string `json:"message,omitempty"`
}
type TableRowCondition = v1.TableRowCondition
type RowConditionType string
type RowConditionType = v1.RowConditionType
// These are valid conditions of a row. This list is not exhaustive and new conditions may be
// included by other resources.
const (
// RowCompleted means the underlying resource has reached completion and may be given less
// visual priority than other resources.
RowCompleted RowConditionType = "Completed"
)
type ConditionStatus = v1.ConditionStatus
type ConditionStatus string
// These are valid condition statuses. "ConditionTrue" means a resource is in the condition.
// "ConditionFalse" means a resource is not in the condition. "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionTrue ConditionStatus = "True"
ConditionFalse ConditionStatus = "False"
ConditionUnknown ConditionStatus = "Unknown"
)
// IncludeObjectPolicy controls which portion of the object is returned with a Table.
type IncludeObjectPolicy string
const (
// IncludeNone returns no object.
IncludeNone IncludeObjectPolicy = "None"
// IncludeMetadata serializes the object containing only its metadata field.
IncludeMetadata IncludeObjectPolicy = "Metadata"
// IncludeObject contains the full object.
IncludeObject IncludeObjectPolicy = "Object"
)
type IncludeObjectPolicy = v1.IncludeObjectPolicy
// 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.
// Specifying "None" will return no object, specifying "Object" will return the full object contents, and
// specifying "Metadata" (the default) will return the object's metadata in the PartialObjectMetadata kind
// in version v1beta1 of the meta.k8s.io API group.
IncludeObject IncludeObjectPolicy `json:"includeObject,omitempty" protobuf:"bytes,1,opt,name=includeObject,casttype=IncludeObjectPolicy"`
}
type TableOptions = v1.TableOptions
// 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.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
}
type PartialObjectMetadata = v1.PartialObjectMetadata
// PartialObjectMetadataList contains a list of objects containing only their metadata
// IMPORTANT: PartialObjectMetadataList has different protobuf field ids in v1beta1 than
// v1 because ListMeta was accidentally omitted prior to 1.15. Therefore this type must
// remain independent of v1.PartialObjectMetadataList to preserve mappings.
// 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"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
v1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,2,opt,name=metadata"`
// items contains each of the included items.
Items []*PartialObjectMetadata `json:"items" protobuf:"bytes,1,rep,name=items"`
Items []v1.PartialObjectMetadata `json:"items" protobuf:"bytes,1,rep,name=items"`
}
const (
RowCompleted = v1.RowCompleted
ConditionTrue = v1.ConditionTrue
ConditionFalse = v1.ConditionFalse
ConditionUnknown = v1.ConditionUnknown
IncludeNone = v1.IncludeNone
IncludeMetadata = v1.IncludeMetadata
IncludeObject = v1.IncludeObject
)

View File

@@ -27,78 +27,14 @@ package v1beta1
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
var map_PartialObjectMetadata = map[string]string{
"": "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.",
"metadata": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata",
}
func (PartialObjectMetadata) SwaggerDoc() map[string]string {
return map_PartialObjectMetadata
}
var map_PartialObjectMetadataList = map[string]string{
"": "PartialObjectMetadataList contains a list of objects containing only their metadata",
"items": "items contains each of the included items.",
"": "PartialObjectMetadataList contains a list of objects containing only their metadata.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"items": "items contains each of the included items.",
}
func (PartialObjectMetadataList) SwaggerDoc() map[string]string {
return map_PartialObjectMetadataList
}
var map_Table = map[string]string{
"": "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.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"columnDefinitions": "columnDefinitions describes each column in the returned items array. The number of cells per row will always match the number of column definitions.",
"rows": "rows is the list of items in the table.",
}
func (Table) SwaggerDoc() map[string]string {
return map_Table
}
var map_TableColumnDefinition = map[string]string{
"": "TableColumnDefinition contains information about a column returned in the Table.",
"name": "name is a human readable name for the column.",
"type": "type is an OpenAPI type definition for this column. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.",
"format": "format is an optional OpenAPI type definition for this column. The 'name' format is applied to the primary identifier column to assist in clients identifying column is the resource name. See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.",
"description": "description is a human readable description of this column.",
"priority": "priority is an integer defining the relative importance of this column compared to others. Lower numbers are considered higher priority. Columns that may be omitted in limited space scenarios should be given a higher priority.",
}
func (TableColumnDefinition) SwaggerDoc() map[string]string {
return map_TableColumnDefinition
}
var map_TableOptions = map[string]string{
"": "TableOptions are used when a Table is requested by the caller.",
"includeObject": "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 specifying \"Metadata\" (the default) will return the object's metadata in the PartialObjectMetadata kind in version v1beta1 of the meta.k8s.io API group.",
}
func (TableOptions) SwaggerDoc() map[string]string {
return map_TableOptions
}
var map_TableRow = map[string]string{
"": "TableRow is an individual row in a table.",
"cells": "cells will be as wide as headers and may contain strings, numbers (float64 or int64), booleans, simple maps, or lists, or null. See the type field of the column definition for a more detailed description.",
"conditions": "conditions describe additional status of a row that are relevant for a human user.",
"object": "This field contains the requested additional information about each object based on the includeObject policy when requesting the Table. If \"None\", this field is empty, if \"Object\" this will be the default serialization of the object for the current API version, and if \"Metadata\" (the default) will contain the object metadata. Check the returned kind and apiVersion of the object before parsing.",
}
func (TableRow) SwaggerDoc() map[string]string {
return map_TableRow
}
var map_TableRowCondition = map[string]string{
"": "TableRowCondition allows a row to be marked with additional information.",
"type": "Type of row condition.",
"status": "Status of the condition, one of True, False, Unknown.",
"reason": "(brief) machine readable reason for the condition's last transition.",
"message": "Human readable message indicating details about last transition.",
}
func (TableRowCondition) SwaggerDoc() map[string]string {
return map_TableRowCondition
}
// AUTO-GENERATED FUNCTIONS END HERE

View File

@@ -0,0 +1,34 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/util/validation/field"
)
// ValidateTableOptions returns any invalid flags on TableOptions.
func ValidateTableOptions(opts *metav1beta1.TableOptions) field.ErrorList {
var allErrs field.ErrorList
switch opts.IncludeObject {
case metav1.IncludeMetadata, metav1.IncludeNone, metav1.IncludeObject, "":
default:
allErrs = append(allErrs, field.Invalid(field.NewPath("includeObject"), opts.IncludeObject, "must be 'Metadata', 'Object', 'None', or empty"))
}
return allErrs
}

View File

@@ -21,48 +21,20 @@ limitations under the License.
package v1beta1
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
// 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
}
return nil
}
// 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
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]*PartialObjectMetadata, len(*in))
*out = make([]v1.PartialObjectMetadata, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(PartialObjectMetadata)
(*in).DeepCopyInto(*out)
}
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
@@ -85,105 +57,3 @@ func (in *PartialObjectMetadataList) DeepCopyObject() runtime.Object {
}
return nil
}
// 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
}
return nil
}
// 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
}
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
}
// 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 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

@@ -54,10 +54,6 @@ func jsonTag(field reflect.StructField) (string, bool) {
return tag, omitempty
}
func formatValue(value interface{}) string {
return fmt.Sprintf("%v", value)
}
func isPointerKind(kind reflect.Kind) bool {
return kind == reflect.Ptr
}

View File

@@ -172,7 +172,7 @@ func ConvertSelectorToLabelsMap(selector string) (Set, error) {
return labelsMap, err
}
value := strings.TrimSpace(l[1])
if err := validateLabelValue(value); err != nil {
if err := validateLabelValue(key, value); err != nil {
return labelsMap, err
}
labelsMap[key] = value

View File

@@ -162,7 +162,7 @@ func NewRequirement(key string, op selection.Operator, vals []string) (*Requirem
}
for i := range vals {
if err := validateLabelValue(vals[i]); err != nil {
if err := validateLabelValue(key, vals[i]); err != nil {
return nil, err
}
}
@@ -837,9 +837,9 @@ func validateLabelKey(k string) error {
return nil
}
func validateLabelValue(v string) error {
func validateLabelValue(k, v string) error {
if errs := validation.IsValidLabelValue(v); len(errs) != 0 {
return fmt.Errorf("invalid label value: %q: %s", v, strings.Join(errs, "; "))
return fmt.Errorf("invalid label value: %q: at key: %q: %s", v, k, strings.Join(errs, "; "))
}
return nil
}

View File

@@ -94,7 +94,7 @@ func parseBool(key string) bool {
}
value, err := strconv.ParseBool(key)
if err != nil {
utilruntime.HandleError(fmt.Errorf("Couldn't parse '%s' as bool for unstructured mismatch detection", key))
utilruntime.HandleError(fmt.Errorf("couldn't parse '%s' as bool for unstructured mismatch detection", key))
}
return value
}
@@ -746,7 +746,7 @@ func isZero(v reflect.Value) bool {
func structToUnstructured(sv, dv reflect.Value) error {
st, dt := sv.Type(), dv.Type()
if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
dv.Set(reflect.MakeMap(mapStringInterfaceType))
dv.Set(reflect.MakeMapWithSize(mapStringInterfaceType, st.NumField()))
dv = dv.Elem()
dt = dv.Type()
}

View File

@@ -120,3 +120,32 @@ func IsMissingVersion(err error) bool {
_, ok := err.(*missingVersionErr)
return ok
}
// strictDecodingError is a base error type that is returned by a strict Decoder such
// as UniversalStrictDecoder.
type strictDecodingError struct {
message string
data string
}
// NewStrictDecodingError creates a new strictDecodingError object.
func NewStrictDecodingError(message string, data string) error {
return &strictDecodingError{
message: message,
data: data,
}
}
func (e *strictDecodingError) Error() string {
return fmt.Sprintf("strict decoder error for %s: %s", e.data, e.message)
}
// IsStrictDecodingError returns true if the error indicates that the provided object
// strictness violations.
func IsStrictDecodingError(err error) bool {
if err == nil {
return false
}
_, ok := err.(*strictDecodingError)
return ok
}

View File

@@ -17,27 +17,19 @@ limitations under the License.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto
/*
Package runtime is a generated protocol buffer package.
It is generated from these files:
k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto
It has these top-level messages:
RawExtension
TypeMeta
Unknown
*/
package runtime
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
import strings "strings"
import reflect "reflect"
io "io"
math "math"
math_bits "math/bits"
reflect "reflect"
strings "strings"
import io "io"
proto "github.com/gogo/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@@ -50,27 +42,132 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
func (m *RawExtension) Reset() { *m = RawExtension{} }
func (*RawExtension) ProtoMessage() {}
func (*RawExtension) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
func (m *RawExtension) Reset() { *m = RawExtension{} }
func (*RawExtension) ProtoMessage() {}
func (*RawExtension) Descriptor() ([]byte, []int) {
return fileDescriptor_9d3c45d7f546725c, []int{0}
}
func (m *RawExtension) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *RawExtension) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
func (m *RawExtension) XXX_Merge(src proto.Message) {
xxx_messageInfo_RawExtension.Merge(m, src)
}
func (m *RawExtension) XXX_Size() int {
return m.Size()
}
func (m *RawExtension) XXX_DiscardUnknown() {
xxx_messageInfo_RawExtension.DiscardUnknown(m)
}
func (m *TypeMeta) Reset() { *m = TypeMeta{} }
func (*TypeMeta) ProtoMessage() {}
func (*TypeMeta) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{1} }
var xxx_messageInfo_RawExtension proto.InternalMessageInfo
func (m *Unknown) Reset() { *m = Unknown{} }
func (*Unknown) ProtoMessage() {}
func (*Unknown) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{2} }
func (m *TypeMeta) Reset() { *m = TypeMeta{} }
func (*TypeMeta) ProtoMessage() {}
func (*TypeMeta) Descriptor() ([]byte, []int) {
return fileDescriptor_9d3c45d7f546725c, []int{1}
}
func (m *TypeMeta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TypeMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
func (m *TypeMeta) XXX_Merge(src proto.Message) {
xxx_messageInfo_TypeMeta.Merge(m, src)
}
func (m *TypeMeta) XXX_Size() int {
return m.Size()
}
func (m *TypeMeta) XXX_DiscardUnknown() {
xxx_messageInfo_TypeMeta.DiscardUnknown(m)
}
var xxx_messageInfo_TypeMeta proto.InternalMessageInfo
func (m *Unknown) Reset() { *m = Unknown{} }
func (*Unknown) ProtoMessage() {}
func (*Unknown) Descriptor() ([]byte, []int) {
return fileDescriptor_9d3c45d7f546725c, []int{2}
}
func (m *Unknown) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Unknown) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
func (m *Unknown) XXX_Merge(src proto.Message) {
xxx_messageInfo_Unknown.Merge(m, src)
}
func (m *Unknown) XXX_Size() int {
return m.Size()
}
func (m *Unknown) XXX_DiscardUnknown() {
xxx_messageInfo_Unknown.DiscardUnknown(m)
}
var xxx_messageInfo_Unknown proto.InternalMessageInfo
func init() {
proto.RegisterType((*RawExtension)(nil), "k8s.io.apimachinery.pkg.runtime.RawExtension")
proto.RegisterType((*TypeMeta)(nil), "k8s.io.apimachinery.pkg.runtime.TypeMeta")
proto.RegisterType((*Unknown)(nil), "k8s.io.apimachinery.pkg.runtime.Unknown")
}
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto", fileDescriptor_9d3c45d7f546725c)
}
var fileDescriptor_9d3c45d7f546725c = []byte{
// 378 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0x4f, 0xab, 0x13, 0x31,
0x14, 0xc5, 0x27, 0xaf, 0x85, 0x3e, 0xd3, 0xc2, 0x93, 0xb8, 0x70, 0x74, 0x91, 0x79, 0x74, 0xe5,
0x5b, 0xbc, 0x04, 0x1e, 0x08, 0x6e, 0x3b, 0xa5, 0xa0, 0x88, 0x20, 0xc1, 0x3f, 0xe0, 0xca, 0x74,
0x26, 0x4e, 0xc3, 0xd0, 0x9b, 0x21, 0xcd, 0x38, 0x76, 0xe7, 0x47, 0xf0, 0x63, 0x75, 0xd9, 0x65,
0x57, 0xc5, 0x8e, 0x1f, 0xc2, 0xad, 0x34, 0x4d, 0x6b, 0xd5, 0x85, 0xbb, 0xe4, 0x9e, 0xf3, 0x3b,
0xf7, 0x1e, 0xfc, 0xbc, 0x7c, 0xb6, 0x60, 0xda, 0xf0, 0xb2, 0x9e, 0x2a, 0x0b, 0xca, 0xa9, 0x05,
0xff, 0xac, 0x20, 0x37, 0x96, 0x07, 0x41, 0x56, 0x7a, 0x2e, 0xb3, 0x99, 0x06, 0x65, 0x97, 0xbc,
0x2a, 0x0b, 0x6e, 0x6b, 0x70, 0x7a, 0xae, 0x78, 0xa1, 0x40, 0x59, 0xe9, 0x54, 0xce, 0x2a, 0x6b,
0x9c, 0x21, 0xc9, 0x01, 0x60, 0xe7, 0x00, 0xab, 0xca, 0x82, 0x05, 0xe0, 0xf1, 0x6d, 0xa1, 0xdd,
0xac, 0x9e, 0xb2, 0xcc, 0xcc, 0x79, 0x61, 0x0a, 0xc3, 0x3d, 0x37, 0xad, 0x3f, 0xf9, 0x9f, 0xff,
0xf8, 0xd7, 0x21, 0x6f, 0x78, 0x83, 0x07, 0x42, 0x36, 0x93, 0x2f, 0x4e, 0xc1, 0x42, 0x1b, 0x20,
0x8f, 0x70, 0xc7, 0xca, 0x26, 0x46, 0xd7, 0xe8, 0xc9, 0x20, 0xed, 0xb5, 0xdb, 0xa4, 0x23, 0x64,
0x23, 0xf6, 0xb3, 0xe1, 0x47, 0x7c, 0xf9, 0x66, 0x59, 0xa9, 0x57, 0xca, 0x49, 0x72, 0x87, 0xb1,
0xac, 0xf4, 0x3b, 0x65, 0xf7, 0x90, 0x77, 0xdf, 0x4b, 0xc9, 0x6a, 0x9b, 0x44, 0xed, 0x36, 0xc1,
0xa3, 0xd7, 0x2f, 0x82, 0x22, 0xce, 0x5c, 0xe4, 0x1a, 0x77, 0x4b, 0x0d, 0x79, 0x7c, 0xe1, 0xdd,
0x83, 0xe0, 0xee, 0xbe, 0xd4, 0x90, 0x0b, 0xaf, 0x0c, 0x7f, 0x22, 0xdc, 0x7b, 0x0b, 0x25, 0x98,
0x06, 0xc8, 0x7b, 0x7c, 0xe9, 0xc2, 0x36, 0x9f, 0xdf, 0xbf, 0xbb, 0x61, 0xff, 0xe9, 0xce, 0x8e,
0xe7, 0xa5, 0xf7, 0x43, 0xf8, 0xe9, 0x60, 0x71, 0x0a, 0x3b, 0x36, 0xbc, 0xf8, 0xb7, 0x21, 0x19,
0xe1, 0xab, 0xcc, 0x80, 0x53, 0xe0, 0x26, 0x90, 0x99, 0x5c, 0x43, 0x11, 0x77, 0xfc, 0xb1, 0x0f,
0x43, 0xde, 0xd5, 0xf8, 0x4f, 0x59, 0xfc, 0xed, 0x27, 0x4f, 0x71, 0x3f, 0x8c, 0xf6, 0xab, 0xe3,
0xae, 0xc7, 0x1f, 0x04, 0xbc, 0x3f, 0xfe, 0x2d, 0x89, 0x73, 0x5f, 0x7a, 0xbb, 0xda, 0xd1, 0x68,
0xbd, 0xa3, 0xd1, 0x66, 0x47, 0xa3, 0xaf, 0x2d, 0x45, 0xab, 0x96, 0xa2, 0x75, 0x4b, 0xd1, 0xa6,
0xa5, 0xe8, 0x7b, 0x4b, 0xd1, 0xb7, 0x1f, 0x34, 0xfa, 0xd0, 0x0b, 0x45, 0x7f, 0x05, 0x00, 0x00,
0xff, 0xff, 0xe3, 0x33, 0x18, 0x0b, 0x50, 0x02, 0x00, 0x00,
}
func (m *RawExtension) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
@@ -78,23 +175,29 @@ func (m *RawExtension) Marshal() (dAtA []byte, err error) {
}
func (m *RawExtension) MarshalTo(dAtA []byte) (int, error) {
var i int
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *RawExtension) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Raw != nil {
dAtA[i] = 0xa
i++
i -= len(m.Raw)
copy(dAtA[i:], m.Raw)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Raw)))
i += copy(dAtA[i:], m.Raw)
i--
dAtA[i] = 0xa
}
return i, nil
return len(dAtA) - i, nil
}
func (m *TypeMeta) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
@@ -102,25 +205,32 @@ func (m *TypeMeta) Marshal() (dAtA []byte, err error) {
}
func (m *TypeMeta) MarshalTo(dAtA []byte) (int, error) {
var i int
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TypeMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion)))
i += copy(dAtA[i:], m.APIVersion)
dAtA[i] = 0x12
i++
i -= len(m.Kind)
copy(dAtA[i:], m.Kind)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Kind)))
i += copy(dAtA[i:], m.Kind)
return i, nil
i--
dAtA[i] = 0x12
i -= len(m.APIVersion)
copy(dAtA[i:], m.APIVersion)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.APIVersion)))
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func (m *Unknown) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
@@ -128,45 +238,60 @@ func (m *Unknown) Marshal() (dAtA []byte, err error) {
}
func (m *Unknown) MarshalTo(dAtA []byte) (int, error) {
var i int
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Unknown) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
dAtA[i] = 0xa
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.TypeMeta.Size()))
n1, err := m.TypeMeta.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n1
if m.Raw != nil {
dAtA[i] = 0x12
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Raw)))
i += copy(dAtA[i:], m.Raw)
}
dAtA[i] = 0x1a
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.ContentEncoding)))
i += copy(dAtA[i:], m.ContentEncoding)
dAtA[i] = 0x22
i++
i -= len(m.ContentType)
copy(dAtA[i:], m.ContentType)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.ContentType)))
i += copy(dAtA[i:], m.ContentType)
return i, nil
i--
dAtA[i] = 0x22
i -= len(m.ContentEncoding)
copy(dAtA[i:], m.ContentEncoding)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.ContentEncoding)))
i--
dAtA[i] = 0x1a
if m.Raw != nil {
i -= len(m.Raw)
copy(dAtA[i:], m.Raw)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Raw)))
i--
dAtA[i] = 0x12
}
{
size, err := m.TypeMeta.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenerated(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
offset -= sovGenerated(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
return base
}
func (m *RawExtension) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Raw != nil {
@@ -177,6 +302,9 @@ func (m *RawExtension) Size() (n int) {
}
func (m *TypeMeta) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.APIVersion)
@@ -187,6 +315,9 @@ func (m *TypeMeta) Size() (n int) {
}
func (m *Unknown) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = m.TypeMeta.Size()
@@ -203,14 +334,7 @@ func (m *Unknown) Size() (n int) {
}
func sovGenerated(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenerated(x uint64) (n int) {
return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -272,7 +396,7 @@ func (m *RawExtension) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -300,7 +424,7 @@ func (m *RawExtension) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -309,6 +433,9 @@ func (m *RawExtension) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -326,6 +453,9 @@ func (m *RawExtension) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@@ -353,7 +483,7 @@ func (m *TypeMeta) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -381,7 +511,7 @@ func (m *TypeMeta) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -391,6 +521,9 @@ func (m *TypeMeta) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -410,7 +543,7 @@ func (m *TypeMeta) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -420,6 +553,9 @@ func (m *TypeMeta) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -434,6 +570,9 @@ func (m *TypeMeta) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@@ -461,7 +600,7 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -489,7 +628,7 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
msglen |= (int(b) & 0x7F) << shift
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -498,6 +637,9 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -519,7 +661,7 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= (int(b) & 0x7F) << shift
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -528,6 +670,9 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -550,7 +695,7 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -560,6 +705,9 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -579,7 +727,7 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -589,6 +737,9 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -603,6 +754,9 @@ func (m *Unknown) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@@ -669,10 +823,13 @@ func skipGenerated(dAtA []byte) (n int, err error) {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthGenerated
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthGenerated
}
return iNdEx, nil
case 3:
for {
@@ -701,6 +858,9 @@ func skipGenerated(dAtA []byte) (n int, err error) {
return 0, err
}
iNdEx = start + next
if iNdEx < 0 {
return 0, ErrInvalidLengthGenerated
}
}
return iNdEx, nil
case 4:
@@ -719,35 +879,3 @@ var (
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/generated.proto", fileDescriptorGenerated)
}
var fileDescriptorGenerated = []byte{
// 378 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0x4f, 0xab, 0x13, 0x31,
0x14, 0xc5, 0x27, 0xaf, 0x85, 0x3e, 0xd3, 0xc2, 0x93, 0xb8, 0x70, 0x74, 0x91, 0x79, 0x74, 0xe5,
0x5b, 0xbc, 0x04, 0x1e, 0x08, 0x6e, 0x3b, 0xa5, 0xa0, 0x88, 0x20, 0xc1, 0x3f, 0xe0, 0xca, 0x74,
0x26, 0x4e, 0xc3, 0xd0, 0x9b, 0x21, 0xcd, 0x38, 0x76, 0xe7, 0x47, 0xf0, 0x63, 0x75, 0xd9, 0x65,
0x57, 0xc5, 0x8e, 0x1f, 0xc2, 0xad, 0x34, 0x4d, 0x6b, 0xd5, 0x85, 0xbb, 0xe4, 0x9e, 0xf3, 0x3b,
0xf7, 0x1e, 0xfc, 0xbc, 0x7c, 0xb6, 0x60, 0xda, 0xf0, 0xb2, 0x9e, 0x2a, 0x0b, 0xca, 0xa9, 0x05,
0xff, 0xac, 0x20, 0x37, 0x96, 0x07, 0x41, 0x56, 0x7a, 0x2e, 0xb3, 0x99, 0x06, 0x65, 0x97, 0xbc,
0x2a, 0x0b, 0x6e, 0x6b, 0x70, 0x7a, 0xae, 0x78, 0xa1, 0x40, 0x59, 0xe9, 0x54, 0xce, 0x2a, 0x6b,
0x9c, 0x21, 0xc9, 0x01, 0x60, 0xe7, 0x00, 0xab, 0xca, 0x82, 0x05, 0xe0, 0xf1, 0x6d, 0xa1, 0xdd,
0xac, 0x9e, 0xb2, 0xcc, 0xcc, 0x79, 0x61, 0x0a, 0xc3, 0x3d, 0x37, 0xad, 0x3f, 0xf9, 0x9f, 0xff,
0xf8, 0xd7, 0x21, 0x6f, 0x78, 0x83, 0x07, 0x42, 0x36, 0x93, 0x2f, 0x4e, 0xc1, 0x42, 0x1b, 0x20,
0x8f, 0x70, 0xc7, 0xca, 0x26, 0x46, 0xd7, 0xe8, 0xc9, 0x20, 0xed, 0xb5, 0xdb, 0xa4, 0x23, 0x64,
0x23, 0xf6, 0xb3, 0xe1, 0x47, 0x7c, 0xf9, 0x66, 0x59, 0xa9, 0x57, 0xca, 0x49, 0x72, 0x87, 0xb1,
0xac, 0xf4, 0x3b, 0x65, 0xf7, 0x90, 0x77, 0xdf, 0x4b, 0xc9, 0x6a, 0x9b, 0x44, 0xed, 0x36, 0xc1,
0xa3, 0xd7, 0x2f, 0x82, 0x22, 0xce, 0x5c, 0xe4, 0x1a, 0x77, 0x4b, 0x0d, 0x79, 0x7c, 0xe1, 0xdd,
0x83, 0xe0, 0xee, 0xbe, 0xd4, 0x90, 0x0b, 0xaf, 0x0c, 0x7f, 0x22, 0xdc, 0x7b, 0x0b, 0x25, 0x98,
0x06, 0xc8, 0x7b, 0x7c, 0xe9, 0xc2, 0x36, 0x9f, 0xdf, 0xbf, 0xbb, 0x61, 0xff, 0xe9, 0xce, 0x8e,
0xe7, 0xa5, 0xf7, 0x43, 0xf8, 0xe9, 0x60, 0x71, 0x0a, 0x3b, 0x36, 0xbc, 0xf8, 0xb7, 0x21, 0x19,
0xe1, 0xab, 0xcc, 0x80, 0x53, 0xe0, 0x26, 0x90, 0x99, 0x5c, 0x43, 0x11, 0x77, 0xfc, 0xb1, 0x0f,
0x43, 0xde, 0xd5, 0xf8, 0x4f, 0x59, 0xfc, 0xed, 0x27, 0x4f, 0x71, 0x3f, 0x8c, 0xf6, 0xab, 0xe3,
0xae, 0xc7, 0x1f, 0x04, 0xbc, 0x3f, 0xfe, 0x2d, 0x89, 0x73, 0x5f, 0x7a, 0xbb, 0xda, 0xd1, 0x68,
0xbd, 0xa3, 0xd1, 0x66, 0x47, 0xa3, 0xaf, 0x2d, 0x45, 0xab, 0x96, 0xa2, 0x75, 0x4b, 0xd1, 0xa6,
0xa5, 0xe8, 0x7b, 0x4b, 0xd1, 0xb7, 0x1f, 0x34, 0xfa, 0xd0, 0x0b, 0x45, 0x7f, 0x05, 0x00, 0x00,
0xff, 0xff, 0xe3, 0x33, 0x18, 0x0b, 0x50, 0x02, 0x00, 0x00,
}

View File

@@ -51,7 +51,7 @@ func UnsafeObjectConvertor(scheme *Scheme) ObjectConvertor {
func SetField(src interface{}, v reflect.Value, fieldName string) error {
field := v.FieldByName(fieldName)
if !field.IsValid() {
return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface())
return fmt.Errorf("couldn't find %v field in %T", fieldName, v.Interface())
}
srcValue := reflect.ValueOf(src)
if srcValue.Type().AssignableTo(field.Type()) {
@@ -70,7 +70,7 @@ func SetField(src interface{}, v reflect.Value, fieldName string) error {
func Field(v reflect.Value, fieldName string, dest interface{}) error {
field := v.FieldByName(fieldName)
if !field.IsValid() {
return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface())
return fmt.Errorf("couldn't find %v field in %T", fieldName, v.Interface())
}
destValue, err := conversion.EnforcePtr(dest)
if err != nil {
@@ -93,7 +93,7 @@ func Field(v reflect.Value, fieldName string, dest interface{}) error {
func FieldPtr(v reflect.Value, fieldName string, dest interface{}) error {
field := v.FieldByName(fieldName)
if !field.IsValid() {
return fmt.Errorf("couldn't find %v field in %#v", fieldName, v.Interface())
return fmt.Errorf("couldn't find %v field in %T", fieldName, v.Interface())
}
v, err := conversion.EnforcePtr(dest)
if err != nil {
@@ -210,3 +210,50 @@ type defaultFramer struct{}
func (defaultFramer) NewFrameReader(r io.ReadCloser) io.ReadCloser { return r }
func (defaultFramer) NewFrameWriter(w io.Writer) io.Writer { return w }
// WithVersionEncoder serializes an object and ensures the GVK is set.
type WithVersionEncoder struct {
Version GroupVersioner
Encoder
ObjectTyper
}
// Encode does not do conversion. It sets the gvk during serialization.
func (e WithVersionEncoder) Encode(obj Object, stream io.Writer) error {
gvks, _, err := e.ObjectTyper.ObjectKinds(obj)
if err != nil {
if IsNotRegisteredError(err) {
return e.Encoder.Encode(obj, stream)
}
return err
}
kind := obj.GetObjectKind()
oldGVK := kind.GroupVersionKind()
gvk := gvks[0]
if e.Version != nil {
preferredGVK, ok := e.Version.KindForGroupVersionKinds(gvks)
if ok {
gvk = preferredGVK
}
}
kind.SetGroupVersionKind(gvk)
err = e.Encoder.Encode(obj, stream)
kind.SetGroupVersionKind(oldGVK)
return err
}
// WithoutVersionDecoder clears the group version kind of a deserialized object.
type WithoutVersionDecoder struct {
Decoder
}
// Decode does not do conversion. It removes the gvk during deserialization.
func (d WithoutVersionDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error) {
obj, gvk, err := d.Decoder.Decode(data, defaults, into)
if obj != nil {
kind := obj.GetObjectKind()
// clearing the gvk is just a convention of a codec
kind.SetGroupVersionKind(schema.GroupVersionKind{})
}
return obj, gvk, err
}

View File

@@ -91,6 +91,10 @@ type Framer interface {
type SerializerInfo struct {
// MediaType is the value that represents this serializer over the wire.
MediaType string
// MediaTypeType is the first part of the MediaType ("application" in "application/json").
MediaTypeType string
// MediaTypeSubType is the second part of the MediaType ("json" in "application/json").
MediaTypeSubType string
// EncodesAsText indicates this serializer can be encoded to UTF-8 safely.
EncodesAsText bool
// Serializer is the individual object serializer for this media type.
@@ -206,6 +210,25 @@ type ObjectCreater interface {
New(kind schema.GroupVersionKind) (out Object, err error)
}
// EquivalentResourceMapper provides information about resources that address the same underlying data as a specified resource
type EquivalentResourceMapper interface {
// EquivalentResourcesFor returns a list of resources that address the same underlying data as resource.
// If subresource is specified, only equivalent resources which also have the same subresource are included.
// The specified resource can be included in the returned list.
EquivalentResourcesFor(resource schema.GroupVersionResource, subresource string) []schema.GroupVersionResource
// KindFor returns the kind expected by the specified resource[/subresource].
// A zero value is returned if the kind is unknown.
KindFor(resource schema.GroupVersionResource, subresource string) schema.GroupVersionKind
}
// EquivalentResourceRegistry provides an EquivalentResourceMapper interface,
// and allows registering known resource[/subresource] -> kind
type EquivalentResourceRegistry interface {
EquivalentResourceMapper
// RegisterKindFor registers the existence of the specified resource[/subresource] along with its expected kind.
RegisterKindFor(resource schema.GroupVersionResource, subresource string, kind schema.GroupVersionKind)
}
// ResourceVersioner provides methods for setting and retrieving
// the resource version from an API object.
type ResourceVersioner interface {
@@ -237,6 +260,9 @@ type Object interface {
// to JSON allowed.
type Unstructured interface {
Object
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.
// This should be called instead of reflect.New() for unstructured types because the go type alone does not preserve kind/apiVersion info.
NewEmptyInstance() Unstructured
// UnstructuredContent returns a non-nil map with this object's contents. Values may be
// []interface{}, map[string]interface{}, or any primitive type. Contents are typically serialized to
// and from JSON. SetUnstructuredContent should be used to mutate the contents.

98
vendor/k8s.io/apimachinery/pkg/runtime/mapper.go generated vendored Normal file
View File

@@ -0,0 +1,98 @@
/*
Copyright 2019 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 runtime
import (
"sync"
"k8s.io/apimachinery/pkg/runtime/schema"
)
type equivalentResourceRegistry struct {
// keyFunc computes a key for the specified resource (this allows honoring colocated resources across API groups).
// if null, or if "" is returned, resource.String() is used as the key
keyFunc func(resource schema.GroupResource) string
// resources maps key -> subresource -> equivalent resources (subresource is not included in the returned resources).
// main resources are stored with subresource="".
resources map[string]map[string][]schema.GroupVersionResource
// kinds maps resource -> subresource -> kind
kinds map[schema.GroupVersionResource]map[string]schema.GroupVersionKind
// keys caches the computed key for each GroupResource
keys map[schema.GroupResource]string
mutex sync.RWMutex
}
var _ EquivalentResourceMapper = (*equivalentResourceRegistry)(nil)
var _ EquivalentResourceRegistry = (*equivalentResourceRegistry)(nil)
// NewEquivalentResourceRegistry creates a resource registry that considers all versions of a GroupResource to be equivalent.
func NewEquivalentResourceRegistry() EquivalentResourceRegistry {
return &equivalentResourceRegistry{}
}
// NewEquivalentResourceRegistryWithIdentity creates a resource mapper with a custom identity function.
// If "" is returned by the function, GroupResource#String is used as the identity.
// GroupResources with the same identity string are considered equivalent.
func NewEquivalentResourceRegistryWithIdentity(keyFunc func(schema.GroupResource) string) EquivalentResourceRegistry {
return &equivalentResourceRegistry{keyFunc: keyFunc}
}
func (r *equivalentResourceRegistry) EquivalentResourcesFor(resource schema.GroupVersionResource, subresource string) []schema.GroupVersionResource {
r.mutex.RLock()
defer r.mutex.RUnlock()
return r.resources[r.keys[resource.GroupResource()]][subresource]
}
func (r *equivalentResourceRegistry) KindFor(resource schema.GroupVersionResource, subresource string) schema.GroupVersionKind {
r.mutex.RLock()
defer r.mutex.RUnlock()
return r.kinds[resource][subresource]
}
func (r *equivalentResourceRegistry) RegisterKindFor(resource schema.GroupVersionResource, subresource string, kind schema.GroupVersionKind) {
r.mutex.Lock()
defer r.mutex.Unlock()
if r.kinds == nil {
r.kinds = map[schema.GroupVersionResource]map[string]schema.GroupVersionKind{}
}
if r.kinds[resource] == nil {
r.kinds[resource] = map[string]schema.GroupVersionKind{}
}
r.kinds[resource][subresource] = kind
// get the shared key of the parent resource
key := ""
gr := resource.GroupResource()
if r.keyFunc != nil {
key = r.keyFunc(gr)
}
if key == "" {
key = gr.String()
}
if r.keys == nil {
r.keys = map[schema.GroupResource]string{}
}
r.keys[gr] = key
if r.resources == nil {
r.resources = map[string]map[string][]schema.GroupVersionResource{}
}
if r.resources[key] == nil {
r.resources[key] = map[string][]schema.GroupVersionResource{}
}
r.resources[key][subresource] = append(r.resources[key][subresource], resource)
}

View File

@@ -17,19 +17,15 @@ limitations under the License.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto
/*
Package schema is a generated protocol buffer package.
It is generated from these files:
k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto
It has these top-level messages:
*/
package schema
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
math "math"
proto "github.com/gogo/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@@ -43,10 +39,10 @@ var _ = math.Inf
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto", fileDescriptorGenerated)
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/runtime/schema/generated.proto", fileDescriptor_0462724132518e0d)
}
var fileDescriptorGenerated = []byte{
var fileDescriptor_0462724132518e0d = []byte{
// 185 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0xcc, 0xaf, 0x6e, 0xc3, 0x30,
0x10, 0xc7, 0x71, 0x9b, 0x0c, 0x0c, 0x0e, 0x0e, 0x1c, 0x1c, 0xda, 0x7c, 0x74, 0xb8, 0x2f, 0x50,

View File

@@ -17,9 +17,13 @@ limitations under the License.
package serializer
import (
"mime"
"strings"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
)
@@ -44,30 +48,53 @@ type serializerType struct {
StreamSerializer runtime.Serializer
}
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory) []serializerType {
jsonSerializer := json.NewSerializer(mf, scheme, scheme, false)
jsonPrettySerializer := json.NewSerializer(mf, scheme, scheme, true)
yamlSerializer := json.NewYAMLSerializer(mf, scheme, scheme)
func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, options CodecFactoryOptions) []serializerType {
jsonSerializer := json.NewSerializerWithOptions(
mf, scheme, scheme,
json.SerializerOptions{Yaml: false, Pretty: false, Strict: options.Strict},
)
jsonSerializerType := serializerType{
AcceptContentTypes: []string{runtime.ContentTypeJSON},
ContentType: runtime.ContentTypeJSON,
FileExtensions: []string{"json"},
EncodesAsText: true,
Serializer: jsonSerializer,
Framer: json.Framer,
StreamSerializer: jsonSerializer,
}
if options.Pretty {
jsonSerializerType.PrettySerializer = json.NewSerializerWithOptions(
mf, scheme, scheme,
json.SerializerOptions{Yaml: false, Pretty: true, Strict: options.Strict},
)
}
yamlSerializer := json.NewSerializerWithOptions(
mf, scheme, scheme,
json.SerializerOptions{Yaml: true, Pretty: false, Strict: options.Strict},
)
protoSerializer := protobuf.NewSerializer(scheme, scheme)
protoRawSerializer := protobuf.NewRawSerializer(scheme, scheme)
serializers := []serializerType{
jsonSerializerType,
{
AcceptContentTypes: []string{"application/json"},
ContentType: "application/json",
FileExtensions: []string{"json"},
EncodesAsText: true,
Serializer: jsonSerializer,
PrettySerializer: jsonPrettySerializer,
Framer: json.Framer,
StreamSerializer: jsonSerializer,
},
{
AcceptContentTypes: []string{"application/yaml"},
ContentType: "application/yaml",
AcceptContentTypes: []string{runtime.ContentTypeYAML},
ContentType: runtime.ContentTypeYAML,
FileExtensions: []string{"yaml"},
EncodesAsText: true,
Serializer: yamlSerializer,
},
{
AcceptContentTypes: []string{runtime.ContentTypeProtobuf},
ContentType: runtime.ContentTypeProtobuf,
FileExtensions: []string{"pb"},
Serializer: protoSerializer,
Framer: protobuf.LengthDelimitedFramer,
StreamSerializer: protoRawSerializer,
},
}
for _, fn := range serializerExtensions {
@@ -89,14 +116,56 @@ type CodecFactory struct {
legacySerializer runtime.Serializer
}
// CodecFactoryOptions holds the options for configuring CodecFactory behavior
type CodecFactoryOptions struct {
// Strict configures all serializers in strict mode
Strict bool
// Pretty includes a pretty serializer along with the non-pretty one
Pretty bool
}
// CodecFactoryOptionsMutator takes a pointer to an options struct and then modifies it.
// Functions implementing this type can be passed to the NewCodecFactory() constructor.
type CodecFactoryOptionsMutator func(*CodecFactoryOptions)
// EnablePretty enables including a pretty serializer along with the non-pretty one
func EnablePretty(options *CodecFactoryOptions) {
options.Pretty = true
}
// DisablePretty disables including a pretty serializer along with the non-pretty one
func DisablePretty(options *CodecFactoryOptions) {
options.Pretty = false
}
// EnableStrict enables configuring all serializers in strict mode
func EnableStrict(options *CodecFactoryOptions) {
options.Strict = true
}
// DisableStrict disables configuring all serializers in strict mode
func DisableStrict(options *CodecFactoryOptions) {
options.Strict = false
}
// NewCodecFactory provides methods for retrieving serializers for the supported wire formats
// and conversion wrappers to define preferred internal and external versions. In the future,
// as the internal version is used less, callers may instead use a defaulting serializer and
// only convert objects which are shared internally (Status, common API machinery).
//
// Mutators can be passed to change the CodecFactoryOptions before construction of the factory.
// It is recommended to explicitly pass mutators instead of relying on defaults.
// By default, Pretty is enabled -- this is conformant with previously supported behavior.
//
// TODO: allow other codecs to be compiled in?
// TODO: accept a scheme interface
func NewCodecFactory(scheme *runtime.Scheme) CodecFactory {
serializers := newSerializersForScheme(scheme, json.DefaultMetaFactory)
func NewCodecFactory(scheme *runtime.Scheme, mutators ...CodecFactoryOptionsMutator) CodecFactory {
options := CodecFactoryOptions{Pretty: true}
for _, fn := range mutators {
fn(&options)
}
serializers := newSerializersForScheme(scheme, json.DefaultMetaFactory, options)
return newCodecFactory(scheme, serializers)
}
@@ -120,6 +189,15 @@ func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) Codec
Serializer: d.Serializer,
PrettySerializer: d.PrettySerializer,
}
mediaType, _, err := mime.ParseMediaType(info.MediaType)
if err != nil {
panic(err)
}
parts := strings.SplitN(mediaType, "/", 2)
info.MediaTypeType = parts[0]
info.MediaTypeSubType = parts[1]
if d.StreamSerializer != nil {
info.StreamSerializer = &runtime.StreamSerializerInfo{
Serializer: d.StreamSerializer,
@@ -148,6 +226,12 @@ func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) Codec
}
}
// WithoutConversion returns a NegotiatedSerializer that performs no conversion, even if the
// caller requests it.
func (f CodecFactory) WithoutConversion() runtime.NegotiatedSerializer {
return WithoutConversionCodecFactory{f}
}
// SupportedMediaTypes returns the RFC2046 media types that this factory has serializers for.
func (f CodecFactory) SupportedMediaTypes() []runtime.SerializerInfo {
return f.accepts
@@ -215,23 +299,26 @@ func (f CodecFactory) EncoderForVersion(encoder runtime.Encoder, gv runtime.Grou
return f.CodecForVersions(encoder, nil, gv, nil)
}
// DirectCodecFactory provides methods for retrieving "DirectCodec"s, which do not do conversion.
type DirectCodecFactory struct {
// WithoutConversionCodecFactory is a CodecFactory that will explicitly ignore requests to perform conversion.
// This wrapper is used while code migrates away from using conversion (such as external clients) and in the future
// will be unnecessary when we change the signature of NegotiatedSerializer.
type WithoutConversionCodecFactory struct {
CodecFactory
}
// EncoderForVersion returns an encoder that does not do conversion.
func (f DirectCodecFactory) EncoderForVersion(serializer runtime.Encoder, version runtime.GroupVersioner) runtime.Encoder {
return versioning.DirectEncoder{
// EncoderForVersion returns an encoder that does not do conversion, but does set the group version kind of the object
// when serialized.
func (f WithoutConversionCodecFactory) EncoderForVersion(serializer runtime.Encoder, version runtime.GroupVersioner) runtime.Encoder {
return runtime.WithVersionEncoder{
Version: version,
Encoder: serializer,
ObjectTyper: f.CodecFactory.scheme,
}
}
// DecoderToVersion returns an decoder that does not do conversion. gv is ignored.
func (f DirectCodecFactory) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder {
return versioning.DirectDecoder{
// DecoderToVersion returns an decoder that does not do conversion.
func (f WithoutConversionCodecFactory) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder {
return runtime.WithoutVersionDecoder{
Decoder: serializer,
}
}

View File

@@ -35,34 +35,56 @@ import (
// NewSerializer creates a JSON serializer that handles encoding versioned objects into the proper JSON form. If typer
// is not nil, the object has the group, version, and kind fields set.
// Deprecated: use NewSerializerWithOptions instead.
func NewSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, pretty bool) *Serializer {
return &Serializer{
meta: meta,
creater: creater,
typer: typer,
yaml: false,
pretty: pretty,
}
return NewSerializerWithOptions(meta, creater, typer, SerializerOptions{false, pretty, false})
}
// NewYAMLSerializer creates a YAML serializer that handles encoding versioned objects into the proper YAML form. If typer
// is not nil, the object has the group, version, and kind fields set. This serializer supports only the subset of YAML that
// matches JSON, and will error if constructs are used that do not serialize to JSON.
// Deprecated: use NewSerializerWithOptions instead.
func NewYAMLSerializer(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper) *Serializer {
return NewSerializerWithOptions(meta, creater, typer, SerializerOptions{true, false, false})
}
// NewSerializerWithOptions creates a JSON/YAML serializer that handles encoding versioned objects into the proper JSON/YAML
// form. If typer is not nil, the object has the group, version, and kind fields set. Options are copied into the Serializer
// and are immutable.
func NewSerializerWithOptions(meta MetaFactory, creater runtime.ObjectCreater, typer runtime.ObjectTyper, options SerializerOptions) *Serializer {
return &Serializer{
meta: meta,
creater: creater,
typer: typer,
yaml: true,
options: options,
}
}
// SerializerOptions holds the options which are used to configure a JSON/YAML serializer.
// example:
// (1) To configure a JSON serializer, set `Yaml` to `false`.
// (2) To configure a YAML serializer, set `Yaml` to `true`.
// (3) To configure a strict serializer that can return strictDecodingError, set `Strict` to `true`.
type SerializerOptions struct {
// Yaml: configures the Serializer to work with JSON(false) or YAML(true).
// When `Yaml` is enabled, this serializer only supports the subset of YAML that
// matches JSON, and will error if constructs are used that do not serialize to JSON.
Yaml bool
// Pretty: configures a JSON enabled Serializer(`Yaml: false`) to produce human-readable output.
// This option is silently ignored when `Yaml` is `true`.
Pretty bool
// Strict: configures the Serializer to return strictDecodingError's when duplicate fields are present decoding JSON or YAML.
// Note that enabling this option is not as performant as the non-strict variant, and should not be used in fast paths.
Strict bool
}
type Serializer struct {
meta MetaFactory
options SerializerOptions
creater runtime.ObjectCreater
typer runtime.ObjectTyper
yaml bool
pretty bool
}
// Serializer implements Serializer
@@ -100,7 +122,27 @@ func (customNumberDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
}
iter.ReportError("DecodeNumber", err.Error())
default:
// init depth, if needed
if iter.Attachment == nil {
iter.Attachment = int(1)
}
// remember current depth
originalAttachment := iter.Attachment
// increment depth before descending
if i, ok := iter.Attachment.(int); ok {
iter.Attachment = i + 1
if i > 10000 {
iter.ReportError("parse", "exceeded max depth")
return
}
}
*(*interface{})(ptr) = iter.Read()
// restore current depth
iter.Attachment = originalAttachment
}
}
@@ -119,11 +161,28 @@ func CaseSensitiveJsonIterator() jsoniter.API {
return config
}
// Private copy of jsoniter to try to shield against possible mutations
// StrictCaseSensitiveJsonIterator returns a jsoniterator API that's configured to be
// case-sensitive, but also disallows unknown fields when unmarshalling. It is compatible with
// the encoding/json standard library.
func StrictCaseSensitiveJsonIterator() jsoniter.API {
config := jsoniter.Config{
EscapeHTML: true,
SortMapKeys: true,
ValidateJsonRawMessage: true,
CaseSensitive: true,
DisallowUnknownFields: true,
}.Froze()
// Force jsoniter to decode number to interface{} via int64/float64, if possible.
config.RegisterExtension(&customNumberExtension{})
return config
}
// Private copies of jsoniter to try to shield against possible mutations
// from outside. Still does not protect from package level jsoniter.Register*() functions - someone calling them
// in some other library will mess with every usage of the jsoniter library in the whole program.
// See https://github.com/json-iterator/go/issues/265
var caseSensitiveJsonIterator = CaseSensitiveJsonIterator()
var strictCaseSensitiveJsonIterator = StrictCaseSensitiveJsonIterator()
// gvkWithDefaults returns group kind and version defaulting from provided default
func gvkWithDefaults(actual, defaultGVK schema.GroupVersionKind) schema.GroupVersionKind {
@@ -160,7 +219,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
}
data := originalData
if s.yaml {
if s.options.Yaml {
altered, err := yaml.YAMLToJSON(data)
if err != nil {
return nil, nil, err
@@ -216,12 +275,38 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
if err := caseSensitiveJsonIterator.Unmarshal(data, obj); err != nil {
return nil, actual, err
}
// If the deserializer is non-strict, return successfully here.
if !s.options.Strict {
return obj, actual, nil
}
// In strict mode pass the data trough the YAMLToJSONStrict converter.
// This is done to catch duplicate fields regardless of encoding (JSON or YAML). For JSON data,
// the output would equal the input, unless there is a parsing error such as duplicate fields.
// As we know this was successful in the non-strict case, the only error that may be returned here
// is because of the newly-added strictness. hence we know we can return the typed strictDecoderError
// the actual error is that the object contains duplicate fields.
altered, err := yaml.YAMLToJSONStrict(originalData)
if err != nil {
return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
}
// As performance is not an issue for now for the strict deserializer (one has regardless to do
// the unmarshal twice), we take the sanitized, altered data that is guaranteed to have no duplicated
// fields, and unmarshal this into a copy of the already-populated obj. Any error that occurs here is
// due to that a matching field doesn't exist in the object. hence we can return a typed strictDecoderError,
// the actual error is that the object contains unknown field.
strictObj := obj.DeepCopyObject()
if err := strictCaseSensitiveJsonIterator.Unmarshal(altered, strictObj); err != nil {
return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
}
// Always return the same object as the non-strict serializer to avoid any deviations.
return obj, actual, nil
}
// Encode serializes the provided object to the given writer.
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
if s.yaml {
if s.options.Yaml {
json, err := caseSensitiveJsonIterator.Marshal(obj)
if err != nil {
return err
@@ -234,7 +319,7 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
return err
}
if s.pretty {
if s.options.Pretty {
data, err := caseSensitiveJsonIterator.MarshalIndent(obj, "", " ")
if err != nil {
return err
@@ -248,7 +333,7 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
// RecognizesData implements the RecognizingDecoder interface.
func (s *Serializer) RecognizesData(peek io.Reader) (ok, unknown bool, err error) {
if s.yaml {
if s.options.Yaml {
// we could potentially look for '---'
return false, true, nil
}

View File

@@ -69,22 +69,18 @@ func IsNotMarshalable(err error) bool {
// NewSerializer creates a Protobuf serializer that handles encoding versioned objects into the proper wire form. If a typer
// is passed, the encoded object will have group, version, and kind fields set. If typer is nil, the objects will be written
// as-is (any type info passed with the object will be used).
//
// This encoding scheme is experimental, and is subject to change at any time.
func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, defaultContentType string) *Serializer {
func NewSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper) *Serializer {
return &Serializer{
prefix: protoEncodingPrefix,
creater: creater,
typer: typer,
contentType: defaultContentType,
prefix: protoEncodingPrefix,
creater: creater,
typer: typer,
}
}
type Serializer struct {
prefix []byte
creater runtime.ObjectCreater
typer runtime.ObjectTyper
contentType string
prefix []byte
creater runtime.ObjectCreater
typer runtime.ObjectTyper
}
var _ runtime.Serializer = &Serializer{}
@@ -138,7 +134,7 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil {
*intoUnknown = unk
if ok, _, _ := s.RecognizesData(bytes.NewBuffer(unk.Raw)); ok {
intoUnknown.ContentType = s.contentType
intoUnknown.ContentType = runtime.ContentTypeProtobuf
}
return intoUnknown, &actual, nil
}
@@ -207,7 +203,7 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
switch t := obj.(type) {
case bufferedMarshaller:
// this path performs a single allocation during write but requires the caller to implement
// the more efficient Size and MarshalTo methods
// the more efficient Size and MarshalToSizedBuffer methods
encodedSize := uint64(t.Size())
estimatedSize := prefixSize + estimateUnknownSize(&unk, encodedSize)
data := make([]byte, estimatedSize)
@@ -287,6 +283,12 @@ type bufferedMarshaller interface {
runtime.ProtobufMarshaller
}
// Like bufferedMarshaller, but is able to marshal backwards, which is more efficient since it doesn't call Size() as frequently.
type bufferedReverseMarshaller interface {
proto.Sizer
runtime.ProtobufReverseMarshaller
}
// estimateUnknownSize returns the expected bytes consumed by a given runtime.Unknown
// object with a nil RawJSON struct and the expected size of the provided buffer. The
// returned size will not be correct if RawJSOn is set on unk.
@@ -303,20 +305,18 @@ func estimateUnknownSize(unk *runtime.Unknown, byteSize uint64) uint64 {
// encoded object, and thus is not self describing (callers must know what type is being described in order to decode).
//
// This encoding scheme is experimental, and is subject to change at any time.
func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper, defaultContentType string) *RawSerializer {
func NewRawSerializer(creater runtime.ObjectCreater, typer runtime.ObjectTyper) *RawSerializer {
return &RawSerializer{
creater: creater,
typer: typer,
contentType: defaultContentType,
creater: creater,
typer: typer,
}
}
// RawSerializer encodes and decodes objects without adding a runtime.Unknown wrapper (objects are encoded without identifying
// type).
type RawSerializer struct {
creater runtime.ObjectCreater
typer runtime.ObjectTyper
contentType string
creater runtime.ObjectCreater
typer runtime.ObjectTyper
}
var _ runtime.Serializer = &RawSerializer{}
@@ -358,7 +358,7 @@ func (s *RawSerializer) Decode(originalData []byte, gvk *schema.GroupVersionKind
if intoUnknown, ok := into.(*runtime.Unknown); ok && intoUnknown != nil {
intoUnknown.Raw = data
intoUnknown.ContentEncoding = ""
intoUnknown.ContentType = s.contentType
intoUnknown.ContentType = runtime.ContentTypeProtobuf
intoUnknown.SetGroupVersionKind(*actual)
return intoUnknown, actual, nil
}
@@ -411,12 +411,28 @@ func unmarshalToObject(typer runtime.ObjectTyper, creater runtime.ObjectCreater,
if err := proto.Unmarshal(data, pb); err != nil {
return nil, actual, err
}
if actual != nil {
obj.GetObjectKind().SetGroupVersionKind(*actual)
}
return obj, actual, nil
}
// Encode serializes the provided object to the given writer. Overrides is ignored.
func (s *RawSerializer) Encode(obj runtime.Object, w io.Writer) error {
switch t := obj.(type) {
case bufferedReverseMarshaller:
// this path performs a single allocation during write but requires the caller to implement
// the more efficient Size and MarshalToSizedBuffer methods
encodedSize := uint64(t.Size())
data := make([]byte, encodedSize)
n, err := t.MarshalToSizedBuffer(data)
if err != nil {
return err
}
_, err = w.Write(data[:n])
return err
case bufferedMarshaller:
// this path performs a single allocation during write but requires the caller to implement
// the more efficient Size and MarshalTo methods

View File

@@ -1,48 +0,0 @@
/*
Copyright 2014 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package serializer
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer/protobuf"
)
const (
// contentTypeProtobuf is the protobuf type exposed for Kubernetes. It is private to prevent others from
// depending on it unintentionally.
// TODO: potentially move to pkg/api (since it's part of the Kube public API) and pass it in to the
// CodecFactory on initialization.
contentTypeProtobuf = "application/vnd.kubernetes.protobuf"
)
func protobufSerializer(scheme *runtime.Scheme) (serializerType, bool) {
serializer := protobuf.NewSerializer(scheme, scheme, contentTypeProtobuf)
raw := protobuf.NewRawSerializer(scheme, scheme, contentTypeProtobuf)
return serializerType{
AcceptContentTypes: []string{contentTypeProtobuf},
ContentType: contentTypeProtobuf,
FileExtensions: []string{"pb"},
Serializer: serializer,
Framer: protobuf.LengthDelimitedFramer,
StreamSerializer: raw,
}, true
}
func init() {
serializerExtensions = append(serializerExtensions, protobufSerializer)
}

View File

@@ -106,20 +106,13 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
}
if d, ok := obj.(runtime.NestedObjectDecoder); ok {
if err := d.DecodeNestedObjects(DirectDecoder{c.decoder}); err != nil {
if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil {
return nil, gvk, err
}
}
// if we specify a target, use generic conversion.
if into != nil {
if into == obj {
if isVersioned {
return versioned, gvk, nil
}
return into, gvk, nil
}
// perform defaulting if requested
if c.defaulter != nil {
// create a copy to ensure defaulting is not applied to the original versioned objects
@@ -133,6 +126,14 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
}
}
// Short-circuit conversion if the into object is same object
if into == obj {
if isVersioned {
return versioned, gvk, nil
}
return into, gvk, nil
}
if err := c.convertor.Convert(obj, into, c.decodeVersion); err != nil {
return nil, gvk, err
}
@@ -199,84 +200,33 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
return err
}
objectKind := obj.GetObjectKind()
old := objectKind.GroupVersionKind()
// restore the old GVK after encoding
defer objectKind.SetGroupVersionKind(old)
if c.encodeVersion == nil || isUnversioned {
if e, ok := obj.(runtime.NestedObjectEncoder); ok {
if err := e.EncodeNestedObjects(DirectEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
if err := e.EncodeNestedObjects(runtime.WithVersionEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
return err
}
}
objectKind := obj.GetObjectKind()
old := objectKind.GroupVersionKind()
objectKind.SetGroupVersionKind(gvks[0])
err = c.encoder.Encode(obj, w)
objectKind.SetGroupVersionKind(old)
return err
return c.encoder.Encode(obj, w)
}
// Perform a conversion if necessary
objectKind := obj.GetObjectKind()
old := objectKind.GroupVersionKind()
out, err := c.convertor.ConvertToVersion(obj, c.encodeVersion)
if err != nil {
return err
}
if e, ok := out.(runtime.NestedObjectEncoder); ok {
if err := e.EncodeNestedObjects(DirectEncoder{Version: c.encodeVersion, Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
if err := e.EncodeNestedObjects(runtime.WithVersionEncoder{Version: c.encodeVersion, Encoder: c.encoder, ObjectTyper: c.typer}); err != nil {
return err
}
}
// Conversion is responsible for setting the proper group, version, and kind onto the outgoing object
err = c.encoder.Encode(out, w)
// restore the old GVK, in case conversion returned the same object
objectKind.SetGroupVersionKind(old)
return err
}
// DirectEncoder serializes an object and ensures the GVK is set.
type DirectEncoder struct {
Version runtime.GroupVersioner
runtime.Encoder
runtime.ObjectTyper
}
// Encode does not do conversion. It sets the gvk during serialization.
func (e DirectEncoder) Encode(obj runtime.Object, stream io.Writer) error {
gvks, _, err := e.ObjectTyper.ObjectKinds(obj)
if err != nil {
if runtime.IsNotRegisteredError(err) {
return e.Encoder.Encode(obj, stream)
}
return err
}
kind := obj.GetObjectKind()
oldGVK := kind.GroupVersionKind()
gvk := gvks[0]
if e.Version != nil {
preferredGVK, ok := e.Version.KindForGroupVersionKinds(gvks)
if ok {
gvk = preferredGVK
}
}
kind.SetGroupVersionKind(gvk)
err = e.Encoder.Encode(obj, stream)
kind.SetGroupVersionKind(oldGVK)
return err
}
// DirectDecoder clears the group version kind of a deserialized object.
type DirectDecoder struct {
runtime.Decoder
}
// Decode does not do conversion. It removes the gvk during deserialization.
func (d DirectDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
obj, gvk, err := d.Decoder.Decode(data, defaults, into)
if obj != nil {
kind := obj.GetObjectKind()
// clearing the gvk is just a convention of a codec
kind.SetGroupVersionKind(schema.GroupVersionKind{})
}
return obj, gvk, err
return c.encoder.Encode(out, w)
}

View File

@@ -41,7 +41,9 @@ type TypeMeta struct {
}
const (
ContentTypeJSON string = "application/json"
ContentTypeJSON string = "application/json"
ContentTypeYAML string = "application/yaml"
ContentTypeProtobuf string = "application/vnd.kubernetes.protobuf"
)
// RawExtension is used to hold extensions in external versions.
@@ -93,7 +95,7 @@ type RawExtension struct {
// Raw is the underlying serialization of this object.
//
// TODO: Determine how to detect ContentType and ContentEncoding of 'Raw' data.
Raw []byte `protobuf:"bytes,1,opt,name=raw"`
Raw []byte `json:"-" protobuf:"bytes,1,opt,name=raw"`
// Object can hold a representation of this extension - useful for working with versioned
// structs.
Object Object `json:"-"`

View File

@@ -24,46 +24,66 @@ type ProtobufMarshaller interface {
MarshalTo(data []byte) (int, error)
}
type ProtobufReverseMarshaller interface {
MarshalToSizedBuffer(data []byte) (int, error)
}
// NestedMarshalTo allows a caller to avoid extra allocations during serialization of an Unknown
// that will contain an object that implements ProtobufMarshaller.
// that will contain an object that implements ProtobufMarshaller or ProtobufReverseMarshaller.
func (m *Unknown) NestedMarshalTo(data []byte, b ProtobufMarshaller, size uint64) (int, error) {
var i int
_ = i
var l int
_ = l
data[i] = 0xa
i++
i = encodeVarintGenerated(data, i, uint64(m.TypeMeta.Size()))
n1, err := m.TypeMeta.MarshalTo(data[i:])
// Calculate the full size of the message.
msgSize := m.Size()
if b != nil {
msgSize += int(size) + sovGenerated(size) + 1
}
// Reverse marshal the fields of m.
i := msgSize
i -= len(m.ContentType)
copy(data[i:], m.ContentType)
i = encodeVarintGenerated(data, i, uint64(len(m.ContentType)))
i--
data[i] = 0x22
i -= len(m.ContentEncoding)
copy(data[i:], m.ContentEncoding)
i = encodeVarintGenerated(data, i, uint64(len(m.ContentEncoding)))
i--
data[i] = 0x1a
if b != nil {
if r, ok := b.(ProtobufReverseMarshaller); ok {
n1, err := r.MarshalToSizedBuffer(data[:i])
if err != nil {
return 0, err
}
i -= int(size)
if uint64(n1) != size {
// programmer error: the Size() method for protobuf does not match the results of LashramOt, which means the proto
// struct returned would be wrong.
return 0, fmt.Errorf("the Size() value of %T was %d, but NestedMarshalTo wrote %d bytes to data", b, size, n1)
}
} else {
i -= int(size)
n1, err := b.MarshalTo(data[i:])
if err != nil {
return 0, err
}
if uint64(n1) != size {
// programmer error: the Size() method for protobuf does not match the results of MarshalTo, which means the proto
// struct returned would be wrong.
return 0, fmt.Errorf("the Size() value of %T was %d, but NestedMarshalTo wrote %d bytes to data", b, size, n1)
}
}
i = encodeVarintGenerated(data, i, size)
i--
data[i] = 0x12
}
n2, err := m.TypeMeta.MarshalToSizedBuffer(data[:i])
if err != nil {
return 0, err
}
i += n1
if b != nil {
data[i] = 0x12
i++
i = encodeVarintGenerated(data, i, size)
n2, err := b.MarshalTo(data[i:])
if err != nil {
return 0, err
}
if uint64(n2) != size {
// programmer error: the Size() method for protobuf does not match the results of MarshalTo, which means the proto
// struct returned would be wrong.
return 0, fmt.Errorf("the Size() value of %T was %d, but NestedMarshalTo wrote %d bytes to data", b, size, n2)
}
i += n2
}
data[i] = 0x1a
i++
i = encodeVarintGenerated(data, i, uint64(len(m.ContentEncoding)))
i += copy(data[i:], m.ContentEncoding)
data[i] = 0x22
i++
i = encodeVarintGenerated(data, i, uint64(len(m.ContentType)))
i += copy(data[i:], m.ContentType)
return i, nil
i -= n2
i = encodeVarintGenerated(data, i, uint64(n2))
i--
data[i] = 0xa
return msgSize - i, nil
}

View File

@@ -25,4 +25,5 @@ const (
JSONPatchType PatchType = "application/json-patch+json"
MergePatchType PatchType = "application/merge-patch+json"
StrategicMergePatchType PatchType = "application/strategic-merge-patch+json"
ApplyPatchType PatchType = "application/apply-patch+yaml"
)

View File

@@ -21,11 +21,18 @@ import (
"time"
)
// PassiveClock allows for injecting fake or real clocks into code
// that needs to read the current time but does not support scheduling
// activity in the future.
type PassiveClock interface {
Now() time.Time
Since(time.Time) time.Duration
}
// Clock allows for injecting fake or real clocks into code that
// needs to do arbitrary things based on time.
type Clock interface {
Now() time.Time
Since(time.Time) time.Duration
PassiveClock
After(time.Duration) <-chan time.Time
NewTimer(time.Duration) Timer
Sleep(time.Duration)
@@ -66,10 +73,15 @@ func (RealClock) Sleep(d time.Duration) {
time.Sleep(d)
}
// FakeClock implements Clock, but returns an arbitrary time.
type FakeClock struct {
// FakePassiveClock implements PassiveClock, but returns an arbitrary time.
type FakePassiveClock struct {
lock sync.RWMutex
time time.Time
}
// FakeClock implements Clock, but returns an arbitrary time.
type FakeClock struct {
FakePassiveClock
// waiters are waiting for the fake time to pass their specified time
waiters []fakeClockWaiter
@@ -80,29 +92,41 @@ type fakeClockWaiter struct {
stepInterval time.Duration
skipIfBlocked bool
destChan chan time.Time
fired bool
}
func NewFakeClock(t time.Time) *FakeClock {
return &FakeClock{
func NewFakePassiveClock(t time.Time) *FakePassiveClock {
return &FakePassiveClock{
time: t,
}
}
func NewFakeClock(t time.Time) *FakeClock {
return &FakeClock{
FakePassiveClock: *NewFakePassiveClock(t),
}
}
// Now returns f's time.
func (f *FakeClock) Now() time.Time {
func (f *FakePassiveClock) Now() time.Time {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time
}
// Since returns time since the time in f.
func (f *FakeClock) Since(ts time.Time) time.Duration {
func (f *FakePassiveClock) Since(ts time.Time) time.Duration {
f.lock.RLock()
defer f.lock.RUnlock()
return f.time.Sub(ts)
}
// Sets the time.
func (f *FakePassiveClock) SetTime(t time.Time) {
f.lock.Lock()
defer f.lock.Unlock()
f.time = t
}
// Fake version of time.After(d).
func (f *FakeClock) After(d time.Duration) <-chan time.Time {
f.lock.Lock()
@@ -175,12 +199,10 @@ func (f *FakeClock) setTimeLocked(t time.Time) {
if w.skipIfBlocked {
select {
case w.destChan <- t:
w.fired = true
default:
}
} else {
w.destChan <- t
w.fired = true
}
if w.stepInterval > 0 {
@@ -287,36 +309,50 @@ func (f *fakeTimer) C() <-chan time.Time {
return f.waiter.destChan
}
// Stop stops the timer and returns true if the timer has not yet fired, or false otherwise.
// Stop conditionally stops the timer. If the timer has neither fired
// nor been stopped then this call stops the timer and returns true,
// otherwise this call returns false. This is like time.Timer::Stop.
func (f *fakeTimer) Stop() bool {
f.fakeClock.lock.Lock()
defer f.fakeClock.lock.Unlock()
newWaiters := make([]fakeClockWaiter, 0, len(f.fakeClock.waiters))
for i := range f.fakeClock.waiters {
w := &f.fakeClock.waiters[i]
if w != &f.waiter {
newWaiters = append(newWaiters, *w)
// The timer has already fired or been stopped, unless it is found
// among the clock's waiters.
stopped := false
oldWaiters := f.fakeClock.waiters
newWaiters := make([]fakeClockWaiter, 0, len(oldWaiters))
seekChan := f.waiter.destChan
for i := range oldWaiters {
// Identify the timer's fakeClockWaiter by the identity of the
// destination channel, nothing else is necessarily unique and
// constant since the timer's creation.
if oldWaiters[i].destChan == seekChan {
stopped = true
} else {
newWaiters = append(newWaiters, oldWaiters[i])
}
}
f.fakeClock.waiters = newWaiters
return !f.waiter.fired
return stopped
}
// Reset resets the timer to the fake clock's "now" + d. It returns true if the timer has not yet
// fired, or false otherwise.
// Reset conditionally updates the firing time of the timer. If the
// timer has neither fired nor been stopped then this call resets the
// timer to the fake clock's "now" + d and returns true, otherwise
// this call returns false. This is like time.Timer::Reset.
func (f *fakeTimer) Reset(d time.Duration) bool {
f.fakeClock.lock.Lock()
defer f.fakeClock.lock.Unlock()
active := !f.waiter.fired
f.waiter.fired = false
f.waiter.targetTime = f.fakeClock.time.Add(d)
return active
waiters := f.fakeClock.waiters
seekChan := f.waiter.destChan
for i := range waiters {
if waiters[i].destChan == seekChan {
waiters[i].targetTime = f.fakeClock.time.Add(d)
return true
}
}
return false
}
type Ticker interface {

View File

@@ -18,16 +18,12 @@ package diff
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
"sort"
"strings"
"text/tabwriter"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/util/validation/field"
"github.com/google/go-cmp/cmp"
)
// StringDiff diffs a and b and returns a human readable diff.
@@ -50,220 +46,29 @@ func StringDiff(a, b string) string {
return string(out)
}
// ObjectDiff writes the two objects out as JSON and prints out the identical part of
// the objects followed by the remaining part of 'a' and finally the remaining part of 'b'.
// For debugging tests.
func legacyDiff(a, b interface{}) string {
return cmp.Diff(a, b)
}
// ObjectDiff prints the diff of two go objects and fails if the objects
// contain unhandled unexported fields.
// DEPRECATED: use github.com/google/go-cmp/cmp.Diff
func ObjectDiff(a, b interface{}) string {
ab, err := json.Marshal(a)
if err != nil {
panic(fmt.Sprintf("a: %v", err))
}
bb, err := json.Marshal(b)
if err != nil {
panic(fmt.Sprintf("b: %v", err))
}
return StringDiff(string(ab), string(bb))
return legacyDiff(a, b)
}
// ObjectGoPrintDiff is like ObjectDiff, but uses go-spew to print the objects,
// which shows absolutely everything by recursing into every single pointer
// (go's %#v formatters OTOH stop at a certain point). This is needed when you
// can't figure out why reflect.DeepEqual is returning false and nothing is
// showing you differences. This will.
// ObjectGoPrintDiff prints the diff of two go objects and fails if the objects
// contain unhandled unexported fields.
// DEPRECATED: use github.com/google/go-cmp/cmp.Diff
func ObjectGoPrintDiff(a, b interface{}) string {
s := spew.ConfigState{DisableMethods: true}
return StringDiff(
s.Sprintf("%#v", a),
s.Sprintf("%#v", b),
)
return legacyDiff(a, b)
}
// ObjectReflectDiff prints the diff of two go objects and fails if the objects
// contain unhandled unexported fields.
// DEPRECATED: use github.com/google/go-cmp/cmp.Diff
func ObjectReflectDiff(a, b interface{}) string {
vA, vB := reflect.ValueOf(a), reflect.ValueOf(b)
if vA.Type() != vB.Type() {
return fmt.Sprintf("type A %T and type B %T do not match", a, b)
}
diffs := objectReflectDiff(field.NewPath("object"), vA, vB)
if len(diffs) == 0 {
return "<no diffs>"
}
out := []string{""}
for _, d := range diffs {
elidedA, elidedB := limit(d.a, d.b, 80)
out = append(out,
fmt.Sprintf("%s:", d.path),
fmt.Sprintf(" a: %s", elidedA),
fmt.Sprintf(" b: %s", elidedB),
)
}
return strings.Join(out, "\n")
}
// limit:
// 1. stringifies aObj and bObj
// 2. elides identical prefixes if either is too long
// 3. elides remaining content from the end if either is too long
func limit(aObj, bObj interface{}, max int) (string, string) {
elidedPrefix := ""
elidedASuffix := ""
elidedBSuffix := ""
a, b := fmt.Sprintf("%#v", aObj), fmt.Sprintf("%#v", bObj)
if aObj != nil && bObj != nil {
if aType, bType := fmt.Sprintf("%T", aObj), fmt.Sprintf("%T", bObj); aType != bType {
a = fmt.Sprintf("%s (%s)", a, aType)
b = fmt.Sprintf("%s (%s)", b, bType)
}
}
for {
switch {
case len(a) > max && len(a) > 4 && len(b) > 4 && a[:4] == b[:4]:
// a is too long, b has data, and the first several characters are the same
elidedPrefix = "..."
a = a[2:]
b = b[2:]
case len(b) > max && len(b) > 4 && len(a) > 4 && a[:4] == b[:4]:
// b is too long, a has data, and the first several characters are the same
elidedPrefix = "..."
a = a[2:]
b = b[2:]
case len(a) > max:
a = a[:max]
elidedASuffix = "..."
case len(b) > max:
b = b[:max]
elidedBSuffix = "..."
default:
// both are short enough
return elidedPrefix + a + elidedASuffix, elidedPrefix + b + elidedBSuffix
}
}
}
func public(s string) bool {
if len(s) == 0 {
return false
}
return s[:1] == strings.ToUpper(s[:1])
}
type diff struct {
path *field.Path
a, b interface{}
}
type orderedDiffs []diff
func (d orderedDiffs) Len() int { return len(d) }
func (d orderedDiffs) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
func (d orderedDiffs) Less(i, j int) bool {
a, b := d[i].path.String(), d[j].path.String()
if a < b {
return true
}
return false
}
func objectReflectDiff(path *field.Path, a, b reflect.Value) []diff {
switch a.Type().Kind() {
case reflect.Struct:
var changes []diff
for i := 0; i < a.Type().NumField(); i++ {
if !public(a.Type().Field(i).Name) {
if reflect.DeepEqual(a.Interface(), b.Interface()) {
continue
}
return []diff{{path: path, a: fmt.Sprintf("%#v", a), b: fmt.Sprintf("%#v", b)}}
}
if sub := objectReflectDiff(path.Child(a.Type().Field(i).Name), a.Field(i), b.Field(i)); len(sub) > 0 {
changes = append(changes, sub...)
}
}
return changes
case reflect.Ptr, reflect.Interface:
if a.IsNil() || b.IsNil() {
switch {
case a.IsNil() && b.IsNil():
return nil
case a.IsNil():
return []diff{{path: path, a: nil, b: b.Interface()}}
default:
return []diff{{path: path, a: a.Interface(), b: nil}}
}
}
return objectReflectDiff(path, a.Elem(), b.Elem())
case reflect.Chan:
if !reflect.DeepEqual(a.Interface(), b.Interface()) {
return []diff{{path: path, a: a.Interface(), b: b.Interface()}}
}
return nil
case reflect.Slice:
lA, lB := a.Len(), b.Len()
l := lA
if lB < lA {
l = lB
}
if lA == lB && lA == 0 {
if a.IsNil() != b.IsNil() {
return []diff{{path: path, a: a.Interface(), b: b.Interface()}}
}
return nil
}
var diffs []diff
for i := 0; i < l; i++ {
if !reflect.DeepEqual(a.Index(i), b.Index(i)) {
diffs = append(diffs, objectReflectDiff(path.Index(i), a.Index(i), b.Index(i))...)
}
}
for i := l; i < lA; i++ {
diffs = append(diffs, diff{path: path.Index(i), a: a.Index(i), b: nil})
}
for i := l; i < lB; i++ {
diffs = append(diffs, diff{path: path.Index(i), a: nil, b: b.Index(i)})
}
return diffs
case reflect.Map:
if reflect.DeepEqual(a.Interface(), b.Interface()) {
return nil
}
aKeys := make(map[interface{}]interface{})
for _, key := range a.MapKeys() {
aKeys[key.Interface()] = a.MapIndex(key).Interface()
}
var missing []diff
for _, key := range b.MapKeys() {
if _, ok := aKeys[key.Interface()]; ok {
delete(aKeys, key.Interface())
if reflect.DeepEqual(a.MapIndex(key).Interface(), b.MapIndex(key).Interface()) {
continue
}
missing = append(missing, objectReflectDiff(path.Key(fmt.Sprintf("%s", key.Interface())), a.MapIndex(key), b.MapIndex(key))...)
continue
}
missing = append(missing, diff{path: path.Key(fmt.Sprintf("%s", key.Interface())), a: nil, b: b.MapIndex(key).Interface()})
}
for key, value := range aKeys {
missing = append(missing, diff{path: path.Key(fmt.Sprintf("%s", key)), a: value, b: nil})
}
if len(missing) == 0 {
missing = append(missing, diff{path: path, a: a.Interface(), b: b.Interface()})
}
sort.Sort(orderedDiffs(missing))
return missing
default:
if reflect.DeepEqual(a.Interface(), b.Interface()) {
return nil
}
if !a.CanInterface() {
return []diff{{path: path, a: fmt.Sprintf("%#v", a), b: fmt.Sprintf("%#v", b)}}
}
return []diff{{path: path, a: a.Interface(), b: b.Interface()}}
}
return legacyDiff(a, b)
}
// ObjectGoPrintSideBySide prints a and b as textual dumps side by side,

View File

@@ -19,6 +19,8 @@ package errors
import (
"errors"
"fmt"
"k8s.io/apimachinery/pkg/util/sets"
)
// MessageCountMap contains occurrence for each error message.
@@ -67,12 +69,38 @@ func (agg aggregate) Error() string {
if len(agg) == 1 {
return agg[0].Error()
}
result := fmt.Sprintf("[%s", agg[0].Error())
for i := 1; i < len(agg); i++ {
result += fmt.Sprintf(", %s", agg[i].Error())
seenerrs := sets.NewString()
result := ""
agg.visit(func(err error) {
msg := err.Error()
if seenerrs.Has(msg) {
return
}
seenerrs.Insert(msg)
if len(seenerrs) > 1 {
result += ", "
}
result += msg
})
if len(seenerrs) == 1 {
return result
}
return "[" + result + "]"
}
func (agg aggregate) visit(f func(err error)) {
for _, err := range agg {
switch err := err.(type) {
case aggregate:
err.visit(f)
case Aggregate:
for _, nestedErr := range err.Errors() {
f(nestedErr)
}
default:
f(err)
}
}
result += "]"
return result
}
// Errors is part of the Aggregate interface.

View File

@@ -17,22 +17,17 @@ limitations under the License.
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto
/*
Package intstr is a generated protocol buffer package.
It is generated from these files:
k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto
It has these top-level messages:
IntOrString
*/
package intstr
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
import io "io"
io "io"
math "math"
math_bits "math/bits"
proto "github.com/gogo/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
@@ -45,17 +40,69 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
func (m *IntOrString) Reset() { *m = IntOrString{} }
func (*IntOrString) ProtoMessage() {}
func (*IntOrString) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
func (m *IntOrString) Reset() { *m = IntOrString{} }
func (*IntOrString) ProtoMessage() {}
func (*IntOrString) Descriptor() ([]byte, []int) {
return fileDescriptor_94e046ae3ce6121c, []int{0}
}
func (m *IntOrString) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *IntOrString) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
func (m *IntOrString) XXX_Merge(src proto.Message) {
xxx_messageInfo_IntOrString.Merge(m, src)
}
func (m *IntOrString) XXX_Size() int {
return m.Size()
}
func (m *IntOrString) XXX_DiscardUnknown() {
xxx_messageInfo_IntOrString.DiscardUnknown(m)
}
var xxx_messageInfo_IntOrString proto.InternalMessageInfo
func init() {
proto.RegisterType((*IntOrString)(nil), "k8s.io.apimachinery.pkg.util.intstr.IntOrString")
}
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto", fileDescriptor_94e046ae3ce6121c)
}
var fileDescriptor_94e046ae3ce6121c = []byte{
// 292 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8f, 0x31, 0x4b, 0x33, 0x31,
0x1c, 0xc6, 0x93, 0xb7, 0x7d, 0x8b, 0x9e, 0xe0, 0x50, 0x1c, 0x8a, 0x43, 0x7a, 0x28, 0xc8, 0x0d,
0x9a, 0xac, 0xe2, 0xd8, 0xad, 0x20, 0x08, 0x57, 0x71, 0x70, 0xbb, 0x6b, 0x63, 0x1a, 0xae, 0x4d,
0x42, 0xee, 0x7f, 0xc2, 0x6d, 0xfd, 0x08, 0xba, 0x39, 0xfa, 0x71, 0x6e, 0xec, 0xd8, 0x41, 0x8a,
0x17, 0xbf, 0x85, 0x93, 0x5c, 0xee, 0x40, 0xa7, 0xe4, 0x79, 0x9e, 0xdf, 0x2f, 0x90, 0xe0, 0x36,
0xbb, 0xce, 0xa9, 0xd4, 0x2c, 0x2b, 0x52, 0x6e, 0x15, 0x07, 0x9e, 0xb3, 0x67, 0xae, 0x16, 0xda,
0xb2, 0x6e, 0x48, 0x8c, 0x5c, 0x27, 0xf3, 0xa5, 0x54, 0xdc, 0x96, 0xcc, 0x64, 0x82, 0x15, 0x20,
0x57, 0x4c, 0x2a, 0xc8, 0xc1, 0x32, 0xc1, 0x15, 0xb7, 0x09, 0xf0, 0x05, 0x35, 0x56, 0x83, 0x1e,
0x9e, 0xb7, 0x12, 0xfd, 0x2b, 0x51, 0x93, 0x09, 0xda, 0x48, 0xb4, 0x95, 0x4e, 0xaf, 0x84, 0x84,
0x65, 0x91, 0xd2, 0xb9, 0x5e, 0x33, 0xa1, 0x85, 0x66, 0xde, 0x4d, 0x8b, 0x27, 0x9f, 0x7c, 0xf0,
0xb7, 0xf6, 0xcd, 0xb3, 0x57, 0x1c, 0x1c, 0x4d, 0x15, 0xdc, 0xd9, 0x19, 0x58, 0xa9, 0xc4, 0x30,
0x0a, 0xfa, 0x50, 0x1a, 0x3e, 0xc2, 0x21, 0x8e, 0x7a, 0x93, 0x93, 0x6a, 0x3f, 0x46, 0x6e, 0x3f,
0xee, 0xdf, 0x97, 0x86, 0x7f, 0x77, 0x67, 0xec, 0x89, 0xe1, 0x45, 0x30, 0x90, 0x0a, 0x1e, 0x92,
0xd5, 0xe8, 0x5f, 0x88, 0xa3, 0xff, 0x93, 0xe3, 0x8e, 0x1d, 0x4c, 0x7d, 0x1b, 0x77, 0x6b, 0xc3,
0xe5, 0x60, 0x1b, 0xae, 0x17, 0xe2, 0xe8, 0xf0, 0x97, 0x9b, 0xf9, 0x36, 0xee, 0xd6, 0x9b, 0x83,
0xb7, 0xf7, 0x31, 0xda, 0x7c, 0x84, 0x68, 0x72, 0x59, 0xd5, 0x04, 0x6d, 0x6b, 0x82, 0x76, 0x35,
0x41, 0x1b, 0x47, 0x70, 0xe5, 0x08, 0xde, 0x3a, 0x82, 0x77, 0x8e, 0xe0, 0x4f, 0x47, 0xf0, 0xcb,
0x17, 0x41, 0x8f, 0x83, 0xf6, 0xc3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x52, 0xa0, 0xb5, 0xc9,
0x64, 0x01, 0x00, 0x00,
}
func (m *IntOrString) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalTo(dAtA)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
@@ -63,33 +110,44 @@ func (m *IntOrString) Marshal() (dAtA []byte, err error) {
}
func (m *IntOrString) MarshalTo(dAtA []byte) (int, error) {
var i int
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *IntOrString) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
dAtA[i] = 0x8
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.Type))
dAtA[i] = 0x10
i++
i = encodeVarintGenerated(dAtA, i, uint64(m.IntVal))
dAtA[i] = 0x1a
i++
i -= len(m.StrVal)
copy(dAtA[i:], m.StrVal)
i = encodeVarintGenerated(dAtA, i, uint64(len(m.StrVal)))
i += copy(dAtA[i:], m.StrVal)
return i, nil
i--
dAtA[i] = 0x1a
i = encodeVarintGenerated(dAtA, i, uint64(m.IntVal))
i--
dAtA[i] = 0x10
i = encodeVarintGenerated(dAtA, i, uint64(m.Type))
i--
dAtA[i] = 0x8
return len(dAtA) - i, nil
}
func encodeVarintGenerated(dAtA []byte, offset int, v uint64) int {
offset -= sovGenerated(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return offset + 1
return base
}
func (m *IntOrString) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
n += 1 + sovGenerated(uint64(m.Type))
@@ -100,14 +158,7 @@ func (m *IntOrString) Size() (n int) {
}
func sovGenerated(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenerated(x uint64) (n int) {
return sovGenerated(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -127,7 +178,7 @@ func (m *IntOrString) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -155,7 +206,7 @@ func (m *IntOrString) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.Type |= (Type(b) & 0x7F) << shift
m.Type |= Type(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -174,7 +225,7 @@ func (m *IntOrString) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
m.IntVal |= (int32(b) & 0x7F) << shift
m.IntVal |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -193,7 +244,7 @@ func (m *IntOrString) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
@@ -203,6 +254,9 @@ func (m *IntOrString) Unmarshal(dAtA []byte) error {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenerated
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
@@ -217,6 +271,9 @@ func (m *IntOrString) Unmarshal(dAtA []byte) error {
if skippy < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthGenerated
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
@@ -283,10 +340,13 @@ func skipGenerated(dAtA []byte) (n int, err error) {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthGenerated
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthGenerated
}
return iNdEx, nil
case 3:
for {
@@ -315,6 +375,9 @@ func skipGenerated(dAtA []byte) (n int, err error) {
return 0, err
}
iNdEx = start + next
if iNdEx < 0 {
return 0, ErrInvalidLengthGenerated
}
}
return iNdEx, nil
case 4:
@@ -333,30 +396,3 @@ var (
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
)
func init() {
proto.RegisterFile("k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/intstr/generated.proto", fileDescriptorGenerated)
}
var fileDescriptorGenerated = []byte{
// 292 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x8f, 0x31, 0x4b, 0x33, 0x31,
0x1c, 0xc6, 0x93, 0xb7, 0x7d, 0x8b, 0x9e, 0xe0, 0x50, 0x1c, 0x8a, 0x43, 0x7a, 0x28, 0xc8, 0x0d,
0x9a, 0xac, 0xe2, 0xd8, 0xad, 0x20, 0x08, 0x57, 0x71, 0x70, 0xbb, 0x6b, 0x63, 0x1a, 0xae, 0x4d,
0x42, 0xee, 0x7f, 0xc2, 0x6d, 0xfd, 0x08, 0xba, 0x39, 0xfa, 0x71, 0x6e, 0xec, 0xd8, 0x41, 0x8a,
0x17, 0xbf, 0x85, 0x93, 0x5c, 0xee, 0x40, 0xa7, 0xe4, 0x79, 0x9e, 0xdf, 0x2f, 0x90, 0xe0, 0x36,
0xbb, 0xce, 0xa9, 0xd4, 0x2c, 0x2b, 0x52, 0x6e, 0x15, 0x07, 0x9e, 0xb3, 0x67, 0xae, 0x16, 0xda,
0xb2, 0x6e, 0x48, 0x8c, 0x5c, 0x27, 0xf3, 0xa5, 0x54, 0xdc, 0x96, 0xcc, 0x64, 0x82, 0x15, 0x20,
0x57, 0x4c, 0x2a, 0xc8, 0xc1, 0x32, 0xc1, 0x15, 0xb7, 0x09, 0xf0, 0x05, 0x35, 0x56, 0x83, 0x1e,
0x9e, 0xb7, 0x12, 0xfd, 0x2b, 0x51, 0x93, 0x09, 0xda, 0x48, 0xb4, 0x95, 0x4e, 0xaf, 0x84, 0x84,
0x65, 0x91, 0xd2, 0xb9, 0x5e, 0x33, 0xa1, 0x85, 0x66, 0xde, 0x4d, 0x8b, 0x27, 0x9f, 0x7c, 0xf0,
0xb7, 0xf6, 0xcd, 0xb3, 0x57, 0x1c, 0x1c, 0x4d, 0x15, 0xdc, 0xd9, 0x19, 0x58, 0xa9, 0xc4, 0x30,
0x0a, 0xfa, 0x50, 0x1a, 0x3e, 0xc2, 0x21, 0x8e, 0x7a, 0x93, 0x93, 0x6a, 0x3f, 0x46, 0x6e, 0x3f,
0xee, 0xdf, 0x97, 0x86, 0x7f, 0x77, 0x67, 0xec, 0x89, 0xe1, 0x45, 0x30, 0x90, 0x0a, 0x1e, 0x92,
0xd5, 0xe8, 0x5f, 0x88, 0xa3, 0xff, 0x93, 0xe3, 0x8e, 0x1d, 0x4c, 0x7d, 0x1b, 0x77, 0x6b, 0xc3,
0xe5, 0x60, 0x1b, 0xae, 0x17, 0xe2, 0xe8, 0xf0, 0x97, 0x9b, 0xf9, 0x36, 0xee, 0xd6, 0x9b, 0x83,
0xb7, 0xf7, 0x31, 0xda, 0x7c, 0x84, 0x68, 0x72, 0x59, 0xd5, 0x04, 0x6d, 0x6b, 0x82, 0x76, 0x35,
0x41, 0x1b, 0x47, 0x70, 0xe5, 0x08, 0xde, 0x3a, 0x82, 0x77, 0x8e, 0xe0, 0x4f, 0x47, 0xf0, 0xcb,
0x17, 0x41, 0x8f, 0x83, 0xf6, 0xc3, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x52, 0xa0, 0xb5, 0xc9,
0x64, 0x01, 0x00, 0x00,
}

View File

@@ -45,7 +45,7 @@ type IntOrString struct {
}
// Type represents the stored type of IntOrString.
type Type int
type Type int64
const (
Int Type = iota // The IntOrString holds an int.
@@ -122,11 +122,11 @@ func (intstr IntOrString) MarshalJSON() ([]byte, error) {
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ IntOrString) OpenAPISchemaType() []string { return []string{"string"} }
func (IntOrString) OpenAPISchemaType() []string { return []string{"string"} }
// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ IntOrString) OpenAPISchemaFormat() string { return "int-or-string" }
func (IntOrString) OpenAPISchemaFormat() string { return "int-or-string" }
func (intstr *IntOrString) Fuzz(c fuzz.Continue) {
if intstr == nil {

View File

@@ -19,6 +19,7 @@ package json
import (
"bytes"
"encoding/json"
"fmt"
"io"
)
@@ -34,6 +35,9 @@ func Marshal(v interface{}) ([]byte, error) {
return json.Marshal(v)
}
// limit recursive depth to prevent stack overflow errors
const maxDepth = 10000
// Unmarshal unmarshals the given data
// If v is a *map[string]interface{}, numbers are converted to int64 or float64
func Unmarshal(data []byte, v interface{}) error {
@@ -48,7 +52,7 @@ func Unmarshal(data []byte, v interface{}) error {
return err
}
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
return convertMapNumbers(*v)
return convertMapNumbers(*v, 0)
case *[]interface{}:
// Build a decoder from the given data
@@ -60,7 +64,7 @@ func Unmarshal(data []byte, v interface{}) error {
return err
}
// If the decode succeeds, post-process the map to convert json.Number objects to int64 or float64
return convertSliceNumbers(*v)
return convertSliceNumbers(*v, 0)
default:
return json.Unmarshal(data, v)
@@ -69,16 +73,20 @@ func Unmarshal(data []byte, v interface{}) error {
// convertMapNumbers traverses the map, converting any json.Number values to int64 or float64.
// values which are map[string]interface{} or []interface{} are recursively visited
func convertMapNumbers(m map[string]interface{}) error {
func convertMapNumbers(m map[string]interface{}, depth int) error {
if depth > maxDepth {
return fmt.Errorf("exceeded max depth of %d", maxDepth)
}
var err error
for k, v := range m {
switch v := v.(type) {
case json.Number:
m[k], err = convertNumber(v)
case map[string]interface{}:
err = convertMapNumbers(v)
err = convertMapNumbers(v, depth+1)
case []interface{}:
err = convertSliceNumbers(v)
err = convertSliceNumbers(v, depth+1)
}
if err != nil {
return err
@@ -89,16 +97,20 @@ func convertMapNumbers(m map[string]interface{}) error {
// convertSliceNumbers traverses the slice, converting any json.Number values to int64 or float64.
// values which are map[string]interface{} or []interface{} are recursively visited
func convertSliceNumbers(s []interface{}) error {
func convertSliceNumbers(s []interface{}, depth int) error {
if depth > maxDepth {
return fmt.Errorf("exceeded max depth of %d", maxDepth)
}
var err error
for i, v := range s {
switch v := v.(type) {
case json.Number:
s[i], err = convertNumber(v)
case map[string]interface{}:
err = convertMapNumbers(v)
err = convertMapNumbers(v, depth+1)
case []interface{}:
err = convertSliceNumbers(v)
err = convertSliceNumbers(v, depth+1)
}
if err != nil {
return err

View File

@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- pwittrock
reviewers:

View File

@@ -68,14 +68,17 @@ func IsProbableEOF(err error) bool {
if uerr, ok := err.(*url.Error); ok {
err = uerr.Err
}
msg := err.Error()
switch {
case err == io.EOF:
return true
case err.Error() == "http: can't write HTTP request on broken connection":
case msg == "http: can't write HTTP request on broken connection":
return true
case strings.Contains(err.Error(), "connection reset by peer"):
case strings.Contains(msg, "http2: server sent GOAWAY and closed the connection"):
return true
case strings.Contains(strings.ToLower(err.Error()), "use of closed network connection"):
case strings.Contains(msg, "connection reset by peer"):
return true
case strings.Contains(strings.ToLower(msg), "use of closed network connection"):
return true
}
return false
@@ -98,6 +101,9 @@ func SetOldTransportDefaults(t *http.Transport) *http.Transport {
if t.TLSHandshakeTimeout == 0 {
t.TLSHandshakeTimeout = defaultTransport.TLSHandshakeTimeout
}
if t.IdleConnTimeout == 0 {
t.IdleConnTimeout = defaultTransport.IdleConnTimeout
}
return t
}
@@ -108,7 +114,7 @@ func SetTransportDefaults(t *http.Transport) *http.Transport {
// Allow clients to disable http2 if needed.
if s := os.Getenv("DISABLE_HTTP2"); len(s) > 0 {
klog.Infof("HTTP2 has been explicitly disabled")
} else {
} else if allowsHTTP2(t) {
if err := http2.ConfigureTransport(t); err != nil {
klog.Warningf("Transport failed http2 configuration: %v", err)
}
@@ -116,6 +122,21 @@ func SetTransportDefaults(t *http.Transport) *http.Transport {
return t
}
func allowsHTTP2(t *http.Transport) bool {
if t.TLSClientConfig == nil || len(t.TLSClientConfig.NextProtos) == 0 {
// the transport expressed no NextProto preference, allow
return true
}
for _, p := range t.TLSClientConfig.NextProtos {
if p == http2.NextProtoTLS {
// the transport explicitly allowed http/2
return true
}
}
// the transport explicitly set NextProtos and excluded http/2
return false
}
type RoundTripperWrapper interface {
http.RoundTripper
WrappedRoundTripper() http.RoundTripper

View File

@@ -54,3 +54,20 @@ func IsConnectionReset(err error) bool {
}
return false
}
// Returns if the given err is "connection refused" error
func IsConnectionRefused(err error) bool {
if urlErr, ok := err.(*url.Error); ok {
err = urlErr.Err
}
if opErr, ok := err.(*net.OpError); ok {
err = opErr.Err
}
if osErr, ok := err.(*os.SyscallError); ok {
err = osErr.Err
}
if errno, ok := err.(syscall.Errno); ok && errno == syscall.ECONNREFUSED {
return true
}
return false
}

View File

@@ -18,6 +18,7 @@ package runtime
import (
"fmt"
"net/http"
"runtime"
"sync"
"time"
@@ -40,11 +41,7 @@ var PanicHandlers = []func(interface{}){logPanic}
// called in case of panic. HandleCrash actually crashes, after calling the
// handlers and logging the panic message.
//
// TODO: remove this function. We are switching to a world where it's safe for
// apiserver to panic, since it will be restarted by kubelet. At the beginning
// of the Kubernetes project, nothing was going to restart apiserver and so
// catching panics was important. But it's actually much simpler for monitoring
// software if we just exit when an unexpected panic happens.
// E.g., you can provide one or more additional handlers for something like shutting down go routines gracefully.
func HandleCrash(additionalHandlers ...func(interface{})) {
if r := recover(); r != nil {
for _, fn := range PanicHandlers {
@@ -60,29 +57,28 @@ func HandleCrash(additionalHandlers ...func(interface{})) {
}
}
// logPanic logs the caller tree when a panic occurs.
// logPanic logs the caller tree when a panic occurs (except in the special case of http.ErrAbortHandler).
func logPanic(r interface{}) {
callers := getCallers(r)
if r == http.ErrAbortHandler {
// honor the http.ErrAbortHandler sentinel panic value:
// ErrAbortHandler is a sentinel panic value to abort a handler.
// While any panic from ServeHTTP aborts the response to the client,
// panicking with ErrAbortHandler also suppresses logging of a stack trace to the server's error log.
return
}
// Same as stdlib http server code. Manually allocate stack trace buffer size
// to prevent excessively large logs
const size = 64 << 10
stacktrace := make([]byte, size)
stacktrace = stacktrace[:runtime.Stack(stacktrace, false)]
if _, ok := r.(string); ok {
klog.Errorf("Observed a panic: %s\n%v", r, callers)
klog.Errorf("Observed a panic: %s\n%s", r, stacktrace)
} else {
klog.Errorf("Observed a panic: %#v (%v)\n%v", r, r, callers)
klog.Errorf("Observed a panic: %#v (%v)\n%s", r, r, stacktrace)
}
}
func getCallers(r interface{}) string {
callers := ""
for i := 0; true; i++ {
_, file, line, ok := runtime.Caller(i)
if !ok {
break
}
callers = callers + fmt.Sprintf("%v:%v\n", file, line)
}
return callers
}
// ErrorHandlers is a list of functions which will be invoked when an unreturnable
// error occurs.
// TODO(lavalamp): for testability, this and the below HandleError function
@@ -155,13 +151,17 @@ func GetCaller() string {
// handlers to handle errors and panics the same way.
func RecoverFromPanic(err *error) {
if r := recover(); r != nil {
callers := getCallers(r)
// Same as stdlib http server code. Manually allocate stack trace buffer size
// to prevent excessively large logs
const size = 64 << 10
stacktrace := make([]byte, size)
stacktrace = stacktrace[:runtime.Stack(stacktrace, false)]
*err = fmt.Errorf(
"recovered from panic %q. (err=%v) Call stack:\n%v",
"recovered from panic %q. (err=%v) Call stack:\n%s",
r,
*err,
callers)
stacktrace)
}
}

View File

@@ -46,17 +46,19 @@ func ByteKeySet(theMap interface{}) Byte {
}
// Insert adds items to the set.
func (s Byte) Insert(items ...byte) {
func (s Byte) Insert(items ...byte) Byte {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s Byte) Delete(items ...byte) {
func (s Byte) Delete(items ...byte) Byte {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.

View File

@@ -46,17 +46,19 @@ func IntKeySet(theMap interface{}) Int {
}
// Insert adds items to the set.
func (s Int) Insert(items ...int) {
func (s Int) Insert(items ...int) Int {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s Int) Delete(items ...int) {
func (s Int) Delete(items ...int) Int {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.

205
vendor/k8s.io/apimachinery/pkg/util/sets/int32.go generated vendored Normal file
View File

@@ -0,0 +1,205 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by set-gen. DO NOT EDIT.
package sets
import (
"reflect"
"sort"
)
// sets.Int32 is a set of int32s, implemented via map[int32]struct{} for minimal memory consumption.
type Int32 map[int32]Empty
// NewInt32 creates a Int32 from a list of values.
func NewInt32(items ...int32) Int32 {
ss := Int32{}
ss.Insert(items...)
return ss
}
// Int32KeySet creates a Int32 from a keys of a map[int32](? extends interface{}).
// If the value passed in is not actually a map, this will panic.
func Int32KeySet(theMap interface{}) Int32 {
v := reflect.ValueOf(theMap)
ret := Int32{}
for _, keyValue := range v.MapKeys() {
ret.Insert(keyValue.Interface().(int32))
}
return ret
}
// Insert adds items to the set.
func (s Int32) Insert(items ...int32) Int32 {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s Int32) Delete(items ...int32) Int32 {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.
func (s Int32) Has(item int32) bool {
_, contained := s[item]
return contained
}
// HasAll returns true if and only if all items are contained in the set.
func (s Int32) HasAll(items ...int32) bool {
for _, item := range items {
if !s.Has(item) {
return false
}
}
return true
}
// HasAny returns true if any items are contained in the set.
func (s Int32) HasAny(items ...int32) bool {
for _, item := range items {
if s.Has(item) {
return true
}
}
return false
}
// Difference returns a set of objects that are not in s2
// For example:
// s1 = {a1, a2, a3}
// s2 = {a1, a2, a4, a5}
// s1.Difference(s2) = {a3}
// s2.Difference(s1) = {a4, a5}
func (s Int32) Difference(s2 Int32) Int32 {
result := NewInt32()
for key := range s {
if !s2.Has(key) {
result.Insert(key)
}
}
return result
}
// Union returns a new set which includes items in either s1 or s2.
// For example:
// s1 = {a1, a2}
// s2 = {a3, a4}
// s1.Union(s2) = {a1, a2, a3, a4}
// s2.Union(s1) = {a1, a2, a3, a4}
func (s1 Int32) Union(s2 Int32) Int32 {
result := NewInt32()
for key := range s1 {
result.Insert(key)
}
for key := range s2 {
result.Insert(key)
}
return result
}
// Intersection returns a new set which includes the item in BOTH s1 and s2
// For example:
// s1 = {a1, a2}
// s2 = {a2, a3}
// s1.Intersection(s2) = {a2}
func (s1 Int32) Intersection(s2 Int32) Int32 {
var walk, other Int32
result := NewInt32()
if s1.Len() < s2.Len() {
walk = s1
other = s2
} else {
walk = s2
other = s1
}
for key := range walk {
if other.Has(key) {
result.Insert(key)
}
}
return result
}
// IsSuperset returns true if and only if s1 is a superset of s2.
func (s1 Int32) IsSuperset(s2 Int32) bool {
for item := range s2 {
if !s1.Has(item) {
return false
}
}
return true
}
// Equal returns true if and only if s1 is equal (as a set) to s2.
// Two sets are equal if their membership is identical.
// (In practice, this means same elements, order doesn't matter)
func (s1 Int32) Equal(s2 Int32) bool {
return len(s1) == len(s2) && s1.IsSuperset(s2)
}
type sortableSliceOfInt32 []int32
func (s sortableSliceOfInt32) Len() int { return len(s) }
func (s sortableSliceOfInt32) Less(i, j int) bool { return lessInt32(s[i], s[j]) }
func (s sortableSliceOfInt32) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// List returns the contents as a sorted int32 slice.
func (s Int32) List() []int32 {
res := make(sortableSliceOfInt32, 0, len(s))
for key := range s {
res = append(res, key)
}
sort.Sort(res)
return []int32(res)
}
// UnsortedList returns the slice with contents in random order.
func (s Int32) UnsortedList() []int32 {
res := make([]int32, 0, len(s))
for key := range s {
res = append(res, key)
}
return res
}
// Returns a single element from the set.
func (s Int32) PopAny() (int32, bool) {
for key := range s {
s.Delete(key)
return key, true
}
var zeroValue int32
return zeroValue, false
}
// Len returns the size of the set.
func (s Int32) Len() int {
return len(s)
}
func lessInt32(lhs, rhs int32) bool {
return lhs < rhs
}

View File

@@ -46,17 +46,19 @@ func Int64KeySet(theMap interface{}) Int64 {
}
// Insert adds items to the set.
func (s Int64) Insert(items ...int64) {
func (s Int64) Insert(items ...int64) Int64 {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s Int64) Delete(items ...int64) {
func (s Int64) Delete(items ...int64) Int64 {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.

View File

@@ -46,17 +46,19 @@ func StringKeySet(theMap interface{}) String {
}
// Insert adds items to the set.
func (s String) Insert(items ...string) {
func (s String) Insert(items ...string) String {
for _, item := range items {
s[item] = Empty{}
}
return s
}
// Delete removes all items from the set.
func (s String) Delete(items ...string) {
func (s String) Delete(items ...string) String {
for _, item := range items {
delete(s, item)
}
return s
}
// Has returns true if and only if item is contained in the set.

View File

@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- pwittrock
- mengqiy

View File

@@ -17,27 +17,11 @@ limitations under the License.
package uuid
import (
"sync"
"github.com/pborman/uuid"
"github.com/google/uuid"
"k8s.io/apimachinery/pkg/types"
)
var uuidLock sync.Mutex
var lastUUID uuid.UUID
func NewUUID() types.UID {
uuidLock.Lock()
defer uuidLock.Unlock()
result := uuid.NewUUID()
// The UUID package is naive and can generate identical UUIDs if the
// time interval is quick enough.
// The UUID uses 100 ns increments so it's short enough to actively
// wait for a new value.
for uuid.Equal(lastUUID, result) == true {
result = uuid.NewUUID()
}
lastUUID = result
return types.UID(result.String())
return types.UID(uuid.New().String())
}

View File

@@ -116,6 +116,10 @@ const (
// This is similar to ErrorTypeInvalid, but the error will not include the
// too-long value. See TooLong().
ErrorTypeTooLong ErrorType = "FieldValueTooLong"
// ErrorTypeTooMany is used to report "too many". This is used to
// report that a given list has too many items. This is similar to FieldValueTooLong,
// but the error indicates quantity instead of length.
ErrorTypeTooMany ErrorType = "FieldValueTooMany"
// ErrorTypeInternal is used to report other errors that are not related
// to user input. See InternalError().
ErrorTypeInternal ErrorType = "InternalError"
@@ -138,6 +142,8 @@ func (t ErrorType) String() string {
return "Forbidden"
case ErrorTypeTooLong:
return "Too long"
case ErrorTypeTooMany:
return "Too many"
case ErrorTypeInternal:
return "Internal error"
default:
@@ -201,6 +207,13 @@ func TooLong(field *Path, value interface{}, maxLength int) *Error {
return &Error{ErrorTypeTooLong, field.String(), value, fmt.Sprintf("must have at most %d characters", maxLength)}
}
// TooMany returns a *Error indicating "too many". This is used to
// report that a given list has too many items. This is similar to TooLong,
// but the returned error indicates quantity instead of length.
func TooMany(field *Path, actualQuantity, maxQuantity int) *Error {
return &Error{ErrorTypeTooMany, field.String(), actualQuantity, fmt.Sprintf("must have at most %d items", maxQuantity)}
}
// InternalError returns a *Error indicating "internal error". This is used
// to signal that an error was found that was not directly related to user
// input. The err argument must be non-nil.

View File

@@ -87,6 +87,8 @@ func IsFullyQualifiedName(fldPath *field.Path, name string) field.ErrorList {
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"
// LabelValueMaxLength is a label's max length
const LabelValueMaxLength int = 63
var labelValueRegexp = regexp.MustCompile("^" + labelValueFmt + "$")
@@ -107,6 +109,8 @@ func IsValidLabelValue(value string) []string {
const dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
const dns1123LabelErrMsg string = "a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character"
// DNS1123LabelMaxLength is a label's max length in DNS (RFC 1123)
const DNS1123LabelMaxLength int = 63
var dns1123LabelRegexp = regexp.MustCompile("^" + dns1123LabelFmt + "$")
@@ -126,6 +130,8 @@ func IsDNS1123Label(value string) []string {
const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"
const dns1123SubdomainErrorMsg string = "a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
// DNS1123SubdomainMaxLength is a subdomain's max length in DNS (RFC 1123)
const DNS1123SubdomainMaxLength int = 253
var dns1123SubdomainRegexp = regexp.MustCompile("^" + dns1123SubdomainFmt + "$")
@@ -145,6 +151,8 @@ 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 '-', start with an alphabetic character, and end with an alphanumeric character"
// DNS1035LabelMaxLength is a label's max length in DNS (RFC 1035)
const DNS1035LabelMaxLength int = 63
var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$")
@@ -282,6 +290,7 @@ const percentErrMsg string = "a valid percent string must be a numeric string fo
var percentRegexp = regexp.MustCompile("^" + percentFmt + "$")
// IsValidPercent checks that string is in the form of a percentage
func IsValidPercent(percent string) []string {
if !percentRegexp.MatchString(percent) {
return []string{RegexError(percentErrMsg, percentFmt, "1%", "93%")}
@@ -391,13 +400,13 @@ func hasChDirPrefix(value string) []string {
return errs
}
// IsSocketAddr checks that a string conforms is a valid socket address
// IsValidSocketAddr checks that string represents a valid socket address
// as defined in RFC 789. (e.g 0.0.0.0:10254 or [::]:10254))
func IsValidSocketAddr(value string) []string {
var errs []string
ip, port, err := net.SplitHostPort(value)
if err != nil {
return append(errs, "must be a valid socket address format, (e.g. 0.0.0.0:10254 or [::]:10254)")
errs = append(errs, "must be a valid socket address format, (e.g. 0.0.0.0:10254 or [::]:10254)")
return errs
}
portInt, _ := strconv.Atoi(port)

View File

@@ -88,6 +88,15 @@ func Until(f func(), period time.Duration, stopCh <-chan struct{}) {
JitterUntil(f, period, 0.0, true, stopCh)
}
// UntilWithContext loops until context is done, running f every period.
//
// UntilWithContext is syntactic sugar on top of JitterUntilWithContext
// with zero jitter factor and with sliding = true (which means the timer
// for period starts after the f completes).
func UntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) {
JitterUntilWithContext(ctx, f, period, 0.0, true)
}
// NonSlidingUntil loops until stop channel is closed, running f every
// period.
//
@@ -98,6 +107,16 @@ func NonSlidingUntil(f func(), period time.Duration, stopCh <-chan struct{}) {
JitterUntil(f, period, 0.0, false, stopCh)
}
// NonSlidingUntilWithContext loops until context is done, running f every
// period.
//
// NonSlidingUntilWithContext is syntactic sugar on top of JitterUntilWithContext
// with zero jitter factor, with sliding = false (meaning the timer for period
// starts at the same time as the function starts).
func NonSlidingUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration) {
JitterUntilWithContext(ctx, f, period, 0.0, false)
}
// JitterUntil loops until stop channel is closed, running f every period.
//
// If jitterFactor is positive, the period is jittered before every run of f.
@@ -151,6 +170,19 @@ func JitterUntil(f func(), period time.Duration, jitterFactor float64, sliding b
}
}
// JitterUntilWithContext loops until context is done, running f every period.
//
// If jitterFactor is positive, the period is jittered before every run of f.
// If jitterFactor is not positive, the period is unchanged and not jittered.
//
// If sliding is true, the period is computed after f runs. If it is false then
// period includes the runtime for f.
//
// Cancel context to stop. f may not be invoked if context is already expired.
func JitterUntilWithContext(ctx context.Context, f func(context.Context), period time.Duration, jitterFactor float64, sliding bool) {
JitterUntil(func() { f(ctx) }, period, jitterFactor, sliding, ctx.Done())
}
// Jitter returns a time.Duration between duration and duration + maxFactor *
// duration.
//
@@ -173,36 +205,97 @@ type ConditionFunc func() (done bool, err error)
// Backoff holds parameters applied to a Backoff function.
type Backoff struct {
Duration time.Duration // the base duration
Factor float64 // Duration is multiplied by factor each iteration
Jitter float64 // The amount of jitter applied each iteration
Steps int // Exit with error after this many steps
// The initial duration.
Duration time.Duration
// Duration is multiplied by factor each iteration, if factor is not zero
// and the limits imposed by Steps and Cap have not been reached.
// Should not be negative.
// The jitter does not contribute to the updates to the duration parameter.
Factor float64
// The sleep at each iteration is the duration plus an additional
// amount chosen uniformly at random from the interval between
// zero and `jitter*duration`.
Jitter float64
// The remaining number of iterations in which the duration
// parameter may change (but progress can be stopped earlier by
// hitting the cap). If not positive, the duration is not
// changed. Used for exponential backoff in combination with
// Factor and Cap.
Steps int
// A limit on revised values of the duration parameter. If a
// multiplication by the factor parameter would make the duration
// exceed the cap then the duration is set to the cap and the
// steps parameter is set to zero.
Cap time.Duration
}
// Step (1) returns an amount of time to sleep determined by the
// original Duration and Jitter and (2) mutates the provided Backoff
// to update its Steps and Duration.
func (b *Backoff) Step() time.Duration {
if b.Steps < 1 {
if b.Jitter > 0 {
return Jitter(b.Duration, b.Jitter)
}
return b.Duration
}
b.Steps--
duration := b.Duration
// calculate the next step
if b.Factor != 0 {
b.Duration = time.Duration(float64(b.Duration) * b.Factor)
if b.Cap > 0 && b.Duration > b.Cap {
b.Duration = b.Cap
b.Steps = 0
}
}
if b.Jitter > 0 {
duration = Jitter(duration, b.Jitter)
}
return duration
}
// contextForChannel derives a child context from a parent channel.
//
// The derived context's Done channel is closed when the returned cancel function
// is called or when the parent channel is closed, whichever happens first.
//
// Note the caller must *always* call the CancelFunc, otherwise resources may be leaked.
func contextForChannel(parentCh <-chan struct{}) (context.Context, context.CancelFunc) {
ctx, cancel := context.WithCancel(context.Background())
go func() {
select {
case <-parentCh:
cancel()
case <-ctx.Done():
}
}()
return ctx, cancel
}
// ExponentialBackoff repeats a condition check with exponential backoff.
//
// It checks the condition up to Steps times, increasing the wait by multiplying
// the previous duration by Factor.
//
// If Jitter is greater than zero, a random amount of each duration is added
// (between duration and duration*(1+jitter)).
//
// If the condition never returns true, ErrWaitTimeout is returned. All other
// errors terminate immediately.
// It repeatedly checks the condition and then sleeps, using `backoff.Step()`
// to determine the length of the sleep and adjust Duration and Steps.
// Stops and returns as soon as:
// 1. the condition check returns true or an error,
// 2. `backoff.Steps` checks of the condition have been done, or
// 3. a sleep truncated by the cap on duration has been completed.
// In case (1) the returned error is what the condition function returned.
// In all other cases, ErrWaitTimeout is returned.
func ExponentialBackoff(backoff Backoff, condition ConditionFunc) error {
duration := backoff.Duration
for i := 0; i < backoff.Steps; i++ {
if i != 0 {
adjusted := duration
if backoff.Jitter > 0.0 {
adjusted = Jitter(duration, backoff.Jitter)
}
time.Sleep(adjusted)
duration = time.Duration(float64(duration) * backoff.Factor)
}
for backoff.Steps > 0 {
if ok, err := condition(); err != nil || ok {
return err
}
if backoff.Steps == 1 {
break
}
time.Sleep(backoff.Step())
}
return ErrWaitTimeout
}
@@ -287,7 +380,9 @@ func PollImmediateInfinite(interval time.Duration, condition ConditionFunc) erro
// PollUntil always waits interval before the first run of 'condition'.
// 'condition' will always be invoked at least once.
func PollUntil(interval time.Duration, condition ConditionFunc, stopCh <-chan struct{}) error {
return WaitFor(poller(interval, 0), condition, stopCh)
ctx, cancel := contextForChannel(stopCh)
defer cancel()
return WaitFor(poller(interval, 0), condition, ctx.Done())
}
// PollImmediateUntil tries a condition func until it returns true, an error or stopCh is closed.
@@ -317,36 +412,48 @@ type WaitFunc func(done <-chan struct{}) <-chan struct{}
// WaitFor continually checks 'fn' as driven by 'wait'.
//
// WaitFor gets a channel from 'wait()'', and then invokes 'fn' once for every value
// placed on the channel and once more when the channel is closed.
// placed on the channel and once more when the channel is closed. If the channel is closed
// and 'fn' returns false without error, WaitFor returns ErrWaitTimeout.
//
// If 'fn' returns an error the loop ends and that error is returned, and if
// If 'fn' returns an error the loop ends and that error is returned. If
// 'fn' returns true the loop ends and nil is returned.
//
// ErrWaitTimeout will be returned if the channel is closed without fn ever
// ErrWaitTimeout will be returned if the 'done' channel is closed without fn ever
// returning true.
//
// When the done channel is closed, because the golang `select` statement is
// "uniform pseudo-random", the `fn` might still run one or multiple time,
// though eventually `WaitFor` will return.
func WaitFor(wait WaitFunc, fn ConditionFunc, done <-chan struct{}) error {
c := wait(done)
stopCh := make(chan struct{})
defer close(stopCh)
c := wait(stopCh)
for {
_, open := <-c
ok, err := fn()
if err != nil {
return err
}
if ok {
return nil
}
if !open {
break
select {
case _, open := <-c:
ok, err := fn()
if err != nil {
return err
}
if ok {
return nil
}
if !open {
return ErrWaitTimeout
}
case <-done:
return ErrWaitTimeout
}
}
return ErrWaitTimeout
}
// poller returns a WaitFunc that will send to the channel every interval until
// timeout has elapsed and then closes the channel.
//
// Over very short intervals you may receive no ticks before the channel is
// closed. A timeout of 0 is interpreted as an infinity.
// closed. A timeout of 0 is interpreted as an infinity, and in such a case
// it would be the caller's responsibility to close the done channel.
// Failure to do so would result in a leaked goroutine.
//
// Output ticks are not buffered. If the channel is not ready to receive an
// item, the tick is skipped.

View File

@@ -217,11 +217,9 @@ func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
if d.decoder == nil {
buffer, origData, isJSON := GuessJSONStream(d.r, d.bufferSize)
if isJSON {
klog.V(4).Infof("decoding stream as JSON")
d.decoder = json.NewDecoder(buffer)
d.rawData = origData
} else {
klog.V(4).Infof("decoding stream as YAML")
d.decoder = NewYAMLToJSONDecoder(buffer)
}
}

View File

@@ -17,13 +17,15 @@ limitations under the License.
package watch
import (
"fmt"
"io"
"sync"
"k8s.io/klog"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/net"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/klog"
)
// Decoder allows StreamWatcher to watch any stream for which a Decoder can be written.
@@ -39,19 +41,28 @@ type Decoder interface {
Close()
}
// Reporter hides the details of how an error is turned into a runtime.Object for
// reporting on a watch stream since this package may not import a higher level report.
type Reporter interface {
// AsObject must convert err into a valid runtime.Object for the watch stream.
AsObject(err error) runtime.Object
}
// StreamWatcher turns any stream for which you can write a Decoder interface
// into a watch.Interface.
type StreamWatcher struct {
sync.Mutex
source Decoder
result chan Event
stopped bool
source Decoder
reporter Reporter
result chan Event
stopped bool
}
// NewStreamWatcher creates a StreamWatcher from the given decoder.
func NewStreamWatcher(d Decoder) *StreamWatcher {
func NewStreamWatcher(d Decoder, r Reporter) *StreamWatcher {
sw := &StreamWatcher{
source: d,
source: d,
reporter: r,
// It's easy for a consumer to add buffering via an extra
// goroutine/channel, but impossible for them to remove it,
// so nonbuffered is better.
@@ -102,11 +113,13 @@ func (sw *StreamWatcher) receive() {
case io.ErrUnexpectedEOF:
klog.V(1).Infof("Unexpected EOF during watch stream event decoding: %v", err)
default:
msg := "Unable to decode an event from the watch stream: %v"
if net.IsProbableEOF(err) {
klog.V(5).Infof(msg, err)
klog.V(5).Infof("Unable to decode an event from the watch stream: %v", err)
} else {
klog.Errorf(msg, err)
sw.result <- Event{
Type: Error,
Object: sw.reporter.AsObject(fmt.Errorf("unable to decode an event from the watch stream: %v", err)),
}
}
}
return

View File

@@ -44,6 +44,7 @@ const (
Added EventType = "ADDED"
Modified EventType = "MODIFIED"
Deleted EventType = "DELETED"
Bookmark EventType = "BOOKMARK"
Error EventType = "ERROR"
DefaultChanSize int32 = 100
@@ -57,6 +58,10 @@ type Event struct {
// Object is:
// * If Type is Added or Modified: the new state of the object.
// * If Type is Deleted: the state of the object immediately before deletion.
// * If Type is Bookmark: the object (instance of a type being watched) where
// only ResourceVersion field is set. On successful restart of watch from a
// bookmark resourceVersion, client is guaranteed to not get repeat event
// nor miss any events.
// * If Type is Error: *api.Status is recommended; other types may make sense
// depending on context.
Object runtime.Object

View File

@@ -1,3 +1,5 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- pwittrock
reviewers: