Skip to content

Commit

Permalink
feat(namespaces): Add namespaces response
Browse files Browse the repository at this point in the history
  • Loading branch information
Zachary Seguin committed Aug 13, 2020
1 parent 42c7019 commit 4370e46
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 12 deletions.
6 changes: 5 additions & 1 deletion access.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ func (s *server) checkAccess(subjectAccessReviewTemplate authorizationv1.Subject
}

// Update the SubjectAccessReview request with the namespace and user information
sar.Spec.ResourceAttributes.Namespace = vars["namespace"]
if namespace, ok := vars["namespace"]; ok {
sar.Spec.ResourceAttributes.Namespace = namespace
} else {
sar.Spec.ResourceAttributes.Namespace = ""
}
sar.Spec.User = user

// Submit the SubjectAccessReview to the Kubernetes API server
Expand Down
19 changes: 8 additions & 11 deletions listers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,37 @@ func (s *server) setupListers(ctx context.Context) error {
factory := informers.NewSharedInformerFactory(s.clientsets.kubernetes, 5*time.Minute)
kubeflowFactory := kubeflowinformers.NewSharedInformerFactory(s.clientsets.kubeflow, time.Minute*5)

// Namespaces
namespacesInformer := factory.Core().V1().Namespaces()
s.listers.namespaces = namespacesInformer.Lister()

// Events
eventsInformer := factory.Core().V1().Events()
go eventsInformer.Informer().Run(ctx.Done())

s.listers.events = eventsInformer.Lister()

// StorageClasses
storageClassesInformer := factory.Storage().V1().StorageClasses()
go storageClassesInformer.Informer().Run(ctx.Done())

s.listers.storageClasses = storageClassesInformer.Lister()

// PersistentVolumeClaims
pvcInformer := factory.Core().V1().PersistentVolumeClaims()
go pvcInformer.Informer().Run(ctx.Done())

s.listers.persistentVolumeClaims = pvcInformer.Lister()

// PodDefaults
podDefaultsInformer := kubeflowFactory.Kubeflow().V1alpha1().PodDefaults()
go podDefaultsInformer.Informer().Run(ctx.Done())

s.listers.podDefaults = podDefaultsInformer.Lister()

// Notebooks
notebooksInformer := kubeflowFactory.Kubeflow().V1().Notebooks()
go notebooksInformer.Informer().Run(ctx.Done())

s.listers.notebooks = notebooksInformer.Lister()

go factory.Start(ctx.Done())
go kubeflowFactory.Start(ctx.Done())

// Wait until sync
log.Printf("synching caches...")
tctx, _ := context.WithTimeout(ctx, time.Minute)
if !cache.WaitForCacheSync(tctx.Done(), eventsInformer.Informer().HasSynced, storageClassesInformer.Informer().HasSynced, pvcInformer.Informer().HasSynced, podDefaultsInformer.Informer().HasSynced, notebooksInformer.Informer().HasSynced) {
if !cache.WaitForCacheSync(tctx.Done(), namespacesInformer.Informer().HasSynced, eventsInformer.Informer().HasSynced, storageClassesInformer.Informer().HasSynced, pvcInformer.Informer().HasSynced, podDefaultsInformer.Informer().HasSynced, notebooksInformer.Informer().HasSynced) {
return fmt.Errorf("timeout synching caches")
}
log.Printf("done synching caches")
Expand Down
12 changes: 12 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var userIDHeader string
var staticDirectory string

type listers struct {
namespaces v1listers.NamespaceLister
events v1listers.EventLister
storageClasses storagev1listers.StorageClassLister
persistentVolumeClaims v1listers.PersistentVolumeClaimLister
Expand Down Expand Up @@ -117,8 +118,19 @@ func main() {

// Setup route handlers
router.HandleFunc("/api/config", s.GetConfig).Methods("GET")

router.HandleFunc("/api/storageclasses/default", s.GetDefaultStorageClass).Methods("GET")

router.HandleFunc("/api/namespaces", s.checkAccess(authorizationv1.SubjectAccessReview{
Spec: authorizationv1.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationv1.ResourceAttributes{
Group: corev1.SchemeGroupVersion.Group,
Verb: "list",
Resource: "namespaces",
Version: corev1.SchemeGroupVersion.Version,
},
},
}, s.GetNamespaces)).Methods("GET")
router.HandleFunc("/api/namespaces/{namespace}/notebooks", s.checkAccess(authorizationv1.SubjectAccessReview{
Spec: authorizationv1.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationv1.ResourceAttributes{
Expand Down
40 changes: 40 additions & 0 deletions namespaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package main

import (
"log"
"net/http"
"sort"

"k8s.io/apimachinery/pkg/labels"
)

type namespacesresponse struct {
APIResponse
Namespaces []string `json:"namespaces"`
}

// GetNamespaces returns the namespaces in the environment.
func (s *server) GetNamespaces(w http.ResponseWriter, r *http.Request) {
log.Printf("loading namespaces")

namespaces, err := s.listers.namespaces.List(labels.Everything())
if err != nil {
s.error(w, r, err)
return
}

sort.Sort(namespacesByName(namespaces))

resp := namespacesresponse{
APIResponse: APIResponse{
Success: true,
},
Namespaces: make([]string, 0),
}

for _, namespace := range namespaces {
resp.Namespaces = append(resp.Namespaces, namespace.Name)
}

s.respond(w, r, resp)
}
15 changes: 15 additions & 0 deletions sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,18 @@ func (pvcs persistentVolumeClaimsByName) Less(a, b int) bool {
func (pvcs persistentVolumeClaimsByName) Swap(a, b int) {
pvcs[a], pvcs[b] = pvcs[b], pvcs[a]
}

// Namespaces by Name
type namespacesByName []*corev1.Namespace

func (namespaces namespacesByName) Len() int {
return len(namespaces)
}

func (namespaces namespacesByName) Less(a, b int) bool {
return namespaces[a].Name < namespaces[b].Name
}

func (namespaces namespacesByName) Swap(a, b int) {
namespaces[a], namespaces[b] = namespaces[b], namespaces[a]
}

0 comments on commit 4370e46

Please sign in to comment.