@@ -13,6 +13,7 @@ import (
1313
1414 yaml "gopkg.in/yaml.v3"
1515 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
16+ "k8s.io/apimachinery/pkg/util/validation"
1617 "open-cluster-management.io/ocm-kustomize-generator-plugins/internal/types"
1718)
1819
@@ -30,6 +31,8 @@ const (
3031 placementAPIVersion = "cluster.open-cluster-management.io/v1beta1"
3132 placementKind = "Placement"
3233 maxObjectNameLength = 63
34+ dnsReference = "https://kubernetes.io/docs/concepts/overview/working-with-objects/names/" +
35+ "#dns-subdomain-names"
3336)
3437
3538// Plugin is used to store the PolicyGenerator configuration and the methods to generate the
@@ -648,6 +651,41 @@ func (p *Plugin) assertValidConfig() error {
648651 )
649652 }
650653
654+ // validate placement and binding names are DNS compliant
655+ defPlrName := p .PolicyDefaults .Placement .PlacementRuleName
656+ if defPlrName != "" && len (validation .IsDNS1123Subdomain (defPlrName )) > 0 {
657+ return fmt .Errorf (
658+ "PolicyDefaults.Placement.PlacementRuleName placement name `%s` is not DNS compliant. See %s" ,
659+ defPlrName ,
660+ dnsReference ,
661+ )
662+ }
663+
664+ defPlcmtPlName := p .PolicyDefaults .Placement .PlacementName
665+ if defPlcmtPlName != "" && len (validation .IsDNS1123Subdomain (defPlcmtPlName )) > 0 {
666+ return fmt .Errorf (
667+ "PolicyDefaults.Placement.PlacementName `%s` is not DNS compliant. See %s" ,
668+ defPlcmtPlName ,
669+ dnsReference ,
670+ )
671+ }
672+
673+ defPlName := p .PolicyDefaults .Placement .Name
674+ if defPlName != "" && len (validation .IsDNS1123Subdomain (defPlName )) > 0 {
675+ return fmt .Errorf (
676+ "PolicyDefaults.Placement.Name `%s` is not DNS compliant. See %s" , defPlName , dnsReference ,
677+ )
678+ }
679+
680+ if p .PlacementBindingDefaults .Name != "" &&
681+ len (validation .IsDNS1123Subdomain (p .PlacementBindingDefaults .Name )) > 0 {
682+ return fmt .Errorf (
683+ "PlacementBindingDefaults.Name `%s` is not DNS compliant. See %s" ,
684+ p .PlacementBindingDefaults .Name ,
685+ dnsReference ,
686+ )
687+ }
688+
651689 defaultPlacementOptions := 0
652690 if len (p .PolicyDefaults .Placement .LabelSelector ) != 0 || len (p .PolicyDefaults .Placement .ClusterSelectors ) != 0 {
653691 defaultPlacementOptions ++
@@ -685,6 +723,12 @@ func (p *Plugin) assertValidConfig() error {
685723 )
686724 }
687725
726+ if len (validation .IsDNS1123Subdomain (policy .Name )) > 0 {
727+ return fmt .Errorf (
728+ "policy name `%s` is not DNS compliant. See %s" , policy .Name , dnsReference ,
729+ )
730+ }
731+
688732 if seenPlc [policy .Name ] {
689733 return fmt .Errorf (
690734 "each policy must have a unique name set, but found a duplicate name: %s" , policy .Name ,
@@ -799,6 +843,34 @@ func (p *Plugin) assertValidConfig() error {
799843 )
800844 }
801845
846+ // validate placement names are DNS compliant
847+ plcPlrName := policy .Placement .PlacementRuleName
848+ if plcPlrName != "" && len (validation .IsDNS1123Subdomain (plcPlrName )) > 0 {
849+ return fmt .Errorf (
850+ "policy.Placement.PlacementRuleName `%s` is not DNS compliant. See %s" ,
851+ plcPlrName ,
852+ dnsReference ,
853+ )
854+ }
855+
856+ plcPlcmtPlName := policy .Placement .PlacementName
857+ if plcPlcmtPlName != "" && len (validation .IsDNS1123Subdomain (plcPlcmtPlName )) > 0 {
858+ return fmt .Errorf (
859+ "policy.Placement.PlacementRuleName `%s` is not DNS compliant. See %s" ,
860+ plcPlcmtPlName ,
861+ dnsReference ,
862+ )
863+ }
864+
865+ plcPlName := policy .Placement .Name
866+ if plcPlName != "" && len (validation .IsDNS1123Subdomain (plcPlName )) > 0 {
867+ return fmt .Errorf (
868+ "policy.Placement.PlacementRuleName `%s` is not DNS compliant. See %s" ,
869+ plcPlName ,
870+ dnsReference ,
871+ )
872+ }
873+
802874 policyPlacementOptions := 0
803875 if len (policy .Placement .LabelSelector ) != 0 || len (policy .Placement .ClusterSelectors ) != 0 {
804876 policyPlacementOptions ++
@@ -872,6 +944,12 @@ func (p *Plugin) assertValidConfig() error {
872944 )
873945 }
874946
947+ if len (validation .IsDNS1123Subdomain (plcset .Name )) > 0 {
948+ return fmt .Errorf (
949+ "policy set name `%s` is not DNS compliant. See %s" , plcset .Name , dnsReference ,
950+ )
951+ }
952+
875953 if seenPlcset [plcset .Name ] {
876954 return fmt .Errorf (
877955 "each policySet must have a unique name set, but found a duplicate name: %s" , plcset .Name ,
@@ -900,6 +978,28 @@ func (p *Plugin) assertValidConfig() error {
900978 )
901979 }
902980
981+ // validate placement names are DNS compliant
982+ plcSetPlrName := plcset .Placement .PlacementRuleName
983+ if plcSetPlrName != "" && len (validation .IsDNS1123Subdomain (plcSetPlrName )) > 0 {
984+ return fmt .Errorf (
985+ "plcset.Placement.PlacementRuleName `%s` is not DNS compliant. See %s" , plcSetPlrName , dnsReference ,
986+ )
987+ }
988+
989+ plcSetPlcmtPlName := plcset .Placement .PlacementName
990+ if plcSetPlcmtPlName != "" && len (validation .IsDNS1123Subdomain (plcSetPlcmtPlName )) > 0 {
991+ return fmt .Errorf (
992+ "plcset.Placement.PlacementName `%s` is not DNS compliant. See %s" , plcSetPlcmtPlName , dnsReference ,
993+ )
994+ }
995+
996+ plcSetPlName := plcset .Placement .Name
997+ if plcSetPlName != "" && len (validation .IsDNS1123Subdomain (plcSetPlName )) > 0 {
998+ return fmt .Errorf (
999+ "plcset.Placement.Name `%s` is not DNS compliant. See %s" , plcSetPlName , dnsReference ,
1000+ )
1001+ }
1002+
9031003 policySetPlacementOptions := 0
9041004 if len (plcset .Placement .LabelSelector ) != 0 || len (plcset .Placement .ClusterSelectors ) != 0 {
9051005 policySetPlacementOptions ++
0 commit comments