diff --git a/cmd/neofs-node/config/node/config.go b/cmd/neofs-node/config/node/config.go new file mode 100644 index 000000000..b78223ed1 --- /dev/null +++ b/cmd/neofs-node/config/node/config.go @@ -0,0 +1,81 @@ +package nodeconfig + +import ( + "errors" + "fmt" + "strconv" + + "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" + "github.com/nspcc-dev/neofs-node/pkg/network" +) + +const ( + subsection = "node" + + attributePrefix = "attribute" +) + +var ( + errKeyNotSet = errors.New("empty/not set key address, see `node.key` section") + errAddressNotSet = errors.New("empty/not set bootstrap address, see `node.address` section") +) + +// Key returns value of "key" config parameter +// from "node" section. +// +// Panics if value is not a non-empty string. +func Key(c *config.Config) string { + v := config.StringSafe(c.Sub(subsection), "key") + if v == "" { + panic(errKeyNotSet) + } + + // TODO: add string -> `ecdsa.PrivateKey` parsing logic + // after https://github.com/nspcc-dev/neofs-node/pull/569. + + return v +} + +// BootstrapAddress returns value of "address" config parameter +// from "node" section as network.Address. +// +// Panics if value is not a valid NeoFS network address +func BootstrapAddress(c *config.Config) *network.Address { + v := config.StringSafe(c.Sub(subsection), "address") + if v == "" { + panic(errAddressNotSet) + } + + addr, err := network.AddressFromString(v) + if err != nil { + panic(fmt.Errorf("could not convert bootstrap address %s to %T: %w", v, addr, err)) + } + + return addr +} + +// Attributes returns list of config parameters +// from "node" section that are set in "attribute_i" format, +// where i in range [0,100). +func Attributes(c *config.Config) (attrs []string) { + const maxAttributes = 100 + + for i := 0; i < maxAttributes; i++ { + attr := config.StringSafe(c.Sub(subsection), attributePrefix+"_"+strconv.Itoa(i)) + if attr == "" { + return + } + + attrs = append(attrs, attr) + } + + return +} + +// Relay returns value of "relay" config parameter +// from "node" section. +// +// Returns false if value is not set. +func Relay(c *config.Config) bool { + return config.BoolSafe(c.Sub(subsection), "relay") +} diff --git a/cmd/neofs-node/config/node/config_test.go b/cmd/neofs-node/config/node/config_test.go new file mode 100644 index 000000000..a869a97e6 --- /dev/null +++ b/cmd/neofs-node/config/node/config_test.go @@ -0,0 +1,64 @@ +package nodeconfig + +import ( + "testing" + + "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config" + configtest "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/test" + "github.com/nspcc-dev/neofs-node/pkg/network" + "github.com/stretchr/testify/require" +) + +func TestNodeSection(t *testing.T) { + t.Run("defaults", func(t *testing.T) { + empty := configtest.EmptyConfig() + + require.PanicsWithError( + t, + errKeyNotSet.Error(), + func() { + Key(empty) + }, + ) + + require.PanicsWithError( + t, + errAddressNotSet.Error(), + func() { + BootstrapAddress(empty) + }, + ) + + attribute := Attributes(empty) + relay := Relay(empty) + + require.Empty(t, attribute) + require.Equal(t, false, relay) + }) + + const path = "../../../../config/example/node" + + var fileConfigTest = func(c *config.Config) { + key := Key(c) + addr := BootstrapAddress(c) + attributes := Attributes(c) + relay := Relay(c) + + expectedAddr, err := network.AddressFromString("s01.neofs.devenv:8080") + require.NoError(t, err) + + require.Equal(t, "path/hex/WIF", key) + require.Equal(t, true, addr.Equal(expectedAddr)) + require.Equal(t, true, relay) + + require.Len(t, attributes, 2) + require.Equal(t, "Price:11", attributes[0]) + require.Equal(t, "UN-LOCODE:RU MSK", attributes[1]) + } + + configtest.ForEachFileType(path, fileConfigTest) + + t.Run("ENV", func(t *testing.T) { + configtest.ForEnvFileType(path, fileConfigTest) + }) +} diff --git a/config/example/node.env b/config/example/node.env index d7ed1978b..b6070680a 100644 --- a/config/example/node.env +++ b/config/example/node.env @@ -6,6 +6,12 @@ NEOFS_PROFILER_SHUTDOWN_TIMEOUT=15s NEOFS_METRICS_ADDRESS=127.0.0.1:9090 NEOFS_METRICS_SHUTDOWN_TIMEOUT=15s +# Node section +NEOFS_NODE_KEY=path/hex/WIF +NEOFS_NODE_ADDRESS=s01.neofs.devenv:8080 +NEOFS_NODE_ATTRIBUTE_0=Price:11 +NEOFS_NODE_ATTRIBUTE_1=UN-LOCODE:RU MSK +NEOFS_NODE_RELAY=true # Storage engine section NEOFS_STORAGE_SHARD_NUM=2 diff --git a/config/example/node.json b/config/example/node.json index 4b3e964b3..45cbfaa03 100644 --- a/config/example/node.json +++ b/config/example/node.json @@ -10,6 +10,13 @@ "address": "127.0.0.1:9090", "shutdown_timeout": "15s" }, + "node": { + "key": "path/hex/WIF", + "address": "s01.neofs.devenv:8080", + "attribute_0": "Price:11", + "attribute_1": "UN-LOCODE:RU MSK", + "relay": true + }, "storage": { "shard_num": 2, "shard": { diff --git a/config/example/node.yaml b/config/example/node.yaml index 9b37515b7..a62da5c6b 100644 --- a/config/example/node.yaml +++ b/config/example/node.yaml @@ -9,6 +9,13 @@ metrics: address: 127.0.0.1:9090 shutdown_timeout: 15s +node: + key: path/hex/WIF + address: s01.neofs.devenv:8080 + attribute_0: "Price:11" + attribute_1: UN-LOCODE:RU MSK + relay: true + storage: shard_num: 2 shard: