K8s `unstructured` helper?
s3rj1k opened this issue · 6 comments
I am curious would it be possible to add some simple wrapper support for K8s unstructured
, as it would be really great to use gabs with that object natively.
Hey @s3rj1k, I'd need some more details about that, but, skimming through this article, it sounds like you want to create a gabs container from a weakly-decoded JSON. Is that correct? If yes, try this:
package main
import (
"fmt"
"github.com/Jeffail/gabs/v2"
)
func main() {
newEnvs := []interface{}{
map[string]interface{}{
"name": "NAMESPACE",
"valueFrom": map[string]interface{}{
"fieldRef": map[string]interface{}{
"fieldPath": "metadata.namespace",
},
},
},
map[string]interface{}{
"name": "POD_UID",
"valueFrom": map[string]interface{}{
"fieldRef": map[string]interface{}{
"fieldPath": "metadata.uid",
},
},
},
}
obj := gabs.Wrap(newEnvs)
fmt.Println(obj.Path("*.valueFrom.fieldRef.fieldPath").String())
}
@mihaitodor hey, thanks for quick response, I just want a helper to convert gabs <-> unstructured
Basically unstructured has embedded Object map[string]interface{}
where gabs container has interface{}
.
The flow would be something like this:
- unstructured -> gabs.container
- some gabs magic manipulating data
- gabs.container -> unstructured
(hopefully with minimal memory allocation)
@s3rj1k Sure, have you tried the .Data()
method?
package main
import (
"fmt"
"github.com/Jeffail/gabs/v2"
"github.com/davecgh/go-spew/spew"
)
func main() {
newEnvs := []interface{}{
map[string]interface{}{
"name": "NAMESPACE",
"valueFrom": map[string]interface{}{
"fieldRef": map[string]interface{}{
"fieldPath": "metadata.namespace",
},
},
},
map[string]interface{}{
"name": "POD_UID",
"valueFrom": map[string]interface{}{
"fieldRef": map[string]interface{}{
"fieldPath": "metadata.uid",
},
},
},
}
obj := gabs.Wrap(newEnvs)
fmt.Println(obj.Path("*.valueFrom.fieldRef.fieldPath").String())
spew.Dump(obj.Data())
obj.SetP(666, "0.valueFrom.fieldRef.fieldPath")
spew.Dump(obj.Data())
}
PS: You should be able to use type assertions to get the actual type from the interface{}
returned by Data()
(in the example above, that would be obj.Data().([]interface{})
).
Flow is a bit different, reversed
package main
import (
"log"
"github.com/Jeffail/gabs/v2"
"github.com/davecgh/go-spew/spew"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/yaml"
)
func main() {
b := []byte(`
apiVersion: v1
kind: Pod
metadata:
name: my-pod
namespace: default
spec:
containers:
- name: nginx
image: nginx:latest
`)
obj := new(unstructured.Unstructured)
err := yaml.Unmarshal(b, obj)
if err != nil {
log.Fatalf("Failed to unmarshal YAML: %v", err)
}
container := gabs.Wrap(obj.Object)
objNew := new(unstructured.Unstructured)
objNew.SetUnstructuredContent(container.Data().(map[string]interface{}))
spew.Dump(obj.Object)
spew.Dump(objNew.Object)
}
so what I am after here is basically
container.Data().(map[string]interface{})
a more streamlined version of this ^^^
Sure, but that's specific to your use case. Nothing wrong with publishing your own gabs wrapper which exposes a method that returns container.Data().(map[string]interface{})
, even if it's just some boilerplate.
Sure, but that's specific to your use case. Nothing wrong with publishing your own gabs wrapper which exposes a method that returns
container.Data().(map[string]interface{})
, even if it's just some boilerplate.
Yea, I was hoping for method similar to Data
but that will return map[string]interface{}
by type casting it internally and panic when error occurs.