github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/uniter/runner/jujuc/secret-set_test.go (about) 1 // Copyright 2021 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc_test 5 6 import ( 7 "os" 8 "path/filepath" 9 "time" 10 11 "github.com/juju/cmd/v3" 12 "github.com/juju/cmd/v3/cmdtesting" 13 "github.com/juju/testing" 14 jc "github.com/juju/testing/checkers" 15 gc "gopkg.in/check.v1" 16 17 coresecrets "github.com/juju/juju/core/secrets" 18 "github.com/juju/juju/worker/uniter/runner/jujuc" 19 ) 20 21 type SecretUpdateSuite struct { 22 ContextSuite 23 } 24 25 var _ = gc.Suite(&SecretUpdateSuite{}) 26 27 func (s *SecretUpdateSuite) TestUpdateSecretInvalidArgs(c *gc.C) { 28 hctx, _ := s.ContextSuite.NewHookContext() 29 30 for _, t := range []struct { 31 args []string 32 err string 33 }{ 34 { 35 args: []string{}, 36 err: "ERROR missing secret URI", 37 }, { 38 args: []string{"foo"}, 39 err: `ERROR secret URI "foo" not valid`, 40 }, { 41 args: []string{"secret:9m4e2mr0ui3e8a215n4g", "s3cret"}, 42 err: `ERROR key value "s3cret" not valid`, 43 }, { 44 args: []string{"secret:9m4e2mr0ui3e8a215n4g", "foo=bar", "--rotate", "foo"}, 45 err: `ERROR rotate policy "foo" not valid`, 46 }, { 47 args: []string{"secret:9m4e2mr0ui3e8a215n4g", "foo=bar", "--expire", "-1h"}, 48 err: `ERROR negative expire duration "-1h" not valid`, 49 }, { 50 args: []string{"secret:9m4e2mr0ui3e8a215n4g", "foo=bar", "--expire", "2022-01-01"}, 51 err: `ERROR expire time or duration "2022-01-01" not valid`, 52 }, 53 } { 54 com, err := jujuc.NewCommand(hctx, "secret-set") 55 c.Assert(err, jc.ErrorIsNil) 56 ctx := cmdtesting.Context(c) 57 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, t.args) 58 59 c.Assert(code, gc.Equals, 2) 60 c.Assert(bufferString(ctx.Stderr), gc.Equals, t.err+"\n") 61 } 62 } 63 64 func (s *SecretUpdateSuite) TestUpdateSecret(c *gc.C) { 65 hctx, _ := s.ContextSuite.NewHookContext() 66 67 expectedExpiry := time.Now().Add(time.Hour) 68 com, err := jujuc.NewCommand(hctx, "secret-set") 69 c.Assert(err, jc.ErrorIsNil) 70 ctx := cmdtesting.Context(c) 71 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, []string{ 72 "secret:9m4e2mr0ui3e8a215n4g", "data=secret", 73 "--rotate", "daily", "--expire", "1h", 74 "--description", "sssshhhh", 75 "--label", "foobar", 76 }) 77 78 c.Assert(code, gc.Equals, 0) 79 val := coresecrets.NewSecretValue(map[string]string{"data": "c2VjcmV0"}) 80 expectedArgs := &jujuc.SecretUpdateArgs{ 81 Value: val, 82 RotatePolicy: ptr(coresecrets.RotateDaily), 83 Description: ptr("sssshhhh"), 84 Label: ptr("foobar"), 85 } 86 s.Stub.CheckCallNames(c, "UpdateSecret") 87 call := s.Stub.Calls()[0] 88 c.Assert(call.Args, gc.HasLen, 2) 89 c.Assert(call.Args[0], gc.Equals, "secret:9m4e2mr0ui3e8a215n4g") 90 args, ok := call.Args[1].(*jujuc.SecretUpdateArgs) 91 c.Assert(ok, jc.IsTrue) 92 c.Assert(args.ExpireTime, gc.NotNil) 93 c.Assert(args.ExpireTime.After(expectedExpiry), jc.IsTrue) 94 args.ExpireTime = nil 95 c.Assert(args, jc.DeepEquals, expectedArgs) 96 } 97 98 func (s *SecretUpdateSuite) TestUpdateSecretBase64(c *gc.C) { 99 hctx, _ := s.ContextSuite.NewHookContext() 100 101 com, err := jujuc.NewCommand(hctx, "secret-set") 102 c.Assert(err, jc.ErrorIsNil) 103 ctx := cmdtesting.Context(c) 104 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, []string{"secret:9m4e2mr0ui3e8a215n4g", "token#base64=key="}) 105 106 c.Assert(code, gc.Equals, 0) 107 val := coresecrets.NewSecretValue(map[string]string{"token": "key="}) 108 args := &jujuc.SecretUpdateArgs{ 109 Value: val, 110 } 111 s.Stub.CheckCalls(c, []testing.StubCall{{FuncName: "UpdateSecret", Args: []interface{}{"secret:9m4e2mr0ui3e8a215n4g", args}}}) 112 } 113 114 func (s *SecretUpdateSuite) TestUpdateSecretRotateInterval(c *gc.C) { 115 hctx, _ := s.ContextSuite.NewHookContext() 116 117 com, err := jujuc.NewCommand(hctx, "secret-set") 118 c.Assert(err, jc.ErrorIsNil) 119 ctx := cmdtesting.Context(c) 120 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, []string{"--rotate", "daily", "secret:9m4e2mr0ui3e8a215n4g"}) 121 122 c.Assert(code, gc.Equals, 0) 123 args := &jujuc.SecretUpdateArgs{ 124 Value: coresecrets.NewSecretValue(nil), 125 RotatePolicy: ptr(coresecrets.RotateDaily), 126 } 127 s.Stub.CheckCalls(c, []testing.StubCall{{FuncName: "UpdateSecret", Args: []interface{}{"secret:9m4e2mr0ui3e8a215n4g", args}}}) 128 } 129 130 func (s *SecretUpdateSuite) TestUpdateSecretFromFile(c *gc.C) { 131 data := ` 132 key: |- 133 secret 134 another-key: !!binary | 135 R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 136 OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ 137 +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC 138 AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=` 139 140 dir := c.MkDir() 141 fileName := filepath.Join(dir, "secret.yaml") 142 err := os.WriteFile(fileName, []byte(data), os.FileMode(0644)) 143 c.Assert(err, jc.ErrorIsNil) 144 145 hctx, _ := s.ContextSuite.NewHookContext() 146 com, err := jujuc.NewCommand(hctx, "secret-set") 147 c.Assert(err, jc.ErrorIsNil) 148 ctx := cmdtesting.Context(c) 149 code := cmd.Main(jujuc.NewJujucCommandWrappedForTest(com), ctx, []string{"secret:9m4e2mr0ui3e8a215n4g", "token#base64=key=", "--file", fileName}) 150 151 c.Assert(code, gc.Equals, 0) 152 val := coresecrets.NewSecretValue(map[string]string{ 153 "token": "key=", 154 "key": "c2VjcmV0", 155 "another-key": `R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=`, 156 }) 157 args := &jujuc.SecretUpdateArgs{ 158 Value: val, 159 } 160 s.Stub.CheckCalls(c, []testing.StubCall{{FuncName: "UpdateSecret", Args: []interface{}{"secret:9m4e2mr0ui3e8a215n4g", args}}}) 161 }