165 lines
3.3 KiB
Go
165 lines
3.3 KiB
Go
package resources
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
|
|
"github.com/dapr/kubernetes-operator/pkg/pointer"
|
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
)
|
|
|
|
func OwnerReference(owner client.Object) metav1.OwnerReference {
|
|
return metav1.OwnerReference{
|
|
APIVersion: owner.GetObjectKind().GroupVersionKind().GroupVersion().String(),
|
|
Kind: owner.GetObjectKind().GroupVersionKind().Kind,
|
|
Name: owner.GetName(),
|
|
UID: owner.GetUID(),
|
|
BlockOwnerDeletion: pointer.Any(true),
|
|
Controller: pointer.Any(true),
|
|
}
|
|
}
|
|
|
|
func OwnerReferences(owner client.Object) []metav1.OwnerReference {
|
|
return []metav1.OwnerReference{
|
|
OwnerReference(owner),
|
|
}
|
|
}
|
|
|
|
func Annotations(target *unstructured.Unstructured, annotations map[string]string) {
|
|
m := target.GetAnnotations()
|
|
|
|
if m == nil {
|
|
m = make(map[string]string)
|
|
}
|
|
|
|
for k, v := range annotations {
|
|
m[k] = v
|
|
}
|
|
|
|
target.SetAnnotations(m)
|
|
}
|
|
|
|
func Labels(target *unstructured.Unstructured, labels map[string]string) {
|
|
m := target.GetLabels()
|
|
|
|
if m == nil {
|
|
m = make(map[string]string)
|
|
}
|
|
|
|
for k, v := range labels {
|
|
m[k] = v
|
|
}
|
|
|
|
target.SetLabels(m)
|
|
}
|
|
|
|
func Label(target *unstructured.Unstructured, key string) string {
|
|
m := target.GetLabels()
|
|
|
|
if m == nil {
|
|
return ""
|
|
}
|
|
|
|
return m[key]
|
|
}
|
|
|
|
func Ref(obj client.Object) string {
|
|
name := obj.GetName()
|
|
if obj.GetNamespace() == "" {
|
|
name = obj.GetNamespace() + ":" + obj.GetName()
|
|
}
|
|
|
|
return fmt.Sprintf(
|
|
"%s:%s:%s",
|
|
obj.GetObjectKind().GroupVersionKind().Kind,
|
|
obj.GetObjectKind().GroupVersionKind().GroupVersion().String(),
|
|
name,
|
|
)
|
|
}
|
|
|
|
func ToUnstructured(s *runtime.Scheme, obj runtime.Object) (*unstructured.Unstructured, error) {
|
|
switch ot := obj.(type) {
|
|
case *unstructured.Unstructured:
|
|
return ot, nil
|
|
default:
|
|
var err error
|
|
var u unstructured.Unstructured
|
|
|
|
u.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(obj)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to convert to unstructured: %w", err)
|
|
}
|
|
|
|
gvk := u.GroupVersionKind()
|
|
if gvk.Group == "" || gvk.Kind == "" {
|
|
gvks, _, err := s.ObjectKinds(obj)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to convert to unstructured - unable to get GVK %w", err)
|
|
}
|
|
|
|
apiv, k := gvks[0].ToAPIVersionAndKind()
|
|
|
|
u.SetAPIVersion(apiv)
|
|
u.SetKind(k)
|
|
}
|
|
|
|
return &u, nil
|
|
}
|
|
}
|
|
|
|
func Decode(decoder runtime.Decoder, content []byte) ([]unstructured.Unstructured, error) {
|
|
results := make([]unstructured.Unstructured, 0)
|
|
|
|
r := bytes.NewReader(content)
|
|
yd := yaml.NewDecoder(r)
|
|
|
|
for {
|
|
var out map[string]interface{}
|
|
|
|
err := yd.Decode(&out)
|
|
if err != nil {
|
|
if errors.Is(err, io.EOF) {
|
|
break
|
|
}
|
|
|
|
return nil, fmt.Errorf("unable to decode resource: %w", err)
|
|
}
|
|
|
|
if len(out) == 0 {
|
|
continue
|
|
}
|
|
|
|
if out["Kind"] == "" {
|
|
continue
|
|
}
|
|
|
|
encoded, err := yaml.Marshal(out)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to marshal resource: %w", err)
|
|
}
|
|
|
|
var obj unstructured.Unstructured
|
|
|
|
if _, _, err = decoder.Decode(encoded, nil, &obj); err != nil {
|
|
if runtime.IsMissingKind(err) {
|
|
continue
|
|
}
|
|
|
|
return nil, fmt.Errorf("unable to decode resource: %w", err)
|
|
}
|
|
|
|
results = append(results, obj)
|
|
}
|
|
|
|
return results, nil
|
|
}
|