[#983] node: Configure subnets

Add `subnet` sub-section to `node` section of storage node config. Add
`entries` value which allows to enumerate subnets for entrance. Add
`exit_zero` value which allows to not enter zero subnet.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-11-28 15:06:07 +03:00 committed by LeL
parent b27c72c02a
commit 0fb838b169
6 changed files with 98 additions and 0 deletions

View file

@ -145,3 +145,30 @@ func (p PersistentStateConfig) Path() string {
return PersistentStatePathDefault return PersistentStatePathDefault
} }
// SubnetConfig represents node configuration related to subnets.
type SubnetConfig config.Config
// Init initializes SubnetConfig from "subnet" sub-section of "node" section
// of the root config.
func (x *SubnetConfig) Init(root config.Config) {
*x = SubnetConfig(*root.Sub(subsection).Sub("subnet"))
}
// ExitZero returns value of "exit_zero" config parameter as bool.
// Returns false if value can not be cast.
func (x SubnetConfig) ExitZero() bool {
return config.BoolSafe((*config.Config)(&x), "exit_zero")
}
// IterateSubnets casts value of "entries" config parameter to string slice,
// iterates over all of its elements and passes them to f.
//
// Does nothing if value can not be cast to string slice.
func (x SubnetConfig) IterateSubnets(f func(string)) {
ids := config.StringSliceSafe((*config.Config)(&x), "entries")
for i := range ids {
f(ids[i])
}
}

View file

@ -35,6 +35,20 @@ func TestNodeSection(t *testing.T) {
require.Empty(t, attribute) require.Empty(t, attribute)
require.Equal(t, false, relay) require.Equal(t, false, relay)
require.Equal(t, PersistentStatePathDefault, persistatePath) require.Equal(t, PersistentStatePathDefault, persistatePath)
var subnetCfg SubnetConfig
subnetCfg.Init(*empty)
require.False(t, subnetCfg.ExitZero())
called := false
subnetCfg.IterateSubnets(func(string) {
called = true
})
require.False(t, called)
}) })
const path = "../../../../config/example/node" const path = "../../../../config/example/node"
@ -99,6 +113,20 @@ func TestNodeSection(t *testing.T) {
address.Uint160ToString(wKey.GetScriptHash())) address.Uint160ToString(wKey.GetScriptHash()))
require.Equal(t, "/state", persistatePath) require.Equal(t, "/state", persistatePath)
var subnetCfg SubnetConfig
subnetCfg.Init(*c)
require.True(t, subnetCfg.ExitZero())
var ids []string
subnetCfg.IterateSubnets(func(id string) {
ids = append(ids, id)
})
require.Equal(t, []string{"123", "456", "789"}, ids)
} }
configtest.ForEachFileType(path, fileConfigTest) configtest.ForEachFileType(path, fileConfigTest)

View file

@ -8,6 +8,7 @@ import (
netmapV2 "github.com/nspcc-dev/neofs-api-go/v2/netmap" netmapV2 "github.com/nspcc-dev/neofs-api-go/v2/netmap"
netmapGRPC "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" netmapGRPC "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/refs"
nodeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/node"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper" "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
"github.com/nspcc-dev/neofs-node/pkg/morph/event" "github.com/nspcc-dev/neofs-node/pkg/morph/event"
@ -17,6 +18,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/services/control" "github.com/nspcc-dev/neofs-node/pkg/services/control"
netmapService "github.com/nspcc-dev/neofs-node/pkg/services/netmap" netmapService "github.com/nspcc-dev/neofs-node/pkg/services/netmap"
netmapSDK "github.com/nspcc-dev/neofs-sdk-go/netmap" netmapSDK "github.com/nspcc-dev/neofs-sdk-go/netmap"
subnetid "github.com/nspcc-dev/neofs-sdk-go/subnet/id"
"go.uber.org/atomic" "go.uber.org/atomic"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -87,6 +89,8 @@ func initNetmapService(c *cfg) {
c.cfgNodeInfo.localInfo.SetAttributes(parseAttributes(c.appCfg)...) c.cfgNodeInfo.localInfo.SetAttributes(parseAttributes(c.appCfg)...)
c.cfgNodeInfo.localInfo.SetState(netmapSDK.NodeStateOffline) c.cfgNodeInfo.localInfo.SetState(netmapSDK.NodeStateOffline)
readSubnetCfg(c)
if c.cfgMorph.client == nil { if c.cfgMorph.client == nil {
initMorphComponents(c) initMorphComponents(c)
} }
@ -165,6 +169,29 @@ func initNetmapService(c *cfg) {
} }
} }
func readSubnetCfg(c *cfg) {
var subnetCfg nodeconfig.SubnetConfig
subnetCfg.Init(*c.appCfg)
var (
id subnetid.ID
err error
)
subnetCfg.IterateSubnets(func(idTxt string) {
err = id.UnmarshalText([]byte(idTxt))
fatalOnErrDetails("parse subnet entry", err)
c.cfgNodeInfo.localInfo.EnterSubnet(id)
})
if subnetCfg.ExitZero() {
subnetid.MakeZero(&id)
c.cfgNodeInfo.localInfo.ExitSubnet(id)
}
}
// bootstrapNode adds current node to the Network map. // bootstrapNode adds current node to the Network map.
// Must be called after initNetmapService. // Must be called after initNetmapService.
func bootstrapNode(c *cfg) { func bootstrapNode(c *cfg) {

View file

@ -16,6 +16,8 @@ NEOFS_NODE_ATTRIBUTE_0=Price:11
NEOFS_NODE_ATTRIBUTE_1="UN-LOCODE:RU MSK" NEOFS_NODE_ATTRIBUTE_1="UN-LOCODE:RU MSK"
NEOFS_NODE_RELAY=true NEOFS_NODE_RELAY=true
NEOFS_NODE_PERSISTENT_STATE_PATH=/state NEOFS_NODE_PERSISTENT_STATE_PATH=/state
NEOFS_NODE_SUBNET_EXIT_ZERO=true
NEOFS_NODE_SUBNET_ENTRIES=123 456 789
# gRPC section # gRPC section
NEOFS_GRPC_NUM=2 NEOFS_GRPC_NUM=2

View file

@ -28,6 +28,14 @@
"relay": true, "relay": true,
"persistent_state": { "persistent_state": {
"path": "/state" "path": "/state"
},
"subnet": {
"exit_zero": true,
"entries": [
"123",
"456",
"789"
]
} }
}, },
"grpc": { "grpc": {

View file

@ -25,6 +25,12 @@ node:
relay: true # start Storage node in relay mode without bootstrapping into the Network map relay: true # start Storage node in relay mode without bootstrapping into the Network map
persistent_state: # path to persistent state file of Storage node persistent_state: # path to persistent state file of Storage node
path: /state path: /state
subnet:
exit_zero: true # toggle entrance to zero subnet (overrides corresponding attribute and occurrence in `entries`)
entries: # list of IDs of subnets to enter in a text format of NeoFS API protocol (overrides corresponding attributes)
- 123
- 456
- 789
grpc: grpc:
num: 2 # total number of listener endpoints num: 2 # total number of listener endpoints