Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental changes from OmegaConf work #1173 #1175

Merged
merged 8 commits into from
May 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions .github/workflows/test-build-publish.yml
Original file line number Diff line number Diff line change
@@ -50,33 +50,36 @@ jobs:
fail-fast: false
matrix:
python-version: ['3.10', '3.11']

steps:
- name: Checkout kapitan recursively
uses: actions/checkout@v4
with:
submodules: recursive

- name: Install poetry
run: pipx install poetry
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
cache: 'pip'
cache: 'poetry'
python-version: ${{ matrix.python-version }}

- name: Install testing dependencies
- name: Install libraries dependencies
run: |
poetry install --no-root
- name: Install testing dependencies (Helm)
run: |
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 762E3157
sudo apt-get -qq update
sudo apt-get install -y gnupg2 git curl
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
sudo ./get_helm.sh
pip3 install --editable ".[test]"
pip3 install coverage black
- name: Run tests
run: |-
# includes make test
make test_coverage
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
- name: Run pytest
uses: pavelzw/pytest-action@v2
with:
verbose: true
emoji: false
job-summary: true
custom-pytest: poetry run pytest
custom-arguments: '-q'
click-to-expand: true
report-title: 'Kapitan tests'

build:
name: build ${{ matrix.platform }} image
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -10,7 +10,8 @@ RUN apt-get update \
&& apt-get install --no-install-recommends -y \
curl \
build-essential \
git
git \
default-jre

ENV POETRY_VERSION=1.7.1
ENV VIRTUAL_ENV=/opt/venv
3 changes: 2 additions & 1 deletion kapitan/cached.py
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
# SPDX-License-Identifier: Apache-2.0

"cached module"
from argparse import Namespace

inv = {}
inv_cache = {}
@@ -16,7 +17,7 @@
dot_kapitan = {}
ref_controller_obj = None
revealer_obj = None
args = {} # args won't need resetting
args = args = Namespace() # args won't need resetting
inv_sources = set()


32 changes: 16 additions & 16 deletions kapitan/cli.py
Original file line number Diff line number Diff line change
@@ -92,9 +92,9 @@ def trigger_compile(args):
validate=args.validate,
schemas_path=args.schemas_path,
jinja2_filters=args.jinja2_filters,
verbose=hasattr(args, "verbose") and args.verbose,
verbose=args.verbose,
use_go_jsonnet=args.use_go_jsonnet,
compose_target_name=args.compose_target_name,
compose_target_name=args.compose_target_name
)


@@ -111,6 +111,12 @@ def build_parser():
choices=AVAILABLE_BACKENDS.keys(),
help="Select the inventory backend to use (default=reclass)",
)
inventory_backend_parser.add_argument(
"--migrate",
action="store_true",
default=from_dot_kapitan("inventory_backend", "migrate", False),
help="Migrate your inventory to your selected inventory backend.",
)

inventory_backend_parser.add_argument(
"--compose-target-name", "--compose-target-name",
@@ -595,6 +601,7 @@ def build_parser():
"validate",
aliases=["v"],
help="validates the compile output against schemas as specified in inventory",
parents=[inventory_backend_parser]
)
validate_parser.set_defaults(func=schema_validate_compiled, name="validate")

@@ -651,26 +658,19 @@ def main():

logger.debug("Running with args: %s", args)

try:
cmd = sys.argv[1]
except IndexError:
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)

# cache args where key is subcommand
assert "name" in args, "All cli commands must have provided default name"
cached.args[args.name] = args
if "inventory_backend" in args:
cached.args["inventory-backend"] = args.inventory_backend
cached.args.setdefault("global", {}).setdefault("inventory-backend", args.inventory_backend)
cached.args = args

if "compose_target_name" in args:
cached.args.setdefault("global", {}).setdefault("compose_target_name", args.compose_target_name)

if hasattr(args, "verbose") and args.verbose:
setup_logging(level=logging.DEBUG, force=True)
logging_level = logging.DEBUG
elif hasattr(args, "quiet") and args.quiet:
setup_logging(level=logging.CRITICAL, force=True)
logging_level = logging.CRITICAL
else:
logging_level = logging.INFO
setup_logging(level=logging_level, force=True)

