mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
Manually set GVK in extract, add commentary to extractor
This commit is contained in:
parent
9f4a4d812d
commit
dda31bbf2e
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
@ -23,12 +24,17 @@ import (
|
|||||||
"sigs.k8s.io/structured-merge-diff/v4/typed"
|
"sigs.k8s.io/structured-merge-diff/v4/typed"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// This is a small hacky script that tests the extract config against a real cluster
|
||||||
|
// to demonstrate a bug I'm seeing with the GVKParser where it claims there
|
||||||
|
// are duplicate GVK entries
|
||||||
|
// TODO: don't commit this, delete it before merging.
|
||||||
|
// Any and all functionality from this script should be captured in the appropriate integration test.
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("vim-go")
|
|
||||||
defaultNS := "default"
|
defaultNS := "default"
|
||||||
mydep := "mydep"
|
mydep := "mydep"
|
||||||
mgr := "mymanager"
|
mgr := "mymanager"
|
||||||
kubeconfig := "/usr/local/google/home/kevindelgado/.kube/config"
|
// TODO: make this an arg
|
||||||
|
kubeconfig := os.Getenv("KUBECONFIG")
|
||||||
|
|
||||||
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
@ -337,12 +337,8 @@ func (s unstructuredJSONScheme) Decode(data []byte, _ *schema.GroupVersionKind,
|
|||||||
}
|
}
|
||||||
|
|
||||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||||
//goruntime.Breakpoint()
|
|
||||||
if len(gvk.Kind) == 0 {
|
if len(gvk.Kind) == 0 {
|
||||||
//goruntime.Breakpoint()
|
return nil, &gvk, runtime.NewMissingKindErr(string(data))
|
||||||
//return nil, &gvk, runtime.NewMissingKindErr(string(data))
|
|
||||||
fmt.Println("MISSING KIND, ignoring err")
|
|
||||||
fmt.Printf("string(data) = %+v\n", string(data))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj, &gvk, nil
|
return obj, &gvk, nil
|
||||||
|
@ -75,16 +75,13 @@ func ExtractInto(object runtime.Object, objectType typed.ParseableType, fieldMan
|
|||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unable to convert managed fields for %s to unstructured, expected map, got %T", fieldManager, u)
|
return fmt.Errorf("unable to convert managed fields for %s to unstructured, expected map, got %T", fieldManager, u)
|
||||||
}
|
}
|
||||||
fmt.Printf("u = %+v\n", u)
|
|
||||||
fmt.Println("---")
|
// set the type meta manually if it doesn't exist to avoid missing kind errors
|
||||||
fmt.Printf("typedObj = %+v\n", typedObj)
|
// when decoding from unstructured JSON
|
||||||
fmt.Println("---")
|
if _, ok := m["kind"]; !ok {
|
||||||
fmt.Printf("object = %+v\n", object)
|
m["kind"] = object.GetObjectKind().GroupVersionKind().Kind
|
||||||
fmt.Println("---")
|
m["apiVersion"] = object.GetObjectKind().GroupVersionKind().GroupVersion().String()
|
||||||
fmt.Printf("m = %+v\n", m)
|
}
|
||||||
fmt.Println("---")
|
|
||||||
fmt.Printf("applyConfiguration = %+v\n", applyConfiguration)
|
|
||||||
fmt.Println("---")
|
|
||||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(m, applyConfiguration); err != nil {
|
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(m, applyConfiguration); err != nil {
|
||||||
return fmt.Errorf("error extracting into obj from unstructured: %w", err)
|
return fmt.Errorf("error extracting into obj from unstructured: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -65,15 +65,12 @@ func NewGVKParser(models proto.Models, preserveUnknownFields bool) (*GvkParser,
|
|||||||
panic(fmt.Sprintf("ListModels returns a model that can't be looked-up for: %v", modelName))
|
panic(fmt.Sprintf("ListModels returns a model that can't be looked-up for: %v", modelName))
|
||||||
}
|
}
|
||||||
gvkList := parseGroupVersionKind(model)
|
gvkList := parseGroupVersionKind(model)
|
||||||
//fmt.Println("+++")
|
|
||||||
//fmt.Printf("gvkList = %+v\n", gvkList)
|
|
||||||
//fmt.Println("+++")
|
|
||||||
for _, gvk := range gvkList {
|
for _, gvk := range gvkList {
|
||||||
if len(gvk.Kind) > 0 {
|
if len(gvk.Kind) > 0 {
|
||||||
_, ok := parser.gvks[gvk]
|
_, ok := parser.gvks[gvk]
|
||||||
if ok {
|
if ok {
|
||||||
//return nil, fmt.Errorf("duplicate entry for %v", gvk)
|
// TODO: double check why this is failing in real_cluster_script.go
|
||||||
fmt.Printf("duplicate entry for %v\n", gvk)
|
return nil, fmt.Errorf("duplicate entry for %v", gvk)
|
||||||
}
|
}
|
||||||
parser.gvks[gvk] = modelName
|
parser.gvks[gvk] = modelName
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,27 @@ import (
|
|||||||
"sigs.k8s.io/structured-merge-diff/v4/typed"
|
"sigs.k8s.io/structured-merge-diff/v4/typed"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UnstructuredExtractor enables extracting the applied configuration state from object for fieldManager into an
|
||||||
|
// unstructured object type.
|
||||||
type UnstructuredExtractor interface {
|
type UnstructuredExtractor interface {
|
||||||
ExtractUnstructured(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error)
|
ExtractUnstructured(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error)
|
||||||
ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error)
|
ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type parserCache interface {
|
// objectTypeCache is a cache of typed.ParseableTypes
|
||||||
parserForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error)
|
type objectTypeCache interface {
|
||||||
|
objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type nonCachingParserCache struct {
|
// nonCachingObjectTypeCache is a objectTypeCache that does no caching
|
||||||
|
// (i.e. it downloads the OpenAPISchema every time)
|
||||||
|
// Useful during the proof-of-concept stage until we agree on a caching solution.
|
||||||
|
type nonCachingObjectTypeCache struct {
|
||||||
discoveryClient *discovery.DiscoveryClient
|
discoveryClient *discovery.DiscoveryClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *nonCachingParserCache) parserForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) {
|
// objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache
|
||||||
|
func (c *nonCachingObjectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind) (*typed.ParseableType, error) {
|
||||||
doc, err := c.discoveryClient.OpenAPISchema()
|
doc, err := c.discoveryClient.OpenAPISchema()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -43,31 +50,38 @@ func (c *nonCachingParserCache) parserForGVK(gvk schema.GroupVersionKind) (*type
|
|||||||
}
|
}
|
||||||
|
|
||||||
type extractor struct {
|
type extractor struct {
|
||||||
cache parserCache
|
cache objectTypeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewUnstructuredExtractor creates the extractor with which you can extract the applied configuration
|
||||||
|
// for a given manager from an unstructured object.
|
||||||
func NewUnstructuredExtractor(dc *discovery.DiscoveryClient) UnstructuredExtractor {
|
func NewUnstructuredExtractor(dc *discovery.DiscoveryClient) UnstructuredExtractor {
|
||||||
return &extractor{
|
return &extractor{
|
||||||
cache: &nonCachingParserCache{dc},
|
cache: &nonCachingObjectTypeCache{dc},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtractUnstructured extracts the applied configuration owned by fiieldManager from an unstructured object.
|
||||||
|
// Note that the apply configuration itself is also an unstructured object.
|
||||||
func (e *extractor) ExtractUnstructured(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error) {
|
func (e *extractor) ExtractUnstructured(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error) {
|
||||||
return e.extractUnstructured(object, fieldManager, "")
|
return e.extractUnstructured(object, fieldManager, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtractUnstructuredStatus is the same as ExtractUnstructured except
|
||||||
|
// that it extracts the status subresource applied configuration.
|
||||||
|
// Experimental!
|
||||||
func (e *extractor) ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error) {
|
func (e *extractor) ExtractUnstructuredStatus(object *unstructured.Unstructured, fieldManager string) (*unstructured.Unstructured, error) {
|
||||||
return e.extractUnstructured(object, fieldManager, "status")
|
return e.extractUnstructured(object, fieldManager, "status")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *extractor) extractUnstructured(object *unstructured.Unstructured, fieldManager string, subresource string) (*unstructured.Unstructured, error) {
|
func (e *extractor) extractUnstructured(object *unstructured.Unstructured, fieldManager string, subresource string) (*unstructured.Unstructured, error) {
|
||||||
gvk := object.GetObjectKind().GroupVersionKind()
|
gvk := object.GetObjectKind().GroupVersionKind()
|
||||||
parser, err := e.cache.parserForGVK(gvk)
|
objectType, err := e.cache.objectTypeForGVK(gvk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &unstructured.Unstructured{}
|
result := &unstructured.Unstructured{}
|
||||||
err = managedfields.ExtractInto(object, *parser, fieldManager, result, subresource)
|
err = managedfields.ExtractInto(object, *objectType, fieldManager, result, subresource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
1
vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go
generated
vendored
1
vendor/sigs.k8s.io/structured-merge-diff/v4/value/reflectcache.go
generated
vendored
@ -269,7 +269,6 @@ func (e TypeReflectCacheEntry) FromUnstructured(sv, dv reflect.Value) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error encoding %s to json: %v", st.String(), err)
|
return fmt.Errorf("error encoding %s to json: %v", st.String(), err)
|
||||||
}
|
}
|
||||||
// TODO: this is where we're failing
|
|
||||||
if unmarshaler, ok := e.getJsonUnmarshaler(dv); ok {
|
if unmarshaler, ok := e.getJsonUnmarshaler(dv); ok {
|
||||||
return unmarshaler.UnmarshalJSON(data)
|
return unmarshaler.UnmarshalJSON(data)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user