Skip to content

Commit

Permalink
Add pattern matching to validateSelectors
Browse files Browse the repository at this point in the history
Signed-off-by: Parthvi Vala <pvala@redhat.com>
  • Loading branch information
valaparthvi committed Jan 12, 2023
1 parent 5e0ff55 commit 33e9a5b
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,11 @@ func matchesSelector(req *runtimehooksv1.GeneratePatchesRequestItem, templateVar
return true
}
unquoted, _ := strconv.Unquote(string(templateMDClassJSON.Raw))
if strings.HasPrefix(mdClass, "*") {
mdClass = strings.TrimPrefix(mdClass, "*")
if strings.HasSuffix(unquoted, mdClass) {
return true
}
if strings.HasPrefix(mdClass, "*") && strings.HasSuffix(unquoted, strings.TrimPrefix(mdClass, "*")) {
return true
}
if strings.HasSuffix(mdClass, "*") {
mdClass = strings.TrimSuffix(mdClass, "*")
if strings.HasPrefix(unquoted, mdClass) {
return true
}
if strings.HasSuffix(mdClass, "*") && strings.HasPrefix(unquoted, strings.TrimSuffix(mdClass, "*")) {
return true
}
}
}
Expand Down
17 changes: 12 additions & 5 deletions internal/webhooks/patch_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"strings"
"text/template"

sprig "github.com/Masterminds/sprig/v3"
sprig "github.com/go-task/slim-sprig"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
Expand Down Expand Up @@ -218,19 +218,26 @@ func validateSelectors(selector clusterv1.PatchSelector, class *clusterv1.Cluste
"\"*\" rune can only appear at the beginning, or ending of the selector"))
break
}
// a valid selector with/out "*" should comply with Kubernetes naming standards.
// a valid selector without "*" should comply with Kubernetes naming standards.
if validation.IsQualifiedName(strings.ReplaceAll(name, "*", "a")) != nil {
allErrs = append(allErrs, field.Invalid(
path.Child("matchResources", "machineDeploymentClass", "names").Index(i),
name,
"selector does not comply with the Kubernetes naming standards"))
break
}
match = true
break
}
for _, md := range class.Spec.Workers.MachineDeployments {
if md.Class == name {
var matches bool
if md.Class == name || name == "*" {
matches = true
} else if strings.HasPrefix(name, "*") && strings.HasSuffix(md.Class, strings.TrimPrefix(name, "*")) {
matches = true
} else if strings.HasSuffix(name, "*") && strings.HasPrefix(md.Class, strings.TrimSuffix(name, "*")) {
matches = true
}

if matches {
if selectorMatchTemplate(selector, md.Template.Infrastructure.Ref) ||
selectorMatchTemplate(selector, md.Template.Bootstrap.Ref) {
match = true
Expand Down
58 changes: 57 additions & 1 deletion internal/webhooks/patch_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1877,7 +1877,7 @@ func Test_validateSelectors(t *testing.T) {
wantErr: true,
},
{
name: "pass if selector targets an existing MachineDeploymentClass InfrastructureTemplate with *",
name: "pass if selector targets an existing MachineDeploymentClass InfrastructureTemplate with prefix *",
selector: clusterv1.PatchSelector{
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
Kind: "InfrastructureMachineTemplate",
Expand All @@ -1904,6 +1904,62 @@ func Test_validateSelectors(t *testing.T) {
).
Build(),
},
{
name: "pass if selector targets an existing MachineDeploymentClass InfrastructureTemplate with suffix *",
selector: clusterv1.PatchSelector{
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
Kind: "InfrastructureMachineTemplate",
MatchResources: clusterv1.PatchSelectorMatch{
MachineDeploymentClass: &clusterv1.PatchSelectorMatchMachineDeploymentClass{
Names: []string{"*-a"},
},
},
},
clusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1").
WithWorkerMachineDeploymentClasses(
*builder.MachineDeploymentClass("a-something-a").
WithInfrastructureTemplate(
refToUnstructured(&corev1.ObjectReference{
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
Kind: "InfrastructureMachineTemplate",
})).
WithBootstrapTemplate(
refToUnstructured(&corev1.ObjectReference{
APIVersion: "bootstrap.cluster.x-k8s.io/v1beta1",
Kind: "BootstrapTemplate",
})).
Build(),
).
Build(),
},
{
name: "pass if selector targets all existing MachineDeploymentClass InfrastructureTemplate with *",
selector: clusterv1.PatchSelector{
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
Kind: "InfrastructureMachineTemplate",
MatchResources: clusterv1.PatchSelectorMatch{
MachineDeploymentClass: &clusterv1.PatchSelectorMatchMachineDeploymentClass{
Names: []string{"*"},
},
},
},
clusterClass: builder.ClusterClass(metav1.NamespaceDefault, "class1").
WithWorkerMachineDeploymentClasses(
*builder.MachineDeploymentClass("a-something-a").
WithInfrastructureTemplate(
refToUnstructured(&corev1.ObjectReference{
APIVersion: "infrastructure.cluster.x-k8s.io/v1beta1",
Kind: "InfrastructureMachineTemplate",
})).
WithBootstrapTemplate(
refToUnstructured(&corev1.ObjectReference{
APIVersion: "bootstrap.cluster.x-k8s.io/v1beta1",
Kind: "BootstrapTemplate",
})).
Build(),
).
Build(),
},
// The following tests have selectors which match multiple resources at the same time.
{
name: "fail if selector targets a matching infrastructureCluster reference and a not matching control plane",
Expand Down

0 comments on commit 33e9a5b

Please sign in to comment.