Removed references to tower in InventorySource and Credentials

--- Removed reference to tower in  InventorySource and InventoryUpdate model
--- Added a migration for above change
--- Added new CONTROLLER* variables in awx/main/models/credentials/__init__.py
--- Migrated awxkit to new CONTROLLER* variables
--- Updated the tests to use new CONTROLLER* variables
--- Fix some issues with upgrade path, rename more cases
This commit is contained in:
Amol Gautam
2021-06-10 13:32:38 -04:00
committed by Shane McDonald
parent 645f7f6dac
commit b64c2d6861
18 changed files with 171 additions and 50 deletions

View File

@@ -0,0 +1,108 @@
# Generated by Django 2.2.16 on 2021-06-17 13:12
import logging
from django.db import migrations, models
from awx.main.models.credential import ManagedCredentialType, CredentialType as ModernCredentialType
logger = logging.getLogger(__name__)
def forwards(apps, schema_editor):
InventoryUpdate = apps.get_model('main', 'InventoryUpdate')
InventorySource = apps.get_model('main', 'InventorySource')
r = InventoryUpdate.objects.filter(source='tower').update(source='controller')
if r:
logger.warn(f'Renamed {r} tower inventory updates to controller')
InventorySource.objects.filter(source='tower').update(source='controller')
if r:
logger.warn(f'Renamed {r} tower inventory sources to controller')
CredentialType = apps.get_model('main', 'CredentialType')
tower_type = CredentialType.objects.filter(managed_by_tower=True, namespace='tower').first()
if tower_type is not None and not CredentialType.objects.filter(managed_by_tower=True, namespace='controller', kind='cloud').exists():
registry_type = ManagedCredentialType.registry.get('controller')
if not registry_type:
raise RuntimeError('Excpected to find controller credential, this may need to be edited in the future!')
logger.info('Renaming the Ansible Tower credential type for existing install')
tower_type.name = registry_type.name # sensitive to translations
tower_type.namespace = 'controller' # if not done, will error setup_tower_managed_defaults
tower_type.save(update_fields=['name', 'namespace'])
ModernCredentialType.setup_tower_managed_defaults()
def backwards(apps, schema_editor):
InventoryUpdate = apps.get_model('main', 'InventoryUpdate')
InventorySource = apps.get_model('main', 'InventorySource')
r = InventoryUpdate.objects.filter(source='controller').update(source='tower')
if r:
logger.warn(f'Renamed {r} controller inventory updates to tower')
r = InventorySource.objects.filter(source='controller').update(source='tower')
if r:
logger.warn(f'Renamed {r} controller inventory sources to tower')
CredentialType = apps.get_model('main', 'CredentialType')
tower_type = CredentialType.objects.filter(managed_by_tower=True, namespace='controller', kind='cloud').first()
if tower_type is not None and not CredentialType.objects.filter(managed_by_tower=True, namespace='tower').exists():
logger.info('Renaming the controller credential type back')
tower_type.namespace = 'tower'
tower_type.name = 'Ansible Tower'
tower_type.save(update_fields=['namespace', 'name'])
class Migration(migrations.Migration):
dependencies = [
('main', '0147_validate_ee_image_field'),
]
operations = [
migrations.RunPython(migrations.RunPython.noop, backwards),
migrations.AlterField(
model_name='inventorysource',
name='source',
field=models.CharField(
choices=[
('file', 'File, Directory or Script'),
('scm', 'Sourced from a Project'),
('ec2', 'Amazon EC2'),
('gce', 'Google Compute Engine'),
('azure_rm', 'Microsoft Azure Resource Manager'),
('vmware', 'VMware vCenter'),
('satellite6', 'Red Hat Satellite 6'),
('openstack', 'OpenStack'),
('rhv', 'Red Hat Virtualization'),
('controller', 'Red Hat Ansible Automation Platform'),
('insights', 'Red Hat Insights'),
],
default=None,
max_length=32,
),
),
migrations.AlterField(
model_name='inventoryupdate',
name='source',
field=models.CharField(
choices=[
('file', 'File, Directory or Script'),
('scm', 'Sourced from a Project'),
('ec2', 'Amazon EC2'),
('gce', 'Google Compute Engine'),
('azure_rm', 'Microsoft Azure Resource Manager'),
('vmware', 'VMware vCenter'),
('satellite6', 'Red Hat Satellite 6'),
('openstack', 'OpenStack'),
('rhv', 'Red Hat Virtualization'),
('controller', 'Red Hat Ansible Automation Platform'),
('insights', 'Red Hat Insights'),
],
default=None,
max_length=32,
),
),
migrations.RunPython(forwards, migrations.RunPython.noop),
]