# call chosen command
args.func(args)
6 changes: 3 additions & 3 deletions kapitan/inputs/base.py
Original file line number Diff line number Diff line change
@@ -89,9 +89,9 @@ def make_compile_dirs(self, target_name, output_path, **kwargs):
"""make compile dirs, skips if dirs exist"""
_compile_path = os.path.join(self.compile_path, target_name, output_path)
if kwargs.get("compose_target_name", False):
os.makedirs(_compile_path.replace(".", "/"), exist_ok=True)
else:
os.makedirs(_compile_path, exist_ok=True)
_compile_path = _compile_path.replace(".", "/")

os.makedirs(_compile_path, exist_ok=True)

def compile_file(self, file_path, compile_path, ext_vars, **kwargs):
"""implements compilation for file_path to compile_path with ext_vars"""
2 changes: 1 addition & 1 deletion kapitan/inputs/jinja2_filters.py
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ def load_jinja2_filters_from_file(env, jinja2_filters):
# Custom filters
def reveal_maybe(ref_tag):
"Will reveal ref_tag if valid and --reveal flag is used"
if cached.args["compile"].reveal:
if cached.args.reveal:
return cached.revealer_obj.reveal_raw(ref_tag)
else:
return ref_tag
5 changes: 2 additions & 3 deletions kapitan/inputs/kadet.py
Original file line number Diff line number Diff line change
@@ -25,9 +25,8 @@
kadet.ABORT_EXCEPTION_TYPE = CompileError

logger = logging.getLogger(__name__)
inventory_path = cached.args.get(
"inventory_path"
) # XXX think about this as it probably breaks usage as library
inventory_path = vars(cached.args).get("inventory_path")
# XXX think about this as it probably breaks usage as library
search_paths = contextvars.ContextVar("current search_paths in thread")
current_target = contextvars.ContextVar("current target in thread")

5 changes: 3 additions & 2 deletions kapitan/inventory/inv_reclass.py
Original file line number Diff line number Diff line change
@@ -10,13 +10,14 @@

from kapitan.errors import InventoryError

from .inventory import Inventory
from .inventory import Inventory, InventoryTarget

logger = logging.getLogger(__name__)


class ReclassInventory(Inventory):
def render_targets(self, targets: list = None, ignore_class_notfound: bool = False):

def render_targets(self, targets: list[InventoryTarget] = None, ignore_class_notfound: bool = False) -> None:
"""
Runs a reclass inventory in inventory_path
(same output as running ./reclass.py -b inv_base_uri/ --inventory)
78 changes: 43 additions & 35 deletions kapitan/inventory/inventory.py
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@
class InventoryTarget:
name: str
path: str
composed_name: str
parameters: dict = field(default_factory=dict)
classes: list = field(default_factory=list)
applications: list = field(default_factory=list)
@@ -48,47 +47,43 @@ def inventory(self) -> dict:
get all targets from inventory
targets will be rendered
"""
if not self.targets:
self.search_targets()

inventory = self.get_targets([*self.targets.keys()])

return {
target_name: {"parameters": target.parameters, "classes": target.classes}
for target_name, target in inventory.items()
target.name: {"parameters": target.parameters, "classes": target.classes}
for target in self.get_targets().values()
}

def search_targets(self) -> dict:
"""
look for targets at '<inventory_path>/targets/' and return targets without rendering parameters
"""

for root, dirs, files in os.walk(self.targets_path):
for file in files:
# split file extension and check if yml/yaml
path = os.path.join(root, file)
name, ext = os.path.splitext(file)
path = os.path.relpath(os.path.join(root, file), self.targets_path)

if self.compose_target_name:
name, ext = os.path.splitext(path)
name = name.replace(os.sep, ".")
else:
name, ext = os.path.splitext(file)

if ext not in (".yml", ".yaml"):
logger.debug(f"{file}: targets have to be .yml or .yaml files.")
logger.debug(f"ignoring {file}: targets have to be .yml or .yaml files.")
continue

