#!/usr/bin/env python

import logging
import sys
import subprocess
import yaml
from time import time
from stat import S_IFDIR, S_IFLNK, S_IFREG
from fuse import FUSE, FuseOSError, Operations, LoggingMixIn

class KubernetesClient(object):
    def _run_command(self, cmd):
        output = subprocess.check_output(['kubectl'] + cmd)
        return yaml.load(output)

    def get_namespaces(self):
        payload = self._run_command('get ns -o yaml'.split())
        names = [ item['metadata']['name'] for item in payload['items']]
        return names

    def get_entities(self, ns, entity):
    	namespace = ['--namespace', ns] if ns != 'all' else ['--all-namespaces']
        payload = self._run_command(['get', entity, '-o', 'yaml'] + namespace)
        names = [ item['metadata']['name'] for item in payload['items']]
        return names

class KubePathBuilder(object):
    def __init__(self, namespace = None, resource_type = None, object_id = None, action = None):
        self.namespace = namespace 
        self.resource_type = resource_type
        self.object_id = object_id
        self.action = None

    def list_files(self, client):
        if self.object_id is not None:
            return ['describe', 'logs', 'json', 'yaml']
        if self.resource_type is not None:
            return client.get_entities(self.namespace, self.resource_type)
        if self.namespace is not None:
            return ['svc', 'pod', 'rc']
        return client.get_namespaces() + ['all']

    def parse_path(self, path):
        if path == '/': return self
        parts = path[1:].split("/")
        self.namespace = parts[0] if len(parts) > 0 else None
        self.resource_type = parts[1] if len(parts) > 1 else None
        self.object_id = parts[2] if len(parts) > 2 else None
        self.action = parts[3] if len(parts) > 3 else None
        print self
        return self

    def __repr__(self):
        result = ['<']
        if self.action is not None:
            result.append("action %s on" % self.action)
        if self.object_id is not None:
            result.append('object %s' % self.object_id)
        if self.resource_type is not None:
            result.append("of type %s" % self.resource_type)
        if self.namespace is not None:
            result.append('in namespace %s' % self.namespace)
        result.append('>')
        return " ".join(result)
        
    def _stat_dir(self):
        return dict(st_mode=(S_IFDIR), st_nlink=2,
                st_size=0, st_ctime=time(), st_mtime=time(),
                st_atime=time())

    def _stat_file(self):
        return dict(st_mode=(S_IFREG), st_nlink=1,
                st_size=0, st_ctime=time(), st_mtime=time(),
                st_atime=time())

    def getattr(self, client):
        if self.action is not None:
            return self._stat_file()
        return self._stat_dir()

class KubeFuse(LoggingMixIn, Operations):

    def __init__(self):
        self.client = KubernetesClient()

    def readdir(self, path, fh):
        return KubePathBuilder().parse_path(path).list_files(self.client)

    def getattr(self, path, fh=None):
        return KubePathBuilder().parse_path(path).getattr(self.client)


if __name__ == '__main__':
    if len(sys.argv) != 2:
        print('usage: %s <mountpoint>' % sys.argv[0])
        exit(1)

    logging.basicConfig(level=logging.DEBUG)
    fuse = FUSE(KubeFuse(), sys.argv[1], foreground=True)

@@ -72,16 +72,26 @@
 rt yaml%0A
+import os%0A
 from tim
@@ -146,16 +146,25 @@
  S_IFREG
+, S_IFIFO
 %0Afrom fu
@@ -612,9 +612,12 @@
     
-%09
+    
 name
@@ -859,16 +859,300 @@
  names%0A%0A
+    def get_object_in_format(self, ns, entity_type, object, format):%0A        namespace = %5B'--namespace', ns%5D if ns != 'all' else %5B'--all-namespaces'%5D%0A        payload = subprocess.check_output(%5B'kubectl', 'get', entity_type, object, '-o', format%5D + namespace)%0A        return payload%0A%0A%0A
 class Ku
@@ -2750,16 +2750,23 @@
 (S_IFDIR
+ %7C 0555
 ), st_nl
@@ -2929,16 +2929,23 @@
 (S_IFREG
+ %7C 0444
 ), st_nl
@@ -2967,32 +2967,36 @@
         st_size=
+5000
 0, st_ctime=time
@@ -3187,16 +3187,436 @@
 _dir()%0A%0A
+    def read(self, client, size, offset):%0A        if self.action is None:%0A            raise FuseOSError(errno.ENOENT)%0A%0A        data = ''%0A        if self.action in %5B'describe', 'logs'%5D:%0A            pass%0A        if self.action in %5B'json', 'yaml'%5D:%0A            data = client.get_object_in_format(self.namespace, self.resource_type, self.object_id, self.action)%0A            data = data%5Boffset:size + 1%5D%0A        return data%0A%0A
 class Ku
@@ -3714,16 +3714,36 @@
 Client()
+%0A        self.fd = 0
 %0A%0A    de
@@ -3878,24 +3878,24 @@
 , fh=None):%0A
-
         retu
@@ -3954,16 +3954,221 @@
 lient)%0A%0A
+    def open(self, path, flags):%0A        self.fd += 1%0A        return self.fd%0A%0A    def read(self, path, size, offset, fh):%0A        return KubePathBuilder().parse_path(path).read(self.client, size, offset)%0A%0A
 %0Aif __na

Read json and yaml. It's a bit hacky, but it works if the payload is not enormous