diff --git a/.zuul.yaml b/.zuul.yaml
new file mode 100644
index 0000000..7dd42ac
--- /dev/null
+++ b/.zuul.yaml
@@ -0,0 +1,103 @@
+---
+- project:
+    check:
+      jobs:
+        - openstack-tox-linters
+    gate:
+      jobs:
+        - openstack-tox-linters
+    post:
+      jobs:
+        - stx-vault-armada-app-upload-git-mirror
+
+- job:
+    name: stx-vault-armada-app-upload-git-mirror
+    parent: upload-git-mirror
+    description: >
+      Mirrors opendev.org/starlingx/vault-armada-app to
+      github.com/starlingx/vault-armada-app
+    vars:
+      git_mirror_repository: starlingx/vault-armada-app
+    secrets:
+      - name: git_mirror_credentials
+        secret: stx-vault-armada-app-github-secret
+        pass-to-parent: true
+
+- secret:
+    name: stx-vault-armada-app-github-secret
+    data:
+      user: git
+      host: github.com
+      # yamllint disable-line rule:line-length
+      host_key: github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
+      ssh_key: !encrypted/pkcs1-oaep
+        - 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 
\ No newline at end of file
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 0000000..f2f8e6d
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,16 @@
+If you would like to contribute to the development of OpenStack,
+you must follow the steps in this page:
+
+   https://docs.openstack.org/infra/manual/developers.html
+
+Once those steps have been completed, changes to OpenStack
+should be submitted for review via the Gerrit tool, following
+the workflow documented at:
+
+   https://docs.openstack.org/infra/manual/developers.html#development-workflow
+
+Pull requests submitted through GitHub will be ignored.
+
+Bugs should be filed in Launchpad:
+
+   https://bugs.launchpad.net/starlingx
diff --git a/HACKING.rst b/HACKING.rst
new file mode 100644
index 0000000..61c83c5
--- /dev/null
+++ b/HACKING.rst
@@ -0,0 +1,17 @@
+StarlingX Vault-Armada-App Style Commandments
+================================================================
+
+- Step 1: Read the OpenStack style commandments
+  https://docs.openstack.org/hacking/latest/
+- Step 2: Read on
+
+Vault-Armada-App Specific Commandments
+---------------------------------------------------------
+
+None so far
+
+Running tests
+-------------
+The approach to running tests is to simply run the command ``tox``. This will
+create virtual environments, populate them with dependencies and run all of
+the tests that OpenStack CI systems run.
diff --git a/centos_build_layer.cfg b/centos_build_layer.cfg
new file mode 100644
index 0000000..c581999
--- /dev/null
+++ b/centos_build_layer.cfg
@@ -0,0 +1 @@
+flock
diff --git a/centos_iso_image.inc b/centos_iso_image.inc
new file mode 100644
index 0000000..9ce391d
--- /dev/null
+++ b/centos_iso_image.inc
@@ -0,0 +1 @@
+stx-vault-helm
diff --git a/centos_pkg_dirs b/centos_pkg_dirs
new file mode 100644
index 0000000..4c7c598
--- /dev/null
+++ b/centos_pkg_dirs
@@ -0,0 +1,2 @@
+stx-vault-helm
+python-k8sapp-vault
\ No newline at end of file
diff --git a/centos_pkg_dirs_containers b/centos_pkg_dirs_containers
new file mode 100644
index 0000000..4c7c598
--- /dev/null
+++ b/centos_pkg_dirs_containers
@@ -0,0 +1,2 @@
+stx-vault-helm
+python-k8sapp-vault
\ No newline at end of file
diff --git a/centos_tarball-dl.lst b/centos_tarball-dl.lst
new file mode 100644
index 0000000..40b11f5
--- /dev/null
+++ b/centos_tarball-dl.lst
@@ -0,0 +1 @@
+helm-charts-vault-0-6-0.tar.gz#helm-charts-vault#https://github.com/hashicorp/vault-helm/archive/v0.6.0.tar.gz#http##
diff --git a/config b/config
new file mode 100644
index 0000000..6c566d9
--- /dev/null
+++ b/config
@@ -0,0 +1,12 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+[remote "origin"]
+	url = https://review.opendev.org/starlingx/vault-armada-app.git
+	fetch = +refs/heads/*:refs/remotes/origin/*
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master
+	rebase = true
diff --git a/github_sync.trigger b/github_sync.trigger
new file mode 100644
index 0000000..b8a4ee2
--- /dev/null
+++ b/github_sync.trigger
@@ -0,0 +1,2 @@
+# to trigger the upload job to sync to GitHub
+1
diff --git a/python-k8sapp-vault/centos/build_srpm.data b/python-k8sapp-vault/centos/build_srpm.data
new file mode 100644
index 0000000..302126a
--- /dev/null
+++ b/python-k8sapp-vault/centos/build_srpm.data
@@ -0,0 +1,7 @@
+SRC_DIR="k8sapp_vault"
+
+# Keep the SRCREV in sync with stx-vault-helm so the app version is the
+# same as the plugin version
+#TIS_BASE_SRCREV=94d4c26f982e2e8c222517900c504580d1e3a09d
+#TIS_PATCH_VER=GITREVCOUNT
+TIS_PATCH_VER=0
diff --git a/python-k8sapp-vault/centos/python-k8sapp-vault.spec b/python-k8sapp-vault/centos/python-k8sapp-vault.spec
new file mode 100644
index 0000000..94cb728
--- /dev/null
+++ b/python-k8sapp-vault/centos/python-k8sapp-vault.spec
@@ -0,0 +1,61 @@
+%global app_name vault
+%global pypi_name k8sapp-vault
+%global sname k8sapp_vault
+
+Name:           python-%{pypi_name}
+Version:        20.06
+Release:        %{tis_patch_ver}%{?_tis_dist}
+Summary:        StarlingX sysinv extensions: Vault
+
+License:        Apache-2.0
+Source0:        %{name}-%{version}.tar.gz
+
+BuildArch:      noarch
+
+BuildRequires: python-setuptools
+BuildRequires: python-pbr
+BuildRequires: python2-pip
+BuildRequires: python2-wheel
+
+%description
+StarlingX sysinv extensions: Vault K8S app
+
+%package -n     python2-%{pypi_name}
+Summary:        StarlingX sysinv extensions: Vault K8S app
+
+Requires:       python-pbr >= 2.0.0
+Requires:       sysinv >= 1.0
+
+%description -n python2-%{pypi_name}
+StarlingX sysinv extensions: Vault K8S app
+
+%prep
+%setup
+# Remove bundled egg-info
+rm -rf %{pypi_name}.egg-info
+
+%build
+export PBR_VERSION=%{version}
+%{__python2} setup.py build
+
+%py2_build_wheel
+
+%install
+export PBR_VERSION=%{version}.%{tis_patch_ver}
+export SKIP_PIP_INSTALL=1
+%{__python2} setup.py install --skip-build --root %{buildroot}
+mkdir -p ${RPM_BUILD_ROOT}/plugins/%{app_name}
+install -m 644 dist/*.whl ${RPM_BUILD_ROOT}/plugins/%{app_name}/
+
+%files
+%{python2_sitelib}/%{sname}
+%{python2_sitelib}/%{sname}-*.egg-info
+
+%package wheels
+Summary: %{name} wheels
+
+%description wheels
+Contains python wheels for %{name}
+
+%files wheels
+/plugins/*
diff --git a/python-k8sapp-vault/k8sapp_vault/.gitignore b/python-k8sapp-vault/k8sapp_vault/.gitignore
new file mode 100644
index 0000000..78c457c
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/.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
diff --git a/python-k8sapp-vault/k8sapp_vault/.stestr.conf b/python-k8sapp-vault/k8sapp_vault/.stestr.conf
new file mode 100644
index 0000000..d1ac0a0
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/.stestr.conf
@@ -0,0 +1,4 @@
+[DEFAULT]
+test_path=./k8sapp_vault/tests
+top_dir=./k8sapp_vault
+#parallel_class=True
diff --git a/python-k8sapp-vault/k8sapp_vault/LICENSE b/python-k8sapp-vault/k8sapp_vault/LICENSE
new file mode 100644
index 0000000..d6e2801
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2019 Wind River Systems, Inc.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/python-k8sapp-vault/k8sapp_vault/README.rst b/python-k8sapp-vault/k8sapp_vault/README.rst
new file mode 100644
index 0000000..865d801
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/README.rst
@@ -0,0 +1,7 @@
+k8sapp-vault
+===================
+
+This project contains StarlingX Kubernetes application specific python plugins
+for Vault. These plugins are required to integrate the oidc authorization 
+application into the StarlingX application framework and to support the 
+various StarlingX deployments.
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/__init__.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/common/__init__.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/common/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/common/constants.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/common/constants.py
new file mode 100644
index 0000000..7e7603a
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/common/constants.py
@@ -0,0 +1,10 @@
+#
+# Copyright (c) 2020 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+# Helm: Supported charts:
+# These values match the names in the chart package's Chart.yaml
+HELM_CHART_VAULT = 'vault'
+HELM_CHART_PSP_ROLEBINDING = 'psp-rolebinding'
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/__init__.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/psp_rolebinding.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/psp_rolebinding.py
new file mode 100644
index 0000000..7af36b2
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/psp_rolebinding.py
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2020 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+from k8sapp_vault.common import constants as app_constants
+
+from sysinv.common import constants
+from sysinv.common import exception
+
+from sysinv.helm import base
+from sysinv.helm import common
+
+
+class PSPRolebindingHelm(base.BaseHelm):
+    """Class to encapsulate helm operations for the psp rolebinding chart"""
+
+    SUPPORTED_NAMESPACES = base.BaseHelm.SUPPORTED_NAMESPACES + \
+        [common.HELM_NS_VAULT]
+    SUPPORTED_APP_NAMESPACES = {
+        constants.HELM_APP_VAULT:
+            base.BaseHelm.SUPPORTED_NAMESPACES + [common.HELM_NS_VAULT],
+    }
+
+    CHART = app_constants.HELM_CHART_PSP_ROLEBINDING
+    SERVICE_NAME = 'psp-rolebinding'
+
+    def get_namespaces(self):
+        return self.SUPPORTED_NAMESPACES
+
+    def get_overrides(self, namespace=None):
+        overrides = {
+            common.HELM_NS_VAULT: {}
+        }
+
+        if namespace in self.SUPPORTED_NAMESPACES:
+            return overrides[namespace]
+        elif namespace:
+            raise exception.InvalidHelmNamespace(chart=self.CHART,
+                                                 namespace=namespace)
+        else:
+            return overrides
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/vault.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/vault.py
new file mode 100644
index 0000000..fc7593f
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/helm/vault.py
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2020 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+from k8sapp_vault.common import constants as app_constants
+
+from sysinv.common import constants
+from sysinv.common import exception
+
+from sysinv.helm import base
+from sysinv.helm import common
+
+
+class VaultHelm(base.BaseHelm):
+    """Class to encapsulate helm operations for the vault chart"""
+
+    SUPPORTED_NAMESPACES = base.BaseHelm.SUPPORTED_NAMESPACES + \
+        [common.HELM_NS_VAULT]
+    SUPPORTED_APP_NAMESPACES = {
+        constants.HELM_APP_VAULT:
+            base.BaseHelm.SUPPORTED_NAMESPACES + [common.HELM_NS_VAULT],
+    }
+
+    CHART = app_constants.HELM_CHART_VAULT
+
+    SERVICE_NAME = 'vault'
+
+    def get_namespaces(self):
+        return self.SUPPORTED_NAMESPACES
+
+    def get_overrides(self, namespace=None):
+
+        overrides = {
+            common.HELM_NS_VAULT: {
+                'server': {
+                    'ha': {
+                        'replicas': max(1, self._num_provisioned_controllers()),
+                    },
+                },
+            }
+        }
+
+        if namespace in self.SUPPORTED_NAMESPACES:
+            return overrides[namespace]
+        elif namespace:
+            raise exception.InvalidHelmNamespace(chart=self.CHART,
+                                                 namespace=namespace)
+        else:
+            return overrides
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/__init__.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/test_plugins.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/test_plugins.py
new file mode 100644
index 0000000..9968d73
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/test_plugins.py
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2020 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+from sysinv.common import constants
+from sysinv.tests.db import base as dbbase
+from sysinv.tests.helm.test_helm import HelmOperatorTestSuiteMixin
+
+
+class K8SAppVaultAppMixin(object):
+    app_name = constants.HELM_APP_VAULT
+    path_name = app_name + '.tgz'
+
+    def setUp(self):
+        super(K8SAppVaultAppMixin, self).setUp()
+
+
+# Test Configuration:
+# - Controller
+# - IPv6
+# - Ceph Storage
+# - vault app
+class K8sAppVaultControllerTestCase(K8SAppVaultAppMixin,
+                                      dbbase.BaseIPv6Mixin,
+                                      dbbase.BaseCephStorageBackendMixin,
+                                      HelmOperatorTestSuiteMixin,
+                                      dbbase.ControllerHostTestCase):
+    pass
+
+
+# Test Configuration:
+# - AIO
+# - IPv4
+# - Ceph Storage
+# - vault app
+class K8SAppVaultAIOTestCase(K8SAppVaultAppMixin,
+                               dbbase.BaseCephStorageBackendMixin,
+                               HelmOperatorTestSuiteMixin,
+                               dbbase.AIOSimplexHostTestCase):
+    pass
diff --git a/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/test_vault.py b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/test_vault.py
new file mode 100644
index 0000000..3813ad6
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/k8sapp_vault/tests/test_vault.py
@@ -0,0 +1,51 @@
+# Copyright (c) 2020 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+from k8sapp_vault.common import constants as app_constants
+from k8sapp_vault.tests import test_plugins
+
+from sysinv.db import api as dbapi
+from sysinv.helm import common
+
+from sysinv.tests.db import base as dbbase
+from sysinv.tests.db import utils as dbutils
+from sysinv.tests.helm import base
+
+
+class VaultTestCase(test_plugins.K8SAppVaultAppMixin,
+                          base.HelmTestCaseMixin):
+
+    def setUp(self):
+        super(VaultTestCase, self).setUp()
+        self.app = dbutils.create_test_app(name='vault')
+        self.dbapi = dbapi.get_instance()
+
+
+class VaultIPv4ControllerHostTestCase(VaultTestCase,
+                                            dbbase.ProvisionedControllerHostTestCase):
+
+    def test_replicas(self):
+        overrides = self.operator.get_helm_chart_overrides(
+            app_constants.HELM_CHART_VAULT,
+            cnamespace=common.HELM_NS_VAULT)
+
+        self.assertOverridesParameters(overrides, {
+            # 1 replica for 1 controller
+            'replicaCount': 1
+        })
+
+
+class VaultIPv6AIODuplexSystemTestCase(VaultTestCase,
+                                             dbbase.BaseIPv6Mixin,
+                                             dbbase.ProvisionedAIODuplexSystemTestCase):
+
+    def test_replicas(self):
+        overrides = self.operator.get_helm_chart_overrides(
+            app_constants.HELM_CHART_VAULT,
+            cnamespace=common.HELM_NS_VAULT)
+
+        self.assertOverridesParameters(overrides, {
+            # 2 replicas for 2 controllers
+            'replicaCount': 2
+        })
diff --git a/python-k8sapp-vault/k8sapp_vault/pylint.rc b/python-k8sapp-vault/k8sapp_vault/pylint.rc
new file mode 100644
index 0000000..6e869c3
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/pylint.rc
@@ -0,0 +1,238 @@
+[MASTER]
+# Specify a configuration file.
+rcfile=pylint.rc
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Add files or directories to the blacklist. Should be base names, not paths.
+ignore=tests
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Use multiple processes to speed up Pylint.
+jobs=4
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code
+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.
+#enable=
+
+# 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
+disable=C, R
+
+[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
+
+# 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
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+
+[SIMILARITIES]
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+
+[FORMAT]
+# Maximum number of characters on a single line.
+max-line-length=85
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually 4 spaces or "\t" (1 tab).
+indent-string='    '
+
+
+[TYPECHECK]
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis
+ignored-modules=distutils,eventlet.green.subprocess,six,six.moves
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+# pylint is confused by sqlalchemy Table, as well as sqlalchemy Enum types
+# ie: (unprovisioned, identity)
+# LookupDict in requests library confuses pylint
+ignored-classes=SQLObject, optparse.Values, thread._local, _thread._local,
+                Table, unprovisioned, identity, LookupDict
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed. Python regular
+# expressions are accepted.
+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]+))$
+
+# Regular expression which should only match correct module level names
+const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+
+# Regular expression which should only match correct class names
+class-rgx=[A-Z_][a-zA-Z0-9]+$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# Regular expression which should only match functions or classes name which do
+# not require a docstring
+no-docstring-rgx=__.*__
+
+
+[MISCELLANEOUS]
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,XXX,TODO
+
+
+[VARIABLES]
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching the beginning of the name of dummy variables
+# (i.e. not used).
+dummy-variables-rgx=_|dummy
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+
+[IMPORTS]
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+
+[DESIGN]
+# Maximum number of arguments for function / method
+max-args=5
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branchs=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+
+[CLASSES]
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+
+[EXCEPTIONS]
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=Exception
diff --git a/python-k8sapp-vault/k8sapp_vault/requirements.txt b/python-k8sapp-vault/k8sapp_vault/requirements.txt
new file mode 100644
index 0000000..e71df21
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/requirements.txt
@@ -0,0 +1,2 @@
+pbr>=2.0.0
+PyYAML==3.10
diff --git a/python-k8sapp-vault/k8sapp_vault/setup.cfg b/python-k8sapp-vault/k8sapp_vault/setup.cfg
new file mode 100644
index 0000000..2f68f3c
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/setup.cfg
@@ -0,0 +1,40 @@
+[metadata]
+name = k8sapp-vault
+summary = StarlingX sysinv extensions for vault
+long_description = file: README.rst
+long_description_content_type = text/x-rst
+license = Apache 2.0
+author = StarlingX
+author-email = starlingx-discuss@lists.starlingx.io
+home-page = https://www.starlingx.io/
+classifier =
+    Environment :: OpenStack
+    Intended Audience :: Information Technology
+    Intended Audience :: System Administrators
+    License :: OSI Approved :: Apache Software License
+    Operating System :: POSIX :: Linux
+    Programming Language :: Python
+    Programming Language :: Python :: 2
+    Programming Language :: Python :: 2.7
+    Programming Language :: Python :: 3
+    Programming Language :: Python :: 3.4
+    Programming Language :: Python :: 3.5
+
+[files]
+packages =
+    k8sapp_vault
+
+[global]
+setup-hooks =
+    pbr.hooks.setup_hook
+
+[entry_points]
+systemconfig.helm_applications =
+    vault = systemconfig.helm_plugins.vault
+
+systemconfig.helm_plugins.vault =
+    001_vault = k8sapp_vault.helm.vault:VaultHelm
+    002_psp-rolebinding = k8sapp_vault.helm.psp_rolebinding:PSPRolebindingHelm
+
+[wheel]
+universal = 1
diff --git a/python-k8sapp-vault/k8sapp_vault/setup.py b/python-k8sapp-vault/k8sapp_vault/setup.py
new file mode 100644
index 0000000..e8729b8
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/setup.py
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2020 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+import setuptools
+
+
+setuptools.setup(
+    setup_requires=['pbr>=2.0.0'],
+    pbr=True)
diff --git a/python-k8sapp-vault/k8sapp_vault/test-requirements.txt b/python-k8sapp-vault/k8sapp_vault/test-requirements.txt
new file mode 100644
index 0000000..e248a36
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/test-requirements.txt
@@ -0,0 +1,26 @@
+# 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
+coverage>=3.6
+discover
+fixtures>=3.0.0 # Apache-2.0/BSD
+mock>=2.0.0 # BSD
+passlib>=1.7.0
+psycopg2-binary
+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
+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
+markupsafe
diff --git a/python-k8sapp-vault/k8sapp_vault/tox.ini b/python-k8sapp-vault/k8sapp_vault/tox.ini
new file mode 100644
index 0000000..4cc980f
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/tox.ini
@@ -0,0 +1,131 @@
+[tox]
+envlist = flake8,py27,py36,pylint,bandit
+minversion = 1.6
+# skipsdist = True
+#,pip-missing-reqs
+
+# tox does not work if the path to the workdir is too long, so move it to /tmp
+toxworkdir = /tmp/{env:USER}_k8svaulttox
+stxdir = {toxinidir}/../../..
+distshare={toxworkdir}/.tox/distshare
+
+[testenv]
+# usedevelop = True
+# 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 true and rpm-python must be yum installed on your dev machine.
+sitepackages = True
+
+# tox is silly... these need to be separated by a newline....
+whitelist_externals = bash
+                      find
+
+install_command = pip install \
+    -v -v -v \
+    -c{toxinidir}/upper-constraints.txt \
+    -c{env:UPPER_CONSTRAINTS_FILE:https://opendev.org/openstack/requirements/raw/branch/stable/stein/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
+         PYTHONDONTWRITEBYTECODE=1
+         OS_TEST_PATH=./k8sapp_vault/tests
+         LANG=en_US.UTF-8
+         LANGUAGE=en_US:en
+         LC_ALL=C
+         EVENTS_YAML=./k8sapp_vault/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
+       -e{[tox]stxdir}/fault/python-fmclient/fmclient
+       -e{[tox]stxdir}/utilities/ceph/python-cephclient/python-cephclient
+       -e{[tox]stxdir}/update/cgcs-patch/cgcs-patch
+
+
+commands =
+  find . -type f -name "*.pyc" -delete
+
+[flake8]
+exclude = build,dist,tools,.eggs
+max-line-length=120
+
+[testenv:flake8]
+basepython = python3
+deps = -r{toxinidir}/test-requirements.txt
+       flake8-bugbear
+commands =
+  flake8 {posargs} .
+
+[testenv:py27]
+basepython = python2.7
+commands =
+  {[testenv]commands}
+  stestr run {posargs}
+  stestr slowest
+
+[testenv:py36]
+basepython = python3.6
+commands =
+  {[testenv]commands}
+  stestr run {posargs}
+  stestr slowest
+
+[testenv:pep8]
+# testenv:flake8 clone
+basepython = {[testenv:flake8]basepython}
+deps = {[testenv:flake8]deps}
+commands = {[testenv:flake8]commands}
+
+[testenv:venv]
+commands = {posargs}
+
+[bandit]
+
+[testenv:bandit]
+basepython = python3
+deps = -r{toxinidir}/test-requirements.txt
+        bandit
+
+commands = bandit --ini tox.ini -n 5 -r k8sapp_vault
+
+[testenv:pylint]
+basepython = python2.7
+sitepackages = False
+
+deps = {[testenv]deps}
+       pylint
+commands =
+     pylint {posargs} k8sapp_vault --rcfile=./pylint.rc
+
+[testenv:cover]
+basepython = python2.7
+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_vault/tests k8sapp_vault
diff --git a/python-k8sapp-vault/k8sapp_vault/upper-constraints.txt b/python-k8sapp-vault/k8sapp_vault/upper-constraints.txt
new file mode 100644
index 0000000..9c30188
--- /dev/null
+++ b/python-k8sapp-vault/k8sapp_vault/upper-constraints.txt
@@ -0,0 +1 @@
+# Override upstream constraints based on StarlingX load
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..c01ade2
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+# Nothing
diff --git a/stx-vault-helm/centos/build_srpm.data b/stx-vault-helm/centos/build_srpm.data
new file mode 100644
index 0000000..23ca50f
--- /dev/null
+++ b/stx-vault-helm/centos/build_srpm.data
@@ -0,0 +1,14 @@
+SRC_DIR="stx-vault-helm"
+
+TAR_NAME=helm-charts-vault-0-6-0
+VERSION=1.0.0
+TAR="$TAR_NAME.tar.gz"
+
+COPY_LIST="${CGCS_BASE}/downloads/$TAR $PKG_BASE/$SRC_DIR/files/* $PKG_BASE/$SRC_DIR/manifests/*"
+
+TIS_PATCH_VER=0
+
+# Keep the SRCREV in sync with python-k8sapp-cert-manager so the app version is
+# the same as the plugin version
+#TIS_BASE_SRCREV=94d4c26f982e2e8c222517900c504580d1e3a09d
+#TIS_PATCH_VER=GITREVCOUNT
\ No newline at end of file
diff --git a/stx-vault-helm/centos/stx-vault-helm.spec b/stx-vault-helm/centos/stx-vault-helm.spec
new file mode 100644
index 0000000..31c3ed4
--- /dev/null
+++ b/stx-vault-helm/centos/stx-vault-helm.spec
@@ -0,0 +1,116 @@
+# Application tunables (maps to metadata)
+%global app_name vault
+%global helm_repo stx-platform
+
+%global armada_folder  /usr/lib/armada
+
+# Install location
+%global app_folder /usr/local/share/applications/helm
+
+# Build variables
+%global helm_folder /usr/lib/helm
+%global toolkit_version 0.1.0
+
+Summary: StarlingX Vault Armada Helm Charts
+Name: stx-vault-helm
+Version: 1.0
+Release: %{tis_patch_ver}%{?_tis_dist}
+License: Apache-2.0
+Group: base
+Packager: Wind River <info@windriver.com>
+URL: unknown
+
+Source0: helm-charts-vault-0-6-0.tar.gz
+Source1: repositories.yaml
+Source2: index.yaml
+Source3: Makefile
+Source4: metadata.yaml
+Source5: vault_manifest.yaml
+
+BuildArch: noarch
+
+BuildRequires: helm
+BuildRequires: python-k8sapp-vault
+BuildRequires: python-k8sapp-vault-wheels
+
+%description
+StarlingX Vault Helm Charts
+
+%prep
+%setup -n helm-charts-vault
+
+%build
+# initialize helm and build the toolkit
+# helm init --client-only does not work if there is no networking
+# The following commands do essentially the same as: helm init
+%define helm_home  %{getenv:HOME}/.helm
+mkdir  %{helm_home}
+mkdir  %{helm_home}/repository
+mkdir  %{helm_home}/repository/cache
+mkdir  %{helm_home}/repository/local
+mkdir  %{helm_home}/plugins
+mkdir  %{helm_home}/starters
+mkdir  %{helm_home}/cache
+mkdir  %{helm_home}/cache/archive
+
+# Stage a repository file that only has a local repo
+cp %{SOURCE1} %{helm_home}/repository/repositories.yaml
+
+# Stage a local repo index that can be updated by the build
+cp %{SOURCE2} %{helm_home}/repository/local/index.yaml
+
+# Host a server for the charts
+helm serve --repo-path . &
+helm repo rm local
+helm repo add local http://localhost:8879/charts
+
+# Create the tgz file
+cp %{SOURCE3} ./
+mkdir ./vault
+cp ./Chart.yaml ./vault
+mv ./values.yaml ./vault
+mv ./templates ./vault/templates
+
+make vault
+make psp-rolebinding
+cd -
+
+# Terminate helm server (the last backgrounded task)
+kill %1
+
+# Create a chart tarball compliant with sysinv kube-app.py
+%define app_staging %{_builddir}/staging
+%define app_tarball %{app_name}-%{version}-%{tis_patch_ver}.tgz
+
+# Setup staging
+mkdir -p %{app_staging}
+cp %{SOURCE4} %{app_staging}
+cp %{SOURCE5} %{app_staging}
+mkdir -p %{app_staging}/charts
+cp ./helm-charts-vault/*.tgz %{app_staging}/charts
+cd %{app_staging}
+
+# Populate metadata
+sed -i 's/@APP_NAME@/%{app_name}/g' %{app_staging}/metadata.yaml
+sed -i 's/@APP_VERSION@/%{version}-%{tis_patch_ver}/g' %{app_staging}/metadata.yaml
+sed -i 's/@HELM_REPO@/%{helm_repo}/g' %{app_staging}/metadata.yaml
+
+
+# Copy the plugins: installed in the buildroot
+mkdir -p %{app_staging}/plugins
+cp /plugins/%{app_name}/*.whl %{app_staging}/plugins
+
+# package it up
+find . -type f ! -name '*.md5' -print0 | xargs -0 md5sum > checksum.md5
+tar -zcf %{_builddir}/%{app_tarball} -C %{app_staging}/ .
+
+# Cleanup staging
+rm -fr %{app_staging}
+
+%install
+install -d -m 755 %{buildroot}/%{app_folder}
+install -p -D -m 755 %{_builddir}/%{app_tarball} %{buildroot}/%{app_folder}
+
+%files
+%defattr(-,root,root,-)
+%{app_folder}/*
diff --git a/stx-vault-helm/stx-vault-helm/README b/stx-vault-helm/stx-vault-helm/README
new file mode 100644
index 0000000..b773ef4
--- /dev/null
+++ b/stx-vault-helm/stx-vault-helm/README
@@ -0,0 +1,5 @@
+This directory contains all StarlingX charts that need to be built for this
+application. Some charts are common across applications. These common charts
+reside in the stx-config/kubernetes/helm-charts directory. To include these in
+this application update the build_srpm.data file and use the COPY_LIST_TO_TAR
+mechanism to populate these common charts.
diff --git a/stx-vault-helm/stx-vault-helm/files/Makefile b/stx-vault-helm/stx-vault-helm/files/Makefile
new file mode 100644
index 0000000..03a3bb5
--- /dev/null
+++ b/stx-vault-helm/stx-vault-helm/files/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright 2017 The Openstack-Helm Authors.
+#
+# Copyright (c) 2019 Wind River Systems, Inc.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# It's necessary to set this because some environments don't link sh -> bash.
+SHELL := /bin/bash
+TASK  := build
+
+EXCLUDES := helm-toolkit doc tests tools logs tmp
+CHARTS := helm-toolkit $(filter-out $(EXCLUDES), $(patsubst %/.,%,$(wildcard */.)))
+
+.PHONY: $(EXCLUDES) $(CHARTS)
+
+all: $(CHARTS)
+
+$(CHARTS):
+	@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
+
+lint-%: init-%
+	if [ -d $* ]; then helm lint $*; fi
+
+build-%: 
+	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
+
+%:
+	@:
diff --git a/stx-vault-helm/stx-vault-helm/files/index.yaml b/stx-vault-helm/stx-vault-helm/files/index.yaml
new file mode 100644
index 0000000..36db709
--- /dev/null
+++ b/stx-vault-helm/stx-vault-helm/files/index.yaml
@@ -0,0 +1,3 @@
+apiVersion: v1
+entries: {}
+generated: 2019-01-07T12:33:46.098166523-06:00
diff --git a/stx-vault-helm/stx-vault-helm/files/metadata.yaml b/stx-vault-helm/stx-vault-helm/files/metadata.yaml
new file mode 100644
index 0000000..8a9e1c8
--- /dev/null
+++ b/stx-vault-helm/stx-vault-helm/files/metadata.yaml
@@ -0,0 +1,6 @@
+maintain_user_overrides: true
+
+app_name: @APP_NAME@
+app_version: @APP_VERSION@
+helm_repo: @HELM_REPO@
+
diff --git a/stx-vault-helm/stx-vault-helm/files/repositories.yaml b/stx-vault-helm/stx-vault-helm/files/repositories.yaml
new file mode 100644
index 0000000..e613b63
--- /dev/null
+++ b/stx-vault-helm/stx-vault-helm/files/repositories.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+generated: 2019-01-02T15:19:36.215111369-06:00
+repositories:
+- caFile: ""
+  cache: /builddir/.helm/repository/cache/local-index.yaml
+  certFile: ""
+  keyFile: ""
+  name: local
+  password: ""
+  url: http://127.0.0.1:8879/charts
+  username: ""
+
diff --git a/stx-vault-helm/stx-vault-helm/manifests/vault_manifest.yaml b/stx-vault-helm/stx-vault-helm/manifests/vault_manifest.yaml
new file mode 100644
index 0000000..24252b8
--- /dev/null
+++ b/stx-vault-helm/stx-vault-helm/manifests/vault_manifest.yaml
@@ -0,0 +1,72 @@
+---
+schema: armada/Chart/v1
+metadata:
+  schema: metadata/Document/v1
+  name: vault
+data:
+  chart_name: vault
+  release: vault
+  namespace: vault
+  wait:
+    timeout: 1800
+    labels:
+      app: vault
+  install:
+    no_hooks: false
+  upgrade:
+    no_hooks: false
+    pre:
+      delete:
+        - type: job
+          labels:
+            app: vault
+  values:
+    global:
+      enabled: true
+    injector:
+      enabled: true
+      image:
+        repository: hashicorp/vault-k8s
+        tag: 0.4.0
+      agentImage:
+        repository: vault
+        tag: 1.4.2
+    server:
+      image:
+        repository: vault
+        tag: 1.4.2
+      auditStorage:
+        enabled: true
+        size: 10Gi
+      ha:
+        enabled: true
+        replicas: 3
+        raft:
+          enabled: true
+      extraLabels:
+        app: vault
+  source:
+    type: tar
+    location: http://172.17.0.1/helm_charts/stx-platform/vault-0.6.0.tgz
+    subpath: vault
+    reference: master
+  dependencies: []
+---
+schema: armada/ChartGroup/v1
+metadata:
+  schema: metadata/Document/v1
+  name: vault
+data:
+  description: "Deploy Vault"
+  sequenced: false
+  chart_group:
+    - vault
+---
+schema: armada/Manifest/v1
+metadata:
+  schema: metadata/Document/v1
+  name: vault-manifest
+data:
+  release_prefix: stx
+  chart_groups:
+    - vault
\ No newline at end of file
diff --git a/test-requirements.txt b/test-requirements.txt
new file mode 100644
index 0000000..8ae3e22
--- /dev/null
+++ b/test-requirements.txt
@@ -0,0 +1,3 @@
+# hacking pulls in flake8
+hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
+bashate >= 0.2
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..cede375
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,35 @@
+[tox]
+envlist = linters
+minversion = 2.3
+skipsdist = True
+sitepackages=False
+
+[testenv]
+install_command = pip install -U {opts} {packages}
+setenv =
+   VIRTUAL_ENV={envdir}
+   OS_STDOUT_CAPTURE=1
+   OS_STDERR_CAPTURE=1
+   OS_DEBUG=1
+   OS_LOG_CAPTURE=1
+deps =
+  -r{toxinidir}/requirements.txt
+  -r{toxinidir}/test-requirements.txt
+whitelist_externals =
+  bash
+
+[testenv:bashate]
+# Treat all E* codes as Errors rather than warnings using: -e 'E*'
+commands =
+  bash -c "find {toxinidir}                    \
+         -not \( -type d -name .?\* -prune \) \
+         -type f                              \
+         -not -name \*~                       \
+         -not -name \*.md                     \
+         -name \*.sh                          \
+         -print0 | xargs -r -n 1 -0 bashate -v   \
+         -e 'E*'"
+
+[testenv:linters]
+commands =
+    {[testenv:bashate]commands}