mirror of https://github.com/fluxcd/cli-utils.git
598 lines
18 KiB
Go
598 lines
18 KiB
Go
// Copyright 2020 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package inventory
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/cli-runtime/pkg/resource"
|
|
clienttesting "k8s.io/client-go/testing"
|
|
cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
|
|
"sigs.k8s.io/cli-utils/pkg/apis/actuation"
|
|
"sigs.k8s.io/cli-utils/pkg/common"
|
|
"sigs.k8s.io/cli-utils/pkg/object"
|
|
)
|
|
|
|
func podStatus(info *resource.Info) actuation.ObjectStatus {
|
|
return actuation.ObjectStatus{
|
|
ObjectReference: ObjectReferenceFromObjMetadata(ignoreErrInfoToObjMeta(info)),
|
|
Strategy: actuation.ActuationStrategyApply,
|
|
Actuation: actuation.ActuationSucceeded,
|
|
Reconcile: actuation.ReconcileSucceeded,
|
|
}
|
|
}
|
|
|
|
func podData(name string) map[string]string {
|
|
return map[string]string{
|
|
fmt.Sprintf("test-inventory-namespace_%s__Pod", name): "{\"actuation\":\"Succeeded\",\"reconcile\":\"Succeeded\",\"strategy\":\"Apply\"}",
|
|
}
|
|
}
|
|
|
|
func podDataNoStatus(name string) map[string]string {
|
|
return map[string]string{
|
|
fmt.Sprintf("test-inventory-namespace_%s__Pod", name): "",
|
|
}
|
|
}
|
|
|
|
func TestGetClusterInventoryInfo(t *testing.T) {
|
|
tests := map[string]struct {
|
|
statusPolicy StatusPolicy
|
|
inv Info
|
|
localObjs object.ObjMetadataSet
|
|
objStatus []actuation.ObjectStatus
|
|
isError bool
|
|
}{
|
|
"Nil local inventory object is an error": {
|
|
inv: nil,
|
|
localObjs: object.ObjMetadataSet{},
|
|
isError: true,
|
|
},
|
|
"Empty local inventory object": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{},
|
|
isError: false,
|
|
},
|
|
"Local inventory with a single object": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
},
|
|
objStatus: []actuation.ObjectStatus{podStatus(pod2Info)},
|
|
isError: false,
|
|
},
|
|
"Local inventory with multiple objects": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
ignoreErrInfoToObjMeta(pod3Info)},
|
|
objStatus: []actuation.ObjectStatus{
|
|
podStatus(pod1Info),
|
|
podStatus(pod2Info),
|
|
podStatus(pod3Info),
|
|
},
|
|
isError: false,
|
|
},
|
|
}
|
|
|
|
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
|
|
defer tf.Cleanup()
|
|
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, tc.statusPolicy, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
|
|
var inv *unstructured.Unstructured
|
|
if tc.inv != nil {
|
|
inv = storeObjsInInventory(tc.inv, tc.localObjs, tc.objStatus)
|
|
}
|
|
clusterInv, err := invClient.GetClusterInventoryInfo(WrapInventoryInfoObj(inv))
|
|
if tc.isError {
|
|
if err == nil {
|
|
t.Fatalf("expected error but received none")
|
|
}
|
|
return
|
|
}
|
|
if !tc.isError && err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
if clusterInv != nil {
|
|
wrapped := WrapInventoryObj(clusterInv)
|
|
clusterObjs, err := wrapped.Load()
|
|
if err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
if !tc.localObjs.Equal(clusterObjs) {
|
|
t.Fatalf("expected cluster objs (%v), got (%v)", tc.localObjs, clusterObjs)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMerge(t *testing.T) {
|
|
tests := map[string]struct {
|
|
statusPolicy StatusPolicy
|
|
localInv Info
|
|
localObjs object.ObjMetadataSet
|
|
clusterObjs object.ObjMetadataSet
|
|
pruneObjs object.ObjMetadataSet
|
|
isError bool
|
|
}{
|
|
"Nil local inventory object is error": {
|
|
localInv: nil,
|
|
localObjs: object.ObjMetadataSet{},
|
|
clusterObjs: object.ObjMetadataSet{},
|
|
pruneObjs: object.ObjMetadataSet{},
|
|
isError: true,
|
|
statusPolicy: StatusPolicyAll,
|
|
},
|
|
"Cluster and local inventories empty: no prune objects; no change": {
|
|
localInv: copyInventory(),
|
|
localObjs: object.ObjMetadataSet{},
|
|
clusterObjs: object.ObjMetadataSet{},
|
|
pruneObjs: object.ObjMetadataSet{},
|
|
isError: false,
|
|
statusPolicy: StatusPolicyAll,
|
|
},
|
|
"Cluster and local inventories same: no prune objects; no change": {
|
|
localInv: copyInventory(),
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
},
|
|
clusterObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
},
|
|
pruneObjs: object.ObjMetadataSet{},
|
|
isError: false,
|
|
statusPolicy: StatusPolicyAll,
|
|
},
|
|
"Cluster two obj, local one: prune obj": {
|
|
localInv: copyInventory(),
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
},
|
|
clusterObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod3Info),
|
|
},
|
|
pruneObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod3Info),
|
|
},
|
|
statusPolicy: StatusPolicyAll,
|
|
isError: false,
|
|
},
|
|
"Cluster multiple objs, local multiple different objs: prune objs": {
|
|
localInv: copyInventory(),
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
},
|
|
clusterObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
ignoreErrInfoToObjMeta(pod3Info)},
|
|
pruneObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod3Info),
|
|
},
|
|
statusPolicy: StatusPolicyAll,
|
|
isError: false,
|
|
},
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
for i := range common.Strategies {
|
|
drs := common.Strategies[i]
|
|
t.Run(name, func(t *testing.T) {
|
|
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
|
|
defer tf.Cleanup()
|
|
|
|
tf.FakeDynamicClient.PrependReactor("list", "configmaps", toReactionFunc(tc.clusterObjs))
|
|
// Create the local inventory object storing "tc.localObjs"
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, tc.statusPolicy, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
|
|
// Call "Merge" to create the union of clusterObjs and localObjs.
|
|
pruneObjs, err := invClient.Merge(tc.localInv, tc.localObjs, drs)
|
|
if tc.isError {
|
|
if err == nil {
|
|
t.Fatalf("expected error but received none")
|
|
}
|
|
return
|
|
}
|
|
if !tc.isError && err != nil {
|
|
t.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if !tc.pruneObjs.Equal(pruneObjs) {
|
|
t.Errorf("expected (%v) prune objs; got (%v)", tc.pruneObjs, pruneObjs)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCreateInventory(t *testing.T) {
|
|
tests := map[string]struct {
|
|
statusPolicy StatusPolicy
|
|
inv Info
|
|
localObjs object.ObjMetadataSet
|
|
error string
|
|
objStatus []actuation.ObjectStatus
|
|
}{
|
|
"Nil local inventory object is an error": {
|
|
inv: nil,
|
|
localObjs: object.ObjMetadataSet{},
|
|
error: "attempting create a nil inventory object",
|
|
},
|
|
"Empty local inventory object": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{},
|
|
},
|
|
"Local inventory with a single object": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
},
|
|
objStatus: []actuation.ObjectStatus{podStatus(pod2Info)},
|
|
},
|
|
"Local inventory with multiple objects": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
ignoreErrInfoToObjMeta(pod3Info)},
|
|
objStatus: []actuation.ObjectStatus{
|
|
podStatus(pod1Info),
|
|
podStatus(pod2Info),
|
|
podStatus(pod3Info),
|
|
},
|
|
},
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
|
|
defer tf.Cleanup()
|
|
|
|
var storedInventory map[string]string
|
|
tf.FakeDynamicClient.PrependReactor("create", "configmaps", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
|
obj := *action.(clienttesting.CreateAction).GetObject().(*unstructured.Unstructured)
|
|
storedInventory, _, _ = unstructured.NestedStringMap(obj.Object, "data")
|
|
return true, nil, nil
|
|
})
|
|
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, tc.statusPolicy, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
inv := invClient.invToUnstructuredFunc(tc.inv)
|
|
if inv != nil {
|
|
inv = storeObjsInInventory(tc.inv, tc.localObjs, tc.objStatus)
|
|
}
|
|
_, err = invClient.createInventoryObj(inv, common.DryRunNone)
|
|
if tc.error != "" {
|
|
assert.EqualError(t, err, tc.error)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
expectedInventory := tc.localObjs.ToStringMap()
|
|
// handle empty inventories special to avoid problems with empty vs nil maps
|
|
if len(expectedInventory) != 0 || len(storedInventory) != 0 {
|
|
for key := range expectedInventory {
|
|
if _, found := storedInventory[key]; !found {
|
|
t.Errorf("%s not found in the stored inventory", key)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReplace(t *testing.T) {
|
|
tests := map[string]struct {
|
|
statusPolicy StatusPolicy
|
|
localObjs object.ObjMetadataSet
|
|
clusterObjs object.ObjMetadataSet
|
|
objStatus []actuation.ObjectStatus
|
|
data map[string]string
|
|
}{
|
|
"Cluster and local inventories empty": {
|
|
localObjs: object.ObjMetadataSet{},
|
|
clusterObjs: object.ObjMetadataSet{},
|
|
data: map[string]string{},
|
|
},
|
|
"Cluster and local inventories same": {
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
},
|
|
clusterObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
},
|
|
objStatus: []actuation.ObjectStatus{podStatus(pod1Info)},
|
|
data: podData("pod-1"),
|
|
statusPolicy: StatusPolicyAll,
|
|
},
|
|
"Cluster two obj, local one": {
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
},
|
|
clusterObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod3Info),
|
|
},
|
|
objStatus: []actuation.ObjectStatus{podStatus(pod1Info), podStatus(pod3Info)},
|
|
data: podData("pod-1"),
|
|
statusPolicy: StatusPolicyAll,
|
|
},
|
|
"Cluster multiple objs, local multiple different objs": {
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
},
|
|
clusterObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
ignoreErrInfoToObjMeta(pod3Info)},
|
|
objStatus: []actuation.ObjectStatus{podStatus(pod2Info), podStatus(pod1Info), podStatus(pod3Info)},
|
|
data: podData("pod-2"),
|
|
statusPolicy: StatusPolicyAll,
|
|
},
|
|
"Cluster multiple objs, local multiple different objs with StatusPolicyNone": {
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
},
|
|
clusterObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
ignoreErrInfoToObjMeta(pod3Info)},
|
|
objStatus: []actuation.ObjectStatus{podStatus(pod2Info), podStatus(pod1Info), podStatus(pod3Info)},
|
|
data: podDataNoStatus("pod-2"),
|
|
statusPolicy: StatusPolicyNone,
|
|
},
|
|
}
|
|
|
|
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
|
|
defer tf.Cleanup()
|
|
|
|
// Client and server dry-run do not throw errors.
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, StatusPolicyAll, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
err = invClient.Replace(copyInventory(), object.ObjMetadataSet{}, nil, common.DryRunClient)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
err = invClient.Replace(copyInventory(), object.ObjMetadataSet{}, nil, common.DryRunServer)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
// Create inventory client, and store the cluster objs in the inventory object.
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, tc.statusPolicy, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
wrappedInv := invClient.InventoryFactoryFunc(inventoryObj)
|
|
if err := wrappedInv.Store(tc.clusterObjs, tc.objStatus); err != nil {
|
|
t.Fatalf("unexpected error storing inventory objects: %s", err)
|
|
}
|
|
inv, err := wrappedInv.GetObject()
|
|
if err != nil {
|
|
t.Fatalf("unexpected error storing inventory objects: %s", err)
|
|
}
|
|
// Call replaceInventory with the new set of "localObjs"
|
|
inv, _, err = invClient.replaceInventory(inv, tc.localObjs, tc.objStatus)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
wrappedInv = invClient.InventoryFactoryFunc(inv)
|
|
// Validate that the stored objects are now the "localObjs".
|
|
actualObjs, err := wrappedInv.Load()
|
|
if err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
if !tc.localObjs.Equal(actualObjs) {
|
|
t.Errorf("expected objects (%s), got (%s)", tc.localObjs, actualObjs)
|
|
}
|
|
data, _, err := unstructured.NestedStringMap(inv.Object, "data")
|
|
if err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
if diff := cmp.Diff(data, tc.data); diff != "" {
|
|
t.Fatalf(diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetClusterObjs(t *testing.T) {
|
|
tests := map[string]struct {
|
|
statusPolicy StatusPolicy
|
|
localInv Info
|
|
clusterObjs object.ObjMetadataSet
|
|
isError bool
|
|
}{
|
|
"Nil cluster inventory is error": {
|
|
localInv: nil,
|
|
clusterObjs: object.ObjMetadataSet{},
|
|
isError: true,
|
|
},
|
|
"No cluster objs": {
|
|
localInv: copyInventory(),
|
|
clusterObjs: object.ObjMetadataSet{},
|
|
isError: false,
|
|
},
|
|
"Single cluster obj": {
|
|
localInv: copyInventory(),
|
|
clusterObjs: object.ObjMetadataSet{ignoreErrInfoToObjMeta(pod1Info)},
|
|
isError: false,
|
|
},
|
|
"Multiple cluster objs": {
|
|
localInv: copyInventory(),
|
|
clusterObjs: object.ObjMetadataSet{ignoreErrInfoToObjMeta(pod1Info), ignoreErrInfoToObjMeta(pod3Info)},
|
|
isError: false,
|
|
},
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
|
|
defer tf.Cleanup()
|
|
tf.FakeDynamicClient.PrependReactor("list", "configmaps", toReactionFunc(tc.clusterObjs))
|
|
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, tc.statusPolicy, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
clusterObjs, err := invClient.GetClusterObjs(tc.localInv)
|
|
if tc.isError {
|
|
if err == nil {
|
|
t.Fatalf("expected error but received none")
|
|
}
|
|
return
|
|
}
|
|
if !tc.isError && err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
if !tc.clusterObjs.Equal(clusterObjs) {
|
|
t.Errorf("expected (%v) cluster inventory objs; got (%v)", tc.clusterObjs, clusterObjs)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteInventoryObj(t *testing.T) {
|
|
tests := map[string]struct {
|
|
statusPolicy StatusPolicy
|
|
inv Info
|
|
localObjs object.ObjMetadataSet
|
|
objStatus []actuation.ObjectStatus
|
|
}{
|
|
"Nil local inventory object is an error": {
|
|
inv: nil,
|
|
localObjs: object.ObjMetadataSet{},
|
|
},
|
|
"Empty local inventory object": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{},
|
|
},
|
|
"Local inventory with a single object": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
},
|
|
objStatus: []actuation.ObjectStatus{podStatus(pod2Info)},
|
|
},
|
|
"Local inventory with multiple objects": {
|
|
inv: localInv,
|
|
localObjs: object.ObjMetadataSet{
|
|
ignoreErrInfoToObjMeta(pod1Info),
|
|
ignoreErrInfoToObjMeta(pod2Info),
|
|
ignoreErrInfoToObjMeta(pod3Info)},
|
|
objStatus: []actuation.ObjectStatus{
|
|
podStatus(pod1Info),
|
|
podStatus(pod2Info),
|
|
podStatus(pod3Info),
|
|
},
|
|
},
|
|
}
|
|
|
|
for name, tc := range tests {
|
|
for i := range common.Strategies {
|
|
drs := common.Strategies[i]
|
|
t.Run(name, func(t *testing.T) {
|
|
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
|
|
defer tf.Cleanup()
|
|
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, tc.statusPolicy, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
inv := invClient.invToUnstructuredFunc(tc.inv)
|
|
if inv != nil {
|
|
inv = storeObjsInInventory(tc.inv, tc.localObjs, tc.objStatus)
|
|
}
|
|
err = invClient.deleteInventoryObjByName(inv, drs)
|
|
if err != nil {
|
|
t.Fatalf("unexpected error received: %s", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestApplyInventoryNamespace(t *testing.T) {
|
|
testCases := map[string]struct {
|
|
statusPolicy StatusPolicy
|
|
namespace *unstructured.Unstructured
|
|
dryRunStrategy common.DryRunStrategy
|
|
reactorError error
|
|
}{
|
|
"inventory namespace doesn't exist": {
|
|
namespace: inventoryNamespace,
|
|
dryRunStrategy: common.DryRunNone,
|
|
reactorError: nil,
|
|
},
|
|
"inventory namespace already exist": {
|
|
namespace: inventoryNamespace,
|
|
dryRunStrategy: common.DryRunNone,
|
|
reactorError: errors.NewAlreadyExists(schema.GroupResource{
|
|
Group: "",
|
|
Resource: "namespaces",
|
|
}, testNamespace),
|
|
},
|
|
}
|
|
|
|
for tn, tc := range testCases {
|
|
t.Run(tn, func(t *testing.T) {
|
|
tf := cmdtesting.NewTestFactory().WithNamespace(testNamespace)
|
|
defer tf.Cleanup()
|
|
|
|
tf.FakeDynamicClient.PrependReactor("create", "namespaces", func(action clienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
|
return true, nil, tc.reactorError
|
|
})
|
|
|
|
invClient, err := NewClient(tf,
|
|
WrapInventoryObj, InvInfoToConfigMap, tc.statusPolicy, ConfigMapGVK)
|
|
require.NoError(t, err)
|
|
err = invClient.ApplyInventoryNamespace(tc.namespace, tc.dryRunStrategy)
|
|
assert.NoError(t, err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func ignoreErrInfoToObjMeta(info *resource.Info) object.ObjMetadata {
|
|
objMeta, _ := object.InfoToObjMeta(info)
|
|
return objMeta
|
|
}
|
|
|
|
func toReactionFunc(objs object.ObjMetadataSet) clienttesting.ReactionFunc {
|
|
return func(action clienttesting.Action) (bool, runtime.Object, error) {
|
|
u := copyInventoryInfo()
|
|
err := unstructured.SetNestedStringMap(u.Object, objs.ToStringMap(), "data")
|
|
if err != nil {
|
|
return true, nil, err
|
|
}
|
|
list := &unstructured.UnstructuredList{}
|
|
list.Items = []unstructured.Unstructured{*u}
|
|
return true, list, err
|
|
}
|
|
}
|
|
|
|
func storeObjsInInventory(info Info, objs object.ObjMetadataSet, status []actuation.ObjectStatus) *unstructured.Unstructured {
|
|
wrapped := WrapInventoryObj(InvInfoToConfigMap(info))
|
|
_ = wrapped.Store(objs, status)
|
|
inv, _ := wrapped.GetObject()
|
|
return inv
|
|
}
|