From d2ffd79c2ca878f83316b3c860e40ba3fd0caf03 Mon Sep 17 00:00:00 2001 From: Henning Seljenes Date: Sat, 20 Aug 2022 21:31:42 -0400 Subject: [PATCH] Initial commit --- .gitignore | 6 +++++ LICENSE | 21 ++++++++++++++++++ README.md | 3 +++ qwota_cli.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + setup.py | 28 ++++++++++++++++++++++++ 6 files changed, 116 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 qwota_cli.py create mode 100644 requirements.txt create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4e8b110 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__ +build +dist +venv +*.egg-info +.idea \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..813e858 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Henning Seljenes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8e1c9d0 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +Quickly check AppliedClusterResourceQuota. + +Login to a cluster on the command line using kubectl/oc then run qwota. \ No newline at end of file diff --git a/qwota_cli.py b/qwota_cli.py new file mode 100644 index 0000000..5baeca1 --- /dev/null +++ b/qwota_cli.py @@ -0,0 +1,57 @@ +import re +from kubernetes import config +from openshift.dynamic import DynamicClient + + +def cli(): + k8s = config.new_client_from_config(context=current_context()['name']) + oc = DynamicClient(k8s) + v1_acrq = oc.resources.get(api_version='v1', kind='AppliedClusterResourceQuota') + acrq = v1_acrq.get(namespace=current_namespace(), pretty=False) + for acrq_item in acrq.get('items'): + if '--terminating' in acrq_item.get('metadata').get('name'): + continue + status = acrq_item.get('status').get('total') + for quota_key in status.get('hard').keys(): + used = status.get('used').get(quota_key) + hard = status.get('hard').get(quota_key) + used_int = int_value(used) + hard_int = int_value(hard) + if used_int == 0: + continue + + usage_str = graph(used_int, hard_int) + + print(f'{usage_str} {quota_key} ({used} of {hard})') + + +def current_context(): + return config.list_kube_config_contexts()[1] + + +def current_namespace(): + return current_context()['context']['namespace'] + + +def int_value(value): + only_digits = int(re.sub('[^\d]', '', value)) + if 'k' in value: + return only_digits * 1000 + if 'Gi' in value: + return only_digits * 1000 + if 'Mi' in value: + return only_digits + if 'm' in value: + return only_digits / 1000 + return int(only_digits) + + +def graph(used, hard): + usage_p = round((used / hard) * 100) + usage = '.' * (round(usage_p / 10)*2) + blanks = ' ' * (20 - len(usage)) + return f'|{usage}{blanks}|' + + +if __name__ == '__main__': + cli() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e3a2108 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +openshift \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..d867f1a --- /dev/null +++ b/setup.py @@ -0,0 +1,28 @@ +from setuptools import setup, find_packages +with open("README.md", "r", encoding="utf-8") as fh: + long_description = fh.read() +with open("requirements.txt", "r", encoding="utf-8") as fh: + requirements = fh.read() +setup( + name = 'qwota', + version = '0.0.1', + author = 'Henning Seljenes', + author_email = 'henning.seljenes@gmail.com', + license = 'MIT', + description = 'Tool for checking OpenShift AppliedClusterQuotaResource', + long_description = long_description, + long_description_content_type = "text/markdown", + url = '', + py_modules = ['qwota'], + packages = find_packages(), + install_requires = [requirements], + python_requires='>=3', + classifiers=[ + "Programming Language :: Python", + "Operating System :: OS Independent", + ], + entry_points = ''' + [console_scripts] + qwota=qwota_cli:cli + ''' +) \ No newline at end of file