diff --git a/daemonset.go b/daemonset.go index cdaa888..2b04854 100644 --- a/daemonset.go +++ b/daemonset.go @@ -1,3 +1,17 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -6,6 +20,7 @@ import ( "strings" ) +// DaemonSets place a pod on each server type daemonSet struct { Metadata metadata Owner resource @@ -18,6 +33,7 @@ type daemonSetResolver struct { d daemonSet } +// Translate unmarshalled json into a deployment object func mapToDaemonSet( ctx context.Context, jsonObj map[string]interface{}) daemonSet { @@ -29,6 +45,7 @@ func mapToDaemonSet( return daemonSet{meta, owner, rootOwner, nil} } +// DaemonSets have pods as children func getDaemonSetPods(ctx context.Context, d daemonSet) *[]pod { dsName := d.Metadata.Name dsNamePrefix := dsName + "-" @@ -53,6 +70,7 @@ func getDaemonSetPods(ctx context.Context, d daemonSet) *[]pod { return &results } +// Resource method implementations func (r *daemonSetResolver) Kind() string { return DaemonSetKind } @@ -75,6 +93,7 @@ func (r *daemonSetResolver) RootOwner() *resourceResolver { return &resourceResolver{r.ctx, r.d.RootOwner} } +// Resolve child Pods func (r *daemonSetResolver) Pods() []*podResolver { if r.d.Pods == nil { r.d.Pods = getDaemonSetPods(r.ctx, r.d) diff --git a/deployment.go b/deployment.go index de86a22..43a2213 100644 --- a/deployment.go +++ b/deployment.go @@ -1,3 +1,17 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -6,6 +20,8 @@ import ( "strings" ) +// Top level Kubernetes replicated controller. Deployments are built out +// of ReplicaSets. type deployment struct { Metadata metadata Owner resource @@ -18,6 +34,7 @@ type deploymentResolver struct { d deployment } +// Translate unmarshalled json into a deployment object func mapToDeployment( ctx context.Context, jsonObj map[string]interface{}) deployment { @@ -26,6 +43,7 @@ func mapToDeployment( return deployment{meta, nil, nil, nil} } +// Retrieve the ReplicaSets comprising the deployment func getReplicaSets(ctx context.Context, d deployment) *[]replicaSet { depName := d.Metadata.Name depNamePrefix := depName + "-" @@ -50,6 +68,7 @@ func getReplicaSets(ctx context.Context, d deployment) *[]replicaSet { return &results } +// Resource method implementations func (r *deploymentResolver) Kind() string { return DeploymentKind } @@ -66,6 +85,7 @@ func (r *deploymentResolver) RootOwner() *resourceResolver { return &resourceResolver{r.ctx, &deploymentResolver{r.ctx, r.d}} } +// Resolve child ReplicaSets func (r *deploymentResolver) ReplicaSets() []*replicaSetResolver { if r.d.ReplicaSets == nil { r.d.ReplicaSets = getReplicaSets(r.ctx, r.d) diff --git a/kubeaccess.go b/kubeaccess.go index f99cfc8..86c71be 100644 --- a/kubeaccess.go +++ b/kubeaccess.go @@ -1,3 +1,17 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -9,6 +23,9 @@ import ( "os/exec" ) +// Functions for retrieving Kubernetes information from a cluster + +// Get a single resource instance from a namespace func getK8sResource(kind, namespace, name string) map[string]interface{} { return fromJson( lookUpResource(kind, namespace, name)).(map[string]interface{}) @@ -44,6 +61,7 @@ func lookUpResource(kind, namespace, name string) []byte { return bytes } +// Get all resource instances of a specific kind func getAllK8sObjsOfKind( ctx context.Context, kind string, @@ -78,6 +96,7 @@ func getAllK8sObjsOfKind( return results } +// Get all resource instances of a specific kind in a specific namespace func getAllK8sObjsOfKindInNamespace( ctx context.Context, kind, ns string, diff --git a/kubeicql.go b/kubeicql.go index 0687e68..73a667c 100644 --- a/kubeicql.go +++ b/kubeicql.go @@ -1,16 +1,25 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( "context" ) -// The schema below defines the objects and relationships that can be -// queried and modified. Each "type" below can be returned from -// queries so a "resolver" must be implemented. The resolver has a -// method for each field of the object and the graphql server calls a -// resolver method as needed based on what is requested by the -// user. Each type has a struct that holds its scalar values while set -// or list values are constructed on demand. +// The schema below defines the objects and relationships for Kubernetes. +// It is not yet complete. var Schema = ` schema { @@ -167,6 +176,7 @@ const DeploymentKind = "Deployment" type Resolver struct { } +// Pod lookups func (r *Resolver) AllPods(ctx context.Context) *[]*podResolver { pset := getAllK8sObjsOfKind( ctx, @@ -215,6 +225,7 @@ func (r *Resolver) PodByName( return nil } +// Deployment lookups func (r *Resolver) AllDeployments(ctx context.Context) *[]*deploymentResolver { dset := getAllK8sObjsOfKind( ctx, @@ -264,6 +275,7 @@ func (r *Resolver) DeploymentByName( return nil } +// ReplicaSet lookups func (r *Resolver) AllReplicaSets(ctx context.Context) *[]*replicaSetResolver { rset := getAllK8sObjsOfKind( ctx, @@ -313,6 +325,7 @@ func (r *Resolver) ReplicaSetByName( return nil } +// StatefulSet lookups func (r *Resolver) AllStatefulSets(ctx context.Context) *[]*statefulSetResolver { sset := getAllK8sObjsOfKind( ctx, @@ -362,6 +375,7 @@ func (r *Resolver) StatefulSetByName( return nil } +// DaemonSet lookups func (r *Resolver) AllDaemonSets(ctx context.Context) *[]*daemonSetResolver { dset := getAllK8sObjsOfKind( ctx, diff --git a/label.go b/label.go index ba74332..0ba85b9 100644 --- a/label.go +++ b/label.go @@ -1,9 +1,24 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( "context" ) +// Single label value within a Kubernetes object type label struct { Name string Value string @@ -14,6 +29,7 @@ type labelResolver struct { l *label } +// Translate unmarshalled json into a set of labels func mapToLabels(lMap map[string]interface{}) *[]label { var labels []label diff --git a/metadata.go b/metadata.go index adc4bc0..b672fb3 100644 --- a/metadata.go +++ b/metadata.go @@ -1,9 +1,24 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( "context" ) +// Kubernetes metadata type metadata struct { CreationTimestamp *string GenerateName *string @@ -21,6 +36,7 @@ type metadataResolver struct { m metadata } +// Translate unmarshalled json into a metadata object func mapToMetadata( ctx context.Context, ns string, jsonObj map[string]interface{}) metadata { var m metadata @@ -42,6 +58,7 @@ func mapToMetadata( m.SelfLink = jsonObj["selfLink"].(string) m.Uid = jsonObj["uid"].(string) + // Similar to getOwner if orArray := jsonObj["ownerReferences"]; orArray != nil { for _, oref := range orArray.([]interface{}) { ormap := oref.(map[string]interface{}) @@ -58,6 +75,7 @@ func mapToMetadata( return m } +// Metadata methods func (r *metadataResolver) CreationTimestamp() *string { return r.m.CreationTimestamp } diff --git a/owners.go b/owner.go similarity index 67% rename from owners.go rename to owner.go index 55ad8c6..7cb4eea 100644 --- a/owners.go +++ b/owner.go @@ -1,3 +1,17 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -5,12 +19,15 @@ import ( // "fmt" ) +// Tracks ownership relationships between Kubernetes objects. If an object +// has no owner, we treat it as its own owner type ownerRef struct { ctx context.Context ref map[string]interface{} - cachedOwner resource + cachedOwner resource // cached info for on-demand lookup } +// resource method implementations func (r *ownerRef) Kind() string { if r.cachedOwner == nil { r.cachedOwner = getOwner(r.ctx, r.ref) @@ -39,6 +56,8 @@ func (r *ownerRef) RootOwner() *resourceResolver { return r.cachedOwner.RootOwner() } +// Fetch owners by getting ownerReferences and doing lookups based +// on their contents func getRawOwner(val map[string]interface{}) map[string]interface{} { if orefs := getMetadataField(val, "ownerReferences"); orefs != nil { oArray := orefs.([]interface{}) diff --git a/pods.go b/pod.go similarity index 59% rename from pods.go rename to pod.go index 8ce22f7..823dcab 100644 --- a/pods.go +++ b/pod.go @@ -1,3 +1,17 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -5,6 +19,7 @@ import ( // "fmt" ) +// The base Kubernetes component type pod struct { Metadata metadata Owner resource @@ -16,6 +31,7 @@ type podResolver struct { p pod } +// Translate unmarshalled json into a metadata object func mapToPod(ctx context.Context, jsonObj map[string]interface{}) pod { placeholder := &ownerRef{ctx, jsonObj, nil} owner := placeholder @@ -25,6 +41,7 @@ func mapToPod(ctx context.Context, jsonObj map[string]interface{}) pod { return pod{meta, owner, rootOwner} } +// Resource method implementations func (r *podResolver) Kind() string { return PodKind } diff --git a/replicaset.go b/replicaset.go index 1f7f5d5..b0b4c29 100644 --- a/replicaset.go +++ b/replicaset.go @@ -1,3 +1,17 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -6,6 +20,7 @@ import ( "strings" ) +// ReplicaSets manage replicated pods type replicaSet struct { Metadata metadata Owner resource @@ -18,6 +33,7 @@ type replicaSetResolver struct { r replicaSet } +// Translate unmarshalled json into a deployment object func mapToReplicaSet( ctx context.Context, jsonObj map[string]interface{}) replicaSet { @@ -29,6 +45,7 @@ func mapToReplicaSet( return replicaSet{meta, owner, rootOwner, nil} } +// ReplicaSets have pods as children func getReplicaSetPods(ctx context.Context, r replicaSet) *[]pod { rsName := r.Metadata.Name rsNamePrefix := rsName + "-" @@ -53,6 +70,7 @@ func getReplicaSetPods(ctx context.Context, r replicaSet) *[]pod { return &results } +// Resource method implementations func (r *replicaSetResolver) Kind() string { return ReplicaSetKind } @@ -75,6 +93,7 @@ func (r *replicaSetResolver) RootOwner() *resourceResolver { return &resourceResolver{r.ctx, r.r.RootOwner} } +// Resolve child Pods func (r *replicaSetResolver) Pods() []*podResolver { if r.r.Pods == nil { r.r.Pods = getReplicaSetPods(r.ctx, r.r) diff --git a/resource.go b/resource.go index e76d8a4..7fd9c90 100644 --- a/resource.go +++ b/resource.go @@ -1,3 +1,17 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( @@ -5,6 +19,9 @@ import ( "fmt" ) +// Represents all "active" components: (Pods, Deployments, DaemonSets, +// StatefulSets, ReplicaSets + type resource interface { Kind() string Metadata() *metadataResolver @@ -17,6 +34,7 @@ type resourceResolver struct { r resource } +// Translate a map containing unmarshalled json into a resource instance. func mapToResource( ctx context.Context, rMap map[string]interface{}) resource { @@ -39,6 +57,7 @@ func mapToResource( return nil } +// Turn an instance of a resource into one of its implementers func (r *resourceResolver) ToPod() (*podResolver, bool) { c, ok := r.r.(*podResolver) return c, ok @@ -64,6 +83,7 @@ func (r *resourceResolver) ToDeployment() (*deploymentResolver, bool) { return c, ok } +// Implementations of the methods common to all resources func (r *resourceResolver) Kind() string { return r.r.Kind() } diff --git a/server.go b/server.go index d06d546..2fd7cf9 100644 --- a/server.go +++ b/server.go @@ -1,7 +1,20 @@ +// Copyright 2018 Yipee.io +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package main import ( - "context" "fmt" "github.com/gorilla/mux" graphql "github.com/neelance/graphql-go" @@ -32,22 +45,7 @@ func main() { })) r.Handle("/query", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - headerMap := r.Header - service := "" - identity := "" - if headerMap["Service"] != nil { - service = headerMap["Service"][0] - } - if headerMap["Identity"] != nil { - identity = headerMap["Identity"][0] - } - handler.ServeHTTP(w, - r.WithContext( - context.WithValue( - context.WithValue( - r.Context(), - UserData("service"), service), - UserData("identity"), identity))) + handler.ServeHTTP(w, r) })).Methods("POST") r.HandleFunc("/query", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -60,37 +58,37 @@ var page = []byte(`
- - - - - + + + + + -