123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- /*
- Copyright 2018 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 (
- "fmt"
- "reflect"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/runtime/schema"
- "k8s.io/client-go/dynamic"
- )
- // CRDGetter is a function that can download the list of GVK for all
- // CRDs.
- type CRDGetter func() ([]schema.GroupKind, error)
- func CRDFromDynamic(client dynamic.Interface) CRDGetter {
- return func() ([]schema.GroupKind, error) {
- list, err := client.Resource(schema.GroupVersionResource{
- Group: "apiextensions.k8s.io",
- Version: "v1beta1",
- Resource: "customresourcedefinitions",
- }).List(metav1.ListOptions{})
- if err != nil {
- return nil, fmt.Errorf("failed to list CRDs: %v", err)
- }
- if list == nil {
- return nil, nil
- }
- gks := []schema.GroupKind{}
- // We need to parse the list to get the gvk, I guess that's fine.
- for _, crd := range (*list).Items {
- // Look for group, version, and kind
- group, _, _ := unstructured.NestedString(crd.Object, "spec", "group")
- kind, _, _ := unstructured.NestedString(crd.Object, "spec", "names", "kind")
- gks = append(gks, schema.GroupKind{
- Group: group,
- Kind: kind,
- })
- }
- return gks, nil
- }
- }
- // CRDFinder keeps a cache of known CRDs and finds a given GVK in the
- // list.
- type CRDFinder interface {
- HasCRD(gvk schema.GroupKind) (bool, error)
- }
- func NewCRDFinder(getter CRDGetter) CRDFinder {
- return &crdFinder{
- getter: getter,
- }
- }
- type crdFinder struct {
- getter CRDGetter
- cache *[]schema.GroupKind
- }
- func (f *crdFinder) cacheCRDs() error {
- if f.cache != nil {
- return nil
- }
- list, err := f.getter()
- if err != nil {
- return err
- }
- f.cache = &list
- return nil
- }
- func (f *crdFinder) findCRD(gvk schema.GroupKind) bool {
- for _, crd := range *f.cache {
- if reflect.DeepEqual(gvk, crd) {
- return true
- }
- }
- return false
- }
- func (f *crdFinder) HasCRD(gvk schema.GroupKind) (bool, error) {
- if err := f.cacheCRDs(); err != nil {
- return false, err
- }
- return f.findCRD(gvk), nil
- }
|