From e91d383165f5f0712b14305ba8b29d4e6162ce4a Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Fri, 18 Oct 2019 18:28:59 -0400 Subject: [PATCH 01/46] Fix off-by-one errors --- awx/ui/client/features/output/render.service.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index 161aebceb3..11d7108cd0 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -473,7 +473,7 @@ function JobRenderService ($q, $compile, $sce, $window) { this.shift = lines => { // We multiply by two here under the assumption that one element and one text node // is generated for each line of output. - const count = 2 * lines; + const count = (2 * lines) + 1; const elements = this.el.contents().slice(0, count); return this.remove(elements); @@ -482,7 +482,7 @@ function JobRenderService ($q, $compile, $sce, $window) { this.pop = lines => { // We multiply by two here under the assumption that one element and one text node // is generated for each line of output. - const count = 2 * lines; + const count = (2 * lines) + 1; const elements = this.el.contents().slice(-count); return this.remove(elements); @@ -558,7 +558,7 @@ function JobRenderService ($q, $compile, $sce, $window) { } const max = this.state.tail; - const min = max - count; + const min = max - count + 1; let lines = 0; @@ -589,7 +589,7 @@ function JobRenderService ($q, $compile, $sce, $window) { } const min = this.state.head; - const max = min + count; + const max = min + count - 1; let lines = 0; From cf5d3d55f05cab224013a3cdc90be4b6f22d92b7 Mon Sep 17 00:00:00 2001 From: Jake McDermott Date: Fri, 18 Oct 2019 18:44:06 -0400 Subject: [PATCH 02/46] Set omitted runner event line lengths to 0 runner_on_start events have zero-length strings for their stdout fields. We don't want to display these in the ui so we omit them. Although the stdout field is an empty string, it still has a recorded line length of 1 that we must account for. Since we're not rendering the blank line, we must also go back and set the event record's line length to 0 in order to avoid deleting too many lines when we pop or shift events off of the view while scrolling. --- awx/ui/client/features/output/render.service.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/awx/ui/client/features/output/render.service.js b/awx/ui/client/features/output/render.service.js index 11d7108cd0..3dad042aa4 100644 --- a/awx/ui/client/features/output/render.service.js +++ b/awx/ui/client/features/output/render.service.js @@ -213,6 +213,18 @@ function JobRenderService ($q, $compile, $sce, $window) { const record = this.createRecord(event, lines); if (lines.length === 1 && lines[0] === '') { + // Some events, mainly runner_on_start events, have an actual line count of 1 + // (stdout = '') and a claimed line count of 0 (end_line - start_line = 0). + // Since a zero-length string has an actual line count of 1, they'll still get + // rendered as blank lines unless we intercept them and add some special + // handling to remove them. + // + // Although we're not going to render the blank line, the actual line count of + // the zero-length stdout string, which is 1, has already been recorded at this + // point so we must also go back and set the event's recorded line length to 0 + // in order to avoid deleting too many lines when we need to pop or shift a + // page that contains this event off of the view. + this.records[record.uuid].lineCount = 0; return { html: '', count: 0 }; } From 6dfc714c75b47314894e1e59c35c4c525914367c Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Mon, 21 Oct 2019 11:01:35 -0400 Subject: [PATCH 03/46] when isolated or container jobs fail to launch, set job status to error a status of error makes more sense, because failed generally points to an issue with the playbook itself, while error is more generally used for reporting issues internal to Tower see: https://github.com/ansible/awx/issues/4909 --- awx/main/isolated/manager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/awx/main/isolated/manager.py b/awx/main/isolated/manager.py index d78587cf7b..5a0555ed72 100644 --- a/awx/main/isolated/manager.py +++ b/awx/main/isolated/manager.py @@ -172,6 +172,7 @@ class IsolatedManager(object): if runner_obj.status == 'failed': self.instance.result_traceback = runner_obj.stdout.read() self.instance.save(update_fields=['result_traceback']) + return 'error', runner_obj.rc return runner_obj.status, runner_obj.rc From d06b0de74b3d6d7e549157d3892f3523c8d20518 Mon Sep 17 00:00:00 2001 From: mabashian Date: Mon, 21 Oct 2019 11:55:12 -0400 Subject: [PATCH 04/46] Revert 6282b5bacbb30f31bc7bbf53df668ac8ed68829f --- awx/ui/client/legacy/styles/lists.less | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/legacy/styles/lists.less b/awx/ui/client/legacy/styles/lists.less index 8357a78b78..3e004461af 100644 --- a/awx/ui/client/legacy/styles/lists.less +++ b/awx/ui/client/legacy/styles/lists.less @@ -372,7 +372,9 @@ table, tbody { .List-noItems { margin-top: 52px; - display: inline-block; + display: flex; + align-items: center; + justify-content: center; width: 100%; height: 200px; border-radius: 5px; @@ -381,7 +383,7 @@ table, tbody { color: @list-no-items-txt; text-transform: uppercase; text-align: center; - padding: 80px 10px; + padding: 10px; } .modal-body > .List-noItems { From b2b33605cc457a408b0e959bd500eefcca19e406 Mon Sep 17 00:00:00 2001 From: Graham Mainwaring Date: Mon, 21 Oct 2019 16:10:25 -0400 Subject: [PATCH 05/46] Add UI toggle to disable public Galaxy (#3867) --- awx/main/conf.py | 10 +++++++++ awx/main/redact.py | 8 ++++--- awx/main/tasks.py | 12 +++++++--- awx/settings/defaults.py | 22 ++++++++++--------- .../jobs-form/configuration-jobs.form.js | 3 +++ 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/awx/main/conf.py b/awx/main/conf.py index cce5e0a5de..f63fee564f 100644 --- a/awx/main/conf.py +++ b/awx/main/conf.py @@ -513,6 +513,16 @@ register( category_slug='jobs' ) +register( + 'PUBLIC_GALAXY_ENABLED', + field_class=fields.BooleanField, + default=True, + label=_('Allow Access to Public Galaxy'), + help_text=_('Allow or deny access to the public Ansible Galaxy during project updates.'), + category=_('Jobs'), + category_slug='jobs' +) + register( 'STDOUT_MAX_BYTES_DISPLAY', field_class=fields.IntegerField, diff --git a/awx/main/redact.py b/awx/main/redact.py index ae60684377..77fc062135 100644 --- a/awx/main/redact.py +++ b/awx/main/redact.py @@ -12,10 +12,12 @@ class UriCleaner(object): @staticmethod def remove_sensitive(cleartext): + # exclude_list contains the items that will _not_ be redacted + exclude_list = [settings.PUBLIC_GALAXY_SERVER['url']] if settings.PRIMARY_GALAXY_URL: - exclude_list = [settings.PRIMARY_GALAXY_URL] + [server['url'] for server in settings.FALLBACK_GALAXY_SERVERS] - else: - exclude_list = [server['url'] for server in settings.FALLBACK_GALAXY_SERVERS] + exclude_list += [settings.PRIMARY_GALAXY_URL] + if settings.FALLBACK_GALAXY_SERVERS: + exclude_list += [server['url'] for server in settings.FALLBACK_GALAXY_SERVERS] redactedtext = cleartext text_index = 0 while True: diff --git a/awx/main/tasks.py b/awx/main/tasks.py index ff53cd00ac..a91a4cf4b2 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -1959,9 +1959,15 @@ class RunProjectUpdate(BaseTask): env['PROJECT_UPDATE_ID'] = str(project_update.pk) env['ANSIBLE_CALLBACK_PLUGINS'] = self.get_path_to('..', 'plugins', 'callback') env['ANSIBLE_GALAXY_IGNORE'] = True - # Set up the fallback server, which is the normal Ansible Galaxy by default - galaxy_servers = list(settings.FALLBACK_GALAXY_SERVERS) - # If private galaxy URL is non-blank, that means this feature is enabled + # Set up the public Galaxy server, if enabled + if settings.PUBLIC_GALAXY_ENABLED: + galaxy_servers = [settings.PUBLIC_GALAXY_SERVER] + else: + galaxy_servers = [] + # Set up fallback Galaxy servers, if configured + if settings.FALLBACK_GALAXY_SERVERS: + galaxy_servers = settings.FALLBACK_GALAXY_SERVERS + galaxy_servers + # Set up the primary Galaxy server, if configured if settings.PRIMARY_GALAXY_URL: galaxy_servers = [{'id': 'primary_galaxy'}] + galaxy_servers for key in GALAXY_SERVER_FIELDS: diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 658d41d6b3..ab8a5492e8 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -635,16 +635,18 @@ PRIMARY_GALAXY_USERNAME = '' PRIMARY_GALAXY_TOKEN = '' PRIMARY_GALAXY_PASSWORD = '' PRIMARY_GALAXY_AUTH_URL = '' -# Settings for the fallback galaxy server(s), normally this is the -# actual Ansible Galaxy site. -# server options: 'id', 'url', 'username', 'password', 'token', 'auth_url' -# To not use any fallback servers set this to [] -FALLBACK_GALAXY_SERVERS = [ - { - 'id': 'galaxy', - 'url': 'https://galaxy.ansible.com' - } -] + +# Settings for the public galaxy server(s). +PUBLIC_GALAXY_ENABLED = True +PUBLIC_GALAXY_SERVER = { + 'id': 'galaxy', + 'url': 'https://galaxy.ansible.com' +} + +# List of dicts of fallback (additional) Galaxy servers. If configured, these +# will be higher precedence than public Galaxy, but lower than primary Galaxy. +# Available options: 'id', 'url', 'username', 'password', 'token', 'auth_url' +FALLBACK_GALAXY_SERVERS = [] # Enable bubblewrap support for running jobs (playbook runs only). # Note: This setting may be overridden by database settings. diff --git a/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js b/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js index 445b0864a2..ab3aa7404c 100644 --- a/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js +++ b/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js @@ -89,6 +89,9 @@ export default ['i18n', function(i18n) { type: 'text', reset: 'PRIMARY_GALAXY_AUTH_URL', }, + PUBLIC_GALAXY_ENABLED: { + type: 'toggleSwitch', + }, AWX_TASK_ENV: { type: 'textarea', reset: 'AWX_TASK_ENV', From 2b6cfd7b3d7260329a0dd49163a9c1da73fe0b83 Mon Sep 17 00:00:00 2001 From: Marliana Lara Date: Mon, 21 Oct 2019 16:13:52 -0400 Subject: [PATCH 06/46] Handle undefined schedule value in job detail component --- awx/ui/client/features/output/details.component.js | 4 +++- awx/ui/client/features/output/details.partial.html | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/awx/ui/client/features/output/details.component.js b/awx/ui/client/features/output/details.component.js index 532b04055a..de76ee669e 100644 --- a/awx/ui/client/features/output/details.component.js +++ b/awx/ui/client/features/output/details.component.js @@ -282,10 +282,12 @@ function getLaunchedByDetails () { tooltip = strings.get('tooltips.SCHEDULE'); link = `/#/templates/job_template/${jobTemplate.id}/schedules/${schedule.id}`; value = $filter('sanitize')(schedule.name); - } else { + } else if (schedule) { tooltip = null; link = null; value = $filter('sanitize')(schedule.name); + } else { + return null; } return { label, link, tooltip, value }; diff --git a/awx/ui/client/features/output/details.partial.html b/awx/ui/client/features/output/details.partial.html index 14bf856269..7264059b49 100644 --- a/awx/ui/client/features/output/details.partial.html +++ b/awx/ui/client/features/output/details.partial.html @@ -5,7 +5,7 @@
- +