Skip to content

Commit

Permalink
control: add network management via ir control
Browse files Browse the repository at this point in the history
New `neofs-cli control notary` with `list`, `request` and `sign` commands.
- `list` - get list of all notary requests from notary pool.
- `request` - send a notary request with one of the following methods:
`newEpoch`, `setConfig` and `removeNode`.
- `sign` - sign the notary request using a hash.

Closes #2088, #1866.

Signed-off-by: Andrey Butusov <[email protected]>
  • Loading branch information
End-rey committed Dec 19, 2024
1 parent 474d541 commit cecb448
Show file tree
Hide file tree
Showing 23 changed files with 2,595 additions and 102 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog for NeoFS Node
## [Unreleased]

### Added
- `neofs-cli control notary` with `list`, `request` and `sign` commands (#3059)

### Fixed
- Incomplete metabase migration to version 3 leading to node start failure (#3048)
Expand Down
20 changes: 20 additions & 0 deletions cmd/neofs-cli/modules/control/notary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package control

import (
"github.com/spf13/cobra"
)

var notaryCmd = &cobra.Command{
Use: "notary",
Short: "Commands with notary request with alphabet key of inner ring node",
}

func initControlNotaryCmd() {
notaryCmd.AddCommand(listNotaryCmd)
notaryCmd.AddCommand(notaryRequestCmd)
notaryCmd.AddCommand(notarySignCmd)

initControlNotaryListCmd()
initControlNotaryRequestCmd()
initControlNotarySignCmd()

Check warning on line 19 in cmd/neofs-cli/modules/control/notary.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary.go#L12-L19

Added lines #L12 - L19 were not covered by tests
}
67 changes: 67 additions & 0 deletions cmd/neofs-cli/modules/control/notary_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package control

import (
"fmt"

rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
ircontrol "github.com/nspcc-dev/neofs-node/pkg/services/control/ir"
ircontrolsrv "github.com/nspcc-dev/neofs-node/pkg/services/control/ir/server"
"github.com/spf13/cobra"
)

var listNotaryCmd = &cobra.Command{
Use: "list",
Short: "Get list of all notary requests in network",
Long: "Get list of all notary requests in network",
Args: cobra.NoArgs,
RunE: listNotary,
}

func initControlNotaryListCmd() {
initControlFlags(listNotaryCmd)

Check warning on line 23 in cmd/neofs-cli/modules/control/notary_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_list.go#L22-L23

Added lines #L22 - L23 were not covered by tests
}

func listNotary(cmd *cobra.Command, _ []string) error {
ctx, cancel := commonflags.GetCommandContext(cmd)
defer cancel()

pk, err := key.Get(cmd)
if err != nil {
return err
}

Check warning on line 33 in cmd/neofs-cli/modules/control/notary_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_list.go#L26-L33

Added lines #L26 - L33 were not covered by tests

cli, err := getClient(ctx)
if err != nil {
return err
}

Check warning on line 38 in cmd/neofs-cli/modules/control/notary_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_list.go#L35-L38

Added lines #L35 - L38 were not covered by tests

req := new(ircontrol.NotaryListRequest)

req.SetBody(new(ircontrol.NotaryListRequest_Body))

err = ircontrolsrv.SignMessage(pk, req)
if err != nil {
return fmt.Errorf("could not sign request: %w", err)
}

Check warning on line 47 in cmd/neofs-cli/modules/control/notary_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_list.go#L40-L47

Added lines #L40 - L47 were not covered by tests

var resp *ircontrol.NotaryListResponse
err = cli.ExecRaw(func(client *rawclient.Client) error {
resp, err = ircontrol.NotaryList(client, req)
return err
})
if err != nil {
return fmt.Errorf("rpc error: %w", err)
}

Check warning on line 56 in cmd/neofs-cli/modules/control/notary_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_list.go#L49-L56

Added lines #L49 - L56 were not covered by tests

err = verifyResponse(resp.GetSignature(), resp.GetBody())
if err != nil {
return err
}

Check warning on line 61 in cmd/neofs-cli/modules/control/notary_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_list.go#L58-L61

Added lines #L58 - L61 were not covered by tests

hashes := resp.GetBody().GetTransactions()

cmd.Printf("Hashes: %s\n", hashes)
return nil

Check warning on line 66 in cmd/neofs-cli/modules/control/notary_list.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_list.go#L63-L66

Added lines #L63 - L66 were not covered by tests
}
173 changes: 173 additions & 0 deletions cmd/neofs-cli/modules/control/notary_request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package control

import (
"errors"
"fmt"
"strconv"
"strings"

rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
ircontrol "github.com/nspcc-dev/neofs-node/pkg/services/control/ir"
ircontrolsrv "github.com/nspcc-dev/neofs-node/pkg/services/control/ir/server"
"github.com/spf13/cobra"
)

const (
netmapEpochKey = "EpochDuration"
netmapMaxObjectSizeKey = "MaxObjectSize"
netmapAuditFeeKey = "AuditFee"
netmapContainerFeeKey = "ContainerFee"
netmapContainerAliasFeeKey = "ContainerAliasFee"
netmapEigenTrustIterationsKey = "EigenTrustIterations"
netmapEigenTrustAlphaKey = "EigenTrustAlpha"
netmapBasicIncomeRateKey = "BasicIncomeRate"
netmapInnerRingCandidateFeeKey = "InnerRingCandidateFee"
netmapWithdrawFeeKey = "WithdrawFee"
netmapHomomorphicHashDisabledKey = "HomomorphicHashingDisabled"
netmapMaintenanceAllowedKey = "MaintenanceModeAllowed"

notaryMethodFlag = "method"
notaryForceConfigSetFlag = "force"
)

var notaryRequestCmd = &cobra.Command{
Use: "request",
Short: "Create and send a notary request",
Long: "Create and send a notary request with one of the following methods:\n" +
"- newEpoch, transaction for creating of new NeoFS epoch event in FS chain, no args\n" +
"- setConfig, transaction to add/update global config value in the NeoFS network, args in the form key1=val1\n" +
"- removeNode, transaction to move nodes to the Offline state in the candidates list, args are the public keys of the nodes",
RunE: notaryRequest,
}

func initControlNotaryRequestCmd() {
initControlFlags(notaryRequestCmd)

flags := notaryRequestCmd.Flags()
flags.String(notaryMethodFlag, "", "Requested method")
flags.Bool(notaryForceConfigSetFlag, false, "Only for 'setConfig' method. Force setting not well-known configuration key.")

Check warning on line 50 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L45-L50

Added lines #L45 - L50 were not covered by tests
}

func notaryRequest(cmd *cobra.Command, args []string) error {
ctx, cancel := commonflags.GetCommandContext(cmd)
defer cancel()

pk, err := key.Get(cmd)
if err != nil {
return err
}

Check warning on line 60 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L53-L60

Added lines #L53 - L60 were not covered by tests

cli, err := getClient(ctx)
if err != nil {
return err
}

Check warning on line 65 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L62-L65

Added lines #L62 - L65 were not covered by tests

req := new(ircontrol.NotaryRequestRequest)
body := new(ircontrol.NotaryRequestRequest_Body)
req.SetBody(body)

method, _ := cmd.Flags().GetString(notaryMethodFlag)
body.SetMethod(method)

switch method {
case "newEpoch":
if len(args) > 0 {
cmd.Println("method 'newEpoch', but the args provided, they will be ignored")
}
case "setConfig":
forceFlag, _ := cmd.Flags().GetBool(notaryForceConfigSetFlag)

if len(args) == 0 {
return fmt.Errorf("no arguments provided for 'setConfig'")
}

Check warning on line 84 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L67-L84

Added lines #L67 - L84 were not covered by tests

bodyArgs := make([]string, 0, len(args)*2)
for _, arg := range args {
k, v, err := parseConfigPair(arg, forceFlag)
if err != nil {
return err
}

Check warning on line 91 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L86-L91

Added lines #L86 - L91 were not covered by tests

bodyArgs = append(bodyArgs, k, fmt.Sprint(v))

Check warning on line 93 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L93

Added line #L93 was not covered by tests
}
body.SetArgs(bodyArgs)
case "removeNode":
if len(args) == 0 {
return errors.New("method 'removeNode', at least 1 argument must be provided - the public key of the node")
}
body.SetArgs(args)

Check warning on line 100 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L95-L100

Added lines #L95 - L100 were not covered by tests
}

err = ircontrolsrv.SignMessage(pk, req)
if err != nil {
return fmt.Errorf("could not sign request: %w", err)
}

Check warning on line 106 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L103-L106

Added lines #L103 - L106 were not covered by tests

var resp *ircontrol.NotaryRequestResponse
err = cli.ExecRaw(func(client *rawclient.Client) error {
resp, err = ircontrol.NotaryRequest(client, req)
return err
})
if err != nil {
return fmt.Errorf("rpc error: %w", err)
}

Check warning on line 115 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L108-L115

Added lines #L108 - L115 were not covered by tests

err = verifyResponse(resp.GetSignature(), resp.GetBody())
if err != nil {
return err
}

Check warning on line 120 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L117-L120

Added lines #L117 - L120 were not covered by tests

hashes := resp.GetBody().GetHash()

cmd.Printf("Tx Hash: %s\n", hashes)
return nil

Check warning on line 125 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L122-L125

Added lines #L122 - L125 were not covered by tests
}

func parseConfigPair(kvStr string, force bool) (key string, val any, err error) {
kv := strings.SplitN(kvStr, "=", 2)
if len(kv) != 2 {
return "", nil, fmt.Errorf("invalid parameter format: must be 'key=val', got: %s", kvStr)
}

Check warning on line 132 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L128-L132

Added lines #L128 - L132 were not covered by tests

key = kv[0]
valRaw := kv[1]

switch key {

Check warning on line 137 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L134-L137

Added lines #L134 - L137 were not covered by tests
case netmapAuditFeeKey, netmapBasicIncomeRateKey,
netmapContainerFeeKey, netmapContainerAliasFeeKey,
netmapEigenTrustIterationsKey,
netmapEpochKey, netmapInnerRingCandidateFeeKey,
netmapMaxObjectSizeKey, netmapWithdrawFeeKey:
val, err = strconv.ParseInt(valRaw, 10, 64)
if err != nil {
err = fmt.Errorf("invalid value for %s key, expected int, got '%s'", key, valRaw)
}
case netmapEigenTrustAlphaKey:
// just check that it could
// be parsed correctly
_, err = strconv.ParseFloat(kv[1], 64)
if err != nil {
err = fmt.Errorf("invalid value for %s key, expected float, got '%s'", key, valRaw)
}

Check warning on line 153 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L142-L153

Added lines #L142 - L153 were not covered by tests

val = valRaw
case netmapHomomorphicHashDisabledKey, netmapMaintenanceAllowedKey:
val, err = strconv.ParseBool(valRaw)
if err != nil {
err = fmt.Errorf("invalid value for %s key, expected bool, got '%s'", key, valRaw)
}

Check warning on line 160 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L155-L160

Added lines #L155 - L160 were not covered by tests

default:
if !force {
return "", nil, fmt.Errorf(
"'%s' key is not well-known, use '--%s' flag if want to set it anyway",
key, notaryForceConfigSetFlag)
}

Check warning on line 167 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L162-L167

Added lines #L162 - L167 were not covered by tests

val = valRaw

Check warning on line 169 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L169

Added line #L169 was not covered by tests
}

return

Check warning on line 172 in cmd/neofs-cli/modules/control/notary_request.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_request.go#L172

Added line #L172 was not covered by tests
}
71 changes: 71 additions & 0 deletions cmd/neofs-cli/modules/control/notary_sign.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package control

import (
"fmt"

rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags"
"github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key"
ircontrol "github.com/nspcc-dev/neofs-node/pkg/services/control/ir"
ircontrolsrv "github.com/nspcc-dev/neofs-node/pkg/services/control/ir/server"
"github.com/spf13/cobra"
)

var notarySignHashFlag string

var notarySignCmd = &cobra.Command{
Use: "sign",
Short: "Sign notary request with it hash",
Long: "Sign notary request with it hash",
Args: cobra.NoArgs,
RunE: notarySign,
}

func initControlNotarySignCmd() {
initControlFlags(notarySignCmd)

flags := notarySignCmd.Flags()
flags.StringVar(&notarySignHashFlag, "hash", "", "hash of the notary request")

Check warning on line 28 in cmd/neofs-cli/modules/control/notary_sign.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_sign.go#L24-L28

Added lines #L24 - L28 were not covered by tests
}

func notarySign(cmd *cobra.Command, _ []string) error {
ctx, cancel := commonflags.GetCommandContext(cmd)
defer cancel()

pk, err := key.Get(cmd)
if err != nil {
return err
}

Check warning on line 38 in cmd/neofs-cli/modules/control/notary_sign.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_sign.go#L31-L38

Added lines #L31 - L38 were not covered by tests

cli, err := getClient(ctx)
if err != nil {
return err
}

Check warning on line 43 in cmd/neofs-cli/modules/control/notary_sign.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_sign.go#L40-L43

Added lines #L40 - L43 were not covered by tests

req := new(ircontrol.NotarySignRequest)
body := new(ircontrol.NotarySignRequest_Body)
req.SetBody(body)
body.SetHash(notarySignHashFlag)

err = ircontrolsrv.SignMessage(pk, req)
if err != nil {
return fmt.Errorf("could not sign request: %w", err)
}

Check warning on line 53 in cmd/neofs-cli/modules/control/notary_sign.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_sign.go#L45-L53

Added lines #L45 - L53 were not covered by tests

var resp *ircontrol.NotarySignResponse
err = cli.ExecRaw(func(client *rawclient.Client) error {
resp, err = ircontrol.NotarySign(client, req)
return err
})
if err != nil {
return fmt.Errorf("rpc error: %w", err)
}

Check warning on line 62 in cmd/neofs-cli/modules/control/notary_sign.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_sign.go#L55-L62

Added lines #L55 - L62 were not covered by tests

err = verifyResponse(resp.GetSignature(), resp.GetBody())
if err != nil {
return err
}

Check warning on line 67 in cmd/neofs-cli/modules/control/notary_sign.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_sign.go#L64-L67

Added lines #L64 - L67 were not covered by tests

cmd.Printf("Hashes: %s\n", notarySignHashFlag)
return nil

Check warning on line 70 in cmd/neofs-cli/modules/control/notary_sign.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/notary_sign.go#L69-L70

Added lines #L69 - L70 were not covered by tests
}
2 changes: 2 additions & 0 deletions cmd/neofs-cli/modules/control/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func init() {
shardsCmd,
synchronizeTreeCmd,
objectCmd,
notaryCmd,

Check warning on line 37 in cmd/neofs-cli/modules/control/root.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/root.go#L37

Added line #L37 was not covered by tests
)

initControlHealthCheckCmd()
Expand All @@ -42,4 +43,5 @@ func init() {
initControlShardsCmd()
initControlSynchronizeTreeCmd()
initControlObjectsCmd()
initControlNotaryCmd()

Check warning on line 46 in cmd/neofs-cli/modules/control/root.go

View check run for this annotation

Codecov / codecov/patch

cmd/neofs-cli/modules/control/root.go#L46

Added line #L46 was not covered by tests
}
1 change: 1 addition & 0 deletions pkg/innerring/innerring.go
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,7 @@ func serveControl(server *Server, log *zap.Logger, cfg *viper.Viper, errChan cha

p.SetPrivateKey(*server.key)
p.SetHealthChecker(server)
p.SetNetworkManager(server)

Check warning on line 1276 in pkg/innerring/innerring.go

View check run for this annotation

Codecov / codecov/patch

pkg/innerring/innerring.go#L1276

Added line #L1276 was not covered by tests

controlSvc := controlsrv.New(p,
controlsrv.WithAllowedKeys(authKeys),
Expand Down
Loading

0 comments on commit cecb448

Please sign in to comment.