From b4cfbc4b11756109a6fa09d9a5a87f726f981556 Mon Sep 17 00:00:00 2001 From: Joseph Phillips Date: Mon, 2 Dec 2024 19:39:48 +0100 Subject: [PATCH] feat: use secret management caveat wrapper This is preparation for using WithLease in the secrets service. Instead of doing a point in time check and return, we return a function for use to execute logic requiring secret management. At present the caveat is always permissive if we have passed checks, but will use WithLease to ensure the checks hold for the duration of execution. --- domain/secret/service/access.go | 49 +++-- domain/secret/service/access_test.go | 12 +- domain/secret/service/delete.go | 27 +-- domain/secret/service/service.go | 264 ++++++++++++++------------ domain/secret/service/service_test.go | 12 +- 5 files changed, 211 insertions(+), 153 deletions(-) diff --git a/domain/secret/service/access.go b/domain/secret/service/access.go index a25324fcf7d..8a71eb18f7b 100644 --- a/domain/secret/service/access.go +++ b/domain/secret/service/access.go @@ -129,10 +129,14 @@ func (s *SecretService) getSecretAccess(ctx context.Context, uri *secrets.URI, a // satisfying [secreterrors.InvalidSecretPermissionChange] is returned. // It returns [secreterrors.PermissionDenied] if the secret cannot be managed by the accessor. func (s *SecretService) GrantSecretAccess(ctx context.Context, uri *secrets.URI, params SecretAccessParams) error { - if err := s.canManage(ctx, uri, params.Accessor, params.LeaderToken); err != nil { + withCaveat, err := s.getManagementCaveat(ctx, uri, params.Accessor, params.LeaderToken) + if err != nil { return errors.Trace(err) } - return s.secretState.GrantAccess(ctx, uri, grantParams(params)) + + return withCaveat(ctx, func(innerCtx context.Context) error { + return s.secretState.GrantAccess(innerCtx, uri, grantParams(params)) + }) } func grantParams(in SecretAccessParams) domainsecret.GrantParams { @@ -168,7 +172,8 @@ func grantParams(in SecretAccessParams) domainsecret.GrantParams { // RevokeSecretAccess revokes access to the secret for the specified subject. // It returns an error satisfying [secreterrors.SecretNotFound] if the secret is not found. func (s *SecretService) RevokeSecretAccess(ctx context.Context, uri *secrets.URI, params SecretAccessParams) error { - if err := s.canManage(ctx, uri, params.Accessor, params.LeaderToken); err != nil { + withCaveat, err := s.getManagementCaveat(ctx, uri, params.Accessor, params.LeaderToken) + if err != nil { return errors.Trace(err) } @@ -186,29 +191,42 @@ func (s *SecretService) RevokeSecretAccess(ctx context.Context, uri *secrets.URI p.SubjectTypeID = domainsecret.SubjectModel } - return s.secretState.RevokeAccess(ctx, uri, p) + return withCaveat(ctx, func(innerCtx context.Context) error { + return s.secretState.RevokeAccess(innerCtx, uri, p) + }) } -// canManage checks that the accessor can manage the secret. -// If the request is for a secret owned by an application, the unit must be the leader. -func (s *SecretService) canManage( +// getManagementCaveat returns a function within which an operation can be +// executed if the caveat remains satisfied. +// If the secret is unit-owned and the unit can manage it, the caveat is always +// permissive. +// If the secret is application-owned, the unit must be, and remain the leader +// of that application. +// If the caveat can never be satisfied, an error is returned - the input +// accessor can never manage the input secret. +func (s *SecretService) getManagementCaveat( ctx context.Context, uri *secrets.URI, assessor SecretAccessor, leaderToken leadership.Token, -) error { +) (func(context.Context, func(context.Context) error) error, error) { hasRole, err := s.getSecretAccess(ctx, uri, assessor) if err != nil { // Typically not found error. - return errors.Trace(err) + return nil, errors.Trace(err) } if hasRole.Allowed(secrets.RoleManage) { - return nil + return func(ctx context.Context, fn func(context.Context) error) error { + return fn(ctx) + }, nil } // Units can manage app owned secrets if they are the leader. if assessor.Kind == UnitAccessor { if leaderToken == nil { - return secreterrors.PermissionDenied + return nil, secreterrors.PermissionDenied } + + // TODO (manadart 2024-11-29): This section will be updated to + // return a WithLease wrapper in a patch to follow. if err := leaderToken.Check(); err == nil { appName, _ := names.UnitApplication(assessor.ID) hasRole, err = s.getSecretAccess(ctx, uri, SecretAccessor{ @@ -217,14 +235,17 @@ func (s *SecretService) canManage( }) if err != nil { // Typically not found error. - return errors.Trace(err) + return nil, errors.Trace(err) } if hasRole.Allowed(secrets.RoleManage) { - return nil + return func(ctx context.Context, fn func(context.Context) error) error { + return fn(ctx) + }, nil } } } - return fmt.Errorf("%q is not allowed to manage this secret%w", assessor.ID, errors.Hide(secreterrors.PermissionDenied)) + return nil, fmt.Errorf( + "%q is not allowed to manage this secret %w", assessor.ID, errors.Hide(secreterrors.PermissionDenied)) } // canRead checks that the accessor can read the secret. diff --git a/domain/secret/service/access_test.go b/domain/secret/service/access_test.go index 3c708a42e3e..d6c89a47f6b 100644 --- a/domain/secret/service/access_test.go +++ b/domain/secret/service/access_test.go @@ -14,7 +14,7 @@ import ( domainsecret "github.com/juju/juju/domain/secret" ) -func (s *serviceSuite) TestCanManageOwnerUnit(c *gc.C) { +func (s *serviceSuite) TestGetManagementCaveatOwnerUnit(c *gc.C) { ctrl := s.setupMocks(c) defer ctrl.Finish() @@ -27,14 +27,14 @@ func (s *serviceSuite) TestCanManageOwnerUnit(c *gc.C) { token := NewMockToken(ctrl) - err := s.service.canManage(context.Background(), uri, SecretAccessor{ + _, err := s.service.getManagementCaveat(context.Background(), uri, SecretAccessor{ Kind: UnitAccessor, ID: "mariadb/0", }, token) c.Assert(err, jc.ErrorIsNil) } -func (s *serviceSuite) TestCanManageLeaderUnitAppSecret(c *gc.C) { +func (s *serviceSuite) TestGetManagementCaveatLeaderUnitAppSecret(c *gc.C) { ctrl := s.setupMocks(c) defer ctrl.Finish() @@ -52,14 +52,14 @@ func (s *serviceSuite) TestCanManageLeaderUnitAppSecret(c *gc.C) { token := NewMockToken(ctrl) token.EXPECT().Check().Return(nil) - err := s.service.canManage(context.Background(), uri, SecretAccessor{ + _, err := s.service.getManagementCaveat(context.Background(), uri, SecretAccessor{ Kind: UnitAccessor, ID: "mariadb/0", }, token) c.Assert(err, jc.ErrorIsNil) } -func (s *serviceSuite) TestCanManageUserSecrets(c *gc.C) { +func (s *serviceSuite) TestGetManagementCaveatUserSecrets(c *gc.C) { ctrl := s.setupMocks(c) defer ctrl.Finish() @@ -72,7 +72,7 @@ func (s *serviceSuite) TestCanManageUserSecrets(c *gc.C) { token := NewMockToken(ctrl) - err := s.service.canManage(context.Background(), uri, SecretAccessor{ + _, err := s.service.getManagementCaveat(context.Background(), uri, SecretAccessor{ Kind: ModelAccessor, ID: "model-uuid", }, token) diff --git a/domain/secret/service/delete.go b/domain/secret/service/delete.go index 83848acfc12..deaa0c5c140 100644 --- a/domain/secret/service/delete.go +++ b/domain/secret/service/delete.go @@ -6,17 +6,16 @@ package service import ( "context" - "github.com/juju/errors" - "github.com/juju/juju/core/secrets" "github.com/juju/juju/domain" + "github.com/juju/juju/internal/errors" ) // DeleteObsoleteUserSecretRevisions deletes any obsolete user secret revisions that are marked as auto-prune. func (s *SecretService) DeleteObsoleteUserSecretRevisions(ctx context.Context) error { deletedRevisionIDs, err := s.secretState.DeleteObsoleteUserSecretRevisions(ctx) if err != nil { - return errors.Trace(err) + return errors.Capture(err) } if err = s.secretBackendState.RemoveSecretBackendReference(ctx, deletedRevisionIDs...); err != nil { // We don't want to error out if we can't remove the backend reference. @@ -29,13 +28,19 @@ func (s *SecretService) DeleteObsoleteUserSecretRevisions(ctx context.Context) e // If revisions is nil or the last remaining revisions are removed. // It returns [secreterrors.PermissionDenied] if the secret cannot be managed by the accessor. func (s *SecretService) DeleteSecret(ctx context.Context, uri *secrets.URI, params DeleteSecretParams) error { - if err := s.canManage(ctx, uri, params.Accessor, params.LeaderToken); err != nil { - return errors.Trace(err) - } - if err := s.secretState.RunAtomic(ctx, func(ctx domain.AtomicContext) error { - return s.secretState.DeleteSecret(ctx, uri, params.Revisions) - }); err != nil { - return errors.Annotatef(err, "deleting secret %q", uri.ID) + withCaveat, err := s.getManagementCaveat(ctx, uri, params.Accessor, params.LeaderToken) + if err != nil { + return errors.Capture(err) } - return nil + + return withCaveat(ctx, func(innerCtx context.Context) error { + // TODO (manadart 2024-11-29): This context naming is nasty, + // but will be removed with RunAtomic. + if err := s.secretState.RunAtomic(innerCtx, func(innerInnerCtx domain.AtomicContext) error { + return s.secretState.DeleteSecret(innerInnerCtx, uri, params.Revisions) + }); err != nil { + return errors.Errorf("deleting secret %q: %w", uri.ID, err) + } + return nil + }) } diff --git a/domain/secret/service/service.go b/domain/secret/service/service.go index 594dd1c9f0e..a8464077214 100644 --- a/domain/secret/service/service.go +++ b/domain/secret/service/service.go @@ -241,7 +241,7 @@ func (s *SecretService) CreateUserSecret(ctx context.Context, uri *secrets.URI, if err = s.secretState.RunAtomic(ctx, func(ctx domain.AtomicContext) error { return s.createSecret(ctx, params.Version, uri, secrets.Owner{Kind: secrets.ModelOwner}, p) }); err != nil { - return jujuerrors.Annotatef(err, "cannot create user secret %q", uri.ID) + return jujuerrors.Annotatef(err, "creating user secret %q", uri.ID) } return nil } @@ -330,9 +330,10 @@ func (s *SecretService) CreateCharmSecret(ctx context.Context, uri *secrets.URI, // It also returns an error satisfying [secreterrors.SecretLabelAlreadyExists] if // the secret owner already has a secret with the same label. // It returns [secreterrors.PermissionDenied] if the secret cannot be managed by the accessor. -func (s *SecretService) UpdateUserSecret(ctx context.Context, uri *secrets.URI, params UpdateUserSecretParams) (errOut error) { - if err := s.canManage(ctx, uri, params.Accessor, nil); err != nil { - return jujuerrors.Trace(err) +func (s *SecretService) UpdateUserSecret(ctx context.Context, uri *secrets.URI, params UpdateUserSecretParams) error { + withCaveat, err := s.getManagementCaveat(ctx, uri, params.Accessor, nil) + if err != nil { + return errors.Capture(err) } p := domainsecret.UpsertSecretParams{ @@ -341,79 +342,85 @@ func (s *SecretService) UpdateUserSecret(ctx context.Context, uri *secrets.URI, AutoPrune: params.AutoPrune, Checksum: params.Checksum, } - // Take a copy as we may set it to nil below - // if the content is saved to a backend. - if len(params.Data) > 0 { - p.Data = make(map[string]string) - for k, v := range params.Data { - p.Data[k] = v - } - backend, backendID, err := s.getBackendForUserSecrets(ctx, params.Accessor) - if err != nil { - return jujuerrors.Trace(err) - } + return withCaveat(ctx, func(innerCtx context.Context) (errOut error) { + // Take a copy as we may set it to nil below + // if the content is saved to a backend. + if len(params.Data) > 0 { + p.Data = make(map[string]string) + for k, v := range params.Data { + p.Data[k] = v + } - latestRevision, err := s.secretState.GetLatestRevision(ctx, uri) - if err != nil { - // Check if the uri exists or not. - return jujuerrors.Trace(err) - } - revId, err := backend.SaveContent(ctx, uri, latestRevision+1, secrets.NewSecretValue(params.Data)) - if err != nil && !errors.Is(err, jujuerrors.NotSupported) { - return jujuerrors.Annotatef(err, "saving secret content to backend") + backend, backendID, err := s.getBackendForUserSecrets(innerCtx, params.Accessor) + if err != nil { + return errors.Capture(err) + } + + latestRevision, err := s.secretState.GetLatestRevision(innerCtx, uri) + if err != nil { + // Check if the uri exists or not. + return errors.Capture(err) + } + revId, err := backend.SaveContent(innerCtx, uri, latestRevision+1, secrets.NewSecretValue(params.Data)) + if err != nil && !errors.Is(err, jujuerrors.NotSupported) { + return errors.Errorf("saving secret content to backend: %w", err) + } + if err == nil { + defer func() { + if errOut != nil { + // If we failed to update the secret, we should delete the + // secret value from the backend for the new revision. + if err2 := backend.DeleteContent(innerCtx, revId); err2 != nil && + !errors.Is(err2, jujuerrors.NotSupported) && + !errors.Is(err2, secreterrors.SecretRevisionNotFound) { + s.logger.Warningf("failed to delete secret %q: %v", revId, err2) + } + } + }() + p.Data = nil + p.ValueRef = &secrets.ValueRef{ + BackendID: backendID, + RevisionID: revId, + } + } } - if err == nil { + + if p.ValueRef != nil || len(p.Data) != 0 { + revisionID, err := s.uuidGenerator() + if err != nil { + return errors.Capture(err) + } + p.RevisionID = ptr(revisionID.String()) + + modelID, err := s.secretState.GetModelUUID(innerCtx) + if err != nil { + return errors.Errorf("getting model uuid: %w", err) + } + rollBack, err := s.secretBackendState.AddSecretBackendReference( + innerCtx, p.ValueRef, coremodel.UUID(modelID), revisionID.String()) + if err != nil { + return errors.Capture(err) + } defer func() { if errOut != nil { - // If we failed to update the secret, we should delete the - // secret value from the backend for the new revision. - if err2 := backend.DeleteContent(ctx, revId); err2 != nil && - !errors.Is(err2, jujuerrors.NotSupported) && - !errors.Is(err2, secreterrors.SecretRevisionNotFound) { - s.logger.Warningf("failed to delete secret %q: %v", revId, err2) + if err := rollBack(); err != nil { + s.logger.Warningf("failed to roll back secret reference count: %v", err) } } }() - p.Data = nil - p.ValueRef = &secrets.ValueRef{ - BackendID: backendID, - RevisionID: revId, - } - } - } - - if p.ValueRef != nil || len(p.Data) != 0 { - revisionID, err := s.uuidGenerator() - if err != nil { - return jujuerrors.Trace(err) } - p.RevisionID = ptr(revisionID.String()) - modelID, err := s.secretState.GetModelUUID(ctx) + // TODO (manadart 2024-11-29): This context naming is nasty, + // but will be removed with RunAtomic. + err := s.secretState.RunAtomic(innerCtx, func(innerInnerCtx domain.AtomicContext) error { + return s.updateSecret(innerInnerCtx, uri, p) + }) if err != nil { - return jujuerrors.Annotate(err, "getting model uuid") + return errors.Errorf("updating user secret %q: %w", uri.ID, err) } - rollBack, err := s.secretBackendState.AddSecretBackendReference(ctx, p.ValueRef, coremodel.UUID(modelID), revisionID.String()) - if err != nil { - return jujuerrors.Trace(err) - } - defer func() { - if errOut != nil { - if err := rollBack(); err != nil { - s.logger.Warningf("failed to roll back secret reference count: %v", err) - } - } - }() - } - - err := s.secretState.RunAtomic(ctx, func(ctx domain.AtomicContext) error { - return s.updateSecret(ctx, uri, p) + return nil }) - if err != nil { - return jujuerrors.Annotatef(err, "cannot update user secret %q", uri.ID) - } - return nil } // UpdateCharmSecret updates a charm secret with the specified parameters, returning an error @@ -421,13 +428,14 @@ func (s *SecretService) UpdateUserSecret(ctx context.Context, uri *secrets.URI, // It also returns an error satisfying [secreterrors.SecretLabelAlreadyExists] if // the secret owner already has a secret with the same label. // It returns [secreterrors.PermissionDenied] if the secret cannot be managed by the accessor. -func (s *SecretService) UpdateCharmSecret(ctx context.Context, uri *secrets.URI, params UpdateCharmSecretParams) (errOut error) { +func (s *SecretService) UpdateCharmSecret(ctx context.Context, uri *secrets.URI, params UpdateCharmSecretParams) error { if len(params.Data) > 0 && params.ValueRef != nil { return jujuerrors.New("must specify either content or a value reference but not both") } - if err := s.canManage(ctx, uri, params.Accessor, params.LeaderToken); err != nil { - return jujuerrors.Trace(err) + withCaveat, err := s.getManagementCaveat(ctx, uri, params.Accessor, params.LeaderToken) + if err != nil { + return errors.Capture(err) } p := domainsecret.UpsertSecretParams{ @@ -442,7 +450,7 @@ func (s *SecretService) UpdateCharmSecret(ctx context.Context, uri *secrets.URI, if params.RotatePolicy.WillRotate() { policy, err := s.secretState.GetRotatePolicy(ctx, uri) if err != nil { - return jujuerrors.Trace(err) + return errors.Capture(err) } if !policy.WillRotate() { p.NextRotateTime = params.RotatePolicy.NextRotateTime(s.clock.Now()) @@ -455,36 +463,42 @@ func (s *SecretService) UpdateCharmSecret(ctx context.Context, uri *secrets.URI, } } - if p.ValueRef != nil || len(p.Data) != 0 { - revisionID, err := s.uuidGenerator() - if err != nil { - return jujuerrors.Trace(err) - } - p.RevisionID = ptr(revisionID.String()) + return withCaveat(ctx, func(innerCtx context.Context) (errOut error) { + if p.ValueRef != nil || len(p.Data) != 0 { + revisionID, err := s.uuidGenerator() + if err != nil { + return jujuerrors.Trace(err) + } + p.RevisionID = ptr(revisionID.String()) - modelID, err := s.secretState.GetModelUUID(ctx) - if err != nil { - return jujuerrors.Annotate(err, "getting model uuid") + modelID, err := s.secretState.GetModelUUID(innerCtx) + if err != nil { + return jujuerrors.Annotate(err, "getting model uuid") + } + rollBack, err := s.secretBackendState.AddSecretBackendReference( + innerCtx, p.ValueRef, coremodel.UUID(modelID), revisionID.String()) + if err != nil { + return jujuerrors.Trace(err) + } + defer func() { + if errOut != nil { + if err := rollBack(); err != nil { + s.logger.Warningf("failed to roll back secret reference count: %v", err) + } + } + }() } - rollBack, err := s.secretBackendState.AddSecretBackendReference(ctx, p.ValueRef, coremodel.UUID(modelID), revisionID.String()) + + // TODO (manadart 2024-11-29): This context naming is nasty, + // but will be removed with RunAtomic. + err := s.secretState.RunAtomic(innerCtx, func(innerInnerCtx domain.AtomicContext) error { + return s.updateSecret(innerInnerCtx, uri, p) + }) if err != nil { - return jujuerrors.Trace(err) + return jujuerrors.Annotatef(err, "cannot update charm secret %q", uri.ID) } - defer func() { - if errOut != nil { - if err := rollBack(); err != nil { - s.logger.Warningf("failed to roll back secret reference count: %v", err) - } - } - }() - } - err := s.secretState.RunAtomic(ctx, func(ctx domain.AtomicContext) error { - return s.updateSecret(ctx, uri, p) + return nil }) - if err != nil { - return jujuerrors.Annotatef(err, "cannot update charm secret %q", uri.ID) - } - return nil } func (s *SecretService) createSecret( @@ -831,51 +845,61 @@ func (s *SecretService) getAppOwnedOrUnitOwnedSecretMetadata(ctx context.Context // ChangeSecretBackend sets the secret backend where the specified secret revision is stored. // It returns [secreterrors.SecretNotFound] is there's no such secret. // It returns [secreterrors.PermissionDenied] if the secret cannot be managed by the accessor. -func (s *SecretService) ChangeSecretBackend(ctx context.Context, uri *secrets.URI, revision int, params ChangeSecretBackendParams) (errOut error) { - if err := s.canManage(ctx, uri, params.Accessor, params.LeaderToken); err != nil { - return jujuerrors.Trace(err) +func (s *SecretService) ChangeSecretBackend( + ctx context.Context, uri *secrets.URI, revision int, params ChangeSecretBackendParams, +) error { + withCaveat, err := s.getManagementCaveat(ctx, uri, params.Accessor, params.LeaderToken) + if err != nil { + return errors.Capture(err) } + revisionIDStr, err := s.secretState.GetSecretRevisionID(ctx, uri, revision) if err != nil { - return jujuerrors.Trace(err) + return errors.Capture(err) } revisionID, err := uuid.UUIDFromString(revisionIDStr) if err != nil { - return jujuerrors.Trace(err) + return errors.Capture(err) } modelID, err := s.secretState.GetModelUUID(ctx) if err != nil { return jujuerrors.Annotate(err, "getting model uuid") } - rollBack, err := s.secretBackendState.UpdateSecretBackendReference(ctx, params.ValueRef, coremodel.UUID(modelID), revisionID.String()) - if err != nil { - return jujuerrors.Trace(err) - } - defer func() { - if errOut != nil { - if err := rollBack(); err != nil { - s.logger.Warningf("failed to roll back secret reference count: %v", err) - } + + return withCaveat(ctx, func(innerCtx context.Context) (errOut error) { + rollBack, err := s.secretBackendState.UpdateSecretBackendReference( + innerCtx, params.ValueRef, coremodel.UUID(modelID), revisionID.String()) + if err != nil { + return errors.Capture(err) } - }() - err = s.secretState.ChangeSecretBackend(ctx, revisionID, params.ValueRef, params.Data) - if err != nil { - return jujuerrors.Trace(err) - } - return nil + defer func() { + if errOut != nil { + if err := rollBack(); err != nil { + s.logger.Warningf("failed to roll back secret reference count: %v", err) + } + } + }() + + err = s.secretState.ChangeSecretBackend(innerCtx, revisionID, params.ValueRef, params.Data) + if err != nil { + return errors.Capture(err) + } + return nil + }) } // SecretRotated rotates the secret with the specified URI. func (s *SecretService) SecretRotated(ctx context.Context, uri *secrets.URI, params SecretRotatedParams) error { - if err := s.canManage(ctx, uri, params.Accessor, params.LeaderToken); err != nil { - return jujuerrors.Trace(err) + withCaveat, err := s.getManagementCaveat(ctx, uri, params.Accessor, params.LeaderToken) + if err != nil { + return errors.Capture(err) } info, err := s.secretState.GetRotationExpiryInfo(ctx, uri) if err != nil { - return jujuerrors.Trace(err) + return errors.Capture(err) } if !info.RotatePolicy.WillRotate() { s.logger.Debugf("secret %q was rotated but now is set to not rotate") @@ -886,8 +910,10 @@ func (s *SecretService) SecretRotated(ctx context.Context, uri *secrets.URI, par now := s.clock.Now() lastRotateTime = &now } + nextRotateTime := *info.RotatePolicy.NextRotateTime(*lastRotateTime) s.logger.Debugf("secret %q was rotated: rev was %d, now %d", uri.ID, params.OriginalRevision, info.LatestRevision) + // If the secret will expire before it is due to be next rotated, rotate sooner to allow // the charm a chance to update it before it expires. willExpire := info.LatestExpireTime != nil && info.LatestExpireTime.Before(nextRotateTime) @@ -895,9 +921,13 @@ func (s *SecretService) SecretRotated(ctx context.Context, uri *secrets.URI, par if willExpire { s.logger.Warningf("secret %q rev %d will expire before next scheduled rotation", uri.ID, info.LatestRevision) } + if willExpire && forcedRotateTime.Before(*info.LatestExpireTime) || !params.Skip && info.LatestRevision == params.OriginalRevision { nextRotateTime = forcedRotateTime } s.logger.Debugf("secret %q next rotate time is now: %s", uri.ID, nextRotateTime.UTC().Format(time.RFC3339)) - return s.secretState.SecretRotated(ctx, uri, nextRotateTime) + + return withCaveat(ctx, func(innerCtx context.Context) (errOut error) { + return s.secretState.SecretRotated(innerCtx, uri, nextRotateTime) + }) } diff --git a/domain/secret/service/service_test.go b/domain/secret/service/service_test.go index 33ad32cb03c..4bf0c2d8cf8 100644 --- a/domain/secret/service/service_test.go +++ b/domain/secret/service/service_test.go @@ -164,9 +164,11 @@ func (s *serviceSuite) assertCreateUserSecret(c *gc.C, isInternal, finalStepFail } s.secretsBackendProvider.EXPECT().Type().Return("active-type").AnyTimes() - s.secretsBackendProvider.EXPECT().NewBackend(ptr(backendConfigs.Configs["backend-id"])).DoAndReturn(func(cfg *provider.ModelBackendConfig) (provider.SecretsBackend, error) { - return s.secretsBackend, nil - }) + s.secretsBackendProvider.EXPECT().NewBackend(ptr(backendConfigs.Configs["backend-id"])).DoAndReturn( + func(cfg *provider.ModelBackendConfig) (provider.SecretsBackend, error) { + return s.secretsBackend, nil + }, + ) s.state.EXPECT().GetModelUUID(gomock.Any()).Return(s.modelID.String(), nil) uri := coresecrets.NewURI() @@ -215,7 +217,7 @@ func (s *serviceSuite) assertCreateUserSecret(c *gc.C, isInternal, finalStepFail if labelExists { c.Assert(err, jc.ErrorIs, secreterrors.SecretLabelAlreadyExists) } else { - c.Assert(err, gc.ErrorMatches, "cannot create user secret .*some error") + c.Assert(err, gc.ErrorMatches, "creating user secret .*some error") } } else { c.Assert(err, jc.ErrorIsNil) @@ -312,7 +314,7 @@ func (s *serviceSuite) assertUpdateUserSecret(c *gc.C, isInternal, finalStepFail if labelExists { c.Assert(err, jc.ErrorIs, secreterrors.SecretLabelAlreadyExists) } else { - c.Assert(err, gc.ErrorMatches, "cannot update user secret .*some error") + c.Assert(err, gc.ErrorMatches, "updating user secret .*some error") } } else { c.Assert(err, jc.ErrorIsNil)