WIP: HTTP-01 solver that stores challenge tokens in FrostFS #4
2 changed files with 29 additions and 31 deletions
|
@ -8,19 +8,18 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/base58"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
status "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
containerid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
objectid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/nspcc-dev/neo-go/pkg/encoding/base58"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
)
|
||||
|
||||
// Barebones API client for a single FrostFS container
|
||||
// Storage provides barebones API client for a single FrostFS container.
|
||||
type Storage struct {
|
||||
endpoint string
|
||||
container containerid.ID
|
||||
|
@ -30,7 +29,7 @@ type Storage struct {
|
|||
|
||||
const storageRequestTimeout = 10 * time.Second
|
||||
|
||||
// Create FrostFS client for working with a single storage container
|
||||
// Open FrostFS client for working with a single storage container.
|
||||
func Open(endpoint, containerID string, key *ecdsa.PrivateKey) (*Storage, error) {
|
||||
var container containerid.ID
|
||||
err := container.DecodeString(containerID)
|
||||
|
@ -95,10 +94,10 @@ func (s *Storage) Save(ctx context.Context, data []byte, attr ...string) (oid st
|
|||
return "", fmt.Errorf("saving object to storage: %w", stat.(error))
|
||||
}
|
||||
id, _ := obj.ID()
|
||||
return fmt.Sprint(id), nil
|
||||
return id.String(), nil
|
||||
}
|
||||
|
||||
// Delete object from container
|
||||
// Delete object from container.
|
||||
func (s *Storage) Delete(ctx context.Context, oid string) error {
|
||||
var obj objectid.ID
|
||||
err := obj.DecodeString(oid)
|
||||
|
@ -126,13 +125,13 @@ func (s *Storage) Delete(ctx context.Context, oid string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Open new connection to FrostFS storage node
|
||||
// Open new connection to FrostFS storage node.
|
||||
func (s *Storage) dial(ctx context.Context) (*client.Client, error) {
|
||||
var wallet client.PrmInit
|
||||
wallet.Key = *s.key
|
||||
var w client.PrmInit
|
||||
w.Key = *s.key
|
||||
|
||||
var c client.Client
|
||||
c.Init(wallet)
|
||||
c.Init(w)
|
||||
|
||||
var endpoint client.PrmDial
|
||||
endpoint.Endpoint = s.endpoint
|
||||
|
@ -144,7 +143,7 @@ func (s *Storage) dial(ctx context.Context) (*client.Client, error) {
|
|||
return &c, nil
|
||||
}
|
||||
|
||||
// Compose object attributes slice
|
||||
// Compose object attributes slice.
|
||||
func keyval2attrs(attr ...string) ([]object.Attribute, error) {
|
||||
if len(attr)%2 != 0 {
|
||||
return nil, fmt.Errorf("odd number of key-value strings: %d (must be even)", len(attr))
|
||||
|
@ -163,9 +162,8 @@ func keyval2attrs(attr ...string) ([]object.Attribute, error) {
|
|||
return attributes, nil
|
||||
}
|
||||
|
||||
// Load private key from wallet file
|
||||
// Load private key from wallet file.
|
||||
func getKey(walletPath, walletAccount, walletPassword string) (*ecdsa.PrivateKey, error) {
|
||||
var err error
|
||||
if walletPath == "" {
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) // TODO: using ephemeral keys for now, later read from env vars
|
||||
if err != nil {
|
||||
|
@ -183,7 +181,7 @@ func getKey(walletPath, walletAccount, walletPassword string) (*ecdsa.PrivateKey
|
|||
}
|
||||
account := w.Accounts[0]
|
||||
if walletAccount != "" {
|
||||
decode, err := base58.CheckDecode(walletAccount)
|
||||
decode, err := base58.CheckDecode(walletAccount) //nolint:govet // err shadow declaration
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid account address: %w", err)
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ package frostfs
|
|||
// Tests for our FrostFS client code
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
|
@ -12,14 +10,16 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
)
|
||||
|
||||
// Initialize storage backend for tests
|
||||
// Initialize storage backend for tests.
|
||||
func openStorage(t *testing.T) *Storage {
|
||||
cid := os.Getenv("FROSTFS_CID") // example: 348WWfBKbS79Wbmm38MRE3oBoEDM5Ga1XXbGKGNyisDM
|
||||
endpoint := os.Getenv("FROSTFS_ENDPOINT") // example: grpc://localhost:8802
|
||||
t.Helper()
|
||||
cid := os.Getenv("FROSTFS_CID") // sample: "348WWfBKbS79Wbmm38MRE3oBoEDM5Ga1XXbGKGNyisDM"
|
||||
endpoint := os.Getenv("FROSTFS_ENDPOINT") // sample: "grpc://localhost:8802"
|
||||
if cid == "" || endpoint == "" {
|
||||
t.Skipf("one or more environment variables not set: FROSTFS_ENDPOINT, FROSTFS_CID")
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ func openStorage(t *testing.T) *Storage {
|
|||
return storage
|
||||
}
|
||||
|
||||
// Save some bytes to FrostFS and clean up after
|
||||
// Save some bytes to FrostFS and clean up after.
|
||||
func TestObjectPutDelete(t *testing.T) {
|
||||
var payload = []byte("Hello FrostFS!\n")
|
||||
payload := []byte("Hello FrostFS!\n")
|
||||
storage := openStorage(t)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
|
@ -52,9 +52,9 @@ func TestObjectPutDelete(t *testing.T) {
|
|||
t.Logf("deleted object: %s", oid)
|
||||
}
|
||||
|
||||
// Check that FrostFS is in fact a content addressable storage
|
||||
// Check that FrostFS is in fact a content addressable storage.
|
||||
func TestMulipleObjects(t *testing.T) {
|
||||
var payload = []byte("Multiple objects with same content should get the same object ID")
|
||||
payload := []byte("Multiple objects with same content should get the same object ID")
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
|
@ -76,7 +76,7 @@ func TestMulipleObjects(t *testing.T) {
|
|||
continue
|
||||
}
|
||||
if obj != baseline {
|
||||
t.Fatalf("non-identical object id: %s != %s", baseline, obj)
|
||||
panic(fmt.Errorf("non-identical object id: %s != %s", baseline, obj))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,17 +84,17 @@ func TestMulipleObjects(t *testing.T) {
|
|||
|
||||
const testCount = 5
|
||||
storage := openStorage(t)
|
||||
for i := 0; i < testCount; i++ {
|
||||
for i := 0; i < testCount; i++ { //nolint:intrange
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
oid, err := storage.Save(ctx, payload, "FileName", "CAS.txt", "Tag", "test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
panic(err)
|
||||
}
|
||||
err = storage.Delete(ctx, oid)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
panic(err)
|
||||
}
|
||||
t.Log(oid)
|
||||
}()
|
||||
|
@ -102,7 +102,7 @@ func TestMulipleObjects(t *testing.T) {
|
|||
wg.Wait()
|
||||
}
|
||||
|
||||
// Check opening wallet from file system
|
||||
// Check opening wallet from file system.
|
||||
func TestLoadWallet(t *testing.T) {
|
||||
const (
|
||||
walletPath = "client_test_wallet.json"
|
||||
|
@ -127,5 +127,5 @@ func TestLoadWallet(t *testing.T) {
|
|||
func key2addr(k *ecdsa.PrivateKey) string {
|
||||
var owner user.ID
|
||||
user.IDFromKey(&owner, k.PublicKey)
|
||||
return fmt.Sprint(owner)
|
||||
return owner.String()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue