Skip to content

Commit

Permalink
Merge branch 'update-gha' of github.com:jessicamack/awx into update-gha
Browse files Browse the repository at this point in the history
  • Loading branch information
jessicamack committed Oct 16, 2024
2 parents 1898688 + c6dc6cb commit 6872f15
Show file tree
Hide file tree
Showing 23 changed files with 499 additions and 582 deletions.
20 changes: 19 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,25 @@ jobs:
tests:
- name: api-test
command: /start_tests.sh test_coverage
coverage-upload-name: ""
- name: api-migrations
command: /start_tests.sh test_migrations
coverage-upload-name: ""
- name: api-lint
command: /var/lib/awx/venv/awx/bin/tox -e linters
coverage-upload-name: ""
- name: api-swagger
command: /start_tests.sh swagger
coverage-upload-name: ""
- name: awx-collection
command: /start_tests.sh test_collection_all
coverage-upload-name: "awx-collection"
- name: api-schema
command: >-
/start_tests.sh detect-schema-change SCHEMA_DIFF_BASE_BRANCH=${{
github.event.pull_request.base.ref || github.ref_name
}}
coverage-upload-name: ""

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -109,7 +115,7 @@ jobs:
-v \
--user "${{ vars.PDE_ORG_RESULTS_AGGREGATOR_UPLOAD_USER }}:${{ secrets.PDE_ORG_RESULTS_UPLOAD_PASSWORD }}" \
--form "xunit_xml=@${junit_file}" \
--form "component_name=awx" \
--form "component_name=${{ matrix.tests.coverage-upload-name || 'awx' }}" \
--form "git_commit_sha=${{ github.sha }}" \
--form "git_repository_url=https://github.com/${{ github.repository }}" \
"${{ vars.PDE_ORG_RESULTS_AGGREGATOR_UPLOAD_URL }}/api/results/upload/"
Expand All @@ -123,6 +129,10 @@ jobs:
with:
show-progress: false

- uses: actions/setup-python@v5
with:
python-version: '3.x'

- uses: ./.github/actions/run_awx_devel
id: awx
with:
Expand Down Expand Up @@ -260,6 +270,10 @@ jobs:
with:
show-progress: false

- uses: actions/setup-python@v5
with:
python-version: '3.x'

- uses: ./.github/actions/run_awx_devel
id: awx
with:
Expand Down Expand Up @@ -331,6 +345,10 @@ jobs:
with:
show-progress: false

- uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Upgrade ansible-core
run: python3 -m pip install --upgrade ansible-core

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ jobs:
with:
show-progress: false

- uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: install tox
run: pip install tox

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/label_pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ jobs:
with:
show-progress: false

- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Install python requests
run: pip install requests
- name: Check if user is a member of Ansible org
Expand Down
9 changes: 6 additions & 3 deletions awx/api/generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
from rest_framework.renderers import StaticHTMLRenderer
from rest_framework.negotiation import DefaultContentNegotiation

# Shared code for the AWX platform
from awx_plugins.interfaces._temporary_private_licensing_api import detect_server_product_name

# django-ansible-base
from ansible_base.rest_filters.rest_framework.field_lookup_backend import FieldLookupBackend
from ansible_base.lib.utils.models import get_all_field_names
Expand All @@ -43,7 +46,6 @@
from awx.main.models.rbac import give_creator_permissions
from awx.main.access import optimize_queryset
from awx.main.utils import camelcase_to_underscore, get_search_fields, getattrd, get_object_or_400, decrypt_field, get_awx_version
from awx.main.utils.licensing import server_product_name
from awx.main.utils.proxy import is_proxy_in_headers, delete_headers_starting_with_http
from awx.main.views import ApiErrorView
from awx.api.serializers import ResourceAccessListElementSerializer, CopySerializer
Expand Down Expand Up @@ -244,7 +246,8 @@ def finalize_response(self, request, response, *args, **kwargs):
if hasattr(self, '__init_request_error__'):
response = self.handle_exception(self.__init_request_error__)
if response.status_code == 401:
response.data['detail'] += _(' To establish a login session, visit') + ' /api/login/.'
if response.data and 'detail' in response.data:
response.data['detail'] += _(' To establish a login session, visit') + ' /api/login/.'
logger.info(status_msg)
else:
logger.warning(status_msg)
Expand All @@ -253,7 +256,7 @@ def finalize_response(self, request, response, *args, **kwargs):
time_started = getattr(self, 'time_started', None)
if request.user.is_authenticated:
response['X-API-Product-Version'] = get_awx_version()
response['X-API-Product-Name'] = server_product_name()
response['X-API-Product-Name'] = detect_server_product_name()

response['X-API-Node'] = settings.CLUSTER_HOST_ID
if time_started:
Expand Down
8 changes: 5 additions & 3 deletions awx/main/models/credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
from django.utils.timezone import now
from django.contrib.auth.models import User

