Skip to content

Commit

Permalink
Add context alerting by colorizing it (#34)
Browse files Browse the repository at this point in the history
* feat(segment): add segment color for specific context

Signed-off-by: imjoseangel <josea.munoz@gmail.com>
  • Loading branch information
imjoseangel authored Jan 2, 2021
1 parent e1d86d7 commit 992e707
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 36 deletions.
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ repos:
types: [text]
exclude: ^ci/ansi$ # 3rd-party script

- id: pylint
name: pylint
entry: pylint
language: python
types: [python]
exclude: tests/functional/|tests/input|tests/extensions/data|tests/regrtest_data/|tests/data/|doc/

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: master
hooks:
Expand Down
47 changes: 33 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

![CodeQL](https://github.com/imjoseangel/powerline-k8sstatus/workflows/CodeQL/badge.svg) [![codecov](https://codecov.io/gh/imjoseangel/powerline-k8sstatus/branch/devel/graph/badge.svg)](https://codecov.io/gh/imjoseangel/powerline-k8sstatus) ![Python package](https://github.com/imjoseangel/powerline-k8sstatus/workflows/Python%20package/badge.svg)


A [Powerline][1] segment for showing the status of current Kubernetes context.

By [imjoseangel][2]
Expand All @@ -14,14 +13,11 @@ It will show any or all of:
* context name
* namespace


You can also:

* Toggle on or off the powerline-k8sstatus segment using an environment variable which can easily be mapped to a function in your ~/.profile file.

(On development):

* Define certain namespaces and/or contexts to be colored differently for alerting purposes. For instance, you can have your production namespaces or context showing up in bright red.
* Define certain contexts to be colored differently for alerting purposes. For instance, you can have your production context showing up in bright red.

## Requirements

Expand All @@ -43,9 +39,26 @@ for example in `.config/powerline/colorschemes/default.json`:
```json
{
"groups": {
"k8sstatus": {"fg": "white", "bg": "solarized:red", "attrs": []},
"k8sstatus_namespace": {"fg": "gray10", "bg": "darkestblue", "attrs": []},
"k8sstatus:divider": {"fg": "white", "bg": "mediumorange", "attrs": []}
"k8sstatus": {
"fg": "brightestorange",
"bg": "gray2",
"attrs": []
},
"k8sstatus:alert": {
"fg": "white",
"bg": "solarized:red",
"attrs": []
},
"k8sstatus_namespace": {
"fg": "gray10",
"bg": "darkestblue",
"attrs": []
},
"k8sstatus:divider": {
"fg": "white",
"bg": "mediumorange",
"attrs": []
}
}
}
```
Expand All @@ -55,14 +68,20 @@ for example in `.config/powerline/themes/shell/default.json`:

```json
{
"function": "powerline_k8sstatus.k8sstatus",
"priority": 50,
"args": {
"show_namespace": true
}
}
"function": "powerline_k8sstatus.k8sstatus",
"priority": 50,
"args": {
"show_namespace": true,
"alert_context": [
"minikube",
"production"
]
}
},
```

Context names added to the `alert_context` arguments will be outlined in the segment by a different colour.

Reload powerline running `powerline-daemon --replace` to load the new settings.

By default **powerline-k8sstatus** will display the Kubernetes status segment context. It can be disabled temporarily if the environment variable `POWERLINE_K8SSTATUS` is set to `0`. One way to do this would be with a simple function, such as putting this `k8sstatus` function in your `~/.bash_profile`:
Expand Down
18 changes: 13 additions & 5 deletions powerline_k8sstatus/segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,24 @@ class K8SStatusSegment(Segment):
divider_highlight_group = None

@staticmethod
def build_segments(context, namespace):
def build_segments(context, namespace, alert):
segments = [{'contents': (u'\U00002388 {}').format(
context), 'highlight_groups': ['k8sstatus']}]
context), 'highlight_groups': [alert]}]

if namespace and namespace.lower() != 'default':
segments.append({
'contents': namespace,
'highlight_groups': ['k8sstatus_namespace', 'k8sstatus'],
'highlight_groups': ['k8sstatus_namespace', alert],
'divider_highlight_group': 'k8sstatus:divider'
})

return segments

