From 0271aa611c404b3625564f80e4a066c36b001871 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Tue, 26 Jul 2016 09:44:00 -0400 Subject: [PATCH 1/4] add field to JT for asking to skip tags --- awx/api/serializers.py | 20 ++++++--------- awx/api/templates/api/job_template_launch.md | 2 ++ awx/main/access.py | 4 +-- .../migrations/0027_v302_add_ask_skip_tags.py | 25 +++++++++++++++++++ awx/main/models/jobs.py | 12 ++++++++- .../functional/api/test_job_runtime_params.py | 2 ++ .../tests/functional/api/test_job_template.py | 3 ++- 7 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 awx/main/migrations/0027_v302_add_ask_skip_tags.py diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 730cd97f82..0663971337 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1825,7 +1825,7 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer): class Meta: model = JobTemplate fields = ('*', 'host_config_key', 'ask_variables_on_launch', 'ask_limit_on_launch', - 'ask_tags_on_launch', 'ask_job_type_on_launch', 'ask_inventory_on_launch', + 'ask_tags_on_launch', 'ask_skip_tags_on_launch', 'ask_job_type_on_launch', 'ask_inventory_on_launch', 'ask_credential_on_launch', 'survey_enabled', 'become_enabled', 'allow_simultaneous') def get_related(self, obj): @@ -1907,17 +1907,12 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer): class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer): passwords_needed_to_start = serializers.ReadOnlyField() - ask_variables_on_launch = serializers.ReadOnlyField() - ask_limit_on_launch = serializers.ReadOnlyField() - ask_tags_on_launch = serializers.ReadOnlyField() - ask_job_type_on_launch = serializers.ReadOnlyField() - ask_inventory_on_launch = serializers.ReadOnlyField() - ask_credential_on_launch = serializers.ReadOnlyField() class Meta: model = Job fields = ('*', 'job_template', 'passwords_needed_to_start', 'ask_variables_on_launch', - 'ask_limit_on_launch', 'ask_tags_on_launch', 'ask_job_type_on_launch', + 'ask_limit_on_launch', 'ask_tags_on_launch', + 'ask_skip_tags_on_launch', 'ask_job_type_on_launch', 'ask_inventory_on_launch', 'ask_credential_on_launch') def get_related(self, obj): @@ -2282,14 +2277,15 @@ class JobLaunchSerializer(BaseSerializer): fields = ('can_start_without_user_input', 'passwords_needed_to_start', 'extra_vars', 'limit', 'job_tags', 'skip_tags', 'job_type', 'inventory', 'credential', 'ask_variables_on_launch', 'ask_tags_on_launch', - 'ask_job_type_on_launch', 'ask_limit_on_launch', + 'ask_skip_tags_on_launch', 'ask_job_type_on_launch', 'ask_limit_on_launch', 'ask_inventory_on_launch', 'ask_credential_on_launch', 'survey_enabled', 'variables_needed_to_start', 'credential_needed_to_start', 'inventory_needed_to_start', 'job_template_data', 'defaults') - read_only_fields = ('ask_variables_on_launch', 'ask_limit_on_launch', - 'ask_tags_on_launch', 'ask_job_type_on_launch', - 'ask_inventory_on_launch', 'ask_credential_on_launch') + read_only_fields = ( + 'ask_variables_on_launch', 'ask_limit_on_launch', 'ask_tags_on_launch', + 'ask_skip_tags_on_launch', 'ask_job_type_on_launch', + 'ask_inventory_on_launch', 'ask_credential_on_launch') extra_kwargs = { 'credential': {'write_only': True,}, 'limit': {'write_only': True,}, diff --git a/awx/api/templates/api/job_template_launch.md b/awx/api/templates/api/job_template_launch.md index 0c17c3d842..10c2c4288e 100644 --- a/awx/api/templates/api/job_template_launch.md +++ b/awx/api/templates/api/job_template_launch.md @@ -8,6 +8,8 @@ The response will include the following fields: configured to prompt for variables upon launch (boolean, read-only) * `ask_tags_on_launch`: Flag indicating whether the job_template is configured to prompt for tags upon launch (boolean, read-only) +* `ask_skip_tags_on_launch`: Flag indicating whether the job_template is + configured to prompt for skip_tags upon launch (boolean, read-only) * `ask_job_type_on_launch`: Flag indicating whether the job_template is configured to prompt for job_type upon launch (boolean, read-only) * `ask_limit_on_launch`: Flag indicating whether the job_template is diff --git a/awx/main/access.py b/awx/main/access.py index ed3a5b86c9..e5ca8fa0ec 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -981,8 +981,8 @@ class JobTemplateAccess(BaseAccess): field_whitelist = [ 'name', 'description', 'forks', 'limit', 'verbosity', 'extra_vars', 'job_tags', 'force_handlers', 'skip_tags', 'ask_variables_on_launch', - 'ask_tags_on_launch', 'ask_job_type_on_launch', 'ask_inventory_on_launch', - 'ask_credential_on_launch', 'survey_enabled', + 'ask_tags_on_launch', 'ask_job_type_on_launch', 'ask_skip_tags_on_launch', + 'ask_inventory_on_launch', 'ask_credential_on_launch', 'survey_enabled', # These fields are ignored, but it is convenient for QA to allow clients to post them 'last_job_run', 'created', 'modified', diff --git a/awx/main/migrations/0027_v302_add_ask_skip_tags.py b/awx/main/migrations/0027_v302_add_ask_skip_tags.py new file mode 100644 index 0000000000..7d237ca9ff --- /dev/null +++ b/awx/main/migrations/0027_v302_add_ask_skip_tags.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import awx.main.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0026_v300_credential_unique'), + ] + + operations = [ + migrations.AddField( + model_name='jobtemplate', + name='ask_skip_tags_on_launch', + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name='credential', + name='read_role', + field=awx.main.fields.ImplicitRoleField(related_name='+', parent_role=[b'singleton:system_auditor', b'organization.auditor_role', b'use_role', b'admin_role'], to='main.Role', null=b'True'), + ), + ] diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index ac67bf8d67..a7c1c6041d 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -199,6 +199,10 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): blank=True, default=False, ) + ask_skip_tags_on_launch = models.BooleanField( + blank=True, + default=False, + ) ask_job_type_on_launch = models.BooleanField( blank=True, default=False, @@ -418,7 +422,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): extra_vars=self.ask_variables_on_launch, limit=self.ask_limit_on_launch, job_tags=self.ask_tags_on_launch, - skip_tags=self.ask_tags_on_launch, + skip_tags=self.ask_skip_tags_on_launch, job_type=self.ask_job_type_on_launch, inventory=self.ask_inventory_on_launch, credential=self.ask_credential_on_launch @@ -550,6 +554,12 @@ class Job(UnifiedJob, JobOptions): return self.job_template.ask_tags_on_launch return False + @property + def ask_skip_tags_on_launch(self): + if self.job_template is not None: + return self.job_template.ask_skip_tags_on_launch + return False + @property def ask_job_type_on_launch(self): if self.job_template is not None: diff --git a/awx/main/tests/functional/api/test_job_runtime_params.py b/awx/main/tests/functional/api/test_job_runtime_params.py index 46aeadb6d0..bcbbb07dc9 100644 --- a/awx/main/tests/functional/api/test_job_runtime_params.py +++ b/awx/main/tests/functional/api/test_job_runtime_params.py @@ -37,6 +37,7 @@ def job_template_prompts(project, inventory, machine_credential): name='deploy-job-template', ask_variables_on_launch=on_off, ask_tags_on_launch=on_off, + ask_skip_tags_on_launch=on_off, ask_job_type_on_launch=on_off, ask_inventory_on_launch=on_off, ask_limit_on_launch=on_off, @@ -54,6 +55,7 @@ def job_template_prompts_null(project): name='deploy-job-template', ask_variables_on_launch=True, ask_tags_on_launch=True, + ask_skip_tags_on_launch=True, ask_job_type_on_launch=True, ask_inventory_on_launch=True, ask_limit_on_launch=True, diff --git a/awx/main/tests/functional/api/test_job_template.py b/awx/main/tests/functional/api/test_job_template.py index cab2e53731..a5a961f88e 100644 --- a/awx/main/tests/functional/api/test_job_template.py +++ b/awx/main/tests/functional/api/test_job_template.py @@ -103,9 +103,10 @@ def test_edit_nonsenstive(patch, job_template_factory, alice): 'extra_vars': '--', 'job_tags': 'sometags', 'force_handlers': True, - 'skip_tags': True, + 'skip_tags': 'thistag,thattag', 'ask_variables_on_launch':True, 'ask_tags_on_launch':True, + 'ask_skip_tags_on_launch':True, 'ask_job_type_on_launch':True, 'ask_inventory_on_launch':True, 'ask_credential_on_launch': True, From 0e702e0a50576067cdd7c43e7348f20939b665b0 Mon Sep 17 00:00:00 2001 From: Michael Abashian Date: Wed, 27 Jul 2016 10:44:53 -0400 Subject: [PATCH 2/4] Added support for skip_tags in the UI --- awx/ui/client/src/forms/JobTemplates.js | 22 +++++++++++++++++++ awx/ui/client/src/helpers/JobTemplates.js | 3 +++ .../src/job-detail/job-detail.partial.html | 5 +++++ .../launchjob.factory.js | 4 ++++ .../job-submission.controller.js | 6 ++++- .../job-submission.partial.html | 10 ++++++++- .../add/job-templates-add.controller.js | 1 + .../edit/job-templates-edit.controller.js | 1 + 8 files changed, 50 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/src/forms/JobTemplates.js b/awx/ui/client/src/forms/JobTemplates.js index 6cb6f833a2..7d5adad1df 100644 --- a/awx/ui/client/src/forms/JobTemplates.js +++ b/awx/ui/client/src/forms/JobTemplates.js @@ -240,6 +240,28 @@ export default text: 'Prompt on launch' } }, + skip_tags: { + label: 'Skip Tags', + type: 'textarea', + rows: 5, + addRequired: false, + editRequired: false, + 'elementClass': 'Form-textInput', + column: 2, + awPopOver: "

Provide a comma separated list of tags.

\n" + + "

Tags are useful when you have a large playbook, and you want to run a specific part of a play or task.

" + + "

For example, you might have a task consisting of a long list of actions. Tag values can be assigned to each action. " + + "Suppose the actions have been assigned tag values of "configuration", "packages" and "install".

" + + "

If you just want to run the "configuration" and "packages" actions, you would enter the following here " + + "in the Job Tags field:

\n
configuration,packages
\n", + dataTitle: "Skip Tags", + dataPlacement: "right", + dataContainer: "body", + subCheckbox: { + variable: 'ask_skip_tags_on_launch', + text: 'Prompt on launch' + } + }, checkbox_group: { label: 'Options', type: 'checkbox_group', diff --git a/awx/ui/client/src/helpers/JobTemplates.js b/awx/ui/client/src/helpers/JobTemplates.js index 2947c05546..dba72869a4 100644 --- a/awx/ui/client/src/helpers/JobTemplates.js +++ b/awx/ui/client/src/helpers/JobTemplates.js @@ -132,6 +132,9 @@ angular.module('JobTemplatesHelper', ['Utilities']) scope.ask_tags_on_launch = (data.ask_tags_on_launch) ? true : false; master.ask_tags_on_launch = scope.ask_tags_on_launch; + scope.ask_skip_tags_on_launch = (data.ask_skip_tags_on_launch) ? true : false; + master.ask_skip_tags_on_launch = scope.ask_skip_tags_on_launch; + scope.ask_job_type_on_launch = (data.ask_job_type_on_launch) ? true : false; master.ask_job_type_on_launch = scope.ask_job_type_on_launch; diff --git a/awx/ui/client/src/job-detail/job-detail.partial.html b/awx/ui/client/src/job-detail/job-detail.partial.html index 0be9e4eb6b..37bf4de249 100644 --- a/awx/ui/client/src/job-detail/job-detail.partial.html +++ b/awx/ui/client/src/job-detail/job-detail.partial.html @@ -154,6 +154,11 @@
{{ job.job_tags }}
+
+ +
{{ job.skip_tags }}
+
+
diff --git a/awx/ui/client/src/job-submission/job-submission-factories/launchjob.factory.js b/awx/ui/client/src/job-submission/job-submission-factories/launchjob.factory.js index 74e57cf149..ff0ee1e824 100644 --- a/awx/ui/client/src/job-submission/job-submission-factories/launchjob.factory.js +++ b/awx/ui/client/src/job-submission/job-submission-factories/launchjob.factory.js @@ -46,6 +46,10 @@ export default job_launch_data.job_tags = scope.other_prompt_data.job_tags; } + if(scope.ask_skip_tags_on_launch && scope.other_prompt_data && scope.other_prompt_data.skip_tags){ + job_launch_data.skip_tags = scope.other_prompt_data.skip_tags; + } + if(scope.ask_limit_on_launch && scope.other_prompt_data && scope.other_prompt_data.limit){ job_launch_data.limit = scope.other_prompt_data.limit; } diff --git a/awx/ui/client/src/job-submission/job-submission.controller.js b/awx/ui/client/src/job-submission/job-submission.controller.js index 16fc77324e..008c34990f 100644 --- a/awx/ui/client/src/job-submission/job-submission.controller.js +++ b/awx/ui/client/src/job-submission/job-submission.controller.js @@ -153,7 +153,7 @@ export default // General catch-all for "other prompts" - used in this link function and to hide the Other Prompts tab when // it should be hidden - $scope.has_other_prompts = (data.ask_job_type_on_launch || data.ask_limit_on_launch || data.ask_tags_on_launch || data.ask_variables_on_launch) ? true : false; + $scope.has_other_prompts = (data.ask_job_type_on_launch || data.ask_limit_on_launch || data.ask_tags_on_launch || data.ask_skip_tags_on_launch || data.ask_variables_on_launch) ? true : false; $scope.password_needed = data.passwords_needed_to_start && data.passwords_needed_to_start.length > 0; $scope.has_default_inventory = data.defaults && data.defaults.inventory && data.defaults.inventory.id; $scope.has_default_credential = data.defaults && data.defaults.credential && data.defaults.credential.id; @@ -172,6 +172,10 @@ export default $scope.other_prompt_data.job_tags = (data.defaults && data.defaults.job_tags) ? data.defaults.job_tags : ""; } + if($scope.ask_skip_tags_on_launch) { + $scope.other_prompt_data.skip_tags = (data.defaults && data.defaults.skip_tags) ? data.defaults.skip_tags : ""; + } + if($scope.ask_variables_on_launch) { $scope.jobLaunchVariables = (data.defaults && data.defaults.extra_vars) ? data.defaults.extra_vars : "---"; $scope.other_prompt_data.parseType = 'yaml'; diff --git a/awx/ui/client/src/job-submission/job-submission.partial.html b/awx/ui/client/src/job-submission/job-submission.partial.html index 3f69234d91..1c1d398586 100644 --- a/awx/ui/client/src/job-submission/job-submission.partial.html +++ b/awx/ui/client/src/job-submission/job-submission.partial.html @@ -148,7 +148,15 @@ Job Tags
- + +
+
+
+ +
+
diff --git a/awx/ui/client/src/job-templates/add/job-templates-add.controller.js b/awx/ui/client/src/job-templates/add/job-templates-add.controller.js index 717aac7a08..39a9377c0a 100644 --- a/awx/ui/client/src/job-templates/add/job-templates-add.controller.js +++ b/awx/ui/client/src/job-templates/add/job-templates-add.controller.js @@ -518,6 +518,7 @@ } data.ask_tags_on_launch = $scope.ask_tags_on_launch ? $scope.ask_tags_on_launch : false; + data.ask_skip_tags_on_launch = $scope.ask_skip_tags_on_launch ? $scope.ask_skip_tags_on_launch : false; data.ask_limit_on_launch = $scope.ask_limit_on_launch ? $scope.ask_limit_on_launch : false; data.ask_job_type_on_launch = $scope.ask_job_type_on_launch ? $scope.ask_job_type_on_launch : false; data.ask_inventory_on_launch = $scope.ask_inventory_on_launch ? $scope.ask_inventory_on_launch : false; diff --git a/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js b/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js index 8a2f433dbc..c30412504a 100644 --- a/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js +++ b/awx/ui/client/src/job-templates/edit/job-templates-edit.controller.js @@ -640,6 +640,7 @@ export default } data.ask_tags_on_launch = $scope.ask_tags_on_launch ? $scope.ask_tags_on_launch : false; + data.ask_skip_tags_on_launch = $scope.ask_skip_tags_on_launch ? $scope.ask_skip_tags_on_launch : false; data.ask_limit_on_launch = $scope.ask_limit_on_launch ? $scope.ask_limit_on_launch : false; data.ask_job_type_on_launch = $scope.ask_job_type_on_launch ? $scope.ask_job_type_on_launch : false; data.ask_inventory_on_launch = $scope.ask_inventory_on_launch ? $scope.ask_inventory_on_launch : false; From bedcdadcfc775e595d117de7c008e33b13a7bb8b Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Wed, 27 Jul 2016 11:14:15 -0400 Subject: [PATCH 3/4] job launch read_only fields made more clear --- awx/api/serializers.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 0663971337..06bffdf446 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1906,14 +1906,14 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer): class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer): - passwords_needed_to_start = serializers.ReadOnlyField() - class Meta: model = Job - fields = ('*', 'job_template', 'passwords_needed_to_start', 'ask_variables_on_launch', - 'ask_limit_on_launch', 'ask_tags_on_launch', - 'ask_skip_tags_on_launch', 'ask_job_type_on_launch', - 'ask_inventory_on_launch', 'ask_credential_on_launch') + fields = ('*', 'job_template', ) + read_only_fields = ( + '*', 'passwords_needed_to_start', 'ask_variables_on_launch', + 'ask_limit_on_launch', 'ask_tags_on_launch', + 'ask_skip_tags_on_launch', 'ask_job_type_on_launch', + 'ask_inventory_on_launch', 'ask_credential_on_launch') def get_related(self, obj): res = super(JobSerializer, self).get_related(obj) From c6ecdbbfc148a374521f7e675d27ec85686f0d9c Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Mon, 1 Aug 2016 16:23:47 -0400 Subject: [PATCH 4/4] remove unrelated field from ask_skip_tags_on_launch migration and update migration and access.py changes to not conflict with other changes --- ...add_ask_skip_tags.py => 0029_v302_add_ask_skip_tags.py} | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) rename awx/main/migrations/{0027_v302_add_ask_skip_tags.py => 0029_v302_add_ask_skip_tags.py} (52%) diff --git a/awx/main/migrations/0027_v302_add_ask_skip_tags.py b/awx/main/migrations/0029_v302_add_ask_skip_tags.py similarity index 52% rename from awx/main/migrations/0027_v302_add_ask_skip_tags.py rename to awx/main/migrations/0029_v302_add_ask_skip_tags.py index 7d237ca9ff..0aa5192c33 100644 --- a/awx/main/migrations/0027_v302_add_ask_skip_tags.py +++ b/awx/main/migrations/0029_v302_add_ask_skip_tags.py @@ -8,7 +8,7 @@ import awx.main.fields class Migration(migrations.Migration): dependencies = [ - ('main', '0026_v300_credential_unique'), + ('main', '0028_v300_org_team_cascade'), ] operations = [ @@ -17,9 +17,4 @@ class Migration(migrations.Migration): name='ask_skip_tags_on_launch', field=models.BooleanField(default=False), ), - migrations.AlterField( - model_name='credential', - name='read_role', - field=awx.main.fields.ImplicitRoleField(related_name='+', parent_role=[b'singleton:system_auditor', b'organization.auditor_role', b'use_role', b'admin_role'], to='main.Role', null=b'True'), - ), ]