Skip to content

Commit 34ca695

Browse files
JustinKuliopenshift-merge-robot
authored andcommitted
Add options for policy ordering
The new `dependencies` field in the generator is the same as the new `dependencies` field in the Policy type, however, more fields are optional and will be filled in by the generator with useful defaults. The new `ignorePending` field is also the same, but since that would be set on templates, and the generator does not expose much at the template level, here the field is set on the policy, and the generator sets the correct field in all the templates of that policy. For a similar reason, the `extraDependencies` field is not exposed in the generator at all. The new `orderViaDependencies` field will set up a chain of dependencies on the created policies. So if 3 policies are created by the generator, policy 2 will depend on policy 1, and policy 3 will depend on policy 2. In all cases, dependency lists are merged - setting it on a specific policy will *not* override the defaults, or a dependency added by the `orderViaDependencies` flag. Refs: - stolostron/backlog#26183 Signed-off-by: Justin Kulikauskas <[email protected]>
1 parent 98b3236 commit 34ca695

File tree

6 files changed

+352
-17
lines changed

6 files changed

+352
-17
lines changed

docs/policygenerator-reference.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ placementBindingDefaults:
1010
# Set an explicit placement binding name to use rather than rely on the default.
1111
name: ""
1212

13+
# Optional. Determines whether to define dependencies on the policies so they are applied in the
14+
# order they are defined in the manifests list. This defaults to false, and all the policies
15+
# can be applied at the same time.
16+
orderViaDependencies: false
17+
1318
# Required. Any default value listed here can be overridden under an entry in the policies array
1419
# except for "namespace".
1520
policyDefaults:
@@ -32,6 +37,21 @@ policyDefaults:
3237
# manifests being wrapped in the policy. If set to false, a configuration policy per manifest will
3338
# be generated. This defaults to true.
3439
consolidateManifests: true
40+
# Optional. A list of objects that should be in specific compliance states before this policy is
41+
# applied.
42+
dependencies:
43+
# Required. The name of the object being depended on.
44+
- name: ""
45+
# Optional. The namespace of the object being depended on. Will default to the namespace of
46+
# policies from this generator.
47+
namespace: ""
48+
# Optional. The compliance state the object should be in. Defaults to "Compliant"
49+
compliance: "Compliant"
50+
# Optional. The kind of the object. Defaults to "Policy", but can also be things like
51+
# ConfigurationPolicy.
52+
kind: "Policy"
53+
# Optional. The APIVersion of the object. Defaults to "policy.open-cluster-management.io/v1"
54+
apiVersion: "policy.open-cluster-management.io/v1"
3555
# Optional. Determines whether the policy is enabled or disabled. A disabled policy will not be
3656
# propagated to any managed clusters and will show no status as a result.
3757
disabled: false
@@ -47,6 +67,9 @@ policyDefaults:
4767
# deleted. Pruning only takes place if the remediation action of the policy has been set to "enforce". Example values
4868
# are "DeleteIfCreated", "DeleteAll", or "None". This defaults to unset, which is equivalent to "None".
4969
pruneObjectBehavior: "None"
70+
# Optional. Determines whether to treat the policy as compliant when it is waiting for its
71+
# dependencies to reach their desired states. Defaults to false.
72+
ignorePending: false
5073
# Optional. When the policy references a Gatekeeper policy manifest, this determines if an additional
5174
# configuration policy should be generated in order to receive policy violations in Open Cluster
5275
# Management when the Gatekeeper policy has been violated. This defaults to true.
@@ -191,12 +214,27 @@ policies:
191214
# Optional. (See policyDefaults.controls for description.)
192215
controls:
193216
- "CM-2 Baseline Configuration"
217+
# Optional. (See policyDefaults.dependencies for description.) Note: the list defined here will
218+
# be merged with the default list.
219+
dependencies:
220+
# Required. (See policyDefaults.dependencies.name for description.)
221+
- name: ""
222+
# Optional. (See policyDefaults.dependencies.namespace for description.)
223+
namespace: ""
224+
# Optional. (See policyDefaults.dependencies.compliance for description.)
225+
compliance: "Compliant"
226+
# Optional. (See policyDefaults.dependencies.kind for description.)
227+
kind: "Policy"
228+
# Optional. (See policyDefaults.dependencies.apiVersion for description.)
229+
apiVersion: "policy.open-cluster-management.io/v1"
194230
# Optional. (See policyDefaults.disabled for description.)
195231
disabled: false
196232
# Optional. (See policyDefaults.evaluationInterval for description.)
197233
evaluationInterval: {}
198234
# Optional. (See policyDefaults.pruneObjectBehavior for description.)
199235
pruneObjectBehavior: ""
236+
# Optional. (See policyDefaults.ignorePending for description.)
237+
ignorePending: false
200238
# Optional. (See policyDefaults.informGatekeeperPolicies for description.)
201239
informGatekeeperPolicies: true
202240
# Optional. (See policyDefaults.informKyvernoPolicies for description.)

internal/plugin.go

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ type Plugin struct {
4646
PlacementBindingDefaults struct {
4747
Name string `json:"name,omitempty" yaml:"name,omitempty"`
4848
} `json:"placementBindingDefaults,omitempty" yaml:"placementBindingDefaults,omitempty"`
49+
OrderViaDependencies bool `json:"orderViaDependencies,omitempty" yaml:"orderViaDependencies,omitempty"`
50+
4951
PolicyDefaults types.PolicyDefaults `json:"policyDefaults,omitempty" yaml:"policyDefaults,omitempty"`
5052
Policies []types.PolicyConfig `json:"policies" yaml:"policies"`
5153
PolicySets []types.PolicySetConfig `json:"policySets" yaml:"policySets"`
@@ -411,6 +413,27 @@ func (p *Plugin) applyDefaults(unmarshaledConfig map[string]interface{}) {
411413
}
412414
}
413415

