pkg/common/utils/resource/metadata.go (106 lines of code) (raw):
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package resource
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"strings"
)
type Labels map[string]string
func NewLabels(labels ...Labels) Labels {
nlabels := Labels{}
for _, l := range labels {
for k, v := range l {
nlabels[k] = v
}
}
return nlabels
}
func (l Labels) Add(key, value string) {
l[key] = value
}
func (l Labels) AddLabel(label Labels) {
if label == nil {
return
}
for k, v := range label {
l[k] = v
}
}
type Annotations map[string]string
func NewAnnotations(annotations ...Annotations) Annotations {
annotation := Annotations{}
for _, a := range annotations {
for k, v := range a {
annotation[k] = v
}
}
return annotation
}
func (a Annotations) Add(key, value string) {
a[key] = value
}
func (a Annotations) AddAnnotation(annotation Annotations) {
for k, v := range annotation {
a[k] = v
}
}
// mergeMetadata takes labels and annotations from the old resource and merges
// them into the new resource. If a key is present in both resources, the new
// resource wins. It also copies the ResourceVersion from the old resource to
// the new resource to prevent update conflicts.
func MergeMetadata(new *metav1.ObjectMeta, old metav1.ObjectMeta) {
new.ResourceVersion = old.ResourceVersion
new.SetFinalizers(MergeSlices(new.Finalizers, old.Finalizers))
new.SetLabels(mergeMaps(new.Labels, old.Labels))
new.SetAnnotations(mergeMaps(new.Annotations, old.Annotations))
new.OwnerReferences = mergeOwnerReferences(new.OwnerReferences, old.OwnerReferences)
}
func MergeSlices(new []string, old []string) []string {
set := make(map[string]bool)
for _, s := range new {
set[s] = true
}
for _, os := range old {
if _, ok := set[os]; ok {
continue
}
new = append(new, os)
}
return new
}
func mergeMaps(new map[string]string, old map[string]string) map[string]string {
return mergeMapsByPrefix(new, old, "")
}
func mergeMapsByPrefix(from map[string]string, to map[string]string, prefix string) map[string]string {
if to == nil {
to = make(map[string]string)
}
if from == nil {
from = make(map[string]string)
}
for k, v := range from {
if strings.HasPrefix(k, prefix) {
to[k] = v
}
}
return to
}
func mergeOwnerReferences(old []metav1.OwnerReference, new []metav1.OwnerReference) []metav1.OwnerReference {
existing := make(map[metav1.OwnerReference]bool)
for _, ownerRef := range old {
existing[ownerRef] = true
}
for _, ownerRef := range new {
if _, ok := existing[ownerRef]; !ok {
old = append(old, ownerRef)
}
}
return old
}
func GetInt32Pointer(v int32) *int32 {
return &v
}
func GetOwnerReference(o client.Object) metav1.OwnerReference {
apiVersion, kind := o.GetObjectKind().GroupVersionKind().ToAPIVersionAndKind()
return metav1.OwnerReference{
APIVersion: apiVersion,
Kind: kind,
Name: o.GetName(),
UID: o.GetUID(),
}
}