def __call__(self, pl, segment_info, create_watcher, show_namespace=False):
def __call__(self, pl, segment_info, create_watcher=None, alert_context: list = None,
show_namespace=False):

if alert_context is None:
alert_context = []

try:
if segment_info['environ'].get('POWERLINE_K8SSTATUS') == "0":
Expand All @@ -48,6 +52,10 @@ def __call__(self, pl, segment_info, create_watcher, show_namespace=False):
return

context = active_context['name']
contextstatus = "k8sstatus"

if context in alert_context:
contextstatus = "k8sstatus:alert"

if show_namespace:
try:
Expand All @@ -57,7 +65,7 @@ def __call__(self, pl, segment_info, create_watcher, show_namespace=False):
else:
namespace = 'default'

return self.build_segments(context, namespace)
return self.build_segments(context, namespace, contextstatus)


k8sstatus = with_docstring(
Expand Down
Binary file modified screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 26 additions & 17 deletions tests/test_powerlinek8sstatus.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,49 +76,49 @@ def setup_nonemocked_context(monkeypatch):

@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_namespacemocked_context', 'expected_symbol')
def test_cluster_notnamespace(pl, segment_info, expected_symbol):
def test_context_notnamespace(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output == [expected_symbol]


@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_namespacemocked_context', 'expected_symbol')
def test_cluster_namespace(pl, segment_info, expected_symbol):
def test_context_namespace(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='', show_namespace=True)
pl=pl, segment_info=segment_info, show_namespace=True)
assert output == [expected_symbol, EXPECTED_NAMESPACE]


@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_mocked_context', 'expected_symbol')
def test_cluster_notnamespacedefault(pl, segment_info, expected_symbol):
def test_context_notnamespacedefault(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output == [expected_symbol]


@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_mocked_context', 'expected_symbol')
def test_cluster_notnamespacedefaulttrue(pl, segment_info, expected_symbol):
def test_context_notnamespacedefaulttrue(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='', show_namespace=True)
pl=pl, segment_info=segment_info, show_namespace=True)
assert output == [expected_symbol]


@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_notnamespacemocked_context', 'expected_symbol')
def test_cluster_notnamespacdefined(pl, segment_info, expected_symbol):
def test_context_notnamespacdefined(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output == [expected_symbol]


@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_notnamespacemocked_context', 'expected_symbol')
def test_cluster_notnamespacedefinedtrue(pl, segment_info, expected_symbol):
def test_context_notnamespacedefinedtrue(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='', show_namespace=True)
pl=pl, segment_info=segment_info, show_namespace=True)
assert output == [expected_symbol]


Expand All @@ -127,7 +127,7 @@ def test_cluster_notnamespacedefinedtrue(pl, segment_info, expected_symbol):
def test_envvar_notzero(pl, expected_symbol):
segment_info = {'environ': {'POWERLINE_K8SSTATUS': '1'}}
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output == [expected_symbol]


Expand All @@ -136,7 +136,7 @@ def test_envvar_notzero(pl, expected_symbol):
def test_envvar_notzeroempty(pl, expected_symbol):
segment_info = {'environ': {}}
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output == [expected_symbol]


Expand All @@ -145,21 +145,30 @@ def test_envvar_notzeroempty(pl, expected_symbol):
def test_envvar_zero(pl, expected_symbol):
segment_info = {'environ': {'POWERLINE_K8SSTATUS': '0'}}
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output is None


@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_mocked_context')
def test_no_items(pl, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output is None


@pytest.mark.parametrize('expected_symbol', ['k8sstatus'], indirect=True)
@pytest.mark.usefixtures('setup_nonemocked_context', 'expected_symbol')
def test_none_items(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info, create_watcher='')
pl=pl, segment_info=segment_info)
assert output is None


@pytest.mark.parametrize('expected_symbol', ['k8sstatus:alert'], indirect=True)
@pytest.mark.usefixtures('setup_mocked_context', 'expected_symbol')
def test_context_defaultalert(pl, segment_info, expected_symbol):
output = powerlinek8s.k8sstatus(
pl=pl, segment_info=segment_info,
alert_context=['minikube'])
assert output == [expected_symbol]

0 comments on commit 992e707

Please sign in to comment.