View File

@@ -1006,23 +1006,25 @@ ManagedCredentialType(
) )
ManagedCredentialType( ManagedCredentialType(
namespace='tower', namespace='controller',
kind='cloud', kind='cloud',
name=ugettext_noop('Ansible Tower'), name=ugettext_noop('Red Hat Ansible Automation Platform'),
managed_by_tower=True, managed_by_tower=True,
inputs={ inputs={
'fields': [ 'fields': [
{ {
'id': 'host', 'id': 'host',
'label': ugettext_noop('Ansible Tower Hostname'), 'label': ugettext_noop('Red Hat Ansible Automation Platform'),
'type': 'string', 'type': 'string',
'help_text': ugettext_noop('The Ansible Tower base URL to authenticate with.'), 'help_text': ugettext_noop('Red Hat Ansible Automation Platform base URL to authenticate with.'),
}, },
{ {
'id': 'username', 'id': 'username',
'label': ugettext_noop('Username'), 'label': ugettext_noop('Username'),
'type': 'string', 'type': 'string',
'help_text': ugettext_noop('The Ansible Tower user to authenticate as.' 'This should not be set if an OAuth token is being used.'), 'help_text': ugettext_noop(
'Red Hat Ansible Automation Platform username id to authenticate as.' 'This should not be set if an OAuth token is being used.'
),
}, },
{ {
'id': 'password', 'id': 'password',
@@ -1048,6 +1050,11 @@ ManagedCredentialType(
'TOWER_PASSWORD': '{{password}}', 'TOWER_PASSWORD': '{{password}}',
'TOWER_VERIFY_SSL': '{{verify_ssl}}', 'TOWER_VERIFY_SSL': '{{verify_ssl}}',
'TOWER_OAUTH_TOKEN': '{{oauth_token}}', 'TOWER_OAUTH_TOKEN': '{{oauth_token}}',
'CONTROLLER_HOST': '{{host}}',
'CONTROLLER_USERNAME': '{{username}}',
'CONTROLLER_PASSWORD': '{{password}}',
'CONTROLLER_VERIFY_SSL': '{{verify_ssl}}',
'CONTROLLER_OAUTH_TOKEN': '{{oauth_token}}',
} }
}, },
) )

View File

@@ -805,7 +805,7 @@ class InventorySourceOptions(BaseModel):
('satellite6', _('Red Hat Satellite 6')), ('satellite6', _('Red Hat Satellite 6')),
('openstack', _('OpenStack')), ('openstack', _('OpenStack')),
('rhv', _('Red Hat Virtualization')), ('rhv', _('Red Hat Virtualization')),
('tower', _('Ansible Tower')), ('controller', _('Red Hat Ansible Automation Platform')),
('insights', _('Red Hat Insights')), ('insights', _('Red Hat Insights')),
] ]
@@ -1529,8 +1529,8 @@ class satellite6(PluginFileInjector):
return ret return ret
class tower(PluginFileInjector): class controller(PluginFileInjector):
plugin_name = 'tower' plugin_name = 'tower' # TODO: relying on routing for now, update after EEs pick up revised collection
base_injector = 'template' base_injector = 'template'
namespace = 'awx' namespace = 'awx'
collection = 'awx' collection = 'awx'

View File

@@ -4,5 +4,10 @@
"TOWER_PASSWORD": "fooo", "TOWER_PASSWORD": "fooo",
"TOWER_USERNAME": "fooo", "TOWER_USERNAME": "fooo",
"TOWER_OAUTH_TOKEN": "", "TOWER_OAUTH_TOKEN": "",
"TOWER_VERIFY_SSL": "False" "TOWER_VERIFY_SSL": "False",
"CONTROLLER_HOST": "https://foo.invalid",
"CONTROLLER_PASSWORD": "fooo",
"CONTROLLER_USERNAME": "fooo",
"CONTROLLER_OAUTH_TOKEN": "",
"CONTROLLER_VERIFY_SSL": "False"
} }

View File

