Skip to content

Commit 533e455

Browse files
committed
Introduce structured keys in pkg/cache
1 parent a259d60 commit 533e455

File tree

1 file changed

+58
-23
lines changed

1 file changed

+58
-23
lines changed

pkg/cache/keyfunc.go

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,33 @@ import (
2626
"k8s.io/client-go/tools/cache"
2727
)
2828

29+
// Key identifies an object of some implict kind.
30+
// Put another way, Key identifies an instance of some implicit resource.
31+
// Put another way, Key is what SplitMetaClusterNamespaceKey wants to return.
32+
type Key struct {
33+
Cluster logicalcluster.Name
34+
Namespace string
35+
Name string
36+
}
37+
38+
// String returns the standard string representation of the given Key
39+
func (key Key) String() string {
40+
var ans string
41+
if key.Cluster != "" {
42+
ans += key.Cluster.String() + "|"
43+
}
44+
if key.Namespace != "" {
45+
ans += key.Namespace + "/"
46+
}
47+
ans += key.Name
48+
return ans
49+
50+
}
51+
52+
func (key Key) Parts() (cluster logicalcluster.Name, namespace, name string) {
53+
return key.Cluster, key.Namespace, key.Name
54+
}
55+
2956
// DeletionHandlingMetaClusterNamespaceKeyFunc checks for
3057
// DeletedFinalStateUnknown objects before calling
3158
// MetaClusterNamespaceKeyFunc.
@@ -36,38 +63,38 @@ func DeletionHandlingMetaClusterNamespaceKeyFunc(obj interface{}) (string, error
3663
return MetaClusterNamespaceKeyFunc(obj)
3764
}
3865

66+
// ObjMetaClusterNamespaceKey is a convenient default KeyFunc which knows how to make
67+
// structured keys for API objects which implement meta.Interface.
68+
// This is the structured alternative to MetaClusterNamespaceKeyFunc;
69+
// putting such an object reference in a queue means that no parsing errors are possible downstream.
70+
func ObjMetaClusterNamespaceKey(obj interface{}) (Key, error) {
71+
if key, ok := obj.(cache.ExplicitKey); ok {
72+
return ParseKey(string(key))
73+
}
74+
meta, err := meta.Accessor(obj)
75+
if err != nil {
76+
return Key{}, fmt.Errorf("object has no meta: %v", err)
77+
}
78+
return Key{Cluster: logicalcluster.From(meta), Namespace: meta.GetNamespace(), Name: meta.GetName()}, nil
79+
}
80+
3981
// MetaClusterNamespaceKeyFunc is a convenient default KeyFunc which knows how to make
4082
// keys for API objects which implement meta.Interface.
4183
// The key uses the format <clusterName>|<namespace>/<name> unless <namespace> is empty, then
4284
// it's just <clusterName>|<name>, and if running in a single-cluster context where no explicit
4385
// cluster name is given, it's just <name>.
4486
func MetaClusterNamespaceKeyFunc(obj interface{}) (string, error) {
45-
if key, ok := obj.(cache.ExplicitKey); ok {
46-
return string(key), nil
47-
}
48-
meta, err := meta.Accessor(obj)
49-
if err != nil {
50-
return "", fmt.Errorf("object has no meta: %v", err)
51-
}
52-
return ToClusterAwareKey(logicalcluster.From(meta).String(), meta.GetNamespace(), meta.GetName()), nil
87+
key, err := ObjMetaClusterNamespaceKey(obj)
88+
return key.String(), err
5389
}
5490

5591
// ToClusterAwareKey formats a cluster, namespace, and name as a key.
5692
func ToClusterAwareKey(cluster, namespace, name string) string {
57-
var key string
58-
if cluster != "" {
59-
key += cluster + "|"
60-
}
61-
if namespace != "" {
62-
key += namespace + "/"
63-
}
64-
key += name
65-
return key
93+
return Key{Cluster: logicalcluster.Name(cluster), Namespace: namespace, Name: name}.String()
6694
}
6795

68-
// SplitMetaClusterNamespaceKey returns the namespace and name that
69-
// MetaClusterNamespaceKeyFunc encoded into key.
70-
func SplitMetaClusterNamespaceKey(key string) (clusterName logicalcluster.Name, namespace, name string, err error) {
96+
// ParseKey is the structured form of SplitMetaClusterNamespaceKey
97+
func ParseKey(key string) (Key, error) {
7198
invalidKey := fmt.Errorf("unexpected key format: %q", key)
7299
outerParts := strings.Split(key, "|")
73100
switch len(outerParts) {
@@ -76,14 +103,22 @@ func SplitMetaClusterNamespaceKey(key string) (clusterName logicalcluster.Name,
76103
if err != nil {
77104
err = invalidKey
78105
}
79-
return "", namespace, name, err
106+
return Key{Cluster: "", Namespace: namespace, Name: name}, err
80107
case 2:
81108
namespace, name, err := cache.SplitMetaNamespaceKey(outerParts[1])
82109
if err != nil {
83110
err = invalidKey
84111
}
85-
return logicalcluster.Name(outerParts[0]), namespace, name, err
112+
return Key{Cluster: logicalcluster.Name(outerParts[0]), Namespace: namespace, Name: name}, err
86113
default:
87-
return "", "", "", invalidKey
114+
return Key{Cluster: "", Namespace: "", Name: ""}, invalidKey
88115
}
89116
}
117+
118+
// SplitMetaClusterNamespaceKey returns the cluster, namespace, and name that
119+
// MetaClusterNamespaceKeyFunc encoded into key.
120+
func SplitMetaClusterNamespaceKey(key string) (clusterName logicalcluster.Name, namespace, name string, err error) {
121+
parsed, err := ParseKey(key)
122+
clusterName, namespace, name = parsed.Parts()
123+
return
124+
}

0 commit comments

Comments
 (0)