package modules import ( "context" "fmt" "os" "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" ) 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().String(containerIDFlag, "", "CID or NNS name of auth container that contains provided credential (must be provided if custom access key id is used)") 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.Flags().String(rpcEndpointFlag, "", "NEO node RPC address (must be provided if container-id is nns name)") _ = 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 wrapPreparationError(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 wrapPreparationError(fmt.Errorf("failed to load s3 gate private key: %s", err)) } poolCfg := PoolConfig{ Key: key, 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 wrapFrostFSInitError(cli.Exit(fmt.Sprintf("failed to create FrostFS component: %s", err), 2)) } accessBox, accessKeyID, _, err := getAccessBoxID() if err != nil { return wrapPreparationError(err) } obtainSecretOptions := &authmate.ObtainSecretOptions{ Container: accessBox, AccessKeyID: accessKeyID, GatePrivateKey: gateKey, } if err = authmate.New(log, frostFS).ObtainSecret(ctx, os.Stdout, obtainSecretOptions); err != nil { return wrapBusinessLogicError(fmt.Errorf("failed to obtain secret: %s", err)) } return nil }