mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-29 08:20:20 +00:00
116 lines
3.8 KiB
Go
116 lines
3.8 KiB
Go
|
/*
|
||
|
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 util
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// [DEPRECATED] ToCanonicalName converts Golang package/type canonical name into REST friendly OpenAPI name.
|
||
|
// This method is deprecated because it has a misleading name. Please use ToRESTFriendlyName
|
||
|
// instead
|
||
|
//
|
||
|
// NOTE: actually the "canonical name" in this method should be named "REST friendly OpenAPI name",
|
||
|
// which is different from "canonical name" defined in GetCanonicalTypeName. The "canonical name" defined
|
||
|
// in GetCanonicalTypeName means Go type names with full package path.
|
||
|
//
|
||
|
// Examples of REST friendly OpenAPI name:
|
||
|
//
|
||
|
// Input: k8s.io/api/core/v1.Pod
|
||
|
// Output: io.k8s.api.core.v1.Pod
|
||
|
//
|
||
|
// Input: k8s.io/api/core/v1
|
||
|
// Output: io.k8s.api.core.v1
|
||
|
//
|
||
|
// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo
|
||
|
// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo
|
||
|
func ToCanonicalName(name string) string {
|
||
|
return ToRESTFriendlyName(name)
|
||
|
}
|
||
|
|
||
|
// ToRESTFriendlyName converts Golang package/type canonical name into REST friendly OpenAPI name.
|
||
|
//
|
||
|
// Examples of REST friendly OpenAPI name:
|
||
|
//
|
||
|
// Input: k8s.io/api/core/v1.Pod
|
||
|
// Output: io.k8s.api.core.v1.Pod
|
||
|
//
|
||
|
// Input: k8s.io/api/core/v1
|
||
|
// Output: io.k8s.api.core.v1
|
||
|
//
|
||
|
// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo
|
||
|
// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo
|
||
|
func ToRESTFriendlyName(name string) string {
|
||
|
nameParts := strings.Split(name, "/")
|
||
|
// Reverse first part. e.g., io.k8s... instead of k8s.io...
|
||
|
if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") {
|
||
|
parts := strings.Split(nameParts[0], ".")
|
||
|
for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 {
|
||
|
parts[i], parts[j] = parts[j], parts[i]
|
||
|
}
|
||
|
nameParts[0] = strings.Join(parts, ".")
|
||
|
}
|
||
|
return strings.Join(nameParts, ".")
|
||
|
}
|
||
|
|
||
|
// OpenAPICanonicalTypeNamer is an interface for models without Go type to seed model name.
|
||
|
//
|
||
|
// OpenAPI canonical names are Go type names with full package path, for uniquely indentifying
|
||
|
// a model / Go type. If a Go type is vendored from another package, only the path after "/vendor/"
|
||
|
// should be used. For custom resource definition (CRD), the canonical name is expected to be
|
||
|
//
|
||
|
// group/version.kind
|
||
|
//
|
||
|
// Examples of canonical name:
|
||
|
//
|
||
|
// Go type: k8s.io/kubernetes/pkg/apis/core.Pod
|
||
|
// CRD: csi.storage.k8s.io/v1alpha1.CSINodeInfo
|
||
|
//
|
||
|
// Example for vendored Go type:
|
||
|
//
|
||
|
// Original full path: k8s.io/kubernetes/vendor/k8s.io/api/core/v1.Pod
|
||
|
// Canonical name: k8s.io/api/core/v1.Pod
|
||
|
//
|
||
|
// Original full path: vendor/k8s.io/api/core/v1.Pod
|
||
|
// Canonical name: k8s.io/api/core/v1.Pod
|
||
|
type OpenAPICanonicalTypeNamer interface {
|
||
|
OpenAPICanonicalTypeName() string
|
||
|
}
|
||
|
|
||
|
// GetCanonicalTypeName will find the canonical type name of a sample object, removing
|
||
|
// the "vendor" part of the path
|
||
|
func GetCanonicalTypeName(model interface{}) string {
|
||
|
if namer, ok := model.(OpenAPICanonicalTypeNamer); ok {
|
||
|
return namer.OpenAPICanonicalTypeName()
|
||
|
}
|
||
|
t := reflect.TypeOf(model)
|
||
|
if t.Kind() == reflect.Ptr {
|
||
|
t = t.Elem()
|
||
|
}
|
||
|
if t.PkgPath() == "" {
|
||
|
return t.Name()
|
||
|
}
|
||
|
path := t.PkgPath()
|
||
|
if strings.Contains(path, "/vendor/") {
|
||
|
path = path[strings.Index(path, "/vendor/")+len("/vendor/"):]
|
||
|
} else if strings.HasPrefix(path, "vendor/") {
|
||
|
path = strings.TrimPrefix(path, "vendor/")
|
||
|
}
|
||
|
return path + "." + t.Name()
|
||
|
}
|