# Shared code for the AWX platform
from awx_plugins.interfaces._temporary_private_container_api import get_incontainer_path

# DRF
from awx.main.utils.pglock import advisory_lock
from rest_framework.serializers import ValidationError as DRFValidationError
Expand All @@ -41,7 +44,6 @@
)
from awx.main.utils import decrypt_field, classproperty, set_environ
from awx.main.utils.safe_yaml import safe_dump
from awx.main.utils.execution_environments import to_container_path
from awx.main.validators import validate_ssh_private_key
from awx.main.models.base import CommonModelNameNotUnique, PasswordFieldsModel, PrimordialModel
from awx.main.models.mixins import ResourceMixin
Expand Down Expand Up @@ -623,7 +625,7 @@ class TowerNamespace:
with open(path, 'w') as f:
f.write(data)
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
container_path = to_container_path(path, private_data_dir)
container_path = get_incontainer_path(path, private_data_dir)

# determine if filename indicates single file or many
if file_label.find('.') == -1:
Expand Down Expand Up @@ -665,7 +667,7 @@ def build_extra_vars_file(vars, private_dir):
extra_vars = build_extra_vars(self.injectors.get('extra_vars', {}))
if extra_vars:
path = build_extra_vars_file(extra_vars, private_data_dir)
container_path = to_container_path(path, private_data_dir)
container_path = get_incontainer_path(path, private_data_dir)
args.extend(['-e', '@%s' % container_path])


Expand Down
10 changes: 6 additions & 4 deletions awx/main/tasks/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
# Django
from django.conf import settings

# Shared code for the AWX platform
from awx_plugins.interfaces._temporary_private_container_api import CONTAINER_ROOT, get_incontainer_path