# initialize target
composed_name = (
os.path.splitext(os.path.relpath(path, self.targets_path))[0]
.replace(os.sep, ".")
.lstrip(".")
)
target = InventoryTarget(name, path, composed_name)
if self.compose_target_name:
target.name = target.composed_name
target = InventoryTarget(name, path)



# check for same name
if self.targets.get(target.name):
raise InventoryError(
f"Conflicting targets {target.name}: {target.path} and {self.targets[target.name].path}"
f"Conflicting targets {target.name}: {target.path} and {self.targets[target.name].path}. "
f"Consider using '--compose-target-name'."
)

self.targets[target.name] = target

return self.targets

def get_target(self, target_name: str, ignore_class_not_found: bool = False) -> InventoryTarget:
@@ -97,28 +92,35 @@ def get_target(self, target_name: str, ignore_class_not_found: bool = False) ->
"""
return self.get_targets([target_name], ignore_class_not_found)[target_name]

def get_targets(self, target_names: list, ignore_class_not_found: bool = False) -> dict:
def get_targets(self, target_names: list[str] = [], ignore_class_not_found: bool = False) -> dict:
"""
helper function to get rendered InventoryTarget objects for multiple targets
"""
if not self.targets:
self.search_targets()

targets_to_render = []

for target_name in target_names:
target = self.targets.get(target_name)
if not target:
if ignore_class_not_found:
continue
raise InventoryError(f"target '{target_name}' not found")

targets = {}

if not target_names:
targets = self.targets
else:
try:
targets = { target_name : self.targets[target_name] for target_name in target_names }
except KeyError as e:
if not ignore_class_not_found:
raise InventoryError(f"targets not found: {set(target_names)-set(self.targets)}" )

for target in targets.values():
if not target.parameters:
targets_to_render.append(target)

if targets_to_render:
self.render_targets(targets_to_render, ignore_class_not_found)

return {name: target for name, target in self.targets.items() if name in target_names}
return self.targets

def get_parameters(self, target_names: Union[str, list], ignore_class_not_found: bool = False) -> dict:
def get_parameters(self, target_names: str | list[str], ignore_class_not_found: bool = False) -> dict:
"""
helper function to get rendered parameters for single target or multiple targets
"""
@@ -129,12 +131,18 @@ def get_parameters(self, target_names: Union[str, list], ignore_class_not_found:
return {name: target.parameters for name, target in self.get_targets(target_names)}

@abstractmethod
def render_targets(self, targets: list = None, ignore_class_notfound: bool = False):
def render_targets(self, targets: list[InventoryTarget] = None, ignore_class_notfound: bool = False) -> None:
"""
create the inventory depending on which backend gets used
"""
raise NotImplementedError

def migrate(self):
"""
migrate the inventory, e.g. change interpolation syntax to new syntax
"""
pass

def __getitem__(self, key):
return self.inventory[key]

34 changes: 20 additions & 14 deletions kapitan/resources.py
Original file line number Diff line number Diff line change
@@ -253,10 +253,7 @@ def inventory(search_paths: list, target_name: str = None, inventory_path: str =
set inventory_path to read custom path. None defaults to value set via cli
Returns a dictionary with the inventory for target
"""
if inventory_path is None:
# grab inventory_path value from cli subcommand
inventory_path_arg = cached.args.get("compile") or cached.args.get("inventory")
inventory_path = inventory_path_arg.inventory_path
inventory_path = inventory_path or cached.args.inventory_path

inv_path_exists = False

@@ -317,19 +314,28 @@ def get_inventory(inventory_path) -> Inventory:
if cached.inv and cached.inv.targets:
return cached.inv

compose_target_name = hasattr(cached.args, "compose_target_name") and cached.args.compose_target_name
if hasattr(cached.args, "compose_node_name") and cached.args.compose_node_name:
logger.warning(
"inventory flag '--compose-node-name' is deprecated and scheduled to be dropped with the next release. "
"Please use '--compose-target-name' instead."
)
compose_target_name = True

