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 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)) } 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 wrapBusinessLogicError(fmt.Errorf("failed to obtain secret: %s", err)) } return nil }