From 6d3ebf4dc62c3d9ee762a4772ac3521abebee59a Mon Sep 17 00:00:00 2001 From: Mayank Patel Date: Wed, 4 Oct 2023 07:55:40 -0400 Subject: [PATCH] Add Node Interface metrics exporter app to StarlingX This commit contains integration of node interface metrics microservice ,python plugin and custom helm chart for metrics exporter app. As per requirement node interface metrics pod run on worker node. This builds a deb format package that contains the .tgz file that can be installed on the controller using the system application tool. Test plan: PASSED: Build process is successful with creation of debian package. PASSED: Extract the content of the debian package and check if the helm chart tar file is present. PASSED: AIO-SX app successfully uploaded, applied, removed and deleted using the 'system application' commands. PASSED: AIO-DX app successfully uploaded, applied, removed and deleted using the 'system application' commands. PASSED: STANDARD app successfully uploaded, applied, removed and deleted using the 'system application' commands. Verified pods are running on compute node only. PASSED: After delete All the helm chart has been removed as well all K8s resources. PASSED: Update application version from 1.0-1 to 1.0-2 Story: 2010918 Task: 48885 Change-Id: I93d7494b04be16c808a6ad6af115659f8298ee10 Signed-off-by: Mayank Patel --- .zuul.yaml | 41 ++++ bindep.txt | 10 + .../.gitignore | 35 ++++ .../README.rst | 4 +- .../common/constants.py | 7 +- .../helm/node_interface_metrics_exporter.py | 65 +------ ...fecycle_node_interface_metrics_exporter.py | 157 ++++++++++++++- .../test_node_interface_metrics_exporter.py | 2 +- .../tests/test_plugins.py | 2 +- .../pylint.rc | 12 +- .../setup.cfg | 2 +- .../test-requirements.txt | 2 +- .../tox.ini | 179 ++++++++++++++++++ .../debian/deb_folder/rules | 6 +- .../README | 12 -- .../files/metadata.yaml | 4 +- .../fluxcd-manifests/base/kustomization.yaml | 1 - .../nime-static-overrides.yaml | 6 + .../helm-charts/Makefile | 28 +-- .../helm-charts/README.md | 45 +++++ .../templates/daemonset.yaml | 55 ++++++ .../templates/role.yaml | 24 +++ .../templates/rolebinding.yaml | 21 ++ .../values.yaml | 14 ++ test-requirements.txt | 2 +- tox.ini | 17 +- 26 files changed, 644 insertions(+), 109 deletions(-) create mode 100644 bindep.txt create mode 100644 python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/.gitignore create mode 100644 python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/tox.ini delete mode 100644 stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/README create mode 100644 stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/README.md create mode 100644 stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/daemonset.yaml create mode 100644 stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/role.yaml create mode 100644 stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/rolebinding.yaml create mode 100644 stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/values.yaml diff --git a/.zuul.yaml b/.zuul.yaml index 7ccbd0a..2537304 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -3,6 +3,47 @@ check: jobs: - openstack-tox-linters + - k8sapp-node-interface-metrics-exporter-tox-py39 + - k8sapp-node-interface-metrics-exporter-tox-pylint gate: jobs: - openstack-tox-linters + - k8sapp-node-interface-metrics-exporter-tox-py39 + - k8sapp-node-interface-metrics-exporter-tox-pylint + +- job: + name: k8sapp-node-interface-metrics-exporter-tox-py39 + parent: openstack-tox-py39 + description: | + Run py39 test for k8sapp_node_interface_metrics_exporter + nodeset: debian-bullseye + required-projects: + - starlingx/config + - starlingx/fault + - starlingx/update + - starlingx/utilities + - starlingx/root + files: + - python3-k8sapp-node-interface-metrics-exporter/* + vars: + tox_extra_args: -c python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/tox.ini + tox_constraints_file: '{{ ansible_user_dir }}/src/opendev.org/starlingx/root/build-tools/requirements/debian/upper-constraints.txt' + +- job: + name: k8sapp-node-interface-metrics-exporter-tox-pylint + parent: tox + description: | + Run pylint test for k8sapp_node_interface_metrics_exporter + nodeset: debian-bullseye + required-projects: + - starlingx/config + - starlingx/fault + - starlingx/update + - starlingx/utilities + - starlingx/root + files: + - python3-k8sapp-node-interface-metrics-exporter/* + vars: + tox_envlist: pylint + tox_extra_args: -c python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/tox.ini + tox_constraints_file: '{{ ansible_user_dir }}/src/opendev.org/starlingx/root/build-tools/requirements/debian/upper-constraints.txt' diff --git a/bindep.txt b/bindep.txt new file mode 100644 index 0000000..3ffe69f --- /dev/null +++ b/bindep.txt @@ -0,0 +1,10 @@ +# This is a cross-platform list tracking distribution packages needed for install and tests; +# see https://docs.openstack.org/infra/bindep/ for additional information. + +libffi-dev [platform:dpkg] +libldap2-dev [platform:dpkg] +libxml2-dev [platform:dpkg] +libxslt1-dev [platform:dpkg] +libsasl2-dev [platform:dpkg] +libffi-devel [platform:rpm] +python3-all-dev [platform:dpkg] diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/.gitignore b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/.gitignore new file mode 100644 index 0000000..e39c1b7 --- /dev/null +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/.gitignore @@ -0,0 +1,35 @@ +# Compiled files +*.py[co] +*.a +*.o +*.so + +# Sphinx +_build +doc/source/api/ + +# Packages/installer info +*.egg +*.egg-info +dist +build +eggs +parts +var +sdist +develop-eggs +.installed.cfg + +# Other +*.DS_Store +.stestr +.testrepository +.tox +.venv +.*.swp +.coverage +bandit.xml +cover +AUTHORS +ChangeLog +*.sqlite \ No newline at end of file diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/README.rst b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/README.rst index 8cac562..23b4a03 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/README.rst +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/README.rst @@ -3,5 +3,5 @@ k8sapp-node-interface-merics-exporter This project contains StarlingX Kubernetes application specific python plugins for Node Interface Metrics Exporter. These plugins are required to integrate -the Power Metrics application into the StarlingX application framework and to -support the various StarlingX deployments. +the Node Metrics Exporter application into the StarlingX application framework +and to support the various StarlingX deployments. diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/common/constants.py b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/common/constants.py index 0fa8aac..41140dd 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/common/constants.py +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/common/constants.py @@ -5,10 +5,13 @@ # # Namespace to deploy the application -HELM_NS_PM = 'node-interface-metrics-exporter' +HELM_NS_METRICS_EXPORTER = 'node-interface-metrics-exporter' # Application Name -HELM_APP_PM = 'node-interface-metrics-exporter' +HELM_APP_METRICS_EXPORTER = 'node-interface-metrics-exporter' + +# Chart Name +HELM_CHART_METRICS_EXPORTER = 'node-interface-metrics-exporter' # Application component label HELM_LABEL_PARAMETER = 'podLabels' diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/helm/node_interface_metrics_exporter.py b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/helm/node_interface_metrics_exporter.py index bec4399..42e1161 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/helm/node_interface_metrics_exporter.py +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/helm/node_interface_metrics_exporter.py @@ -4,68 +4,42 @@ # SPDX-License-Identifier: Apache-2.0 # +from oslo_log import log as logging + from k8sapp_node_interface_metrics_exporter.common import constants as app_constants -from oslo_log import log as logging -from sysinv.common import constants from sysinv.common import exception -from sysinv.common import kubernetes -from sysinv.db import api as sys_dbapi from sysinv.helm import base LOG = logging.getLogger(__name__) -class NodeInterfaceMetricsExporterHelm(base.FluxCDBaseHelm): + +class NodeInterfaceMetricsExporterHelm(base.BaseHelm): """Class to encapsulate helm operations for the metrics exporter chart.""" - SUPPORTED_NAMESPACES = base.FluxCDBaseHelm.SUPPORTED_NAMESPACES + \ - [app_constants.HELM_NS_PM] + SUPPORTED_NAMESPACES = base.BaseHelm.SUPPORTED_NAMESPACES + \ + [app_constants.HELM_NS_METRICS_EXPORTER] SUPPORTED_APP_NAMESPACES = { - app_constants.HELM_APP_PM: SUPPORTED_NAMESPACES + app_constants.HELM_APP_METRICS_EXPORTER: SUPPORTED_NAMESPACES } - SERVICE_NAME = app_constants.HELM_APP_PM + SERVICE_NAME = app_constants.HELM_APP_METRICS_EXPORTER SUPPORTED_COMPONENT_OVERRIDES = [ app_constants.HELM_COMPONENT_LABEL_VALUE_PLATFORM, app_constants.HELM_COMPONENT_LABEL_VALUE_APPLICATION ] - DEFAULT_AFFINITY = app_constants.HELM_COMPONENT_LABEL_VALUE_PLATFORM + CHART = app_constants.HELM_CHART_METRICS_EXPORTER def get_namespaces(self): return self.SUPPORTED_NAMESPACES def get_overrides(self, namespace=None): - dbapi_instance = dbapi.get_instance() - db_app = dbapi_instance.kube_app_get(app_constants.HELM_APP_PM) - - # User chart overrides - chart_overrides = self._get_user_helm_overrides( - dbapi_instance, - db_app, - app_constants.HELM_NS_PM, - 'user_overrides') - - user_affinity = chart_overrides.get(app_constants.HELM_COMPONENT_LABEL, - self.DEFAULT_AFFINITY) - - if user_affinity in self.SUPPORTED_COMPONENT_OVERRIDES: - affinity = user_affinity - else: - LOG.warn(f"User override value {user_affinity} " - f"for {app_constants.HELM_COMPONENT_LABEL} is invalid, " - f"using default value {self.DEFAULT_AFFINITY}") - affinity = self.DEFAULT_AFFINITY - overrides = { - app_constants.HELM_NS_PM: { - app_constants.HELM_LABEL_PARAMETER: { - app_constants.HELM_COMPONENT_LABEL: affinity - } - } + app_constants.HELM_NS_METRICS_EXPORTER: {} } if namespace in self.SUPPORTED_NAMESPACES: @@ -75,22 +49,3 @@ class NodeInterfaceMetricsExporterHelm(base.FluxCDBaseHelm): raise exception.InvalidHelmNamespace(chart=self.CHART, namespace=namespace) return overrides - - @staticmethod - def _get_user_helm_overrides(dbapi_instance, app, chart, namespace, - type_of_overrides): - """Helper function for querying helm overrides from db.""" - helm_overrides = {} - try: - overrides = dbapi_instance.helm_override_get( - app_id=app.id, - name=chart, - namespace=namespace, - )[type_of_overrides] - - if isinstance(overrides, str): - helm_overrides = yaml.safe_load(overrides) - except exception.HelmOverrideNotFound: - LOG.debug("Overrides for this chart not found, nothing to be done.") - return helm_overrides - diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/lifecycle/lifecycle_node_interface_metrics_exporter.py b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/lifecycle/lifecycle_node_interface_metrics_exporter.py index f3bc94b..67c44bd 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/lifecycle/lifecycle_node_interface_metrics_exporter.py +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/lifecycle/lifecycle_node_interface_metrics_exporter.py @@ -10,12 +10,165 @@ from oslo_log import log as logging -from sysinv.common import constants as sysinv_constants +import yaml + +from sysinv.common import constants as inv_constants +from sysinv.common import exception +from sysinv.common import kubernetes +from sysinv.common import utils as cutils from sysinv.helm import lifecycle_base as base -from sysinv.helm import lifecycle_utils +from sysinv.helm.lifecycle_constants import LifecycleConstants from k8sapp_node_interface_metrics_exporter.common import constants as app_constants LOG = logging.getLogger(__name__) +class NodeInterfaceMetricsExporterAppLifecycleOperator(base.AppLifecycleOperator): + def app_lifecycle_actions( + self, context, conductor_obj, app_op, app, hook_info + ): + """Perform lifecycle actions for an operation + + :param context: request context, can be None + :param conductor_obj: conductor object, can be None + :param app_op: AppOperator object + :param app: AppOperator.Application object + :param hook_info: LifecycleHookInfo object + + """ + if hook_info.lifecycle_type == inv_constants.APP_LIFECYCLE_TYPE_FLUXCD_REQUEST: + if hook_info.operation == inv_constants.APP_APPLY_OP: + if hook_info.relative_timing == inv_constants.APP_LIFECYCLE_TIMING_POST: + return self.post_apply(app_op, app, hook_info) + + if hook_info.lifecycle_type == inv_constants.APP_LIFECYCLE_TYPE_OPERATION: + if hook_info.operation == inv_constants.APP_REMOVE_OP: + if hook_info.relative_timing == inv_constants.APP_LIFECYCLE_TIMING_POST: + return self.post_remove(app) + super( + NodeInterfaceMetricsExporterAppLifecycleOperator, self + ).app_lifecycle_actions(context, conductor_obj, app_op, app, hook_info) + + def post_apply(self, app_op, app, hook_info): + if LifecycleConstants.EXTRA not in hook_info: + raise exception.LifecycleMissingInfo("Missing {}".format(LifecycleConstants.EXTRA)) + if LifecycleConstants.RETURN_CODE not in hook_info[LifecycleConstants.EXTRA]: + raise exception.LifecycleMissingInfo( + "Missing {} {}".format(LifecycleConstants.EXTRA, LifecycleConstants.RETURN_CODE)) + + # raise a specific exception to be caught by the + # retry decorator and attempt a re-apply + if not hook_info[LifecycleConstants.EXTRA][LifecycleConstants.RETURN_CODE] and \ + not app_op.is_app_aborted(app.name): + LOG.info("%s app failed applying. Retrying." % str(app.name)) + raise exception.ApplicationApplyFailure(name=app.name) + + dbapi_instance = app_op._dbapi + db_app_id = dbapi_instance.kube_app_get(app.name).id + + client_core = app_op._kube._get_kubernetesclient_core() + component_constant = ( + app_constants.HELM_COMPONENT_LABEL + ) + + # chart overrides + chart_overrides = self._get_helm_user_overrides( + dbapi_instance, db_app_id + ) + + override_label = {} + + # Namespaces variables + namespace = client_core.read_namespace( + app_constants.HELM_NS_METRICS_EXPORTER + ) + + # Old namespace variable + old_namespace_label = ( + namespace.metadata.labels.get(component_constant) + if component_constant in namespace.metadata.labels + else None + ) + + if component_constant in chart_overrides: + # User Override variables + dict_chart_overrides = yaml.safe_load(chart_overrides) + override_label = dict_chart_overrides.get(component_constant) + + if override_label == "application": + namespace.metadata.labels.update( + {component_constant: "application"} + ) + app_op._kube.kube_patch_namespace( + app_constants.HELM_NS_METRICS_EXPORTER, namespace + ) + elif override_label == "platform": + namespace.metadata.labels.update({component_constant: "platform"}) + app_op._kube.kube_patch_namespace( + app_constants.HELM_NS_METRICS_EXPORTER, namespace + ) + elif not override_label: + namespace.metadata.labels.update({component_constant: "platform"}) + app_op._kube.kube_patch_namespace( + app_constants.HELM_NS_METRICS_EXPORTER, namespace + ) + else: + LOG.info( + f"WARNING: Namespace label {override_label} not supported" + ) + + namespace_label = namespace.metadata.labels.get(component_constant) + if old_namespace_label != namespace_label: + self._delete_ineterface_metrics_exporter_pods(app_op, client_core) + + def post_remove(self, app): + LOG.debug( + "Executing post_remove for {} app".format( + app_constants.HELM_APP_METRICS_EXPORTER + ) + ) + cmd = [ + "kubectl", + "--kubeconfig", + kubernetes.KUBERNETES_ADMIN_CONF, + "delete", + "namespace", + app_constants.HELM_NS_METRICS_EXPORTER, + ] + stdout, stderr = cutils.trycmd(*cmd) + LOG.debug( + "{} app: cmd={} stdout={} stderr={}".format( + app.name, cmd, stdout, stderr + ) + ) + + def _get_helm_user_overrides(self, dbapi_instance, db_app_id): + try: + overrides = dbapi_instance.helm_override_get( + app_id=db_app_id, + name=app_constants.HELM_APP_METRICS_EXPORTER, + namespace=app_constants.HELM_NS_METRICS_EXPORTER, + ) + except exception.HelmOverrideNotFound: + values = { + "name": app_constants.HELM_APP_METRICS_EXPORTER, + "namespace": app_constants.HELM_NS_METRICS_EXPORTER, + "db_app_id": db_app_id, + } + overrides = dbapi_instance.helm_override_create(values=values) + return overrides.user_overrides or "" + + def _delete_ineterface_metrics_exporter_pods(self, app_op, client_core): + # pod list + system_pods = client_core.list_namespaced_pod( + app_constants.HELM_NS_METRICS_EXPORTER + ) + + # On namespace label change delete pods to force restart + for pod in system_pods.items: + app_op._kube.kube_delete_pod( + name=pod.metadata.name, + namespace=app_constants.HELM_NS_METRICS_EXPORTER, + grace_periods_seconds=0, + ) diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_node_interface_metrics_exporter.py b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_node_interface_metrics_exporter.py index a50e052..254d87f 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_node_interface_metrics_exporter.py +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_node_interface_metrics_exporter.py @@ -30,4 +30,4 @@ class NodeInterfaceMetricsExporterTestCaseDummy( """Dummy Class to pass the zuul.""" def test_dummy(self): - pass \ No newline at end of file + pass diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_plugins.py b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_plugins.py index 4408d26..b22e7e4 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_plugins.py +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/k8sapp_node_interface_metrics_exporter/tests/test_plugins.py @@ -10,7 +10,7 @@ from k8sapp_node_interface_metrics_exporter.common import constants as app_const class K8SAppNodeInterfaceMetricsExporterAppMixin(object): - app_name = app_constants.HELM_APP_PM + app_name = app_constants.HELM_APP_METRICS_EXPORTER path_name = app_name + '.tgz' # pylint: disable=invalid-name,useless-parent-delegation diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/pylint.rc b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/pylint.rc index 13b0acd..5e909c7 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/pylint.rc +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/pylint.rc @@ -14,7 +14,7 @@ persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins=pylint.extensions.bad_builtin +load-plugins= # Use multiple processes to speed up Pylint. jobs=4 @@ -39,16 +39,21 @@ extension-pkg-whitelist=lxml.etree,greenlet # https://pylint.readthedocs.io/en/latest/user_guide disable= # C codes refer to Convention + C0103, # invalid-name C0114, # missing-module-docstring C0115, # missing-class-docstring C0116, # missing-function-docstring + C0209, # consider-using-f-string + C0301, # line-too-long # R codes refer to refactoring R0205, # useless-object-inheritance R0901, # too-many-ancestors R0903, # too-few-public-methods R0913, # too-many-arguments # W codes are warnings - W0212, # protected-access + R1710, # inconsistent-return-statements + R1725, # super-with-arguments + W0212, # protected-access [REPORTS] # Set the output format. Available formats are text, parseable, colorized, msvs @@ -229,6 +234,5 @@ valid-classmethod-first-arg=cls [EXCEPTIONS] -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" +# Exceptions that will emit a warning when caught. overgeneral-exceptions=builtins.BaseException,builtins.Exception diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/setup.cfg b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/setup.cfg index d390bef..b6e11af 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/setup.cfg +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/setup.cfg @@ -30,7 +30,7 @@ systemconfig.helm_applications = node-interface-metrics-exporter = systemconfig.helm_plugins.node_interface_metrics_exporter systemconfig.helm_plugins.node_interface_metrics_exporter = - 001_metrics-exporter = k8sapp_node_interface_metrics_exporter.helm.node_interface_metrics_exporter:NodeInterfaceMetricsExporterHelm + 001_node-interface-metrics-exporter = k8sapp_node_interface_metrics_exporter.helm.node_interface_metrics_exporter:NodeInterfaceMetricsExporterHelm systemconfig.app_lifecycle = node-interface-metrics-exporter = k8sapp_node_interface_metrics_exporter.lifecycle.lifecycle_node_interface_metrics_exporter:NodeInterfaceMetricsExporterAppLifecycleOperator diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/test-requirements.txt b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/test-requirements.txt index 1191b51..a140bcc 100644 --- a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/test-requirements.txt +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/test-requirements.txt @@ -17,4 +17,4 @@ testrepository>=0.0.18 testtools!=1.2.0,>=0.9.36 isort<5;python_version>="3.0" pylint -pycryptodomex \ No newline at end of file +pycryptodomex diff --git a/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/tox.ini b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/tox.ini new file mode 100644 index 0000000..9c9ac29 --- /dev/null +++ b/python3-k8sapp-node-interface-metrics-exporter/k8sapp_node_interface_metrics_exporter/tox.ini @@ -0,0 +1,179 @@ +[tox] +envlist = flake8,py39,pylint +minversion = 1.6 +skipsdist = True + +# tox does not work if the path to the workdir is too long, so move it to /tmp +# tox 3.1.0 adds TOX_LIMITED_SHEBANG +toxworkdir = /tmp/{env:USER}_k8snodeinterfacemetricsexportertox +stxdir = {toxinidir}/../../.. +distshare={toxworkdir}/.tox/distshare + +[testenv] +basepython = python3.9 +usedevelop = True + +# tox is silly... these need to be separated by a newline.... +allowlist_externals = bash + find + +install_command = pip install -v -v -v \ + -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/starlingx/root/raw/branch/master/build-tools/requirements/debian/upper-constraints.txt} \ + {opts} {packages} + +# Note the hash seed is set to 0 until can be tested with a +# random hash seed successfully. +setenv = VIRTUAL_ENV={envdir} + PYTHONHASHSEED=0 + PIP_RESOLVER_DEBUG=1 + PYTHONDONTWRITEBYTECODE=1 + OS_TEST_PATH=./k8sapp_node_interface_metrics_exporter/tests + LANG=en_US.UTF-8 + LANGUAGE=en_US:en + LC_ALL=C + EVENTS_YAML=./k8sapp_node_interface_metrics_exporter/tests/events_for_testing.yaml + SYSINV_TEST_ENV=True + TOX_WORK_DIR={toxworkdir} + PYLINTHOME={toxworkdir} + +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + -e{[tox]stxdir}/config/sysinv/sysinv/sysinv + -e{[tox]stxdir}/config/tsconfig/tsconfig + -e{[tox]stxdir}/fault/fm-api/source + -e{[tox]stxdir}/fault/python-fmclient/fmclient + -e{[tox]stxdir}/update/sw-patch/cgcs-patch + -e{[tox]stxdir}/utilities/ceph/python-cephclient/python-cephclient + +commands = + find . -type f -name "*.pyc" -delete + +[flake8] +# H series are hacking +# H101 is TODO +# H102 is apache license +# H104 file contains only comments (ie: license) +# H105 author tags +# H306 imports not in alphabetical order +# H401 docstring should not start with a space +# H403 multi line docstrings should end on a new line +# H404 multi line docstring should start without a leading new line +# H405 multi line docstring summary not separated with an empty line +# H701 Empty localization string +# H702 Formatting operation should be outside of localization method call +# H703 Multiple positional placeholders + +# B series are bugbear +# B006 Do not use mutable data structures for argument defaults. Needs to be FIXED. +# B007 Loop control variable not used within the loop body. +# B009 Do not call getattr with a constant attribute value +# B010 Do not call setattr with a constant attribute value +# B012 return/continue/break inside finally blocks cause exceptions to be silenced +# B014 Redundant exception types +# B301 Python 3 does not include `.iter*` methods on dictionaries. (this should be suppressed on a per line basis) + +# W series are warnings +# W503 line break before binary operator +# W504 line break after binary operator +# W605 invalid escape sequence + +# E series are pep8 +# E117 over-indented +# E126 continuation line over-indented for hanging indent +# E127 continuation line over-indented for visual indent +# E128 continuation line under-indented for visual indent +# E402 module level import not at top of file +# E741 ambiguous variable name + +ignore = H101,H102,H104,H105,H306,H401,H403,H404,H405,H701,H702,H703, + B006,B007,B009,B010,B012,B014,B301 + W503,W504,W605, + E117,E126,E127,E128,E402,E741 +exclude = build,dist,tools,.eggs +max-line-length=120 + +[testenv:flake8] +deps = -r{toxinidir}/test-requirements.txt +commands = + flake8 {posargs} . + +[testenv:py39] +commands = + stestr run {posargs} + stestr slowest + +[testenv:pep8] +# testenv:flake8 clone +deps = -r{toxinidir}/test-requirements.txt +commands = {[testenv:flake8]commands} + +[testenv:venv] +commands = {posargs} + +[bandit] +# The following bandit tests are being skipped: +# B101: Test for use of assert +# B103: Test for setting permissive file permissions +# B104: Test for binding to all interfaces +# B105: Test for use of hard-coded password strings +# B108: Test for insecure usage of tmp file/directory +# B110: Try, Except, Pass detected. +# B303: Use of insecure MD2, MD4, MD5, or SHA1 hash function. +# B307: Blacklisted call to eval. +# B310: Audit url open for permitted schemes +# B311: Standard pseudo-random generators are not suitable for security/cryptographic purposes +# B314: Blacklisted calls to xml.etree.ElementTree +# B318: Blacklisted calls to xml.dom.minidom +# B320: Blacklisted calls to lxml.etree +# B404: Import of subprocess module +# B405: import xml.etree +# B408: import xml.minidom +# B410: import lxml +# B506: Test for use of yaml load +# B602: Test for use of popen with shell equals true +# B603: Test for use of subprocess without shell equals true +# B604: Test for any function with shell equals true +# B605: Test for starting a process with a shell +# B607: Test for starting a process with a partial path +# B608: Possible SQL injection vector through string-based query +# +# Note: 'skips' entry cannot be split across multiple lines +# +skips = B101,B103,B104,B105,B108,B110,B303,B307,B310,B311,B314,B318,B320,B404,B405,B408,B410,B506,B602,B603,B604,B605,B607,B608 +exclude = tests + +[testenv:bandit] +deps = -r{toxinidir}/test-requirements.txt +commands = bandit --ini tox.ini -n 5 -r k8sapp_node_interface_metrics_exporter + +[testenv:pylint] +install_command = pip install -v -v -v \ + -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/starlingx/root/raw/branch/master/build-tools/requirements/debian/upper-constraints.txt} \ + {opts} {packages} +commands = + pylint {posargs} k8sapp_node_interface_metrics_exporter --rcfile=./pylint.rc + +[testenv:cover] +# not sure is passenv is still needed +passenv = CURL_CA_BUNDLE +deps = {[testenv]deps} +setenv = {[testenv]setenv} + PYTHON=coverage run --parallel-mode + +commands = + {[testenv]commands} + coverage erase + stestr run {posargs} + coverage combine + coverage html -d cover + coverage xml -o cover/coverage.xml + coverage report + +[testenv:pip-missing-reqs] +# do not install test-requirements as that will pollute the virtualenv for +# determining missing packages +# this also means that pip-missing-reqs must be installed separately, outside +# of the requirements.txt files +deps = pip_missing_reqs + -rrequirements.txt +commands=pip-missing-reqs -d --ignore-file=/k8sapp_node_interface_metrics_exporter/tests k8sapp_node_interface_metrics_exporter diff --git a/stx-node-interface-metrics-exporter-helm/debian/deb_folder/rules b/stx-node-interface-metrics-exporter-helm/debian/deb_folder/rules index a37d697..ad1d0b2 100755 --- a/stx-node-interface-metrics-exporter-helm/debian/deb_folder/rules +++ b/stx-node-interface-metrics-exporter-helm/debian/deb_folder/rules @@ -20,14 +20,14 @@ export STAGING = staging override_dh_auto_build: # Create the helm-chart TGZ file. - #cd helm-charts && make + cd helm-charts && make # Setup the staging directory. mkdir -p $(STAGING) cp files/metadata.yaml $(STAGING) cp -Rv fluxcd-manifests/ $(STAGING) mkdir -p $(STAGING)/charts - #cp helm-charts/*.tgz $(STAGING)/charts + cp helm-charts/*.tgz $(STAGING)/charts # Populate metadata. sed -i 's/@APP_NAME@/$(APP_NAME)/g' $(STAGING)/metadata.yaml @@ -36,7 +36,7 @@ override_dh_auto_build: # Copy the plugins: installed in the buildroot mkdir -p $(STAGING)/plugins - #cp /plugins/*.whl $(STAGING)/plugins + cp /plugins/*.whl $(STAGING)/plugins # Prepare staging for fluxcd package cp -R fluxcd-manifests $(STAGING)/ diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/README b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/README deleted file mode 100644 index 84a8ebb..0000000 --- a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/README +++ /dev/null @@ -1,12 +0,0 @@ -## Intel Device Plugins Operator Helm -This directory contains helm chart that need to be built for this -application. This helm chart deploys the Interface Matrics Exporter -on Kubernetes clusters. - -## Source -TODO:MAYANK => Custom helm chart related info -Charts are based on Custom helm chart - -## Installation -Installation of helm-chart is done automatically from the intel-device-plugins-operator-helm package. - diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/files/metadata.yaml b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/files/metadata.yaml index 2498be2..3972200 100644 --- a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/files/metadata.yaml +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/files/metadata.yaml @@ -2,9 +2,11 @@ app_name: @APP_NAME@ app_version: @APP_VERSION@ helm_repo: @HELM_REPO@ +maintain_user_overrides: true +maintain_attributes: true + upgrades: auto_update: true behavior: platform_managed_app: yes - desired_state: applied diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/base/kustomization.yaml b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/base/kustomization.yaml index 1bdef7e..9bc69b1 100644 --- a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/base/kustomization.yaml +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/base/kustomization.yaml @@ -6,4 +6,3 @@ resources: - helmrepository.yaml - - namespace.yaml \ No newline at end of file diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/node-interface-metrics-exporter/nime-static-overrides.yaml b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/node-interface-metrics-exporter/nime-static-overrides.yaml index 6ca1ee6..67f523e 100644 --- a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/node-interface-metrics-exporter/nime-static-overrides.yaml +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/fluxcd-manifests/node-interface-metrics-exporter/nime-static-overrides.yaml @@ -3,3 +3,9 @@ # # SPDX-License-Identifier: Apache-2.0 # + +app.starlingx.io/component: platform + +image: + repository: starlingx/metrics-exporter-api + tag: latest diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/Makefile b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/Makefile index fe1ba06..bba65c5 100644 --- a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/Makefile +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/Makefile @@ -15,27 +15,27 @@ CHARTS := helm-toolkit $(filter-out $(EXCLUDES), $(patsubst %/.,%,$(wildcard */. all: $(CHARTS) $(CHARTS): - @if [ -d $@ ]; then \ - echo; \ - echo "===== Processing [$@] chart ====="; \ - make $(TASK)-$@; \ - fi + @if [ -d $@ ]; then \ + echo; \ + echo "===== Processing [$@] chart ====="; \ + make $(TASK)-$@; \ + fi init-%: - if [ -f $*/Makefile ]; then make -C $*; fi - if [ -f $*/requirements.yaml ]; then helm dep up $*; fi + if [ -f $*/Makefile ]; then make -C $*; fi + if [ -f $*/requirements.yaml ]; then helm dep up $*; fi lint-%: init-% - if [ -d $* ]; then helm lint $*; fi + if [ -d $* ]; then helm lint $*; fi build-%: lint-% - if [ -d $* ]; then helm package $*; fi + if [ -d $* ]; then helm package $*; fi clean: - @echo "Clean all build artifacts" - rm -f */templates/_partials.tpl */templates/_globals.tpl - rm -f *tgz */charts/*tgz */requirements.lock - rm -rf */charts */tmpcharts + @echo "Clean all build artifacts" + rm -f */templates/_partials.tpl */templates/_globals.tpl + rm -f *tgz */charts/*tgz */requirements.lock + rm -rf */charts */tmpcharts %: - @: + @: diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/README.md b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/README.md new file mode 100644 index 0000000..3e67dc0 --- /dev/null +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/README.md @@ -0,0 +1,45 @@ +# Node Interface Metricse Exporter Helm Chart + +This Helm Chart comes with everything that is needed to run Node Interface +Metrics Exporter app. + +## How to install + +Create the namespace where Helm should install the components with + +```console +$ kubectl create namespace "node-interface-metrics-exporter" +``` + +This chart can be installed using the default values with: + +```console +$ helm upgrade --install node-interface-metrics-exporter stx-platform/node-interface-metrics-exporter +``` + +It is possible to replace the default "args" values of values.yaml file to +change or add new args to Node interface metrics exporter. + +You may want to override values.yaml file use the following command: + +```console +$ helm upgrade --install node-interface-metrics-exporter -f values.yaml stx-platform/node-interface-metrics-exporter +``` + +### Delete Chart + +If you want to delete your Chart, use this command + +```console +$ helm uninstall node-interface-metrics-exporter +``` + +If you want to delete the namespace, use this command + +```console +$ kubectl delete namespace node-interface-metrics-exporter +``` + +For more information about installing and using Helm, see the +[Helm Docs](https://helm.sh/docs/). For a quick introduction to Charts, +see the [Chart Guide](https://helm.sh/docs/topics/charts/). diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/daemonset.yaml b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/daemonset.yaml new file mode 100644 index 0000000..2be7b03 --- /dev/null +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/daemonset.yaml @@ -0,0 +1,55 @@ +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Values.name }} + namespace: {{ .Values.namespace }} + labels: + app: {{ .Values.labels.app }} + chart: {{ .Chart.Name }} +spec: + selector: + matchLabels: + app: {{ .Values.labels.app }} + template: + metadata: + namespace: {{ .Values.namespace }} + labels: + app: {{ .Values.labels.app }} + spec: + hostNetwork: true + imagePullSecrets: + - name: {{ .Values.imagePullSecrets}} + containers: + - name: {{ .Values.name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + env: + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + resources: + limits: + cpu: 100m + memory: 200Mi + volumeMounts: + - mountPath: /data/sys + name: sys + volumes: + - hostPath: + path: /sys + type: "" + name: sys diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/role.yaml b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/role.yaml new file mode 100644 index 0000000..77b0942 --- /dev/null +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/role.yaml @@ -0,0 +1,24 @@ +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: node-interface-metrics-role + namespace: node-interface-metrics-exporter +rules: +- apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - create + - get + - list + - watch + - patch + - delete diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/rolebinding.yaml b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/rolebinding.yaml new file mode 100644 index 0000000..1643811 --- /dev/null +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/templates/rolebinding.yaml @@ -0,0 +1,21 @@ +# +# Copyright (c) 2023 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app: "" + name: node-interface-metrics-rolebinding + namespace: node-interface-metrics-exporter +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: node-interface-metrics-role +subjects: +- kind: ServiceAccount + name: node-interface-metrics-role + namespace: node-interface-metrics-exporter diff --git a/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/values.yaml b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/values.yaml new file mode 100644 index 0000000..6689896 --- /dev/null +++ b/stx-node-interface-metrics-exporter-helm/stx-node-interface-metrics-exporter-helm/helm-charts/node-interface-metrics-exporter/values.yaml @@ -0,0 +1,14 @@ +# Default values for node-interface-metrics-exporter. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + repository: starlingx/metrics-exporter-api + tag: latest + +namespace: node-interface-metrics-exporter +imagePullSecrets: default-registry-key + +name: node-interface-metrics-exporter +labels: + app: nime-app diff --git a/test-requirements.txt b/test-requirements.txt index 8ae3e22..fa7c694 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,3 +1,3 @@ # hacking pulls in flake8 -hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0 +hacking>=1.1.0,<=2.0.0 # Apache-2.0 bashate >= 0.2 diff --git a/tox.ini b/tox.ini index f86f050..c7c70f3 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,11 @@ skipsdist = True sitepackages=False [testenv] -install_command = pip install -U {opts} {packages} +basepython = python3 +install_command = pip install -U \ + {opts} {packages} \ + -c{env:TOX_CONSTRAINTS_FILE:https://opendev.org/starlingx/root/raw/branch/master/build-tools/requirements/debian/upper-constraints.txt} + setenv = VIRTUAL_ENV={envdir} OS_STDOUT_CAPTURE=1 @@ -18,9 +22,9 @@ deps = allowlist_externals = bash -passenv = - XDG_CACHE_HOME - +[testenv:linters] +commands = + {[testenv:bashate]commands} [testenv:bashate] # Treat all E* codes as Errors rather than warnings using: -e 'E*' @@ -34,10 +38,6 @@ commands = -print0 | xargs -r -n 1 -0 bashate -v \ -e 'E*'" -[testenv:linters] -commands = - {[testenv:bashate]commands} - [testenv:flake8] basepython = python3 description = Dummy environment to allow flake8 to be run in subdir tox @@ -49,3 +49,4 @@ description = Dummy environment to allow pylint to be run in subdir tox [testenv:bandit] basepython = python3 description = Dummy environment to allow bandit to be run in subdir tox +