Skip to content

Commit 669d3ae

Browse files
stttsbertinatto
authored andcommitted
UPSTREAM: <carry>: noderestrictions: add node-role.kubernetes.io/* to allowed node labels
Server side validation of node labels was added in kubernetes#90307. We only disabled kubelet-side validation before to make our node role labels work. UPSTREAM: <carry>: add control plane to allow roles OpenShift-Rebase-Source: 38bfed3 OpenShift-Rebase-Source: aff4434 UPSTREAM: <carry>: Do not allow nodes to set forbidden openshift labels Signed-off-by: Harshal Patil <[email protected]>
1 parent 300ea93 commit 669d3ae

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

cmd/kubelet/app/options/options.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ func ValidateKubeletFlags(f *KubeletFlags) error {
150150
invalidLabelErrs := make(map[string][]string)
151151
for k, v := range f.NodeLabels {
152152
if isKubernetesLabel(k) && !kubeletapis.IsKubeletLabel(k) {
153+
if kubeletapis.IsForbiddenOpenshiftLabel(k) {
154+
continue
155+
}
153156
unknownLabels.Insert(k)
154157
}
155158

plugin/pkg/admission/noderestriction/admission.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ func (p *Plugin) admitNode(nodeName string, a admission.Attributes) error {
520520
// Don't allow a node to register with labels outside the allowed set.
521521
// This would allow a node to add or modify its labels in a way that would let it steer privileged workloads to itself.
522522
modifiedLabels := getModifiedLabels(node.Labels, nil)
523-
if forbiddenLabels := p.getForbiddenLabels(modifiedLabels); len(forbiddenLabels) > 0 {
523+
if forbiddenLabels := p.getForbiddenLabels(modifiedLabels, a.GetOperation()); len(forbiddenLabels) > 0 {
524524
return admission.NewForbidden(a, fmt.Errorf("node %q is not allowed to set the following labels: %s", nodeName, strings.Join(forbiddenLabels.List(), ", ")))
525525
}
526526
}
@@ -556,9 +556,10 @@ func (p *Plugin) admitNode(nodeName string, a admission.Attributes) error {
556556
// Don't allow a node to update labels outside the allowed set.
557557
// This would allow a node to add or modify its labels in a way that would let it steer privileged workloads to itself.
558558
modifiedLabels := getModifiedLabels(node.Labels, oldNode.Labels)
559-
if forbiddenUpdateLabels := p.getForbiddenLabels(modifiedLabels); len(forbiddenUpdateLabels) > 0 {
559+
if forbiddenUpdateLabels := p.getForbiddenLabels(modifiedLabels, a.GetOperation()); len(forbiddenUpdateLabels) > 0 {
560560
return admission.NewForbidden(a, fmt.Errorf("is not allowed to modify labels: %s", strings.Join(forbiddenUpdateLabels.List(), ", ")))
561561
}
562+
562563
}
563564

564565
return nil
@@ -599,7 +600,7 @@ func getLabelNamespace(key string) string {
599600
}
600601

601602
// getForbiddenLabels returns the set of labels that may not be added, removed, or modified by the node on create or update.
602-
func (p *Plugin) getForbiddenLabels(modifiedLabels sets.String) sets.String {
603+
func (p *Plugin) getForbiddenLabels(modifiedLabels sets.String, admissionOpn admission.Operation) sets.String {
603604
if len(modifiedLabels) == 0 {
604605
return nil
605606
}
@@ -614,6 +615,11 @@ func (p *Plugin) getForbiddenLabels(modifiedLabels sets.String) sets.String {
614615
// forbid kubelets from setting unknown kubernetes.io and k8s.io labels on update
615616
if isKubernetesLabel(label) && !kubeletapis.IsKubeletLabel(label) {
616617
// TODO: defer to label policy once available
618+
if admissionOpn == admission.Create {
619+
if kubeletapis.IsForbiddenOpenshiftLabel(label) {
620+
continue
621+
}
622+
}
617623
forbiddenLabels.Insert(label)
618624
}
619625
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package apis
18+
19+
import (
20+
"k8s.io/apimachinery/pkg/util/sets"
21+
)
22+
23+
const (
24+
NodeLabelControlPlane = "node-role.kubernetes.io/control-plane"
25+
NodeLabelMaster = "node-role.kubernetes.io/master"
26+
NodeLabelWorker = "node-role.kubernetes.io/worker"
27+
NodeLabelEtcd = "node-role.kubernetes.io/etcd"
28+
)
29+
30+
var openshiftNodeLabels = sets.NewString(
31+
NodeLabelControlPlane,
32+
NodeLabelMaster,
33+
NodeLabelWorker,
34+
NodeLabelEtcd,
35+
)
36+
37+
func OpenShiftNodeLabels() []string {
38+
return openshiftNodeLabels.List()
39+
}
40+
41+
func IsForbiddenOpenshiftLabel(label string) bool {
42+
return openshiftNodeLabels.Has(label)
43+
}

0 commit comments

Comments
 (0)