Code and tests to validate retention config (#5117)
Basic validation checks that make sure maintenance and retention options are consistent with each other. This at least makes sure retention is either enabled and maintenance extends locks or nothing is locked at all. Going to be part of a set of PRs for validating the kopia config --- #### Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No #### Type of change - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [x] 🤖 Supportability/Tests - [ ] 💻 CI/Deployment - [ ] 🧹 Tech Debt/Cleanup #### Test Plan - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
cc24f9b6e7
commit
683f163df1
@ -136,3 +136,34 @@ func (r *Opts) setBlobConfigMode(
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify checks that the config info in r passes kopia's retention validation
|
||||||
|
// checks when it comes to locking durations and that if retention is requested
|
||||||
|
// in the blob config blob then lock extension is also configured to run during
|
||||||
|
// maintenance. If rentention is not enabled in the blob config blob then lock
|
||||||
|
// extension should be disabled during maintenance.
|
||||||
|
func (r Opts) Verify(ctx context.Context) error {
|
||||||
|
if !r.blobCfg.IsRetentionEnabled() {
|
||||||
|
if r.params.ExtendObjectLocks {
|
||||||
|
return clues.NewWC(
|
||||||
|
ctx,
|
||||||
|
"retention disabled but maintenance lock extension enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both disabled.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rest of function handles case where retention is enabled in the blob config
|
||||||
|
// blob.
|
||||||
|
if !r.params.ExtendObjectLocks {
|
||||||
|
return clues.NewWC(
|
||||||
|
ctx,
|
||||||
|
"retention enabled but maintenance lock extension disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
return clues.Stack(maintenance.CheckExtendRetention(
|
||||||
|
ctx,
|
||||||
|
r.blobCfg,
|
||||||
|
&r.params)).OrNil()
|
||||||
|
}
|
||||||
|
|||||||
@ -202,3 +202,97 @@ func (suite *OptsUnitSuite) TestSet() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *OptsUnitSuite) TestVerify() {
|
||||||
|
mode := blob.Governance
|
||||||
|
fullCycleInterval := time.Hour * 24
|
||||||
|
duration := 2 * fullCycleInterval
|
||||||
|
|
||||||
|
table := []struct {
|
||||||
|
name string
|
||||||
|
input *retention.Opts
|
||||||
|
expectErr assert.ErrorAssertionFunc
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ValidDisabled",
|
||||||
|
input: retention.OptsFromConfigs(
|
||||||
|
format.BlobStorageConfiguration{},
|
||||||
|
maintenance.Params{
|
||||||
|
FullCycle: maintenance.CycleParams{
|
||||||
|
Interval: fullCycleInterval,
|
||||||
|
},
|
||||||
|
ExtendObjectLocks: false,
|
||||||
|
}),
|
||||||
|
expectErr: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ValidEnabled",
|
||||||
|
input: retention.OptsFromConfigs(
|
||||||
|
format.BlobStorageConfiguration{
|
||||||
|
RetentionMode: mode,
|
||||||
|
RetentionPeriod: duration,
|
||||||
|
},
|
||||||
|
maintenance.Params{
|
||||||
|
FullCycle: maintenance.CycleParams{
|
||||||
|
Interval: fullCycleInterval,
|
||||||
|
},
|
||||||
|
ExtendObjectLocks: true,
|
||||||
|
}),
|
||||||
|
expectErr: assert.NoError,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "InvalidDuration",
|
||||||
|
input: retention.OptsFromConfigs(
|
||||||
|
format.BlobStorageConfiguration{
|
||||||
|
RetentionMode: mode,
|
||||||
|
RetentionPeriod: fullCycleInterval,
|
||||||
|
},
|
||||||
|
maintenance.Params{
|
||||||
|
FullCycle: maintenance.CycleParams{
|
||||||
|
Interval: fullCycleInterval,
|
||||||
|
},
|
||||||
|
ExtendObjectLocks: true,
|
||||||
|
}),
|
||||||
|
expectErr: assert.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "InvalidNotExtending",
|
||||||
|
input: retention.OptsFromConfigs(
|
||||||
|
format.BlobStorageConfiguration{
|
||||||
|
RetentionMode: mode,
|
||||||
|
RetentionPeriod: duration,
|
||||||
|
},
|
||||||
|
maintenance.Params{
|
||||||
|
FullCycle: maintenance.CycleParams{
|
||||||
|
Interval: fullCycleInterval,
|
||||||
|
},
|
||||||
|
ExtendObjectLocks: false,
|
||||||
|
}),
|
||||||
|
expectErr: assert.Error,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "InvalidNotConfigured",
|
||||||
|
input: retention.OptsFromConfigs(
|
||||||
|
format.BlobStorageConfiguration{},
|
||||||
|
maintenance.Params{
|
||||||
|
FullCycle: maintenance.CycleParams{
|
||||||
|
Interval: fullCycleInterval,
|
||||||
|
},
|
||||||
|
ExtendObjectLocks: true,
|
||||||
|
}),
|
||||||
|
expectErr: assert.Error,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range table {
|
||||||
|
suite.Run(test.name, func() {
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
ctx, flush := tester.NewContext(t)
|
||||||
|
t.Cleanup(flush)
|
||||||
|
|
||||||
|
err := test.input.Verify(ctx)
|
||||||
|
test.expectErr(t, err, clues.ToCore(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user