mirror of https://github.com/knative/client.git
149 lines
4.3 KiB
Go
149 lines
4.3 KiB
Go
// Copyright © 2019 The Knative 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 dynamic
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
)
|
|
|
|
// gvrFromUnstructured takes a unstructured object of CRD type and finds GVR from its spec
|
|
func gvrFromUnstructured(u *unstructured.Unstructured) (gvr schema.GroupVersionResource, err error) {
|
|
group, err := groupFromUnstructured(u)
|
|
if err != nil {
|
|
return gvr, err
|
|
}
|
|
|
|
version, err := versionFromUnstructured(u)
|
|
if err != nil {
|
|
return gvr, err
|
|
}
|
|
|
|
resource, err := resourceFromUnstructured(u)
|
|
if err != nil {
|
|
return gvr, err
|
|
}
|
|
|
|
return schema.GroupVersionResource{
|
|
Group: group,
|
|
Version: version,
|
|
Resource: resource,
|
|
}, nil
|
|
}
|
|
|
|
func groupFromUnstructured(u *unstructured.Unstructured) (string, error) {
|
|
content := u.UnstructuredContent()
|
|
group, found, err := unstructured.NestedString(content, "spec", "group")
|
|
if err != nil || !found {
|
|
return "", fmt.Errorf("can't find group for source GVR: %w", err)
|
|
}
|
|
return group, nil
|
|
}
|
|
|
|
func versionFromUnstructured(u *unstructured.Unstructured) (version string, err error) {
|
|
content := u.UnstructuredContent()
|
|
versions, found, err := unstructured.NestedSlice(content, "spec", "versions")
|
|
if err != nil || !found || len(versions) == 0 {
|
|
// fallback to .spec.version
|
|
version, found, err = unstructured.NestedString(content, "spec", "version")
|
|
if err != nil || !found {
|
|
return version, fmt.Errorf("can't find version for source GVR: %w", err)
|
|
}
|
|
} else {
|
|
for _, v := range versions {
|
|
if vmap, ok := v.(map[string]interface{}); ok {
|
|
// find the version name which is being served
|
|
if vmap["served"] == true {
|
|
version = vmap["name"].(string)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// if we could find the version at all
|
|
if version == "" {
|
|
err = fmt.Errorf("can't find version for source GVR")
|
|
}
|
|
return version, err
|
|
}
|
|
|
|
func resourceFromUnstructured(u *unstructured.Unstructured) (string, error) {
|
|
content := u.UnstructuredContent()
|
|
resource, found, err := unstructured.NestedString(content, "spec", "names", "plural")
|
|
if err != nil || !found {
|
|
return "", fmt.Errorf("can't find resource for source GVR: %w", err)
|
|
}
|
|
return resource, nil
|
|
}
|
|
|
|
func kindFromUnstructured(u *unstructured.Unstructured) (string, error) {
|
|
content := u.UnstructuredContent()
|
|
kind, found, err := unstructured.NestedString(content, "spec", "names", "kind")
|
|
if !found || err != nil {
|
|
return "", fmt.Errorf("can't find source kind from source CRD: %w", err)
|
|
}
|
|
return kind, nil
|
|
}
|
|
|
|
// TypesFilter for keeping list of sources types to filter upo
|
|
type TypesFilter []string
|
|
|
|
// WithType function for easy filtering on source types
|
|
type WithType func(filters *TypesFilter)
|
|
|
|
// WithTypes for recording the source type filtering function WithType
|
|
type WithTypes []WithType
|
|
|
|
// WithTypeFilter can be used to filter based on source type name
|
|
func WithTypeFilter(name string) WithType {
|
|
return func(filters *TypesFilter) {
|
|
*filters = append(*filters, name)
|
|
}
|
|
}
|
|
|
|
// List returns the source type name list recorded via WithTypeFilter
|
|
func (types WithTypes) List() []string {
|
|
var stypes TypesFilter
|
|
for _, f := range types {
|
|
f(&stypes)
|
|
}
|
|
return stypes
|
|
}
|
|
|
|
// UnstructuredCRDFromGVK constructs an unstructured object using the given GVK
|
|
func UnstructuredCRDFromGVK(gvk schema.GroupVersionKind) *unstructured.Unstructured {
|
|
name := fmt.Sprintf("%ss.%s", strings.ToLower(gvk.Kind), gvk.Group)
|
|
plural := fmt.Sprintf("%ss", strings.ToLower(gvk.Kind))
|
|
u := &unstructured.Unstructured{}
|
|
u.SetUnstructuredContent(map[string]interface{}{
|
|
"metadata": map[string]interface{}{
|
|
"name": name,
|
|
},
|
|
"spec": map[string]interface{}{
|
|
"group": gvk.Group,
|
|
"version": gvk.Version,
|
|
"names": map[string]interface{}{
|
|
"kind": gvk.Kind,
|
|
"plural": plural,
|
|
},
|
|
},
|
|
})
|
|
|
|
return u
|
|
}
|