diff --git a/.gitignore b/.gitignore
index 172bf57..f51ee66 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
 .tox
+venv/
\ No newline at end of file
diff --git a/.zuul.yaml b/.zuul.yaml
index 1169227..079958f 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -8,6 +8,7 @@
         - k8sapp-platform-tox-py39
         - k8sapp-platform-tox-flake8
         - k8sapp-platform-tox-pylint
+        - k8sapp-platform-tox-metadata
         - k8sapp-platform-tox-bandit
     gate:
       jobs:
@@ -15,6 +16,7 @@
         - k8sapp-platform-tox-py39
         - k8sapp-platform-tox-flake8
         - k8sapp-platform-tox-pylint
+        - k8sapp-platform-tox-metadata
         - k8sapp-platform-tox-bandit
     post:
       jobs:
@@ -44,11 +46,37 @@
     description: |
       Run flake8 test for k8sapp_platform
     nodeset: debian-bullseye
+    required-projects:
+      - starlingx/config
+      - starlingx/fault
+      - starlingx/update
+      - starlingx/utilities
+      - starlingx/root
     files:
       - python3-k8sapp-platform/*
     vars:
       tox_envlist: flake8
       tox_extra_args: -c python3-k8sapp-platform/k8sapp_platform/tox.ini
+      tox_constraints_file: '{{ ansible_user_dir }}/src/opendev.org/starlingx/root/build-tools/requirements/debian/upper-constraints.txt'
+
+- job:
+    name: k8sapp-platform-tox-metadata
+    parent: tox
+    description: |
+      Run metadata test for k8sapp_platform
+    nodeset: debian-bullseye
+    required-projects:
+      - starlingx/config
+      - starlingx/fault
+      - starlingx/update
+      - starlingx/utilities
+      - starlingx/root
+    files:
+      - python3-k8sapp-platform/*
+    vars:
+      tox_envlist: metadata
+      tox_extra_args: -c python3-k8sapp-platform/k8sapp_platform/tox.ini
+      tox_constraints_file: '{{ ansible_user_dir }}/src/opendev.org/starlingx/root/build-tools/requirements/debian/upper-constraints.txt'
 
 - job:
     name: k8sapp-platform-tox-pylint
@@ -75,11 +103,19 @@
     description: |
       Run bandit test for k8sapp_platform
     nodeset: debian-bullseye
+    required-projects:
+      - starlingx/config
+      - starlingx/fault
+      - starlingx/update
+      - starlingx/utilities
+      - starlingx/root
     files:
       - python3-k8sapp-platform/*
     vars:
       tox_envlist: bandit
       tox_extra_args: -c python3-k8sapp-platform/k8sapp_platform/tox.ini
+      tox_constraints_file: '{{ ansible_user_dir }}/src/opendev.org/starlingx/root/build-tools/requirements/debian/upper-constraints.txt'
+
 
 - job:
     name: stx-platform-armada-app-upload-git-mirror
diff --git a/python3-k8sapp-platform/k8sapp_platform/pylint.rc b/python3-k8sapp-platform/k8sapp_platform/pylint.rc
index e1e3ccd..d9e84e0 100755
--- a/python3-k8sapp-platform/k8sapp_platform/pylint.rc
+++ b/python3-k8sapp-platform/k8sapp_platform/pylint.rc
@@ -7,7 +7,7 @@ rcfile=pylint.rc
 #init-hook=
 
 # Add files or directories to the blacklist. Should be base names, not paths.
-ignore=tests
+ignore=
 
 # Pickle collected data for later comparisons.
 persistent=yes
@@ -31,175 +31,135 @@ extension-pkg-whitelist=lxml.etree,greenlet
 
 
 [MESSAGES CONTROL]
-# Enable the message, report, category or checker with the given id(s). You can
-# either give multiple identifier separated by comma (,) or put this option
-# multiple time.
-#
-# Python3 checker:
-#
-# E1601: print-statement
-# E1602: parameter-unpacking
-# E1603: unpacking-in-except
-# E1604: old-raise-syntax
-# E1605: backtick
-# E1606: long-suffix
-# E1607: old-ne-operator
-# E1608: old-octal-literal
-# E1609: import-star-module-level
-# E1610: non-ascii-bytes-literal
-# E1611: invalid-unicode-literal
-# W1601: apply-builtin
-# W1602: basestring-builtin
-# W1603: buffer-builtin
-# W1604: cmp-builtin
-# W1605: coerce-builtin
-# W1606: execfile-builtin
-# W1607: file-builtin
-# W1608: long-builtin
-# W1609: raw_input-builtin
-# W1610: reduce-builtin
-# W1611: standarderror-builtin
-# W1612: unicode-builtin
-# W1613: xrange-builtin
-# W1614: coerce-method
-# W1615: delslice-method
-# W1616: getslice-method
-# W1617: setslice-method
-# W1618: no-absolute-import
-# W1619: old-division
-# W1620: dict-iter-method
-# W1621: dict-view-method
-# W1622: next-method-called
-# W1623: metaclass-assignment
-# W1624: indexing-exception
-# W1625: raising-string
-# W1626: reload-builtin
-# W1627: oct-method
-# W1628: hex-method
-# W1629: nonzero-method
-# W1630: cmp-method
-# W1632: input-builtin
-# W1633: round-builtin
-# W1634: intern-builtin
-# W1635: unichr-builtin
-# W1636: map-builtin-not-iterating
-# W1637: zip-builtin-not-iterating
-# W1638: range-builtin-not-iterating
-# W1639: filter-builtin-not-iterating
-# W1640: using-cmp-argument
-# W1641: eq-without-hash
-# W1642: div-method
-# W1643: idiv-method
-# W1644: rdiv-method
-# W1645: exception-message-attribute
-# W1646: invalid-str-codec
-# W1647: sys-max-int
-# W1648: bad-python3-import
-# W1649: deprecated-string-function
-# W1650: deprecated-str-translate-call
-# W1651: deprecated-itertools-function
-# W1652: deprecated-types-field
-# W1653: next-method-defined
-# W1654: dict-items-not-iterating
-# W1655: dict-keys-not-iterating
-# W1656: dict-values-not-iterating
-# W1657: deprecated-operator-function
-# W1658: deprecated-urllib-function
-# W1659: xreadlines-attribute
-# W1660: deprecated-sys-function
-# W1661: exception-escape
-# W1662: comprehension-escape
-enable=E1603,E1609,E1610,E1602,E1606,E1608,E1607,E1605,E1604,E1601,E1611,W1652,
-       W1651,W1649,W1657,W1660,W1658,W1659,W1623,W1622,W1620,W1621,W1645,W1641,
-       W1624,W1648,W1625,W1611,W1662,W1661,W1650,W1640,W1630,W1614,W1615,W1642,
-       W1616,W1628,W1643,W1629,W1627,W1644,W1617,W1601,W1602,W1603,W1604,W1605,
-       W1654,W1655,W1656,W1619,W1606,W1607,W1639,W1618,W1632,W1634,W1608,W1636,
-       W1653,W1646,W1638,W1609,W1610,W1626,W1633,W1647,W1635,W1612,W1613,W1637
-
 # Disable the message, report, category or checker with the given id(s). You
 # can either give multiple identifier separated by comma (,) or put this option
 # multiple time (only on the command line, not in the configuration file where
 # it should appear only once).
 # See "Messages Control" section of
 # https://pylint.readthedocs.io/en/latest/user_guide
-# We are disabling (C)onvention
-# We are disabling (R)efactor
-# We are selectively disabling (W)arning
-# We are not disabling (F)atal, (E)rror
-# The following warnings should be fixed:
-# fixme (todo, xxx, fixme)
-# W0101: unreachable
-# W0105: pointless-string-statement
-# W0106: expression-not-assigned
-# W0107: unnecessary-pass
-# W0108: unnecessary-lambda
-# W0110: deprecated-lambda
-# W0123: eval-used
-# W0150: lost-exception
-# W0201: attribute-defined-outside-init
-# W0211: bad-staticmethod-argument
-# W0212: protected-access
-# W0221: arguments-differ
-# W0223: abstract-method
-# W0231: super-init-not-called
-# W0235: useless-super-delegation
-# W0311: bad-indentation
-# W0402: deprecated-module
-# W0403: relative-import
-# W0404: reimported
-# W0602: global-variable-not-assigned
-# W0603: global-statement
-# W0612: unused-variable
-# W0613: unused-argument
-# W0621: redefined-outer-name
-# W0622: redefined-builtin
-# W0631: undefined-loop-variable
-# W0632: unbalanced-tuple-unpacking
-# W0701: bad-except-order
-# W0706: The except handler raises immediately (try-except-raise)
-# W0707: raise-missing-from
-# W0719: broad-exception-raised
-# W1113: keyword-arg-before-vararg
-# W1201: logging-not-lazy
-# W1401: anomalous-backslash-in-string
-# W1406: redundant-u-string-prefix
-# W1505: Using deprecated method getargspec() (deprecated-method)
-# W1514: unspecified-encoding
-# W1618: no-absolute-import (Python3 checker)
-# W0237: arguments-renamed
-# W4904: deprecated-class
-# W4905: deprecated-decorator
-# All these errors should be fixed:
-# E0012: pylint for python3 does not support inline deprecation
-# E0213: no-self-argument
-# E0401: import-error
-# E0604: invalid-all-object
-# E0633: unpacking-non-sequence
-# E0701: bad-except-order
-# E1101: no-member
-# E1102: not-callable
-# E1111: assignment-from-no-return
-# E1120: no-value-for-parameter
-# E1121: too-many-function-args
-disable=C, R, fixme, W0101, W0105, W0106, W0107, W0108, W0110, W0123, W0150,
-        W0201, W0211, W0212, W0221, W0223, W0231, W0235, W0311, W0402, W0403,
-        W0404, W0602, W0603, W0612, W0613, W0621, W0622, W0631, W0632, W0701,
-        W0706, W0707, W0719, W1113, W1201, W1401, W1406, W1505, W1514, W1618,
-        W0237, W4904, W4905, E0012, E0213, E0401, E0604, E0633, E0701, E1101,
-        E1102, E1111, E1120, E1121
+disable=
+        # C codes refer to Convention
+ C0103, # invalid-name
+ C0104, # disallowed-nameA
+ C0112, # empty-docstring
+ C0114, # missing-module-docstring
+ C0115, # missing-class-docstring
+ C0116, # missing-function-docstring
+ C0123, # unidiomatic-typecheck !!!
+ C0201, # consider-iterating-dictionary
+ C0202, # bad-classmethod-argument
+ C0206, # consider-using-dict-items
+ C0207, # use-maxsplit-arg
+ C0209, # consider-using-f-string
+ C0301, # line-too-long
+ C0302, # too-many-lines
+ C0325, # superfluous-parens
+ C0411, # wrong-import-order
+ C0412, # ungrouped-imports
+ C0413, # wrong-import-position
+ C0414, # useless-import-alias  !!!
+ C0415, # import-outside-toplevel
+ C1802, # use-implicit-booleaness-not-len !!!
+ C2801, # unnecessary-dunder-call  !!!
+ C3002, # unnecessary-direct-lambda-call !!!
+        # R codes refer to refactoring
+ R0022, # useless-option-value !!!
+ R0205, # useless-object-inheritance
+ R0402, # consider-using-from-import
+ R0901, # too-many-ancestors
+ R0902, # too-many-instance-attributes
+ R0903, # too-few-public-methods
+ R0904, # too-many-public-methods
+ R0911, # too-many-return-statements
+ R0912, # too-many-branches
+ R0913, # too-many-arguments
+ R0914, # too-many-locals
+ R0915, # too-many-statements
+ R0916, # too-many-boolean-expressions
+ R1702, # too-many-nested-blocks
+ R1703, # simplifiable-if-statement
+ R1704, # redefined-argument-from-local !!!
+ R1705, # no-else-return
+ R1707, # trailing-comma-tuple  !!!
+ R1708, # stop-iteration-return !!!
+ R1710, # inconsistent-return-statements
+ R1711, # useless-return
+ R1714, # consider-using-in
+ R1717, # consider-using-dict-comprehension !!!
+ R1718, # consider-using-set-comprehension
+ R1719, # simplifiable-if-expression
+ R1720, # no-else-raise
+ R1721, # unnecessary-comprehension
+ R1722, # consider-using-sys-exit !!!
+ R1723, # no-else-break
+ R1724, # no-else-continue
+ R1725, # super-with-arguments
+ R1726, # simplifiable-condition  !!!
+ R1728, # consider-using-generator
+ R1729, # use-a-generator
+ R1730, # consider-using-min-builtin  !!!
+ R1731, # consider-using-max-builtin  !!!
+ R1732, # consider-using-with
+ R1733, # unnecessary-dict-index-lookup !!
+ R1734, # use-list-literal
+ R1735, # use-dict-literal
+        # W codes are warnings
+ W0101, # unreachable
+ W0105, # pointless-string-statement
+ W0106, # expression-not-assigned
+ W0107, # unnecessary-pass
+ W0108, # unnecessary-lambda
+ W0109, # duplicate-key                  !!!
+ W0123, # eval-used
+ W0125, # using-constant-test            !!!
+ W0133, # pointless-exception-statement  !!!
+ W0143, # comparison-with-callable       !!!
+ W0150, # lost-exception
+ W0201, # attribute-defined-outside-init
+ W0211, # bad-staticmethod-argument
+ W0212, # protected-access
+ W0221, # arguments-differ
+ W0223, # abstract-method
+ W0231, # super-init-not-called
+ W0235, # useless-super-delegation
+ W0237, # arguments-renamed  !!!
+ W0311, # bad-indentation
+ W0402, # deprecated-module
+ W0404, # reimported
+ W0511, # fixme
+ W0602, # global-variable-not-assigned  !!!
+ W0603, # global-statement
+ W0612, # unused-variable
+ W0613, # unused-argument
+ W0621, # redefined-outer-name
+ W0622, # redefined-builtin
+ W0631, # undefined-loop-variable
+ W0703, # broad-except (pylint 2.16 renamed to broad-except-caught)
+ W0706, # try-except-raise
+ W0707, # raise-missing-from
+ W0719, # broad-exception-raised
+ W1113, # keyword-arg-before-vararg
+ W1310, # format-string-without-interpolation  !!!
+ W1401, # anomalous-backslash-in-string
+ W1406, # redundant-u-string-prefix
+ W1505, # deprecated-method
+ W1514, # unspecified-encoding
+ W3101, # missing-timeout
+ E0601, # used-before-assignment  !!!
+ E0605, # invalid-all-format      !!!
+ E1101, # no-member
+ E1111, # assignment-from-no-return
+ E1121, # too-many-function-args  !!!
+ E1123, # unexpected-keyword-arg  !!!
+ E1136, # unsubscriptable-object  !!!
 
 [REPORTS]
 # Set the output format. Available formats are text, parseable, colorized, msvs
 # (visual studio) and html
 output-format=text
 
-# Put messages in a separate file for each module / package specified on the
-# command line instead of printing them on stdout. Reports (if any) will be
-# written in a file name "pylint_global.[txt|html]".
-files-output=no
-
 # Tells whether to display a full report or only the messages
-reports=yes
+reports=no
 
 # Python expression which should return a note less than 10 (10 is the highest
 # note). You have access to the variables errors warning, statement which
@@ -256,9 +216,6 @@ generated-members=REQUEST,acl_users,aq_parent
 
 
 [BASIC]
-# List of builtins function names that should not be used, separated by a comma
-bad-functions=map,filter,apply,input
-
 # Regular expression which should only match correct module names
 module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
 
@@ -348,7 +305,7 @@ max-locals=15
 max-returns=6
 
 # Maximum number of branch for function / method body
-max-branchs=12
+max-branches=12
 
 # Maximum number of statements in function / method body
 max-statements=50
@@ -375,6 +332,5 @@ valid-classmethod-first-arg=cls
 
 
 [EXCEPTIONS]
-# Exceptions that will emit a warning when being caught. Defaults to
-# "Exception"
-overgeneral-exceptions=Exception
+# Exceptions that will emit a warning when caught.
+overgeneral-exceptions=builtins.BaseException,builtins.Exception
diff --git a/python3-k8sapp-platform/k8sapp_platform/requirements.txt b/python3-k8sapp-platform/k8sapp_platform/requirements.txt
index 43f8edc..8f225d8 100644
--- a/python3-k8sapp-platform/k8sapp_platform/requirements.txt
+++ b/python3-k8sapp-platform/k8sapp_platform/requirements.txt
@@ -1,2 +1,2 @@
-pbr>=0.5
-PyYAML>=3.10
+pbr>=2.0.0
+PyYAML>=3.10.0
diff --git a/python3-k8sapp-platform/k8sapp_platform/test-requirements.txt b/python3-k8sapp-platform/k8sapp_platform/test-requirements.txt
index 65209c8..a140bcc 100644
--- a/python3-k8sapp-platform/k8sapp_platform/test-requirements.txt
+++ b/python3-k8sapp-platform/k8sapp_platform/test-requirements.txt
@@ -1,28 +1,20 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-flake8<3.8.0
-pycodestyle<2.6.0 # MIT License
 hacking>=1.1.0,<=2.0.0 # Apache-2.0
+astroid
+bandit<1.7.2;python_version>="3.0"
 coverage>=3.6
-discover
 fixtures>=3.0.0 # Apache-2.0/BSD
 mock>=2.0.0 # BSD
-passlib>=1.7.0
-psycopg2-binary
-python-barbicanclient<3.1.0,>=3.0.1
 python-subunit>=0.0.18
 requests-mock>=0.6.0 # Apache-2.0
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
-oslosphinx<2.6.0,>=2.5.0 # Apache-2.0
+sphinx
+oslosphinx
 oslotest>=3.2.0 # Apache-2.0
 stestr>=1.0.0 # Apache-2.0
 testrepository>=0.0.18
 testtools!=1.2.0,>=0.9.36
-tempest-lib<0.5.0,>=0.4.0
-ipaddr
-pytest
-pyudev
-migrate
-python-ldap>=3.1.0
-markupsafe
+isort<5;python_version>="3.0"
+pylint
+pycryptodomex
diff --git a/python3-k8sapp-platform/k8sapp_platform/tox.ini b/python3-k8sapp-platform/k8sapp_platform/tox.ini
index f73607e..f54e47d 100644
--- a/python3-k8sapp-platform/k8sapp_platform/tox.ini
+++ b/python3-k8sapp-platform/k8sapp_platform/tox.ini
@@ -1,38 +1,32 @@
 [tox]
-envlist = flake8,py39,pylint,bandit
+envlist = flake8,py39,pylint,metadata,bandit
 minversion = 1.6
-# skipsdist = True
-#,pip-missing-reqs
+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}_k8splatformtox
 stxdir = {toxinidir}/../../..
 distshare={toxworkdir}/.tox/distshare
 
 [testenv]
-basepython = python3
-
-# enabling usedevelop results in  py27 develop-inst:
-# Exception: Versioning for this project requires either an sdist tarball,
-# or access to an upstream git repository.
-# Note. site-packages is false and rpm-python must be yum installed on your dev machine.
+basepython = python3.9
 usedevelop = True
-sitepackages = False
 
 # tox is silly... these need to be separated by a newline....
 allowlist_externals = bash
                       find
+                      echo
 
-install_command = pip install --use-deprecated legacy-resolver \
-    -v -v -v \
-    -c{toxinidir}/upper-constraints.txt \
-    -c{env:TOX_CONSTRAINTS_FILE:https://opendev.org/starlingx/root/raw/branch/master/build-tools/requirements/debian/upper-constraints.txt} \
+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_platform/tests
          LANG=en_US.UTF-8
@@ -43,14 +37,13 @@ setenv = VIRTUAL_ENV={envdir}
          TOX_WORK_DIR={toxworkdir}
          PYLINTHOME={toxworkdir}
 
-# for debian the path to cgcs-patch is incorrect
 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/cgcs-patch/cgcs-patch
+       -e{[tox]stxdir}/update/sw-patch/cgcs-patch
        -e{[tox]stxdir}/utilities/ceph/python-cephclient/python-cephclient
 
 commands =
@@ -79,7 +72,6 @@ commands =
 # 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)
-# B306 `BaseException.message` has been deprecated.  Needs to be FIXED
 
 # W series are warnings
 # W503 line break before binary operator
@@ -92,32 +84,28 @@ commands =
 # 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,B306,
+         B006,B007,B009,B010,B012,B014,B301
          W503,W504,W605,
-         E117,E126,E127,E128,E402
+         E117,E126,E127,E128,E402,E741
 exclude = build,dist,tools,.eggs
 max-line-length=120
 
 [testenv:flake8]
-basepython = python3
 deps = -r{toxinidir}/test-requirements.txt
-       flake8-bugbear
 commands =
-  flake8 {posargs} .
+  flake8 {posargs} ./k8sapp_platform
 
 [testenv:py39]
-basepython = python3.9
 commands =
-  {[testenv]commands}
   stestr run {posargs}
   stestr slowest
 
 [testenv:pep8]
 # testenv:flake8 clone
-basepython = {[testenv:flake8]basepython}
-deps = {[testenv:flake8]deps}
+deps = -r{toxinidir}/test-requirements.txt
 commands = {[testenv:flake8]commands}
 
 [testenv:venv]
@@ -148,25 +136,27 @@ commands = {posargs}
 # 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
+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
-        bandit
-
 commands = bandit --ini tox.ini -n 5 -r k8sapp_platform
 
 [testenv:pylint]
-deps = {[testenv]deps}
-       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_platform --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
@@ -188,3 +178,11 @@ commands =
 deps = pip_missing_reqs
        -rrequirements.txt
 commands=pip-missing-reqs -d --ignore-file=/k8sapp_platform/tests k8sapp_platform
+
+[testenv:metadata]
+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}
+# Pass top level app folder to 'sysinv-app tox' command.
+commands =
+  bash -c "echo $(dirname $(dirname $(pwd))) | xargs -n 1 sysinv-app tox"
\ No newline at end of file
diff --git a/stx-platform-helm/debian/deb_folder/rules b/stx-platform-helm/debian/deb_folder/rules
index 38f2eb3..72dc3ce 100755
--- a/stx-platform-helm/debian/deb_folder/rules
+++ b/stx-platform-helm/debian/deb_folder/rules
@@ -31,9 +31,9 @@ override_dh_auto_build:
 	cp /usr/lib/helm/ceph-csi-*.tgz $(STAGING_FLUXCD)/charts
 
 	# Populate metadata.
-	sed -i 's/@APP_NAME@/$(APP_NAME)/g' $(STAGING_FLUXCD)/metadata.yaml
-	sed -i 's/@APP_VERSION@/$(APP_VERSION)/g' $(STAGING_FLUXCD)/metadata.yaml
-	sed -i 's/@HELM_REPO@/$(HELM_REPO)/g' $(STAGING_FLUXCD)/metadata.yaml
+	sed -i 's/APP_REPLACE_NAME/$(APP_NAME)/g' $(STAGING_FLUXCD)/metadata.yaml
+	sed -i 's/APP_REPLACE_VERSION/$(APP_VERSION)/g' $(STAGING_FLUXCD)/metadata.yaml
+	sed -i 's/HELM_REPLACE_REPO/$(HELM_REPO)/g' $(STAGING_FLUXCD)/metadata.yaml
 
 	# Copy the plugins: installed in the buildroot
 	mkdir -p $(STAGING_FLUXCD)/plugins
diff --git a/stx-platform-helm/stx-platform-helm/files/metadata.yaml b/stx-platform-helm/stx-platform-helm/files/metadata.yaml
index 9254772..8e7e5b4 100644
--- a/stx-platform-helm/stx-platform-helm/files/metadata.yaml
+++ b/stx-platform-helm/stx-platform-helm/files/metadata.yaml
@@ -1,6 +1,6 @@
-app_name: @APP_NAME@
-app_version: @APP_VERSION@
-helm_repo: @HELM_REPO@
+app_name: APP_REPLACE_NAME
+app_version: APP_REPLACE_VERSION
+helm_repo: HELM_REPLACE_REPO
 maintain_user_overrides: true
 
 upgrades:
diff --git a/tox.ini b/tox.ini
index 97252e8..feb7435 100644
--- a/tox.ini
+++ b/tox.ini
@@ -21,6 +21,22 @@ deps =
 allowlist_externals =
   bash
 
+[testenv:flake8]
+basepython = python3
+description = Dummy environment to allow flake8 to be run in subdir tox
+
+[testenv:pylint]
+basepython = python3
+description = Dummy environment to allow pylint to be run in subdir tox
+
+[testenv:metadata]
+basepython = python3
+description = Dummy environment to allow sysinv-app to be run in subdir tox
+
+[testenv:bandit]
+basepython = python3
+description = Dummy environment to allow bandit to be run in subdir tox
+
 [testenv:bashate]
 # Treat all E* codes as Errors rather than warnings using: -e 'E*'
 commands =
@@ -36,12 +52,3 @@ commands =
 [testenv:linters]
 commands =
     {[testenv:bashate]commands}
-
-[testenv:flake8]
-description = Dummy environment to allow flake8 to be run in subdir tox
-
-[testenv:pylint]
-description = Dummy environment to allow pylint to be run in subdir tox
-
-[testenv:bandit]
-description = Dummy environment to allow bandit to be run in subdir tox