Merge pull request #72947 from apelisse/wip-feature-serverside-apply-merge

Merge feature-serverside-apply back in master

Kubernetes-commit: 2a5a41a08b08075aa2960170c8342d974ccc2cd3
This commit is contained in:
Kubernetes Publisher
2019-02-04 18:28:03 -08:00
parent 3787f3c1f6
commit cfd89cde21
54 changed files with 5404 additions and 530 deletions
+24
View File
@@ -27,6 +27,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
"sigs.k8s.io/structured-merge-diff/merge"
)
const (
@@ -184,6 +185,29 @@ func NewConflict(qualifiedResource schema.GroupResource, name string, err error)
}}
}
// NewApplyConflict returns an error including details on the requests apply conflicts
func NewApplyConflict(conflicts merge.Conflicts) *StatusError {
causes := make([]metav1.StatusCause, 0, len(conflicts))
for _, conflict := range conflicts {
causes = append(causes, metav1.StatusCause{
Type: metav1.CauseType("conflict"),
Message: conflict.Error(),
Field: conflict.Path.String(),
})
}
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: fmt.Sprintf("Apply failed with %d conflicts: %s", len(conflicts), conflicts.Error()),
}}
}
// 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{
+2 -2
View File
@@ -20,14 +20,13 @@ 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
@@ -138,6 +137,7 @@ func AsPartialObjectMetadata(m metav1.Object) *metav1beta1.PartialObjectMetadata
Finalizers: m.GetFinalizers(),
ClusterName: m.GetClusterName(),
Initializers: m.GetInitializers(),
ManagedFields: m.GetManagedFields(),
},
}
}
+1 -1
View File
@@ -680,7 +680,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)
}
File diff suppressed because it is too large Load Diff
+74
View File
@@ -202,6 +202,23 @@ message ExportOptions {
optional bool exact = 2;
}
// Fields stores a set of fields in a data structure like a Trie.
// To understand how this is used, see: https://github.com/kubernetes-sigs/structured-merge-diff
message Fields {
// Map stores a set of fields in a data structure like a Trie.
//
// 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 k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal
map<string, Fields> map = 1;
}
// GetOptions is the standard query options to the standard REST get call.
message GetOptions {
// When specified:
@@ -436,6 +453,31 @@ 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;
// Fields identifies a set of fields.
// +optional
optional Fields fields = 5;
}
// MicroTime is version of Time with microsecond level precision.
//
// +protobuf.options.marshal=false
@@ -617,6 +659,19 @@ 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.
//
// This field is alpha and can be changed or removed without notice.
//
// +optional
repeated ManagedFieldsEntry managedFields = 17;
}
// OwnerReference contains enough information to let you identify an owning
@@ -656,6 +711,24 @@ message OwnerReference {
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;
}
// Preconditions must be fulfilled before an operation (update, delete, etc.) is carried out.
message Preconditions {
// Specifies the target UID.
@@ -841,6 +914,7 @@ message TypeMeta {
}
// 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
+15
View File
@@ -17,6 +17,7 @@ limitations under the License.
package v1
import (
"encoding/json"
"fmt"
"k8s.io/apimachinery/pkg/fields"
@@ -243,4 +244,18 @@ func ResetObjectMetaForStatus(meta, existingMeta Object) {
meta.SetAnnotations(existingMeta.GetAnnotations())
meta.SetFinalizers(existingMeta.GetFinalizers())
meta.SetOwnerReferences(existingMeta.GetOwnerReferences())
meta.SetManagedFields(existingMeta.GetManagedFields())
}
// MarshalJSON implements json.Marshaler
func (f Fields) MarshalJSON() ([]byte, error) {
return json.Marshal(&f.Map)
}
// UnmarshalJSON implements json.Unmarshaler
func (f *Fields) UnmarshalJSON(b []byte) error {
return json.Unmarshal(b, &f.Map)
}
var _ json.Marshaler = Fields{}
var _ json.Unmarshaler = &Fields{}
+8 -2
View File
@@ -63,6 +63,8 @@ type Object interface {
SetOwnerReferences([]OwnerReference)
GetClusterName() string
SetClusterName(clusterName string)
GetManagedFields() []ManagedFieldsEntry
SetManagedFields(managedFields []ManagedFieldsEntry)
}
// ListMetaAccessor retrieves the list interface from an object
@@ -166,5 +168,9 @@ func (meta *ObjectMeta) GetOwnerReferences() []OwnerReference { return m
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
}
+2
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,6 +91,7 @@ func init() {
&DeleteOptions{},
&CreateOptions{},
&UpdateOptions{},
&PatchOptions{},
)
// register manually. This usually goes through the SchemeBuilder, which we cannot use here.
+82
View File
@@ -252,6 +252,19 @@ 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"`
// 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.
//
// This field is alpha and can be changed or removed without notice.
//
// +optional
ManagedFields []ManagedFieldsEntry `json:"managedFields,omitempty" protobuf:"bytes,17,rep,name=managedFields"`
}
// Initializers tracks the progress of initialization.
@@ -494,7 +507,30 @@ type CreateOptions struct {
// +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"`
}
// +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"`
@@ -1009,3 +1045,49 @@ 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 identifies a set of fields.
// +optional
Fields *Fields `json:"fields,omitempty" protobuf:"bytes,5,opt,name=fields,casttype=Fields"`
}
// ManagedFieldsOperationType is the type of operation which lead to a ManagedFieldsEntry being created.
type ManagedFieldsOperationType string
const (
ManagedFieldsOperationApply ManagedFieldsOperationType = "Apply"
ManagedFieldsOperationUpdate ManagedFieldsOperationType = "Update"
)
// Fields stores a set of fields in a data structure like a Trie.
// To understand how this is used, see: https://github.com/kubernetes-sigs/structured-merge-diff
type Fields struct {
// Map stores a set of fields in a data structure like a Trie.
//
// 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 k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal
Map map[string]Fields `json:",inline" protobuf:"bytes,1,rep,name=map"`
}
+33 -1
View File
@@ -118,6 +118,14 @@ func (ExportOptions) SwaggerDoc() map[string]string {
return map_ExportOptions
}
var map_Fields = map[string]string{
"": "Fields stores a set of fields in a data structure like a Trie. To understand how this is used, see: https://github.com/kubernetes-sigs/structured-merge-diff",
}
func (Fields) SwaggerDoc() map[string]string {
return map_Fields
}
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.",
@@ -213,6 +221,19 @@ 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'",
"fields": "Fields identifies a set of fields.",
}
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",
@@ -231,6 +252,7 @@ var map_ObjectMeta = map[string]string{
"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.\n\nDEPRECATED - initializers are an alpha field and will be removed in v1.15.",
"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.\n\nThis field is alpha and can be changed or removed without notice.",
}
func (ObjectMeta) SwaggerDoc() map[string]string {
@@ -259,6 +281,16 @@ 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.",
}
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.",
@@ -337,7 +369,7 @@ func (TypeMeta) SwaggerDoc() map[string]string {
}
var map_UpdateOptions = map[string]string{
"": "UpdateOptions may be provided when updating an API object.",
"": "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",
}
+48 -2
View File
@@ -143,13 +143,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{})
@@ -436,7 +443,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 +457,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")
}
+90
View File
@@ -312,6 +312,29 @@ 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 *Fields) DeepCopyInto(out *Fields) {
*out = *in
if in.Map != nil {
in, out := &in.Map, &out.Map
*out = make(map[string]Fields, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Fields.
func (in *Fields) DeepCopy() *Fields {
if in == nil {
return nil
}
out := new(Fields)
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
@@ -624,6 +647,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.Fields != nil {
in, out := &in.Fields, &out.Fields
*out = new(Fields)
(*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 {
@@ -678,6 +726,13 @@ func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) {
*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
}
@@ -733,6 +788,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
+1
View File
@@ -42,6 +42,7 @@ type TypeMeta struct {
const (
ContentTypeJSON string = "application/json"
ContentTypeYAML string = "application/yaml"
)
// RawExtension is used to hold extensions in external versions.
+1
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"
)
-2
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)
}
}