mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
basic caching working
This commit is contained in:
parent
dda31bbf2e
commit
7b9757faa4
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"time"
|
||||||
|
|
||||||
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"
|
||||||
@ -16,6 +16,7 @@ import (
|
|||||||
corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
|
corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
|
||||||
metav1ac "k8s.io/client-go/applyconfigurations/meta/v1"
|
metav1ac "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
"k8s.io/client-go/discovery"
|
"k8s.io/client-go/discovery"
|
||||||
|
"k8s.io/client-go/discovery/cached/disk"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||||
@ -24,17 +25,12 @@ 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"
|
||||||
// TODO: make this an arg
|
kubeconfig := "/usr/local/google/home/kevindelgado/.kube/config"
|
||||||
kubeconfig := os.Getenv("KUBECONFIG")
|
|
||||||
|
|
||||||
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -173,7 +169,10 @@ func main() {
|
|||||||
fmt.Printf("appliedGuestbook = %+v\n", appliedGuestbook)
|
fmt.Printf("appliedGuestbook = %+v\n", appliedGuestbook)
|
||||||
fmt.Println("---")
|
fmt.Println("---")
|
||||||
|
|
||||||
discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(config)
|
discoveryClient, err := disk.NewCachedDiscoveryClientForConfig(config, ".", ".", time.Hour)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
//// OLD WAY
|
//// OLD WAY
|
||||||
//extractedGuestbook, err := extractUnstructured(appliedGuestbook, guestbookGVR, discoveryClient, mgr)
|
//extractedGuestbook, err := extractUnstructured(appliedGuestbook, guestbookGVR, discoveryClient, mgr)
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
@ -187,6 +186,8 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
// do it again see if we get a 304
|
||||||
|
extractedGuestbook, err = extractor.ExtractUnstructured(appliedGuestbook, mgr)
|
||||||
fmt.Println("---")
|
fmt.Println("---")
|
||||||
fmt.Printf("extractedGuestbook = %+v\n", extractedGuestbook)
|
fmt.Printf("extractedGuestbook = %+v\n", extractedGuestbook)
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha512"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/managedfields"
|
"k8s.io/apimachinery/pkg/util/managedfields"
|
||||||
@ -26,7 +30,11 @@ type objectTypeCache interface {
|
|||||||
// (i.e. it downloads the OpenAPISchema every time)
|
// (i.e. it downloads the OpenAPISchema every time)
|
||||||
// Useful during the proof-of-concept stage until we agree on a caching solution.
|
// Useful during the proof-of-concept stage until we agree on a caching solution.
|
||||||
type nonCachingObjectTypeCache struct {
|
type nonCachingObjectTypeCache struct {
|
||||||
discoveryClient *discovery.DiscoveryClient
|
// TODO: lock this?
|
||||||
|
discoveryClient discovery.DiscoveryInterface
|
||||||
|
docHash [sha512.Size]uint8
|
||||||
|
gvkParser *fieldmanager.GvkParser
|
||||||
|
typeForGVK map[schema.GroupVersionKind]*typed.ParseableType
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache
|
// objectTypeForGVK retrieves the typed.ParseableType for a given gvk from the cache
|
||||||
@ -36,17 +44,47 @@ func (c *nonCachingObjectTypeCache) objectTypeForGVK(gvk schema.GroupVersionKind
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
models, err := proto.NewOpenAPIData(doc)
|
docBytes, err := json.Marshal(doc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
docHash := sha512.Sum512(docBytes)
|
||||||
|
|
||||||
gvkParser, err := fieldmanager.NewGVKParser(models, false)
|
// cache hit
|
||||||
if err != nil {
|
if c.docHash == docHash {
|
||||||
return nil, err
|
fmt.Println("cache hit")
|
||||||
|
fmt.Printf("docHash = %+v\n", docHash)
|
||||||
|
objType, ok := c.typeForGVK[gvk]
|
||||||
|
if ok {
|
||||||
|
fmt.Println("gvk recognized")
|
||||||
|
fmt.Printf("gvk = %+v\n", gvk)
|
||||||
|
return objType, nil
|
||||||
|
}
|
||||||
|
objType = c.gvkParser.Type(gvk)
|
||||||
|
c.typeForGVK[gvk] = objType
|
||||||
|
return objType, nil
|
||||||
|
} else {
|
||||||
|
fmt.Println("cache miss")
|
||||||
|
// cache miss
|
||||||
|
models, err := proto.NewOpenAPIData(doc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gvkParser, err := fieldmanager.NewGVKParser(models, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
objType := gvkParser.Type(gvk)
|
||||||
|
c.docHash = docHash
|
||||||
|
c.gvkParser = gvkParser
|
||||||
|
c.typeForGVK = map[schema.GroupVersionKind]*typed.ParseableType{
|
||||||
|
gvk: objType,
|
||||||
|
}
|
||||||
|
|
||||||
|
return objType, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return gvkParser.Type(gvk), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type extractor struct {
|
type extractor struct {
|
||||||
@ -55,9 +93,11 @@ type extractor struct {
|
|||||||
|
|
||||||
// NewUnstructuredExtractor creates the extractor with which you can extract the applied configuration
|
// NewUnstructuredExtractor creates the extractor with which you can extract the applied configuration
|
||||||
// for a given manager from an unstructured object.
|
// for a given manager from an unstructured object.
|
||||||
func NewUnstructuredExtractor(dc *discovery.DiscoveryClient) UnstructuredExtractor {
|
func NewUnstructuredExtractor(dc discovery.DiscoveryInterface) UnstructuredExtractor {
|
||||||
return &extractor{
|
return &extractor{
|
||||||
cache: &nonCachingObjectTypeCache{dc},
|
cache: &nonCachingObjectTypeCache{
|
||||||
|
discoveryClient: dc,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,6 +244,7 @@ func TestUnstructuredExtract(t *testing.T) {
|
|||||||
t.Fatalf("failed to marshal pod into bytes: %v", err)
|
t.Fatalf("failed to marshal pod into bytes: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply the unstructured object to the cluster
|
||||||
actual, err := dynamicClient.Resource(resource).Namespace("default").Patch(
|
actual, err := dynamicClient.Resource(resource).Namespace("default").Patch(
|
||||||
context.TODO(),
|
context.TODO(),
|
||||||
name,
|
name,
|
||||||
|
Loading…
Reference in New Issue
Block a user