Compare commits

...

1728 Commits

Author SHA1 Message Date
softwarefactory-project-zuul[bot]
9bf721665d Merge pull request #8723 from ryanpetrello/bump-16
Bump version to 16.0.0

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-10 17:39:28 +00:00
Ryan Petrello
5f6a383ebe Bump version to 16.0.0 2020-12-10 12:12:51 -05:00
softwarefactory-project-zuul[bot]
871b862731 Merge pull request #8799 from jakemcdermott/fix-8355-part0
Place some initial files for migration view

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-10 16:31:28 +00:00
softwarefactory-project-zuul[bot]
851f7b4c7e Merge pull request #8812 from gamuniz/change_galaxy_token_logger_warning
log galaxy token message as warning

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-10 16:22:13 +00:00
softwarefactory-project-zuul[bot]
c78a50b44d Merge pull request #8728 from mabashian/social-auth
Adds support for GitHub, Azure AD, Google and SAML auth to the UI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-10 16:13:56 +00:00
Jake McDermott
704029459f Place some initial files for migration view
This restores some of the original files and routes from the migration
view of the classic ui with the eventual goal of fully reintegrating this
system with the new ui.

See: b39db745d4
2020-12-10 11:00:43 -05:00
Gabe Muniz
b78cacb4d8 log galaxy token message as warning 2020-12-10 10:36:02 -05:00
softwarefactory-project-zuul[bot]
4c5757b3bd Merge pull request #8754 from ryanpetrello/strict-csp
Introduce a strict Content-Security-Policy

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-10 15:32:53 +00:00
Jake McDermott
ca2f67e0a9 FFox ESR 78 Compatibility 2020-12-10 09:39:25 -05:00
mabashian
889eb2331c Adds support for GitHub, Azure AD, Google and SAML auth to the UI 2020-12-08 17:28:03 -05:00
softwarefactory-project-zuul[bot]
8e46166313 Merge pull request #8790 from rooftopcellist/quantity_not_exported
Aggregate quantity per sub allocation, not exported

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-08 21:52:49 +00:00
Christian M. Adams
b81f082a18 Aggregate quantity per sub allocation, not exported
* The exported field shows total quantity exported to a manifest for a given sub.  We want to sum the quantities of each sub allocation in a manifest instead.
2020-12-08 16:23:43 -05:00
nixocio
51b18aa012 Fix JobEvent tests
Fix JobEvent tests
2020-12-08 14:49:26 -05:00
softwarefactory-project-zuul[bot]
5e51dd2ff7 Merge pull request #8787 from shanemcd/remove-fsgroup-hack
Remove fsgroup hack

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-08 19:20:26 +00:00
Jake McDermott
15704e55e1 Move INLINE_RUNTIME_CHUNK flag to scripts definition
We _always_ want INLINE_RUNTIME_CHUNK to be false when building the ui,
even if someone happens to unexpectedly make a production build without
using the top-level make targets for some reason.
2020-12-08 13:26:10 -05:00
Jake McDermott
b3266f6c62 Avoid prop reference error in test 2020-12-08 13:26:07 -05:00
Jake McDermott
c120b731a4 Add global mock for webpack csp var 2020-12-08 13:26:05 -05:00
Jake McDermott
ab61675c2d Add system for strict-csp stdout html generation 2020-12-08 13:26:02 -05:00
Jake McDermott
548ebd5999 Add w3c-compliant reporting for CSP violations 2020-12-08 13:25:59 -05:00
Jake McDermott
12077627e4 Integrate CSP config with frontend framework 2020-12-08 13:25:56 -05:00
Ryan Petrello
3d5f28f790 Introduce a strict Content-Security-Policy 2020-12-08 13:25:46 -05:00
Shane McDonald
8788c904c8 Revert: Force containers in k8s to run under root group
This reverts most of:
423df6618d

Since https://github.com/sclorg/redis-container/pull/62 is now shipped downstream
2020-12-08 13:06:00 -05:00
Shane McDonald
e85a32d463 Fix typo in deployment template 2020-12-08 13:00:14 -05:00
softwarefactory-project-zuul[bot]
be08e0ce69 Merge pull request #8766 from Spredzy/bump_to_nodejs14
NodeJS: Bump to actively maintained LTS 14.15.1

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-08 15:30:26 +00:00
softwarefactory-project-zuul[bot]
3aba1e9db5 Merge pull request #8614 from jctanner/COLLECTION_PLAYBOOK_STATS
analytics: include modified column and full event_data for playbook_on_stats

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-08 13:08:41 +00:00
softwarefactory-project-zuul[bot]
4992fed5a3 Merge pull request #8770 from rooftopcellist/sat_include_port
Read in and use the Sat port if applicable for Subscriptions

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-07 21:41:41 +00:00
Christian M. Adams
aa7514a993 Read in and use the Sat port if applicable for Subscriptions 2020-12-07 13:59:58 -05:00
softwarefactory-project-zuul[bot]
ea8ebe8a9f Merge pull request #8619 from mabashian/login-functional
Convert Login.jsx to functional component

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-07 17:57:03 +00:00
mabashian
7ff82db691 Fix login after source variables change 2020-12-07 12:26:39 -05:00
mabashian
8a8bfc5176 Convert Login.jsx to functional component in preparation for social auth integration 2020-12-07 12:26:39 -05:00
Yanis Guenane
14685b9157 NodeJS: Bump to actively maintained LTS 14.15.1 2020-12-07 18:14:35 +01:00
softwarefactory-project-zuul[bot]
87e564026e Merge pull request #8775 from rooftopcellist/powertools
Fix image build - powertools repo ref changed

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-07 16:53:39 +00:00
Christian M. Adams
8795d860d6 Fix image build - powertools repo ref changed 2020-12-07 11:08:00 -05:00
softwarefactory-project-zuul[bot]
d14fa93ce9 Merge pull request #8758 from hjkatz/patch-7
Use literal quotation marks for Kubernetes annotations instead of quo…

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 20:03:33 +00:00
softwarefactory-project-zuul[bot]
e7090a6f8a Merge pull request #8757 from hjkatz/patch-6
Add kubernetes_pod_annotations to management-pod.yml.j2

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 19:38:17 +00:00
Harrison Katz
b6b87aea76 Use literal quotation marks for Kubernetes annotations instead of quote filter 2020-12-04 14:34:08 -05:00
softwarefactory-project-zuul[bot]
e6d1810844 Merge pull request #8756 from hjkatz/patch-5
Fix typo for kubernetes_service_account_annotations variable

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 19:33:49 +00:00
Harrison Katz
720e8055f8 Add kubernetes_pod_annotations to management-pod.yml.j2 2020-12-04 14:08:55 -05:00
Harrison Katz
182ff3464e Fix typo for kubernetes_service_account_annotations variable 2020-12-04 14:02:51 -05:00
softwarefactory-project-zuul[bot]
973c9d313e Merge pull request #8751 from hjkatz/patch-4
Separate Kubernetes Ingress TLS spec from backend spec

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 17:03:26 +00:00
softwarefactory-project-zuul[bot]
a89a683eb4 Merge pull request #8733 from balonik/no-preload-data
make preload data optional again

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 15:59:12 +00:00
softwarefactory-project-zuul[bot]
52646362c3 Merge pull request #8747 from hjkatz/patch-3
Add Kubernetes Service support for annotations

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 15:53:39 +00:00
softwarefactory-project-zuul[bot]
8a433f30e4 Merge pull request #8746 from hjkatz/patch-2
Add quotes to kubernetes annotations

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 15:53:35 +00:00
softwarefactory-project-zuul[bot]
496eea9647 Merge pull request #8743 from hjkatz/patch-1
Remove duplicate spec key from Ingress for kubernetes template

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 15:53:30 +00:00
Harrison Katz
6ab3d5301c Separate Kubernetes Ingress TLS spec from backend spec 2020-12-04 10:50:49 -05:00
softwarefactory-project-zuul[bot]
d93d0f00ee Merge pull request #8721 from rooftopcellist/remove_available_instance
Remove redundant available_instances field

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 15:45:29 +00:00
softwarefactory-project-zuul[bot]
4cc947d65d Merge pull request #8722 from jakemcdermott/fix-8695
Handle prompted inventory without value on schedules

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-04 14:33:58 +00:00
Harrison Katz
8b4b54d2c4 Add Kubernetes Service support for annotations 2020-12-03 18:36:02 -05:00
Harrison Katz
701deb2268 Add quotes to kubernetes annotations 2020-12-03 18:28:50 -05:00
Harrison Katz
85adc4a0ab Remove duplicate spec key from Ingress for kubernetes template 2020-12-03 18:18:18 -05:00
softwarefactory-project-zuul[bot]
9fc5579a50 Merge pull request #8737 from nixocio/ui_fix_select_translation
Add string to translation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-03 17:05:36 +00:00
softwarefactory-project-zuul[bot]
7faf9c6267 Merge pull request #8624 from nixocio/ui_issue_8620
Hide instance group for Inventory Details if the data is not available

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-03 13:24:05 +00:00
nixocio
8cb9341d8f Add string to translation
Add string to translation.
2020-12-02 16:42:15 -05:00
softwarefactory-project-zuul[bot]
8e024c234c Merge pull request #8732 from AlanCoding/save_the_hg
Change to manual instead of deleting hg projects

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-02 15:56:37 +00:00
JAKUBIS Peter H50R8VA
a5f676c3e1 make preload data optional again
Signed-off-by: JAKUBIS Peter H50R8VA <peter.jakubis@erstegroup.com>
2020-12-02 16:17:25 +01:00
Alan Rominger
99f3825826 Change to manual instead of deleting hg projects 2020-12-02 09:08:18 -05:00
softwarefactory-project-zuul[bot]
29926ba5d9 Merge pull request #8727 from AlanCoding/mercury_drops
Remove mercurial support

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-01 22:11:42 +00:00
Alan Rominger
db9fbf1493 Add log for the case that hg projects were deleted 2020-12-01 15:53:55 -05:00
Alan Rominger
590d64f40e Remove hg updates and projects in migration 2020-12-01 15:38:40 -05:00
Alan Rominger
64fa18cafe Run the UI prettier tool for CI fix 2020-12-01 14:49:49 -05:00
Alan Rominger
634df240ed Attempt to fix UI test with hg,svn replacement 2020-12-01 14:25:11 -05:00
Alan Rominger
44e6e9344b Remove mercurial support 2020-12-01 14:06:34 -05:00
nixocio
4b5b95a0f8 Hide instance group for Inventory Details if the data is not available
Hide instance group for Inventory Details if the data is not available.
This is the the same approach used in other details screens.

See: https://github.com/ansible/awx/issues/8620
2020-12-01 13:10:24 -05:00
softwarefactory-project-zuul[bot]
f5e1f2ed14 Merge pull request #8710 from wenottingham/herein-lies-the-extent-of-my-radius-knowledge
Remove old radius library from requirements

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-01 18:07:35 +00:00
softwarefactory-project-zuul[bot]
c232289323 Merge pull request #8534 from tapled/update-helm-chart-location
Updated Helm Chart Location

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-01 17:07:46 +00:00
Jake McDermott
db8c56caf4 Handle prompted inventory without value on schedules 2020-12-01 11:53:19 -05:00
Christian M. Adams
8e66172ed4 Remove redundant available_instances field 2020-12-01 11:20:21 -05:00
softwarefactory-project-zuul[bot]
62be4defa2 Merge pull request #8719 from ryanpetrello/tzid-support
correct a note about TZID support

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-01 14:58:28 +00:00
softwarefactory-project-zuul[bot]
cb590be095 Merge pull request #8718 from chrismeyersfsu/fix-inv_migration
add missing imports

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-01 14:49:07 +00:00
Ryan Petrello
72c3339719 correct a note about TZID support 2020-12-01 09:10:03 -05:00
softwarefactory-project-zuul[bot]
7ca35634a7 Merge pull request #8633 from marshmalien/refactor-project-functional
Fix notification list toolbar filter keys and convert Project/* to functional components

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-12-01 13:52:22 +00:00
Chris Meyers
4ab4f2f8f9 add missing imports 2020-12-01 08:40:18 -05:00
Marliana Lara
3e64e8225a Add ouiaIds to Select component 2020-11-30 16:13:35 -05:00
softwarefactory-project-zuul[bot]
b65d9ede81 Merge pull request #8323 from AlanCoding/prepare_your_containers
Refactor to hook in programmatic use of inventory import saving-to-DB code

Reviewed-by: Jim Ladd
             https://github.com/jladdjr
2020-11-30 20:41:58 +00:00
Bill Nottingham
12edbdab11 Remove old radius library from requirements
If it's not required by django-radius, we probably don't need it.
2020-11-30 15:12:52 -05:00
softwarefactory-project-zuul[bot]
fcdb38469b Merge pull request #8700 from jerosa/patch-1
Add Git-LFS to build image

Reviewed-by: Bill Nottingham
             https://github.com/wenottingham
2020-11-30 19:40:06 +00:00
Alan Rominger
900127fde7 Fix bug in inventory update canceling 2020-11-30 14:39:02 -05:00
softwarefactory-project-zuul[bot]
ffb2198eab Merge pull request #8594 from nixocio/ui_issue_8276
Mark organization as a required field for Galaxy crendentials

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-30 18:44:56 +00:00
softwarefactory-project-zuul[bot]
503a753241 Merge pull request #8672 from wenottingham/if-you-are-sneakerneting-does-it-become-a-pedifest
Allow combining multiple subscriptions if they are in a manifest.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-30 18:30:11 +00:00
Alan Rominger
7734def856 Fix inventory log timestamp, organize logging code
The fixes and issue where the timestaps in the stdout for
inventory updates gave the time since the start of the dispatcher
instead of the time since the start of the update.

This commit also moves the handler into the utils module where
other custom AWX handlers live, instead of tasks.py
this is to keep tasks.py relatively clean, as best as possible
2020-11-30 11:36:16 -05:00
Alan Rominger
d6e84b54c9 Some fixes for line numbering, and fixes for license error handling (#8)
* Change handling of error cases to global post_run_hook
* handle license errors correctly again
* Fix some issues with line ordering from the custom logger thing
* Remove debug log statement
* Use PermissionDenied for license errors
* More elegant handling of line initialization

Update tests to new exception type

Catch all save errors, fix timing offset bug

Fix license error handling inside import command
2020-11-30 11:35:33 -05:00
Alan Rominger
ec93af4ba8 Not all license errors are caught, do not assume they are 2020-11-30 11:35:32 -05:00
Jim Ladd
197d50bc44 patch test_inventory_update_injected_content
* proot now enabled at task-level
  since tasks are no longer calling
  awx-manage (which would set up its own proot)
* dropping proot env var since it's not
  relevant to the test
2020-11-30 11:35:32 -05:00
Jim Ladd
5ad60a3ed4 use inventory_id to get advisory_lock 2020-11-30 11:35:32 -05:00
Jim Ladd
38638b4a6b add note to remove private_dir when proot removed 2020-11-30 11:35:32 -05:00
Jim Ladd
232801e0ba cache end_line for RunInventoryUpdate jobs 2020-11-30 11:35:32 -05:00
Jim Ladd
d55f36eb90 add clarifying comment
* noting that the inv update task only uses the
  inventory update management command to
  save the inv to the database
  (it doesn't do the work of fetching hosts / groups)
2020-11-30 11:35:31 -05:00
Jim Ladd
277c47ba4e add TODO reminders to remove proot / venv code
* won't be needed once we move to container-based
  execution
2020-11-30 11:35:31 -05:00
Jim Ladd
12cbc9756b inventory updates should use custom venv 2020-11-30 11:35:31 -05:00
Jim Ladd
72df8723f6 lint 2020-11-30 11:35:31 -05:00
Jim Ladd
a8710bf2f1 restore proot for inventory updates
- in the past, inv. update jobs called `awx-manage inventory_update`
  which took care of setting up process isolation
- at this point, though, inv. update jobs call runner / ansible-inventory
  directly, so we need another way to put process isolation in place
- thankfully, there was already support for providing process isolation
  for other types of jobs (namely JT Jobs, Project Updates and Ad Hoc
  commands)
- so, we do what those other jobs do and override the stub for should_use_proot
  (which by default returns false) so that it keys off of the
  `AWX_PROOT_ENABLED` setting
2020-11-30 11:35:31 -05:00
Jim Ladd
4bdc488fe7 restore proot code
* add TODOs to note where proot-related code
  can be removed in the future
  (after moving to container-based execution)
2020-11-30 11:35:31 -05:00
Jim Ladd
9633714c49 create lock for perform_update
* perform_update can be called from either awx-manage
  or the RunInventoryUpdate task
* need to make sure that the inventory updates
  that happen with perform_update are atomic
2020-11-30 11:35:31 -05:00
Shane McDonald
66bdcee854 Address rebase fallout 2020-11-30 11:35:31 -05:00
Shane McDonald
e61f79c8c3 Fix tests 2020-11-30 11:35:30 -05:00
Alan Rominger
96fc38d182 Swap in-memory logger to write stdout in post_save_hook
This commit makes the needed changes to inventory update
post_save_hook logic so that the historic log lines that
inventory updates write will be written to stdout,
but this hack bypasses the ansible-runner verbose event
logic and dispatches verbose events directly.

Fix the venv application with the ansible-inventory system
(note: much of this is undone in a later commit)

Deal with some minor test updates for
the ansible-inventory interface changes
2020-11-30 11:32:26 -05:00
Alan Rominger
ae9ae14e5a Migrate inventory CLI options to programatic interface
POC, successfully importing with this commit

Attempt to surface saving related errors as a part of that
2020-11-30 11:31:38 -05:00
Alan Rominger
39fa70c58b Start on refactor to hook in inventory programatic use 2020-11-30 11:28:49 -05:00
nixocio
4f132e302f Mark organization as a required field for Galaxy crendentials
Mark organization as a required field for Galaxy credential type.

See: https://github.com/ansible/awx/issues/8276
2020-11-30 11:27:06 -05:00
softwarefactory-project-zuul[bot]
a45f586599 Merge pull request #8655 from mabashian/8606-adhoc-detail-cred
Display machine credential in job details when present

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-30 14:09:28 +00:00
softwarefactory-project-zuul[bot]
170e64070b Merge pull request #8659 from mabashian/7989-group-action-buttons
Hide edit/delete buttons on group details view for users that don't have permissions

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-30 13:37:35 +00:00
jerosa
7e0d2aabbd Add Git-LFS to build image 2020-11-28 14:13:59 +01:00
softwarefactory-project-zuul[bot]
ff3f5fd529 Merge pull request #8628 from nixocio/ui_issue_7681
Hide sync icon for smart inventory rows in Inventory List

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-27 21:21:30 +00:00
Bill Nottingham
52db0bf0c0 Allow combining multiple subscriptions if they are in a manifest.
The rules:
- subs must be of same SKU type (all MCTxxxx, all SERxxxx, etc)
- when combining, we take the earliest end date
2020-11-25 17:03:12 -05:00
softwarefactory-project-zuul[bot]
1e66a977c7 Merge pull request #8375 from mabashian/workflow-approvals
Adds workflow approval list and details

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-25 21:09:04 +00:00
softwarefactory-project-zuul[bot]
1b233aa8cc Merge pull request #8682 from jakemcdermott/fix-8669
Only display inventory file for scm sources

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-25 17:01:55 +00:00
Jake McDermott
294b9c8910 Only display inventory file for scm sources 2020-11-25 11:02:07 -05:00
softwarefactory-project-zuul[bot]
6f43784c47 Merge pull request #8671 from AlanCoding/weird_fail
Avoid copies made from failed updates

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-25 15:58:51 +00:00
softwarefactory-project-zuul[bot]
9921887ce8 Merge pull request #8679 from AlanCoding/text_soup
Apply more rigor to asserting text in stdout

Reviewed-by: awxbot
             https://github.com/awxbot
2020-11-25 15:49:29 +00:00
Alan Rominger
501cf297df Apply more rigor to asserting text in stdout 2020-11-25 10:04:48 -05:00
softwarefactory-project-zuul[bot]
169f55c908 Merge pull request #8668 from jakemcdermott/zuul-updates-ship-ui-next
Remove *-next make targets

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-24 21:24:19 +00:00
Jake McDermott
c0d8474ac6 Undo staged locale changes after devel build 2020-11-24 15:39:54 -05:00
Alan Rominger
44949b73cf Avoid copies made from failed updates 2020-11-24 15:33:44 -05:00
softwarefactory-project-zuul[bot]
b55c5f7de2 Merge pull request #8612 from fosterseth/fix-8501_delete_workflow_app_temp_500
Allow deletion of workflow approval template

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-24 19:07:10 +00:00
Jake McDermott
ef27ebfed8 Remove *-next make targets 2020-11-24 13:58:19 -05:00
Seth Foster
a66eca82c2 can delete approval node 2020-11-24 12:27:42 -05:00
softwarefactory-project-zuul[bot]
7248e2c6d0 Merge pull request #8607 from ansible/ship-ui-next
Ship the new ui

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-24 16:48:21 +00:00
mabashian
24f3499bd9 Hide edit/delete buttons on group details view for users that don't have permissions 2020-11-23 16:20:24 -05:00
softwarefactory-project-zuul[bot]
a50034be3c Merge pull request #8651 from wenottingham/not-any-more
Clean up some old sourve var settings in unit tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-23 20:34:52 +00:00
softwarefactory-project-zuul[bot]
470db2bc91 Merge pull request #8588 from nixocio/ui_async
Update usage of useDeleteItems

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-23 20:27:53 +00:00
Jake McDermott
02021fe2c9 Source variables provided at build time 2020-11-23 15:14:55 -05:00
softwarefactory-project-zuul[bot]
4882ca0481 Merge pull request #8643 from AlexSCorey/8642-InventoryonWFJTForm
Inventory Lookup on WFJT Form should not be required

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-23 18:57:22 +00:00
Jake McDermott
526a4c303f Include awx logos for official installs 2020-11-23 13:52:25 -05:00
softwarefactory-project-zuul[bot]
bb5f494fbd Merge pull request #8626 from nixocio/ui_minor_strings_update
Add minor update to strings

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-23 18:24:21 +00:00
Jake McDermott
c81bc60a33 Source default login logo from static files 2020-11-23 13:22:45 -05:00
Jake McDermott
a28c44e509 Source header logo from static files 2020-11-23 13:22:38 -05:00
Jake McDermott
27219d34eb Remove vestigal django stuff for old ui 2020-11-23 13:22:34 -05:00
Jake McDermott
f49e4a646f Remove legacy make targets 2020-11-23 13:22:30 -05:00
Jake McDermott
b699864f00 remove classic ui 2020-11-23 13:22:25 -05:00
Jake McDermott
abaeec40ae Ship the new ui with awx installation and builds 2020-11-23 13:22:12 -05:00
mabashian
f81f6cf114 Remove fullWidth prop from machine credential detail field as it's not needed 2020-11-23 11:45:59 -05:00
mabashian
81bccc1c7f Display machine credential in job details when present 2020-11-23 11:41:07 -05:00
nixocio
e23b47b997 Add minor update to strings
Add minor update to strings. And adjust the usage of `toTitleCase` to
dynamic strings.
2020-11-23 09:29:20 -05:00
nixocio
faec21ed08 Update usage of useDeleteItems
* Update usage of useDeleteItems.
* Remove async when not necessary
* Update return of promises
2020-11-23 09:15:23 -05:00
softwarefactory-project-zuul[bot]
1deb4ff5e4 Merge pull request #8472 from marshmalien/setting-misc-system-forms
Add setting "system" category forms and tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-20 22:49:55 +00:00
Bill Nottingham
13788c4568 Clean up some old sourve var settings in unit tests
Also if you want to use assert, use assert.
2020-11-20 16:32:47 -05:00
softwarefactory-project-zuul[bot]
69b818ff83 Merge pull request #8587 from nixocio/ui_issue_8548
Add updates related to smart inventories

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-20 15:19:48 +00:00
nixocio
a8400e4b7c Add updates related to smart inventories
Add updates related to smart inventories.

* Add popover for `Smart host filter`.
* Add popover for `Instance Groups` on Smart Inventory screen.
* Rename `Host filter` to `Smart host filter` per mockup.
* Add inventory as part of dynamic host filter.

See: https://github.com/ansible/awx/issues/8581
Also: https://github.com/ansible/awx/issues/8548
2020-11-19 17:17:23 -05:00
nixocio
9141e789aa Hide sync icon for smart inventory rows in Inventory List
Hide sync icon for smart inventory rows in Inventory List

See: https://github.com/ansible/awx/issues/7681
2020-11-19 17:12:02 -05:00
Alex Corey
60ccdfa4e6 removes asterisk from wfjt form inventory field 2020-11-19 14:33:55 -05:00
Marliana Lara
0d7f7df043 Update failed project sync error message 2020-11-19 14:32:42 -05:00
softwarefactory-project-zuul[bot]
b6a55e53d5 Merge pull request #8622 from mabashian/nav-expanded
Fix nav console error

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-19 17:39:25 +00:00
Marliana Lara
1a33f7ce1a Fix notification template type search query key 2020-11-18 16:00:02 -05:00
softwarefactory-project-zuul[bot]
f22fa9c5b0 Merge pull request #8617 from AlanCoding/valid_groups
Avoid invalid group characters in default inventory script factory

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-18 20:26:28 +00:00
James Tanner
3e7554974a set a column name so it doesnt end up as "case" 2020-11-18 12:12:29 -05:00
mabashian
d3928a0c0f Get rid of onExpand but keep isExpanded on side nav 2020-11-18 11:34:54 -05:00
James Tanner
153a1ecd39 bump minor 2020-11-18 11:30:48 -05:00
James Tanner
d6f9c5a0b6 get the modified column too 2020-11-18 11:28:22 -05:00
Marliana Lara
2f47bacb4f Convert project/* components into functional components 2020-11-18 10:54:38 -05:00
Alan Rominger
91eff51390 Avoid invalid group characters in default inventory script factory 2020-11-18 10:16:08 -05:00
James Tanner
9cf294f3d7 implement ryanp suggestion 2020-11-18 09:57:22 -05:00
softwarefactory-project-zuul[bot]
691b4512b5 Merge pull request #8615 from jakemcdermott/fix-navbar
Fix the navbar

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-18 00:41:30 +00:00
Jake McDermott
471e22a4e2 Start with nav expanded 2020-11-17 18:54:11 -05:00
James Tanner
a1c2d458de get a csv of playbook_on_stats event data 2020-11-17 17:48:13 -05:00
mabashian
ef1da5d5de Wrap status label in a div so that it doesn't vertically stretch with it's parent. 2020-11-17 17:05:49 -05:00
Marliana Lara
865f348167 Add descriptive helper text when log aggregator toggle is disabled 2020-11-17 11:01:34 -05:00
Marliana Lara
30f5fbb07a Use ouiaId instead of data-cy id in RevertButton 2020-11-17 11:01:34 -05:00
Marliana Lara
d57fee7b63 Do not render setting field if config is empty 2020-11-17 11:01:34 -05:00
Marliana Lara
79930347f9 Fix number input validation bug 2020-11-17 11:01:33 -05:00
Marliana Lara
e0feda780b Add setting system category forms and tests
* Add activity stream, logging, and misc system forms
 * Hookup logging test alert
 * Hookup revert buttons
 * Add useModal helper hook
 * Swap VariablesDetail for CodeDetail within setting detail views
 * Update SettingDetail import path in setting detail views
2020-11-17 11:01:30 -05:00
mabashian
76c39e38c0 Update snapshot after adding cannotDelete prop to ToolbarDeleteButton 2020-11-17 09:18:59 -05:00
mabashian
8cd4d06903 Hide the delete button on workflow approval details when job is pending 2020-11-17 08:42:35 -05:00
mabashian
8c263f17ab Adds data-cy attributes to the fields in the workflow approval details 2020-11-17 08:42:35 -05:00
mabashian
a4e4f0aa98 Show 'Deleted' when the source workflow job is deleted in workflow approvals list/details 2020-11-17 08:42:35 -05:00
mabashian
ebf9bf429c Add description to the list of default search keys on workflow approvals list 2020-11-17 08:42:35 -05:00
mabashian
30e461c18e Fix basic name filtering on workflow approvals list 2020-11-17 08:42:35 -05:00
mabashian
b8b3424c1f Prevent users from attempting to delete pending approvals 2020-11-17 08:42:35 -05:00
mabashian
929be1652a Move all mock workflow approvals out to data.workflowApprovals.json 2020-11-17 08:42:35 -05:00
mabashian
2be5ae3b2d Remove old TODO 2020-11-17 08:42:35 -05:00
mabashian
aba14bfb8c Combine approve/deny modals into one modal 2020-11-17 08:42:35 -05:00
mabashian
a9c3484387 Move approval action buttons from rows to to level list actions. UX updates to the display of the status. 2020-11-17 08:42:35 -05:00
mabashian
ee7f73623f Adds /#/workflow_approvals list and details and allows users to approve or deny workflow approvals from these interfaces 2020-11-17 08:42:35 -05:00
softwarefactory-project-zuul[bot]
b338da40c5 Merge pull request #8482 from jakemcdermott/fix-8465
Fix inconsistent screen title bars

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-16 21:14:25 +00:00
softwarefactory-project-zuul[bot]
00fb955544 Merge pull request #8563 from AlexSCorey/8535-UpgradePF
Updates PF dependency

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-16 18:16:17 +00:00
softwarefactory-project-zuul[bot]
74711a55bb Merge pull request #8552 from DeloitteHux/ng-helm-install
Add helm installation (#8551)

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-16 17:47:31 +00:00
Jake McDermott
d30dd97c96 Fix inconsistent screen title bars 2020-11-16 11:39:04 -05:00
softwarefactory-project-zuul[bot]
10664d1931 Merge pull request #8582 from wenottingham/collect-again
Revert portions of 40a10dcc5f

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-13 22:54:23 +00:00
Bill Nottingham
7b04fa114e Revert portions of 40a10dcc5f
Keep some of the collectors, while removing ones we calculate
in other ways.
2020-11-13 14:50:04 -05:00
softwarefactory-project-zuul[bot]
0d843899e1 Merge pull request #8519 from nixocio/ui_issue_8098
Remove groups/hosts when deleting inventory sources

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-13 18:37:07 +00:00
Alex Corey
54e1991ff4 Update PF Dependency and associated components and tests 2020-11-13 10:11:05 -05:00
softwarefactory-project-zuul[bot]
76fd63ba5f Merge pull request #8463 from nixocio/ui_issue_7130
Add feature to associate teams to users

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-12 18:21:25 +00:00
nixocio
07edf505e7 Add feature to associate teams to users
Add feature to associate teams to users. For the time being when
associating Users to a team, the User will be associated with `member_role` only. And when `diassociating` the User from a team all related roles - member, read, and admin will be removed.

Also, fix a bug related to search not being cleared after closing/cancel
the `AssociateModal`.
2020-11-12 10:06:33 -05:00
softwarefactory-project-zuul[bot]
1078bf76ad Merge pull request #8575 from ryanpetrello/yet-more-downstream-bits
more downstream changes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-11 19:27:28 +00:00
softwarefactory-project-zuul[bot]
cb4fcb9d80 Merge pull request #8566 from AlexSCorey/8539-SurveyRequiredFields
Adds asterisk to required survey questions in preview modal

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-11 18:58:30 +00:00
Ryan Petrello
32e149c76e Merge branch 'downstream' into devel 2020-11-11 13:30:28 -05:00
Ryan Petrello
4d8176e6af Merge remote-tracking branch 'downstream' into downstream 2020-11-11 13:30:21 -05:00
Ryan Petrello
ddd109059f Merge pull request #4682 from wenottingham/subs-corner-cases
Use the exported count in the manifest for the node count, if present.
2020-11-11 13:13:01 -05:00
softwarefactory-project-zuul[bot]
4d480cb95f Merge pull request #8413 from sean-m-sullivan/role_list
Tower_role Improvements, Approvals and use of Lists

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-11 17:37:21 +00:00
softwarefactory-project-zuul[bot]
69c3acfb39 Merge pull request #8570 from ryanpetrello/analytics-cleanup
removed unused analytics metrics

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2020-11-11 17:26:27 +00:00
Bill Nottingham
a092406543 Use the exported count in the manifest for the node count, if present. 2020-11-11 12:20:32 -05:00
Christian Adams
a65008f762 Merge pull request #4680 from ansible/i18n_release_3.8.0_translations
(More) UI translation strings for release_3.8.0 branch
2020-11-11 12:07:35 -05:00
ansible-translation-bot
2a44a72024 UI translation strings for release_3.8.0 branch 2020-11-11 15:42:54 +00:00
Ryan Petrello
40a10dcc5f removed unused analytics metrics 2020-11-11 09:56:20 -05:00
ansible-translation-bot
d25d5762e0 UI translation strings for release_3.8.0 branch 2020-11-11 14:12:48 +00:00
softwarefactory-project-zuul[bot]
073e518c16 Merge pull request #8503 from AlexSCorey/8237-FixKebabifiedToolbarBtns
Fixes toolbar buttons in Advanced Search mode

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-11 13:25:15 +00:00
Ryan Petrello
454c8e66e0 Merge pull request #4678 from beeankha/delete_cloudforms_from_collections
Remove Cloudforms as a credential type from collections
2020-11-10 17:12:16 -05:00
softwarefactory-project-zuul[bot]
cd5553a1dc Merge pull request #8567 from ryanpetrello/busted-cf-migration
avoid breaking upgrades from certain AWX versions

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-10 21:18:13 +00:00
Christian Adams
e4d9cd4000 Merge pull request #4676 from ansible/i18n_release_3.8.0_translations
UI translation strings for release_3.8.0 branch
2020-11-10 16:07:22 -05:00
beeankha
400c55faaa Remove Cloudforms as a credential type from collections 2020-11-10 15:49:55 -05:00
Ryan Petrello
fabd2eec63 avoid breaking upgrades from certain AWX versions
the prior version of this migration was rewritten, so we should
run the function again to really make sure that cleanup happens
2020-11-10 15:18:49 -05:00
Alex Corey
619fabc3a1 adds asterisk to required survey questions in preview modal 2020-11-10 11:47:30 -05:00
sean-m-sullivan
4e4f1d3cce update comment 2020-11-10 10:04:05 -06:00
sean-m-sullivan
e2e3d30b49 update comment 2020-11-10 09:16:08 -06:00
Christian Adams
ff78cade3a Merge pull request #4677 from rooftopcellist/fix_hover_help
Fix hover-over help text for subscriptions
2020-11-10 09:56:08 -05:00
Christian M. Adams
97381f6810 Fix hover-over help text for subscriptions 2020-11-10 09:32:16 -05:00
sean-m-sullivan
999086968c Merge branch 'role_list' of github.com:sean-m-sullivan/awx into role_list 2020-11-10 08:17:09 -06:00
sean-m-sullivan
ab4abf4e3b update comment 2020-11-10 08:17:01 -06:00
Sean Sullivan
0fd0f0c1bd Merge pull request #21 from ansible/devel
Rebase
2020-11-10 08:13:52 -06:00
softwarefactory-project-zuul[bot]
d16055806b Merge pull request #8520 from AlexSCorey/7636-WFJTSurveyNotEnabled
Toggles WFJT survey on and off

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-10 12:25:57 +00:00
ansible-translation-bot
e09ac530d5 UI translation strings for release_3.8.0 branch 2020-11-09 16:27:11 +00:00
ansible-translation-bot
1923926422 UI translation strings for release_3.8.0 branch 2020-11-09 15:09:59 +00:00
softwarefactory-project-zuul[bot]
7d3bf36227 Merge pull request #8559 from ryanpetrello/yet-anooooooother-downstream-merge
Merge in some downstream bug fixes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-06 19:29:18 +00:00
Ryan Petrello
d653c05da8 Merge branch 'downstream' into devel 2020-11-06 13:22:26 -05:00
softwarefactory-project-zuul[bot]
862a6835fe Merge pull request #8545 from nixocio/ui_issue_4968
Mark `Host Config Key` as a required field

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-06 17:23:16 +00:00
Ryan Petrello
33f3ad17cb Merge pull request #4671 from ryanpetrello/cloudforms-minus-minus
entirely remove CloudForms inventory sources instead of converting
2020-11-06 11:30:23 -05:00
Ryan Petrello
52d9fbce73 update cloudforms-specific tests 2020-11-06 10:39:14 -05:00
softwarefactory-project-zuul[bot]
0933a94ae7 Merge pull request #8528 from AlexSCorey/7673-AddOrgToInventoryList
Adds Organization to Inventory List item

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-06 14:09:58 +00:00
Ryan Petrello
0b701b3b24 entirely remove CloudForms inventory sources instead of converting 2020-11-06 01:02:55 -05:00
Nicolas G
b4a45e4cf4 Add helm installation (#8551)
Update to address https://github.com/ansible/awx/issues/8551
Install `helm` binaries along with `kubectl`
2020-11-05 17:49:04 -05:00
softwarefactory-project-zuul[bot]
0567a2a3bf Merge pull request #8540 from marshmalien/8461-notification-detail-link
Fix notification list to notification list item detail link

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-05 22:23:47 +00:00
Alex Corey
e372f4f8f6 Adds list item label 2020-11-05 16:54:48 -05:00
softwarefactory-project-zuul[bot]
dccddfffe6 Merge pull request #8483 from AlexSCorey/8261-AddRelatedGroups
Supports Associating Related Inventory Group

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-05 21:08:21 +00:00
softwarefactory-project-zuul[bot]
948e4c13d2 Merge pull request #8549 from jakemcdermott/remove-cf-form
Delete cloudforms

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-05 19:43:49 +00:00
softwarefactory-project-zuul[bot]
13f2b3f632 Merge pull request #8531 from AlexSCorey/8196-PrivilegeEscalation
Fixes broken select

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-05 19:06:15 +00:00
Alex Corey
944c32da24 resolve cyclical group association 2020-11-05 13:41:43 -05:00
Ryan Petrello
b8f1fa1a13 Merge pull request #4666 from ryanpetrello/dont-test-me
update a janky old test
2020-11-05 13:36:24 -05:00
Jake McDermott
10ab12c99a Delete cloudforms 2020-11-05 12:40:03 -05:00
Ryan Petrello
662ee6fa36 update a janky old test
UJT list views don't work this way anymore after
a929e82060
2020-11-05 12:29:06 -05:00
Alex Corey
314fdd6066 add identifier 2020-11-05 11:44:33 -05:00
softwarefactory-project-zuul[bot]
94352c9a72 Merge pull request #8446 from nixocio/ui_issue_4950
Hide max hosts field on org form

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-05 16:03:07 +00:00
nixocio
4268f1aeeb Mark Host Config Key as a required field
Mark `Host Config Key` as a required field

See:https://github.com/ansible/awx/issues/4968
2020-11-05 09:52:33 -05:00
softwarefactory-project-zuul[bot]
31c85dd89f Merge pull request #8510 from keithjgrant/7952-host-filter-lookup-fix
Host filter lookup fix

Reviewed-by: Tiago Góes <tiago.goes2009@gmail.com>
             https://github.com/tiagodread
2020-11-05 13:38:11 +00:00
Ryan Petrello
e9f1f8c6fe Merge pull request #4670 from wenottingham/pendoh-no
Put everyone in the 'anonymous' pendo bucket regardless of setting
2020-11-05 08:36:13 -05:00
Keith Grant
8d87d9e6e7 mark Clear filters button for translation 2020-11-04 15:36:40 -08:00
nixocio
d324baf1b0 Hide max hosts field on org form
Hide max hosts field on org form.

Also, simplify the usage of context API to read the value of me
parameter.

Hide max hosts field on org form.

See: https://github.com/ansible/awx/issues/4950
2020-11-04 17:23:22 -05:00
Marliana Lara
52c8033a08 Fix notification list item detail pathname link 2020-11-04 15:31:00 -05:00
Bill Nottingham
28a70ced56 Put everyone in the 'anonymous' pendo bucket regardless of setting
We no longer have the key detailed accounts are indexed on.
2020-11-04 15:18:12 -05:00
softwarefactory-project-zuul[bot]
bf6064db21 Merge pull request #8508 from marshmalien/8493-enable-all-inv-src-vars
Add Source Vars to all inventory source types

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-04 18:48:09 +00:00
Ryan Petrello
e406e4298b Merge pull request #4660 from beeankha/fix_import_export_failures
Change import/export Collections Module to Detect Errors vs Warnings
2020-11-04 09:59:25 -05:00
Johannes Gross
591a3e7a60 Updated Helm Chart Location
Signed-off-by: Johannes Gross <jgross@bright-skies.de>
2020-11-04 13:16:05 +01:00
softwarefactory-project-zuul[bot]
370440f63d Merge pull request #8526 from mabashian/convert-WorkflowJobTemplatejsx-functional
Convert WorkflowJobTemplate.jsx to functional component

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-04 01:14:45 +00:00
Marliana Lara
330625b565 Enable source vars for all inventory types 2020-11-03 17:55:00 -05:00
nixocio
5de34a9c0b Remove groups/hosts when deleting inventory sources
Remove related resources groups/hosts when deleting inventory sources.

The current UI deletes `groups` and `hosts` once the inventory source is
deleted. Add this behavior to the new UI.

See: https://github.com/ansible/awx/issues/8098
2020-11-03 16:51:37 -05:00
Ryan Petrello
35eda3a9a7 Merge pull request #4664 from ryanpetrello/pin-collections-requirements
pin known working collections in 3.8.0
2020-11-03 15:23:29 -05:00
Ryan Petrello
ac4b38bc30 Merge remote-tracking branch 'downstream/release_3.8.0' into devel 2020-11-03 15:11:50 -05:00
mabashian
3052e2077d Import WorkflowJobTemplateEdit from the correct place 2020-11-03 14:29:11 -05:00
Ryan Petrello
439302b38e pin known working collections in 3.8.0 2020-11-03 14:26:31 -05:00
Alex Corey
22029b9d7c fixes broken select 2020-11-03 14:09:13 -05:00
softwarefactory-project-zuul[bot]
114bcd0349 Merge pull request #8487 from epfl-si/feature/I-want-my-own-metadata
[feature] Keep pod_spec_override-provided pod labels

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2020-11-03 17:38:57 +00:00
softwarefactory-project-zuul[bot]
6f8725c680 Merge pull request #8529 from ryanpetrello/old-pending-notifications
allow deleting NotificationTemplates w/ old pending notifications

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-03 16:37:38 +00:00
Ryan Petrello
4a75ae9869 allow deleting NotificationTemplates w/ old pending notifications
see: https://github.com/ansible/awx/issues/8525
2020-11-03 11:09:30 -05:00
Alex Corey
68b399fdef Adds Organization to Inventory List item 2020-11-03 10:49:53 -05:00
mabashian
514cba6467 Convert WorkflowJobTemplate to functional component 2020-11-03 10:14:30 -05:00
beeankha
7dfa957619 Change import/export logging detection to detect errors vs warnings 2020-11-02 16:24:51 -05:00
Chris Meyers
cd9838d579 Merge pull request #4661 from ansible/fix-flake8_3.8.0
fix flake8
2020-11-02 15:48:07 -05:00
Chris Meyers
d8ca3ba894 fix flake8 2020-11-02 15:45:16 -05:00
Alex Corey
8ff2c5b576 Supports Associating Related Inventory Group
This also adds support for creating a new inventory group and
associating it at the same time.
2020-11-02 14:59:54 -05:00
Keith Grant
8df6dc0ca0 fix SmartInventoryForm chips 2020-11-02 11:24:01 -08:00
Alex Corey
a1fa21d5a9 toggles WFJT survey on and off 2020-11-02 14:23:04 -05:00
softwarefactory-project-zuul[bot]
df54a1edb5 Merge pull request #8516 from wenottingham/no-version-file
Don't write a tower_version file in awx

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-02 18:52:22 +00:00
Jake McDermott
cc89608d2c Merge pull request #4659 from jakemcdermott/fix-4658
Disable edit mode cred form unless edit capability is true
2020-11-02 13:26:05 -05:00
Jake McDermott
da7896dbc4 Disable edit mode cred form unless edit capability is true 2020-11-02 13:20:44 -05:00
Bill Nottingham
7a9eff7e65 Don't write a tower_version file in awx 2020-11-02 12:54:51 -05:00
softwarefactory-project-zuul[bot]
48ecd2400c Merge pull request #8491 from nixocio/ui_issue_8467
Remove activity from inventory details page

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-02 15:39:54 +00:00
nixocio
78ce54bc4a Remove activity from inventory details page
Remove activity from inventory details page

This information is already present on the `Complete jobs` tab.

See: https://github.com/ansible/awx/issues/8467
2020-11-02 10:09:09 -05:00
softwarefactory-project-zuul[bot]
1a4f2f43b7 Merge pull request #8492 from nixocio/ui_issue_7706
Remove Type from ScheduleList Sort

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-11-02 14:54:20 +00:00
Alex Corey
15ad6a0180 Fixes toolbar buttons in Advanced Search mode 2020-11-02 09:54:15 -05:00
nixocio
7cb3cf4e37 Remove Type from ScheduleList Sort
Remove Type from ScheduleList Sort, and make `name` as default sort.

See: https://github.com/ansible/awx/issues/7706
2020-11-02 09:18:41 -05:00
Keith Grant
c58c7e285c use Promise.all to make requests in parallel 2020-10-30 14:48:02 -07:00
Keith Grant
adc68b672d add advanced search keys to host filter lookup 2020-10-30 14:45:05 -07:00
softwarefactory-project-zuul[bot]
17b5b531bf Merge pull request #8506 from ryanpetrello/yet-another-downstream-merge
merge in some downstream changes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-30 21:15:20 +00:00
softwarefactory-project-zuul[bot]
52ffcc9f7c Merge pull request #8496 from jainnikhil30/fix_tower_inventory_empty__child_group
Add empty child group to inventory groups before adding it to the parent group

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-30 21:02:11 +00:00
Ryan Petrello
3ce9a778f8 fix busted webhook notifications
whoops, I broke it
2020-10-30 16:40:02 -04:00
Christian M. Adams
3e9a98170e Update tool tip for RH username & password settings 2020-10-30 16:40:02 -04:00
Jake McDermott
5ce9e5b03d Use SUBSCRIPTION_* variables in config route 2020-10-30 16:40:02 -04:00
Ryan Petrello
94b6b31185 fix a minor bug in the way we report certain license upload errors 2020-10-30 16:40:02 -04:00
Christian M. Adams
b031e1f05e Properly record the license type when sub is a trial 2020-10-30 16:40:02 -04:00
Elyézer Rezende
aae0b29008 Separate page object for config/attach endpoint 2020-10-30 16:40:02 -04:00
Christian M. Adams
422c7308fd Update compliance wording in UI on license page 2020-10-30 16:40:01 -04:00
Ryan Petrello
23f1cea29b correct manifest argument spec for the tower_license module 2020-10-30 16:40:01 -04:00
Christian M. Adams
633dc60d49 Simplify link to fit UI column 2020-10-30 16:40:01 -04:00
Bill Nottingham
b9960abea6 Add a help popover that points to the docs 2020-10-30 16:40:01 -04:00
Bill Nottingham
2388758f8a Update the license wording and UX 2020-10-30 16:40:01 -04:00
Christian M. Adams
b05c34a969 Valid key always set correctly, compliant field set correctly 2020-10-30 16:40:01 -04:00
Christian M. Adams
bfca3d9910 Update get subscriptions button name in UI 2020-10-30 16:40:01 -04:00
Ryan Petrello
f9511ed7da fix a typo in the tower_license module documentation 2020-10-30 16:40:01 -04:00
mabashian
2e93d9f022 Fix failing license test after rhCreds was changed to subscriptionCreds 2020-10-30 16:40:00 -04:00
Ryan Petrello
478111e7df cut down on queries necessary to generate the X-API-Product-Name header 2020-10-30 16:40:00 -04:00
Christian M. Adams
dd459e23e2 Add migration to prefill rh username and password for subscriptions 2020-10-30 16:40:00 -04:00
Ryan Petrello
e50c2c2867 warn about legacy license usage in the licensing UI 2020-10-30 16:40:00 -04:00
Ryan Petrello
7f9784c443 clarify that the manifest file is a .zip file 2020-10-30 16:40:00 -04:00
Ryan Petrello
1294efdeb9 consolidate a few license code function calls 2020-10-30 16:40:00 -04:00
Christian M. Adams
be4e4ff47c Clean up unnecessary comments 2020-10-30 16:40:00 -04:00
Bill Nottingham
309396f199 flake8 2020-10-30 16:39:59 -04:00
Bill Nottingham
393e1b75e9 Return more user-friendly errors for assorted manifest failures 2020-10-30 16:39:59 -04:00
Ryan Petrello
c139a998b8 simplify how awx "open" licensing works 2020-10-30 16:39:59 -04:00
Ryan Petrello
e591f1f002 update the tower_license module to properly upload manifests 2020-10-30 16:39:59 -04:00
Christian M. Adams
67000f0ce9 Remove license_key check & fix docker-compose make command 2020-10-30 16:39:59 -04:00
Ryan Petrello
0ddf47740c fix incorrect detection of license on inventory updates 2020-10-30 16:39:59 -04:00
Christian M. Adams
05de875ace Fix flake8 2020-10-30 16:39:59 -04:00
Christian M. Adams
d8b7791375 Revert subman install and setfacl 2020-10-30 16:39:59 -04:00
Christian M. Adams
b609e4ee84 remove outdated license references 2020-10-30 16:39:58 -04:00
Christian M. Adams
0a23bb6e36 Install subman and set ACL for rhsm.conf for dev 2020-10-30 16:39:58 -04:00
Ryan Petrello
74c7883b3b cleanup more old licensing cruft 2020-10-30 16:39:58 -04:00
Ryan Petrello
0a36959ef1 clarify some Sat6 verbiage in the license screen 2020-10-30 16:39:58 -04:00
Ryan Petrello
2ae429b4ac remove unnneeded licenses 2020-10-30 16:39:58 -04:00
Ryan Petrello
13f2e90a82 change rhsm candlepin crt location 2020-10-30 16:39:58 -04:00
Ryan Petrello
74ad1f36ac remove some entitlements config we no longer need 2020-10-30 16:39:58 -04:00
Christian M. Adams
cb86193459 Fallback to RH Candlepin Verify setting for OCP 2020-10-30 16:39:57 -04:00
Ryan Petrello
86d0ee590f clarify messaging and behavior when subscription-manager isn't installed 2020-10-30 16:39:57 -04:00
Christian M. Adams
10242cd6c4 Add error handling for missing rhsm.conf 2020-10-30 16:39:57 -04:00
Ryan Petrello
3bb930c769 cleanup up some unused code/comments, and simplify the license migration 2020-10-30 16:39:57 -04:00
Ryan Petrello
ef43d85271 remove Organization label from RHSM/Sat6 license form 2020-10-30 16:39:57 -04:00
Ryan Petrello
927b055e65 change license uploading to parse RHSM manifests
Co-authored-by: Christian Adams <chadams@redhat.com>
2020-10-30 16:39:57 -04:00
Ryan Petrello
4445d096f5 reimplement licensing to work with RHSM and entitlement uploads
Co-authored-by: Christian Adams <chadams@redhat.com>
2020-10-30 16:39:57 -04:00
Bill Nottingham
48934e8544 Enable source vars for all inventory types
Update plugin popover to point to the plugin docs.
2020-10-30 16:39:57 -04:00
Jeff Bradberry
cb570a2ba1 Fix the 'absent' state in tower_instance_group 2020-10-30 16:39:56 -04:00
Jeff Bradberry
607bc07887 Rework the export of full dependent objects
and include hosts and groups in the export.
2020-10-30 16:39:56 -04:00
Ryan Petrello
df874966a6 fix a display bug in webhook notifications with unicode characters
see: https://github.com/ansible/awx/issues/7400
2020-10-30 16:39:56 -04:00
Caleb Boylan
b5c2a6ad65 fix lookup plugin fqcn issue 2020-10-30 16:39:54 -04:00
softwarefactory-project-zuul[bot]
e38d082394 Merge pull request #8509 from ryanpetrello/daylight-wastings-time
Abolish Daylight Savings Time

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-30 20:39:31 +00:00
Ryan Petrello
b9bce03f71 fix a test related to proximity to the DST boundary
technically speaking, this test could still fail on the Saturday before
DST boundaries

...but I don't care
2020-10-30 16:10:07 -04:00
Ryan Petrello
024d148b7f Merge pull request #4648 from rebeccahhh/non_admin_jt_copy
Allow user to copy job templates as permissions intended
2020-10-30 15:46:58 -04:00
Ryan Petrello
8775afc5ea Merge pull request #4656 from ryanpetrello/ryan-broke-webhooks
fix busted webhook notifications
2020-10-30 13:09:46 -04:00
Ryan Petrello
2f738415b8 fix busted webhook notifications
whoops, I broke it
2020-10-30 13:05:37 -04:00
Ryan Petrello
57cd474beb Merge pull request #4634 from ryanpetrello/licensing-rhsm-changes-380
reimplement licensing to work with RHSM and entitlement uploads
2020-10-30 13:03:08 -04:00
softwarefactory-project-zuul[bot]
9b00421ec3 Merge pull request #8468 from nixocio/ui_issue_8453
Fix username as a required field

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-30 15:27:13 +00:00
Nikhil Jain
23a852bdab add the empty child group to groups before adding it to the parent group 2020-10-30 14:23:57 +05:30
softwarefactory-project-zuul[bot]
52d178bbe4 Merge pull request #8489 from sean-m-sullivan/workflow_node_logic
Update Logic for workflow node creation/deletion

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-29 18:36:40 +00:00
sean-m-sullivan
5703aa8af5 pep8 fixing 2020-10-29 11:50:29 -05:00
Christian M. Adams
a4e76db672 Update tool tip for RH username & password settings 2020-10-29 12:15:24 -04:00
Jake McDermott
31275122a1 Merge pull request #4653 from wenottingham/taking-inventory-of-ourselves
Enable source vars for all inventory types
2020-10-29 11:06:39 -04:00
sean-m-sullivan
beb329c31e update logic for node creation 2020-10-29 09:52:13 -05:00
Dominique Quatravaux
deb56bf4f8 [fix] Now with doctest that actually passes 2020-10-29 14:03:19 +01:00
Dominique Quatravaux
87b97530ff [fix] flake8 2020-10-29 13:35:24 +01:00
Dominique Quatravaux
3335ea953e [feature] Keep pod_spec_override-provided pod labels
- Write a deepmerge() implementation, keeping only the test suite of
https://stackoverflow.com/a/20666342/435004

- Use it to deep-merge pod['metadata'] with user input,
instead of replacing fields in it
2020-10-29 13:35:24 +01:00
Bill Nottingham
0fbc02864e Enable source vars for all inventory types
Update plugin popover to point to the plugin docs.
2020-10-28 19:58:14 -04:00
Jake McDermott
94eec401c3 Use SUBSCRIPTION_* variables in config route 2020-10-28 19:03:38 -04:00
Keith Grant
fa07889f39 switch host filter lookup to use icontains searches for name/group 2020-10-28 15:41:03 -07:00
softwarefactory-project-zuul[bot]
82a42d1db7 Merge pull request #8476 from jlmitch5/fixSearchLabelBug
fix issue where adding a search tag could cause an error

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-28 21:05:53 +00:00
softwarefactory-project-zuul[bot]
a672022a6a Merge pull request #8479 from jlmitch5/fixUserDetailLink
fix malformed user details link in toolbar

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-28 18:44:52 +00:00
Ryan Petrello
a75874a5d0 Merge pull request #4650 from jbradberry/tower-instance-group-absent
Fix a typo in checking the 'absent' state for the tower_instance_group module
2020-10-28 14:38:01 -04:00
Jeff Bradberry
ff7fe2acdf Fix the 'absent' state in tower_instance_group 2020-10-28 14:27:03 -04:00
Ryan Petrello
98d2e1a898 Merge pull request #4622 from jbradberry/import-export-groups-hosts
Rework the export of full dependent objects
2020-10-28 13:55:12 -04:00
John Mitchell
9517bf01ce fix malformed user details link in toolbar 2020-10-28 13:52:59 -04:00
Jeff Bradberry
b8b1e3d760 Rework the export of full dependent objects
and include hosts and groups in the export.
2020-10-28 13:43:14 -04:00
Ryan Petrello
e5c0889361 Merge pull request #4649 from ryanpetrello/webhook-unicode-bug
fix a display bug in webhook notifications with unicode characters
2020-10-28 13:08:15 -04:00
Ryan Petrello
41d3b164ea fix a display bug in webhook notifications with unicode characters
see: https://github.com/ansible/awx/issues/7400
2020-10-28 13:03:34 -04:00
John Mitchell
3a512f39ae fix issue where adding a search tag could cause an error 2020-10-28 11:36:05 -04:00
nixocio
40e821d0d8 Fix username as a required field
Fix username as a required field. `UserForm` is used for adding and
editing an user. When adding an user, the initial user value is a `{}`
update logic to cover this case.

Also, add unit-tests to cover this particular case.

See: https://github.com/ansible/awx/issues/8453
2020-10-28 10:11:38 -04:00
Ryan Petrello
ee06df97a4 fix a minor bug in the way we report certain license upload errors 2020-10-28 09:58:39 -04:00
softwarefactory-project-zuul[bot]
0d3c9ebc2b Merge pull request #8471 from ryanpetrello/whoops-scm
fix a minor bug introduced in Project save validation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-27 20:13:53 +00:00
Christian M. Adams
6d412fd8e7 Properly record the license type when sub is a trial 2020-10-27 16:05:43 -04:00
Ryan Petrello
e0af178968 fix a minor bug introduced in Project save validation 2020-10-27 15:42:36 -04:00
softwarefactory-project-zuul[bot]
720d705df3 Merge pull request #8466 from jlmitch5/dashboardInvSyncFailureFix
update inventory sync failure count to look at correct data

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-27 19:31:01 +00:00
softwarefactory-project-zuul[bot]
e35b0d1441 Merge pull request #8430 from AlexSCorey/8361-MergeAddDropDown
Merges 2 tool bar add buttons that use dropdowns

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-27 19:22:28 +00:00
Elyézer Rezende
ddcbb1f9c2 Separate page object for config/attach endpoint 2020-10-27 15:13:13 -04:00
Alex Corey
2e90cd8d31 fixes failing tests and template list dropdown 2020-10-27 14:54:47 -04:00
Alex Corey
a2ca2729ba Merges 2 tool bar add buttons that use dropdowns 2020-10-27 14:37:23 -04:00
softwarefactory-project-zuul[bot]
51600986c9 Merge pull request #8462 from jakegatsby/devel
cast create_preload_data to boolean with `create_preload_data | bool` in launch_awx_task.sh.j2

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2020-10-27 15:32:21 +00:00
Christian M. Adams
0a839430e7 Update compliance wording in UI on license page 2020-10-27 10:51:11 -04:00
John Mitchell
abaefd0319 update inventory sync failure count to look at correct data 2020-10-27 10:44:00 -04:00
softwarefactory-project-zuul[bot]
5a67aa7fff Merge pull request #8447 from thedoubl3j/local_path_mod
related #7665 added 400 if user attempts an edit to local_path in a SCM project

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-27 13:30:28 +00:00
Ryan Petrello
22e68fe973 correct manifest argument spec for the tower_license module 2020-10-27 09:09:39 -04:00
softwarefactory-project-zuul[bot]
4db5447db8 Merge pull request #8394 from chrismeyersfsu/enhancement-profiling_code
centralize reusable profiling code

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-27 12:57:02 +00:00
Chris Meyers
eb47c8dbc6 centralize reusable profiling code 2020-10-27 08:21:41 -04:00
Jake Jackson
abd0eb53bf fix tests 2020-10-27 00:39:51 -04:00
Jake Jackson
dbc4b677f6 related #7665 added 400 if user attempts an edit to local_path in a SCM project and test case 2020-10-26 22:47:37 -04:00
Christian M. Adams
f83e4cf092 Simplify link to fit UI column 2020-10-26 22:17:20 -04:00
Bill Nottingham
bb38940638 Add a help popover that points to the docs 2020-10-26 20:04:18 -04:00
Bill Nottingham
a72a688506 Update the license wording and UX 2020-10-26 18:35:16 -04:00
Christian M. Adams
1f5df7e39c Valid key always set correctly, compliant field set correctly 2020-10-26 16:25:25 -04:00
odroid
8a325d40e4 create_preload_data | bool in launch_awx_task.sh.j2 2020-10-26 15:22:29 -04:00
Caleb Boylan
581a0b67f0 Merge pull request #4645 from squidboylan/fix_collections_tests
fix lookup plugin fqcn issue
2020-10-26 11:37:31 -07:00
softwarefactory-project-zuul[bot]
a71261d5fd Merge pull request #8419 from keithjgrant/8331-number-survey-fields
Fix integer/float errors in survey

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-26 18:14:44 +00:00
Caleb Boylan
98f572a50e fix lookup plugin fqcn issue 2020-10-26 10:02:11 -07:00
Christian M. Adams
44633c2ba7 Update get subscriptions button name in UI 2020-10-26 12:16:53 -04:00
softwarefactory-project-zuul[bot]
53dede734f Merge pull request #8345 from donald-picard-kr/update-tower-job-wait-for-workflow
add support for wait of project_updates jobs, inventory_update, and w…

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-26 15:47:27 +00:00
softwarefactory-project-zuul[bot]
95a4cc7b76 Merge pull request #8457 from ryanpetrello/downstream-sync
merge in some downstream bug fixes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-26 14:46:23 +00:00
softwarefactory-project-zuul[bot]
db3e79e240 Merge pull request #8449 from lennart/local_docker_labels
allow labelling docker web container

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-26 14:30:31 +00:00
Ryan Petrello
b7f1393c33 fix a typo in the tower_license module documentation 2020-10-26 10:18:58 -04:00
mabashian
3c1cc7fcef Fix failing license test after rhCreds was changed to subscriptionCreds 2020-10-26 10:14:16 -04:00
Ryan Petrello
6097066cd8 Merge branch 'downstream' into devel 2020-10-26 09:32:00 -04:00
Ryan Petrello
048e35850a cut down on queries necessary to generate the X-API-Product-Name header 2020-10-26 09:19:46 -04:00
Chris Meyers
d2ceb39d73 Merge pull request #4616 from chrismeyersfsu/fix-same_jt_abuse
Fix same jt abuse
2020-10-26 09:13:08 -04:00
Lennart Melzer
2991ddfc52 allow labelling docker web container 2020-10-25 14:34:48 +01:00
Keith Grant
a8bb3519c5 fix multiselect survey question on launch 2020-10-23 14:37:32 -07:00
Christian M. Adams
98b2ac77c8 Add migration to prefill rh username and password for subscriptions 2020-10-23 17:01:14 -04:00
softwarefactory-project-zuul[bot]
d550487bc8 Merge pull request #8433 from Malizor/devel
Expose the SCM Branch name in the playbook environment

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-23 17:40:07 +00:00
Ryan Petrello
942d7ccfc6 warn about legacy license usage in the licensing UI 2020-10-23 11:42:35 -04:00
softwarefactory-project-zuul[bot]
02fa85206f Merge pull request #8441 from nixocio/ui_issue_7595
Rename users and access tabs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-23 15:39:49 +00:00
Ryan Petrello
b36afa3c3e clarify that the manifest file is a .zip file 2020-10-23 11:08:50 -04:00
Ryan Petrello
3fe9d1c096 consolidate a few license code function calls 2020-10-23 11:05:08 -04:00
Christian M. Adams
8a9f75c291 Clean up unnecessary comments 2020-10-23 11:00:08 -04:00
Bill Nottingham
bfb8e384a8 flake8 2020-10-23 10:58:29 -04:00
Bill Nottingham
9bc17db45d Return more user-friendly errors for assorted manifest failures 2020-10-23 10:57:43 -04:00
Ryan Petrello
7c63a6592e simplify how awx "open" licensing works 2020-10-23 10:56:19 -04:00
Ryan Petrello
1f0b1923d7 update the tower_license module to properly upload manifests 2020-10-23 10:30:51 -04:00
Chris Meyers
6e8996f59f Merge pull request #4626 from chrismeyersfsu/enhancement-graph_jobs_3_8_0
terminal graph of job status changes
2020-10-23 10:22:04 -04:00
Chris Meyers
79d7c6d9b3 make optimization code work with container groups
* Task manager fit_ optimization code caused problems with container
group code.
* Note that we don't actually get the benefit of the optimization for
container groups. We just make it so that the code doesn't blow up. It
will take another pass to apply optimizations to the container group
task manager path.
2020-10-23 10:17:30 -04:00
Chris Meyers
ce052922c6 terminal graph of job status changes
* Visualize how jobs go from pending, waiting, running over time
2020-10-23 10:15:32 -04:00
softwarefactory-project-zuul[bot]
20e2472329 Merge pull request #8442 from beeankha/revert_to_satellite6
Revert "Kind" Choice from 'satellite' to 'satellite6'

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-23 13:54:11 +00:00
beeankha
26ebf47c71 Revert choice from 'satellite' to 'satellite6' 2020-10-22 18:03:09 -04:00
softwarefactory-project-zuul[bot]
f54116afbb Merge pull request #8431 from wenottingham/pg-ate-ten
Move to rhel8 PG10 container for persistent PG

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-22 21:38:51 +00:00
Bill Nottingham
f1d2d79f00 Move to rhel8 PG10 container for persistent PG
Merge in updated liveness checks from upstream template
2020-10-22 17:08:16 -04:00
Christian M. Adams
25ace77048 Remove license_key check & fix docker-compose make command 2020-10-22 16:49:13 -04:00
Ryan Petrello
91f72672a1 fix incorrect detection of license on inventory updates 2020-10-22 16:07:28 -04:00
Christian M. Adams
44e9ba1117 Fix flake8 2020-10-22 15:47:54 -04:00
Christian M. Adams
a5b644c23c Revert subman install and setfacl 2020-10-22 15:40:05 -04:00
softwarefactory-project-zuul[bot]
3ff1d77c03 Merge pull request #8438 from beeankha/add_cred_kind_options
Update Doc String for tower_credential Module "Kind" Choices

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-22 19:09:16 +00:00
Christian M. Adams
784c924d88 remove outdated license references 2020-10-22 14:59:48 -04:00
softwarefactory-project-zuul[bot]
466dff96e9 Merge pull request #8402 from jlmitch5/dashboardAug20
add ui_next dashboard

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-22 18:45:11 +00:00
Christian M. Adams
fbde4797f8 Install subman and set ACL for rhsm.conf for dev 2020-10-22 14:39:31 -04:00
Ryan Petrello
2df924ae78 cleanup more old licensing cruft 2020-10-22 14:37:26 -04:00
Ryan Petrello
be5ff0a088 clarify some Sat6 verbiage in the license screen 2020-10-22 14:32:03 -04:00
Ryan Petrello
d8514851bf remove unnneeded licenses 2020-10-22 14:29:34 -04:00
Ryan Petrello
849079316a change rhsm candlepin crt location 2020-10-22 14:08:19 -04:00
Ryan Petrello
f266325fb0 remove some entitlements config we no longer need 2020-10-22 13:46:36 -04:00
nixocio
dcc3422484 Rename users and access tabs
Rename users and access tabs

See: https://github.com/ansible/awx/issues/7595
2020-10-22 13:42:41 -04:00
Christian M. Adams
f812d2e318 Fallback to RH Candlepin Verify setting for OCP 2020-10-22 13:33:41 -04:00
Ryan Petrello
0c63e6a624 clarify messaging and behavior when subscription-manager isn't installed 2020-10-22 13:20:55 -04:00
softwarefactory-project-zuul[bot]
a532421eef Merge pull request #8436 from jbradberry/profile-sql-message
Improve handling of 0 and negative thresholds in the profile_sql command

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-22 17:04:40 +00:00
Christian M. Adams
23f365786c Add error handling for missing rhsm.conf 2020-10-22 12:29:29 -04:00
softwarefactory-project-zuul[bot]
8206874158 Merge pull request #8434 from nicolas-g/patch-1
Add support for Kubernetes Pod annotations

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-22 16:07:09 +00:00
Chris Meyers
7baf681b55 Merge pull request #4623 from chrismeyersfsu/enhancement-db_application_name_3_8_0
fill in postgres application_name on connection
2020-10-22 12:04:41 -04:00
Ryan Petrello
fcf56b4ba6 cleanup up some unused code/comments, and simplify the license migration 2020-10-22 11:56:47 -04:00
Ryan Petrello
afc028147a remove Organization label from RHSM/Sat6 license form 2020-10-22 11:56:47 -04:00
Ryan Petrello
a7c7ac714f change license uploading to parse RHSM manifests
Co-authored-by: Christian Adams <chadams@redhat.com>
2020-10-22 11:56:41 -04:00
beeankha
4b625f0f13 Update credential 'kind' choices 🔑 2020-10-22 11:54:42 -04:00
Jeff Bradberry
d6e39376c8 Improve handling of 0 and negative thresholds in the profile_sql command
- output a profiling disabled message when appropriate
- specify that we are doing SQL profiling in the enabled case
- treat negative thresholds the same as zero, disabling profiling
2020-10-22 11:27:21 -04:00
Ryan Petrello
ffab48c77f reimplement licensing to work with RHSM and entitlement uploads
Co-authored-by: Christian Adams <chadams@redhat.com>
2020-10-22 11:10:28 -04:00
Donald Picard
8f66cfa2c0 related #8344 add support for wait of project_updates jobs, inventory_update, and workflow_job.
Signed-off-by: Donald Picard <donald.picard@sogeti.com>
2020-10-22 09:05:02 -04:00
Nicolas G
a50e32d4ea Add support for Kubernetes Pod annotations
Variable `kubernetes_pod_annotations` will add annotations to Kubernetes pods
2020-10-21 19:59:11 -04:00
Nicolas Delvaux
a58e37e31f Expose {awx,tower}_job_scm_branch variables in the environment
related #8429
2020-10-22 00:09:18 +02:00
Nicolas Delvaux
51aed19b29 Expose {awx,tower}_project_scm_branch variables in the environment 2020-10-21 23:54:48 +02:00
Tiago Góes
e30569cc1b Change the id from / to - 2020-10-21 18:26:19 -03:00
softwarefactory-project-zuul[bot]
81a79c30cb Merge pull request #7976 from bbayszczak/missing_creds_type_to_tower_credentials_module
add missing creds types to tower_credential module

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-21 19:03:41 +00:00
John Mitchell
2c0de9ce3d update render dashboard default unit t est 2020-10-21 12:52:38 -04:00
softwarefactory-project-zuul[bot]
3b3dfb6dbe Merge pull request #8424 from ansible/deps-autofix-10-21
Autofix dependencies

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-10-21 16:33:42 +00:00
Bianca Henderson
143831ffd0 Add required whitespace 2020-10-21 12:21:30 -04:00
softwarefactory-project-zuul[bot]
6bd573cf07 Merge pull request #8263 from AlexSCorey/8238-AddRelatedGroups
8238 add related groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-21 15:42:55 +00:00
softwarefactory-project-zuul[bot]
447bc4b4da Merge pull request #8364 from sean-m-sullivan/workflow_approval
Workflow approval

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
             https://github.com/beeankha
2020-10-21 15:08:01 +00:00
softwarefactory-project-zuul[bot]
7c038c9329 Merge pull request #8348 from nesanton/feature/8347
Rename inventory_source param to name in tower_inventory_source_update

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-21 14:53:27 +00:00
Ryan Petrello
a26d20cbf2 Merge pull request #4631 from ryanpetrello/galaxy-creds-cli
allow the CLI to associate Galaxy credentials to Organizations
2020-10-21 10:40:55 -04:00
John Mitchell
52deb7fd86 update dashboard and graph code to aid in automated testing 2020-10-21 10:32:37 -04:00
Ryan Petrello
c373d5307f allow the CLI to associate Galaxy credentials to Organizations
$ awx organizations associate Default --galaxy_credential "Ansible Galaxy"
2020-10-21 09:39:33 -04:00
Jake McDermott
1ab0e318f9 Fix vulnerable dependencies 2020-10-21 08:57:41 -04:00
softwarefactory-project-zuul[bot]
062ce5f735 Merge pull request #7281 from mabashian/7127-cred-input-details
Updates credential details to support plugin and prompt fields

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-10-21 00:32:26 +00:00
Keith Grant
9b5e59f045 add number validator support for negative numbers, large numbers 2020-10-20 15:44:17 -07:00
Alex Corey
8cb8cfe3d5 fixes search and sort 2020-10-20 17:53:54 -04:00
John Mitchell
5f4d6daf1b update dashboard to 3 tab single pane 2020-10-20 17:33:37 -04:00
Alex Corey
bebaf2d97e Uses existing kebabified workflow for run command 2020-10-20 17:07:01 -04:00
Alex Corey
ef85a321bc brings all lists in line with exsiting Ad Hoc workflow 2020-10-20 17:05:51 -04:00
Alex Corey
b919d4885c reformats long string, removes unneeded key 2020-10-20 17:05:51 -04:00
Alex Corey
f604065246 Refactors to show add button properly in Advanced Search mode 2020-10-20 17:05:51 -04:00
Alex Corey
9620da287c Adds Related Groups List 2020-10-20 17:05:51 -04:00
sean-m-sullivan
1ca46893bb update 2020-10-20 15:55:15 -05:00
softwarefactory-project-zuul[bot]
717861fb46 Merge pull request #8339 from keithjgrant/7515-form-error-polish
Refactor FormSubmitError for easier testing, better error display

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-10-20 20:52:09 +00:00
John Mitchell
8839fb9af3 remove unused comment from template lists 2020-10-20 16:42:28 -04:00
John Mitchell
a3c5f50bbf add dashboard (including counts, line chart and portal mode style lists) to ui_next 2020-10-20 16:42:28 -04:00
John Mitchell
5ea98ab02a add copy of template list for dashboard use, moving around shared ws hook to util 2020-10-20 16:42:28 -04:00
John Mitchell
782e8d5875 add two_weeks filter to dashbaord job graph api view 2020-10-20 16:42:28 -04:00
Jake McDermott
36abc9b123 Merge pull request #4630 from jakemcdermott/current-date
[3.8] Use current year in about modal
2020-10-20 15:31:31 -04:00
Anton Nesterov
130f6300c5 Fix missing alias in argument_spec and add tests for it 2020-10-20 21:15:28 +02:00
Jake McDermott
7bc7cb00ac Use current year in about modal 2020-10-20 15:13:58 -04:00
softwarefactory-project-zuul[bot]
f3ac57e3b6 Merge pull request #8346 from marshmalien/popover-component
Merge FieldTooltip and DetailPopover into single Popover component

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-20 18:55:02 +00:00
Keith Grant
a9c01e891f remove console log
Co-authored-by: Jake McDermott <yo@jakemcdermott.me>
2020-10-20 11:18:40 -07:00
Keith Grant
acd8a8dd3c fix integer/float errors in survey 2020-10-20 10:47:26 -07:00
Jake McDermott
f85548abeb Merge pull request #4628 from mabashian/4310-license-string
Replace SETTINGS > SYSTEM with SETTINGS &gt; SYSTEM to get around issue with translating this string
2020-10-20 12:34:19 -04:00
softwarefactory-project-zuul[bot]
44776189de Merge pull request #8162 from nixocio/ui_instance_groups_update_labels
Update labels to display isolated and controller instance groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-20 16:11:55 +00:00
Rebeccah
a929e82060 replacing capabilities prefetch definition with empty braces and removing the dunder. Explanation: Originally _capabilities_prefetch was populated with: ['admin', 'execute', {'copy': ['jobtemplate.project.use', 'jobtemplate.inventory.use', 'organization.workflow_admin']}]
This was problematic because it was overwriting the original values that had been defined in the other serializers. Additionally, there are no other dunders for other capabilities prefetch
this was likely added because UnifiedJobTemplateSerializer does not have it's own capabilities, but rather derives them from JTSerializer and WFJTSeralizer, but it worked better without the dunder once I removed the data that was overwriting the data from the WFJT and JT serializers.
2020-10-20 11:58:53 -04:00
Marliana Lara
5d0b001764 Fix prop type errors in unit tests 2020-10-20 11:57:32 -04:00
Marliana Lara
f369f8535d Add default aria label to Popover component 2020-10-20 11:55:04 -04:00
Marliana Lara
35ba74d265 Merge FieldTooltip and DetailPopover into single Popover component 2020-10-20 11:55:00 -04:00
nixocio
c8b9cbe0d5 Update labels to display isolated and controller instance groups
Update labels to display isolated and controller instance groups.

See: https://github.com/ansible/awx/issues/8244
Also: https://github.com/ansible/awx/issues/7467
2020-10-20 11:39:17 -04:00
softwarefactory-project-zuul[bot]
677fb594e8 Merge pull request #8281 from mabashian/7835-galaxy-cred-org-2
Add Galaxy Credentials field to organizations form

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-20 15:37:08 +00:00
softwarefactory-project-zuul[bot]
439e872a05 Merge pull request #8404 from mabashian/fix-test-consoles
Fix issues with prop types that were causing errors to be logged during tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-20 15:33:53 +00:00
mabashian
d27c482e5e Pass actual error to ContentError so it can be displayed 2020-10-20 11:16:38 -04:00
mabashian
34e85dea8b Check for existence of data.next before checking it 2020-10-20 11:16:38 -04:00
mabashian
6df173ce1d Update return structure of readInputSources to match what the edit component is expecting. This also required me to make corresponding updates to the detail component so that it matched. 2020-10-20 11:16:38 -04:00
mabashian
e6a1ad0127 Ran prettier 2020-10-20 11:16:38 -04:00
mabashian
c3c7e120c8 Removes use of Trans tag in favor of t/i18n 2020-10-20 11:16:38 -04:00
mabashian
81822dfd1c Adds an upper limit on recursive calls set statically in the method at 5. 2020-10-20 11:16:38 -04:00
mabashian
a71a9057a2 Wraps GET requests in useRequest in order to handle unmounting more gracefully if the requests are still pending. 2020-10-20 11:16:38 -04:00
mabashian
a1d1a1078b Adds logic to recursively fetch input sources in the model method. This way we don't have to duplicate this logic every place that calls the method. 2020-10-20 11:16:38 -04:00
mabashian
e7cd9bbb98 Display fields that have plugins configured. 2020-10-20 11:16:38 -04:00
mabashian
908e583c69 Display prompt on launch passwords properly 2020-10-20 11:16:38 -04:00
mabashian
19ae4eadfb Add galaxy credentials field to organizations form 2020-10-20 11:03:27 -04:00
mabashian
485cee56bc Fix issues with prop types that were causing errors to be logged during tests 2020-10-20 10:59:39 -04:00
softwarefactory-project-zuul[bot]
9e4a236c64 Merge pull request #8417 from nicolas-g/patch-1
Add Kubernetes Deployment support for annotations

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-20 14:53:44 +00:00
softwarefactory-project-zuul[bot]
e4e5d65a71 Merge pull request #8415 from ryanpetrello/release-15.0.1
bump version to 15.0.1

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
             https://github.com/beeankha
2020-10-20 14:49:59 +00:00
Sean Sullivan
3a34a079aa Merge pull request #18 from ansible/devel
rebase to ansible/awx
2020-10-20 09:41:56 -05:00
sean-m-sullivan
03c7504d2b fix existing item error 2020-10-20 09:40:45 -05:00
mabashian
7a9b55c21b Replace SETTINGS > SYSTEM with SETTINGS &gt; SYSTEM to get around issue with translating this string 2020-10-20 10:31:30 -04:00
Ryan Petrello
67a5ad7dd6 Bump version to 15.0.1 2020-10-20 09:39:43 -04:00
Ryan Petrello
06b1243857 Merge pull request #8396 from shanemcd/retry-galaxy
Makefile logic to retry failed galaxy installs
2020-10-20 09:37:47 -04:00
Chris Meyers
84cb7be079 fill in postgres application_name on connection
* Tried to fill in application_name in awx/__init__.py but I think that
is too late
* Fill in database application_name with enough information to easily
trace the connection from postgres back to the node and pid that
initiated the connection.
* Set application_name in django settings so that application_name is
set _before_ the first postgres connection is established.
2020-10-20 08:32:09 -04:00
Sean Sullivan
dc26580466 Update to response code
set response code for current versions of tower/awx
2020-10-19 19:46:49 -05:00
sean-m-sullivan
1636f0cb25 linting 2020-10-19 17:35:18 -05:00
Sean Sullivan
f6a1707684 Merge pull request #17 from ansible/devel
Rebase
2020-10-19 15:56:04 -05:00
sean-m-sullivan
fe55dca661 make workflow approval creation return an HTTP 201, not 200 OK 2020-10-19 15:55:49 -05:00
softwarefactory-project-zuul[bot]
fb2cea7274 Merge pull request #8416 from ryanpetrello/wf-approval-201
make workflow approval creation return an HTTP 201, not 200 OK

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-19 20:51:32 +00:00
sean-m-sullivan
a8159c0391 revert check 2020-10-19 15:35:36 -05:00
Nicolas G
23c386223c Add Kubernetes Deployment support for annotations
Annotations are only supported for ingress and service accounts
This PR will allow you now to specify annotations for Kubernetes Deployment
 resources by defining `kubernetes_deployment_annotations` var list
2020-10-19 16:33:54 -04:00
Ryan Petrello
57b2cd402b make workflow approval creation return an HTTP 201, not 200 OK
see: e16a910062 (diff-67c0fe4fc2a405ad611e42d1457e8aa5)
2020-10-19 16:20:40 -04:00
sean-m-sullivan
5959809fed make workflow approval creation return an HTTP 201, not 200 OK 2020-10-19 15:19:01 -05:00
sean-m-sullivan
e416b55b1a update to fix missing options and fix pep8 2020-10-19 15:15:33 -05:00
sean-m-sullivan
91ef686fe0 update to incorporate requested changes, change approve to 201 response. 2020-10-19 15:11:19 -05:00
softwarefactory-project-zuul[bot]
d7864c58c1 Merge pull request #8403 from chrismeyersfsu/fix-same_jt_abuse_devel
Improve general performance for a variety of high-load job launch use cases

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-19 19:38:32 +00:00
softwarefactory-project-zuul[bot]
933de6aa97 Merge pull request #8312 from thedoubl3j/requirement_yaml
related #4540 updating project_update.yml to accept yaml extension 

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-19 19:32:01 +00:00
softwarefactory-project-zuul[bot]
ed5074c09c Merge pull request #8408 from marcolussetti/fix-docker-compose-install
Point installer to community.general.docker_image

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-19 18:47:57 +00:00
softwarefactory-project-zuul[bot]
5c751f3f8e Merge pull request #8230 from nixocio/ui_issue_7751
Add username to tooltip

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-19 17:20:01 +00:00
sean-m-sullivan
862cd974ff linting 2020-10-19 12:12:08 -05:00
Jake Jackson
be6ed623f6 updating project_update.yml to accept yaml extension 2020-10-19 11:23:44 -04:00
Chris Meyers
11cc6362b5 reduce per-job database query count
* Do not query the database for the set of Instance that belong to the
group for which we are trying to fit a job on, for each job.
* Instead, cache the set of instances per-instance group.
2020-10-19 11:01:11 -04:00
Chris Meyers
bdabe36029 reduce parent->child lock contention
* We update the parent unified job template to point at new jobs
created. We also update a similar foreign key when the job finishes
running. This causes lock contention when the job template is
allow_simultaneous and there are a lot of jobs from that job template
running in parallel. I've seen as bad as 5 minutes waiting for the lock
when a job finishes.
* This change moves the parent->child update to OUTSIDE of the
transaction if the job is allow_simultaneous (inherited from the parent
unified job). We sacrafice a bit of correctness for performance. The
logic is, if you are launching 1,000 parallel jobs do you really care
that the job template contains a pointer to the last one you launched?
Probably not. If you do, you can always query jobs related to the job
template sorted by created time.
2020-10-19 11:01:05 -04:00
Chris Meyers
2eac5a8873 reduce per-job database query count
* Do not query the database for the set of Instance that belong to the
group for which we are trying to fit a job on, for each job.
* Instead, cache the set of instances per-instance group.
2020-10-19 10:54:56 -04:00
Chris Meyers
09a0448c3e reduce parent->child lock contention
* We update the parent unified job template to point at new jobs
created. We also update a similar foreign key when the job finishes
running. This causes lock contention when the job template is
allow_simultaneous and there are a lot of jobs from that job template
running in parallel. I've seen as bad as 5 minutes waiting for the lock
when a job finishes.
* This change moves the parent->child update to OUTSIDE of the
transaction if the job is allow_simultaneous (inherited from the parent
unified job). We sacrafice a bit of correctness for performance. The
logic is, if you are launching 1,000 parallel jobs do you really care
that the job template contains a pointer to the last one you launched?
Probably not. If you do, you can always query jobs related to the job
template sorted by created time.
2020-10-19 10:54:51 -04:00
Marco Lussetti
9818440d0f curtail change to ansible >= 2.10 per feedback 2020-10-19 06:28:50 -07:00
Anton Nesterov
2e237661f8 Add the inventory_source as alias. 2020-10-17 17:33:53 +02:00
Anton Nesterov
8a09731a52 Rename inventory_source param to name
* fixes #8347
* Rename inventory_source to name in the tower_inventory_source_update
* Allow to specify both name or id for `name` and `inventory` params
2020-10-17 17:33:53 +02:00
sean-m-sullivan
4151361420 linting 2020-10-17 01:13:50 -05:00
sean-m-sullivan
c0e1ac266c add tests 2020-10-17 01:00:14 -05:00
Sean Sullivan
6c1f688bf1 Merge pull request #16 from sean-m-sullivan/approval_role
update to approval role
2020-10-17 00:10:00 -05:00
sean-m-sullivan
0393d537de rewrite to use lists 2020-10-17 00:08:39 -05:00
sean-m-sullivan
82bb8033ec update to approval role 2020-10-16 13:27:28 -05:00
Sean Sullivan
106b19a05d Merge pull request #13 from ansible/devel
Rebase
2020-10-16 12:15:47 -05:00
sean-m-sullivan
7ca2f33112 update test 2020-10-16 11:22:12 -05:00
sean-m-sullivan
ad1937b394 update test 2020-10-16 11:16:15 -05:00
sean-m-sullivan
0fee6d8b86 update test 2020-10-16 10:52:56 -05:00
Marco Lussetti
8217d14e36 Point installer to community.general.docker_image
Fixes issue in Ansible 2.10.2 where docker_image command is not found.
2020-10-15 20:38:29 -07:00
softwarefactory-project-zuul[bot]
28e792056d Merge pull request #8398 from john-westcott-iv/fix_stack_trace
Fixing stack trace from an error not having a detail

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-15 21:37:49 +00:00
softwarefactory-project-zuul[bot]
59b5104431 Merge pull request #8397 from john-westcott-iv/inv_src_get_one_fix
Fixing get_one calls in tower_inventory_source_update

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-15 21:33:19 +00:00
John Westcott IV
c759c83daf Fixing stack trace from an error not having a detail 2020-10-15 15:09:11 -04:00
John Westcott IV
407356239b Fixing get_one calls in tower_inventory_source_update 2020-10-15 12:40:31 -04:00
softwarefactory-project-zuul[bot]
1d1e1787c4 Merge pull request #8395 from jakemcdermott/current-year
Use current year in about modal

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-15 15:47:06 +00:00
Shane McDonald
df43221c24 Makefile logic to retry failed galaxy installs 2020-10-15 10:43:48 -04:00
Jake McDermott
09c961fc56 Use current year in about modal 2020-10-15 10:02:27 -04:00
softwarefactory-project-zuul[bot]
cd72bb6cb2 Merge pull request #8393 from mabashian/remove-mathjs
Remove mathjs as a dependency

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-14 18:36:01 +00:00
softwarefactory-project-zuul[bot]
26616a409f Merge pull request #8386 from john-westcott-iv/issue_8338
Fixing resetting of variables and adding unit test for condition

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-14 18:11:46 +00:00
Jake McDermott
3c71ab1bd7 Remove math licenses 2020-10-14 14:07:53 -04:00
softwarefactory-project-zuul[bot]
47cffd3c02 Merge pull request #8392 from mabashian/upgrade-angular-1.8.1
Upgrade angular to 1.8.1

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-10-14 17:17:29 +00:00
softwarefactory-project-zuul[bot]
63249dc241 Merge pull request #8351 from nixocio/ui_issue_7721
Update AddDropDownButton to show down caret

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-14 17:13:13 +00:00
John Westcott IV
0d8b1d172c Fixing linting and spelling 2020-10-14 12:39:15 -04:00
mabashian
851c802ea8 Remove mathjs as a dependency 2020-10-14 12:18:51 -04:00
mabashian
1d65b8cd53 Upgrade angular to 1.8.1 2020-10-14 11:16:51 -04:00
sean-m-sullivan
237727dd62 update pytest 2020-10-13 20:56:50 -05:00
sean-m-sullivan
d9184e02f5 update pytest 2020-10-13 20:40:35 -05:00
sean-m-sullivan
3b903a7459 fix typo 2020-10-13 18:41:52 -05:00
sean-m-sullivan
c72c335b0c fix pep8 issues 2020-10-13 18:27:27 -05:00
sean-m-sullivan
51eb4e6d6b update to auto_exit, add tests, add mutual exclusive parameters 2020-10-13 18:17:22 -05:00
John Westcott IV
f0449adcf8 Fixing resetting of variables and adding unit test for condition 2020-10-13 16:46:05 -04:00
sean-m-sullivan
e16a910062 updated workflow task name 2020-10-13 14:24:56 -05:00
sean-m-sullivan
6b27ee6a3c updated workflow name 2020-10-13 14:24:22 -05:00
softwarefactory-project-zuul[bot]
1ecd38a4ee Merge pull request #8369 from nixocio/ui_issue_5685
Add general updates for User screen

Reviewed-by: Kersom
             https://github.com/nixocio
2020-10-13 18:56:53 +00:00
softwarefactory-project-zuul[bot]
defb65d3d5 Merge pull request #8319 from asohh/devel
Added Groups/Hosts/Sources count to inventory list rows #7674

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-13 15:10:36 +00:00
softwarefactory-project-zuul[bot]
f283a6ef68 Merge pull request #8382 from ryanpetrello/cli-docs-clarification
clarify the instructions for building CLI docs

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2020-10-13 13:44:11 +00:00
softwarefactory-project-zuul[bot]
f9e8c03ec6 Merge pull request #7090 from jladdjr/updates_to_same_inv_should_happen_serially
Updates to a given inventory should happen serially

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-13 13:28:01 +00:00
Ryan Petrello
77d0958490 clarify the instructios for building CLI docs 2020-10-13 09:04:35 -04:00
softwarefactory-project-zuul[bot]
058049aa1b Merge pull request #8376 from ryanpetrello/15-0-0-galaxy-note
Clarify behavioral changes from content syncing behavior in 15.0.0+

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-12 20:22:37 +00:00
softwarefactory-project-zuul[bot]
bad064b577 Merge pull request #8370 from ryanpetrello/fix-bad-extra-vars-warning
fix a confusing error message when extra vars aren't valid JSON/YAML

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-12 20:17:15 +00:00
Ryan Petrello
faf0fa9040 Clarify behavioral changes from content syncing behavior in 15.0.0+
see: https://github.com/ansible/awx/issues/8341
2020-10-12 15:51:08 -04:00
sean-m-sullivan
226046dd16 update 2020-10-12 12:03:37 -05:00
Ryan Petrello
0cdcbdfea6 fix a confusing error message when extra vars aren't valid JSON/YAML
see: https://github.com/ansible/awx/issues/8359
2020-10-12 12:56:13 -04:00
Jim Ladd
05ac2c1ec2 Updates to a given inventory should happen serially 2020-10-12 09:34:37 -07:00
nixocio
1dd7651d49 Add general updates for User screen
* Add type of login used as part of UserListItem.
* Add type of login used as part of UserDetail.
* Hide password field, UserForm, in case login method is LDAP or Social.
* Make username field, UserForm, not required in case login is LDAP or
Social.

See: https://github.com/ansible/awx/issues/5685
2020-10-12 12:03:31 -04:00
softwarefactory-project-zuul[bot]
49c0b77c60 Merge pull request #8326 from wenottingham/param-a-lot
Fix 500 when required LDAP group parameters aren't set.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-12 15:58:27 +00:00
softwarefactory-project-zuul[bot]
119c907279 Merge pull request #8353 from jbradberry/zedr-wfjt-inventories
Zedr wfjt inventories

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-12 15:55:01 +00:00
sean-m-sullivan
c205ee81f0 update delete 2020-10-12 00:17:18 -05:00
sean-m-sullivan
c57ec1ea79 update delete 2020-10-10 13:25:09 -05:00
sean-m-sullivan
c3045f6a29 update delete 2020-10-10 13:02:58 -05:00
sean-m-sullivan
7ffa70422a remove typo changes 2020-10-10 11:57:34 -05:00
sean-m-sullivan
5655f766f0 linting 2020-10-10 11:56:00 -05:00
sean-m-sullivan
a2c8e3d87e clean up and tests added 2020-10-10 11:53:50 -05:00
Adrian Sorge
8f37afeec4 Changed Listgroup to div 2020-10-10 14:21:19 +01:00
sean-m-sullivan
9bcb5ef0c9 intial update for workflow approval nodes 2020-10-10 04:06:49 -05:00
Sean Sullivan
501c91f035 Merge pull request #12 from ansible/devel
rebase
2020-10-09 23:25:32 -05:00
Jeff Bradberry
a07dabae9e Attempt to infer related pages on export when the link is missing 2020-10-09 14:06:28 -04:00
softwarefactory-project-zuul[bot]
e6c124962b Merge pull request #8352 from nixocio/ui_issue_6857
Mark missing words for translation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-09 16:01:40 +00:00
softwarefactory-project-zuul[bot]
bb15132031 Merge pull request #8306 from thedoubl3j/sanity_ignore
fixing quotes to not fail smart quotes sanity test

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-09 15:16:13 +00:00
softwarefactory-project-zuul[bot]
0d4226a903 Merge pull request #8342 from AlexSCorey/8283-InventoryHelperMisalignment
Fixes invalid text location

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-08 19:49:43 +00:00
Keith Grant
2133b83db4 fix handling of nested API form errors 2020-10-08 09:14:51 -07:00
nixocio
d149e23170 Mark missing words for translation
Add missing words for translation.

`...more`, and `Show Less` were already marked for translation in a
previous PR, since this code is shared as part of the `ChipGroup` code.

See: https://github.com/ansible/awx/issues/6857
2020-10-08 11:25:24 -04:00
Rigel Di Scala
32c08a09c3 Serialize Workflow Job Template inventories by natural key - related #7798
This changeset introduces two changes:

 1. Update the API representation of Workflow Job Templates to use the
 natural key of the Inventory type instead of its id;
 2. Override the related property of the CLI's WorkflowJobTemplate page
 type to patch the related references during the export process,
 allowing the resource to be serialised using the natural key of the
 Inventory type instead of the id.

Change n.2 is a workaround that is used when exporting resources from
AWX/Tower instances that don't have change n.1. It can be removed in the
future.
2020-10-08 10:21:00 -04:00
nixocio
1fbcd7e434 Update AddDropDownButton to show down caret
Update AddDropDownButton to show down caret

See: https://github.com/ansible/awx/issues/7721
2020-10-08 09:17:50 -04:00
softwarefactory-project-zuul[bot]
a1700404cd Merge pull request #8243 from AlexSCorey/AdHocCommandsOnLists
Adds Ad Hoc Commands To Remaining Lists

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-07 21:55:14 +00:00
Alex Corey
b04be850b5 fixes bug where one can launch erronously, adds tests for that bug 2020-10-07 12:18:13 -04:00
Keith Grant
f5e4147502 add comment to tests 2020-10-07 08:30:11 -07:00
softwarefactory-project-zuul[bot]
503886b704 Merge pull request #8325 from rooftopcellist/i18n_devel_ja_oct5
UI translation strings for devel branch

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-07 13:50:07 +00:00
Alex Corey
ee28dff7cb fixes invalid text location 2020-10-07 09:11:44 -04:00
Keith Grant
52f37242fc clean up & unit test form error handling 2020-10-06 14:48:23 -07:00
softwarefactory-project-zuul[bot]
37b3cc72b2 Merge pull request #8235 from AlexSCorey/5913-RefactorJTPOL
Restructures Job Template POL and renames useSteps

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-06 18:47:12 +00:00
Bill Nottingham
bc22fa56dc Fix 500 when required LDAP group parameters aren't set. 2020-10-05 22:15:20 -07:00
softwarefactory-project-zuul[bot]
4af4252604 Merge pull request #8298 from keithjgrant/7677-a11y-text
Add accessibility labels to job status/cloud sync icons

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-05 21:54:01 +00:00
Alex Corey
b1a1c82169 fixes unresponsive clear all on survey step 2020-10-05 17:13:52 -04:00
Alex Corey
935c7a5328 refactors useSteps to allow each step to handle errors 2020-10-05 17:13:52 -04:00
ansible-translation-bot
792662f3d6 UI translation strings for devel branch 2020-10-05 16:02:24 -04:00
Adrian Sorge
d4e4e3020c changes of npm run prettier 2020-10-05 18:02:54 +01:00
Adrian Sorge
7b13a42daa Fixed Suggestions from Code Review 2020-10-05 17:49:21 +01:00
softwarefactory-project-zuul[bot]
ac105ccd05 Merge pull request #8315 from jakemcdermott/deps-autofix-10-02
Address dependency warning

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-10-05 16:00:12 +00:00
Keith Grant
b7070b7a72 add aria-hidden to Running/Waiting job icons 2020-10-05 08:23:41 -07:00
Adrian Sorge
70141f3d77 Added Groups/Hosts/Sources count to inventory list rows #7674 2020-10-04 15:17:25 +01:00
Jake McDermott
4907aa35a9 Update vulnerable dependency 2020-10-02 20:35:30 -04:00
Alex Corey
f051c4d58a fixes bug with disappearing modal and arguments field validation 2020-10-02 17:17:49 -04:00
softwarefactory-project-zuul[bot]
bd224a75db Merge pull request #8282 from marshmalien/8044-inventory-file-bug
Fix inventory file dropdown placeholder value

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-02 20:35:08 +00:00
Alex Corey
eb2d7c6a77 Adds Ad Hoc Commands 2020-10-02 15:41:25 -04:00
softwarefactory-project-zuul[bot]
0b824ee058 Merge pull request #8313 from ryanpetrello/fix-garbled-unicode-in-notifications
fix a display bug in notification bodies with unicode characters

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-02 19:30:21 +00:00
Ryan Petrello
30b6fd27b3 fix a display bug in notification bodies with unicode characters
see: https://github.com/ansible/awx/issues/7400
2020-10-02 14:37:25 -04:00
softwarefactory-project-zuul[bot]
1792b1350c Merge pull request #8308 from rebeccahhh/awxkit_errormessage_correction
correct error message when calling tower_AWXKit collections module and venv doesn't have it

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-02 16:56:03 +00:00
softwarefactory-project-zuul[bot]
6a61b7ce49 Merge pull request #8307 from ryanpetrello/wf-approval-delete
fix a bug that prevents deletion of workflow approval records

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-01 22:43:32 +00:00
Rebeccah
5df37d4279 switched exit_json to be fail_json so it didn't trigger an error when attempting to utilize the missing_required_lib from ansible. Additionally fixed it for the second usage for correct usage. Given that it is an exception the correct one would not be to exit without failure, as exit_json does, but instead to use fail_json and be able to present the error 2020-10-01 18:28:26 -04:00
Ryan Petrello
64485c1066 fix a bug that prevents deletion of workflow approval records
see: https://github.com/ansible/awx/issues/8305
2020-10-01 16:06:53 -04:00
Jake Jackson
427e1cd214 fixing quotes to not fail smart quotes sanity test 2020-10-01 15:32:43 -04:00
softwarefactory-project-zuul[bot]
796a61da86 Merge pull request #8299 from jakemcdermott/fix-8154
Force logout and clear before social auth login

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-10-01 17:47:12 +00:00
Keith Grant
afe09695d4 update tests 2020-10-01 09:55:17 -07:00
softwarefactory-project-zuul[bot]
f774ef8635 Merge pull request #8304 from jakemcdermott/fix-7892
Remove self-closing tags from webhook cred lookup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-10-01 16:34:00 +00:00
Jake McDermott
bfd224eb7c Remove self-closing tags from webhook cred lookup 2020-10-01 11:44:23 -04:00
Jake McDermott
7479b9faca Force logout and clear before social auth login 2020-10-01 11:15:46 -04:00
Keith Grant
e204325d1d add a11y label to SyncStatusIndicator 2020-09-30 14:36:07 -07:00
Keith Grant
c75c6ae03d add a11y label to StatusIcon 2020-09-30 14:32:45 -07:00
softwarefactory-project-zuul[bot]
1b6acdf84d Merge pull request #8274 from beeankha/add_collection_test_readme
Add New Testing Document for AWX Collections

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-30 19:17:46 +00:00
softwarefactory-project-zuul[bot]
5c0432b979 Merge pull request #8186 from marshmalien/setting-details
Add setting details and unit tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-30 19:01:30 +00:00
softwarefactory-project-zuul[bot]
c7869f0408 Merge pull request #8280 from nixocio/ui_issue_8189
Make ContainerGroupDetails a bit more robust

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-30 19:00:25 +00:00
Marliana Lara
5650344fe8 Fix inventory file dropdown placeholder value 2020-09-30 14:08:08 -04:00
nixocio
ae29eb9673 Make ContainerGroupDetails a bit more robust
In order to create a container group is necessary to provide a
credential.

See: https://github.com/ansible/awx/issues/8184

This change makes the code related to display the credential as part of
the container group details a bit more robust. Avoiding to attempt to
show a non-existent credential - what is not supposed to exist.

Closes: https://github.com/ansible/awx/issues/8199
2020-09-30 13:37:38 -04:00
softwarefactory-project-zuul[bot]
dc997346b6 Merge pull request #8279 from ryanpetrello/drf-release-note
Clarify changelog addition to address CVE-2020-25626

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-30 16:55:45 +00:00
Ryan Petrello
70a371b212 s/Tower/AWX 2020-09-30 12:28:11 -04:00
Ryan Petrello
429e752c26 Clarify changelog addition to address CVE-2020-25626 2020-09-30 12:20:43 -04:00
softwarefactory-project-zuul[bot]
679256fd25 Merge pull request #8239 from nixocio/ui_issue_8184
Add validate for `CredentialLookup` using required prop

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-30 15:24:35 +00:00
beeankha
1bb6601782 Add New Testing Doc for AWX Collections 2020-09-30 10:43:10 -04:00
softwarefactory-project-zuul[bot]
0a1ecd4fe3 Merge pull request #8248 from ryanpetrello/15.0.0-bump
bump version to 15.0.0

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-30 13:07:08 +00:00
softwarefactory-project-zuul[bot]
e7a5d4c5d8 Merge pull request #8267 from mabashian/8252-jt-tabs-reload
Reset error/result only after the next request has resolved to prevent render flickering

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-30 12:24:08 +00:00
Ryan Petrello
2e371dd2ea more 15.0.0 changelog 2020-09-29 17:38:42 -04:00
Ryan Petrello
98b24cd2d8 Bump version to 15.0.0 2020-09-29 17:36:32 -04:00
softwarefactory-project-zuul[bot]
abc6a84210 Merge pull request #8260 from ryanpetrello/drf-upgrade
update to the latest Django Rest Framework

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 20:59:45 +00:00
softwarefactory-project-zuul[bot]
a9cfae70ff Merge pull request #8041 from mabashian/7680-inv-pending-delete
Adds support for pending deletion on inventory list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 20:07:17 +00:00
softwarefactory-project-zuul[bot]
f47812845e Merge pull request #8229 from nixocio/ui_issue_7410
Make filter a bit more consistent accross UI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 19:53:52 +00:00
mabashian
e13b16bf1c Add erroneously removed exhaustive dep comment 2020-09-29 15:42:11 -04:00
nixocio
aa69b925ad Make filter a bit more consistent accross UI
Add `description`, `created_by` and `modified_by` when those fields are
available.

See: https://github.com/ansible/awx/issues/7410
2020-09-29 15:23:28 -04:00
mabashian
ae1d27255b Add delete error handling on inventory detail view 2020-09-29 15:05:35 -04:00
mabashian
f672cee3a0 Reset error/result only after the next request has resolved to prevent render flicking 2020-09-29 13:11:06 -04:00
softwarefactory-project-zuul[bot]
820d4d292e Merge pull request #8253 from beeankha/edit_approval_node_bugfix
Fix Approval Node Edit Permissions

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 16:45:07 +00:00
softwarefactory-project-zuul[bot]
70dfe9a1f2 Merge pull request #8265 from Lodenk/typofix
fixed typo in the word example

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 16:36:58 +00:00
softwarefactory-project-zuul[bot]
6567fab1c8 Merge pull request #8251 from ryanpetrello/fix-vault-password-prompt-bug
fix a bug that can break password prompting in certain scenarios

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2020-09-29 16:35:55 +00:00
beeankha
f584c1cc47 Fix Approval Node Edit Permissions 2020-09-29 12:14:12 -04:00
Patrick
359682022f fixed typo in the word example 2020-09-29 12:00:37 -04:00
softwarefactory-project-zuul[bot]
f39015156b Merge pull request #8228 from john-westcott-iv/tower_ad_hoc_module
Adding ad hoc command modules

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 14:59:52 +00:00
Ryan Petrello
089b0503bb update to the latest Django Rest Framework 2020-09-29 10:25:07 -04:00
softwarefactory-project-zuul[bot]
2019f808b9 Merge pull request #8254 from RULCSoft/fix-typos
Fix a few typos in awx/ui

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 14:04:51 +00:00
mabashian
3f1434f0f5 Only attempt to display sting error messages in ErrorDetail 2020-09-29 09:59:39 -04:00
softwarefactory-project-zuul[bot]
7f7864fe2b Merge pull request #8259 from rooftopcellist/gettext_translations
Include Gettext in dev container image for translation automation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-29 13:48:28 +00:00
Ryan Petrello
c52054951d fix a bug that can break password prompting in certain scenarios
see: https://github.com/ansible/awx/issues/8202
2020-09-29 09:34:38 -04:00
mabashian
6942b4d5b6 Change deleteTeams to deleteInventories 2020-09-29 09:29:18 -04:00
mabashian
10110643ed Flatten out decision tree when an inventory websocket message is processed 2020-09-29 09:09:52 -04:00
mabashian
40e4ba43ef Copy the query params so that we don't add id__in to them. This fixes a bug where a newly copied row would not show up on the list if a websocket message for an inventory source sync had come through beforehand because id__in had been added to the query params. 2020-09-29 09:09:52 -04:00
mabashian
6681ffa8df Add default module_name to adhoc details step test to get rid of logged console error 2020-09-29 09:09:52 -04:00
mabashian
d84615f64b Rename onLoading/onDoneLoading props to onCopyStart and onCopyFinish. Wrap the functions being passed in as those props in useCallback to keep them hooks safe. 2020-09-29 09:09:52 -04:00
mabashian
4b566e9388 Adds support for pending deletion on inventory list 2020-09-29 09:09:52 -04:00
Christian M. Adams
e7b5f311b5 Include Gettext in dev container image for translation automation 2020-09-29 08:53:18 -04:00
Jorge Vallecillo
b335f698e4 Fix a few typos in awx/ui 2020-09-28 19:00:25 -06:00
softwarefactory-project-zuul[bot]
d6201d9eb6 Merge pull request #8224 from tchellomello/import_db
Ability to import standard pgdump into Openshift

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-28 17:24:35 +00:00
nixocio
98b9d4358d Add username to tooltip
Add username to tooltip when user cannot be deleted.

See: https://github.com/ansible/awx/issues/7751
2020-09-28 13:22:01 -04:00
Marliana Lara
bd3c4ca50f Fix aria label routed tab bug value "Object Object" 2020-09-28 12:11:10 -04:00
softwarefactory-project-zuul[bot]
d6f0e16b4d Merge pull request #8242 from wenottingham/certifi-ably-unbundled
Replace certifi with an alternate version

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-28 16:10:30 +00:00
softwarefactory-project-zuul[bot]
0c7bfa543b Merge pull request #8001 from velzend/allow_skipping_provision_instance_and_register_queue
allow skipping provision instance and register queue

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-28 15:20:35 +00:00
softwarefactory-project-zuul[bot]
36d4f255a3 Merge pull request #8236 from ryanpetrello/more-callback-cleanup
refactor some callback receiver code

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-28 15:20:29 +00:00
softwarefactory-project-zuul[bot]
30fd418cc9 Merge pull request #8220 from mabashian/fix-padding-pol-fields
Fix padding on field labels with prompt on launch checkboxes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-28 13:42:37 +00:00
softwarefactory-project-zuul[bot]
24e9484f55 Merge pull request #7338 from mabashian/cred-plugin-test-button
Hook up Test button on Metadata step in credential plugin wizard

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-09-25 19:52:44 +00:00
Bill Nottingham
85b694410b Adjust included licenses 2020-09-25 15:51:55 -04:00
Bill Nottingham
d0ba59735c Replace certifi with an alternate version
This version just uses the system cert store.
2020-09-25 14:39:16 -04:00
nixocio
1aa90af342 Add validate for CredentialLookup using required prop
When using `CredentialLookup` with required prop. The `validate`
argument must be provided to the `useField`.

See: https://github.com/ansible/awx/issues/8184
2020-09-25 14:19:51 -04:00
Marliana Lara
558dfb685e Add a new key "unit" to api setting fields
* Add detail popover
* Fix broken redirects
* Add additional id and data-cy attributes to Detail components
* Remove galaxy fields from job settings
2020-09-25 14:00:27 -04:00
beeankha
b34c1f4c79 Update integration tests 2020-09-25 13:23:34 -04:00
Ryan Petrello
baad765179 refactor some callback receiver code
the bigint migration removed the foreign key constraints for:

- host_id
- job_id (and projectupdate_id, etc...)

because of this, we don't really need to check explicitly for a host_id
IntegrityError anymore (because it won't occur)

additionally, while it's possible to insert an event with a mismatched
job_id now (for example, you can totally start a long-running job, and
delete the job record in the background using the ORM or psql), doing
so results in DoesNotExist errors in the code that handles the
playbook_on_stats events
2020-09-25 13:12:42 -04:00
softwarefactory-project-zuul[bot]
b4d6270eab Merge pull request #8232 from mabashian/8219-extra-GET-requests
Fix extra GET requests on Notif Template/Container Groups forms

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-25 13:37:43 +00:00
John Westcott IV
842e490ba6 Removing needs devel ad hoc entry 2020-09-25 08:51:28 -04:00
John Westcott IV
5b10482256 Fixing linting 2020-09-25 08:49:28 -04:00
John Westcott IV
baf3b617cb Initial commit of ad hoc module 2020-09-25 08:49:28 -04:00
softwarefactory-project-zuul[bot]
acc0ba570e Merge pull request #8205 from john-westcott-iv/tower_application_continuation
Tower application continuation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-25 00:24:01 +00:00
mabashian
56ed2c6afa Autopopulate credential on container group form and organization on notification template form 2020-09-24 17:26:33 -04:00
mabashian
24a4236232 Wrap onChange functions passed to lookups in useCallback since these functions are eventually passed to a hook and used in a dependency array. 2020-09-24 17:07:58 -04:00
softwarefactory-project-zuul[bot]
ce65ed0ac6 Merge pull request #8191 from ryanpetrello/callback-directly-to-redis
remove multiprocessing.Queue usage from the callback receiver

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-24 18:21:49 +00:00
Ryan Petrello
cd0b9de7b9 remove multiprocessing.Queue usage from the callback receiver
instead, just have each worker connect directly to redis
this has a few benefits:

- it's simpler to explain and debug
- back pressure on the queue keeps messages around in redis (which is
  observable, and survives the restart of Python processes)
- it's likely notably more performant at high loads
2020-09-24 13:53:58 -04:00
John Westcott IV
a9ea2523c9 Fixing linting/doc issues 2020-09-24 13:33:35 -04:00
softwarefactory-project-zuul[bot]
d97f80df43 Merge pull request #8221 from beeankha/job_timeout_notification_bugfix
Enable "On Fail" Notifications to Send Upon Timeout of Job Templates

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-24 13:53:04 +00:00
Marcelo Moreira de Mello
f1b8a63d91 Ability to import standard pgdump into Openshift 2020-09-23 22:33:57 -04:00
beeankha
c855ce95aa Fix JT timeout notification bug 2020-09-23 15:45:11 -04:00
mabashian
b714a0dc7e Fix padding on field labels with prompt on launch checkboxes 2020-09-23 15:27:31 -04:00
Marliana Lara
a69a40a429 Rename radius to correct name 2020-09-23 15:00:06 -04:00
Marliana Lara
749afd53a1 Rename radius to incorrect name 2020-09-23 14:59:00 -04:00
Marliana Lara
7dc1157f69 Rename files to incorrect name
Rename files to correct name
2020-09-23 14:54:29 -04:00
Marliana Lara
b768b0222e Add setting details and unit tests 2020-09-23 14:54:26 -04:00
softwarefactory-project-zuul[bot]
aac17b9d2c Merge pull request #8206 from ryanpetrello/more-bulk-update-last-job
change host -> last_job_id bulk update query to avoid locking issues

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-23 15:18:42 +00:00
softwarefactory-project-zuul[bot]
d7ca49ce4a Merge pull request #8193 from ryanpetrello/ws-broadcast-limited
add a few additional optimizations to the callback receiver

Reviewed-by: Shane McDonald <me@shanemcd.com>
             https://github.com/shanemcd
2020-09-23 14:58:41 +00:00
John Westcott IV
4a4e62e035 Removing tower_application from needs_development in completeness test 2020-09-23 09:54:06 -04:00
softwarefactory-project-zuul[bot]
e5f5ad198a Merge pull request #8212 from branic/add_postgres_custom_root_ca
Add custom root ca certificate via configmap

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-23 13:41:13 +00:00
softwarefactory-project-zuul[bot]
ee3f835ea9 Merge pull request #8213 from ryanpetrello/galaxy-ignore-certs-ui
expose GALAXY_IGNORE_CERTS in the job settings UI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-23 13:15:28 +00:00
John Westcott IV
cb1ba9e3a4 Fixing zuul issues 2020-09-23 09:03:03 -04:00
Ryan Petrello
1f0cd8df71 expose GALAXY_IGNORE_CERTS in the job settings UI 2020-09-23 08:36:52 -04:00
Brant Evans
512da5a01c Add custom root ca certificate via configmap
Signed-off-by: Brant Evans <bevans@redhat.com>
2020-09-22 16:42:39 -07:00
Ryan Petrello
89ff8e1f3e change host -> last_job_id bulk update query to avoid locking issues
see: https://github.com/ansible/awx/issues/8145
2020-09-22 16:04:28 -04:00
softwarefactory-project-zuul[bot]
3184bccb33 Merge pull request #8204 from marshmalien/words-matter-pt2
Replace google oauth2 setting with more inclusive language

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-22 19:43:40 +00:00
John Westcott IV
c5df37777b Addig tests and updating minor module bugs 2020-09-22 15:22:35 -04:00
Marliana Lara
0732b047b5 Replace setting term with inclusive language 2020-09-22 15:09:55 -04:00
Geoffrey Bachelot
1c729518a5 Delete depcreated username parameter 2020-09-22 14:54:35 -04:00
Geoffrey Bachelot
5a374585de delete deprecated parameters and add missing skip_authorization 2020-09-22 14:54:35 -04:00
Geoffrey Bachelot
b9d2e431a6 Create tower_application module 2020-09-22 14:54:35 -04:00
Ryan Petrello
b370e8389e add a few additional optimizations to the callback receiver 2020-09-22 08:51:01 -04:00
Jake McDermott
b6afc085a7 Reload on stats when live updates are disabled 2020-09-21 20:42:44 -04:00
Ryan Petrello
bed2dea04d don't broadcast ws:// events when UI_LIVE_UPDATES_ENABLED is False 2020-09-21 20:42:39 -04:00
softwarefactory-project-zuul[bot]
31cd36b768 Merge pull request #8104 from mabashian/4254-auto-pop-lookup
Auto populate various required lookups on various forms

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-21 21:37:02 +00:00
softwarefactory-project-zuul[bot]
dc492d0cfd Merge pull request #8179 from nixocio/ui_fix_undefined_variable
Fix issue with undefined variable

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-21 18:28:15 +00:00
softwarefactory-project-zuul[bot]
9a8580144c Merge pull request #8189 from kdelee/analytics_logging
Need log level info to show up with new settings

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-21 17:52:15 +00:00
mabashian
10ae6c9042 Cleans up console error thrown from this test. Also fixed the last test as it wasn't actually testing the desired behavior. 2020-09-21 13:24:23 -04:00
mabashian
8bee409a4a Auto populate various required lookups on various forms 2020-09-21 13:24:23 -04:00
Elijah DeLee
7c7d15a8be Need log level info to show up with new settings 2020-09-21 11:22:43 -04:00
softwarefactory-project-zuul[bot]
9eb8ac620f Merge pull request #8180 from jakemcdermott/deps-autofix
Upgrade lingui-cli to 2.9.2

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-09-21 15:08:19 +00:00
softwarefactory-project-zuul[bot]
44d1e15ef4 Merge pull request #8177 from ryanpetrello/rrule-bug
fix an rrule bug that causes improper HOURLY/MINUTELY calculation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-18 20:02:10 +00:00
softwarefactory-project-zuul[bot]
0c81b83080 Merge pull request #8078 from nixocio/ui_issue_8073
Add Container Group details

Reviewed-by: Kersom
             https://github.com/nixocio
2020-09-18 19:15:14 +00:00
softwarefactory-project-zuul[bot]
a2408892a8 Merge pull request #8152 from AlanCoding/import_fix
Fix AWX collection import test interference with Default organization

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-18 19:05:22 +00:00
softwarefactory-project-zuul[bot]
deab7395f2 Merge pull request #8150 from keithjgrant/7878-notification-websockets
Update status after sending test notification

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-18 17:52:38 +00:00
Keith Grant
3ed05e9d9b fix NotificationTemplateItem test 2020-09-18 10:20:17 -07:00
Jake McDermott
34579226ef Upgrade lingui-cli to 2.9.2 2020-09-18 13:01:04 -04:00
nixocio
9d0b37e96c Fix issue with undefined variable
Fix issue with undefined variable when data related to `me` is not
available.
2020-09-18 12:30:53 -04:00
softwarefactory-project-zuul[bot]
256123dc9d Merge pull request #8168 from keithjgrant/3321-session-management
Logout session if config returns 401

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-09-18 16:08:06 +00:00
Ryan Petrello
bf1d93168b fix an rrule bug that causes improper HOURLY/MINUTELY calculation
see: https://github.com/ansible/awx/issues/8071
2020-09-18 12:06:07 -04:00
softwarefactory-project-zuul[bot]
39497fa502 Merge pull request #8178 from ryanpetrello/callback-status-sos
report callback receiver status in the sosreport

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-18 15:15:21 +00:00
Ryan Petrello
a1ddbd760d report callback receiver status in the sosreport 2020-09-18 10:49:50 -04:00
softwarefactory-project-zuul[bot]
c17bb36bcd Merge pull request #8167 from ryanpetrello/callback-cleanup
Add support for a `--status` to the callback receiver (and improve our approach to stats collection in general)

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-18 13:58:30 +00:00
Keith Grant
43d339d1cd fix test 2020-09-17 13:46:43 -07:00
softwarefactory-project-zuul[bot]
56c5a39087 Merge pull request #8159 from john-westcott-iv/lookup_plugin_fix
Fixing issue with lookup plugin not able to load host, user, etc

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-17 20:03:15 +00:00
Ryan Petrello
57f8e48894 make --status more robust for dispatcher, and add support for receiver
make the --status flag work by fetching a periodically recorded snapshot
of internal process state; additionally, update the callback receiver to
*also* record these statistics so we can gain more insight into any
performance issues
2020-09-17 15:33:37 -04:00
Keith Grant
cde8cb57da allow app skeleton to display while config is loading 2020-09-17 12:31:13 -07:00
softwarefactory-project-zuul[bot]
969f75778c Merge pull request #8166 from wenottingham/log-log-log
Fix analytics logging

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-17 18:42:29 +00:00
Bill Nottingham
18c27437b7 Fix analytics logging
The analytics change PR adjusted the logging for awx.analytics,
which solved the issue, but should have used the targeted awx.main.analytics.

Also flip a couple of loggers to use the regular awx.analytics (awx analytics)
logger instead of awx.main.analytics (the automation anayltics task system).
2020-09-17 13:39:14 -04:00
John Westcott IV
baa00bd582 Truthy strikes again 2020-09-17 07:51:01 -04:00
Keith Grant
6c4f9364ee kick back to login page if config gets 401 response 2020-09-16 15:35:02 -07:00
John Westcott IV
ee3a90d193 Adding example of specifying connection info 2020-09-16 14:52:41 -04:00
John Westcott IV
24bdbd8c58 Fixing issue with lookup plugin not able to load host, user, etc 2020-09-16 14:41:04 -04:00
Ryan Petrello
0df6409244 remove task state tracking from the callback receiver
we don't have support for displaying these stats anyways, so there's
no point in using resources tracking them, especially for high-volume
installs
2020-09-16 13:40:42 -04:00
softwarefactory-project-zuul[bot]
aceb8229ba Merge pull request #8153 from AlanCoding/delete_things
Remove out of date collection testing tools

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-16 15:05:56 +00:00
Alan Rominger
e177432b8f Do not expect failure in tower_import test 2020-09-16 10:34:11 -04:00
softwarefactory-project-zuul[bot]
1860a2f71d Merge pull request #8087 from AlanCoding/update_secrets
Add new option update_secrets to allow lazy or strict updating

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-16 03:19:55 +00:00
Alan Rominger
05fb47dece Remove out of date collection testing tools 2020-09-15 22:59:12 -04:00
Alan Rominger
3aec1a115d fix wording 2020-09-15 22:38:37 -04:00
Alan Rominger
2f1a9a28ea streamline credential test 2020-09-15 22:38:37 -04:00
Alan Rominger
362d6a3204 Add new option update_secrets to allow lazy or strict updating 2020-09-15 22:38:37 -04:00
Nicolas Payart
8e97214309 Add option update_password (always, on_create) to tower_user module 2020-09-15 22:37:50 -04:00
Alan Rominger
48f30c5106 Fix AWX collection import test interference with Default organization 2020-09-15 22:03:37 -04:00
Keith Grant
a10f52c70e poll for notification status after sending test 2020-09-15 15:37:44 -07:00
softwarefactory-project-zuul[bot]
ef3a497c42 Merge pull request #8147 from ryanpetrello/py-path
move an optional import for awxkit

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-15 19:32:26 +00:00
softwarefactory-project-zuul[bot]
4b72630087 Merge pull request #8136 from neoaggelos/awxkit-import-yaml-loader
Support `!import` and `!include` in `awx import -f yaml` command

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-15 18:56:06 +00:00
softwarefactory-project-zuul[bot]
432e167930 Merge pull request #8105 from keithjgrant/7877-notification-custom-messages
Notification Detail: show custom messages

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-15 18:53:41 +00:00
Ryan Petrello
1a533a2a23 move an optional import for awxkit
I'm not sure that this function is actually in use anywhere anymore, but
it shouldn't be a top-level import because it represents an optional
dependency.
2020-09-15 14:50:01 -04:00
Keith Grant
fa0abc0dd8 notification templates: fix un-select all 2020-09-15 10:56:55 -07:00
softwarefactory-project-zuul[bot]
b0875965db Merge pull request #8138 from moreiramarti/devel
K8s ServiceAccount variabilization

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-15 14:35:08 +00:00
nixocio
d3d3fe8892 Add Container Group details
Add Container Group details.

See: https://github.com/ansible/awx/issues/8073
2020-09-15 09:11:34 -04:00
Keith Grant
236ae6c5b6 handle null messages.workflow_approval some more 2020-09-14 16:05:03 -07:00
Keith Grant
b27d9b680a handle null messages.workflow_approval 2020-09-14 15:17:39 -07:00
softwarefactory-project-zuul[bot]
22bff7adec Merge pull request #8141 from kdelee/fix_analytics_tests
Print one targz per line (analytics gather)

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-14 22:04:23 +00:00
softwarefactory-project-zuul[bot]
a90bb36b72 Merge pull request #8055 from mabashian/8052-workflow-viz-rbac
Fixes some rbac issues in the workflow toolbar and start screen

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-14 21:14:12 +00:00
Elijah DeLee
d8e4ac773b Print one tarball per line
Printing out a python like list is hard to process for tests
Better to print out one tarball per line
2020-09-14 17:00:31 -04:00
softwarefactory-project-zuul[bot]
1a581a79ea Merge pull request #8070 from nixocio/ui_add_edit_container_groups
Add/Edit Container Groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-14 20:48:05 +00:00
softwarefactory-project-zuul[bot]
99da5770a7 Merge pull request #8139 from ansible/jakemcdermott-remove-self-closing-tag-tags
Remove self-closing tags for tag component

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-14 16:59:55 +00:00
Martinho Moreira
8d5914b3f1 K8s ServiceAccount variabilization 2020-09-14 17:37:45 +02:00
Jake McDermott
c6aeb755a4 Remove self-closing tags for tag component 2020-09-14 11:28:52 -04:00
softwarefactory-project-zuul[bot]
9d66b41e84 Merge pull request #7991 from bbayszczak/hashivault_auth_path_in_inputs
hashivault_kv auth_path moved from metadata to inputs

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-09-14 15:28:07 +00:00
Aggelos Kolaitis
b8cf644959 Add name to StringIO object to fix failing test 2020-09-13 17:41:53 +03:00
Aggelos Kolaitis
9918b2581c Support !import and !include in awx import -f yaml command 2020-09-13 17:01:12 +03:00
softwarefactory-project-zuul[bot]
b69fad83b1 Merge pull request #7709 from wenottingham/so-many-del-toros
Adjust analytics gathering

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 21:41:05 +00:00
softwarefactory-project-zuul[bot]
424bf94a15 Merge pull request #8101 from ansible/jakemcdermott-expand-nav
Start with navigation expanded

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 20:16:02 +00:00
softwarefactory-project-zuul[bot]
9d4bad559f Merge pull request #8102 from jakemcdermott/remove-dead-projects-code
Remove dead projects code

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 20:09:25 +00:00
softwarefactory-project-zuul[bot]
1e9fb6b640 Merge pull request #8133 from fosterseth/update_task_manager_system_docs
Update task manager docs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 18:50:10 +00:00
mabashian
ad1c4b1586 Add unique ID to cred field external plugin button(s) 2020-09-11 14:17:35 -04:00
softwarefactory-project-zuul[bot]
412a294461 Merge pull request #7940 from mabashian/6616-workflow-results-sockets
Update job status and workflow node job status based on websocket events

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 17:31:47 +00:00
Seth Foster
3606b4e334 these rules no longer apply as of PRs 5519 and 5489 2020-09-11 12:59:18 -04:00
softwarefactory-project-zuul[bot]
0c5aaa2872 Merge pull request #8132 from wenottingham/halfway-there
Make ansible venv psutil match awx venv version

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 16:52:23 +00:00
Bill Nottingham
f1c59477c0 Make ansible venv psutil match awx venv version 2020-09-11 12:02:00 -04:00
softwarefactory-project-zuul[bot]
0a871c6107 Merge pull request #8119 from soomsoom/unarchive-rpm-pacakges
Adding unzip dnf package

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 15:57:38 +00:00
softwarefactory-project-zuul[bot]
61c4c5292c Merge pull request #8125 from jakemcdermott/fix-api-urls
Fix malformed urls

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 15:53:39 +00:00
softwarefactory-project-zuul[bot]
88c691fd6e Merge pull request #7993 from mabashian/7364-jobs-list-cancel
Adds cancel button to jobs list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-11 15:07:30 +00:00
mabashian
68426daaff Fix residual error from merge conflict 2020-09-11 10:50:27 -04:00
mabashian
d654af77cf Moves cred plugin test button down into wizard footer 2020-09-11 10:50:27 -04:00
mabashian
5cfca7896f Adds proptypes to CredentialPluginTestAlert component 2020-09-11 10:50:27 -04:00
mabashian
9f8691dbea Add the credential id and metadata from the form to the dependency array of useCallback when testing cred plugin configuration. This allows us to remove the variables passed in to the request. 2020-09-11 10:50:27 -04:00
mabashian
62054bbfc8 Pulls CredentialPlugins out of CredentialFormFields and into the root of the shared dir 2020-09-11 10:50:27 -04:00
mabashian
aed96de195 Fix merge conflict 2020-09-11 10:50:27 -04:00
mabashian
67f46b4d7e Hook up Test button on Metadata step in credential plugin wizard 2020-09-11 10:50:27 -04:00
mabashian
8fab4559b9 Add data-job-status attr to all StatusIcons so that automated tests can determine whether or not a status has been updated via websockets. 2020-09-11 09:27:44 -04:00
mabashian
45ca9976f3 Fix merge conflict error 2020-09-11 09:17:42 -04:00
mabashian
5b56bda0bb Fix tests after changing node data structure 2020-09-11 09:17:42 -04:00
mabashian
c318a17590 Refresh nodes after workflow has finished running so that we can display all job info for relevant nodes. 2020-09-11 09:17:42 -04:00
mabashian
e28c9bb3c4 Remove unnecessary constant variable 2020-09-11 09:17:42 -04:00
mabashian
c209c98e3f Update job for job detail/workflow details based on websockets. Re-fetch job after job finishes running to display all available info. 2020-09-11 09:17:42 -04:00
mabashian
af77116f1e Convert Job.jsx to functional component in preparation for socket hook usage 2020-09-11 09:17:42 -04:00
mabashian
328e503f5b Update workflow node job status based on websocket messages 2020-09-11 09:17:42 -04:00
mabashian
5d4ef86db7 Rename inv/inv source ws functions 2020-09-11 09:17:42 -04:00
mabashian
3e99e94b8c Redirect user to visualizer page after successful workflow creation 2020-09-11 09:17:42 -04:00
Bill Nottingham
13802fcf2b Don't return error messages for license errors
Just log the exception and return None.
2020-09-10 21:19:07 -04:00
Jake McDermott
b2ad75a1b7 Fix malformed urls 2020-09-10 18:31:49 -04:00
mabashian
130a43f5c4 Simplify kebab modal open logic 2020-09-10 15:32:30 -04:00
mabashian
0fc6affe85 Refactor kebab modal tracking logic in delete/cancel buttons 2020-09-10 15:32:29 -04:00
mabashian
c8a07309ee Fix typo 2020-09-10 15:32:29 -04:00
mabashian
2b60759edc Fix bug where delete/cancel buttons in kebab would not actually make delete/cancel requests 2020-09-10 15:32:29 -04:00
mabashian
225f57fefd Remove use of i18n.plural in favor of low level i18n._. 2020-09-10 15:32:29 -04:00
mabashian
bae10718d5 Remove RelatedAPI model in favor of JobsAPI. Adds cancel method to JobsAPI and uses that on the jobs list. 2020-09-10 15:32:29 -04:00
mabashian
f27b541396 Adds cancel button to jobs list toolbar 2020-09-10 15:32:29 -04:00
mabashian
6889128571 Peel axios instantiation out into it's own file so that it can be used in the RelatedAPI model 2020-09-10 15:32:29 -04:00
softwarefactory-project-zuul[bot]
4b51c71220 Merge pull request #8109 from AlanCoding/hack_null_org
Hack to delete orphaned organizations, consolidate get_one methods

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-10 18:15:45 +00:00
Jake McDermott
59ecefb1c5 Start with navigation expanded 2020-09-10 13:48:32 -04:00
Jake McDermott
c3f9993e18 Remove dead projects code 2020-09-10 13:28:00 -04:00
softwarefactory-project-zuul[bot]
328b270c9f Merge pull request #8121 from ryanpetrello/galaxy-cred-collection
address a few follow-up issues for Org -> Galaxy Credentials support

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-10 15:58:27 +00:00
Ryan Petrello
af238be377 address a few follow-up issues for Org -> Galaxy Credentials support
- add support for managing galaxy creds in the tower organization module
- fix a minor serializer bug
2020-09-10 11:00:21 -04:00
softwarefactory-project-zuul[bot]
4bb851ca66 Merge pull request #8118 from mjeffin/postres-volume-typo
Update docker-compose.yml.j2

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-10 14:39:43 +00:00
Alan Rominger
2e1f5cebb7 Further refine error message and update integration tests
Fix test with spaces

pep8 failure

More test tweaks

Even more test fixes
2020-09-10 09:49:27 -04:00
Alan Rominger
a73323f3d6 Hack to delete orphaned organizations, consolidate get_one methods
minor test update

Updating the message if more than one object is found

Update test to new message
2020-09-10 09:00:50 -04:00
soomsoom
014a38682d Adding unzip dnf package
Adding unzip DNF package to resolve an issue with the unarchive module when run locally
2020-09-10 06:26:07 -04:00
mjeffin
38fd652f89 Update docker-compose.yml.j2
Add quotes around volume value for posgres data. I installed via docker without changing any values and the UI was stuck in upgrading for long time. Browsed around and figured out that issue was due to postgres volume as a query was getting error. Inspected the template and found that there was no quotes around volume, unlike volumes for others. 
I added the quotes and docker compose was working
2020-09-10 13:53:52 +05:30
softwarefactory-project-zuul[bot]
ff7c2e9180 Merge pull request #8111 from ryanpetrello/bye-bye-boto
remove boto as an awx dependency

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-10 01:39:00 +00:00
softwarefactory-project-zuul[bot]
e39622d42e Merge pull request #8058 from sean-m-sullivan/workflow_label
Workflow label

Reviewed-by: Alan Rominger <arominge@redhat.com>
             https://github.com/AlanCoding
2020-09-10 01:21:06 +00:00
Bill Nottingham
05ad85e7a6 Remove the model for the now unused TowerAnalyticsState. 2020-09-09 20:18:04 -04:00
Bill Nottingham
a604ecffb8 Adjust query_info to set the collection time based on what's passed. 2020-09-09 20:05:48 -04:00
Bill Nottingham
09f7d70428 Use isoformat() rather than strftime
Reformat SQL in unit tests because sqlite.
2020-09-09 20:05:32 -04:00
Bill Nottingham
d4ba62695f Put awx analytics logs also in the task system logger
Errors/warnings when gathering analytics are about 50/50 split between
the gathering code in analytics and the task code that calls it, so
they should be in the same place for debugging sanity.
2020-09-09 17:42:40 -04:00
Bill Nottingham
c753324872 Move back to less frequent collections, and split large event tables
This should ensure we stay under 100MB at all times.
2020-09-09 17:42:40 -04:00
Bill Nottingham
9f67b6742c Fail more gracefully if analytics.ship() is called with a bad path,
or it's deleted out from under us.
2020-09-09 17:42:40 -04:00
Bill Nottingham
1a15f18be3 Stop using the TowerAnalyticsState solo model
This is now tracked in the AUTOMATION_ANALYTICS_LAST_GATHER setting.
2020-09-09 17:42:40 -04:00
Bill Nottingham
40309e6f70 Ensure we do not send large bundles, or empty bundles
Collect expensive collectors separately, and in a loop
where we make smaller intermediate dumps.

Don't return a table dump if there are no records, and
don't put that CSV in the manifest.

Fix up unit tests.
2020-09-09 17:42:40 -04:00
Bill Nottingham
1c4b06fe1e Refactor analytics collectors.
- Only have one registration class
- Add description fields
- Add automation collector information to /api/v2/config
2020-09-09 17:10:14 -04:00
softwarefactory-project-zuul[bot]
dff7667532 Merge pull request #7905 from AlexSCorey/6603-AdHocCommands
Add Ad Hoc Commands

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-09 20:21:41 +00:00
Daniel Sami
da58db7431 grammar fix 2020-09-09 15:42:02 -04:00
Alex Corey
3402e5db35 updates tooltip component, fixes formik configuration on ad hoc qizard 2020-09-09 15:20:18 -04:00
Daniel Sami
fe115fdd16 dropped translation tag 2020-09-09 14:39:54 -04:00
Ryan Petrello
a817708d70 remove boto as an awx dependency
see: https://github.com/ansible/awx/issues/2115
2020-09-09 14:33:33 -04:00
Alex Corey
678dcad437 updates tooltip component, fixes formik configuration on ad hoc qizard 2020-09-09 12:46:19 -04:00
Alex Corey
0e3fbb74d4 updates keys 2020-09-09 12:46:19 -04:00
Alex Corey
94469cc8c0 Adds Proptypes and updates tooltips to make them more translatable 2020-09-09 12:46:19 -04:00
Alex Corey
e6ae171f4b Adds Ad Hoc Commands Wizard 2020-09-09 12:46:19 -04:00
softwarefactory-project-zuul[bot]
caa7b43fe0 Merge pull request #7817 from ryanpetrello/galaxy-credentials
Support Organization-scoped Galaxy installs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-09 16:17:18 +00:00
mabashian
19886f7ec3 Hide edit button on workflow node details view for users that don't have the ability to edit the workflow 2020-09-09 09:44:09 -04:00
mabashian
945dfbb648 Fixes some rbac issues in the workflow toolbar and start screen. Add/edit-related buttons should be hidden for users that cannot edit the workflow. 2020-09-09 09:07:46 -04:00
Sean Sullivan
470b7aaeea Merge pull request #10 from ansible/devel
Rebase from devel
2020-09-09 07:49:37 -05:00
Keith Grant
6af427d4e1 update test snapshot 2020-09-08 14:45:20 -07:00
softwarefactory-project-zuul[bot]
a3e08a3d09 Merge pull request #8072 from john-westcott-iv/get_one_fix
Modify get_one method to allow IDs in addition to names

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-08 21:30:59 +00:00
Keith Grant
e0e48bf922 add custom messages to Notification Detail 2020-09-08 14:04:38 -07:00
Keith Grant
7042542e6a add ArrayDetail 2020-09-08 14:00:57 -07:00
softwarefactory-project-zuul[bot]
3f63800f58 Merge pull request #7967 from keithjgrant/7876-notifications-form
Notifications form

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-08 20:56:21 +00:00
softwarefactory-project-zuul[bot]
800cf30d92 Merge pull request #8089 from rooftopcellist/update_analytics_job_test
Provide a distinct column name for inventory_name in unifiedjob analy…

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-08 20:04:31 +00:00
John Westcott IV
570251dc3d Modifying get_item_name to handle a None object 2020-09-08 15:28:57 -04:00
John Westcott IV
faa33efdd2 Fixing registered name 2020-09-08 15:28:37 -04:00
John Westcott IV
09b8f82bbb Fixing test issue and 'modornizing' test 2020-09-08 15:28:21 -04:00
sean-m-sullivan
cfdfa911e8 update lint 2020-09-08 14:00:12 -05:00
softwarefactory-project-zuul[bot]
cd8c74e28f Merge pull request #8094 from ryanpetrello/upgrade-django-libs
Update Django and channels_redis

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-08 17:46:35 +00:00
John Westcott IV
4c0e288fee Touching up to missing sport of get_one returning multiple params 2020-09-08 13:38:44 -04:00
Keith Grant
13e6757666 add ids to CodeMirror FormGroup containers 2020-09-08 10:17:18 -07:00
softwarefactory-project-zuul[bot]
90c3bfc6ae Merge pull request #8074 from fosterseth/fix-7655_task_manager_times_out
Prevent task manager timeout by limiting number of jobs to start

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-08 16:42:20 +00:00
Seth Foster
e09274e533 PR #8074 - limit how many jobs the task manager can start on a given run 2020-09-08 12:16:06 -04:00
John Westcott IV
c2cfaec7d1 Fixing name -> username 2020-09-08 11:52:53 -04:00
John Westcott IV
d6f35a71d7 Adding allow_unknown option for get_item_name 2020-09-08 11:51:47 -04:00
John Westcott IV
6467d34445 Touching up tower_inventory_source after rebase 2020-09-08 11:36:33 -04:00
Christian M. Adams
0681444294 Provide a distinct column name for inventory_name in unifiedjob analytics csv 2020-09-08 11:14:24 -04:00
John Westcott IV
0a8db586d1 Changing how get_one returns 2020-09-08 11:10:18 -04:00
John Westcott IV
106157c600 get_one now also returns the name field, and modifying modules for get_one and added in some IDs in a handful of unit tests 2020-09-08 11:06:01 -04:00
John Westcott IV
4c4d6dad49 Adding get_item_name and making static methods 2020-09-08 11:03:10 -04:00
John Westcott IV
24ec129235 Modifying credential for new get_one 2020-09-08 11:03:10 -04:00
John Westcott IV
5042ad3a2b Updating user module for new get_one 2020-09-08 11:03:10 -04:00
John Westcott IV
51959b29de Adding name_or_id to get_one to make module more uniform 2020-09-08 11:03:10 -04:00
Ryan Petrello
c862b3e5a2 Revert "work around a memory leak in channels_redis"
This reverts commit e25da217e8.
2020-09-08 10:40:47 -04:00
Ryan Petrello
f81560b12c update Django and channels_redis
see: https://github.com/ansible/tower/issues/4439
also, addresses CVE-2020-24583 and CVE-2020-24584
2020-09-08 10:39:26 -04:00
softwarefactory-project-zuul[bot]
68265ea9b5 Merge pull request #8092 from nixocio/ui_issue_8091
List jobs for container groups

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-09-08 14:33:57 +00:00
softwarefactory-project-zuul[bot]
6e6aa1fdab Merge pull request #8033 from beeankha/update_inv_src_module
Add New tower_inventory_source_update Module

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-08 14:04:32 +00:00
Benoit Bayszczak
08c9219f48 rename 'approle_auth_path' to 'default_auth_path' & fix kwargs.get 2020-09-08 10:39:12 +02:00
beeankha
c7114b2571 Add specific lookup data to error message 2020-09-07 11:43:44 -04:00
softwarefactory-project-zuul[bot]
127ca4bc54 Merge pull request #7975 from AlexSCorey/7973-DisableTemplateFormFields
Disables template and workflow template fields.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-06 21:26:23 +00:00
Alex Corey
b51f013880 disables prompt on launch checkbox 2020-09-05 08:32:15 -04:00
Alex Corey
fc4060778b Disables template and workflow template fields for users that do not have permissions for those fields. 2020-09-05 08:32:15 -04:00
Keith Grant
40d3e4ee8b handle error string in FormSubmitError 2020-09-04 16:24:09 -07:00
beeankha
a0b8f6a25d Make org an optional parameter for both inv source and inv source update modules 2020-09-04 18:56:58 -04:00
Keith Grant
9711c33675 fix multiple notification form bugs 2020-09-04 15:50:04 -07:00
Keith Grant
b119bc475f convert http headers field to string for codemirror 2020-09-04 15:50:04 -07:00
Keith Grant
055abd57cd fix new test from rebase 2020-09-04 15:50:04 -07:00
Keith Grant
95c4b6c922 trying to force tests to re-run 2020-09-04 15:50:04 -07:00
Keith Grant
7ab9d899e4 mark text for translation 2020-09-04 15:49:11 -07:00
Keith Grant
c700d07a0a fix lint error 2020-09-04 15:49:11 -07:00
Keith Grant
4a616d9f81 ensure notification template re-loads after saving 2020-09-04 15:49:11 -07:00
mabashian
e830da97f3 Fix broken credential form tests after id change 2020-09-04 15:49:11 -07:00
Keith Grant
43ac5a0574 add some notification form tests; notification add screen 2020-09-04 15:49:11 -07:00
Keith Grant
9bb834a422 create ArrayTextField component 2020-09-04 15:49:11 -07:00
Keith Grant
458d29a579 only submit customized notification messages if changed 2020-09-04 15:49:11 -07:00
Keith Grant
19fc0d9a96 reset notification messages to defaults when switching to new type 2020-09-04 15:49:11 -07:00
Keith Grant
ba95775ded add custom notification messages subform 2020-09-04 15:49:11 -07:00
Keith Grant
bb12e0a3a9 fix initial values for notification type fields 2020-09-04 15:49:10 -07:00
Keith Grant
09178dd5f2 flush out notification form and type subform 2020-09-04 15:49:10 -07:00
nixocio
d4b2e1998e List jobs for container groups
Add list of jobs related to container groups.

See: https://github.com/ansible/awx/issues/8091
2020-09-04 16:21:32 -04:00
softwarefactory-project-zuul[bot]
9c90804300 Merge pull request #7974 from AlexSCorey/6561-WFJTDeetsNotLoad
Adds fix to load template details 

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-04 20:16:30 +00:00
softwarefactory-project-zuul[bot]
95b43c0087 Merge pull request #8075 from ryanpetrello/redis-capacity-check
if redis is unreachable, set instance capacity to zero

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-04 20:06:21 +00:00
softwarefactory-project-zuul[bot]
3f8cd21233 Merge pull request #8084 from ryanpetrello/bye-fact-scanning
remove old fact scanning plugins

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-04 19:13:56 +00:00
softwarefactory-project-zuul[bot]
e6cd27a858 Merge pull request #7960 from mabashian/6113-6703-cred-file-upload
Support file upload/drag and drop on credential mutliline fields

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-04 17:27:43 +00:00
beeankha
4133ec974b Follow same pattern as project update module, add task to integration test 2020-09-04 13:05:34 -04:00
softwarefactory-project-zuul[bot]
70f1bffe42 Merge pull request #8069 from ryanpetrello/saml-autopop
add the ability to prevent SAML auto-population behavior

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-04 16:01:23 +00:00
mabashian
77c211dabe Adds id's to credential form buttons 2020-09-04 11:22:34 -04:00
Ryan Petrello
013b411a0a remove old fact scanning plugins 2020-09-04 10:51:34 -04:00
beeankha
7764f1c1a5 Fix inv source org lookup, adjust unit tests (since org is now required for inv source module), update README, edit typos in test-related README 2020-09-04 10:19:56 -04:00
beeankha
b78dea3e4b Add wait ability to the module 2020-09-04 10:19:56 -04:00
beeankha
1ce5d7d539 Add ability to look up inventory sources by org name/ID 2020-09-04 10:19:56 -04:00
beeankha
65e0ed8c77 Fix linter error 2020-09-04 10:19:56 -04:00
beeankha
72dbd10c2a Initial commit for new inventory sync module 2020-09-04 10:19:56 -04:00
mabashian
e5f9ed827b Undo commenting out of strictmode 2020-09-04 09:20:09 -04:00
mabashian
2d2108b1de Support file upload/drag and drop on credential mutliline fields 2020-09-04 09:20:09 -04:00
Ryan Petrello
b01d204137 if redis is unreachable, set instance capacity to zero 2020-09-03 15:11:53 -04:00
Ryan Petrello
a6d26d7dab add the ability to prevent SAML auto-population behavior 2020-09-03 11:21:14 -04:00
nixocio
adffa29346 Add/Edit Container Groups
Add/Edit container groups.

See: https://github.com/ansible/awx/issues/7955
2020-09-03 10:13:24 -04:00
softwarefactory-project-zuul[bot]
cce66e366f Merge pull request #8065 from e-desouza/patch-1
Update from pip to pip3

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-03 12:35:07 +00:00
Elton de Souza
371276b2e1 Update from pip to pip3 2020-09-02 21:11:46 -04:00
softwarefactory-project-zuul[bot]
77b1afe6fd Merge pull request #7873 from sean-m-sullivan/project_update
Project update

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-02 15:39:23 +00:00
sean-m-sullivan
5478c5f2fb linting 2020-09-02 08:30:09 -05:00
sean-m-sullivan
e2bf3a0287 update to use isdigit and updated tests 2020-09-02 07:19:11 -05:00
sean-m-sullivan
a17eedd9fe update to not use organizations 2020-09-01 23:08:15 -05:00
sean-m-sullivan
d05c7d6cc5 update to use organizations 2020-09-01 22:54:08 -05:00
sean-m-sullivan
6200467629 add label to workflow templates 2020-09-01 18:58:39 -05:00
Sean Sullivan
dbd8431b14 Merge pull request #6 from ansible/devel
Rebase to devel
2020-09-01 18:50:03 -05:00
softwarefactory-project-zuul[bot]
b11a5c1190 Merge pull request #8057 from ryanpetrello/proj-archive-py2
update the project archive sync support for py2 compatability

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 23:40:58 +00:00
sean-m-sullivan
532447ed40 update to tower module 2020-09-01 16:43:58 -05:00
sean-m-sullivan
300a4510ac update completness 2020-09-01 15:59:53 -05:00
sean-m-sullivan
d269a6d233 update 2020-09-01 15:59:04 -05:00
softwarefactory-project-zuul[bot]
967e35fec9 Merge pull request #8056 from ryanpetrello/dead-code-ansible-path
remove some dead code

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 20:33:43 +00:00
softwarefactory-project-zuul[bot]
fcd1169093 Merge pull request #8043 from john-westcott-iv/instance_groups_module
Adding tower_instance_group module

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 20:26:44 +00:00
sean-m-sullivan
d95d8121f9 added to no endpoints for module 2020-09-01 15:22:14 -05:00
sean-m-sullivan
5d4413041e update to wait 2020-09-01 14:59:16 -05:00
Ryan Petrello
798f6371af update the project archive sync support for py2 compatability
playbook runs in AWX are still supported in python2, so this adds
support for archive-based project syncs in py2
2020-09-01 15:58:43 -04:00
Sean Sullivan
8e317cabc0 Merge pull request #5 from ansible/devel
Rebase from devel
2020-09-01 14:42:23 -05:00
Ryan Petrello
3edaa6bc14 remove some dead code 2020-09-01 15:26:38 -04:00
softwarefactory-project-zuul[bot]
30616c1fce Merge pull request #8022 from sean-m-sullivan/wait_function
Add wait function and update collection modules

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
             https://github.com/beeankha
2020-09-01 19:13:12 +00:00
softwarefactory-project-zuul[bot]
57eed5863a Merge pull request #8054 from ryanpetrello/postgres-upgrade-note
add a changelog note about upgrade issues from 13.0 -> 14.0

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 19:10:55 +00:00
softwarefactory-project-zuul[bot]
1c55d10d81 Merge pull request #7965 from rebeccahhh/devel
adding in inventory to unified job query for analytics

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 18:27:27 +00:00
Ryan Petrello
f4af74dabe renumber the Galaxy credential migration after rebasing 2020-09-01 13:47:26 -04:00
Elyézer Rezende
ad85b176f4 Update awxkit to manage Org galaxy credentials
Add the new credential type to the Credential page object and helper
methods to manage the galaxy credentials for the Organization page
object.
2020-09-01 13:46:47 -04:00
Ryan Petrello
4046b18eff properly handle Galaxy credentials if a Project is orphaned 2020-09-01 13:45:03 -04:00
Ryan Petrello
a869d7da35 create the Galaxy credential for new installs in the preload script
doing this in the migration *before* any Organizations actually exist
is stirring up RBAC dragons that I don't have time to fight

this commit meanst that *new* installs will pre-create the default
Galaxy (public) credential in create_preload_data, while
*upgraded/migrations* installs will do so via the migration
2020-09-01 13:45:03 -04:00
mabashian
895010c675 Pre-populate organization galaxy credential field with the default galaxy credential 2020-09-01 13:45:03 -04:00
Ryan Petrello
a30ca9c19c don't run ansible-galaxy installs if there are no Galaxy credentials 2020-09-01 13:45:03 -04:00
Ryan Petrello
30da93a64e update the help text for Organization galaxy credentials 2020-09-01 13:45:03 -04:00
mabashian
458807c0c7 Add a Galaxy Credential multi-select field to the Organizations form 2020-09-01 13:45:03 -04:00
Ryan Petrello
011822b1f0 make a global "managed by AWX/Tower" Credential to represent Galaxy 2020-09-01 13:45:03 -04:00
Ryan Petrello
e5552b547b properly migrate settings.FALLBACK_GALAXY_SERVERS 2020-09-01 13:45:02 -04:00
Ryan Petrello
1b4dd7c783 enforce Organization ownership of Galaxy credentials 2020-09-01 13:45:02 -04:00
Ryan Petrello
25a9a9c3ba remove redaction exclusions for Galaxy URLs (basic auth support is gone) 2020-09-01 13:45:02 -04:00
Ryan Petrello
130e279012 add a data migration for Galaxy credentials
see: https://github.com/ansible/awx/issues/7813
2020-09-01 13:45:02 -04:00
Ryan Petrello
b8e0d087e5 add model support, an API, and a migration for Org -> Galaxy credentials
see: https://github.com/ansible/awx/issues/7813
2020-09-01 13:44:59 -04:00
softwarefactory-project-zuul[bot]
8996d0a464 Merge pull request #7763 from chrismeyersfsu/feature-inv_plugin_conf
Feature inv plugin conf

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 17:44:22 +00:00
Ryan Petrello
40ac719d6d add a changelog note about upgrade issues from 13.0 -> 14.0 2020-09-01 13:32:09 -04:00
John Westcott IV
5f29b4bc18 Fixing typo 2020-09-01 13:17:24 -04:00
Ryan Petrello
059999c7c3 update the inventory source module to respect new fields 2020-09-01 13:15:07 -04:00
Chris Meyers
924273f589 more get_ansible_version test failure fixes 2020-09-01 12:50:59 -04:00
Chris Meyers
72fc314da1 flake8 fix 2020-09-01 12:50:59 -04:00
Chris Meyers
043a7f8599 more get_ansible_version removal 2020-09-01 12:50:59 -04:00
Chris Meyers
a6712cfd60 bump inv plugin migration to avoid conflict 2020-09-01 12:50:59 -04:00
Alan Rominger
99aff93930 Get rid of ansible version checking 2020-09-01 12:50:59 -04:00
Chris Meyers
03ad1aa141 remove backwords migraiton support for inv plugins
* Do not write out inventory source_vars to a file on disk as they _may_
contain sensitive information. This also removes support for backwards
migrations. This is fine, backwards migration is really only useful
during development.
2020-09-01 12:50:59 -04:00
Jake McDermott
dcf5917a4e Check that host_filter is regexp 2020-09-01 12:50:58 -04:00
Jake McDermott
f04aff81c4 Add details to inv source field help text 2020-09-01 12:50:58 -04:00
Chris Meyers
a9cdf07690 push global invsource fields onto invsource obj 2020-09-01 12:50:58 -04:00
Chris Meyers
d518891520 inventory plugin inventory parameter take precedence over env vars 2020-09-01 12:50:58 -04:00
Chris Meyers
48fb1e973c overwrite plugin: at runtime
* Before, we were re-writing `plugin:` when users updated the
InventorySource via the API. Now, we just override at run-time. This
makes for a more sane API interaction
2020-09-01 12:50:58 -04:00
Chris Meyers
c7794fc3e4 fix missed import 2020-09-01 12:50:58 -04:00
Jake McDermott
2fdeba47a5 Add new common inventory source fields 2020-09-01 12:50:58 -04:00
Chris Meyers
12cf607e8a simplify InventorySourceOption inheritance hack 2020-09-01 12:50:58 -04:00
Chris Meyers
7d4493e109 rename inventory migration 2020-09-01 12:50:57 -04:00
Jake McDermott
b253540047 Add new common inventory source fields 2020-09-01 12:50:57 -04:00
Jake McDermott
42e70bc852 Delete inventory source fields 2020-09-01 12:50:57 -04:00
Jake McDermott
dce946e93f Delete inventory source fields 2020-09-01 12:50:57 -04:00
Chris Meyers
2eec1317bd safer migrations 2020-09-01 12:50:57 -04:00
Chris Meyers
b7efad5640 do not enforce plugin: for source=scm
* InventorySource w/ source type scm point to an inventory file via
source_file. source_vars are ignored.
2020-09-01 12:50:57 -04:00
Chris Meyers
35d264d7f8 forgot to add migration helper
* move models/inventory.py plugin injector logic to a place frozen in
time useable by the migration code.
2020-09-01 12:50:57 -04:00
Chris Meyers
34adbe6028 fix tests for new inv plugin behavior
* Enforce plugin:
2020-09-01 12:50:57 -04:00
Chris Meyers
a8a47f314e remove source_regions 2020-09-01 12:50:56 -04:00
Chris Meyers
f32716a0f1 remove instance_filter 2020-09-01 12:50:56 -04:00
Chris Meyers
7278e7c025 remove group_by from inventory source
* Does not remove group_by testing
2020-09-01 12:50:56 -04:00
Chris Meyers
e11040f421 migrate to new style inv plugin 2020-09-01 12:50:53 -04:00
sean-m-sullivan
9f3635be07 update test to timeout message change 2020-09-01 10:45:41 -05:00
sean-m-sullivan
50637807fc fixed typo 2020-09-01 10:38:15 -05:00
John Westcott IV
d01f2d6caf Converting policy_instance_list from dict to list 2020-09-01 11:02:39 -04:00
softwarefactory-project-zuul[bot]
2fa8b7e594 Merge pull request #8007 from ryanpetrello/defer-artifacts
defer loading Job.artifacts and .extra_vars on host views to improve performance

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 14:08:00 +00:00
John Westcott IV
36ab0dd03e Fixing white spaces 2020-09-01 09:24:36 -04:00
softwarefactory-project-zuul[bot]
671c571628 Merge pull request #8047 from AlanCoding/less_mounting
Remove more special access to folders outside job private_data_dir

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-09-01 02:42:15 +00:00
Alan Rominger
0b371b4340 Copy library folder to job private data dir
Remove inventory scripts show because they no longer exist

Remove reference to non-existent callback directory

Remove more references to removed path
2020-08-31 22:14:59 -04:00
John Westcott IV
72bdd17518 Fixing regression 2020-08-31 16:56:42 -04:00
John Westcott IV
574c3b65b2 Converting from string to array 2020-08-31 16:56:42 -04:00
John Westcott IV
5a8bcd357b Fixing linting issues 2020-08-31 16:56:42 -04:00
John Westcott IV
1bd8f4ad3e Removing tower_instance_group from completness 2020-08-31 16:56:42 -04:00
John Westcott IV
2369bcb25c Removing forward feature needed for testing locally 2020-08-31 16:56:42 -04:00
John Westcott IV
9e29dd08fb Adding tower_instance_group module 2020-08-31 16:56:42 -04:00
sean-m-sullivan
cd45cfec30 updated doc and pep8 2020-08-31 15:53:54 -05:00
sean-m-sullivan
d9d454d435 Merge branch 'wait_function' of github.com:sean-m-sullivan/awx into wait_function 2020-08-31 15:24:40 -05:00
sean-m-sullivan
0bc927820b updated legacy messages 2020-08-31 15:24:32 -05:00
softwarefactory-project-zuul[bot]
e1095a0a94 Merge pull request #8046 from nixocio/ui_fix_date_projects
Update date format for project list item

Reviewed-by: John Hill <johill@redhat.com>
             https://github.com/unlikelyzero
2020-08-31 18:46:51 +00:00
Sean Sullivan
d0ab307787 Merge pull request #4 from ansible/devel
Rebase from Dev
2020-08-31 13:45:49 -05:00
softwarefactory-project-zuul[bot]
6c9e417eb9 Merge pull request #7730 from mabashian/7339-test-button
Adds support for a Test button on the credential form when the credential type is 'external'

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-31 18:43:00 +00:00
softwarefactory-project-zuul[bot]
2837eb7027 Merge pull request #8049 from john-westcott-iv/fix_notification_tests
Cleaning up tower_notification references

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-31 18:19:12 +00:00
softwarefactory-project-zuul[bot]
ad28a36cdf Merge pull request #8048 from AlanCoding/notification_name
correct name of tower_notification redirect

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-31 16:20:37 +00:00
John Westcott IV
ff4ed64978 Cleaning up tower_notification references 2020-08-31 11:57:01 -04:00
Alan Rominger
b84343d292 correct name of tower_notification redirect 2020-08-31 10:18:08 -04:00
nixocio
970ecde0ea Update date format for project list item
Update date format for project list item.

See: https://github.com/ansible/awx/issues/7694
2020-08-30 20:58:58 -04:00
softwarefactory-project-zuul[bot]
ddad5095a4 Merge pull request #8024 from velzend/regsiter_typo
typo: regsiter -> register

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-30 19:53:33 +00:00
softwarefactory-project-zuul[bot]
730cabe597 Merge pull request #8038 from john-westcott-iv/check_token_pre_del
Adding check that we are authenticated and also have a token

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-30 17:54:13 +00:00
softwarefactory-project-zuul[bot]
07ebf677de Merge pull request #8039 from john-westcott-iv/transaction_check
Adding transaction to mock requests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-30 17:54:07 +00:00
softwarefactory-project-zuul[bot]
c7f4c4bdc1 Merge pull request #8029 from AlanCoding/project_cwd
Run project updates from a copy of the playbook vendoring directory

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-29 03:48:01 +00:00
mabashian
9d511a4c04 Fix id on credential select fields 2020-08-28 17:02:25 -04:00
softwarefactory-project-zuul[bot]
bd4b009bea Merge pull request #8035 from nixocio/ui_update_instance_groups
Update instance groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-28 20:37:34 +00:00
mabashian
ae4f1a15d3 Add ID's to the buttons in the external test modal for cred form 2020-08-28 15:43:44 -04:00
mabashian
e93aa34864 Adds support for a Test button on the credential form when the credential type is 'external' 2020-08-28 15:43:44 -04:00
softwarefactory-project-zuul[bot]
bebd882688 Merge pull request #8040 from rooftopcellist/be_more_accepting
Accept all responses <300 from Insights API

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-28 19:43:27 +00:00
Christian M. Adams
4ea648307e Accept all responses <300 from Insights API 2020-08-28 12:45:50 -04:00
John Westcott IV
feb9bcff4d Adding transaction to mock requests 2020-08-28 12:43:33 -04:00
softwarefactory-project-zuul[bot]
40603c213a Merge pull request #8037 from bbayszczak/fix_typo_comment_hashivault
[credential_plugin/hashivault] fix typo

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-28 16:40:46 +00:00
Benoit Bayszczak
e8b54abec4 [credential_plugin/hashivault] edit tests 2020-08-28 17:39:37 +02:00
Benoit Bayszczak
878b754d9f [credential_plugin/hashivault] fix typo 2020-08-28 17:33:19 +02:00
Benoit Bayszczak
16fdf0e28f [credential_plugin/hashivault] add approle_auth_path in inputs 2020-08-28 17:22:07 +02:00
nixocio
21330a54cb Update instance groups
* Simplify criteria to instance group to be considered unavailable
* Round values for used capacity

See: https://github.com/ansible/awx/issues/7467
2020-08-28 11:07:03 -04:00
John Westcott IV
51f4aa2b48 Adding check that we are authenticated and also have a token 2020-08-28 11:04:15 -04:00
softwarefactory-project-zuul[bot]
fe5fb0c523 Merge pull request #7997 from mabashian/7480-webhook-disable
Fixes bug where users were unable to turn webhooks off when editing templates

Reviewed-by: Tiago Góes <tiago.goes2009@gmail.com>
             https://github.com/tiagodread
2020-08-28 14:27:56 +00:00
sean-m-sullivan
b3ec080e08 updated output 2020-08-28 08:25:21 -05:00
sean-m-sullivan
fd77a8aca5 updated output 2020-08-28 08:22:44 -05:00
sean-m-sullivan
7bd3f9d63c updated to error if finished not in result 2020-08-28 07:37:29 -05:00
sean-m-sullivan
d971375907 updated to error if finished not in result 2020-08-28 07:35:13 -05:00
sean-m-sullivan
007b0d841e updated parameters and errors 2020-08-28 07:19:39 -05:00
softwarefactory-project-zuul[bot]
aa637d515a Merge pull request #7929 from nixocio/ui_associate_instances
Associate instances to instance groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-27 17:49:00 +00:00
softwarefactory-project-zuul[bot]
ad3e2cbfcd Merge pull request #8028 from dsesami/8027-workflow-sparkline
Change WFJT details sparkline hyperlink

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-27 16:29:42 +00:00
softwarefactory-project-zuul[bot]
f1ee44b6c2 Merge pull request #8016 from john-westcott-iv/inventory_insights
Adding insights credential to tower_inventory

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-27 16:14:37 +00:00
Daniel Sami
dc7e721968 Change WFJT details sparkline hyperlink 2020-08-27 11:54:38 -04:00
nixocio
632204de83 Associate instances to instance groups
Associate instances to instance groups.

See: https://github.com/ansible/awx/issues/7801
2020-08-27 11:33:45 -04:00
Alan Rominger
e811711a49 Put project playbook in runner project folder 2020-08-27 11:07:10 -04:00
John Westcott IV
64d98a120c Removing debugging end play 2020-08-27 09:47:48 -04:00
Benoit Bayszczak
cf5d1a2d03 restore previous tests as we need to keep backward compatibility
This reverts commit 7c8e5ace52.
2020-08-27 11:06:14 +02:00
tp48cf
5cd12b8088 typo: regsiter -> register 2020-08-27 09:23:41 +02:00
sean-m-sullivan
49e2a3fa5a update documentation 2020-08-26 23:44:31 -05:00
sean-m-sullivan
0c18587851 update to use time function 2020-08-26 23:30:18 -05:00
softwarefactory-project-zuul[bot]
f18d9212cb Merge pull request #7987 from nixocio/ui_add_adv_search
Add advanced search keys for InstanceGroup and CredentialType Lists

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-27 02:55:19 +00:00
softwarefactory-project-zuul[bot]
9b353c70f3 Merge pull request #8019 from mabashian/7663-workflow-viz-button
Adds visualizer button to workflow template rows on templates list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-27 02:54:03 +00:00
Sean Sullivan
243c2cfe15 Merge pull request #3 from ansible/devel
rebase to devel
2020-08-26 20:53:39 -05:00
beeankha
0f3aefe592 Fix pep8 errors, rebase 2020-08-26 19:51:10 -04:00
John Westcott IV
7afd84dc49 Resolving issue in test_completness 2020-08-26 19:50:04 -04:00
John Westcott IV
1b1a14f220 Fixing linting spacing issue 2020-08-26 19:50:04 -04:00
John Westcott IV
2690fcec31 Adding insights credential to tower_inventory
Fixed a spacing issue in documentation

Enhanced integration test to include a block to ensure cleanup of assets
2020-08-26 19:50:04 -04:00
softwarefactory-project-zuul[bot]
9323156f4c Merge pull request #7983 from beeankha/collections_pylint_fixes
Fix pylint Errors in Collections Modules

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-26 22:31:22 +00:00
mabashian
73d21a01cb Adds visualizer button to workflow template rows on templates list 2020-08-26 17:03:48 -04:00
Rebeccah
9a6f641df0 adding in inventory to unified job query for analytics 2020-08-26 16:32:02 -04:00
beeankha
3ddee3072b Add errors to ignore file, remove noqa directives 2020-08-26 16:09:42 -04:00
softwarefactory-project-zuul[bot]
1514a5ac23 Merge pull request #7963 from john-westcott-iv/tools
Collections Completeness Tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-26 19:34:52 +00:00
softwarefactory-project-zuul[bot]
ccb1e0a748 Merge pull request #8008 from mabashian/8002-plurals
Use low level i18n._ instead of i18n.plural for plurals on the schedule form

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-08-26 18:11:04 +00:00
Ryan Petrello
73baf3fcf9 defer loading Job.artifacts on host views to improve performance
see: https://github.com/ansible/awx/issues/8006

this data can be *really* large, and we don't actually need it for the summary fields on this API endpoint
2020-08-26 13:34:15 -04:00
mabashian
c731e4282b Use low level i18n._ instead of i18n.plural for plurals on the schedule form. This fixes a bug where the page would crash on static builds when a frequency was selected. 2020-08-26 13:18:07 -04:00
softwarefactory-project-zuul[bot]
57949078bb Merge pull request #7945 from beeankha/tower_role_id_fix
Get tower_role Module to Accept IDs for Related Objects

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-26 14:21:32 +00:00
John Westcott IV
2b6e4fe353 Permissions change, spell check, pep8, etc 2020-08-26 10:16:37 -04:00
John Westcott IV
b7b304eb84 Changing how we check modules
Options which are not in the API POST and are marked in the module as deprecated are ignored

If an option is not in the API POST but is marked as a list we assume its a relation
2020-08-26 10:16:37 -04:00
John Westcott IV
8f97109ac7 Fixing PY2 compile issues 2020-08-26 10:16:37 -04:00
John Westcott IV
730a9b25ac Fixing pep8 and other issues 2020-08-26 10:16:37 -04:00
John Westcott IV
a36d942f67 Migrating old test_notification test to test_notification_template 2020-08-26 10:16:37 -04:00
John Westcott IV
b1ffbf1e39 Change module from tower_notification to tower_notification_template 2020-08-26 10:16:37 -04:00
John Westcott IV
f8290f0ce3 Fixing flake8 and adding more module OKs 2020-08-26 10:16:37 -04:00
John Westcott IV
41ca20dc99 Changing scm_credential to credential to match API 2020-08-26 10:16:37 -04:00
John Westcott IV
3b6152a380 Changing job_timeout to an aliase of timeout to match the API 2020-08-26 10:16:37 -04:00
John Westcott IV
1ad4c4ab86 Fixing pep8 issues 2020-08-26 10:16:37 -04:00
John Westcott IV
9353e94629 Spell checking 2020-08-26 10:16:37 -04:00
John Westcott IV
85a1233764 Adding read-only endpoint check, fixing typo, adding needs_development check 2020-08-26 10:16:37 -04:00
John Westcott IV
c2cdd8e403 Initial commit of test_completeness 2020-08-26 10:16:37 -04:00
softwarefactory-project-zuul[bot]
96e1920d36 Merge pull request #7988 from nixocio/add_more_styles_delete_button
Update styles to delete button to be secondary 

Reviewed-by: Michael Abashian
             https://github.com/mabashian
2020-08-26 14:02:46 +00:00
tp48cf
d9e09f482d allow skipping provision instance and register queue 2020-08-26 15:56:01 +02:00
sean-m-sullivan
bed3a9ee41 added id lookup 2020-08-26 08:11:51 -05:00
Benoit Bayszczak
7c8e5ace52 fix tests 2020-08-26 11:14:04 +02:00
softwarefactory-project-zuul[bot]
b8a04f05d1 Merge pull request #7992 from AlexSCorey/RemovesColonOnListItem
Removes colon from survey list item

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-26 00:48:50 +00:00
softwarefactory-project-zuul[bot]
2b18eee92a Merge pull request #7969 from nixocio/ui_add_isolate_job_label
Add label to identify isolated instance group JobDetail screen

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-26 00:48:43 +00:00
mabashian
8fac722b10 Fixes bug where users were unable to turn webhooks off when editing job templates/workflow job templates 2020-08-25 16:02:55 -04:00
beeankha
4bc1a128ec Add noqa directive for super calls 2020-08-25 15:49:20 -04:00
beeankha
da732a3941 Add unit test, update lookup method to favor ID over name 2020-08-25 14:57:02 -04:00
Alex Corey
c0a2a69835 removes colon from suvery list item 2020-08-25 13:32:57 -04:00
softwarefactory-project-zuul[bot]
48f00587f8 Merge pull request #7990 from ryanpetrello/build-needs-facts
gather facts for image builds so we can detect arch

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2020-08-25 16:12:12 +00:00
Benoit Bayszczak
00fc5f6b93 hashivault_kv auth_path moved from metadata to inputs
The auth_path is used with the approle auth method
It's not linked to the secret we are reading but to the auth method,
this parameter has to be moved to inputs
2020-08-25 18:01:09 +02:00
Ryan Petrello
04229ba14b gather facts for image builds so we can detect arch
related: https://github.com/ansible/awx/pull/7607/
2020-08-25 11:36:26 -04:00
Benoit Bayszczak
d49a61b63e add missing creds types to tower_credential module
Add the following native credentials types to the tower_credential module
 - 'satellite': 'Red Hat Satellite 6' # renaming of satellite6
 - 'aim': 'CyberArk AIM Central Credential Provider Lookup'
 - 'conjur': 'CyberArk Conjur Secret Lookup'
 - 'hashivault_kv': 'HashiCorp Vault Secret Lookup'
 - 'hashivault_ssh': 'HashiCorp Vault Signed SSH'
 - 'azure_kv': 'Microsoft Azure Key Vault'
 - 'kubernetes_bearer_token': 'OpenShift or Kubernetes API Bearer Token'
 - 'github_token': 'GitHub Personal Access Token'
 - 'gitlab_token': 'GitLab Personal Access Token'
2020-08-25 17:24:17 +02:00
softwarefactory-project-zuul[bot]
e8cc4cee52 Merge pull request #7985 from ryanpetrello/release-14.1.0
Bump version to 14.1.0

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2020-08-25 14:57:57 +00:00
softwarefactory-project-zuul[bot]
5507f264e3 Merge pull request #7919 from marshmalien/7806-smart-inv-detail
Add smart inventory host detail view

Reviewed-by: Daniel Sami
             https://github.com/dsesami
2020-08-25 14:47:04 +00:00
nixocio
6794f331c3 Update styles to delete button to be secondary
Update styles to delete button to be secondary.

See: https://github.com/ansible/awx/issues/7041
Also: https://github.com/ansible/awx/issues/7984
2020-08-25 10:39:28 -04:00
softwarefactory-project-zuul[bot]
3236f50fe7 Merge pull request #7950 from ryanpetrello/fix-channels-memory-leak
work around a memory leak in channels_redis

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-25 14:26:47 +00:00
softwarefactory-project-zuul[bot]
d0e0dbea24 Merge pull request #7986 from kldavis52/api_status_405_error
Api status 405 error message update, address issue#5744

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-25 14:00:24 +00:00
Ryan Petrello
e0acf73ac6 add a changelog note about the channels_redis memory leak 2020-08-25 09:58:04 -04:00
Ryan Petrello
e25da217e8 work around a memory leak in channels_redis
see: https://github.com/django/channels_redis/issues/212
see: https://github.com/django/channels_redis/pull/219/
2020-08-25 09:58:03 -04:00
Ryan Petrello
04188aa2d6 Bump version to 14.1.0 2020-08-25 09:45:05 -04:00
softwarefactory-project-zuul[bot]
35efbb043d Merge pull request #7966 from ryanpetrello/vanishing-instance
improve job reaping for jobs that were started on a missing Instance

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-25 13:36:35 +00:00
Ryan Petrello
64da67fa2e mprove error message when changing an inventory from regular -> smart
see: https://github.com/ansible/awx/issues/5744
Co-Authored-By: kldavis52 <kyle.linnard.davis@gmail.com>
2020-08-25 09:25:54 -04:00
sean-m-sullivan
13f3292af0 updated test 2020-08-25 07:04:27 -05:00
nixocio
de130eb798 Add advanced search keys for InstanceGroup and CredentialType Lists
Add advanced search keys for `InstanceGroup` and `CredentialType` Lists.

See: https://github.com/ansible/awx/pull/7895/files
2020-08-24 21:27:44 -04:00
Marliana Lara
febfb985a4 Add smart inventory host detail view
* Remove host toggle from smart inv host list
2020-08-24 17:19:22 -04:00
beeankha
75a0c0ab1e Prioritize integer names over IDs more effectively 2020-08-24 17:13:22 -04:00
beeankha
54317236f3 Fix pep8 error, remove redundant var assignment 2020-08-24 17:13:22 -04:00
John Westcott IV
0fd618d88b Changing test suite and fixing user issue in tower_api 2020-08-24 17:13:21 -04:00
beeankha
e9d66df77a Initial commit for tower_role name vs id lookup bug fix 2020-08-24 17:13:21 -04:00
beeankha
ef7a74c4a3 Initial commit of pylint fixes 2020-08-24 16:47:16 -04:00
softwarefactory-project-zuul[bot]
5248ac4498 Merge pull request #7921 from mabashian/6172-schedule-detail-vars
Adds extra variables to schedule details

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-24 20:45:32 +00:00
softwarefactory-project-zuul[bot]
1a033653ae Merge pull request #7978 from jakemcdermott/fix-7977
Don't display facts until facts are loaded

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-24 19:33:26 +00:00
softwarefactory-project-zuul[bot]
45f7e4a663 Merge pull request #7911 from AmadeusITGroup/archive_url_scm_type
Add Remote Archive SCM Type to support using artifacts and releases as projects

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-24 17:16:12 +00:00
Jake McDermott
0af9e01610 Don't display facts until facts are loaded 2020-08-24 12:55:32 -04:00
softwarefactory-project-zuul[bot]
6ef27e5458 Merge pull request #7962 from hit0ri/fix-broadcast-websocket-secret-length
Fix broadcast_websocket_secret length

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-24 16:11:13 +00:00
Alex Corey
90e8d5697e Adds fix to load template details screen even for users without webhook key permissions 2020-08-24 11:39:29 -04:00
nixocio
447bde95e3 Add label to identify isolated instance group JobDetail screen
Add label to identify isolated instance group JobDetail screen as per
mock up.

See: https://tower-mockups.testing.ansible.com/patternfly/jobs/jobs-detail/
2020-08-23 14:58:06 -04:00
Sean Sullivan
cda05c4f03 Updated test for lint
Updated test for lint
2020-08-22 20:16:27 -05:00
sean-m-sullivan
3794f095cf update to tower_project_update 2020-08-22 13:43:14 -05:00
Philip Douglass
6dc41f54fc Ensure scm credentials are passed for archive scm type 2020-08-22 11:16:04 -04:00
Ryan Petrello
de59d1d3f6 improve job reaping for jobs that were started on a missing Instance
see: https://github.com/ansible/awx/issues/7848
2020-08-21 16:32:17 -04:00
softwarefactory-project-zuul[bot]
2a824fc1d5 Merge pull request #7964 from nixocio/ui_update_button
Update disassociate button variant

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-21 19:36:43 +00:00
nixocio
17a40808b4 Update disassociate button variant
Update disassociate button variant.

See: https://github.com/ansible/awx/issues/7041

Also: https://tower-mockups.testing.ansible.com/patternfly/instance-groups/instance-groups-instances/
2020-08-21 14:46:15 -04:00
softwarefactory-project-zuul[bot]
fb381c18da Merge pull request #7961 from mabashian/fix-audit-warnings
Fix npm audit warnings

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-21 18:14:47 +00:00
Philip Douglass
30ae0f53ec Reject setting scm_branch for Remote Archive projects 2020-08-21 13:09:09 -04:00
Philip Douglass
2d23748971 Add Remote Archive SCM Type feature to CHANGELOG.md
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-21 12:53:51 -04:00
softwarefactory-project-zuul[bot]
3c39067d7d Merge pull request #7958 from shanemcd/fix-container-groups
Fix container groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-21 13:59:27 +00:00
Taras Dyshkant
e4095a0c27 Fix broadcast_websocket_secret length
Password lookup parameters must be within the same set of quotes.
Otherwise a default value of length is used (20).
2020-08-21 16:43:07 +03:00
mabashian
80fe98b8d6 Fix npm audit warnings 2020-08-21 09:20:29 -04:00
Shane McDonald
8ae328e427 Switch back to built-in kubectl connection plugin
There's a bug in the upstream community.kubernetes plugin. We can open up a
follow-up PR once that has been patched.
2020-08-20 21:42:07 -04:00
softwarefactory-project-zuul[bot]
51029a8b7a Merge pull request #7910 from nixocio/ui_issue_5684
Add type column to users list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 21:13:00 +00:00
softwarefactory-project-zuul[bot]
5458411b19 Merge pull request #7803 from mabashian/6425-approval-notif
Adds support for toggling approval notifications on orgs and wfjts

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 20:23:50 +00:00
softwarefactory-project-zuul[bot]
bfe00d46ad Merge pull request #7903 from jlmitch5/searchableKeysPt3
update newly useRequested lists to get advanced searchableKeys

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 19:59:54 +00:00
softwarefactory-project-zuul[bot]
b92fab2048 Merge pull request #7866 from nixocio/ui_add_isolated_instance_groups_marker
Add label to show isolated group 

Reviewed-by: Kersom
             https://github.com/nixocio
2020-08-20 18:32:52 +00:00
mabashian
222a65c875 Adds extra variables to schedule details. Updates parameters by which we display prompt fields on schedule details. Extend VariableDetails component to be able to handle values that come in raw JSON form. 2020-08-20 14:29:24 -04:00
mabashian
daeb5a8de8 Only disable single notification row when toggling, not all rows 2020-08-20 14:24:05 -04:00
nixocio
6ed65a9c81 Add label to show isolated group
Add label to show isolated group.

See: https://tower-mockups.testing.ansible.com/patternfly/instance-groups/instance-groups/
2020-08-20 13:59:56 -04:00
Philip Douglass
d259500332 Implement Remote Archive SCM Type for ui_next
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 13:52:31 -04:00
Philip Douglass
70cbccd2ef Add migration for new Remote Archive SCM Type 2020-08-20 13:38:10 -04:00
Philip DOUGLASS
f72b777b07 Add plugin to cleanly manage possibly versioned project archives
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 13:38:10 -04:00
Philip Douglass
6720cd9bda Add block to download and unpack a remote archive
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 13:38:10 -04:00
Philip Douglass
b011e34fae Show fields for archive when selected as scm_type
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 13:38:10 -04:00
mabashian
681b765b9a Adds support for toggling approval notifications on orgs and wfjts 2020-08-20 13:36:32 -04:00
John Mitchell
d03448aa9d add searchable keys support for AssociateModal and SelectResourceStep lists 2020-08-20 12:53:35 -04:00
John Mitchell
aee2a81b27 update newly useRequested lists to get advanced searchableKeys 2020-08-20 12:53:35 -04:00
nixocio
8402cf97de Add type column to users list
Add type column to users list. Also, update `UserListItem` to be a
functional component.

See: https://github.com/ansible/awx/issues/5684
2020-08-20 12:50:13 -04:00
Philip Douglass
8157ab2fa9 Hide scm_branch field when scm_type is archive
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 12:34:35 -04:00
Philip Douglass
2f3f6e60d1 Add archive to scm_type expected test results
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 12:34:35 -04:00
Philip Douglass
d224aa09f0 Add archive to TestProjectUpdateCredentials test parametrize
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 12:34:35 -04:00
Philip Douglass
997351eee3 Add archive project data to Dashboard view
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 12:34:35 -04:00
Philip Douglass
47cabc4229 Add archive SCM url handling to update_scm_url()
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 12:34:35 -04:00
Philip Douglass
2cfa4eb60a Add archive option to SCM_TYPE_CHOICES for Remote Archives
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-08-20 12:34:35 -04:00
softwarefactory-project-zuul[bot]
a659b9d994 Merge pull request #7851 from mabashian/5910-workflow-prompt
Support workflow prompting on launch

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-08-20 16:30:29 +00:00
softwarefactory-project-zuul[bot]
780b2be8bf Merge pull request #7943 from mabashian/7660-workflow-details
Adds workflow detail tab to workflow results

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-08-20 16:30:23 +00:00
softwarefactory-project-zuul[bot]
a2a8c47166 Merge pull request #7864 from nixocio/ui_issue_7767
Add feature to edit instance group

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-08-20 16:30:16 +00:00
softwarefactory-project-zuul[bot]
6fcd017d48 Merge pull request #7951 from nixocio/ui_issue_7930
Add list of jobs for instance groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 16:22:35 +00:00
softwarefactory-project-zuul[bot]
bd093b8999 Merge pull request #7947 from nixocio/ui_instance_group_update_css_red
Use a patternfly CSS variable instead of red

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 16:22:29 +00:00
softwarefactory-project-zuul[bot]
cae45cec21 Merge pull request #7949 from ryanpetrello/even-more-changelog
more changelog updates

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 15:59:25 +00:00
nixocio
70295c3e75 Add list of jobs for instance groups
Add list of jobs for instance groups.

See: https://github.com/ansible/awx/issues/7930
2020-08-20 11:40:04 -04:00
Sean Sullivan
d6815e5114 Removed reference to sync
Updated references to sync in favour of update.
2020-08-20 10:30:43 -05:00
Ryan Petrello
0266ed3836 more changelog updates 2020-08-20 10:44:06 -04:00
softwarefactory-project-zuul[bot]
9ff4712844 Merge pull request #7948 from ryanpetrello/arm-changelog
changelog for arm64 builds

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 14:34:33 +00:00
Ryan Petrello
821cfba88a changelog for arm64 builds 2020-08-20 10:05:27 -04:00
nixocio
efa12b12ec Use a patternfly CSS variable instead of red
Use a patternfly CSS variable instead of red.

See: https://pf4.patternfly.org/documentation/overview/global-css-variables
2020-08-20 09:53:39 -04:00
softwarefactory-project-zuul[bot]
070c7e611c Merge pull request #7936 from AlexSCorey/FixesCredentialLookupNotfetchingdata
Adds fix to allow look up to fetch data

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-20 13:42:25 +00:00
softwarefactory-project-zuul[bot]
5d208cc14e Merge pull request #7607 from agaffney/arm_image_build
ARM image build support

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-19 22:07:32 +00:00
softwarefactory-project-zuul[bot]
e22d32c96b Merge pull request #7705 from anxstj/custom_environments
Change Dockerfile to copy custom venv

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-19 21:55:01 +00:00
softwarefactory-project-zuul[bot]
cf116d18b4 Merge pull request #7799 from john-westcott-iv/import-export-collecion-modules
Adding import/export modules around AWX Kit features

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-19 20:51:05 +00:00
softwarefactory-project-zuul[bot]
a3eff133fe Merge pull request #7942 from ryanpetrello/iso-removal
fix a bug that prevents the explicit removal of instances from groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-19 19:16:20 +00:00
John Westcott IV
a5afe0214a Trying to make AWXKIT tests not run on python2 2020-08-19 14:29:42 -04:00
John Westcott IV
b93319e359 Updating to remove auth_type since its not longer required 2020-08-19 14:27:02 -04:00
John Westcott IV
2c8c1ff595 Fixing sanity error 2020-08-19 14:14:49 -04:00
John Westcott IV
3abd77c4c0 Fixing oauth token login and making module respect token over username/password 2020-08-19 14:12:50 -04:00
John Westcott IV
a2eab45d61 Trying to gobble up logs incase there are errors 2020-08-19 14:12:50 -04:00
beeankha
76f08744f6 Fix linter whitespace error 2020-08-19 14:12:50 -04:00
John Westcott IV
01e08ba0e1 Fixing exit_module -> exit_json 2020-08-19 14:12:50 -04:00
John Westcott IV
c2e0c0655b Fixing validate-module errors 2020-08-19 14:12:50 -04:00
John Westcott IV
8688740e93 Fixing ansible pep8 issues 2020-08-19 14:12:50 -04:00
John Westcott IV
3fe61cfa4f Fixing linting issues 2020-08-19 14:12:50 -04:00
John Westcott IV
5107f164a2 Expanding examples 2020-08-19 14:12:50 -04:00
John Westcott IV
9bf19daa5e Another linting issue 2020-08-19 14:12:50 -04:00
John Westcott IV
f2b9bdd552 Removed default: '' and updated [] to '' per specification 2020-08-19 14:12:50 -04:00
John Westcott IV
8a0cd747e1 Fixing truthy linting issues 2020-08-19 14:12:50 -04:00
John Westcott IV
748bdbd2dd Fix python3 Zuul error with awxkit 2020-08-19 14:12:50 -04:00
John Westcott IV
08e5dd87e6 Adding integration tests and example in import 2020-08-19 14:12:50 -04:00
John Westcott IV
40f6741474 Adding import/export awx kit features
Changed library structure

Origional TowerModule becomes TowerLegacyModule

TowerModule from tower_api becomes TowerAPIModule

A real base TowerModule is created in tower_module.py

A new TowerAWXKitModule is created in tower_awxkit

TowerAWXKitModule and TowerAPIModule are child classes of TowerModule
2020-08-19 14:12:50 -04:00
mabashian
c0cb1dee91 Adds workflow detail tab to workflow results 2020-08-19 13:55:42 -04:00
Alex Corey
7bff11379c Update awx/ui_next/src/components/Lookup/CredentialLookup.jsx
Co-authored-by: Jake McDermott <yo@jakemcdermott.me>
2020-08-19 13:32:48 -04:00
Ryan Petrello
b14515b287 fix a bug that prevents the explicit removal of instances from groups 2020-08-19 13:22:31 -04:00
softwarefactory-project-zuul[bot]
383f8aa8f9 Merge pull request #7937 from ryanpetrello/only-bearer
clean up old authtoken support

Reviewed-by: John Westcott IV
             https://github.com/john-westcott-iv
2020-08-19 17:10:51 +00:00
softwarefactory-project-zuul[bot]
9d2498cf6b Merge pull request #7934 from ryanpetrello/deprecate-mercurial
add a deprecation warning for mercurial project syncs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-19 16:32:32 +00:00
Ryan Petrello
815d691622 clean up old authtoken support
just use Bearer tokens - those are the only type of tokens we support
2020-08-19 12:23:00 -04:00
Alex Corey
8a2bf8c1fc adds fix to allow look up to fetch data 2020-08-19 12:18:04 -04:00
softwarefactory-project-zuul[bot]
fb66766463 Merge pull request #7933 from jakemcdermott/fix-7756
Use organization api to create users

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-19 15:36:27 +00:00
Ryan Petrello
612bb81976 add a deprecation warning for mercurial project syncs
see: https://github.com/ansible/awx/issues/7932
2020-08-19 11:19:03 -04:00
Jake McDermott
dc9f2441df Embolden user organization name 2020-08-19 11:02:22 -04:00
Jake McDermott
806a468600 Use organization api to create users
This ensures that the user will be related to the chosen organization
when it is created.
2020-08-19 11:02:11 -04:00
softwarefactory-project-zuul[bot]
d452c1d7a9 Merge pull request #7918 from ryanpetrello/surro-get-outta-here
make event stdout encoding more resilient to UTF-16 surrogate pairs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-18 14:48:11 +00:00
Ryan Petrello
33e2c059ed make event stdout encoding more resilient to UTF-16 surrogate pairs
see: https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates
2020-08-18 10:23:20 -04:00
softwarefactory-project-zuul[bot]
e7281a753f Merge pull request #7922 from shanemcd/pin-xdist
Fix API tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-18 12:52:45 +00:00
Shane McDonald
54e87378d5 Pin pytest-xdist 2020-08-17 20:43:02 -04:00
mabashian
1e9a71a2e4 Run prettier 2020-08-13 11:55:57 -04:00
mabashian
98b7f3b618 Support workflow prompting on launch 2020-08-13 11:36:58 -04:00
softwarefactory-project-zuul[bot]
54f8742747 Merge pull request #7070 from JoelKle/fix_rerun_ability
Installer - local_docker - fixed the ability to rerun the playbook

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-13 14:12:08 +00:00
softwarefactory-project-zuul[bot]
06efba6f72 Merge pull request #7800 from AlexSCorey/7789-UserTokenDetails
Adds User Token Details page

Reviewed-by: Daniel Sami
             https://github.com/dsesami
2020-08-12 21:00:38 +00:00
Alex Corey
15fda43a10 Utilizes UserDateDetail, Capitalizes Scope value, fixes spelling errors 2020-08-12 16:34:59 -04:00
Alex Corey
19d6a3f65e Adds User Token Details page 2020-08-12 16:33:32 -04:00
softwarefactory-project-zuul[bot]
f86697536c Merge pull request #7807 from marshmalien/7683-smart-inv-hosts
Add smart inventory host list view

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-12 18:41:51 +00:00
softwarefactory-project-zuul[bot]
d17266fae0 Merge pull request #7895 from jlmitch5/searchOptionsRequestsPass2
update existing relatedSearchKey requests to new convention and fix U…

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-12 17:19:17 +00:00
John Mitchell
dd68b6ed73 update existing relatedSearchKey requests to new convention and fix UJT searchKeys 2020-08-12 12:21:10 -04:00
Marliana Lara
214cb76e1e Add custom host toggle tooltip for smart inventory hosts 2020-08-12 10:40:59 -04:00
softwarefactory-project-zuul[bot]
9c13c07169 Merge pull request #7894 from ansible/chrismeyersfsu-patch-2
Update websockets.md

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-12 14:23:33 +00:00
softwarefactory-project-zuul[bot]
1d5bdedc9b Merge pull request #7893 from AlanCoding/awx_awx_141
Add changelog preparing for awx.awx 14.1.0 bug fix

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-12 14:16:31 +00:00
softwarefactory-project-zuul[bot]
019ad9da73 Merge pull request #7880 from jlmitch5/kebabifyAdvancedSearch
kebabify additional controls when advanced search is displayed

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-12 13:53:52 +00:00
Chris Meyers
5dd2cb10b4 Update websockets.md 2020-08-12 09:52:10 -04:00
Chris Meyers
aa8d3d5ae4 Update websockets.md
Add more details about backplane websocket functionality.
2020-08-12 09:49:24 -04:00
Alan Rominger
dfad5117fa Add changelog preparing for awx.awx 14.1.0 bug fix 2020-08-12 09:47:52 -04:00
John Mitchell
54d13b6397 remove unnecessary selectors from kebabification test 2020-08-12 09:26:46 -04:00
John Mitchell
1323626d5e add onShowAdvancedSearch callback test 2020-08-12 09:26:46 -04:00
John Mitchell
a352de3da7 change name of hook to be useKebabifiedMenu 2020-08-12 09:26:46 -04:00
John Mitchell
8f04026404 kebabify additional controls when advanced search is displayed 2020-08-12 09:26:46 -04:00
softwarefactory-project-zuul[bot]
0adb9cfd45 Merge pull request #7888 from nixocio/ui_remove_undefined_prop
Remove undefined prop from SelectedList call

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-12 13:14:26 +00:00
nixocio
aace8f5032 Remove undefined prop from SelectedList call
Remove undefined prop from `SelectedList` call.
2020-08-11 16:44:03 -04:00
Marliana Lara
8a4d45ddb6 Add smart inventory host list view 2020-08-11 14:48:39 -04:00
softwarefactory-project-zuul[bot]
025a979cb2 Merge pull request #7867 from keithjgrant/5651-notification-templates
Notification templates list & details

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-11 18:10:35 +00:00
Keith Grant
d27d4e4f28 workaround import/dependency bug in tests 2020-08-11 10:36:42 -07:00
softwarefactory-project-zuul[bot]
1dfc9d224c Merge pull request #7875 from ryanpetrello/more-changes
changelog updates for recent additions

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-11 17:24:32 +00:00
Ryan Petrello
5fb1b1ceea changelog updates for recent additions 2020-08-11 12:52:52 -04:00
Keith Grant
65d4c347c9 add ObjectDetails for HTTP Headers display 2020-08-11 09:36:11 -07:00
Keith Grant
4c555815b3 add notification list tests 2020-08-11 09:36:11 -07:00
Keith Grant
8bb1c985c0 send test notifications 2020-08-11 09:36:11 -07:00
Keith Grant
1405f6ca51 add notification status indicator 2020-08-11 09:36:10 -07:00
Keith Grant
a9451c9864 more template details; add template delete button 2020-08-11 09:36:10 -07:00
Keith Grant
ab4628b199 flush out template detail 2020-08-11 09:36:10 -07:00
Keith Grant
182dce3dc3 flushing out notification template detail 2020-08-11 09:36:10 -07:00
Keith Grant
fbd1147cff start notification template list 2020-08-11 09:36:10 -07:00
softwarefactory-project-zuul[bot]
0e730311bb Merge pull request #7871 from ryanpetrello/upgrade-ldap
update to a newer python-ldap to address a bug

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-11 16:29:30 +00:00
softwarefactory-project-zuul[bot]
9d4c05b15e Merge pull request #7872 from AlanCoding/devel_version
Fix awx.awx version replacement regex

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-11 15:47:16 +00:00
sean-m-sullivan
69dc0a892f fix lint 2020-08-11 09:56:08 -05:00
sean-m-sullivan
813e38636a fix documentation 2020-08-11 09:38:18 -05:00
nixocio
e3fe680d14 Add feature to edit instance group
Add feature to edit instance group.

See: https://github.com/ansible/awx/issues/7767
2020-08-11 10:37:08 -04:00
softwarefactory-project-zuul[bot]
3ca43e63b5 Merge pull request #7808 from zedr/feat-yaml-import
Allow YAML as a CLI import format

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-11 14:31:01 +00:00
sean-m-sullivan
262b2bf8ff Merge branch 'project_update' of github.com:sean-m-sullivan/awx into project_update 2020-08-11 09:28:31 -05:00
sean-m-sullivan
af1fc5a9e9 add tests 2020-08-11 09:28:17 -05:00
Alan Rominger
2a0c61de63 Change regex to match what is in source 2020-08-11 10:04:14 -04:00
Sean Sullivan
8af315cf29 Create tower_project_update
Add module to update tower project and wait until synced.
2020-08-11 08:54:10 -05:00
Ryan Petrello
987c7d48a0 minor cleanup up CLI import -f yaml support 2020-08-11 09:44:13 -04:00
Ryan Petrello
5e9d372db2 update to a newer python-ldap to address a bug
see: https://github.com/ansible/awx/issues/7868
2020-08-11 09:34:04 -04:00
Sean Sullivan
7089c5f06e Merge pull request #2 from ansible/devel
Rebase
2020-08-11 07:56:11 -05:00
Rigel Di Scala
579604d2c6 Allow YAML as a CLI import format
This changset allows the import of YAML formatted resources. The CLI
user can indicate which format to use with the `-f, --format` option.
The CLI help text has been amended to reflect the new feature.

The AWX CLI `export` subcommand offers the option of formatting the output
as YAML or JSON, so it makes sense that the `import` subcommand reflects
this.

A simple test is also provided. In order to ease the task of testing
commands that import resources by reading the stdin, the CLI has been
extended to allow specifying an alternative file descriptor for stdin,
similarly to stdout and stderr.
2020-08-10 23:43:53 +02:00
softwarefactory-project-zuul[bot]
ddb6c5d0cc Merge pull request #7644 from marshmalien/smart-inventory-forms
Add smart inventory add/edit forms and host filter lookup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-10 19:08:36 +00:00
softwarefactory-project-zuul[bot]
9bd6a323aa Merge pull request #7860 from AlanCoding/upgrade_gitpython
Upgrade gitpython to pick up bug fix

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-10 19:07:26 +00:00
Alan Rominger
8aacd006e0 Revert updater changes to Ansible requirements 2020-08-10 14:29:07 -04:00
Alan Rominger
f269d5b2ed Upgrade gitpython to pick up bug fix 2020-08-10 14:29:05 -04:00
Marliana Lara
af218aaa0b Decode host filter chip values and fix boolean search filter chip bug 2020-08-10 14:19:55 -04:00
Marliana Lara
8e6d475a9d Add smart inventory edit form 2020-08-10 14:09:01 -04:00
Marliana Lara
6a304dce55 Add smart inventory add form and host filter lookup 2020-08-10 14:09:01 -04:00
Marliana Lara
5864d61b5b Refactor organization look to use useRequest hook 2020-08-10 14:08:57 -04:00
softwarefactory-project-zuul[bot]
fbb9998b68 Merge pull request #7776 from nixocio/ui_add_instance_group
Add feature to add instance group

Reviewed-by: Kersom
             https://github.com/nixocio
2020-08-10 17:35:01 +00:00
softwarefactory-project-zuul[bot]
c6317c0113 Merge pull request #7861 from ansible/chrismeyersfsu-patch-1
Update websockets.md

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-10 17:33:54 +00:00
softwarefactory-project-zuul[bot]
d48cc1ab43 Merge pull request #7847 from zedr/feat-workflow-labels
Export Workflow Job Template Node Labels

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-10 17:27:21 +00:00
softwarefactory-project-zuul[bot]
ccdb2b4ca3 Merge pull request #7856 from zedr/fix-related-import-return
Fix early return in assign related method

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-10 17:26:05 +00:00
nixocio
897c8b74a5 Add feature to add instance group
Add feature to add instance group.

See: https://github.com/ansible/awx/issues/7744
2020-08-10 13:06:56 -04:00
Chris Meyers
fdc53bd0d3 Update websockets.md
spelling
2020-08-10 12:58:49 -04:00
Chris Meyers
1cf48ffc9e Update websockets.md
Add documentation for websocket backplane secret key exchange logic.
2020-08-10 12:58:49 -04:00
Rigel Di Scala
0beff054af Export Workflow Job Template Node Labels
This change adds related Labels to the Workflow Job Template document that is
exported by the AWX CLI.

Previously, exporting and then importing Workflow Job Templates would
not retain their related Labels.
2020-08-10 12:56:52 -04:00
Rigel Di Scala
eeebd517d1 Fix early return in assign related method
This change fixes an erroneus early return in a private method that was
preventing more than one type of related object from being correctly
assigned to the parent object, and therefore imported.

Also, a minor spelling mistake was corrected.
2020-08-10 12:54:23 -04:00
softwarefactory-project-zuul[bot]
395b338221 Merge pull request #7863 from ryanpetrello/fix-tox
fix busted flake8 CI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-10 16:53:08 +00:00
Ryan Petrello
32542021c6 fix busted flake8 CI 2020-08-10 12:26:12 -04:00
softwarefactory-project-zuul[bot]
52bb71b63e Merge pull request #7840 from beeankha/credential_input_idempotency
Make 'inputs' Unchanged When Blank in Credentials Module

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
             https://github.com/beeankha
2020-08-06 18:04:15 +00:00
softwarefactory-project-zuul[bot]
91df10dbb5 Merge pull request #7739 from jlmitch5/advSearch
Advanced search

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-06 17:57:24 +00:00
John Mitchell
61ce8cb029 delete inadverdently added back InventoryScriptLookup file 2020-08-06 13:21:00 -04:00
John Mitchell
cbea77a90c update rest of lookups to use correct searchableKeys props 2020-08-06 13:21:00 -04:00
John Mitchell
f8bd8abc82 make name default searchColumn for ProjectJobTemplatesList. also add helpful error message to tell you this is the issue 2020-08-06 13:21:00 -04:00
John Mitchell
f24654fb26 update searchablekeys prop names for project lookup 2020-08-06 13:21:00 -04:00
John Mitchell
495b4142c7 make sortColumnKey error message more clear 2020-08-06 13:21:00 -04:00
John Mitchell
f15325aebf add back in searchable keys props to user token list 2020-08-06 13:21:00 -04:00
John Mitchell
5b362ef162 add selectors for cypress tests 2020-08-06 13:21:00 -04:00
John Mitchell
0876b944ed fix AddRersourceRole sort column 2020-08-06 13:21:00 -04:00
John Mitchell
ede1260675 fix merge conflicts and failing test 2020-08-06 13:21:00 -04:00
John Mitchell
36585ad74e Move Search to hooks and excise PF Dropdown in favor of Select 2020-08-06 13:21:00 -04:00
John Mitchell
dc2bf503d1 Add AdvancedSearch propTypes and defaultProps 2020-08-06 13:21:00 -04:00
John Mitchell
2229d43e8b fix duplicate variable and key usng array index issues 2020-08-06 13:21:00 -04:00
John Mitchell
5ffc2e4188 Updates to support advanced search changes:
- make set type and lookup prefixes/suffixes on searchColumns explicitly defined
- send possible search keys from options requests on (most) lists
2020-08-06 13:21:00 -04:00
John Mitchell
b46a87209a Add advanced search to UI 2020-08-06 12:17:49 -04:00
softwarefactory-project-zuul[bot]
c7dd0bc2b9 Merge pull request #7842 from nixocio/ui_remove_not_defined_props
Remove showExpandCollapse prop from the DataListToolbar calls

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-06 16:16:00 +00:00
softwarefactory-project-zuul[bot]
0b38a8be7e Merge pull request #7747 from marshmalien/add-settings-framework
Add settings navigation skeleton

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-06 16:14:33 +00:00
softwarefactory-project-zuul[bot]
6d9aed35d7 Merge pull request #7810 from mabashian/7564-access-add-btn
Fix rbac on Add button on User Access/Team Roles lists

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-06 16:10:55 +00:00
softwarefactory-project-zuul[bot]
16ce7b4647 Merge pull request #7821 from mabashian/7814-form-error
Handle form submission errors that may be deeply nested in the return object

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-06 16:09:29 +00:00
softwarefactory-project-zuul[bot]
d58a66d587 Merge pull request #7838 from ryanpetrello/bump-14-0-0
Bump version to 14.0.0

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-06 15:45:35 +00:00
nixocio
03274db695 Remove showExpandCollapse prop from the DataListToolbar calls
Remove showExpandCollapse prop from the DataListToolbar calls. This is
not an expected prop to be passed to this component.

Inside DataListToolbar.

```
  const showExpandCollapse = onCompact && onExpand;
```

In order to use this feature, `onCompact` and `onExpand` props should
be passed.

...
2020-08-06 10:58:20 -04:00
softwarefactory-project-zuul[bot]
2c5d3ff64a Merge pull request #7477 from AlanCoding/ee_req
Add execution environment metadata to AWX collection

Reviewed-by: Alan Rominger <arominge@redhat.com>
             https://github.com/AlanCoding
2020-08-06 14:24:39 +00:00
AlanCoding
f953e6ab55 Add execution environment metadata to AWX collection 2020-08-05 22:46:23 -04:00
beeankha
dcc500e7bb Make 'inputs' idempotent in credentials module, add test to check this works 2020-08-05 16:44:22 -04:00
Ryan Petrello
99e417d748 Bump version to 14.0.0 2020-08-05 16:22:03 -04:00
softwarefactory-project-zuul[bot]
1c0dc1cccb Merge pull request #7836 from ryanpetrello/downstream-merge
merge in a few downstream fixes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-05 19:42:53 +00:00
Ryan Petrello
6067fc36f6 begin a 14.0.0 changelog 2020-08-05 14:53:01 -04:00
Ryan Petrello
0c6be1f4d7 Merge branch 'downstream' into devel 2020-08-05 14:48:36 -04:00
softwarefactory-project-zuul[bot]
57732d4630 Merge pull request #7824 from shanemcd/fix-isolated-dev-env
Fix isolated dev env

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-04 23:30:56 +00:00
softwarefactory-project-zuul[bot]
3af31df2c9 Merge pull request #7823 from john-westcott-iv/cancel_500_error
Catching runtime error

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2020-08-04 22:25:50 +00:00
Shane McDonald
00ea453ccd Fix isolated dev env 2020-08-04 17:25:57 -04:00
John Westcott IV
27676b0634 Adding RuntimeError which is returned from a connection error in awx/main/dispatch/control.py 2020-08-04 17:17:38 -04:00
mabashian
4a3e4af0d9 Updated import/export names for consistency 2020-08-04 15:29:59 -04:00
mabashian
b145f97e0e Handle form submission errors that may be deeply nested in the return object 2020-08-04 14:30:42 -04:00
softwarefactory-project-zuul[bot]
2a9804e589 Merge pull request #7768 from wenottingham/add-some-nozzles
Create marginally more realistic event data with firehose

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-04 16:02:27 +00:00
softwarefactory-project-zuul[bot]
b990271dec Merge pull request #7811 from ryanpetrello/deprecate-galaxy-basic-auth
mark PRIMARY_GALAXY_USERNAME and PRIMARY_GALAXY_PASSWORD as deprecated

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-04 14:45:58 +00:00
Ryan Petrello
76ba363513 mark PRIMARY_GALAXY_USERNAME and PRIMARY_GALAXY_PASSWORD as deprecated 2020-08-04 10:18:40 -04:00
mabashian
4ce2235f68 Fix rbac on Add button on User Access/Team Roles lists 2020-08-04 08:49:51 -04:00
Bill Nottingham
bd6cac966a Create marginally more realistic event data with firehose 2020-08-03 20:57:10 -04:00
softwarefactory-project-zuul[bot]
15c4ab3a9b Merge pull request #7802 from ryanpetrello/vnnn-minus
remove vNNN from example migration files

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-03 20:09:24 +00:00
Ryan Petrello
820c0782ad remove vNNN from example migration files 2020-08-03 15:30:37 -04:00
softwarefactory-project-zuul[bot]
b11908ed1f Merge pull request #7577 from AlexSCorey/RemovesInventoryScripts
Removes Inventory Script screens, routes, stubs etc.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-03 18:37:25 +00:00
softwarefactory-project-zuul[bot]
e20ea5edba Merge pull request #7724 from AlexSCorey/7434-UserTokensDelete
Adds delete functionality to user tokens list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-03 18:14:28 +00:00
Alex Corey
3d08754be5 Removes Inventory Script screens, routes, stubs etc. 2020-08-03 14:07:44 -04:00
Alex Corey
164d4e6419 Adds delete functionality to user tokens list 2020-08-03 13:46:34 -04:00
softwarefactory-project-zuul[bot]
d5ab54977c Merge pull request #7796 from zedr/fix-py3-yaml-bytes-decoded
Fix garbage being printed when exporting as YAML - related #7795

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-08-03 16:38:16 +00:00
Rigel Di Scala
490746fe8c Fix garbage being printed when exporting as YAML - related #7795
This resolves issue #7795, by passing the `encoding` keyword argument
only when the code is run on a Python 2 interpreter.

related #7795.
2020-08-03 11:57:45 -04:00
softwarefactory-project-zuul[bot]
def79de72b Merge pull request #7785 from mabashian/convert-NotificationList-functional
Converts NotificationList to functional component and now uses useRequest

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 19:29:56 +00:00
softwarefactory-project-zuul[bot]
f2fa28e9dc Merge pull request #7786 from mabashian/convert-OrganizationLookup-useRequest
Updates OrganizationLookup to use useRequest

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 19:29:50 +00:00
Andrew Gaffney
02252f3f97 ARM image build support
* upgrade `chromedriver` for ARM support
* upgrade `pynacl` to fix `libsodium` build issue on ARM
* remove unnecessary i686-specific `libstdc++.so.6` package
* install `kubectl` and `tini` from upstream binaries for ARM support
* use upstream `postgres` and `alpine` docker images for `postgresql` helm chart

Fixes #7051
2020-07-31 14:22:35 -04:00
softwarefactory-project-zuul[bot]
fed02ef14a Merge pull request #7634 from norpol/patch-1
Fix requirements updater.sh "sourcing" snippet

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 17:54:17 +00:00
softwarefactory-project-zuul[bot]
1077e218bd Merge pull request #7782 from ryanpetrello/galaxy-collection-install-29
only support ansible-galaxy collection in 2.9+

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 17:54:10 +00:00
softwarefactory-project-zuul[bot]
76f75f1745 Merge pull request #7787 from squidboylan/collection_test_fix
Fix collection test inventory

Reviewed-by: Alan Rominger <arominge@redhat.com>
             https://github.com/AlanCoding
2020-07-31 17:26:25 +00:00
softwarefactory-project-zuul[bot]
1bb597bba4 Merge pull request #7788 from ryanpetrello/eff-string
fix a typo in an f-string

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 17:22:35 +00:00
Ryan Petrello
a0e5e74cab fix a typo in an f-string 2020-07-31 12:48:45 -04:00
Caleb Boylan
d935e3c5a3 Fix collection test inventory 2020-07-31 09:47:10 -07:00
mabashian
460ce7fcfa Updates OrganizationLookup to use useRequest 2020-07-31 12:01:55 -04:00
softwarefactory-project-zuul[bot]
ec8725d54f Merge pull request #7614 from vjanssens/5626-add-item-count
Add pagination/item count to DataListToolbar

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 14:58:29 +00:00
mabashian
d8af8baae3 Converts NotificationList to functional component and now uses useRequest 2020-07-31 10:49:27 -04:00
softwarefactory-project-zuul[bot]
d36999acc7 Merge pull request #7784 from ryanpetrello/comments
make these issue template sentences comments

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 14:34:06 +00:00
Ryan Petrello
5b8cfa353f make these issue template sentences comments
(because people are filing issues and leaving this text at the top)
2020-07-31 09:58:52 -04:00
softwarefactory-project-zuul[bot]
07e86adbb7 Merge pull request #7750 from Orabig/devel
Allow to use an existing PVC for postgresql install with Helm

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-31 13:53:09 +00:00
Ryan Petrello
1ad623f253 only support ansible-galaxy collection in 2.9+
see: https://github.com/ansible/awx/issues/7769
2020-07-31 09:42:07 -04:00
softwarefactory-project-zuul[bot]
c0a0e16ba0 Merge pull request #7742 from nixocio/ui_rebased_issue_7640
Add details page for instance group

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 20:07:54 +00:00
softwarefactory-project-zuul[bot]
91d3f954cd Merge pull request #7772 from mabashian/convert-ResourceAccessList-functional
Converts ResourceAccessList to functional component

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 18:10:29 +00:00
softwarefactory-project-zuul[bot]
b5f87b1bac Merge pull request #7774 from ryanpetrello/bug-filing-extra
update the bug report and feature templates w/ additional instructions

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 18:03:43 +00:00
Ryan Petrello
173628c709 update the bug report and feature templates w/ additional instructions 2020-07-30 13:24:54 -04:00
softwarefactory-project-zuul[bot]
2cabaf8727 Merge pull request #7732 from AlexSCorey/7728-TeamsUsers
Adds Teams Access List and renames Tabs and files under teams

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 16:09:14 +00:00
softwarefactory-project-zuul[bot]
d38b3afd21 Merge pull request #7764 from fosterseth/add-kubernetes_web_svc_type
Add kubernetes_web_svc_type variable to installer/inventory

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 14:59:39 +00:00
softwarefactory-project-zuul[bot]
162aab7272 Merge pull request #7738 from mabashian/test-console-cleanup
Test console cleanup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 14:20:20 +00:00
mabashian
dcaab9bc8b Converts ResourceAccessList to functional component 2020-07-30 10:10:56 -04:00
softwarefactory-project-zuul[bot]
8f1c071acf Merge pull request #7733 from nixocio/ui_update_delete
Update delete button variant to secondary

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 14:03:36 +00:00
softwarefactory-project-zuul[bot]
efdee6ed1f Merge pull request #7770 from AlanCoding/falsy_inv
Handle not-provided falsy values in tower_inventory_source

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-30 12:24:20 +00:00
AlanCoding
750c22a150 Handle not-provided falsy values in tower_inventory_source 2020-07-29 21:55:20 -04:00
softwarefactory-project-zuul[bot]
b444d10369 Merge pull request #7745 from mabashian/convert-WFJTList-useRequest
Converts WorkflowJobTemplatesList to use useRequest in preparation for advanced search

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-29 23:48:10 +00:00
softwarefactory-project-zuul[bot]
2f81a1d803 Merge pull request #7752 from mabashian/convert-ProjectList-useRequest
Converts ProjectsList to use useRequest in preparation for advanced search

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-29 23:12:51 +00:00
softwarefactory-project-zuul[bot]
902566ccfb Merge pull request #7761 from mabashian/convert-OrganizationTeamList-useRequest
Converts OrganizationTeamList to use useRequest in preparation for advanced search

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-07-29 23:04:23 +00:00
softwarefactory-project-zuul[bot]
dd828cba26 Merge pull request #7754 from mabashian/convert-JobTemplatesList-useRequest
Converts JobTemplatesList to use useRequest in preparation for advanced search

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-07-29 23:04:18 +00:00
softwarefactory-project-zuul[bot]
45809abc6f Merge pull request #7743 from mabashian/convert-UserList-functional
Converts UserList to functional component

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-07-29 22:52:45 +00:00
softwarefactory-project-zuul[bot]
3bcad7be81 Merge pull request #7759 from mabashian/convert-ProjectJobTemplatesList-hooks
Update ProjectJobTemplatesList to use useSelected, useRequest, useDeleteItems hooks

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-07-29 22:50:06 +00:00
softwarefactory-project-zuul[bot]
21a2b1a630 Merge pull request #7755 from mabashian/convert-InventorySourcesList-useRequest
Converts InventorySourcesList to use useRequest in preparation for advanced search

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2020-07-29 22:48:32 +00:00
softwarefactory-project-zuul[bot]
0d75e1540c Merge pull request #7765 from mabashian/convert-InventoryGroupsList-useRequest
Convert InventoryGroupsList to use useRequest and useSelected hooks

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-29 22:48:27 +00:00
softwarefactory-project-zuul[bot]
d43ea41b7f Merge pull request #7748 from jakemcdermott/noportal
Delete portal mode

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-29 20:45:04 +00:00
softwarefactory-project-zuul[bot]
aca1e73d84 Merge pull request #7753 from rooftopcellist/fix_unmarked_strings
Use quotations when marking strings for translation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-29 19:37:05 +00:00
Christian Adams
6e75d25b74 Merge pull request #4492 from rooftopcellist/fix_broken_ui_links
Use quotations when marking strings for translation [3.7.2]
2020-07-29 15:28:18 -04:00
mabashian
ccecd90015 Convert InventoryGroupsList to use useRequest and useSelected hooks 2020-07-29 15:07:06 -04:00
softwarefactory-project-zuul[bot]
5c400b96fe Merge pull request #7762 from gamuniz/add_helpful_dialog_profilesql
Add helpful dialog profilesql

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-29 18:28:15 +00:00
Seth Foster
07160d9719 Add kubernetes_web_svc_type variable to installer/inventory
awx-web-svc is now settable, e.g. ClusterIP or NodePort. Default
is NodePort
2020-07-29 14:18:10 -04:00
Marliana Lara
42158dea59 Hide license route based on install and add useConfig hook 2020-07-29 14:11:49 -04:00
nixocio
a4dd20872c Add details page for instance group
This PR also:

* Modify routing system to add `container_groups` as well.
* Add `DetailBadge` component.
* Add container group files as placeholder.

See: https://github.com/ansible/awx/issues/7640
Also: https://github.com/ansible/awx/issues/7467
2020-07-29 13:27:57 -04:00
Gabe Muniz
0de900a021 fixed for flake8 compliance 2020-07-29 13:13:01 -04:00
mabashian
b35aa1ac83 Converts OrganizationTeamList to use useRequest in preparation for advanced search 2020-07-29 13:12:10 -04:00
Gabe Muniz
9b06fb1e6a added helpful messaging using profile sql 2020-07-29 12:48:01 -04:00
Alex Corey
24acacbcb6 Renames files to match the tabs better. 2020-07-29 12:24:09 -04:00
mabashian
98e44de7a1 Update capitalization to match PF guidelines 2020-07-29 11:45:58 -04:00
mabashian
b11f2f017f Update capitalization to match PF guidelines 2020-07-29 11:44:17 -04:00
mabashian
9d8a177c75 Update capitalization to match PF guidelines 2020-07-29 11:43:28 -04:00
mabashian
7d8963388f Update capitalization to match PF guidelines 2020-07-29 11:41:16 -04:00
mabashian
3e0d0ec62d Update capitalization to match PF guidelines 2020-07-29 11:39:32 -04:00
mabashian
a34953cd6c Update list to use useSelected, useRequest, useDeleteItems hooks 2020-07-29 11:32:08 -04:00
Marliana Lara
c24e169bf6 Add settings framework 2020-07-29 10:58:48 -04:00
mabashian
48b29352d7 Converts InventorySourcesList to use useRequest in preparation for advanced search 2020-07-29 10:08:45 -04:00
mabashian
8addc6bb59 Converts JobTemplatesList to use useRequest in preparation for advanced search 2020-07-29 09:48:54 -04:00
Christian Adams
76b25d8c96 Use quotations when marking strings for translation 2020-07-29 09:42:18 -04:00
mabashian
e343c9698d Converts ProjectsList to use useRequest in preparation for advanced search 2020-07-29 09:09:27 -04:00
mabashian
bc02321689 Adopt useSelected 2020-07-29 08:45:06 -04:00
Benoît Chauvet
e917cffb5f Allow to use an existing PersistanceVolumeClaim for postgresql install with Helm
Signed-off-by: Benoît Chauvet <benoit.chauvet@gmail.com>
2020-07-29 14:11:12 +02:00
Alan Rominger
b4c3da55d2 Merge pull request #4474 from AlanCoding/per_update_cache_37
[3.7] Per update roles and collections cache
2020-07-29 06:58:25 -04:00
Christian Adams
b1481ec6e3 Use quotations when marking strings for translation 2020-07-28 21:23:14 -04:00
Jake McDermott
3b597cd80a Delete portal mode 2020-07-28 20:27:25 -04:00
softwarefactory-project-zuul[bot]
b009b01251 Merge pull request #7707 from nixocio/ui_update_per_mockup
Update wording to equal mock up

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-29 00:06:59 +00:00
mabashian
2409bc5ee3 Converts WorkflowJobTemplatesList to use useRequest in preparation for advanced search 2020-07-28 17:13:56 -04:00
mabashian
f775ed3f77 Converts UserList to functional component 2020-07-28 16:22:51 -04:00
nixocio
d373cbdca9 Update delete button variant to secondary
Update delete button variant to secondary, except in Modals.

see: https://github.com/ansible/awx/issues/7722
2020-07-28 14:05:12 -04:00
AlanCoding
daaa0c8efe Avoid using long name of option not in 2.8 2020-07-28 13:57:31 -04:00
Bill Nottingham
c6eb8cf59b Cache downloaded roles & collections
Populate the cache the first time the job is run for a revision
that needs them, and for future runs for that revision just
copy it into the private directory.

Delete the cache on project deletion.

Invalidate the cache on a new project revision

Also download roles/collections during the sync job

Since we're writing into a per-revision cache, we can do this easily now.

Don't try and install content if there aren't any requirements expecting it

Adjust pathing to the proper location.

Force install if doing a manual sync.

Requirements may be unversioned.

Remove the cache when delete-on-update is set

Integrate content caching with existing task logic

Revert the --force flags

use the update id as metric for role caching

Shift the movement of cache to job folder from rsync task to python

Only install roles and collections if needed

Deal with roles and collections for jobs without sync
Skip local copy if roles or collections turned off

update docs for content caching

Design pivot - use empty cache dir to indicate lack of content

Do not cache content if we did not install content

Test changes to allay concerns about reliability of local_path

Do not blow away cache for SCM inventory updates

Remove project update vars no longer used

Remove job pre-creation of content folders

code style edit, always use cache_id as property in tasks

Fix log message
2020-07-28 13:57:28 -04:00
Alex Corey
8e27e0ce28 Teams Access List using Resource Access component 2020-07-28 13:17:11 -04:00
Alex Corey
a070d57080 Adds Teams Roles List and Disassociate functionality 2020-07-28 13:17:11 -04:00
mabashian
721c8d98f8 Prevents debug messages from being logged while tests are running 2020-07-28 13:13:00 -04:00
softwarefactory-project-zuul[bot]
196368d89b Merge pull request #7736 from beeankha/rrule_module_minor_edits
Make Some Doc Edits in the rrule Collections Module

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2020-07-28 16:27:22 +00:00
mabashian
8b2c98ffde Fixes console errors thrown about React state updates being be wrapped into act(...) on the job template add form 2020-07-28 12:08:40 -04:00
mabashian
1faaba4e6c Fixes console errors thrown about React state updates being be wrapped into act(...) on the inventory form 2020-07-28 12:05:02 -04:00
Ryan Petrello
7938bf58d4 Merge pull request #4485 from ryanpetrello/more-cred-failure-cleanup-372
properly obfuscate connection errors for credential lookup failure
2020-07-28 12:04:03 -04:00
beeankha
fe176a4f8c Match test playbook output to edited module output 2020-07-28 11:50:19 -04:00
mabashian
7e8d0b5883 Fixes console errors thrown about isValid on the workflow job template form 2020-07-28 11:49:17 -04:00
Ryan Petrello
91594a1ae8 properly obfuscate connection errors for credential lookup failure 2020-07-28 11:38:48 -04:00
mabashian
e6e79227e5 Fixes console errors thrown about isValid on the credential form 2020-07-28 11:26:48 -04:00
Ryan Petrello
b03b12163f Merge pull request #4486 from ryanpetrello/fix-372-unit-tests
pin pytest-forked to fix broken unit tests
2020-07-28 11:18:52 -04:00
Ryan Petrello
1c08206792 pin pytest-forked to fix broken unit tests 2020-07-28 11:16:52 -04:00
softwarefactory-project-zuul[bot]
3f0a8eb5bc Merge pull request #7633 from nixocio/ui_add_list_instance_group
Add feature list instance groups

Reviewed-by: Alex Corey <Alex.swansboro@gmail.com>
             https://github.com/AlexSCorey
2020-07-28 14:57:02 +00:00
beeankha
95cf6aa6d0 Make minor edits to the rrule module 2020-07-28 10:36:52 -04:00
nixocio
c2b1209cf3 Add feature list instance groups
Add list and delete for instance groups/container groups.

See: https://github.com/ansible/awx/issues/7557
Also: https://github.com/ansible/awx/issues/7642
2020-07-27 16:51:34 -04:00
softwarefactory-project-zuul[bot]
7bec29bac7 Merge pull request #7726 from fosterseth/fix-helm-url
Update helm urls in install guide

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-27 18:55:40 +00:00
Seth Foster
053b7caf3a Update helm urls 2020-07-27 13:01:29 -04:00
softwarefactory-project-zuul[bot]
6b867e7d97 Merge pull request #7596 from nixocio/ui_set_strict_mode
Set React to Strict Mode

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-27 15:56:57 +00:00
softwarefactory-project-zuul[bot]
708244881c Merge pull request #7643 from AlanCoding/per_update_cache
Implement per-update cache for roles and collections

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-27 15:45:48 +00:00
Alan Rominger
967f3cc6a7 Merge pull request #4472 from AlanCoding/upgrade_vmware
Upgrade community.vmware for better error surfacing
2020-07-27 10:16:12 -04:00
softwarefactory-project-zuul[bot]
e1902b6fe1 Merge pull request #7713 from mabashian/fix-form-field-help
Fixes bug where help icon showed up beneath the form label

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-27 13:42:41 +00:00
Vadiem Janssens
36316ae9a5 Fix tests
Signed-off-by: Vadiem Janssens <info@vadiemjanssens.nl>
2020-07-26 20:56:40 +02:00
Vadiem Janssens
8e4edca85d Replace itemCount with DataListToolbar pagination 2020-07-26 20:33:43 +02:00
Vadiem Janssens
30a499b785 Add item count to DataListToolbar
Signed-off-by: Vadiem Janssens <info@vadiemjanssens.nl>
2020-07-26 20:33:43 +02:00
softwarefactory-project-zuul[bot]
68c62d74f6 Merge pull request #7671 from jlmitch5/pfUpdate0920
update pf to 09 2020 release

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-23 20:57:07 +00:00
Ryan Petrello
847d6c65bd Merge pull request #4480 from ryanpetrello/372-cred-plugin-30x
properly report 30x errors on credential plugin tests
2020-07-23 15:27:27 -04:00
Ryan Petrello
f29e7b9c81 properly report 30x errors on credential plugin tests 2020-07-23 14:50:35 -04:00
Ryan Petrello
32831794ee Merge pull request #4477 from ryanpetrello/372-signal-deadlock
force worker processes to have a different signal handler from the parent
2020-07-23 12:21:44 -04:00
Jeff Bradberry
6b82ae46bc Force worker processes to have a different signal handler from the parent
Situations have come up where the 5+ minute kill signal for
run_task_manager is emitted to the worker process running it, but
since the worker improperly inherited the AWXConsumerBase().stop()
handler a deadlock ultimately was triggered on the database
connection.
2020-07-23 12:09:59 -04:00
Ryan Petrello
26660fa82e Merge pull request #4464 from ryanpetrello/named-url-vuln-372
update the named URL code to properly return 404 vs 403
2020-07-23 12:07:33 -04:00
mabashian
45286ebf41 Fixes bug where help icon showed up beneath the form label. I believe the labelIcon prop was added in a recent update of PF and is what we should be using. 2020-07-23 10:43:10 -04:00
softwarefactory-project-zuul[bot]
71d3fd3dbc Merge pull request #7698 from geerlingguy/pg-data-use-default-path
Use default path for pgdata volume in docker-compose template

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-23 13:02:53 +00:00
softwarefactory-project-zuul[bot]
6527d23b42 Merge pull request #7696 from AmadeusITGroup/fix_invalid_quote_filter
Installer: remove quote filter from docker_registry_password

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-23 13:00:52 +00:00
nixocio
1b767daaf6 Update wording to equal mock up
Update wording used for 'Job Templates' and 'Credential Types' to be
equal mock up.

See: https://tower-mockups.testing.ansible.com/patternfly/cred-types/cred-types/
Also: https://tower-mockups.testing.ansible.com/patternfly/templates/templates/
2020-07-22 14:00:24 -04:00
Ryan Petrello
860183f178 update the named URL code to properly return 404 vs 403 2020-07-22 12:15:34 -04:00
softwarefactory-project-zuul[bot]
3e753a7315 Merge pull request #7702 from ansible/fix-broken-offline-builds
Fix broken offline builds

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-22 13:22:19 +00:00
Stefan Jakobs
58da3df03e Change Dockerfile to copy custom venv 2020-07-22 14:00:05 +02:00
Shane McDonald
606296f68b Fix broken offline builds 2020-07-21 18:19:51 -04:00
Jeff Geerling
06fd131637 Use default path for pgdata volume in docker-compose template 2020-07-21 15:35:24 -05:00
softwarefactory-project-zuul[bot]
cf6c36ecab Merge pull request #7697 from nixocio/ui_small_refactor_credential_type_tests
Small update CredentialTypeList

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-21 20:17:23 +00:00
nixocio
fc9f1a3518 Small update CredentialTypeList
Small update CredentialTypeList. Update naming of function to
`deleteCredentialTypes`.
2020-07-21 15:50:43 -04:00
Philip DOUGLASS
ab20b5bd10 Installer: remove quote filter from docker_registry_password
The docker_registry_password var isn't interpolated by the shell, so
it shouldn't be quoted

Fixes: #7695
Signed-off-by: Philip DOUGLASS <philip.douglass@amadeus.com>
2020-07-21 15:33:42 -04:00
AlanCoding
0e8f30a4a2 Upgrade community.vmware for better error surfacing 2020-07-21 13:03:24 -04:00
AlanCoding
ddb8c93f17 Fix log message 2020-07-21 11:21:21 -04:00
AlanCoding
425c70826f code style edit, always use cache_id as property in tasks 2020-07-21 10:50:13 -04:00
AlanCoding
8195bd7386 Remove job pre-creation of content folders 2020-07-20 19:45:22 -04:00
AlanCoding
300d54864d Remove project update vars no longer used 2020-07-20 19:45:21 -04:00
AlanCoding
fefab89815 Integrate content caching with existing task logic
Revert the --force flags

use the update id as metric for role caching

Shift the movement of cache to job folder from rsync task to python

Only install roles and collections if needed

Deal with roles and collections for jobs without sync
Skip local copy if roles or collections turned off

update docs for content caching

Design pivot - use empty cache dir to indicate lack of content

Do not cache content if we did not install content

Test changes to allay concerns about reliability of local_path

Do not blow away cache for SCM inventory updates
2020-07-20 19:45:21 -04:00
Bill Nottingham
72848fa097 Remove the cache when delete-on-update is set 2020-07-20 19:45:20 -04:00
Bill Nottingham
85ec3dd5c4 Force install if doing a manual sync.
Requirements may be unversioned.
2020-07-20 19:45:20 -04:00
Bill Nottingham
98de4cb35f Adjust pathing to the proper location. 2020-07-20 19:45:20 -04:00
Bill Nottingham
dab7889715 Don't try and install content if there aren't any requirements expecting it 2020-07-20 19:45:19 -04:00
Bill Nottingham
95e69124af Also download roles/collections during the sync job
Since we're writing into a per-revision cache, we can do this easily now.
2020-07-20 19:45:19 -04:00
Bill Nottingham
1f4c46d873 Invalidate the cache on a new project revision 2020-07-20 19:45:18 -04:00
Bill Nottingham
d272ee3521 Cache downloaded roles & collections
Populate the cache the first time the job is run for a revision
that needs them, and for future runs for that revision just
copy it into the private directory.

Delete the cache on project deletion.
2020-07-20 19:45:15 -04:00
softwarefactory-project-zuul[bot]
bedbafe0f9 Merge pull request #7613 from keithjgrant/6622-template-list-websockets
Add websocket support to TemplateList

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-20 20:19:57 +00:00
softwarefactory-project-zuul[bot]
676491134d Merge pull request #7620 from keithjgrant/6621-inventory-sources-sockets
Inventory sources websockets

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-20 20:18:51 +00:00
softwarefactory-project-zuul[bot]
b36c5d9209 Merge pull request #7652 from jakemcdermott/fix-7651
Check for required node version before build or install

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-20 19:54:21 +00:00
softwarefactory-project-zuul[bot]
7296415fd9 Merge pull request #7635 from tchellomello/user_API_created
Exposes created attribute via API for User django ORM

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-20 19:40:47 +00:00
John Mitchell
00b3ff6e51 update snapshot and tooltip test 2020-07-20 14:06:14 -04:00
John Mitchell
bfaa2abd31 update pf to 09 2020 release 2020-07-20 13:42:14 -04:00
Ryan Petrello
34be08d38e add tests for filtering User.created_by in the API 2020-07-20 11:28:32 -04:00
Jake McDermott
2992a5f5a4 Check node version before build or install 2020-07-20 09:13:43 -04:00
Marcelo Moreira de Mello
3803763c53 Exposes the User.created attribute via API
Signed-off-by: Marcelo Moreira de Mello <tchello.mello@gmail.com>
2020-07-17 15:47:17 -04:00
softwarefactory-project-zuul[bot]
f0aec0d444 Merge pull request #7641 from josephpisciotta/devel
Remove the NodePort type for the web svc.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-17 19:01:27 +00:00
softwarefactory-project-zuul[bot]
765595fd11 Merge pull request #7629 from ryanpetrello/k8s-creds
add the ability to specify K8S/OCP credentials on a Job Template

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-17 17:07:46 +00:00
Joseph Pisciotta
75c6c068a7 Remove the NodePort type for the web svc. 2020-07-17 12:51:29 -04:00
softwarefactory-project-zuul[bot]
036780d337 Merge pull request #7559 from AlexSCorey/7513-SurveySelectAllBox
Removes unneeded select all checkbox in Survey List

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-16 22:39:41 +00:00
Phi|eas |ebada
a05aa20f24 Update updater.sh
I wrote this script a year ago and just realized that this sourcing won't work lol
2020-07-16 23:24:09 +02:00
softwarefactory-project-zuul[bot]
4db3cd0326 Merge pull request #7627 from jakemcdermott/fix-7512
Show grant and client type validation errors

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-16 21:00:29 +00:00
softwarefactory-project-zuul[bot]
2e07ac3c2c Merge pull request #7628 from jakemcdermott/fix-7511
Improve nav behavior

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-16 21:00:22 +00:00
softwarefactory-project-zuul[bot]
77717b6134 Merge pull request #7631 from jakemcdermott/fix-5236
Use summary job_type on host list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-16 19:40:36 +00:00
Jake McDermott
bf74aae80e Use summary job_type on host list 2020-07-16 14:10:55 -04:00
Alex Corey
496862592a fixes erroneous render 2020-07-16 12:59:58 -04:00
Alex Corey
ad536ec3d9 Removes commented out line 2020-07-16 12:59:52 -04:00
Alex Corey
bc69406f31 removes unneeded select all checkbox 2020-07-16 12:59:52 -04:00
Ryan Petrello
959b81aec5 refactor k8s credential injectors to properly handle verify=f 2020-07-16 12:43:10 -04:00
Ryan Petrello
1a39cbc2f4 add tests for k8s credential usage in Job Templates 2020-07-16 12:22:11 -04:00
Ryan Petrello
715dc4ece8 add a license for ruamel.ordereddict (for openshift lib support) 2020-07-16 11:38:54 -04:00
Ryan Petrello
c44f8e9122 implement k8s credential selection in the new patternfly UI 2020-07-16 11:25:03 -04:00
Ryan Petrello
75a0382c31 show k8s credentials in the Job Template prompt on launch UI 2020-07-16 10:53:21 -04:00
Ryan Petrello
0b221a42c0 Add the ability to specify K8S/OCP credentials on a Job Template
see: https://github.com/ansible/awx/issues/5735
2020-07-15 17:44:07 -04:00
Jake McDermott
6f43462689 Improve nav behavior
* Use more selective route matching when determining if a nav item is
active

* Don't automatically collapse nav groups when user navigates to a
different group
2020-07-15 12:46:08 -04:00
Jake McDermott
d1a4f010b9 Show grant and client type validation errors 2020-07-15 12:05:51 -04:00
softwarefactory-project-zuul[bot]
79b95883a3 Merge pull request #7618 from jakemcdermott/update-deps-03
Fix most of this week's npm warnings

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-15 14:49:04 +00:00
Keith Grant
f1e3b4f4f0 add useWsInventorySources tests 2020-07-14 14:29:24 -07:00
Ryan Petrello
c410f1f344 Merge pull request #4458 from ryanpetrello/fifo-cred-plugin-hang-372
[3.7.2] remove the usage of create_temporary_fifo from credential plugins
2020-07-14 17:21:35 -04:00
Ryan Petrello
310a0f88e5 remove the usage of create_temporary_fifo from credential plugins
this resolves an issue that causes an endless hang on with Cyberark AIM
lookups when a certificate *and* key are specified

the underlying issue here is that we can't rely on the underyling Python
ssl implementation to *only* read from the fifo that stores the pem data
*only once*; in reality, we need to just use *actual* tempfiles for
stability purposes

see: https://github.com/ansible/awx/issues/6986
see: https://github.com/urllib3/urllib3/issues/1880
2020-07-14 16:24:03 -04:00
Keith Grant
4fca57dfd2 add ws support to inventory sources list 2020-07-14 11:43:59 -07:00
Jake McDermott
e89326dbf2 Fix vulnerable 2nd order dependency 2020-07-14 14:42:46 -04:00
softwarefactory-project-zuul[bot]
cd6df9299f Merge pull request #7286 from john-westcott-iv/lookup_plugins
Adding tower_api and tower_get_id lookup plugins

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-14 18:04:27 +00:00
softwarefactory-project-zuul[bot]
80a6d4a29d Merge pull request #7611 from ryanpetrello/host-recent-job-type
add job type to Host summary_fields.recent_jobs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-14 14:04:58 +00:00
John Westcott IV
222e58dd34 Adding lookup to rrule plugin test logic for new tooling
This change is provided with the tower_api lookup plugin because the require tower_meta module is part of this commit
2020-07-14 09:38:26 -04:00
John Westcott IV
0be7d9b21a Removing redundant check 2020-07-14 09:38:26 -04:00
John Westcott IV
5a6c7a5788 Fixing copyrights and linting issues 2020-07-14 09:38:26 -04:00
John Westcott IV
3784f9515e More refinement of examples 2020-07-14 09:38:26 -04:00
John Westcott IV
6638d6c2bb Update examples 2020-07-14 09:38:26 -04:00
John Westcott IV
afbdeb5ff8 Fixing linting errors 2020-07-14 09:38:26 -04:00
John Westcott IV
381e9d2901 Reverting commit 81b192c3b0520be0897f95e2630edab295e6bf24, we should fail only if we are > max_objects 2020-07-14 09:38:26 -04:00
John Westcott IV
dd478af227 Overhaul of the testing suite 2020-07-14 09:38:26 -04:00
John Westcott IV
0424370d49 Revamp of the examples 2020-07-14 09:38:26 -04:00
John Westcott IV
1a4bb42ac5 When using return_ids send back a list of strings instead of ints.
When we used ints and passed this data into a nother call like:
    - name: Create a job template with a looked up credential from a folded lookup
      tower_job_template:
        name: "{{ job_template_name }}"
        credentials: >-
            {{ lookup(
                'awx.awx.tower_api',
                'credentials',
                query_params={ 'name' : credential_name },
                return_ids=True,
                expect_one=True,
                wantlist=True
            ) }}
        project: "{{ project_name }}"
        inventory: Demo Inventory
        playbook: hello_world.yml
        job_type: run
        state: present
      register: create_jt

Ansible would raise this warning:
[WARNING]: The value 30 (type int) in a string field was converted to '30' (type string). If this does not look like what you expect, quote the entire value to ensure it does not change.

Returning a list of strings prevents that.
2020-07-14 09:38:26 -04:00
John Westcott IV
fdb008fb8c Added note about exception if list view return is > max_objects 2020-07-14 09:38:26 -04:00
John Westcott IV
d793f0bc99 Making the count check >= instead of just > 2020-07-14 09:38:26 -04:00
John Westcott IV
a9c16a6c90 Fixing undefined variabe 2020-07-14 09:38:26 -04:00
Alan Rominger
34c23caed3 make lookup plugin compatible with ansible.tower namespace (#9) 2020-07-14 09:38:26 -04:00
AlanCoding
8239232d4d Delete the tower_get_id plugin and tests 2020-07-14 09:38:26 -04:00
AlanCoding
30ff112c87 Pull in functionality from lookup plugin get_id into tower_api itself 2020-07-14 09:38:26 -04:00
John Westcott IV
f4454a6c93 Make tower_api a generic GET'er 2020-07-14 09:38:26 -04:00
John Westcott IV
44a3057d16 Initial fixes from github comments 2020-07-14 09:38:26 -04:00
John Westcott IV
3c02265986 Fixing doc issue 2020-07-14 09:38:26 -04:00
beeankha
6715ea493f Fix documentation in api lookup plugin, fix typos in integration tests 2020-07-14 09:38:26 -04:00
John Westcott IV
96ae3268a5 Fixing linting issues 2020-07-14 09:38:26 -04:00
John Westcott IV
6d626b3793 Adding tower_api and tower_get_id lookup plugins 2020-07-14 09:38:26 -04:00
Keith Grant
350c585499 update useWsTemplates to use useWebsocket hook 2020-07-13 13:32:13 -07:00
Keith Grant
b76783791a add useWsTemplates tests 2020-07-13 13:27:38 -07:00
Keith Grant
981c9527b2 add template list websocket support 2020-07-13 13:27:38 -07:00
softwarefactory-project-zuul[bot]
09dcb91c09 Merge pull request #7598 from keithjgrant/6618-websocket-inventories-list
Add Websocket support to inventories list

Reviewed-by: Daniel Sami
             https://github.com/dsesami
2020-07-13 20:25:49 +00:00
Ryan Petrello
3ef07ee5f7 Merge pull request #4447 from ryanpetrello/372-master-main-links
fixed broken UI links
2020-07-13 15:49:11 -04:00
Gabe Muniz
1edae24644 fixed broken UI links 2020-07-13 15:36:07 -04:00
softwarefactory-project-zuul[bot]
d4b0251845 Merge pull request #7615 from gamuniz/remove_broken_links
fixed broken UI links

Reviewed-by: awxbot
             https://github.com/awxbot
2020-07-13 19:31:56 +00:00
Gabe Muniz
ff90e64448 fixed broken UI links 2020-07-13 14:53:34 -04:00
Ryan Petrello
ab11d3188d refactor the job type name into a single property 2020-07-13 09:43:43 -04:00
Ryan Petrello
f51774c06e add job type to Host summary_fields.recent_jobs
see: https://github.com/ansible/awx/issues/5236
2020-07-13 09:02:04 -04:00
softwarefactory-project-zuul[bot]
83458711cd Merge pull request #7605 from wenottingham/jobberry-fields-forever
Add artifacts field of jobs to the allowed list for notifications

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-10 21:01:08 +00:00
Bill Nottingham
46734f5c10 Add artifacts field of jobs to the allowed list for notifications 2020-07-10 16:34:25 -04:00
softwarefactory-project-zuul[bot]
b8b0812e13 Merge pull request #7604 from philipsd6/enable-html-custom-login-info
Update help_text for Custom Login Info to show support for HTML

Reviewed-by: awxbot
             https://github.com/awxbot
2020-07-10 19:08:48 +00:00
Keith Grant
38e0968690 useWsInventories cleanup 2020-07-10 08:33:35 -07:00
Philip Douglass
1ec2bd7ed2 Update help_text for Custom Login Info to show support for HTML
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-07-10 10:11:02 -04:00
softwarefactory-project-zuul[bot]
d10fdda453 Merge pull request #7575 from weltamdraht/add_extra_hosts
Adding inventory variable to set "extra_hosts" in generated compose file

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-10 14:05:26 +00:00
Jake McDermott
2737cded72 Merge pull request #4442 from jakemcdermott/fix-4440
[3.7.2] Include instance_id in host edit request
2020-07-10 09:43:50 -04:00
Jake McDermott
4f2ce90137 Include instance_id in host edit request 2020-07-10 09:39:54 -04:00
softwarefactory-project-zuul[bot]
d4305f734a Merge pull request #7585 from philipsd6/enable-html-custom-login-info
Safely enable HTML in Custom Login Info

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-10 12:57:17 +00:00
weltamdraht
347529a0cf Adding inventory variable to set "extra_hosts" in generated compose file
Signed-off-by: weltamdraht <andreas.aderhold@dwd.de>
2020-07-10 13:25:07 +02:00
softwarefactory-project-zuul[bot]
e4470f1200 Merge pull request #7592 from jakemcdermott/fix-7591
Include instance_id in host edit request

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-09 21:17:18 +00:00
Keith Grant
f225df1acd add useWsInventories tests 2020-07-09 14:12:56 -07:00
nixocio
01f210e392 Set React to Strict Mode
Set React to Strict Mode.

See: https://reactjs.org/docs/strict-mode.html
2020-07-09 15:37:19 -04:00
Keith Grant
455e018099 refactor shared WS logic into useWebsocket hook 2020-07-09 10:14:03 -07:00
Philip Douglass
4c98a1cb20 Set white-space style based on customLoginInfoIsHTML
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-07-09 18:56:19 +02:00
Philip Douglass
202a68aca0 Add customLoginInfoIsHTML test
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-07-09 18:56:19 +02:00
Philip Douglass
29666bf3b6 Remove white-space: pre-wrap from loginModalNotice
Signed-off-by: Philip Douglass <philip.douglass@amadeus.com>
2020-07-09 18:56:19 +02:00
Jake McDermott
ddbe20d41b Include instance_id in host edit request 2020-07-09 11:27:45 -04:00
Ryan Petrello
140d9ae3ee Merge pull request #4429 from wenottingham/label-maker
Reintroduce label filtering
2020-07-09 09:00:57 -04:00
Keith Grant
84bea3d348 websockets: show live inventory source sync status 2020-07-08 15:20:42 -07:00
softwarefactory-project-zuul[bot]
d0ac028265 Merge pull request #7489 from nixocio/ui_issue_7326
Add edit credential types

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-08 20:53:09 +00:00
Ryan Petrello
7322e13436 add tests for clarified label permissions 2020-07-08 16:53:05 -04:00
softwarefactory-project-zuul[bot]
9065b29bd6 Merge pull request #7584 from ryanpetrello/jinja2-sandbox
use jinja2.sandbox for credential type injectors

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-08 20:53:02 +00:00
softwarefactory-project-zuul[bot]
dbdc856ed3 Merge pull request #7576 from ryanpetrello/instance-group-capabilities
show user capabilities for instance groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-08 20:05:55 +00:00
Ryan Petrello
1cf2f009ed prevent unsafe jinja from being saved in the first place for cred types
see: https://github.com/ansible/tower-security/issues/21
2020-07-08 15:48:58 -04:00
Ryan Petrello
2bdd83e029 use jinja2.sandbox for credential type injectors 2020-07-08 15:48:47 -04:00
softwarefactory-project-zuul[bot]
e91395d517 Merge pull request #7497 from AlexSCorey/ApplicationTokens
Adds Application Token List with delete functionality

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-08 19:42:17 +00:00
softwarefactory-project-zuul[bot]
19115a157e Merge pull request #7555 from AlexSCorey/7433-UserTokensAdd
Adds User TokenAdd Functionality

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-08 19:33:06 +00:00
Alex Corey
a9d4046ec5 Adds Application Token List with delete functionality 2020-07-08 15:13:31 -04:00
Alex Corey
bbc4522063 Adds User TokenAdd Functionality 2020-07-08 14:47:23 -04:00
softwarefactory-project-zuul[bot]
fb3271da3c Merge pull request #7578 from squidboylan/raise_sleep_timeout
Raise job length for testing job wait

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-08 18:36:42 +00:00
Caleb Boylan
56d800e851 Raise job length for testing job wait 2020-07-08 09:28:19 -07:00
Ryan Petrello
319308193c show user capabilities for instance groups 2020-07-08 09:17:55 -04:00
Keith Grant
15ae0976dd add sync status indicator to inventory list 2020-07-07 16:37:08 -07:00
softwarefactory-project-zuul[bot]
f121dc59f6 Merge pull request #7529 from nixocio/ui_issue_7471
Add stub files for Instance Groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-07 21:12:23 +00:00
softwarefactory-project-zuul[bot]
f050b73560 Merge pull request #7568 from jakemcdermott/fix-7534
Update to ansible/angular-scheduler#v0.4.4

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-07 19:43:00 +00:00
Jake McDermott
bd624508e3 Update to ansible/angular-scheduler#v0.4.4 2020-07-07 15:04:07 -04:00
softwarefactory-project-zuul[bot]
b9fb9389e6 Merge pull request #7537 from jakemcdermott/fix-7483
Fix custom credential field validation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-07 19:02:53 +00:00
softwarefactory-project-zuul[bot]
bf28bdecb7 Merge pull request #7540 from keithjgrant/6618-websocket-projects-list
Add Websocket support to Projects List

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-07 19:00:10 +00:00
softwarefactory-project-zuul[bot]
23cab61408 Merge pull request #7444 from AlexSCorey/7412-OrganizationEditButton
Adds edit icon to the OrganizationTeams list 

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-07 17:32:34 +00:00
nixocio
777d44ec34 Add edit credential types
Add feature to edit credential types.

See: https://github.com/ansible/awx/issues/7326
2020-07-07 13:30:54 -04:00
Ryan Petrello
bc14e995fd Merge pull request #4434 from ryanpetrello/jinja-injector-sandbox-validation
prevent unsafe jinja from being saved in the first place for cred types
2020-07-07 12:47:15 -04:00
Ryan Petrello
61d3a765ee prevent unsafe jinja from being saved in the first place for cred types
see: https://github.com/ansible/tower-security/issues/21
2020-07-07 10:59:14 -04:00
Ryan Petrello
f943277ef0 Merge pull request #4433 from ghjm/webhook_error_detail
Error detail in webhook and credential tests
2020-07-07 10:35:21 -04:00
softwarefactory-project-zuul[bot]
9a6da9cea7 Merge pull request #7552 from ikke-t/fix-7545
Allow anyone to start awx and awx_task [#7545]

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-07 14:34:16 +00:00
Ilkka Tengvall
8b4b1f5f81 Allow anyone to start awx and awx_task [#7545] 2020-07-07 15:04:23 +03:00
Graham Mainwaring
5a96af79d4 Reduce error detail in credential lookups 2020-07-06 21:41:28 -04:00
Graham Mainwaring
b7f37d5e26 Reduce error detail in webhook notification 2020-07-06 21:17:21 -04:00
Graham Mainwaring
d14aee70a1 Don't follow redirects in credential plugins 2020-07-06 17:18:30 -04:00
Ryan Petrello
8aa11f4848 Merge pull request #4430 from ryanpetrello/jinja2-injector-sandbox
use jinja2.sandbox for credential type injectors
2020-07-06 15:21:21 -04:00
Jake McDermott
05799d9795 Avoid non-unique field name collisions
Custom credentials can have input fields named 'name', 'organization',
'description', etc. Underscore these variables to make collisions
less likely to occur.
2020-07-06 14:08:53 -04:00
Jake McDermott
ea4b435ea7 Ignore required field validation for booleans 2020-07-06 14:08:46 -04:00
Ryan Petrello
2f1b4d81e1 use jinja2.sandbox for credential type injectors 2020-07-06 13:50:33 -04:00
Bill Nottingham
a88f03b372 Reintroduce label filtering
Labels are visible if you have a role on the org they are in, or
on a job template they're attached to.
2020-07-06 13:50:00 -04:00
softwarefactory-project-zuul[bot]
dbfb1780f1 Merge pull request #7553 from jakemcdermott/fix-7530
Fix self-closing tags for jquery 3.5 compat

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-06 17:01:46 +00:00
Jake McDermott
a89eff3c1a Remove self-closing tags
jquery doesn't like self-closing tags. jquery doesn't like anything.
2020-07-06 09:34:50 -04:00
JoelKle
699f186890 Fixed a bug, where the redis.conf first would be stored with mod 0600
and in the next task changed to 0666.
This has broke the ability to rerun the playbook.

Signed-off-by: JoelKle <34544090+JoelKle@users.noreply.github.com>
2020-07-03 08:59:28 +02:00
JoelKle
caab751215 Added the ability, to set the broadcast_websocket_secret variable.
This is nessesary if you would like to rerun the playbook.

Signed-off-by: JoelKle <34544090+JoelKle@users.noreply.github.com>
2020-07-03 08:59:28 +02:00
Keith Grant
2e3e1be22a add useWsProjects tests 2020-07-02 15:42:51 -07:00
softwarefactory-project-zuul[bot]
a74fbd6578 Merge pull request #7432 from elyezer/update-module-tests
Only pass either user or org on modules test

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-02 21:01:00 +00:00
Keith Grant
803ea322d6 update path to useThrottle in tests 2020-07-02 10:51:57 -07:00
Keith Grant
9657117941 add ProjectList websocket support 2020-07-02 09:29:56 -07:00
softwarefactory-project-zuul[bot]
b56c753613 Merge pull request #7525 from ryanpetrello/encrypted-keyword
don't allow users to specify $encrypted$ for encrypted credential fields

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-02 15:47:33 +00:00
softwarefactory-project-zuul[bot]
8b3dfae717 Merge pull request #7501 from ansible/jakemcdermott-no-modules-for-project-root
Delete node_modules in project root

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-02 00:36:56 +00:00
softwarefactory-project-zuul[bot]
8f50514b3d Merge pull request #7502 from nixocio/ui_lingui_prod
Add extraction of strings to be translated as part of build process

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-01 23:09:05 +00:00
Keith Grant
bdb97c173b move useThrottle to utils 2020-07-01 15:52:06 -07:00
nixocio
24f86cd0d1 Add stub files for Instance Groups
Add stub files for Instance Groups. Routing system, and screens layout.

closes: https://github.com/ansible/awx/issues/7471
2020-07-01 17:27:08 -04:00
softwarefactory-project-zuul[bot]
6e651ce275 Merge pull request #7519 from shanemcd/the-ol-copy-paste
Copy over some downstream changes

Reviewed-by: Shane McDonald <me@shanemcd.com>
             https://github.com/shanemcd
2020-07-01 20:22:51 +00:00
Alex Corey
650a97e989 Adds edit icon to the OrganizationTeams list and renames some files. 2020-07-01 16:08:41 -04:00
Ryan Petrello
1434e5812f don't allow users to specify $encrypted$ for encrypted credential fields
this keyword only has value when you _update_ an existing credential
2020-07-01 15:53:09 -04:00
Shane McDonald
e26387cdf3 Remove references to old images 2020-07-01 14:57:48 -04:00
Shane McDonald
7f81f530fa Copy over downstream change
Allows users to specify pg_username that has uppercase letters to restore succesfully
2020-07-01 14:40:38 -04:00
nixocio
fab94902a0 Add extraction of strings to be translated as part of build process
Add extraction of strings to be translated as part of build process for
ui_next.

Also, sets the source locale. See: https://lingui.js.org/tutorials/cli.html#configuring-source-locale

closes: https://github.com/ansible/awx/issues/7451
2020-07-01 12:05:37 -04:00
softwarefactory-project-zuul[bot]
e3e69b4c6b Merge pull request #7499 from nixocio/ui_translations_issues
Add strings to be translated

Reviewed-by: Kersom
             https://github.com/nixocio
2020-07-01 15:31:59 +00:00
softwarefactory-project-zuul[bot]
642803e471 Merge pull request #7484 from jakemcdermott/update-deps
Remove unused dependencies

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-01 15:14:58 +00:00
softwarefactory-project-zuul[bot]
26f2f159dd Merge pull request #7396 from AlexSCorey/7235-ApplicationsAddEdit
Adds Application edit functionality

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-07-01 15:08:23 +00:00
Jake McDermott
e962933148 Delete node_modules in project root 2020-07-01 10:51:29 -04:00
Alex Corey
169868b927 Adds edit functionality 2020-07-01 10:37:27 -04:00
nixocio
e0ebd5d46c Add strings to be translated
To identify those strings `npm run extract-strings`.
2020-07-01 10:22:45 -04:00
softwarefactory-project-zuul[bot]
d1f9f4dc86 Merge pull request #7457 from marshmalien/smart-inventory-detail
Add smart inventory detail view

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-30 21:45:17 +00:00
softwarefactory-project-zuul[bot]
5c12022529 Merge pull request #7479 from chris93111/patch-2
correction inventory endpoint tower_workflow_job_template_node.py

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-30 17:10:25 +00:00
softwarefactory-project-zuul[bot]
d8f6ea3fe8 Merge pull request #7485 from ryanpetrello/words-matter
replace certain terms with more inclusive language

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-30 17:00:58 +00:00
softwarefactory-project-zuul[bot]
719a4f8aad Merge pull request #7436 from AlexSCorey/7419-UserTokens
Adds Tokens List

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-30 16:51:56 +00:00
Jake McDermott
7bac7abd67 Fix variable names 2020-06-30 12:34:14 -04:00
Alex Corey
776ee43d90 Fixes missing name bug 2020-06-30 12:22:19 -04:00
Ryan Petrello
78229f5871 replace certain terms with more inclusive language
see: https://www.redhat.com/en/blog/making-open-source-more-inclusive-eradicating-problematic-language
2020-06-30 10:49:19 -04:00
Jake McDermott
b4198204a7 Add install step 2020-06-30 10:10:52 -04:00
Jake McDermott
86c1f4d772 Co-locate deps in file 2020-06-30 08:58:37 -04:00
Jake McDermott
e10fb71f93 Move react-scripts to dev dependencies 2020-06-30 08:58:32 -04:00
Jake McDermott
bae50e38da Remove unused dependencies 2020-06-30 08:58:27 -04:00
softwarefactory-project-zuul[bot]
66739a52d6 Merge pull request #7342 from keithjgrant/6618-job-list-ws
Jobs List websockets

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-29 21:51:14 +00:00
softwarefactory-project-zuul[bot]
f060002289 Merge pull request #7478 from ansible/jakemcdermott-fixreadme
Fix unescaped README code block

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-29 21:20:18 +00:00
chris93111
b6883ab64e Update tower_workflow_job_template_node.py
correction to lookup inventory
2020-06-29 22:58:18 +02:00
Jake McDermott
9dadb96d45 Fix unescaped README code block 2020-06-29 16:50:44 -04:00
Keith Grant
5304792949 update useWsJobs tests 2020-06-29 13:49:58 -07:00
Keith Grant
a3e0ae66ba clean up sorting order discrepancies 2020-06-29 13:49:58 -07:00
Keith Grant
9705f7bec6 sort jobs list by selection sort option 2020-06-29 13:49:58 -07:00
Keith Grant
5610309a88 fix sorting jobs by finished date 2020-06-29 13:49:58 -07:00
Keith Grant
25fe090e67 delete un-workable test for useThrottle 2020-06-29 13:49:58 -07:00
Keith Grant
a1f257bd4a fix joblist updating completed jobs lists 2020-06-29 13:49:58 -07:00
Keith Grant
638a6fdaa1 remove extra logging from JobList tests 2020-06-29 13:49:58 -07:00
Keith Grant
b4a6749699 refactor getJobsById into useWsJobs hook 2020-06-29 13:49:58 -07:00
Keith Grant
e50576c820 failed attempt at useThrottle tests 2020-06-29 13:49:58 -07:00
Keith Grant
0bedd6fbd8 mock websockets; test useWsJobs 2020-06-29 13:49:58 -07:00
Keith Grant
48977e50df change jobs debounce to throttle; prevent duplicate rows 2020-06-29 13:49:58 -07:00
Keith Grant
7aa8495d1a debounce fetching of individual jobs 2020-06-29 13:49:58 -07:00
Keith Grant
58b954df3e fetch individual jobs based on websocket messages 2020-06-29 13:49:58 -07:00
Keith Grant
38079b2ad5 don’t add still running jobs to some jobs lists 2020-06-29 13:49:58 -07:00
Keith Grant
b055d34139 update jobs in list based on websockets 2020-06-29 13:49:58 -07:00
Keith Grant
f2641de260 rough out jobs list websockets 2020-06-29 13:49:58 -07:00
Keith Grant
aa12e323b4 ignore .env.local file 2020-06-29 13:49:58 -07:00
softwarefactory-project-zuul[bot]
65a8a656f7 Merge pull request #7469 from jakemcdermott/fix-7454
Use a proxy config that works

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-29 20:21:26 +00:00
Alex Corey
73bb539b16 Adds Tokens List 2020-06-29 16:17:10 -04:00
softwarefactory-project-zuul[bot]
6e99b1cf85 Merge pull request #7452 from nixocio/ui_issue_7430
Add Crendential Type Details

Reviewed-by: Daniel Sami
             https://github.com/dsesami
2020-06-29 20:06:05 +00:00
Jake McDermott
bde1ff1187 Use a proxy config that works 2020-06-29 15:51:51 -04:00
nixocio
bd660254a5 Add Crendential Type Details
Add credential type Details

See: https://github.com/ansible/awx/issues/7430
2020-06-29 15:02:38 -04:00
softwarefactory-project-zuul[bot]
879ab50a12 Merge pull request #7426 from nixocio/ui_issue_7325
Add feature to add Credential Type

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-29 18:54:27 +00:00
nixocio
ad10f3581e Add feature to add Credential Type
Add feature to add Credential Type.

See: https://github.com/ansible/awx/issues/7325
2020-06-29 13:39:57 -04:00
Marliana Lara
eec2177315 Add unit tests that check activity stream is hidden appropriately 2020-06-29 13:20:44 -04:00
softwarefactory-project-zuul[bot]
f5d38f57d4 Merge pull request #7375 from vjanssens/5929-consistent-subforms-in-job-template-forms
Use consistent layout for subforms in job/template forms

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-29 17:15:23 +00:00
Vadiem Janssens
3f33f1c97d Fix failing test
Signed-off-by: Vadiem Janssens <info@vadiemjanssens.nl>
2020-06-29 12:08:48 -04:00
Vadiem Janssens
f9039703ee Remove enableWebhooks conditional in WebhookSubForm
Signed-off-by: Vadiem Janssens <info@vadiemjanssens.nl>
2020-06-29 12:08:48 -04:00
Vadiem Janssens
be33627755 Remove webhook_key and webhook_url from JT form payload
Signed-off-by: Vadiem Janssens <info@vadiemjanssens.nl>
2020-06-29 12:08:48 -04:00
Vadiem Janssens
c9cfaf65a0 Add headingLevels to Title, minor improvements
Signed-off-by: Vadiem Janssens <info@vadiemjanssens.nl>
2020-06-29 12:08:48 -04:00
Vadiem Janssens
12b87fca8c Use consistent layout for subforms in job/template forms
Signed-off-by: Vadiem Janssens <info@vadiemjanssens.nl>
2020-06-29 12:08:48 -04:00
Marliana Lara
b5bbfaab11 Add smart inv detail 2020-06-29 11:30:10 -04:00
softwarefactory-project-zuul[bot]
8ea31d8cdd Merge pull request #7462 from 90er/patch-2
Update ISSUES.md

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-29 13:20:02 +00:00
softwarefactory-project-zuul[bot]
5ae7aa7503 Merge pull request #7461 from 90er/patch-1
Update INSTALL.md

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-29 13:18:45 +00:00
90er
c89277358f Update ISSUES.md
Fixed typo
2020-06-29 09:16:06 +02:00
90er
7e2b3684e2 Update INSTALL.md
Fix typo
2020-06-29 09:11:45 +02:00
softwarefactory-project-zuul[bot]
c7d9d941e3 Merge pull request #7119 from thedoubl3j/hostnogroup
added change so that groups and host names cannot share the same name

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-26 20:19:53 +00:00
softwarefactory-project-zuul[bot]
5b9c19df8f Merge pull request #7115 from nixocio/ui_next_integration
UI next integration

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-26 19:42:30 +00:00
Jake Jackson
30757f8289 moved logic to the validate function and fixed tests accordingly 2020-06-26 15:04:48 -04:00
Jake Jackson
606d4e0ea2 added change so that groups and host names cannot share the same name in the same inventory. added tests to validate 2020-06-25 11:25:21 -04:00
Jake McDermott
1df91eece1 Add devel make targets for ui_next 2020-06-25 10:22:07 -04:00
Jake McDermott
01b8087cb3 Align prod and dev routing 2020-06-25 08:56:21 -04:00
nixocio
aef382862c Update NavItem to link to new basename
Update NavItem to link to the new basename, `next`. Thus avoiding to
redirec to the old ui.

See: https://www.patternfly.org/v4/documentation/react/components/nav
2020-06-25 08:56:19 -04:00
Jake McDermott
41d8edf94a Align imports to django collectstatic locations
Co-authored-by: nixocio <nixocio@gmail.com>
2020-06-25 08:56:11 -04:00
Jake McDermott
ddadf332cc Create static dir during bootstrap
Co-authored-by: nixocio <nixocio@gmail.com>
2020-06-25 08:56:07 -04:00
Jake McDermott
12a22d2442 Add basic django app and file serving for ui_next 2020-06-25 08:55:56 -04:00
softwarefactory-project-zuul[bot]
fa53cdf329 Merge pull request #7431 from ryanpetrello/bottleneck
add a tool for discovering which tasks/hosts are slow for a JT 

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-24 21:32:40 +00:00
softwarefactory-project-zuul[bot]
5445a3b567 Merge pull request #7308 from AlanCoding/in_place_everything
Allow for SCM installs of the AWX collection

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-24 19:41:43 +00:00
softwarefactory-project-zuul[bot]
2e37ffdb15 Merge pull request #6690 from john-westcott-iv/modify_tower_cred_type_for_token
Modifying tower credential type to include an oauth otken

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-24 16:55:25 +00:00
AlanCoding
3b5640aca3 fix test 2020-06-24 10:41:41 -04:00
softwarefactory-project-zuul[bot]
038688ca48 Merge pull request #7355 from AlexSCorey/ApplicationDetails
Adds application details view

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-24 14:37:21 +00:00
Elyézer Rezende
fb5d876b9b Only pass either user or org on modules test 2020-06-24 10:29:19 -04:00
Ryan Petrello
a62047809f update awx-manage bottleneck's help text 2020-06-24 10:25:09 -04:00
Ryan Petrello
b1fcc0578c default awx-manage bottleneck --threshold to 30s 2020-06-24 10:23:01 -04:00
Ryan Petrello
dd42f6351b minor refactoring of awx-manage bottleneck 2020-06-24 10:19:26 -04:00
Alex Corey
fad4b3ca5a Adds application details view 2020-06-24 10:00:12 -04:00
Ryan Petrello
ce65f994dc refactor some timedelta formatting in awx-manage bottleneck 2020-06-24 09:56:23 -04:00
Ryan Petrello
5532760ccf respect --no-color in awx-manage bottleneck 2020-06-24 09:52:30 -04:00
Ryan Petrello
21ea7eb5dc add the name of the task to awx-manage bottleneck output 2020-06-24 09:44:39 -04:00
Ryan Petrello
b01ac1bfa6 add support to the bottleneck script for configuring history size 2020-06-24 09:22:53 -04:00
John Westcott IV
f091de438e Adding help text 2020-06-24 09:14:30 -04:00
John Westcott IV
8a25f385e4 Modifying tower credential type to include an oauth otken 2020-06-24 09:14:30 -04:00
Ryan Petrello
180ed4cd3d add a tool for discovering which tasks/hosts are slow for a JT
this tool looks at the most recent jobs for a specific job template and
attempts to discover the _slowest_ tasks and hosts

$ awx-manage bottleneck --template N
$ awx-manage bottleneck --template N --threshold 1 --ignore yum
$ awx-manage bottleneck --template N --ignore pause --ignore yum
2020-06-24 08:59:48 -04:00
softwarefactory-project-zuul[bot]
c1bbeadf8d Merge pull request #7427 from ryanpetrello/awxkit-install
update instructions and metadata for awxkit/cli installs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-23 22:23:56 +00:00
Ryan Petrello
b6c210ee97 update instructions and metadata for awxkit/cli installs 2020-06-23 17:53:14 -04:00
softwarefactory-project-zuul[bot]
f4514873cd Merge pull request #7425 from ghjm/no_traceback_on_keyboardinterrupt
Don't traceback on KeyboardInterrupt

Reviewed-by: awxbot
             https://github.com/awxbot
2020-06-23 20:45:19 +00:00
softwarefactory-project-zuul[bot]
2c59e83beb Merge pull request #7250 from nixocio/ui_issue_6810
Remove style overrides from Lookup component

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-23 20:39:58 +00:00
Graham Mainwaring
29da0abfc1 Don't traceback on KeyboardInterrupt 2020-06-23 16:14:02 -04:00
nixocio
14b2bd3445 Remove style overrides from Lookup component
Remove style overrides from Lookup component. Also, update related
tests.

closes: https://github.com/ansible/awx/issues/6810
2020-06-23 16:09:56 -04:00
softwarefactory-project-zuul[bot]
77ecb7b7d5 Merge pull request #7424 from ryanpetrello/changelog-tweak
minor CHANGELOG verbiage tweak

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2020-06-23 20:08:13 +00:00
Ryan Petrello
a9938c0e64 minor CHANGELOG verbiage tweak 2020-06-23 15:33:22 -04:00
Christian Adams
f24b15dc2e Merge pull request #4415 from ansible/i18n_release_3.7.1_translations
UI translation strings for release_3.7.1 branch for es and nl
2020-06-19 15:25:33 -04:00
ansible-translation-bot
af199dff7a UI translation strings for release_3.7.1 branch for es and nl 2020-06-19 10:36:21 -04:00
AlanCoding
0dbaf632dc Documentation updates 2020-06-19 09:49:37 -04:00
AlanCoding
a7fe5e1dd2 Fix yamllint error and sync version with module_utils 2020-06-19 09:08:58 -04:00
AlanCoding
96583e9e6b Make version recognizable as pre-release 2020-06-19 09:08:58 -04:00
AlanCoding
73ee11725d Add copy note to galaxy file 2020-06-19 09:08:58 -04:00
AlanCoding
721ed516a4 Separate folder for templating collection stuff 2020-06-19 09:08:57 -04:00
AlanCoding
4848f1298a Include a default galaxy.yml file 2020-06-19 09:08:57 -04:00
John Westcott IV
6c6c1e8488 Adding templating of README.md file for Tower vs AWX collections 2020-06-19 09:08:54 -04:00
Jim Ladd
99b3997084 Merge pull request #4412 from jladdjr/foreman_backwards_compat_for_ssl_verify_3.7.2
add backwards support for ssl_verify in foreman
2020-06-18 18:25:53 -07:00
Jim Ladd
35fe255455 add backwards support for ssl_verify in foreman
* plugin changed option name from
  ssl_verify to validate_cert
2020-06-18 17:02:48 -07:00
Alan Rominger
3cf4f4729d [DO NOT PORT to AWX] Pin dev requirements (#4413) 2020-06-18 09:22:04 -04:00
Ryan Petrello
6376395c68 Merge pull request #4409 from ryanpetrello/371-host-summary-regression
fix a regression in how job host summaries are generated
2020-06-16 17:04:22 -04:00
Ryan Petrello
eaadbe9730 fix a regression in how job host summaries are generated
this change fixes a bug introduced in the optimization at https://github.com/ansible/awx/pull/7352

1. Create inventory with multiple hosts
2. Run a playbook with a limit to match only one host
3. Run job, verify that it only acts on the one host
4. Go to inventory host list and see that all the hosts have last_job updated to point to the job that only acted on one host.
2020-06-16 13:18:14 -04:00
Christian Adams
186c54cb14 Merge pull request #4404 from ansible/i18n_release_3.7.1_translations
UI translation strings for release_3.7.1 branch
2020-06-15 17:10:10 -04:00
ansible-translation-bot
40eb3e43f8 UI translation strings for release_3.7.1 branch 2020-06-12 17:03:37 +00:00
Jim Ladd
e1f7a7619f Merge pull request #4398 from jladdjr/instance_id_fallback
Instance id fallback
2020-06-11 12:19:23 -07:00
Jim Ladd
8eee0d40dd revert EC2_INSTANCE_ID_VAR 2020-06-11 09:52:54 -07:00
Ryan Petrello
fe221c2473 Merge pull request #4399 from shanemcd/kube-queues
Add queue / instance group registration to heartbeat for k8s installs
2020-06-11 09:00:16 -04:00
Jim Ladd
9514adaf3a wrap --instance-id-var in quotes 2020-06-10 13:55:54 -07:00
Shane McDonald
85deb8711c Add queue / instance group registration to heartbeat for k8s installs
There is some history here.

https://github.com/ansible/awx/pull/7190 <- This PR was an attempt at fixing a
bug notting ran into where some jobs on k8s installs would get stuck in Waiting
forever.

The PR mentioned above introduced a bug where there are no instance groups on a
fresh k8s-based install. This is because this process currently happens in the
launch scripts, before the database is up.

With this patch, queue / instance group registration happens in the heartbeat,
right after auto-registering the instance.
2020-06-10 16:55:27 -04:00
Jim Ladd
17eaeb28a8 update VMWARE_INSTANCE_ID_VAR
* Favor instanceUuid
* .. but fall back to instanceuuid if necessary
2020-06-10 13:30:05 -07:00
Ryan Petrello
7c1959010a Merge pull request #4396 from jladdjr/foreman_script_should_not_use_reports_3.7.1
disable reports option for foreman (release_3.7.1)
2020-06-10 08:30:14 -04:00
AlanCoding
1dd9772e41 Allow use of fallback instance_ids 2020-06-09 22:51:42 -07:00
Jim Ladd
18d09f892d disable reports option for foreman 2020-06-09 22:37:35 -07:00
Jake McDermott
ee6f03515e Merge pull request #4340 from jakemcdermott/fix-4336
[3.7.1] Enable management job notications for admins
2020-06-09 16:27:07 -04:00
Jake McDermott
16f81154c0 Merge pull request #4338 from mabashian/4334-backport-v2
[3.7.1] Fixes bug where all_parents_must_converge was not being set for new or existing approval nodes
2020-06-09 15:36:40 -04:00
Ryan Petrello
1d7e2a82c6 Merge pull request #4393 from kdelee/backport_dont_block_log_send
[3.7.1] don't block on log aggregator socket.send() calls
2020-06-09 14:49:43 -04:00
Ryan Petrello
b7ac5f0ffb Merge pull request #4395 from fosterseth/fix-parents_converge_settable_api_backport
[backport] Make all_parents_must_converge settable when creating node
2020-06-09 11:29:34 -04:00
Seth Foster
0e5f68ef53 Make all_parents_must_converge settable when creating node
When targeting, ../workflow_job_templates/id#/workflow_nodes/ endpoint,
user could not set all_parents_must_converge to true.

3.7.1 backport for awx issue #7063
2020-06-09 11:07:22 -04:00
Ryan Petrello
a057a2e056 Merge pull request #4394 from ryanpetrello/mattermost-371
Send content-type with mattermost notifications, fixes #7264
2020-06-09 10:35:55 -04:00
Florian Apolloner
e9e410f4f8 Send content-type with mattermost notifications, fixes #7264 2020-06-09 10:32:32 -04:00
Ryan Petrello
71cc359ccf don't block on log aggregator socket.send() calls
see: https://github.com/ansible/tower/issues/4391
2020-06-09 10:10:32 -04:00
Sean Sullivan
104073af45 Merge pull request #1 from ansible/devel
Merging remote to devel
2020-06-09 07:50:36 -05:00
Chris Meyers
37c1c33ecd Merge pull request #4389 from chrismeyersfsu/fix-run_wsbroadcast_status_3_7_1
awx-manage run_wsbroadcast --status doesn't work in openshift
2020-06-08 20:18:32 -04:00
chris meyers
2f7ba75ae4 track stats by hostname not remote host/ip
* broadcast websockets have stats tracked (i.e. connection status,
number of messages total, messages per minute, etc). Previous to this
change, stats were tracked by ip address, if it was defined on the
instance, XOR hostname. This changeset tracks stats by hostname.
2020-06-08 16:35:17 -04:00
chris meyers
9c20b9412a delete and re-add host when ip address changes
* The websocket backplane interconnect is done via ip address for
Kubernetes and OpenShift. On init run_wsbroadcast reads all Instances
from the DB and makes a decision to use the ip address or the hostname
based, with preference given to the ip address if defined. For
Kubernetes and OpenShift the nodes can load the Instance before the
ip_address is set. This would cause the connection to be tried by
hostname rather than ip address. This changeset ensures that an ip
address set after an Instance record is created will be detected and
used.
2020-06-08 16:34:51 -04:00
Ryan Petrello
99c0a954e4 Merge pull request #4384 from ryanpetrello/rsyslog-chmod
properly write rsyslog configuration as 0640
2020-06-08 14:05:18 -04:00
Jim Ladd
0a0735344e Merge pull request #4342 from jladdjr/foreman_group_prefix_should_apply_to_all_groups_3.7.1
foreman: use group_prefix for all groups (release_3.7.1)
2020-06-05 15:25:22 -07:00
Jim Ladd
9ae344b772 foreman: use group_prefix for all groups
* awx's "compatibility layer" for the foreman plugin had the
  group_prefix hard-coded to 'foreman_'
2020-06-05 14:44:55 -07:00
Jim Ladd
0c4adfb32e Merge pull request #4387 from jladdjr/bump_foreman_collection_0.8.1
Bump foreman collection to 0.8.1
2020-06-05 12:10:22 -07:00
Jim Ladd
4ce37ec849 Bump foreman collection to 0.8.1
* New release includes:
  'add host_filters and want_ansible_ssh_host like script used to have'
2020-06-05 11:13:01 -07:00
Ryan Petrello
c53e5bdbcf properly write rsyslog configuration as 0640
see: https://github.com/ansible/tower/issues/4383
2020-06-04 15:12:09 -04:00
Christian Adams
e0032f7705 Merge pull request #4367 from rooftopcellist/sumologic_conf
Correctly parse sumologic url paths
2020-06-01 01:36:20 -04:00
Christian Adams
ed05ce164f Merge pull request #4377 from rooftopcellist/cleanup_flake8
Fix misc. linter errors due to the flake8-3.8.1 release
2020-05-29 19:29:17 -04:00
Christian Adams
d98f2714cb Merge pull request #4376 from rooftopcellist/rm_label_3.7.1
Fix 500 on Label Removal for WFJT's [3.7.1]
2020-05-29 18:11:45 -04:00
beeankha
85426f76a5 Fix misc. linter errors due to the flake8-3.8.1 release
- [Ref] https://flake8.pycqa.org/en/latest/release-notes/
2020-05-29 17:58:27 -04:00
Christian Adams
c48da1b384 allow org admins to remove labels 2020-05-29 15:12:35 -04:00
Christian Adams
aec7d3cc93 Correctly parse sumologic url paths
- Sumologic includes a token with a '==' at the end of it's host path.
   This adds rsyslog conf parsing tests and does not escape equals
   signs.
2020-05-27 13:05:31 -04:00
Ryan Petrello
bd23c41d25 Merge pull request #4361 from ryanpetrello/venv-try-except
[3.7.1] backport a change to address venv permission issues
2020-05-26 11:31:16 -04:00
gamuniz
563d3944ed removed pass per feedback 2020-05-26 11:21:58 -04:00
Gabe Muniz
492d01ff3b added try/except to virtual env 2020-05-26 11:21:49 -04:00
Elijah DeLee
3ded30411f Merge pull request #4341 from kdelee/backport_host_summary_optimization_3.7.1
Backport host summary optimization 3.7.1
2020-05-21 13:37:16 -04:00
Bill Nottingham
b38c62d37f Merge pull request #4353 from wenottingham/analytics-skip-3.7.1
Always check configuration before gathering data.
2020-05-21 13:23:08 -04:00
Bill Nottingham
4c499b2d80 Always check configuration before gathering data.
We shouldn't perform expensive operations if we won't be able to send it.
Only log at debug level, otherwise every node will log this every 5
minutes.
2020-05-20 17:24:38 -04:00
Ryan Petrello
3d02bd7a90 Merge pull request #4350 from ryanpetrello/371-os-walkdir-recursive
Revert "follow symlinks while discovering valid playbooks"
2020-05-20 16:50:28 -04:00
Ryan Petrello
71257c18c2 Revert "follow symlinks while discovering valid playbooks"
This reverts commit 3dd21d720e.
2020-05-20 16:47:38 -04:00
Ryan Petrello
d85df2e4a1 further optimize job host summary queries 2020-05-19 13:00:12 -04:00
Ryan Petrello
59d457207c properly update .failed, .last_job_id, and last_job_host_summary 2020-05-19 13:00:05 -04:00
Ryan Petrello
3ea642f212 properly handle host summary bulk updates if hosts go missing 2020-05-19 13:00:00 -04:00
Ryan Petrello
b6d3c3c1a3 drastically optimize job host summary creation
see: https://github.com/ansible/awx/issues/6991
2020-05-19 12:59:54 -04:00
Jake McDermott
b83db0500f Enable management job notications for admins 2020-05-19 10:52:09 -04:00
mabashian
c4d9b81c55 Fixes bug where all_parents_must_converge was not being set for new or existing approval nodes. 2020-05-18 15:16:05 -04:00
Shane McDonald
cdfc9e05d4 Fix offline RHEL 8 builds
This was causing our EL8 Brew builds to break, because it wasn't being
vendored. This is in fact required for python3. It was being resolved as a
dependency of other things (see list at end of line), so it was being downloaded
on-the-fly since our normal builds have internet access. It only broke when it
wasn't vendored for offline builds.
2020-05-15 17:52:08 -04:00
2492 changed files with 72602 additions and 207214 deletions

View File

@@ -3,6 +3,12 @@ name: "\U0001F41B Bug report"
about: Create a report to help us improve
---
<!-- Issues are for **concrete, actionable bugs and feature requests** only - if you're just asking for debugging help or technical support, please use:
- http://webchat.freenode.net/?channels=ansible-awx
- https://groups.google.com/forum/#!forum/awx-project
We have to limit this because of limited volunteer time to respond to issues! -->
##### ISSUE TYPE
- Bug Report

View File

@@ -3,6 +3,12 @@ name: "✨ Feature request"
about: Suggest an idea for this project
---
<!-- Issues are for **concrete, actionable bugs and feature requests** only - if you're just asking for debugging help or technical support, please use:
- http://webchat.freenode.net/?channels=ansible-awx
- https://groups.google.com/forum/#!forum/awx-project
We have to limit this because of limited volunteer time to respond to issues! -->
##### ISSUE TYPE
- Feature Idea

9
.gitignore vendored
View File

@@ -29,11 +29,11 @@ awx/ui/client/languages
awx/ui/templates/ui/index.html
awx/ui/templates/ui/installing.html
awx/ui_next/node_modules/
awx/ui_next/src/locales/
awx/ui_next/coverage/
awx/ui_next/build/locales/_build
awx/ui_next/build
awx/ui_next/.env.local
rsyslog.pid
/tower-license
/tower-license/**
tools/prometheus/data
tools/docker-compose/Dockerfile
@@ -139,9 +139,10 @@ use_dev_supervisor.txt
# Ansible module tests
/awx_collection_test_venv/
/awx_collection/*.tar.gz
/awx_collection/galaxy.yml
/sanity/
/awx_collection_build/
.idea/*
*.unison.tmp
*.#
/tools/docker-compose/overrides/

View File

@@ -2,8 +2,101 @@
This is a list of high-level changes for each release of AWX. A full list of commits can be found at `https://github.com/ansible/awx/releases/tag/<version>`.
## 16.0.0 (December 10, 2020)
- AWX now ships with a reimagined user interface. **Please read this before upgrading:** https://groups.google.com/g/awx-project/c/KuT5Ao92HWo
- Removed support for syncing inventory from Red Hat CloudForms - https://github.com/ansible/awx/commit/0b701b3b2
- Removed support for Mercurial-based project updates - https://github.com/ansible/awx/issues/7932
- Upgraded NodeJS to actively maintained LTS 14.15.1 - https://github.com/ansible/awx/pull/8766
- Added Git-LFS to the default image build - https://github.com/ansible/awx/pull/8700
- Added the ability to specify `metadata.labels` in the podspec for container groups - https://github.com/ansible/awx/issues/8486
- Added support for Kubernetes pod annotations - https://github.com/ansible/awx/pull/8434
- Added the ability to label the web container in local Docker installs - https://github.com/ansible/awx/pull/8449
- Added additional metadata (as an extra var) to playbook runs to report the SCM branch name - https://github.com/ansible/awx/pull/8433
- Fixed a bug that caused k8s installations to fail due to an incorrect Helm repo - https://github.com/ansible/awx/issues/8715
- Fixed a bug that prevented certain Workflow Approval resources from being deleted - https://github.com/ansible/awx/pull/8612
- Fixed a bug that prevented the deletion of inventories stuck in "pending deletion" state - https://github.com/ansible/awx/issues/8525
- Fixed a display bug in webhook notifications with certain unicode characters - https://github.com/ansible/awx/issues/7400
- Improved support for exporting dependent objects (Inventory Hosts and Groups) in the `awx export` CLI tool - https://github.com/ansible/awx/commit/607bc0788
## 15.0.1 (October 20, 2020)
- Added several optimizations to improve performance for a variety of high-load simultaneous job launch use cases https://github.com/ansible/awx/pull/8403
- Added the ability to source roles and collections from requirements.yaml files (not just requirements.yml) - https://github.com/ansible/awx/issues/4540
- awx.awx collection modules now provide a clearer error message for incompatible versions of awxkit - https://github.com/ansible/awx/issues/8127
- Fixed a bug in notification messages that contain certain unicode characters - https://github.com/ansible/awx/issues/7400
- Fixed a bug that prevents the deletion of Workflow Approval records - https://github.com/ansible/awx/issues/8305
- Fixed a bug that broke the selection of webhook credentials - https://github.com/ansible/awx/issues/7892
- Fixed a bug which can cause confusing behavior for social auth logins across distinct browser tabs - https://github.com/ansible/awx/issues/8154
- Fixed several bugs in the output of Workflow Job Templates using the `awx export` tool - https://github.com/ansible/awx/issues/7798 https://github.com/ansible/awx/pull/7847
- Fixed a race condition that can lead to missing hosts when running parallel inventory syncs - https://github.com/ansible/awx/issues/5571
- Fixed an HTTP 500 error when certain LDAP group parameters aren't properly set - https://github.com/ansible/awx/issues/7622
- Updated a few dependencies in response to several CVEs:
* CVE-2020-7720
* CVE-2020-7743
* CVE-2020-7676
## 15.0.0 (September 30, 2020)
- Added improved support for fetching Ansible collections from private Galaxy content sources (such as https://github.com/ansible/galaxy_ng) - https://github.com/ansible/awx/issues/7813
**Note:** as part of this change, new Organizations created in the AWX API will _no longer_ automatically synchronize roles and collections from galaxy.ansible.com by default. More details on this change can be found at: https://github.com/ansible/awx/issues/8341#issuecomment-707310633
- AWX now utilizes a version of certifi that auto-discovers certificates in the system certificate store - https://github.com/ansible/awx/pull/8242
- Added support for arbitrary custom inventory plugin configuration: https://github.com/ansible/awx/issues/5150
- Added an optional setting to disable the auto-creation of organizations and teams on successful SAML login. - https://github.com/ansible/awx/pull/8069
- Added a number of optimizations to AWX's callback receiver to improve the speed of stdout processing for simultaneous playbooks runs - https://github.com/ansible/awx/pull/8193 https://github.com/ansible/awx/pull/8191
- Added the ability to use `!include` and `!import` constructors when constructing YAML for use with the AWX CLI - https://github.com/ansible/awx/issues/8135
- Fixed a bug that prevented certain users from being able to edit approval nodes in Workflows - https://github.com/ansible/awx/pull/8253
- Fixed a bug that broke password prompting for credentials in certain cases - https://github.com/ansible/awx/issues/8202
- Fixed a bug which can cause PostgreSQL deadlocks when running many parallel playbooks against large shared inventories - https://github.com/ansible/awx/issues/8145
- Fixed a bug which can cause delays in AWX's task manager when large numbers of simultaneous jobs are scheduled - https://github.com/ansible/awx/issues/7655
- Fixed a bug which can cause certain scheduled jobs - those that run every X minute(s) or hour(s) - to fail to run at the proper time - https://github.com/ansible/awx/issues/8071
- Fixed a performance issue for playbooks that store large amounts of data using the `set_stats` module - https://github.com/ansible/awx/issues/8006
- Fixed a bug related to AWX's handling of the auth_path argument for the HashiVault KeyValue credential plugin - https://github.com/ansible/awx/pull/7991
- Fixed a bug that broke support for Remote Archive SCM Type project syncs on platforms that utilize Python2 - https://github.com/ansible/awx/pull/8057
- Updated to the latest version of Django Rest Framework to address CVE-2020-25626
- Updated to the latest version of Django to address CVE-2020-24583 and CVE-2020-24584
- Updated to the latest verson of channels_redis to address a bug that slowly causes Daphne processes to leak memory over time - https://github.com/django/channels_redis/issues/212
## 14.1.0 (Aug 25, 2020)
- AWX images can now be built on ARM64 - https://github.com/ansible/awx/pull/7607
- Added the Remote Archive SCM Type to support using immutable artifacts and releases (such as tarballs and zip files) as projects - https://github.com/ansible/awx/issues/7954
- Deprecated official support for Mercurial-based project updates - https://github.com/ansible/awx/issues/7932
- Added resource import/export support to the official AWX collection - https://github.com/ansible/awx/issues/7329
- Added the ability to import YAML-based resources (instead of just JSON) when using the AWX CLI - https://github.com/ansible/awx/pull/7808
- Users upgrading from older versions of AWX may encounter an issue that causes their postgres container to restart in a loop (https://github.com/ansible/awx/issues/7854) - if you encounter this, bring your containers down and then back up (e.g., `docker-compose down && docker-compose up -d`) after upgrading to 14.1.0.
- Updated the AWX CLI to export labels associated with Workflow Job Templates - https://github.com/ansible/awx/pull/7847
- Updated to the latest python-ldap to address a bug - https://github.com/ansible/awx/issues/7868
- Upgraded git-python to fix a bug that caused workflows to sometimes fail - https://github.com/ansible/awx/issues/6119
- Worked around a bug in the channels_redis library that slowly causes Daphne processes to leak memory over time - https://github.com/django/channels_redis/issues/212
- Fixed a bug in the AWX CLI that prevented Workflow nodes from importing properly - https://github.com/ansible/awx/issues/7793
- Fixed a bug in the awx.awx collection release process that templated the wrong version - https://github.com/ansible/awx/issues/7870
- Fixed a bug that caused errors rendering stdout that contained UTF-16 surrogate pairs - https://github.com/ansible/awx/pull/7918
## 14.0.0 (Aug 6, 2020)
- As part of our commitment to inclusivity in open source, we recently took some time to audit AWX's source code and user interface and replace certain terminology with more inclusive language. Strictly speaking, this isn't a bug or a feature, but we think it's important and worth calling attention to:
* https://github.com/ansible/awx/commit/78229f58715fbfbf88177e54031f532543b57acc
* https://www.redhat.com/en/blog/making-open-source-more-inclusive-eradicating-problematic-language
- Installing roles and collections via requirements.yml as part of Project Updates now requires at least Ansible 2.9 - https://github.com/ansible/awx/issues/7769
- Deprecated the use of the `PRIMARY_GALAXY_USERNAME` and `PRIMARY_GALAXY_PASSWORD` settings. We recommend using tokens to access Galaxy or Automation Hub.
- Added local caching for downloaded roles and collections so they are not re-downloaded on nodes where they are up to date with the project - https://github.com/ansible/awx/issues/5518
- Added the ability to associate K8S/OpenShift credentials to Job Template for playbook interaction with the `community.kubernetes` collection - https://github.com/ansible/awx/issues/5735
- Added the ability to include HTML in the Custom Login Info presented on the login page - https://github.com/ansible/awx/issues/7600
- Fixed https://access.redhat.com/security/cve/cve-2020-14327 - Server-side request forgery on credentials
- Fixed https://access.redhat.com/security/cve/cve-2020-14328 - Server-side request forgery on webhooks
- Fixed https://access.redhat.com/security/cve/cve-2020-14329 - Sensitive data exposure on labels
- Fixed https://access.redhat.com/security/cve/cve-2020-14337 - Named URLs allow for testing the presence or absence of objects
- Fixed a number of bugs in the user interface related to an upgrade of jQuery:
* https://github.com/ansible/awx/issues/7530
* https://github.com/ansible/awx/issues/7546
* https://github.com/ansible/awx/issues/7534
* https://github.com/ansible/awx/issues/7606
- Fixed a bug that caused the `-f yaml` flag of the AWX CLI to not print properly formatted YAML - https://github.com/ansible/awx/issues/7795
- Fixed a bug in the installer that caused errors when `docker_registry_password` was set - https://github.com/ansible/awx/issues/7695
- Fixed a permissions error that prevented certain users from starting AWX services - https://github.com/ansible/awx/issues/7545
- Fixed a bug that allows superusers to run unsafe Jinja code when defining custom Credential Types - https://github.com/ansible/awx/pull/7584/
- Fixed a bug that prevented users from creating (or editing) custom Credential Types containing boolean fields - https://github.com/ansible/awx/issues/7483
- Fixed a bug that prevented users with postgres usernames containing uppercase letters from restoring backups succesfully - https://github.com/ansible/awx/pull/7519
- Fixed a bug which allowed the creation (in the Tower API) of Groups and Hosts with the same name - https://github.com/ansible/awx/issues/4680
## 13.0.0 (Jun 23, 2020)
- Added import and export subcommands to the awx-cli tool, replacing send and receive from the old tower-cli (https://github.com/ansible/awx/pull/6125).
- Added import and export commands to the official AWX CLI, replacing send and receive from the old tower-cli (https://github.com/ansible/awx/pull/6125).
- Removed scripts as a means of running inventory updates of built-in types (https://github.com/ansible/awx/pull/6911)
- Ansible 2.8 is now partially unsupported; some inventory source types are known to no longer work.
- Fixed an issue where the vmware inventory source ssl_verify source variable was not recognized (https://github.com/ansible/awx/pull/7360)
@@ -11,11 +104,11 @@ This is a list of high-level changes for each release of AWX. A full list of com
- Fixed a bug that caused rsyslogd's configuration file to have world-readable file permissions, potentially leaking secrets (CVE-2020-10782)
## 12.0.0 (Jun 9, 2020)
- Removed memcached as a dependency of AWX (https://github.com/ansible/awx/pull/7240)
- Removed memcached as a dependency of AWX (https://github.com/ansible/awx/pull/7240)
- Moved to a single container image build instead of separate awx_web and awx_task images. The container image is just `awx` (https://github.com/ansible/awx/pull/7228)
- Official AWX container image builds now use a two-stage container build process that notably reduces the size of our published images (https://github.com/ansible/awx/pull/7017)
- Removed support for HipChat notifications ([EoL announcement](https://www.atlassian.com/partnerships/slack/faq#faq-98b17ca3-247f-423b-9a78-70a91681eff0)); all previously-created HipChat notification templates will be deleted due to this removal.
- Fixed a bug which broke AWX installations with oc version 4.3 (https://github.com/ansible/awx/pull/6948/files)
- Fixed a bug which broke AWX installations with oc version 4.3 (https://github.com/ansible/awx/pull/6948/)
- Fixed a performance issue that caused notable delay of stdout processing for playbooks run against large numbers of hosts (https://github.com/ansible/awx/issues/6991)
- Fixed a bug that caused CyberArk AIM credential plugin looks to hang forever in some environments (https://github.com/ansible/awx/issues/6986)
- Fixed a bug that caused ANY/ALL converage settings not to properly save when editing approval nodes in the UI (https://github.com/ansible/awx/issues/6998)

View File

@@ -80,7 +80,7 @@ For Linux platforms, refer to the following from Docker:
If you're not using Docker for Mac, or Docker for Windows, you may need, or choose to, install the Docker compose Python module separately, in which case you'll need to run the following:
```bash
(host)$ pip install docker-compose
(host)$ pip3 install docker-compose
```
#### Frontend Development

View File

@@ -43,7 +43,7 @@ This document provides a guide for installing AWX.
- [Installing the AWX CLI](#installing-the-awx-cli)
* [Building the CLI Documentation](#building-the-cli-documentation)
## Getting started
### Clone the repo
@@ -78,10 +78,12 @@ Before you can run a deployment, you'll need the following installed in your loc
- [docker](https://pypi.org/project/docker/) Python module
+ This is incompatible with `docker-py`. If you have previously installed `docker-py`, please uninstall it.
+ We use this module instead of `docker-py` because it is what the `docker-compose` Python module requires.
- [community.general.docker_image collection](https://docs.ansible.com/ansible/latest/collections/community/general/docker_image_module.html)
+ This is only required if you are using Ansible >= 2.10
- [GNU Make](https://www.gnu.org/software/make/)
- [Git](https://git-scm.com/) Requires Version 1.8.4+
- Python 3.6+
- [Node 10.x LTS version](https://nodejs.org/en/download/)
- [Node 14.x LTS version](https://nodejs.org/en/download/)
+ This is only required if you're [building your own container images](#official-vs-building-images) with `use_container_for_build=false`
- [NPM 6.x LTS](https://docs.npmjs.com/)
+ This is only required if you're [building your own container images](#official-vs-building-images) with `use_container_for_build=false`
@@ -351,7 +353,7 @@ Once you access the AWX server, you will be prompted with a login dialog. The de
A Kubernetes deployment will require you to have access to a Kubernetes cluster as well as the following tools:
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
- [helm](https://docs.helm.sh/using_helm/#quickstart-guide)
- [helm](https://helm.sh/docs/intro/quickstart/)
The installation program will reference `kubectl` directly. `helm` is only necessary if you are letting the installer configure PostgreSQL for you.
@@ -382,9 +384,11 @@ Before starting the install process, review the [inventory](./installer/inventor
### Configuring Helm
If you want the AWX installer to manage creating the database pod (rather than installing and configuring postgres on your own). Then you will need to have a working `helm` installation, you can find details here: [https://docs.helm.sh/using_helm/#quickstart-guide](https://docs.helm.sh/using_helm/#quickstart-guide).
If you want the AWX installer to manage creating the database pod (rather than installing and configuring postgres on your own). Then you will need to have a working `helm` installation, you can find details here: [https://helm.sh/docs/intro/quickstart/](https://helm.sh/docs/intro/quickstart/).
Newer Kubernetes clusters with RBAC enabled will need to make sure a service account is created, make sure to follow the instructions here [https://docs.helm.sh/using_helm/#role-based-access-control](https://docs.helm.sh/using_helm/#role-based-access-control)
You do not need to create a [Persistent Volume Claim](https://docs.openshift.org/latest/dev_guide/persistent_volumes.html) as Helm does it for you. However, an existing one may be used by setting the `pg_persistence_existingclaim` variable.
Newer Kubernetes clusters with RBAC enabled will need to make sure a service account is created, make sure to follow the instructions here [https://helm.sh/docs/topics/rbac/](https://helm.sh/docs/topics/rbac/)
### Run the installer
@@ -575,7 +579,7 @@ If you're deploying using Docker Compose, container names will be prefixed by th
Immediately after the containers start, the *awx_task* container will perform required setup tasks, including database migrations. These tasks need to complete before the web interface can be accessed. To monitor the progress, you can follow the container's STDOUT by running the following:
```bash
# Tail the the awx_task log
# Tail the awx_task log
$ docker logs -f awx_task
```
@@ -651,17 +655,16 @@ Potential uses include:
* Checking on the status and output of job runs
* Managing objects like organizations, users, teams, etc...
The preferred way to install the AWX CLI is through pip directly from GitHub:
The preferred way to install the AWX CLI is through pip directly from PyPI:
pip install "https://github.com/ansible/awx/archive/$VERSION.tar.gz#egg=awxkit&subdirectory=awxkit"
pip3 install awxkit
awx --help
...where ``$VERSION`` is the version of AWX you're running. To see a list of all available releases, visit: https://github.com/ansible/awx/releases
## Building the CLI Documentation
To build the docs, spin up a real AWX server, `pip install sphinx sphinxcontrib-autoprogram`, and run:
To build the docs, spin up a real AWX server, `pip3 install sphinx sphinxcontrib-autoprogram`, and run:
~ cd awxkit/awxkit/cli/docs
~ TOWER_HOST=https://awx.example.org TOWER_USERNAME=example TOWER_PASSWORD=secret make clean html
~ cd build/html/ && python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ..

View File

@@ -31,7 +31,7 @@ If your issue isn't considered high priority, then please be patient as it may t
`state:needs_info` The issue needs more information. This could be more debug output, more specifics out the system such as version information. Any detail that is currently preventing this issue from moving forward. This should be considered a blocked state.
`state:needs_review` The the issue/pull request needs to be reviewed by other maintainers and contributors. This is usually used when there is a question out to another maintainer or when a person is less familar with an area of the code base the issue is for.
`state:needs_review` The issue/pull request needs to be reviewed by other maintainers and contributors. This is usually used when there is a question out to another maintainer or when a person is less familar with an area of the code base the issue is for.
`state:needs_revision` More commonly used on pull requests, this state represents that there are changes that are being waited on.

View File

@@ -4,8 +4,8 @@ recursive-include awx *.mo
recursive-include awx/static *
recursive-include awx/templates *.html
recursive-include awx/api/templates *.md *.html
recursive-include awx/ui/templates *.html
recursive-include awx/ui/static *
recursive-include awx/ui_next/build *.html
recursive-include awx/ui_next/build *
recursive-include awx/playbooks *.yml
recursive-include awx/lib/site-packages *
recursive-include awx/plugins *.ps1

152
Makefile
View File

@@ -56,11 +56,6 @@ WHEEL_COMMAND ?= bdist_wheel
SDIST_TAR_FILE ?= $(SDIST_TAR_NAME).tar.gz
WHEEL_FILE ?= $(WHEEL_NAME)-py2-none-any.whl
# UI flag files
UI_DEPS_FLAG_FILE = awx/ui/.deps_built
UI_RELEASE_DEPS_FLAG_FILE = awx/ui/.release_deps_built
UI_RELEASE_FLAG_FILE = awx/ui/.release_built
I18N_FLAG_FILE = .i18n_built
.PHONY: awx-link clean clean-tmp clean-venv requirements requirements_dev \
@@ -70,21 +65,6 @@ I18N_FLAG_FILE = .i18n_built
ui-docker-machine ui-docker ui-release ui-devel \
ui-test ui-deps ui-test-ci VERSION
# remove ui build artifacts
clean-ui: clean-languages
rm -rf awx/ui/static/
rm -rf awx/ui/node_modules/
rm -rf awx/ui/test/unit/reports/
rm -rf awx/ui/test/spec/reports/
rm -rf awx/ui/test/e2e/reports/
rm -rf awx/ui/client/languages/
rm -rf awx/ui_next/node_modules/
rm -rf awx/ui_next/coverage/
rm -rf awx/ui_next/build/locales/_build/
rm -f $(UI_DEPS_FLAG_FILE)
rm -f $(UI_RELEASE_DEPS_FLAG_FILE)
rm -f $(UI_RELEASE_FLAG_FILE)
clean-tmp:
rm -rf tmp/
@@ -213,7 +193,11 @@ requirements_awx_dev:
requirements_collections:
mkdir -p $(COLLECTION_BASE)
ansible-galaxy collection install -r requirements/collections_requirements.yml -p $(COLLECTION_BASE)
n=0; \
until [ "$$n" -ge 5 ]; do \
ansible-galaxy collection install -r requirements/collections_requirements.yml -p $(COLLECTION_BASE) && break; \
n=$$((n+1)); \
done
requirements: requirements_ansible requirements_awx requirements_collections
@@ -368,7 +352,7 @@ test:
PYTHONDONTWRITEBYTECODE=1 py.test -p no:cacheprovider -n auto $(TEST_DIRS)
cmp VERSION awxkit/VERSION || "VERSION and awxkit/VERSION *must* match"
cd awxkit && $(VENV_BASE)/awx/bin/tox -re py3
awx-manage check_migrations --dry-run --check -n 'vNNN_missing_migration_file'
awx-manage check_migrations --dry-run --check -n 'missing_migration_file'
COLLECTION_TEST_DIRS ?= awx_collection/test/awx
COLLECTION_TEST_TARGET ?=
@@ -401,11 +385,11 @@ symlink_collection:
build_collection:
ansible-playbook -i localhost, awx_collection/tools/template_galaxy.yml -e collection_package=$(COLLECTION_PACKAGE) -e collection_namespace=$(COLLECTION_NAMESPACE) -e collection_version=$(VERSION) -e '{"awx_template_version":false}'
ansible-galaxy collection build awx_collection --force --output-path=awx_collection
ansible-galaxy collection build awx_collection_build --force --output-path=awx_collection_build
install_collection: build_collection
rm -rf $(COLLECTION_INSTALL)
ansible-galaxy collection install awx_collection/$(COLLECTION_NAMESPACE)-$(COLLECTION_PACKAGE)-$(VERSION).tar.gz
ansible-galaxy collection install awx_collection_build/$(COLLECTION_NAMESPACE)-$(COLLECTION_PACKAGE)-$(VERSION).tar.gz
test_collection_sanity: install_collection
cd $(COLLECTION_INSTALL) && ansible-test sanity
@@ -475,116 +459,36 @@ else
@echo No PO files
endif
# generate UI .pot
pot: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run pot
# generate django .pot .po
LANG = "en-us"
messages:
@if [ "$(VENV_BASE)" ]; then \
. $(VENV_BASE)/awx/bin/activate; \
fi; \
$(PYTHON) manage.py makemessages -l $(LANG) --keep-pot
# generate l10n .json .mo
languages: $(I18N_FLAG_FILE)
$(I18N_FLAG_FILE): $(UI_RELEASE_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run languages
$(PYTHON) tools/scripts/compilemessages.py
touch $(I18N_FLAG_FILE)
# End l10n TASKS
# --------------------------------------
# UI RELEASE TASKS
# --------------------------------------
ui-release: $(UI_RELEASE_FLAG_FILE)
$(UI_RELEASE_FLAG_FILE): $(I18N_FLAG_FILE) $(UI_RELEASE_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run build-release
touch $(UI_RELEASE_FLAG_FILE)
$(UI_RELEASE_DEPS_FLAG_FILE):
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 $(NPM_BIN) --unsafe-perm --prefix awx/ui ci --no-save awx/ui
touch $(UI_RELEASE_DEPS_FLAG_FILE)
# END UI RELEASE TASKS
# --------------------------------------
# UI TASKS
# --------------------------------------
ui-deps: $(UI_DEPS_FLAG_FILE)
awx/ui_next/node_modules:
$(NPM_BIN) --prefix awx/ui_next install
$(UI_DEPS_FLAG_FILE):
@if [ -f ${UI_RELEASE_DEPS_FLAG_FILE} ]; then \
rm -rf awx/ui/node_modules; \
rm -f ${UI_RELEASE_DEPS_FLAG_FILE}; \
fi; \
$(NPM_BIN) --unsafe-perm --prefix awx/ui ci --no-save awx/ui
touch $(UI_DEPS_FLAG_FILE)
clean-ui:
rm -rf node_modules
rm -rf awx/ui_next/node_modules
rm -rf awx/ui_next/build
ui-docker-machine: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run ui-docker-machine -- $(MAKEFLAGS)
# Native docker. Builds UI and raises BrowserSync & filesystem polling.
ui-docker: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run ui-docker -- $(MAKEFLAGS)
# Builds UI with development UI without raising browser-sync or filesystem polling.
ui-devel: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run build-devel -- $(MAKEFLAGS)
ui-test: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run test
ui-lint: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) run --prefix awx/ui jshint
$(NPM_BIN) run --prefix awx/ui lint
# A standard go-to target for API developers to use building the frontend
ui: clean-ui ui-devel
ui-test-ci: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) --prefix awx/ui run test:ci
$(NPM_BIN) --prefix awx/ui run unit
jshint: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) run --prefix awx/ui jshint
$(NPM_BIN) run --prefix awx/ui lint
ui-release: ui-devel
ui-devel: awx/ui_next/node_modules
$(NPM_BIN) --prefix awx/ui_next run extract-strings
$(NPM_BIN) --prefix awx/ui_next run compile-strings
$(NPM_BIN) --prefix awx/ui_next run build
git checkout awx/ui_next/src/locales
mkdir -p awx/public/static/css
mkdir -p awx/public/static/js
mkdir -p awx/public/static/media
cp -r awx/ui_next/build/static/css/* awx/public/static/css
cp -r awx/ui_next/build/static/js/* awx/public/static/js
cp -r awx/ui_next/build/static/media/* awx/public/static/media
ui-zuul-lint-and-test:
CHROMIUM_BIN=$(CHROMIUM_BIN) ./awx/ui/build/zuul_download_chromium.sh
CHROMIUM_BIN=$(CHROMIUM_BIN) PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 $(NPM_BIN) --unsafe-perm --prefix awx/ui ci --no-save awx/ui
CHROMIUM_BIN=$(CHROMIUM_BIN) $(NPM_BIN) run --prefix awx/ui jshint
CHROMIUM_BIN=$(CHROMIUM_BIN) $(NPM_BIN) run --prefix awx/ui lint
CHROME_BIN=$(CHROMIUM_BIN) $(NPM_BIN) --prefix awx/ui run test:ci
CHROME_BIN=$(CHROMIUM_BIN) $(NPM_BIN) --prefix awx/ui run unit
# END UI TASKS
# --------------------------------------
# UI NEXT TASKS
# --------------------------------------
ui-next-lint:
$(NPM_BIN) --prefix awx/ui_next install
$(NPM_BIN) run --prefix awx/ui_next lint
$(NPM_BIN) run --prefix awx/ui_next prettier-check
ui-next-test:
$(NPM_BIN) --prefix awx/ui_next install
$(NPM_BIN) run --prefix awx/ui_next test
ui-next-zuul-lint-and-test:
$(NPM_BIN) --prefix awx/ui_next install
$(NPM_BIN) run --prefix awx/ui_next lint
$(NPM_BIN) run --prefix awx/ui_next prettier-check
$(NPM_BIN) run --prefix awx/ui_next test
# END UI NEXT TASKS
# --------------------------------------
# Build a pip-installable package into dist/ with a timestamped version number.
dev_build:
@@ -631,9 +535,11 @@ awx/projects:
docker-compose-isolated: awx/projects
CURRENT_UID=$(shell id -u) TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose -f tools/docker-compose.yml -f tools/docker-isolated-override.yml up
COMPOSE_UP_OPTS ?=
# Docker Compose Development environment
docker-compose: docker-auth awx/projects
CURRENT_UID=$(shell id -u) OS="$(shell docker info | grep 'Operating System')" TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose -f tools/docker-compose.yml up --no-recreate awx
CURRENT_UID=$(shell id -u) OS="$(shell docker info | grep 'Operating System')" TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose -f tools/docker-compose.yml $(COMPOSE_UP_OPTS) up --no-recreate awx
docker-compose-cluster: docker-auth awx/projects
CURRENT_UID=$(shell id -u) TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose -f tools/docker-compose-cluster.yml up

View File

@@ -1 +1 @@
13.0.0
16.0.0

View File

@@ -16,6 +16,7 @@ register(
help_text=_('Number of seconds that a user is inactive before they will need to login again.'),
category=_('Authentication'),
category_slug='authentication',
unit=_('seconds'),
)
register(
'SESSIONS_PER_USER',
@@ -49,6 +50,7 @@ register(
'in the number of seconds.'),
category=_('Authentication'),
category_slug='authentication',
unit=_('seconds'),
)
register(
'ALLOW_OAUTH2_FOR_EXTERNAL_USERS',

View File

@@ -146,7 +146,7 @@ class FieldLookupBackend(BaseFilterBackend):
# A list of fields that we know can be filtered on without the possiblity
# of introducing duplicates
NO_DUPLICATES_WHITELIST = (CharField, IntegerField, BooleanField)
NO_DUPLICATES_ALLOW_LIST = (CharField, IntegerField, BooleanField)
def get_fields_from_lookup(self, model, lookup):
@@ -205,7 +205,7 @@ class FieldLookupBackend(BaseFilterBackend):
field_list, new_lookup = self.get_fields_from_lookup(model, lookup)
field = field_list[-1]
needs_distinct = (not all(isinstance(f, self.NO_DUPLICATES_WHITELIST) for f in field_list))
needs_distinct = (not all(isinstance(f, self.NO_DUPLICATES_ALLOW_LIST) for f in field_list))
# Type names are stored without underscores internally, but are presented and
# and serialized over the API containing underscores so we remove `_`
@@ -257,6 +257,11 @@ class FieldLookupBackend(BaseFilterBackend):
if key in self.RESERVED_NAMES:
continue
# HACK: make `created` available via API for the Django User ORM model
# so it keep compatiblity with other objects which exposes the `created` attr.
if queryset.model._meta.object_name == 'User' and key.startswith('created'):
key = key.replace('created', 'date_joined')
# HACK: Make job event filtering by host name mostly work even
# when not capturing job event hosts M2M.
if queryset.model._meta.object_name == 'JobEvent' and key.startswith('hosts__name'):

View File

@@ -47,10 +47,9 @@ from awx.main.utils import (
get_object_or_400,
decrypt_field,
get_awx_version,
get_licenser,
StubLicense
)
from awx.main.utils.db import get_all_field_names
from awx.main.views import ApiErrorView
from awx.api.serializers import ResourceAccessListElementSerializer, CopySerializer, UserSerializer
from awx.api.versioning import URLPathVersioning
from awx.api.metadata import SublistAttachDetatchMetadata, Metadata
@@ -159,11 +158,11 @@ class APIView(views.APIView):
self.queries_before = len(connection.queries)
# If there are any custom headers in REMOTE_HOST_HEADERS, make sure
# they respect the proxy whitelist
# they respect the allowed proxy list
if all([
settings.PROXY_IP_WHITELIST,
request.environ.get('REMOTE_ADDR') not in settings.PROXY_IP_WHITELIST,
request.environ.get('REMOTE_HOST') not in settings.PROXY_IP_WHITELIST
settings.PROXY_IP_ALLOWED_LIST,
request.environ.get('REMOTE_ADDR') not in settings.PROXY_IP_ALLOWED_LIST,
request.environ.get('REMOTE_HOST') not in settings.PROXY_IP_ALLOWED_LIST
]):
for custom_header in settings.REMOTE_HOST_HEADERS:
if custom_header.startswith('HTTP_'):
@@ -188,6 +187,30 @@ class APIView(views.APIView):
'''
Log warning for 400 requests. Add header with elapsed time.
'''
from awx.main.utils import get_licenser
from awx.main.utils.licensing import OpenLicense
#
# If the URL was rewritten, and we get a 404, we should entirely
# replace the view in the request context with an ApiErrorView()
# Without this change, there will be subtle differences in the BrowseableAPIRenderer
#
# These differences could provide contextual clues which would allow
# anonymous users to determine if usernames were valid or not
# (e.g., if an anonymous user visited `/api/v2/users/valid/`, and got a 404,
# but also saw that the page heading said "User Detail", they might notice
# that's a difference in behavior from a request to `/api/v2/users/not-valid/`, which
# would show a page header of "Not Found"). Changing the view here
# guarantees that the rendered response will look exactly like the response
# when you visit a URL that has no matching URL paths in `awx.api.urls`.
#
if response.status_code == 404 and 'awx.named_url_rewritten' in request.environ:
self.headers.pop('Allow', None)
response = super(APIView, self).finalize_response(request, response, *args, **kwargs)
view = ApiErrorView()
setattr(view, 'request', request)
response.renderer_context['view'] = view
return response
if response.status_code >= 400:
status_msg = "status %s received by user %s attempting to access %s from %s" % \
(response.status_code, request.user, request.path, request.META.get('REMOTE_ADDR', None))
@@ -201,7 +224,8 @@ class APIView(views.APIView):
response = super(APIView, self).finalize_response(request, response, *args, **kwargs)
time_started = getattr(self, 'time_started', None)
response['X-API-Product-Version'] = get_awx_version()
response['X-API-Product-Name'] = 'AWX' if isinstance(get_licenser(), StubLicense) else 'Red Hat Ansible Tower'
response['X-API-Product-Name'] = 'AWX' if isinstance(get_licenser(), OpenLicense) else 'Red Hat Ansible Tower'
response['X-API-Node'] = settings.CLUSTER_HOST_ID
if time_started:
time_elapsed = time.time() - self.time_started
@@ -837,7 +861,7 @@ class CopyAPIView(GenericAPIView):
@staticmethod
def _decrypt_model_field_if_needed(obj, field_name, field_val):
if field_name in getattr(type(obj), 'REENCRYPTION_BLACKLIST_AT_COPY', []):
if field_name in getattr(type(obj), 'REENCRYPTION_BLOCKLIST_AT_COPY', []):
return field_val
if isinstance(obj, Credential) and field_name == 'inputs':
for secret in obj.credential_type.secret_fields:
@@ -883,7 +907,7 @@ class CopyAPIView(GenericAPIView):
field_val = getattr(obj, field.name)
except AttributeError:
continue
# Adjust copy blacklist fields here.
# Adjust copy blocked fields here.
if field.name in fields_to_discard or field.name in [
'id', 'pk', 'polymorphic_ctype', 'unifiedjobtemplate_ptr', 'created_by', 'modified_by'
] or field.name.endswith('_role'):

View File

@@ -23,7 +23,7 @@ from rest_framework.request import clone_request
# AWX
from awx.api.fields import ChoiceNullField
from awx.main.fields import JSONField, ImplicitRoleField
from awx.main.models import InventorySource, NotificationTemplate
from awx.main.models import NotificationTemplate
from awx.main.scheduler.kubernetes import PodManager
@@ -39,7 +39,7 @@ class Metadata(metadata.SimpleMetadata):
'min_length', 'max_length',
'min_value', 'max_value',
'category', 'category_slug',
'defined_in_file'
'defined_in_file', 'unit',
]
for attr in text_attrs:
@@ -115,19 +115,6 @@ class Metadata(metadata.SimpleMetadata):
if getattr(field, 'write_only', False):
field_info['write_only'] = True
# Special handling of inventory source_region choices that vary based on
# selected inventory source.
if field.field_name == 'source_regions':
for cp in ('azure_rm', 'ec2', 'gce'):
get_regions = getattr(InventorySource, 'get_%s_region_choices' % cp)
field_info['%s_region_choices' % cp] = get_regions()
# Special handling of group_by choices for EC2.
if field.field_name == 'group_by':
for cp in ('ec2',):
get_group_by_choices = getattr(InventorySource, 'get_%s_group_by_choices' % cp)
field_info['%s_group_by_choices' % cp] = get_group_by_choices()
# Special handling of notification configuration where the required properties
# are conditional on the type selected.
if field.field_name == 'notification_configuration':

View File

@@ -7,6 +7,24 @@ from prometheus_client.parser import text_string_to_metric_families
# Django REST Framework
from rest_framework import renderers
from rest_framework.request import override_method
from rest_framework.utils import encoders
class SurrogateEncoder(encoders.JSONEncoder):
def encode(self, obj):
ret = super(SurrogateEncoder, self).encode(obj)
try:
ret.encode()
except UnicodeEncodeError as e:
if 'surrogates not allowed' in e.reason:
ret = ret.encode('utf-8', 'replace').decode()
return ret
class DefaultJSONRenderer(renderers.JSONRenderer):
encoder_class = SurrogateEncoder
class BrowsableAPIRenderer(renderers.BrowsableAPIRenderer):

View File

@@ -453,7 +453,7 @@ class BaseSerializer(serializers.ModelSerializer, metaclass=BaseSerializerMetacl
if 'capability_map' not in self.context:
if hasattr(self, 'polymorphic_base'):
model = self.polymorphic_base.Meta.model
prefetch_list = self.polymorphic_base._capabilities_prefetch
prefetch_list = self.polymorphic_base.capabilities_prefetch
else:
model = self.Meta.model
prefetch_list = self.capabilities_prefetch
@@ -640,12 +640,9 @@ class EmptySerializer(serializers.Serializer):
class UnifiedJobTemplateSerializer(BaseSerializer):
# As a base serializer, the capabilities prefetch is not used directly
_capabilities_prefetch = [
'admin', 'execute',
{'copy': ['jobtemplate.project.use', 'jobtemplate.inventory.use',
'organization.workflow_admin']}
]
# As a base serializer, the capabilities prefetch is not used directly,
# instead they are derived from the Workflow Job Template Serializer and the Job Template Serializer, respectively.
capabilities_prefetch = []
class Meta:
model = UnifiedJobTemplate
@@ -695,7 +692,7 @@ class UnifiedJobTemplateSerializer(BaseSerializer):
serializer.polymorphic_base = self
# capabilities prefetch is only valid for these models
if isinstance(obj, (JobTemplate, WorkflowJobTemplate)):
serializer.capabilities_prefetch = self._capabilities_prefetch
serializer.capabilities_prefetch = serializer_class.capabilities_prefetch
else:
serializer.capabilities_prefetch = None
return serializer.to_representation(obj)
@@ -1269,6 +1266,7 @@ class OrganizationSerializer(BaseSerializer):
object_roles = self.reverse('api:organization_object_roles_list', kwargs={'pk': obj.pk}),
access_list = self.reverse('api:organization_access_list', kwargs={'pk': obj.pk}),
instance_groups = self.reverse('api:organization_instance_groups_list', kwargs={'pk': obj.pk}),
galaxy_credentials = self.reverse('api:organization_galaxy_credentials_list', kwargs={'pk': obj.pk}),
))
return res
@@ -1332,10 +1330,14 @@ class ProjectOptionsSerializer(BaseSerializer):
scm_type = attrs.get('scm_type', u'') or u''
if self.instance and not scm_type:
valid_local_paths.append(self.instance.local_path)
if self.instance and scm_type and "local_path" in attrs and self.instance.local_path != attrs['local_path']:
errors['local_path'] = _(f'Cannot change local_path for {scm_type}-based projects')
if scm_type:
attrs.pop('local_path', None)
if 'local_path' in attrs and attrs['local_path'] not in valid_local_paths:
errors['local_path'] = _('This path is already being used by another manual project.')
if attrs.get('scm_branch') and scm_type == 'archive':
errors['scm_branch'] = _('SCM branch cannot be used with archive projects.')
if attrs.get('scm_refspec') and scm_type != 'git':
errors['scm_refspec'] = _('SCM refspec can only be used with git projects.')
@@ -1697,9 +1699,13 @@ class HostSerializer(BaseSerializerWithVariables):
d.setdefault('recent_jobs', [{
'id': j.job.id,
'name': j.job.job_template.name if j.job.job_template is not None else "",
'type': j.job.job_type_name,
'status': j.job.status,
'finished': j.job.finished,
} for j in obj.job_host_summaries.select_related('job__job_template').order_by('-created')[:5]])
} for j in obj.job_host_summaries.select_related('job__job_template').order_by('-created').defer(
'job__extra_vars',
'job__artifacts',
)[:5]])
return d
def _get_host_port_from_name(self, name):
@@ -1731,6 +1737,7 @@ class HostSerializer(BaseSerializerWithVariables):
def validate(self, attrs):
name = force_text(attrs.get('name', self.instance and self.instance.name or ''))
inventory = attrs.get('inventory', self.instance and self.instance.inventory or '')
host, port = self._get_host_port_from_name(name)
if port:
@@ -1739,6 +1746,8 @@ class HostSerializer(BaseSerializerWithVariables):
vars_dict = parse_yaml_or_json(variables)
vars_dict['ansible_ssh_port'] = port
attrs['variables'] = json.dumps(vars_dict)
if Group.objects.filter(name=name, inventory=inventory).exists():
raise serializers.ValidationError(_('A Group with that name already exists.'))
return super(HostSerializer, self).validate(attrs)
@@ -1805,6 +1814,13 @@ class GroupSerializer(BaseSerializerWithVariables):
res['inventory'] = self.reverse('api:inventory_detail', kwargs={'pk': obj.inventory.pk})
return res
def validate(self, attrs):
name = force_text(attrs.get('name', self.instance and self.instance.name or ''))
inventory = attrs.get('inventory', self.instance and self.instance.inventory or '')
if Host.objects.filter(name=name, inventory=inventory).exists():
raise serializers.ValidationError(_('A Host with that name already exists.'))
return super(GroupSerializer, self).validate(attrs)
def validate_name(self, value):
if value in ('all', '_meta'):
raise serializers.ValidationError(_('Invalid group name.'))
@@ -1921,7 +1937,7 @@ class InventorySourceOptionsSerializer(BaseSerializer):
class Meta:
fields = ('*', 'source', 'source_path', 'source_script', 'source_vars', 'credential',
'source_regions', 'instance_filters', 'group_by', 'overwrite', 'overwrite_vars',
'enabled_var', 'enabled_value', 'host_filter', 'overwrite', 'overwrite_vars',
'custom_virtualenv', 'timeout', 'verbosity')
def get_related(self, obj):
@@ -1936,12 +1952,12 @@ class InventorySourceOptionsSerializer(BaseSerializer):
def validate_source_vars(self, value):
ret = vars_validate_or_raise(value)
for env_k in parse_yaml_or_json(value):
if env_k in settings.INV_ENV_VARIABLE_BLACKLIST:
if env_k in settings.INV_ENV_VARIABLE_BLOCKED:
raise serializers.ValidationError(_("`{}` is a prohibited environment variable".format(env_k)))
return ret
def validate(self, attrs):
# TODO: Validate source, validate source_regions
# TODO: Validate source
errors = {}
source = attrs.get('source', self.instance and self.instance.source or '')
@@ -2520,10 +2536,11 @@ class CredentialTypeSerializer(BaseSerializer):
class CredentialSerializer(BaseSerializer):
show_capabilities = ['edit', 'delete', 'copy', 'use']
capabilities_prefetch = ['admin', 'use']
managed_by_tower = serializers.ReadOnlyField()
class Meta:
model = Credential
fields = ('*', 'organization', 'credential_type', 'inputs', 'kind', 'cloud', 'kubernetes')
fields = ('*', 'organization', 'credential_type', 'managed_by_tower', 'inputs', 'kind', 'cloud', 'kubernetes')
extra_kwargs = {
'credential_type': {
'label': _('Credential Type'),
@@ -2587,6 +2604,13 @@ class CredentialSerializer(BaseSerializer):
return summary_dict
def validate(self, attrs):
if self.instance and self.instance.managed_by_tower:
raise PermissionDenied(
detail=_("Modifications not allowed for managed credentials")
)
return super(CredentialSerializer, self).validate(attrs)
def get_validation_exclusions(self, obj=None):
ret = super(CredentialSerializer, self).get_validation_exclusions(obj)
for field in ('credential_type', 'inputs'):
@@ -2594,6 +2618,17 @@ class CredentialSerializer(BaseSerializer):
ret.remove(field)
return ret
def validate_organization(self, org):
if (
self.instance and
self.instance.credential_type.kind == 'galaxy' and
org is None
):
raise serializers.ValidationError(_(
"Galaxy credentials must be owned by an Organization."
))
return org
def validate_credential_type(self, credential_type):
if self.instance and credential_type.pk != self.instance.credential_type.pk:
for related_objects in (
@@ -2658,6 +2693,15 @@ class CredentialSerializerCreate(CredentialSerializer):
if attrs.get('team'):
attrs['organization'] = attrs['team'].organization
if (
'credential_type' in attrs and
attrs['credential_type'].kind == 'galaxy' and
list(owner_fields) != ['organization']
):
raise serializers.ValidationError({"organization": _(
"Galaxy credentials must be owned by an Organization."
)})
return super(CredentialSerializerCreate, self).validate(attrs)
def create(self, validated_data):
@@ -2831,7 +2875,7 @@ class JobTemplateMixin(object):
return [{
'id': x.id, 'status': x.status, 'finished': x.finished, 'canceled_on': x.canceled_on,
# Make type consistent with API top-level key, for instance workflow_job
'type': x.get_real_instance_class()._meta.verbose_name.replace(' ', '_')
'type': x.job_type_name
} for x in optimized_qs[:10]]
def get_summary_fields(self, obj):
@@ -3393,6 +3437,12 @@ class WorkflowJobTemplateSerializer(JobTemplateMixin, LabelsListMixin, UnifiedJo
res['organization'] = self.reverse('api:organization_detail', kwargs={'pk': obj.organization.pk})
if obj.webhook_credential_id:
res['webhook_credential'] = self.reverse('api:credential_detail', kwargs={'pk': obj.webhook_credential_id})
if obj.inventory_id:
res['inventory'] = self.reverse(
'api:inventory_detail', kwargs={
'pk': obj.inventory_id
}
)
return res
def validate_extra_vars(self, value):
@@ -3895,12 +3945,12 @@ class ProjectUpdateEventSerializer(JobEventSerializer):
return UriCleaner.remove_sensitive(obj.stdout)
def get_event_data(self, obj):
# the project update playbook uses the git, hg, or svn modules
# the project update playbook uses the git or svn modules
# to clone repositories, and those modules are prone to printing
# raw SCM URLs in their stdout (which *could* contain passwords)
# attempt to detect and filter HTTP basic auth passwords in the stdout
# of these types of events
if obj.event_data.get('task_action') in ('git', 'hg', 'svn'):
if obj.event_data.get('task_action') in ('git', 'svn'):
try:
return json.loads(
UriCleaner.remove_sensitive(
@@ -4089,7 +4139,8 @@ class JobLaunchSerializer(BaseSerializer):
errors.setdefault('credentials', []).append(_(
'Cannot assign multiple {} credentials.'
).format(cred.unique_hash(display=True)))
if cred.credential_type.kind not in ('ssh', 'vault', 'cloud', 'net'):
if cred.credential_type.kind not in ('ssh', 'vault', 'cloud',
'net', 'kubernetes'):
errors.setdefault('credentials', []).append(_(
'Cannot assign a Credential of kind `{}`'
).format(cred.credential_type.kind))
@@ -4111,7 +4162,10 @@ class JobLaunchSerializer(BaseSerializer):
# verify that credentials (either provided or existing) don't
# require launch-time passwords that have not been provided
if 'credentials' in accepted:
launch_credentials = accepted['credentials']
launch_credentials = Credential.unique_dict(
list(template_credentials.all()) +
list(accepted['credentials'])
).values()
else:
launch_credentials = template_credentials
passwords = attrs.get('credential_passwords', {}) # get from original attrs
@@ -4653,6 +4707,8 @@ class InstanceSerializer(BaseSerializer):
class InstanceGroupSerializer(BaseSerializer):
show_capabilities = ['edit', 'delete']
committed_capacity = serializers.SerializerMethodField()
consumed_capacity = serializers.SerializerMethodField()
percent_capacity_remaining = serializers.SerializerMethodField()

View File

@@ -4,7 +4,6 @@ The following lists the expected format and details of our rrules:
* DTSTART is expected to be in UTC
* INTERVAL is required
* SECONDLY is not supported
* TZID is not supported
* RRULE must precede the rule statements
* BYDAY is supported but not BYDAY with a numerical prefix
* BYYEARDAY and BYWEEKNO are not supported

View File

@@ -8,7 +8,7 @@ The `period` of the data can be adjusted with:
?period=month
Where `month` can be replaced with `week`, or `day`. `month` is the default.
Where `month` can be replaced with `week`, `two_weeks`, or `day`. `month` is the default.
The type of job can be filtered with:

View File

@@ -21,6 +21,7 @@ from awx.api.views import (
OrganizationNotificationTemplatesSuccessList,
OrganizationNotificationTemplatesApprovalList,
OrganizationInstanceGroupsList,
OrganizationGalaxyCredentialsList,
OrganizationObjectRolesList,
OrganizationAccessList,
OrganizationApplicationList,
@@ -49,6 +50,7 @@ urls = [
url(r'^(?P<pk>[0-9]+)/notification_templates_approvals/$', OrganizationNotificationTemplatesApprovalList.as_view(),
name='organization_notification_templates_approvals_list'),
url(r'^(?P<pk>[0-9]+)/instance_groups/$', OrganizationInstanceGroupsList.as_view(), name='organization_instance_groups_list'),
url(r'^(?P<pk>[0-9]+)/galaxy_credentials/$', OrganizationGalaxyCredentialsList.as_view(), name='organization_galaxy_credentials_list'),
url(r'^(?P<pk>[0-9]+)/object_roles/$', OrganizationObjectRolesList.as_view(), name='organization_object_roles_list'),
url(r'^(?P<pk>[0-9]+)/access_list/$', OrganizationAccessList.as_view(), name='organization_access_list'),
url(r'^(?P<pk>[0-9]+)/applications/$', OrganizationApplicationList.as_view(), name='organization_applications_list'),

View File

@@ -15,6 +15,7 @@ from awx.api.views import (
ApiV2PingView,
ApiV2ConfigView,
ApiV2SubscriptionView,
ApiV2AttachView,
AuthView,
UserMeList,
DashboardView,
@@ -94,6 +95,7 @@ v2_urls = [
url(r'^ping/$', ApiV2PingView.as_view(), name='api_v2_ping_view'),
url(r'^config/$', ApiV2ConfigView.as_view(), name='api_v2_config_view'),
url(r'^config/subscriptions/$', ApiV2SubscriptionView.as_view(), name='api_v2_subscription_view'),
url(r'^config/attach/$', ApiV2AttachView.as_view(), name='api_v2_attach_view'),
url(r'^auth/$', AuthView.as_view()),
url(r'^me/$', UserMeList.as_view(), name='user_me_list'),
url(r'^dashboard/$', DashboardView.as_view(), name='dashboard_view'),

View File

@@ -14,6 +14,8 @@ import time
from base64 import b64encode
from collections import OrderedDict
from urllib3.exceptions import ConnectTimeoutError
# Django
from django.conf import settings
@@ -122,6 +124,7 @@ from awx.api.views.organization import ( # noqa
OrganizationNotificationTemplatesSuccessList,
OrganizationNotificationTemplatesApprovalList,
OrganizationInstanceGroupsList,
OrganizationGalaxyCredentialsList,
OrganizationAccessList,
OrganizationObjectRolesList,
)
@@ -150,6 +153,7 @@ from awx.api.views.root import ( # noqa
ApiV2PingView,
ApiV2ConfigView,
ApiV2SubscriptionView,
ApiV2AttachView,
)
from awx.api.views.webhooks import ( # noqa
WebhookKeyView,
@@ -171,6 +175,15 @@ def api_exception_handler(exc, context):
exc = ParseError(exc.args[0])
if isinstance(context['view'], UnifiedJobStdout):
context['view'].renderer_classes = [renderers.BrowsableAPIRenderer, JSONRenderer]
if isinstance(exc, APIException):
req = context['request']._request
if 'awx.named_url_rewritten' in req.environ and not str(getattr(exc, 'status_code', 0)).startswith('2'):
# if the URL was rewritten, and it's not a 2xx level status code,
# revert the request.path to its original value to avoid leaking
# any context about the existance of resources
req.path = req.environ['awx.named_url_rewritten']
if exc.status_code == 403:
exc = NotFound(detail=_('Not found.'))
return exception_handler(exc, context)
@@ -229,8 +242,8 @@ class DashboardView(APIView):
git_failed_projects = git_projects.filter(last_job_failed=True)
svn_projects = user_projects.filter(scm_type='svn')
svn_failed_projects = svn_projects.filter(last_job_failed=True)
hg_projects = user_projects.filter(scm_type='hg')
hg_failed_projects = hg_projects.filter(last_job_failed=True)
archive_projects = user_projects.filter(scm_type='archive')
archive_failed_projects = archive_projects.filter(last_job_failed=True)
data['scm_types'] = {}
data['scm_types']['git'] = {'url': reverse('api:project_list', request=request) + "?scm_type=git",
'label': 'Git',
@@ -242,11 +255,11 @@ class DashboardView(APIView):
'failures_url': reverse('api:project_list', request=request) + "?scm_type=svn&last_job_failed=True",
'total': svn_projects.count(),
'failed': svn_failed_projects.count()}
data['scm_types']['hg'] = {'url': reverse('api:project_list', request=request) + "?scm_type=hg",
'label': 'Mercurial',
'failures_url': reverse('api:project_list', request=request) + "?scm_type=hg&last_job_failed=True",
'total': hg_projects.count(),
'failed': hg_failed_projects.count()}
data['scm_types']['archive'] = {'url': reverse('api:project_list', request=request) + "?scm_type=archive",
'label': 'Remote Archive',
'failures_url': reverse('api:project_list', request=request) + "?scm_type=archive&last_job_failed=True",
'total': archive_projects.count(),
'failed': archive_failed_projects.count()}
user_list = get_user_queryset(request.user, models.User)
team_list = get_user_queryset(request.user, models.Team)
@@ -297,6 +310,9 @@ class DashboardJobsGraphView(APIView):
if period == 'month':
end_date = start_date - dateutil.relativedelta.relativedelta(months=1)
interval = 'days'
elif period == 'two_weeks':
end_date = start_date - dateutil.relativedelta.relativedelta(weeks=2)
interval = 'days'
elif period == 'week':
end_date = start_date - dateutil.relativedelta.relativedelta(weeks=1)
interval = 'days'
@@ -1337,6 +1353,13 @@ class CredentialDetail(RetrieveUpdateDestroyAPIView):
model = models.Credential
serializer_class = serializers.CredentialSerializer
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
if instance.managed_by_tower:
raise PermissionDenied(detail=_("Deletion not allowed for managed credentials"))
return super(CredentialDetail, self).destroy(request, *args, **kwargs)
class CredentialActivityStreamList(SubListAPIView):
@@ -1397,10 +1420,18 @@ class CredentialExternalTest(SubDetailAPIView):
obj.credential_type.plugin.backend(**backend_kwargs)
return Response({}, status=status.HTTP_202_ACCEPTED)
except requests.exceptions.HTTPError as exc:
message = 'HTTP {}\n{}'.format(exc.response.status_code, exc.response.text)
message = 'HTTP {}'.format(exc.response.status_code)
return Response({'inputs': message}, status=status.HTTP_400_BAD_REQUEST)
except Exception as exc:
return Response({'inputs': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
message = exc.__class__.__name__
args = getattr(exc, 'args', [])
for a in args:
if isinstance(
getattr(a, 'reason', None),
ConnectTimeoutError
):
message = str(a.reason)
return Response({'inputs': message}, status=status.HTTP_400_BAD_REQUEST)
class CredentialInputSourceDetail(RetrieveUpdateDestroyAPIView):
@@ -1449,10 +1480,18 @@ class CredentialTypeExternalTest(SubDetailAPIView):
obj.plugin.backend(**backend_kwargs)
return Response({}, status=status.HTTP_202_ACCEPTED)
except requests.exceptions.HTTPError as exc:
message = 'HTTP {}\n{}'.format(exc.response.status_code, exc.response.text)
message = 'HTTP {}'.format(exc.response.status_code)
return Response({'inputs': message}, status=status.HTTP_400_BAD_REQUEST)
except Exception as exc:
return Response({'inputs': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
message = exc.__class__.__name__
args = getattr(exc, 'args', [])
for a in args:
if isinstance(
getattr(a, 'reason', None),
ConnectTimeoutError
):
message = str(a.reason)
return Response({'inputs': message}, status=status.HTTP_400_BAD_REQUEST)
class HostRelatedSearchMixin(object):
@@ -2657,7 +2696,7 @@ class JobTemplateCredentialsList(SubListCreateAttachDetachAPIView):
return {"error": _("Cannot assign multiple {credential_type} credentials.").format(
credential_type=sub.unique_hash(display=True))}
kind = sub.credential_type.kind
if kind not in ('ssh', 'vault', 'cloud', 'net'):
if kind not in ('ssh', 'vault', 'cloud', 'net', 'kubernetes'):
return {'error': _('Cannot assign a Credential of kind `{}`.').format(kind)}
return super(JobTemplateCredentialsList, self).is_valid_relation(parent, sub, created)
@@ -3001,7 +3040,7 @@ class WorkflowJobTemplateNodeCreateApproval(RetrieveAPIView):
approval_template,
context=self.get_serializer_context()
).data
return Response(data, status=status.HTTP_200_OK)
return Response(data, status=status.HTTP_201_CREATED)
def check_permissions(self, request):
obj = self.get_object().workflow_job_template
@@ -4211,7 +4250,9 @@ class NotificationTemplateDetail(RetrieveUpdateDestroyAPIView):
obj = self.get_object()
if not request.user.can_access(self.model, 'delete', obj):
return Response(status=status.HTTP_404_NOT_FOUND)
if obj.notifications.filter(status='pending').exists():
hours_old = now() - dateutil.relativedelta.relativedelta(hours=8)
if obj.notifications.filter(status='pending', created__gt=hours_old).exists():
return Response({"error": _("Delete not allowed while there are pending notifications")},
status=status.HTTP_405_METHOD_NOT_ALLOWED)
return super(NotificationTemplateDetail, self).delete(request, *args, **kwargs)

View File

@@ -134,7 +134,8 @@ class InventoryDetail(RelatedJobsPreventDeleteMixin, ControlledByScmMixin, Retri
# Do not allow changes to an Inventory kind.
if kind is not None and obj.kind != kind:
return self.http_method_not_allowed(request, *args, **kwargs)
return Response(dict(error=_('You cannot turn a regular inventory into a "smart" inventory.')),
status=status.HTTP_405_METHOD_NOT_ALLOWED)
return super(InventoryDetail, self).update(request, *args, **kwargs)
def destroy(self, request, *args, **kwargs):

View File

@@ -22,7 +22,7 @@ from awx.api.generics import (
)
logger = logging.getLogger('awx.main.analytics')
logger = logging.getLogger('awx.analytics')
class MetricsView(APIView):

View File

@@ -7,6 +7,7 @@ import logging
# Django
from django.db.models import Count
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext_lazy as _
# AWX
from awx.main.models import (
@@ -20,7 +21,8 @@ from awx.main.models import (
Role,
User,
Team,
InstanceGroup
InstanceGroup,
Credential
)
from awx.api.generics import (
ListCreateAPIView,
@@ -42,7 +44,8 @@ from awx.api.serializers import (
RoleSerializer,
NotificationTemplateSerializer,
InstanceGroupSerializer,
ProjectSerializer, JobTemplateSerializer, WorkflowJobTemplateSerializer
ProjectSerializer, JobTemplateSerializer, WorkflowJobTemplateSerializer,
CredentialSerializer
)
from awx.api.views.mixin import (
RelatedJobsPreventDeleteMixin,
@@ -214,6 +217,20 @@ class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
relationship = 'instance_groups'
class OrganizationGalaxyCredentialsList(SubListAttachDetachAPIView):
model = Credential
serializer_class = CredentialSerializer
parent_model = Organization
relationship = 'galaxy_credentials'
def is_valid_relation(self, parent, sub, created=False):
if sub.kind != 'galaxy_api_token':
return {'msg': _(
f"Credential must be a Galaxy credential, not {sub.credential_type.name}."
)}
class OrganizationAccessList(ResourceAccessList):
model = User # needs to be User for AccessLists's

View File

@@ -1,9 +1,10 @@
# Copyright (c) 2018 Ansible, Inc.
# All Rights Reserved.
import base64
import json
import logging
import operator
import json
from collections import OrderedDict
from django.conf import settings
@@ -21,6 +22,7 @@ import requests
from awx.api.generics import APIView
from awx.conf.registry import settings_registry
from awx.main.analytics import all_collectors
from awx.main.ha import is_ha_environment
from awx.main.utils import (
get_awx_version,
@@ -28,8 +30,8 @@ from awx.main.utils import (
get_custom_venv_choices,
to_python_boolean,
)
from awx.main.utils.licensing import validate_entitlement_manifest
from awx.api.versioning import reverse, drf_reverse
from awx.conf.license import get_license
from awx.main.constants import PRIVILEGE_ESCALATION_METHODS
from awx.main.models import (
Project,
@@ -177,7 +179,7 @@ class ApiV2PingView(APIView):
class ApiV2SubscriptionView(APIView):
permission_classes = (IsAuthenticated,)
name = _('Configuration')
name = _('Subscriptions')
swagger_topic = 'System Configuration'
def check_permissions(self, request):
@@ -188,18 +190,18 @@ class ApiV2SubscriptionView(APIView):
def post(self, request):
from awx.main.utils.common import get_licenser
data = request.data.copy()
if data.get('rh_password') == '$encrypted$':
data['rh_password'] = settings.REDHAT_PASSWORD
if data.get('subscriptions_password') == '$encrypted$':
data['subscriptions_password'] = settings.SUBSCRIPTIONS_PASSWORD
try:
user, pw = data.get('rh_username'), data.get('rh_password')
user, pw = data.get('subscriptions_username'), data.get('subscriptions_password')
with set_environ(**settings.AWX_TASK_ENV):
validated = get_licenser().validate_rh(user, pw)
if user:
settings.REDHAT_USERNAME = data['rh_username']
settings.SUBSCRIPTIONS_USERNAME = data['subscriptions_username']
if pw:
settings.REDHAT_PASSWORD = data['rh_password']
settings.SUBSCRIPTIONS_PASSWORD = data['subscriptions_password']
except Exception as exc:
msg = _("Invalid License")
msg = _("Invalid Subscription")
if (
isinstance(exc, requests.exceptions.HTTPError) and
getattr(getattr(exc, 'response', None), 'status_code', None) == 401
@@ -212,13 +214,63 @@ class ApiV2SubscriptionView(APIView):
elif isinstance(exc, (ValueError, OSError)) and exc.args:
msg = exc.args[0]
else:
logger.exception(smart_text(u"Invalid license submitted."),
logger.exception(smart_text(u"Invalid subscription submitted."),
extra=dict(actor=request.user.username))
return Response({"error": msg}, status=status.HTTP_400_BAD_REQUEST)
return Response(validated)
class ApiV2AttachView(APIView):
permission_classes = (IsAuthenticated,)
name = _('Attach Subscription')
swagger_topic = 'System Configuration'
def check_permissions(self, request):
super(ApiV2AttachView, self).check_permissions(request)
if not request.user.is_superuser and request.method.lower() not in {'options', 'head'}:
self.permission_denied(request) # Raises PermissionDenied exception.
def post(self, request):
data = request.data.copy()
pool_id = data.get('pool_id', None)
if not pool_id:
return Response({"error": _("No subscription pool ID provided.")}, status=status.HTTP_400_BAD_REQUEST)
user = getattr(settings, 'SUBSCRIPTIONS_USERNAME', None)
pw = getattr(settings, 'SUBSCRIPTIONS_PASSWORD', None)
if pool_id and user and pw:
from awx.main.utils.common import get_licenser
data = request.data.copy()
try:
with set_environ(**settings.AWX_TASK_ENV):
validated = get_licenser().validate_rh(user, pw)
except Exception as exc:
msg = _("Invalid Subscription")
if (
isinstance(exc, requests.exceptions.HTTPError) and
getattr(getattr(exc, 'response', None), 'status_code', None) == 401
):
msg = _("The provided credentials are invalid (HTTP 401).")
elif isinstance(exc, requests.exceptions.ProxyError):
msg = _("Unable to connect to proxy server.")
elif isinstance(exc, requests.exceptions.ConnectionError):
msg = _("Could not connect to subscription service.")
elif isinstance(exc, (ValueError, OSError)) and exc.args:
msg = exc.args[0]
else:
logger.exception(smart_text(u"Invalid subscription submitted."),
extra=dict(actor=request.user.username))
return Response({"error": msg}, status=status.HTTP_400_BAD_REQUEST)
for sub in validated:
if sub['pool_id'] == pool_id:
sub['valid_key'] = True
settings.LICENSE = sub
return Response(sub)
return Response({"error": _("Error processing subscription metadata.")}, status=status.HTTP_400_BAD_REQUEST)
class ApiV2ConfigView(APIView):
permission_classes = (IsAuthenticated,)
@@ -233,15 +285,11 @@ class ApiV2ConfigView(APIView):
def get(self, request, format=None):
'''Return various sitewide configuration settings'''
if request.user.is_superuser or request.user.is_system_auditor:
license_data = get_license(show_key=True)
else:
license_data = get_license(show_key=False)
from awx.main.utils.common import get_licenser
license_data = get_licenser().validate()
if not license_data.get('valid_key', False):
license_data = {}
if license_data and 'features' in license_data and 'activity_streams' in license_data['features']:
# FIXME: Make the final setting value dependent on the feature?
license_data['features']['activity_streams'] &= settings.ACTIVITY_STREAM_ENABLED
pendo_state = settings.PENDO_TRACKING_STATE if settings.PENDO_TRACKING_STATE in ('off', 'anonymous', 'detailed') else 'off'
@@ -252,6 +300,7 @@ class ApiV2ConfigView(APIView):
ansible_version=get_ansible_version(),
eula=render_to_string("eula.md") if license_data.get('license_type', 'UNLICENSED') != 'open' else '',
analytics_status=pendo_state,
analytics_collectors=all_collectors(),
become_methods=PRIVILEGE_ESCALATION_METHODS,
)
@@ -279,9 +328,10 @@ class ApiV2ConfigView(APIView):
return Response(data)
def post(self, request):
if not isinstance(request.data, dict):
return Response({"error": _("Invalid license data")}, status=status.HTTP_400_BAD_REQUEST)
return Response({"error": _("Invalid subscription data")}, status=status.HTTP_400_BAD_REQUEST)
if "eula_accepted" not in request.data:
return Response({"error": _("Missing 'eula_accepted' property")}, status=status.HTTP_400_BAD_REQUEST)
try:
@@ -298,25 +348,47 @@ class ApiV2ConfigView(APIView):
logger.info(smart_text(u"Invalid JSON submitted for license."),
extra=dict(actor=request.user.username))
return Response({"error": _("Invalid JSON")}, status=status.HTTP_400_BAD_REQUEST)
try:
from awx.main.utils.common import get_licenser
license_data = json.loads(data_actual)
license_data_validated = get_licenser(**license_data).validate()
except Exception:
logger.warning(smart_text(u"Invalid license submitted."),
extra=dict(actor=request.user.username))
return Response({"error": _("Invalid License")}, status=status.HTTP_400_BAD_REQUEST)
from awx.main.utils.common import get_licenser
license_data = json.loads(data_actual)
if 'license_key' in license_data:
return Response({"error": _('Legacy license submitted. A subscription manifest is now required.')}, status=status.HTTP_400_BAD_REQUEST)
if 'manifest' in license_data:
try:
json_actual = json.loads(base64.b64decode(license_data['manifest']))
if 'license_key' in json_actual:
return Response(
{"error": _('Legacy license submitted. A subscription manifest is now required.')},
status=status.HTTP_400_BAD_REQUEST
)
except Exception:
pass
try:
license_data = validate_entitlement_manifest(license_data['manifest'])
except ValueError as e:
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
except Exception:
logger.exception('Invalid manifest submitted. {}')
return Response({"error": _('Invalid manifest submitted.')}, status=status.HTTP_400_BAD_REQUEST)
try:
license_data_validated = get_licenser().license_from_manifest(license_data)
except Exception:
logger.warning(smart_text(u"Invalid subscription submitted."),
extra=dict(actor=request.user.username))
return Response({"error": _("Invalid License")}, status=status.HTTP_400_BAD_REQUEST)
else:
license_data_validated = get_licenser().validate()
# If the license is valid, write it to the database.
if license_data_validated['valid_key']:
settings.LICENSE = license_data
if not settings_registry.is_setting_read_only('TOWER_URL_BASE'):
settings.TOWER_URL_BASE = "{}://{}".format(request.scheme, request.get_host())
return Response(license_data_validated)
logger.warning(smart_text(u"Invalid license submitted."),
logger.warning(smart_text(u"Invalid subscription submitted."),
extra=dict(actor=request.user.username))
return Response({"error": _("Invalid license")}, status=status.HTTP_400_BAD_REQUEST)
return Response({"error": _("Invalid subscription")}, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request):
try:

View File

@@ -25,10 +25,12 @@ if MODE == 'production':
try:
fd = open("/var/lib/awx/.tower_version", "r")
if fd.read().strip() != tower_version:
raise Exception()
except Exception:
raise ValueError()
except FileNotFoundError:
pass
except ValueError as e:
logger.error("Missing or incorrect metadata for Tower version. Ensure Tower was installed using the setup playbook.")
raise Exception("Missing or incorrect metadata for Tower version. Ensure Tower was installed using the setup playbook.")
raise Exception("Missing or incorrect metadata for Tower version. Ensure Tower was installed using the setup playbook.") from e
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "awx.settings")

View File

@@ -1,18 +1,14 @@
# Copyright (c) 2016 Ansible, Inc.
# All Rights Reserved.
__all__ = ['get_license']
def _get_validated_license_data():
from awx.main.utils.common import get_licenser
from awx.main.utils import get_licenser
return get_licenser().validate()
def get_license(show_key=False):
def get_license():
"""Return a dictionary representing the active license on this Tower instance."""
license_data = _get_validated_license_data()
if not show_key:
license_data.pop('license_key', None)
return license_data
return _get_validated_license_data()

View File

@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
from awx.conf.migrations import _rename_setting
def copy_allowed_ips(apps, schema_editor):
_rename_setting.rename_setting(apps, schema_editor, old_key='PROXY_IP_WHITELIST', new_key='PROXY_IP_ALLOWED_LIST')
class Migration(migrations.Migration):
dependencies = [
('conf', '0006_v331_ldap_group_type'),
]
operations = [
migrations.RunPython(copy_allowed_ips),
]

View File

@@ -0,0 +1,26 @@
# Generated by Django 2.2.11 on 2020-08-04 15:19
import logging
from django.db import migrations
from awx.conf.migrations._subscriptions import clear_old_license, prefill_rh_credentials
logger = logging.getLogger('awx.conf.migrations')
def _noop(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('conf', '0007_v380_rename_more_settings'),
]
operations = [
migrations.RunPython(clear_old_license, _noop),
migrations.RunPython(prefill_rh_credentials, _noop)
]

View File

@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
import logging
from django.utils.timezone import now
from awx.main.utils.encryption import decrypt_field, encrypt_field
logger = logging.getLogger('awx.conf.settings')
__all__ = ['clear_old_license', 'prefill_rh_credentials']
def clear_old_license(apps, schema_editor):
Setting = apps.get_model('conf', 'Setting')
Setting.objects.filter(key='LICENSE').delete()
def _migrate_setting(apps, old_key, new_key, encrypted=False):
Setting = apps.get_model('conf', 'Setting')
if not Setting.objects.filter(key=old_key).exists():
return
new_setting = Setting.objects.create(key=new_key,
created=now(),
modified=now()
)
if encrypted:
new_setting.value = decrypt_field(Setting.objects.filter(key=old_key).first(), 'value')
new_setting.value = encrypt_field(new_setting, 'value')
else:
new_setting.value = getattr(Setting.objects.filter(key=old_key).first(), 'value')
new_setting.save()
def prefill_rh_credentials(apps, schema_editor):
_migrate_setting(apps, 'REDHAT_USERNAME', 'SUBSCRIPTIONS_USERNAME', encrypted=False)
_migrate_setting(apps, 'REDHAT_PASSWORD', 'SUBSCRIPTIONS_PASSWORD', encrypted=True)

View File

@@ -78,14 +78,6 @@ class Setting(CreatedModifiedModel):
def get_cache_id_key(self, key):
return '{}_ID'.format(key)
def display_value(self):
if self.key == 'LICENSE' and 'license_key' in self.value:
# don't log the license key in activity stream
value = self.value.copy()
value['license_key'] = '********'
return value
return self.value
import awx.conf.signals # noqa

View File

@@ -129,12 +129,14 @@ class SettingsRegistry(object):
placeholder = field_kwargs.pop('placeholder', empty)
encrypted = bool(field_kwargs.pop('encrypted', False))
defined_in_file = bool(field_kwargs.pop('defined_in_file', False))
unit = field_kwargs.pop('unit', None)
if getattr(field_kwargs.get('child', None), 'source', None) is not None:
field_kwargs['child'].source = None
field_instance = field_class(**field_kwargs)
field_instance.category_slug = category_slug
field_instance.category = category
field_instance.depends_on = depends_on
field_instance.unit = unit
if placeholder is not empty:
field_instance.placeholder = placeholder
field_instance.defined_in_file = defined_in_file

View File

@@ -17,6 +17,8 @@ from django.utils.functional import cached_property
# Django REST Framework
from rest_framework.fields import empty, SkipField
import cachetools
# Tower
from awx.main.utils import encrypt_field, decrypt_field
from awx.conf import settings_registry
@@ -28,6 +30,8 @@ from awx.conf.migrations._reencrypt import decrypt_field as old_decrypt_field
logger = logging.getLogger('awx.conf.settings')
SETTING_MEMORY_TTL = 5 if 'callback_receiver' in ' '.join(sys.argv) else 0
# Store a special value to indicate when a setting is not set in the database.
SETTING_CACHE_NOTSET = '___notset___'
@@ -406,6 +410,7 @@ class SettingsWrapper(UserSettingsHolder):
def SETTINGS_MODULE(self):
return self._get_default('SETTINGS_MODULE')
@cachetools.cached(cache=cachetools.TTLCache(maxsize=2048, ttl=SETTING_MEMORY_TTL))
def __getattr__(self, name):
value = empty
if name in self.all_supported_settings:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -333,14 +333,14 @@ class BaseAccess(object):
report_violation(_("License has expired."))
free_instances = validation_info.get('free_instances', 0)
available_instances = validation_info.get('available_instances', 0)
instance_count = validation_info.get('instance_count', 0)
if add_host_name:
host_exists = Host.objects.filter(name=add_host_name).exists()
if not host_exists and free_instances == 0:
report_violation(_("License count of %s instances has been reached.") % available_instances)
report_violation(_("License count of %s instances has been reached.") % instance_count)
elif not host_exists and free_instances < 0:
report_violation(_("License count of %s instances has been exceeded.") % available_instances)
report_violation(_("License count of %s instances has been exceeded.") % instance_count)
elif not add_host_name and free_instances < 0:
report_violation(_("Host count exceeds available instances."))
@@ -1103,11 +1103,6 @@ class CredentialTypeAccess(BaseAccess):
def can_use(self, obj):
return True
def get_method_capability(self, method, obj, parent_obj):
if obj.managed_by_tower:
return False
return super(CredentialTypeAccess, self).get_method_capability(method, obj, parent_obj)
def filtered_queryset(self):
return self.model.objects.all()
@@ -1182,6 +1177,8 @@ class CredentialAccess(BaseAccess):
def get_user_capabilities(self, obj, **kwargs):
user_capabilities = super(CredentialAccess, self).get_user_capabilities(obj, **kwargs)
user_capabilities['use'] = self.can_use(obj)
if getattr(obj, 'managed_by_tower', False) is True:
user_capabilities['edit'] = user_capabilities['delete'] = False
return user_capabilities
@@ -1513,8 +1510,7 @@ class JobTemplateAccess(NotificationAttachMixin, BaseAccess):
thus can be made by a job template administrator which may not have access
to the any inventory, project, or credentials associated with the template.
'''
# We are white listing fields that can
field_whitelist = [
allowed_fields = [
'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_skip_tags_on_launch',
@@ -1529,7 +1525,7 @@ class JobTemplateAccess(NotificationAttachMixin, BaseAccess):
if k not in [x.name for x in obj._meta.concrete_fields]:
continue
if hasattr(obj, k) and getattr(obj, k) != v:
if k not in field_whitelist and v != getattr(obj, '%s_id' % k, None) \
if k not in allowed_fields and v != getattr(obj, '%s_id' % k, None) \
and not (hasattr(obj, '%s_id' % k) and getattr(obj, '%s_id' % k) is None and v == ''): # Equate '' to None in the case of foreign keys
return False
return True
@@ -2480,13 +2476,16 @@ class NotificationAccess(BaseAccess):
class LabelAccess(BaseAccess):
'''
I can see/use a Label if I have permission to associated organization
I can see/use a Label if I have permission to associated organization, or to a JT that the label is on
'''
model = Label
prefetch_related = ('modified_by', 'created_by', 'organization',)
def filtered_queryset(self):
return self.model.objects.all()
return self.model.objects.filter(
Q(organization__in=Organization.accessible_pk_qs(self.user, 'read_role')) |
Q(unifiedjobtemplate_labels__in=UnifiedJobTemplate.accessible_pk_qs(self.user, 'read_role'))
)
@check_superuser
def can_add(self, data):
@@ -2751,6 +2750,9 @@ class WorkflowApprovalTemplateAccess(BaseAccess):
else:
return (self.check_related('workflow_approval_template', UnifiedJobTemplate, role_field='admin_role'))
def can_change(self, obj, data):
return self.user.can_access(WorkflowJobTemplate, 'change', obj.workflow_job_template, data={})
def can_start(self, obj, validate_license=False):
# for copying WFJTs that contain approval nodes
if self.user.is_superuser:

View File

@@ -1 +1 @@
from .core import register, gather, ship, table_version # noqa
from .core import all_collectors, expensive_collectors, register, gather, ship # noqa

View File

@@ -20,7 +20,7 @@ from django.conf import settings
BROADCAST_WEBSOCKET_REDIS_KEY_NAME = 'broadcast_websocket_stats'
logger = logging.getLogger('awx.main.analytics.broadcast_websocket')
logger = logging.getLogger('awx.analytics.broadcast_websocket')
def dt_to_seconds(dt):

View File

@@ -1,3 +1,4 @@
import io
import os
import os.path
import platform
@@ -6,13 +7,14 @@ from django.db import connection
from django.db.models import Count
from django.conf import settings
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from awx.conf.license import get_license
from awx.main.utils import (get_awx_version, get_ansible_version,
get_custom_venv_choices, camelcase_to_underscore)
from awx.main import models
from django.contrib.sessions.models import Session
from awx.main.analytics import register, table_version
from awx.main.analytics import register
'''
This module is used to define metrics collected by awx.main.analytics.gather()
@@ -31,9 +33,9 @@ data _since_ the last report date - i.e., new data in the last 24 hours)
'''
@register('config', '1.1')
def config(since):
license_info = get_license(show_key=False)
@register('config', '1.2', description=_('General platform configuration.'))
def config(since, **kwargs):
license_info = get_license()
install_type = 'traditional'
if os.environ.get('container') == 'oci':
install_type = 'openshift'
@@ -63,8 +65,8 @@ def config(since):
}
@register('counts', '1.0')
def counts(since):
@register('counts', '1.0', description=_('Counts of objects such as organizations, inventories, and projects'))
def counts(since, **kwargs):
counts = {}
for cls in (models.Organization, models.Team, models.User,
models.Inventory, models.Credential, models.Project,
@@ -98,8 +100,8 @@ def counts(since):
return counts
@register('org_counts', '1.0')
def org_counts(since):
@register('org_counts', '1.0', description=_('Counts of users and teams by organization'))
def org_counts(since, **kwargs):
counts = {}
for org in models.Organization.objects.annotate(num_users=Count('member_role__members', distinct=True),
num_teams=Count('teams', distinct=True)).values('name', 'id', 'num_users', 'num_teams'):
@@ -110,8 +112,8 @@ def org_counts(since):
return counts
@register('cred_type_counts', '1.0')
def cred_type_counts(since):
@register('cred_type_counts', '1.0', description=_('Counts of credentials by credential type'))
def cred_type_counts(since, **kwargs):
counts = {}
for cred_type in models.CredentialType.objects.annotate(num_credentials=Count(
'credentials', distinct=True)).values('name', 'id', 'managed_by_tower', 'num_credentials'):
@@ -122,8 +124,8 @@ def cred_type_counts(since):
return counts
@register('inventory_counts', '1.2')
def inventory_counts(since):
@register('inventory_counts', '1.2', description=_('Inventories, their inventory sources, and host counts'))
def inventory_counts(since, **kwargs):
counts = {}
for inv in models.Inventory.objects.filter(kind='').annotate(num_sources=Count('inventory_sources', distinct=True),
num_hosts=Count('hosts', distinct=True)).only('id', 'name', 'kind'):
@@ -147,8 +149,8 @@ def inventory_counts(since):
return counts
@register('projects_by_scm_type', '1.0')
def projects_by_scm_type(since):
@register('projects_by_scm_type', '1.0', description=_('Counts of projects by source control type'))
def projects_by_scm_type(since, **kwargs):
counts = dict(
(t[0] or 'manual', 0)
for t in models.Project.SCM_TYPE_CHOICES
@@ -166,8 +168,8 @@ def _get_isolated_datetime(last_check):
return last_check
@register('instance_info', '1.0')
def instance_info(since, include_hostnames=False):
@register('instance_info', '1.0', description=_('Cluster topology and capacity'))
def instance_info(since, include_hostnames=False, **kwargs):
info = {}
instances = models.Instance.objects.values_list('hostname').values(
'uuid', 'version', 'capacity', 'cpu', 'memory', 'managed_by_policy', 'hostname', 'last_isolated_check', 'enabled')
@@ -192,8 +194,7 @@ def instance_info(since, include_hostnames=False):
return info
@register('job_counts', '1.0')
def job_counts(since):
def job_counts(since, **kwargs):
counts = {}
counts['total_jobs'] = models.UnifiedJob.objects.exclude(launch_type='sync').count()
counts['status'] = dict(models.UnifiedJob.objects.exclude(launch_type='sync').values_list('status').annotate(Count('status')).order_by())
@@ -202,8 +203,7 @@ def job_counts(since):
return counts
@register('job_instance_counts', '1.0')
def job_instance_counts(since):
def job_instance_counts(since, **kwargs):
counts = {}
job_types = models.UnifiedJob.objects.exclude(launch_type='sync').values_list(
'execution_node', 'launch_type').annotate(job_launch_type=Count('launch_type')).order_by()
@@ -217,36 +217,79 @@ def job_instance_counts(since):
return counts
@register('query_info', '1.0')
def query_info(since, collection_type):
@register('query_info', '1.0', description=_('Metadata about the analytics collected'))
def query_info(since, collection_type, until, **kwargs):
query_info = {}
query_info['last_run'] = str(since)
query_info['current_time'] = str(now())
query_info['current_time'] = str(until)
query_info['collection_type'] = collection_type
return query_info
# Copies Job Events from db to a .csv to be shipped
@table_version('events_table.csv', '1.1')
@table_version('unified_jobs_table.csv', '1.0')
@table_version('unified_job_template_table.csv', '1.0')
@table_version('workflow_job_node_table.csv', '1.0')
@table_version('workflow_job_template_node_table.csv', '1.0')
def copy_tables(since, full_path, subset=None):
def _copy_table(table, query, path):
file_path = os.path.join(path, table + '_table.csv')
file = open(file_path, 'w', encoding='utf-8')
with connection.cursor() as cursor:
cursor.copy_expert(query, file)
file.close()
return file_path
'''
The event table can be *very* large, and we have a 100MB upload limit.
Split large table dumps at dump time into a series of files.
'''
MAX_TABLE_SIZE = 200 * 1048576
class FileSplitter(io.StringIO):
def __init__(self, filespec=None, *args, **kwargs):
self.filespec = filespec
self.files = []
self.currentfile = None
self.header = None
self.counter = 0
self.cycle_file()
def cycle_file(self):
if self.currentfile:
self.currentfile.close()
self.counter = 0
fname = '{}_split{}'.format(self.filespec, len(self.files))
self.currentfile = open(fname, 'w', encoding='utf-8')
self.files.append(fname)
if self.header:
self.currentfile.write('{}\n'.format(self.header))
def file_list(self):
self.currentfile.close()
# Check for an empty dump
if len(self.header) + 1 == self.counter:
os.remove(self.files[-1])
self.files = self.files[:-1]
# If we only have one file, remove the suffix
if len(self.files) == 1:
os.rename(self.files[0],self.files[0].replace('_split0',''))
return self.files
def write(self, s):
if not self.header:
self.header = s[0:s.index('\n')]
self.counter += self.currentfile.write(s)
if self.counter >= MAX_TABLE_SIZE:
self.cycle_file()
def _copy_table(table, query, path):
file_path = os.path.join(path, table + '_table.csv')
file = FileSplitter(filespec=file_path)
with connection.cursor() as cursor:
cursor.copy_expert(query, file)
return file.file_list()
@register('events_table', '1.2', format='csv', description=_('Automation task records'), expensive=True)
def events_table(since, full_path, until, **kwargs):
events_query = '''COPY (SELECT main_jobevent.id,
main_jobevent.created,
main_jobevent.modified,
main_jobevent.uuid,
main_jobevent.parent_uuid,
main_jobevent.event,
main_jobevent.event_data::json->'task_action' AS task_action,
(CASE WHEN event = 'playbook_on_stats' THEN event_data END) as playbook_on_stats,
main_jobevent.failed,
main_jobevent.changed,
main_jobevent.playbook,
@@ -262,16 +305,21 @@ def copy_tables(since, full_path, subset=None):
main_jobevent.event_data::json->'res'->'warnings' AS warnings,
main_jobevent.event_data::json->'res'->'deprecations' AS deprecations
FROM main_jobevent
WHERE main_jobevent.created > {}
ORDER BY main_jobevent.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
if not subset or 'events' in subset:
_copy_table(table='events', query=events_query, path=full_path)
WHERE (main_jobevent.created > '{}' AND main_jobevent.created <= '{}')
ORDER BY main_jobevent.id ASC) TO STDOUT WITH CSV HEADER
'''.format(since.isoformat(),until.isoformat())
return _copy_table(table='events', query=events_query, path=full_path)
@register('unified_jobs_table', '1.1', format='csv', description=_('Data on jobs run'), expensive=True)
def unified_jobs_table(since, full_path, until, **kwargs):
unified_job_query = '''COPY (SELECT main_unifiedjob.id,
main_unifiedjob.polymorphic_ctype_id,
django_content_type.model,
main_unifiedjob.organization_id,
main_organization.name as organization_name,
main_job.inventory_id,
main_inventory.name as inventory_name,
main_unifiedjob.created,
main_unifiedjob.name,
main_unifiedjob.unified_job_template_id,
@@ -289,13 +337,19 @@ def copy_tables(since, full_path, subset=None):
main_unifiedjob.instance_group_id
FROM main_unifiedjob
JOIN django_content_type ON main_unifiedjob.polymorphic_ctype_id = django_content_type.id
LEFT JOIN main_job ON main_unifiedjob.id = main_job.unifiedjob_ptr_id
LEFT JOIN main_inventory ON main_job.inventory_id = main_inventory.id
LEFT JOIN main_organization ON main_organization.id = main_unifiedjob.organization_id
WHERE (main_unifiedjob.created > {0} OR main_unifiedjob.finished > {0})
WHERE ((main_unifiedjob.created > '{0}' AND main_unifiedjob.created <= '{1}')
OR (main_unifiedjob.finished > '{0}' AND main_unifiedjob.finished <= '{1}'))
AND main_unifiedjob.launch_type != 'sync'
ORDER BY main_unifiedjob.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
if not subset or 'unified_jobs' in subset:
_copy_table(table='unified_jobs', query=unified_job_query, path=full_path)
ORDER BY main_unifiedjob.id ASC) TO STDOUT WITH CSV HEADER
'''.format(since.isoformat(),until.isoformat())
return _copy_table(table='unified_jobs', query=unified_job_query, path=full_path)
@register('unified_job_template_table', '1.0', format='csv', description=_('Data on job templates'))
def unified_job_template_table(since, full_path, **kwargs):
unified_job_template_query = '''COPY (SELECT main_unifiedjobtemplate.id,
main_unifiedjobtemplate.polymorphic_ctype_id,
django_content_type.model,
@@ -314,9 +368,11 @@ def copy_tables(since, full_path, subset=None):
FROM main_unifiedjobtemplate, django_content_type
WHERE main_unifiedjobtemplate.polymorphic_ctype_id = django_content_type.id
ORDER BY main_unifiedjobtemplate.id ASC) TO STDOUT WITH CSV HEADER'''
if not subset or 'unified_job_template' in subset:
_copy_table(table='unified_job_template', query=unified_job_template_query, path=full_path)
return _copy_table(table='unified_job_template', query=unified_job_template_query, path=full_path)
@register('workflow_job_node_table', '1.0', format='csv', description=_('Data on workflow runs'), expensive=True)
def workflow_job_node_table(since, full_path, until, **kwargs):
workflow_job_node_query = '''COPY (SELECT main_workflowjobnode.id,
main_workflowjobnode.created,
main_workflowjobnode.modified,
@@ -345,11 +401,14 @@ def copy_tables(since, full_path, subset=None):
FROM main_workflowjobnode_always_nodes
GROUP BY from_workflowjobnode_id
) always_nodes ON main_workflowjobnode.id = always_nodes.from_workflowjobnode_id
WHERE main_workflowjobnode.modified > {}
ORDER BY main_workflowjobnode.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
if not subset or 'workflow_job_node' in subset:
_copy_table(table='workflow_job_node', query=workflow_job_node_query, path=full_path)
WHERE (main_workflowjobnode.modified > '{}' AND main_workflowjobnode.modified <= '{}')
ORDER BY main_workflowjobnode.id ASC) TO STDOUT WITH CSV HEADER
'''.format(since.isoformat(),until.isoformat())
return _copy_table(table='workflow_job_node', query=workflow_job_node_query, path=full_path)
@register('workflow_job_template_node_table', '1.0', format='csv', description=_('Data on workflows'))
def workflow_job_template_node_table(since, full_path, **kwargs):
workflow_job_template_node_query = '''COPY (SELECT main_workflowjobtemplatenode.id,
main_workflowjobtemplatenode.created,
main_workflowjobtemplatenode.modified,
@@ -377,7 +436,4 @@ def copy_tables(since, full_path, subset=None):
GROUP BY from_workflowjobtemplatenode_id
) always_nodes ON main_workflowjobtemplatenode.id = always_nodes.from_workflowjobtemplatenode_id
ORDER BY main_workflowjobtemplatenode.id ASC) TO STDOUT WITH CSV HEADER'''
if not subset or 'workflow_job_template_node' in subset:
_copy_table(table='workflow_job_template_node', query=workflow_job_template_node_query, path=full_path)
return
return _copy_table(table='workflow_job_template_node', query=workflow_job_template_node_query, path=full_path)

View File

@@ -14,21 +14,17 @@ from rest_framework.exceptions import PermissionDenied
from awx.conf.license import get_license
from awx.main.models import Job
from awx.main.access import access_registry
from awx.main.models.ha import TowerAnalyticsState
from awx.main.utils import get_awx_http_client_headers, set_environ
__all__ = ['register', 'gather', 'ship', 'table_version']
__all__ = ['register', 'gather', 'ship']
logger = logging.getLogger('awx.main.analytics')
manifest = dict()
def _valid_license():
try:
if get_license(show_key=False).get('license_type', 'UNLICENSED') == 'open':
if get_license().get('license_type', 'UNLICENSED') == 'open':
return False
access_registry[Job](None).check_license()
except PermissionDenied:
@@ -37,114 +33,194 @@ def _valid_license():
return True
def register(key, version):
def all_collectors():
from awx.main.analytics import collectors
collector_dict = {}
module = collectors
for name, func in inspect.getmembers(module):
if inspect.isfunction(func) and hasattr(func, '__awx_analytics_key__'):
key = func.__awx_analytics_key__
desc = func.__awx_analytics_description__ or ''
version = func.__awx_analytics_version__
collector_dict[key] = { 'name': key, 'version': version, 'description': desc}
return collector_dict
def expensive_collectors():
from awx.main.analytics import collectors
ret = []
module = collectors
for name, func in inspect.getmembers(module):
if inspect.isfunction(func) and hasattr(func, '__awx_analytics_key__') and func.__awx_expensive__:
ret.append(func.__awx_analytics_key__)
return ret
def register(key, version, description=None, format='json', expensive=False):
"""
A decorator used to register a function as a metric collector.
Decorated functions should return JSON-serializable objects.
Decorated functions should do the following based on format:
- json: return JSON-serializable objects.
- csv: write CSV data to a filename named 'key'
@register('projects_by_scm_type', 1)
def projects_by_scm_type():
return {'git': 5, 'svn': 1, 'hg': 0}
return {'git': 5, 'svn': 1}
"""
def decorate(f):
f.__awx_analytics_key__ = key
f.__awx_analytics_version__ = version
f.__awx_analytics_description__ = description
f.__awx_analytics_type__ = format
f.__awx_expensive__ = expensive
return f
return decorate
def table_version(file_name, version):
global manifest
manifest[file_name] = version
def decorate(f):
return f
return decorate
def gather(dest=None, module=None, collection_type='scheduled'):
def gather(dest=None, module=None, subset = None, since = None, until = now(), collection_type='scheduled'):
"""
Gather all defined metrics and write them as JSON files in a .tgz
:param dest: the (optional) absolute path to write a compressed tarball
:pararm module: the module to search for registered analytic collector
:param module: the module to search for registered analytic collector
functions; defaults to awx.main.analytics.collectors
"""
def _write_manifest(destdir, manifest):
path = os.path.join(destdir, 'manifest.json')
with open(path, 'w', encoding='utf-8') as f:
try:
json.dump(manifest, f)
except Exception:
f.close()
os.remove(f.name)
logger.exception("Could not generate manifest.json")
run_now = now()
state = TowerAnalyticsState.get_solo()
last_run = state.last_run
logger.debug("Last analytics run was: {}".format(last_run))
max_interval = now() - timedelta(weeks=4)
if last_run < max_interval or not last_run:
last_run = max_interval
last_run = since or settings.AUTOMATION_ANALYTICS_LAST_GATHER or (now() - timedelta(weeks=4))
logger.debug("Last analytics run was: {}".format(settings.AUTOMATION_ANALYTICS_LAST_GATHER))
if _valid_license() is False:
logger.exception("Invalid License provided, or No License Provided")
return "Error: Invalid License provided, or No License Provided"
return None
if collection_type != 'dry-run' and not settings.INSIGHTS_TRACKING_STATE:
logger.error("Automation Analytics not enabled. Use --dry-run to gather locally without sending.")
return
return None
if module is None:
collector_list = []
if module:
collector_module = module
else:
from awx.main.analytics import collectors
module = collectors
collector_module = collectors
for name, func in inspect.getmembers(collector_module):
if (
inspect.isfunction(func) and
hasattr(func, '__awx_analytics_key__') and
(not subset or name in subset)
):
collector_list.append((name, func))
manifest = dict()
dest = dest or tempfile.mkdtemp(prefix='awx_analytics')
for name, func in inspect.getmembers(module):
if inspect.isfunction(func) and hasattr(func, '__awx_analytics_key__'):
gather_dir = os.path.join(dest, 'stage')
os.mkdir(gather_dir, 0o700)
num_splits = 1
for name, func in collector_list:
if func.__awx_analytics_type__ == 'json':
key = func.__awx_analytics_key__
manifest['{}.json'.format(key)] = func.__awx_analytics_version__
path = '{}.json'.format(os.path.join(dest, key))
path = '{}.json'.format(os.path.join(gather_dir, key))
with open(path, 'w', encoding='utf-8') as f:
try:
if func.__name__ == 'query_info':
json.dump(func(last_run, collection_type=collection_type), f)
else:
json.dump(func(last_run), f)
json.dump(func(last_run, collection_type=collection_type, until=until), f)
manifest['{}.json'.format(key)] = func.__awx_analytics_version__
except Exception:
logger.exception("Could not generate metric {}.json".format(key))
f.close()
os.remove(f.name)
path = os.path.join(dest, 'manifest.json')
with open(path, 'w', encoding='utf-8') as f:
try:
json.dump(manifest, f)
except Exception:
logger.exception("Could not generate manifest.json")
f.close()
os.remove(f.name)
elif func.__awx_analytics_type__ == 'csv':
key = func.__awx_analytics_key__
try:
files = func(last_run, full_path=gather_dir, until=until)
if files:
manifest['{}.csv'.format(key)] = func.__awx_analytics_version__
if len(files) > num_splits:
num_splits = len(files)
except Exception:
logger.exception("Could not generate metric {}.csv".format(key))
try:
collectors.copy_tables(since=last_run, full_path=dest)
except Exception:
logger.exception("Could not copy tables")
# can't use isoformat() since it has colons, which GNU tar doesn't like
tarname = '_'.join([
settings.SYSTEM_UUID,
run_now.strftime('%Y-%m-%d-%H%M%S%z')
])
try:
tgz = shutil.make_archive(
os.path.join(os.path.dirname(dest), tarname),
'gztar',
dest
)
return tgz
except Exception:
logger.exception("Failed to write analytics archive file")
finally:
if not manifest:
# No data was collected
logger.warning("No data from {} to {}".format(last_run, until))
shutil.rmtree(dest)
return None
# Always include config.json if we're using our collectors
if 'config.json' not in manifest.keys() and not module:
from awx.main.analytics import collectors
config = collectors.config
path = '{}.json'.format(os.path.join(gather_dir, config.__awx_analytics_key__))
with open(path, 'w', encoding='utf-8') as f:
try:
json.dump(collectors.config(last_run), f)
manifest['config.json'] = config.__awx_analytics_version__
except Exception:
logger.exception("Could not generate metric {}.json".format(key))
f.close()
os.remove(f.name)
shutil.rmtree(dest)
return None
stage_dirs = [gather_dir]
if num_splits > 1:
for i in range(0, num_splits):
split_path = os.path.join(dest, 'split{}'.format(i))
os.mkdir(split_path, 0o700)
filtered_manifest = {}
shutil.copy(os.path.join(gather_dir, 'config.json'), split_path)
filtered_manifest['config.json'] = manifest['config.json']
suffix = '_split{}'.format(i)
for file in os.listdir(gather_dir):
if file.endswith(suffix):
old_file = os.path.join(gather_dir, file)
new_filename = file.replace(suffix, '')
new_file = os.path.join(split_path, new_filename)
shutil.move(old_file, new_file)
filtered_manifest[new_filename] = manifest[new_filename]
_write_manifest(split_path, filtered_manifest)
stage_dirs.append(split_path)
for item in list(manifest.keys()):
if not os.path.exists(os.path.join(gather_dir, item)):
manifest.pop(item)
_write_manifest(gather_dir, manifest)
tarfiles = []
try:
for i in range(0, len(stage_dirs)):
stage_dir = stage_dirs[i]
# can't use isoformat() since it has colons, which GNU tar doesn't like
tarname = '_'.join([
settings.SYSTEM_UUID,
until.strftime('%Y-%m-%d-%H%M%S%z'),
str(i)
])
tgz = shutil.make_archive(
os.path.join(os.path.dirname(dest), tarname),
'gztar',
stage_dir
)
tarfiles.append(tgz)
except Exception:
shutil.rmtree(stage_dir, ignore_errors = True)
logger.exception("Failed to write analytics archive file")
finally:
shutil.rmtree(dest, ignore_errors = True)
return tarfiles
def ship(path):
@@ -154,6 +230,9 @@ def ship(path):
if not path:
logger.error('Automation Analytics TAR not found')
return
if not os.path.exists(path):
logger.error('Automation Analytics TAR {} not found'.format(path))
return
if "Error:" in str(path):
return
try:
@@ -180,13 +259,11 @@ def ship(path):
auth=(rh_user, rh_password),
headers=s.headers,
timeout=(31, 31))
if response.status_code != 202:
# Accept 2XX status_codes
if response.status_code >= 300:
return logger.exception('Upload failed with status {}, {}'.format(response.status_code,
response.text))
run_now = now()
state = TowerAnalyticsState.get_solo()
state.last_run = run_now
state.save()
finally:
# cleanup tar.gz
os.remove(path)
if os.path.exists(path):
os.remove(path)

View File

@@ -12,7 +12,7 @@ from prometheus_client import (
from awx.conf.license import get_license
from awx.main.utils import (get_awx_version, get_ansible_version)
from awx.main.analytics.collectors import (
counts,
counts,
instance_info,
job_instance_counts,
job_counts,
@@ -54,7 +54,7 @@ LICENSE_INSTANCE_FREE = Gauge('awx_license_instance_free', 'Number of remaining
def metrics():
license_info = get_license(show_key=False)
license_info = get_license()
SYSTEM_INFO.info({
'install_uuid': settings.INSTALL_UUID,
'insights_analytics': str(settings.INSIGHTS_TRACKING_STATE),
@@ -68,7 +68,7 @@ def metrics():
'external_logger_type': getattr(settings, 'LOG_AGGREGATOR_TYPE', 'None')
})
LICENSE_INSTANCE_TOTAL.set(str(license_info.get('available_instances', 0)))
LICENSE_INSTANCE_TOTAL.set(str(license_info.get('instance_count', 0)))
LICENSE_INSTANCE_FREE.set(str(license_info.get('free_instances', 0)))
current_counts = counts(None)

View File

@@ -1,8 +1,5 @@
# Python
import json
import logging
import os
from distutils.version import LooseVersion as Version
# Django
from django.utils.translation import ugettext_lazy as _
@@ -14,6 +11,7 @@ from rest_framework.fields import FloatField
# Tower
from awx.conf import fields, register, register_validate
logger = logging.getLogger('awx.main.conf')
register(
@@ -80,11 +78,11 @@ register(
)
register(
'PROXY_IP_WHITELIST',
'PROXY_IP_ALLOWED_LIST',
field_class=fields.StringListField,
label=_('Proxy IP Whitelist'),
label=_('Proxy IP Allowed List'),
help_text=_("If Tower is behind a reverse proxy/load balancer, use this setting "
"to whitelist the proxy IP addresses from which Tower should trust "
"to configure the proxy IP addresses from which Tower should trust "
"custom REMOTE_HOST_HEADERS header values. "
"If this setting is an empty list (the default), the headers specified by "
"REMOTE_HOST_HEADERS will be trusted unconditionally')"),
@@ -93,22 +91,10 @@ register(
)
def _load_default_license_from_file():
try:
license_file = os.environ.get('AWX_LICENSE_FILE', '/etc/tower/license')
if os.path.exists(license_file):
license_data = json.load(open(license_file))
logger.debug('Read license data from "%s".', license_file)
return license_data
except Exception:
logger.warning('Could not read license from "%s".', license_file, exc_info=True)
return {}
register(
'LICENSE',
field_class=fields.DictField,
default=_load_default_license_from_file,
default=lambda: {},
label=_('License'),
help_text=_('The license controls which features and functionality are '
'enabled. Use /api/v2/config/ to update or change '
@@ -125,7 +111,7 @@ register(
encrypted=False,
read_only=False,
label=_('Red Hat customer username'),
help_text=_('This username is used to retrieve license information and to send Automation Analytics'), # noqa
help_text=_('This username is used to send data to Automation Analytics'),
category=_('System'),
category_slug='system',
)
@@ -138,7 +124,33 @@ register(
encrypted=True,
read_only=False,
label=_('Red Hat customer password'),
help_text=_('This password is used to retrieve license information and to send Automation Analytics'), # noqa
help_text=_('This password is used to send data to Automation Analytics'),
category=_('System'),
category_slug='system',
)
register(
'SUBSCRIPTIONS_USERNAME',
field_class=fields.CharField,
default='',
allow_blank=True,
encrypted=False,
read_only=False,
label=_('Red Hat or Satellite username'),
help_text=_('This username is used to retrieve subscription and content information'), # noqa
category=_('System'),
category_slug='system',
)
register(
'SUBSCRIPTIONS_PASSWORD',
field_class=fields.CharField,
default='',
allow_blank=True,
encrypted=True,
read_only=False,
label=_('Red Hat or Satellite password'),
help_text=_('This password is used to retrieve subscription and content information'), # noqa
category=_('System'),
category_slug='system',
)
@@ -149,7 +161,7 @@ register(
default='https://example.com',
schemes=('http', 'https'),
allow_plain_hostname=True, # Allow hostname only without TLD.
label=_('Automation Analytics upload URL.'),
label=_('Automation Analytics upload URL'),
help_text=_('This setting is used to to configure data collection for the Automation Analytics dashboard'),
category=_('System'),
category_slug='system',
@@ -241,7 +253,7 @@ register(
field_class=fields.StringListField,
required=False,
label=_('Paths to expose to isolated jobs'),
help_text=_('Whitelist of paths that would otherwise be hidden to expose to isolated jobs. Enter one path per line.'),
help_text=_('List of paths that would otherwise be hidden to expose to isolated jobs. Enter one path per line.'),
category=_('Jobs'),
category_slug='jobs',
)
@@ -254,6 +266,7 @@ register(
help_text=_('The number of seconds to sleep between status checks for jobs running on isolated instances.'),
category=_('Jobs'),
category_slug='jobs',
unit=_('seconds'),
)
register(
@@ -265,6 +278,7 @@ register(
'This includes the time needed to copy source control files (playbooks) to the isolated instance.'),
category=_('Jobs'),
category_slug='jobs',
unit=_('seconds'),
)
register(
@@ -277,6 +291,7 @@ register(
'Value should be substantially greater than expected network latency.'),
category=_('Jobs'),
category_slug='jobs',
unit=_('seconds'),
)
register(
@@ -436,91 +451,12 @@ register(
category_slug='jobs',
)
register(
'PRIMARY_GALAXY_URL',
field_class=fields.URLField,
required=False,
allow_blank=True,
label=_('Primary Galaxy Server URL'),
help_text=_(
'For organizations that run their own Galaxy service, this gives the option to specify a '
'host as the primary galaxy server. Requirements will be downloaded from the primary if the '
'specific role or collection is available there. If the content is not avilable in the primary, '
'or if this field is left blank, it will default to galaxy.ansible.com.'
),
category=_('Jobs'),
category_slug='jobs'
)
register(
'PRIMARY_GALAXY_USERNAME',
field_class=fields.CharField,
required=False,
allow_blank=True,
label=_('Primary Galaxy Server Username'),
help_text=_('For using a galaxy server at higher precedence than the public Ansible Galaxy. '
'The username to use for basic authentication against the Galaxy instance, '
'this is mutually exclusive with PRIMARY_GALAXY_TOKEN.'),
category=_('Jobs'),
category_slug='jobs'
)
register(
'PRIMARY_GALAXY_PASSWORD',
field_class=fields.CharField,
encrypted=True,
required=False,
allow_blank=True,
label=_('Primary Galaxy Server Password'),
help_text=_('For using a galaxy server at higher precedence than the public Ansible Galaxy. '
'The password to use for basic authentication against the Galaxy instance, '
'this is mutually exclusive with PRIMARY_GALAXY_TOKEN.'),
category=_('Jobs'),
category_slug='jobs'
)
register(
'PRIMARY_GALAXY_TOKEN',
field_class=fields.CharField,
encrypted=True,
required=False,
allow_blank=True,
label=_('Primary Galaxy Server Token'),
help_text=_('For using a galaxy server at higher precedence than the public Ansible Galaxy. '
'The token to use for connecting with the Galaxy instance, '
'this is mutually exclusive with corresponding username and password settings.'),
category=_('Jobs'),
category_slug='jobs'
)
register(
'PRIMARY_GALAXY_AUTH_URL',
field_class=fields.CharField,
required=False,
allow_blank=True,
label=_('Primary Galaxy Authentication URL'),
help_text=_('For using a galaxy server at higher precedence than the public Ansible Galaxy. '
'The token_endpoint of a Keycloak server.'),
category=_('Jobs'),
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(
'GALAXY_IGNORE_CERTS',
field_class=fields.BooleanField,
default=False,
label=_('Ignore Ansible Galaxy SSL Certificate Verification'),
help_text=_('If set to true, certificate validation will not be done when'
help_text=_('If set to true, certificate validation will not be done when '
'installing content from any Galaxy server.'),
category=_('Jobs'),
category_slug='jobs'
@@ -577,6 +513,7 @@ register(
'timeout should be imposed. A timeout set on an individual job template will override this.'),
category=_('Jobs'),
category_slug='jobs',
unit=_('seconds'),
)
register(
@@ -589,6 +526,7 @@ register(
'timeout should be imposed. A timeout set on an individual inventory source will override this.'),
category=_('Jobs'),
category_slug='jobs',
unit=_('seconds'),
)
register(
@@ -601,6 +539,7 @@ register(
'timeout should be imposed. A timeout set on an individual project will override this.'),
category=_('Jobs'),
category_slug='jobs',
unit=_('seconds'),
)
register(
@@ -615,6 +554,7 @@ register(
'Use a value of 0 to indicate that no timeout should be imposed.'),
category=_('Jobs'),
category_slug='jobs',
unit=_('seconds'),
)
register(
@@ -622,7 +562,7 @@ register(
field_class=fields.IntegerField,
allow_null=False,
default=200,
label=_('Maximum number of forks per job.'),
label=_('Maximum number of forks per job'),
help_text=_('Saving a Job Template with more than this number of forks will result in an error. '
'When set to 0, no limit is applied.'),
category=_('Jobs'),
@@ -752,6 +692,7 @@ register(
'aggregator protocols.'),
category=_('Logging'),
category_slug='logging',
unit=_('seconds'),
)
register(
'LOG_AGGREGATOR_VERIFY_CERT',
@@ -832,7 +773,8 @@ register(
default=14400, # every 4 hours
min_value=1800, # every 30 minutes
category=_('System'),
category_slug='system'
category_slug='system',
unit=_('seconds'),
)
@@ -854,84 +796,4 @@ def logging_validate(serializer, attrs):
return attrs
def galaxy_validate(serializer, attrs):
"""Ansible Galaxy config options have mutual exclusivity rules, these rules
are enforced here on serializer validation so that users will not be able
to save settings which obviously break all project updates.
"""
prefix = 'PRIMARY_GALAXY_'
errors = {}
def _new_value(setting_name):
if setting_name in attrs:
return attrs[setting_name]
elif not serializer.instance:
return ''
return getattr(serializer.instance, setting_name, '')
if not _new_value('PRIMARY_GALAXY_URL'):
if _new_value('PUBLIC_GALAXY_ENABLED') is False:
msg = _('A URL for Primary Galaxy must be defined before disabling public Galaxy.')
# put error in both keys because UI has trouble with errors in toggles
for key in ('PRIMARY_GALAXY_URL', 'PUBLIC_GALAXY_ENABLED'):
errors.setdefault(key, [])
errors[key].append(msg)
raise serializers.ValidationError(errors)
from awx.main.constants import GALAXY_SERVER_FIELDS
if not any('{}{}'.format(prefix, subfield.upper()) in attrs for subfield in GALAXY_SERVER_FIELDS):
return attrs
galaxy_data = {}
for subfield in GALAXY_SERVER_FIELDS:
galaxy_data[subfield] = _new_value('{}{}'.format(prefix, subfield.upper()))
if not galaxy_data['url']:
for k, v in galaxy_data.items():
if v:
setting_name = '{}{}'.format(prefix, k.upper())
errors.setdefault(setting_name, [])
errors[setting_name].append(_(
'Cannot provide field if PRIMARY_GALAXY_URL is not set.'
))
for k in GALAXY_SERVER_FIELDS:
if galaxy_data[k]:
setting_name = '{}{}'.format(prefix, k.upper())
if (not serializer.instance) or (not getattr(serializer.instance, setting_name, '')):
# new auth is applied, so check if compatible with version
from awx.main.utils import get_ansible_version
current_version = get_ansible_version()
min_version = '2.9'
if Version(current_version) < Version(min_version):
errors.setdefault(setting_name, [])
errors[setting_name].append(_(
'Galaxy server settings are not available until Ansible {min_version}, '
'you are running {current_version}.'
).format(min_version=min_version, current_version=current_version))
if (galaxy_data['password'] or galaxy_data['username']) and (galaxy_data['token'] or galaxy_data['auth_url']):
for k in ('password', 'username', 'token', 'auth_url'):
setting_name = '{}{}'.format(prefix, k.upper())
if setting_name in attrs:
errors.setdefault(setting_name, [])
errors[setting_name].append(_(
'Setting Galaxy token and authentication URL is mutually exclusive with username and password.'
))
if bool(galaxy_data['username']) != bool(galaxy_data['password']):
msg = _('If authenticating via username and password, both must be provided.')
for k in ('username', 'password'):
setting_name = '{}{}'.format(prefix, k.upper())
errors.setdefault(setting_name, [])
errors[setting_name].append(msg)
if bool(galaxy_data['token']) != bool(galaxy_data['auth_url']):
msg = _('If authenticating via token, both token and authentication URL must be provided.')
for k in ('token', 'auth_url'):
setting_name = '{}{}'.format(prefix, k.upper())
errors.setdefault(setting_name, [])
errors[setting_name].append(msg)
if errors:
raise serializers.ValidationError(errors)
return attrs
register_validate('logging', logging_validate)
register_validate('jobs', galaxy_validate)

View File

@@ -31,7 +31,7 @@ STANDARD_INVENTORY_UPDATE_ENV = {
CAN_CANCEL = ('new', 'pending', 'waiting', 'running')
ACTIVE_STATES = CAN_CANCEL
CENSOR_VALUE = '************'
ENV_BLACKLIST = frozenset((
ENV_BLOCKLIST = frozenset((
'VIRTUAL_ENV', 'PATH', 'PYTHONPATH', 'PROOT_TMP_DIR', 'JOB_ID',
'INVENTORY_ID', 'INVENTORY_SOURCE_ID', 'INVENTORY_UPDATE_ID',
'AD_HOC_COMMAND_ID', 'REST_API_URL', 'REST_API_TOKEN', 'MAX_EVENT_RES',
@@ -41,7 +41,7 @@ ENV_BLACKLIST = frozenset((
))
# loggers that may be called in process of emitting a log
LOGGER_BLACKLIST = (
LOGGER_BLOCKLIST = (
'awx.main.utils.handlers',
'awx.main.utils.formatters',
'awx.main.utils.filters',
@@ -50,7 +50,3 @@ LOGGER_BLACKLIST = (
# loggers that may be called getting logging settings
'awx.conf'
)
# these correspond to both AWX and Ansible settings to keep naming consistent
# for instance, settings.PRIMARY_GALAXY_AUTH_URL vs env var ANSIBLE_GALAXY_SERVER_FOO_AUTH_URL
GALAXY_SERVER_FIELDS = ('url', 'username', 'password', 'token', 'auth_url')

View File

@@ -1,4 +1,4 @@
from .plugin import CredentialPlugin, CertFiles
from .plugin import CredentialPlugin, CertFiles, raise_for_status
from urllib.parse import quote, urlencode, urljoin
@@ -82,8 +82,9 @@ def aim_backend(**kwargs):
timeout=30,
cert=cert,
verify=verify,
allow_redirects=False,
)
res.raise_for_status()
raise_for_status(res)
return res.json()['Content']

View File

@@ -1,4 +1,4 @@
from .plugin import CredentialPlugin, CertFiles
from .plugin import CredentialPlugin, CertFiles, raise_for_status
import base64
from urllib.parse import urljoin, quote
@@ -58,7 +58,8 @@ def conjur_backend(**kwargs):
auth_kwargs = {
'headers': {'Content-Type': 'text/plain'},
'data': api_key
'data': api_key,
'allow_redirects': False,
}
with CertFiles(cacert) as cert:
@@ -68,11 +69,12 @@ def conjur_backend(**kwargs):
urljoin(url, '/'.join(['authn', account, username, 'authenticate'])),
**auth_kwargs
)
resp.raise_for_status()
raise_for_status(resp)
token = base64.b64encode(resp.content).decode('utf-8')
lookup_kwargs = {
'headers': {'Authorization': 'Token token="{}"'.format(token)},
'allow_redirects': False,
}
# https://www.conjur.org/api.html#secrets-retrieve-a-secret-get
@@ -88,7 +90,7 @@ def conjur_backend(**kwargs):
with CertFiles(cacert) as cert:
lookup_kwargs['verify'] = cert
resp = requests.get(path, timeout=30, **lookup_kwargs)
resp.raise_for_status()
raise_for_status(resp)
return resp.text

View File

@@ -3,7 +3,7 @@ import os
import pathlib
from urllib.parse import urljoin
from .plugin import CredentialPlugin, CertFiles
from .plugin import CredentialPlugin, CertFiles, raise_for_status
import requests
from django.utils.translation import ugettext_lazy as _
@@ -40,6 +40,13 @@ base_inputs = {
'multiline': False,
'secret': True,
'help_text': _('The Secret ID for AppRole Authentication')
}, {
'id': 'default_auth_path',
'label': _('Path to Approle Auth'),
'type': 'string',
'multiline': False,
'default': 'approle',
'help_text': _('The AppRole Authentication path to use if one isn\'t provided in the metadata when linking to an input field. Defaults to \'approle\'')
}
],
'metadata': [{
@@ -47,10 +54,11 @@ base_inputs = {
'label': _('Path to Secret'),
'type': 'string',
'help_text': _('The path to the secret stored in the secret backend e.g, /some/secret/')
},{
}, {
'id': 'auth_path',
'label': _('Path to Auth'),
'type': 'string',
'multiline': False,
'help_text': _('The path where the Authentication method is mounted e.g, approle')
}],
'required': ['url', 'secret_path'],
@@ -118,7 +126,9 @@ def handle_auth(**kwargs):
def approle_auth(**kwargs):
role_id = kwargs['role_id']
secret_id = kwargs['secret_id']
auth_path = kwargs.get('auth_path') or 'approle'
# we first try to use the 'auth_path' from the metadata
# if not found we try to fetch the 'default_auth_path' from inputs
auth_path = kwargs.get('auth_path') or kwargs['default_auth_path']
url = urljoin(kwargs['url'], 'v1')
cacert = kwargs.get('cacert', None)
@@ -145,11 +155,14 @@ def kv_backend(**kwargs):
cacert = kwargs.get('cacert', None)
api_version = kwargs['api_version']
request_kwargs = {'timeout': 30}
request_kwargs = {
'timeout': 30,
'allow_redirects': False,
}
sess = requests.Session()
sess.headers['Authorization'] = 'Bearer {}'.format(token)
# Compatability header for older installs of Hashicorp Vault
# Compatibility header for older installs of Hashicorp Vault
sess.headers['X-Vault-Token'] = token
if api_version == 'v2':
@@ -175,7 +188,7 @@ def kv_backend(**kwargs):
with CertFiles(cacert) as cert:
request_kwargs['verify'] = cert
response = sess.get(request_url, **request_kwargs)
response.raise_for_status()
raise_for_status(response)
json = response.json()
if api_version == 'v2':
@@ -198,7 +211,10 @@ def ssh_backend(**kwargs):
role = kwargs['role']
cacert = kwargs.get('cacert', None)
request_kwargs = {'timeout': 30}
request_kwargs = {
'timeout': 30,
'allow_redirects': False,
}
request_kwargs['json'] = {'public_key': kwargs['public_key']}
if kwargs.get('valid_principals'):
@@ -215,7 +231,7 @@ def ssh_backend(**kwargs):
request_kwargs['verify'] = cert
resp = sess.post(request_url, **request_kwargs)
resp.raise_for_status()
raise_for_status(resp)
return resp.json()['data']['signed_key']

View File

@@ -3,9 +3,19 @@ import tempfile
from collections import namedtuple
from requests.exceptions import HTTPError
CredentialPlugin = namedtuple('CredentialPlugin', ['name', 'inputs', 'backend'])
def raise_for_status(resp):
resp.raise_for_status()
if resp.status_code >= 300:
exc = HTTPError()
setattr(exc, 'response', resp)
raise exc
class CertFiles():
"""
A context manager used for writing a certificate and (optional) key

View File

@@ -2,6 +2,9 @@ import logging
import uuid
import json
from django.conf import settings
import redis
from awx.main.dispatch import get_local_queuename
from . import pg_bus_conn
@@ -21,7 +24,15 @@ class Control(object):
self.queuename = host or get_local_queuename()
def status(self, *args, **kwargs):
return self.control_with_reply('status', *args, **kwargs)
r = redis.Redis.from_url(settings.BROKER_URL)
if self.service == 'dispatcher':
stats = r.get(f'awx_{self.service}_statistics') or b''
return stats.decode('utf-8')
else:
workers = []
for key in r.keys('awx_callback_receiver_statistics_*'):
workers.append(r.get(key).decode('utf-8'))
return '\n'.join(workers)
def running(self, *args, **kwargs):
return self.control_with_reply('running', *args, **kwargs)
@@ -43,7 +54,7 @@ class Control(object):
for reply in conn.events(select_timeout=timeout, yield_timeouts=True):
if reply is None:
logger.error(f'{self.service} did not reply within {timeout}s')
raise RuntimeError("{self.service} did not reply within {timeout}s")
raise RuntimeError(f"{self.service} did not reply within {timeout}s")
break
return json.loads(reply.payload)

View File

@@ -5,6 +5,7 @@ import signal
import sys
import time
import traceback
from datetime import datetime
from uuid import uuid4
import collections
@@ -27,6 +28,12 @@ else:
logger = logging.getLogger('awx.main.dispatch')
class NoOpResultQueue(object):
def put(self, item):
pass
class PoolWorker(object):
'''
Used to track a worker child process and its pending and finished messages.
@@ -56,11 +63,13 @@ class PoolWorker(object):
It is "idle" when self.managed_tasks is empty.
'''
def __init__(self, queue_size, target, args):
track_managed_tasks = False
def __init__(self, queue_size, target, args, **kwargs):
self.messages_sent = 0
self.messages_finished = 0
self.managed_tasks = collections.OrderedDict()
self.finished = MPQueue(queue_size)
self.finished = MPQueue(queue_size) if self.track_managed_tasks else NoOpResultQueue()
self.queue = MPQueue(queue_size)
self.process = Process(target=target, args=(self.queue, self.finished) + args)
self.process.daemon = True
@@ -74,7 +83,8 @@ class PoolWorker(object):
if not body.get('uuid'):
body['uuid'] = str(uuid4())
uuid = body['uuid']
self.managed_tasks[uuid] = body
if self.track_managed_tasks:
self.managed_tasks[uuid] = body
self.queue.put(body, block=True, timeout=5)
self.messages_sent += 1
self.calculate_managed_tasks()
@@ -111,6 +121,8 @@ class PoolWorker(object):
return str(self.process.exitcode)
def calculate_managed_tasks(self):
if not self.track_managed_tasks:
return
# look to see if any tasks were finished
finished = []
for _ in range(self.finished.qsize()):
@@ -135,6 +147,8 @@ class PoolWorker(object):
@property
def current_task(self):
if not self.track_managed_tasks:
return None
self.calculate_managed_tasks()
# the task at [0] is the one that's running right now (or is about to
# be running)
@@ -145,6 +159,8 @@ class PoolWorker(object):
@property
def orphaned_tasks(self):
if not self.track_managed_tasks:
return []
orphaned = []
if not self.alive:
# if this process had a running task that never finished,
@@ -179,6 +195,11 @@ class PoolWorker(object):
return not self.busy
class StatefulPoolWorker(PoolWorker):
track_managed_tasks = True
class WorkerPool(object):
'''
Creates a pool of forked PoolWorkers.
@@ -200,6 +221,7 @@ class WorkerPool(object):
)
'''
pool_cls = PoolWorker
debug_meta = ''
def __init__(self, min_workers=None, queue_size=None):
@@ -225,7 +247,7 @@ class WorkerPool(object):
# for the DB and cache connections (that way lies race conditions)
django_connection.close()
django_cache.close()
worker = PoolWorker(self.queue_size, self.target, (idx,) + self.target_args)
worker = self.pool_cls(self.queue_size, self.target, (idx,) + self.target_args)
self.workers.append(worker)
try:
worker.start()
@@ -236,13 +258,13 @@ class WorkerPool(object):
return idx, worker
def debug(self, *args, **kwargs):
self.cleanup()
tmpl = Template(
'Recorded at: {{ dt }} \n'
'{{ pool.name }}[pid:{{ pool.pid }}] workers total={{ workers|length }} {{ meta }} \n'
'{% for w in workers %}'
'. worker[pid:{{ w.pid }}]{% if not w.alive %} GONE exit={{ w.exitcode }}{% endif %}'
' sent={{ w.messages_sent }}'
' finished={{ w.messages_finished }}'
'{% if w.messages_finished %} finished={{ w.messages_finished }}{% endif %}'
' qsize={{ w.managed_tasks|length }}'
' rss={{ w.mb }}MB'
'{% for task in w.managed_tasks.values() %}'
@@ -260,7 +282,11 @@ class WorkerPool(object):
'\n'
'{% endfor %}'
)
return tmpl.render(pool=self, workers=self.workers, meta=self.debug_meta)
now = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC')
return tmpl.render(
pool=self, workers=self.workers, meta=self.debug_meta,
dt=now
)
def write(self, preferred_queue, body):
queue_order = sorted(range(len(self.workers)), key=lambda x: -1 if x==preferred_queue else x)
@@ -293,6 +319,8 @@ class AutoscalePool(WorkerPool):
down based on demand
'''
pool_cls = StatefulPoolWorker
def __init__(self, *args, **kwargs):
self.max_workers = kwargs.pop('max_workers', None)
super(AutoscalePool, self).__init__(*args, **kwargs)
@@ -309,6 +337,10 @@ class AutoscalePool(WorkerPool):
# max workers can't be less than min_workers
self.max_workers = max(self.min_workers, self.max_workers)
def debug(self, *args, **kwargs):
self.cleanup()
return super(AutoscalePool, self).debug(*args, **kwargs)
@property
def should_grow(self):
if len(self.workers) < self.min_workers:

View File

@@ -43,6 +43,9 @@ class WorkerSignalHandler:
class AWXConsumerBase(object):
last_stats = time.time()
def __init__(self, name, worker, queues=[], pool=None):
self.should_stop = False
@@ -54,6 +57,7 @@ class AWXConsumerBase(object):
if pool is None:
self.pool = WorkerPool()
self.pool.init_workers(self.worker.work_loop)
self.redis = redis.Redis.from_url(settings.BROKER_URL)
@property
def listening_on(self):
@@ -99,6 +103,16 @@ class AWXConsumerBase(object):
queue = 0
self.pool.write(queue, body)
self.total_messages += 1
self.record_statistics()
def record_statistics(self):
if time.time() - self.last_stats > 1: # buffer stat recording to once per second
try:
self.redis.set(f'awx_{self.name}_statistics', self.pool.debug())
self.last_stats = time.time()
except Exception:
logger.exception(f"encountered an error communicating with redis to store {self.name} statistics")
self.last_stats = time.time()
def run(self, *args, **kwargs):
signal.signal(signal.SIGINT, self.stop)
@@ -118,23 +132,9 @@ class AWXConsumerRedis(AWXConsumerBase):
super(AWXConsumerRedis, self).run(*args, **kwargs)
self.worker.on_start()
time_to_sleep = 1
while True:
queue = redis.Redis.from_url(settings.BROKER_URL)
while True:
try:
res = queue.blpop(self.queues)
time_to_sleep = 1
res = json.loads(res[1])
self.process_task(res)
except redis.exceptions.RedisError:
time_to_sleep = min(time_to_sleep * 2, 30)
logger.exception(f"encountered an error communicating with redis. Reconnect attempt in {time_to_sleep} seconds")
time.sleep(time_to_sleep)
except (json.JSONDecodeError, KeyError):
logger.exception("failed to decode JSON message from redis")
if self.should_stop:
return
logger.debug(f'{os.getpid()} is alive')
time.sleep(60)
class AWXConsumerPG(AWXConsumerBase):

View File

@@ -1,17 +1,18 @@
import cProfile
import json
import logging
import os
import pstats
import signal
import tempfile
import time
import traceback
from queue import Empty as QueueEmpty
from django.conf import settings
from django.utils.timezone import now as tz_now
from django.db import DatabaseError, OperationalError, connection as django_connection
from django.db.utils import InterfaceError, InternalError, IntegrityError
from django.db.utils import InterfaceError, InternalError
import psutil
import redis
from awx.main.consumers import emit_channel_notification
from awx.main.models import (JobEvent, AdHocCommandEvent, ProjectUpdateEvent,
@@ -19,15 +20,12 @@ from awx.main.models import (JobEvent, AdHocCommandEvent, ProjectUpdateEvent,
Job)
from awx.main.tasks import handle_success_and_failure_notifications
from awx.main.models.events import emit_event_detail
from awx.main.utils.profiling import AWXProfiler
from .base import BaseWorker
logger = logging.getLogger('awx.main.commands.run_callback_receiver')
# the number of seconds to buffer events in memory before flushing
# using JobEvent.objects.bulk_create()
BUFFER_SECONDS = .1
class CallbackBrokerWorker(BaseWorker):
'''
@@ -39,31 +37,61 @@ class CallbackBrokerWorker(BaseWorker):
'''
MAX_RETRIES = 2
last_stats = time.time()
total = 0
last_event = ''
prof = None
def __init__(self):
self.buff = {}
self.pid = os.getpid()
self.redis = redis.Redis.from_url(settings.BROKER_URL)
self.prof = AWXProfiler("CallbackBrokerWorker")
for key in self.redis.keys('awx_callback_receiver_statistics_*'):
self.redis.delete(key)
def read(self, queue):
try:
return queue.get(block=True, timeout=BUFFER_SECONDS)
except QueueEmpty:
return {'event': 'FLUSH'}
res = self.redis.blpop(settings.CALLBACK_QUEUE, timeout=settings.JOB_EVENT_BUFFER_SECONDS)
if res is None:
return {'event': 'FLUSH'}
self.total += 1
return json.loads(res[1])
except redis.exceptions.RedisError:
logger.exception("encountered an error communicating with redis")
time.sleep(1)
except (json.JSONDecodeError, KeyError):
logger.exception("failed to decode JSON message from redis")
finally:
self.record_statistics()
return {'event': 'FLUSH'}
def record_statistics(self):
# buffer stat recording to once per (by default) 5s
if time.time() - self.last_stats > settings.JOB_EVENT_STATISTICS_INTERVAL:
try:
self.redis.set(f'awx_callback_receiver_statistics_{self.pid}', self.debug())
self.last_stats = time.time()
except Exception:
logger.exception("encountered an error communicating with redis")
self.last_stats = time.time()
def debug(self):
return f'. worker[pid:{self.pid}] sent={self.total} rss={self.mb}MB {self.last_event}'
@property
def mb(self):
return '{:0.3f}'.format(
psutil.Process(self.pid).memory_info().rss / 1024.0 / 1024.0
)
def toggle_profiling(self, *args):
if self.prof:
self.prof.disable()
filename = f'callback-{os.getpid()}.pstats'
filepath = os.path.join(tempfile.gettempdir(), filename)
with open(filepath, 'w') as f:
pstats.Stats(self.prof, stream=f).sort_stats('cumulative').print_stats()
pstats.Stats(self.prof).dump_stats(filepath + '.raw')
self.prof = False
logger.error(f'profiling is disabled, wrote {filepath}')
else:
self.prof = cProfile.Profile()
self.prof.enable()
if not self.prof.is_started():
self.prof.start()
logger.error('profiling is enabled')
else:
filepath = self.prof.stop()
logger.error(f'profiling is disabled, wrote {filepath}')
def work_loop(self, *args, **kw):
if settings.AWX_CALLBACK_PROFILE:
@@ -84,20 +112,12 @@ class CallbackBrokerWorker(BaseWorker):
e.modified = now
try:
cls.objects.bulk_create(events)
except Exception as exc:
except Exception:
# if an exception occurs, we should re-attempt to save the
# events one-by-one, because something in the list is
# broken/stale (e.g., an IntegrityError on a specific event)
# broken/stale
for e in events:
try:
if (
isinstance(exc, IntegrityError) and
getattr(e, 'host_id', '')
):
# this is one potential IntegrityError we can
# work around - if the host disappears before
# the event can be processed
e.host_id = None
e.save()
except Exception:
logger.exception('Database Error Saving Job Event')
@@ -108,6 +128,8 @@ class CallbackBrokerWorker(BaseWorker):
def perform_work(self, body):
try:
flush = body.get('event') == 'FLUSH'
if flush:
self.last_event = ''
if not flush:
event_map = {
'job_id': JobEvent,
@@ -123,6 +145,8 @@ class CallbackBrokerWorker(BaseWorker):
job_identifier = body[key]
break
self.last_event = f'\n\t- {cls.__name__} for #{job_identifier} ({body.get("event", "")} {body.get("uuid", "")})' # noqa
if body.get('event') == 'EOF':
try:
final_counter = body.get('final_counter', 0)

View File

@@ -30,3 +30,10 @@ class _AwxTaskError():
AwxTaskError = _AwxTaskError()
class PostRunError(Exception):
def __init__(self, msg, status='failed', tb=''):
self.status = status
self.tb = tb
super(PostRunError, self).__init__(msg)

View File

@@ -7,8 +7,8 @@ import json
import re
import urllib.parse
from jinja2 import Environment, StrictUndefined
from jinja2.exceptions import UndefinedError, TemplateSyntaxError
from jinja2 import sandbox, StrictUndefined
from jinja2.exceptions import UndefinedError, TemplateSyntaxError, SecurityError
# Django
from django.contrib.postgres.fields import JSONField as upstream_JSONBField
@@ -50,7 +50,7 @@ from awx.main.models.rbac import (
batch_role_ancestor_rebuilding, Role,
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR, ROLE_SINGLETON_SYSTEM_AUDITOR
)
from awx.main.constants import ENV_BLACKLIST
from awx.main.constants import ENV_BLOCKLIST
from awx.main import utils
@@ -637,6 +637,14 @@ class CredentialInputField(JSONSchemaField):
else:
decrypted_values[k] = v
# don't allow secrets with $encrypted$ on new object creation
if not model_instance.pk:
for field in model_instance.credential_type.secret_fields:
if value.get(field) == '$encrypted$':
raise serializers.ValidationError({
self.name: [f'$encrypted$ is a reserved keyword, and cannot be used for {field}.']
})
super(JSONSchemaField, self).validate(decrypted_values, model_instance)
errors = {}
for error in Draft4Validator(
@@ -870,9 +878,9 @@ class CredentialTypeInjectorField(JSONSchemaField):
'use is not allowed in credentials.').format(env_var),
code='invalid', params={'value': env_var},
)
if env_var in ENV_BLACKLIST:
if env_var in ENV_BLOCKLIST:
raise django_exceptions.ValidationError(
_('Environment variable {} is blacklisted from use in credentials.').format(env_var),
_('Environment variable {} is not allowed to be used in credentials.').format(env_var),
code='invalid', params={'value': env_var},
)
@@ -932,7 +940,7 @@ class CredentialTypeInjectorField(JSONSchemaField):
self.validate_env_var_allowed(key)
for key, tmpl in injector.items():
try:
Environment(
sandbox.ImmutableSandboxedEnvironment(
undefined=StrictUndefined
).from_string(tmpl).render(valid_namespace)
except UndefinedError as e:
@@ -942,6 +950,10 @@ class CredentialTypeInjectorField(JSONSchemaField):
code='invalid',
params={'value': value},
)
except SecurityError as e:
raise django_exceptions.ValidationError(
_('Encountered unsafe code execution: {}').format(e)
)
except TemplateSyntaxError as e:
raise django_exceptions.ValidationError(
_('Syntax error rendering template for {sub_key} inside of {type} ({error_msg})').format(

View File

@@ -58,7 +58,7 @@ class IsolatedManager(object):
os.chmod(temp.name, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
for host in hosts:
inventory['all']['hosts'][host] = {
"ansible_connection": "community.kubernetes.kubectl",
"ansible_connection": "kubectl",
"ansible_kubectl_config": path,
}
else:
@@ -149,7 +149,6 @@ class IsolatedManager(object):
# don't rsync source control metadata (it can be huge!)
'- /project/.git',
'- /project/.svn',
'- /project/.hg',
# don't rsync job events that are in the process of being written
'- /artifacts/job_events/*-partial.json.tmp',
# don't rsync the ssh_key FIFO

View File

@@ -0,0 +1,96 @@
from django.core.management.base import BaseCommand
from django.db import connection
from awx.main.models import JobTemplate
class Command(BaseCommand):
help = "Find the slowest tasks and hosts for a Job Template's most recent runs."
def add_arguments(self, parser):
parser.add_argument('--template', dest='jt', type=int,
help='ID of the Job Template to profile')
parser.add_argument('--threshold', dest='threshold', type=float, default=30,
help='Only show tasks that took at least this many seconds (defaults to 30)')
parser.add_argument('--history', dest='history', type=float, default=25,
help='The number of historic jobs to look at')
parser.add_argument('--ignore', action='append', help='ignore a specific action (e.g., --ignore git)')
def handle(self, *args, **options):
jt = options['jt']
threshold = options['threshold']
history = options['history']
ignore = options['ignore']
print('## ' + JobTemplate.objects.get(pk=jt).name + f' (last {history} runs)\n')
with connection.cursor() as cursor:
cursor.execute(
f'''
SELECT
b.id, b.job_id, b.host_name, b.created - a.created delta,
b.task task,
b.event_data::json->'task_action' task_action,
b.event_data::json->'task_path' task_path
FROM main_jobevent a JOIN main_jobevent b
ON b.parent_uuid = a.parent_uuid AND a.host_name = b.host_name
WHERE
a.event = 'runner_on_start' AND
b.event != 'runner_on_start' AND
b.event != 'runner_on_skipped' AND
b.failed = false AND
a.job_id IN (
SELECT unifiedjob_ptr_id FROM main_job
WHERE job_template_id={jt}
ORDER BY unifiedjob_ptr_id DESC
LIMIT {history}
)
ORDER BY delta DESC;
'''
)
slowest_events = cursor.fetchall()
def format_td(x):
return str(x).split('.')[0]
fastest = dict()
for event in slowest_events:
_id, job_id, host, duration, task, action, playbook = event
playbook = playbook.rsplit('/')[-1]
if ignore and action in ignore:
continue
if host:
fastest[(action, playbook)] = (_id, host, format_td(duration))
host_counts = dict()
warned = set()
print(f'slowest tasks (--threshold={threshold})\n---')
for event in slowest_events:
_id, job_id, host, duration, task, action, playbook = event
if ignore and action in ignore:
continue
if duration.total_seconds() < threshold:
break
playbook = playbook.rsplit('/')[-1]
human_duration = format_td(duration)
fastest_summary = ''
fastest_match = fastest.get((action, playbook))
if fastest_match[2] != human_duration and (host, action, playbook) not in warned:
warned.add((host, action, playbook))
fastest_summary = ' ' + self.style.WARNING(f'{fastest_match[1]} ran this in {fastest_match[2]}s at /api/v2/job_events/{fastest_match[0]}/')
url = f'/api/v2/jobs/{job_id}/'
print(' -- '.join([url, host, human_duration, action, task, playbook]) + fastest_summary)
host_counts.setdefault(host, [])
host_counts[host].append(duration)
host_counts = sorted(host_counts.items(), key=lambda item: [e.total_seconds() for e in item[1]], reverse=True)
print('\nslowest hosts\n---')
for h, matches in host_counts:
total = len(matches)
total_seconds = sum([e.total_seconds() for e in matches])
print(f'{h} had {total} tasks that ran longer than {threshold} second(s) for a total of {total_seconds}')
print('')

View File

@@ -18,7 +18,5 @@ class Command(BaseCommand):
super(Command, self).__init__()
license = get_licenser().validate()
if options.get('data'):
if license.get('license_key', '') != 'UNLICENSED':
license['license_key'] = '********'
return json.dumps(license)
return license.get('license_type', 'none')

View File

@@ -8,5 +8,7 @@ class Command(MakeMigrations):
def execute(self, *args, **options):
settings = connections['default'].settings_dict.copy()
settings['ENGINE'] = 'sqlite3'
if 'application_name' in settings['OPTIONS']:
del settings['OPTIONS']['application_name']
connections['default'] = DatabaseWrapper(settings)
return MakeMigrations().execute(*args, **options)

View File

@@ -42,6 +42,16 @@ class Command(BaseCommand):
},
created_by=superuser)
c.admin_role.members.add(superuser)
public_galaxy_credential = Credential(
name='Ansible Galaxy',
managed_by_tower=True,
credential_type=CredentialType.objects.get(kind='galaxy'),
inputs = {
'url': 'https://galaxy.ansible.com/'
}
)
public_galaxy_credential.save()
o.galaxy_credentials.add(public_galaxy_credential)
i = Inventory.objects.create(name='Demo Inventory',
organization=o,
created_by=superuser)

View File

@@ -1,6 +1,9 @@
import logging
from awx.main.analytics import gather, ship
from dateutil import parser
from django.core.management.base import BaseCommand
from django.utils.timezone import now
class Command(BaseCommand):
@@ -15,6 +18,10 @@ class Command(BaseCommand):
help='Gather analytics without shipping. Works even if analytics are disabled in settings.')
parser.add_argument('--ship', dest='ship', action='store_true',
help='Enable to ship metrics to the Red Hat Cloud')
parser.add_argument('--since', dest='since', action='store',
help='Start date for collection')
parser.add_argument('--until', dest='until', action='store',
help='End date for collection')
def init_logging(self):
self.logger = logging.getLogger('awx.main.analytics')
@@ -28,11 +35,28 @@ class Command(BaseCommand):
self.init_logging()
opt_ship = options.get('ship')
opt_dry_run = options.get('dry-run')
opt_since = options.get('since') or None
opt_until = options.get('until') or None
if opt_since:
since = parser.parse(opt_since)
else:
since = None
if opt_until:
until = parser.parse(opt_until)
else:
until = now()
if opt_ship and opt_dry_run:
self.logger.error('Both --ship and --dry-run cannot be processed at the same time.')
return
tgz = gather(collection_type='manual' if not opt_dry_run else 'dry-run')
if tgz:
self.logger.debug(tgz)
tgzfiles = gather(collection_type='manual' if not opt_dry_run else 'dry-run', since = since, until = until)
if tgzfiles:
for tgz in tgzfiles:
self.logger.info(tgz)
else:
self.logger.error('No analytics collected')
if opt_ship:
ship(tgz)
if tgzfiles:
for tgz in tgzfiles:
ship(tgz)

View File

@@ -0,0 +1,117 @@
# Python
import asciichartpy as chart
import collections
import time
import sys
# Django
from django.db.models import Count
from django.core.management.base import BaseCommand
# AWX
from awx.main.models import (
Job,
Instance
)
DEFAULT_WIDTH = 100
DEFAULT_HEIGHT = 30
def chart_color_lookup(color_str):
return getattr(chart, color_str)
def clear_screen():
print(chr(27) + "[2J")
class JobStatus():
def __init__(self, status, color, width):
self.status = status
self.color = color
self.color_code = chart_color_lookup(color)
self.x = collections.deque(maxlen=width)
self.y = collections.deque(maxlen=width)
def tick(self, x, y):
self.x.append(x)
self.y.append(y)
class JobStatusController:
RESET = chart_color_lookup('reset')
def __init__(self, width):
self.plots = [
JobStatus('pending', 'red', width),
JobStatus('waiting', 'blue', width),
JobStatus('running', 'green', width)
]
self.ts_start = int(time.time())
def tick(self):
ts = int(time.time()) - self.ts_start
q = Job.objects.filter(status__in=['pending','waiting','running']).values_list('status').order_by().annotate(Count('status'))
status_count = dict(pending=0, waiting=0, running=0)
for status, count in q:
status_count[status] = count
for p in self.plots:
p.tick(ts, status_count[p.status])
def series(self):
return [list(p.y) for p in self.plots]
def generate_status(self):
line = ""
lines = []
for p in self.plots:
lines.append(f'{p.color_code}{p.status} {p.y[-1]}{self.RESET}')
line += ", ".join(lines) + '\n'
width = 5
time_running = int(time.time()) - self.ts_start
instances = Instance.objects.all().order_by('hostname')
line += "Capacity: " + ", ".join([f"{instance.capacity:{width}}" for instance in instances]) + '\n'
line += "Remaining: " + ", ".join([f"{instance.remaining_capacity:{width}}" for instance in instances]) + '\n'
line += f"Seconds running: {time_running}" + '\n'
return line
class Command(BaseCommand):
help = "Plot pending, waiting, running jobs over time on the terminal"
def add_arguments(self, parser):
parser.add_argument('--refresh', dest='refresh', type=float, default=1.0,
help='Time between refreshes of the graph and data in seconds (defaults to 1.0)')
parser.add_argument('--width', dest='width', type=int, default=DEFAULT_WIDTH,
help=f'Width of the graph (defaults to {DEFAULT_WIDTH})')
parser.add_argument('--height', dest='height', type=int, default=DEFAULT_HEIGHT,
help=f'Height of the graph (defaults to {DEFAULT_HEIGHT})')
def handle(self, *args, **options):
refresh_seconds = options['refresh']
width = options['width']
height = options['height']
jctl = JobStatusController(width)
conf = {
'colors': [chart_color_lookup(p.color) for p in jctl.plots],
'height': height,
}
while True:
jctl.tick()
draw = chart.plot(jctl.series(), conf)
status_line = jctl.generate_status()
clear_screen()
print(draw)
sys.stdout.write(status_line)
time.sleep(refresh_seconds)

View File

@@ -12,7 +12,6 @@ import sys
import time
import traceback
import shutil
from distutils.version import LooseVersion as Version
# Django
from django.conf import settings
@@ -20,6 +19,9 @@ from django.core.management.base import BaseCommand, CommandError
from django.db import connection, transaction
from django.utils.encoding import smart_text
# DRF error class to distinguish license exceptions
from rest_framework.exceptions import PermissionDenied
# AWX inventory imports
from awx.main.models.inventory import (
Inventory,
@@ -32,14 +34,14 @@ from awx.main.utils.safe_yaml import sanitize_jinja
# other AWX imports
from awx.main.models.rbac import batch_role_ancestor_rebuilding
# TODO: remove proot utils once we move to running inv. updates in containers
from awx.main.utils import (
ignore_inventory_computed_fields,
check_proot_installed,
wrap_args_with_proot,
build_proot_temp_dir,
ignore_inventory_computed_fields,
get_licenser
)
from awx.main.utils.common import _get_ansible_version
from awx.main.signals import disable_activity_stream
from awx.main.constants import STANDARD_INVENTORY_UPDATE_ENV
from awx.main.utils.pglock import advisory_lock
@@ -55,11 +57,11 @@ No license.
See http://www.ansible.com/renew for license information.'''
LICENSE_MESSAGE = '''\
Number of licensed instances exceeded, would bring available instances to %(new_count)d, system is licensed for %(available_instances)d.
Number of licensed instances exceeded, would bring available instances to %(new_count)d, system is licensed for %(instance_count)d.
See http://www.ansible.com/renew for license extension information.'''
DEMO_LICENSE_MESSAGE = '''\
Demo mode free license count exceeded, would bring available instances to %(new_count)d, demo mode allows %(available_instances)d.
Demo mode free license count exceeded, would bring available instances to %(new_count)d, demo mode allows %(instance_count)d.
See http://www.ansible.com/renew for licensing information.'''
@@ -77,13 +79,11 @@ class AnsibleInventoryLoader(object):
/usr/bin/ansible/ansible-inventory -i hosts --list
'''
def __init__(self, source, is_custom=False, venv_path=None, verbosity=0):
def __init__(self, source, venv_path=None, verbosity=0):
self.source = source
self.source_dir = functioning_dir(self.source)
self.is_custom = is_custom
self.tmp_private_dir = None
self.method = 'ansible-inventory'
self.verbosity = verbosity
# TODO: remove once proot has been removed
self.tmp_private_dir = None
if venv_path:
self.venv_path = venv_path
else:
@@ -136,40 +136,31 @@ class AnsibleInventoryLoader(object):
# inside of /venv/ansible, so we override the specified interpreter
# https://github.com/ansible/ansible/issues/50714
bargs = ['python', ansible_inventory_path, '-i', self.source]
ansible_version = _get_ansible_version(ansible_inventory_path[:-len('-inventory')])
if ansible_version != 'unknown':
this_version = Version(ansible_version)
if this_version >= Version('2.5'):
bargs.extend(['--playbook-dir', self.source_dir])
if this_version >= Version('2.8'):
if self.verbosity:
# INFO: -vvv, DEBUG: -vvvvv, for inventory, any more than 3 makes little difference
bargs.append('-{}'.format('v' * min(5, self.verbosity * 2 + 1)))
bargs.extend(['--playbook-dir', functioning_dir(self.source)])
if self.verbosity:
# INFO: -vvv, DEBUG: -vvvvv, for inventory, any more than 3 makes little difference
bargs.append('-{}'.format('v' * min(5, self.verbosity * 2 + 1)))
logger.debug('Using base command: {}'.format(' '.join(bargs)))
return bargs
# TODO: Remove this once we move to running ansible-inventory in containers
# and don't need proot for process isolation anymore
def get_proot_args(self, cmd, env):
cwd = os.getcwd()
if not check_proot_installed():
raise RuntimeError("proot is not installed but is configured for use")
kwargs = {}
if self.is_custom:
# use source's tmp dir for proot, task manager will delete folder
logger.debug("Using provided directory '{}' for isolation.".format(self.source_dir))
kwargs['proot_temp_dir'] = self.source_dir
cwd = self.source_dir
else:
# we cannot safely store tmp data in source dir or trust script contents
if env['AWX_PRIVATE_DATA_DIR']:
# If this is non-blank, file credentials are being used and we need access
private_data_dir = functioning_dir(env['AWX_PRIVATE_DATA_DIR'])
logger.debug("Using private credential data in '{}'.".format(private_data_dir))
kwargs['private_data_dir'] = private_data_dir
self.tmp_private_dir = build_proot_temp_dir()
logger.debug("Using fresh temporary directory '{}' for isolation.".format(self.tmp_private_dir))
kwargs['proot_temp_dir'] = self.tmp_private_dir
kwargs['proot_show_paths'] = [functioning_dir(self.source), settings.AWX_ANSIBLE_COLLECTIONS_PATHS]
# we cannot safely store tmp data in source dir or trust script contents
if env['AWX_PRIVATE_DATA_DIR']:
# If this is non-blank, file credentials are being used and we need access
private_data_dir = functioning_dir(env['AWX_PRIVATE_DATA_DIR'])
logger.debug("Using private credential data in '{}'.".format(private_data_dir))
kwargs['private_data_dir'] = private_data_dir
self.tmp_private_dir = build_proot_temp_dir()
logger.debug("Using fresh temporary directory '{}' for isolation.".format(self.tmp_private_dir))
kwargs['proot_temp_dir'] = self.tmp_private_dir
kwargs['proot_show_paths'] = [functioning_dir(self.source), settings.AWX_ANSIBLE_COLLECTIONS_PATHS]
logger.debug("Running from `{}` working directory.".format(cwd))
if self.venv_path != settings.ANSIBLE_VENV_PATH:
@@ -177,12 +168,14 @@ class AnsibleInventoryLoader(object):
return wrap_args_with_proot(cmd, cwd, **kwargs)
def command_to_json(self, cmd):
data = {}
stdout, stderr = '', ''
env = self.build_env()
if ((self.is_custom or 'AWX_PRIVATE_DATA_DIR' in env) and
# TODO: remove proot args once inv. updates run in containers
if (('AWX_PRIVATE_DATA_DIR' in env) and
getattr(settings, 'AWX_PROOT_ENABLED', False)):
cmd = self.get_proot_args(cmd, env)
@@ -191,11 +184,13 @@ class AnsibleInventoryLoader(object):
stdout = smart_text(stdout)
stderr = smart_text(stderr)
# TODO: can be removed when proot is removed
if self.tmp_private_dir:
shutil.rmtree(self.tmp_private_dir, True)
if proc.returncode != 0:
raise RuntimeError('%s failed (rc=%d) with stdout:\n%s\nstderr:\n%s' % (
self.method, proc.returncode, stdout, stderr))
'ansible-inventory', proc.returncode, stdout, stderr))
for line in stderr.splitlines():
logger.error(line)
@@ -238,9 +233,9 @@ class Command(BaseCommand):
action='store_true', default=False,
help='overwrite (rather than merge) variables')
parser.add_argument('--keep-vars', dest='keep_vars', action='store_true', default=False,
help='use database variables if set')
help='DEPRECATED legacy option, has no effect')
parser.add_argument('--custom', dest='custom', action='store_true', default=False,
help='this is a custom inventory script')
help='DEPRECATED indicates a custom inventory script, no longer used')
parser.add_argument('--source', dest='source', type=str, default=None,
metavar='s', help='inventory directory, file, or script to load')
parser.add_argument('--enabled-var', dest='enabled_var', type=str,
@@ -266,10 +261,10 @@ class Command(BaseCommand):
'specifies the unique, immutable instance ID, may be '
'specified as "foo.bar" to traverse nested dicts.')
def set_logging_level(self):
def set_logging_level(self, verbosity):
log_levels = dict(enumerate([logging.WARNING, logging.INFO,
logging.DEBUG, 0]))
logger.setLevel(log_levels.get(self.verbosity, 0))
logger.setLevel(log_levels.get(verbosity, 0))
def _get_instance_id(self, variables, default=''):
'''
@@ -329,7 +324,8 @@ class Command(BaseCommand):
else:
raise NotImplementedError('Value of enabled {} not understood.'.format(enabled))
def get_source_absolute_path(self, source):
@staticmethod
def get_source_absolute_path(source):
if not os.path.exists(source):
raise IOError('Source does not exist: %s' % source)
source = os.path.join(os.getcwd(), os.path.dirname(source),
@@ -337,61 +333,6 @@ class Command(BaseCommand):
source = os.path.normpath(os.path.abspath(source))
return source
def load_inventory_from_database(self):
'''
Load inventory and related objects from the database.
'''
# Load inventory object based on name or ID.
if self.inventory_id:
q = dict(id=self.inventory_id)
else:
q = dict(name=self.inventory_name)
try:
self.inventory = Inventory.objects.get(**q)
except Inventory.DoesNotExist:
raise CommandError('Inventory with %s = %s cannot be found' % list(q.items())[0])
except Inventory.MultipleObjectsReturned:
raise CommandError('Inventory with %s = %s returned multiple results' % list(q.items())[0])
logger.info('Updating inventory %d: %s' % (self.inventory.pk,
self.inventory.name))
# Load inventory source if specified via environment variable (when
# inventory_import is called from an InventoryUpdate task).
inventory_source_id = os.getenv('INVENTORY_SOURCE_ID', None)
inventory_update_id = os.getenv('INVENTORY_UPDATE_ID', None)
if inventory_source_id:
try:
self.inventory_source = InventorySource.objects.get(pk=inventory_source_id,
inventory=self.inventory)
except InventorySource.DoesNotExist:
raise CommandError('Inventory source with id=%s not found' %
inventory_source_id)
try:
self.inventory_update = InventoryUpdate.objects.get(pk=inventory_update_id)
except InventoryUpdate.DoesNotExist:
raise CommandError('Inventory update with id=%s not found' %
inventory_update_id)
# Otherwise, create a new inventory source to capture this invocation
# via command line.
else:
with ignore_inventory_computed_fields():
self.inventory_source, created = InventorySource.objects.get_or_create(
inventory=self.inventory,
source='file',
source_path=os.path.abspath(self.source),
overwrite=self.overwrite,
overwrite_vars=self.overwrite_vars,
)
self.inventory_update = self.inventory_source.create_inventory_update(
_eager_fields=dict(
job_args=json.dumps(sys.argv),
job_env=dict(os.environ.items()),
job_cwd=os.getcwd())
)
# FIXME: Wait or raise error if inventory is being updated by another
# source.
def _batch_add_m2m(self, related_manager, *objs, **kwargs):
key = (related_manager.instance.pk, related_manager.through._meta.db_table)
flush = bool(kwargs.get('flush', False))
@@ -881,42 +822,41 @@ class Command(BaseCommand):
Load inventory from in-memory groups to the database, overwriting or
merging as appropriate.
'''
with advisory_lock('inventory_{}_update'.format(self.inventory.id)):
# FIXME: Attribute changes to superuser?
# Perform __in queries in batches (mainly for unit tests using SQLite).
self._batch_size = 500
self._build_db_instance_id_map()
self._build_mem_instance_id_map()
if self.overwrite:
self._delete_hosts()
self._delete_groups()
self._delete_group_children_and_hosts()
self._update_inventory()
self._create_update_groups()
self._create_update_hosts()
self._create_update_group_children()
self._create_update_group_hosts()
# FIXME: Attribute changes to superuser?
# Perform __in queries in batches (mainly for unit tests using SQLite).
self._batch_size = 500
self._build_db_instance_id_map()
self._build_mem_instance_id_map()
if self.overwrite:
self._delete_hosts()
self._delete_groups()
self._delete_group_children_and_hosts()
self._update_inventory()
self._create_update_groups()
self._create_update_hosts()
self._create_update_group_children()
self._create_update_group_hosts()
def remote_tower_license_compare(self, local_license_type):
# this requires https://github.com/ansible/ansible/pull/52747
source_vars = self.all_group.variables
remote_license_type = source_vars.get('tower_metadata', {}).get('license_type', None)
if remote_license_type is None:
raise CommandError('Unexpected Error: Tower inventory plugin missing needed metadata!')
raise PermissionDenied('Unexpected Error: Tower inventory plugin missing needed metadata!')
if local_license_type != remote_license_type:
raise CommandError('Tower server licenses must match: source: {} local: {}'.format(
raise PermissionDenied('Tower server licenses must match: source: {} local: {}'.format(
remote_license_type, local_license_type
))
def check_license(self):
license_info = get_licenser().validate()
local_license_type = license_info.get('license_type', 'UNLICENSED')
if license_info.get('license_key', 'UNLICENSED') == 'UNLICENSED':
if local_license_type == 'UNLICENSED':
logger.error(LICENSE_NON_EXISTANT_MESSAGE)
raise CommandError('No license found!')
raise PermissionDenied('No license found!')
elif local_license_type == 'open':
return
available_instances = license_info.get('available_instances', 0)
instance_count = license_info.get('instance_count', 0)
free_instances = license_info.get('free_instances', 0)
time_remaining = license_info.get('time_remaining', 0)
hard_error = license_info.get('trial', False) is True or license_info['instance_count'] == 10
@@ -924,24 +864,24 @@ class Command(BaseCommand):
if time_remaining <= 0:
if hard_error:
logger.error(LICENSE_EXPIRED_MESSAGE)
raise CommandError("License has expired!")
raise PermissionDenied("License has expired!")
else:
logger.warning(LICENSE_EXPIRED_MESSAGE)
# special check for tower-type inventory sources
# but only if running the plugin
TOWER_SOURCE_FILES = ['tower.yml', 'tower.yaml']
if self.inventory_source.source == 'tower' and any(f in self.source for f in TOWER_SOURCE_FILES):
if self.inventory_source.source == 'tower' and any(f in self.inventory_source.source_path for f in TOWER_SOURCE_FILES):
# only if this is the 2nd call to license check, we cannot compare before running plugin
if hasattr(self, 'all_group'):
self.remote_tower_license_compare(local_license_type)
if free_instances < 0:
d = {
'new_count': new_count,
'available_instances': available_instances,
'instance_count': instance_count,
}
if hard_error:
logger.error(LICENSE_MESSAGE % d)
raise CommandError('License count exceeded!')
raise PermissionDenied('License count exceeded!')
else:
logger.warning(LICENSE_MESSAGE % d)
@@ -956,7 +896,7 @@ class Command(BaseCommand):
active_count = Host.objects.org_active_count(org.id)
if active_count > org.max_hosts:
raise CommandError('Host limit for organization exceeded!')
raise PermissionDenied('Host limit for organization exceeded!')
def mark_license_failure(self, save=True):
self.inventory_update.license_error = True
@@ -967,16 +907,103 @@ class Command(BaseCommand):
self.inventory_update.save(update_fields=['org_host_limit_error'])
def handle(self, *args, **options):
self.verbosity = int(options.get('verbosity', 1))
self.set_logging_level()
self.inventory_name = options.get('inventory_name', None)
self.inventory_id = options.get('inventory_id', None)
venv_path = options.get('venv', None)
# Load inventory and related objects from database.
inventory_name = options.get('inventory_name', None)
inventory_id = options.get('inventory_id', None)
if inventory_name and inventory_id:
raise CommandError('--inventory-name and --inventory-id are mutually exclusive')
elif not inventory_name and not inventory_id:
raise CommandError('--inventory-name or --inventory-id is required')
with advisory_lock('inventory_{}_import'.format(inventory_id)):
# Obtain rest of the options needed to run update
raw_source = options.get('source', None)
if not raw_source:
raise CommandError('--source is required')
verbosity = int(options.get('verbosity', 1))
self.set_logging_level(verbosity)
venv_path = options.get('venv', None)
# Load inventory object based on name or ID.
if inventory_id:
q = dict(id=inventory_id)
else:
q = dict(name=inventory_name)
try:
inventory = Inventory.objects.get(**q)
except Inventory.DoesNotExist:
raise CommandError('Inventory with %s = %s cannot be found' % list(q.items())[0])
except Inventory.MultipleObjectsReturned:
raise CommandError('Inventory with %s = %s returned multiple results' % list(q.items())[0])
logger.info('Updating inventory %d: %s' % (inventory.pk, inventory.name))
# Create ad-hoc inventory source and inventory update objects
with ignore_inventory_computed_fields():
source = Command.get_source_absolute_path(raw_source)
inventory_source, created = InventorySource.objects.get_or_create(
inventory=inventory,
source='file',
source_path=os.path.abspath(source),
overwrite=bool(options.get('overwrite', False)),
overwrite_vars=bool(options.get('overwrite_vars', False)),
)
inventory_update = inventory_source.create_inventory_update(
_eager_fields=dict(
job_args=json.dumps(sys.argv),
job_env=dict(os.environ.items()),
job_cwd=os.getcwd())
)
data = AnsibleInventoryLoader(
source=source, venv_path=venv_path, verbosity=verbosity
).load()
logger.debug('Finished loading from source: %s', source)
status, tb, exc = 'error', '', None
try:
self.perform_update(options, data, inventory_update)
status = 'successful'
except Exception as e:
exc = e
if isinstance(e, KeyboardInterrupt):
status = 'canceled'
else:
tb = traceback.format_exc()
with ignore_inventory_computed_fields():
inventory_update = InventoryUpdate.objects.get(pk=inventory_update.pk)
inventory_update.result_traceback = tb
inventory_update.status = status
inventory_update.save(update_fields=['status', 'result_traceback'])
inventory_source.status = status
inventory_source.save(update_fields=['status'])
if exc:
logger.error(str(exc))
if exc:
if isinstance(exc, CommandError):
sys.exit(1)
raise exc
def perform_update(self, options, data, inventory_update):
"""Shared method for both awx-manage CLI updates and inventory updates
from the tasks system.
This saves the inventory data to the database, calling load_into_database
but also wraps that method in a host of options processing
"""
# outside of normal options, these are needed as part of programatic interface
self.inventory = inventory_update.inventory
self.inventory_source = inventory_update.inventory_source
self.inventory_update = inventory_update
# the update options, could be parser object or dict
self.overwrite = bool(options.get('overwrite', False))
self.overwrite_vars = bool(options.get('overwrite_vars', False))
self.keep_vars = bool(options.get('keep_vars', False))
self.is_custom = bool(options.get('custom', False))
self.source = options.get('source', None)
self.enabled_var = options.get('enabled_var', None)
self.enabled_value = options.get('enabled_value', None)
self.group_filter = options.get('group_filter', None) or r'^.+$'
@@ -984,17 +1011,6 @@ class Command(BaseCommand):
self.exclude_empty_groups = bool(options.get('exclude_empty_groups', False))
self.instance_id_var = options.get('instance_id_var', None)
self.invoked_from_dispatcher = False if os.getenv('INVENTORY_SOURCE_ID', None) is None else True
# Load inventory and related objects from database.
if self.inventory_name and self.inventory_id:
raise CommandError('--inventory-name and --inventory-id are mutually exclusive')
elif not self.inventory_name and not self.inventory_id:
raise CommandError('--inventory-name or --inventory-id is required')
if (self.overwrite or self.overwrite_vars) and self.keep_vars:
raise CommandError('--overwrite/--overwrite-vars and --keep-vars are mutually exclusive')
if not self.source:
raise CommandError('--source is required')
try:
self.group_filter_re = re.compile(self.group_filter)
except re.error:
@@ -1005,47 +1021,43 @@ class Command(BaseCommand):
raise CommandError('invalid regular expression for --host-filter')
begin = time.time()
self.load_inventory_from_database()
try:
self.check_license()
except CommandError as e:
self.mark_license_failure(save=True)
raise e
# Since perform_update can be invoked either through the awx-manage CLI
# or from the task system, we need to create a new lock at this level
# (even though inventory_import.Command.handle -- which calls
# perform_update -- has its own lock, inventory_ID_import)
with advisory_lock('inventory_{}_perform_update'.format(self.inventory.id)):
try:
# Check the per-org host limits
self.check_org_host_limit()
except CommandError as e:
self.mark_org_limits_failure(save=True)
raise e
try:
self.check_license()
except PermissionDenied as e:
self.mark_license_failure(save=True)
raise e
try:
# Check the per-org host limits
self.check_org_host_limit()
except PermissionDenied as e:
self.mark_org_limits_failure(save=True)
raise e
status, tb, exc = 'error', '', None
try:
if settings.SQL_DEBUG:
queries_before = len(connection.queries)
# Update inventory update for this command line invocation.
with ignore_inventory_computed_fields():
# TODO: move this to before perform_update
iu = self.inventory_update
if iu.status != 'running':
with transaction.atomic():
self.inventory_update.status = 'running'
self.inventory_update.save()
source = self.get_source_absolute_path(self.source)
data = AnsibleInventoryLoader(source=source, is_custom=self.is_custom,
venv_path=venv_path, verbosity=self.verbosity).load()
logger.debug('Finished loading from source: %s', source)
logger.info('Processing JSON output...')
inventory = MemInventory(
group_filter_re=self.group_filter_re, host_filter_re=self.host_filter_re)
inventory = dict_to_mem_data(data, inventory=inventory)
del data # forget dict from import, could be large
logger.info('Loaded %d groups, %d hosts', len(inventory.all_group.all_groups),
len(inventory.all_group.all_hosts))
@@ -1085,9 +1097,10 @@ class Command(BaseCommand):
if settings.SQL_DEBUG:
queries_before2 = len(connection.queries)
self.inventory.update_computed_fields()
if settings.SQL_DEBUG:
logger.warning('update computed fields took %d queries',
len(connection.queries) - queries_before2)
if settings.SQL_DEBUG:
logger.warning('update computed fields took %d queries',
len(connection.queries) - queries_before2)
# Check if the license is valid.
# If the license is not valid, a CommandError will be thrown,
# and inventory update will be marked as invalid.
@@ -1098,11 +1111,11 @@ class Command(BaseCommand):
# Check the per-org host limits
license_fail = False
self.check_org_host_limit()
except CommandError as e:
except PermissionDenied as e:
if license_fail:
self.mark_license_failure()
self.mark_license_failure(save=True)
else:
self.mark_org_limits_failure()
self.mark_org_limits_failure(save=True)
raise e
if settings.SQL_DEBUG:
@@ -1111,7 +1124,6 @@ class Command(BaseCommand):
else:
logger.info('Inventory import completed for %s in %0.1fs',
self.inventory_source.name, time.time() - begin)
status = 'successful'
# If we're in debug mode, then log the queries and time
# used to do the operation.
@@ -1121,29 +1133,3 @@ class Command(BaseCommand):
logger.warning('Inventory import required %d queries '
'taking %0.3fs', len(queries_this_import),
sqltime)
except Exception as e:
if isinstance(e, KeyboardInterrupt):
status = 'canceled'
exc = e
elif isinstance(e, CommandError):
exc = e
else:
tb = traceback.format_exc()
exc = e
if not self.invoked_from_dispatcher:
with ignore_inventory_computed_fields():
self.inventory_update = InventoryUpdate.objects.get(pk=self.inventory_update.pk)
self.inventory_update.result_traceback = tb
self.inventory_update.status = status
self.inventory_update.save(update_fields=['status', 'result_traceback'])
self.inventory_source.status = status
self.inventory_source.save(update_fields=['status'])
if exc:
logger.error(str(exc))
if exc:
if isinstance(exc, CommandError):
sys.exit(1)
raise exc

View File

@@ -19,3 +19,9 @@ class Command(BaseCommand):
profile_sql.delay(
threshold=options['threshold'], minutes=options['minutes']
)
if options['threshold'] > 0:
print(f"SQL profiling initiated with a threshold of {options['threshold']} second(s) and a"
f" duration of {options['minutes']} minute(s), any queries that meet criteria can"
f" be found in /var/log/tower/profile/.")
else:
print("SQL profiling disabled.")

View File

@@ -13,7 +13,7 @@ from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
"""
Internal tower command.
Regsiter this instance with the database for HA tracking.
Register this instance with the database for HA tracking.
"""
help = (

View File

@@ -32,4 +32,7 @@ class Command(BaseCommand):
sys.exit(1)
i = i.first()
ig.instances.remove(i)
if i.hostname in ig.policy_instance_list:
ig.policy_instance_list.remove(i.hostname)
ig.save()
print("Instance removed from instance group")

View File

@@ -4,6 +4,7 @@
from django.conf import settings
from django.core.management.base import BaseCommand
from awx.main.dispatch.control import Control
from awx.main.dispatch.worker import AWXConsumerRedis, CallbackBrokerWorker
@@ -15,7 +16,14 @@ class Command(BaseCommand):
'''
help = 'Launch the job callback receiver'
def add_arguments(self, parser):
parser.add_argument('--status', dest='status', action='store_true',
help='print the internal state of any running dispatchers')
def handle(self, *arg, **options):
if options.get('status'):
print(Control('callback_receiver').status())
return
consumer = None
try:
consumer = AWXConsumerRedis(

View File

@@ -48,7 +48,13 @@ class HostManager(models.Manager):
"""When the parent instance of the host query set has a `kind=smart` and a `host_filter`
set. Use the `host_filter` to generate the queryset for the hosts.
"""
qs = super(HostManager, self).get_queryset()
qs = super(HostManager, self).get_queryset().defer(
'last_job__extra_vars',
'last_job_host_summary__job__extra_vars',
'last_job__artifacts',
'last_job_host_summary__job__artifacts',
)
if (hasattr(self, 'instance') and
hasattr(self.instance, 'host_filter') and
hasattr(self.instance, 'kind')):

View File

@@ -1,20 +1,16 @@
# Copyright (c) 2015 Ansible, Inc.
# All Rights Reserved.
import uuid
import logging
import threading
import time
import cProfile
import pstats
import os
import urllib.parse
from django.conf import settings
from django.contrib.auth.models import User
from django.db.migrations.executor import MigrationExecutor
from django.db import connection
from django.shortcuts import get_object_or_404, redirect
from django.shortcuts import redirect
from django.apps import apps
from django.utils.deprecation import MiddlewareMixin
from django.utils.translation import ugettext_lazy as _
@@ -22,6 +18,7 @@ from django.urls import reverse, resolve
from awx.main.utils.named_url_graph import generate_graph, GraphNode
from awx.conf import fields, register
from awx.main.utils.profiling import AWXProfiler
logger = logging.getLogger('awx.main.middleware')
@@ -32,11 +29,14 @@ class TimingMiddleware(threading.local, MiddlewareMixin):
dest = '/var/log/tower/profile'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.prof = AWXProfiler("TimingMiddleware")
def process_request(self, request):
self.start_time = time.time()
if settings.AWX_REQUEST_PROFILE:
self.prof = cProfile.Profile()
self.prof.enable()
self.prof.start()
def process_response(self, request, response):
if not hasattr(self, 'start_time'): # some tools may not invoke process_request
@@ -44,33 +44,10 @@ class TimingMiddleware(threading.local, MiddlewareMixin):
total_time = time.time() - self.start_time
response['X-API-Total-Time'] = '%0.3fs' % total_time
if settings.AWX_REQUEST_PROFILE:
self.prof.disable()
cprofile_file = self.save_profile_file(request)
response['cprofile_file'] = cprofile_file
response['X-API-Profile-File'] = self.prof.stop()
perf_logger.info('api response times', extra=dict(python_objects=dict(request=request, response=response)))
return response
def save_profile_file(self, request):
if not os.path.isdir(self.dest):
os.makedirs(self.dest)
filename = '%.3fs-%s.pstats' % (pstats.Stats(self.prof).total_tt, uuid.uuid4())
filepath = os.path.join(self.dest, filename)
with open(filepath, 'w') as f:
f.write('%s %s\n' % (request.method, request.get_full_path()))
pstats.Stats(self.prof, stream=f).sort_stats('cumulative').print_stats()
if settings.AWX_REQUEST_PROFILE_WITH_DOT:
from gprof2dot import main as generate_dot
raw = os.path.join(self.dest, filename) + '.raw'
pstats.Stats(self.prof).dump_stats(raw)
generate_dot([
'-n', '2.5', '-f', 'pstats', '-o',
os.path.join( self.dest, filename).replace('.pstats', '.dot'),
raw
])
os.remove(raw)
return filepath
class SessionTimeoutMiddleware(MiddlewareMixin):
"""
@@ -148,7 +125,21 @@ class URLModificationMiddleware(MiddlewareMixin):
def _named_url_to_pk(cls, node, resource, named_url):
kwargs = {}
if node.populate_named_url_query_kwargs(kwargs, named_url):
return str(get_object_or_404(node.model, **kwargs).pk)
match = node.model.objects.filter(**kwargs).first()
if match:
return str(match.pk)
else:
# if the name does *not* resolve to any actual resource,
# we should still attempt to route it through so that 401s are
# respected
# using "zero" here will cause the URL regex to match e.g.,
# /api/v2/users/<integer>/, but it also means that anonymous
# users will go down the path of having their credentials
# verified; in this way, *anonymous* users will that visit
# /api/v2/users/invalid-username/ *won't* see a 404, they'll
# see a 401 as if they'd gone to /api/v2/users/0/
#
return '0'
if resource == 'job_templates' and '++' not in named_url:
# special case for deprecated job template case
# will not raise a 404 on its own
@@ -178,6 +169,7 @@ class URLModificationMiddleware(MiddlewareMixin):
old_path = request.path_info
new_path = self._convert_named_url(old_path)
if request.path_info != new_path:
request.environ['awx.named_url_rewritten'] = request.path
request.path = request.path.replace(request.path_info, new_path)
request.path_info = new_path
@@ -189,4 +181,4 @@ class MigrationRanCheckMiddleware(MiddlewareMixin):
plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
if bool(plan) and \
getattr(resolve(request.path), 'url_name', '') != 'migrations_notran':
return redirect(reverse("ui:migrations_notran"))
return redirect(reverse("ui_next:migrations_notran"))

View File

@@ -1,11 +1,7 @@
# Generated by Django 2.2.11 on 2020-05-01 13:25
from django.db import migrations, models
from awx.main.migrations._inventory_source import create_scm_script_substitute
def convert_cloudforms_to_scm(apps, schema_editor):
create_scm_script_substitute(apps, 'cloudforms')
from awx.main.migrations._inventory_source import delete_cloudforms_inv_source
class Migration(migrations.Migration):
@@ -15,7 +11,7 @@ class Migration(migrations.Migration):
]
operations = [
migrations.RunPython(convert_cloudforms_to_scm),
migrations.RunPython(delete_cloudforms_inv_source),
migrations.AlterField(
model_name='inventorysource',
name='source',

View File

@@ -0,0 +1,23 @@
# Generated by Django 2.2.11 on 2020-08-18 22:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0117_v400_remove_cloudforms_inventory'),
]
operations = [
migrations.AlterField(
model_name='project',
name='scm_type',
field=models.CharField(blank=True, choices=[('', 'Manual'), ('git', 'Git'), ('hg', 'Mercurial'), ('svn', 'Subversion'), ('insights', 'Red Hat Insights'), ('archive', 'Remote Archive')], default='', help_text='Specifies the source control system used to store the project.', max_length=8, verbose_name='SCM Type'),
),
migrations.AlterField(
model_name='projectupdate',
name='scm_type',
field=models.CharField(blank=True, choices=[('', 'Manual'), ('git', 'Git'), ('hg', 'Mercurial'), ('svn', 'Subversion'), ('insights', 'Red Hat Insights'), ('archive', 'Remote Archive')], default='', help_text='Specifies the source control system used to store the project.', max_length=8, verbose_name='SCM Type'),
),
]

View File

@@ -0,0 +1,104 @@
# Generated by Django 2.2.11 on 2020-07-20 19:56
import logging
import yaml
from django.db import migrations, models
from awx.main.models.base import VarsDictProperty
from ._inventory_source_vars import FrozenInjectors
logger = logging.getLogger('awx.main.migrations')
def _get_inventory_sources(InventorySource):
return InventorySource.objects.filter(source__in=['ec2', 'gce', 'azure_rm', 'vmware', 'satellite6', 'openstack', 'rhv', 'tower'])
def inventory_source_vars_forward(apps, schema_editor):
InventorySource = apps.get_model("main", "InventorySource")
'''
The Django app registry does not keep track of model inheritance. The
source_vars_dict property comes from InventorySourceOptions via inheritance.
This adds that property. Luckily, other properteries and functionality from
InventorySourceOptions is not needed by the injector logic.
'''
setattr(InventorySource, 'source_vars_dict', VarsDictProperty('source_vars'))
source_vars_backup = dict()
for inv_source_obj in _get_inventory_sources(InventorySource):
if inv_source_obj.source in FrozenInjectors:
source_vars_backup[inv_source_obj.id] = dict(inv_source_obj.source_vars_dict)
injector = FrozenInjectors[inv_source_obj.source]()
new_inv_source_vars = injector.inventory_as_dict(inv_source_obj, None)
inv_source_obj.source_vars = yaml.dump(new_inv_source_vars)
inv_source_obj.save()
class Migration(migrations.Migration):
dependencies = [
('main', '0118_add_remote_archive_scm_type'),
]
operations = [
migrations.RunPython(inventory_source_vars_forward),
migrations.RemoveField(
model_name='inventorysource',
name='group_by',
),
migrations.RemoveField(
model_name='inventoryupdate',
name='group_by',
),
migrations.RemoveField(
model_name='inventorysource',
name='instance_filters',
),
migrations.RemoveField(
model_name='inventoryupdate',
name='instance_filters',
),
migrations.RemoveField(
model_name='inventorysource',
name='source_regions',
),
migrations.RemoveField(
model_name='inventoryupdate',
name='source_regions',
),
migrations.AddField(
model_name='inventorysource',
name='enabled_value',
field=models.TextField(blank=True, default='', help_text='Only used when enabled_var is set. Value when the host is considered enabled. For example if enabled_var="status.power_state"and enabled_value="powered_on" with host variables:{ "status": { "power_state": "powered_on", "created": "2020-08-04T18:13:04+00:00", "healthy": true }, "name": "foobar", "ip_address": "192.168.2.1"}The host would be marked enabled. If power_state where any value other than powered_on then the host would be disabled when imported into Tower. If the key is not found then the host will be enabled'),
),
migrations.AddField(
model_name='inventorysource',
name='enabled_var',
field=models.TextField(blank=True, default='', help_text='Retrieve the enabled state from the given dict of host variables. The enabled variable may be specified as "foo.bar", in which case the lookup will traverse into nested dicts, equivalent to: from_dict.get("foo", {}).get("bar", default)'),
),
migrations.AddField(
model_name='inventorysource',
name='host_filter',
field=models.TextField(blank=True, default='', help_text='Regex where only matching hosts will be imported into Tower.'),
),
migrations.AddField(
model_name='inventoryupdate',
name='enabled_value',
field=models.TextField(blank=True, default='', help_text='Only used when enabled_var is set. Value when the host is considered enabled. For example if enabled_var="status.power_state"and enabled_value="powered_on" with host variables:{ "status": { "power_state": "powered_on", "created": "2020-08-04T18:13:04+00:00", "healthy": true }, "name": "foobar", "ip_address": "192.168.2.1"}The host would be marked enabled. If power_state where any value other than powered_on then the host would be disabled when imported into Tower. If the key is not found then the host will be enabled'),
),
migrations.AddField(
model_name='inventoryupdate',
name='enabled_var',
field=models.TextField(blank=True, default='', help_text='Retrieve the enabled state from the given dict of host variables. The enabled variable may be specified as "foo.bar", in which case the lookup will traverse into nested dicts, equivalent to: from_dict.get("foo", {}).get("bar", default)'),
),
migrations.AddField(
model_name='inventoryupdate',
name='host_filter',
field=models.TextField(blank=True, default='', help_text='Regex where only matching hosts will be imported into Tower.'),
),
]

View File

@@ -0,0 +1,51 @@
# Generated by Django 2.2.11 on 2020-08-04 15:19
import logging
import awx.main.fields
from awx.main.utils.encryption import encrypt_field, decrypt_field
from django.db import migrations, models
from django.utils.timezone import now
import django.db.models.deletion
from awx.main.migrations import _galaxy as galaxy
from awx.main.models import CredentialType as ModernCredentialType
from awx.main.utils.common import set_current_apps
logger = logging.getLogger('awx.main.migrations')
class Migration(migrations.Migration):
dependencies = [
('main', '0119_inventory_plugins'),
]
operations = [
migrations.AlterField(
model_name='credentialtype',
name='kind',
field=models.CharField(choices=[('ssh', 'Machine'), ('vault', 'Vault'), ('net', 'Network'), ('scm', 'Source Control'), ('cloud', 'Cloud'), ('token', 'Personal Access Token'), ('insights', 'Insights'), ('external', 'External'), ('kubernetes', 'Kubernetes'), ('galaxy', 'Galaxy/Automation Hub')], max_length=32),
),
migrations.CreateModel(
name='OrganizationGalaxyCredentialMembership',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('position', models.PositiveIntegerField(db_index=True, default=None, null=True)),
('credential', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Credential')),
('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Organization')),
],
),
migrations.AddField(
model_name='organization',
name='galaxy_credentials',
field=awx.main.fields.OrderedManyToManyField(blank=True, related_name='organization_galaxy_credentials', through='main.OrganizationGalaxyCredentialMembership', to='main.Credential'),
),
migrations.AddField(
model_name='credential',
name='managed_by_tower',
field=models.BooleanField(default=False, editable=False),
),
migrations.RunPython(galaxy.migrate_galaxy_settings)
]

View File

@@ -0,0 +1,16 @@
# Generated by Django 2.2.11 on 2020-07-24 17:41
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0120_galaxy_credentials'),
]
operations = [
migrations.DeleteModel(
name='TowerAnalyticsState',
),
]

View File

@@ -0,0 +1,13 @@
from django.db import migrations
from awx.main.migrations._inventory_source import delete_cloudforms_inv_source
class Migration(migrations.Migration):
dependencies = [
('main', '0121_delete_toweranalyticsstate'),
]
operations = [
migrations.RunPython(delete_cloudforms_inv_source),
]

View File

@@ -0,0 +1,23 @@
from django.db import migrations, models
from awx.main.migrations._hg_removal import delete_hg_scm
class Migration(migrations.Migration):
dependencies = [
('main', '0122_really_remove_cloudforms_inventory'),
]
operations = [
migrations.RunPython(delete_hg_scm),
migrations.AlterField(
model_name='project',
name='scm_type',
field=models.CharField(blank=True, choices=[('', 'Manual'), ('git', 'Git'), ('svn', 'Subversion'), ('insights', 'Red Hat Insights'), ('archive', 'Remote Archive')], default='', help_text='Specifies the source control system used to store the project.', max_length=8, verbose_name='SCM Type'),
),
migrations.AlterField(
model_name='projectupdate',
name='scm_type',
field=models.CharField(blank=True, choices=[('', 'Manual'), ('git', 'Git'), ('svn', 'Subversion'), ('insights', 'Red Hat Insights'), ('archive', 'Remote Archive')], default='', help_text='Specifies the source control system used to store the project.', max_length=8, verbose_name='SCM Type'),
),
]

View File

@@ -0,0 +1,125 @@
# Generated by Django 2.2.11 on 2020-08-04 15:19
import logging
from awx.main.utils.encryption import encrypt_field, decrypt_field
from django.conf import settings
from django.utils.timezone import now
from awx.main.models import CredentialType as ModernCredentialType
from awx.main.utils.common import set_current_apps
logger = logging.getLogger('awx.main.migrations')
def migrate_galaxy_settings(apps, schema_editor):
Organization = apps.get_model('main', 'Organization')
if Organization.objects.count() == 0:
# nothing to migrate
return
set_current_apps(apps)
ModernCredentialType.setup_tower_managed_defaults()
CredentialType = apps.get_model('main', 'CredentialType')
Credential = apps.get_model('main', 'Credential')
Setting = apps.get_model('conf', 'Setting')
galaxy_type = CredentialType.objects.get(kind='galaxy')
private_galaxy_url = Setting.objects.filter(key='PRIMARY_GALAXY_URL').first()
# by default, prior versions of AWX/Tower automatically pulled content
# from galaxy.ansible.com
public_galaxy_enabled = True
public_galaxy_setting = Setting.objects.filter(key='PUBLIC_GALAXY_ENABLED').first()
if public_galaxy_setting and public_galaxy_setting.value is False:
# ...UNLESS this behavior was explicitly disabled via this setting
public_galaxy_enabled = False
public_galaxy_credential = Credential(
created=now(),
modified=now(),
name='Ansible Galaxy',
managed_by_tower=True,
credential_type=galaxy_type,
inputs = {
'url': 'https://galaxy.ansible.com/'
}
)
public_galaxy_credential.save()
for org in Organization.objects.all():
if private_galaxy_url and private_galaxy_url.value:
# If a setting exists for a private Galaxy URL, make a credential for it
username = Setting.objects.filter(key='PRIMARY_GALAXY_USERNAME').first()
password = Setting.objects.filter(key='PRIMARY_GALAXY_PASSWORD').first()
if (username and username.value) or (password and password.value):
logger.error(
f'Specifying HTTP basic auth for the Ansible Galaxy API '
f'({private_galaxy_url.value}) is no longer supported. '
'Please provide an API token instead after your upgrade '
'has completed',
)
inputs = {
'url': private_galaxy_url.value
}
token = Setting.objects.filter(key='PRIMARY_GALAXY_TOKEN').first()
if token and token.value:
inputs['token'] = decrypt_field(token, 'value')
auth_url = Setting.objects.filter(key='PRIMARY_GALAXY_AUTH_URL').first()
if auth_url and auth_url.value:
inputs['auth_url'] = auth_url.value
name = f'Private Galaxy ({private_galaxy_url.value})'
if 'cloud.redhat.com' in inputs['url']:
name = f'Ansible Automation Hub ({private_galaxy_url.value})'
cred = Credential(
created=now(),
modified=now(),
name=name,
organization=org,
credential_type=galaxy_type,
inputs=inputs
)
cred.save()
if token and token.value:
# encrypt based on the primary key from the prior save
cred.inputs['token'] = encrypt_field(cred, 'token')
cred.save()
org.galaxy_credentials.add(cred)
fallback_servers = getattr(settings, 'FALLBACK_GALAXY_SERVERS', [])
for fallback in fallback_servers:
url = fallback.get('url', None)
auth_url = fallback.get('auth_url', None)
username = fallback.get('username', None)
password = fallback.get('password', None)
token = fallback.get('token', None)
if username or password:
logger.error(
f'Specifying HTTP basic auth for the Ansible Galaxy API '
f'({url}) is no longer supported. '
'Please provide an API token instead after your upgrade '
'has completed',
)
inputs = {'url': url}
if token:
inputs['token'] = token
if auth_url:
inputs['auth_url'] = auth_url
cred = Credential(
created=now(),
modified=now(),
name=f'Ansible Galaxy ({url})',
organization=org,
credential_type=galaxy_type,
inputs=inputs
)
cred.save()
if token:
# encrypt based on the primary key from the prior save
cred.inputs['token'] = encrypt_field(cred, 'token')
cred.save()
org.galaxy_credentials.add(cred)
if public_galaxy_enabled:
# If public Galaxy was enabled, associate it to the org
org.galaxy_credentials.add(public_galaxy_credential)

View File

@@ -0,0 +1,19 @@
import logging
from awx.main.utils.common import set_current_apps
logger = logging.getLogger('awx.main.migrations')
def delete_hg_scm(apps, schema_editor):
set_current_apps(apps)
Project = apps.get_model('main', 'Project')
ProjectUpdate = apps.get_model('main', 'ProjectUpdate')
ProjectUpdate.objects.filter(project__scm_type='hg').update(scm_type='')
update_ct = Project.objects.filter(scm_type='hg').update(scm_type='')
if update_ct:
logger.warn('Changed {} mercurial projects to manual, deprecation period ended'.format(
update_ct
))

View File

@@ -5,6 +5,7 @@ from uuid import uuid4
from django.utils.encoding import smart_text
from django.utils.timezone import now
from awx.main.utils.common import set_current_apps
from awx.main.utils.common import parse_yaml_or_json
logger = logging.getLogger('awx.main.migrations')
@@ -91,43 +92,14 @@ def back_out_new_instance_id(apps, source, new_id):
))
def create_scm_script_substitute(apps, source):
"""Only applies for cloudforms in practice, but written generally.
Given a source type, this will replace all inventory sources of that type
with SCM inventory sources that source the script from Ansible core
"""
# the revision in the Ansible 2.9 stable branch this project will start out as
# it can still be updated manually later (but staying within 2.9 branch), if desired
ansible_rev = '6f83b9aff42331e15c55a171de0a8b001208c18c'
def delete_cloudforms_inv_source(apps, schema_editor):
set_current_apps(apps)
InventorySource = apps.get_model('main', 'InventorySource')
ContentType = apps.get_model('contenttypes', 'ContentType')
Project = apps.get_model('main', 'Project')
if not InventorySource.objects.filter(source=source).exists():
logger.debug('No sources of type {} to migrate'.format(source))
return
proj_name = 'Replacement project for {} type sources - {}'.format(source, uuid4())
right_now = now()
project = Project.objects.create(
name=proj_name,
created=right_now,
modified=right_now,
description='Created by migration',
polymorphic_ctype=ContentType.objects.get(model='project'),
# project-specific fields
scm_type='git',
scm_url='https://github.com/ansible/ansible.git',
scm_branch='stable-2.9',
scm_revision=ansible_rev
)
ct = 0
for inv_src in InventorySource.objects.filter(source=source).iterator():
inv_src.source = 'scm'
inv_src.source_project = project
inv_src.source_path = 'contrib/inventory/{}.py'.format(source)
inv_src.scm_last_revision = ansible_rev
inv_src.save(update_fields=['source', 'source_project', 'source_path', 'scm_last_revision'])
logger.debug('Changed inventory source {} to scm type'.format(inv_src.pk))
ct += 1
InventoryUpdate = apps.get_model('main', 'InventoryUpdate')
CredentialType = apps.get_model('main', 'CredentialType')
InventoryUpdate.objects.filter(inventory_source__source='cloudforms').delete()
InventorySource.objects.filter(source='cloudforms').delete()
ct = CredentialType.objects.filter(namespace='cloudforms').first()
if ct:
logger.info('Changed total of {} inventory sources from {} type to scm'.format(ct, source))
ct.credentials.all().delete()
ct.delete()

View File

@@ -0,0 +1,757 @@
import json
import re
import logging
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import iri_to_uri
FrozenInjectors = dict()
logger = logging.getLogger('awx.main.migrations')
class PluginFileInjector(object):
plugin_name = None # Ansible core name used to reference plugin
# every source should have collection, these are for the collection name
namespace = None
collection = None
def inventory_as_dict(self, inventory_source, private_data_dir):
"""Default implementation of inventory plugin file contents.
There are some valid cases when all parameters can be obtained from
the environment variables, example "plugin: linode" is valid
ideally, however, some options should be filled from the inventory source data
"""
if self.plugin_name is None:
raise NotImplementedError('At minimum the plugin name is needed for inventory plugin use.')
proper_name = f'{self.namespace}.{self.collection}.{self.plugin_name}'
return {'plugin': proper_name}
class azure_rm(PluginFileInjector):
plugin_name = 'azure_rm'
namespace = 'azure'
collection = 'azcollection'
def inventory_as_dict(self, inventory_source, private_data_dir):
ret = super(azure_rm, self).inventory_as_dict(inventory_source, private_data_dir)
source_vars = inventory_source.source_vars_dict
ret['fail_on_template_errors'] = False
group_by_hostvar = {
'location': {'prefix': '', 'separator': '', 'key': 'location'},
'tag': {'prefix': '', 'separator': '', 'key': 'tags.keys() | list if tags else []'},
# Introduced with https://github.com/ansible/ansible/pull/53046
'security_group': {'prefix': '', 'separator': '', 'key': 'security_group'},
'resource_group': {'prefix': '', 'separator': '', 'key': 'resource_group'},
# Note, os_family was not documented correctly in script, but defaulted to grouping by it
'os_family': {'prefix': '', 'separator': '', 'key': 'os_disk.operating_system_type'}
}
# by default group by everything
# always respect user setting, if they gave it
group_by = [
grouping_name for grouping_name in group_by_hostvar
if source_vars.get('group_by_{}'.format(grouping_name), True)
]
ret['keyed_groups'] = [group_by_hostvar[grouping_name] for grouping_name in group_by]
if 'tag' in group_by:
# Nasty syntax to reproduce "key_value" group names in addition to "key"
ret['keyed_groups'].append({
'prefix': '', 'separator': '',
'key': r'dict(tags.keys() | map("regex_replace", "^(.*)$", "\1_") | list | zip(tags.values() | list)) if tags else []'
})
# Compatibility content
# TODO: add proper support for instance_filters non-specific to compatibility
# TODO: add proper support for group_by non-specific to compatibility
# Dashes were not configurable in azure_rm.py script, we do not want unicode, so always use this
ret['use_contrib_script_compatible_sanitization'] = True
# use same host names as script
ret['plain_host_names'] = True
# By default the script did not filter hosts
ret['default_host_filters'] = []
# User-given host filters
user_filters = []
old_filterables = [
('resource_groups', 'resource_group'),
('tags', 'tags')
# locations / location would be an entry
# but this would conflict with source_regions
]
for key, loc in old_filterables:
value = source_vars.get(key, None)
if value and isinstance(value, str):
# tags can be list of key:value pairs
# e.g. 'Creator:jmarshall, peanutbutter:jelly'
# or tags can be a list of keys
# e.g. 'Creator, peanutbutter'
if key == "tags":
# grab each key value pair
for kvpair in value.split(','):
# split into key and value
kv = kvpair.split(':')
# filter out any host that does not have key
# in their tags.keys() variable
user_filters.append('"{}" not in tags.keys()'.format(kv[0].strip()))
# if a value is provided, check that the key:value pair matches
if len(kv) > 1:
user_filters.append('tags["{}"] != "{}"'.format(kv[0].strip(), kv[1].strip()))
else:
user_filters.append('{} not in {}'.format(
loc, value.split(',')
))
if user_filters:
ret.setdefault('exclude_host_filters', [])
ret['exclude_host_filters'].extend(user_filters)
ret['conditional_groups'] = {'azure': True}
ret['hostvar_expressions'] = {
'provisioning_state': 'provisioning_state | title',
'computer_name': 'name',
'type': 'resource_type',
'private_ip': 'private_ipv4_addresses[0] if private_ipv4_addresses else None',
'public_ip': 'public_ipv4_addresses[0] if public_ipv4_addresses else None',
'public_ip_name': 'public_ip_name if public_ip_name is defined else None',
'public_ip_id': 'public_ip_id if public_ip_id is defined else None',
'tags': 'tags if tags else None'
}
# Special functionality from script
if source_vars.get('use_private_ip', False):
ret['hostvar_expressions']['ansible_host'] = 'private_ipv4_addresses[0]'
# end compatibility content
if inventory_source.source_regions and 'all' not in inventory_source.source_regions:
# initialize a list for this section in inventory file
ret.setdefault('exclude_host_filters', [])
# make a python list of the regions we will use
python_regions = [x.strip() for x in inventory_source.source_regions.split(',')]
# convert that list in memory to python syntax in a string
# now put that in jinja2 syntax operating on hostvar key "location"
# and put that as an entry in the exclusions list
ret['exclude_host_filters'].append("location not in {}".format(repr(python_regions)))
return ret
class ec2(PluginFileInjector):
plugin_name = 'aws_ec2'
namespace = 'amazon'
collection = 'aws'
def _get_ec2_group_by_choices(self):
return [
('ami_id', _('Image ID')),
('availability_zone', _('Availability Zone')),
('aws_account', _('Account')),
('instance_id', _('Instance ID')),
('instance_state', _('Instance State')),
('platform', _('Platform')),
('instance_type', _('Instance Type')),
('key_pair', _('Key Name')),
('region', _('Region')),
('security_group', _('Security Group')),
('tag_keys', _('Tags')),
('tag_none', _('Tag None')),
('vpc_id', _('VPC ID')),
]
def _compat_compose_vars(self):
return {
# vars that change
'ec2_block_devices': (
"dict(block_device_mappings | map(attribute='device_name') | list | zip(block_device_mappings "
"| map(attribute='ebs.volume_id') | list))"
),
'ec2_dns_name': 'public_dns_name',
'ec2_group_name': 'placement.group_name',
'ec2_instance_profile': 'iam_instance_profile | default("")',
'ec2_ip_address': 'public_ip_address',
'ec2_kernel': 'kernel_id | default("")',
'ec2_monitored': "monitoring.state in ['enabled', 'pending']",
'ec2_monitoring_state': 'monitoring.state',
'ec2_placement': 'placement.availability_zone',
'ec2_ramdisk': 'ramdisk_id | default("")',
'ec2_reason': 'state_transition_reason',
'ec2_security_group_ids': "security_groups | map(attribute='group_id') | list | join(',')",
'ec2_security_group_names': "security_groups | map(attribute='group_name') | list | join(',')",
'ec2_tag_Name': 'tags.Name',
'ec2_state': 'state.name',
'ec2_state_code': 'state.code',
'ec2_state_reason': 'state_reason.message if state_reason is defined else ""',
'ec2_sourceDestCheck': 'source_dest_check | default(false) | lower | string', # snake_case syntax intended
'ec2_account_id': 'owner_id',
# vars that just need ec2_ prefix
'ec2_ami_launch_index': 'ami_launch_index | string',
'ec2_architecture': 'architecture',
'ec2_client_token': 'client_token',
'ec2_ebs_optimized': 'ebs_optimized',
'ec2_hypervisor': 'hypervisor',
'ec2_image_id': 'image_id',
'ec2_instance_type': 'instance_type',
'ec2_key_name': 'key_name',
'ec2_launch_time': r'launch_time | regex_replace(" ", "T") | regex_replace("(\+)(\d\d):(\d)(\d)$", ".\g<2>\g<3>Z")',
'ec2_platform': 'platform | default("")',
'ec2_private_dns_name': 'private_dns_name',
'ec2_private_ip_address': 'private_ip_address',
'ec2_public_dns_name': 'public_dns_name',
'ec2_region': 'placement.region',
'ec2_root_device_name': 'root_device_name',
'ec2_root_device_type': 'root_device_type',
# many items need blank defaults because the script tended to keep a common schema
'ec2_spot_instance_request_id': 'spot_instance_request_id | default("")',
'ec2_subnet_id': 'subnet_id | default("")',
'ec2_virtualization_type': 'virtualization_type',
'ec2_vpc_id': 'vpc_id | default("")',
# same as ec2_ip_address, the script provided this
'ansible_host': 'public_ip_address',
# new with https://github.com/ansible/ansible/pull/53645
'ec2_eventsSet': 'events | default("")',
'ec2_persistent': 'persistent | default(false)',
'ec2_requester_id': 'requester_id | default("")'
}
def inventory_as_dict(self, inventory_source, private_data_dir):
ret = super(ec2, self).inventory_as_dict(inventory_source, private_data_dir)
keyed_groups = []
group_by_hostvar = {
'ami_id': {'prefix': '', 'separator': '', 'key': 'image_id', 'parent_group': 'images'},
# 2 entries for zones for same groups to establish 2 parentage trees
'availability_zone': {'prefix': '', 'separator': '', 'key': 'placement.availability_zone', 'parent_group': 'zones'},
'aws_account': {'prefix': '', 'separator': '', 'key': 'ec2_account_id', 'parent_group': 'accounts'}, # composed var
'instance_id': {'prefix': '', 'separator': '', 'key': 'instance_id', 'parent_group': 'instances'}, # normally turned off
'instance_state': {'prefix': 'instance_state', 'key': 'ec2_state', 'parent_group': 'instance_states'}, # composed var
# ec2_platform is a composed var, but group names do not match up to hostvar exactly
'platform': {'prefix': 'platform', 'key': 'platform | default("undefined")', 'parent_group': 'platforms'},
'instance_type': {'prefix': 'type', 'key': 'instance_type', 'parent_group': 'types'},
'key_pair': {'prefix': 'key', 'key': 'key_name', 'parent_group': 'keys'},
'region': {'prefix': '', 'separator': '', 'key': 'placement.region', 'parent_group': 'regions'},
# Security requires some ninja jinja2 syntax, credit to s-hertel
'security_group': {'prefix': 'security_group', 'key': 'security_groups | map(attribute="group_name")', 'parent_group': 'security_groups'},
# tags cannot be parented in exactly the same way as the script due to
# https://github.com/ansible/ansible/pull/53812
'tag_keys': [
{'prefix': 'tag', 'key': 'tags', 'parent_group': 'tags'},
{'prefix': 'tag', 'key': 'tags.keys()', 'parent_group': 'tags'}
],
# 'tag_none': None, # grouping by no tags isn't a different thing with plugin
# naming is redundant, like vpc_id_vpc_8c412cea, but intended
'vpc_id': {'prefix': 'vpc_id', 'key': 'vpc_id', 'parent_group': 'vpcs'},
}
# -- same-ish as script here --
group_by = [x.strip().lower() for x in inventory_source.group_by.split(',') if x.strip()]
for choice in self._get_ec2_group_by_choices():
value = bool((group_by and choice[0] in group_by) or (not group_by and choice[0] != 'instance_id'))
# -- end sameness to script --
if value:
this_keyed_group = group_by_hostvar.get(choice[0], None)
# If a keyed group syntax does not exist, there is nothing we can do to get this group
if this_keyed_group is not None:
if isinstance(this_keyed_group, list):
keyed_groups.extend(this_keyed_group)
else:
keyed_groups.append(this_keyed_group)
# special case, this parentage is only added if both zones and regions are present
if not group_by or ('region' in group_by and 'availability_zone' in group_by):
keyed_groups.append({'prefix': '', 'separator': '', 'key': 'placement.availability_zone', 'parent_group': '{{ placement.region }}'})
source_vars = inventory_source.source_vars_dict
# This is a setting from the script, hopefully no one used it
# if true, it replaces dashes, but not in region / loc names
replace_dash = bool(source_vars.get('replace_dash_in_groups', True))
# Compatibility content
legacy_regex = {
True: r"[^A-Za-z0-9\_]",
False: r"[^A-Za-z0-9\_\-]" # do not replace dash, dash is allowed
}[replace_dash]
list_replacer = 'map("regex_replace", "{rx}", "_") | list'.format(rx=legacy_regex)
# this option, a plugin option, will allow dashes, but not unicode
# when set to False, unicode will be allowed, but it was not allowed by script
# thus, we always have to use this option, and always use our custom regex
ret['use_contrib_script_compatible_sanitization'] = True
for grouping_data in keyed_groups:
if grouping_data['key'] in ('placement.region', 'placement.availability_zone'):
# us-east-2 is always us-east-2 according to ec2.py
# no sanitization in region-ish groups for the script standards, ever ever
continue
if grouping_data['key'] == 'tags':
# dict jinja2 transformation
grouping_data['key'] = 'dict(tags.keys() | {replacer} | zip(tags.values() | {replacer}))'.format(
replacer=list_replacer
)
elif grouping_data['key'] == 'tags.keys()' or grouping_data['prefix'] == 'security_group':
# list jinja2 transformation
grouping_data['key'] += ' | {replacer}'.format(replacer=list_replacer)
else:
# string transformation
grouping_data['key'] += ' | regex_replace("{rx}", "_")'.format(rx=legacy_regex)
# end compatibility content
if source_vars.get('iam_role_arn', None):
ret['iam_role_arn'] = source_vars['iam_role_arn']
# This was an allowed ec2.ini option, also plugin option, so pass through
if source_vars.get('boto_profile', None):
ret['boto_profile'] = source_vars['boto_profile']
elif not replace_dash:
# Using the plugin, but still want dashes allowed
ret['use_contrib_script_compatible_sanitization'] = True
if source_vars.get('nested_groups') is False:
for this_keyed_group in keyed_groups:
this_keyed_group.pop('parent_group', None)
if keyed_groups:
ret['keyed_groups'] = keyed_groups
# Instance ID not part of compat vars, because of settings.EC2_INSTANCE_ID_VAR
compose_dict = {'ec2_id': 'instance_id'}
inst_filters = {}
# Compatibility content
compose_dict.update(self._compat_compose_vars())
# plugin provides "aws_ec2", but not this which the script gave
ret['groups'] = {'ec2': True}
if source_vars.get('hostname_variable') is not None:
hnames = []
for expr in source_vars.get('hostname_variable').split(','):
if expr == 'public_dns_name':
hnames.append('dns-name')
elif not expr.startswith('tag:') and '_' in expr:
hnames.append(expr.replace('_', '-'))
else:
hnames.append(expr)
ret['hostnames'] = hnames
else:
# public_ip as hostname is non-default plugin behavior, script behavior
ret['hostnames'] = [
'network-interface.addresses.association.public-ip',
'dns-name',
'private-dns-name'
]
# The script returned only running state by default, the plugin does not
# https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html#options
# options: pending | running | shutting-down | terminated | stopping | stopped
inst_filters['instance-state-name'] = ['running']
# end compatibility content
if source_vars.get('destination_variable') or source_vars.get('vpc_destination_variable'):
for fd in ('destination_variable', 'vpc_destination_variable'):
if source_vars.get(fd):
compose_dict['ansible_host'] = source_vars.get(fd)
break
if compose_dict:
ret['compose'] = compose_dict
if inventory_source.instance_filters:
# logic used to live in ec2.py, now it belongs to us. Yay more code?
filter_sets = [f for f in inventory_source.instance_filters.split(',') if f]
for instance_filter in filter_sets:
# AND logic not supported, unclear how to...
instance_filter = instance_filter.strip()
if not instance_filter or '=' not in instance_filter:
continue
filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
if not filter_key:
continue
inst_filters[filter_key] = filter_value
if inst_filters:
ret['filters'] = inst_filters
if inventory_source.source_regions and 'all' not in inventory_source.source_regions:
ret['regions'] = inventory_source.source_regions.split(',')
return ret
class gce(PluginFileInjector):
plugin_name = 'gcp_compute'
namespace = 'google'
collection = 'cloud'
def _compat_compose_vars(self):
# missing: gce_image, gce_uuid
# https://github.com/ansible/ansible/issues/51884
return {
'gce_description': 'description if description else None',
'gce_machine_type': 'machineType',
'gce_name': 'name',
'gce_network': 'networkInterfaces[0].network.name',
'gce_private_ip': 'networkInterfaces[0].networkIP',
'gce_public_ip': 'networkInterfaces[0].accessConfigs[0].natIP | default(None)',
'gce_status': 'status',
'gce_subnetwork': 'networkInterfaces[0].subnetwork.name',
'gce_tags': 'tags.get("items", [])',
'gce_zone': 'zone',
'gce_metadata': 'metadata.get("items", []) | items2dict(key_name="key", value_name="value")',
# NOTE: image hostvar is enabled via retrieve_image_info option
'gce_image': 'image',
# We need this as long as hostnames is non-default, otherwise hosts
# will not be addressed correctly, was returned in script
'ansible_ssh_host': 'networkInterfaces[0].accessConfigs[0].natIP | default(networkInterfaces[0].networkIP)'
}
def inventory_as_dict(self, inventory_source, private_data_dir):
ret = super(gce, self).inventory_as_dict(inventory_source, private_data_dir)
# auth related items
ret['auth_kind'] = "serviceaccount"
filters = []
# TODO: implement gce group_by options
# gce never processed the group_by field, if it had, we would selectively
# apply those options here, but it did not, so all groups are added here
keyed_groups = [
# the jinja2 syntax is duplicated with compose
# https://github.com/ansible/ansible/issues/51883
{'prefix': 'network', 'key': 'gce_subnetwork'}, # composed var
{'prefix': '', 'separator': '', 'key': 'gce_private_ip'}, # composed var
{'prefix': '', 'separator': '', 'key': 'gce_public_ip'}, # composed var
{'prefix': '', 'separator': '', 'key': 'machineType'},
{'prefix': '', 'separator': '', 'key': 'zone'},
{'prefix': 'tag', 'key': 'gce_tags'}, # composed var
{'prefix': 'status', 'key': 'status | lower'},
# NOTE: image hostvar is enabled via retrieve_image_info option
{'prefix': '', 'separator': '', 'key': 'image'},
]
# This will be used as the gce instance_id, must be universal, non-compat
compose_dict = {'gce_id': 'id'}
# Compatibility content
# TODO: proper group_by and instance_filters support, irrelevant of compat mode
# The gce.py script never sanitized any names in any way
ret['use_contrib_script_compatible_sanitization'] = True
# Perform extra API query to get the image hostvar
ret['retrieve_image_info'] = True
# Add in old hostvars aliases
compose_dict.update(self._compat_compose_vars())
# Non-default names to match script
ret['hostnames'] = ['name', 'public_ip', 'private_ip']
# end compatibility content
if keyed_groups:
ret['keyed_groups'] = keyed_groups
if filters:
ret['filters'] = filters
if compose_dict:
ret['compose'] = compose_dict
if inventory_source.source_regions and 'all' not in inventory_source.source_regions:
ret['zones'] = inventory_source.source_regions.split(',')
return ret
class vmware(PluginFileInjector):
plugin_name = 'vmware_vm_inventory'
namespace = 'community'
collection = 'vmware'
def inventory_as_dict(self, inventory_source, private_data_dir):
ret = super(vmware, self).inventory_as_dict(inventory_source, private_data_dir)
ret['strict'] = False
# Documentation of props, see
# https://github.com/ansible/ansible/blob/devel/docs/docsite/rst/scenario_guides/vmware_scenarios/vmware_inventory_vm_attributes.rst
UPPERCASE_PROPS = [
"availableField",
"configIssue",
"configStatus",
"customValue", # optional
"datastore",
"effectiveRole",
"guestHeartbeatStatus", # optional
"layout", # optional
"layoutEx", # optional
"name",
"network",
"overallStatus",
"parentVApp", # optional
"permission",
"recentTask",
"resourcePool",
"rootSnapshot",
"snapshot", # optional
"triggeredAlarmState",
"value"
]
NESTED_PROPS = [
"capability",
"config",
"guest",
"runtime",
"storage",
"summary", # repeat of other properties
]
ret['properties'] = UPPERCASE_PROPS + NESTED_PROPS
ret['compose'] = {'ansible_host': 'guest.ipAddress'} # default value
ret['compose']['ansible_ssh_host'] = ret['compose']['ansible_host']
# the ansible_uuid was unique every host, every import, from the script
ret['compose']['ansible_uuid'] = '99999999 | random | to_uuid'
for prop in UPPERCASE_PROPS:
if prop == prop.lower():
continue
ret['compose'][prop.lower()] = prop
ret['with_nested_properties'] = True
# ret['property_name_format'] = 'lower_case' # only dacrystal/topic/vmware-inventory-plugin-property-format
# process custom options
vmware_opts = dict(inventory_source.source_vars_dict.items())
if inventory_source.instance_filters:
vmware_opts.setdefault('host_filters', inventory_source.instance_filters)
if inventory_source.group_by:
vmware_opts.setdefault('groupby_patterns', inventory_source.group_by)
alias_pattern = vmware_opts.get('alias_pattern')
if alias_pattern:
ret.setdefault('hostnames', [])
for alias in alias_pattern.split(','): # make best effort
striped_alias = alias.replace('{', '').replace('}', '').strip() # make best effort
if not striped_alias:
continue
ret['hostnames'].append(striped_alias)
host_pattern = vmware_opts.get('host_pattern') # not working in script
if host_pattern:
stripped_hp = host_pattern.replace('{', '').replace('}', '').strip() # make best effort
ret['compose']['ansible_host'] = stripped_hp
ret['compose']['ansible_ssh_host'] = stripped_hp
host_filters = vmware_opts.get('host_filters')
if host_filters:
ret.setdefault('filters', [])
for hf in host_filters.split(','):
striped_hf = hf.replace('{', '').replace('}', '').strip() # make best effort
if not striped_hf:
continue
ret['filters'].append(striped_hf)
else:
# default behavior filters by power state
ret['filters'] = ['runtime.powerState == "poweredOn"']
groupby_patterns = vmware_opts.get('groupby_patterns')
ret.setdefault('keyed_groups', [])
if groupby_patterns:
for pattern in groupby_patterns.split(','):
stripped_pattern = pattern.replace('{', '').replace('}', '').strip() # make best effort
ret['keyed_groups'].append({
'prefix': '', 'separator': '',
'key': stripped_pattern
})
else:
# default groups from script
for entry in ('config.guestId', '"templates" if config.template else "guests"'):
ret['keyed_groups'].append({
'prefix': '', 'separator': '',
'key': entry
})
return ret
class openstack(PluginFileInjector):
plugin_name = 'openstack'
namespace = 'openstack'
collection = 'cloud'
def inventory_as_dict(self, inventory_source, private_data_dir):
def use_host_name_for_name(a_bool_maybe):
if not isinstance(a_bool_maybe, bool):
# Could be specified by user via "host" or "uuid"
return a_bool_maybe
elif a_bool_maybe:
return 'name' # plugin default
else:
return 'uuid'
ret = super(openstack, self).inventory_as_dict(inventory_source, private_data_dir)
ret['fail_on_errors'] = True
ret['expand_hostvars'] = True
ret['inventory_hostname'] = use_host_name_for_name(False)
# Note: mucking with defaults will break import integrity
# For the plugin, we need to use the same defaults as the old script
# or else imports will conflict. To find script defaults you have
# to read source code of the script.
#
# Script Defaults Plugin Defaults
# 'use_hostnames': False, 'name' (True)
# 'expand_hostvars': True, 'no' (False)
# 'fail_on_errors': True, 'no' (False)
#
# These are, yet again, different from ansible_variables in script logic
# but those are applied inconsistently
source_vars = inventory_source.source_vars_dict
for var_name in ['expand_hostvars', 'fail_on_errors']:
if var_name in source_vars:
ret[var_name] = source_vars[var_name]
if 'use_hostnames' in source_vars:
ret['inventory_hostname'] = use_host_name_for_name(source_vars['use_hostnames'])
return ret
class rhv(PluginFileInjector):
"""ovirt uses the custom credential templating, and that is all
"""
plugin_name = 'ovirt'
initial_version = '2.9'
namespace = 'ovirt'
collection = 'ovirt'
def inventory_as_dict(self, inventory_source, private_data_dir):
ret = super(rhv, self).inventory_as_dict(inventory_source, private_data_dir)
ret['ovirt_insecure'] = False # Default changed from script
# TODO: process strict option upstream
ret['compose'] = {
'ansible_host': '(devices.values() | list)[0][0] if devices else None'
}
ret['keyed_groups'] = []
for key in ('cluster', 'status'):
ret['keyed_groups'].append({'prefix': key, 'separator': '_', 'key': key})
ret['keyed_groups'].append({'prefix': 'tag', 'separator': '_', 'key': 'tags'})
ret['ovirt_hostname_preference'] = ['name', 'fqdn']
source_vars = inventory_source.source_vars_dict
for key, value in source_vars.items():
if key == 'plugin':
continue
ret[key] = value
return ret
class satellite6(PluginFileInjector):
plugin_name = 'foreman'
namespace = 'theforeman'
collection = 'foreman'
def inventory_as_dict(self, inventory_source, private_data_dir):
ret = super(satellite6, self).inventory_as_dict(inventory_source, private_data_dir)
ret['validate_certs'] = False
group_patterns = '[]'
group_prefix = 'foreman_'
want_hostcollections = False
want_ansible_ssh_host = False
want_facts = True
foreman_opts = inventory_source.source_vars_dict.copy()
for k, v in foreman_opts.items():
if k == 'satellite6_group_patterns' and isinstance(v, str):
group_patterns = v
elif k == 'satellite6_group_prefix' and isinstance(v, str):
group_prefix = v
elif k == 'satellite6_want_hostcollections' and isinstance(v, bool):
want_hostcollections = v
elif k == 'satellite6_want_ansible_ssh_host' and isinstance(v, bool):
want_ansible_ssh_host = v
elif k == 'satellite6_want_facts' and isinstance(v, bool):
want_facts = v
# add backwards support for ssl_verify
# plugin uses new option, validate_certs, instead
elif k == 'ssl_verify' and isinstance(v, bool):
ret['validate_certs'] = v
else:
ret[k] = str(v)
# Compatibility content
group_by_hostvar = {
"environment": {"prefix": "{}environment_".format(group_prefix),
"separator": "",
"key": "foreman['environment_name'] | lower | regex_replace(' ', '') | "
"regex_replace('[^A-Za-z0-9_]', '_') | regex_replace('none', '')"},
"location": {"prefix": "{}location_".format(group_prefix),
"separator": "",
"key": "foreman['location_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')"},
"organization": {"prefix": "{}organization_".format(group_prefix),
"separator": "",
"key": "foreman['organization_name'] | lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')"},
"lifecycle_environment": {"prefix": "{}lifecycle_environment_".format(group_prefix),
"separator": "",
"key": "foreman['content_facet_attributes']['lifecycle_environment_name'] | "
"lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')"},
"content_view": {"prefix": "{}content_view_".format(group_prefix),
"separator": "",
"key": "foreman['content_facet_attributes']['content_view_name'] | "
"lower | regex_replace(' ', '') | regex_replace('[^A-Za-z0-9_]', '_')"}
}
ret['legacy_hostvars'] = True # convert hostvar structure to the form used by the script
ret['want_params'] = True
ret['group_prefix'] = group_prefix
ret['want_hostcollections'] = want_hostcollections
ret['want_facts'] = want_facts
if want_ansible_ssh_host:
ret['compose'] = {'ansible_ssh_host': "foreman['ip6'] | default(foreman['ip'], true)"}
ret['keyed_groups'] = [group_by_hostvar[grouping_name] for grouping_name in group_by_hostvar]
def form_keyed_group(group_pattern):
"""
Converts foreman group_pattern to
inventory plugin keyed_group
e.g. {app_param}-{tier_param}-{dc_param}
becomes
"%s-%s-%s" | format(app_param, tier_param, dc_param)
"""
if type(group_pattern) is not str:
return None
params = re.findall('{[^}]*}', group_pattern)
if len(params) == 0:
return None
param_names = []
for p in params:
param_names.append(p[1:-1].strip()) # strip braces and space
# form keyed_group key by
# replacing curly braces with '%s'
# (for use with jinja's format filter)
key = group_pattern
for p in params:
key = key.replace(p, '%s', 1)
# apply jinja filter to key
key = '"{}" | format({})'.format(key, ', '.join(param_names))
keyed_group = {'key': key,
'separator': ''}
return keyed_group
try:
group_patterns = json.loads(group_patterns)
if type(group_patterns) is list:
for group_pattern in group_patterns:
keyed_group = form_keyed_group(group_pattern)
if keyed_group:
ret['keyed_groups'].append(keyed_group)
except json.JSONDecodeError:
logger.warning('Could not parse group_patterns. Expected JSON-formatted string, found: {}'
.format(group_patterns))
return ret
class tower(PluginFileInjector):
plugin_name = 'tower'
namespace = 'awx'
collection = 'awx'
def inventory_as_dict(self, inventory_source, private_data_dir):
ret = super(tower, self).inventory_as_dict(inventory_source, private_data_dir)
# Credentials injected as env vars, same as script
try:
# plugin can take an actual int type
identifier = int(inventory_source.instance_filters)
except ValueError:
# inventory_id could be a named URL
identifier = iri_to_uri(inventory_source.instance_filters)
ret['inventory_id'] = identifier
ret['include_metadata'] = True # used for license check
return ret
for cls in PluginFileInjector.__subclasses__():
FrozenInjectors[cls.__name__] = cls

View File

@@ -127,9 +127,15 @@ def user_get_auditor_of_organizations(user):
return Organization.objects.filter(auditor_role__members=user)
@property
def created(user):
return user.date_joined
User.add_to_class('organizations', user_get_organizations)
User.add_to_class('admin_of_organizations', user_get_admin_of_organizations)
User.add_to_class('auditor_of_organizations', user_get_auditor_of_organizations)
User.add_to_class('created', created)
@property

View File

@@ -407,7 +407,7 @@ def prevent_search(relation):
sensitive_data = prevent_search(models.CharField(...))
The flag set by this function is used by
`awx.api.filters.FieldLookupBackend` to blacklist fields and relations that
`awx.api.filters.FieldLookupBackend` to block fields and relations that
should not be searchable/filterable via search query params
"""
setattr(relation, '__prevent_search__', True)

View File

@@ -11,7 +11,7 @@ import tempfile
from types import SimpleNamespace
# Jinja2
from jinja2 import Template
from jinja2 import sandbox
# Django
from django.db import models
@@ -96,6 +96,10 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
help_text=_('Specify the type of credential you want to create. Refer '
'to the Ansible Tower documentation for details on each type.')
)
managed_by_tower = models.BooleanField(
default=False,
editable=False
)
organization = models.ForeignKey(
'Organization',
null=True,
@@ -331,6 +335,7 @@ class CredentialType(CommonModelNameNotUnique):
('insights', _('Insights')),
('external', _('External')),
('kubernetes', _('Kubernetes')),
('galaxy', _('Galaxy/Automation Hub')),
)
kind = models.CharField(
@@ -514,8 +519,11 @@ class CredentialType(CommonModelNameNotUnique):
# If any file templates are provided, render the files and update the
# special `tower` template namespace so the filename can be
# referenced in other injectors
sandbox_env = sandbox.ImmutableSandboxedEnvironment()
for file_label, file_tmpl in file_tmpls.items():
data = Template(file_tmpl).render(**namespace)
data = sandbox_env.from_string(file_tmpl).render(**namespace)
_, path = tempfile.mkstemp(dir=private_data_dir)
with open(path, 'w') as f:
f.write(data)
@@ -537,14 +545,14 @@ class CredentialType(CommonModelNameNotUnique):
except ValidationError as e:
logger.error('Ignoring prohibited env var {}, reason: {}'.format(env_var, e))
continue
env[env_var] = Template(tmpl).render(**namespace)
safe_env[env_var] = Template(tmpl).render(**safe_namespace)
env[env_var] = sandbox_env.from_string(tmpl).render(**namespace)
safe_env[env_var] = sandbox_env.from_string(tmpl).render(**safe_namespace)
if 'INVENTORY_UPDATE_ID' not in env:
# awx-manage inventory_update does not support extra_vars via -e
extra_vars = {}
for var_name, tmpl in self.injectors.get('extra_vars', {}).items():
extra_vars[var_name] = Template(tmpl).render(**namespace)
extra_vars[var_name] = sandbox_env.from_string(tmpl).render(**namespace)
def build_extra_vars_file(vars, private_dir):
handle, path = tempfile.mkstemp(dir = private_dir)
@@ -873,33 +881,6 @@ ManagedCredentialType(
}
)
ManagedCredentialType(
namespace='cloudforms',
kind='cloud',
name=ugettext_noop('Red Hat CloudForms'),
managed_by_tower=True,
inputs={
'fields': [{
'id': 'host',
'label': ugettext_noop('CloudForms URL'),
'type': 'string',
'help_text': ugettext_noop('Enter the URL for the virtual machine that '
'corresponds to your CloudForms instance. '
'For example, https://cloudforms.example.org')
}, {
'id': 'username',
'label': ugettext_noop('Username'),
'type': 'string'
}, {
'id': 'password',
'label': ugettext_noop('Password'),
'type': 'string',
'secret': True,
}],
'required': ['host', 'username', 'password'],
}
)
ManagedCredentialType(
namespace='gce',
kind='cloud',
@@ -1103,26 +1084,36 @@ ManagedCredentialType(
}, {
'id': 'username',
'label': ugettext_noop('Username'),
'type': 'string'
'type': 'string',
'help_text': ugettext_noop('The Ansible Tower user to authenticate as.'
'This should not be set if an OAuth token is being used.')
}, {
'id': 'password',
'label': ugettext_noop('Password'),
'type': 'string',
'secret': True,
}, {
'id': 'oauth_token',
'label': ugettext_noop('OAuth Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('An OAuth token to use to authenticate to Tower with.'
'This should not be set if username/password are being used.')
}, {
'id': 'verify_ssl',
'label': ugettext_noop('Verify SSL'),
'type': 'boolean',
'secret': False
}],
'required': ['host', 'username', 'password'],
'required': ['host'],
},
injectors={
'env': {
'TOWER_HOST': '{{host}}',
'TOWER_USERNAME': '{{username}}',
'TOWER_PASSWORD': '{{password}}',
'TOWER_VERIFY_SSL': '{{verify_ssl}}'
'TOWER_VERIFY_SSL': '{{verify_ssl}}',
'TOWER_OAUTH_TOKEN': '{{oauth_token}}'
}
},
)
@@ -1160,6 +1151,38 @@ ManagedCredentialType(
)
ManagedCredentialType(
namespace='galaxy_api_token',
kind='galaxy',
name=ugettext_noop('Ansible Galaxy/Automation Hub API Token'),
inputs={
'fields': [{
'id': 'url',
'label': ugettext_noop('Galaxy Server URL'),
'type': 'string',
'help_text': ugettext_noop('The URL of the Galaxy instance to connect to.')
},{
'id': 'auth_url',
'label': ugettext_noop('Auth Server URL'),
'type': 'string',
'help_text': ugettext_noop(
'The URL of a Keycloak server token_endpoint, if using '
'SSO auth.'
)
},{
'id': 'token',
'label': ugettext_noop('API Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop(
'A token to use for authentication against the Galaxy instance.'
)
}],
'required': ['url'],
}
)
class CredentialInputSource(PrimordialModel):
class Meta:

View File

@@ -101,3 +101,17 @@ def openstack(cred, env, private_data_dir):
f.close()
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
env['OS_CLIENT_CONFIG_FILE'] = path
def kubernetes_bearer_token(cred, env, private_data_dir):
env['K8S_AUTH_HOST'] = cred.get_input('host', default='')
env['K8S_AUTH_API_KEY'] = cred.get_input('bearer_token', default='')
if cred.get_input('verify_ssl') and 'ssl_ca_cert' in cred.inputs:
env['K8S_AUTH_VERIFY_SSL'] = 'True'
handle, path = tempfile.mkstemp(dir=private_data_dir)
with os.fdopen(handle, 'w') as f:
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
f.write(cred.get_input('ssl_ca_cert'))
env['K8S_AUTH_SSL_CA_CERT'] = path
else:
env['K8S_AUTH_VERIFY_SSL'] = 'False'

View File

@@ -4,6 +4,8 @@ import datetime
import logging
from collections import defaultdict
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db import models, DatabaseError, connection
from django.utils.dateparse import parse_datetime
from django.utils.text import Truncator
@@ -57,7 +59,18 @@ def create_host_status_counts(event_data):
return dict(host_status_counts)
MINIMAL_EVENTS = set([
'playbook_on_play_start', 'playbook_on_task_start',
'playbook_on_stats', 'EOF'
])
def emit_event_detail(event):
if (
settings.UI_LIVE_UPDATES_ENABLED is False and
event.event not in MINIMAL_EVENTS
):
return
cls = event.__class__
relation = {
JobEvent: 'job_id',
@@ -337,41 +350,47 @@ class BasePlaybookEvent(CreatedModifiedModel):
pass
if isinstance(self, JobEvent):
hostnames = self._hostnames()
self._update_host_summary_from_stats(set(hostnames))
if self.job.inventory:
try:
self.job.inventory.update_computed_fields()
except DatabaseError:
logger.exception('Computed fields database error saving event {}'.format(self.pk))
try:
job = self.job
except ObjectDoesNotExist:
job = None
if job:
hostnames = self._hostnames()
self._update_host_summary_from_stats(set(hostnames))
if job.inventory:
try:
job.inventory.update_computed_fields()
except DatabaseError:
logger.exception('Computed fields database error saving event {}'.format(self.pk))
# find parent links and progagate changed=T and failed=T
changed = self.job.job_events.filter(changed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
failed = self.job.job_events.filter(failed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
# find parent links and progagate changed=T and failed=T
changed = job.job_events.filter(changed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
failed = job.job_events.filter(failed=True).exclude(parent_uuid=None).only('parent_uuid').values_list('parent_uuid', flat=True).distinct() # noqa
JobEvent.objects.filter(
job_id=self.job_id, uuid__in=changed
).update(changed=True)
JobEvent.objects.filter(
job_id=self.job_id, uuid__in=failed
).update(failed=True)
JobEvent.objects.filter(
job_id=self.job_id, uuid__in=changed
).update(changed=True)
JobEvent.objects.filter(
job_id=self.job_id, uuid__in=failed
).update(failed=True)
# send success/failure notifications when we've finished handling the playbook_on_stats event
from awx.main.tasks import handle_success_and_failure_notifications # circular import
# send success/failure notifications when we've finished handling the playbook_on_stats event
from awx.main.tasks import handle_success_and_failure_notifications # circular import
def _send_notifications():
handle_success_and_failure_notifications.apply_async([self.job.id])
connection.on_commit(_send_notifications)
def _send_notifications():
handle_success_and_failure_notifications.apply_async([job.id])
connection.on_commit(_send_notifications)
for field in ('playbook', 'play', 'task', 'role'):
value = force_text(event_data.get(field, '')).strip()
if value != getattr(self, field):
setattr(self, field, value)
analytics_logger.info(
'Event data saved.',
extra=dict(python_objects=dict(job_event=self))
)
if settings.LOG_AGGREGATOR_ENABLED:
analytics_logger.info(
'Event data saved.',
extra=dict(python_objects=dict(job_event=self))
)
@classmethod
def create_from_data(cls, **kwargs):
@@ -484,7 +503,11 @@ class JobEvent(BasePlaybookEvent):
def _update_host_summary_from_stats(self, hostnames):
with ignore_inventory_computed_fields():
if not self.job or not self.job.inventory:
try:
if not self.job or not self.job.inventory:
logger.info('Event {} missing job or inventory, host summaries not updated'.format(self.pk))
return
except ObjectDoesNotExist:
logger.info('Event {} missing job or inventory, host summaries not updated'.format(self.pk))
return
job = self.job
@@ -520,13 +543,21 @@ class JobEvent(BasePlaybookEvent):
(summary['host_id'], summary['id'])
for summary in JobHostSummary.objects.filter(job_id=job.id).values('id', 'host_id')
)
updated_hosts = set()
for h in all_hosts:
# if the hostname *shows up* in the playbook_on_stats event
if h.name in hostnames:
h.last_job_id = job.id
updated_hosts.add(h)
if h.id in host_mapping:
h.last_job_host_summary_id = host_mapping[h.id]
Host.objects.bulk_update(all_hosts, ['last_job_id', 'last_job_host_summary_id'])
updated_hosts.add(h)
Host.objects.bulk_update(
list(updated_hosts),
['last_job_id', 'last_job_host_summary_id'],
batch_size=100
)
@property

View File

@@ -12,6 +12,7 @@ from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.utils.timezone import now, timedelta
import redis
from solo.models import SingletonModel
from awx import __version__ as awx_application_version
@@ -23,7 +24,7 @@ from awx.main.models.unified_jobs import UnifiedJob
from awx.main.utils import get_cpu_capacity, get_mem_capacity, get_system_task_capacity
from awx.main.models.mixins import RelatedJobsMixin
__all__ = ('Instance', 'InstanceGroup', 'TowerScheduleState', 'TowerAnalyticsState')
__all__ = ('Instance', 'InstanceGroup', 'TowerScheduleState')
class HasPolicyEditsMixin(HasEditsMixin):
@@ -152,6 +153,14 @@ class Instance(HasPolicyEditsMixin, BaseModel):
self.capacity = get_system_task_capacity(self.capacity_adjustment)
else:
self.capacity = 0
try:
# if redis is down for some reason, that means we can't persist
# playbook event data; we should consider this a zero capacity event
redis.Redis.from_url(settings.BROKER_URL).ping()
except redis.ConnectionError:
self.capacity = 0
self.cpu = cpu[0]
self.memory = mem[0]
self.cpu_capacity = cpu[1]
@@ -252,18 +261,20 @@ class InstanceGroup(HasPolicyEditsMixin, BaseModel, RelatedJobsMixin):
app_label = 'main'
def fit_task_to_most_remaining_capacity_instance(self, task):
@staticmethod
def fit_task_to_most_remaining_capacity_instance(task, instances):
instance_most_capacity = None
for i in self.instances.filter(capacity__gt=0, enabled=True).order_by('hostname'):
for i in instances:
if i.remaining_capacity >= task.task_impact and \
(instance_most_capacity is None or
i.remaining_capacity > instance_most_capacity.remaining_capacity):
instance_most_capacity = i
return instance_most_capacity
def find_largest_idle_instance(self):
@staticmethod
def find_largest_idle_instance(instances):
largest_instance = None
for i in self.instances.filter(capacity__gt=0, enabled=True).order_by('hostname'):
for i in instances:
if i.jobs_running == 0:
if largest_instance is None:
largest_instance = i
@@ -287,10 +298,6 @@ class TowerScheduleState(SingletonModel):
schedule_last_run = models.DateTimeField(auto_now_add=True)
class TowerAnalyticsState(SingletonModel):
last_run = models.DateTimeField(auto_now_add=True)
def schedule_policy_task():
from awx.main.tasks import apply_cluster_membership_policies
connection.on_commit(lambda: apply_cluster_membership_policies.apply_async())

File diff suppressed because it is too large Load Diff

View File

@@ -798,6 +798,10 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
if self.project:
for name in ('awx', 'tower'):
r['{}_project_revision'.format(name)] = self.project.scm_revision
r['{}_project_scm_branch'.format(name)] = self.project.scm_branch
if self.scm_branch:
for name in ('awx', 'tower'):
r['{}_job_scm_branch'.format(name)] = self.scm_branch
if self.job_template:
for name in ('awx', 'tower'):
r['{}_job_template_id'.format(name)] = self.job_template.pk

View File

@@ -262,25 +262,25 @@ class JobNotificationMixin(object):
'running': 'started',
'failed': 'error'}
# Tree of fields that can be safely referenced in a notification message
JOB_FIELDS_WHITELIST = ['id', 'type', 'url', 'created', 'modified', 'name', 'description', 'job_type', 'playbook',
'forks', 'limit', 'verbosity', 'job_tags', 'force_handlers', 'skip_tags', 'start_at_task',
'timeout', 'use_fact_cache', 'launch_type', 'status', 'failed', 'started', 'finished',
'elapsed', 'job_explanation', 'execution_node', 'controller_node', 'allow_simultaneous',
'scm_revision', 'diff_mode', 'job_slice_number', 'job_slice_count', 'custom_virtualenv',
'approval_status', 'approval_node_name', 'workflow_url', 'scm_branch',
{'host_status_counts': ['skipped', 'ok', 'changed', 'failed', 'failures', 'dark'
'processed', 'rescued', 'ignored']},
{'summary_fields': [{'inventory': ['id', 'name', 'description', 'has_active_failures',
'total_hosts', 'hosts_with_active_failures', 'total_groups',
'has_inventory_sources',
'total_inventory_sources', 'inventory_sources_with_failures',
'organization_id', 'kind']},
{'project': ['id', 'name', 'description', 'status', 'scm_type']},
{'job_template': ['id', 'name', 'description']},
{'unified_job_template': ['id', 'name', 'description', 'unified_job_type']},
{'instance_group': ['name', 'id']},
{'created_by': ['id', 'username', 'first_name', 'last_name']},
{'labels': ['count', 'results']}]}]
JOB_FIELDS_ALLOWED_LIST = ['id', 'type', 'url', 'created', 'modified', 'name', 'description', 'job_type', 'playbook',
'forks', 'limit', 'verbosity', 'job_tags', 'force_handlers', 'skip_tags', 'start_at_task',
'timeout', 'use_fact_cache', 'launch_type', 'status', 'failed', 'started', 'finished',
'elapsed', 'job_explanation', 'execution_node', 'controller_node', 'allow_simultaneous',
'scm_revision', 'diff_mode', 'job_slice_number', 'job_slice_count', 'custom_virtualenv',
'approval_status', 'approval_node_name', 'workflow_url', 'scm_branch', 'artifacts',
{'host_status_counts': ['skipped', 'ok', 'changed', 'failed', 'failures', 'dark'
'processed', 'rescued', 'ignored']},
{'summary_fields': [{'inventory': ['id', 'name', 'description', 'has_active_failures',
'total_hosts', 'hosts_with_active_failures', 'total_groups',
'has_inventory_sources',
'total_inventory_sources', 'inventory_sources_with_failures',
'organization_id', 'kind']},
{'project': ['id', 'name', 'description', 'status', 'scm_type']},
{'job_template': ['id', 'name', 'description']},
{'unified_job_template': ['id', 'name', 'description', 'unified_job_type']},
{'instance_group': ['name', 'id']},
{'created_by': ['id', 'username', 'first_name', 'last_name']},
{'labels': ['count', 'results']}]}]
@classmethod
def context_stub(cls):
@@ -288,6 +288,7 @@ class JobNotificationMixin(object):
Context has the same structure as the context that will actually be used to render
a notification message."""
context = {'job': {'allow_simultaneous': False,
'artifacts': {},
'controller_node': 'foo_controller',
'created': datetime.datetime(2018, 11, 13, 6, 4, 0, 0, tzinfo=datetime.timezone.utc),
'custom_virtualenv': 'my_venv',
@@ -377,8 +378,8 @@ class JobNotificationMixin(object):
def context(self, serialized_job):
"""Returns a dictionary that can be used for rendering notification messages.
The context will contain whitelisted content retrieved from a serialized job object
(see JobNotificationMixin.JOB_FIELDS_WHITELIST), the job's friendly name,
The context will contain allowed content retrieved from a serialized job object
(see JobNotificationMixin.JOB_FIELDS_ALLOWED_LIST the job's friendly name,
and a url to the job run."""
job_context = {'host_status_counts': {}}
summary = None
@@ -392,25 +393,29 @@ class JobNotificationMixin(object):
'job': job_context,
'job_friendly_name': self.get_notification_friendly_name(),
'url': self.get_ui_url(),
'job_metadata': json.dumps(self.notification_data(), indent=4)
'job_metadata': json.dumps(
self.notification_data(),
ensure_ascii=False,
indent=4
)
}
def build_context(node, fields, whitelisted_fields):
for safe_field in whitelisted_fields:
def build_context(node, fields, allowed_fields):
for safe_field in allowed_fields:
if type(safe_field) is dict:
field, whitelist_subnode = safe_field.copy().popitem()
field, allowed_subnode = safe_field.copy().popitem()
# ensure content present in job serialization
if field not in fields:
continue
subnode = fields[field]
node[field] = {}
build_context(node[field], subnode, whitelist_subnode)
build_context(node[field], subnode, allowed_subnode)
else:
# ensure content present in job serialization
if safe_field not in fields:
continue
node[safe_field] = fields[safe_field]
build_context(context['job'], serialized_job, self.JOB_FIELDS_WHITELIST)
build_context(context['job'], serialized_job, self.JOB_FIELDS_ALLOWED_LIST)
return context

View File

@@ -45,6 +45,12 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
blank=True,
through='OrganizationInstanceGroupMembership'
)
galaxy_credentials = OrderedManyToManyField(
'Credential',
blank=True,
through='OrganizationGalaxyCredentialMembership',
related_name='%(class)s_galaxy_credentials'
)
max_hosts = models.PositiveIntegerField(
blank=True,
default=0,
@@ -108,6 +114,23 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
return UnifiedJob.objects.non_polymorphic().filter(organization=self)
class OrganizationGalaxyCredentialMembership(models.Model):
organization = models.ForeignKey(
'Organization',
on_delete=models.CASCADE
)
credential = models.ForeignKey(
'Credential',
on_delete=models.CASCADE
)
position = models.PositiveIntegerField(
null=True,
default=None,
db_index=True,
)
class Team(CommonModelNameNotUnique, ResourceMixin):
'''
A team is a group of users that work on common projects.

View File

@@ -52,9 +52,9 @@ class ProjectOptions(models.Model):
SCM_TYPE_CHOICES = [
('', _('Manual')),
('git', _('Git')),
('hg', _('Mercurial')),
('svn', _('Subversion')),
('insights', _('Red Hat Insights')),
('archive', _('Remote Archive')),
]
class Meta:
@@ -194,6 +194,11 @@ class ProjectOptions(models.Model):
if not check_if_exists or os.path.exists(smart_str(proj_path)):
return proj_path
def get_cache_path(self):
local_path = os.path.basename(self.local_path)
if local_path:
return os.path.join(settings.PROJECTS_ROOT, '.__awx_cache', local_path)
@property
def playbooks(self):
results = []
@@ -418,6 +423,10 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
return True
return False
@property
def cache_id(self):
return str(self.last_job_id)
@property
def notification_templates(self):
base_notification_templates = NotificationTemplate.objects
@@ -455,11 +464,12 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
)
def delete(self, *args, **kwargs):
path_to_delete = self.get_project_path(check_if_exists=False)
paths_to_delete = (self.get_project_path(check_if_exists=False), self.get_cache_path())
r = super(Project, self).delete(*args, **kwargs)
if self.scm_type and path_to_delete: # non-manual, concrete path
from awx.main.tasks import delete_project_files
delete_project_files.delay(path_to_delete)
for path_to_delete in paths_to_delete:
if self.scm_type and path_to_delete: # non-manual, concrete path
from awx.main.tasks import delete_project_files
delete_project_files.delay(path_to_delete)
return r
@@ -554,6 +564,19 @@ class ProjectUpdate(UnifiedJob, ProjectOptions, JobNotificationMixin, TaskManage
def result_stdout_raw(self):
return self._result_stdout_raw(redact_sensitive=True)
@property
def branch_override(self):
"""Whether a branch other than the project default is used."""
if not self.project:
return True
return bool(self.scm_branch and self.scm_branch != self.project.scm_branch)
@property
def cache_id(self):
if self.branch_override or self.job_type == 'check' or (not self.project):
return str(self.id)
return self.project.cache_id
def result_stdout_raw_limited(self, start_line=0, end_line=None, redact_sensitive=True):
return self._result_stdout_raw_limited(start_line, end_line, redact_sensitive=redact_sensitive)
@@ -597,10 +620,7 @@ class ProjectUpdate(UnifiedJob, ProjectOptions, JobNotificationMixin, TaskManage
def save(self, *args, **kwargs):
added_update_fields = []
if not self.job_tags:
job_tags = ['update_{}'.format(self.scm_type)]
if self.job_type == 'run':
job_tags.append('install_roles')
job_tags.append('install_collections')
job_tags = ['update_{}'.format(self.scm_type), 'install_roles', 'install_collections']
self.job_tags = ','.join(job_tags)
added_update_fields.append('job_tags')
if self.scm_delete_on_update and 'delete' not in self.job_tags and self.job_type == 'check':

View File

@@ -205,10 +205,15 @@ class Schedule(PrimordialModel, LaunchTimeConfig):
'A valid TZID must be provided (e.g., America/New_York)'
)
if fast_forward and ('MINUTELY' in rrule or 'HOURLY' in rrule):
if (
fast_forward and
('MINUTELY' in rrule or 'HOURLY' in rrule) and
'COUNT=' not in rrule
):
try:
first_event = x[0]
if first_event < now():
# If the first event was over a week ago...
if (now() - first_event).days > 7:
# hourly/minutely rrules with far-past DTSTART values
# are *really* slow to precompute
# start *from* one week ago to speed things up drastically

View File

@@ -873,7 +873,13 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
# If status changed, update the parent instance.
if self.status != status_before:
self._update_parent_instance()
# Update parent outside of the transaction for Job w/ allow_simultaneous=True
# This dodges lock contention at the expense of the foreign key not being
# completely correct.
if getattr(self, 'allow_simultaneous', False):
connection.on_commit(self._update_parent_instance)
else:
self._update_parent_instance()
# Done.
return result
@@ -962,6 +968,10 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
def event_class(self):
raise NotImplementedError()
@property
def job_type_name(self):
return self.get_real_instance_class()._meta.verbose_name.replace(' ', '_')
@property
def result_stdout_text(self):
related = UnifiedJobDeprecatedStdout.objects.get(pk=self.pk)
@@ -1221,7 +1231,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
def websocket_emit_data(self):
''' Return extra data that should be included when submitting data to the browser over the websocket connection '''
websocket_data = dict(type=self.get_real_instance_class()._meta.verbose_name.replace(' ', '_'))
websocket_data = dict(type=self.job_type_name)
if self.spawned_by_workflow:
websocket_data.update(dict(workflow_job_id=self.workflow_job_id,
workflow_node_id=self.workflow_node_id))
@@ -1362,7 +1372,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
running = self.celery_task_id in ControlDispatcher(
'dispatcher', self.controller_node or self.execution_node
).running(timeout=timeout)
except socket.timeout:
except (socket.timeout, RuntimeError):
logger.error('could not reach dispatcher on {} within {}s'.format(
self.execution_node, timeout
))

View File

@@ -139,7 +139,7 @@ class WorkflowJobTemplateNode(WorkflowNodeBase):
'always_nodes', 'credentials', 'inventory', 'extra_data', 'survey_passwords',
'char_prompts', 'all_parents_must_converge', 'identifier'
]
REENCRYPTION_BLACKLIST_AT_COPY = ['extra_data', 'survey_passwords']
REENCRYPTION_BLOCKLIST_AT_COPY = ['extra_data', 'survey_passwords']
workflow_job_template = models.ForeignKey(
'WorkflowJobTemplate',
@@ -674,7 +674,7 @@ class WorkflowJob(UnifiedJob, WorkflowJobOptions, SurveyJobMixin, JobNotificatio
return self.status == 'running'
class WorkflowApprovalTemplate(UnifiedJobTemplate):
class WorkflowApprovalTemplate(UnifiedJobTemplate, RelatedJobsMixin):
FIELDS_TO_PRESERVE_AT_COPY = ['description', 'timeout',]
@@ -702,6 +702,12 @@ class WorkflowApprovalTemplate(UnifiedJobTemplate):
def workflow_job_template(self):
return self.workflowjobtemplatenodes.first().workflow_job_template
'''
RelatedJobsMixin
'''
def _get_related_jobs(self):
return UnifiedJob.objects.filter(unified_job_template=self)
class WorkflowApproval(UnifiedJob, JobNotificationMixin):
class Meta:
@@ -776,6 +782,10 @@ class WorkflowApproval(UnifiedJob, JobNotificationMixin):
self.send_approval_notification('running')
return can_start
@property
def event_processing_finished(self):
return True
def send_approval_notification(self, approval_status):
from awx.main.tasks import send_notifications # avoid circular import
if self.workflow_job_template is None:

View File

@@ -94,8 +94,8 @@ class GrafanaBackend(AWXBaseEmailBackend, CustomNotificationBase):
headers=grafana_headers,
verify=(not self.grafana_no_verify_ssl))
if r.status_code >= 400:
logger.error(smart_text(_("Error sending notification grafana: {}").format(r.text)))
logger.error(smart_text(_("Error sending notification grafana: {}").format(r.status_code)))
if not self.fail_silently:
raise Exception(smart_text(_("Error sending notification grafana: {}").format(r.text)))
raise Exception(smart_text(_("Error sending notification grafana: {}").format(r.status_code)))
sent_messages += 1
return sent_messages

View File

@@ -46,8 +46,8 @@ class MattermostBackend(AWXBaseEmailBackend, CustomNotificationBase):
r = requests.post("{}".format(m.recipients()[0]),
json=payload, verify=(not self.mattermost_no_verify_ssl))
if r.status_code >= 400:
logger.error(smart_text(_("Error sending notification mattermost: {}").format(r.text)))
logger.error(smart_text(_("Error sending notification mattermost: {}").format(r.status_code)))
if not self.fail_silently:
raise Exception(smart_text(_("Error sending notification mattermost: {}").format(r.text)))
raise Exception(smart_text(_("Error sending notification mattermost: {}").format(r.status_code)))
sent_messages += 1
return sent_messages

View File

@@ -46,9 +46,9 @@ class RocketChatBackend(AWXBaseEmailBackend, CustomNotificationBase):
if r.status_code >= 400:
logger.error(smart_text(
_("Error sending notification rocket.chat: {}").format(r.text)))
_("Error sending notification rocket.chat: {}").format(r.status_code)))
if not self.fail_silently:
raise Exception(smart_text(
_("Error sending notification rocket.chat: {}").format(r.text)))
_("Error sending notification rocket.chat: {}").format(r.status_code)))
sent_messages += 1
return sent_messages

View File

@@ -57,6 +57,7 @@ class WebhookBackend(AWXBaseEmailBackend, CustomNotificationBase):
def send_messages(self, messages):
sent_messages = 0
self.headers['Content-Type'] = 'application/json'
if 'User-Agent' not in self.headers:
self.headers['User-Agent'] = "Tower {}".format(get_awx_version())
if self.http_method.lower() not in ['put','post']:
@@ -68,12 +69,12 @@ class WebhookBackend(AWXBaseEmailBackend, CustomNotificationBase):
auth = (self.username, self.password)
r = chosen_method("{}".format(m.recipients()[0]),
auth=auth,
json=m.body,
data=json.dumps(m.body, ensure_ascii=False).encode('utf-8'),
headers=self.headers,
verify=(not self.disable_ssl_verification))
if r.status_code >= 400:
logger.error(smart_text(_("Error sending notification webhook: {}").format(r.text)))
logger.error(smart_text(_("Error sending notification webhook: {}").format(r.status_code)))
if not self.fail_silently:
raise Exception(smart_text(_("Error sending notification webhook: {}").format(r.text)))
raise Exception(smart_text(_("Error sending notification webhook: {}").format(r.status_code)))
sent_messages += 1
return sent_messages

View File

@@ -1,8 +1,6 @@
import re
import urllib.parse as urlparse
from django.conf import settings
REPLACE_STR = '$encrypted$'
@@ -12,12 +10,6 @@ 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]
if settings.FALLBACK_GALAXY_SERVERS:
exclude_list += [server['url'] for server in settings.FALLBACK_GALAXY_SERVERS]
redactedtext = cleartext
text_index = 0
while True:
@@ -25,10 +17,6 @@ class UriCleaner(object):
if not match:
break
uri_str = match.group(1)
# Do not redact items from the exclude list
if any(uri_str.startswith(exclude_uri) for exclude_uri in exclude_list):
text_index = match.start() + len(uri_str)
continue
try:
# May raise a ValueError if invalid URI for one reason or another
o = urlparse.urlsplit(uri_str)

View File

@@ -12,6 +12,24 @@ from awx.main.utils.common import parse_yaml_or_json
logger = logging.getLogger('awx.main.scheduler')
def deepmerge(a, b):
"""
Merge dict structures and return the result.
>>> a = {'first': {'all_rows': {'pass': 'dog', 'number': '1'}}}
>>> b = {'first': {'all_rows': {'fail': 'cat', 'number': '5'}}}
>>> import pprint; pprint.pprint(deepmerge(a, b))
{'first': {'all_rows': {'fail': 'cat', 'number': '5', 'pass': 'dog'}}}
"""
if isinstance(a, dict) and isinstance(b, dict):
return dict([(k, deepmerge(a.get(k), b.get(k)))
for k in set(a.keys()).union(b.keys())])
elif b is None:
return a
else:
return b
class PodManager(object):
def __init__(self, task=None):
@@ -128,11 +146,13 @@ class PodManager(object):
pod_spec = {**default_pod_spec, **pod_spec_override}
if self.task:
pod_spec['metadata']['name'] = self.pod_name
pod_spec['metadata']['labels'] = {
'ansible-awx': settings.INSTALL_UUID,
'ansible-awx-job-id': str(self.task.id)
}
pod_spec['metadata'] = deepmerge(
pod_spec.get('metadata', {}),
dict(name=self.pod_name,
labels={
'ansible-awx': settings.INSTALL_UUID,
'ansible-awx-job-id': str(self.task.id)
}))
pod_spec['spec']['containers'][0]['name'] = self.pod_name
return pod_spec

View File

@@ -7,15 +7,20 @@ import logging
import uuid
import json
import random
from types import SimpleNamespace
# Django
from django.db import transaction, connection
from django.utils.translation import ugettext_lazy as _, gettext_noop
from django.utils.timezone import now as tz_now
from django.conf import settings
from django.db.models import Q
# AWX
from awx.main.dispatch.reaper import reap_job
from awx.main.models import (
AdHocCommand,
Instance,
InstanceGroup,
InventorySource,
InventoryUpdate,
@@ -42,11 +47,46 @@ logger = logging.getLogger('awx.main.scheduler')
class TaskManager():
def __init__(self):
'''
Do NOT put database queries or other potentially expensive operations
in the task manager init. The task manager object is created every time a
job is created, transitions state, and every 30 seconds on each tower node.
More often then not, the object is destroyed quickly because the NOOP case is hit.
The NOOP case is short-circuit logic. If the task manager realizes that another instance
of the task manager is already running, then it short-circuits and decides not to run.
'''
self.graph = dict()
# start task limit indicates how many pending jobs can be started on this
# .schedule() run. Starting jobs is expensive, and there is code in place to reap
# the task manager after 5 minutes. At scale, the task manager can easily take more than
# 5 minutes to start pending jobs. If this limit is reached, pending jobs
# will no longer be started and will be started on the next task manager cycle.
self.start_task_limit = settings.START_TASK_LIMIT
def after_lock_init(self):
'''
Init AFTER we know this instance of the task manager will run because the lock is acquired.
'''
instances = Instance.objects.filter(~Q(hostname=None), capacity__gt=0, enabled=True)
self.real_instances = {i.hostname: i for i in instances}
instances_partial = [SimpleNamespace(obj=instance,
remaining_capacity=instance.remaining_capacity,
capacity=instance.capacity,
jobs_running=instance.jobs_running,
hostname=instance.hostname) for instance in instances]
instances_by_hostname = {i.hostname: i for i in instances_partial}
for rampart_group in InstanceGroup.objects.prefetch_related('instances'):
self.graph[rampart_group.name] = dict(graph=DependencyGraph(rampart_group.name),
capacity_total=rampart_group.capacity,
consumed_capacity=0)
consumed_capacity=0,
instances=[])
for instance in rampart_group.instances.filter(capacity__gt=0, enabled=True).order_by('hostname'):
if instance.hostname in instances_by_hostname:
self.graph[rampart_group.name]['instances'].append(instances_by_hostname[instance.hostname])
def is_job_blocked(self, task):
# TODO: I'm not happy with this, I think blocking behavior should be decided outside of the dependency graph
@@ -187,6 +227,10 @@ class TaskManager():
return result
def start_task(self, task, rampart_group, dependent_tasks=None, instance=None):
self.start_task_limit -= 1
if self.start_task_limit == 0:
# schedule another run immediately after this task manager
schedule_task_manager()
from awx.main.tasks import handle_work_error, handle_work_success
dependent_tasks = dependent_tasks or []
@@ -241,7 +285,7 @@ class TaskManager():
for group in InstanceGroup.objects.all():
if group.is_containerized or group.controller_id:
continue
match = group.fit_task_to_most_remaining_capacity_instance(task)
match = group.fit_task_to_most_remaining_capacity_instance(task, group.instances.all())
if match:
break
task.instance_group = rampart_group
@@ -446,12 +490,13 @@ class TaskManager():
def process_pending_tasks(self, pending_tasks):
running_workflow_templates = set([wf.unified_job_template_id for wf in self.get_running_workflow_jobs()])
for task in pending_tasks:
if self.start_task_limit <= 0:
break
if self.is_job_blocked(task):
logger.debug("{} is blocked from running".format(task.log_format))
continue
preferred_instance_groups = task.preferred_instance_groups
found_acceptable_queue = False
idle_instance_that_fits = None
if isinstance(task, WorkflowJob):
if task.unified_job_template_id in running_workflow_templates:
if not task.allow_simultaneous:
@@ -468,24 +513,24 @@ class TaskManager():
found_acceptable_queue = True
break
if idle_instance_that_fits is None:
idle_instance_that_fits = rampart_group.find_largest_idle_instance()
remaining_capacity = self.get_remaining_capacity(rampart_group.name)
if not rampart_group.is_containerized and self.get_remaining_capacity(rampart_group.name) <= 0:
logger.debug("Skipping group {}, remaining_capacity {} <= 0".format(
rampart_group.name, remaining_capacity))
continue
execution_instance = rampart_group.fit_task_to_most_remaining_capacity_instance(task)
if execution_instance:
logger.debug("Starting {} in group {} instance {} (remaining_capacity={})".format(
task.log_format, rampart_group.name, execution_instance.hostname, remaining_capacity))
elif not execution_instance and idle_instance_that_fits:
execution_instance = InstanceGroup.fit_task_to_most_remaining_capacity_instance(task, self.graph[rampart_group.name]['instances']) or \
InstanceGroup.find_largest_idle_instance(self.graph[rampart_group.name]['instances'])
if execution_instance or rampart_group.is_containerized:
if not rampart_group.is_containerized:
execution_instance = idle_instance_that_fits
execution_instance.remaining_capacity = max(0, execution_instance.remaining_capacity - task.task_impact)
execution_instance.jobs_running += 1
logger.debug("Starting {} in group {} instance {} (remaining_capacity={})".format(
task.log_format, rampart_group.name, execution_instance.hostname, remaining_capacity))
if execution_instance or rampart_group.is_containerized:
if execution_instance:
execution_instance = self.real_instances[execution_instance.hostname]
self.graph[rampart_group.name]['graph'].add_job(task)
self.start_task(task, rampart_group, task.get_jobs_fail_chain(), execution_instance)
found_acceptable_queue = True
@@ -515,6 +560,20 @@ class TaskManager():
task.job_explanation = timeout_message
task.save(update_fields=['status', 'job_explanation', 'timed_out'])
def reap_jobs_from_orphaned_instances(self):
# discover jobs that are in running state but aren't on an execution node
# that we know about; this is a fairly rare event, but it can occur if you,
# for example, SQL backup an awx install with running jobs and restore it
# elsewhere
for j in UnifiedJob.objects.filter(
status__in=['pending', 'waiting', 'running'],
).exclude(
execution_node__in=Instance.objects.values_list('hostname', flat=True)
):
if j.execution_node and not j.is_containerized:
logger.error(f'{j.execution_node} is not a registered instance; reaping {j.log_format}')
reap_job(j, 'failed')
def calculate_capacity_consumed(self, tasks):
self.graph = InstanceGroup.objects.capacity_values(tasks=tasks, graph=self.graph)
@@ -543,6 +602,9 @@ class TaskManager():
def _schedule(self):
finished_wfjs = []
all_sorted_tasks = self.get_tasks()
self.after_lock_init()
if len(all_sorted_tasks) > 0:
# TODO: Deal with
# latest_project_updates = self.get_latest_project_update_tasks(all_sorted_tasks)
@@ -567,6 +629,7 @@ class TaskManager():
self.spawn_workflow_graph_jobs(running_workflow_tasks)
self.timeout_approval_node()
self.reap_jobs_from_orphaned_instances()
self.process_tasks(all_sorted_tasks)
return finished_wfjs

Some files were not shown because too many files have changed in this diff Show More