diff --git a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_patch.go b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_patch.go index fa75300549f40..64a7502ec9451 100644 --- a/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_patch.go +++ b/staging/src/k8s.io/apiserver/pkg/storage/etcd3/store_patch.go @@ -17,66 +17,49 @@ limitations under the License. package etcd3 import ( - "regexp" "strings" "github.com/kcp-dev/logicalcluster/v2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/klog/v2" -) -var ( - // matches cluster/remainder, capturing cluster. - // - // Example: root:org:ws/some-namespace/some-name - // Example: root:org:ws/some-name - wildcardClusterNameRegex = regexp.MustCompile(`^([^/]+)\/.+`) - - // matches shard/cluster/remainder, capturing shard and cluster. - // - // Example: amber/root:org:ws/some-namespace/some-name - // Example: amber/root:org:ws/some-name - wildcardShardClusterNameRegex = regexp.MustCompile(`^([^\/]+)\/([^\/]+)\/.+`) - - // matches identity-or-customresources/cluster/remainder, capturing cluster - // - // Example: customresources/root:org:ws/some-namespace/some-name - // Example: customresources/root:org:ws/some-name - // Example: 2699f4d273d342adccdc8a32663408226ecf66de7d191113ed3d4dc9bccec2f2/root:org:ws/some-namespace/some-name - // Example: 2699f4d273d342adccdc8a32663408226ecf66de7d191113ed3d4dc9bccec2f2/root:org:ws/some-name - crdWildcardPartialMetadataClusterNameRegex = regexp.MustCompile(`^[^/]+\/([^/]+)\/.+`) + genericapirequest "k8s.io/apiserver/pkg/endpoints/request" ) -// adjustClusterNameIfWildcard determines the logical cluster name. If this is not a wildcard list/watch request, -// the cluster name is returned unmodified. Otherwise, the cluster name is extracted from the key based on whether -// it is a CR partial metadata request (prefix/identity/clusterName/remainder) or not (prefix/clusterName/remainder). +// adjustClusterNameIfWildcard determines the logical cluster name. If this is not a cluster-wildcard list/watch request, +// the cluster name is returned unmodified. Otherwise, the cluster name is extracted from the key based on whether it is +// - a shard-wildcard request: /shardName/clusterName/ +// - CR partial metadata request: /identity/clusterName/ +// - any other request: /clusterName/. func adjustClusterNameIfWildcard(shard genericapirequest.Shard, cluster *genericapirequest.Cluster, crdRequest bool, keyPrefix, key string) logicalcluster.Name { - if cluster.Name != logicalcluster.Wildcard { + if cluster.Name != logicalcluster.Wildcard && !cluster.Wildcard { // TODO: fix this duplicity, as well return cluster.Name } keyWithoutPrefix := strings.TrimPrefix(key, keyPrefix) + parts := strings.SplitN(keyWithoutPrefix, "/", 3) - if !shard.Wildcard() { - var regex *regexp.Regexp - if cluster.PartialMetadataRequest && crdRequest { - regex = crdWildcardPartialMetadataClusterNameRegex - } else { - regex = wildcardClusterNameRegex - } - matches := regex.FindStringSubmatch(keyWithoutPrefix) - if len(matches) >= 2 { - return logicalcluster.New(matches[1]) + extract := func(minLen, i int) logicalcluster.Name { + if len(parts) < minLen { + klog.Warningf("shard=%s cluster=%s invalid key=%s had %d parts, not %d", shard, cluster, keyWithoutPrefix, len(parts), minLen) + return logicalcluster.Name{} } - return logicalcluster.Name{} + return logicalcluster.New(parts[i]) } - matches := wildcardShardClusterNameRegex.FindStringSubmatch(keyWithoutPrefix) - if len(matches) >= 3 { - return logicalcluster.New(matches[2]) + switch { + case shard.Wildcard(): + // expecting shardName/clusterName/ + return extract(3, 1) + case cluster.PartialMetadataRequest && crdRequest: + // expecting 2699f4d273d342adccdc8a32663408226ecf66de7d191113ed3d4dc9bccec2f2/root:org:ws/ + // OR customresources/root:org:ws/ + return extract(3, 1) + default: + // expecting root:org:ws/ + return extract(2, 0) } - return logicalcluster.Name{} } // setClusterNameOnDecodedObject applies clusterName to obj. This is necessary because we don't store the cluster