unstructured IsZero
This commit is contained in:
@@ -1,23 +1,46 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// Similar to
|
||||
// https://dev-k8sref-io.web.app/docs/common-definitions/objectreference-/
|
||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
type ObjectReference struct {
|
||||
Resource string `json:"resource,omitempty"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// APIGroup is the name of the API group that contains the referred object.
|
||||
// The empty string represents the core API group.
|
||||
APIGroup string `json:"apiGroup,omitempty"`
|
||||
|
||||
// APIVersion is the version of the API group that contains the referred object.
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
|
||||
// See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// Tenant isolation
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
|
||||
// Explicit resource identifier
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// May contain a valid JSON/Go field access statement
|
||||
FieldPath string `json:"fieldPath,omitempty"`
|
||||
|
||||
// Sepcific deployment of an object
|
||||
UID types.UID `json:"uid,omitempty"`
|
||||
}
|
||||
|
||||
func (r ObjectReference) ToOwnerReference() metav1.OwnerReference {
|
||||
return metav1.OwnerReference{
|
||||
APIVersion: fmt.Sprintf("%s/%s", r.APIGroup, r.APIVersion),
|
||||
Kind: r.Kind,
|
||||
Name: r.Name,
|
||||
UID: r.UID,
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
// Unstructured allows objects that do not have Golang structs registered to be manipulated
|
||||
// generically.
|
||||
type Unstructured struct {
|
||||
// Object is a JSON compatible map with string, float, int, bool, []interface{},
|
||||
// or map[string]interface{} children.
|
||||
Object map[string]interface{}
|
||||
// Object is a JSON compatible map with string, float, int, bool, []any,
|
||||
// or map[string]any children.
|
||||
Object map[string]any
|
||||
}
|
||||
|
||||
// Produce an API definition that represents map[string]any
|
||||
@@ -27,7 +27,7 @@ func (u Unstructured) OpenAPIDefinition() openapi.OpenAPIDefinition {
|
||||
AdditionalProperties: &spec.SchemaOrBool{Allows: true},
|
||||
},
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: map[string]interface{}{
|
||||
Extensions: map[string]any{
|
||||
"x-kubernetes-preserve-unknown-fields": true,
|
||||
},
|
||||
},
|
||||
@@ -39,14 +39,14 @@ func (u *Unstructured) IsZero() bool {
|
||||
return len(u.Object) == 0
|
||||
}
|
||||
|
||||
func (u *Unstructured) UnstructuredContent() map[string]interface{} {
|
||||
func (u *Unstructured) UnstructuredContent() map[string]any {
|
||||
if u.Object == nil {
|
||||
return make(map[string]interface{})
|
||||
return make(map[string]any)
|
||||
}
|
||||
return u.Object
|
||||
}
|
||||
|
||||
func (u *Unstructured) SetUnstructuredContent(content map[string]interface{}) {
|
||||
func (u *Unstructured) SetUnstructuredContent(content map[string]any) {
|
||||
u.Object = content
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ func (u *Unstructured) DeepCopy() *Unstructured {
|
||||
}
|
||||
out := new(Unstructured)
|
||||
*out = *u
|
||||
out.Object = deepCopyJSONValue(u.Object).(map[string]interface{})
|
||||
out.Object = deepCopyJSONValue(u.Object).(map[string]any)
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -82,24 +82,24 @@ func (u *Unstructured) DeepCopyInto(out *Unstructured) {
|
||||
// runtime.DeepCopyJSON(u.Object)
|
||||
//
|
||||
// BUT this avoids panic on int
|
||||
func deepCopyJSONValue(x interface{}) interface{} {
|
||||
func deepCopyJSONValue(x any) any {
|
||||
switch x := x.(type) {
|
||||
case map[string]interface{}:
|
||||
case map[string]any:
|
||||
if x == nil {
|
||||
// Typed nil - an interface{} that contains a type map[string]interface{} with a value of nil
|
||||
// Typed nil - an any that contains a type map[string]any with a value of nil
|
||||
return x
|
||||
}
|
||||
clone := make(map[string]interface{}, len(x))
|
||||
clone := make(map[string]any, len(x))
|
||||
for k, v := range x {
|
||||
clone[k] = deepCopyJSONValue(v)
|
||||
}
|
||||
return clone
|
||||
case []interface{}:
|
||||
case []any:
|
||||
if x == nil {
|
||||
// Typed nil - an interface{} that contains a type []interface{} with a value of nil
|
||||
// Typed nil - an any that contains a type []any with a value of nil
|
||||
return x
|
||||
}
|
||||
clone := make([]interface{}, len(x))
|
||||
clone := make([]any, len(x))
|
||||
for i, v := range x {
|
||||
clone[i] = deepCopyJSONValue(v)
|
||||
}
|
||||
@@ -128,23 +128,23 @@ func deepCopyJSONValue(x interface{}) interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *Unstructured) Set(field string, value interface{}) {
|
||||
func (u *Unstructured) Set(field string, value any) {
|
||||
if u.Object == nil {
|
||||
u.Object = make(map[string]interface{})
|
||||
u.Object = make(map[string]any)
|
||||
}
|
||||
_ = unstructured.SetNestedField(u.Object, value, field)
|
||||
}
|
||||
|
||||
func (u *Unstructured) Remove(fields ...string) {
|
||||
if u.Object == nil {
|
||||
u.Object = make(map[string]interface{})
|
||||
u.Object = make(map[string]any)
|
||||
}
|
||||
unstructured.RemoveNestedField(u.Object, fields...)
|
||||
}
|
||||
|
||||
func (u *Unstructured) SetNestedField(value interface{}, fields ...string) {
|
||||
func (u *Unstructured) SetNestedField(value any, fields ...string) {
|
||||
if u.Object == nil {
|
||||
u.Object = make(map[string]interface{})
|
||||
u.Object = make(map[string]any)
|
||||
}
|
||||
_ = unstructured.SetNestedField(u.Object, value, fields...)
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ import (
|
||||
|
||||
func TestDeepCopyJSON(t *testing.T) {
|
||||
obj := &Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
Object: map[string]any{
|
||||
"int": int(2),
|
||||
"int16": int16(2),
|
||||
"int32": int32(2),
|
||||
"uint64": uint64(2),
|
||||
"ref": &ObjectReference{
|
||||
Resource: "x",
|
||||
Kind: "x",
|
||||
},
|
||||
"array": []any{
|
||||
int(1), int64(2), "hello",
|
||||
@@ -25,7 +25,7 @@ func TestDeepCopyJSON(t *testing.T) {
|
||||
"bool": true,
|
||||
"map": map[string]any{
|
||||
"x": &ObjectReference{
|
||||
Resource: "x",
|
||||
Kind: "x",
|
||||
},
|
||||
},
|
||||
"object": &v1.APIGroup{
|
||||
|
||||
@@ -83,24 +83,6 @@ func schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref common.Referen
|
||||
Description: "Similar to https://dev-k8sref-io.web.app/docs/common-definitions/objectreference-/ ObjectReference contains enough information to let you inspect or modify the referred object.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"resource": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"namespace": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"apiGroup": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "APIGroup is the name of the API group that contains the referred object. The empty string represents the core API group.",
|
||||
@@ -115,6 +97,41 @@ func schema_apimachinery_apis_common_v0alpha1_ObjectReference(ref common.Referen
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"kind": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"namespace": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Tenant isolation",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"name": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Explicit resource identifier",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"fieldPath": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "May contain a valid JSON/Go field access statement",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"uid": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Sepcific deployment of an object",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"mime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BlobInfo struct {
|
||||
UID string `json:"uid"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
MimeType string `json:"mime,omitempty"`
|
||||
Charset string `json:"charset,omitempty"` // content type = mime+charset
|
||||
}
|
||||
|
||||
// Content type is mime + charset
|
||||
func (b *BlobInfo) SetContentType(v string) {
|
||||
var params map[string]string
|
||||
var err error
|
||||
|
||||
b.Charset = ""
|
||||
b.MimeType, params, err = mime.ParseMediaType(v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
b.Charset = params["charset"]
|
||||
}
|
||||
|
||||
// Content type is mime + charset
|
||||
func (b *BlobInfo) ContentType() string {
|
||||
sb := bytes.NewBufferString(b.MimeType)
|
||||
if b.Charset != "" {
|
||||
sb.WriteString("; charset=")
|
||||
sb.WriteString(b.Charset)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (b *BlobInfo) String() string {
|
||||
sb := bytes.NewBufferString(b.UID)
|
||||
if b.Size > 0 {
|
||||
fmt.Fprintf(sb, "; size=%d", b.Size)
|
||||
}
|
||||
if b.Hash != "" {
|
||||
sb.WriteString("; hash=")
|
||||
sb.WriteString(b.Hash)
|
||||
}
|
||||
if b.MimeType != "" {
|
||||
sb.WriteString("; mime=")
|
||||
sb.WriteString(b.MimeType)
|
||||
}
|
||||
if b.Charset != "" {
|
||||
sb.WriteString("; charset=")
|
||||
sb.WriteString(b.Charset)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func ParseBlobInfo(v string) *BlobInfo {
|
||||
if v == "" {
|
||||
return nil
|
||||
}
|
||||
info := &BlobInfo{}
|
||||
for i, part := range strings.Split(v, ";") {
|
||||
if i == 0 {
|
||||
info.UID = part
|
||||
continue
|
||||
}
|
||||
kv := strings.Split(strings.TrimSpace(part), "=")
|
||||
if len(kv) == 2 {
|
||||
val := kv[1]
|
||||
switch kv[0] {
|
||||
case "size":
|
||||
info.Size, _ = strconv.ParseInt(val, 10, 64)
|
||||
case "hash":
|
||||
info.Hash = val
|
||||
case "mime":
|
||||
info.MimeType = val
|
||||
case "charset":
|
||||
info.Charset = val
|
||||
}
|
||||
}
|
||||
}
|
||||
return info
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"mime"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
@@ -824,82 +821,3 @@ func (m *grafanaMetaAccessor) SetSourceProperties(v SourceProperties) {
|
||||
|
||||
m.obj.SetAnnotations(annot)
|
||||
}
|
||||
|
||||
type BlobInfo struct {
|
||||
UID string `json:"uid"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Hash string `json:"hash,omitempty"`
|
||||
MimeType string `json:"mime,omitempty"`
|
||||
Charset string `json:"charset,omitempty"` // content type = mime+charset
|
||||
}
|
||||
|
||||
// Content type is mime + charset
|
||||
func (b *BlobInfo) SetContentType(v string) {
|
||||
var params map[string]string
|
||||
var err error
|
||||
|
||||
b.Charset = ""
|
||||
b.MimeType, params, err = mime.ParseMediaType(v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
b.Charset = params["charset"]
|
||||
}
|
||||
|
||||
// Content type is mime + charset
|
||||
func (b *BlobInfo) ContentType() string {
|
||||
sb := bytes.NewBufferString(b.MimeType)
|
||||
if b.Charset != "" {
|
||||
sb.WriteString("; charset=")
|
||||
sb.WriteString(b.Charset)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (b *BlobInfo) String() string {
|
||||
sb := bytes.NewBufferString(b.UID)
|
||||
if b.Size > 0 {
|
||||
fmt.Fprintf(sb, "; size=%d", b.Size)
|
||||
}
|
||||
if b.Hash != "" {
|
||||
sb.WriteString("; hash=")
|
||||
sb.WriteString(b.Hash)
|
||||
}
|
||||
if b.MimeType != "" {
|
||||
sb.WriteString("; mime=")
|
||||
sb.WriteString(b.MimeType)
|
||||
}
|
||||
if b.Charset != "" {
|
||||
sb.WriteString("; charset=")
|
||||
sb.WriteString(b.Charset)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func ParseBlobInfo(v string) *BlobInfo {
|
||||
if v == "" {
|
||||
return nil
|
||||
}
|
||||
info := &BlobInfo{}
|
||||
for i, part := range strings.Split(v, ";") {
|
||||
if i == 0 {
|
||||
info.UID = part
|
||||
continue
|
||||
}
|
||||
kv := strings.Split(strings.TrimSpace(part), "=")
|
||||
if len(kv) == 2 {
|
||||
val := kv[1]
|
||||
switch kv[0] {
|
||||
case "size":
|
||||
info.Size, _ = strconv.ParseInt(val, 10, 64)
|
||||
case "hash":
|
||||
info.Hash = val
|
||||
case "mime":
|
||||
info.MimeType = val
|
||||
case "charset":
|
||||
info.Charset = val
|
||||
}
|
||||
}
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
@@ -22070,7 +22070,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Object": {
|
||||
"description": "Object is a JSON compatible map with string, float, int, bool, []interface{},\nor map[string]interface{} children.",
|
||||
"description": "Object is a JSON compatible map with string, float, int, bool, []any,\nor map[string]any children.",
|
||||
"type": "object",
|
||||
"additionalProperties": {}
|
||||
}
|
||||
|
||||
@@ -12117,7 +12117,7 @@
|
||||
"properties": {
|
||||
"Object": {
|
||||
"additionalProperties": {},
|
||||
"description": "Object is a JSON compatible map with string, float, int, bool, []interface{},\nor map[string]interface{} children.",
|
||||
"description": "Object is a JSON compatible map with string, float, int, bool, []any,\nor map[string]any children.",
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user