We have clarified our Privacy Statement even further. Please have a look at our changes.
Browse Source

CLI option --default-custom-columns

tags/19.8.5
Henning Jacobs 2 months ago
parent
commit
d7aa042aa0
5 changed files with 60 additions and 12 deletions
  1. +1
    -1
      .flake8
  2. +11
    -2
      docs/customization.rst
  3. +14
    -0
      kube_web/main.py
  4. +22
    -9
      kube_web/web.py
  5. +12
    -0
      tests/unit/test_main.py

+ 1
- 1
.flake8 View File

@@ -1,3 +1,3 @@
[flake8]
max-line-length=200
max-line-length=240
ignore=E722,W503

+ 11
- 2
docs/customization.rst View File

@@ -32,8 +32,8 @@ You can use :ref:`html-templates` for further customization of the sidebar (e.g.

.. _label-columns:

Label Columns
=============
Label & Custom Columns
======================

Most organizations have a standard set of labels for Kubernetes resources, e.g. all pods might have "app" and "version" labels.
You can instruct Kubernetes Web View to show these labels as columns for the respective resource types via the ``--default-label-columns`` command line option.
@@ -54,6 +54,15 @@ You can hide existing columns via the ``--default-hidden-columns`` command line

--default-hidden-columns=pods=Nominated Node,Readiness Gates

Arbitrary custom columns can be defined with `JMESPath <http://jmespath.org>`_ expressions, e.g. add a column "Images" for pods and the column "Strategy" for deployments:

.. code-block:: bash

--default-custom-columns=pods=Images=spec.containers[*].image;;deployments=Strategy=spec.strategy

Multiple column definitions are separated by a single semicolon (";") whereas multiple different entries for different resource types are separated by two semicolons (";;").
Please be aware that custom columns require one additional Kubernetes API call per listing.


.. _external-links:


+ 14
- 0
kube_web/main.py View File

@@ -34,6 +34,14 @@ def key_value_pairs(value):
return data


def key_value_pairs2(value):
data = {}
for kv_pair in value.split(";;"):
key, sep, value = kv_pair.partition("=")
data[key] = value
return data


def key_value_list_pairs(value):
data = {}
for kv_pair in value.split(";"):
@@ -152,6 +160,12 @@ def parse_args(argv=None):
help="Comma-separated list of columns to hide per resource type; multiple entries separated by semicolon, e.g. 'pods=Nominated Node,Readiness Gates,version;deployments=Selector'",
default={},
)
parser.add_argument(
"--default-custom-columns",
type=key_value_pairs2,
help="Semicolon-separated list of Column=<expresion> pairs per resource type; multiple entries separated by two semicolons, e.g. 'pods=Images=spec.containers[*].image;;deployments=Replicas=spec.replicas'",
default={},
)
parser.add_argument(
"--oauth2-authorized-hook",
type=coroutine_function,

+ 22
- 9
kube_web/web.py View File

@@ -361,6 +361,7 @@ async def join_custom_columns(
table,
namespace: str,
is_all_namespaces: bool,
custom_columns_param: str,
params: dict,
):
if not table.rows:
@@ -371,7 +372,7 @@ async def join_custom_columns(

custom_column_names = []
custom_columns = {}
for part in filter(None, params.get("customcols", "").split(";")):
for part in filter(None, custom_columns_param.split(";")):
name, _, spec = part.partition("=")
custom_column_names.append(name)
custom_columns[name] = jmespath.compile(spec)
@@ -532,12 +533,13 @@ async def do_get_resource_list(
logger.debug(f"Failed to list {_type} in {_cluster.name}: {e}")
error = {"cluster": _cluster, "resource_type": _type, "exception": e}
else:
config = request.app[CONFIG]
# table.rows might be None, e.g. for "csinodes"
if table.rows is None:
table.obj["rows"] = []
label_columns = params.get("labelcols") or request.app[
CONFIG
].default_label_columns.get(_type)
label_columns = params.get("labelcols") or config.default_label_columns.get(
_type
)
add_label_columns(table, label_columns)
filter_table(table, params.get("filter"))

@@ -547,12 +549,23 @@ async def do_get_resource_list(
request, session, _cluster, table, namespace, is_all_namespaces, params
)

await join_custom_columns(
request, session, _cluster, table, namespace, is_all_namespaces, params
custom_columns = params.get("customcols") or config.default_custom_columns.get(
_type
)
if custom_columns:
await join_custom_columns(
request,
session,
_cluster,
table,
namespace,
is_all_namespaces,
custom_columns,
params,
)
hidden_columns = params.get("hidecols") or config.default_hidden_columns.get(
_type
)
hidden_columns = params.get("hidecols") or request.app[
CONFIG
].default_hidden_columns.get(_type)
remove_columns(table, hidden_columns)
guess_column_classes(table)
sort_table(table, params.get("sort"))

+ 12
- 0
tests/unit/test_main.py View File

@@ -12,3 +12,15 @@ def test_parse_sidebar_resource_types():
"Main": ["nodes", "pods"],
"CRDs": ["foos", "bars"],
}


def test_parse_default_custom_columns():
args = parse_args(
[
"--default-custom-columns=pods=A=metadata.name;B=spec;;deployments=Strategy=spec.strategy"
]
)
assert args.default_custom_columns == {
"pods": "A=metadata.name;B=spec",
"deployments": "Strategy=spec.strategy",
}

Loading…
Cancel
Save