416+
for i, dep := range p.PolicyDefaults.Dependencies {
417+
if dep.Namespace == "" {
418+
p.PolicyDefaults.Dependencies[i].Namespace = p.PolicyDefaults.Namespace
419+
}
420+
421+
if dep.Compliance == "" {
422+
p.PolicyDefaults.Dependencies[i].Compliance = "Compliant"
423+
}
424+
425+
if dep.Kind == "" {
426+
p.PolicyDefaults.Dependencies[i].Kind = policyKind
427+
}
428+
429+
if dep.APIVersion == "" {
430+
p.PolicyDefaults.Dependencies[i].APIVersion = policyAPIVersion
431+
}
432+
}
433+
434+
// Used when p.OrderViaDependencies is set
435+
prevPolicyName := ""
436+
414437
for i := range p.Policies {
415438
policy := &p.Policies[i]
416439

@@ -513,6 +536,43 @@ func (p *Plugin) applyDefaults(unmarshaledConfig map[string]interface{}) {
513536
policy.Disabled = p.PolicyDefaults.Disabled
514537
}
515538

539+
ignorePending, ignorePendingIsSet := getPolicyBool(unmarshaledConfig, i, "ignorePending")
540+
if ignorePendingIsSet {
541+
policy.IgnorePending = ignorePending
542+
} else {
543+
policy.IgnorePending = p.PolicyDefaults.IgnorePending
544+
}
545+
546+
for i, dep := range policy.Dependencies {
547+
if dep.Namespace == "" {
548+
policy.Dependencies[i].Namespace = p.PolicyDefaults.Namespace
549+
}
550+
551+
if dep.Compliance == "" {
552+
policy.Dependencies[i].Compliance = "Compliant"
553+
}
554+
555+
if dep.Kind == "" {
556+
policy.Dependencies[i].Kind = policyKind
557+
}
558+
559+
if dep.APIVersion == "" {
560+
policy.Dependencies[i].APIVersion = policyAPIVersion
561+
}
562+
}
563+
564+
policy.Dependencies = append(policy.Dependencies, p.PolicyDefaults.Dependencies...)
565+
566+
if p.OrderViaDependencies && prevPolicyName != "" {
567+
policy.Dependencies = append(policy.Dependencies, types.PolicyDependency{
568+
Name: prevPolicyName,
569+
Namespace: p.PolicyDefaults.Namespace,
570+
Compliance: "Compliant",
571+
Kind: policyKind,
572+
APIVersion: policyAPIVersion,
573+
})
574+
}
575+
516576
// Determine whether defaults are set for placement
517577
plcDefaultSet := len(p.PolicyDefaults.Placement.LabelSelector) != 0 ||
518578
p.PolicyDefaults.Placement.PlacementPath != "" ||
@@ -640,6 +700,8 @@ func (p *Plugin) applyDefaults(unmarshaledConfig map[string]interface{}) {
640700
for plcset := range plcToPlcset[policy.Name] {
641701
policy.PolicySets = append(policy.PolicySets, plcset)
642702
}
703+
704+
prevPolicyName = policy.Name
643705
}
644706

645707
// Sync up the declared policy sets in p.Policies[*]
@@ -740,6 +802,12 @@ func (p *Plugin) assertValidConfig() error {
740802
return errors.New("policies is empty but it must be set")
741803
}
742804

805+
for i, dep := range p.PolicyDefaults.Dependencies {
806+
if dep.Name == "" {
807+
return fmt.Errorf("dependency name must be set in policyDefaults dependency %v", i)
808+
}
809+
}
810+
743811
seenPlc := map[string]bool{}
744812
plCount := struct {
745813
plc int
@@ -985,6 +1053,12 @@ func (p *Plugin) assertValidConfig() error {
9851053
)
9861054
}
9871055
}
1056+
1057+
for i, dep := range policy.Dependencies {
1058+
if dep.Name == "" {
1059+
return fmt.Errorf("dependency name must be set in policy %v dependency %v", policy.Name, i)
1060+
}
1061+
}
9881062
}
9891063

9901064
seenPlcset := map[string]bool{}
@@ -1153,6 +1227,15 @@ func (p *Plugin) createPolicy(policyConf *types.PolicyConfig) error {
11531227
policyConf.Standards, ",",
11541228
)
11551229

1230+
spec := map[string]interface{}{
1231+
"disabled": policyConf.Disabled,
1232+
"policy-templates": policyTemplates,
1233+
}
1234+
1235+
if len(policyConf.Dependencies) != 0 {
1236+
spec["dependencies"] = policyConf.Dependencies
1237+
}
1238+
11561239
policy := map[string]interface{}{
11571240
"apiVersion": policyAPIVersion,
11581241
"kind": policyKind,
@@ -1161,10 +1244,7 @@ func (p *Plugin) createPolicy(policyConf *types.PolicyConfig) error {
11611244
"name": policyConf.Name,
11621245
"namespace": p.PolicyDefaults.Namespace,
11631246
},
1164-
"spec": map[string]interface{}{
1165-
"disabled": policyConf.Disabled,
1166-
"policy-templates": policyTemplates,
1167-
},
1247+
"spec": spec,
11681248
}
11691249

11701250
// set the root policy remediation action if all the remediation actions match

0 commit comments

Comments
 (0)