diff --git a/cmd/s3-authmate/modules/obtain-secret.go b/cmd/s3-authmate/modules/obtain-secret.go new file mode 100644 index 0000000..61cb1de --- /dev/null +++ b/cmd/s3-authmate/modules/obtain-secret.go @@ -0,0 +1,94 @@ +package modules + +import ( + "context" + "fmt" + "os" + "strings" + + "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/authmate" + "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/wallet" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/urfave/cli/v2" +) + +var obtainSecretCmd = &cobra.Command{ + Use: "obtain-secret", + Short: "Obtain a secret from FrostFS network", + Long: "Gets generated secret from credential object (accessbox)", + Example: `frostfs-s3-authmate obtain-secret --wallet wallet.json --peer s01.neofs.devenv:8080 --gate-wallet s3-wallet.json --access-key-id EC3tyWpTEKfGNS888PFBpwQzZTrnwDXReGjgAxa8Em1h037VoWktUZCAk1LVA5SvVbVd2NHHb2NQm9jhcd5WFU5VD`, + RunE: runObtainSecretCmd, +} + +const ( + gateWalletFlag = "gate-wallet" + gateAddressFlag = "gate-address" + accessKeyIDFlag = "access-key-id" +) + +const ( + walletGatePassphraseCfg = "wallet.gate.passphrase" +) + +func initObtainSecretCmd() { + obtainSecretCmd.Flags().String(walletFlag, "", "Path to the wallet that will be owner of the credentials") + obtainSecretCmd.Flags().String(addressFlag, "", "Address of the wallet account") + obtainSecretCmd.Flags().String(peerFlag, "", "Address of a frostfs peer to connect to") + obtainSecretCmd.Flags().String(gateWalletFlag, "", "Path to the s3 gateway wallet to decrypt accessbox") + obtainSecretCmd.Flags().String(gateAddressFlag, "", "Address of the s3 gateway wallet account") + obtainSecretCmd.Flags().String(accessKeyIDFlag, "", "Access key id of s3 credential for which secret must be obtained") + obtainSecretCmd.Flags().Duration(poolDialTimeoutFlag, defaultPoolDialTimeout, "Timeout for connection to the node in pool to be established") + obtainSecretCmd.Flags().Duration(poolHealthcheckTimeoutFlag, defaultPoolHealthcheckTimeout, "Timeout for request to node to decide if it is alive") + obtainSecretCmd.Flags().Duration(poolRebalanceIntervalFlag, defaultPoolRebalanceInterval, "Interval for updating nodes health status") + obtainSecretCmd.Flags().Duration(poolStreamTimeoutFlag, defaultPoolStreamTimeout, "Timeout for individual operation in streaming RPC") + + _ = obtainSecretCmd.MarkFlagRequired(walletFlag) + _ = obtainSecretCmd.MarkFlagRequired(peerFlag) + _ = obtainSecretCmd.MarkFlagRequired(gateWalletFlag) + _ = obtainSecretCmd.MarkFlagRequired(accessKeyIDFlag) +} + +func runObtainSecretCmd(cmd *cobra.Command, _ []string) error { + ctx, cancel := context.WithTimeout(cmd.Context(), viper.GetDuration(timeoutFlag)) + defer cancel() + + log := getLogger() + + password := wallet.GetPassword(viper.GetViper(), walletPassphraseCfg) + key, err := wallet.GetKeyFromPath(viper.GetString(walletFlag), viper.GetString(addressFlag), password) + if err != nil { + return fmt.Errorf("failed to load frostfs private key: %s", err) + } + + gatePassword := wallet.GetPassword(viper.GetViper(), walletGatePassphraseCfg) + gateKey, err := wallet.GetKeyFromPath(viper.GetString(gateWalletFlag), viper.GetString(gateAddressFlag), gatePassword) + if err != nil { + return fmt.Errorf("failed to load s3 gate private key: %s", err) + } + + poolCfg := PoolConfig{ + Key: &key.PrivateKey, + Address: viper.GetString(peerFlag), + DialTimeout: viper.GetDuration(poolDialTimeoutFlag), + HealthcheckTimeout: viper.GetDuration(poolHealthcheckTimeoutFlag), + StreamTimeout: viper.GetDuration(poolStreamTimeoutFlag), + RebalanceInterval: viper.GetDuration(poolRebalanceIntervalFlag), + } + + frostFS, err := createFrostFS(ctx, log, poolCfg) + if err != nil { + return cli.Exit(fmt.Sprintf("failed to create FrostFS component: %s", err), 2) + } + + obtainSecretOptions := &authmate.ObtainSecretOptions{ + SecretAddress: strings.Replace(viper.GetString(accessKeyIDFlag), "0", "/", 1), + GatePrivateKey: gateKey, + } + + if err = authmate.New(log, frostFS).ObtainSecret(ctx, os.Stdout, obtainSecretOptions); err != nil { + return fmt.Errorf("failed to obtain secret: %s", err) + } + + return nil +} diff --git a/cmd/s3-authmate/modules/root.go b/cmd/s3-authmate/modules/root.go index 6b664ef..b42f9d1 100644 --- a/cmd/s3-authmate/modules/root.go +++ b/cmd/s3-authmate/modules/root.go @@ -56,4 +56,7 @@ GoVersion: {{ runtimeVersion }} rootCmd.AddCommand(issueSecretCmd) initIssueSecretCmd() + + rootCmd.AddCommand(obtainSecretCmd) + initObtainSecretCmd() }