diff options
Diffstat (limited to 'pkg/resources/namespaces.go')
-rw-r--r-- | pkg/resources/namespaces.go | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/pkg/resources/namespaces.go b/pkg/resources/namespaces.go new file mode 100644 index 0000000..15ea9d6 --- /dev/null +++ b/pkg/resources/namespaces.go @@ -0,0 +1,110 @@ +package resources + +import ( + "context" + "io" + "math/rand" + "time" + + "github.com/docker/go-p9p" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + corev1 "k8s.io/client-go/informers/core/v1" + "k8s.io/client-go/kubernetes" +) + +type NamespacesRef struct { + client kubernetes.Interface + namespaceInformer corev1.NamespaceInformer + session Session + info *p9p.Dir + readdir *p9p.Readdir +} + +func NewNamespacesRef(client kubernetes.Interface, session Session) *NamespacesRef { + namespaceInformer := session.Informer().Core().V1().Namespaces() + + return &NamespacesRef{ + client: client, + namespaceInformer: namespaceInformer, + session: session, + } +} + +func (r *NamespacesRef) Info() p9p.Dir { + if r.info != nil { + return *r.info + } + + dir := p9p.Dir{} + dir.Qid.Path = rand.Uint64() + dir.Qid.Version = 0 + + dir.Name = "namespaces" + dir.Mode = 0664 + dir.Length = 0 + dir.AccessTime = time.Now() + dir.ModTime = time.Now() + dir.MUID = "none" + + uname, _ := r.session.GetAuth() + dir.UID = uname + dir.GID = uname + + dir.Qid.Type |= p9p.QTDIR + dir.Mode |= p9p.DMDIR + r.info = &dir + + return dir +} + +func (r *NamespacesRef) Get(name string) (Ref, error) { + namespace, err := r.namespaceInformer.Lister().Get(name) + if apierrors.IsNotFound(err) { + return nil, p9p.ErrNotfound + } + if err != nil { + return nil, err + } + + return &NamespaceRef{ + namespace: namespace, + client: r.client, + session: r.session, + }, nil +} + +func (r *NamespacesRef) Read(ctx context.Context, p []byte, offset int64) (n int, err error) { + if r.readdir != nil { + return r.readdir.Read(ctx, p, offset) + } + + namespaces, err := r.namespaceInformer.Lister().List(labels.Everything()) + if err != nil { + return 0, err + } + + namespaceRefs := make([]NamespaceRef, 0, len(namespaces)) + + for _, namespace := range namespaces { + namespace := namespace + namespaceRefs = append(namespaceRefs, NamespaceRef{ + namespace: namespace, + client: r.client, + session: r.session, + }) + } + + r.readdir = p9p.NewReaddir(p9p.NewCodec(), func() (p9p.Dir, error) { + if len(namespaceRefs) == 0 { + return p9p.Dir{}, io.EOF + } + + ns := namespaceRefs[0] + namespaceRefs = namespaceRefs[1:] + + return ns.Info(), nil + }) + + return r.readdir.Read(ctx, p, offset) +} |