Skip to content

Commit

Permalink
support passing additional env vars to host (#176)
Browse files Browse the repository at this point in the history
* support passing additional env vars to host

* Update README with the environment argument example
fix some typos

* Update args_file parsing to behave correctly with eventual cli args.
Update README
  • Loading branch information
Roman Plevka authored Dec 20, 2022
1 parent 0321000 commit fca5b61
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 20 deletions.
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})

This comment has been minimized.

Copy link
@lpramuk

lpramuk Jan 18, 2023

Contributor

@rplevka typo !
I am going to fix it in my #181

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

0 comments on commit fca5b61

Please sign in to comment.