flake8 compliance

This commit is contained in:
sundeep-co-in
2016-10-28 14:07:08 +05:30
13 changed files with 82 additions and 82 deletions

View File

@@ -624,8 +624,8 @@ class UnifiedJobSerializer(BaseSerializer):
obj_size = obj.result_stdout_size obj_size = obj.result_stdout_size
if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY: if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY:
return _("Standard Output too large to display (%(text_size)d bytes), " return _("Standard Output too large to display (%(text_size)d bytes), "
"only download supported for sizes over %(supported_size)d bytes") \ "only download supported for sizes over %(supported_size)d bytes") % {
% {'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY} 'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
return obj.result_stdout return obj.result_stdout
@@ -682,8 +682,8 @@ class UnifiedJobStdoutSerializer(UnifiedJobSerializer):
obj_size = obj.result_stdout_size obj_size = obj.result_stdout_size
if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY: if obj_size > settings.STDOUT_MAX_BYTES_DISPLAY:
return _("Standard Output too large to display (%(text_size)d bytes), " return _("Standard Output too large to display (%(text_size)d bytes), "
"only download supported for sizes over %(supported_size)d bytes") \ "only download supported for sizes over %(supported_size)d bytes") % {
% {'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY} 'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
return obj.result_stdout return obj.result_stdout
def get_types(self): 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) job_type = attrs.get('job_type', self.instance and self.instance.job_type or None)
if not project and job_type != PERM_INVENTORY_SCAN: if not project and job_type != PERM_INVENTORY_SCAN:
raise serializers.ValidationError({'project': _('This field is required.')}) 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.')}) raise serializers.ValidationError({'playbook': _('Playbook not found for project.')})
if project and not playbook: if project and not playbook:
raise serializers.ValidationError({'playbook': _('Must select playbook for project.')}) raise serializers.ValidationError({'playbook': _('Must select playbook for project.')})
@@ -2324,6 +2324,11 @@ class WorkflowJobTemplateNodeSerializer(WorkflowNodeBaseSerializer):
raise serializers.ValidationError({ raise serializers.ValidationError({
"job_type": _("%(job_type)s is not a valid job type. The choices are %(choices)s.") % { "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}}) '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) ujt_obj = attrs.get('unified_job_template', None)
if isinstance(ujt_obj, (WorkflowJobTemplate, SystemJobTemplate)): if isinstance(ujt_obj, (WorkflowJobTemplate, SystemJobTemplate)):
raise serializers.ValidationError({ raise serializers.ValidationError({
@@ -2832,7 +2837,7 @@ class ActivityStreamSerializer(BaseSerializer):
rel = {} rel = {}
if obj.actor is not None: if obj.actor is not None:
rel['actor'] = reverse('api:user_detail', args=(obj.actor.pk,)) 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): if not hasattr(obj, fk):
continue continue
allm2m = getattr(obj, fk).distinct() allm2m = getattr(obj, fk).distinct()

View File

@@ -2343,8 +2343,8 @@ class JobTemplateSurveySpec(GenericAPIView):
if "variable" not in survey_item: if "variable" not in survey_item:
return Response(dict(error=_("'variable' missing from survey question %s.") % str(idx)), status=status.HTTP_400_BAD_REQUEST) 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: if survey_item['variable'] in variable_set:
return Response(dict(error=_("'variable' '%(item)s' duplicated in survey question %(survey)s.") % 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) 'item': survey_item['variable'], 'survey': str(idx)}), status=status.HTTP_400_BAD_REQUEST)
else: else:
variable_set.add(survey_item['variable']) variable_set.add(survey_item['variable'])
if "required" not in survey_item: if "required" not in survey_item:
@@ -3568,8 +3568,8 @@ class UnifiedJobStdout(RetrieveAPIView):
obj_size = unified_job.result_stdout_size obj_size = unified_job.result_stdout_size
if request.accepted_renderer.format != 'txt_download' and obj_size > settings.STDOUT_MAX_BYTES_DISPLAY: 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), " response_message = _("Standard Output too large to display (%(text_size)d bytes), "
"only download supported for sizes over %(supported_size)d bytes") % \ "only download supported for sizes over %(supported_size)d bytes") % {
{'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY} 'text_size': obj_size, 'supported_size': settings.STDOUT_MAX_BYTES_DISPLAY}
if request.accepted_renderer.format == 'json': if request.accepted_renderer.format == 'json':
return Response({'range': {'start': 0, 'end': 1, 'absolute_end': 1}, 'content': response_message}) return Response({'range': {'start': 0, 'end': 1, 'absolute_end': 1}, 'content': response_message})
else: else:

View File

@@ -1,2 +0,0 @@
# Copyright (c) 2015 Ansible, Inc.
# All Rights Reserved.

View File

@@ -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

View File

@@ -1195,7 +1195,10 @@ class JobAccess(BaseAccess):
return True return True
return self.org_access(obj, role_types=['auditor_role', 'admin_role']) 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 if not data: # So the browseable API will work
return True return True
if not self.user.is_superuser: if not self.user.is_superuser:
@@ -1219,7 +1222,9 @@ class JobAccess(BaseAccess):
return True return True
def can_change(self, obj, data): 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 @check_superuser
def can_delete(self, obj): def can_delete(self, obj):

View File

@@ -173,3 +173,21 @@ register(
category=_('Jobs'), category=_('Jobs'),
category_slug='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',
)

View File

@@ -15,12 +15,12 @@ from django.conf import settings
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_str, smart_text from django.utils.encoding import smart_str, smart_text
from django.utils.text import slugify
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.timezone import now, make_aware, get_default_timezone from django.utils.timezone import now, make_aware, get_default_timezone
# AWX # AWX
from awx.lib.compat import slugify
from awx.main.models.base import * # noqa from awx.main.models.base import * # noqa
from awx.main.models.jobs import Job from awx.main.models.jobs import Job
from awx.main.models.notifications import ( from awx.main.models.notifications import (

View File

@@ -140,7 +140,6 @@ class WorkflowNodeBase(CreatedModifiedModel):
'inventory', 'credential', 'char_prompts'] 'inventory', 'credential', 'char_prompts']
class WorkflowJobTemplateNode(WorkflowNodeBase): class WorkflowJobTemplateNode(WorkflowNodeBase):
# TODO: Ensure the API forces workflow_job_template being set
workflow_job_template = models.ForeignKey( workflow_job_template = models.ForeignKey(
'WorkflowJobTemplate', 'WorkflowJobTemplate',
related_name='workflow_job_template_nodes', related_name='workflow_job_template_nodes',
@@ -149,7 +148,7 @@ class WorkflowJobTemplateNode(WorkflowNodeBase):
default=None, default=None,
on_delete=models.CASCADE, on_delete=models.CASCADE,
) )
def get_absolute_url(self): def get_absolute_url(self):
return reverse('api:workflow_job_template_node_detail', args=(self.pk,)) return reverse('api:workflow_job_template_node_detail', args=(self.pk,))

View File

@@ -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): def mk_project(name, organization=None, description=None, persisted=True):
description = description or '{}-description'.format(name) 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: if organization is not None:
project.organization = organization project.organization = organization
if persisted: if persisted:
@@ -134,7 +135,7 @@ def mk_job_template(name, job_type='run',
extra_vars = json.dumps(extra_vars) extra_vars = json.dumps(extra_vars)
jt = JobTemplate(name=name, job_type=job_type, extra_vars=extra_vars, jt = JobTemplate(name=name, job_type=job_type, extra_vars=extra_vars,
playbook='mocked') playbook='helloworld.yml')
jt.inventory = inventory jt.inventory = inventory
if jt.inventory is None: if jt.inventory is None:

View File

@@ -1,22 +1,15 @@
import pytest import pytest
import mock
# AWX # AWX
from awx.api.serializers import JobTemplateSerializer, JobLaunchSerializer from awx.api.serializers import JobTemplateSerializer, JobLaunchSerializer
from awx.main.models.jobs import Job 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 from awx.main.migrations import _save_password_keys as save_password_keys
# Django # Django
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.apps import apps from django.apps import apps
@property
def project_playbooks(self):
return ['mocked', 'mocked.yml', 'alt-mocked.yml']
@pytest.mark.django_db @pytest.mark.django_db
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"grant_project, grant_credential, grant_inventory, expect", [ "grant_project, grant_credential, grant_inventory, expect", [
(True, True, True, 201), (True, True, True, 201),
@@ -38,11 +31,10 @@ def test_create(post, project, machine_credential, inventory, alice, grant_proje
'project': project.id, 'project': project.id,
'credential': machine_credential.id, 'credential': machine_credential.id,
'inventory': inventory.id, 'inventory': inventory.id,
'playbook': 'mocked.yml', 'playbook': 'helloworld.yml',
}, alice, expect=expect) }, alice, expect=expect)
@pytest.mark.django_db @pytest.mark.django_db
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"grant_project, grant_credential, grant_inventory, expect", [ "grant_project, grant_credential, grant_inventory, expect", [
(True, True, True, 200), (True, True, True, 200),
@@ -67,11 +59,10 @@ def test_edit_sensitive_fields(patch, job_template_factory, alice, grant_project
'project': objs.project.id, 'project': objs.project.id,
'credential': objs.credential.id, 'credential': objs.credential.id,
'inventory': objs.inventory.id, 'inventory': objs.inventory.id,
'playbook': 'alt-mocked.yml', 'playbook': 'alt-helloworld.yml',
}, alice, expect=expect) }, alice, expect=expect)
@pytest.mark.django_db @pytest.mark.django_db
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
def test_edit_playbook(patch, job_template_factory, alice): 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_factory('jt', organization='org1', project='prj', inventory='inv', credential='cred')
objs.job_template.admin_role.members.add(alice) 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) objs.inventory.use_role.members.add(alice)
patch(reverse('api:job_template_detail', args=(objs.job_template.id,)), { patch(reverse('api:job_template_detail', args=(objs.job_template.id,)), {
'playbook': 'alt-mocked.yml', 'playbook': 'alt-helloworld.yml',
}, alice, expect=200) }, alice, expect=200)
objs.inventory.use_role.members.remove(alice) objs.inventory.use_role.members.remove(alice)
patch(reverse('api:job_template_detail', args=(objs.job_template.id,)), { patch(reverse('api:job_template_detail', args=(objs.job_template.id,)), {
'playbook': 'mocked.yml', 'playbook': 'helloworld.yml',
}, alice, expect=403) }, alice, expect=403)
@pytest.mark.django_db @pytest.mark.django_db
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
def test_edit_nonsenstive(patch, job_template_factory, alice): def test_edit_nonsenstive(patch, job_template_factory, alice):
objs = job_template_factory('jt', organization='org1', project='prj', inventory='inv', credential='cred') objs = job_template_factory('jt', organization='org1', project='prj', inventory='inv', credential='cred')
jt = objs.job_template jt = objs.job_template
@@ -121,10 +111,6 @@ def jt_copy_edit(job_template_factory, project):
project=project) project=project)
return objects.job_template return objects.job_template
@property
def project_playbooks(self):
return ['mocked', 'mocked.yml', 'alt-mocked.yml']
@pytest.mark.django_db @pytest.mark.django_db
def test_job_template_role_user(post, organization_factory, job_template_factory): def test_job_template_role_user(post, organization_factory, job_template_factory):
objects = organization_factory("org", objects = organization_factory("org",
@@ -143,7 +129,6 @@ def test_job_template_role_user(post, organization_factory, job_template_factory
@pytest.mark.django_db @pytest.mark.django_db
@mock.patch.object(ProjectOptions, "playbooks", project_playbooks)
def test_jt_admin_copy_edit_functional(jt_copy_edit, rando, get, post): def test_jt_admin_copy_edit_functional(jt_copy_edit, rando, get, post):
# Grant random user JT admin access only # Grant random user JT admin access only

View File

@@ -110,7 +110,8 @@ def team_member(user, team):
def project(instance, organization): def project(instance, organization):
prj = Project.objects.create(name="test-proj", prj = Project.objects.create(name="test-proj",
description="test-proj-desc", description="test-proj-desc",
organization=organization organization=organization,
playbook_files=['helloworld.yml', 'alt-helloworld.yml']
) )
return prj return prj

View File

@@ -10,16 +10,17 @@ from datetime import timedelta
from kombu import Queue, Exchange from kombu import Queue, Exchange
# Update this module's local settings from the global settings module. # global settings
from django.conf import 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__] this_module = sys.modules[__name__]
for setting in dir(global_settings): for setting in dir(global_settings):
if setting == setting.upper(): if setting == setting.upper():
setattr(this_module, setting, getattr(global_settings, setting)) 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, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) BASE_DIR = os.path.dirname(os.path.dirname(__file__))
@@ -805,7 +806,7 @@ LOGGING = {
'()': 'django.utils.log.RequireDebugFalse', '()': 'django.utils.log.RequireDebugFalse',
}, },
'require_debug_true': { 'require_debug_true': {
'()': 'awx.lib.compat.RequireDebugTrue', '()': 'django.utils.log.RequireDebugTrue',
}, },
'require_debug_true_or_test': { 'require_debug_true_or_test': {
'()': 'awx.main.utils.RequireDebugTrueOrTest', '()': 'awx.main.utils.RequireDebugTrueOrTest',

View File

@@ -25,24 +25,42 @@
import os import os
from argparse import ArgumentParser 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 import django
from django.conf import settings from django.conf import settings
from django.core.management import call_command 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_SETTING = False
MIN_TRANS_PERCENT = '10' 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): def _handle_response(output, errors):
if not errors and '\n' in output: if not errors and '\n' in output:
for response in output.split('\n'): for response in output.split('\n'):
print(response) print(response)
return True
else: else:
print(errors.strip()) print(errors.strip())
return False
def _check_diff(base_path): 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 (1) project_type should be podir - {locale}/{filename}.po format
(2) only required languages should be kept enabled (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) {'config': PROJECT_CONFIG}, stdout=PIPE, stderr=PIPE, shell=True)
output, errors = p.communicate() 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): def stats(lang=None, both=None):
@@ -104,7 +123,8 @@ def stats(lang=None, both=None):
def update(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. new/updated translatable strings.
""" """
settings.configure() settings.configure()