github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/secret-get.go (about)

     1  // Copyright 2021 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package jujuc
     5  
     6  import (
     7  	"github.com/juju/cmd/v3"
     8  	"github.com/juju/errors"
     9  	"github.com/juju/gnuflag"
    10  
    11  	jujucmd "github.com/juju/juju/cmd"
    12  	"github.com/juju/juju/core/secrets"
    13  )
    14  
    15  type secretGetCommand struct {
    16  	cmd.CommandBase
    17  	ctx Context
    18  	out cmd.Output
    19  
    20  	secretUri *secrets.URI
    21  	label     string
    22  	key       string
    23  	peek      bool
    24  	refresh   bool
    25  }
    26  
    27  // NewSecretGetCommand returns a command to get a secret value.
    28  func NewSecretGetCommand(ctx Context) (cmd.Command, error) {
    29  	return &secretGetCommand{ctx: ctx}, nil
    30  }
    31  
    32  // Info implements cmd.Command.
    33  func (c *secretGetCommand) Info() *cmd.Info {
    34  	doc := `
    35  Get the content of a secret with a given secret ID.
    36  The first time the value is fetched, the latest revision is used.
    37  Subsequent calls will always return this same revision unless
    38  --peek or --refresh are used.
    39  Using --peek will fetch the latest revision just this time.
    40  Using --refresh will fetch the latest revision and continue to
    41  return the same revision next time unless --peek or --refresh is used.
    42  
    43  Either the ID or label can be used to identify the secret.
    44  
    45  Examples
    46      secret-get secret:9m4e2mr0ui3e8a215n4g
    47      secret-get secret:9m4e2mr0ui3e8a215n4g token
    48      secret-get secret:9m4e2mr0ui3e8a215n4g token#base64
    49      secret-get secret:9m4e2mr0ui3e8a215n4g --format json
    50      secret-get secret:9m4e2mr0ui3e8a215n4g --peek
    51      secret-get secret:9m4e2mr0ui3e8a215n4g --refresh
    52      secret-get secret:9m4e2mr0ui3e8a215n4g --label db-password
    53  `
    54  	return jujucmd.Info(&cmd.Info{
    55  		Name:    "secret-get",
    56  		Args:    "<ID> [key[#base64]]",
    57  		Purpose: "get the content of a secret",
    58  		Doc:     doc,
    59  	})
    60  }
    61  
    62  // SetFlags implements cmd.Command.
    63  func (c *secretGetCommand) SetFlags(f *gnuflag.FlagSet) {
    64  	c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{
    65  		"yaml": cmd.FormatYaml,
    66  		"json": cmd.FormatJson,
    67  	})
    68  	f.StringVar(&c.label, "label", "", "a label used to identify the secret in hooks")
    69  	f.BoolVar(&c.peek, "peek", false,
    70  		`get the latest revision just this time`)
    71  	f.BoolVar(&c.refresh, "refresh", false,
    72  		`get the latest revision and also get this same revision for subsequent calls`)
    73  }
    74  
    75  // Init implements cmd.Command.
    76  func (c *secretGetCommand) Init(args []string) (err error) {
    77  	if len(args) > 0 {
    78  		c.secretUri, err = secrets.ParseURI(args[0])
    79  		if err != nil {
    80  			return errors.NotValidf("secret URI %q", args[0])
    81  		}
    82  		args = args[1:]
    83  	}
    84  
    85  	if c.secretUri == nil && c.label == "" {
    86  		return errors.New("require either a secret URI or label")
    87  	}
    88  
    89  	if c.peek && c.refresh {
    90  		return errors.New("specify one of --peek or --refresh but not both")
    91  	}
    92  	if len(args) > 0 {
    93  		c.key = args[0]
    94  		return cmd.CheckEmpty(args[1:])
    95  	}
    96  	return cmd.CheckEmpty(args)
    97  }
    98  
    99  // Run implements cmd.Command.
   100  func (c *secretGetCommand) Run(ctx *cmd.Context) error {
   101  	value, err := c.ctx.GetSecret(c.secretUri, c.label, c.refresh, c.peek)
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	var val interface{}
   107  	val, err = value.Values()
   108  	if err != nil {
   109  		return err
   110  	}
   111  	if c.key == "" {
   112  		return c.out.Write(ctx, val)
   113  	}
   114  
   115  	val, err = value.KeyValue(c.key)
   116  	if err != nil {
   117  		return err
   118  	}
   119  	return c.out.Write(ctx, val)
   120  }