Skip to content

Commit b0d41ad

Browse files
author
Yu Cao
authored
Count policyset placement and validate config (#35)
Policyset placement was not counted in config validation which was causing placement to be generated by default Signed-off-by: Yu Cao <[email protected]>
1 parent fc71481 commit b0d41ad

File tree

2 files changed

+108
-28
lines changed

2 files changed

+108
-28
lines changed

internal/plugin.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,76 @@ func (p *Plugin) assertValidConfig() error {
587587
}
588588
}
589589

590+
for i := range p.PolicySets {
591+
seen := map[string]bool{}
592+
plcset := &p.PolicySets[i]
593+
594+
if plcset.Name == "" {
595+
return fmt.Errorf(
596+
"each policySet must have a name set, but did not find a name at policySet array index %d", i,
597+
)
598+
}
599+
600+
if seen[plcset.Name] {
601+
return fmt.Errorf(
602+
"each policySet must have a unique name set, but found a duplicate name: %s", plcset.Name,
603+
)
604+
}
605+
seen[plcset.Name] = true
606+
607+
// Validate policy Placement settings
608+
if plcset.Placement.PlacementRulePath != "" && plcset.Placement.PlacementPath != "" {
609+
return fmt.Errorf(
610+
"policySet %s must provide only one of placementRulePath or placementPath", plcset.Name,
611+
)
612+
}
613+
614+
if len(plcset.Placement.ClusterSelectors) > 0 && len(plcset.Placement.LabelSelector) > 0 {
615+
return fmt.Errorf(
616+
"policySet %s must provide only one of placement.labelSelector or placement.clusterselectors",
617+
plcset.Name,
618+
)
619+
}
620+
if (len(plcset.Placement.ClusterSelectors) != 0 || len(plcset.Placement.LabelSelector) != 0) &&
621+
(plcset.Placement.PlacementRulePath != "" || plcset.Placement.PlacementPath != "") {
622+
return fmt.Errorf(
623+
"policySet %s may not specify a placement selector and placement path together", plcset.Name,
624+
)
625+
}
626+
if plcset.Placement.PlacementRulePath != "" {
627+
_, err := os.Stat(plcset.Placement.PlacementRulePath)
628+
if err != nil {
629+
return fmt.Errorf(
630+
"could not read the placement rule path %s",
631+
plcset.Placement.PlacementRulePath,
632+
)
633+
}
634+
}
635+
if plcset.Placement.PlacementPath != "" {
636+
_, err := os.Stat(plcset.Placement.PlacementPath)
637+
if err != nil {
638+
return fmt.Errorf(
639+
"could not read the placement path %s",
640+
plcset.Placement.PlacementPath,
641+
)
642+
}
643+
}
644+
645+
foundPl := false
646+
if len(plcset.Placement.LabelSelector) != 0 || plcset.Placement.PlacementPath != "" {
647+
plCount.plc++
648+
foundPl = true
649+
}
650+
if len(plcset.Placement.ClusterSelectors) != 0 || plcset.Placement.PlacementRulePath != "" {
651+
plCount.plr++
652+
if foundPl {
653+
return fmt.Errorf(
654+
"policySet %s may not use both Placement and PlacementRule kinds", plcset.Name,
655+
)
656+
}
657+
}
658+
}
659+
590660
// Validate only one type of placement kind is in use
591661
if plCount.plc != 0 && plCount.plr != 0 {
592662
return fmt.Errorf(

internal/plugin_test.go

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,10 @@ func TestGeneratePolicySetsWithPlacement(t *testing.T) {
13471347

13481348
p.applyDefaults(map[string]interface{}{})
13491349

1350+
if err := p.assertValidConfig(); err != nil {
1351+
t.Fatal(err.Error())
1352+
}
1353+
13501354
expected := `
13511355
---
13521356
apiVersion: policy.open-cluster-management.io/v1
@@ -1389,25 +1393,26 @@ spec:
13891393
policies:
13901394
- policy-app-config
13911395
---
1392-
apiVersion: cluster.open-cluster-management.io/v1alpha1
1393-
kind: Placement
1396+
apiVersion: apps.open-cluster-management.io/v1
1397+
kind: PlacementRule
13941398
metadata:
13951399
name: my-placement-rule
13961400
namespace: my-policies
13971401
spec:
1398-
predicates:
1399-
- requiredClusterSelector:
1400-
labelSelector:
1401-
matchExpressions: []
1402+
clusterConditions:
1403+
- status: "True"
1404+
type: ManagedClusterConditionAvailable
1405+
clusterSelector:
1406+
matchExpressions: []
14021407
---
14031408
apiVersion: policy.open-cluster-management.io/v1
14041409
kind: PlacementBinding
14051410
metadata:
14061411
name: my-placement-binding
14071412
namespace: my-policies
14081413
placementRef:
1409-
apiGroup: cluster.open-cluster-management.io
1410-
kind: Placement
1414+
apiGroup: apps.open-cluster-management.io
1415+
kind: PlacementRule
14111416
name: my-placement-rule
14121417
subjects:
14131418
- apiGroup: policy.open-cluster-management.io
@@ -1458,6 +1463,9 @@ func TestGeneratePolicySetsWithPolicyPlacement(t *testing.T) {
14581463
}
14591464

14601465
p.applyDefaults(map[string]interface{}{})
1466+
if err := p.assertValidConfig(); err != nil {
1467+
t.Fatal(err.Error())
1468+
}
14611469
p.Policies[0].GeneratePlacementWhenInSet = true
14621470

14631471
expected := `
@@ -1502,40 +1510,42 @@ spec:
15021510
policies:
15031511
- policy-app-config
15041512
---
1505-
apiVersion: cluster.open-cluster-management.io/v1alpha1
1506-
kind: Placement
1513+
apiVersion: apps.open-cluster-management.io/v1
1514+
kind: PlacementRule
15071515
metadata:
15081516
name: my-placement
15091517
namespace: my-policies
15101518
spec:
1511-
predicates:
1512-
- requiredClusterSelector:
1513-
labelSelector:
1514-
matchExpressions: []
1519+
clusterConditions:
1520+
- status: "True"
1521+
type: ManagedClusterConditionAvailable
1522+
clusterSelector:
1523+
matchExpressions: []
15151524
---
1516-
apiVersion: cluster.open-cluster-management.io/v1alpha1
1517-
kind: Placement
1525+
apiVersion: apps.open-cluster-management.io/v1
1526+
kind: PlacementRule
15181527
metadata:
15191528
name: policyset-placement
15201529
namespace: my-policies
15211530
spec:
1522-
predicates:
1523-
- requiredClusterSelector:
1524-
labelSelector:
1525-
matchExpressions:
1526-
- key: my
1527-
operator: In
1528-
values:
1529-
- app
1531+
clusterConditions:
1532+
- status: "True"
1533+
type: ManagedClusterConditionAvailable
1534+
clusterSelector:
1535+
matchExpressions:
1536+
- key: my
1537+
operator: In
1538+
values:
1539+
- app
15301540
---
15311541
apiVersion: policy.open-cluster-management.io/v1
15321542
kind: PlacementBinding
15331543
metadata:
15341544
name: binding-policy-app-config
15351545
namespace: my-policies
15361546
placementRef:
1537-
apiGroup: cluster.open-cluster-management.io
1538-
kind: Placement
1547+
apiGroup: apps.open-cluster-management.io
1548+
kind: PlacementRule
15391549
name: my-placement
15401550
subjects:
15411551
- apiGroup: policy.open-cluster-management.io
@@ -1548,8 +1558,8 @@ metadata:
15481558
name: my-placement-binding
15491559
namespace: my-policies
15501560
placementRef:
1551-
apiGroup: cluster.open-cluster-management.io
1552-
kind: Placement
1561+
apiGroup: apps.open-cluster-management.io
1562+
kind: PlacementRule
15531563
name: policyset-placement
15541564
subjects:
15551565
- apiGroup: policy.open-cluster-management.io

0 commit comments

Comments
 (0)