# Runner
import ansible_runner
Expand Down Expand Up @@ -67,7 +70,6 @@
from awx.main.tasks.facts import start_fact_cache, finish_fact_cache
from awx.main.exceptions import AwxTaskError, PostRunError, ReceptorNodeNotFound
from awx.main.utils.ansible import read_ansible_config
from awx.main.utils.execution_environments import CONTAINER_ROOT, to_container_path
from awx.main.utils.safe_yaml import safe_dump, sanitize_jinja
from awx.main.utils.common import (
update_scm_url,
Expand Down Expand Up @@ -299,7 +301,7 @@ def build_env(self, instance, private_data_dir, private_data_files=None):
env = {}
# Add ANSIBLE_* settings to the subprocess environment.
for attr in dir(settings):
if attr == attr.upper() and attr.startswith('ANSIBLE_'):
if attr == attr.upper() and attr.startswith('ANSIBLE_') and not attr.startswith('ANSIBLE_BASE_'):
env[attr] = str(getattr(settings, attr))
# Also set environment variables configured in AWX_TASK_ENV setting.
for key, value in settings.AWX_TASK_ENV.items():
Expand Down Expand Up @@ -909,7 +911,7 @@ def build_env(self, job, private_data_dir, private_data_files=None):
cred_files = private_data_files.get('credentials', {})
for cloud_cred in job.cloud_credentials:
if cloud_cred and cloud_cred.credential_type.namespace == 'openstack' and cred_files.get(cloud_cred, ''):
env['OS_CLIENT_CONFIG_FILE'] = to_container_path(cred_files.get(cloud_cred, ''), private_data_dir)
env['OS_CLIENT_CONFIG_FILE'] = get_incontainer_path(cred_files.get(cloud_cred, ''), private_data_dir)

for network_cred in job.network_credentials:
env['ANSIBLE_NET_USERNAME'] = network_cred.get_input('username', default='')
Expand Down Expand Up @@ -1552,7 +1554,7 @@ def build_args(self, inventory_update, private_data_dir, passwords):
args.append('-i')
script_params = dict(hostvars=True, towervars=True)
source_inv_path = self.write_inventory_file(input_inventory, private_data_dir, f'hosts_{input_inventory.id}', script_params)
args.append(to_container_path(source_inv_path, private_data_dir))
args.append(get_incontainer_path(source_inv_path, private_data_dir))
# Include any facts from input inventories so they can be used in filters
start_fact_cache(
input_inventory.hosts.only(*HOST_FACTS_FIELDS),
Expand Down
32 changes: 32 additions & 0 deletions awx/main/tests/functional/api/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
import pytest

from django.contrib.sessions.middleware import SessionMiddleware
from django.test.utils import override_settings
from django.contrib.auth.models import AnonymousUser

from ansible_base.lib.utils.response import get_relative_url
from ansible_base.lib.testing.fixtures import settings_override_mutable # NOQA: F401 imported to be a pytest fixture

from awx.main.models import User
from awx.api.versioning import reverse
Expand All @@ -16,6 +21,33 @@
EXAMPLE_USER_DATA = {"username": "affable", "first_name": "a", "last_name": "a", "email": "[email protected]", "is_superuser": False, "password": "r$TyKiOCb#ED"}


@pytest.mark.django_db
def test_validate_local_user(post, admin_user, settings, settings_override_mutable): # NOQA: F811 this is how you use a pytest fixture
"Copy of the test by same name in django-ansible-base for integration and compatibility testing"
url = get_relative_url('validate-local-account')
admin_user.set_password('password')
admin_user.save()
data = {
"username": admin_user.username,
"password": "password",
}
with override_settings(RESOURCE_SERVER={"URL": "https://foo.invalid", "SECRET_KEY": "foobar"}):
response = post(url=url, data=data, user=AnonymousUser(), expect=200)

assert 'ansible_id' in response.data
assert response.data['auth_code'] is not None, response.data

# No resource server, return coherent response but can not provide auth code
response = post(url=url, data=data, user=AnonymousUser(), expect=200)
assert 'ansible_id' in response.data
assert response.data['auth_code'] is None

# wrong password
data['password'] = 'foobar'
response = post(url=url, data=data, user=AnonymousUser(), expect=401)
# response.data may be none here, this is just testing that we get no server error


@pytest.mark.django_db
def test_user_create(post, admin):
response = post(reverse('api:user_list'), EXAMPLE_USER_DATA, admin, middleware=SessionMiddleware(mock.Mock()))
Expand Down
7 changes: 4 additions & 3 deletions awx/main/tests/functional/test_inventory_source_injectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
import re
from collections import namedtuple

from awx_plugins.interfaces._temporary_private_container_api import get_incontainer_path

from awx.main.tasks.jobs import RunInventoryUpdate
from awx.main.models import InventorySource, Credential, CredentialType, UnifiedJob, ExecutionEnvironment
from awx.main.constants import CLOUD_PROVIDERS, STANDARD_INVENTORY_UPDATE_ENV
from awx.main.tests import data
from awx.main.utils.execution_environments import to_container_path

from django.conf import settings

Expand Down Expand Up @@ -115,7 +116,7 @@ def read_content(private_data_dir, raw_env, inventory_update):
continue # Ansible runner
abs_file_path = os.path.join(private_data_dir, filename)
file_aliases[abs_file_path] = filename
runner_path = to_container_path(abs_file_path, private_data_dir)
runner_path = get_incontainer_path(abs_file_path, private_data_dir)
if runner_path in inverse_env:
referenced_paths.add(abs_file_path)
alias = 'file_reference'
Expand Down Expand Up @@ -163,7 +164,7 @@ def read_content(private_data_dir, raw_env, inventory_update):
# assert that all files laid down are used
if (
abs_file_path not in referenced_paths
and to_container_path(abs_file_path, private_data_dir) not in inventory_content
and get_incontainer_path(abs_file_path, private_data_dir) not in inventory_content
and abs_file_path not in ignore_files
):
raise AssertionError(
Expand Down
3 changes: 2 additions & 1 deletion awx/main/tests/unit/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import yaml
import jinja2

from awx_plugins.interfaces._temporary_private_container_api import CONTAINER_ROOT

from django.conf import settings

from awx.main.models import (
Expand All @@ -37,7 +39,6 @@
from awx.main.tasks import jobs, system, receptor
from awx.main.utils import encrypt_field, encrypt_value
from awx.main.utils.safe_yaml import SafeLoader
from awx.main.utils.execution_environments import CONTAINER_ROOT

from awx.main.utils.licensing import Licenser
from awx.main.constants import JOB_VARIABLE_PREFIXES
Expand Down
8 changes: 4 additions & 4 deletions awx/main/tests/unit/utils/test_execution_environments.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from awx.main.utils.execution_environments import to_container_path
from awx_plugins.interfaces._temporary_private_container_api import get_incontainer_path


private_data_dir = '/tmp/pdd_iso/awx_xxx'
Expand All @@ -22,7 +22,7 @@
],
)
def test_switch_paths(container_path, host_path):
assert to_container_path(host_path, private_data_dir) == container_path
assert get_incontainer_path(host_path, private_data_dir) == container_path


def test_symlink_isolation_dir(request):
Expand All @@ -40,7 +40,7 @@ def remove_folders():

pdd = f'{dst_path}/awx_xxx'

assert to_container_path(f'{pdd}/env/tmp1234', pdd) == '/runner/env/tmp1234'
assert get_incontainer_path(f'{pdd}/env/tmp1234', pdd) == '/runner/env/tmp1234'


@pytest.mark.parametrize(
Expand All @@ -53,4 +53,4 @@ def remove_folders():
)
def test_invalid_host_path(host_path):
with pytest.raises(RuntimeError):
to_container_path(host_path, private_data_dir)
get_incontainer_path(host_path, private_data_dir)
Loading

0 comments on commit 6872f15

Please sign in to comment.