add ResticRepository CRD and move repo-level actions to a controller

Signed-off-by: Steve Kriss <steve@heptio.com>
This commit is contained in:
Steve Kriss
2018-06-20 09:21:43 -07:00
parent f1e82a2fe3
commit 65ed8da4b7
28 changed files with 1190 additions and 208 deletions
+35 -11
View File
@@ -19,26 +19,31 @@ package restic
import (
"crypto/rand"
"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"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kclientset "k8s.io/client-go/kubernetes"
"github.com/heptio/ark/pkg/apis/ark/v1"
"github.com/heptio/ark/pkg/client"
"github.com/heptio/ark/pkg/cmd"
clientset "github.com/heptio/ark/pkg/generated/clientset/versioned"
"github.com/heptio/ark/pkg/restic"
"github.com/heptio/ark/pkg/util/filesystem"
)
func NewInitRepositoryCommand(f client.Factory) *cobra.Command {
o := NewInitRepositoryOptions()
c := &cobra.Command{
Use: "init-repository",
Short: "create an encryption key for a restic repository",
Long: "create an encryption key for a restic repository",
Use: "init-repository NAMESPACE",
Short: "initialize a restic repository for a specified namespace",
Long: "initialize a restic repository for a specified namespace",
Args: cobra.ExactArgs(1),
Run: func(c *cobra.Command, args []string) {
cmd.CheckError(o.Complete(f))
cmd.CheckError(o.Complete(f, args))
cmd.CheckError(o.Validate(f))
cmd.CheckError(o.Run(f))
},
@@ -57,6 +62,7 @@ type InitRepositoryOptions struct {
fileSystem filesystem.Interface
kubeClient kclientset.Interface
arkClient clientset.Interface
keyBytes []byte
}
@@ -78,7 +84,7 @@ func (o *InitRepositoryOptions) BindFlags(flags *pflag.FlagSet) {
flags.IntVar(&o.KeySize, "key-size", o.KeySize, "Size of the generated key for the restic repository")
}
func (o *InitRepositoryOptions) Complete(f client.Factory) error {
func (o *InitRepositoryOptions) Complete(f client.Factory, args []string) error {
if o.KeyFile != "" && o.KeyData != "" {
return errKeyFileAndKeyDataProvided
}
@@ -87,7 +93,7 @@ func (o *InitRepositoryOptions) Complete(f client.Factory) error {
return errKeySizeTooSmall
}
o.Namespace = f.Namespace()
o.Namespace = args[0]
switch {
case o.KeyFile != "":
@@ -122,9 +128,27 @@ func (o *InitRepositoryOptions) Validate(f client.Factory) error {
return err
}
arkClient, err := f.Client()
if err != nil {
return err
}
o.arkClient = arkClient
return nil
}
func (o *InitRepositoryOptions) Run(f client.Factory) error {
return restic.NewRepositoryKey(o.kubeClient.CoreV1(), o.Namespace, o.keyBytes)
if err := restic.NewRepositoryKey(o.kubeClient.CoreV1(), o.Namespace, o.keyBytes); err != nil {
return err
}
repo := &v1.ResticRepository{
ObjectMeta: metav1.ObjectMeta{
Namespace: f.Namespace(),
Name: o.Namespace,
},
}
_, err := o.arkClient.ArkV1().ResticRepositories(f.Namespace()).Create(repo)
return errors.Wrap(err, "error creating ResticRepository")
}
+5 -5
View File
@@ -36,7 +36,7 @@ func (f *fakeFactory) Namespace() string {
func TestComplete(t *testing.T) {
// no key options provided should error
o := &InitRepositoryOptions{}
err := o.Complete(&fakeFactory{})
err := o.Complete(&fakeFactory{}, []string{"ns"})
assert.EqualError(t, err, errKeySizeTooSmall.Error())
// both KeyFile and KeyData provided should error
@@ -44,7 +44,7 @@ func TestComplete(t *testing.T) {
KeyFile: "/foo",
KeyData: "bar",
}
err = o.Complete(&fakeFactory{})
err = o.Complete(&fakeFactory{}, []string{"ns"})
assert.EqualError(t, err, errKeyFileAndKeyDataProvided.Error())
// if KeyFile is provided, its contents are used
@@ -53,20 +53,20 @@ func TestComplete(t *testing.T) {
KeyFile: "/foo",
fileSystem: arktest.NewFakeFileSystem().WithFile("/foo", fileContents),
}
assert.NoError(t, o.Complete(&fakeFactory{}))
assert.NoError(t, o.Complete(&fakeFactory{}, []string{"ns"}))
assert.Equal(t, fileContents, o.keyBytes)
// if KeyData is provided, it's used
o = &InitRepositoryOptions{
KeyData: "bar",
}
assert.NoError(t, o.Complete(&fakeFactory{}))
assert.NoError(t, o.Complete(&fakeFactory{}, []string{"ns"}))
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.NoError(t, o.Complete(&fakeFactory{}, []string{"ns"}))
assert.Equal(t, o.KeySize, len(o.keyBytes))
}