mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
128 lines
3.2 KiB
Go
128 lines
3.2 KiB
Go
|
/*
|
||
|
Copyright 2017 The Kubernetes Authors.
|
||
|
|
||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
you may not use this file except in compliance with the License.
|
||
|
You may obtain a copy of the License at
|
||
|
|
||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
||
|
Unless required by applicable law or agreed to in writing, software
|
||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
See the License for the specific language governing permissions and
|
||
|
limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package apiserver
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
"sync"
|
||
|
|
||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||
|
"k8s.io/apiserver/pkg/endpoints/discovery"
|
||
|
)
|
||
|
|
||
|
type versionDiscoveryHandler struct {
|
||
|
// TODO, writing is infrequent, optimize this
|
||
|
discoveryLock sync.RWMutex
|
||
|
discovery map[schema.GroupVersion]*discovery.APIVersionHandler
|
||
|
|
||
|
delegate http.Handler
|
||
|
}
|
||
|
|
||
|
func (r *versionDiscoveryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||
|
pathParts := splitPath(req.URL.Path)
|
||
|
// only match /apis/<group>/<version>
|
||
|
if len(pathParts) != 3 || pathParts[0] != "apis" {
|
||
|
r.delegate.ServeHTTP(w, req)
|
||
|
return
|
||
|
}
|
||
|
discovery, ok := r.getDiscovery(schema.GroupVersion{Group: pathParts[1], Version: pathParts[2]})
|
||
|
if !ok {
|
||
|
r.delegate.ServeHTTP(w, req)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
discovery.ServeHTTP(w, req)
|
||
|
}
|
||
|
|
||
|
func (r *versionDiscoveryHandler) getDiscovery(gv schema.GroupVersion) (*discovery.APIVersionHandler, bool) {
|
||
|
r.discoveryLock.RLock()
|
||
|
defer r.discoveryLock.RUnlock()
|
||
|
|
||
|
ret, ok := r.discovery[gv]
|
||
|
return ret, ok
|
||
|
}
|
||
|
|
||
|
func (r *versionDiscoveryHandler) setDiscovery(gv schema.GroupVersion, discovery *discovery.APIVersionHandler) {
|
||
|
r.discoveryLock.Lock()
|
||
|
defer r.discoveryLock.Unlock()
|
||
|
|
||
|
r.discovery[gv] = discovery
|
||
|
}
|
||
|
|
||
|
func (r *versionDiscoveryHandler) unsetDiscovery(gv schema.GroupVersion) {
|
||
|
r.discoveryLock.Lock()
|
||
|
defer r.discoveryLock.Unlock()
|
||
|
|
||
|
delete(r.discovery, gv)
|
||
|
}
|
||
|
|
||
|
type groupDiscoveryHandler struct {
|
||
|
// TODO, writing is infrequent, optimize this
|
||
|
discoveryLock sync.RWMutex
|
||
|
discovery map[string]*discovery.APIGroupHandler
|
||
|
|
||
|
delegate http.Handler
|
||
|
}
|
||
|
|
||
|
func (r *groupDiscoveryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||
|
pathParts := splitPath(req.URL.Path)
|
||
|
// only match /apis/<group>
|
||
|
if len(pathParts) != 2 || pathParts[0] != "apis" {
|
||
|
r.delegate.ServeHTTP(w, req)
|
||
|
return
|
||
|
}
|
||
|
discovery, ok := r.getDiscovery(pathParts[1])
|
||
|
if !ok {
|
||
|
r.delegate.ServeHTTP(w, req)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
discovery.ServeHTTP(w, req)
|
||
|
}
|
||
|
|
||
|
func (r *groupDiscoveryHandler) getDiscovery(group string) (*discovery.APIGroupHandler, bool) {
|
||
|
r.discoveryLock.RLock()
|
||
|
defer r.discoveryLock.RUnlock()
|
||
|
|
||
|
ret, ok := r.discovery[group]
|
||
|
return ret, ok
|
||
|
}
|
||
|
|
||
|
func (r *groupDiscoveryHandler) setDiscovery(group string, discovery *discovery.APIGroupHandler) {
|
||
|
r.discoveryLock.Lock()
|
||
|
defer r.discoveryLock.Unlock()
|
||
|
|
||
|
r.discovery[group] = discovery
|
||
|
}
|
||
|
|
||
|
func (r *groupDiscoveryHandler) unsetDiscovery(group string) {
|
||
|
r.discoveryLock.Lock()
|
||
|
defer r.discoveryLock.Unlock()
|
||
|
|
||
|
delete(r.discovery, group)
|
||
|
}
|
||
|
|
||
|
// splitPath returns the segments for a URL path.
|
||
|
func splitPath(path string) []string {
|
||
|
path = strings.Trim(path, "/")
|
||
|
if path == "" {
|
||
|
return []string{}
|
||
|
}
|
||
|
return strings.Split(path, "/")
|
||
|
}
|