add Cmd to pkg

This commit is contained in:
Jingfang Liu 2019-05-21 15:58:00 -07:00 committed by jingfangliu
parent 558382635f
commit 59cc0784b6
7 changed files with 294 additions and 1 deletions

View File

@ -143,3 +143,28 @@ 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

@ -19,9 +19,9 @@ import (
"io"
"github.com/google/wire"
"sigs.k8s.io/cli-experimental/internal/pkg/util"
"sigs.k8s.io/cli-experimental/internal/pkg/apply"
"sigs.k8s.io/cli-experimental/internal/pkg/clik8s"
"sigs.k8s.io/cli-experimental/internal/pkg/util"
)
// InitializeApply creates a new *apply.Apply object

55
pkg/cmd.go Normal file
View File

@ -0,0 +1,55 @@
/*
Copyright 2019 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 pkg
import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/cli-experimental/internal/pkg/apply"
"sigs.k8s.io/cli-experimental/internal/pkg/delete"
"sigs.k8s.io/cli-experimental/internal/pkg/prune"
)
// Cmd is a wrapper for different structs:
// apply, prune and delete
// These structs share the same client
type Cmd struct {
Applier *apply.Apply
Pruner *prune.Prune
Deleter *delete.Delete
}
// Apply applies resources given the input as a slice of unstructured resources
func (a *Cmd) Apply(resources []*unstructured.Unstructured) error {
a.Applier.Resources = resources
_, err := a.Applier.Do()
return err
}
// 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)
if err != nil {
return nil
}
a.Pruner.Resources = pruneResource
_, err = a.Pruner.Do()
return err
}
// Delete deletes resources given the input as a slice of unstructured resources
func (a *Cmd) Delete(resources []*unstructured.Unstructured) error {
a.Deleter.Resources = resources
_, err := a.Deleter.Do()
return err
}

84
pkg/cmd_test.go Normal file
View File

@ -0,0 +1,84 @@
/*
Copyright 2019 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 pkg
import (
"bytes"
"context"
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/kustomize/pkg/inventory"
)
func setupResources() []*unstructured.Unstructured {
r1 := &unstructured.Unstructured{}
r1.SetGroupVersionKind(schema.GroupVersionKind{
Version: "v1",
Kind: "ConfigMap",
})
r1.SetName("cm1")
r1.SetNamespace("default")
r2 := &unstructured.Unstructured{}
r2.SetGroupVersionKind(schema.GroupVersionKind{
Version: "v1",
Kind: "ConfigMap",
})
r2.SetName("cm2")
r2.SetNamespace("default")
r2.SetAnnotations(map[string]string{
inventory.InventoryAnnotation: "{}",
inventory.InventoryHashAnnotation: "1234567",
})
return []*unstructured.Unstructured{r1, r2}
}
func TestCmd(t *testing.T) {
buf := new(bytes.Buffer)
cmd, err := InitializeCmd(buf, nil)
assert.NoError(t, err)
assert.NotNil(t, cmd)
cmList := &unstructured.UnstructuredList{}
cmList.SetGroupVersionKind(schema.GroupVersionKind{
Kind: "ConfigMapList",
Version: "v1",
})
c := cmd.Applier.DynamicClient
err = c.List(context.Background(), cmList, "default", nil)
assert.NoError(t, err)
assert.Equal(t, len(cmList.Items), 0)
resources := setupResources()
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), 2)
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)
assert.NoError(t, err)
assert.Equal(t, len(cmList.Items), 0)
}

28
pkg/wire.go Normal file
View File

@ -0,0 +1,28 @@
//+build wireinject
/*
Copyright 2019 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 pkg
import (
"io"
"github.com/google/wire"
"sigs.k8s.io/cli-experimental/internal/pkg/util"
)
// InitializeCmd creates a new Cmd object
func InitializeCmd(io.Writer, util.Args) (*Cmd, error) {
panic(wire.Build(ProviderSet))
}

57
pkg/wire_gen.go Normal file
View File

@ -0,0 +1,57 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate wire
//+build !wireinject
package pkg
import (
"io"
"sigs.k8s.io/cli-experimental/internal/pkg/apply"
delete2 "sigs.k8s.io/cli-experimental/internal/pkg/delete"
"sigs.k8s.io/cli-experimental/internal/pkg/prune"
"sigs.k8s.io/cli-experimental/internal/pkg/util"
"sigs.k8s.io/cli-experimental/internal/pkg/wirecli/wirek8s"
)
// Injectors from wire.go:
func InitializeCmd(writer io.Writer, args util.Args) (*Cmd, error) {
configFlags, err := wirek8s.NewConfigFlags(args)
if err != nil {
return nil, err
}
config, err := wirek8s.NewRestConfig(configFlags)
if err != nil {
return nil, err
}
dynamicInterface, err := wirek8s.NewDynamicClient(config)
if err != nil {
return nil, err
}
restMapper, err := wirek8s.NewRestMapper(config)
if err != nil {
return nil, err
}
client, err := wirek8s.NewClient(dynamicInterface, restMapper)
if err != nil {
return nil, err
}
applyApply := apply.Apply{
DynamicClient: client,
Out: writer,
}
prunePrune := prune.Prune{
DynamicClient: client,
Out: writer,
}
deleteDelete := delete2.Delete{
DynamicClient: client,
Out: writer,
}
cmd, err := NewCmd(applyApply, prunePrune, deleteDelete, client)
if err != nil {
return nil, err
}
return cmd, nil
}

44
pkg/wirepkg.go Normal file
View File

@ -0,0 +1,44 @@
/*
Copyright 2019 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 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"
)
// ProviderSet provides the dependencies for creating a Cmd object
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"),
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
}