github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/facades/controller/usersecrets/secrets_test.go (about) 1 // Copyright 2023 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package usersecrets_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/collections/set" 10 "github.com/juju/names/v5" 11 "github.com/juju/testing" 12 jc "github.com/juju/testing/checkers" 13 "go.uber.org/mock/gomock" 14 gc "gopkg.in/check.v1" 15 16 commonsecrets "github.com/juju/juju/apiserver/common/secrets" 17 facademocks "github.com/juju/juju/apiserver/facade/mocks" 18 "github.com/juju/juju/apiserver/facades/controller/usersecrets" 19 "github.com/juju/juju/apiserver/facades/controller/usersecrets/mocks" 20 coresecrets "github.com/juju/juju/core/secrets" 21 "github.com/juju/juju/rpc/params" 22 "github.com/juju/juju/secrets/provider" 23 coretesting "github.com/juju/juju/testing" 24 ) 25 26 type userSecretsSuite struct { 27 testing.IsolationSuite 28 29 authorizer *facademocks.MockAuthorizer 30 resources *facademocks.MockResources 31 authTag names.Tag 32 33 state *mocks.MockSecretsState 34 stringWatcher *mocks.MockStringsWatcher 35 36 provider *mocks.MockSecretBackendProvider 37 backend *mocks.MockSecretsBackend 38 39 facade *usersecrets.UserSecretsManager 40 } 41 42 var _ = gc.Suite(&userSecretsSuite{}) 43 44 func (s *userSecretsSuite) setup(c *gc.C) *gomock.Controller { 45 ctrl := gomock.NewController(c) 46 47 s.authorizer = facademocks.NewMockAuthorizer(ctrl) 48 s.resources = facademocks.NewMockResources(ctrl) 49 s.authTag = names.NewUserTag("foo") 50 s.state = mocks.NewMockSecretsState(ctrl) 51 s.stringWatcher = mocks.NewMockStringsWatcher(ctrl) 52 53 s.provider = mocks.NewMockSecretBackendProvider(ctrl) 54 s.backend = mocks.NewMockSecretsBackend(ctrl) 55 s.PatchValue(&commonsecrets.GetProvider, func(string) (provider.SecretBackendProvider, error) { return s.provider, nil }) 56 57 s.authorizer.EXPECT().AuthController().Return(true) 58 59 var err error 60 s.facade, err = usersecrets.NewTestAPI( 61 s.authorizer, s.resources, s.authTag, 62 coretesting.ControllerTag.Id(), coretesting.ModelTag.Id(), s.state, 63 func() (*provider.ModelBackendConfigInfo, error) { 64 return &provider.ModelBackendConfigInfo{ 65 ActiveID: "backend-id", 66 Configs: map[string]provider.ModelBackendConfig{ 67 "backend-id": { 68 ControllerUUID: coretesting.ControllerTag.Id(), 69 ModelUUID: coretesting.ModelTag.Id(), 70 ModelName: "some-model", 71 BackendConfig: provider.BackendConfig{ 72 BackendType: "active-type", 73 Config: map[string]interface{}{"foo": "active-type"}, 74 }, 75 }, 76 }, 77 }, nil 78 }, 79 ) 80 c.Assert(err, jc.ErrorIsNil) 81 return ctrl 82 } 83 84 func (s *userSecretsSuite) TestWatchRevisionsToPrune(c *gc.C) { 85 defer s.setup(c).Finish() 86 87 s.state.EXPECT().WatchRevisionsToPrune([]names.Tag{names.NewModelTag(coretesting.ModelTag.Id())}).Return(s.stringWatcher, nil) 88 s.resources.EXPECT().Register(s.stringWatcher).Return("watcher-id") 89 stringChan := make(chan []string, 1) 90 stringChan <- []string{"1", "2", "3"} 91 s.stringWatcher.EXPECT().Changes().Return(stringChan) 92 93 result, err := s.facade.WatchRevisionsToPrune() 94 c.Assert(err, jc.ErrorIsNil) 95 c.Assert(result, jc.DeepEquals, params.StringsWatchResult{ 96 StringsWatcherId: "watcher-id", 97 Changes: []string{"1", "2", "3"}, 98 }) 99 } 100 101 func (s *userSecretsSuite) TestDeleteRevisionsAutoPruneEnabled(c *gc.C) { 102 defer s.setup(c).Finish() 103 104 uri := coresecrets.NewURI() 105 s.state.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{ 106 URI: uri, OwnerTag: coretesting.ModelTag.String(), 107 AutoPrune: true, 108 }, nil).Times(2) 109 s.state.EXPECT().GetSecretRevision(uri, 666).Return(&coresecrets.SecretRevisionMetadata{ 110 Revision: 666, 111 ValueRef: &coresecrets.ValueRef{BackendID: "backend-id", RevisionID: "rev-666"}, 112 }, nil) 113 s.state.EXPECT().DeleteSecret(uri, []int{666}).Return([]coresecrets.ValueRef{{ 114 BackendID: "backend-id", 115 RevisionID: "rev-666", 116 }}, nil) 117 118 cfg := &provider.ModelBackendConfig{ 119 ControllerUUID: coretesting.ControllerTag.Id(), 120 ModelUUID: coretesting.ModelTag.Id(), 121 ModelName: "some-model", 122 BackendConfig: provider.BackendConfig{ 123 BackendType: "active-type", 124 Config: map[string]interface{}{"foo": "active-type"}, 125 }, 126 } 127 s.provider.EXPECT().NewBackend(cfg).Return(s.backend, nil) 128 s.backend.EXPECT().DeleteContent(gomock.Any(), "rev-666").Return(nil) 129 s.provider.EXPECT().CleanupSecrets( 130 cfg, names.NewUserTag("foo"), 131 provider.SecretRevisions{uri.ID: set.NewStrings("rev-666")}, 132 ).Return(nil) 133 134 results, err := s.facade.DeleteRevisions( 135 params.DeleteSecretArgs{ 136 Args: []params.DeleteSecretArg{ 137 { 138 URI: uri.String(), 139 Revisions: []int{666}, 140 }, 141 }, 142 }, 143 ) 144 c.Assert(err, jc.ErrorIsNil) 145 c.Assert(results, jc.DeepEquals, params.ErrorResults{ 146 Results: []params.ErrorResult{{}}, 147 }) 148 } 149 150 func (s *userSecretsSuite) TestDeleteRevisionsAutoPruneDisabled(c *gc.C) { 151 defer s.setup(c).Finish() 152 153 uri := coresecrets.NewURI() 154 s.state.EXPECT().GetSecret(uri).Return(&coresecrets.SecretMetadata{ 155 URI: uri, OwnerTag: coretesting.ModelTag.String(), 156 AutoPrune: false, 157 }, nil).Times(2) 158 159 results, err := s.facade.DeleteRevisions( 160 params.DeleteSecretArgs{ 161 Args: []params.DeleteSecretArg{ 162 { 163 URI: uri.String(), 164 Revisions: []int{666}, 165 }, 166 }, 167 }, 168 ) 169 c.Assert(err, jc.ErrorIsNil) 170 c.Assert(results, jc.DeepEquals, params.ErrorResults{ 171 Results: []params.ErrorResult{ 172 { 173 Error: ¶ms.Error{ 174 Message: fmt.Sprintf("cannot delete non auto-prune secret %q", uri.String()), 175 }, 176 }, 177 }, 178 }) 179 }