зеркало из
1
0
Форкнуть 0
node-label-operator/labelsync/labelsync.go

137 строки
5.3 KiB
Go

package labelsync
import (
"errors"
"fmt"
"github.com/Azure/go-autorest/autorest/to"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/record"
azrsrc "github.com/Azure/node-label-operator/azure/computeresource"
"github.com/Azure/node-label-operator/labelsync/naming"
"github.com/Azure/node-label-operator/labelsync/options"
)
// return patch with new labels, if any, otherwise return nil for no new labels or an error
func TagsToNodes(namespacedName types.NamespacedName, computeResource azrsrc.ComputeResource,
node *corev1.Node, configOptions *options.ConfigOptions, log logr.Logger, recorder record.EventRecorder) ([]byte, error) {
newLabels := map[string]*string{} // should allow for null JSON values
for tagName, tagVal := range computeResource.Tags() {
if !naming.ValidLabelName(tagName) {
log.V(0).Info("invalid label name", "tag name", tagName)
continue
}
if !naming.ValidLabelVal(*tagVal) {
log.V(0).Info("invalid label value", "tag value", *tagVal)
continue
}
validLabelName := naming.ConvertTagNameToValidLabelName(tagName, configOptions.LabelPrefix)
labelVal, ok := node.Labels[validLabelName]
if !ok {
// add tag as label
log.V(1).Info("applying tags to nodes", "tag name", tagName, "tag value", *tagVal)
newLabels[validLabelName] = tagVal
} else if labelVal != *tagVal {
switch configOptions.ConflictPolicy {
case options.ARMPrecedence:
// set label anyway
log.V(1).Info("overriding existing node label with ARM tag", "tag name", tagName, "tag value", tagVal)
newLabels[validLabelName] = tagVal
case options.NodePrecedence:
// do nothing
log.V(0).Info("name->value conflict found", "node label value", labelVal, "ARM tag value", *tagVal)
case options.Ignore:
// raise k8s event
recorder.Event(node, "Warning", "ConflictingTagLabelValues",
fmt.Sprintf("ARM tag was not applied to node because a different value for '%s' already exists (%s != %s).", tagName, *tagVal, labelVal))
log.V(0).Info("name->value conflict found, leaving unchanged", "label value", labelVal, "tag value", *tagVal)
default:
return nil, errors.New("unrecognized conflict policy")
}
}
}
// delete labels if tag has been deleted
// if conflict policy is node precedence (which it will most likely not be), then don't delete tags if they exist on node
if labelDeletionAllowed(configOptions) {
for labelFullName, labelVal := range node.Labels {
if naming.HasLabelPrefix(labelFullName, configOptions.LabelPrefix) {
// check if exists on vm/vmss
labelName := naming.LabelWithoutPrefix(labelFullName, configOptions.LabelPrefix)
_, ok := computeResource.Tags()[labelName]
if !ok { // if label doesn't exist on ARM resource, delete
log.V(1).Info("deleting label from node", "label name", labelFullName, "label value", labelVal)
delete(node.Labels, labelFullName) // for some reason this is needed
newLabels[labelFullName] = nil // this should becomes 'null' in JSON, necessary for merge patch
}
}
}
}
if len(newLabels) == 0 { // to avoid unnecessary patching
return nil, nil
}
patch, err := LabelPatchWithDelete(newLabels)
if err != nil {
return nil, err
}
return patch, nil
}
func LabelsToAzureResource(namespacedName types.NamespacedName, computeResource azrsrc.ComputeResource,
node *corev1.Node, configOptions *options.ConfigOptions, log logr.Logger, recorder record.EventRecorder) (map[string]*string, error) {
if len(computeResource.Tags()) >= naming.MaxNumTags {
log.V(0).Info("can't add any more tags", "number of tags", len(computeResource.Tags()))
return computeResource.Tags(), nil
}
newTags := map[string]*string{}
for labelName, labelVal := range node.Labels {
if !naming.ValidTagName(labelName, configOptions.LabelPrefix) {
log.V(2).Info("invalid tag name", "label name", labelName)
continue
}
if !naming.ValidTagVal(labelVal) {
log.V(2).Info("invalid tag name", "label name", labelName)
continue
}
validTagName := naming.ConvertLabelNameToValidTagName(labelName, configOptions.LabelPrefix)
tagVal, ok := computeResource.Tags()[validTagName]
if !ok {
// add label as tag
log.V(1).Info("applying labels to Azure resource", "label name", labelName, "label value", labelVal)
newTags[validTagName] = to.StringPtr(labelVal)
} else if *tagVal != labelVal {
switch configOptions.ConflictPolicy {
case options.NodePrecedence:
// set tag anyway
log.V(1).Info("overriding existing ARM tag with node label", "label name", labelName, "label value", labelVal)
newTags[validTagName] = to.StringPtr(labelVal)
case options.ARMPrecedence:
// do nothing
log.V(0).Info("name->value conflict found", "node label value", labelVal, "ARM tag value", *tagVal)
case options.Ignore:
// raise k8s event
recorder.Event(node, "Warning", "ConflictingTagLabelValues",
fmt.Sprintf("node label was not applied to Azure resource because a different value for '%s' already exists (%s != %s).", labelName, labelVal, *tagVal))
log.V(0).Info("name->value conflict found, leaving unchanged", "label value", labelVal, "tag value", *tagVal)
default:
return nil, errors.New("unrecognized conflict policy")
}
}
}
if len(newTags) == 0 { // if unchanged
return nil, nil
}
return newTags, nil
}