WIP: HTTP-01 solver that stores challenge tokens in FrostFS #4

Draft
potyarkin wants to merge 9 commits from potyarkin/lego:feature/http-01-frostfs-solver into tcl/http-01-frostfs-solver
2 changed files with 29 additions and 31 deletions
Showing only changes of commit 254983fbe2 - Show all commits

View file

@ -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)
}

View file

@ -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()
}