Skip to content

Commit

Permalink
Merge pull request #144 from wallyworld/add-secret-checksum
Browse files Browse the repository at this point in the history
#144

Secret entities get a new field to record the checksum of the latest revision.
The export version is changed to 2. Things like access, consumer info just thunk to the v1 method.

[JIRA-6225](https://warthogs.atlassian.net/browse/JUJU-6225)
  • Loading branch information
jujubot authored Jul 1, 2024
2 parents f1d0363 + 88881e6 commit e21a788
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 28 deletions.
2 changes: 1 addition & 1 deletion model.go
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ func (m *model) AddSecret(args SecretArgs) Secret {

func (m *model) setSecrets(secretList []*secret) {
m.Secrets_ = secrets{
Version: 1,
Version: 2,
Secrets_: secretList,
}
}
Expand Down
3 changes: 2 additions & 1 deletion model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (s *ModelSerializationSuite) TestVersions(c *gc.C) {
c.Assert(initial.Applications_.Version, gc.Equals, len(applicationDeserializationFuncs))
c.Assert(initial.Actions_.Version, gc.Equals, 4)
c.Assert(initial.Operations_.Version, gc.Equals, 2)
c.Assert(initial.Secrets_.Version, gc.Equals, 1)
c.Assert(initial.Secrets_.Version, gc.Equals, 2)
c.Assert(initial.Filesystems_.Version, gc.Equals, len(filesystemDeserializationFuncs))
c.Assert(initial.Relations_.Version, gc.Equals, len(relationFieldsFuncs))
c.Assert(initial.RemoteEntities_.Version, gc.Equals, len(remoteEntityFieldsFuncs))
Expand Down Expand Up @@ -1548,6 +1548,7 @@ func (s *ModelSerializationSuite) TestSecrets(c *gc.C) {
c.Assert(secret.Label(), gc.Equals, secretArgs.Label)
c.Assert(secret.RotatePolicy(), gc.Equals, secretArgs.RotatePolicy)
c.Assert(secret.AutoPrune(), gc.Equals, secretArgs.AutoPrune)
c.Assert(secret.LatestRevisionChecksum(), gc.DeepEquals, secretArgs.LatestRevisionChecksum)
owner, err := secret.Owner()
c.Assert(err, jc.ErrorIsNil)
c.Assert(owner.String(), gc.Equals, secretArgs.Owner.String())
Expand Down
5 changes: 5 additions & 0 deletions secretremoteconsumers.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ type secretRemoteConsumerDeserializationFunc func(map[interface{}]interface{}) (

var secretRemoteConsumerDeserializationFuncs = map[int]secretRemoteConsumerDeserializationFunc{
1: importSecretRemoteConsumerV1,
2: importSecretRemoteConsumerV2,
}

func importSecretRemoteConsumerV2(source map[interface{}]interface{}) (*secretRemoteConsumer, error) {
return importSecretRemoteConsumerV1(source)
}

func importSecretRemoteConsumerV1(source map[interface{}]interface{}) (*secretRemoteConsumer, error) {
Expand Down
61 changes: 50 additions & 11 deletions secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Secret interface {

Revisions() []SecretRevision
LatestRevision() int
LatestRevisionChecksum() string
LatestExpireTime() *time.Time

Validate() error
Expand Down Expand Up @@ -61,6 +62,8 @@ type secret struct {

NextRotateTime_ *time.Time `yaml:"next-rotate-time,omitempty"`

LatestRevisionChecksum_ string `yaml:"latest-revision-checksum"`

// These are updated when revisions are set
// and are not exported.
LatestRevision_ int `yaml:"-"`
Expand Down Expand Up @@ -113,6 +116,11 @@ func (i *secret) LatestRevision() int {
return i.LatestRevision_
}

// LatestRevisionChecksum implements Secret.
func (i *secret) LatestRevisionChecksum() string {
return i.LatestRevisionChecksum_
}

// Id implements Secret.
func (i *secret) Id() string {
return i.ID_
Expand Down Expand Up @@ -233,21 +241,23 @@ type SecretArgs struct {
Consumers []SecretConsumerArgs
RemoteConsumers []SecretRemoteConsumerArgs

NextRotateTime *time.Time
AutoPrune bool
NextRotateTime *time.Time
LatestRevisionChecksum string
AutoPrune bool
}

func newSecret(args SecretArgs) *secret {
secret := &secret{
ID_: args.ID,
Version_: args.Version,
Description_: args.Description,
Label_: args.Label,
RotatePolicy_: args.RotatePolicy,
AutoPrune_: args.AutoPrune,
Created_: args.Created.UTC(),
Updated_: args.Updated.UTC(),
ACL_: newSecretAccess(args.ACL),
ID_: args.ID,
Version_: args.Version,
Description_: args.Description,
Label_: args.Label,
RotatePolicy_: args.RotatePolicy,
AutoPrune_: args.AutoPrune,
LatestRevisionChecksum_: args.LatestRevisionChecksum,
Created_: args.Created.UTC(),
Updated_: args.Updated.UTC(),
ACL_: newSecretAccess(args.ACL),
}
if args.NextRotateTime != nil {
next := args.NextRotateTime.UTC()
Expand Down Expand Up @@ -328,6 +338,7 @@ func importSecretList(sourceList []interface{}, version int) ([]*secret, error)

var secretFieldsFuncs = map[int]fieldsFunc{
1: secretV1Fields,
2: secretV2Fields,
}

func secretV1Fields() (schema.Fields, schema.Defaults) {
Expand Down Expand Up @@ -359,6 +370,13 @@ func secretV1Fields() (schema.Fields, schema.Defaults) {
return fields, defaults
}

func secretV2Fields() (schema.Fields, schema.Defaults) {
fields, defaults := secretV1Fields()
fields["latest-revision-checksum"] = schema.String()
defaults["latest-revision-checksum"] = schema.Omit
return fields, defaults
}

func importSecret(source map[string]interface{}, importVersion int, fieldFunc func() (schema.Fields, schema.Defaults)) (*secret, error) {
fields, defaults := fieldFunc()
checker := schema.FieldMap(fields, defaults)
Expand All @@ -383,6 +401,12 @@ func importSecret(source map[string]interface{}, importVersion int, fieldFunc fu
secret.RotatePolicy_ = policy
}

if importVersion >= 2 {
if checksum, ok := valid["latest-revision-checksum"].(string); ok {
secret.LatestRevisionChecksum_ = checksum
}
}

// This should be in a v2 schema but it's already also in v1.
if autoPrune, ok := valid["auto-prune"].(bool); ok {
secret.AutoPrune_ = autoPrune
Expand Down Expand Up @@ -491,6 +515,11 @@ type secretAccessDeserializationFunc func(map[interface{}]interface{}) (*secretA

var secretAccessDeserializationFuncs = map[int]secretAccessDeserializationFunc{
1: importSecretAccessV1,
2: importSecretAccessV2,
}

func importSecretAccessV2(source map[interface{}]interface{}) (*secretAccess, error) {
return importSecretAccessV1(source)
}

func importSecretAccessV1(source map[interface{}]interface{}) (*secretAccess, error) {
Expand Down Expand Up @@ -609,6 +638,11 @@ type secretConsumerDeserializationFunc func(map[interface{}]interface{}) (*secre

var secretConsumerDeserializationFuncs = map[int]secretConsumerDeserializationFunc{
1: importSecretConsumerV1,
2: importSecretConsumerV2,
}

func importSecretConsumerV2(source map[interface{}]interface{}) (*secretConsumer, error) {
return importSecretConsumerV1(source)
}

func importSecretConsumerV1(source map[interface{}]interface{}) (*secretConsumer, error) {
Expand Down Expand Up @@ -800,6 +834,11 @@ type secretRevisionDeserializationFunc func(map[interface{}]interface{}) (*secre

var secretRevisionRangeDeserializationFuncs = map[int]secretRevisionDeserializationFunc{
1: importSecretRevisionV1,
2: importSecretRevisionV2,
}

func importSecretRevisionV2(source map[interface{}]interface{}) (*secretRevision, error) {
return importSecretRevisionV1(source)
}

func importSecretRevisionV1(source map[interface{}]interface{}) (*secretRevision, error) {
Expand Down
32 changes: 17 additions & 15 deletions secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,21 @@ func testSecretArgs() SecretArgs {
updated := created.Add(time.Hour)
nextRotate := created.Add(2 * time.Hour)
return SecretArgs{
ID: id,
Version: 1,
Description: "a secret",
Label: "secret label",
RotatePolicy: "hourly",
AutoPrune: true,
Owner: names.NewApplicationTag("postgresql"),
Created: created,
Updated: updated,
NextRotateTime: &nextRotate,
Revisions: testSecretRevisionsArgs(),
ACL: testSecretAccessArgs(),
Consumers: testSecretConsumerArgs(),
RemoteConsumers: testSecretRemoteConsumerArgs(),
ID: id,
Version: 1,
Description: "a secret",
Label: "secret label",
RotatePolicy: "hourly",
AutoPrune: true,
Owner: names.NewApplicationTag("postgresql"),
Created: created,
Updated: updated,
NextRotateTime: &nextRotate,
LatestRevisionChecksum: "checksum",
Revisions: testSecretRevisionsArgs(),
ACL: testSecretAccessArgs(),
Consumers: testSecretConsumerArgs(),
RemoteConsumers: testSecretRemoteConsumerArgs(),
}
}

Expand Down Expand Up @@ -126,6 +127,7 @@ func (s *SecretsSerializationSuite) TestNewSecret(c *gc.C) {
c.Check(secret.Updated(), jc.DeepEquals, args.Updated)
c.Check(secret.NextRotateTime(), jc.DeepEquals, args.NextRotateTime)
c.Check(secret.LatestRevision(), gc.Equals, 2)
c.Check(secret.LatestRevisionChecksum(), gc.Equals, "checksum")
c.Check(secret.LatestExpireTime(), jc.DeepEquals, args.Revisions[1].ExpireTime)
owner, err := secret.Owner()
c.Check(err, jc.ErrorIsNil)
Expand Down Expand Up @@ -248,7 +250,7 @@ func (s *SecretsSerializationSuite) exportImport(c *gc.C, secret_ *secret, versi
func (s *SecretsSerializationSuite) TestParsingSerializedData(c *gc.C) {
args := testSecretArgs()
original := newSecret(args)
secret := s.exportImport(c, original, 1)
secret := s.exportImport(c, original, 2)
c.Assert(secret, jc.DeepEquals, original)
}

Expand Down

0 comments on commit e21a788

Please sign in to comment.