address comments

This commit is contained in:
Jingfang Liu 2019-05-22 09:49:19 -07:00 committed by jingfangliu
parent 59cc0784b6
commit 26b23e9eec
7 changed files with 197 additions and 53 deletions

View File

@ -143,28 +143,3 @@ func (o *Prune) deleteObject(ctx context.Context, gvk schema.GroupVersionKind,
}
return obj, nil
}
// GetPruneResources finds the resource used for pruning from a slice of resources
// by looking for a special annotation in the resource
// inventory.InventoryAnnotation
func GetPruneResources(resources []*unstructured.Unstructured) (*unstructured.Unstructured, error) {
count := 0
var result *unstructured.Unstructured
for _, res := range resources {
annotations := res.GetAnnotations()
if _, ok := annotations[inventory.InventoryAnnotation]; ok {
count++
result = res
}
}
switch count {
case 0:
return nil, nil
case 1:
return result, nil
default:
return nil, fmt.Errorf("found multiple resources with inventory annotations")
}
}

View File

@ -18,6 +18,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"sigs.k8s.io/kustomize/pkg/inventory"
"strings"
"sigs.k8s.io/kustomize/pkg/ifc"
@ -177,3 +178,27 @@ func (p *RawConfigHTTPProvider) GetConfig(path string) ([]*unstructured.Unstruct
func (p *RawConfigHTTPProvider) GetPruneConfig(path string) (*unstructured.Unstructured, error) {
return nil, nil
}
// GetPruneResources finds the resource used for pruning from a slice of resources
// by looking for a special annotation in the resource
// inventory.InventoryAnnotation
func GetPruneResources(resources []*unstructured.Unstructured) (*unstructured.Unstructured, error) {
count := 0
var result *unstructured.Unstructured
for _, res := range resources {
annotations := res.GetAnnotations()
if _, ok := annotations[inventory.InventoryAnnotation]; ok {
count++
result = res
}
}
if count == 0 {
return nil, nil
}
if count > 1 {
return nil, fmt.Errorf("found multiple resources with inventory annotations")
}
return result, nil
}

View File

@ -15,13 +15,15 @@ package resourceconfig_test
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"sigs.k8s.io/kustomize/pkg/inventory"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/cli-experimental/internal/pkg/resourceconfig"
"sigs.k8s.io/cli-experimental/internal/pkg/wirecli/wiretest"
"sigs.k8s.io/kustomize/pkg/inventory"
)
func TestKustomizeProvider(t *testing.T) {
@ -64,3 +66,77 @@ func TestKustomizeProvider2(t *testing.T) {
inv.LoadFromAnnotation(pobject.GetAnnotations())
assert.Equal(t, len(inv.Current), 1)
}
func setupKustomizeWithoutInventory(t *testing.T) string {
f, err := ioutil.TempDir("/tmp", "TestApply")
assert.NoError(t, err)
err = ioutil.WriteFile(filepath.Join(f, "kustomization.yaml"), []byte(`
configMapGenerator:
- name: testmap
literals:
- foo=bar
secretGenerator:
- name: testsc
literals:
- bar=baz
namespace: default
`), 0644)
assert.NoError(t, err)
return f
}
func TestGetPruneResources(t *testing.T) {
// with one inventory object
// GetPruneResources can return it
f := setupKustomize(t)
defer os.RemoveAll(f)
kp := wiretest.InitializConfigProvider()
objects, err := kp.GetConfig(f)
assert.NoError(t, err)
assert.Equal(t, len(objects), 2)
r, err := resourceconfig.GetPruneResources(objects)
assert.NoError(t, err)
assert.NotNil(t, r)
// Test the empty input
r, err = resourceconfig.GetPruneResources(
[]*unstructured.Unstructured{})
assert.NoError(t, err)
assert.Nil(t, r)
// Test the nil input
r, err = resourceconfig.GetPruneResources(nil)
assert.NoError(t, err)
assert.Nil(t, r)
// With no inventory object
// GetPruneResources returns nil
f2 := setupKustomizeWithoutInventory(t)
defer os.RemoveAll(f2)
kp = wiretest.InitializConfigProvider()
objects, err = kp.GetConfig(f2)
assert.NoError(t, err)
assert.Equal(t, len(objects), 2)
r, err = resourceconfig.GetPruneResources(objects)
assert.NoError(t, err)
assert.Nil(t, r)
// With multiple objects with inventory annotations
// GetPruneResources returns an error
objects, err = kp.GetConfig(f2)
assert.NoError(t, err)
assert.Equal(t, len(objects), 2)
for _, o := range objects {
o.SetAnnotations(map[string]string{
inventory.InventoryHashAnnotation: "12345",
inventory.InventoryAnnotation: `{"current": {}}`,
})
}
r, err = resourceconfig.GetPruneResources(objects)
assert.Errorf(t, err,
"found multiple resources with inventory annotations")
assert.Nil(t, r)
}

View File

@ -18,6 +18,7 @@ import (
"sigs.k8s.io/cli-experimental/internal/pkg/apply"
"sigs.k8s.io/cli-experimental/internal/pkg/delete"
"sigs.k8s.io/cli-experimental/internal/pkg/prune"
"sigs.k8s.io/cli-experimental/internal/pkg/resourceconfig"
)
// Cmd is a wrapper for different structs:
@ -38,9 +39,9 @@ func (a *Cmd) Apply(resources []*unstructured.Unstructured) error {
// Prune prunes resources given the input as a slice of unstructured resources
func (a *Cmd) Prune(resources []*unstructured.Unstructured) error {
pruneResource, err := prune.GetPruneResources(resources)
pruneResource, err := resourceconfig.GetPruneResources(resources)
if err != nil {
return nil
return err
}
a.Pruner.Resources = pruneResource
_, err = a.Pruner.Do()

View File

@ -24,7 +24,27 @@ import (
"sigs.k8s.io/kustomize/pkg/inventory"
)
func setupResources() []*unstructured.Unstructured {
func TestCmdWithEmptyInput(t *testing.T) {
buf := new(bytes.Buffer)
cmd, err := InitializeCmd(buf, nil)
assert.NoError(t, err)
assert.NotNil(t, cmd)
err = cmd.Apply(nil)
assert.NoError(t, err)
err = cmd.Prune(nil)
assert.NoError(t, err)
err = cmd.Delete(nil)
assert.NoError(t, err)
}
// setupResourcesV1 create a slice of unstructured
// with two ConfigMaps
// one with the inventory annotation
// one without the inventory annotation
func setupResourcesV1() []*unstructured.Unstructured {
r1 := &unstructured.Unstructured{}
r1.SetGroupVersionKind(schema.GroupVersionKind{
Version: "v1",
@ -37,15 +57,61 @@ func setupResources() []*unstructured.Unstructured {
Version: "v1",
Kind: "ConfigMap",
})
r2.SetName("cm2")
r2.SetName("inventory")
r2.SetNamespace("default")
r2.SetAnnotations(map[string]string{
inventory.InventoryAnnotation: "{}",
inventory.InventoryAnnotation:
"{\"current\":{\"~G_v1_ConfigMap|default|cm1\":null}}",
inventory.InventoryHashAnnotation: "1234567",
})
return []*unstructured.Unstructured{r1, r2}
}
// setupResourcesV2 create a slice of unstructured
// with two ConfigMaps
// one with the inventory annotation
// one without the inventory annotation
func setupResourcesV2() []*unstructured.Unstructured {
r1 := &unstructured.Unstructured{}
r1.SetGroupVersionKind(schema.GroupVersionKind{
Version: "v1",
Kind: "ConfigMap",
})
r1.SetName("cm2")
r1.SetNamespace("default")
r2 := &unstructured.Unstructured{}
r2.SetGroupVersionKind(schema.GroupVersionKind{
Version: "v1",
Kind: "ConfigMap",
})
r2.SetName("inventory")
r2.SetNamespace("default")
r2.SetAnnotations(map[string]string{
inventory.InventoryAnnotation:
"{\"current\":{\"~G_v1_ConfigMap|default|cm2\":null}}",
inventory.InventoryHashAnnotation: "7654321",
})
return []*unstructured.Unstructured{r1, r2}
}
/* TestCmd tests Apply/Prune/Delete functions by
taking the following steps:
1. Initialize a Cmd object
2. Create the Resources v1
3. Check that there no existing ConfigMap.
Call apply and prune for the first version of Configs
4. Apply the resources and confirm that there are 2 ConfigMaps
5. Prune the resources and confirm that there are 2 ConfigMaps
Call apply and prune for the second version of Configs
6. Create the Resources v2
7. Apply the resources and confirm that there are 3 ConfigMaps
8. Prune the resources and confirm that there are 2 ConfigMaps
Cleanup
9. Delete the resources and confirm that there is no ConfigMap
*/
func TestCmd(t *testing.T) {
buf := new(bytes.Buffer)
cmd, err := InitializeCmd(buf, nil)
@ -63,7 +129,7 @@ func TestCmd(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, len(cmList.Items), 0)
resources := setupResources()
resources := setupResourcesV1()
err = cmd.Apply(resources)
assert.NoError(t, err)
err = c.List(context.Background(), cmList, "default", nil)
@ -76,6 +142,19 @@ func TestCmd(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, len(cmList.Items), 2)
resources = setupResourcesV2()
err = cmd.Apply(resources)
assert.NoError(t, err)
err = c.List(context.Background(), cmList, "default", nil)
assert.NoError(t, err)
assert.Equal(t, len(cmList.Items), 3)
err = cmd.Prune(resources)
assert.NoError(t, err)
err = c.List(context.Background(), cmList, "default", nil)
assert.NoError(t, err)
assert.Equal(t, len(cmList.Items), 2)
err = cmd.Delete(resources)
assert.NoError(t, err)
err = c.List(context.Background(), cmList, "default", nil)

View File

@ -37,21 +37,22 @@ func InitializeCmd(writer io.Writer, args util.Args) (*Cmd, error) {
if err != nil {
return nil, err
}
applyApply := apply.Apply{
applyApply := &apply.Apply{
DynamicClient: client,
Out: writer,
}
prunePrune := prune.Prune{
prunePrune := &prune.Prune{
DynamicClient: client,
Out: writer,
}
deleteDelete := delete2.Delete{
deleteDelete := &delete2.Delete{
DynamicClient: client,
Out: writer,
}
cmd, err := NewCmd(applyApply, prunePrune, deleteDelete, client)
if err != nil {
return nil, err
cmd := &Cmd{
Applier: applyApply,
Pruner: prunePrune,
Deleter: deleteDelete,
}
return cmd, nil
}

View File

@ -16,7 +16,6 @@ package pkg
import (
"github.com/google/wire"
"sigs.k8s.io/cli-experimental/internal/pkg/apply"
"sigs.k8s.io/cli-experimental/internal/pkg/client"
"sigs.k8s.io/cli-experimental/internal/pkg/delete"
"sigs.k8s.io/cli-experimental/internal/pkg/prune"
"sigs.k8s.io/cli-experimental/internal/pkg/wirecli/wirek8s"
@ -27,18 +26,6 @@ var ProviderSet = wire.NewSet(
wire.Struct(new(apply.Apply), "DynamicClient", "Out"),
wire.Struct(new(prune.Prune), "DynamicClient", "Out"),
wire.Struct(new(delete.Delete), "DynamicClient", "Out"),
wire.Struct(new(Cmd), "*"),
wirek8s.ProviderSet,
NewCmd,
)
// NewCmd returns a new Cmd object
func NewCmd(a apply.Apply, p prune.Prune, d delete.Delete, c client.Client) (*Cmd, error) {
a.DynamicClient = c
p.DynamicClient = c
d.DynamicClient = c
return &Cmd{
Applier: &a,
Pruner: &p,
Deleter: &d,
}, nil
}