@@ -271,10 +271,10 @@ def test_cluster_node_long_node_name(inventory, project):
@pytest.mark.django_db @pytest.mark.django_db
def test_credential_defaults_idempotency(): def test_credential_defaults_idempotency():
CredentialType.setup_tower_managed_defaults() CredentialType.setup_tower_managed_defaults()
old_inputs = CredentialType.objects.get(name='Ansible Tower', kind='cloud').inputs old_inputs = CredentialType.objects.get(name='Red Hat Ansible Automation Platform', kind='cloud').inputs
prior_count = ActivityStream.objects.count() prior_count = ActivityStream.objects.count()
# this is commonly re-ran in migrations, and no changes should be shown # this is commonly re-ran in migrations, and no changes should be shown
# because inputs and injectors are not actually tracked in the database # because inputs and injectors are not actually tracked in the database
CredentialType.setup_tower_managed_defaults() CredentialType.setup_tower_managed_defaults()
assert CredentialType.objects.get(name='Ansible Tower', kind='cloud').inputs == old_inputs assert CredentialType.objects.get(name='Red Hat Ansible Automation Platform', kind='cloud').inputs == old_inputs
assert ActivityStream.objects.count() == prior_count assert ActivityStream.objects.count() == prior_count

View File

@@ -101,6 +101,7 @@ def test_default_cred_types():
'vault', 'vault',
'vmware', 'vmware',
] ]
for type_ in CredentialType.defaults.values(): for type_ in CredentialType.defaults.values():
assert type_().managed_by_tower is True assert type_().managed_by_tower is True

View File

@@ -1794,14 +1794,14 @@ class TestInventoryUpdateCredentials(TestJobExecution):
safe_env = build_safe_env(env) safe_env = build_safe_env(env)
assert env['TOWER_HOST'] == 'https://tower.example.org' assert env['CONTROLLER_HOST'] == 'https://tower.example.org'
assert env['TOWER_USERNAME'] == 'bob' assert env['CONTROLLER_USERNAME'] == 'bob'
assert env['TOWER_PASSWORD'] == 'secret' assert env['CONTROLLER_PASSWORD'] == 'secret'
if verify: if verify:
assert env['TOWER_VERIFY_SSL'] == 'True' assert env['CONTROLLER_VERIFY_SSL'] == 'True'
else: else:
assert env['TOWER_VERIFY_SSL'] == 'False' assert env['CONTROLLER_VERIFY_SSL'] == 'False'
assert safe_env['TOWER_PASSWORD'] == tasks.HIDDEN_PASSWORD assert safe_env['CONTROLLER_PASSWORD'] == tasks.HIDDEN_PASSWORD
def test_tower_source_ssl_verify_empty(self, inventory_update, private_data_dir, mocker): def test_tower_source_ssl_verify_empty(self, inventory_update, private_data_dir, mocker):
task = tasks.RunInventoryUpdate() task = tasks.RunInventoryUpdate()

View File

