mirror of
https://github.com/ansible/awx.git
synced 2026-01-09 23:12:08 -03:30
Add in more model changes around execution environments
- a new unique name field to EE - a new configure-Tower-in-Tower setting DEFAULT_EXECUTION_ENVIRONMENT - an Org-level execution_environment_admin_role - a default_environment field on Project - a new Container Registry credential type - order EEs by reverse of the created timestamp - a method to resolve which EE to use on jobs
This commit is contained in:
parent
c0faa39b53
commit
c1133b3f6d
@ -107,8 +107,8 @@ SUMMARIZABLE_FK_FIELDS = {
|
||||
'insights_credential_id',),
|
||||
'host': DEFAULT_SUMMARY_FIELDS,
|
||||
'group': DEFAULT_SUMMARY_FIELDS,
|
||||
'default_environment': ('id', 'organization_id', 'image', 'description'),
|
||||
'execution_environment': ('id', 'organization_id', 'image', 'description'),
|
||||
'default_environment': DEFAULT_SUMMARY_FIELDS + ('image',),
|
||||
'execution_environment': DEFAULT_SUMMARY_FIELDS + ('image',),
|
||||
'project': DEFAULT_SUMMARY_FIELDS + ('status', 'scm_type'),
|
||||
'source_project': DEFAULT_SUMMARY_FIELDS + ('status', 'scm_type'),
|
||||
'project_update': DEFAULT_SUMMARY_FIELDS + ('status', 'failed',),
|
||||
@ -1365,7 +1365,7 @@ class ExecutionEnvironmentSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = ExecutionEnvironment
|
||||
fields = ('*', '-name', 'organization', 'image', 'managed_by_tower', 'credential')
|
||||
fields = ('*', 'organization', 'image', 'managed_by_tower', 'credential')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(ExecutionEnvironmentSerializer, self).get_related(obj)
|
||||
@ -1395,7 +1395,7 @@ class ProjectSerializer(UnifiedJobTemplateSerializer, ProjectOptionsSerializer):
|
||||
class Meta:
|
||||
model = Project
|
||||
fields = ('*', 'organization', 'scm_update_on_launch',
|
||||
'scm_update_cache_timeout', 'allow_override', 'custom_virtualenv',) + \
|
||||
'scm_update_cache_timeout', 'allow_override', 'custom_virtualenv', 'default_environment') + \
|
||||
('last_update_failed', 'last_updated') # Backwards compatibility
|
||||
|
||||
def get_related(self, obj):
|
||||
@ -1420,6 +1420,9 @@ class ProjectSerializer(UnifiedJobTemplateSerializer, ProjectOptionsSerializer):
|
||||
if obj.organization:
|
||||
res['organization'] = self.reverse('api:organization_detail',
|
||||
kwargs={'pk': obj.organization.pk})
|
||||
if obj.default_environment:
|
||||
res['default_environment'] = self.reverse('api:execution_environment_detail',
|
||||
kwargs={'pk': obj.default_environment_id})
|
||||
# Backwards compatibility.
|
||||
if obj.current_update:
|
||||
res['current_update'] = self.reverse('api:project_update_detail',
|
||||
|
||||
@ -14,6 +14,7 @@ from rest_framework.fields import ( # noqa
|
||||
BooleanField, CharField, ChoiceField, DictField, DateTimeField, EmailField,
|
||||
IntegerField, ListField, NullBooleanField
|
||||
)
|
||||
from rest_framework.serializers import PrimaryKeyRelatedField
|
||||
|
||||
logger = logging.getLogger('awx.conf.fields')
|
||||
|
||||
|
||||
@ -1320,6 +1320,8 @@ class ExecutionEnvironmentAccess(BaseAccess):
|
||||
"""
|
||||
|
||||
model = ExecutionEnvironment
|
||||
select_related = ('organization',)
|
||||
prefetch_related = ('organization__admin_role',)
|
||||
|
||||
def filtered_queryset(self):
|
||||
return ExecutionEnvironment.objects.filter(
|
||||
|
||||
@ -10,6 +10,7 @@ from rest_framework.fields import FloatField
|
||||
|
||||
# Tower
|
||||
from awx.conf import fields, register, register_validate
|
||||
from awx.main.models import ExecutionEnvironment
|
||||
|
||||
|
||||
logger = logging.getLogger('awx.main.conf')
|
||||
@ -176,6 +177,18 @@ register(
|
||||
read_only=True,
|
||||
)
|
||||
|
||||
register(
|
||||
'DEFAULT_EXECUTION_ENVIRONMENT',
|
||||
field_class=fields.PrimaryKeyRelatedField,
|
||||
allow_null=True,
|
||||
default=None,
|
||||
queryset=ExecutionEnvironment.objects.all(),
|
||||
label=_('Global default execution environment'),
|
||||
help_text=_('.'),
|
||||
category=_('System'),
|
||||
category_slug='system',
|
||||
)
|
||||
|
||||
register(
|
||||
'CUSTOM_VENV_PATHS',
|
||||
field_class=fields.StringListPathField,
|
||||
|
||||
41
awx/main/migrations/0125_more_ee_modeling_changes.py
Normal file
41
awx/main/migrations/0125_more_ee_modeling_changes.py
Normal file
@ -0,0 +1,41 @@
|
||||
# Generated by Django 2.2.16 on 2020-11-19 16:20
|
||||
import uuid
|
||||
|
||||
import awx.main.fields
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('main', '0124_execution_environments'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='executionenvironment',
|
||||
options={'ordering': ('-created',)},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='executionenvironment',
|
||||
name='name',
|
||||
field=models.CharField(default=uuid.uuid4, max_length=512, unique=True),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='organization',
|
||||
name='execution_environment_admin_role',
|
||||
field=awx.main.fields.ImplicitRoleField(editable=False, null='True', on_delete=django.db.models.deletion.CASCADE, parent_role='admin_role', related_name='+', to='main.Role'),
|
||||
preserve_default='True',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='project',
|
||||
name='default_environment',
|
||||
field=models.ForeignKey(blank=True, default=None, help_text='The default execution environment for jobs run using this project.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='main.ExecutionEnvironment'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='executionenvironment',
|
||||
unique_together=set(),
|
||||
),
|
||||
]
|
||||
@ -1133,7 +1133,6 @@ ManagedCredentialType(
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
ManagedCredentialType(
|
||||
namespace='kubernetes_bearer_token',
|
||||
kind='kubernetes',
|
||||
@ -1165,6 +1164,37 @@ ManagedCredentialType(
|
||||
}
|
||||
)
|
||||
|
||||
ManagedCredentialType(
|
||||
namespace='registry',
|
||||
kind='registry',
|
||||
name=ugettext_noop('Container Registry'),
|
||||
inputs={
|
||||
'fields': [{
|
||||
'id': 'host',
|
||||
'label': ugettext_noop('Authentication URL'),
|
||||
'type': 'string',
|
||||
'help_text': ugettext_noop('Authentication endpoint for the container registry.'),
|
||||
}, {
|
||||
'id': 'username',
|
||||
'label': ugettext_noop('Username'),
|
||||
'type': 'string',
|
||||
}, {
|
||||
'id': 'password',
|
||||
'label': ugettext_noop('Password'),
|
||||
'type': 'string',
|
||||
'secret': True,
|
||||
}, {
|
||||
'id': 'token',
|
||||
'label': ugettext_noop('Access Token'),
|
||||
'type': 'string',
|
||||
'secret': True,
|
||||
'help_text': ugettext_noop('A token to use to authenticate with. '
|
||||
'This should not be set if username/password are being used.'),
|
||||
}],
|
||||
'required': ['host'],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
ManagedCredentialType(
|
||||
namespace='galaxy_api_token',
|
||||
|
||||
@ -2,16 +2,15 @@ from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from awx.api.versioning import reverse
|
||||
from awx.main.models.base import PrimordialModel
|
||||
from awx.main.models.base import CommonModel
|
||||
|
||||
|
||||
__all__ = ['ExecutionEnvironment']
|
||||
|
||||
|
||||
class ExecutionEnvironment(PrimordialModel):
|
||||
class ExecutionEnvironment(CommonModel):
|
||||
class Meta:
|
||||
unique_together = ('organization', 'image')
|
||||
ordering = (models.F('organization_id').asc(nulls_first=True), 'image')
|
||||
ordering = ('-created',)
|
||||
|
||||
organization = models.ForeignKey(
|
||||
'Organization',
|
||||
|
||||
@ -95,6 +95,9 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
|
||||
job_template_admin_role = ImplicitRoleField(
|
||||
parent_role='admin_role',
|
||||
)
|
||||
execution_environment_admin_role = ImplicitRoleField(
|
||||
parent_role='admin_role',
|
||||
)
|
||||
auditor_role = ImplicitRoleField(
|
||||
parent_role='singleton:' + ROLE_SINGLETON_SYSTEM_AUDITOR,
|
||||
)
|
||||
|
||||
@ -259,6 +259,15 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
|
||||
app_label = 'main'
|
||||
ordering = ('id',)
|
||||
|
||||
default_environment = models.ForeignKey(
|
||||
'ExecutionEnvironment',
|
||||
null=True,
|
||||
blank=True,
|
||||
default=None,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+',
|
||||
help_text=_('The default execution environment for jobs run using this project.'),
|
||||
)
|
||||
scm_update_on_launch = models.BooleanField(
|
||||
default=False,
|
||||
help_text=_('Update the project when a job is launched that uses the project.'),
|
||||
|
||||
@ -40,6 +40,7 @@ role_names = {
|
||||
'inventory_admin_role': _('Inventory Admin'),
|
||||
'credential_admin_role': _('Credential Admin'),
|
||||
'job_template_admin_role': _('Job Template Admin'),
|
||||
'execution_environment_admin_role': _('Execution Environment Admin'),
|
||||
'workflow_admin_role': _('Workflow Admin'),
|
||||
'notification_admin_role': _('Notification Admin'),
|
||||
'auditor_role': _('Auditor'),
|
||||
@ -60,6 +61,7 @@ role_descriptions = {
|
||||
'inventory_admin_role': _('Can manage all inventories of the %s'),
|
||||
'credential_admin_role': _('Can manage all credentials of the %s'),
|
||||
'job_template_admin_role': _('Can manage all job templates of the %s'),
|
||||
'execution_environment_admin_role': _('Can manage all execution environments of the %s'),
|
||||
'workflow_admin_role': _('Can manage all workflows of the %s'),
|
||||
'notification_admin_role': _('Can manage all notifications of the %s'),
|
||||
'auditor_role': _('Can view all aspects of the %s'),
|
||||
|
||||
@ -40,6 +40,7 @@ from awx.main.dispatch import get_local_queuename
|
||||
from awx.main.dispatch.control import Control as ControlDispatcher
|
||||
from awx.main.registrar import activity_stream_registrar
|
||||
from awx.main.models.mixins import ResourceMixin, TaskManagerUnifiedJobMixin, ExecutionEnvironmentMixin
|
||||
from awx.main.models.execution_environments import ExecutionEnvironment
|
||||
from awx.main.utils import (
|
||||
camelcase_to_underscore, get_model_for_type,
|
||||
encrypt_dict, decrypt_field, _inventory_updates,
|
||||
@ -338,6 +339,23 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, ExecutionEn
|
||||
from awx.main.models.notifications import NotificationTemplate
|
||||
return NotificationTemplate.objects.none()
|
||||
|
||||
def resolve_execution_environment(self):
|
||||
"""
|
||||
Return the execution environment that should be used when creating a new job.
|
||||
"""
|
||||
if self.execution_environment is not None:
|
||||
return self.execution_environment
|
||||
if getattr(self, 'project_id', None) and self.project.default_environment is not None:
|
||||
return self.project.default_environment
|
||||
if getattr(self, 'organization', None) and self.organization.default_environment is not None:
|
||||
return self.organization.default_environment
|
||||
if getattr(self, 'inventory', None) and self.inventory.organization is not None:
|
||||
if self.inventory.organization.default_environment is not None:
|
||||
return self.inventory.organization.default_environment
|
||||
if settings.DEFAULT_EXECUTION_ENVIRONMENT is not None:
|
||||
return settings.DEFAULT_EXECUTION_ENVIRONMENT
|
||||
return ExecutionEnvironment.objects.filter(organization=None, managed_by_tower=True).first()
|
||||
|
||||
def create_unified_job(self, **kwargs):
|
||||
'''
|
||||
Create a new unified job based on this unified job template.
|
||||
@ -376,6 +394,8 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, ExecutionEn
|
||||
for fd, val in eager_fields.items():
|
||||
setattr(unified_job, fd, val)
|
||||
|
||||
unified_job.execution_environment = self.resolve_execution_environment()
|
||||
|
||||
# NOTE: slice workflow jobs _get_parent_field_name method
|
||||
# is not correct until this is set
|
||||
if not parent_field_name:
|
||||
|
||||
@ -90,6 +90,7 @@ def test_default_cred_types():
|
||||
'kubernetes_bearer_token',
|
||||
'net',
|
||||
'openstack',
|
||||
'registry',
|
||||
'rhv',
|
||||
'satellite6',
|
||||
'scm',
|
||||
|
||||
@ -175,6 +175,7 @@ REMOTE_HOST_HEADERS = ['REMOTE_ADDR', 'REMOTE_HOST']
|
||||
PROXY_IP_ALLOWED_LIST = []
|
||||
|
||||
CUSTOM_VENV_PATHS = []
|
||||
DEFAULT_EXECUTION_ENVIRONMENT = None
|
||||
|
||||
# Note: This setting may be overridden by database settings.
|
||||
STDOUT_MAX_BYTES_DISPLAY = 1048576
|
||||
|
||||
@ -18,7 +18,7 @@ log = logging.getLogger(__name__)
|
||||
class ExecutionEnvironment(HasCreate, base.Base):
|
||||
|
||||
dependencies = [Organization, Credential]
|
||||
NATURAL_KEY = ('organization', 'image')
|
||||
NATURAL_KEY = ('name',)
|
||||
|
||||
# fields are image, organization, managed_by_tower, credential
|
||||
def create(self, image='quay.io/ansible/ansible-runner:devel', credential=None, **kwargs):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user