frostfs-node/cmd/frostfs-node/config/node/config.go

300 lines
8.6 KiB
Go

package nodeconfig
import (
"fmt"
"io/fs"
"os"
"strconv"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
utilConfig "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/config"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
)
// PersistentSessionsConfig is a wrapper over "persistent_sessions" config section
// which provides access to persistent session tokens storage configuration of node.
type PersistentSessionsConfig struct {
cfg *config.Config
}
// PersistentStateConfig is a wrapper over "persistent_state" config section
// which provides access to persistent state storage configuration of node.
type PersistentStateConfig struct {
cfg *config.Config
}
// NotificationConfig is a wrapper over "notification" config section
// which provides access to object notification configuration of node.
type NotificationConfig struct {
cfg *config.Config
}
// PersistentPolicyRulesConfig is a wrapper over "persistent_policy_rules" config section
// which provides access to persistent policy rules storage configuration of node.
type PersistentPolicyRulesConfig struct {
cfg *config.Config
}
const (
subsection = "node"
persistentSessionsSubsection = "persistent_sessions"
persistentStateSubsection = "persistent_state"
notificationSubsection = "notification"
persistentPolicyRulesSubsection = "persistent_policy_rules"
attributePrefix = "attribute"
// PersistentStatePathDefault is a default path for persistent state file.
PersistentStatePathDefault = ".frostfs-storage-state"
// NotificationTimeoutDefault is a default timeout for object notification operation.
NotificationTimeoutDefault = 5 * time.Second
)
// Key returns the value of "key" config parameter
// from "node" section.
//
// If the value is not set, fallbacks to Wallet section.
//
// Panics if the value is incorrect filename of binary encoded private key.
func Key(c *config.Config) *keys.PrivateKey {
v := config.StringSafe(c.Sub(subsection), "key")
if v == "" {
return Wallet(c)
}
var (
key *keys.PrivateKey
err error
data []byte
)
if data, err = os.ReadFile(v); err == nil {
key, err = keys.NewPrivateKeyFromBytes(data)
}
if err != nil {
panic(fmt.Errorf("invalid private key in node section: %w", err))
}
return key
}
// Wallet returns the value of a node private key from "node" section.
//
// Panics if section contains invalid values.
func Wallet(c *config.Config) *keys.PrivateKey {
v := c.Sub(subsection).Sub("wallet")
acc, err := utilConfig.LoadAccount(
config.String(v, "path"),
config.String(v, "address"),
config.String(v, "password"))
if err != nil {
panic(fmt.Errorf("invalid wallet config: %w", err))
}
return acc.PrivateKey()
}
type stringAddressGroup []string
func (x stringAddressGroup) IterateAddresses(f func(string) bool) {
for i := range x {
if f(x[i]) {
break
}
}
}
func (x stringAddressGroup) NumberOfAddresses() int {
return len(x)
}
// BootstrapAddresses returns the value of "addresses" config parameter
// from "node" section as network.AddressGroup.
//
// Panics if the value is not a string list of valid NeoFS network addresses.
func BootstrapAddresses(c *config.Config) (addr network.AddressGroup) {
v := config.StringSlice(c.Sub(subsection), "addresses")
err := addr.FromIterator(stringAddressGroup(v))
if err != nil {
panic(fmt.Errorf("could not parse bootstrap addresses: %w", 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 the value of "relay" config parameter
// from "node" section.
//
// Returns false if the value is not set.
func Relay(c *config.Config) bool {
return config.BoolSafe(c.Sub(subsection), "relay")
}
// PersistentSessions returns structure that provides access to "persistent_sessions"
// subsection of "node" section.
func PersistentSessions(c *config.Config) PersistentSessionsConfig {
return PersistentSessionsConfig{
c.Sub(subsection).Sub(persistentSessionsSubsection),
}
}
// Path returns the value of "path" config parameter.
func (p PersistentSessionsConfig) Path() string {
return config.String(p.cfg, "path")
}
// PersistentState returns structure that provides access to "persistent_state"
// subsection of "node" section.
func PersistentState(c *config.Config) PersistentStateConfig {
return PersistentStateConfig{
c.Sub(subsection).Sub(persistentStateSubsection),
}
}
// Path returns the value of "path" config parameter.
//
// Returns PersistentStatePathDefault if the value is not a non-empty string.
func (p PersistentStateConfig) Path() string {
v := config.String(p.cfg, "path")
if v != "" {
return v
}
return PersistentStatePathDefault
}
// Notification returns structure that provides access to "notification"
// subsection of "node" section.
func Notification(c *config.Config) NotificationConfig {
return NotificationConfig{
c.Sub(subsection).Sub(notificationSubsection),
}
}
// Enabled returns the value of "enabled" config parameter from "notification"
// subsection of "node" section.
//
// Returns false if the value is not presented.
func (n NotificationConfig) Enabled() bool {
return config.BoolSafe(n.cfg, "enabled")
}
// DefaultTopic returns the value of "default_topic" config parameter from
// "notification" subsection of "node" section.
//
// Returns empty string if the value is not presented.
func (n NotificationConfig) DefaultTopic() string {
return config.StringSafe(n.cfg, "default_topic")
}
// Endpoint returns the value of "endpoint" config parameter from "notification"
// subsection of "node" section.
//
// Returns empty string if the value is not presented.
func (n NotificationConfig) Endpoint() string {
return config.StringSafe(n.cfg, "endpoint")
}
// Timeout returns the value of "timeout" config parameter from "notification"
// subsection of "node" section.
//
// Returns NotificationTimeoutDefault if the value is not positive.
func (n NotificationConfig) Timeout() time.Duration {
v := config.DurationSafe(n.cfg, "timeout")
if v > 0 {
return v
}
return NotificationTimeoutDefault
}
// CertPath returns the value of "certificate_path" config parameter from "notification"
// subsection of "node" section.
//
// Returns empty string if the value is not presented.
func (n NotificationConfig) CertPath() string {
return config.StringSafe(n.cfg, "certificate")
}
// KeyPath returns the value of "key_path" config parameter from
// "notification" subsection of "node" section.
//
// Returns empty string if the value is not presented.
func (n NotificationConfig) KeyPath() string {
return config.StringSafe(n.cfg, "key")
}
// CAPath returns the value of "ca_path" config parameter from
// "notification" subsection of "node" section.
//
// Returns empty string if the value is not presented.
func (n NotificationConfig) CAPath() string {
return config.StringSafe(n.cfg, "ca")
}
const (
// PermDefault is a default permission bits for local override storage file.
PermDefault = 0o644
)
// PersistentPolicyRules returns structure that provides access to "persistent_policy_rules"
// subsection of "node" section.
func PersistentPolicyRules(c *config.Config) PersistentPolicyRulesConfig {
return PersistentPolicyRulesConfig{
c.Sub(subsection).Sub(persistentPolicyRulesSubsection),
}
}
// Path returns the value of "path" config parameter.
//
// Returns empty string if missing, for compatibility with older configurations.
func (l PersistentPolicyRulesConfig) Path() string {
return config.StringSafe(l.cfg, "path")
}
// Perm returns the value of "perm" config parameter as a fs.FileMode.
//
// Returns PermDefault if the value is not a positive number.
func (l PersistentPolicyRulesConfig) Perm() fs.FileMode {
p := config.UintSafe((*config.Config)(l.cfg), "perm")
if p == 0 {
p = PermDefault
}
return fs.FileMode(p)
}
// NoSync returns the value of "no_sync" config parameter as a bool value.
//
// Returns false if the value is not a boolean.
func (l PersistentPolicyRulesConfig) NoSync() bool {
return config.BoolSafe((*config.Config)(l.cfg), "no_sync")
}
// CompatibilityMode returns true if need to run node in compatibility with previous versions mode.
func CompatibilityMode(c *config.Config) bool {
return config.BoolSafe(c.Sub(subsection), "kludge_compatibility_mode")
}