diff --git a/Gopkg.lock b/Gopkg.lock index afab6930cff90332d0d79f55adc8f24ef6a55064..4267290a7b3c05a706ffc813139ff873f0327cde 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -349,6 +349,22 @@ revision = "b4c50a2b199d93b13dc15e78929cfb23bfdf21ab" version = "v1.1.1" +[[projects]] + name = "github.com/wayn3h0/go-uuid" + packages = [ + ".", + "internal/dcesecurity", + "internal/layout", + "internal/namebased", + "internal/namebased/md5", + "internal/namebased/sha1", + "internal/random", + "internal/timebased", + "internal/version" + ] + revision = "1622016a49b50139b1ac263e6ef2804226b3dec6" + version = "v2.2.1" + [[projects]] branch = "master" name = "golang.org/x/crypto" @@ -458,6 +474,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "0618ffbeb3a7333a1d9e7b24f256ac5b7719f25957d07cfd935156b355b2e5e2" + inputs-digest = "ecec019d5ac7140b4607333907f5a4b211fb3551f7cfe51b92e6cc8e3c515488" solver-name = "gps-cdcl" solver-version = 1 diff --git a/cmd/burrow/commands/configure.go b/cmd/burrow/commands/configure.go index 545467cd7a9c410b2a8e4799c4314c729ebf16c4..de13421a319bce30a6291396e7fe44dfd4971c50 100644 --- a/cmd/burrow/commands/configure.go +++ b/cmd/burrow/commands/configure.go @@ -39,8 +39,7 @@ func Configure(cmd *cli.Cmd) { keysTemplateOpt := cmd.StringOpt("z keys-template", mock.DefaultDumpKeysFormat, fmt.Sprintf("Go text/template template (left delim: %s right delim: %s) to generate secret keys "+ - "file specified with --generate-keys. Default:\n%s", mock.LeftTemplateDelim, mock.RightTemplateDelim, - mock.DefaultDumpKeysFormat)) + "file specified with --generate-keys.", mock.LeftTemplateDelim, mock.RightTemplateDelim)) separateGenesisDoc := cmd.StringOpt("w separate-genesis-doc", "", "Emit a separate genesis doc as JSON or TOML") diff --git a/keys/mock/key_client_mock.go b/keys/mock/key_client_mock.go index d2c78231f945cdf3d7db952dc21933f016492298..47bdca9aeb9dba5840d2da98ba6c692db89c9005 100644 --- a/keys/mock/key_client_mock.go +++ b/keys/mock/key_client_mock.go @@ -15,20 +15,23 @@ package mock import ( + "bytes" "crypto/rand" + "encoding/base64" "fmt" - - "bytes" "text/template" - "encoding/base64" + "encoding/json" + + "reflect" acm "github.com/hyperledger/burrow/account" . "github.com/hyperledger/burrow/keys" "github.com/pkg/errors" "github.com/tendermint/ed25519" - crypto "github.com/tendermint/go-crypto" + "github.com/tendermint/go-crypto" "github.com/tmthrgd/go-hex" + "github.com/wayn3h0/go-uuid" "golang.org/x/crypto/ripemd160" ) @@ -48,16 +51,33 @@ const DefaultDumpKeysFormat = `{ { "Name": "<< $key.Name >>", "Address": "<< $key.Address >>", - "PublicKey": "<< $key.PublicKeyBase64 >>", - "PrivateKey": "<< $key.PrivateKeyBase64 >>" + "PublicKey": "<< base64 $key.PublicKey >>", + "PrivateKey": "<< base64 $key.PrivateKey >>" }<< end >> ] }` +const KubernetesKeyDumpFormat = `keysFiles:<< range $index, $key := . >> + key-<< printf "%03d" $index >>: << base64 $key.MonaxKeyJSON >><< end >> +keysAddresses:<< range $index, $key := . >> + key-<< printf "%03d" $index >>: << $key.Address >><< end >> +validatorAddresses:<< range $index, $key := . >> + - << $key.Address >><< end >> +` + const LeftTemplateDelim = "<<" const RightTemplateDelim = ">>" -var DefaultDumpKeysTemplate = template.Must(template.New("MockKeyClient_DumpKeys"). +var templateFuncs template.FuncMap = map[string]interface{}{ + "base64": func(rv reflect.Value) string { + return encode(rv, base64.StdEncoding.EncodeToString) + }, + "hex": func(rv reflect.Value) string { + return encode(rv, hex.EncodeUpperToString) + }, +} + +var DefaultDumpKeysTemplate = template.Must(template.New("MockKeyClient_DumpKeys").Funcs(templateFuncs). Delims(LeftTemplateDelim, RightTemplateDelim). Parse(DefaultDumpKeysFormat)) @@ -110,20 +130,31 @@ func (mockKey *MockKey) Sign(message []byte) (acm.Signature, error) { return acm.SignatureFromBytes(ed25519.Sign(&privateKey, message)[:]) } -func (mockKey *MockKey) PrivateKeyBase64() string { - return base64.StdEncoding.EncodeToString(mockKey.PrivateKey[:]) -} - -func (mockKey *MockKey) PrivateKeyHex() string { - return hex.EncodeUpperToString(mockKey.PrivateKey[:]) -} - -func (mockKey *MockKey) PublicKeyBase64() string { - return base64.StdEncoding.EncodeToString(mockKey.PublicKey) +// TODO: remove after merging keys taken from there to match serialisation +type plainKeyJSON struct { + Id []byte + Type string + Address string + PrivateKey []byte } -func (mockKey *MockKey) PublicKeyHex() string { - return hex.EncodeUpperToString(mockKey.PublicKey) +// Returns JSON string compatible with that stored by monax-keys +func (mockKey *MockKey) MonaxKeyJSON() string { + id, err := uuid.NewRandom() + if err != nil { + return errors.Wrap(err, "could not create monax key json").Error() + } + jsonKey := plainKeyJSON{ + Id: []byte(id.String()), + Address: mockKey.Address.String(), + Type: string(KeyTypeEd25519Ripemd160), + PrivateKey: mockKey.PrivateKey, + } + bs, err := json.Marshal(jsonKey) + if err != nil { + return errors.Wrap(err, "could not create monax key json").Error() + } + return string(bs) } //--------------------------------------------------------------------- @@ -183,9 +214,10 @@ func (mkc *MockKeyClient) HealthCheck() error { } func (mkc *MockKeyClient) DumpKeys(templateString string) (string, error) { - tmpl, err := template.New("DumpKeys").Delims(LeftTemplateDelim, RightTemplateDelim).Parse(templateString) + tmpl, err := template.New("DumpKeys").Delims(LeftTemplateDelim, RightTemplateDelim).Funcs(templateFuncs). + Parse(templateString) if err != nil { - errors.Wrap(err, "could not dump keys to template") + return "", errors.Wrap(err, "could not dump keys to template") } buf := new(bytes.Buffer) keys := make([]*MockKey, 0, len(mkc.knownKeys)) @@ -198,3 +230,14 @@ func (mkc *MockKeyClient) DumpKeys(templateString string) (string, error) { } return buf.String(), nil } + +func encode(rv reflect.Value, encoder func([]byte) string) string { + switch rv.Kind() { + case reflect.Slice: + return encoder(rv.Bytes()) + case reflect.String: + return encoder([]byte(rv.String())) + default: + panic(fmt.Errorf("could not convert %#v to bytes to encode", rv)) + } +} diff --git a/keys/mock/key_client_mock_test.go b/keys/mock/key_client_mock_test.go index ffcec0019c000eecfa116ec1be3e2b275cb6c992..9a5cbef3f520c7c17d16592f51dfb7aae12f7227 100644 --- a/keys/mock/key_client_mock_test.go +++ b/keys/mock/key_client_mock_test.go @@ -5,6 +5,8 @@ import ( "encoding/json" + "fmt" + "github.com/hyperledger/burrow/keys" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -27,3 +29,29 @@ func TestMockKeyClient_DumpKeys(t *testing.T) { require.NoError(t, err) assert.Equal(t, string(bs), dump) } + +func TestMockKeyClient_DumpKeysKubernetes(t *testing.T) { + keyClient := NewMockKeyClient() + _, err := keyClient.Generate("foo", keys.KeyTypeEd25519Ripemd160) + require.NoError(t, err) + _, err = keyClient.Generate("foobar", keys.KeyTypeEd25519Ripemd160) + require.NoError(t, err) + dump, err := keyClient.DumpKeys(KubernetesKeyDumpFormat) + require.NoError(t, err) + fmt.Println(dump) +} + +func TestMockKey_MonaxKeyJSON(t *testing.T) { + key, err := newMockKey("monax-key-test") + require.NoError(t, err) + monaxKey := key.MonaxKeyJSON() + t.Logf("key is: %v", monaxKey) + keyJSON := &plainKeyJSON{} + err = json.Unmarshal([]byte(monaxKey), keyJSON) + require.NoError(t, err) + // byte length of UUID string = 16 * 2 + 4 = 36 + assert.Len(t, keyJSON.Id, 36) + assert.Equal(t, key.Address.String(), keyJSON.Address) + assert.Equal(t, key.PrivateKey, keyJSON.PrivateKey) + assert.Equal(t, string(keys.KeyTypeEd25519Ripemd160), keyJSON.Type) +}