# select inventory backend
backend_id = cached.args.get("inventory-backend")
compose_target_name = cached.args["global"].get("compose_target_name")
backend = AVAILABLE_BACKENDS.get(backend_id)
backend_id = hasattr(cached.args, "inventory_backend") and cached.args.inventory_backend
compose_target_name = hasattr(cached.args, "compose_target_name") and cached.args.compose_target_name
backend = AVAILABLE_BACKENDS.get(backend_id, AVAILABLE_BACKENDS.get("reclass"))
inventory_backend: Inventory = None
if backend != None:
logger.debug(f"Using {backend_id} as inventory backend")
inventory_backend = backend(inventory_path, compose_target_name)
else:
logger.debug(f"Backend {backend_id} is unknown, falling back to reclass as inventory backend")
inventory_backend = ReclassInventory(inventory_path, compose_target_name)

logger.debug(f"Using {backend_id} as inventory backend")
inventory_backend = backend(inventory_path, compose_target_name)

cached.inv = inventory_backend
# migrate inventory to selected inventory backend
if hasattr(cached.args, "migrate") and cached.args.migrate:
inventory_backend.migrate()

inventory_backend.search_targets()

cached.inv = inventory_backend
return inventory_backend
8 changes: 6 additions & 2 deletions kapitan/targets.py
Original file line number Diff line number Diff line change
@@ -124,8 +124,9 @@ def compile_targets(
cached.inv_sources.update(new_sources)
new_sources = list(set(list_sources(target_objs)) - cached.inv_sources)
# reset inventory cache and load target objs to check for missing classes
cached.reset_inv()
target_objs = load_target_inventory(inventory_path, updated_targets, ignore_class_notfound=False)
if new_sources:
cached.reset_inv()
target_objs = load_target_inventory(inventory_path, updated_targets, ignore_class_notfound=False)
# fetch dependencies
if fetch:
fetch_dependencies(output_path, target_objs, dep_cache_dir, force_fetch, pool)
@@ -403,6 +404,7 @@ def search_targets(inventory_path, targets, labels):
)

targets_found = []
# It should come back already rendered
inv = get_inventory(inventory_path)

