Skip to content

Commit

Permalink
Use host data for global args (#621)
Browse files Browse the repository at this point in the history
* Consider host data when collecting global op args.

Host data is preferred over the config default, so the order is now:

+ Operation arguments
+ Any current deploy arguments
+ Host data
+ Config

* Add tests for operation arg extraction.
* Don't assume `host.data.X` will always return `None`.
  • Loading branch information
Fizzadar committed Jul 21, 2021
1 parent 87ca27a commit 7a0065f
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pyinfra/api/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def decorated_func(*args, **kwargs):
'Deploy called without state/host: {0} ({1})'
).format(func, get_call_location()))

deploy_kwargs, _ = pop_global_op_kwargs(state, kwargs)
deploy_kwargs, _ = pop_global_op_kwargs(state, host, kwargs)

# Name the deploy
deploy_name = getattr(func, 'deploy_name', func.__name__)
Expand Down
2 changes: 1 addition & 1 deletion pyinfra/api/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def decorated_func(*args, **kwargs):
#

# Get the meta kwargs (globals that apply to all hosts)
global_kwargs, global_kwarg_keys = pop_global_op_kwargs(state, kwargs)
global_kwargs, global_kwarg_keys = pop_global_op_kwargs(state, host, kwargs)

# If this op is being called inside another, just return here
# (any unwanted/op-related kwargs removed above).
Expand Down
13 changes: 11 additions & 2 deletions pyinfra/api/operation_kwargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,14 @@ def get_executor_kwarg_keys():
return list(keys)


def pop_global_op_kwargs(state, kwargs):
def pop_global_op_kwargs(state, host, kwargs):
'''
Pop and return operation global keyword arguments.
Pop and return operation global keyword arguments, in preferred order:
+ From the current context (operation kwargs)
+ From any current @deploy context (deploy kwargs)
+ From the host data variables
+ From the config variables
'''

meta_kwargs = state.deploy_kwargs or {}
Expand All @@ -149,6 +154,10 @@ def get_kwarg(key, default=None):
if default:
default = default(state.config)

host_default = getattr(host.data, key, None)
if host_default is not None:
default = host_default

value, has_key = get_kwarg(key, default=default)
if handler:
value = handler(state.config, value)
Expand Down
49 changes: 49 additions & 0 deletions tests/test_api/test_api_operation_kwargs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from unittest import TestCase

from pyinfra.api import Config, Inventory, State
from pyinfra.api.operation_kwargs import pop_global_op_kwargs


class TestOperationKwargs(TestCase):
def test_get_from_config(self):
config = Config(SUDO='config-value')
inventory = Inventory((('somehost',), {}))

state = State(config=config, inventory=inventory)

kwargs, keys = pop_global_op_kwargs(state, inventory.get_host('somehost'), {})
assert kwargs['sudo'] == 'config-value'

def test_get_from_host(self):
config = Config(SUDO='config-value')
inventory = Inventory(([('somehost', {'sudo': 'host-value'})], {}))

state = State(config=config, inventory=inventory)

kwargs, keys = pop_global_op_kwargs(state, inventory.get_host('somehost'), {})
assert kwargs['sudo'] == 'host-value'

def test_get_from_state_deploy_kwargs(self):
config = Config(SUDO='config-value')
inventory = Inventory(([('somehost', {'sudo': 'host-value'})], {}))

state = State(config=config, inventory=inventory)
state.deploy_kwargs = {'sudo': 'deploy-kwarg-value'}

kwargs, keys = pop_global_op_kwargs(state, inventory.get_host('somehost'), {})
assert kwargs['sudo'] == 'deploy-kwarg-value'

def test_get_from_kwargs(self):
config = Config(SUDO='config-value')
inventory = Inventory(([('somehost', {'sudo': 'host-value'})], {}))

state = State(config=config, inventory=inventory)
state.deploy_kwargs = {'sudo': 'deploy-kwarg-value'}

kwargs, keys = pop_global_op_kwargs(
state,
inventory.get_host('somehost'),
{'sudo': 'kwarg-value'},
)
assert kwargs['sudo'] == 'kwarg-value'
assert 'sudo' in keys

0 comments on commit 7a0065f

Please sign in to comment.