mirror of https://github.com/fluxcd/cli-utils.git
182 lines
4.4 KiB
Go
182 lines
4.4 KiB
Go
// Copyright 2020 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package customprovider
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/kubectl/pkg/cmd/util"
|
|
"sigs.k8s.io/cli-utils/pkg/apis/actuation"
|
|
"sigs.k8s.io/cli-utils/pkg/common"
|
|
"sigs.k8s.io/cli-utils/pkg/inventory"
|
|
"sigs.k8s.io/cli-utils/pkg/object"
|
|
)
|
|
|
|
var InventoryCRD = []byte(strings.TrimSpace(`
|
|
apiVersion: apiextensions.k8s.io/v1
|
|
kind: CustomResourceDefinition
|
|
metadata:
|
|
name: inventories.cli-utils.example.io
|
|
spec:
|
|
conversion:
|
|
strategy: None
|
|
group: cli-utils.example.io
|
|
names:
|
|
kind: Inventory
|
|
listKind: InventoryList
|
|
plural: inventories
|
|
singular: inventory
|
|
scope: Namespaced
|
|
versions:
|
|
- name: v1alpha1
|
|
schema:
|
|
openAPIV3Schema:
|
|
description: Example for cli-utils e2e tests
|
|
properties:
|
|
apiVersion:
|
|
type: string
|
|
kind:
|
|
type: string
|
|
metadata:
|
|
type: object
|
|
spec:
|
|
properties:
|
|
inventory:
|
|
items:
|
|
properties:
|
|
group:
|
|
type: string
|
|
kind:
|
|
type: string
|
|
name:
|
|
type: string
|
|
namespace:
|
|
type: string
|
|
required:
|
|
- group
|
|
- kind
|
|
- name
|
|
- namespace
|
|
type: object
|
|
type: array
|
|
type: object
|
|
type: object
|
|
served: true
|
|
storage: true
|
|
subresources: {}
|
|
`))
|
|
|
|
var InventoryGVK = schema.GroupVersionKind{
|
|
Group: "cli-utils.example.io",
|
|
Version: "v1alpha1",
|
|
Kind: "Inventory",
|
|
}
|
|
|
|
var _ inventory.ClientFactory = CustomClientFactory{}
|
|
|
|
type CustomClientFactory struct {
|
|
}
|
|
|
|
func (CustomClientFactory) NewClient(factory util.Factory) (inventory.Client, error) {
|
|
// TODO: add status to custom inventory crd and enable StatusPolicyAll
|
|
return inventory.NewClient(factory,
|
|
WrapInventoryObj, invToUnstructuredFunc, inventory.StatusPolicyNone)
|
|
}
|
|
|
|
func invToUnstructuredFunc(inv inventory.Info) *unstructured.Unstructured {
|
|
switch invInfo := inv.(type) {
|
|
case *InventoryCustomType:
|
|
return invInfo.inv
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func WrapInventoryObj(obj *unstructured.Unstructured) inventory.Storage {
|
|
return &InventoryCustomType{inv: obj}
|
|
}
|
|
|
|
func WrapInventoryInfoObj(obj *unstructured.Unstructured) inventory.Info {
|
|
return &InventoryCustomType{inv: obj}
|
|
}
|
|
|
|
var _ inventory.Storage = &InventoryCustomType{}
|
|
var _ inventory.Info = &InventoryCustomType{}
|
|
|
|
type InventoryCustomType struct {
|
|
inv *unstructured.Unstructured
|
|
}
|
|
|
|
func (i InventoryCustomType) Namespace() string {
|
|
return i.inv.GetNamespace()
|
|
}
|
|
|
|
func (i InventoryCustomType) Name() string {
|
|
return i.inv.GetName()
|
|
}
|
|
|
|
func (i InventoryCustomType) Strategy() inventory.Strategy {
|
|
return inventory.NameStrategy
|
|
}
|
|
|
|
func (i InventoryCustomType) ID() string {
|
|
labels := i.inv.GetLabels()
|
|
id, found := labels[common.InventoryLabel]
|
|
if !found {
|
|
return ""
|
|
}
|
|
return id
|
|
}
|
|
|
|
func (i InventoryCustomType) Load() (object.ObjMetadataSet, error) {
|
|
var inv object.ObjMetadataSet
|
|
s, found, err := unstructured.NestedSlice(i.inv.Object, "spec", "inventory")
|
|
if err != nil {
|
|
return inv, err
|
|
}
|
|
if !found {
|
|
return inv, nil
|
|
}
|
|
for _, item := range s {
|
|
m := item.(map[string]interface{})
|
|
namespace, _, _ := unstructured.NestedString(m, "namespace")
|
|
name, _, _ := unstructured.NestedString(m, "name")
|
|
group, _, _ := unstructured.NestedString(m, "group")
|
|
kind, _, _ := unstructured.NestedString(m, "kind")
|
|
id := object.ObjMetadata{
|
|
Namespace: namespace,
|
|
Name: name,
|
|
GroupKind: schema.GroupKind{
|
|
Group: group,
|
|
Kind: kind,
|
|
},
|
|
}
|
|
inv = append(inv, id)
|
|
}
|
|
return inv, nil
|
|
}
|
|
|
|
func (i InventoryCustomType) Store(objs object.ObjMetadataSet, _ []actuation.ObjectStatus) error {
|
|
var inv []interface{}
|
|
for _, obj := range objs {
|
|
inv = append(inv, map[string]interface{}{
|
|
"group": obj.GroupKind.Group,
|
|
"kind": obj.GroupKind.Kind,
|
|
"namespace": obj.Namespace,
|
|
"name": obj.Name,
|
|
})
|
|
}
|
|
if len(inv) > 0 {
|
|
return unstructured.SetNestedSlice(i.inv.Object, inv, "spec", "inventory")
|
|
}
|
|
unstructured.RemoveNestedField(i.inv.Object, "spec")
|
|
return nil
|
|
}
|
|
|
|
func (i InventoryCustomType) GetObject() (*unstructured.Unstructured, error) {
|
|
return i.inv, nil
|
|
}
|