Skip to content

Commit

Permalink
[Security Hardened Shoot Cluster] Rule 1000 check Shoot labels (#398)
Browse files Browse the repository at this point in the history
* Improve rule 1000 to check shoot labels

* Add suggested changes
  • Loading branch information
AleksandarSavchev authored Dec 9, 2024
1 parent 2e69de6 commit b30a4e2
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 33 deletions.
26 changes: 14 additions & 12 deletions pkg/provider/garden/ruleset/securityhardenedshoot/rules/1000.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,26 @@ func (r *Rule1000) Run(ctx context.Context) (rule.RuleResult, error) {
return rule.Result(r, rule.PassedCheckResult("There are no required extensions.", rule.NewTarget())), nil
}

if len(shoot.Spec.Extensions) == 0 {
return rule.Result(r, rule.FailedCheckResult("There are no configured extensions for the shoot cluster.", rule.NewTarget())), nil
}

var checkResults []rule.CheckResult

for _, extension := range r.Options.Extensions {
extensionTypeIndex := slices.IndexFunc(shoot.Spec.Extensions, func(shootSpecExtension gardencorev1beta1.Extension) bool {
return shootSpecExtension.Type == extension.Type
})
var (
extensionIndex = slices.IndexFunc(shoot.Spec.Extensions, func(shootSpecExtension gardencorev1beta1.Extension) bool {
return shootSpecExtension.Type == extension.Type
})
extensionDisabled = extensionIndex >= 0 && shoot.Spec.Extensions[extensionIndex].Disabled != nil && *shoot.Spec.Extensions[extensionIndex].Disabled
extensionLabelValue, extensionLabelExists = shoot.Labels["extensions.extensions.gardener.cloud/"+extension.Type]
)

switch {
case extensionTypeIndex < 0:
checkResults = append(checkResults, rule.FailedCheckResult(fmt.Sprintf("Extension type %s is not configured for the shoot cluster.", extension.Type), rule.NewTarget()))
case shoot.Spec.Extensions[extensionTypeIndex].Disabled == nil || !*shoot.Spec.Extensions[extensionTypeIndex].Disabled:
checkResults = append(checkResults, rule.PassedCheckResult(fmt.Sprintf("Extension type %s is enabled for the shoot cluster.", extension.Type), rule.NewTarget()))
case !extensionLabelExists:
checkResults = append(checkResults, rule.FailedCheckResult(fmt.Sprintf("Extension %s is not configured for the shoot cluster.", extension.Type), rule.NewTarget()))
case extensionLabelValue == "true" && !extensionDisabled:
checkResults = append(checkResults, rule.PassedCheckResult(fmt.Sprintf("Extension %s is enabled for the shoot cluster.", extension.Type), rule.NewTarget()))
case extensionLabelValue == "true" && extensionDisabled:
checkResults = append(checkResults, rule.FailedCheckResult(fmt.Sprintf("Extension %s is disabled in the shoot spec and enabled in labels.", extension.Type), rule.NewTarget()))
default:
checkResults = append(checkResults, rule.FailedCheckResult(fmt.Sprintf("Extension type %s is disabled for the shoot cluster.", extension.Type), rule.NewTarget()))
checkResults = append(checkResults, rule.FailedCheckResult(fmt.Sprintf("Extension %s has unexpected label value: %s.", extension.Type, extensionLabelValue), rule.NewTarget()))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,45 @@ var _ = Describe("#1000", func() {
{Status: rule.Passed, Message: "There are no required extensions.", Target: rule.NewTarget()},
},
),
Entry("should fail when no extensions are configured on the shoot spec",
Entry("should fail when a listed extension cannot be found",
func() {
shoot.Spec.Extensions = nil
shoot.Spec.Extensions = []gardencorev1beta1.Extension{
{
Type: "foo",
},
}
},
&rules.Options1000{Extensions: []rules.Extension{
{
Type: "not-foo",
Type: "foo",
},
},
},
[]rule.CheckResult{
{Status: rule.Failed, Message: "There are no configured extensions for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Failed, Message: "Extension foo is not configured for the shoot cluster.", Target: rule.NewTarget()},
},
),
Entry("should fail when a listed extension cannot be found",
Entry("should pass when a listed extension is enabled by default",
func() {
shoot.Labels = map[string]string{
"extensions.extensions.gardener.cloud/foo": "true",
}
},
&rules.Options1000{Extensions: []rules.Extension{
{
Type: "foo",
},
},
},
[]rule.CheckResult{
{Status: rule.Passed, Message: "Extension foo is enabled for the shoot cluster.", Target: rule.NewTarget()},
},
),
Entry("should pass when a listed extension is added to the extension list in the shoot spec",
func() {
shoot.Labels = map[string]string{
"extensions.extensions.gardener.cloud/foo": "true",
}
shoot.Spec.Extensions = []gardencorev1beta1.Extension{
{
Type: "foo",
Expand All @@ -105,20 +128,23 @@ var _ = Describe("#1000", func() {
},
&rules.Options1000{Extensions: []rules.Extension{
{
Type: "not-foo",
Type: "foo",
},
},
},
[]rule.CheckResult{
{Status: rule.Failed, Message: "Extension type not-foo is not configured for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Passed, Message: "Extension foo is enabled for the shoot cluster.", Target: rule.NewTarget()},
},
),
Entry("should fail when a listed extension is explicitly disabled",
Entry("should pass when a listed extension is added to the extension list in the shoot spec and explicitly enabled",
func() {
shoot.Labels = map[string]string{
"extensions.extensions.gardener.cloud/foo": "true",
}
shoot.Spec.Extensions = []gardencorev1beta1.Extension{
{
Type: "foo",
Disabled: ptr.To(true),
Disabled: ptr.To(false),
},
}
},
Expand All @@ -129,14 +155,18 @@ var _ = Describe("#1000", func() {
},
},
[]rule.CheckResult{
{Status: rule.Failed, Message: "Extension type foo is disabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Passed, Message: "Extension foo is enabled for the shoot cluster.", Target: rule.NewTarget()},
},
),
Entry("should pass when a listed extension is enabled by default",
Entry("should fail when a listed extension is enabled in the shoot labels and disabled in the shoot spec",
func() {
shoot.Labels = map[string]string{
"extensions.extensions.gardener.cloud/foo": "true",
}
shoot.Spec.Extensions = []gardencorev1beta1.Extension{
{
Type: "foo",
Type: "foo",
Disabled: ptr.To(true),
},
}
},
Expand All @@ -147,15 +177,17 @@ var _ = Describe("#1000", func() {
},
},
[]rule.CheckResult{
{Status: rule.Passed, Message: "Extension type foo is enabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Failed, Message: "Extension foo is disabled in the shoot spec and enabled in labels.", Target: rule.NewTarget()},
},
),
Entry("should pass when a listed extension is explicitly enabled",
Entry("should fail when a listed extension has unecpected value in the shoot labels",
func() {
shoot.Labels = map[string]string{
"extensions.extensions.gardener.cloud/foo": "false",
}
shoot.Spec.Extensions = []gardencorev1beta1.Extension{
{
Type: "foo",
Disabled: ptr.To(false),
Type: "foo",
},
}
},
Expand All @@ -166,11 +198,15 @@ var _ = Describe("#1000", func() {
},
},
[]rule.CheckResult{
{Status: rule.Passed, Message: "Extension type foo is enabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Failed, Message: "Extension foo has unexpected label value: false.", Target: rule.NewTarget()},
},
),
Entry("should create a check result for each provided extension in the configuration",
func() {
shoot.Labels = map[string]string{
"extensions.extensions.gardener.cloud/one": "true",
"extensions.extensions.gardener.cloud/two": "true",
}
shoot.Spec.Extensions = []gardencorev1beta1.Extension{
{
Type: "one",
Expand Down Expand Up @@ -201,10 +237,10 @@ var _ = Describe("#1000", func() {
},
},
[]rule.CheckResult{
{Status: rule.Passed, Message: "Extension type one is enabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Passed, Message: "Extension type two is enabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Failed, Message: "Extension type three is disabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Failed, Message: "Extension type four is not configured for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Passed, Message: "Extension one is enabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Passed, Message: "Extension two is enabled for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Failed, Message: "Extension three is not configured for the shoot cluster.", Target: rule.NewTarget()},
{Status: rule.Failed, Message: "Extension four is not configured for the shoot cluster.", Target: rule.NewTarget()},
},
),
)
Expand Down

0 comments on commit b30a4e2

Please sign in to comment.