mirror of
https://github.com/ansible/awx.git
synced 2026-01-10 15:32:07 -03:30
flake8 compliance
This commit is contained in:
commit
d65e121b19
@ -624,8 +624,8 @@ class UnifiedJobSerializer(BaseSerializer):
|
||||
obj_size = obj.result_stdout_size
|
||||
if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY:
|
||||
return _("Standard Output too large to display (%(text_size)d bytes), "
|
||||
"only download supported for sizes over %(supported_size)d bytes") \
|
||||
% {'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
|
||||
"only download supported for sizes over %(supported_size)d bytes") % {
|
||||
'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
|
||||
return obj.result_stdout
|
||||
|
||||
|
||||
@ -682,8 +682,8 @@ class UnifiedJobStdoutSerializer(UnifiedJobSerializer):
|
||||
obj_size = obj.result_stdout_size
|
||||
if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY:
|
||||
return _("Standard Output too large to display (%(text_size)d bytes), "
|
||||
"only download supported for sizes over %(supported_size)d bytes") \
|
||||
% {'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
|
||||
"only download supported for sizes over %(supported_size)d bytes") % {
|
||||
'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
|
||||
return obj.result_stdout
|
||||
|
||||
def get_types(self):
|
||||
@ -1849,7 +1849,7 @@ class JobOptionsSerializer(LabelsListMixin, BaseSerializer):
|
||||
job_type = attrs.get('job_type', self.instance and self.instance.job_type or None)
|
||||
if not project and job_type != PERM_INVENTORY_SCAN:
|
||||
raise serializers.ValidationError({'project': _('This field is required.')})
|
||||
if project and playbook and force_text(playbook) not in project.playbooks:
|
||||
if project and playbook and force_text(playbook) not in project.playbook_files:
|
||||
raise serializers.ValidationError({'playbook': _('Playbook not found for project.')})
|
||||
if project and not playbook:
|
||||
raise serializers.ValidationError({'playbook': _('Must select playbook for project.')})
|
||||
@ -2324,6 +2324,11 @@ class WorkflowJobTemplateNodeSerializer(WorkflowNodeBaseSerializer):
|
||||
raise serializers.ValidationError({
|
||||
"job_type": _("%(job_type)s is not a valid job type. The choices are %(choices)s.") % {
|
||||
'job_type': attrs['char_prompts']['job_type'], 'choices': job_types}})
|
||||
if self.instance is None and ('workflow_job_template' not in attrs or
|
||||
attrs['workflow_job_template'] is None):
|
||||
raise serializers.ValidationError({
|
||||
"workflow_job_template": _("Workflow job template is missing during creation")
|
||||
})
|
||||
ujt_obj = attrs.get('unified_job_template', None)
|
||||
if isinstance(ujt_obj, (WorkflowJobTemplate, SystemJobTemplate)):
|
||||
raise serializers.ValidationError({
|
||||
@ -2832,7 +2837,7 @@ class ActivityStreamSerializer(BaseSerializer):
|
||||
rel = {}
|
||||
if obj.actor is not None:
|
||||
rel['actor'] = reverse('api:user_detail', args=(obj.actor.pk,))
|
||||
for fk, _ in SUMMARIZABLE_FK_FIELDS.items():
|
||||
for fk, __ in SUMMARIZABLE_FK_FIELDS.items():
|
||||
if not hasattr(obj, fk):
|
||||
continue
|
||||
allm2m = getattr(obj, fk).distinct()
|
||||
|
||||
@ -2343,8 +2343,8 @@ class JobTemplateSurveySpec(GenericAPIView):
|
||||
if "variable" not in survey_item:
|
||||
return Response(dict(error=_("'variable' missing from survey question %s.") % str(idx)), status=status.HTTP_400_BAD_REQUEST)
|
||||
if survey_item['variable'] in variable_set:
|
||||
return Response(dict(error=_("'variable' '%(item)s' duplicated in survey question %(survey)s.") %
|
||||
{'item': survey_item['variable'], 'survey': str(idx)}), status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(dict(error=_("'variable' '%(item)s' duplicated in survey question %(survey)s.") % {
|
||||
'item': survey_item['variable'], 'survey': str(idx)}), status=status.HTTP_400_BAD_REQUEST)
|
||||
else:
|
||||
variable_set.add(survey_item['variable'])
|
||||
if "required" not in survey_item:
|
||||
@ -3568,8 +3568,8 @@ class UnifiedJobStdout(RetrieveAPIView):
|
||||
obj_size = unified_job.result_stdout_size
|
||||
if request.accepted_renderer.format != 'txt_download' and obj_size > settings.STDOUT_MAX_BYTES_DISPLAY:
|
||||
response_message = _("Standard Output too large to display (%(text_size)d bytes), "
|
||||
"only download supported for sizes over %(supported_size)d bytes") % \
|
||||
{'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
|
||||
"only download supported for sizes over %(supported_size)d bytes") % {
|
||||
'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
|
||||
if request.accepted_renderer.format == 'json':
|
||||
return Response({'range': {'start': 0, 'end': 1, 'absolute_end': 1}, 'content': response_message})
|
||||
else:
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
# Copyright (c) 2015 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
@ -1,33 +0,0 @@
|
||||
# Copyright (c) 2015 Ansible, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
'''
|
||||
Compability library for support of both Django 1.4.x and Django 1.5.x.
|
||||
'''
|
||||
|
||||
try:
|
||||
from django.utils.html import format_html
|
||||
except ImportError:
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
def format_html(format_string, *args, **kwargs):
|
||||
args_safe = map(conditional_escape, args)
|
||||
kwargs_safe = dict([(k, conditional_escape(v)) for (k, v) in
|
||||
kwargs.items()])
|
||||
return mark_safe(format_string.format(*args_safe, **kwargs_safe))
|
||||
|
||||
try:
|
||||
from django.utils.log import RequireDebugTrue
|
||||
except ImportError:
|
||||
import logging
|
||||
from django.conf import settings
|
||||
|
||||
class RequireDebugTrue(logging.Filter):
|
||||
def filter(self, record):
|
||||
return settings.DEBUG
|
||||
|
||||
try:
|
||||
from django.utils.text import slugify # noqa
|
||||
except ImportError:
|
||||
from django.template.defaultfilters import slugify # noqa
|
||||
@ -1195,7 +1195,10 @@ class JobAccess(BaseAccess):
|
||||
return True
|
||||
return self.org_access(obj, role_types=['auditor_role', 'admin_role'])
|
||||
|
||||
def can_add(self, data):
|
||||
def can_add(self, data, validate_license=True):
|
||||
if validate_license:
|
||||
self.check_license()
|
||||
|
||||
if not data: # So the browseable API will work
|
||||
return True
|
||||
if not self.user.is_superuser:
|
||||
@ -1219,7 +1222,9 @@ class JobAccess(BaseAccess):
|
||||
return True
|
||||
|
||||
def can_change(self, obj, data):
|
||||
return obj.status == 'new' and self.can_read(obj) and self.can_add(data)
|
||||
return (obj.status == 'new' and
|
||||
self.can_read(obj) and
|
||||
self.can_add(data, validate_license=False))
|
||||
|
||||
@check_superuser
|
||||
def can_delete(self, obj):
|
||||
|
||||
@ -173,3 +173,21 @@ register(
|
||||
category=_('Jobs'),
|
||||
category_slug='jobs',
|
||||
)
|
||||
|
||||
register(
|
||||
'DEFAULT_JOB_TIMEOUTS',
|
||||
field_class=fields.DictField,
|
||||
default={
|
||||
'Job': 0,
|
||||
'InventoryUpdate': 0,
|
||||
'ProjectUpdate': 0,
|
||||
},
|
||||
label=_('Default Job Timeouts'),
|
||||
help_text=_('Maximum time to allow jobs to run. Use sub-keys of Job, '
|
||||
'InventoryUpdate, and ProjectUpdate to configure this value '
|
||||
'for each job type. Use value of 0 to indicate that no '
|
||||
'timeout should be imposed. A timeout set on an individual '
|
||||
'job template will override this.'),
|
||||
category=_('Jobs'),
|
||||
category_slug='jobs',
|
||||
)
|
||||
|
||||
@ -15,12 +15,12 @@ from django.conf import settings
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import smart_str, smart_text
|
||||
from django.utils.text import slugify
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.timezone import now, make_aware, get_default_timezone
|
||||
|
||||
# AWX
|
||||
from awx.lib.compat import slugify
|
||||
from awx.main.models.base import * # noqa
|
||||
from awx.main.models.jobs import Job
|
||||
from awx.main.models.notifications import (
|
||||
|
||||
@ -140,7 +140,6 @@ class WorkflowNodeBase(CreatedModifiedModel):
|
||||
'inventory', 'credential', 'char_prompts']
|
||||
|
||||
class WorkflowJobTemplateNode(WorkflowNodeBase):
|
||||
# TODO: Ensure the API forces workflow_job_template being set
|
||||
workflow_job_template = models.ForeignKey(
|
||||
'WorkflowJobTemplate',
|
||||
related_name='workflow_job_template_nodes',
|
||||
@ -149,7 +148,7 @@ class WorkflowJobTemplateNode(WorkflowNodeBase):
|
||||
default=None,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('api:workflow_job_template_node_detail', args=(self.pk,))
|
||||
|
||||
|
||||
@ -74,7 +74,8 @@ def mk_user(name, is_superuser=False, organization=None, team=None, persisted=Tr
|
||||
|
||||
def mk_project(name, organization=None, description=None, persisted=True):
|
||||
description = description or '{}-description'.format(name)
|
||||
project = Project(name=name, description=description)
|
||||
project = Project(name=name, description=description,
|
||||
playbook_files=['helloworld.yml', 'alt-helloworld.yml'])
|
||||
if organization is not None:
|
||||
project.organization = organization
|
||||
if persisted:
|
||||
@ -134,7 +135,7 @@ def mk_job_template(name, job_type='run',
|
||||
extra_vars = json.dumps(extra_vars)
|
||||
|
||||
jt = JobTemplate(name=name, job_type=job_type, extra_vars=extra_vars,
|
||||
playbook='mocked')
|
||||
playbook='helloworld.yml')
|
||||
|
||||
jt.inventory = inventory
|
||||
if jt.inventory is None:
|
||||
|
||||
@ -1,22 +1,15 @@
|
||||
import pytest
|
||||
import mock
|
||||
|
||||
# AWX
|
||||
from awx.api.serializers import JobTemplateSerializer, JobLaunchSerializer
|
||||
from awx.main.models.jobs import Job
|
||||
from awx.main.models.projects import ProjectOptions
|
||||
from awx.main.migrations import _save_password_keys as save_password_keys
|
||||
|
||||
# Django
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.apps import apps
|
||||
|
||||
@property
|
||||
def project_playbooks(self):
|
||||
return ['mocked', 'mocked.yml', 'alt-mocked.yml']
|
||||
|
||||
@pytest.mark.django_db
|
||||
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
|
||||
@pytest.mark.parametrize(
|
||||
"grant_project, grant_credential, grant_inventory, expect", [
|
||||
(True, True, True, 201),
|
||||
@ -38,11 +31,10 @@ def test_create(post, project, machine_credential, inventory, alice, grant_proje
|
||||
'project': project.id,
|
||||
'credential': machine_credential.id,
|
||||
'inventory': inventory.id,
|
||||
'playbook': 'mocked.yml',
|
||||
'playbook': 'helloworld.yml',
|
||||
}, alice, expect=expect)
|
||||
|
||||
@pytest.mark.django_db
|
||||
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
|
||||
@pytest.mark.parametrize(
|
||||
"grant_project, grant_credential, grant_inventory, expect", [
|
||||
(True, True, True, 200),
|
||||
@ -67,11 +59,10 @@ def test_edit_sensitive_fields(patch, job_template_factory, alice, grant_project
|
||||
'project': objs.project.id,
|
||||
'credential': objs.credential.id,
|
||||
'inventory': objs.inventory.id,
|
||||
'playbook': 'alt-mocked.yml',
|
||||
'playbook': 'alt-helloworld.yml',
|
||||
}, alice, expect=expect)
|
||||
|
||||
@pytest.mark.django_db
|
||||
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
|
||||
def test_edit_playbook(patch, job_template_factory, alice):
|
||||
objs = job_template_factory('jt', organization='org1', project='prj', inventory='inv', credential='cred')
|
||||
objs.job_template.admin_role.members.add(alice)
|
||||
@ -80,16 +71,15 @@ def test_edit_playbook(patch, job_template_factory, alice):
|
||||
objs.inventory.use_role.members.add(alice)
|
||||
|
||||
patch(reverse('api:job_template_detail', args=(objs.job_template.id,)), {
|
||||
'playbook': 'alt-mocked.yml',
|
||||
'playbook': 'alt-helloworld.yml',
|
||||
}, alice, expect=200)
|
||||
|
||||
objs.inventory.use_role.members.remove(alice)
|
||||
patch(reverse('api:job_template_detail', args=(objs.job_template.id,)), {
|
||||
'playbook': 'mocked.yml',
|
||||
'playbook': 'helloworld.yml',
|
||||
}, alice, expect=403)
|
||||
|
||||
@pytest.mark.django_db
|
||||
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
|
||||
def test_edit_nonsenstive(patch, job_template_factory, alice):
|
||||
objs = job_template_factory('jt', organization='org1', project='prj', inventory='inv', credential='cred')
|
||||
jt = objs.job_template
|
||||
@ -121,10 +111,6 @@ def jt_copy_edit(job_template_factory, project):
|
||||
project=project)
|
||||
return objects.job_template
|
||||
|
||||
@property
|
||||
def project_playbooks(self):
|
||||
return ['mocked', 'mocked.yml', 'alt-mocked.yml']
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_job_template_role_user(post, organization_factory, job_template_factory):
|
||||
objects = organization_factory("org",
|
||||
@ -143,7 +129,6 @@ def test_job_template_role_user(post, organization_factory, job_template_factory
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
|
||||
def test_jt_admin_copy_edit_functional(jt_copy_edit, rando, get, post):
|
||||
|
||||
# Grant random user JT admin access only
|
||||
|
||||
@ -110,7 +110,8 @@ def team_member(user, team):
|
||||
def project(instance, organization):
|
||||
prj = Project.objects.create(name="test-proj",
|
||||
description="test-proj-desc",
|
||||
organization=organization
|
||||
organization=organization,
|
||||
playbook_files=['helloworld.yml', 'alt-helloworld.yml']
|
||||
)
|
||||
return prj
|
||||
|
||||
|
||||
@ -10,16 +10,17 @@ from datetime import timedelta
|
||||
|
||||
from kombu import Queue, Exchange
|
||||
|
||||
# Update this module's local settings from the global settings module.
|
||||
# global settings
|
||||
from django.conf import global_settings
|
||||
# ugettext lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# Update this module's local settings from the global settings module.
|
||||
this_module = sys.modules[__name__]
|
||||
for setting in dir(global_settings):
|
||||
if setting == setting.upper():
|
||||
setattr(this_module, setting, getattr(global_settings, setting))
|
||||
|
||||
# gettext
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
@ -805,7 +806,7 @@ LOGGING = {
|
||||
'()': 'django.utils.log.RequireDebugFalse',
|
||||
},
|
||||
'require_debug_true': {
|
||||
'()': 'awx.lib.compat.RequireDebugTrue',
|
||||
'()': 'django.utils.log.RequireDebugTrue',
|
||||
},
|
||||
'require_debug_true_or_test': {
|
||||
'()': 'awx.main.utils.RequireDebugTrueOrTest',
|
||||
|
||||
@ -25,24 +25,42 @@
|
||||
|
||||
import os
|
||||
from argparse import ArgumentParser
|
||||
from subprocess import PIPE, Popen, call
|
||||
from subprocess import PIPE, Popen
|
||||
from xml.etree import ElementTree as ET
|
||||
from xml.etree.ElementTree import ParseError
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.core.management import call_command
|
||||
|
||||
|
||||
PROJECT_CONFIG = "tools/scripts/zanata_config/backend-trans-config.xml"
|
||||
PROJECT_CONFIG = "tools/scripts/zanata_config/backend-translations.xml"
|
||||
MIN_TRANS_PERCENT_SETTING = False
|
||||
MIN_TRANS_PERCENT = '10'
|
||||
|
||||
|
||||
def _get_zanata_project_url():
|
||||
project_url = ''
|
||||
try:
|
||||
zanata_config = ET.parse(PROJECT_CONFIG).getroot()
|
||||
server_url = zanata_config.getchildren()[0].text
|
||||
project_id = zanata_config.getchildren()[1].text
|
||||
version_id = zanata_config.getchildren()[2].text
|
||||
middle_url = "iteration/view/" if server_url[-1:] == '/' else "/iteration/view/"
|
||||
project_url = server_url + middle_url + project_id + "/" + version_id + "/documents"
|
||||
except (ParseError, IndexError):
|
||||
print("Please re-check zanata project configuration.")
|
||||
return project_url
|
||||
|
||||
|
||||
def _handle_response(output, errors):
|
||||
if not errors and '\n' in output:
|
||||
for response in output.split('\n'):
|
||||
print(response)
|
||||
return True
|
||||
else:
|
||||
print(errors.strip())
|
||||
return False
|
||||
|
||||
|
||||
def _check_diff(base_path):
|
||||
@ -82,10 +100,11 @@ def push(lang=None, both=None):
|
||||
(1) project_type should be podir - {locale}/{filename}.po format
|
||||
(2) only required languages should be kept enabled
|
||||
"""
|
||||
p = Popen("zanata push --project-config %(config)s --disable-ssl-cert" %
|
||||
p = Popen("zanata push --project-config %(config)s --push-type source --disable-ssl-cert" %
|
||||
{'config': PROJECT_CONFIG}, stdout=PIPE, stderr=PIPE, shell=True)
|
||||
output, errors = p.communicate()
|
||||
_handle_response(output, errors)
|
||||
if _handle_response(output, errors):
|
||||
print("Zanata URL: %s\n" % _get_zanata_project_url())
|
||||
|
||||
|
||||
def stats(lang=None, both=None):
|
||||
@ -104,7 +123,8 @@ def stats(lang=None, both=None):
|
||||
|
||||
def update(lang=None, both=None):
|
||||
"""
|
||||
Update the awx/locale/django.pot files with
|
||||
Update (1) awx/locale/django.pot and/or
|
||||
(2) awx/ui/po/ansible-tower.pot files with
|
||||
new/updated translatable strings.
|
||||
"""
|
||||
settings.configure()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user