for target_name in inv.targets.keys():
@@ -478,6 +480,8 @@ def compile_target(target_obj, search_paths, compile_path, ref_controller, globa
logger.error("Error compiling %s: %s", target_name, e)
continue
else:
import traceback
traceback.print_exception(type(e), e, e.__traceback__)
raise CompileError(f"Error compiling {target_name}: {e}")

logger.info("Compiled %s (%.2fs)", target_obj["target_full_path"], time.time() - start)
36 changes: 16 additions & 20 deletions kapitan/utils.py
Original file line number Diff line number Diff line change
@@ -219,23 +219,22 @@ def multiline_str_presenter(dumper, data):
By default, strings are getting dumped with style='"'.
Ref: https://github.com/yaml/pyyaml/issues/240#issuecomment-1018712495
"""
# get parsed args from cached.py
compile_args = cached.args.get("compile", None)
style = None
if compile_args:
style = compile_args.yaml_multiline_string_style

# check for inventory args too
inventory_args = cached.args.get("inventory", None)
if inventory_args:
style = inventory_args.multiline_string_style

if style == "literal":
style = "|"
elif style == "folded":
style = ">"

if hasattr(cached.args, "multiline_string_style"):
style_selection = cached.args.multiline_string_style
elif hasattr(cached.args, "yaml_multiline_string_style"):
style_selection = cached.args.yaml_multiline_string_style
else:
style = '"'
style_selection = "double-quotes"

supported_styles = {
"literal": "|",
"folded": ">",
"double-quotes": '"'
}

style = supported_styles.get(style_selection)

if data.count("\n") > 0: # check for multiline string
return dumper.represent_scalar("tag:yaml.org,2002:str", data, style=style)
return dumper.represent_scalar("tag:yaml.org,2002:str", data)
@@ -247,10 +246,7 @@ def multiline_str_presenter(dumper, data):
def null_presenter(dumper, data):
"""Configures yaml for omitting value from null-datatype"""
# get parsed args from cached.py
compile_args = cached.args.get("compile", None)
flag_value = None
if compile_args:
flag_value = compile_args.yaml_dump_null_as_empty
flag_value = cached.args.yaml_dump_null_as_empty

if flag_value:
return dumper.represent_scalar("tag:yaml.org,2002:null", "")
182 changes: 179 additions & 3 deletions poetry.lock
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -32,6 +32,13 @@ packages = [
[tool.poetry.scripts]
kapitan = 'kapitan.cli:main'

[tool.poetry.group.dev.dependencies]
pytest = "^8.2.0"
coverage = "^7.5.0"
docker = "^7.0.0"
pytest-md = "^0.2.0"
pytest-emoji = "^0.2.0"

[tool.poetry-version-plugin]
source = "git-tag"

23 changes: 1 addition & 22 deletions tests/test_compile.py
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@

class CompileTestResourcesTestObjs(unittest.TestCase):
def setUp(self):
reset_cache()
os.chdir(os.getcwd() + "/tests/test_resources/")

def test_compile(self):
@@ -163,28 +164,6 @@ def test_compile_not_enough_args(self):
main()
self.assertEqual(cm.exception.code, 1)

def test_compile_not_matching_targets(self):
with (
self.assertLogs(logger="kapitan.targets", level="ERROR") as cm,
contextlib.redirect_stdout(io.StringIO()),
):
# as of now, we cannot capture stdout with contextlib.redirect_stdout
# since we only do logger.error(e) in targets.py before exiting
with self.assertRaises(SystemExit) as ca:
unmatched_filename = "inventory/targets/minikube-es-fake.yml"
correct_filename = "inventory/targets/minikube-es.yml"
os.rename(src=correct_filename, dst=unmatched_filename)
sys.argv = ["kapitan", "compile"] + self.extraArgv

try:
main()
finally:
# correct the filename again, even if assertion fails
if os.path.exists(unmatched_filename):
os.rename(src=unmatched_filename, dst=correct_filename)
error_message_substr = "is missing the corresponding yml file"
self.assertTrue(" ".join(cm.output).find(error_message_substr) != -1)

def test_compile_vars_target_missing(self):
inventory_path = "inventory"
target_filename = "minikube-es"
16 changes: 11 additions & 5 deletions tests/test_compose_node_name.py
Original file line number Diff line number Diff line change
@@ -17,18 +17,24 @@ def setUp(self):

def test_compose_target_name(self):
inventory_path = "examples/kubernetes/inventory"
example_target_names = [
os.path.splitext(f)[0] for f in os.listdir(os.path.join(inventory_path, "targets"))
]

targets_path = os.path.join(inventory_path, "targets")
example_target_names = []

for root, dirs, files in os.walk(targets_path):
for file in files:
# split file extension and check if yml/yaml
path = os.path.relpath(os.path.join(root, file), targets_path)
name = os.path.splitext(path)[0].replace(os.sep, ".")
example_target_names.append(name)

temp_inventory_dir = tempfile.mkdtemp()
shutil.copytree(inventory_path, temp_inventory_dir, dirs_exist_ok=True)

# ensure normal rendering works
compose_target_name = True
inv = self.inventory(temp_inventory_dir, compose_target_name)
found_targets = inv.search_targets()
self.assertEqual(example_target_names, list(found_targets.keys()))
self.assertEqual(sorted(example_target_names), sorted(list(found_targets.keys())))
# ensure that actual rendering finds the same nodes as `search_targets()`
for t in example_target_names:
nodeinfo = inv.get_target(t)
9 changes: 4 additions & 5 deletions tests/test_inventory.py
Original file line number Diff line number Diff line change
@@ -17,12 +17,11 @@

class InventoryTargetTest(unittest.TestCase):
def setUp(self):
# Setup `cached.args` if it's not setup yet
cached.args.setdefault("compile", argparse.Namespace())
# Configure `compile.inventory_path` and `inventory-backend`. This
# allows us to reuse the tests by inheriting from this test class.
cached.args["compile"].inventory_path = "inventory"
cached.args["inventory-backend"] = "reclass"

cached.args.inventory_backend = "reclass"
cached.args.inventory_path = "inventory"

def test_inventory_target(self):
inv = inventory(["examples/kubernetes"], "minikube-es")
@@ -39,4 +38,4 @@ def setUp(self):
self.skipTest("reclass-rs not available")

super().setUp()
cached.args["inventory-backend"] = "reclass-rs"
cached.args.inventory_backend = "reclass-rs"
29 changes: 7 additions & 22 deletions tests/test_jinja2.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
# SPDX-License-Identifier: Apache-2.0

"jinja2 tests"

import argparse
import base64
import unittest
import tempfile
@@ -150,14 +150,9 @@ def test_reveal_maybe_b64encode_tag(self):
f.write("{{ my_ref_tag_var|reveal_maybe|b64encode }}".encode("UTF-8"))
f.seek(0)

# new argparse namespace with --reveal and --refs-path values
namespace = namedtuple("Namespace", [])
namespace.reveal = True
namespace.refs_path = tempfile.mkdtemp()

# reveal_maybe uses cached, so inject namespace
cached.args["compile"] = namespace
cached.ref_controller_obj = RefController(cached.args["compile"].refs_path)
cached.args = argparse.Namespace(reveal=True, refs_path=tempfile.mkdtemp())
cached.ref_controller_obj = RefController(cached.args.refs_path)
cached.revealer_obj = Revealer(cached.ref_controller_obj)

ref_tag = "?{base64:some_value}"
@@ -175,14 +170,9 @@ def test_reveal_maybe_tag_no_reveal_flag(self):
f.write("{{ my_ref_tag_var|reveal_maybe }}".encode("UTF-8"))
f.seek(0)

# new argparse namespace with --reveal and --refs-path values
namespace = namedtuple("Namespace", [])
namespace.reveal = False
namespace.refs_path = tempfile.mkdtemp()

# reveal_maybe uses cached, so inject namespace
cached.args["compile"] = namespace
cached.ref_controller_obj = RefController(cached.args["compile"].refs_path)
cached.args = argparse.Namespace(reveal=False, refs_path=tempfile.mkdtemp())
cached.ref_controller_obj = RefController(cached.args.refs_path)
cached.revealer_obj = Revealer(cached.ref_controller_obj)

ref_tag = "?{base64:some_value}"
@@ -199,14 +189,9 @@ def test_reveal_maybe_no_tag(self):
f.write("{{ my_var|reveal_maybe }}".encode("UTF-8"))
f.seek(0)

# new argparse namespace with --reveal and --refs-path values
namespace = namedtuple("Namespace", [])
namespace.reveal = True
namespace.refs_path = tempfile.mkdtemp()

# reveal_maybe uses cached, so inject namespace
cached.args["compile"] = namespace
cached.ref_controller_obj = RefController(cached.args["compile"].refs_path)
cached.args = argparse.Namespace(reveal=True, refs_path=tempfile.mkdtemp())
cached.ref_controller_obj = RefController(cached.args.refs_path)
cached.revealer_obj = Revealer(cached.ref_controller_obj)

var_value = "heavy_rock!"
4 changes: 3 additions & 1 deletion tests/test_resources/inventory/targets/test-objects.yml
Original file line number Diff line number Diff line change
@@ -3,6 +3,8 @@ classes:

parameters:
my_plainref: ?{plain:my_plainref}
target_name: test-objects
kapitan:
vars:
target: test-objects
target: ${target_name}
namespace: ${target_name}
6 changes: 4 additions & 2 deletions tests/vault_server.py
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ def __init__(self):

def setup_container(self):
env = {
"VAULT_LOCAL_CONFIG": '{"backend": {"file": {"path": "/vault/file"}}, "listener":{"tcp":{"address":"0.0.0.0:8200","tls_disable":"true"}}}'
"VAULT_LOCAL_CONFIG": '{"backend": {"file": {"path": "/vault/file"}}, "disable_mlock" : "true" , "listener":{"tcp":{"address":"0.0.0.0:8200","tls_disable":"true"}}}'
}
vault_container = self.docker_client.containers.run(
image="hashicorp/vault",
@@ -48,11 +48,13 @@ def setup_container(self):
auto_remove=True,
command="server",
)



# make sure the container is up & running before testing

while vault_container.status != "running":
sleep(2)
sleep(5)
vault_container.reload()

port = vault_container.attrs["NetworkSettings"]["Ports"]["8200/tcp"][0]["HostPort"]