Merge pull request #533 from skriss/fix-init-repo-key-data
ark restic init-repository: use key data if providedpull/537/head
commit
c0cf61912d
|
@ -18,11 +18,11 @@ package restic
|
|||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/heptio/ark/pkg/client"
|
||||
"github.com/heptio/ark/pkg/cmd"
|
||||
"github.com/heptio/ark/pkg/restic"
|
||||
"github.com/heptio/ark/pkg/util/filesystem"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -55,16 +55,23 @@ type InitRepositoryOptions struct {
|
|||
KeyData string
|
||||
KeySize int
|
||||
|
||||
fileSystem filesystem.Interface
|
||||
kubeClient kclientset.Interface
|
||||
keyBytes []byte
|
||||
}
|
||||
|
||||
func NewInitRepositoryOptions() *InitRepositoryOptions {
|
||||
return &InitRepositoryOptions{
|
||||
KeySize: 1024,
|
||||
KeySize: 1024,
|
||||
fileSystem: filesystem.NewFileSystem(),
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
errKeyFileAndKeyDataProvided = errors.Errorf("only one of --key-file and --key-data may be specified")
|
||||
errKeySizeTooSmall = errors.Errorf("--key-size must be at least 1")
|
||||
)
|
||||
|
||||
func (o *InitRepositoryOptions) BindFlags(flags *pflag.FlagSet) {
|
||||
flags.StringVar(&o.KeyFile, "key-file", o.KeyFile, "Path to file containing the encryption key for the restic repository. Optional; if unset, Ark will generate a random key for you.")
|
||||
flags.StringVar(&o.KeyData, "key-data", o.KeyData, "Encryption key for the restic repository. Optional; if unset, Ark will generate a random key for you.")
|
||||
|
@ -73,27 +80,28 @@ func (o *InitRepositoryOptions) BindFlags(flags *pflag.FlagSet) {
|
|||
|
||||
func (o *InitRepositoryOptions) Complete(f client.Factory) error {
|
||||
if o.KeyFile != "" && o.KeyData != "" {
|
||||
return errors.Errorf("only one of --key-file and --key-data may be specified")
|
||||
return errKeyFileAndKeyDataProvided
|
||||
}
|
||||
|
||||
if o.KeyFile == "" && o.KeyData == "" && o.KeySize < 1 {
|
||||
return errors.Errorf("--key-size must be at least 1")
|
||||
return errKeySizeTooSmall
|
||||
}
|
||||
|
||||
o.Namespace = f.Namespace()
|
||||
|
||||
if o.KeyFile != "" {
|
||||
data, err := ioutil.ReadFile(o.KeyFile)
|
||||
switch {
|
||||
case o.KeyFile != "":
|
||||
data, err := o.fileSystem.ReadFile(o.KeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.keyBytes = data
|
||||
}
|
||||
|
||||
if len(o.KeyData) == 0 {
|
||||
case o.KeyData != "":
|
||||
o.keyBytes = []byte(o.KeyData)
|
||||
case o.KeySize > 0:
|
||||
o.keyBytes = make([]byte, o.KeySize)
|
||||
// rand.Reader always returns a nil error
|
||||
_, _ = rand.Read(o.keyBytes)
|
||||
rand.Read(o.keyBytes)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package restic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/heptio/ark/pkg/client"
|
||||
clientset "github.com/heptio/ark/pkg/generated/clientset/versioned"
|
||||
arktest "github.com/heptio/ark/pkg/util/test"
|
||||
)
|
||||
|
||||
type fakeFactory struct{}
|
||||
|
||||
var _ client.Factory = &fakeFactory{}
|
||||
|
||||
func (f *fakeFactory) BindFlags(flags *pflag.FlagSet) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (f *fakeFactory) Client() (clientset.Interface, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (f *fakeFactory) KubeClient() (kubernetes.Interface, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (f *fakeFactory) Namespace() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func TestComplete(t *testing.T) {
|
||||
// no key options provided should error
|
||||
o := &InitRepositoryOptions{}
|
||||
err := o.Complete(&fakeFactory{})
|
||||
assert.EqualError(t, err, errKeySizeTooSmall.Error())
|
||||
|
||||
// both KeyFile and KeyData provided should error
|
||||
o = &InitRepositoryOptions{
|
||||
KeyFile: "/foo",
|
||||
KeyData: "bar",
|
||||
}
|
||||
err = o.Complete(&fakeFactory{})
|
||||
assert.EqualError(t, err, errKeyFileAndKeyDataProvided.Error())
|
||||
|
||||
// if KeyFile is provided, its contents are used
|
||||
fileContents := []byte("bar")
|
||||
o = &InitRepositoryOptions{
|
||||
KeyFile: "/foo",
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("/foo", fileContents),
|
||||
}
|
||||
assert.NoError(t, o.Complete(&fakeFactory{}))
|
||||
assert.Equal(t, fileContents, o.keyBytes)
|
||||
|
||||
// if KeyData is provided, it's used
|
||||
o = &InitRepositoryOptions{
|
||||
KeyData: "bar",
|
||||
}
|
||||
assert.NoError(t, o.Complete(&fakeFactory{}))
|
||||
assert.Equal(t, []byte(o.KeyData), o.keyBytes)
|
||||
|
||||
// if KeySize is provided, a random key is generated
|
||||
o = &InitRepositoryOptions{
|
||||
KeySize: 10,
|
||||
}
|
||||
assert.NoError(t, o.Complete(&fakeFactory{}))
|
||||
assert.Equal(t, o.KeySize, len(o.keyBytes))
|
||||
}
|
|
@ -18,12 +18,9 @@ package restore
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
@ -120,7 +117,7 @@ func TestPrioritizeResources(t *testing.T) {
|
|||
func TestRestoreNamespaceFiltering(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fileSystem *fakeFileSystem
|
||||
fileSystem *arktest.FakeFileSystem
|
||||
baseDir string
|
||||
restore *api.Restore
|
||||
expectedReadDirs []string
|
||||
|
@ -128,7 +125,7 @@ func TestRestoreNamespaceFiltering(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "namespacesToRestore having * restores all namespaces",
|
||||
fileSystem: newFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
baseDir: "bak",
|
||||
restore: &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"*"}}},
|
||||
expectedReadDirs: []string{"bak/resources", "bak/resources/nodes/cluster", "bak/resources/secrets/namespaces", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"},
|
||||
|
@ -139,7 +136,7 @@ func TestRestoreNamespaceFiltering(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "namespacesToRestore properly filters",
|
||||
fileSystem: newFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
baseDir: "bak",
|
||||
restore: &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"b", "c"}}},
|
||||
expectedReadDirs: []string{"bak/resources", "bak/resources/nodes/cluster", "bak/resources/secrets/namespaces", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"},
|
||||
|
@ -150,7 +147,7 @@ func TestRestoreNamespaceFiltering(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "namespacesToRestore properly filters with exclusion filter",
|
||||
fileSystem: newFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
baseDir: "bak",
|
||||
restore: &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"*"}, ExcludedNamespaces: []string{"a"}}},
|
||||
expectedReadDirs: []string{"bak/resources", "bak/resources/nodes/cluster", "bak/resources/secrets/namespaces", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"},
|
||||
|
@ -161,7 +158,7 @@ func TestRestoreNamespaceFiltering(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "namespacesToRestore properly filters with inclusion & exclusion filters",
|
||||
fileSystem: newFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectories("bak/resources/nodes/cluster", "bak/resources/secrets/namespaces/a", "bak/resources/secrets/namespaces/b", "bak/resources/secrets/namespaces/c"),
|
||||
baseDir: "bak",
|
||||
restore: &api.Restore{
|
||||
Spec: api.RestoreSpec{
|
||||
|
@ -197,7 +194,7 @@ func TestRestoreNamespaceFiltering(t *testing.T) {
|
|||
assert.Empty(t, errors.Ark)
|
||||
assert.Empty(t, errors.Cluster)
|
||||
assert.Empty(t, errors.Namespaces)
|
||||
assert.Equal(t, test.expectedReadDirs, test.fileSystem.readDirCalls)
|
||||
assert.Equal(t, test.expectedReadDirs, test.fileSystem.ReadDirCalls)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -205,7 +202,7 @@ func TestRestoreNamespaceFiltering(t *testing.T) {
|
|||
func TestRestorePriority(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fileSystem *fakeFileSystem
|
||||
fileSystem *arktest.FakeFileSystem
|
||||
restore *api.Restore
|
||||
baseDir string
|
||||
prioritizedResources []schema.GroupResource
|
||||
|
@ -214,7 +211,7 @@ func TestRestorePriority(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "cluster test",
|
||||
fileSystem: newFakeFileSystem().WithDirectory("bak/resources/a/cluster").WithDirectory("bak/resources/c/cluster"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectory("bak/resources/a/cluster").WithDirectory("bak/resources/c/cluster"),
|
||||
baseDir: "bak",
|
||||
restore: &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"*"}}},
|
||||
prioritizedResources: []schema.GroupResource{
|
||||
|
@ -226,7 +223,7 @@ func TestRestorePriority(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "resource priorities are applied",
|
||||
fileSystem: newFakeFileSystem().WithDirectory("bak/resources/a/cluster").WithDirectory("bak/resources/c/cluster"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectory("bak/resources/a/cluster").WithDirectory("bak/resources/c/cluster"),
|
||||
restore: &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"*"}}},
|
||||
baseDir: "bak",
|
||||
prioritizedResources: []schema.GroupResource{
|
||||
|
@ -238,7 +235,7 @@ func TestRestorePriority(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "basic namespace",
|
||||
fileSystem: newFakeFileSystem().WithDirectory("bak/resources/a/namespaces/ns-1").WithDirectory("bak/resources/c/namespaces/ns-1"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectory("bak/resources/a/namespaces/ns-1").WithDirectory("bak/resources/c/namespaces/ns-1"),
|
||||
restore: &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"*"}}},
|
||||
baseDir: "bak",
|
||||
prioritizedResources: []schema.GroupResource{
|
||||
|
@ -250,7 +247,7 @@ func TestRestorePriority(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "error in a single resource doesn't terminate restore immediately, but is returned",
|
||||
fileSystem: newFakeFileSystem().
|
||||
fileSystem: arktest.NewFakeFileSystem().
|
||||
WithFile("bak/resources/a/namespaces/ns-1/invalid-json.json", []byte("invalid json")).
|
||||
WithDirectory("bak/resources/c/namespaces/ns-1"),
|
||||
restore: &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"*"}}},
|
||||
|
@ -288,7 +285,7 @@ func TestRestorePriority(t *testing.T) {
|
|||
assert.Empty(t, warnings.Namespaces)
|
||||
assert.Equal(t, test.expectedErrors, errors)
|
||||
|
||||
assert.Equal(t, test.expectedReadDirs, test.fileSystem.readDirCalls)
|
||||
assert.Equal(t, test.expectedReadDirs, test.fileSystem.ReadDirCalls)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +296,7 @@ func TestNamespaceRemapping(t *testing.T) {
|
|||
restore = &api.Restore{Spec: api.RestoreSpec{IncludedNamespaces: []string{"*"}, NamespaceMapping: map[string]string{"ns-1": "ns-2"}}}
|
||||
prioritizedResources = []schema.GroupResource{{Resource: "namespaces"}, {Resource: "configmaps"}}
|
||||
labelSelector = labels.NewSelector()
|
||||
fileSystem = newFakeFileSystem().
|
||||
fileSystem = arktest.NewFakeFileSystem().
|
||||
WithFile("bak/resources/configmaps/namespaces/ns-1/cm-1.json", newTestConfigMap().WithNamespace("ns-1").ToJSON()).
|
||||
WithFile("bak/resources/namespaces/cluster/ns-1.json", newTestNamespace("ns-1").ToJSON())
|
||||
expectedNS = "ns-2"
|
||||
|
@ -363,7 +360,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
resourcePath string
|
||||
labelSelector labels.Selector
|
||||
includeClusterResources *bool
|
||||
fileSystem *fakeFileSystem
|
||||
fileSystem *arktest.FakeFileSystem
|
||||
actions []resolvedAction
|
||||
expectedErrors api.RestoreResult
|
||||
expectedObjs []unstructured.Unstructured
|
||||
|
@ -373,7 +370,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
fileSystem: newFakeFileSystem().
|
||||
fileSystem: arktest.NewFakeFileSystem().
|
||||
WithFile("configmaps/cm-1.json", newNamedTestConfigMap("cm-1").ToJSON()).
|
||||
WithFile("configmaps/cm-2.json", newNamedTestConfigMap("cm-2").ToJSON()),
|
||||
expectedObjs: toUnstructured(
|
||||
|
@ -385,7 +382,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
name: "no such directory causes error",
|
||||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
fileSystem: newFakeFileSystem(),
|
||||
fileSystem: arktest.NewFakeFileSystem(),
|
||||
expectedErrors: api.RestoreResult{
|
||||
Namespaces: map[string][]string{
|
||||
"ns-1": {"error reading \"configmaps\" resource directory: open configmaps: file does not exist"},
|
||||
|
@ -396,14 +393,14 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
name: "empty directory is no-op",
|
||||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
fileSystem: newFakeFileSystem().WithDirectory("configmaps"),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithDirectory("configmaps"),
|
||||
},
|
||||
{
|
||||
name: "unmarshall failure does not cause immediate return",
|
||||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
fileSystem: newFakeFileSystem().
|
||||
fileSystem: arktest.NewFakeFileSystem().
|
||||
WithFile("configmaps/cm-1-invalid.json", []byte("this is not valid json")).
|
||||
WithFile("configmaps/cm-2.json", newNamedTestConfigMap("cm-2").ToJSON()),
|
||||
expectedErrors: api.RestoreResult{
|
||||
|
@ -418,7 +415,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.SelectorFromSet(labels.Set(map[string]string{"foo": "bar"})),
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().WithLabels(map[string]string{"foo": "bar"}).ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().WithLabels(map[string]string{"foo": "bar"}).ToJSON()),
|
||||
expectedObjs: toUnstructured(newTestConfigMap().WithLabels(map[string]string{"foo": "bar"}).WithArkLabel("my-restore").ConfigMap),
|
||||
},
|
||||
{
|
||||
|
@ -426,14 +423,14 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.SelectorFromSet(labels.Set(map[string]string{"foo": "not-bar"})),
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().WithLabels(map[string]string{"foo": "bar"}).ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().WithLabels(map[string]string{"foo": "bar"}).ToJSON()),
|
||||
},
|
||||
{
|
||||
name: "items with controller owner are skipped",
|
||||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
fileSystem: newFakeFileSystem().
|
||||
fileSystem: arktest.NewFakeFileSystem().
|
||||
WithFile("configmaps/cm-1.json", newTestConfigMap().WithControllerOwner().ToJSON()).
|
||||
WithFile("configmaps/cm-2.json", newNamedTestConfigMap("cm-2").ToJSON()),
|
||||
expectedObjs: toUnstructured(newNamedTestConfigMap("cm-2").WithArkLabel("my-restore").ConfigMap),
|
||||
|
@ -443,7 +440,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
namespace: "ns-2",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().WithNamespace("ns-1").ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().WithNamespace("ns-1").ToJSON()),
|
||||
expectedObjs: toUnstructured(newTestConfigMap().WithNamespace("ns-2").WithArkLabel("my-restore").ConfigMap),
|
||||
},
|
||||
{
|
||||
|
@ -451,7 +448,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
actions: []resolvedAction{
|
||||
{
|
||||
ItemAction: newFakeAction("configmaps"),
|
||||
|
@ -467,7 +464,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
namespace: "ns-1",
|
||||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
actions: []resolvedAction{
|
||||
{
|
||||
ItemAction: newFakeAction("foo-resource"),
|
||||
|
@ -484,7 +481,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
resourcePath: "persistentvolumes",
|
||||
labelSelector: labels.NewSelector(),
|
||||
includeClusterResources: falsePtr,
|
||||
fileSystem: newFakeFileSystem().WithFile("persistentvolumes/pv-1.json", newTestPV().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("persistentvolumes/pv-1.json", newTestPV().ToJSON()),
|
||||
},
|
||||
{
|
||||
name: "namespaced resources are not skipped when IncludeClusterResources=false",
|
||||
|
@ -492,7 +489,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
includeClusterResources: falsePtr,
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
expectedObjs: toUnstructured(newTestConfigMap().WithArkLabel("my-restore").ConfigMap),
|
||||
},
|
||||
{
|
||||
|
@ -501,7 +498,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
resourcePath: "persistentvolumes",
|
||||
labelSelector: labels.NewSelector(),
|
||||
includeClusterResources: truePtr,
|
||||
fileSystem: newFakeFileSystem().WithFile("persistentvolumes/pv-1.json", newTestPV().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("persistentvolumes/pv-1.json", newTestPV().ToJSON()),
|
||||
expectedObjs: toUnstructured(newTestPV().WithArkLabel("my-restore").PersistentVolume),
|
||||
},
|
||||
{
|
||||
|
@ -510,7 +507,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
includeClusterResources: truePtr,
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
expectedObjs: toUnstructured(newTestConfigMap().WithArkLabel("my-restore").ConfigMap),
|
||||
},
|
||||
{
|
||||
|
@ -519,7 +516,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
resourcePath: "persistentvolumes",
|
||||
labelSelector: labels.NewSelector(),
|
||||
includeClusterResources: nil,
|
||||
fileSystem: newFakeFileSystem().WithFile("persistentvolumes/pv-1.json", newTestPV().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("persistentvolumes/pv-1.json", newTestPV().ToJSON()),
|
||||
expectedObjs: toUnstructured(newTestPV().WithArkLabel("my-restore").PersistentVolume),
|
||||
},
|
||||
{
|
||||
|
@ -528,7 +525,7 @@ func TestRestoreResourceForNamespace(t *testing.T) {
|
|||
resourcePath: "configmaps",
|
||||
labelSelector: labels.NewSelector(),
|
||||
includeClusterResources: nil,
|
||||
fileSystem: newFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
fileSystem: arktest.NewFakeFileSystem().WithFile("configmaps/cm-1.json", newTestConfigMap().ToJSON()),
|
||||
expectedObjs: toUnstructured(newTestConfigMap().WithArkLabel("my-restore").ConfigMap),
|
||||
},
|
||||
}
|
||||
|
@ -1210,68 +1207,6 @@ func (cm *testConfigMap) ToJSON() []byte {
|
|||
return bytes
|
||||
}
|
||||
|
||||
type fakeFileSystem struct {
|
||||
fs afero.Fs
|
||||
|
||||
readDirCalls []string
|
||||
}
|
||||
|
||||
func newFakeFileSystem() *fakeFileSystem {
|
||||
return &fakeFileSystem{
|
||||
fs: afero.NewMemMapFs(),
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) WithFile(path string, data []byte) *fakeFileSystem {
|
||||
file, _ := fs.fs.Create(path)
|
||||
file.Write(data)
|
||||
file.Close()
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) WithDirectory(path string) *fakeFileSystem {
|
||||
fs.fs.MkdirAll(path, 0755)
|
||||
return fs
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) WithDirectories(path ...string) *fakeFileSystem {
|
||||
for _, dir := range path {
|
||||
fs = fs.WithDirectory(dir)
|
||||
}
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) TempDir(dir, prefix string) (string, error) {
|
||||
return afero.TempDir(fs.fs, dir, prefix)
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) MkdirAll(path string, perm os.FileMode) error {
|
||||
return fs.fs.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) Create(name string) (io.WriteCloser, error) {
|
||||
return fs.fs.Create(name)
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) RemoveAll(path string) error {
|
||||
return fs.fs.RemoveAll(path)
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) ReadDir(dirname string) ([]os.FileInfo, error) {
|
||||
fs.readDirCalls = append(fs.readDirCalls, dirname)
|
||||
return afero.ReadDir(fs.fs, dirname)
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) ReadFile(filename string) ([]byte, error) {
|
||||
return afero.ReadFile(fs.fs, filename)
|
||||
}
|
||||
|
||||
func (fs *fakeFileSystem) DirExists(path string) (bool, error) {
|
||||
return afero.DirExists(fs.fs, path)
|
||||
}
|
||||
|
||||
type fakeAction struct {
|
||||
resource string
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
|
||||
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 filesystem
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Interface defines methods for interacting with an
|
||||
// underlying file system.
|
||||
type Interface interface {
|
||||
TempDir(dir, prefix string) (string, error)
|
||||
MkdirAll(path string, perm os.FileMode) error
|
||||
Create(name string) (io.WriteCloser, error)
|
||||
RemoveAll(path string) error
|
||||
ReadDir(dirname string) ([]os.FileInfo, error)
|
||||
ReadFile(filename string) ([]byte, error)
|
||||
DirExists(path string) (bool, error)
|
||||
}
|
||||
|
||||
func NewFileSystem() Interface {
|
||||
return &osFileSystem{}
|
||||
}
|
||||
|
||||
type osFileSystem struct{}
|
||||
|
||||
func (fs *osFileSystem) TempDir(dir, prefix string) (string, error) {
|
||||
return ioutil.TempDir(dir, prefix)
|
||||
}
|
||||
|
||||
func (fs *osFileSystem) MkdirAll(path string, perm os.FileMode) error {
|
||||
return os.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
func (fs *osFileSystem) Create(name string) (io.WriteCloser, error) {
|
||||
return os.Create(name)
|
||||
}
|
||||
|
||||
func (fs *osFileSystem) RemoveAll(path string) error {
|
||||
return os.RemoveAll(path)
|
||||
}
|
||||
|
||||
func (fs *osFileSystem) ReadDir(dirname string) ([]os.FileInfo, error) {
|
||||
return ioutil.ReadDir(dirname)
|
||||
}
|
||||
|
||||
func (fs *osFileSystem) ReadFile(filename string) ([]byte, error) {
|
||||
return ioutil.ReadFile(filename)
|
||||
}
|
||||
|
||||
func (fs *osFileSystem) DirExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
type FakeFileSystem struct {
|
||||
fs afero.Fs
|
||||
|
||||
ReadDirCalls []string
|
||||
}
|
||||
|
||||
func NewFakeFileSystem() *FakeFileSystem {
|
||||
return &FakeFileSystem{
|
||||
fs: afero.NewMemMapFs(),
|
||||
}
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) TempDir(dir, prefix string) (string, error) {
|
||||
return afero.TempDir(fs.fs, dir, prefix)
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) MkdirAll(path string, perm os.FileMode) error {
|
||||
return fs.fs.MkdirAll(path, perm)
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) Create(name string) (io.WriteCloser, error) {
|
||||
return fs.fs.Create(name)
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) RemoveAll(path string) error {
|
||||
return fs.fs.RemoveAll(path)
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) ReadDir(dirname string) ([]os.FileInfo, error) {
|
||||
fs.ReadDirCalls = append(fs.ReadDirCalls, dirname)
|
||||
return afero.ReadDir(fs.fs, dirname)
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) ReadFile(filename string) ([]byte, error) {
|
||||
return afero.ReadFile(fs.fs, filename)
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) DirExists(path string) (bool, error) {
|
||||
return afero.DirExists(fs.fs, path)
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) WithFile(path string, data []byte) *FakeFileSystem {
|
||||
file, _ := fs.fs.Create(path)
|
||||
file.Write(data)
|
||||
file.Close()
|
||||
|
||||
return fs
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) WithDirectory(path string) *FakeFileSystem {
|
||||
fs.fs.MkdirAll(path, 0755)
|
||||
return fs
|
||||
}
|
||||
|
||||
func (fs *FakeFileSystem) WithDirectories(path ...string) *FakeFileSystem {
|
||||
for _, dir := range path {
|
||||
fs = fs.WithDirectory(dir)
|
||||
}
|
||||
|
||||
return fs
|
||||
}
|
Loading…
Reference in New Issue