Skip to content

Commit

Permalink
[yurthub] support cache response for partial object metadata requests…
Browse files Browse the repository at this point in the history
…, like the following request: (openyurtio#2170)

curl -H "Accept: application/json;as=PartialObjectMetadataList;g=meta.k8s.io;v=v1" "$API_SERVER/apis/apiextensions.k8s.io/v1/customresourcedefinitions"

Signed-off-by: rambohe-ch <[email protected]>
  • Loading branch information
rambohe-ch authored and zyjhtangtang committed Oct 23, 2024
1 parent aed7925 commit 85f4b21
Show file tree
Hide file tree
Showing 12 changed files with 757 additions and 626 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/hashicorp/go-version v1.6.0
github.com/jarcoal/httpmock v1.3.0
github.com/lithammer/dedent v1.1.0
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
github.com/onsi/ginkgo/v2 v2.11.0
github.com/onsi/gomega v1.27.10
github.com/opencontainers/selinux v1.11.0
Expand Down Expand Up @@ -127,7 +128,6 @@ require (
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
Expand Down
10 changes: 9 additions & 1 deletion pkg/yurthub/cachemanager/cache_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ func NewCacheAgents(informerFactory informers.SharedInformerFactory, store Stora
}

func (ca *CacheAgent) HasAny(items ...string) bool {
return ca.agents.HasAny(items...)
newAgents := make([]string, 0, len(items))
for i := range items {
if n := strings.Index(items[i], "/partialobjectmetadata"); n != -1 {
newAgents = append(newAgents, items[i][:n])
} else {
newAgents = append(newAgents, items[i])
}
}
return ca.agents.HasAny(newAgents...)
}

func (ca *CacheAgent) addConfigmap(obj interface{}) {
Expand Down
68 changes: 49 additions & 19 deletions pkg/yurthub/cachemanager/cache_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,27 @@ func (cm *cacheManager) queryListObject(req *http.Request) (runtime.Object, erro
return nil, err
}

listGvk, err := cm.prepareGvkForListObj(schema.GroupVersionResource{
Group: info.APIGroup,
Version: info.APIVersion,
Resource: info.Resource,
})
if err != nil {
klog.Errorf("could not get gvk for ListObject for req: %s, %v", util.ReqString(req), err)
// If err is hubmeta.ErrGVRNotRecognized, the reverse proxy will set the HTTP Status Code as 404.
return nil, err
var listGvk schema.GroupVersionKind
convertGVK, ok := util.ConvertGVKFrom(ctx)
if ok && convertGVK != nil {
listGvk = schema.GroupVersionKind{
Group: convertGVK.Group,
Version: convertGVK.Version,
Kind: convertGVK.Kind,
}
} else {
listGvk, err = cm.prepareGvkForListObj(schema.GroupVersionResource{
Group: info.APIGroup,
Version: info.APIVersion,
Resource: info.Resource,
})
if err != nil {
klog.Errorf("could not get gvk for ListObject for req: %s, %v", util.ReqString(req), err)
// If err is hubmeta.ErrGVRNotRecognized, the reverse proxy will set the HTTP Status Code as 404.
return nil, err
}
}

listObj, err := generateEmptyListObjOfGVK(listGvk)
if err != nil {
klog.Errorf("could not create ListObj for gvk %s for req: %s, %v", listGvk.String(), util.ReqString(req), err)
Expand Down Expand Up @@ -439,7 +450,18 @@ func (cm *cacheManager) saveWatchObject(ctx context.Context, info *apirequest.Re
func (cm *cacheManager) saveListObject(ctx context.Context, info *apirequest.RequestInfo, b []byte) error {
comp, _ := util.ClientComponentFrom(ctx)
respContentType, _ := util.RespContentTypeFrom(ctx)
s := cm.serializerManager.CreateSerializer(respContentType, info.APIGroup, info.APIVersion, info.Resource)
gvr := schema.GroupVersionResource{
Group: info.APIGroup,
Version: info.APIVersion,
Resource: info.Resource,
}

convertGVK, ok := util.ConvertGVKFrom(ctx)
if ok && convertGVK != nil {
gvr, _ = meta.UnsafeGuessKindToResource(*convertGVK)
}

s := cm.serializerManager.CreateSerializer(respContentType, gvr.Group, gvr.Version, gvr.Resource)
if s == nil {
klog.Errorf("could not create serializer in saveListObject, %s", util.ReqInfoString(info))
return fmt.Errorf("could not create serializer in saveListObject, %s", util.ReqInfoString(info))
Expand All @@ -464,22 +486,20 @@ func (cm *cacheManager) saveListObject(ctx context.Context, info *apirequest.Req
}
klog.V(5).Infof("list items for %s is: %d", util.ReqInfoString(info), len(items))

kind := strings.TrimSuffix(list.GetObjectKind().GroupVersionKind().Kind, "List")
apiVersion := schema.GroupVersion{
Group: info.APIGroup,
Version: info.APIVersion,
}.String()
gvk := list.GetObjectKind().GroupVersionKind()
kind := strings.TrimSuffix(gvk.Kind, "List")
groupVersion := gvk.GroupVersion().String()
accessor := meta.NewAccessor()

// Verify if DynamicRESTMapper(which store the CRD info) needs to be updated
if err := cm.restMapperManager.UpdateKind(schema.GroupVersionKind{Group: info.APIGroup, Version: info.APIVersion, Kind: kind}); err != nil {
if err := cm.restMapperManager.UpdateKind(schema.GroupVersionKind{Group: gvk.Group, Version: gvk.Version, Kind: kind}); err != nil {
klog.Errorf("could not update the DynamicRESTMapper %v", err)
}

if info.Name != "" && len(items) == 1 {
// list with fieldSelector=metadata.name=xxx
accessor.SetKind(items[0], kind)
accessor.SetAPIVersion(items[0], apiVersion)
accessor.SetAPIVersion(items[0], groupVersion)
name, _ := accessor.Name(items[0])
ns, _ := accessor.Namespace(items[0])
if ns == "" {
Expand All @@ -500,7 +520,7 @@ func (cm *cacheManager) saveListObject(ctx context.Context, info *apirequest.Req
comp, _ := util.ClientComponentFrom(ctx)
for i := range items {
accessor.SetKind(items[i], kind)
accessor.SetAPIVersion(items[i], apiVersion)
accessor.SetAPIVersion(items[i], groupVersion)
name, _ := accessor.Name(items[i])
ns, _ := accessor.Namespace(items[i])
if ns == "" {
Expand Down Expand Up @@ -528,8 +548,18 @@ func (cm *cacheManager) saveListObject(ctx context.Context, info *apirequest.Req
func (cm *cacheManager) saveOneObject(ctx context.Context, info *apirequest.RequestInfo, b []byte) error {
comp, _ := util.ClientComponentFrom(ctx)
respContentType, _ := util.RespContentTypeFrom(ctx)
gvr := schema.GroupVersionResource{
Group: info.APIGroup,
Version: info.APIVersion,
Resource: info.Resource,
}

s := cm.serializerManager.CreateSerializer(respContentType, info.APIGroup, info.APIVersion, info.Resource)
convertGVK, ok := util.ConvertGVKFrom(ctx)
if ok && convertGVK != nil {
gvr, _ = meta.UnsafeGuessKindToResource(*convertGVK)
}

s := cm.serializerManager.CreateSerializer(respContentType, gvr.Group, gvr.Version, gvr.Resource)
if s == nil {
klog.Errorf("could not create serializer in saveOneObject, %s", util.ReqInfoString(info))
return fmt.Errorf("could not create serializer in saveOneObject, %s", util.ReqInfoString(info))
Expand Down
Loading

0 comments on commit 85f4b21

Please sign in to comment.