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

support passing additional env vars to host #176

Merged
merged 3 commits into from
Dec 20, 2022
Merged
Show file tree
Hide file tree
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
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@ A username can still be provided when using a token to authenticate. This user w

# CLI Usage
**Checking out a VM or container**
You can pass in any arbitrary arguments you want.
```
broker checkout --workflow "workflow-name" --workflow-arg1 something --workflow-arg2 else
```
You can pass in any arbitrary arguments you want. Broker can also checkout multiple VMs at once by specifying a count.
Passing environment variables to the target container.
```
broker checkout --nick rhel7 --environment "VAR1=val1,VAR2=val2"
```
Broker can also checkout multiple VMs at once by specifying a count.
```
broker checkout --nick rhel7 --count 3
```
Expand All @@ -57,6 +62,9 @@ broker checkout --nick rhel7 --AnsibleTower testing
```
If you have more complex data structures you need to pass in, you can do that in two ways.
You can populate a json or yaml file where the top-level keys will become broker arguments and their nested data structures become values.
Note:
The json and yaml files need to use the supported suffix ('json', 'yaml', '.yml') in order to be properly recognized.
Any eventual arbitrary arguments passed to CLI will be combined with those in the passed argument file with the CLI ones taking precedence.
```
broker checkout --nick rhel7 --args-file tests/data/broker_args.json
```
Expand Down Expand Up @@ -204,11 +212,11 @@ from broker import Broker
```
The Broker class largely accepts the same arguments as you would pass via the CLI. One key difference is that you need to use underscores instead of dashes. For example, a checkout at the CLI that looks like this
```
broker checkout --nick rhel7 --args-file tests/data/broker_args.json
broker checkout --nick rhel7 --args-file tests/data/broker_args.json --environment="VAR1=val1,VAR2=val2"
```
could look like this in an API usage
```python
rhel7_host = Broker(nick="rhel7", args_file="tests/data/broker_args.json").checkout()
rhel7_host = Broker(nick="rhel7", args_file="tests/data/broker_args.json", environment={"VAR1": "val1", "VAR2": "val2"}).checkout()
```
Broker will carry out its usual actions and package the resulting host in a Host object. This host object will also include some basic functionality, like the ability to execute ssh commands on the host.
Executed ssh command results are packaged in a Results object containing status (return code), stdout, and stderr.
Expand Down
8 changes: 4 additions & 4 deletions broker/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def cli(version):
@click.option(
"--args-file",
type=click.Path(exists=True),
help="A json or yaml file mappng arguments to values",
help="A json or yaml file mapping arguments to values",
)
@provider_options
@click.pass_context
Expand All @@ -146,7 +146,7 @@ def checkout(ctx, background, nick, count, args_file, **kwargs):

:param nick: shortcut for arguments saved in settings.yaml, passed in as a string

:param args_file: this broker argument wil be replaced with the contents of the file passed in
:param args_file: this broker argument will be replaced with the contents of the file passed in
"""
broker_args = helpers.clean_dict(kwargs)
if nick:
Expand Down Expand Up @@ -342,7 +342,7 @@ def duplicate(vm, background, count, all_, filter):
@click.option(
"--args-file",
type=click.Path(exists=True),
help="A json or yaml file mappng arguments to values",
help="A json or yaml file mapping arguments to values",
)
@provider_options
@click.pass_context
Expand All @@ -362,7 +362,7 @@ def execute(ctx, background, nick, output_format, artifacts, args_file, **kwargs

:param artifacts: AnsibleTower provider specific option for choosing what to return

:param args_file: this broker argument wil be replaced with the contents of the file passed in
:param args_file: this broker argument will be replaced with the contents of the file passed in
"""
broker_args = helpers.clean_dict(kwargs)
if nick:
Expand Down
29 changes: 17 additions & 12 deletions broker/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,25 +180,30 @@ def resolve_file_args(broker_args):
then attempt to resolve them. If not resolved, keep arg/value pair intact.
"""
final_args = {}
for key, val in broker_args.items():
# parse the eventual args_file first
if val := broker_args.pop('args_file', None):
if isinstance(val, Path) or (
isinstance(val, str) and val[-4:] in ("json", "yaml", ".yml")
):
if data := load_file(val):
if key == "args_file":
if isinstance(data, dict):
final_args.update(data)
elif isinstance(data, list):
for d in data:
final_args.update(d)
else:
final_args[key] = data
elif key == "args_file":
if isinstance(data, dict):
final_args.update(data)
elif isinstance(data, list):
for d in data:
final_args.update(d)
else:
raise exceptions.BrokerError(f"No data loaded from {val}")

for key, val in broker_args.items():
if isinstance(val, Path) or (
isinstance(val, str) and val[-4:] in ("json", "yaml", ".yml")
):
if data := load_file(val):
final_args.update({key: data})
else:
final_args[key] = val
final_arg.update({key: val})
else:
final_args[key] = val
final_args.update({key: val})
return final_args


Expand Down
7 changes: 6 additions & 1 deletion broker/providers/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,13 @@ def run_container(self, container_host, **kwargs):
if not kwargs.get("name"):
kwargs["name"] = self._gen_name()
kwargs["ports"] = self._port_mapping(container_host, **kwargs)

envars = kwargs.get('environment', {})
if isinstance(envars, str):
envars = {var.split('=')[0]: var.split('=')[1] for var in envars.split(',')}
# add some context information about the container's requester
envars, origin = {}, helpers.find_origin()
origin = helpers.find_origin()

if "for" in origin:
origin = origin.split()[-1]
envars["BROKER_ORIGIN"] = origin[0]
Expand Down