Fix Beryllium xray core. fix #500
parent
f74e754f58
commit
8a0b78a77b
|
|
@ -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)
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)},
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue