working commit
This commit is contained in:
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright 2023 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"
|
||||
|
||||
// SetListOptionsDefaults sets defaults on the provided ListOptions if applicable.
|
||||
//
|
||||
// TODO(#115478): once the watch-list fg is always on we register this function in the scheme (via AddTypeDefaultingFunc).
|
||||
// TODO(#115478): when the function is registered in the scheme remove all callers of this method.
|
||||
func SetListOptionsDefaults(obj *ListOptions, isWatchListFeatureEnabled bool) {
|
||||
if !isWatchListFeatureEnabled {
|
||||
return
|
||||
}
|
||||
if obj.SendInitialEvents != nil || len(obj.ResourceVersionMatch) != 0 {
|
||||
return
|
||||
}
|
||||
legacy := obj.ResourceVersion == "" || obj.ResourceVersion == "0"
|
||||
if obj.Watch && legacy {
|
||||
turnOnInitialEvents := true
|
||||
obj.SendInitialEvents = &turnOnInitialEvents
|
||||
obj.ResourceVersionMatch = metav1.ResourceVersionMatchNotOlderThan
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:conversion-gen=k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
|
||||
package internalversion
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name for this API.
|
||||
const GroupName = "meta.k8s.io"
|
||||
|
||||
var (
|
||||
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
|
||||
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
|
||||
SchemeBuilder runtime.SchemeBuilder
|
||||
localSchemeBuilder = &SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// addToGroupVersion registers common meta types into schemas.
|
||||
func addToGroupVersion(scheme *runtime.Scheme) error {
|
||||
if err := scheme.AddIgnoredConversionType(&metav1.TypeMeta{}, &metav1.TypeMeta{}); err != nil {
|
||||
return err
|
||||
}
|
||||
// ListOptions is the only options struct which needs conversion (it exposes labels and fields
|
||||
// as selectors for convenience). The other types have only a single representation today.
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&ListOptions{},
|
||||
&metav1.GetOptions{},
|
||||
&metav1.DeleteOptions{},
|
||||
&metav1.CreateOptions{},
|
||||
&metav1.UpdateOptions{},
|
||||
)
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&metav1.Table{},
|
||||
&metav1.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{},
|
||||
&metav1.CreateOptions{},
|
||||
&metav1.UpdateOptions{})
|
||||
|
||||
metav1.AddToGroupVersion(scheme, metav1.SchemeGroupVersion)
|
||||
if err := metav1beta1.RegisterConversions(scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unlike other API groups, meta internal knows about all meta external versions, but keeps
|
||||
// the logic for conversion private.
|
||||
func init() {
|
||||
localSchemeBuilder.Register(addToGroupVersion)
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scheme
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
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 scheme
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
)
|
||||
|
||||
// Scheme is the registry for any type that adheres to the meta API spec.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
// Codecs provides access to encoding and decoding for the scheme.
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
|
||||
// ParameterCodec handles versioning of objects that are converted to query parameters.
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
|
||||
// Unlike other API groups, meta internal knows about all meta external versions, but keeps
|
||||
// the logic for conversion private.
|
||||
func init() {
|
||||
utilruntime.Must(internalversion.AddToScheme(Scheme))
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package internalversion
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ListOptions is the query options to a standard REST list call.
|
||||
type ListOptions struct {
|
||||
metav1.TypeMeta
|
||||
|
||||
// A selector based on labels
|
||||
LabelSelector labels.Selector
|
||||
// A selector based on fields
|
||||
FieldSelector fields.Selector
|
||||
// If true, 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.
|
||||
AllowWatchBookmarks bool
|
||||
// resourceVersion sets a constraint on what resource versions a request may be served from.
|
||||
// See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for
|
||||
// details.
|
||||
ResourceVersion string
|
||||
// resourceVersionMatch determines how resourceVersion is applied to list calls.
|
||||
// It is highly recommended that resourceVersionMatch be set for list calls where
|
||||
// resourceVersion is set.
|
||||
// See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for
|
||||
// details.
|
||||
ResourceVersionMatch metav1.ResourceVersionMatch
|
||||
|
||||
// Timeout for the list/watch call.
|
||||
TimeoutSeconds *int64
|
||||
// Limit specifies the maximum number of results to return from the server. The server may
|
||||
// not support this field on all resource types, but if it does and more results remain it
|
||||
// will set the continue field on the returned list object.
|
||||
Limit int64
|
||||
// Continue is a token returned by the server that lets a client retrieve chunks of results
|
||||
// from the server by specifying limit. The server may reject requests for continuation tokens
|
||||
// it does not recognize and will return a 410 error if the token can no longer be used because
|
||||
// it has expired.
|
||||
Continue string
|
||||
|
||||
// `sendInitialEvents=true` may be set together with `watch=true`.
|
||||
// In that case, the watch stream will begin with synthetic events to
|
||||
// produce the current state of objects in the collection. Once all such
|
||||
// events have been sent, a synthetic "Bookmark" event will be sent.
|
||||
// The bookmark will report the ResourceVersion (RV) corresponding to the
|
||||
// set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation.
|
||||
// Afterwards, the watch stream will proceed as usual, sending watch events
|
||||
// corresponding to changes (subsequent to the RV) to objects watched.
|
||||
//
|
||||
// When `sendInitialEvents` option is set, we require `resourceVersionMatch`
|
||||
// option to also be set. The semantic of the watch request is as following:
|
||||
// - `resourceVersionMatch` = NotOlderThan
|
||||
// is interpreted as "data at least as new as the provided `resourceVersion`"
|
||||
// and the bookmark event is send when the state is synced
|
||||
// to a `resourceVersion` at least as fresh as the one provided by the ListOptions.
|
||||
// If `resourceVersion` is unset, this is interpreted as "consistent read" and the
|
||||
// bookmark event is send when the state is synced at least to the moment
|
||||
// when request started being processed.
|
||||
// - `resourceVersionMatch` set to any other value or unset
|
||||
// Invalid error is returned.
|
||||
//
|
||||
// Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward
|
||||
// compatibility reasons) and to false otherwise.
|
||||
SendInitialEvents *bool
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// List holds a list of objects, which may not be known by the server.
|
||||
type List struct {
|
||||
metav1.TypeMeta
|
||||
// +optional
|
||||
metav1.ListMeta
|
||||
|
||||
Items []runtime.Object
|
||||
}
|
||||
Generated
Vendored
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// ValidateListOptions returns all validation errors found while validating the ListOptions.
|
||||
func ValidateListOptions(options *internalversion.ListOptions, isWatchListFeatureEnabled bool) field.ErrorList {
|
||||
if options.Watch {
|
||||
return validateWatchOptions(options, isWatchListFeatureEnabled)
|
||||
}
|
||||
allErrs := field.ErrorList{}
|
||||
if match := options.ResourceVersionMatch; len(match) > 0 {
|
||||
if len(options.ResourceVersion) == 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden unless resourceVersion is provided"))
|
||||
}
|
||||
if len(options.Continue) > 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden when continue is provided"))
|
||||
}
|
||||
if match != metav1.ResourceVersionMatchExact && match != metav1.ResourceVersionMatchNotOlderThan {
|
||||
allErrs = append(allErrs, field.NotSupported(field.NewPath("resourceVersionMatch"), match, []string{string(metav1.ResourceVersionMatchExact), string(metav1.ResourceVersionMatchNotOlderThan), ""}))
|
||||
}
|
||||
if match == metav1.ResourceVersionMatchExact && options.ResourceVersion == "0" {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch \"exact\" is forbidden for resourceVersion \"0\""))
|
||||
}
|
||||
}
|
||||
if options.SendInitialEvents != nil {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("sendInitialEvents"), "sendInitialEvents is forbidden for list"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateWatchOptions(options *internalversion.ListOptions, isWatchListFeatureEnabled bool) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
match := options.ResourceVersionMatch
|
||||
if options.SendInitialEvents != nil {
|
||||
if match != metav1.ResourceVersionMatchNotOlderThan {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), fmt.Sprintf("sendInitialEvents requires setting resourceVersionMatch to %s", metav1.ResourceVersionMatchNotOlderThan)))
|
||||
}
|
||||
if !isWatchListFeatureEnabled {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("sendInitialEvents"), "sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"))
|
||||
}
|
||||
}
|
||||
if len(match) > 0 {
|
||||
if options.SendInitialEvents == nil {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden for watch unless sendInitialEvents is provided"))
|
||||
}
|
||||
if match != metav1.ResourceVersionMatchNotOlderThan {
|
||||
allErrs = append(allErrs, field.NotSupported(field.NewPath("resourceVersionMatch"), match, []string{string(metav1.ResourceVersionMatchNotOlderThan)}))
|
||||
}
|
||||
if len(options.Continue) > 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(field.NewPath("resourceVersionMatch"), "resourceVersionMatch is forbidden when continue is provided"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
Generated
Vendored
+148
@@ -0,0 +1,148 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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 conversion-gen. DO NOT EDIT.
|
||||
|
||||
package internalversion
|
||||
|
||||
import (
|
||||
unsafe "unsafe"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*List)(nil), (*v1.List)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_internalversion_List_To_v1_List(a.(*List), b.(*v1.List), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.List)(nil), (*List)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_List_To_internalversion_List(a.(*v1.List), b.(*List), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*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.AddGeneratedConversionFunc((*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
|
||||
}
|
||||
|
||||
func autoConvert_internalversion_List_To_v1_List(in *List, out *v1.List, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]runtime.RawExtension, len(*in))
|
||||
for i := range *in {
|
||||
if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&(*in)[i], &(*out)[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_internalversion_List_To_v1_List is an autogenerated conversion function.
|
||||
func Convert_internalversion_List_To_v1_List(in *List, out *v1.List, s conversion.Scope) error {
|
||||
return autoConvert_internalversion_List_To_v1_List(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_List_To_internalversion_List(in *v1.List, out *List, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]runtime.Object, len(*in))
|
||||
for i := range *in {
|
||||
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&(*in)[i], &(*out)[i], s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Items = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_List_To_internalversion_List is an autogenerated conversion function.
|
||||
func Convert_v1_List_To_internalversion_List(in *v1.List, out *List, s conversion.Scope) error {
|
||||
return autoConvert_v1_List_To_internalversion_List(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out *v1.ListOptions, s conversion.Scope) error {
|
||||
if err := v1.Convert_labels_Selector_To_string(&in.LabelSelector, &out.LabelSelector, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := v1.Convert_fields_Selector_To_string(&in.FieldSelector, &out.FieldSelector, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Watch = in.Watch
|
||||
out.AllowWatchBookmarks = in.AllowWatchBookmarks
|
||||
out.ResourceVersion = in.ResourceVersion
|
||||
out.ResourceVersionMatch = v1.ResourceVersionMatch(in.ResourceVersionMatch)
|
||||
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
|
||||
out.Limit = in.Limit
|
||||
out.Continue = in.Continue
|
||||
out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents))
|
||||
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
|
||||
}
|
||||
if err := v1.Convert_string_To_fields_Selector(&in.FieldSelector, &out.FieldSelector, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.Watch = in.Watch
|
||||
out.AllowWatchBookmarks = in.AllowWatchBookmarks
|
||||
out.ResourceVersion = in.ResourceVersion
|
||||
out.ResourceVersionMatch = v1.ResourceVersionMatch(in.ResourceVersionMatch)
|
||||
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
|
||||
out.Limit = in.Limit
|
||||
out.Continue = in.Continue
|
||||
out.SendInitialEvents = (*bool)(unsafe.Pointer(in.SendInitialEvents))
|
||||
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)
|
||||
}
|
||||
Generated
Vendored
+102
@@ -0,0 +1,102 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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 deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package internalversion
|
||||
|
||||
import (
|
||||
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 *List) DeepCopyInto(out *List) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]runtime.Object, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
(*out)[i] = (*in)[i].DeepCopyObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new List.
|
||||
func (in *List) DeepCopy() *List {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(List)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *List) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ListOptions) DeepCopyInto(out *ListOptions) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.LabelSelector != nil {
|
||||
out.LabelSelector = in.LabelSelector.DeepCopySelector()
|
||||
}
|
||||
if in.FieldSelector != nil {
|
||||
out.FieldSelector = in.FieldSelector.DeepCopySelector()
|
||||
}
|
||||
if in.TimeoutSeconds != nil {
|
||||
in, out := &in.TimeoutSeconds, &out.TimeoutSeconds
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
if in.SendInitialEvents != nil {
|
||||
in, out := &in.SendInitialEvents, &out.SendInitialEvents
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListOptions.
|
||||
func (in *ListOptions) DeepCopy() *ListOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ListOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ListOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Generated
Vendored
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
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 unstructuredscheme
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/versioning"
|
||||
)
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
|
||||
// NewUnstructuredNegotiatedSerializer returns a simple, negotiated serializer
|
||||
func NewUnstructuredNegotiatedSerializer() runtime.NegotiatedSerializer {
|
||||
return unstructuredNegotiatedSerializer{
|
||||
scheme: scheme,
|
||||
typer: NewUnstructuredObjectTyper(),
|
||||
creator: NewUnstructuredCreator(),
|
||||
}
|
||||
}
|
||||
|
||||
type unstructuredNegotiatedSerializer struct {
|
||||
scheme *runtime.Scheme
|
||||
typer runtime.ObjectTyper
|
||||
creator runtime.ObjectCreater
|
||||
}
|
||||
|
||||
func (s unstructuredNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
|
||||
return []runtime.SerializerInfo{
|
||||
{
|
||||
MediaType: "application/json",
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "json",
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializerWithOptions(json.DefaultMetaFactory, s.creator, s.typer, json.SerializerOptions{}),
|
||||
PrettySerializer: json.NewSerializerWithOptions(json.DefaultMetaFactory, s.creator, s.typer, json.SerializerOptions{Pretty: true}),
|
||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializerWithOptions(json.DefaultMetaFactory, s.creator, s.typer, json.SerializerOptions{}),
|
||||
Framer: json.Framer,
|
||||
},
|
||||
},
|
||||
{
|
||||
MediaType: "application/yaml",
|
||||
MediaTypeType: "application",
|
||||
MediaTypeSubType: "yaml",
|
||||
EncodesAsText: true,
|
||||
Serializer: json.NewSerializerWithOptions(json.DefaultMetaFactory, s.creator, s.typer, json.SerializerOptions{Yaml: true}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s unstructuredNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
||||
return versioning.NewDefaultingCodecForScheme(s.scheme, encoder, nil, gv, nil)
|
||||
}
|
||||
|
||||
func (s unstructuredNegotiatedSerializer) DecoderToVersion(decoder runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
|
||||
return versioning.NewDefaultingCodecForScheme(s.scheme, nil, decoder, nil, gv)
|
||||
}
|
||||
|
||||
type unstructuredObjectTyper struct {
|
||||
}
|
||||
|
||||
// NewUnstructuredObjectTyper returns an object typer that can deal with unstructured things
|
||||
func NewUnstructuredObjectTyper() runtime.ObjectTyper {
|
||||
return unstructuredObjectTyper{}
|
||||
}
|
||||
|
||||
func (t unstructuredObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
// Delegate for things other than Unstructured.
|
||||
if _, ok := obj.(runtime.Unstructured); !ok {
|
||||
return nil, false, fmt.Errorf("cannot type %T", obj)
|
||||
}
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
if len(gvk.Kind) == 0 {
|
||||
return nil, false, runtime.NewMissingKindErr("object has no kind field ")
|
||||
}
|
||||
if len(gvk.Version) == 0 {
|
||||
return nil, false, runtime.NewMissingVersionErr("object has no apiVersion field")
|
||||
}
|
||||
|
||||
return []schema.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil
|
||||
}
|
||||
|
||||
func (t unstructuredObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type unstructuredCreator struct{}
|
||||
|
||||
// NewUnstructuredCreator returns a simple object creator that always returns an unstructured
|
||||
func NewUnstructuredCreator() runtime.ObjectCreater {
|
||||
return unstructuredCreator{}
|
||||
}
|
||||
|
||||
func (c unstructuredCreator) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||
ret := &unstructured.Unstructured{}
|
||||
ret.SetGroupVersionKind(kind)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type unstructuredDefaulter struct {
|
||||
}
|
||||
|
||||
// NewUnstructuredDefaulter returns defaulter suitable for unstructured types that doesn't default anything
|
||||
func NewUnstructuredDefaulter() runtime.ObjectDefaulter {
|
||||
return unstructuredDefaulter{}
|
||||
}
|
||||
|
||||
func (d unstructuredDefaulter) Default(in runtime.Object) {
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
)
|
||||
|
||||
// Convert_Slice_string_To_v1beta1_IncludeObjectPolicy allows converting a URL query parameter value
|
||||
func Convert_Slice_string_To_v1beta1_IncludeObjectPolicy(in *[]string, out *IncludeObjectPolicy, s conversion.Scope) error {
|
||||
if len(*in) > 0 {
|
||||
*out = IncludeObjectPolicy((*in)[0])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_PartialObjectMetadataList_To_v1_PartialObjectMetadataList allows converting PartialObjectMetadataList between versions
|
||||
func Convert_v1beta1_PartialObjectMetadataList_To_v1_PartialObjectMetadataList(in *PartialObjectMetadataList, out *v1.PartialObjectMetadataList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]v1.PartialObjectMetadata)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_PartialObjectMetadataList_To_v1beta1_PartialObjectMetadataList allows converting PartialObjectMetadataList between versions
|
||||
func Convert_v1_PartialObjectMetadataList_To_v1beta1_PartialObjectMetadataList(in *v1.PartialObjectMetadataList, out *PartialObjectMetadataList, s conversion.Scope) error {
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Items = *(*[]v1.PartialObjectMetadata)(unsafe.Pointer(&in.Items))
|
||||
return nil
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
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 v1beta1
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:openapi-model-package=io.k8s.apimachinery.pkg.apis.meta.v1beta1
|
||||
|
||||
// +groupName=meta.k8s.io
|
||||
|
||||
package v1beta1
|
||||
+341
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
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 protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: k8s.io/apimachinery/pkg/apis/meta/v1beta1/generated.proto
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
|
||||
io "io"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
math_bits "math/bits"
|
||||
reflect "reflect"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
func (m *PartialObjectMetadataList) Reset() { *m = PartialObjectMetadataList{} }
|
||||
|
||||
func (m *PartialObjectMetadataList) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *PartialObjectMetadataList) MarshalTo(dAtA []byte) (int, error) {
|
||||
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 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--
|
||||
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 base
|
||||
}
|
||||
func (m *PartialObjectMetadataList) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Items) > 0 {
|
||||
for _, e := range m.Items {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
}
|
||||
}
|
||||
l = m.ListMeta.Size()
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenerated(x uint64) (n int) {
|
||||
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 *PartialObjectMetadataList) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
repeatedStringForItems := "[]PartialObjectMetadata{"
|
||||
for _, f := range this.Items {
|
||||
repeatedStringForItems += fmt.Sprintf("%v", f) + ","
|
||||
}
|
||||
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
|
||||
}
|
||||
func valueToStringGenerated(v interface{}) string {
|
||||
rv := reflect.ValueOf(v)
|
||||
if rv.IsNil() {
|
||||
return "nil"
|
||||
}
|
||||
pv := reflect.Indirect(rv).Interface()
|
||||
return fmt.Sprintf("*%v", pv)
|
||||
}
|
||||
func (m *PartialObjectMetadataList) 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: PartialObjectMetadataList: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: PartialObjectMetadataList: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Items", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
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
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ListMeta", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.ListMeta.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) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenerated(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenerated
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupGenerated
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthGenerated
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupGenerated = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package k8s.io.apimachinery.pkg.apis.meta.v1beta1;
|
||||
|
||||
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
|
||||
|
||||
// Package-wide variables from generator "generated".
|
||||
option go_package = "k8s.io/apimachinery/pkg/apis/meta/v1beta1";
|
||||
|
||||
// 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 .k8s.io.apimachinery.pkg.apis.meta.v1.PartialObjectMetadata items = 1;
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
//go:build kubernetes_protomessage_one_more_release
|
||||
// +build kubernetes_protomessage_one_more_release
|
||||
|
||||
/*
|
||||
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 go-to-protobuf. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
func (*PartialObjectMetadataList) ProtoMessage() {}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name for this API.
|
||||
const GroupName = "meta.k8s.io"
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// AddMetaToScheme registers base meta types into schemas.
|
||||
func AddMetaToScheme(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Table{},
|
||||
&TableOptions{},
|
||||
&PartialObjectMetadata{},
|
||||
&PartialObjectMetadataList{},
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
func RegisterConversions(s *runtime.Scheme) error {
|
||||
if err := s.AddGeneratedConversionFunc((*PartialObjectMetadataList)(nil), (*v1.PartialObjectMetadataList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_PartialObjectMetadataList_To_v1_PartialObjectMetadataList(a.(*PartialObjectMetadataList), b.(*v1.PartialObjectMetadataList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1.PartialObjectMetadataList)(nil), (*PartialObjectMetadataList)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1_PartialObjectMetadataList_To_v1beta1_PartialObjectMetadataList(a.(*v1.PartialObjectMetadataList), b.(*PartialObjectMetadataList), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
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 v1beta1 is alpha objects from meta that will be introduced.
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// 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 = v1.Table
|
||||
|
||||
// TableColumnDefinition contains information about a column returned in the Table.
|
||||
// +protobuf=false
|
||||
type TableColumnDefinition = v1.TableColumnDefinition
|
||||
|
||||
// TableRow is an individual row in a table.
|
||||
// +protobuf=false
|
||||
type TableRow = v1.TableRow
|
||||
|
||||
// TableRowCondition allows a row to be marked with additional information.
|
||||
// +protobuf=false
|
||||
type TableRowCondition = v1.TableRowCondition
|
||||
|
||||
type RowConditionType = v1.RowConditionType
|
||||
|
||||
type ConditionStatus = v1.ConditionStatus
|
||||
|
||||
type IncludeObjectPolicy = v1.IncludeObjectPolicy
|
||||
|
||||
// TableOptions are used when a Table is requested by the caller.
|
||||
// +k8s:conversion-gen:explicit-from=net/url.Values
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
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 = v1.PartialObjectMetadata
|
||||
|
||||
// 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 []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
|
||||
)
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
// This file contains a collection of methods that can be used from go-restful to
|
||||
// generate Swagger API documentation for its models. Please read this PR for more
|
||||
// information on the implementation: https://github.com/emicklei/go-restful/pull/215
|
||||
//
|
||||
// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if
|
||||
// they are on one line! For multiple line or blocks that you want to ignore use ---.
|
||||
// Any context after a --- is ignored.
|
||||
//
|
||||
// Those methods can be generated by using hack/update-codegen.sh
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS START HERE. DO NOT EDIT.
|
||||
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
|
||||
}
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS END HERE
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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 deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
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 *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([]v1.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
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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 defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
// All generated defaulters are covering - they call all nested defaulters.
|
||||
func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
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 openapi-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
// OpenAPIModelName returns the OpenAPI model name for this type.
|
||||
func (in PartialObjectMetadataList) OpenAPIModelName() string {
|
||||
return "io.k8s.apimachinery.pkg.apis.meta.v1beta1.PartialObjectMetadataList"
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
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 cache
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
|
||||
// NewExpiring returns an initialized expiring cache.
|
||||
func NewExpiring() *Expiring {
|
||||
return NewExpiringWithClock(clock.RealClock{})
|
||||
}
|
||||
|
||||
// NewExpiringWithClock is like NewExpiring but allows passing in a custom
|
||||
// clock for testing.
|
||||
func NewExpiringWithClock(clock clock.Clock) *Expiring {
|
||||
return &Expiring{
|
||||
clock: clock,
|
||||
cache: make(map[interface{}]entry),
|
||||
}
|
||||
}
|
||||
|
||||
// Expiring is a map whose entries expire after a per-entry timeout.
|
||||
type Expiring struct {
|
||||
// AllowExpiredGet causes the expiration check to be skipped on Get.
|
||||
// It should only be used when a key always corresponds to the exact same value.
|
||||
// Thus when this field is true, expired keys are considered valid
|
||||
// until the next call to Set (which causes the GC to run).
|
||||
// It may not be changed concurrently with calls to Get.
|
||||
AllowExpiredGet bool
|
||||
|
||||
clock clock.Clock
|
||||
|
||||
// mu protects the below fields
|
||||
mu sync.RWMutex
|
||||
// cache is the internal map that backs the cache.
|
||||
cache map[interface{}]entry
|
||||
// generation is used as a cheap resource version for cache entries. Cleanups
|
||||
// are scheduled with a key and generation. When the cleanup runs, it first
|
||||
// compares its generation with the current generation of the entry. It
|
||||
// deletes the entry iff the generation matches. This prevents cleanups
|
||||
// scheduled for earlier versions of an entry from deleting later versions of
|
||||
// an entry when Set() is called multiple times with the same key.
|
||||
//
|
||||
// The integer value of the generation of an entry is meaningless.
|
||||
generation uint64
|
||||
|
||||
heap expiringHeap
|
||||
}
|
||||
|
||||
type entry struct {
|
||||
val interface{}
|
||||
expiry time.Time
|
||||
generation uint64
|
||||
}
|
||||
|
||||
// Get looks up an entry in the cache.
|
||||
func (c *Expiring) Get(key interface{}) (val interface{}, ok bool) {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
e, ok := c.cache[key]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
if !c.AllowExpiredGet && !c.clock.Now().Before(e.expiry) {
|
||||
return nil, false
|
||||
}
|
||||
return e.val, true
|
||||
}
|
||||
|
||||
// Set sets a key/value/expiry entry in the map, overwriting any previous entry
|
||||
// with the same key. The entry expires at the given expiry time, but its TTL
|
||||
// may be lengthened or shortened by additional calls to Set(). Garbage
|
||||
// collection of expired entries occurs during calls to Set(), however calls to
|
||||
// Get() will not return expired entries that have not yet been garbage
|
||||
// collected.
|
||||
func (c *Expiring) Set(key interface{}, val interface{}, ttl time.Duration) {
|
||||
now := c.clock.Now()
|
||||
expiry := now.Add(ttl)
|
||||
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.generation++
|
||||
|
||||
c.cache[key] = entry{
|
||||
val: val,
|
||||
expiry: expiry,
|
||||
generation: c.generation,
|
||||
}
|
||||
|
||||
// Run GC inline before pushing the new entry.
|
||||
c.gc(now)
|
||||
|
||||
heap.Push(&c.heap, &expiringHeapEntry{
|
||||
key: key,
|
||||
expiry: expiry,
|
||||
generation: c.generation,
|
||||
})
|
||||
}
|
||||
|
||||
// Delete deletes an entry in the map.
|
||||
func (c *Expiring) Delete(key interface{}) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.del(key, 0)
|
||||
}
|
||||
|
||||
// del deletes the entry for the given key. The generation argument is the
|
||||
// generation of the entry that should be deleted. If the generation has been
|
||||
// changed (e.g. if a set has occurred on an existing element but the old
|
||||
// cleanup still runs), this is a noop. If the generation argument is 0, the
|
||||
// entry's generation is ignored and the entry is deleted.
|
||||
//
|
||||
// del must be called under the write lock.
|
||||
func (c *Expiring) del(key interface{}, generation uint64) {
|
||||
e, ok := c.cache[key]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if generation != 0 && generation != e.generation {
|
||||
return
|
||||
}
|
||||
delete(c.cache, key)
|
||||
}
|
||||
|
||||
// Len returns the number of items in the cache.
|
||||
func (c *Expiring) Len() int {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
return len(c.cache)
|
||||
}
|
||||
|
||||
func (c *Expiring) gc(now time.Time) {
|
||||
for {
|
||||
// Return from gc if the heap is empty or the next element is not yet
|
||||
// expired.
|
||||
//
|
||||
// heap[0] is a peek at the next element in the heap, which is not obvious
|
||||
// from looking at the (*expiringHeap).Pop() implementation below.
|
||||
// heap.Pop() swaps the first entry with the last entry of the heap, then
|
||||
// calls (*expiringHeap).Pop() which returns the last element.
|
||||
if len(c.heap) == 0 || now.Before(c.heap[0].expiry) {
|
||||
return
|
||||
}
|
||||
cleanup := heap.Pop(&c.heap).(*expiringHeapEntry)
|
||||
c.del(cleanup.key, cleanup.generation)
|
||||
}
|
||||
}
|
||||
|
||||
type expiringHeapEntry struct {
|
||||
key interface{}
|
||||
expiry time.Time
|
||||
generation uint64
|
||||
}
|
||||
|
||||
// expiringHeap is a min-heap ordered by expiration time of its entries. The
|
||||
// expiring cache uses this as a priority queue to efficiently organize entries
|
||||
// which will be garbage collected once they expire.
|
||||
type expiringHeap []*expiringHeapEntry
|
||||
|
||||
var _ heap.Interface = &expiringHeap{}
|
||||
|
||||
func (cq expiringHeap) Len() int {
|
||||
return len(cq)
|
||||
}
|
||||
|
||||
func (cq expiringHeap) Less(i, j int) bool {
|
||||
return cq[i].expiry.Before(cq[j].expiry)
|
||||
}
|
||||
|
||||
func (cq expiringHeap) Swap(i, j int) {
|
||||
cq[i], cq[j] = cq[j], cq[i]
|
||||
}
|
||||
|
||||
func (cq *expiringHeap) Push(c interface{}) {
|
||||
*cq = append(*cq, c.(*expiringHeapEntry))
|
||||
}
|
||||
|
||||
func (cq *expiringHeap) Pop() interface{} {
|
||||
c := (*cq)[cq.Len()-1]
|
||||
*cq = (*cq)[:cq.Len()-1]
|
||||
return c
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Clock defines an interface for obtaining the current time
|
||||
type Clock interface {
|
||||
Now() time.Time
|
||||
}
|
||||
|
||||
// realClock implements the Clock interface by calling time.Now()
|
||||
type realClock struct{}
|
||||
|
||||
func (realClock) Now() time.Time { return time.Now() }
|
||||
|
||||
// LRUExpireCache is a cache that ensures the mostly recently accessed keys are returned with
|
||||
// a ttl beyond which keys are forcibly expired.
|
||||
type LRUExpireCache struct {
|
||||
// clock is used to obtain the current time
|
||||
clock Clock
|
||||
|
||||
lock sync.Mutex
|
||||
|
||||
maxSize int
|
||||
evictionList list.List
|
||||
entries map[interface{}]*list.Element
|
||||
}
|
||||
|
||||
// NewLRUExpireCache creates an expiring cache with the given size
|
||||
func NewLRUExpireCache(maxSize int) *LRUExpireCache {
|
||||
return NewLRUExpireCacheWithClock(maxSize, realClock{})
|
||||
}
|
||||
|
||||
// NewLRUExpireCacheWithClock creates an expiring cache with the given size, using the specified clock to obtain the current time.
|
||||
func NewLRUExpireCacheWithClock(maxSize int, clock Clock) *LRUExpireCache {
|
||||
if maxSize <= 0 {
|
||||
panic("maxSize must be > 0")
|
||||
}
|
||||
|
||||
return &LRUExpireCache{
|
||||
clock: clock,
|
||||
maxSize: maxSize,
|
||||
entries: map[interface{}]*list.Element{},
|
||||
}
|
||||
}
|
||||
|
||||
type cacheEntry struct {
|
||||
key interface{}
|
||||
value interface{}
|
||||
expireTime time.Time
|
||||
}
|
||||
|
||||
// Add adds the value to the cache at key with the specified maximum duration.
|
||||
func (c *LRUExpireCache) Add(key interface{}, value interface{}, ttl time.Duration) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
// Key already exists
|
||||
oldElement, ok := c.entries[key]
|
||||
if ok {
|
||||
c.evictionList.MoveToFront(oldElement)
|
||||
oldElement.Value.(*cacheEntry).value = value
|
||||
oldElement.Value.(*cacheEntry).expireTime = c.clock.Now().Add(ttl)
|
||||
return
|
||||
}
|
||||
|
||||
// Make space if necessary
|
||||
if c.evictionList.Len() >= c.maxSize {
|
||||
toEvict := c.evictionList.Back()
|
||||
c.evictionList.Remove(toEvict)
|
||||
delete(c.entries, toEvict.Value.(*cacheEntry).key)
|
||||
}
|
||||
|
||||
// Add new entry
|
||||
entry := &cacheEntry{
|
||||
key: key,
|
||||
value: value,
|
||||
expireTime: c.clock.Now().Add(ttl),
|
||||
}
|
||||
element := c.evictionList.PushFront(entry)
|
||||
c.entries[key] = element
|
||||
}
|
||||
|
||||
// Get returns the value at the specified key from the cache if it exists and is not
|
||||
// expired, or returns false.
|
||||
func (c *LRUExpireCache) Get(key interface{}) (interface{}, bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
element, ok := c.entries[key]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if c.clock.Now().After(element.Value.(*cacheEntry).expireTime) {
|
||||
c.evictionList.Remove(element)
|
||||
delete(c.entries, key)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.evictionList.MoveToFront(element)
|
||||
|
||||
return element.Value.(*cacheEntry).value, true
|
||||
}
|
||||
|
||||
// Remove removes the specified key from the cache if it exists
|
||||
func (c *LRUExpireCache) Remove(key interface{}) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
element, ok := c.entries[key]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.evictionList.Remove(element)
|
||||
delete(c.entries, key)
|
||||
}
|
||||
|
||||
// RemoveAll removes all keys that match predicate.
|
||||
func (c *LRUExpireCache) RemoveAll(predicate func(key any) bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
for key, element := range c.entries {
|
||||
if predicate(key) {
|
||||
c.evictionList.Remove(element)
|
||||
delete(c.entries, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keys returns all unexpired keys in the cache.
|
||||
//
|
||||
// Keep in mind that subsequent calls to Get() for any of the returned keys
|
||||
// might return "not found".
|
||||
//
|
||||
// Keys are returned ordered from least recently used to most recently used.
|
||||
func (c *LRUExpireCache) Keys() []interface{} {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
now := c.clock.Now()
|
||||
|
||||
val := make([]interface{}, 0, c.evictionList.Len())
|
||||
for element := c.evictionList.Back(); element != nil; element = element.Prev() {
|
||||
// Only return unexpired keys
|
||||
if !now.After(element.Value.(*cacheEntry).expireTime) {
|
||||
val = append(val, element.Value.(*cacheEntry).key)
|
||||
}
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
//go:build usegocmp
|
||||
// +build usegocmp
|
||||
|
||||
/*
|
||||
Copyright 2025 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 diff
|
||||
|
||||
import (
|
||||
"github.com/google/go-cmp/cmp" //nolint:depguard
|
||||
)
|
||||
|
||||
// Diff returns a string representation of the difference between two objects.
|
||||
// When built with the usegocmp tag, it uses go-cmp/cmp to generate a diff
|
||||
// between the objects.
|
||||
func Diff(a, b any) string {
|
||||
return cmp.Diff(a, b)
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
//go:build !usegocmp
|
||||
// +build !usegocmp
|
||||
|
||||
/*
|
||||
Copyright 2025 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 diff
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/dump"
|
||||
)
|
||||
|
||||
// Diff returns a string representation of the difference between two objects.
|
||||
// When built without the usegocmp tag, it uses go-difflib/difflib to generate a
|
||||
// unified diff of the objects. It attempts to use JSON serialization first,
|
||||
// falling back to an object dump via the dump package if JSON marshaling fails.
|
||||
func Diff(a, b any) string {
|
||||
|
||||
aStr, aErr := toPrettyJSON(a)
|
||||
bStr, bErr := toPrettyJSON(b)
|
||||
if aErr != nil || bErr != nil {
|
||||
aStr = dump.Pretty(a)
|
||||
bStr = dump.Pretty(b)
|
||||
}
|
||||
|
||||
diff := difflib.UnifiedDiff{
|
||||
A: difflib.SplitLines(aStr),
|
||||
B: difflib.SplitLines(bStr),
|
||||
Context: 3,
|
||||
}
|
||||
|
||||
diffstr, err := difflib.GetUnifiedDiffString(diff)
|
||||
if err != nil {
|
||||
return fmt.Sprintf("error generating diff: %v", err)
|
||||
}
|
||||
|
||||
return diffstr
|
||||
}
|
||||
|
||||
// toPrettyJSON converts an object to a pretty-printed JSON string.
|
||||
func toPrettyJSON(data any) (string, error) {
|
||||
jsonData, err := json.MarshalIndent(data, "", " ")
|
||||
return string(jsonData), err
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
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 diff
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/dump"
|
||||
)
|
||||
|
||||
// ObjectGoPrintSideBySide prints a and b as textual dumps side by side,
|
||||
// enabling easy visual scanning for mismatches.
|
||||
func ObjectGoPrintSideBySide(a, b interface{}) string {
|
||||
sA := dump.Pretty(a)
|
||||
sB := dump.Pretty(b)
|
||||
|
||||
linesA := strings.Split(sA, "\n")
|
||||
linesB := strings.Split(sB, "\n")
|
||||
width := 0
|
||||
for _, s := range linesA {
|
||||
l := len(s)
|
||||
if l > width {
|
||||
width = l
|
||||
}
|
||||
}
|
||||
for _, s := range linesB {
|
||||
l := len(s)
|
||||
if l > width {
|
||||
width = l
|
||||
}
|
||||
}
|
||||
buf := &bytes.Buffer{}
|
||||
w := tabwriter.NewWriter(buf, width, 0, 1, ' ', 0)
|
||||
max := len(linesA)
|
||||
if len(linesB) > max {
|
||||
max = len(linesB)
|
||||
}
|
||||
for i := 0; i < max; i++ {
|
||||
var a, b string
|
||||
if i < len(linesA) {
|
||||
a = linesA[i]
|
||||
}
|
||||
if i < len(linesB) {
|
||||
b = linesB[i]
|
||||
}
|
||||
_, _ = fmt.Fprintf(w, "%s\t%s\n", a, b)
|
||||
}
|
||||
_ = w.Flush()
|
||||
return buf.String()
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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 duration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ShortHumanDuration returns a succinct representation of the provided duration
|
||||
// with limited precision for consumption by humans.
|
||||
func ShortHumanDuration(d time.Duration) string {
|
||||
// Allow deviation no more than 2 seconds(excluded) to tolerate machine time
|
||||
// inconsistence, it can be considered as almost now.
|
||||
if seconds := int(d.Seconds()); seconds < -1 {
|
||||
return "<invalid>"
|
||||
} else if seconds < 0 {
|
||||
return "0s"
|
||||
} else if seconds < 60 {
|
||||
return fmt.Sprintf("%ds", seconds)
|
||||
} else if minutes := int(d.Minutes()); minutes < 60 {
|
||||
return fmt.Sprintf("%dm", minutes)
|
||||
} else if hours := int(d.Hours()); hours < 24 {
|
||||
return fmt.Sprintf("%dh", hours)
|
||||
} else if hours < 24*365 {
|
||||
return fmt.Sprintf("%dd", hours/24)
|
||||
}
|
||||
return fmt.Sprintf("%dy", int(d.Hours()/24/365))
|
||||
}
|
||||
|
||||
// HumanDuration returns a succinct representation of the provided duration
|
||||
// with limited precision for consumption by humans. It provides ~2-3 significant
|
||||
// figures of duration.
|
||||
func HumanDuration(d time.Duration) string {
|
||||
// Allow deviation no more than 2 seconds(excluded) to tolerate machine time
|
||||
// inconsistence, it can be considered as almost now.
|
||||
if seconds := int(d.Seconds()); seconds < -1 {
|
||||
return "<invalid>"
|
||||
} else if seconds < 0 {
|
||||
return "0s"
|
||||
} else if seconds < 60*2 {
|
||||
return fmt.Sprintf("%ds", seconds)
|
||||
}
|
||||
minutes := int(d / time.Minute)
|
||||
if minutes < 10 {
|
||||
s := int(d/time.Second) % 60
|
||||
if s == 0 {
|
||||
return fmt.Sprintf("%dm", minutes)
|
||||
}
|
||||
return fmt.Sprintf("%dm%ds", minutes, s)
|
||||
} else if minutes < 60*3 {
|
||||
return fmt.Sprintf("%dm", minutes)
|
||||
}
|
||||
hours := int(d / time.Hour)
|
||||
if hours < 8 {
|
||||
m := int(d/time.Minute) % 60
|
||||
if m == 0 {
|
||||
return fmt.Sprintf("%dh", hours)
|
||||
}
|
||||
return fmt.Sprintf("%dh%dm", hours, m)
|
||||
} else if hours < 48 {
|
||||
return fmt.Sprintf("%dh", hours)
|
||||
} else if hours < 24*8 {
|
||||
h := hours % 24
|
||||
if h == 0 {
|
||||
return fmt.Sprintf("%dd", hours/24)
|
||||
}
|
||||
return fmt.Sprintf("%dd%dh", hours/24, h)
|
||||
} else if hours < 24*365*2 {
|
||||
return fmt.Sprintf("%dd", hours/24)
|
||||
} else if hours < 24*365*8 {
|
||||
dy := int(hours/24) % 365
|
||||
if dy == 0 {
|
||||
return fmt.Sprintf("%dy", hours/24/365)
|
||||
}
|
||||
return fmt.Sprintf("%dy%dd", hours/24/365, dy)
|
||||
}
|
||||
return fmt.Sprintf("%dy", int(hours/24/365))
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
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 jsonmergepatch
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"gopkg.in/evanphx/json-patch.v4"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||
)
|
||||
|
||||
// Create a 3-way merge patch based-on JSON merge patch.
|
||||
// Calculate addition-and-change patch between current and modified.
|
||||
// Calculate deletion patch between original and modified.
|
||||
func CreateThreeWayJSONMergePatch(original, modified, current []byte, fns ...mergepatch.PreconditionFunc) ([]byte, error) {
|
||||
if len(original) == 0 {
|
||||
original = []byte(`{}`)
|
||||
}
|
||||
if len(modified) == 0 {
|
||||
modified = []byte(`{}`)
|
||||
}
|
||||
if len(current) == 0 {
|
||||
current = []byte(`{}`)
|
||||
}
|
||||
|
||||
addAndChangePatch, err := jsonpatch.CreateMergePatch(current, modified)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Only keep addition and changes
|
||||
addAndChangePatch, addAndChangePatchObj, err := keepOrDeleteNullInJsonPatch(addAndChangePatch, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deletePatch, err := jsonpatch.CreateMergePatch(original, modified)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Only keep deletion
|
||||
deletePatch, deletePatchObj, err := keepOrDeleteNullInJsonPatch(deletePatch, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hasConflicts, err := mergepatch.HasConflicts(addAndChangePatchObj, deletePatchObj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if hasConflicts {
|
||||
return nil, mergepatch.NewErrConflict(mergepatch.ToYAMLOrError(addAndChangePatchObj), mergepatch.ToYAMLOrError(deletePatchObj))
|
||||
}
|
||||
patch, err := jsonpatch.MergePatch(deletePatch, addAndChangePatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var patchMap map[string]interface{}
|
||||
err = json.Unmarshal(patch, &patchMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal patch for precondition check: %s", patch)
|
||||
}
|
||||
meetPreconditions, err := meetPreconditions(patchMap, fns...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !meetPreconditions {
|
||||
return nil, mergepatch.NewErrPreconditionFailed(patchMap)
|
||||
}
|
||||
|
||||
return patch, nil
|
||||
}
|
||||
|
||||
// keepOrDeleteNullInJsonPatch takes a json-encoded byte array and a boolean.
|
||||
// It returns a filtered object and its corresponding json-encoded byte array.
|
||||
// It is a wrapper of func keepOrDeleteNullInObj
|
||||
func keepOrDeleteNullInJsonPatch(patch []byte, keepNull bool) ([]byte, map[string]interface{}, error) {
|
||||
var patchMap map[string]interface{}
|
||||
err := json.Unmarshal(patch, &patchMap)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
filteredMap, err := keepOrDeleteNullInObj(patchMap, keepNull)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
o, err := json.Marshal(filteredMap)
|
||||
return o, filteredMap, err
|
||||
}
|
||||
|
||||
// keepOrDeleteNullInObj will keep only the null value and delete all the others,
|
||||
// if keepNull is true. Otherwise, it will delete all the null value and keep the others.
|
||||
func keepOrDeleteNullInObj(m map[string]interface{}, keepNull bool) (map[string]interface{}, error) {
|
||||
filteredMap := make(map[string]interface{})
|
||||
var err error
|
||||
for key, val := range m {
|
||||
switch {
|
||||
case keepNull && val == nil:
|
||||
filteredMap[key] = nil
|
||||
case val != nil:
|
||||
switch typedVal := val.(type) {
|
||||
case map[string]interface{}:
|
||||
// Explicitly-set empty maps are treated as values instead of empty patches
|
||||
if len(typedVal) == 0 {
|
||||
if !keepNull {
|
||||
filteredMap[key] = typedVal
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var filteredSubMap map[string]interface{}
|
||||
filteredSubMap, err = keepOrDeleteNullInObj(typedVal, keepNull)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If the returned filtered submap was empty, this is an empty patch for the entire subdict, so the key
|
||||
// should not be set
|
||||
if len(filteredSubMap) != 0 {
|
||||
filteredMap[key] = filteredSubMap
|
||||
}
|
||||
|
||||
case []interface{}, string, float64, bool, int64, nil:
|
||||
// Lists are always replaced in Json, no need to check each entry in the list.
|
||||
if !keepNull {
|
||||
filteredMap[key] = val
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown type: %v", reflect.TypeOf(typedVal))
|
||||
}
|
||||
}
|
||||
}
|
||||
return filteredMap, nil
|
||||
}
|
||||
|
||||
func meetPreconditions(patchObj map[string]interface{}, fns ...mergepatch.PreconditionFunc) (bool, error) {
|
||||
// Apply the preconditions to the patch, and return an error if any of them fail.
|
||||
for _, fn := range fns {
|
||||
if !fn(patchObj) {
|
||||
return false, fmt.Errorf("precondition failed for: %v", patchObj)
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
Reference in New Issue
Block a user