github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/secret-revoke.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  	"github.com/juju/names/v5"
    11  
    12  	jujucmd "github.com/juju/juju/cmd"
    13  	"github.com/juju/juju/core/secrets"
    14  )
    15  
    16  type secretRevokeCommand struct {
    17  	cmd.CommandBase
    18  	ctx Context
    19  
    20  	secretURL *secrets.URI
    21  	app       string
    22  	unit      string
    23  
    24  	relationId      int
    25  	relationIdProxy gnuflag.Value
    26  }
    27  
    28  // NewSecretRevokeCommand returns a command to revoke access to a secret.
    29  func NewSecretRevokeCommand(ctx Context) (cmd.Command, error) {
    30  	cmd := &secretRevokeCommand{ctx: ctx}
    31  	var err error
    32  	cmd.relationIdProxy, err = NewRelationIdValue(ctx, &cmd.relationId)
    33  	if err != nil {
    34  		return nil, errors.Trace(err)
    35  	}
    36  	return cmd, nil
    37  }
    38  
    39  // Info implements cmd.Command.
    40  func (c *secretRevokeCommand) Info() *cmd.Info {
    41  	doc := `
    42  Revoke access to view the value of a specified secret.
    43  Access may be revoked from an application (all units of
    44  that application lose access), or from a specified unit.
    45  If run in a relation hook, the related application's 
    46  access is revoked, unless a uni is specified, in which
    47  case just that unit's access is revoked.'
    48  
    49  Examples:
    50      secret-revoke secret:9m4e2mr0ui3e8a215n4g
    51      secret-revoke secret:9m4e2mr0ui3e8a215n4g --relation 1
    52      secret-revoke secret:9m4e2mr0ui3e8a215n4g --app mediawiki
    53      secret-revoke secret:9m4e2mr0ui3e8a215n4g --unit mediawiki/6
    54  `
    55  	return jujucmd.Info(&cmd.Info{
    56  		Name:    "secret-revoke",
    57  		Args:    "<ID>",
    58  		Purpose: "revoke access to a secret",
    59  		Doc:     doc,
    60  	})
    61  }
    62  
    63  // SetFlags implements cmd.Command.
    64  func (c *secretRevokeCommand) SetFlags(f *gnuflag.FlagSet) {
    65  	f.StringVar(&c.app, "app", "", "the application to revoke access")
    66  	f.StringVar(&c.app, "application", "", "")
    67  	f.StringVar(&c.unit, "unit", "", "the unit to revoke access")
    68  	f.Var(c.relationIdProxy, "r", "the relation for which to revoke the grant")
    69  	f.Var(c.relationIdProxy, "relation", "the relation for which to revoke the grant")
    70  }
    71  
    72  // Init implements cmd.Command.
    73  func (c *secretRevokeCommand) Init(args []string) error {
    74  	if len(args) < 1 {
    75  		return errors.New("missing secret URI")
    76  	}
    77  	var err error
    78  	if c.secretURL, err = secrets.ParseURI(args[0]); err != nil {
    79  		return errors.Trace(err)
    80  	}
    81  	if c.app != "" {
    82  		if !names.IsValidApplication(c.app) {
    83  			return errors.NotValidf("application %q", c.app)
    84  		}
    85  	}
    86  	if c.unit != "" {
    87  		if !names.IsValidUnit(c.unit) {
    88  			return errors.NotValidf("unit %q", c.unit)
    89  		}
    90  	}
    91  	if c.app != "" && c.unit != "" {
    92  		return errors.New("specify only one of application or unit")
    93  	}
    94  	if c.relationId >= 0 {
    95  		r, err := c.ctx.Relation(c.relationId)
    96  		if err != nil {
    97  			return errors.Trace(err)
    98  		}
    99  		if c.app != "" {
   100  			return errors.New("do not specify both relation and app")
   101  		}
   102  		c.app = r.RemoteApplicationName()
   103  	}
   104  	if c.app == "" && c.unit == "" {
   105  		return errors.New("missing relation or application or unit")
   106  	}
   107  	return cmd.CheckEmpty(args[1:])
   108  }
   109  
   110  // Run implements cmd.Command.
   111  func (c *secretRevokeCommand) Run(_ *cmd.Context) error {
   112  	args := &SecretGrantRevokeArgs{}
   113  	if c.app != "" {
   114  		args.ApplicationName = &c.app
   115  	}
   116  	if c.unit != "" {
   117  		args.UnitName = &c.unit
   118  	}
   119  
   120  	return c.ctx.RevokeSecret(c.secretURL, args)
   121  }