github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/secret-info-get.go (about) 1 // Copyright 2022 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc 5 6 import ( 7 "time" 8 9 "github.com/juju/cmd/v3" 10 "github.com/juju/errors" 11 "github.com/juju/gnuflag" 12 13 jujucmd "github.com/juju/juju/cmd" 14 "github.com/juju/juju/core/secrets" 15 ) 16 17 type secretInfoGetCommand struct { 18 cmd.CommandBase 19 ctx Context 20 out cmd.Output 21 22 secretUri *secrets.URI 23 label string 24 } 25 26 // NewSecretInfoGetCommand returns a command to get secret metadata. 27 func NewSecretInfoGetCommand(ctx Context) (cmd.Command, error) { 28 return &secretInfoGetCommand{ctx: ctx}, nil 29 } 30 31 // Info implements cmd.Command. 32 func (c *secretInfoGetCommand) Info() *cmd.Info { 33 doc := ` 34 Get the metadata of a secret with a given secret ID. 35 Either the ID or label can be used to identify the secret. 36 37 Examples 38 secret-info-get secret:9m4e2mr0ui3e8a215n4g 39 secret-info-get --label db-password 40 ` 41 return jujucmd.Info(&cmd.Info{ 42 Name: "secret-info-get", 43 Args: "<ID>", 44 Purpose: "get a secret's metadata info", 45 Doc: doc, 46 }) 47 } 48 49 // SetFlags implements cmd.Command. 50 func (c *secretInfoGetCommand) SetFlags(f *gnuflag.FlagSet) { 51 c.out.AddFlags(f, "yaml", map[string]cmd.Formatter{ 52 "yaml": cmd.FormatYaml, 53 "json": cmd.FormatJson, 54 }) 55 f.StringVar(&c.label, "label", "", "a label used to identify the secret") 56 } 57 58 // Init implements cmd.Command. 59 func (c *secretInfoGetCommand) Init(args []string) (err error) { 60 if len(args) > 0 { 61 c.secretUri, err = secrets.ParseURI(args[0]) 62 if err != nil { 63 return errors.NotValidf("secret URI %q", args[0]) 64 } 65 args = args[1:] 66 } 67 68 if c.secretUri == nil && c.label == "" { 69 return errors.New("require either a secret URI or label") 70 } 71 if c.secretUri != nil && c.label != "" { 72 return errors.New("specify either a secret URI or label but not both") 73 } 74 return cmd.CheckEmpty(args) 75 } 76 77 type metadataDisplay struct { 78 LatestRevision int `yaml:"revision" json:"revision"` 79 Label string `yaml:"label" json:"label"` 80 Owner string `yaml:"owner" json:"owner"` 81 Description string `yaml:"description,omitempty" json:"description,omitempty"` 82 RotatePolicy secrets.RotatePolicy `yaml:"rotation,omitempty" json:"rotation,omitempty"` 83 LatestExpireTime *time.Time `yaml:"expiry,omitempty" json:"expiry,omitempty"` 84 NextRotateTime *time.Time `yaml:"rotates,omitempty" json:"rotates,omitempty"` 85 Access []accessInfo `yaml:"access,omitempty" json:"access,omitempty"` 86 } 87 88 // accessInfo holds info about a secret access information. 89 type accessInfo struct { 90 Target string `yaml:"target" json:"target"` 91 Scope string `yaml:"scope" json:"scope"` 92 Role secrets.SecretRole `yaml:"role" json:"role"` 93 } 94 95 func toAccessInfo(grants []secrets.AccessInfo) []accessInfo { 96 result := make([]accessInfo, len(grants)) 97 for i, grant := range grants { 98 result[i] = accessInfo{ 99 Target: grant.Target, 100 Scope: grant.Scope, 101 Role: grant.Role, 102 } 103 } 104 return result 105 } 106 107 // Run implements cmd.Command. 108 func (c *secretInfoGetCommand) Run(ctx *cmd.Context) error { 109 all, err := c.ctx.SecretMetadata() 110 if err != nil { 111 return err 112 } 113 print := func(id string, md SecretMetadata) error { 114 return c.out.Write(ctx, map[string]metadataDisplay{ 115 id: { 116 LatestRevision: md.LatestRevision, 117 Label: md.Label, 118 Owner: md.Owner.Kind(), 119 Description: md.Description, 120 RotatePolicy: md.RotatePolicy, 121 LatestExpireTime: md.LatestExpireTime, 122 NextRotateTime: md.NextRotateTime, 123 Access: toAccessInfo(md.Access), 124 }}) 125 } 126 var want string 127 if c.secretUri != nil { 128 want = c.secretUri.ID 129 if md, found := all[want]; found { 130 return print(want, md) 131 } 132 133 } else { 134 want = c.label 135 for id, md := range all { 136 if md.Label == want { 137 return print(id, md) 138 } 139 } 140 } 141 return errors.NotFoundf("secret %q", want) 142 }