diff --git a/Dockerfile b/Dockerfile index a505de8..fb68b08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ FROM isl-dsdc.ca.com:5000/ca-standard-images/alpine34:latest USER 496 ADD --chown=496:496 ./kubeiql.elf /usr/local/bin/kubeiql -ADD --chown=496:496 https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VSN:-v1.11.2}/bin/linux/amd64/kubectl /usr/local/bin/kubectl -RUN chmod 777 /usr/local/bin/kubectl +#ADD --chown=496:496 https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VSN:-v1.11.2}/bin/linux/amd64/kubectl /usr/local/bin/kubectl +#RUN chmod 777 /usr/local/bin/kubectl EXPOSE 8128 CMD ["/usr/local/bin/kubeiql"] diff --git a/README.md b/README.md index 055bfdd..d93bf7a 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ localhost port 8080 (run "kubectl proxy --port=8080") 'token', e.g. /var/run/secrets/kubernetes.io/serviceaccount from a pod inside a cluster * Tests are lacking -* Not yet built into a container (which we will need to deploy within - the cluster's API service) +* See https://hub.docker.com/r/yipeeio/kubeiql/ for a docker image + ## Getting Started To experiment with the API: diff --git a/cache_public.go b/cache_access.go similarity index 100% rename from cache_public.go rename to cache_access.go diff --git a/cache_private.go b/cache_impl.go similarity index 97% rename from cache_private.go rename to cache_impl.go index a13f050..8160441 100644 --- a/cache_private.go +++ b/cache_impl.go @@ -21,8 +21,8 @@ import ( // N.B.: this is the cache implementation whose functions are // not intended to be called directly. // The intended cache interface -// is in cache_public.go: namely "Lookup", "Add", "Remove", -// and the key-building functions. +// is in cache_access.go: namely "Lookup", "Add", "Remove", +// along with the key-building functions. // All access to the cache is intended to be via the server mailbox. // That is our serialization mechanism (akin to an erlang gen_server). // diff --git a/kubeaccess.go b/kubeaccess.go index 0854d06..57250e3 100644 --- a/kubeaccess.go +++ b/kubeaccess.go @@ -17,10 +17,7 @@ package main import ( "context" "encoding/json" - // "fmt" - "io/ioutil" - "log" - "os/exec" + "fmt" ) // Functions for retrieving Kubernetes information from a cluster @@ -70,41 +67,13 @@ func isTest() bool { func lookUpMap( ctx context.Context, kind, namespace, name string) JsonObject { - cache := getCache(ctx) key := cacheKey(kind, namespace, name) var cachedVal interface{} - if isWatchedKind(kind) { - cachedVal = GetCache().Lookup(key) - } else { - cachedVal = (*cache)[key] + if !isWatchedKind(kind) { + panic(fmt.Sprintf("Add watcher for kind '%s'", kind)) } - var result JsonObject - if cachedVal == nil { - if isTest() { - return map[string]interface{}{} - } - cmd := exec.Command(KubectlPath, "get", - "-o", "json", "--namespace", namespace, kind, name) - stdout, err := cmd.StdoutPipe() - if err != nil { - log.Fatal(err) - } - if err := cmd.Start(); err != nil { - log.Fatal(err) - } - bytes, err := ioutil.ReadAll(stdout) - if err != nil { - log.Fatal(err) - } - if err := cmd.Wait(); err != nil { - log.Fatal(err) - } - result = fromJson(bytes).(JsonObject) - (*cache)[key] = result - } else { - result = cachedVal.(JsonObject) - } - return result + cachedVal = GetCache().Lookup(key) + return cachedVal.(JsonObject) } func lookUpResource(ctx context.Context, kind, namespace, name string) resource { @@ -117,47 +86,16 @@ func lookUpResource(ctx context.Context, kind, namespace, name string) resource return mapToResource(ctx, mapval) } -// Get all resource instances of a specific kind -func getAllK8sObjsOfKind( +func getCachedResourceList( ctx context.Context, - kind string, + cacheKey string, test func(JsonObject) bool) []resource { - cache := getCache(ctx) + var cachedJsonObjs []JsonObject var results []resource - var objs interface{} - if isWatchedKind(kind) { - objs = GetCache().Lookup(kind) - } else { - objs = (*cache)[kind] - } - if objs != nil { + if objs := GetCache().Lookup(cacheKey); objs != nil { cachedJsonObjs = objs.([]JsonObject) - } else { - if isTest() { - return make([]resource, 0) - } - cmd := exec.Command(KubectlPath, "get", - "-o", "json", "--all-namespaces", kind) - stdout, err := cmd.StdoutPipe() - if err != nil { - log.Fatal(err) - } - if err := cmd.Start(); err != nil { - log.Fatal(err) - } - bytes, err := ioutil.ReadAll(stdout) - if err != nil { - log.Fatal(err) - } - if err := cmd.Wait(); err != nil { - log.Fatal(err) - } - arr := (fromJson(bytes).(JsonObject))["items"].(JsonArray) - for _, val := range arr { - cachedJsonObjs = append(cachedJsonObjs, val.(JsonObject)) - } } for _, res := range cachedJsonObjs { val := mapToResource(ctx, res) @@ -165,70 +103,32 @@ func getAllK8sObjsOfKind( results = append(results, val) } } - if results == nil { results = make([]resource, 0) } - if (*cache)[kind] == nil && len(cachedJsonObjs) > 0 { - (*cache)[kind] = cachedJsonObjs - } return results } -// Get all resource instances of a specific kind in a specific namespace +// Get all resource instances of a specific kind +func getAllK8sObjsOfKind( + ctx context.Context, + kind string, + test func(JsonObject) bool) []resource { + if !isWatchedKind(kind) { + panic(fmt.Sprintf("Add watcher for kind '%s'", kind)) + } + return getCachedResourceList(ctx, kind, test) +} + +// Get all resource instances of a specific kind in a specific namespace func getAllK8sObjsOfKindInNamespace( ctx context.Context, kind, ns string, test func(JsonObject) bool) []resource { - cache := getCache(ctx) - var cachedJsonObjs []JsonObject - var results []resource key := nsCacheKey(kind, ns) - var objs interface{} - if isWatchedKind(kind) { - objs = GetCache().Lookup(key) - } else { - objs = (*cache)[key] + if !isWatchedKind(kind) { + panic(fmt.Sprintf("Add watcher for kind '%s'", kind)) } - if objs != nil { - cachedJsonObjs = objs.([]JsonObject) - } else { - if isTest() { - return make([]resource, 0) - } - cmd := exec.Command(KubectlPath, "get", - "-o", "json", "--namespace", ns, kind) - stdout, err := cmd.StdoutPipe() - if err != nil { - log.Fatal(err) - } - if err := cmd.Start(); err != nil { - log.Fatal(err) - } - bytes, err := ioutil.ReadAll(stdout) - if err != nil { - log.Fatal(err) - } - if err := cmd.Wait(); err != nil { - log.Fatal(err) - } - arr := (fromJson(bytes).(JsonObject))["items"].(JsonArray) - for _, val := range arr { - cachedJsonObjs = append(cachedJsonObjs, val.(JsonObject)) - } - } - for _, res := range cachedJsonObjs { - val := mapToResource(ctx, res) - if test(res) { - results = append(results, val) - } - } - if results == nil { - results = make([]resource, 0) - } - if (*cache)[key] == nil && len(cachedJsonObjs) > 0 { - (*cache)[key] = cachedJsonObjs - } - return results + return getCachedResourceList(ctx, key, test) }