@@ -32,7 +32,6 @@ import (
3232 "github.com/gorilla/mux"
3333 "github.com/gorilla/securecookie"
3434 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
35- apiextensionslisters "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
3635 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3736 "k8s.io/apimachinery/pkg/labels"
3837 "k8s.io/apimachinery/pkg/runtime"
@@ -70,9 +69,8 @@ type handler struct {
7069 cookieEncryptionKey []byte
7170 cookieSigningKey []byte
7271
73- client * http.Client
74- apiextensionsLister apiextensionslisters.CustomResourceDefinitionLister
75- kubeManager * kubernetes.Manager
72+ client * http.Client
73+ kubeManager * kubernetes.Manager
7674}
7775
7876func NewHandler (
@@ -81,7 +79,6 @@ func NewHandler(
8179 cookieSigningKey , cookieEncryptionKey []byte ,
8280 scope kubebindv1alpha2.InformerScope ,
8381 mgr * kubernetes.Manager ,
84- apiextensionsLister apiextensionslisters.CustomResourceDefinitionLister ,
8582) (* handler , error ) {
8683 return & handler {
8784 oidc : provider ,
@@ -92,26 +89,30 @@ func NewHandler(
9289 scope : scope ,
9390 client : http .DefaultClient ,
9491 kubeManager : mgr ,
95- apiextensionsLister : apiextensionsLister ,
9692 cookieSigningKey : cookieSigningKey ,
9793 cookieEncryptionKey : cookieEncryptionKey ,
9894 }, nil
9995}
10096
10197func (h * handler ) AddRoutes (mux * mux.Router ) {
102- mux .HandleFunc ("/export" , h .handleServiceExport ).Methods ("GET" )
103- mux .HandleFunc ("/resources" , h .handleResources ).Methods ("GET" )
104- mux .HandleFunc ("/bind" , h .handleBind ).Methods ("GET" )
105- mux .HandleFunc ("/authorize" , h .handleAuthorize ).Methods ("GET" )
98+ // Every route is cluster scoped.
99+ mux .HandleFunc ("/clusters/{cluster}/exports" , h .handleServiceExport ).Methods ("GET" )
100+ mux .HandleFunc ("/clusters/{cluster}/resources" , h .handleResources ).Methods ("GET" )
101+ mux .HandleFunc ("/clusters/{cluster}/bind" , h .handleBind ).Methods ("GET" )
102+ mux .HandleFunc ("/clusters/{cluster}/authorize" , h .handleAuthorize ).Methods ("GET" )
103+
106104 mux .HandleFunc ("/callback" , h .handleCallback ).Methods ("GET" )
107105}
108106
109107func (h * handler ) handleServiceExport (w http.ResponseWriter , r * http.Request ) {
110108 logger := klog .FromContext (r .Context ()).WithValues ("method" , r .Method , "url" , r .URL .String ())
109+ logger .Info ("handleServiceExport" )
110+
111+ cluster := mux .Vars (r )["cluster" ] // Not yet replace -.
111112
112113 oidcAuthorizeURL := h .oidcAuthorizeURL
113114 if oidcAuthorizeURL == "" {
114- oidcAuthorizeURL = fmt .Sprintf ("http://%s/authorize" , r .Host )
115+ oidcAuthorizeURL = fmt .Sprintf ("http://%s/clusters/%s/ authorize" , r .Host , cluster )
115116 }
116117
117118 ver , err := bindversion .BinaryVersion (componentbaseversion .Get ().GitVersion )
@@ -159,11 +160,13 @@ func prepareNoCache(w http.ResponseWriter) {
159160func (h * handler ) handleAuthorize (w http.ResponseWriter , r * http.Request ) {
160161 logger := klog .FromContext (r .Context ()).WithValues ("method" , r .Method , "url" , r .URL .String ())
161162
163+ cluster := mux .Vars (r )["cluster" ]
164+
162165 scopes := []string {"openid" , "profile" , "email" , "offline_access" }
163166 code := & AuthCode {
164167 RedirectURL : r .URL .Query ().Get ("u" ),
165168 SessionID : r .URL .Query ().Get ("s" ),
166- ClusterID : r . URL . Query (). Get ( "c" ) ,
169+ ClusterID : cluster ,
167170 }
168171 if p := r .URL .Query ().Get ("p" ); p != "" && code .RedirectURL == "" {
169172 code .RedirectURL = fmt .Sprintf ("http://localhost:%s/callback" , p )
@@ -277,40 +280,46 @@ func (h *handler) handleCallback(w http.ResponseWriter, r *http.Request) {
277280 }
278281
279282 http .SetCookie (w , cookie .MakeCookie (r , cookieName , encoded , time .Duration (1 )* time .Hour ))
280- http .Redirect (w , r , "/resources?s=" + authCode .SessionID , http .StatusFound )
283+ http .Redirect (w , r , "/clusters/" + authCode . ClusterID + "/ resources?s="+ authCode .SessionID , http .StatusFound )
281284}
282285
283286func (h * handler ) handleResources (w http.ResponseWriter , r * http.Request ) {
284287 logger := klog .FromContext (r .Context ()).WithValues ("method" , r .Method , "url" , r .URL .String ())
285288
286289 prepareNoCache (w )
287290
291+ clusterPath := mux .Vars (r )["cluster" ]
292+ var cluster string
293+ if clusterPath == "-" {
294+ cluster = "" // empty strings means - all cluster for for Multicluster-runtime. But this does not work for bind UI.
295+ }
296+
288297 if h .testingAutoSelect != "" {
289298 parts := strings .SplitN (h .testingAutoSelect , "." , 2 )
290- http .Redirect (w , r , "/resources/" + parts [0 ]+ "/" + parts [1 ], http .StatusFound )
299+ http .Redirect (w , r , "/clusters/" + cluster + "/ resources/"+ parts [0 ]+ "/" + parts [1 ], http .StatusFound )
291300 return
292301 }
293302
294303 labelSelector := labels.Set {
295304 resources .ExportedCRDsLabel : "true" ,
296305 }
297- crds , err := h .apiextensionsLister . List ( labelSelector .AsSelector ())
306+ crds , err := h .kubeManager . ListCustomResourceDefinitions ( r . Context (), cluster , labelSelector .AsSelector ())
298307 if err != nil {
299308 logger .Error (err , "failed to list crds" )
300309 http .Error (w , "internal error" , http .StatusInternalServerError )
301310 return
302311 }
303- sort .SliceStable (crds , func (i , j int ) bool {
304- return crds [i ].Name < crds [j ].Name
312+ sort .SliceStable (crds . Items , func (i , j int ) bool {
313+ return crds . Items [i ].Name < crds . Items [j ].Name
305314 })
306315 rightScopedCRDs := []* apiextensionsv1.CustomResourceDefinition {}
307- for _ , crd := range crds {
316+ for _ , crd := range crds . Items {
308317 if h .scope == kubebindv1alpha2 .ClusterScope || crd .Spec .Scope == apiextensionsv1 .NamespaceScoped {
309- rightScopedCRDs = append (rightScopedCRDs , crd )
318+ rightScopedCRDs = append (rightScopedCRDs , & crd )
310319 }
311320 }
312321
313- apiResourceSchemas , err := h .kubeManager .ListAPIResourceSchemas (r .Context ())
322+ apiResourceSchemas , err := h .kubeManager .ListAPIResourceSchemas (r .Context (), cluster )
314323 if err != nil {
315324 logger .Error (err , "failed to get api resource schemas" )
316325 http .Error (w , "internal error" , http .StatusInternalServerError )
@@ -319,10 +328,12 @@ func (h *handler) handleResources(w http.ResponseWriter, r *http.Request) {
319328 bs := bytes.Buffer {}
320329 if err := resourcesTemplate .Execute (& bs , struct {
321330 SessionID string
331+ Cluster string
322332 CRDs []* apiextensionsv1.CustomResourceDefinition
323333 APIResourceSchemas []kubebindv1alpha2.APIResourceSchema
324334 }{
325335 SessionID : r .URL .Query ().Get ("s" ),
336+ Cluster : clusterPath ,
326337 CRDs : rightScopedCRDs ,
327338 APIResourceSchemas : apiResourceSchemas .Items ,
328339 }); err != nil {
@@ -368,7 +379,12 @@ func (h *handler) handleBind(w http.ResponseWriter, r *http.Request) {
368379
369380 group := r .URL .Query ().Get ("group" )
370381 resource := r .URL .Query ().Get ("resource" )
371- kfg , err := h .kubeManager .HandleResources (r .Context (), idToken .Subject + "#" + state .ClusterID , resource , group )
382+ cluster := mux .Vars (r )["cluster" ]
383+ if cluster == "-" {
384+ cluster = ""
385+ }
386+
387+ kfg , err := h .kubeManager .HandleResources (r .Context (), idToken .Subject + "#" + state .ClusterID , cluster , resource , group )
372388 if err != nil {
373389 logger .Error (err , "failed to handle resources" )
374390 http .Error (w , "internal error" , http .StatusInternalServerError )
@@ -414,6 +430,7 @@ func (h *handler) handleBind(w http.ResponseWriter, r *http.Request) {
414430 Kubeconfig : kfg ,
415431 Requests : []runtime.RawExtension {{Raw : requestBytes }},
416432 }
433+
417434 payload , err := json .Marshal (& response )
418435 if err != nil {
419436 logger .Error (err , "failed to marshal auth response" )
0 commit comments