package control import ( "context" "crypto/ecdsa" "sync/atomic" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/engine" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/replicator" policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine" ) // Server is an entity that serves // Control service on storage node. type Server struct { *cfg // TODO (aarifullin): this counter is used to assign id for rule chains // added as local overrides and will be removed as soon as in-memory // implementation will be replaced. apeChainCounter atomic.Uint32 } // HealthChecker is component interface for calculating // the current health status of a node. type HealthChecker interface { // NetmapStatus must calculate and return current status of the node in FrostFS network map. // // If status can not be calculated for any reason, // control.netmapStatus_STATUS_UNDEFINED should be returned. NetmapStatus() control.NetmapStatus // HealthStatus must calculate and return current health status of the node application. // // If status can not be calculated for any reason, // control.HealthStatus_HEALTH_STATUS_UNDEFINED should be returned. HealthStatus() control.HealthStatus } // NodeState is an interface of storage node network state. type NodeState interface { // SetNetmapStatus switches the storage node to the given network status. // // If status is control.NetmapStatus_MAINTENANCE and maintenance is allowed // in the network settings, the node additionally starts local maintenance. SetNetmapStatus(ctx context.Context, st control.NetmapStatus) error // ForceMaintenance works like SetNetmapStatus(control.NetmapStatus_MAINTENANCE) // but starts local maintenance regardless of the network settings. ForceMaintenance(ctx context.Context) error GetNetmapStatus() (control.NetmapStatus, uint64, error) } // LocalOverrideStorageDecorator interface provides methods to decorate LocalOverrideEngine // interface methods. type LocalOverrideStorageDecorator interface { // LocalStorage method can be decorated by using sync primitives in the case if the local // override storage state should be consistent for chain router. LocalStorage() policyengine.LocalOverrideStorage } // Option of the Server's constructor. type Option func(*cfg) type cfg struct { key *ecdsa.PrivateKey allowedKeys [][]byte healthChecker HealthChecker netMapSrc netmap.Source cnrSrc container.Source localOverrideStorage LocalOverrideStorageDecorator replicator *replicator.Replicator nodeState NodeState treeService TreeService s *engine.StorageEngine } func defaultCfg() *cfg { return &cfg{} } // New creates, initializes and returns new Server instance. func New(opts ...Option) *Server { c := defaultCfg() for _, opt := range opts { opt(c) } return &Server{ cfg: c, } } // WithKey returns option to set private key // used for signing responses. func WithKey(key *ecdsa.PrivateKey) Option { return func(c *cfg) { c.key = key } } // WithAuthorizedKeys returns option to add list of public // keys that have rights to use Control service. func WithAuthorizedKeys(keys [][]byte) Option { return func(c *cfg) { c.allowedKeys = append(c.allowedKeys, keys...) } } // WithHealthChecker returns option to set component // to calculate node health status. func WithHealthChecker(hc HealthChecker) Option { return func(c *cfg) { c.healthChecker = hc } } // WithNetMapSource returns option to set network map storage. func WithNetMapSource(netMapSrc netmap.Source) Option { return func(c *cfg) { c.netMapSrc = netMapSrc } } // WithContainerSource returns option to set container storage. func WithContainerSource(cnrSrc container.Source) Option { return func(c *cfg) { c.cnrSrc = cnrSrc } } // WithReplicator returns option to set network map storage. func WithReplicator(r *replicator.Replicator) Option { return func(c *cfg) { c.replicator = r } } // WithNodeState returns option to set node network state component. func WithNodeState(state NodeState) Option { return func(c *cfg) { c.nodeState = state } } // WithLocalStorage returns option to set local storage engine that // contains information about shards. func WithLocalStorage(engine *engine.StorageEngine) Option { return func(c *cfg) { c.s = engine } } // WithTreeService returns an option to set tree service. func WithTreeService(s TreeService) Option { return func(c *cfg) { c.treeService = s } } // WithLocalOverrideStorage returns the option to set access policy engine // chain override storage. func WithLocalOverrideStorage(localOverrideStorage LocalOverrideStorageDecorator) Option { return func(c *cfg) { c.localOverrideStorage = localOverrideStorage } }