Fix Beryllium xray core. fix #500

mine
derailed 2020-01-20 18:22:10 -07:00
parent f74e754f58
commit 8a0b78a77b
8 changed files with 352 additions and 22 deletions

View File

@ -0,0 +1,39 @@
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_small.png" align="right" width="200" height="auto"/>
# Release v0.13.2
## Notes
Thank you to all that contributed with flushing out issues and enhancements for K9s! I'll try to mark some of these issues as fixed. But if you don't mind grab the latest rev and see if we're happier with some of the fixes! If you've filed an issue please help me verify and close. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated!
Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
---
### XRay Reloaded. Part Duh!
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_xray.png"/>
Found a waffle thin issue in the Beryllium(Be) core causing K9s xray vision to only operate on one eye ;)
Should be all betta' now...
Supported resources:
* Pods
* Deployments
* Services
* StatefulSets
* DaemonSets
* ReplicaSets
Still watch out for that overbite!! so please proceed with caution...
---
## Resolved Bugs/Features
* [Issue #500](https://github.com/derailed/k9s/issues/500)
---
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)

View File

@ -68,7 +68,10 @@ func (c *Command) xrayCmd(cmd string) error {
return errors.New("You must specify a resource") return errors.New("You must specify a resource")
} }
gvr, ok := c.alias.AsGVR(tokens[1]) gvr, ok := c.alias.AsGVR(tokens[1])
if !ok || !allowedXRay(gvr) { if !ok {
return fmt.Errorf("Huh? `%s` Command not found", cmd)
}
if !allowedXRay(gvr) {
return fmt.Errorf("Huh? `%s` Command not found", cmd) return fmt.Errorf("Huh? `%s` Command not found", cmd)
} }
return c.exec(cmd, "xrays", NewXray(gvr), true) return c.exec(cmd, "xrays", NewXray(gvr), true)
@ -85,11 +88,10 @@ func (c *Command) run(cmd, path string, clearStack bool) error {
if err != nil { if err != nil {
return err return err
} }
log.Debug().Msgf("CMD %v %v %v", gvr, v, err)
switch cmds[0] { switch cmds[0] {
case "ctx", "context", "contexts": case "ctx", "context", "contexts":
if len(cmds) == 2 && c.app.switchCtx(cmds[1], true) != nil { if len(cmds) == 2 {
return fmt.Errorf("context switch failed!") return useContext(c.app, cmds[1])
} }
view := c.componentFor(gvr, path, v) view := c.componentFor(gvr, path, v)
return c.exec(cmd, gvr, view, clearStack) return c.exec(cmd, gvr, view, clearStack)

View File

@ -34,21 +34,19 @@ func (c *Context) bindKeys(aa ui.KeyActions) {
func (c *Context) useCtx(app *App, model ui.Tabular, gvr, path string) { func (c *Context) useCtx(app *App, model ui.Tabular, gvr, path string) {
log.Debug().Msgf("SWITCH CTX %q--%q", gvr, path) log.Debug().Msgf("SWITCH CTX %q--%q", gvr, path)
if err := c.useContext(path); err != nil { if err := useContext(app, path); err != nil {
app.Flash().Err(err) app.Flash().Err(err)
return return
} }
if err := app.gotoResource("po", true); err != nil { c.Refresh()
app.Flash().Err(err) c.GetTable().Select(1, 0)
}
} }
func (c *Context) useContext(name string) error { func useContext(app *App, name string) error {
res, err := dao.AccessorFor(c.App().factory, client.NewGVR(c.GVR())) res, err := dao.AccessorFor(app.factory, client.NewGVR("contexts"))
if err != nil { if err != nil {
return nil return nil
} }
switcher, ok := res.(dao.Switchable) switcher, ok := res.(dao.Switchable)
if !ok { if !ok {
return errors.New("Expecting a switchable resource") return errors.New("Expecting a switchable resource")
@ -56,11 +54,9 @@ func (c *Context) useContext(name string) error {
if err := switcher.Switch(name); err != nil { if err := switcher.Switch(name); err != nil {
return err return err
} }
if err := c.App().switchCtx(name, false); err != nil { if err := app.switchCtx(name, false); err != nil {
return err return err
} }
c.Refresh()
c.GetTable().Select(1, 0)
return nil return nil
} }

View File

@ -68,7 +68,7 @@ func (c *Container) secretRefs(f dao.Factory, parent *TreeNode, ns string, ref *
return return
} }
gvr, id := "v1/secrets", client.FQN(ns, ref.LocalObjectReference.Name) gvr, id := "v1/secrets", client.FQN(ns, ref.LocalObjectReference.Name)
addRef(f, parent, id, gvr, ref.Optional) addRef(f, parent, gvr, id, ref.Optional)
} }
func (c *Container) configMapRefs(f dao.Factory, parent *TreeNode, ns string, ref *v1.ConfigMapKeySelector) { func (c *Container) configMapRefs(f dao.Factory, parent *TreeNode, ns string, ref *v1.ConfigMapKeySelector) {
@ -90,11 +90,13 @@ func addRef(f dao.Factory, parent *TreeNode, gvr, id string, optional *bool) {
} }
} }
func validate(f dao.Factory, n *TreeNode, _ *bool) { func validate(f dao.Factory, n *TreeNode, optional *bool) {
res, err := f.Get(n.GVR, n.ID, false, labels.Everything()) res, err := f.Get(n.GVR, n.ID, false, labels.Everything())
if err != nil || res == nil { if err != nil || res == nil {
log.Warn().Err(err).Msgf("Missing ref %q::%q", n.GVR, n.ID) if optional == nil || !*optional {
n.Extras[StatusKey] = MissingRefStatus log.Warn().Err(err).Msgf("Missing ref %q::%q", n.GVR, n.ID)
n.Extras[StatusKey] = MissingRefStatus
}
return return
} }
n.Extras[StatusKey] = OkStatus n.Extras[StatusKey] = OkStatus

View File

@ -54,7 +54,7 @@ func TestCORefs(t *testing.T) {
co: render.ContainerRes{Container: makeCMContainer("c1", true)}, co: render.ContainerRes{Container: makeCMContainer("c1", true)},
level1: 1, level1: 1,
level2: 1, level2: 1,
e: xray.MissingRefStatus, e: xray.OkStatus,
}, },
"cm_doubleRef": { "cm_doubleRef": {
co: render.ContainerRes{Container: makeDoubleCMKeysContainer("c1", false)}, co: render.ContainerRes{Container: makeDoubleCMKeysContainer("c1", false)},
@ -72,7 +72,7 @@ func TestCORefs(t *testing.T) {
co: render.ContainerRes{Container: makeSecContainer("c1", true)}, co: render.ContainerRes{Container: makeSecContainer("c1", true)},
level1: 1, level1: 1,
level2: 1, level2: 1,
e: xray.MissingRefStatus, e: xray.OkStatus,
}, },
"envFrom_optional": { "envFrom_optional": {
co: render.ContainerRes{Container: makeCMEnvFromContainer("c1", false)}, co: render.ContainerRes{Container: makeCMEnvFromContainer("c1", false)},

View File

@ -114,13 +114,13 @@ func (*Pod) podVolumeRefs(f dao.Factory, parent *TreeNode, ns string, vv []v1.Vo
for _, v := range vv { for _, v := range vv {
sec := v.VolumeSource.Secret sec := v.VolumeSource.Secret
if sec != nil { if sec != nil {
addRef(f, parent, "v1/secrets", client.FQN(ns, sec.SecretName), nil) addRef(f, parent, "v1/secrets", client.FQN(ns, sec.SecretName), sec.Optional)
continue continue
} }
cm := v.VolumeSource.ConfigMap cm := v.VolumeSource.ConfigMap
if cm != nil { if cm != nil {
addRef(f, parent, "v1/configmaps", client.FQN(ns, cm.LocalObjectReference.Name), nil) addRef(f, parent, "v1/configmaps", client.FQN(ns, cm.LocalObjectReference.Name), cm.Optional)
continue continue
} }

View File

@ -28,6 +28,12 @@ func TestPodRender(t *testing.T) {
level2: 2, level2: 2,
status: xray.OkStatus, status: xray.OkStatus,
}, },
"cilium": {
file: "cilium",
level1: 1,
level2: 3,
status: xray.OkStatus,
},
} }
var re xray.Pod var re xray.Pod

View File

@ -0,0 +1,285 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"creationTimestamp": "2020-01-21T00:06:31Z",
"generateName": "cilium-operator-55658fb5c4-",
"labels": {
"io.cilium/app": "operator",
"name": "cilium-operator",
"pod-template-hash": "55658fb5c4"
},
"name": "cilium-operator-55658fb5c4-rxtnl",
"namespace": "kube-system",
"ownerReferences": [
{
"apiVersion": "apps/v1",
"blockOwnerDeletion": true,
"controller": true,
"kind": "ReplicaSet",
"name": "cilium-operator-55658fb5c4",
"uid": "aa49a24b-e5b7-4349-88ce-c275ee36097c"
}
],
"resourceVersion": "1255",
"selfLink": "/api/v1/namespaces/kube-system/pods/cilium-operator-55658fb5c4-rxtnl",
"uid": "db060299-45c3-40c6-9a87-d8643f0d51e2"
},
"spec": {
"containers": [
{
"args": [
"--debug=$(CILIUM_DEBUG)",
"--identity-allocation-mode=$(CILIUM_IDENTITY_ALLOCATION_MODE)"
],
"command": [
"cilium-operator"
],
"env": [
{
"name": "CILIUM_K8S_NAMESPACE",
"valueFrom": {
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "metadata.namespace"
}
}
},
{
"name": "K8S_NODE_NAME",
"valueFrom": {
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "spec.nodeName"
}
}
},
{
"name": "CILIUM_DEBUG",
"valueFrom": {
"configMapKeyRef": {
"key": "debug",
"name": "cilium-config",
"optional": true
}
}
},
{
"name": "CILIUM_CLUSTER_NAME",
"valueFrom": {
"configMapKeyRef": {
"key": "cluster-name",
"name": "cilium-config",
"optional": true
}
}
},
{
"name": "CILIUM_CLUSTER_ID",
"valueFrom": {
"configMapKeyRef": {
"key": "cluster-id",
"name": "cilium-config",
"optional": true
}
}
},
{
"name": "CILIUM_IPAM",
"valueFrom": {
"configMapKeyRef": {
"key": "ipam",
"name": "cilium-config",
"optional": true
}
}
},
{
"name": "CILIUM_DISABLE_ENDPOINT_CRD",
"valueFrom": {
"configMapKeyRef": {
"key": "disable-endpoint-crd",
"name": "cilium-config",
"optional": true
}
}
},
{
"name": "CILIUM_KVSTORE",
"valueFrom": {
"configMapKeyRef": {
"key": "kvstore",
"name": "cilium-config",
"optional": true
}
}
},
{
"name": "CILIUM_KVSTORE_OPT",
"valueFrom": {
"configMapKeyRef": {
"key": "kvstore-opt",
"name": "cilium-config",
"optional": true
}
}
},
{
"name": "AWS_ACCESS_KEY_ID",
"valueFrom": {
"secretKeyRef": {
"key": "AWS_ACCESS_KEY_ID",
"name": "cilium-aws",
"optional": true
}
}
},
{
"name": "AWS_SECRET_ACCESS_KEY",
"valueFrom": {
"secretKeyRef": {
"key": "AWS_SECRET_ACCESS_KEY",
"name": "cilium-aws",
"optional": true
}
}
},
{
"name": "AWS_DEFAULT_REGION",
"valueFrom": {
"secretKeyRef": {
"key": "AWS_DEFAULT_REGION",
"name": "cilium-aws",
"optional": true
}
}
},
{
"name": "CILIUM_IDENTITY_ALLOCATION_MODE",
"valueFrom": {
"configMapKeyRef": {
"key": "identity-allocation-mode",
"name": "cilium-config",
"optional": true
}
}
}
],
"image": "docker.io/cilium/operator:v1.6.5",
"imagePullPolicy": "IfNotPresent",
"livenessProbe": {
"failureThreshold": 3,
"httpGet": {
"path": "/healthz",
"port": 9234,
"scheme": "HTTP"
},
"initialDelaySeconds": 60,
"periodSeconds": 10,
"successThreshold": 1,
"timeoutSeconds": 3
},
"name": "cilium-operator",
"resources": {},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "cilium-operator-token-r9t5t",
"readOnly": true
}
]
}
],
"dnsPolicy": "ClusterFirst",
"enableServiceLinks": true,
"hostNetwork": true,
"nodeName": "minikube",
"priority": 0,
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"serviceAccount": "cilium-operator",
"serviceAccountName": "cilium-operator",
"terminationGracePeriodSeconds": 30,
"tolerations": [
{
"effect": "NoExecute",
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"tolerationSeconds": 300
},
{
"effect": "NoExecute",
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"tolerationSeconds": 300
}
],
"volumes": [
{
"name": "cilium-operator-token-r9t5t",
"secret": {
"defaultMode": 420,
"secretName": "cilium-operator-token-r9t5t"
}
}
]
},
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2020-01-21T00:07:39Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2020-01-21T00:07:47Z",
"status": "True",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2020-01-21T00:07:47Z",
"status": "True",
"type": "ContainersReady"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2020-01-21T00:07:39Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"containerID": "docker://9bc42a0d9395adafd9f8d922350c9029f8fa234060df9b03dd5e256804613f68",
"image": "cilium/operator:v1.6.5",
"imageID": "docker-pullable://cilium/operator@sha256:bcf273e7af15e7a0c9eb8df2f87fc81fe56323217ec8b2b35cd9cd5115920055",
"lastState": {},
"name": "cilium-operator",
"ready": true,
"restartCount": 0,
"started": true,
"state": {
"running": {
"startedAt": "2020-01-21T00:07:46Z"
}
}
}
],
"hostIP": "192.168.64.7",
"phase": "Running",
"podIP": "192.168.64.7",
"podIPs": [
{
"ip": "192.168.64.7"
}
],
"qosClass": "BestEffort",
"startTime": "2020-01-21T00:07:39Z"
}
}