...

Source file src/k8s.io/kube-openapi/pkg/util/util.go

Documentation: k8s.io/kube-openapi/pkg/util

     1  /*
     2  Copyright 2017 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 util
    18  
    19  import (
    20  	"reflect"
    21  	"strings"
    22  )
    23  
    24  // [DEPRECATED] ToCanonicalName converts Golang package/type canonical name into REST friendly OpenAPI name.
    25  // This method is deprecated because it has a misleading name. Please use ToRESTFriendlyName
    26  // instead
    27  //
    28  // NOTE: actually the "canonical name" in this method should be named "REST friendly OpenAPI name",
    29  // which is different from "canonical name" defined in GetCanonicalTypeName. The "canonical name" defined
    30  // in GetCanonicalTypeName means Go type names with full package path.
    31  //
    32  // Examples of REST friendly OpenAPI name:
    33  //
    34  //	Input:  k8s.io/api/core/v1.Pod
    35  //	Output: io.k8s.api.core.v1.Pod
    36  //
    37  //	Input:  k8s.io/api/core/v1
    38  //	Output: io.k8s.api.core.v1
    39  //
    40  //	Input:  csi.storage.k8s.io/v1alpha1.CSINodeInfo
    41  //	Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo
    42  func ToCanonicalName(name string) string {
    43  	return ToRESTFriendlyName(name)
    44  }
    45  
    46  // ToRESTFriendlyName converts Golang package/type canonical name into REST friendly OpenAPI name.
    47  //
    48  // Examples of REST friendly OpenAPI name:
    49  //
    50  //	Input:  k8s.io/api/core/v1.Pod
    51  //	Output: io.k8s.api.core.v1.Pod
    52  //
    53  //	Input:  k8s.io/api/core/v1
    54  //	Output: io.k8s.api.core.v1
    55  //
    56  //	Input:  csi.storage.k8s.io/v1alpha1.CSINodeInfo
    57  //	Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo
    58  func ToRESTFriendlyName(name string) string {
    59  	nameParts := strings.Split(name, "/")
    60  	// Reverse first part. e.g., io.k8s... instead of k8s.io...
    61  	if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") {
    62  		parts := strings.Split(nameParts[0], ".")
    63  		for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 {
    64  			parts[i], parts[j] = parts[j], parts[i]
    65  		}
    66  		nameParts[0] = strings.Join(parts, ".")
    67  	}
    68  	return strings.Join(nameParts, ".")
    69  }
    70  
    71  // OpenAPICanonicalTypeNamer is an interface for models without Go type to seed model name.
    72  //
    73  // OpenAPI canonical names are Go type names with full package path, for uniquely indentifying
    74  // a model / Go type. If a Go type is vendored from another package, only the path after "/vendor/"
    75  // should be used. For custom resource definition (CRD), the canonical name is expected to be
    76  //
    77  //	group/version.kind
    78  //
    79  // Examples of canonical name:
    80  //
    81  //	Go type: k8s.io/kubernetes/pkg/apis/core.Pod
    82  //	CRD:     csi.storage.k8s.io/v1alpha1.CSINodeInfo
    83  //
    84  // Example for vendored Go type:
    85  //
    86  //	Original full path:  k8s.io/kubernetes/vendor/k8s.io/api/core/v1.Pod
    87  //	Canonical name:      k8s.io/api/core/v1.Pod
    88  //
    89  //	Original full path:  vendor/k8s.io/api/core/v1.Pod
    90  //	Canonical name:      k8s.io/api/core/v1.Pod
    91  type OpenAPICanonicalTypeNamer interface {
    92  	OpenAPICanonicalTypeName() string
    93  }
    94  
    95  // GetCanonicalTypeName will find the canonical type name of a sample object, removing
    96  // the "vendor" part of the path
    97  func GetCanonicalTypeName(model interface{}) string {
    98  	if namer, ok := model.(OpenAPICanonicalTypeNamer); ok {
    99  		return namer.OpenAPICanonicalTypeName()
   100  	}
   101  	t := reflect.TypeOf(model)
   102  	if t.Kind() == reflect.Ptr {
   103  		t = t.Elem()
   104  	}
   105  	if t.PkgPath() == "" {
   106  		return t.Name()
   107  	}
   108  	path := t.PkgPath()
   109  	if strings.Contains(path, "/vendor/") {
   110  		path = path[strings.Index(path, "/vendor/")+len("/vendor/"):]
   111  	} else if strings.HasPrefix(path, "vendor/") {
   112  		path = strings.TrimPrefix(path, "vendor/")
   113  	}
   114  	return path + "." + t.Name()
   115  }
   116  

View as plain text