@@ -81,7 +81,7 @@ options:
- Deprecated, please use credential_type - Deprecated, please use credential_type
required: False required: False
type: str type: str
choices: ["aws", "tower", "gce", "azure_rm", "openstack", "satellite6", "rhv", "vmware", "aim", "conjur", "hashivault_kv", "hashivault_ssh", choices: ["aws", "controller", "gce", "azure_rm", "openstack", "satellite6", "rhv", "vmware", "aim", "conjur", "hashivault_kv", "hashivault_ssh",
"azure_kv", "insights", "kubernetes_bearer_token", "net", "scm", "ssh", "github_token", "gitlab_token", "vault"] "azure_kv", "insights", "kubernetes_bearer_token", "net", "scm", "ssh", "github_token", "gitlab_token", "vault"]
host: host:
description: description:
@@ -292,7 +292,7 @@ from ..module_utils.controller_api import ControllerAPIModule
KIND_CHOICES = { KIND_CHOICES = {
'aws': 'Amazon Web Services', 'aws': 'Amazon Web Services',
'tower': 'Ansible Tower', 'controller': 'Red Hat Ansible Automation Platform',
'gce': 'Google Compute Engine', 'gce': 'Google Compute Engine',
'azure_rm': 'Microsoft Azure Resource Manager', 'azure_rm': 'Microsoft Azure Resource Manager',
'openstack': 'OpenStack', 'openstack': 'OpenStack',

View File

@@ -12,7 +12,7 @@
[comment]: # (* upon build of the collection *) [comment]: # (* upon build of the collection *)
[comment]: # (*******************************************************) [comment]: # (*******************************************************)
This Ansible collection allows for easy interaction with an {% if collection_package | lower() == 'awx' %}AWX{% else %}Ansible Tower{% endif %} server via Ansible playbooks. This Ansible collection allows for easy interaction with an {% if collection_package | lower() == 'awx' %}AWX{% else %}Red Hat Ansible Automation Platform{% endif %} server via Ansible playbooks.
This source for this collection lives in the `awx_collection` folder inside of the This source for this collection lives in the `awx_collection` folder inside of the
AWX source. AWX source.

View File

@@ -79,7 +79,7 @@ credential_type_name_to_config_kind_map = {
'amazon web services': 'aws', 'amazon web services': 'aws',
'container registry': 'registry', 'container registry': 'registry',
'ansible galaxy/automation hub api token': 'galaxy', 'ansible galaxy/automation hub api token': 'galaxy',
'ansible tower': 'tower', 'red hat ansible automation platform': 'controller',
'google compute engine': 'gce', 'google compute engine': 'gce',
'insights': 'insights', 'insights': 'insights',
'openshift or kubernetes api bearer token': 'kubernetes', 'openshift or kubernetes api bearer token': 'kubernetes',

View File

@@ -2,6 +2,6 @@ Building the Documentation
-------------------------- --------------------------
To build the docs, spin up a real AWX server, `pip install sphinx sphinxcontrib-autoprogram`, and run: To build the docs, spin up a real AWX server, `pip install sphinx sphinxcontrib-autoprogram`, and run:
~ TOWER_HOST=https://awx.example.org TOWER_USERNAME=example TOWER_PASSWORD=secret make clean html ~ CONTROLLER_HOST=https://awx.example.org CONTROLLER_USERNAME=example CONTROLLER_PASSWORD=secret make clean html
~ cd build/html/ && python -m http.server ~ cd build/html/ && python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) .. Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ..

View File

@@ -12,9 +12,9 @@ The preferred mechanism for authenticating with AWX and |RHAT| is by generating
.. code:: bash .. code:: bash
TOWER_HOST=https://awx.example.org \ CONTROLLER_HOST=https://awx.example.org \
TOWER_USERNAME=alice \ CONTROLLER_USERNAME=alice \
TOWER_PASSWORD=secret \ CONTROLLER_PASSWORD=secret \
awx login awx login
As a convenience, the ``awx login -f human`` command prints a shell-formatted token As a convenience, the ``awx login -f human`` command prints a shell-formatted token
@@ -22,15 +22,15 @@ value:
.. code:: bash .. code:: bash
export TOWER_OAUTH_TOKEN=6E5SXhld7AMOhpRveZsLJQsfs9VS8U export CONTROLLER_OAUTH_TOKEN=6E5SXhld7AMOhpRveZsLJQsfs9VS8U
By ingesting this token, you can run subsequent CLI commands without having to By ingesting this token, you can run subsequent CLI commands without having to
specify your username and password each time: specify your username and password each time:
.. code:: bash .. code:: bash
export TOWER_HOST=https://awx.example.org export CONTROLLER_HOST=https://awx.example.org
$(TOWER_USERNAME=alice TOWER_PASSWORD=secret awx login -f human) $(CONTROLLER_USERNAME=alice CONTROLLER_PASSWORD=secret awx login -f human)
awx config awx config
Working with OAuth2.0 Applications Working with OAuth2.0 Applications
@@ -43,7 +43,7 @@ application was created.
.. code:: bash .. code:: bash
TOWER_USERNAME=alice TOWER_PASSWORD=secret awx login \ CONTROLLER_USERNAME=alice CONTROLLER_PASSWORD=secret awx login \
--conf.client_id <value> --conf.client_secret <value> --conf.client_id <value> --conf.client_secret <value>
@@ -55,7 +55,7 @@ a read-only token, specify ``--scope read``:
.. code:: bash .. code:: bash
TOWER_USERNAME=alice TOWER_PASSWORD=secret \ CONTROLLER_USERNAME=alice CONTROLLER_PASSWORD=secret \
awx login --conf.scope read awx login --conf.scope read
Session Authentication Session Authentication
@@ -65,5 +65,5 @@ specify your username and password on every invocation:
.. code:: bash .. code:: bash
TOWER_USERNAME=alice TOWER_PASSWORD=secret awx jobs list CONTROLLER_USERNAME=alice CONTROLLER_PASSWORD=secret awx jobs list
awx --conf.username alice --conf.password secret jobs list awx --conf.username alice --conf.password secret jobs list

View File

@@ -54,4 +54,4 @@ Colorized Output
By default, |prog| prints colorized output using ANSI color codes. To disable By default, |prog| prints colorized output using ANSI color codes. To disable
this functionality, specify ``--conf.color f`` or set the environment variable this functionality, specify ``--conf.color f`` or set the environment variable
``TOWER_COLOR=f``. ``CONTROLLER_COLOR=f``.

View File

@@ -77,17 +77,17 @@ A few of the most important ones are:
``-f, --conf.format`` ``-f, --conf.format``
used to specify a custom output format (the default is json) used to specify a custom output format (the default is json)
``--conf.host, TOWER_HOST`` ``--conf.host, CONTROLLER_HOST``
the full URL of the AWX/|RHAT| host (i.e., https://my.awx.example.org) the full URL of the AWX/|RHAT| host (i.e., https://my.awx.example.org)
``-k, --conf.insecure, TOWER_VERIFY_SSL`` ``-k, --conf.insecure, CONTROLLER_VERIFY_SSL``
allows insecure server connections when using SSL allows insecure server connections when using SSL
``--conf.username, TOWER_USERNAME`` ``--conf.username, CONTROLLER_USERNAME``
the AWX username to use for authentication the AWX username to use for authentication
``--conf.password, TOWER_PASSWORD`` ``--conf.password, CONTROLLER_PASSWORD``
the AWX password to use for authentication the AWX password to use for authentication
``--conf.token, TOWER_OAUTH_TOKEN`` ``--conf.token, CONTROLLER_OAUTH_TOKEN``
an OAuth2.0 token to use for authentication an OAuth2.0 token to use for authentication

View File

@@ -11,30 +11,30 @@ def add_authentication_arguments(parser, env):
auth = parser.add_argument_group('authentication') auth = parser.add_argument_group('authentication')
auth.add_argument( auth.add_argument(
'--conf.host', '--conf.host',
default=env.get('TOWER_HOST', 'https://127.0.0.1:443'), default=env.get('CONTROLLER_HOST', env.get('TOWER_HOST', 'https://127.0.0.1:443')),
metavar='https://example.awx.org', metavar='https://example.awx.org',
) )
auth.add_argument( auth.add_argument(
'--conf.token', '--conf.token',
default=env.get('TOWER_OAUTH_TOKEN', env.get('TOWER_TOKEN', '')), default=env.get('CONTROLLER_OAUTH_TOKEN', env.get('CONTROLLER_TOKEN', env.get('TOWER_OAUTH_TOKEN', env.get('TOWER_TOKEN', '')))),
help='an OAuth2.0 token (get one by using `awx login`)', help='an OAuth2.0 token (get one by using `awx login`)',
metavar='TEXT', metavar='TEXT',
) )
auth.add_argument( auth.add_argument(
'--conf.username', '--conf.username',
default=env.get('TOWER_USERNAME', 'admin'), default=env.get('CONTROLLER_USERNAME', env.get('TOWER_USERNAME', 'admin')),
metavar='TEXT', metavar='TEXT',
) )
auth.add_argument( auth.add_argument(
'--conf.password', '--conf.password',
default=env.get('TOWER_PASSWORD', 'password'), default=env.get('CONTROLLER_PASSWORD', env.get('TOWER_PASSWORD', 'password')),
metavar='TEXT', metavar='TEXT',
) )
auth.add_argument( auth.add_argument(
'-k', '-k',
'--conf.insecure', '--conf.insecure',
help='Allow insecure server connections when using SSL', help='Allow insecure server connections when using SSL',
default=not strtobool(env.get('TOWER_VERIFY_SSL', 'True')), default=not strtobool(env.get('CONTROLLER_VERIFY_SSL', env.get('TOWER_VERIFY_SSL', 'True'))),
action='store_true', action='store_true',
) )
@@ -47,7 +47,7 @@ def add_output_formatting_arguments(parser, env):
'--conf.format', '--conf.format',
dest='conf.format', dest='conf.format',
choices=FORMATTERS.keys(), choices=FORMATTERS.keys(),
default=env.get('TOWER_FORMAT', 'json'), default=env.get('CONTROLLER_FORMAT', env.get('TOWER_FORMAT', 'json')),
help=('specify a format for the input and output'), help=('specify a format for the input and output'),
) )
formatting.add_argument( formatting.add_argument(
@@ -61,7 +61,7 @@ def add_output_formatting_arguments(parser, env):
'--conf.color', '--conf.color',
metavar='BOOLEAN', metavar='BOOLEAN',
help='Display colorized output. Defaults to True', help='Display colorized output. Defaults to True',
default=env.get('TOWER_COLOR', 't'), default=env.get('CONTROLLER_COLOR', env.get('TOWER_COLOR', 't')),
type=strtobool, type=strtobool,
) )
formatting.add_argument( formatting.add_argument(
@@ -69,7 +69,7 @@ def add_output_formatting_arguments(parser, env):
'--verbose', '--verbose',
dest='conf.verbose', dest='conf.verbose',
help='print debug-level logs, including requests made', help='print debug-level logs, including requests made',
default=strtobool(env.get('TOWER_VERBOSE', 'f')), default=strtobool(env.get('CONTROLLER_VERBOSE', env.get('TOWER_VERBOSE', 'f'))),
action="store_true", action="store_true",
) )

View File

@@ -99,7 +99,7 @@ class Login(CustomCommand):
else: else:
fmt = client.get_config('format') fmt = client.get_config('format')
if fmt == 'human': if fmt == 'human':
print('export TOWER_OAUTH_TOKEN={}'.format(token)) print('export CONTROLLER_OAUTH_TOKEN={}'.format(token))
else: else:
print(to_str(FORMATTERS[fmt]({'token': token}, '.')).strip()) print(to_str(FORMATTERS[fmt]({'token': token}, '.')).strip())

View File

@@ -43,7 +43,7 @@ def render():
# The return value of this function is an argparse.ArgumentParser, which # The return value of this function is an argparse.ArgumentParser, which
# the sphinxcontrib.autoprogram plugin crawls and generates an indexed # the sphinxcontrib.autoprogram plugin crawls and generates an indexed
# Sphinx document from. # Sphinx document from.
for e in ('TOWER_HOST', 'TOWER_USERNAME', 'TOWER_PASSWORD'): for e in ('CONTROLLER_HOST', 'CONTROLLER_USERNAME', 'CONTROLLER_PASSWORD'):
if not os.environ.get(e): if not os.environ.get(e):
raise SystemExit('Please specify a valid {} for a real (running) installation.'.format(e)) # noqa raise SystemExit('Please specify a valid {} for a real (running) installation.'.format(e)) # noqa
cli = CLI() cli = CLI()

View File

@@ -7,7 +7,7 @@ from awxkit import config
def test_host_from_environment(): def test_host_from_environment():
cli = CLI() cli = CLI()
cli.parse_args(['awx'], env={'TOWER_HOST': 'https://xyz.local'}) cli.parse_args(['awx'], env={'CONTROLLER_HOST': 'https://xyz.local'})
with pytest.raises(ConnectionError): with pytest.raises(ConnectionError):
cli.connect() cli.connect()
assert config.base_url == 'https://xyz.local' assert config.base_url == 'https://xyz.local'
@@ -23,7 +23,7 @@ def test_host_from_argv():
def test_username_and_password_from_environment(): def test_username_and_password_from_environment():
cli = CLI() cli = CLI()
cli.parse_args(['awx'], env={'TOWER_USERNAME': 'mary', 'TOWER_PASSWORD': 'secret'}) cli.parse_args(['awx'], env={'CONTROLLER_USERNAME': 'mary', 'CONTROLLER_PASSWORD': 'secret'})
with pytest.raises(ConnectionError): with pytest.raises(ConnectionError):
cli.connect() cli.connect()
@@ -43,7 +43,7 @@ def test_username_and_password_argv():
def test_config_precedence(): def test_config_precedence():
cli = CLI() cli = CLI()
cli.parse_args(['awx', '--conf.username', 'mary', '--conf.password', 'secret'], env={'TOWER_USERNAME': 'IGNORE', 'TOWER_PASSWORD': 'IGNORE'}) cli.parse_args(['awx', '--conf.username', 'mary', '--conf.password', 'secret'], env={'CONTROLLER_USERNAME': 'IGNORE', 'CONTROLLER_PASSWORD': 'IGNORE'})
with pytest.raises(ConnectionError): with pytest.raises(ConnectionError):
cli.connect() cli.connect()