github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/api/meta/meta.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package meta
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  
    23  	metav1 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/apis/meta/v1"
    24  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/conversion"
    25  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime"
    26  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/schema"
    27  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/types"
    28  	"k8s.io/klog/v2"
    29  )
    30  
    31  // errNotList is returned when an object implements the Object style interfaces but not the List style
    32  // interfaces.
    33  var errNotList = fmt.Errorf("object does not implement the List interfaces")
    34  
    35  var errNotCommon = fmt.Errorf("object does not implement the common interface for accessing the SelfLink")
    36  
    37  // CommonAccessor returns a Common interface for the provided object or an error if the object does
    38  // not provide List.
    39  func CommonAccessor(obj interface{}) (metav1.Common, error) {
    40  	switch t := obj.(type) {
    41  	case List:
    42  		return t, nil
    43  	case ListMetaAccessor:
    44  		if m := t.GetListMeta(); m != nil {
    45  			return m, nil
    46  		}
    47  		return nil, errNotCommon
    48  	case metav1.ListMetaAccessor:
    49  		if m := t.GetListMeta(); m != nil {
    50  			return m, nil
    51  		}
    52  		return nil, errNotCommon
    53  	case metav1.Object:
    54  		return t, nil
    55  	case metav1.ObjectMetaAccessor:
    56  		if m := t.GetObjectMeta(); m != nil {
    57  			return m, nil
    58  		}
    59  		return nil, errNotCommon
    60  	default:
    61  		return nil, errNotCommon
    62  	}
    63  }
    64  
    65  // ListAccessor returns a List interface for the provided object or an error if the object does
    66  // not provide List.
    67  // IMPORTANT: Objects are NOT a superset of lists. Do not use this check to determine whether an
    68  // object *is* a List.
    69  func ListAccessor(obj interface{}) (List, error) {
    70  	switch t := obj.(type) {
    71  	case List:
    72  		return t, nil
    73  	case ListMetaAccessor:
    74  		if m := t.GetListMeta(); m != nil {
    75  			return m, nil
    76  		}
    77  		return nil, errNotList
    78  	case metav1.ListMetaAccessor:
    79  		if m := t.GetListMeta(); m != nil {
    80  			return m, nil
    81  		}
    82  		return nil, errNotList
    83  	default:
    84  		return nil, errNotList
    85  	}
    86  }
    87  
    88  // errNotObject is returned when an object implements the List style interfaces but not the Object style
    89  // interfaces.
    90  var errNotObject = fmt.Errorf("object does not implement the Object interfaces")
    91  
    92  // Accessor takes an arbitrary object pointer and returns meta.Interface.
    93  // obj must be a pointer to an API type. An error is returned if the minimum
    94  // required fields are missing. Fields that are not required return the default
    95  // value and are a no-op if set.
    96  func Accessor(obj interface{}) (metav1.Object, error) {
    97  	switch t := obj.(type) {
    98  	case metav1.Object:
    99  		return t, nil
   100  	case metav1.ObjectMetaAccessor:
   101  		if m := t.GetObjectMeta(); m != nil {
   102  			return m, nil
   103  		}
   104  		return nil, errNotObject
   105  	default:
   106  		return nil, errNotObject
   107  	}
   108  }
   109  
   110  // AsPartialObjectMetadata takes the metav1 interface and returns a partial object.
   111  // TODO: consider making this solely a conversion action.
   112  func AsPartialObjectMetadata(m metav1.Object) *metav1.PartialObjectMetadata {
   113  	switch t := m.(type) {
   114  	case *metav1.ObjectMeta:
   115  		return &metav1.PartialObjectMetadata{ObjectMeta: *t}
   116  	default:
   117  		return &metav1.PartialObjectMetadata{
   118  			ObjectMeta: metav1.ObjectMeta{
   119  				Name:                       m.GetName(),
   120  				GenerateName:               m.GetGenerateName(),
   121  				Namespace:                  m.GetNamespace(),
   122  				SelfLink:                   m.GetSelfLink(),
   123  				UID:                        m.GetUID(),
   124  				ResourceVersion:            m.GetResourceVersion(),
   125  				Generation:                 m.GetGeneration(),
   126  				CreationTimestamp:          m.GetCreationTimestamp(),
   127  				DeletionTimestamp:          m.GetDeletionTimestamp(),
   128  				DeletionGracePeriodSeconds: m.GetDeletionGracePeriodSeconds(),
   129  				Labels:                     m.GetLabels(),
   130  				Annotations:                m.GetAnnotations(),
   131  				OwnerReferences:            m.GetOwnerReferences(),
   132  				Finalizers:                 m.GetFinalizers(),
   133  				ManagedFields:              m.GetManagedFields(),
   134  			},
   135  		}
   136  	}
   137  }
   138  
   139  // TypeAccessor returns an interface that allows retrieving and modifying the APIVersion
   140  // and Kind of an in-memory internal object.
   141  // TODO: this interface is used to test code that does not have ObjectMeta or ListMeta
   142  // in round tripping (objects which can use apiVersion/kind, but do not fit the Kube
   143  // api conventions).
   144  func TypeAccessor(obj interface{}) (Type, error) {
   145  	if typed, ok := obj.(runtime.Object); ok {
   146  		return objectAccessor{typed}, nil
   147  	}
   148  	v, err := conversion.EnforcePtr(obj)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	t := v.Type()
   153  	if v.Kind() != reflect.Struct {
   154  		return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface())
   155  	}
   156  
   157  	typeMeta := v.FieldByName("TypeMeta")
   158  	if !typeMeta.IsValid() {
   159  		return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t)
   160  	}
   161  	a := &genericAccessor{}
   162  	if err := extractFromTypeMeta(typeMeta, a); err != nil {
   163  		return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err)
   164  	}
   165  	return a, nil
   166  }
   167  
   168  type objectAccessor struct {
   169  	runtime.Object
   170  }
   171  
   172  func (obj objectAccessor) GetKind() string {
   173  	return obj.GetObjectKind().GroupVersionKind().Kind
   174  }
   175  
   176  func (obj objectAccessor) SetKind(kind string) {
   177  	gvk := obj.GetObjectKind().GroupVersionKind()
   178  	gvk.Kind = kind
   179  	obj.GetObjectKind().SetGroupVersionKind(gvk)
   180  }
   181  
   182  func (obj objectAccessor) GetAPIVersion() string {
   183  	return obj.GetObjectKind().GroupVersionKind().GroupVersion().String()
   184  }
   185  
   186  func (obj objectAccessor) SetAPIVersion(version string) {
   187  	gvk := obj.GetObjectKind().GroupVersionKind()
   188  	gv, err := schema.ParseGroupVersion(version)
   189  	if err != nil {
   190  		gv = schema.GroupVersion{Version: version}
   191  	}
   192  	gvk.Group, gvk.Version = gv.Group, gv.Version
   193  	obj.GetObjectKind().SetGroupVersionKind(gvk)
   194  }
   195  
   196  // NewAccessor returns a MetadataAccessor that can retrieve
   197  // or manipulate resource version on objects derived from core API
   198  // metadata concepts.
   199  func NewAccessor() MetadataAccessor {
   200  	return resourceAccessor{}
   201  }
   202  
   203  // resourceAccessor implements ResourceVersioner and SelfLinker.
   204  type resourceAccessor struct{}
   205  
   206  func (resourceAccessor) Kind(obj runtime.Object) (string, error) {
   207  	return objectAccessor{obj}.GetKind(), nil
   208  }
   209  
   210  func (resourceAccessor) SetKind(obj runtime.Object, kind string) error {
   211  	objectAccessor{obj}.SetKind(kind)
   212  	return nil
   213  }
   214  
   215  func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) {
   216  	return objectAccessor{obj}.GetAPIVersion(), nil
   217  }
   218  
   219  func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error {
   220  	objectAccessor{obj}.SetAPIVersion(version)
   221  	return nil
   222  }
   223  
   224  func (resourceAccessor) Namespace(obj runtime.Object) (string, error) {
   225  	accessor, err := Accessor(obj)
   226  	if err != nil {
   227  		return "", err
   228  	}
   229  	return accessor.GetNamespace(), nil
   230  }
   231  
   232  func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error {
   233  	accessor, err := Accessor(obj)
   234  	if err != nil {
   235  		return err
   236  	}
   237  	accessor.SetNamespace(namespace)
   238  	return nil
   239  }
   240  
   241  func (resourceAccessor) Name(obj runtime.Object) (string, error) {
   242  	accessor, err := Accessor(obj)
   243  	if err != nil {
   244  		return "", err
   245  	}
   246  	return accessor.GetName(), nil
   247  }
   248  
   249  func (resourceAccessor) SetName(obj runtime.Object, name string) error {
   250  	accessor, err := Accessor(obj)
   251  	if err != nil {
   252  		return err
   253  	}
   254  	accessor.SetName(name)
   255  	return nil
   256  }
   257  
   258  func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) {
   259  	accessor, err := Accessor(obj)
   260  	if err != nil {
   261  		return "", err
   262  	}
   263  	return accessor.GetGenerateName(), nil
   264  }
   265  
   266  func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error {
   267  	accessor, err := Accessor(obj)
   268  	if err != nil {
   269  		return err
   270  	}
   271  	accessor.SetGenerateName(name)
   272  	return nil
   273  }
   274  
   275  func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) {
   276  	accessor, err := Accessor(obj)
   277  	if err != nil {
   278  		return "", err
   279  	}
   280  	return accessor.GetUID(), nil
   281  }
   282  
   283  func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
   284  	accessor, err := Accessor(obj)
   285  	if err != nil {
   286  		return err
   287  	}
   288  	accessor.SetUID(uid)
   289  	return nil
   290  }
   291  
   292  func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
   293  	accessor, err := CommonAccessor(obj)
   294  	if err != nil {
   295  		return "", err
   296  	}
   297  	return accessor.GetSelfLink(), nil
   298  }
   299  
   300  func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
   301  	accessor, err := CommonAccessor(obj)
   302  	if err != nil {
   303  		return err
   304  	}
   305  	accessor.SetSelfLink(selfLink)
   306  	return nil
   307  }
   308  
   309  func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) {
   310  	accessor, err := Accessor(obj)
   311  	if err != nil {
   312  		return nil, err
   313  	}
   314  	return accessor.GetLabels(), nil
   315  }
   316  
   317  func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error {
   318  	accessor, err := Accessor(obj)
   319  	if err != nil {
   320  		return err
   321  	}
   322  	accessor.SetLabels(labels)
   323  	return nil
   324  }
   325  
   326  func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, error) {
   327  	accessor, err := Accessor(obj)
   328  	if err != nil {
   329  		return nil, err
   330  	}
   331  	return accessor.GetAnnotations(), nil
   332  }
   333  
   334  func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error {
   335  	accessor, err := Accessor(obj)
   336  	if err != nil {
   337  		return err
   338  	}
   339  	accessor.SetAnnotations(annotations)
   340  	return nil
   341  }
   342  
   343  func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
   344  	accessor, err := CommonAccessor(obj)
   345  	if err != nil {
   346  		return "", err
   347  	}
   348  	return accessor.GetResourceVersion(), nil
   349  }
   350  
   351  func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
   352  	accessor, err := CommonAccessor(obj)
   353  	if err != nil {
   354  		return err
   355  	}
   356  	accessor.SetResourceVersion(version)
   357  	return nil
   358  }
   359  
   360  func (resourceAccessor) Continue(obj runtime.Object) (string, error) {
   361  	accessor, err := ListAccessor(obj)
   362  	if err != nil {
   363  		return "", err
   364  	}
   365  	return accessor.GetContinue(), nil
   366  }
   367  
   368  func (resourceAccessor) SetContinue(obj runtime.Object, version string) error {
   369  	accessor, err := ListAccessor(obj)
   370  	if err != nil {
   371  		return err
   372  	}
   373  	accessor.SetContinue(version)
   374  	return nil
   375  }
   376  
   377  // extractFromOwnerReference extracts v to o. v is the OwnerReferences field of an object.
   378  func extractFromOwnerReference(v reflect.Value, o *metav1.OwnerReference) error {
   379  	if err := runtime.Field(v, "APIVersion", &o.APIVersion); err != nil {
   380  		return err
   381  	}
   382  	if err := runtime.Field(v, "Kind", &o.Kind); err != nil {
   383  		return err
   384  	}
   385  	if err := runtime.Field(v, "Name", &o.Name); err != nil {
   386  		return err
   387  	}
   388  	if err := runtime.Field(v, "UID", &o.UID); err != nil {
   389  		return err
   390  	}
   391  	var controllerPtr *bool
   392  	if err := runtime.Field(v, "Controller", &controllerPtr); err != nil {
   393  		return err
   394  	}
   395  	if controllerPtr != nil {
   396  		controller := *controllerPtr
   397  		o.Controller = &controller
   398  	}
   399  	var blockOwnerDeletionPtr *bool
   400  	if err := runtime.Field(v, "BlockOwnerDeletion", &blockOwnerDeletionPtr); err != nil {
   401  		return err
   402  	}
   403  	if blockOwnerDeletionPtr != nil {
   404  		block := *blockOwnerDeletionPtr
   405  		o.BlockOwnerDeletion = &block
   406  	}
   407  	return nil
   408  }
   409  
   410  // setOwnerReference sets v to o. v is the OwnerReferences field of an object.
   411  func setOwnerReference(v reflect.Value, o *metav1.OwnerReference) error {
   412  	if err := runtime.SetField(o.APIVersion, v, "APIVersion"); err != nil {
   413  		return err
   414  	}
   415  	if err := runtime.SetField(o.Kind, v, "Kind"); err != nil {
   416  		return err
   417  	}
   418  	if err := runtime.SetField(o.Name, v, "Name"); err != nil {
   419  		return err
   420  	}
   421  	if err := runtime.SetField(o.UID, v, "UID"); err != nil {
   422  		return err
   423  	}
   424  	if o.Controller != nil {
   425  		controller := *(o.Controller)
   426  		if err := runtime.SetField(&controller, v, "Controller"); err != nil {
   427  			return err
   428  		}
   429  	}
   430  	if o.BlockOwnerDeletion != nil {
   431  		block := *(o.BlockOwnerDeletion)
   432  		if err := runtime.SetField(&block, v, "BlockOwnerDeletion"); err != nil {
   433  			return err
   434  		}
   435  	}
   436  	return nil
   437  }
   438  
   439  // genericAccessor contains pointers to strings that can modify an arbitrary
   440  // struct and implements the Accessor interface.
   441  type genericAccessor struct {
   442  	namespace         *string
   443  	name              *string
   444  	generateName      *string
   445  	uid               *types.UID
   446  	apiVersion        *string
   447  	kind              *string
   448  	resourceVersion   *string
   449  	selfLink          *string
   450  	creationTimestamp *metav1.Time
   451  	deletionTimestamp **metav1.Time
   452  	labels            *map[string]string
   453  	annotations       *map[string]string
   454  	ownerReferences   reflect.Value
   455  	finalizers        *[]string
   456  }
   457  
   458  func (a genericAccessor) GetNamespace() string {
   459  	if a.namespace == nil {
   460  		return ""
   461  	}
   462  	return *a.namespace
   463  }
   464  
   465  func (a genericAccessor) SetNamespace(namespace string) {
   466  	if a.namespace == nil {
   467  		return
   468  	}
   469  	*a.namespace = namespace
   470  }
   471  
   472  func (a genericAccessor) GetName() string {
   473  	if a.name == nil {
   474  		return ""
   475  	}
   476  	return *a.name
   477  }
   478  
   479  func (a genericAccessor) SetName(name string) {
   480  	if a.name == nil {
   481  		return
   482  	}
   483  	*a.name = name
   484  }
   485  
   486  func (a genericAccessor) GetGenerateName() string {
   487  	if a.generateName == nil {
   488  		return ""
   489  	}
   490  	return *a.generateName
   491  }
   492  
   493  func (a genericAccessor) SetGenerateName(generateName string) {
   494  	if a.generateName == nil {
   495  		return
   496  	}
   497  	*a.generateName = generateName
   498  }
   499  
   500  func (a genericAccessor) GetUID() types.UID {
   501  	if a.uid == nil {
   502  		return ""
   503  	}
   504  	return *a.uid
   505  }
   506  
   507  func (a genericAccessor) SetUID(uid types.UID) {
   508  	if a.uid == nil {
   509  		return
   510  	}
   511  	*a.uid = uid
   512  }
   513  
   514  func (a genericAccessor) GetAPIVersion() string {
   515  	return *a.apiVersion
   516  }
   517  
   518  func (a genericAccessor) SetAPIVersion(version string) {
   519  	*a.apiVersion = version
   520  }
   521  
   522  func (a genericAccessor) GetKind() string {
   523  	return *a.kind
   524  }
   525  
   526  func (a genericAccessor) SetKind(kind string) {
   527  	*a.kind = kind
   528  }
   529  
   530  func (a genericAccessor) GetResourceVersion() string {
   531  	return *a.resourceVersion
   532  }
   533  
   534  func (a genericAccessor) SetResourceVersion(version string) {
   535  	*a.resourceVersion = version
   536  }
   537  
   538  func (a genericAccessor) GetSelfLink() string {
   539  	return *a.selfLink
   540  }
   541  
   542  func (a genericAccessor) SetSelfLink(selfLink string) {
   543  	*a.selfLink = selfLink
   544  }
   545  
   546  func (a genericAccessor) GetCreationTimestamp() metav1.Time {
   547  	return *a.creationTimestamp
   548  }
   549  
   550  func (a genericAccessor) SetCreationTimestamp(timestamp metav1.Time) {
   551  	*a.creationTimestamp = timestamp
   552  }
   553  
   554  func (a genericAccessor) GetDeletionTimestamp() *metav1.Time {
   555  	return *a.deletionTimestamp
   556  }
   557  
   558  func (a genericAccessor) SetDeletionTimestamp(timestamp *metav1.Time) {
   559  	*a.deletionTimestamp = timestamp
   560  }
   561  
   562  func (a genericAccessor) GetLabels() map[string]string {
   563  	if a.labels == nil {
   564  		return nil
   565  	}
   566  	return *a.labels
   567  }
   568  
   569  func (a genericAccessor) SetLabels(labels map[string]string) {
   570  	*a.labels = labels
   571  }
   572  
   573  func (a genericAccessor) GetAnnotations() map[string]string {
   574  	if a.annotations == nil {
   575  		return nil
   576  	}
   577  	return *a.annotations
   578  }
   579  
   580  func (a genericAccessor) SetAnnotations(annotations map[string]string) {
   581  	if a.annotations == nil {
   582  		emptyAnnotations := make(map[string]string)
   583  		a.annotations = &emptyAnnotations
   584  	}
   585  	*a.annotations = annotations
   586  }
   587  
   588  func (a genericAccessor) GetFinalizers() []string {
   589  	if a.finalizers == nil {
   590  		return nil
   591  	}
   592  	return *a.finalizers
   593  }
   594  
   595  func (a genericAccessor) SetFinalizers(finalizers []string) {
   596  	*a.finalizers = finalizers
   597  }
   598  
   599  func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference {
   600  	var ret []metav1.OwnerReference
   601  	s := a.ownerReferences
   602  	if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice {
   603  		klog.Errorf("expect %v to be a pointer to slice", s)
   604  		return ret
   605  	}
   606  	s = s.Elem()
   607  	// Set the capacity to one element greater to avoid copy if the caller later append an element.
   608  	ret = make([]metav1.OwnerReference, s.Len(), s.Len()+1)
   609  	for i := 0; i < s.Len(); i++ {
   610  		if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil {
   611  			klog.Errorf("extractFromOwnerReference failed: %v", err)
   612  			return ret
   613  		}
   614  	}
   615  	return ret
   616  }
   617  
   618  func (a genericAccessor) SetOwnerReferences(references []metav1.OwnerReference) {
   619  	s := a.ownerReferences
   620  	if s.Kind() != reflect.Pointer || s.Elem().Kind() != reflect.Slice {
   621  		klog.Errorf("expect %v to be a pointer to slice", s)
   622  	}
   623  	s = s.Elem()
   624  	newReferences := reflect.MakeSlice(s.Type(), len(references), len(references))
   625  	for i := 0; i < len(references); i++ {
   626  		if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil {
   627  			klog.Errorf("setOwnerReference failed: %v", err)
   628  			return
   629  		}
   630  	}
   631  	s.Set(newReferences)
   632  }
   633  
   634  // extractFromTypeMeta extracts pointers to version and kind fields from an object
   635  func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error {
   636  	if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil {
   637  		return err
   638  	}
   639  	if err := runtime.FieldPtr(v, "Kind", &a.kind); err != nil {
   640  		return err
   641  	}
   642  	return nil
   643  }