Compare commits

..

1979 Commits
6.0.0 ... 8.0.0

Author SHA1 Message Date
softwarefactory-project-zuul[bot]
3277d3afe0 Merge pull request #5050 from ryanpetrello/release-8.0.0
Bump VERSION to 8.0.0

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-21 17:26:33 +00:00
Ryan Petrello
45136b6503 Bump VERSION to 8.0.0 2019-10-21 12:29:24 -04:00
Ryan Petrello
e9af6af97c Merge pull request #5047 from ryanpetrello/devel
merge a variety of downstream bug fixes
2019-10-21 12:27:54 -04:00
Ryan Petrello
f86d647571 Merge branch 'hardening' into devel 2019-10-21 12:09:27 -04:00
Ryan Petrello
f02357ca16 Merge pull request #3871 from mabashian/3865-add-buttons
Revert 6282b5bacb
2019-10-21 12:08:52 -04:00
mabashian
e64b087e9f Revert 6282b5bacb 2019-10-21 11:55:12 -04:00
Ryan Petrello
5bb7e69a4d Merge pull request #3864 from ansible/container-launch-error
when isolated or container jobs fail to launch, set job status to error
2019-10-21 11:18:04 -04:00
Ryan Petrello
a8aed53c10 when isolated or container jobs fail to launch, set job status to error
a status of error makes more sense, because failed generally points to
an issue with the playbook itself, while error is more generally used
for reporting issues internal to Tower

see: https://github.com/ansible/awx/issues/4909
2019-10-21 11:02:31 -04:00
Jake McDermott
b19539069c Merge pull request #3863 from jakemcdermott/fix-3578-part-3
Set omitted runner_on_start event line lengths to 0
2019-10-21 10:37:09 -04:00
Jake McDermott
312cf13777 Set omitted runner event line lengths to 0
runner_on_start events have zero-length strings for their stdout
fields. We don't want to display these in the ui so we omit them.
Although the stdout field is an empty string, it still has a recorded
line length of 1 that we must account for. Since we're not rendering
the blank line, we must also go back and set the event record's line
length to 0 in order to avoid deleting too many lines when we pop or
shift events off of the view while scrolling.
2019-10-19 19:18:45 -04:00
Jake McDermott
c6033399d0 Fix off-by-one errors 2019-10-19 18:58:42 -04:00
Ryan Petrello
85f118c17d Merge pull request #3852 from ansible/pod-reaper
implement a simple periodic pod reaper for container groups
2019-10-18 16:50:30 -04:00
softwarefactory-project-zuul[bot]
0de805ac67 Merge pull request #5035 from keithjgrant/4617-inventory-lookup-error-message
Add error messages for InventorySelect

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-18 19:46:29 +00:00
Ryan Petrello
c7426fbff4 Merge pull request #3861 from wenottingham/where-did-you-come-from
Log the remote IP for logged in users
2019-10-18 15:16:34 -04:00
softwarefactory-project-zuul[bot]
3cbd52a56e Merge pull request #5040 from keithjgrant/4976-job-list-status-icons
Add status icon to job list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-18 19:12:14 +00:00
Jake McDermott
97a635ef49 Merge pull request #3844 from jakemcdermott/fix-3578-part-1
Always disable search when processing events
2019-10-18 15:07:41 -04:00
Keith Grant
155ed75f15 update jt Inventory field error message 2019-10-18 11:38:01 -07:00
Bill Nottingham
a664c5eabe Log the remote IP for logged in users 2019-10-18 14:28:10 -04:00
Keith Grant
8b23c6e19a add job id to jobs list 2019-10-18 10:44:39 -07:00
Keith Grant
a5d9bbb1e6 add status icon to job list 2019-10-18 10:08:59 -07:00
softwarefactory-project-zuul[bot]
c262df0dfe Merge pull request #5009 from wanderboessenkool/rabbit-healthcheck-cpu-usage
Change 'rabbitmqctl status' to a wget | grep to save CPU

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-18 16:48:39 +00:00
Jake McDermott
3f113129a9 Merge pull request #3851 from jakemcdermott/fix-3578-part-2
Get the last two pages of events on page load
2019-10-18 12:46:19 -04:00
Keith Grant
df7e034b96 fix blur behavior/error messages in JT form 2019-10-18 08:40:48 -07:00
Ryan Petrello
bd8b3a4f74 Merge pull request #3856 from ansible/revert-3842-callback-receiver-status
Revert "add support for `awx-manage run_callback_receiver --status`"
2019-10-18 10:10:58 -04:00
Ryan Petrello
d01088d33e Revert "add support for awx-manage run_callback_receiver --status" 2019-10-18 09:49:02 -04:00
Ryan Petrello
0012602b30 Merge pull request #3853 from ansible/fix-upgrades
properly migrate the CyberArk AIM type to its new name
2019-10-18 07:55:20 -04:00
Wander Boessenkool
8ecc1f37f0 Move python healthcheck script from probes to configMap 2019-10-18 10:15:21 +02:00
Ryan Petrello
0ab44e70f9 properly migrate the CyberArk AIM type to its new name 2019-10-17 22:40:33 -04:00
Jake McDermott
95c9e8e068 Always disable search when processing events
When jobs are still processing events, the UI uses numerical ranges
based on job_event.counter instead of page numbers. We can't apply
search filters in this state because then there would be no way to
distinguish between events that are missing due to being filtered out
by search and events that are missing because they're still being
processed.

The UI must be able to distinguish between the two types of missing
events because their absence is presented differently. Events that are
filtered out by a search query have no visual representation, while
events that are missing due to event processing or other causes are
displayed as clickable "..." segments.
2019-10-17 18:37:33 -04:00
Wander Boessenkool
c49e64e62c Make HTTPConnection import python 2,3 agnostic 2019-10-17 23:36:33 +02:00
Wander Boessenkool
00c9d756e8 Move installtime hardcoded rabbitmq credentials to environment variables for healthcheck 2019-10-17 23:23:29 +02:00
Ryan Petrello
16812542f8 implement a simple periodic pod reaper for container groups
see: https://github.com/ansible/awx/issues/4911
2019-10-17 17:06:36 -04:00
Ryan Petrello
0bcd1db239 Merge pull request #3850 from ansible/container-groups-cleanup-adhoc
clean up pods for all k8s execution, not just playbook runs
2019-10-17 16:53:23 -04:00
Bill Nottingham
9edbcdc7b0 Merge pull request #3848 from wenottingham/have-never-read-or-watched-the-help
Adjust description/help text for profiling features.
2019-10-17 16:48:12 -04:00
Wander Boessenkool
9ab58e9757 Change healthcheck from wget and grep to python with httplib 2019-10-17 22:25:20 +02:00
Jake McDermott
1fae3534a1 Get the last two pages of events on page load
When the page loads, we want to retrieve and initially display enough
content for the scrollbar to show. If the very last page doesn't
have enough content for the scrollbar to show, the user won't be able
to scroll up to see more job history. To avoid this scenario, we always
fetch the last _two_ pages when loading the view.
2019-10-17 16:19:19 -04:00
Graham Mainwaring
a038f9fd78 Merge pull request #3845 from ghjm/gather_analytics_dry_run
Add a --dry-run option to gather analytics locally, even if analytics is disabled in settings.
2019-10-17 16:17:18 -04:00
Ryan Petrello
ff1e1b2010 Merge pull request #3849 from ansible/k8s-native-execution-node
properly set execution_node for project and inv updates run "in k8s"
2019-10-17 16:06:16 -04:00
Wander Boessenkool
d6134fb194 Change /bin/ash to /bin/sh as requested by @shanecmd 2019-10-17 21:37:51 +02:00
Ryan Petrello
570ffad52b clean up pods for all k8s execution, not just playbook runs
see: https://github.com/ansible/awx/issues/4908
2019-10-17 15:29:44 -04:00
Ryan Petrello
1cf02e1e17 properly set execution_node for project and inv updates run "in k8s"
see: https://github.com/ansible/awx/issues/4907
2019-10-17 15:15:24 -04:00
Bill Nottingham
2f350cfda7 Adjust description/help text for profiling features.
Note that data is merely for sosreport collection for now, and
warn against increasing collection frequency.
2019-10-17 15:04:21 -04:00
Keith Grant
8e2622d117 add error messages for InventorySelect 2019-10-17 10:55:37 -07:00
Graham Mainwaring
7dd241fcff Add a --dry-run option to gather analytics locally, even if analytics is disabled in settings. 2019-10-17 13:54:13 -04:00
Ryan Petrello
c6a28756f2 Merge pull request #3841 from ansible/fix-5028
fix a 500 error when creating/editing notification templates
2019-10-17 12:06:36 -04:00
Ryan Petrello
94eb1aacb8 Merge pull request #3842 from ansible/callback-receiver-status
add support for `awx-manage run_callback_receiver --status`
2019-10-17 11:46:27 -04:00
Ryan Petrello
ffb1707e74 add support for awx-manage run_callback_receiver --status 2019-10-17 11:10:27 -04:00
Ryan Petrello
5e797a5ad5 Merge pull request #3840 from ansible/fix-5029
fix a minor bug in the notification templates UI
2019-10-17 10:33:34 -04:00
Ryan Petrello
4c92e0af77 fix a 500 error when creating/editing notification templates
see: https://github.com/ansible/awx/issues/5028
2019-10-17 08:53:01 -04:00
Ryan Petrello
24b9a6a38d fix a minor bug in the notification templates UI
see: https://github.com/ansible/awx/issues/5029
2019-10-17 08:43:04 -04:00
softwarefactory-project-zuul[bot]
857683e548 Merge pull request #4917 from jakemcdermott/ui-next-ci
Tune webpack config and add Dockerfile

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-16 22:29:58 +00:00
softwarefactory-project-zuul[bot]
4bf96362cc Merge pull request #5018 from ryanpetrello/cli-deprecation-warnings
warn about endpoint deprecation in the CLI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-16 20:37:29 +00:00
Ryan Petrello
5001d3158d Merge pull request #3837 from ansible/rename-cyberark-aim
rename the CyberArk AIM credential type
2019-10-16 16:12:58 -04:00
Ryan Petrello
ce5bb9197e rename the CyberArk AIM credential type
see: https://github.com/ansible/awx/issues/4400
2019-10-16 15:58:35 -04:00
Ryan Petrello
309e89e0f0 Merge pull request #3813 from matburt/fix_smart_inventory_impact
Change host counting for task impact
2019-10-16 15:56:50 -04:00
Ryan Petrello
e27dbfcc0b Merge pull request #3836 from wenottingham/eeeeeeeeEEEEEEEEEEEEEEEEeeeeeeeeeenum
Remove removal requirement that isn't actually in the requirements
2019-10-16 15:35:31 -04:00
Bill Nottingham
7df448a348 Remove removal requirement that isn't actually in the requirements 2019-10-16 15:34:33 -04:00
Bill Nottingham
e220e9d8d7 Merge pull request #3834 from wenottingham/seriously-cut-it-out-google
Blacklist rsa even more.
2019-10-16 15:30:01 -04:00
Ryan Petrello
c8a29bac66 warn about endpoint deprecation in the CLI 2019-10-16 15:26:59 -04:00
Bill Nottingham
11d39bd8cc Blacklist rsa even more. 2019-10-16 15:17:19 -04:00
softwarefactory-project-zuul[bot]
1376b8a149 Merge pull request #5020 from ryanpetrello/devel
merge a variety of downstream bug fixes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-16 18:13:02 +00:00
Ryan Petrello
750208b2da Merge pull request #3831 from rooftopcellist/use_system_ca_for_collection
Make Analytics collections verify with system trusted CA
2019-10-16 13:55:07 -04:00
Christian Adams
9d81b00772 have analytics collections verify with system trusted CA list 2019-10-16 13:32:06 -04:00
Ryan Petrello
c7be94c2f2 Merge branch 'hardening' into devel 2019-10-16 13:15:20 -04:00
Ryan Petrello
1adf5ee51d Merge pull request #3805 from beeankha/cli_approval_notification_support
Enable Approval Notification Support for CLI
2019-10-16 13:09:22 -04:00
Ryan Petrello
da998fb196 Merge pull request #3828 from AlanCoding/deprecate_script
API deprecation of inventory script views
2019-10-16 11:27:41 -04:00
Ryan Petrello
b559860c78 Merge pull request #3804 from jbradberry/cli-no-truncate
Do not truncate job event list stdout when called from the CLI
2019-10-16 10:36:29 -04:00
Ryan Petrello
a31e2bdac1 Merge pull request #3829 from ansible/tz-fix
fix a tz parsing bug
2019-10-16 10:31:44 -04:00
beeankha
62e4ebb85d Minor change to README, plus a rebase. 2019-10-16 09:50:00 -04:00
beeankha
aa4f5ccca9 Add blank line (flake8) 2019-10-16 09:50:00 -04:00
beeankha
fdddba18be Update code to be compatible with py2 2019-10-16 09:50:00 -04:00
beeankha
ad89c5eea7 Enable approval notification support for CLI 2019-10-16 09:50:00 -04:00
Jake McDermott
e15bb4de44 Merge pull request #3827 from jakemcdermott/fix_flake8_error
Fix flake8 error
2019-10-16 09:47:57 -04:00
Ryan Petrello
5f2e1c9705 fix a tz parsing bug 2019-10-16 09:46:18 -04:00
Jake McDermott
8c5b0cbd57 Merge pull request #3815 from jakemcdermott/fix-3790
Allow navigation to previous launch prompt tabs
2019-10-16 09:36:54 -04:00
Jake McDermott
73272e338b Merge pull request #3809 from AlexSCorey/4944-4943-TOCBugs
Sys Aud can see CG forms, Adds correct CG form link, Disables CodeMirror
2019-10-16 09:35:02 -04:00
AlanCoding
86ef81cebf API deprecation of inventory script views 2019-10-16 09:34:21 -04:00
Jake McDermott
cd18ec408c Remove unused variable 2019-10-16 09:30:43 -04:00
Ryan Petrello
90c5efa336 Merge pull request #3824 from AlanCoding/one_less_redirect
Avoid unnecessary OPTIONS redirect
2019-10-16 09:17:03 -04:00
Alex Corey
4134d0b516 Updates PR and Addresses Console Error
THis commit imroves conditional rendering of the container groups form for
System Auditors.  It also removes a ng-class condition in the IG list that was unused.
2019-10-16 09:15:44 -04:00
AlanCoding
2123092bdc Avoid unnecessary OPTIONS redirect 2019-10-16 09:08:22 -04:00
softwarefactory-project-zuul[bot]
ba7b53b38e Merge pull request #4992 from keithjgrant/4817-react-router-upgrade
4817 react router upgrade

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-15 20:29:16 +00:00
Keith Grant
cac5417916 delete commented code 2019-10-15 12:56:39 -07:00
Keith Grant
b318f24490 don't skip JobDetail test now that async act works 2019-10-15 12:55:26 -07:00
Bill Nottingham
c2743d8678 Merge pull request #3802 from wenottingham/oh-noes-not-again
Check the user's ansible.cfg for role/collection paths.
2019-10-15 14:21:18 -04:00
Bill Nottingham
60ca843b71 Use logger.exception instead of logger.warning. 2019-10-15 14:20:09 -04:00
Keith Grant
766f863655 update ProjectDetails tests with memoryHistory 2019-10-15 11:11:44 -07:00
Seth Foster
e85fe6a3b7 Merge pull request #3807 from fosterseth/release_3.6.0
Allow oauth2 settings to be set in the ui and api
2019-10-15 13:40:25 -04:00
Keith Grant
0b190c2d0d fix login/logout redirect behavior 2019-10-15 10:25:40 -07:00
Keith Grant
c7d73c4583 lint fixes 2019-10-15 10:25:40 -07:00
Keith Grant
7ad2c03480 clean up 'act()' warnings in tests 2019-10-15 10:25:40 -07:00
Keith Grant
9e44fea7b5 bump react to lastest patch version 2019-10-15 10:25:40 -07:00
Keith Grant
baf5bbc53a finish updating tests for upgraded react-router 2019-10-15 10:25:40 -07:00
Keith Grant
20c24eb275 WIP upgrade react & react-router 2019-10-15 10:25:40 -07:00
Alex Corey
5cf84ddb60 Sys Aud can see CG forms, Adds correct CG form link, Disables CodeMirror
This allows the System Auditor to see the container groups form in a disabled state.
If the pod_spec_override has been changed that field will be open when the page renders
but it will be disabled. It also greys out all code mirror text area fields for System Auditor.
It adds the correct url for the Container Groups message bar to inform users of possible
pitfalls associated with that feature.
2019-10-15 10:47:04 -04:00
Jake McDermott
85781d0bc1 Allow navigation to previous launch prompt tabs 2019-10-14 17:07:50 -04:00
softwarefactory-project-zuul[bot]
cbed525547 Merge pull request #4965 from marshmalien/project-detail
Add project detail and unit tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-14 18:30:30 +00:00
Michael Abashian
31c14b005c Merge pull request #3816 from ansible/4945-wfjt-responsivity-styles
Fix workflow results detail panel responsive style
2019-10-14 14:28:38 -04:00
Michael Abashian
7574541037 Merge pull request #3814 from ansible/4846-wfjt-notifications-placeholder
Style empty list placeholder text inline
2019-10-14 14:28:03 -04:00
Marliana Lara
e5184e0ed1 Fix workflow results detail panel responsive style 2019-10-14 13:50:59 -04:00
Marliana Lara
6282b5bacb Style empty list placeholder text inline 2019-10-14 13:11:31 -04:00
Wander Boessenkool
038fd9271d Properly escape quotes 2019-10-14 17:53:28 +02:00
Seth Foster
8e26e4edd5 Allow oauth2 settings to be set in the ui and api
Oauth2 settings were initialized early in the awx import stage, and
those settings were not modifiable. This change allows oauth2 to check
for settings in django.conf settings, which are dynamically updated
through api calls at runtime. As a result, oauth2 settings will match
the values in django.conf settings at any point in time.
2019-10-14 11:38:20 -04:00
softwarefactory-project-zuul[bot]
027e79b7f5 Merge pull request #5006 from keithjgrant/4550-searchbar-no-results
Retain search bar when zero results found

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-14 15:31:55 +00:00
Jeff Bradberry
cf89108edf Force the CLI to use no_truncate for the monitor calls 2019-10-14 11:21:11 -04:00
Matthew
e06bf9f87e Change host counting for task impact
Go through the job -> inventory module linkage to calculate the hosts for a more accurate view
of the number of hosts that could be impacted. This also creates a bailout that will set count
hosts to the forks rather than assuming some crazy low number in the case where we can't determine
the actual number of hosts because we are missing the inventory
2019-10-14 10:41:21 -04:00
Wander Boessenkool
e87055095c Change 'rabbitmqctl status' to a wget | grep
- This reduces CPU usage from 250 millis on idle to 25 millis on idle
- Default rabbitmq user needs administrator privileges
2019-10-14 14:53:53 +02:00
Jeff Bradberry
e672e68a02 Allow the job event list views to take a no_truncate GET param 2019-10-11 17:18:36 -04:00
Graham Mainwaring
263c44a09b Merge pull request #3808 from ghjm/workflow_approved_by
Add approved_by field to workflow approvals
2019-10-11 17:00:54 -04:00
Graham Mainwaring
08839e1381 Add approved_by field to workflow approvals 2019-10-11 16:57:13 -04:00
Keith Grant
faffbc3e65 retain search bar when zero results found 2019-10-11 12:11:41 -07:00
Alan Rominger
8e296bbf8c Merge pull request #3796 from AlanCoding/inventory_fq_36
use fully qualified inventory plugin name
2019-10-11 06:56:13 -04:00
Jake McDermott
03d59e1616 Tune webpack config and add Dockerfile
Add Dockerfile for running containerized dev server. Update webpack
config to make dev server available over exposed docker port.
2019-10-10 17:37:27 -04:00
Jeff Bradberry
9efa7b84df Depend on a serializer context variable no_truncate
to decide whether to turn off the ANSI control sequence-aware
truncation, instead of needing inappropriate awareness of the details
of the view that invoked the serializer.  This will also allow us to
have views that can more flexibly turn off the truncation under other
circumstances.
2019-10-10 16:08:17 -04:00
Ryan Petrello
8e1f7695b1 Merge pull request #3803 from ansible/back-to-pending
Prevent pods from failing if the reason is because of a resource quota
2019-10-10 16:08:08 -04:00
Ryan Petrello
d6adab576f Merge pull request #3800 from ansible/update-vmware-inv-script
update to latest vmware_inventory.py
2019-10-10 16:07:31 -04:00
Jeff Bradberry
a803cedd7c Break out a new reusable truncate_stdout utility function 2019-10-10 16:07:08 -04:00
Ryan Petrello
d5bdf554f1 fix a programming error when k8s pods fail to launch 2019-10-10 15:54:00 -04:00
Shane McDonald
8f75382b81 Implement retry logic for container group pod launches 2019-10-10 15:53:56 -04:00
Shane McDonald
b93164e1ed Prevent pods from failing if the reason is because of a resource quota
Signed-off-by: Shane McDonald <me@shanemcd.com>
2019-10-10 15:53:50 -04:00
Bill Nottingham
31bdde00c9 Check the user's ansible.cfg for role/collection paths.
There's no other way to add our new paths reliably without breaking things.
2019-10-10 15:09:26 -04:00
Ryan Petrello
ed52e8348b Merge pull request #3799 from ansible/log-audit-note
add a note about settings.LOG_AGGREGATOR_AUDIT usage
2019-10-10 11:32:34 -04:00
Ryan Petrello
008fe42b4d update to latest vmware_inventory.py
06c7b87613/contrib/inventory/vmware_inventory.py
2019-10-10 10:49:15 -04:00
Ryan Petrello
d9dbbe6748 add a note about settings.LOG_AGGREGATOR_AUDIT usage
see: https://github.com/ansible/awx/pull/4872#issuecomment-540133448
2019-10-10 10:44:23 -04:00
AlanCoding
16ebfe3a63 use fully qualified inventory plugin name 2019-10-10 08:51:18 -04:00
softwarefactory-project-zuul[bot]
08df2cad68 Merge pull request #4974 from jakemcdermott/switch-default-job-panel
Switch default job panel to output

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-10-10 04:24:04 +00:00
softwarefactory-project-zuul[bot]
ca039f5338 Merge pull request #4957 from jakemcdermott/webhooks-labels
Use consistent wording for JT options

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-10 02:44:16 +00:00
Marliana Lara
4b83bda306 Wrap phrase for translation and update test 2019-10-09 22:24:50 -04:00
Marliana Lara
7fc4e8d20a Add project detail and unit tests 2019-10-09 22:24:49 -04:00
softwarefactory-project-zuul[bot]
4c697ae477 Merge pull request #4905 from rooftopcellist/collection_frequency
Update Frequency of Collection for Automation Analytics

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-10 02:22:51 +00:00
Christian Adams
844b8a803f update frequency of collection for automation analytics 2019-10-09 21:10:48 -04:00
Ryan Petrello
7fe32ab607 Merge pull request #4868 from rebeccahhh/survey-spec-default
Sanitize newlines out of survey option inputs
2019-10-09 21:09:33 -04:00
Ryan Petrello
cc27c95187 Merge pull request #4872 from ryanpetrello/log-aggregration-auditing
add a settings flag for writing all external logs to disk
2019-10-09 21:09:19 -04:00
softwarefactory-project-zuul[bot]
9745bfbdb4 Merge pull request #4931 from austlane/devel
Requirements.txt: Upgrade bundled pyvmomi to 6.7.3

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-10 00:20:50 +00:00
Austin
d6708b2b59 Upgrade bundled pyvmomi to 6.7.3
Fixes issues with vmware_guest_facts expecting version 6.7.1 or greater (JSON support)
2019-10-09 14:45:00 -04:00
Jake McDermott
c202574ae3 Switch default job panel to output 2019-10-09 14:31:44 -04:00
Rebeccah
7efacb69aa added in parsing for multiple choice and multiselect, which either takes a string, splits it up, and then eliminates any extra newlines, or just accepts alist. Extra newlines are sanitized out.
Signed-off-by: Rebeccah <rhunter@redhat.com>
2019-10-09 13:59:32 -04:00
Ryan Petrello
a076e84a33 add a settings flag for writing all external logs to disk 2019-10-09 13:54:54 -04:00
Jake McDermott
bc6648b518 Use consistent wording for JT options 2019-10-09 13:22:40 -04:00
softwarefactory-project-zuul[bot]
ff67d65065 Merge pull request #4932 from jakemcdermott/combine-lint-and-test
Add targets for combined lint and test

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 15:50:22 +00:00
softwarefactory-project-zuul[bot]
aab8495998 Merge pull request #4939 from AlanCoding/no_warning
Get rid of warning in collections install

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 15:19:28 +00:00
softwarefactory-project-zuul[bot]
0f1a92bd51 Merge pull request #4589 from AlanCoding/mah_galaxy
Allow use of user-specified private galaxy server with fallback

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 15:01:12 +00:00
softwarefactory-project-zuul[bot]
f10dc16014 Merge pull request #4921 from ryanpetrello/ryan-broke-it
fix a bug that breaks inventory update stdout when used in a workflow

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 14:50:52 +00:00
softwarefactory-project-zuul[bot]
bbc4ec48b9 Merge pull request #4933 from beeankha/org_notification_fix
Org-Level Notification Fix + Show URL 

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 14:25:43 +00:00
softwarefactory-project-zuul[bot]
fff8664219 Merge pull request #4941 from mabashian/3727-output-scroll
Removes restriction on scrolling for output fewer than 50 lines

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 13:46:46 +00:00
softwarefactory-project-zuul[bot]
bc8f5ad015 Merge pull request #4929 from mabashian/ui-next-inventories
Adds basic inventory list and scaffolding for inv/smart inv details and related tabs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 13:46:43 +00:00
softwarefactory-project-zuul[bot]
9fade47bbf Merge pull request #4937 from Spredzy/fix_svn_project_sync
project_update: Make subversion module honor locale

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-09 13:40:26 +00:00
softwarefactory-project-zuul[bot]
5ad922a861 Merge pull request #4938 from jakemcdermott/fix-missing-iso
Use summary_fields.controller_id to tell if job is isolated

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-08 20:18:03 +00:00
mabashian
f34bd632d8 Adds unit test coverage for add button rbac on several lists 2019-10-08 16:10:55 -04:00
mabashian
d239d55d2a Failed delete string pluralization 2019-10-08 15:15:13 -04:00
mabashian
d9ad906167 Adds basic inventory list and scaffolding for inv/smart inv details+related tabs 2019-10-08 15:09:32 -04:00
AlanCoding
d40ab38745 Get rid of warning in collections install 2019-10-08 14:19:52 -04:00
mabashian
8acd4376d9 Removes restriction on scrolling for output fewer than 50 lines 2019-10-08 14:15:25 -04:00
Jake McDermott
a7a194296c Use summary_fields.controller_id to tell if job is isolated 2019-10-08 12:08:23 -04:00
Yanis Guenane
166635ac79 project_update: Make subversion module honor locale
Currently the subversion module does not honor system configured locale
as the module itself overrides them to `C`.

This commit enforces the module to honor the `LANG` locale for
deployment. Allowing project update with repo that contains UTF-8
characters.

Closes: https://github.com/ansible/awx/issues/4936
Signed-off-by: Yanis Guenane <yguenane@redhat.com>
2019-10-08 17:54:53 +02:00
AlanCoding
f10296b1b7 Revert "bump required version to 2.10"
This reverts commit e0e9c8321b.
2019-10-08 11:20:57 -04:00
AlanCoding
e0e9c8321b bump required version to 2.10 2019-10-08 11:00:57 -04:00
softwarefactory-project-zuul[bot]
52b145dbf6 Merge pull request #4930 from mabashian/4889-number-input-scroll
Prevent usage of mousewheel on spinner elements

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-08 14:25:07 +00:00
AlanCoding
0594bdf650 Add more galaxy server param validation 2019-10-07 20:03:40 -04:00
softwarefactory-project-zuul[bot]
ba9758ccc7 Merge pull request #4915 from jakemcdermott/fix-template-load-error
Gracefully handle missing template summary fields 

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-07 19:35:40 +00:00
beeankha
02b13fd4ae Enable notifications to send at org level, ...
... and list the URL in body of approval notification messages.
2019-10-07 15:34:09 -04:00
AlanCoding
06c62c4861 update docs for galaxy auth URL material 2019-10-07 14:52:10 -04:00
Jake McDermott
132555485c Add targets for combined lint and test
Reduce the total number of simultaneous zuul jobs.
2019-10-07 14:49:18 -04:00
softwarefactory-project-zuul[bot]
f1a9e68985 Merge pull request #4928 from saito-hideki/issue/4749
Fixed missing user-id in URL links when adding users to Team and Org …

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-07 18:32:19 +00:00
AlanCoding
c09039e963 Add setting for auth_url
Also adjust public galaxy URL setting to
allow using only the primary Galaxy server

Include auth_url in token exclusivity validation
2019-10-07 14:02:43 -04:00
AlanCoding
85c99cc38a Redact env vars for Galaxy token or password 2019-10-07 14:02:43 -04:00
AlanCoding
576ff1007e Describe usage of primary galaxy server in docs 2019-10-07 14:02:43 -04:00
AlanCoding
922e779a86 Rename private to primary in galaxy settings
use a setting for the public galaxy URL
2019-10-07 14:02:43 -04:00
AlanCoding
8bda048e6d validate galaxy server settings
involves some changes to the redact code
2019-10-07 14:02:42 -04:00
AlanCoding
093bf6877b Finish adding settings to UI 2019-10-07 14:02:42 -04:00
AlanCoding
d59d8562db Avoid redacting Galaxy URLs 2019-10-07 14:02:42 -04:00
AlanCoding
c566c332f9 Initial env var implementation of private galaxy server 2019-10-07 14:02:42 -04:00
mabashian
cb4a3a799e Prevent usage of mousewheel on spinner elements 2019-10-07 11:28:51 -04:00
softwarefactory-project-zuul[bot]
5a5b46aea0 Merge pull request #4903 from jakemcdermott/add-output-for-all-job-types
Make job output panel work with all job types

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-07 15:17:53 +00:00
Jake McDermott
85909c4264 Gracefully handle missing summary fields
Not all templates have `modified_by`, `created_by` fields or
other summary_fields. Avoid page load error by only referencing these
fields if they exist.
2019-10-07 10:57:56 -04:00
softwarefactory-project-zuul[bot]
9d2c877143 Merge pull request #4913 from jakemcdermott/list-item-date-formatting
Add basic date formatter

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-07 14:27:39 +00:00
Hideki Saito
8e94c0686a Fixed missing user-id in URL links when adding users to Team and Org in modal
- Fixed issue #4749

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-10-07 09:47:29 +00:00
softwarefactory-project-zuul[bot]
52447f59c1 Merge pull request #4924 from ryanpetrello/runner-1-4-2
pin to runner==1.4.2

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-05 18:55:36 +00:00
Ryan Petrello
04eed02428 pin to runner==1.4.2 2019-10-04 17:11:34 -04:00
Ryan Petrello
b45b9333e1 Merge pull request #4716 from jladdjr/perf_stats
Enable collection of performance stats
2019-10-04 17:09:30 -04:00
softwarefactory-project-zuul[bot]
62659aefc2 Merge pull request #4189 from shanemcd/toc
Container Groups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-04 20:19:12 +00:00
softwarefactory-project-zuul[bot]
a52ccd1086 Merge pull request #4859 from mabashian/ui-next-projects
Add projects list and scaffolding for project details+tabs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-04 19:54:15 +00:00
Jim Ladd
bd9a196ef9 bump ansible-runner to 1.4.1 2019-10-04 12:48:29 -07:00
Ryan Petrello
64b04e6347 bump ansible-runner to 1.4.0 2019-10-04 12:48:29 -07:00
Jim Ladd
15e70d2173 Add tests for resource profiling 2019-10-04 12:48:29 -07:00
Keith Grant
b981f3eed6 add resource profiling toggle in jobs settings 2019-10-04 12:48:29 -07:00
Jim Ladd
2c1c2f452d Add libcgroup-tools to dev env (provides cgcreate, cgexec, etc) 2019-10-04 12:48:29 -07:00
Jim Ladd
cf1c9a0559 Add awx settings for resource profiling 2019-10-04 12:48:29 -07:00
Jim Ladd
ed3f49a69d Add support for calling runner with perf stats 2019-10-04 12:48:29 -07:00
Alex Corey
74b398f920 Add Tech Preview notice to Container Group UI
and some refactoring
2019-10-04 15:17:57 -04:00
Ryan Petrello
ae0c9ead40 fix a bug that breaks inventory update stdout when used in a workflow
see: https://github.com/ansible/awx/issues/4920
related: https://github.com/ansible/awx/pull/4731
2019-10-04 15:17:39 -04:00
mabashian
d6a0f929a8 Fix merge conflict fallout 2019-10-04 15:10:02 -04:00
softwarefactory-project-zuul[bot]
f5358f748e Merge pull request #4919 from ryanpetrello/jupyter-minus-minus
remove jupyter from supervisor in the dev env

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-04 19:07:47 +00:00
mabashian
c9e889ca82 Removes residual references to org from project list components. Assign IDs to project and jt related tabs after array has been finalized. 2019-10-04 15:06:06 -04:00
mabashian
f502fbfad6 Put project related tabs in the correct order 2019-10-04 15:06:06 -04:00
mabashian
b8fe3f648e Add projects list and scaffolding for project details+tabs 2019-10-04 15:06:06 -04:00
softwarefactory-project-zuul[bot]
8d3ecf708b Merge pull request #4856 from AlexSCorey/4247-ResponsveTemplateList
Makes template list Responsive

Reviewed-by: Alex Corey <Alex.swansboro@gmail.com>
             https://github.com/AlexSCorey
2019-10-04 18:50:24 +00:00
Alex Corey
9289ade1ec IG List responsiveness 2019-10-04 13:21:28 -04:00
Alex Corey
958c8a4177 Fixes Credential Type Issue, ExtraVars Toggle Issue, Job Results Inert Link 2019-10-04 13:21:28 -04:00
Shane McDonald
59413e0a8f Change default pod spec in OPTIONS request to json 2019-10-04 13:21:28 -04:00
Mat Wilson
ad1e7c46c3 add k8s cred type to awxkit 2019-10-04 13:21:28 -04:00
Alex Corey
8fabb1f10d Show override toggle as off when pod_spec matches default 2019-10-04 13:21:28 -04:00
Alex Corey
895c71f62c removes instances tab from CGs 2019-10-04 13:21:27 -04:00
Alex Corey
32a57e9a97 add default pod spec to edit 2019-10-04 13:21:27 -04:00
Alex Corey
584777e21e Adds Tabs to CGs 2019-10-04 13:21:27 -04:00
Jake McDermott
61a756c59d add is_containerized to ig serializer 2019-10-04 13:21:27 -04:00
Jake McDermott
b547a8c3ca link to container group from job runs 2019-10-04 13:21:27 -04:00
Alex Corey
007f33c186 Add Container Group Form Render and cred type modal pops up
modal render proper cred

WIP

modal rendering properly

card for edit CG renders, no fields

add code mirror and some list styling

address PR issues
2019-10-04 13:21:27 -04:00
Shane McDonald
aab1cd68b0 Fix InstanceGroup summary fields 2019-10-04 13:21:24 -04:00
Shane McDonald
92cc9a9213 Create separate Make target for cleaning API-related artifacts
My workflow for running tests is now:

```
$ docker exec -ti tools_awx_1 make clean-api awx-link test
```
2019-10-04 13:21:23 -04:00
Shane McDonald
b9c675e3a2 API documentation for container groups 2019-10-04 13:21:23 -04:00
Shane McDonald
bd5003ca98 Task manager / scheduler Kubernetes integration 2019-10-04 13:21:21 -04:00
Jake McDermott
d3b0edf75a Apply date formatter to lists and details 2019-10-04 13:17:15 -04:00
Jake McDermott
9421781cc7 Add basic date formatter 2019-10-04 13:16:42 -04:00
Shane McDonald
a9059edc65 Allow associating a credential with an instance group 2019-10-04 12:54:31 -04:00
Shane McDonald
7850e3a835 Ignore unison and emacs temporary files 2019-10-04 12:54:31 -04:00
Ryan Petrello
34d02011db remove jupyter from supervisor in the dev env
if you use this tool, just run `make jupyter`
2019-10-04 11:53:26 -04:00
softwarefactory-project-zuul[bot]
353692a0ba Merge pull request #4896 from mabashian/ui_next-notifs
Refactor notifications list and add it to JT details

Reviewed-by: Michael Abashian
             https://github.com/mabashian
2019-10-04 14:50:35 +00:00
mabashian
90451e551d Add notifications to the breadcrumb config for templates 2019-10-04 09:48:38 -04:00
mabashian
2457926f0a Refactor notifications list to be more generic. Hook notifictions tab up on JT details. 2019-10-04 09:48:38 -04:00
softwarefactory-project-zuul[bot]
cf27ac295a Merge pull request #4893 from wenottingham/we-will-not-present-you-for-confirmation
Remove text about confirming launch-time passwords.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-04 10:40:56 +00:00
Jim Ladd
7e40673dd0 Add docs for perf data collection 2019-10-03 23:54:00 -07:00
softwarefactory-project-zuul[bot]
daa6f35d02 Merge pull request #4914 from jladdjr/increase_instance_version_length
Increase instance version length

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-04 05:37:40 +00:00
Jim Ladd
cdcf2fa4c2 Increase instance version length 2019-10-03 21:24:07 -04:00
Jake McDermott
275765b8fc Refactor language utility
Move the language helper out of RootProvider and into a utilities
module so that it can be more easiliy reused where needed. In some
cases we want the full language code so that logic has been moved
into a separate function.
2019-10-03 20:26:47 -04:00
softwarefactory-project-zuul[bot]
2786395808 Merge pull request #4436 from jbradberry/webhook-receivers
Webhook receivers

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 22:23:22 +00:00
Jake McDermott
731982c736 Build correct job_event url for different job types 2019-10-03 16:27:02 -04:00
softwarefactory-project-zuul[bot]
d2214acd6d Merge pull request #4895 from rooftopcellist/rm_cruft
Remove unneeded debug statement

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 20:07:44 +00:00
Bill Nottingham
9d593f0715 Remove text about confirming launch-time passwords.
We haven't done confirmation on these for a long time.
2019-10-03 15:22:15 -04:00
softwarefactory-project-zuul[bot]
9e778b24c7 Merge pull request #4890 from rooftopcellist/refresh_expiry
Add RefreshToken Expiration setting in UI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 19:13:58 +00:00
softwarefactory-project-zuul[bot]
bdd28bcb3b Merge pull request #4899 from ryanpetrello/cli-improved-name-lookups
attempt to properly map more foreign keys to named lookups

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 18:52:57 +00:00
Christian Adams
19a6c70858 remove cruft leftover from the postgresql upgrade 2019-10-03 14:43:56 -04:00
softwarefactory-project-zuul[bot]
393474f33d Merge pull request #4701 from AlanCoding/awx_modules_merge
Migrate Ansible tower modules to collection maintained alongside AWX

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 18:25:55 +00:00
softwarefactory-project-zuul[bot]
b41e6394c5 Merge pull request #4898 from mabashian/upgrade-handlebars-uglify
Bumps handlebars and uglify-js deps

Reviewed-by: Michael Abashian
             https://github.com/mabashian
2019-10-03 17:35:24 +00:00
Christian Adams
f36f10a702 add RefreshToken Expiration setting in UI 2019-10-03 13:13:31 -04:00
Ryan Petrello
fccd6a2286 attempt to properly map more foreign keys to named lookups
this is imperfect, but it's at least an improvement until we can come up
with a better solution

in order to really do this right, the API itself probably needs to grow
some more metadata that allows us to specify *actual* `type`s that
relate to API resources

see: https://github.com/ansible/awx/issues/4874
2019-10-03 12:59:06 -04:00
mabashian
ea2312259f Bumps handlebars and uglify-js deps 2019-10-03 12:54:56 -04:00
softwarefactory-project-zuul[bot]
0e2b7767f5 Merge pull request #4900 from mabashian/fix-snapshot
Fix broken notif list snapshot

Reviewed-by: awxbot
             https://github.com/awxbot
2019-10-03 16:52:56 +00:00
mabashian
82505cd43a Fix broken notif list snapshot 2019-10-03 12:19:50 -04:00
softwarefactory-project-zuul[bot]
5b17ce5729 Merge pull request #4886 from fosterseth/fix-4710-clearexpiredtokens
Set oauth2 refresh token expiration setting

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 16:19:10 +00:00
softwarefactory-project-zuul[bot]
82b313c767 Merge pull request #4871 from rooftopcellist/check_db
Add awx-manage command to check db connection

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 15:16:32 +00:00
softwarefactory-project-zuul[bot]
fec67a3545 Merge pull request #4888 from ryanpetrello/cli-send-receive-note
cli: add a note about send/receive

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 14:17:08 +00:00
softwarefactory-project-zuul[bot]
202af079eb Merge pull request #4849 from mabashian/3779-license-error
Show error body when license application fails

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 12:57:23 +00:00
softwarefactory-project-zuul[bot]
f78d7637a4 Merge pull request #4853 from mabashian/4778-workflow-text-overlap
Prevent text overlap on workflow nodes when an approval node is deleted

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-03 12:48:56 +00:00
softwarefactory-project-zuul[bot]
71bd257191 Merge pull request #4875 from keithjgrant/4684-jt-form-cleanup
Job Template form cleanup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 22:24:57 +00:00
Keith Grant
82064eb4dc fix prop type error in LabelSelect 2019-10-02 14:17:14 -07:00
Seth Foster
bbd625f3aa update help_text to include information about REFRESH_TOKEN_EXPIRE_SECONDS 2019-10-02 17:16:01 -04:00
softwarefactory-project-zuul[bot]
3725ccb43b Merge pull request #4865 from mabashian/3607-settings
Fix settings page rendering when some fields are set manually in file

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 19:43:18 +00:00
Seth Foster
8b22c86b10 Register default settings for OAUTH2_PROVIDER app
Grab AUTHORIZATION_CODE_EXPIRE_SECONDS from oauth2_settings
rather than hard code.

Add REFRESH_TOKEN_EXPIRE_SECONDS to valid_key_names
in OAuth2ProviderField class
2019-10-02 15:29:45 -04:00
softwarefactory-project-zuul[bot]
e6a5d18ebe Merge pull request #4885 from wenottingham/minor-typo
Apply some minor copy edits to awx docs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 18:35:32 +00:00
softwarefactory-project-zuul[bot]
eca191f7f5 Merge pull request #4839 from rebeccahhh/devel
added in ability to delete a user if they are part of your organization

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 18:35:27 +00:00
Ryan Petrello
35fe127891 cli: add a note about send/receive 2019-10-02 14:06:56 -04:00
Seth Foster
db1ad2de95 Set REFRESH_TOKEN_EXPIRE_SECONDS
- Set OAUTH2 REFRESH_TOKEN_EXPIRE_SECONDS to 1 month
  (2628000 seconds)
- If not set, awx-manage cleartokens, or cleanup_tokens,
  will not work properly
- Once cleartokens is run, this setting is the amount of
  time after an access token expires that we keep its
  refresh token in the database
2019-10-02 13:51:46 -04:00
Bill Nottingham
ac12a9cfe1 Apply some minor copy edits 2019-10-02 13:46:10 -04:00
softwarefactory-project-zuul[bot]
dacda644ac Merge pull request #4882 from jbradberry/isolated-playbooks-with-spaces
Quote the playbook passed to runner from the isolated manager

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 17:40:20 +00:00
softwarefactory-project-zuul[bot]
cfa407e001 Merge pull request #4843 from lunarthegrey/patch-1
Fix issue #3705

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 17:38:13 +00:00
softwarefactory-project-zuul[bot]
329630ce2a Merge pull request #4869 from mabashian/4192-enter-textarea
Unbind keydown listeners when Alert modals are closed.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 15:11:21 +00:00
Jeff Bradberry
1122d28a1b Quote the playbook passed to runner from the isolated manager 2019-10-02 11:10:19 -04:00
softwarefactory-project-zuul[bot]
a9b299cd98 Merge pull request #4881 from ryanpetrello/cli-ssh-example
cli: warn users if they specify a missing file with @

Reviewed-by: Yanis Guenane
             https://github.com/Spredzy
2019-10-02 15:00:51 +00:00
Ryan Petrello
6c1488ed00 cli: warn users if they specify a missing file with @ 2019-10-02 10:28:04 -04:00
softwarefactory-project-zuul[bot]
1f62d223a2 Merge pull request #4880 from ryanpetrello/cli-install-rst
template CLI install documentation into a separate file

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-02 14:04:05 +00:00
Ryan Petrello
da23c4e949 template CLI install documentation into a separate file 2019-10-02 09:41:11 -04:00
Keith Grant
6d00d43273 prettier 2019-10-01 15:20:51 -07:00
Keith Grant
77b68e0eb7 use getAddedAndRemoved for saving instance groups 2019-10-01 14:37:42 -07:00
softwarefactory-project-zuul[bot]
945d100302 Merge pull request #4836 from fosterseth/fix-4334-active-user-removed
check if User exists before saving UserSessionMembership

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-01 19:59:11 +00:00
Christian Adams
c0fd70f189 add mgmt cmd to check db connection 2019-10-01 15:40:43 -04:00
Keith Grant
ba4e79fd3a update JT form tests 2019-10-01 11:03:36 -07:00
AlanCoding
db0bd471c3 rename playbook vars to have collection_ 2019-10-01 13:45:07 -04:00
mabashian
616fe285fa Unbind keydown listeners when Alert modals are closed.
This fixes a bug where attempting to hit enter in any sort of textarea would be ignored if the user had previously encountered an Alert modal while navigating throughout the application.
2019-10-01 12:38:43 -04:00
Jake McDermott
b4b2cf76f6 Refactor job secondary label assignment 2019-10-01 10:33:47 -04:00
mabashian
4aeda635ff Checks to make sure that OAUTH2_PROVIDER key is returned by api in settings options before attempting to use it. This fixes a bug where setting ACCESS_TOKEN_EXPIRE_SECONDS and AUTHORIZATION_CODE_EXPIRE_SECONDS manually in a file was causing the settings page to render improperly. 2019-10-01 10:17:33 -04:00
softwarefactory-project-zuul[bot]
7e8c00ee24 Merge pull request #4864 from ryanpetrello/dont-stop-the-beat
warn loudly if celerybeat encounters AMQP connection issues

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-01 13:56:54 +00:00
Ryan Petrello
27c4e35ee4 warn loudly if celerybeat encounters AMQP connection issues
related: https://github.com/ansible/awx/pull/4857
2019-10-01 09:32:22 -04:00
softwarefactory-project-zuul[bot]
80a17987ff Merge pull request #4854 from ryanpetrello/cli-login-formatting
cli: make `awx login` respect the -f flag

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-10-01 01:14:15 +00:00
softwarefactory-project-zuul[bot]
10a6a29a07 Merge pull request #4857 from ryanpetrello/kombu-dns
make kombu DNS failures louder in the logs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-30 21:35:29 +00:00
Ryan Petrello
b80eafe4a1 make kombu DNS failures louder in the logs 2019-09-30 16:48:09 -04:00
Alex Corey
6c443a0a6a fix lint error 2019-09-30 16:38:51 -04:00
Alex Corey
55378c635e Makes template list responive 2019-09-30 16:28:24 -04:00
Ryan Petrello
a4047e414f cli: make awx login respect the -f flag
see: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/awx-project/ZAlhpLMBzVw/fUSqujoWBQAJ
2019-09-30 15:38:08 -04:00
Jeff Bradberry
d549877ebd Check for the existance of a UnifiedJobTemplate with the same webhook GUID
instead of trying (incorrectly) to be specific about the JT/WFJT type.
2019-09-30 15:26:49 -04:00
Rebeccah
28a119ca96 re-worked unit test into 3 seperate unit tests, one for orphans, one for group members, and one for multi-group members 2019-09-30 15:07:19 -04:00
Rebeccah
758529d7dd added in unit test for org admin deleting user 2019-09-30 15:07:19 -04:00
Rebeccah
075d1a2521 removed superuser check since can_admin already checks that, and also added allow orphans so admins can delete orphaned users 2019-09-30 15:07:19 -04:00
Rebeccah
69924c9544 added in ability to delete a user if they are part of your organization 2019-09-30 15:07:19 -04:00
softwarefactory-project-zuul[bot]
b858001c8f Merge pull request #4851 from ryanpetrello/fix-host-key-checking
improve host key checking configurability

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-30 18:38:05 +00:00
Ryan Petrello
82be87566f improve host key checking configurability
see: https://github.com/ansible/tower/issues/3737
2019-09-30 14:13:07 -04:00
mabashian
52b8b7676a Prevent text overlap on workflow nodes when an approval node is deleted 2019-09-30 13:38:46 -04:00
Jeff Bradberry
204c05aa3b Change the webhook post-back payload to use the job UI url 2019-09-30 13:32:23 -04:00
Jeff Bradberry
ac34b24868 Post the job or workflow url to the webhook service as part of the status 2019-09-30 13:32:23 -04:00
Jeff Bradberry
ffe89820e3 Return to using ContentType.kind
which is _not_ the `kind` attribute being deprecated.
2019-09-30 13:32:23 -04:00
Jeff Bradberry
062c4908c9 Modify the webhook debounce logic
to check if we've already previously run a job with the same webhook
GUID plus template id.  This will allow organizations to write
multiple JT/WFJTs to handle the same set of webhook events.
2019-09-30 13:32:23 -04:00
Jeff Bradberry
b6b70e55fb Address a variety of small review issues 2019-09-30 13:32:23 -04:00
Jeff Bradberry
6aa6471b7c Add help_text to the new fields 2019-09-30 13:32:23 -04:00
Jeff Bradberry
e14d4ddec6 Add a doc template to the webhook key API view 2019-09-30 13:32:23 -04:00
Jake McDermott
84dcda0a61 Use job launch_type field to detect webhook jobs
We have a launch type field for categorizing the different ways jobs
can be launched. This updates the UI to use this field when checking
if a job was launched by a webhook.
2019-09-30 13:32:23 -04:00
Jeff Bradberry
df24f5d28f Add a new launch_type of 'webhook' 2019-09-30 13:32:23 -04:00
Jeff Bradberry
fea7f914d2 Avoid the use of CredentialType.kind 2019-09-30 13:32:23 -04:00
Elijah DeLee
d4c8167b1b add arguments to awxkit for webhooks on jt or wfjt 2019-09-30 13:32:22 -04:00
Jeff Bradberry
a4873d97d8 Raise a validation error if a credential is set while the service is not 2019-09-30 13:32:22 -04:00
Jeff Bradberry
efe4ea6575 Fix the webhook receiver url for workflow jobs 2019-09-30 13:32:22 -04:00
Jeff Bradberry
b415c31b4f Fix problems with posting to Gitlab's API 2019-09-30 13:32:22 -04:00
Jeff Bradberry
e91462d085 Update the Webhook Credential help text tooltip
to make it more apparent to the user that this is an optional part of
the feature, and that failure to add a webhook credential will disable
status post-backs.
2019-09-30 13:32:22 -04:00
Jake McDermott
e85ff83be6 Apply 403 alert fixes for Workflows, too 2019-09-30 13:32:22 -04:00
Jake McDermott
d500c1bb40 Don't alert user of 403 errors for webhook key 2019-09-30 13:32:22 -04:00
Jeff Bradberry
885841caea Drop Bitbucket support
since only the Bitbucket Server product supports signed payloads,
bitbucket.org does not.  And we are requiring signed payloads.
2019-09-30 13:32:22 -04:00
Jake McDermott
f7396cf81a Always include selected webhook service in creation requests 2019-09-30 13:32:22 -04:00
Jeff Bradberry
286da3a7eb Posting webhook status now works 2019-09-30 13:32:21 -04:00
Jeff Bradberry
40b03eb6ef Enable the call to update_webhook_status
by calling it directly within send_notification_templates.  Also,
update the context field in the payload to be either 'ansible/awx' or
'ansible/tower', depending on which is being used.
2019-09-30 13:32:21 -04:00
Jeff Bradberry
c76c531b7a Provide a payload for the webhook status post-back 2019-09-30 13:32:21 -04:00
Jake McDermott
75d3359b6f make label consistent with help text 2019-09-30 13:32:21 -04:00
Jeff Bradberry
4ad5054222 Add logic to post the job status for webhooks back to the service
under some circumstances.
2019-09-30 13:32:21 -04:00
Jeff Bradberry
aa34984d7c Fix the git ref extractor for Gitlab pull requests 2019-09-30 13:32:21 -04:00
Jake McDermott
08594682a4 stub options request in workflow add unit test 2019-09-30 13:32:21 -04:00
Jeff Bradberry
d73abda5d1 Update the webhook receiver git ref extractor logic
to deal with the null-ref case, and to deal correctly with Github push events.
2019-09-30 13:32:21 -04:00
Jake McDermott
3bc91f123e add trailing '/' to webhook urls 2019-09-30 13:32:21 -04:00
Jake McDermott
41ba5c0968 add webhook fields to workflow unit test mock 2019-09-30 13:32:21 -04:00
Jeff Bradberry
e8e3a601b2 Pull out a git ref for each event type where we might care 2019-09-30 13:32:21 -04:00
Jake McDermott
b96c03e456 represent webhooks on job lists 2019-09-30 13:32:21 -04:00
Jake McDermott
5e9448a854 always show launched by webhook details if there's a webhook guid 2019-09-30 13:32:21 -04:00
Jake McDermott
6b17e86f30 add launched-by-webhook details to job runs 2019-09-30 13:32:21 -04:00
Jake McDermott
00337990db add webhook fields to workflows 2019-09-30 13:32:21 -04:00
Jake McDermott
1a33ae61a7 use key icon for webhook cred 2019-09-30 13:32:21 -04:00
Jake McDermott
5f7bfaa20a support server-side webhook key generation 2019-09-30 13:32:21 -04:00
Jeff Bradberry
178a2c7c49 Disable the authentication classes for the webhook receivers
One of them was consuming the body of the posts.  We do still need to
have an extraneous `request.body` expression, though now in
WebhookReceiverBase.post, since the `request.data` expression in the
logging also consumes the request body.
2019-09-30 13:32:20 -04:00
Jeff Bradberry
58e5f02129 Expose the new webhook fields in the job and workflow serializers 2019-09-30 13:32:20 -04:00
Jeff Bradberry
dd6c97ed87 Include a message in the webhook response 2019-09-30 13:32:20 -04:00
Jeff Bradberry
7aa424b210 Make sure that the new webhook fields are populated when firing off a job
Also, added a temporary hacky workaround for the fact that something
in our request/response stack for APIView is consuming the request
contents in an unfriendly way, preventing the `.body` @property from
working.
2019-09-30 13:32:20 -04:00
Jake McDermott
e0a363beb8 issue network calls for setting and getting webhook key 2019-09-30 13:32:20 -04:00
Jake McDermott
48eb502161 wip 2019-09-30 13:32:20 -04:00
Jake McDermott
151de89c26 add webhook credential field 2019-09-30 13:32:20 -04:00
Jake McDermott
f5c151d5c4 add webhook url field 2019-09-30 13:32:20 -04:00
Jake McDermott
17b34b1e36 add webhook service field 2019-09-30 13:32:20 -04:00
Jeff Bradberry
ee1d118752 Add the webhook receiver url to the related urls in the serializers 2019-09-30 13:32:20 -04:00
Jeff Bradberry
245931f603 Debounce when multiple copies of the same webhook event come in 2019-09-30 13:26:04 -04:00
Jeff Bradberry
095aa77857 Create a new model mixin for Job and WorkflowJob webhook fields 2019-09-30 13:26:04 -04:00
Jeff Bradberry
bb1397a3d4 Validate the webhook credential
- we should allow a null credential, so that the admin can choose to configure not posting back status changes of the triggered job
- the credential must be of the new 'token' kind
- if we do configure a credential, its type must match the selected SCM service
2019-09-30 13:26:04 -04:00
Jeff Bradberry
5848f0360a Update test_default_cred_types to include the new personal access token types 2019-09-30 13:26:04 -04:00
Jeff Bradberry
83fc2187cc Fix the summary fields for webhook_credential 2019-09-30 13:26:04 -04:00
Jeff Bradberry
4dba9916dc Add a new set of personal access token credential types 2019-09-30 13:26:03 -04:00
Jeff Bradberry
8836ed44ce Construct an ID for Gitlab webhooks
by taking the SHA1 of the body of the webhook request.
2019-09-30 13:26:03 -04:00
Jeff Bradberry
992c414737 Launch a Job or WorkflowJob based on the incoming webhook 2019-09-30 13:26:03 -04:00
Jeff Bradberry
66a8186995 Get the webhook receiver views to work at least minimally 2019-09-30 13:26:03 -04:00
Jeff Bradberry
fa15696ffe Remove some dead comments 2019-09-30 13:26:03 -04:00
Jeff Bradberry
82a0dc0024 Cycle or unset the webhook key if the webhook service changes
Also, tests.
2019-09-30 13:26:03 -04:00
Jeff Bradberry
d4b20b7340 Update tests to use the expect keyword argument for get() and post() 2019-09-30 13:26:03 -04:00
Jeff Bradberry
c0ad5a7768 Expose the webhook_service and webhook_credential fields in the serializer
webhook_credential specifically as a summary field.
2019-09-30 13:26:03 -04:00
Jeff Bradberry
d9ac291115 Add some RBAC oriented tests for the webhook secret key view 2019-09-30 13:26:03 -04:00
Jeff Bradberry
6b86cf6e86 Revert to using the explicit dispatch to the appropriate model
since passing the model class at url include time doesn't work.
2019-09-30 13:26:03 -04:00
Jeff Bradberry
771ef275d4 Include a check for the webhook_key related resource url
in the tests for JTs and WFJTs.
2019-09-30 13:26:03 -04:00
Jeff Bradberry
2310413dc0 Fix problem with the tests by dynamically setting the view model
instead of using a model @property or lookup method.
2019-09-30 13:26:03 -04:00
Jeff Bradberry
edb9d6b16c Add the related link to the webhook secrets view to the serializers 2019-09-30 13:26:03 -04:00
Jeff Bradberry
7973a18103 Switch to using a permission class for the webhook secret key view
This view is now behaving as expected for superuser, org admin, JT
admin, JT exec, and org member roles.
2019-09-30 13:23:27 -04:00
Jeff Bradberry
747a2283d6 Attempt to get the RBAC right on the webhook secret key view 2019-09-30 13:23:27 -04:00
Jeff Bradberry
9d269d59d6 Add an api view for obtaining and rotating the webhook key 2019-09-30 13:23:27 -04:00
Jeff Bradberry
b0c530402f Move the webhook url include from the top level urlconf to the JT/WFJT urlconfs 2019-09-30 13:23:26 -04:00
Jeff Bradberry
50a54c9214 Forbid access to the webhook receiver views if webhook_key is not set 2019-09-30 13:23:26 -04:00
Jeff Bradberry
8f97dbf781 Hook in the webhook receiver views into the urlconf 2019-09-30 13:23:26 -04:00
Jeff Bradberry
a7a99ed141 Beginnings of the API views for the webhook receivers 2019-09-30 13:23:26 -04:00
Jeff Bradberry
d6116490c6 Add the webhook-specific fields to JobTemplate and WorkflowJobTemplate 2019-09-30 13:23:26 -04:00
softwarefactory-project-zuul[bot]
ff8e896b0f Merge pull request #4850 from wenottingham/to-the-cloud!
Adjust help message; we're no longer using the insights client

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-30 16:46:22 +00:00
Bill Nottingham
fc70d8b321 Adjust help message; we're no longer using the insights client 2019-09-30 12:17:46 -04:00
mabashian
a61306580a Show error body when license application fails 2019-09-30 12:09:24 -04:00
Lunar
afe38b8e68 Change to ~/.awx 2019-09-30 10:58:37 -05:00
softwarefactory-project-zuul[bot]
505dcf9dd2 Merge pull request #4657 from beeankha/wf_approval_notification
[WIP] Notification Support for Workflow Approval Nodes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-30 14:54:59 +00:00
softwarefactory-project-zuul[bot]
1d2123a4f9 Merge pull request #4845 from ryanpetrello/cli-fix-ujt-allow
cli: fix `awx unified_job_templates`

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-30 14:10:14 +00:00
Ryan Petrello
4adf9bab67 cli: fix awx unified_job_templates
this endpoint doesn't return an HTTP Allow header at all (because you
can't really do anything other than list templates)
2019-09-30 09:32:58 -04:00
Lunar
adac87adf2 Fix issue #3705
/tmp should not be used, it gets wiped and causes issues as noted in issue #3705.
2019-09-29 23:20:09 -05:00
AlanCoding
7dd8e35e8c Use namespaced doc fragment, cleanup
doc fragment will now be at awx.awx.auth
changed from just tower, which source from core

remove Makefile things no longer needed
2019-09-27 23:09:39 -04:00
Keith Grant
554a63d8fc write LabelSelect tests 2019-09-27 15:30:42 -07:00
Keith Grant
da149d931c rework MultiSelect into controlled input; refactoring 2019-09-27 15:06:15 -07:00
mabashian
3182197287 Makes notification toggles more responsive on smaller screens. 2019-09-27 15:48:00 -04:00
beeankha
9ed4e1682d Remove redundant whitespace 2019-09-27 15:48:00 -04:00
beeankha
5aa6a94710 Enable approval notifications to show up at...
...workflow jobs notifications endpoint
2019-09-27 15:48:00 -04:00
beeankha
96689f45c8 Update approval notification message 2019-09-27 15:48:00 -04:00
beeankha
ce6a276e1f Update migration file 2019-09-27 15:48:00 -04:00
beeankha
8eb1484129 Update migration file, change status syntax 2019-09-27 15:48:00 -04:00
beeankha
1ddf9fd1ed Fix up models, clean up code re: PR comments 2019-09-27 15:48:00 -04:00
beeankha
17a8e08d93 Add unit tests for approval notifications 2019-09-27 15:48:00 -04:00
beeankha
f835c8650b Enable org-level approval notifications to work. 2019-09-27 15:48:00 -04:00
beeankha
aa5a4d42c7 Enable email notifications to work,
...and customize default messages
2019-09-27 15:48:00 -04:00
beeankha
57fd6b7280 Set default messages for approval notifications 2019-09-27 15:48:00 -04:00
mabashian
7eb7aad491 Adds approval toggles to wf and org notif lists 2019-09-27 15:48:00 -04:00
beeankha
e2b8adcd09 Remove notification endpoint from approvals list 2019-09-27 15:48:00 -04:00
beeankha
13450fdbf9 Set up approval notifications to send 2019-09-27 15:48:00 -04:00
beeankha
6be2d84adb Add endpoints for approval node notifications
...and also add a migration file.
2019-09-27 15:48:00 -04:00
softwarefactory-project-zuul[bot]
d2a5af44de Merge pull request #4792 from mabashian/relaunch-jobs
Add relaunch to Jobs list and Job Details views

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-27 19:18:48 +00:00
AlanCoding
75bb7aae14 update references to collection folder 2019-09-27 14:29:04 -04:00
AlanCoding
98619c5e23 rename awx modules folder to collection 2019-09-27 14:29:04 -04:00
AlanCoding
35afa37417 Rename to collection, add license, galaxy build 2019-09-27 14:29:03 -04:00
AlanCoding
2f0f692f4a Integrate Ansible core tower modules content into AWX
This commit includes all the changes involved in
converting the old Ansible Tower modules from commits
in Ansible core into the AWX collection that replaces it.
Also includes work needed to integrate it into the
AWX processes like tests, docs, and the Makefile.

Apply changes from content_collector tool

Add integrated module tests
  operate via run_module fixture
  add makefile target for them

Add flake8 target and fix flake8 errors

Update README

Make consolidated target for testing modules
2019-09-27 14:29:03 -04:00
AlanCoding
5271c993ac Move commit for migration of Ansible core tower modules 2019-09-27 14:29:03 -04:00
AlanCoding
38112bae22 Use to_native for error messages, fix docs typo 2019-09-27 14:29:03 -04:00
Andrey Klychkov
30a6efdb93 fix typos in web_infrastructure modules (#62202) 2019-09-27 14:29:02 -04:00
Alan Rominger
bffc1bfdd4 Allow tower inventory plugin to accept integer inventory_id (#61338) 2019-09-27 14:29:02 -04:00
Alicia Cozine
a7bf31d423 clarifies how ASK works for Tower credentials (#59050)
* clarifies how ASK works for credentials
2019-09-27 14:29:02 -04:00
Pilou
1ae1011ccb tower_role: ensure alias of "validate_certs" parameter is handled (#57518)
* tower_role: ensure alias of validate_certs is handled

* tower modules: remove tower_verify_ssl alias too

Error was:

    Failed to update role: The Tower server claims it was sent a bad request.
    GET https://tower/api/v2/projects/22/object_roles/
    Params: [('tower_verify_ssl', False), ('role_field', 'admin_role')]
    Data: None
    Response: {"detail": "Role has no field named 'tower_verify_ssl'"}

Full traceback:

    File "/tmp/ansible_tower_role_payload_7_2p0X/__main__.py", line 145, in main
      result = role.grant(**params)
    File "/usr/local/lib/python2.7/dist-packages/tower_cli/resources/role.py", line 365, in grant
      return self.role_write(fail_on_found=fail_on_found, **kwargs)
    File "/usr/local/lib/python2.7/dist-packages/tower_cli/resources/role.py", line 242, in role_write
      fail_on_multiple_results=True, **data)
    File "/usr/local/lib/python2.7/dist-packages/tower_cli/models/base.py", line 301, in read
      r = client.get(url, params=params)
    File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 546, in get
      return self.request('GET', url, **kwargs)
    File "/usr/local/lib/python2.7/dist-packages/tower_cli/api.py", line 299, in request
      kwargs.get('data', None), r.content.decode('utf8'))
2019-09-27 14:29:02 -04:00
Alberto Murillo
83183cd7ce tower_workflow_template: Add missing options (#56891)
The following options can be set on a workflow template but the
functionallity to do so from this module was missing.

inventory
ask_variables_on_launch
ask_inventory_on_launch

Fixes #49728

Signed-off-by: Alberto Murillo <albertomurillosilva@gmail.com>
2019-09-27 14:29:02 -04:00
Pilou
934d7d62ef fix tower_credential example: lookup are run on controller (#57516)
- don't advise to use lookups in order to fetch path on managed nodes
- fix example:
    - use slurp instead 'file' lookup
    - remove extraneous brackets
2019-09-27 14:29:01 -04:00
Hideki Saito
5dce6258e6 tower_user: Fix to create a system auditor properly (#54585)
- Fixed issue #54446: tower_user cannot create an auditor user

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-09-27 14:29:01 -04:00
Pilou
87f6065a05 tower_credential: ssh_key_data isn't a path anymore (#57113) 2019-09-27 14:29:01 -04:00
stoned
4ca0d8c72a Add missing roles to tower_role module (#56182)
* Add missing roles to tower_role module

* Placate 'ansible-test sanity --test pep8'
2019-09-27 14:29:01 -04:00
Hideki Saito
ba8bd25da2 Fixed wrong variable specification format in examples (#55252)
Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-09-27 14:29:00 -04:00
Hideki Saito
df0bd0797c Fix handling of inventory and credential options for tower_job_launch (#54967)
- Fixed issue #25017,#37567
- Add example for prompt on launch
- Add integration test for prompt on launch

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-09-27 14:29:00 -04:00
James Cassell
3aa7ee8d17 standardize TLS connection properties (#54315)
* openstack: standardize tls params

* tower: tower_verify_ssl->validate_certs

* docker: use standard tls config params

- cacert_path -> ca_cert
- cert_path -> client_cert
- key_path -> client_key
- tls_verify -> validate_certs

* k8s: standardize tls connection params

- verify_ssl -> validate_certs
- ssl_ca_cert -> ca_cert
- cert_file -> client_cert
- key_file -> client_key

* ingate: verify_ssl -> validate_certs

* manageiq: standardize tls params

- verify_ssl -> validate_certs
- ca_bundle_path -> ca_cert

* mysql: standardize tls params

- ssl_ca -> ca_cert
- ssl_cert -> client_cert
- ssl_key -> client_key

* nios: ssl_verify -> validate_certs

* postgresql: ssl_rootcert -> ca_cert

* rabbitmq: standardize tls params

- cacert -> ca_cert
- cert -> client_cert
- key -> client_key

* rackspace: verify_ssl -> validate_certs

* vca: verify_certs -> validate_certs

* kubevirt_cdi_upload: upload_host_verify_ssl -> upload_host_validate_certs

* lxd: standardize tls params

- key_file -> client_key
- cert_file -> client_cert

* get_certificate: ca_certs -> ca_cert

* get_certificate.py: clarify one or more certs in a file

Co-Authored-By: jamescassell <code@james.cassell.me>

* zabbix: tls_issuer -> ca_cert

* bigip_device_auth_ldap: standardize tls params

- ssl_check_peer -> validate_certs
- ssl_client_cert -> client_cert
- ssl_client_key -> client_key
- ssl_ca_cert -> ca_cert

* vdirect: vdirect_validate_certs -> validate_certs

* mqtt: standardize tls params

- ca_certs -> ca_cert
- certfile -> client_cert
- keyfile -> client_key

* pulp_repo: standardize tls params

remove `importer_ssl` prefix

* rhn_register: sslcacert -> ca_cert

* yum_repository: standardize tls params

The fix for yum_repository is not straightforward since this module is
only a thin wrapper for the underlying commands and config.  In this
case, we add the new values as aliases, keeping the old as primary,
only due to the internal structure of the module.

Aliases added:
- sslcacert -> ca_cert
- sslclientcert -> client_cert
- sslclientkey -> client_key
- sslverify -> validate_certs

* gitlab_hook: enable_ssl_verification -> hook_validate_certs

* Adjust arguments for docker_swarm inventory plugin.

* foreman callback: standardize tls params

- ssl_cert -> client_cert
- ssl_key -> client_key

* grafana_annotations: validate_grafana_certs -> validate_certs

* nrdp callback: validate_nrdp_certs -> validate_certs

* kubectl connection: standardize tls params

- kubectl_cert_file -> client_cert
- kubectl_key_file -> client_key
- kubectl_ssl_ca_cert -> ca_cert
- kubectl_verify_ssl -> validate_certs

* oc connection: standardize tls params

- oc_cert_file -> client_cert
- oc_key_file -> client_key
- oc_ssl_ca_cert -> ca_cert
- oc_verify_ssl -> validate_certs

* psrp connection: cert_trust_path -> ca_cert

TODO: cert_validation -> validate_certs (multi-valued vs bool)

* k8s inventory: standardize tls params

- cert_file -> client_cert
- key_file -> client_key
- ca_cert -> ca_cert
- verify_ssl -> validate_certs

* openshift inventory: standardize tls params

- cert_file -> client_cert
- key_file -> client_key
- ca_cert -> ca_cert
- verify_ssl -> validate_certs

* tower inventory: verify_ssl -> validate_certs

* hashi_vault lookup: cacert -> ca_cert

* k8s lookup: standardize tls params

- cert_file -> client_cert
- key_file -> client_key
- ca_cert -> ca_cert
- verify_ssl -> validate_certs

* laps_passord lookup: cacert_file -> ca_cert

* changelog for TLS parameter standardization
2019-09-27 14:29:00 -04:00
Pilou
aeaab41120 tower_settings: "get" isn't implemented, "value" parameter is required (#54028)
* tower_settings doc: 'get' isn't implemented

* tower_settings: fix typo in argument_spec
2019-09-27 14:29:00 -04:00
Abhijeet Kasurde
1eb61ba5ce tower_credential: Add parameter vault_id (#53400)
vault_id allows user to specify vault identifier as per Tower UI.

Fixes: #45644

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2019-09-27 14:28:59 -04:00
Alan Rominger
91d0c47120 Add option for tower inventory to give general metadata (#52747) 2019-09-27 14:28:59 -04:00
Abhijeet Kasurde
b96b69360f tower: Handle AuthError (#53377)
Handle AuthError raised when user provides incorrect password
for Tower admin user.

Fixes: #50535

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2019-09-27 14:28:59 -04:00
David Medberry
b034295c99 Update tower_credential.py (#51469)
misspelled word and poor capitalization (in the same sentence of the doc string)

+label: docsite_pr
2019-09-27 14:28:59 -04:00
Pilou
c6e47a0a16 tower modules: check that 'verify_ssl' defined in ~/.tower_cli.cfg isn't ignored (#50687)
* Check that verify_ssl defined in tower_cli.cfg isn't ignored

* Avoid to override verify_ssl value defined in tower_cli.cfg

By default, tower-cli library enables SSL certificates check. But
verify_ssl false value defined in config files read by default by
tower-cli library (for example /etc/tower/tower_cli.cfg) was ignored
because overriden by the tower_verify_ssl parameter default value.

* fix a typo in comment
2019-09-27 14:28:58 -04:00
Jordan Borean
ca782a495d Final round of moving modules to new import error msg (#51852)
* Final round of moving modules to new import error msg

* readd URL to jenkins install guide

* fix unit tests
2019-09-27 14:28:58 -04:00
Dennis Lerch
71c625bd83 add diff_mode_enabled to documentation
option 'diff_mode_enabled' is not mentioned in documentation

+label: docsite_pr
2019-09-27 14:28:58 -04:00
Samuel Carpentier
5c2bc09f9d New module: tower_notification (#50512)
* New module: tower_notification

* Fix CI check failures

* Add integration tests and extend examples

* Add missing required field for deletion tests and examples

* Add missing required field for deletion tests and examples

* Set port type to int

* Add missing field for Slack notification

* Add missing field types for IRC notification

* Update module documentation

* Correct field name and type for IRC notification

* Uniformize 'targets' field

* Uniformize 'targets' field
2019-09-27 14:28:57 -04:00
jainnikhil30
58c4ae6a00 Add scm_update_cache_timeout, job_timeout and custom_virtualenv to tower_project (#51330)
* adding scm_update_cache_timeout and job_timeout to tower_project module

* add support for cache_timeout, job_timeout and custom_venv for tower_project module

* add the version_added
2019-09-27 14:28:57 -04:00
John Westcott IV
37509af868 Adding TowerCLI receive module (#51023) 2019-09-27 14:28:57 -04:00
John Westcott IV
41f649b5a2 Adding tower_workflow_launch (#42701) 2019-09-27 14:28:57 -04:00
John Westcott IV
5ef995cd7d Adding TowerCLI send module (#37843) 2019-09-27 14:28:56 -04:00
jainnikhil30
a32981242b Fixing exception import for tower modules (#50447)
* fixing the exception import from tower modules

* Adding tests for checking tower modules are failing with correct msg

* fixed failing tests

* fixed failing test in tower_team
2019-09-27 14:28:56 -04:00
Alicia Cozine
c821996051 fix docs for tower modules (#50710) 2019-09-27 14:28:56 -04:00
Andrea Tartaglia
a37a18c0bf Added organization in the scm_credential get (#49884)
* Added organization in the scm_credential get

* Fallback looking for cred in project org

* Tests project with multi org credential

* Fixed CI issue

* Added changelog fragment
2019-09-27 14:28:56 -04:00
Dag Wieers
b11374157d Convert to reduced list of known types (#50010) 2019-09-27 14:28:55 -04:00
Abhijeet Kasurde
2d6743635e E325 Removal - Part II (#49196)
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2019-09-27 14:28:55 -04:00
seag-rvc
590341ed7d Update tower_host.py (#49186)
<!--- Your description here -->
Current example does not show how to declare variables
+label: docsite_pr
2019-09-27 14:28:55 -04:00
Hugh Ma
ae980b9a82 Add survey_spec parameter to module. (#48182)
* Add survey_spec parameter to module.
Fixes #48011

* Removed trailing white space. Added integration test.
2019-09-27 14:28:55 -04:00
Sean Cavanaugh
94b557d8aa adding additional example and clarification (#47224)
The kind: paramter is missing from the original example (which won't actually work).  The organization needs to be listed as required (if you don't list it, you will get an error).  Also adding additional example using the tower_username and tower_password method.
2019-09-27 14:28:54 -04:00
Sloane Hertel
5dc9ca222f add more consistent extension matching for inventory plugins (#46786)
* Add consistent extension matching for inventory plugins that support YAML configuration files

* Document extension matching expectations
2019-09-27 14:28:54 -04:00
Yanis Guenane
79166209ee inventory/tower: authors -< author so Doc can pick it up (#45936) 2019-09-27 14:28:54 -04:00
Dag Wieers
45a8992254 Docs: Avoid use of 'default: null' (#45795)
Various modules document the default 'null' value, but it causes None to
be shown in the documentation explicitly.
2019-09-27 14:28:54 -04:00
Meecr0b
def043c383 tower_credential: expect ssh_key_data to be a string instead of path (#45158)
* expect ssh_key_data to be a string instead of path

ssh_key_data should be a string filled with the private key
the old behavior can be archived with a lookup

Fixes #45119

* clarifies ssh_key_data description, adds newline
2019-09-27 14:28:53 -04:00
Adrien Fleury
7b6dc13078 New module : tower_credential_type (#37243)
* Add new module *tower_credential_type*

* Add support for credential type creation and/or deletion
* Add test coverage for tower_credential_type
2019-09-27 14:28:53 -04:00
Adrien Fleury
ee2709a898 New module tower_workflow_template. (#37520)
* Add new module *tower_workflow_template*

Manage Tower workflows and their schemas.
2019-09-27 14:28:53 -04:00
jainnikhil30
d9d56b4b50 Add 'tower_settings' module for managing Ansible Tower Settings (#43933)
* add the tower_settings module
2019-09-27 14:28:52 -04:00
Yunfan Zhang
7580f9c2b9 Added Ansible Tower inventory plugin. (#41816)
Signed-off-by: Yunfan Zhang <yz322@duke.edu>
2019-09-27 14:28:52 -04:00
curry9999
d4f4983a89 To improve readability, we added a line feed. (#43801)
* 	modified:   google/gcp_compute_backend_bucket.py
	modified:   google/gcp_compute_backend_service.py
	modified:   google/gcp_compute_forwarding_rule.py
	modified:   google/gcp_compute_global_forwarding_rule.py
	modified:   google/gcp_compute_image.py
	modified:   google/gcp_compute_instance.py
	modified:   google/gcp_compute_instance_group.py
	modified:   google/gcp_compute_instance_group_manager.py
	modified:   google/gcp_compute_instance_template.py
	modified:   google/gcp_compute_route.py
	modified:   google/gcp_compute_subnetwork.py
	modified:   google/gcp_compute_target_http_proxy.py
	modified:   google/gcp_compute_target_https_proxy.py
	modified:   google/gcp_compute_target_ssl_proxy.py
	modified:   google/gcp_compute_target_tcp_proxy.py
	modified:   google/gcp_compute_url_map.py
	modified:   google/gcp_container_node_pool.py
	modified:   google/gcp_dns_resource_record_set.py
	modified:   google/gcp_pubsub_subscription.py
	modified:   google/gcp_storage_bucket_access_control.py

* 	modified:   lib/ansible/modules/cloud/amazon/aws_ses_identity.py
	modified:   lib/ansible/modules/cloud/amazon/route53_facts.py
	modified:   lib/ansible/modules/cloud/cloudscale/cloudscale_server.py
	modified:   lib/ansible/modules/network/aos/_aos_logical_device.py
	modified:   lib/ansible/modules/network/aos/_aos_rack_type.py
	modified:   lib/ansible/modules/network/aos/_aos_template.py
	modified:   lib/ansible/modules/network/cumulus/nclu.py
	modified:   lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py
	modified:   lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py
2019-09-27 14:28:52 -04:00
Will Thames
24cedcc560 Allow tower_inventory_sources params to be False (#43749)
Ensure that params set to False are respected, rather than ignored.
2019-09-27 14:28:52 -04:00
Pilou
64014faf02 Tower modules: move HAS_TOWER_CLI check in module_utils and minor improvements (#39809)
* tower_* modules: move HAS_TOWER_CLI in TowerModule

Besides this change allows to define other common parameters such as
mutually_exclusive.

* tower_*: config file can not be used with auth params

* tower module_utils: remove useless call to expanduser

'path' type: expanduser & expandvars are automatically called
2019-09-27 14:28:51 -04:00
David Moreau Simard
9b228d7d2d Properly detect credentials for tower_project
It seemed like it was mostly the wrong variables been looked at, making
it so a git repository could not be created without a credential.
2019-09-27 14:28:51 -04:00
Pierre-Louis Bonicoli
1349449e1e tower_project: manual projects don't require creds 2019-09-27 14:28:51 -04:00
Abhijeet Kasurde
185e9a09e0 Correct typo from 'Valut' to 'Vault' (#41574)
Correct typo from 'Valut' to 'Vault'

+label: docsite_pr
2019-09-27 14:28:51 -04:00
jaevans
623e0f7cc9 Add support for Tower Smart inventories (#41458)
* Support Smart Inventories

Add kind and host_filter fields and pass through to tower_cli.

* Add documentation for new Smart Inventories options

* Add missing description header for host_filter documentation

* Add version added tags to new options

* Bumped vesion_added to 2.7
2019-09-27 14:28:50 -04:00
Andrew J Huffman
8569bf71af Updating tower_job_template.py (#38821)
* Updating tower_job_template.py

* tower_job_template: Update parameter version_added to 2.7

* Ensure that unset credentials aren't passed

Passing empty strings for unset credentials causes ValueErrors as
the API expects an integer. Don't pass unset credentials
2019-09-27 14:28:50 -04:00
Adrien Fleury
6471481d02 Module: Tower inventory source module (#37110)
* tower_inventory_source: Add support for the inventory source via ansible-tower-cli.

* Add test coverage for tower_inventory_source.

* Update version_added to 2.7
2019-09-27 14:28:50 -04:00
Pierre Roux
139703aafb Fix tower_* modules **params kwargs (#40137)
* Add cleaning function to handle **params

The cleaning function is only added to tower modules which pass a `**params`
argument as an unpacked dictionnary to the tower-cli method calls.

Fix #39745

* Remove previous code added only for tower_role

In 872a7b4, the `update_resources` function was modified so that it would clear unwanted
parameters. However, this behaviour is desired for other modules too, modified in
another commit. (see tower_clean_params).
2019-09-27 14:28:50 -04:00
Ryan Petrello
65aeb2b68a add some Tower module integration tests (and fix a bug or two) (#37421)
* add additional test coverage for tower modules

* add test coverage for the tower_credential module

* add test coverage for the tower_user module

* fix a bug in py3 for tower_credential when ssh_key_data is specified

* add test coverage for tower_host, tower_label, and tower_project

* add test coverage for tower_inventory and tower_job_template

* add more test coverage for tower modules

- tower_job_launch
- tower_job_list
- tower_job_wait
- tower_job_cancel

* add a check mode/version assertion for tower module integration tests

* add test coverage for the tower_role module

* add test coverage for the tower_group module

* add more integration test edge cases for various tower modules

* give the job_wait module more time before failing

* randomize passwords in the tower_user and tower_group tests
2019-09-27 14:28:49 -04:00
Dag Wieers
0b26297177 Clean up module documentation (#36909)
* Clean up module documentation

This PR includes:
- Removal of `default: None` (and variations)
- Removal of `required: false`
- Fixing booleans and `type: bool` where required

* Fix remaining (new) validation issues
2019-09-27 14:28:49 -04:00
Pilou
3e8de196ac ansible_tower modules doc: fix typos, use formatting functions (#37414)
* fix typos

* use formatting functions

* use 'job template' instead of 'job_template'

* acronyms: user uppercase

* become_enabled param is about privilege escalation
2019-09-27 14:28:49 -04:00
Ryan Petrello
b14323c985 properly pass /api/v1/ credential fields for older Towers (#36917) 2019-09-27 14:28:48 -04:00
Ryan Petrello
2e04969f17 properly detect the absence of credential_type in older tower-cli (#36908) 2019-09-27 14:28:48 -04:00
Ryan Petrello
2edca4f357 tower cred: support credential kind/type for /api/v1/ and /api/v2/ (#36662)
older versions of Tower (3.1) don't have a concept of CredentialTypes
(this was introduced in Tower 3.2).  This change detects older versions
of pre-3.2 tower-cli that *only* support the deprecated `kind`
attribute.
2019-09-27 14:28:48 -04:00
Ryan Petrello
d192297987 tower cred: update kind options in documentation 2019-09-27 14:28:48 -04:00
Ryan Petrello
0bb7e06761 tower cred: filter user name lookup by the proper key 2019-09-27 14:28:47 -04:00
Ryan Petrello
4213ca1424 tower cred: implement credential /api/v1/ kind compatability 2019-09-27 14:28:47 -04:00
Thierry Bouvet
3db3430129 Fix credentials for Tower API V2 2019-09-27 14:28:47 -04:00
Toshio Kuratomi
f7592f6ae7 Port arg specs from type='str' to type='path' 2019-09-27 14:28:47 -04:00
Pilou
ac82751dfa ansible_tower: fix broken import, reuse tower_argument_spec and documentation fragment (#29115)
* module_utils/ansible_tower: fix broken import

* tower_*: use tower_argument_spec & doc fragment

* tower doc fragment: Ansible requires Python 2.6+

* tower_job_wait: fix broken import (Py3 compat)
2019-09-27 14:28:46 -04:00
ethackal
f46db65bad Fixes verify_ssl option when False in ansible_tower module util (#30308)
* Fixes verify_ssl option when False in ansible_tower module util

* fixed comparison to None per PEP-8 standards
2019-09-27 14:28:46 -04:00
Toshio Kuratomi
d0ffc3f626 Update metadata to 1.1 2019-09-27 14:28:46 -04:00
Toshio Kuratomi
e9ec80d86b Remove wildcard imports
Made the following changes:

* Removed wildcard imports
* Replaced long form of GPL header with short form
* Removed get_exception usage
* Added from __future__ boilerplate
  * Adjust division operator to // where necessary

For the following files:

* web_infrastructure modules
* system modules
* linode, lxc, lxd, atomic, cloudscale, dimensiondata, ovh, packet,
  profitbricks, pubnub, smartos, softlayer, univention modules
* compat dirs (disabled as its used intentionally)
2019-09-27 14:28:46 -04:00
Christopher Galtenberg
56723c3203 Improve help text for extra-vars requiring @ for filename
(cherry picked from commit 1b34de89ee1d75cb7f616b5a34cd5043bf7dfd2b)
2019-09-27 14:28:45 -04:00
Abhijeet Kasurde
fdbafe42ab Fix spelling mistakes (comments only) (#25564)
Original Author : klemens <ka7@github.com>

Taking over previous PR as per
https://github.com/ansible/ansible/pull/23644#issuecomment-307334525

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2019-09-27 14:28:45 -04:00
Bill Nottingham
7c0554bf7b Fix handling of extra_vars_path parameter. (#25272)
tower-cli process_extra_vars takes a list.
2019-09-27 14:28:45 -04:00
Dag Wieers
49df11d478 Collated PEP8 fixes (#25293)
- Make PEP8 compliant
2019-09-27 14:28:45 -04:00
James Labocki
5ef7003395 Fix indentation for register module in example (#25274) 2019-09-27 14:28:44 -04:00
Kevin Clark
640e528fdc adds privilege escalation method for pmrun(Unix Privilege Manager 6.0) 2019-09-27 14:28:44 -04:00
Lee Shakespeare
06e09550af Lookup credential id and pass in credential rather than scm_credential (#24624)
* Lookup credential id and pass in credential rather than scm_credential

* Change the excepting handling to catch missing credentials

* Make error messages for not found lookups more useful
2019-09-27 14:28:44 -04:00
Lee Shakespeare
74c7c7b532 Tower user remove organization (#24544)
* Remove organization field from the tower_user module re: issue #24510

* Fix trailing spaces.

* Fixes for Shippable errors, pep8

* Remove a random inserted space.
2019-09-27 14:28:44 -04:00
Abhijeet Kasurde
62bc1a8662 Pep8 fixes for web_infra/ansible_tower (#24479)
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2019-09-27 14:28:43 -04:00
Andrea Tartaglia
9469bbc06f fixed RETURN docs for modules (#24011)
* fixed RETURN docs for remaining modules

* updated proxymysql_mysql_users 'sample' to yaml dict

* fixed whitespace errors
2019-09-27 14:28:43 -04:00
Toshio Kuratomi
7cdde96c3c New metadata 1.0 (#22587)
Changes to the metadata format were approved here:
https://github.com/ansible/proposals/issues/54
* Update documentation to the new metadata format
* Changes to metadata-tool to account for new metadata
  * Add GPL license header
  * Add upgrade subcommand to upgrade metadata version
  * Change default metadata to the new format
  * Fix exclusion of non-modules from the metadata report
* Fix ansible-doc for new module metadata
* Exclude metadata version from ansible-doc output
* Fix website docs generation for the new metadata
* Update metadata schema in valiate-modules test
* Update the metadata in all modules to the new version
2019-09-27 14:28:43 -04:00
John R Barker
bc2a63c415 Fix invalid fields in module DOCUMENATION (#22297)
* fix module doc fields

* More module docs corrections

* More module docs corrections

* More module docs corrections

* More module docs corrections

* correct aliases

* Review comments

* Must quote ':'

* More authors

* Use suboptions:

* restore type: bool

* type should be in the same place

* More tidyups

* authors

* Use suboptions

* revert

* remove duplicate author

* More issues post rebase
2019-09-27 14:28:43 -04:00
Wayne Witzel III
9c6c9c3708 Ansible Tower job_wait module (#22160)
* Ansible Tower job_wait module

* clean up documentation and update code comment
2019-09-27 14:28:42 -04:00
Wayne Witzel III
6a2e3d2915 Ansible Tower job cancel module (#22161)
* Ansible Tower job cancel module

* fix interpreter line
2019-09-27 14:28:42 -04:00
Wayne Witzel III
85977be23c Ansible Tower job list module (#22164) 2019-09-27 14:28:42 -04:00
Wayne Witzel III
3855393cd3 Ansible Tower job_launch module (#22148)
* Ansible Tower job_launch module

* Added RETURN documentation and fixed import locations

* remove superfluos required attributes, make tags a list, and fix some typos

* only join tags if they are actually a list

* use isinstance instead of type, cleanup imports
2019-09-27 14:28:42 -04:00
Wayne Witzel III
bd6e5c2529 add Ansible Tower role module (#21592)
* add Ansible Tower role module

* remove owner as choice from role paramenter
2019-09-27 14:28:41 -04:00
Wayne Witzel III
8a5914affd add Tower JobTemplate module (#21681)
* add Tower JobTemplate module

* add host_config_key and remove defaults from required parameters
2019-09-27 14:28:41 -04:00
Wayne Witzel III
979adfd16c add Ansible Tower team module (#21593) 2019-09-27 14:28:41 -04:00
John R Barker
5f2381e9ad Correct example 2019-09-27 14:28:41 -04:00
Wayne Witzel III
99027e4b30 Add Tower Project module (#21479) 2019-09-27 14:28:40 -04:00
Wayne Witzel III
150c0a9fdc Add Tower Group module (#21480) 2019-09-27 14:28:40 -04:00
Wayne Witzel III
2c825b792f Add Tower Host module (#21482) 2019-09-27 14:28:40 -04:00
Wayne Witzel III
2f9b0733bb Add Tower Inventory module (#21483) 2019-09-27 14:28:40 -04:00
Wayne Witzel III
962668389a Add Tower Label module (#21485) 2019-09-27 14:28:39 -04:00
Wayne Witzel III
0699e44b53 Ansible Tower user and credential module (#21020)
* rename tower config module parameters to avoid conflicts

* add Ansible Tower user module

* add Ansible Tower credential module

* remove errant hash from interpreter line

* friendlier error messages

* Update tower_verify_ssl defaults and module examples

* Update tower_verify_ssl default documentation

* Tower expects satellite6 not foreman
2019-09-27 14:28:39 -04:00
Matt Martz
788a2e5fc8 Update validate-modules (#20932)
* Update validate-modules

* Validates ANSIBLE_METADATA
* Ensures imports happen after documentation vars
* Some pep8 cleanup

* Clean up some left over unneeded code

* Update modules for new module guidelines and validate-modules checks

* Update imports for ec2_vpc_route_table and ec2_vpc_nat_gateway
2019-09-27 14:28:39 -04:00
Brian Coca
16e6b3f148 updated friendlier description 2019-09-27 14:28:39 -04:00
Wayne Witzel III
6140308675 Ansible Tower organization module (#20355)
* add Ansible Tower organization module

* skip Python 2.4 check for ansible_tower module

* make spec and doc match, extract tower auth helper method

* added auth params at module level

* support check mode

* extract check mode check to ansible_tower utils, add utils to 2.4 skip

* update interpreter shebang

* remove colon from docs

* no log for password, verify_ssl default to true
2019-09-27 14:28:35 -04:00
mabashian
518a25430d Adjust unit test after adding conditional render to modals in launch button component 2019-09-27 13:47:13 -04:00
Seth Foster
b6ffde75ef check expired sessions only if User exists
- Indent rest of code into the conditional
  that checks for expired sessions of that User
- If user doesn't exist, no need to check
2019-09-27 12:31:10 -04:00
softwarefactory-project-zuul[bot]
8d44ab55f1 Merge pull request #4837 from ryanpetrello/faster-dev-iso
lower the isolated poll interval in development

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-27 16:21:22 +00:00
Keith Grant
6e9804b713 Rework saving labels 2019-09-27 08:53:52 -07:00
Seth Foster
94fa745859 removed duplicate import of User 2019-09-27 11:47:44 -04:00
softwarefactory-project-zuul[bot]
eacc7b8eb0 Merge pull request #4827 from ryanpetrello/fix-docker-compose-cluster
fix broken `docker-compose-cluster` config

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-27 15:35:18 +00:00
Ryan Petrello
73c3b8849b lower the isolated poll interval in development
(waiting 30s is annoying)
2019-09-27 11:26:10 -04:00
mabashian
bb474b0797 Only render the launch modals if errors are present. This addresses a local unit test failure. 2019-09-27 11:05:23 -04:00
Seth Foster
c94ebba0b3 Saving user session checks if User exists
- Check that model User object exists with id=user_id
  before attempting to save to database
- UserSessionMembership saves to the database using
  foreign key, User
- However, User with matching id might not exist if
  browser sends request with stale cookies
- Change made in regards to issue #4334
2019-09-27 10:52:53 -04:00
mabashian
af90a78df5 Extends LaunchButton component to include support for relaunching. Adds relaunch button to jobs list and job detail view(s). 2019-09-27 10:37:46 -04:00
softwarefactory-project-zuul[bot]
de68de7f9a Merge pull request #4735 from AlanCoding/come_as_you_are
Copy git submodules as-is to avoid auth and path errors

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-27 13:49:16 +00:00
softwarefactory-project-zuul[bot]
04ba7aaf89 Merge pull request #4835 from ryanpetrello/plural-credentials
Update the "Credential" label on JT forms to say "Credentials"

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-27 13:16:50 +00:00
AlanCoding
454f76c066 Copy git submodules as-is to avoid auth and path errors 2019-09-27 09:03:47 -04:00
softwarefactory-project-zuul[bot]
9b281bbc8a Merge pull request #4829 from ryanpetrello/fix-4294
Fix error with rejoining node to cluster after lost connection to postgres

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-27 12:50:25 +00:00
Ryan Petrello
870b76dc59 Update the "Credential" label on JT forms to say "Credentials"
see: https://github.com/ansible/awx/issues/4831
2019-09-27 08:44:04 -04:00
Buymov Ivan
f2676064fd Fix error with rejoining node to cluster after lost connection to postgres 2019-09-27 01:17:27 -04:00
Ryan Petrello
4b62f4845a fix broken docker-compose-cluster config 2019-09-27 00:37:29 -04:00
softwarefactory-project-zuul[bot]
bc6edf7af3 Merge pull request #3583 from kumy/patch-1
Use variables to set rabbitmq host and port

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-27 01:18:20 +00:00
kumy
3dd69a06e7 Use variables to set rabbitmq host and port 2019-09-26 20:53:55 -04:00
softwarefactory-project-zuul[bot]
cb8c9567b0 Merge pull request #4807 from ryanpetrello/cred-plugins-with-promptable-passphrase
fix a bug that prevents launch-time passphrases w/ cred plugins

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-26 21:40:58 +00:00
Ryan Petrello
d30d51d72c fix a bug that prevents launch-time passphrases w/ cred plugins
with the advent of credential plugins there's no way for us to *actually
know* the RSA key value at the time the credential is _created_, because
the order of operations is:

1.  Create the credential with a specified passphrase
2.  Associate a new dynamic inventory source pointed at some third party
    provider (hashi, cyberark, etc...)

this commit removes the code that warns you about an extraneous
passphrase (if you don't specify a private key)

additionally, the code for determining whether or not a credential
_requires_ a password/phrase at launch time has been updated to test
private key validity based on the *actual* value from the third party
provider

see: https://github.com/ansible/awx/issues/4791
2019-09-26 17:14:25 -04:00
softwarefactory-project-zuul[bot]
693e588a25 Merge pull request #4659 from bcoca/nicer_error
better error message on missing runner

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-26 20:52:33 +00:00
softwarefactory-project-zuul[bot]
0f42782feb Merge pull request #4804 from AlexSCorey/4616-4766-JTAddBtn-ToolBarCheckBox
ToolBar checkbox checks, JT Add Button closes and Test Clean up

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-26 20:41:27 +00:00
Alex Corey
90cac2ec35 fix lint errors 2019-09-26 16:11:34 -04:00
softwarefactory-project-zuul[bot]
8343552dfc Merge pull request #4822 from jbradberry/team-grant-permissions-visibility
Change the visibility of the Grant Permission button on the team edit page

Reviewed-by: Marliana Lara <marliana.lara@gmail.com>
             https://github.com/marshmalien
2019-09-26 20:02:56 +00:00
softwarefactory-project-zuul[bot]
c229e586da Merge pull request #4825 from jbradberry/prevent-notification-config-search
Prevent search on the NotificationTemplate.notification_configuration field

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-26 19:40:26 +00:00
softwarefactory-project-zuul[bot]
778b306208 Merge pull request #4824 from rooftopcellist/scl_in_containers
Add needed scl enables for community container installs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-26 19:40:21 +00:00
softwarefactory-project-zuul[bot]
415592219c Merge pull request #4823 from ryanpetrello/even-more-pendo
allow *.pendo.io as an img-src in our Content Security Policy

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-26 19:40:16 +00:00
softwarefactory-project-zuul[bot]
3a7756393e Merge pull request #4816 from marshmalien/add-missing-job-detail-fields
Add missing job detail fields

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-26 19:40:10 +00:00
Jeff Bradberry
1a7148dc80 Prevent search on the NotificationTemplate.notification_configuration field 2019-09-26 14:37:04 -04:00
Alex Corey
d42ffd7353 Removes unused fnc and unnecessary props adds dom node to Empty State
This.node was use for the add button for both empty list and list with data.
This was done to reduce complexity in handleAddToggle() and I don't think it
will cause bugs because those two elements are not rendered at the same time.
2019-09-26 13:32:00 -04:00
Christian Adams
9f8d975a19 revert to get needed scl enables for community container installs 2019-09-26 13:24:26 -04:00
Ryan Petrello
955bb4a44c allow *.pendo.io as an img-src in our Content Security Policy 2019-09-26 13:12:54 -04:00
Keith Grant
71511b66ac fix JobTemplate tests 2019-09-26 10:01:34 -07:00
Marliana Lara
e97fc54deb Add class to StatusIcon wrapper and fix merge conflicts 2019-09-26 11:50:38 -04:00
Jeff Bradberry
ee27313b42 Change the visibility of the Grant Permission button on the team edit page
In the case where MANAGE_ORGANIZATION_AUTH = False, an Org admin is
still supposed to have the capability of adding resource roles to a
team.  This was in fact still doable directly in the API, or via the
organization edit page.
2019-09-26 11:28:25 -04:00
Keith Grant
439727f1bd extract new LabelSelect component from JobTemplateForm 2019-09-25 15:18:30 -07:00
Marliana Lara
76325eefd3 Expand job detail tests to verify more fields
* Update job detail tests to use large mock job data source
* Move mock job data source into a shared file
* Update OrgAccess snapshot due to DetailList style change
2019-09-25 16:39:05 -04:00
Marliana Lara
4b8a06801c Add missing job detail fields and status icons 2019-09-25 16:35:29 -04:00
Alex Corey
38b506bb94 Removes isPlain prop from DropdownItem 2019-09-25 10:28:57 -04:00
Keith Grant
61f6e3c4d2 Refactor to PlaybookSelect component 2019-09-24 14:49:15 -07:00
softwarefactory-project-zuul[bot]
640e5391f3 Merge pull request #4783 from AlexSCorey/4222-JobResultsDelete
Adds delete button to job details and handle delete errors

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-24 21:48:22 +00:00
Alex Corey
1316ace475 Fixes translation omissions 2019-09-24 16:34:09 -04:00
softwarefactory-project-zuul[bot]
3282caf629 Merge pull request #4770 from AlexSCorey/Pluralization
Requires individual components to pluralize

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-24 15:55:11 +00:00
Alex Corey
b3b53a8ce4 Pluralized modal titles and empty state strings
All itemNames used in empty state messages, and delete modal titles
need to be plural and capitalized.  Because of this change we no
longer need the ucFirst() in utils/strings.js.
2019-09-24 11:21:54 -04:00
Alex Corey
8dd4379bf2 Adds proper translation. removes ucFirst()> 2019-09-24 11:21:54 -04:00
Alex Corey
b79c686336 requires individual components to pluralize 2019-09-24 11:21:54 -04:00
softwarefactory-project-zuul[bot]
d08c601690 Merge pull request #4803 from ryanpetrello/more-pendo-fixes
correct CSP header to allow all pendo.io traffic

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-24 02:35:13 +00:00
softwarefactory-project-zuul[bot]
86f8d648cc Merge pull request #4787 from keithjgrant/qs-util-cleanup
QS util cleanup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-23 23:03:22 +00:00
softwarefactory-project-zuul[bot]
34bdb6d1c3 Merge pull request #4808 from rooftopcellist/awxkit_docs_link
add link to awxkit docs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-23 20:08:47 +00:00
Christian Adams
9548c8ae19 add link to awxkit docs 2019-09-23 15:38:51 -04:00
softwarefactory-project-zuul[bot]
e147869d75 Merge pull request #4789 from wenottingham/lacking-in-insights
Rename Automation Insights to Automation Analytics.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-23 18:46:41 +00:00
Keith Grant
362339d89c add FieldTooltip component, some JobTemplateForm cleanup 2019-09-23 11:00:13 -07:00
softwarefactory-project-zuul[bot]
ebbcefd7df Merge pull request #4806 from beeankha/url_update
Update URL

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-23 17:42:01 +00:00
beeankha
6a9940c027 Update URL 2019-09-23 13:17:26 -04:00
softwarefactory-project-zuul[bot]
8c755dd316 Merge pull request #4795 from wenottingham/sanitization
Add some sanitizations

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-23 14:58:41 +00:00
softwarefactory-project-zuul[bot]
fcfd59ebe2 Merge pull request #4767 from beeankha/awx_doc_edits
[WIP] Edit AWX Docs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-23 14:30:12 +00:00
Alex Corey
ce1d9793ce ToolBar checkbox checks and JT Add Button closes and Test Clean up
The Select-All check box in the DataList Toolbar will be checked when the
user clicks on it. Also, the JT Add button closes when the user clicks
elsewhere on the page as well as when the user clicks on the button a second time.
I also cleaned up some tests in the DataListToolBar file.
2019-09-23 09:49:38 -04:00
beeankha
f35ad41e17 Fix misc. errors and typos 2019-09-23 09:46:54 -04:00
Ryan Petrello
d52aa11422 correct CSP header to allow all pendo.io traffic 2019-09-23 09:15:55 -04:00
softwarefactory-project-zuul[bot]
c628a54c79 Merge pull request #4796 from wenottingham/get-our-finest-attributes
Fix SAML login when only certain attributes are set.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-21 15:51:43 +00:00
Keith Grant
5d840af223 fix typo, clarify test names 2019-09-20 13:45:22 -07:00
Keith Grant
1f149bb086 refactor encodeNoneDefaultQueryString 2019-09-20 13:41:30 -07:00
Keith Grant
508535be66 rework removeParams 2019-09-20 13:41:30 -07:00
Keith Grant
cb69cac62d split qs addParams into mergeParams and replaceParams for clarity 2019-09-20 13:41:30 -07:00
Keith Grant
3ea4a32940 qs cleanup, more tests 2019-09-20 13:41:30 -07:00
Keith Grant
d6f93737c4 improve qs test coverage, minor cleanup 2019-09-20 13:41:30 -07:00
Keith Grant
eb0c4fd4d4 refactor parseQueryString 2019-09-20 13:41:30 -07:00
Bill Nottingham
36571a1275 Fix SAML login when only certain attributes are set.
The user may not set all of saml_{attr,admin_attr,auditor_attr},
so don't assume they all exist.
2019-09-20 15:28:38 -04:00
softwarefactory-project-zuul[bot]
b2b475d1a6 Merge pull request #4742 from jlmitch5/searchv2
ui_next search updates

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-20 18:28:52 +00:00
Bill Nottingham
01177f3632 Add some sanitizations (from @jakemcdermott, @mabashian) 2019-09-20 13:58:12 -04:00
John Mitchell
ac530e1328 utilize far instead of function for search type 2019-09-20 13:49:00 -04:00
John Mitchell
9605d8049d rewrite search key type check to be a var instead of a function 2019-09-20 13:49:00 -04:00
John Mitchell
d2e335c7c5 revert restriction on defaultParams 2019-09-20 13:49:00 -04:00
John Mitchell
678fba1ffb fix tests with search updates 2019-09-20 13:48:59 -04:00
John Mitchell
34e1b8be1d make default params only accept page, page_size and order_by 2019-09-20 13:48:59 -04:00
John Mitchell
86029934ad selectively add icontains to only text-based searches 2019-09-20 13:48:59 -04:00
softwarefactory-project-zuul[bot]
ec3edb07e8 Merge pull request #4779 from omgjlk/proper-vault-headers
Use proper headers to auth with Vault

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-20 16:30:56 +00:00
softwarefactory-project-zuul[bot]
fcc61a5752 Merge pull request #4777 from jlmitch5/styleCleanupUiNext
assorted style cleanup in UI next

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-20 16:00:27 +00:00
beeankha
860715d088 More AWX docs edits 2019-09-20 11:32:10 -04:00
beeankha
e2be392f31 Edit AWX docs 2019-09-20 11:32:10 -04:00
mabashian
f49d566f17 Update failed snapshot 2019-09-20 11:05:18 -04:00
mabashian
83e413b0bf Fix prettier failures 2019-09-20 11:05:18 -04:00
John Mitchell
e68349b6b5 assorted style cleanup in UI next
- round all corners of combo fields
- make sure required asterisk is always before help popover ?
- bug: fix ? popover from opening lookups
- fix spacing of detail toggle for http error
2019-09-20 11:05:18 -04:00
softwarefactory-project-zuul[bot]
14cc203945 Merge pull request #4784 from fosterseth/fix-3646-ldapserverfielduri
fix for LDAPServerURIField error if number present in top-level-domain

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-20 15:00:46 +00:00
Seth Foster
ca5de6378a Fix LDAPServerURIField number in domain
- Bug: API error if LDAPServerURIField contains a number in the top level domain
- Add custom regex in LDAPServerURIField class that is passed to django
  URLValidator
- The custom regex allows for numbers to be present in the top level domain
- Unit tests check that valid URIs pass through URLValidator, and that
  invalid URIs raise the correct exception
- Related to issue #3646
2019-09-20 10:36:47 -04:00
Alex Corey
1ebe91cbf7 Adds delete button to job details and handle delete errors
After successful deletion of Job the user is nativated back to Jobs List.
If the job is not successfully deleted a alert modal pops up and on close
the user remains on Job Details page.
2019-09-19 17:34:18 -04:00
softwarefactory-project-zuul[bot]
154cda7501 Merge pull request #4782 from mabashian/inventory-lookup
Changes InventoriesLookup to InventoryLookup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-19 21:27:50 +00:00
Bill Nottingham
badba581fd Rename Automation Insights to Automation Analytics.
Fix user-facing code, don't worry about settings names.
2019-09-19 17:00:10 -04:00
mabashian
a6a50f0eb1 Changes InventoriesLookup to InventoryLookup and removes pluralization of lookup headers for Inventory and Project since only one can be selected. 2019-09-19 11:13:55 -04:00
softwarefactory-project-zuul[bot]
b00fc29cdc Merge pull request #4762 from shanemcd/devel
Fix cluster dev env

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-19 13:45:43 +00:00
softwarefactory-project-zuul[bot]
13f628f73d Merge pull request #4776 from mabashian/3924-icons
Fix 3rd party auth icon rendering in login modal

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-18 23:39:25 +00:00
Jesse Keating
e1bdbeaa5c Restore new style headers
This leads to having both the new style header and the old compatability
header. Best of both worlds!
2019-09-18 13:27:55 -07:00
Jesse Keating
b3c264bf21 Use proper headers to auth with Vault
Reading examples at
https://learn.hashicorp.com/vault/getting-started/apis show needing to
use `X-Vault-Token` header, instead of `Authorization`. Without this
header, the vault server would return a 400 status with an error message
of "missing client token". With this change AWX is now able to interface
with the Hashicorp backend.
2019-09-18 12:26:47 -07:00
mabashian
53992d41d5 Re-generate fontcustom .woff file. This should fix microsoft and google icon rendering on login modal. 2019-09-18 13:50:15 -04:00
softwarefactory-project-zuul[bot]
686d4fe26f Merge pull request #4769 from mabashian/4554-mgt-jobs-column
Fix management job column width issues

Reviewed-by: Michael Abashian
             https://github.com/mabashian
2019-09-17 18:35:47 +00:00
mabashian
774a4e32cc Fix management job column width issues 2019-09-17 13:45:20 -04:00
Shane McDonald
22441d280e Fix pg password in cluster dev env 2019-09-17 08:45:19 -04:00
softwarefactory-project-zuul[bot]
fe850c247f Merge pull request #4755 from rooftopcellist/fix_awx_pass
pass correct awx-dev password on startup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-16 23:28:01 +00:00
softwarefactory-project-zuul[bot]
c651029cdb Merge pull request #4756 from AlexSCorey/4744-JobSchedulers
fixes grid so action buttons stay in view

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-16 22:06:58 +00:00
Christian Adams
54d50d71ab pass correct awx-dev password on startup 2019-09-16 17:25:15 -04:00
Alex Corey
ef4f1df9bb fixes grid so action buttons stay in view 2019-09-16 16:27:10 -04:00
softwarefactory-project-zuul[bot]
b5fa1606bd Merge pull request #4369 from AlanCoding/workflow_limit
Implementation of WFJT limit & SCM_branch prompting

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-16 20:17:59 +00:00
softwarefactory-project-zuul[bot]
3139bc9248 Merge pull request #4723 from rebeccahhh/devel
expose schedule name for scheduled workflow node job

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-16 20:17:54 +00:00
softwarefactory-project-zuul[bot]
a6c0793695 Merge pull request #4753 from AlexSCorey/4423-LoggingRevertNoSave
allows user to save form after reverting

Reviewed-by: Alex Corey <Alex.swansboro@gmail.com>
             https://github.com/AlexSCorey
2019-09-16 19:26:27 +00:00
softwarefactory-project-zuul[bot]
5a24e223b7 Merge pull request #4743 from AlexSCorey/4523-InertWFJTLink
allows all WFJT  tabs to properly route to workflow visualizer

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-16 19:26:20 +00:00
AlanCoding
e3c1189f56 bump migration 2019-09-16 14:51:57 -04:00
AlanCoding
fdf9dd733b bump migration 2019-09-16 14:51:56 -04:00
Jake McDermott
9697e1befb comment fixup 2019-09-16 14:51:56 -04:00
Jake McDermott
84a8559ea0 psuedo -> pseudo 2019-09-16 14:51:56 -04:00
Jake McDermott
8ac8fb9016 add more details to workflow limit help text 2019-09-16 14:51:56 -04:00
AlanCoding
01bb32ebb0 Deal with limit prompting in factory 2019-09-16 14:51:56 -04:00
AlanCoding
711c240baf Consistently give WJ extra_vars as text 2019-09-16 14:51:56 -04:00
AlanCoding
291528d823 adjust UI unit tests again
bump migration

bump migration again
2019-09-16 14:51:56 -04:00
AlanCoding
1406ea3026 Fix missing places for ask_limit and ask_scm_branch 2019-09-16 14:51:55 -04:00
AlanCoding
e8581f6892 Implement WFJT prompting for limit & scm_branch
add feature to UI and awxkit

restructure some details of create_unified_job
  for workflows to allow use of char_prompts
  hidden field
avoid conflict with sliced jobs in char_prompts copy logic

update developer docs

update migration reference

bump migration
2019-09-16 14:51:53 -04:00
Rebeccah
fbf182de28 removed refernce to workflow job in parent schedule naming as it is unnecessary 2019-09-16 14:22:37 -04:00
Rebeccah
5fab9e418b added functional test to test new schedule functionality 2019-09-16 14:22:37 -04:00
Rebeccah
d39b931377 added in logic to check if the parent workflow has a schedule and onsolidated a couple import statements 2019-09-16 14:22:37 -04:00
Alex Corey
9028afab07 allows user to save form after reverting 2019-09-16 12:55:31 -04:00
softwarefactory-project-zuul[bot]
d3b413c125 Merge pull request #4752 from shanemcd/drop-pg-scl
Stop using PG SCL in dev env

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-16 16:40:11 +00:00
softwarefactory-project-zuul[bot]
ab1db04164 Merge pull request #4734 from rooftopcellist/awx-dev
Revert DB passwords for container installs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-16 16:09:15 +00:00
Shane McDonald
3b89e894db Stop using PG SCL in dev env 2019-09-16 11:41:13 -04:00
Christian Adams
bdbbb2a4a2 Fix authentication bug with container installs
- update awx-dev db password where needed
2019-09-15 19:52:41 -04:00
Alex Corey
9e8d0758c8 allows all WFJT tabs to properly route to workflow visualizer 2019-09-13 15:21:54 -04:00
softwarefactory-project-zuul[bot]
9f0657e19a Merge pull request #4714 from keithjgrant/4521-noti-template-type-switch
fix bugs when switching NTs to Webhook type

Reviewed-by: Keith Grant
             https://github.com/keithjgrant
2019-09-13 18:20:13 +00:00
softwarefactory-project-zuul[bot]
6bc09028ca Merge pull request #4741 from wenottingham/there-are-no-limits
Tweak license partial to properly show 'unlimited' for the value we consider unlimited.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-13 17:36:04 +00:00
softwarefactory-project-zuul[bot]
e1c7cd7e9f Merge pull request #4740 from ryanpetrello/pycharm-port
change the default port range for the sdb debugging tool

Reviewed-by: Seth Foster
             https://github.com/fosterseth
2019-09-13 17:32:15 +00:00
softwarefactory-project-zuul[bot]
806648af89 Merge pull request #4611 from ryanpetrello/license-updates
update trial license enforcement logic

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-13 17:27:01 +00:00
softwarefactory-project-zuul[bot]
3e3940efd5 Merge pull request #4733 from keithjgrant/4612-lookup-param-bugs
Prevent Lookup search filters from affecting other Lookups on page

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-13 17:01:18 +00:00
Ryan Petrello
662033db44 fix some awxkit flake8 failures 2019-09-13 12:14:33 -04:00
Elijah DeLee
eba69142f1 add subscriptions endpoint to awxkit 2019-09-13 12:14:33 -04:00
mabashian
8a29276a7d Fix whitespace 2019-09-13 12:14:32 -04:00
mabashian
611f163289 Make sure that the license page under settings has creds available 2019-09-13 12:14:31 -04:00
mabashian
113622c05e Moves initial system settings rest call out to resolve 2019-09-13 12:14:31 -04:00
mabashian
608567795d Add support for looking up and selecting licenses on license page 2019-09-13 12:14:30 -04:00
Ryan Petrello
29fd399b06 introduce a new API for generating licenses from candlepin creds 2019-09-13 12:14:29 -04:00
mabashian
04f458c007 Cleanup inline styles 2019-09-13 12:14:29 -04:00
mabashian
38a7d62745 Add support for custom error messaging on license page 2019-09-13 12:14:28 -04:00
mabashian
53925f5e98 Tweaks to the ux for saved creds 2019-09-13 12:14:27 -04:00
mabashian
2474a3a2ea Pull creds into license form if available via settings 2019-09-13 12:14:27 -04:00
mabashian
900fcbf87e Add rh username and pass to license form 2019-09-13 12:14:26 -04:00
Ryan Petrello
846e67ee6a update trial license enforcement logic 2019-09-13 12:14:25 -04:00
Bill Nottingham
98daee4823 Show unlimited licenses as unlimited.
Don't show 'hosts remaining' for unlimited licenses.
2019-09-13 12:07:35 -04:00
Ryan Petrello
5ed97e0f65 change the default port range for the sdb debugging tool
the current range conflicts w/ a port used by the pycharm editor
2019-09-13 11:55:43 -04:00
Keith Grant
e854b179e4 add test for Lookup clearing QS params 2019-09-13 08:48:17 -07:00
Keith Grant
26e320582a namespace qs params for each lookup separately 2019-09-13 08:48:17 -07:00
Keith Grant
ee864b2df3 clear Lookup query params when lookup is closed 2019-09-13 08:48:17 -07:00
Keith Grant
e309ad25e4 de-lint 2019-09-13 08:45:19 -07:00
Keith Grant
55244834a3 fix bugs when switching NTs to Webhook type 2019-09-13 08:45:19 -07:00
softwarefactory-project-zuul[bot]
4e1fbb3e91 Merge pull request #4731 from ryanpetrello/job-event-contains-workflow
record the parent workflow ID for job events that originate from a WFJT

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-13 15:40:25 +00:00
softwarefactory-project-zuul[bot]
fe43bab174 Merge pull request #4727 from jakemcdermott/fix-4726
show extra vars on workflow template schedules

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-13 14:33:44 +00:00
softwarefactory-project-zuul[bot]
ed692018cd Merge pull request #4732 from ryanpetrello/cli-migrating
cli: show a better error if AWX is migrating

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-13 13:50:14 +00:00
Jake McDermott
311860e027 show extra vars on workflow template schedules
When the workflow job template prompts for extra vars, we show the
extra vars input field on the scheduler.
2019-09-13 09:12:15 -04:00
Ryan Petrello
b5225bd80d record the parent WFJ ID for job events that originate from a WFJT 2019-09-13 08:28:32 -04:00
softwarefactory-project-zuul[bot]
60fc952716 Merge pull request #4730 from shanemcd/fix-entrypoint-args
Consolidate scl enable calls

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 23:10:47 +00:00
Ryan Petrello
9d93cf8021 cli: show a better error if AWX is migrating
see: https://github.com/ansible/awx/issues/4721
2019-09-12 17:16:16 -04:00
Shane McDonald
fe0db4e329 Consolidate scl enable calls 2019-09-12 15:43:09 -04:00
Shane McDonald
3c0a0e1f4a Fix arg parsing in entrypoint 2019-09-12 15:12:04 -04:00
softwarefactory-project-zuul[bot]
70057bc0f2 Merge pull request #4058 from rooftopcellist/pg10
Postgres 10 Upgrade

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 18:58:34 +00:00
Shane McDonald
b2e8e3cc3d Add scl enable back to start_tests script
I think we need to specify the entrypoint in the pod definition too
2019-09-12 14:03:08 -04:00
Shane McDonald
804ec0dde9 Handle SCL enable in one place 2019-09-12 13:54:32 -04:00
softwarefactory-project-zuul[bot]
3e6131c509 Merge pull request #4724 from dsesami/flake-fixes
flake fixes for e2e

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 17:48:27 +00:00
Shane McDonald
e7bb5ac3e4 Fix tests 2019-09-12 13:41:41 -04:00
Daniel Sami
f2ccce3478 flake fixes for e2e 2019-09-12 13:05:35 -04:00
Shane McDonald
036567817e Implement local docker pg upgrade 2019-09-12 12:52:43 -04:00
Christian Adams
ec1e93cc69 Upgrade to postgres 10.6
- use awx-python in shebang in dev env
  - scl enable where needed for rhel7 & container installs
  - use scram-sha-256 pg user hashing by default
  - ensure psycopg2 is using the correct PG_CONFIG at build time for the right libpq version
2019-09-12 12:52:43 -04:00
Jose OrPa
04ab736f09 #3778 Upgrading postgresql to v10 2019-09-12 12:52:42 -04:00
softwarefactory-project-zuul[bot]
ffc6e2218e Merge pull request #4627 from rooftopcellist/upload_directly
Upload directly

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 14:40:53 +00:00
softwarefactory-project-zuul[bot]
253e0765bd Merge pull request #4719 from ryanpetrello/runner-on-start
add metadata for new runner_on_start events

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 14:06:07 +00:00
softwarefactory-project-zuul[bot]
2d78534223 Merge pull request #4674 from AlanCoding/clean_galaxy_out
Use project verbosity without color for galaxy commands

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 13:54:27 +00:00
softwarefactory-project-zuul[bot]
34645523fd Merge pull request #4718 from Spredzy/proper-args
e2e/test: NPMRC_FILE is a build-arg not an environment variable

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 13:40:50 +00:00
Ryan Petrello
90c7514303 add metadata for new runner_on_start events
see: https://github.com/ansible/awx/issues/4129
2019-09-12 09:05:54 -04:00
Yanis Guenane
3c22f99234 e2e/test: NPMRC_FILE is a build-arg not an environment variable 2019-09-12 14:39:28 +02:00
softwarefactory-project-zuul[bot]
d8fbf1e21a Merge pull request #4706 from ryanpetrello/faster-dashboard
optimize dashboard performance for larger UnifiedJob counts

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 10:51:42 +00:00
softwarefactory-project-zuul[bot]
168e03ea0e Merge pull request #4715 from ansible/cli-more-readme
cli: add instructions for using awx -h

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-12 01:37:05 +00:00
Ryan Petrello
3eecda4edc cli: add instructions for using awx -h 2019-09-11 20:43:20 -04:00
Ryan Petrello
c0d9600b66 WIP: optimize dashboard performance for larger UnifiedJob counts 2019-09-11 20:37:27 -04:00
softwarefactory-project-zuul[bot]
087b68aa65 Merge pull request #4713 from ryanpetrello/cli-readme
add a bit more detail to the awx CLI README

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2019-09-11 21:12:45 +00:00
Ryan Petrello
83ee4fb289 add a bit more detail to the awx CLI README 2019-09-11 16:24:13 -04:00
softwarefactory-project-zuul[bot]
51a724451c Merge pull request #4677 from marshmalien/4430-host-details-modal
[ui_next] Add host details modal

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-11 18:09:52 +00:00
Christian Adams
6309c0a426 Upload using RH cred settings 2019-09-11 13:24:09 -04:00
softwarefactory-project-zuul[bot]
14ef06854d Merge pull request #4711 from Spredzy/pass-npmrc
e2e/cluster: Allow one to pass a npmrc config file

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-11 15:49:22 +00:00
Marliana Lara
ad2e58cd43 Align the top of the modal to a fixed distance from the top of the
browser
2019-09-11 11:48:17 -04:00
Yanis Guenane
2ea280bbaf Dockerfile: Allow one to pass a npmrc file 2019-09-11 17:08:33 +02:00
softwarefactory-project-zuul[bot]
788c5d3741 Merge pull request #4709 from dsesami/flake-wait
Added a longer timeout for spinny specifically

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-11 14:39:05 +00:00
Yanis Guenane
0e5abb5fa3 Revert "add npm registry arg"
This reverts commit 844f3fde72.
2019-09-11 16:12:50 +02:00
Daniel Sami
5dbcafc392 Added a longer timeout for spinny specifically 2019-09-11 08:59:20 -04:00
Marliana Lara
e53c979344 Show changed status when the status is both ok and changed 2019-09-10 17:09:25 -04:00
Marliana Lara
2527a78874 Combine host and job status icons into one generic status icon 2019-09-10 17:06:53 -04:00
Marliana Lara
871f2cf9c5 Add host event modal tests and code cleanup 2019-09-10 16:29:25 -04:00
softwarefactory-project-zuul[bot]
f3dc4abe37 Merge pull request #4702 from AlexSCorey/4446-TokenDelete
Tokens Properly reload after successful deletion

Reviewed-by: Alex Corey <Alex.swansboro@gmail.com>
             https://github.com/AlexSCorey
2019-09-10 20:28:35 +00:00
softwarefactory-project-zuul[bot]
7646185e2c Merge pull request #4704 from keithjgrant/4522-save-nt-after-fixing-form-errors
Fix Notification Template form validation of headers field

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 19:56:33 +00:00
softwarefactory-project-zuul[bot]
a9a1c6eb6d Merge pull request #4683 from dsesami/npm-registry-arg
Add npm registry arg

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 19:56:25 +00:00
softwarefactory-project-zuul[bot]
4b1706401f Merge pull request #4686 from mabashian/ui_next-ux-improvements
Various UX improvements

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 19:44:22 +00:00
Keith Grant
8192b79b1f fix NT validation of headers after saving 2019-09-10 10:45:19 -07:00
softwarefactory-project-zuul[bot]
8868fa6416 Merge pull request #4689 from mabashian/search-tag-key
Display search key along with value in tag

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 17:28:03 +00:00
softwarefactory-project-zuul[bot]
71215d3d03 Merge pull request #4690 from mabashian/npm-audit
Upgrades lodash and angular-moment

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-09-10 17:20:05 +00:00
softwarefactory-project-zuul[bot]
5193209ca7 Merge pull request #4699 from mabashian/4549-not-found
Don't render the 404 not found page until the content's finished loading

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 17:14:32 +00:00
softwarefactory-project-zuul[bot]
d73dd02e5b Merge pull request #4628 from saito-hideki/issue/4528
Fix condition to show prompt button on the schedule add/edit form

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 16:59:03 +00:00
Alex Corey
e23c1477da Properly reloads after successful deletion 2019-09-10 12:13:41 -04:00
softwarefactory-project-zuul[bot]
19d6941034 Merge pull request #4697 from ryanpetrello/cli-human-uniqueness
cli: fix a minor bug in uniqueness rule detection

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 15:01:34 +00:00
mabashian
d4b2cacb3e Don't render the 404 not found page until the content's finished loading 2019-09-10 10:30:17 -04:00
softwarefactory-project-zuul[bot]
2f7476c804 Merge pull request #4692 from ryanpetrello/cli-detail-options
cli: make "detail" actions actually respect Allow: headers

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 14:18:12 +00:00
Ryan Petrello
39ee60a913 cli: fix a minor bug in uniqueness rule detection 2019-09-10 10:17:09 -04:00
mabashian
da43b9b84c Prettify FilterTags 2019-09-10 10:08:42 -04:00
softwarefactory-project-zuul[bot]
eaf3a28d57 Merge pull request #4695 from ryanpetrello/oauth-token-exclusive-lock
move the oauth2 last_used update to the bottom of the request

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-10 12:55:15 +00:00
Ryan Petrello
14f8ef4f44 move the oauth2 last_used update to the bottom of the request
this avoids acquiring a row lock (and holding it for the duration of
transactions which include a very slow query)
2019-09-10 08:15:13 -04:00
Ryan Petrello
ee47e98c50 cli: make "detail" actions actually respect Allow: headers 2019-09-09 21:11:15 -04:00
softwarefactory-project-zuul[bot]
edb7ddb9ae Merge pull request #4687 from AlexSCorey/4685-LookUpPluralization
Adds proper pluralization to Look Up modal empty state

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-09 21:23:32 +00:00
mabashian
f69f43e3ba Upgrades lodash and angular-moment 2019-09-09 16:31:11 -04:00
softwarefactory-project-zuul[bot]
d9a7859a05 Merge pull request #4630 from ryanpetrello/cli-roles
cli: add support for granting and revoking roles from users/teams

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-09 20:19:12 +00:00
softwarefactory-project-zuul[bot]
ff32a5286e Merge pull request #4688 from ryanpetrello/human-format-null
fix a human format bug for settings

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-09 20:08:59 +00:00
mabashian
629e2e89b9 Fix linting error 2019-09-09 15:50:41 -04:00
mabashian
ea015190de Display search key along with value in tag 2019-09-09 15:41:39 -04:00
Ryan Petrello
6762702868 cli: add support for granting and revoking roles from users/teams 2019-09-09 15:27:16 -04:00
Ryan Petrello
3e97608914 fix a human format bug for settings 2019-09-09 15:25:04 -04:00
Alex Corey
a95394b135 Adds proper pluralization to Look Up modal empty state 2019-09-09 14:55:39 -04:00
softwarefactory-project-zuul[bot]
276b577103 Merge pull request #4648 from ryanpetrello/format-metrics-human
cli: add special code for formatting metrics and settings with -f human

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-09 18:52:29 +00:00
softwarefactory-project-zuul[bot]
b1666f2692 Merge pull request #4653 from ryanpetrello/attach-detach-by-name
cli: add support for attach/detaching creds/notifications via name

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-09-09 18:52:22 +00:00
mabashian
1f8f4e184b Various UX improvements 2019-09-09 12:54:31 -04:00
Daniel Sami
844f3fde72 add npm registry arg 2019-09-09 11:56:10 -04:00
softwarefactory-project-zuul[bot]
a3a5db1c44 Merge pull request #4678 from wenottingham/cloudy-with-a-chance-of-updates
Update assorted cloud module requirements.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-08 19:42:45 +00:00
softwarefactory-project-zuul[bot]
28630cb7fa Merge pull request #4650 from keithjgrant/4431-jt-form-advanced-fields
4431 jt form advanced fields

Reviewed-by: Keith Grant
             https://github.com/keithjgrant
2019-09-06 23:02:08 +00:00
Keith Grant
820605b0ca fix JT form tests 2019-09-06 14:29:00 -07:00
softwarefactory-project-zuul[bot]
bc79093102 Merge pull request #4679 from ryanpetrello/fix-doc-819
fix up a minor Swagger doc bug

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2019-09-06 21:15:34 +00:00
Ryan Petrello
eb2fc80114 fix up a minor Swagger doc bug 2019-09-06 16:28:06 -04:00
Bill Nottingham
eb2de51f86 add licenses for new azure deps 2019-09-06 15:55:16 -04:00
Bill Nottingham
7aa94a9bb5 Update assorted cloud module requirements.
Update boto3 for ec2_transit_gateway module.
Update Azure requirements to sync with Ansible 2.9 branch.
2019-09-06 15:30:08 -04:00
Keith Grant
be6f5e18ae fixing JT Form tests post-rebase 2019-09-06 11:35:24 -07:00
Keith Grant
9777b79818 hide overflow in ExpandingContainer while opening 2019-09-06 09:59:58 -07:00
Marliana Lara
25aa9bc43e Change empty state text 2019-09-06 12:52:44 -04:00
Marliana Lara
a79de2b4ed Fix existing test failures 2019-09-06 12:44:11 -04:00
Marliana Lara
7480baf256 Add host event modal 2019-09-06 12:43:53 -04:00
Marliana Lara
5babab7af4 Add host status icon and pull status styles into separate file 2019-09-06 12:43:17 -04:00
Keith Grant
4e73f4b778 show all advanced JT fields on edit form 2019-09-06 09:14:19 -07:00
softwarefactory-project-zuul[bot]
4f05955724 Merge pull request #4671 from gamuniz/fix_204_insights_api
fixed insights api 204 errors

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-06 16:03:46 +00:00
AlanCoding
ebc369bfef Use project verbosity without color for galaxy commands 2019-09-06 11:02:20 -04:00
Ben Thomasson
10d53637ad Changes uploader to use the insights api directly 2019-09-06 10:58:35 -04:00
Gabe Muniz
23a7151278 fixed insights api 204 errors 2019-09-06 09:27:17 -04:00
Keith Grant
0254cf3567 wire-in instance groups to JT form 2019-09-05 16:47:34 -07:00
softwarefactory-project-zuul[bot]
f91a02a9e4 Merge pull request #4661 from ansible/apurva_wait_for_job_fix
awxkit: don't suppress error when job does not exist

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-05 21:37:15 +00:00
Keith Grant
93b794eaa7 JT Form fixes after rebase 2019-09-05 13:45:30 -07:00
softwarefactory-project-zuul[bot]
927c99a2f4 Merge pull request #4667 from AlanCoding/update_fix
fix project sync revision bug

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-05 20:29:10 +00:00
softwarefactory-project-zuul[bot]
b4759de30d Merge pull request #4529 from wenottingham/the-pirates-are-bringing-r-bac
Fix display of indirect access permissions.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-05 17:40:44 +00:00
Apurva Bakshi
11a71f5ffa fix attribute error 2019-09-05 13:16:39 -04:00
Ryan Petrello
064f871fff add special code for formatting metrics and settings with -f human
see: https://github.com/ansible/awx/issues/4566
2019-09-05 11:55:23 -04:00
softwarefactory-project-zuul[bot]
ffbce2611a Merge pull request #4656 from wenottingham/collection-fix
Revert 9b95cc27c4.

Reviewed-by: Alan Rominger <arominge@redhat.com>
             https://github.com/AlanCoding
2019-09-05 13:50:18 +00:00
softwarefactory-project-zuul[bot]
8b9ddb5922 Merge pull request #4663 from ryanpetrello/fix-3741
fix a 500 error that can occur when a WorkflowApproval's node is deleted

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
             https://github.com/beeankha
2019-09-05 13:41:06 +00:00
AlanCoding
c65b77a20a fix project sync revision bug 2019-09-05 08:49:52 -04:00
Ryan Petrello
b7e8044d69 fix a 500 error that can occur when a WorkflowApproval's node is deleted 2019-09-04 21:12:22 -04:00
Keith Grant
8b1ca12d8f update JobTemplateForm tests 2019-09-04 15:54:30 -07:00
Keith Grant
4f546be87a add JT form callback fields 2019-09-04 14:35:39 -07:00
Keith Grant
e6475f21f6 flush out JT form; upgrade enzyme; add CheckboxField 2019-09-04 14:34:57 -07:00
Keith Grant
218348412b creat TagMultiSelect component; cleanup MultiSelect 2019-09-04 14:22:08 -07:00
Bill Nottingham
db64717551 Merge pull request #2 from AlanCoding/collection-fix-fix
Fix collection precedence bug, add new to left of list
2019-09-04 17:01:30 -04:00
Keith Grant
9edc686ab5 add generic onChange prop to MultiSelect 2019-09-04 13:58:32 -07:00
softwarefactory-project-zuul[bot]
c819a78a4b Merge pull request #4647 from rebeccahhh/devel
Added 'rescued' and 'ignored' fields into all_hosts dictionary update

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-04 20:48:04 +00:00
AlanCoding
11146a071f Fix collection precedence bug, add new to left of list 2019-09-04 15:32:03 -04:00
Keith Grant
4d31d83e1e add instance groups to JT form 2019-09-04 11:22:02 -07:00
Keith Grant
3a9a884bbc add omitProps helper 2019-09-04 11:19:05 -07:00
Keith Grant
8a31be6ffe refactor lookup components 2019-09-04 11:19:05 -07:00
Keith Grant
6fd86fed65 add jt advanced fields 2019-09-04 10:45:34 -07:00
softwarefactory-project-zuul[bot]
4edfe7e5fc Merge pull request #4658 from ryanpetrello/7.0.0-release
Bump VERSION to 7.0.0

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-04 17:27:01 +00:00
Brian Coca
9d48ba4243 better error message on missing runner 2019-09-04 13:16:55 -04:00
Keith Grant
80bdb1a67a add CollapsibleSection & ExpandingContainer components 2019-09-04 09:55:24 -07:00
Ryan Petrello
1fc210d002 Bump VERSION to 7.0.0 2019-09-04 12:48:52 -04:00
softwarefactory-project-zuul[bot]
4bcb941df9 Merge pull request #4655 from ryanpetrello/cli-py2-u-marker
cli: fix a -f human formatting bug in py2

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-04 16:18:58 +00:00
Bill Nottingham
24c16b1c58 Fix to enable system paths along with requirements override, from @alancoding. 2019-09-04 11:43:48 -04:00
Bill Nottingham
0fb7c859f4 Revert 9b95cc27c4.
We do not want to create a new setting for a on-Tower-host global
collection path at this time.
2019-09-04 11:43:33 -04:00
Ryan Petrello
dbfe85da53 cli: fix a -f human formatting bug in py2
if we encounter non-strings in JSON responses, attempt to represent them
as JSON, instead of stringify-ing them (in py2, stringify-ing adds `u`
markers, which is confusing to users)
2019-09-04 11:10:12 -04:00
softwarefactory-project-zuul[bot]
66907151a0 Merge pull request #4651 from ryanpetrello/py2-argparse-alias
cli: add support for deprecated tower-cli aliases in py2

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-04 14:24:15 +00:00
softwarefactory-project-zuul[bot]
8a1a3918f1 Merge pull request #4641 from mabashian/upgrade-react
Ensure react 16.8 or greater is used

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-04 14:18:19 +00:00
softwarefactory-project-zuul[bot]
7418453d6f Merge pull request #4652 from ryanpetrello/cli-file-load-bug
cli: fix a bug introduced in @ file support

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-04 02:30:10 +00:00
Ryan Petrello
1e5bcca0b9 cli: add support for attach/detaching creds/notifications via name 2019-09-03 21:51:39 -04:00
Ryan Petrello
70989ca616 cli: fix a bug introduced in @ file support 2019-09-03 21:33:46 -04:00
Ryan Petrello
b888c4b75a cli: add support for deprecated tower-cli aliases in py2 2019-09-03 21:22:49 -04:00
Rebeccah
daba25f107 added 'ignored' and 'rescued' into all_hosts dictionary update 2019-09-03 18:58:29 -04:00
softwarefactory-project-zuul[bot]
ba8b876dd3 Merge pull request #4640 from ryanpetrello/cli-lookup-by-name
cli: add ability to specify a name instead of primary key

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-03 22:09:10 +00:00
Ryan Petrello
4ec5e82023 cli: add ability to specify a name instead of primary key 2019-09-03 17:27:10 -04:00
softwarefactory-project-zuul[bot]
392fc803fa Merge pull request #4646 from rooftopcellist/rm_mk_dbshell
remove redundant dbshell make target

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-03 19:43:58 +00:00
softwarefactory-project-zuul[bot]
b62c0c57cb Merge pull request #4644 from ryanpetrello/sos-license
include license data/state in the sosreport

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-03 19:41:21 +00:00
Christian Adams
70f9f09fef remove redundant dbshell make target 2019-09-03 14:22:07 -04:00
Ryan Petrello
7a8234bb09 include license data/state in the sosreport 2019-09-03 13:56:02 -04:00
mabashian
120190eb82 Ensure react 16.8 or greater is used 2019-09-03 12:24:13 -04:00
softwarefactory-project-zuul[bot]
f21c6dc330 Merge pull request #4624 from ryanpetrello/cli-association
cli: implement support for credential and notification association

Reviewed-by: Elijah DeLee <kdelee@redhat.com>
             https://github.com/kdelee
2019-09-03 14:53:44 +00:00
softwarefactory-project-zuul[bot]
45f9457abe Merge pull request #4626 from ryanpetrello/more-cli-doc-examples
cli: add support for loading JSON/YAML w/ the ansible-like @ syntax

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-09-03 13:09:29 +00:00
Hideki Saito
9d2441789e Fix condition to show prompt button on the schedule add/edit form
it hides the prompt button on survey form when prompt is extra vars only.

- Fixed issue #4528

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-09-03 02:15:14 +00:00
softwarefactory-project-zuul[bot]
09c105e125 Merge pull request #4631 from wenottingham/stop-me-before-i-touch-javascript-again
Fix fetching of result traceback in job details.

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-08-30 22:01:38 +00:00
Jake McDermott
a7db4cf367 set result traceback state on sync and send it to subscribers 2019-08-30 17:05:33 -04:00
Bill Nottingham
a0671bd36a Fix fetching of result traceback in job details.
Add it to the list of things to subscribe to and fetch at the end.
2019-08-30 17:05:33 -04:00
Bill Nottingham
b4f6b380fd Show a tooltip for indirect permissions to show where they come from. 2019-08-30 16:28:39 -04:00
softwarefactory-project-zuul[bot]
fd32eff281 Merge pull request #4632 from ryanpetrello/adhoc-event-log-agg
send adhoc command events to the external job_event logger

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-30 19:47:12 +00:00
Ryan Petrello
8d251c2f2e send adhoc command events to the external job_event logger
see: https://github.com/ansible/awx/issues/4545
2019-08-30 15:08:25 -04:00
Ryan Petrello
8e58a4a7de cli: add support for loading JSON/YAML w/ the ansible-like @ syntax 2019-08-30 00:51:46 -04:00
softwarefactory-project-zuul[bot]
8dc1737419 Merge pull request #4609 from mabashian/4429-deps
Update Patternfly and Axios deps

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-29 22:30:05 +00:00
softwarefactory-project-zuul[bot]
3c82785eb3 Merge pull request #4625 from beeankha/approval_timeout_websocket
Update Approval Node Count in the Event of a Timeout

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-29 21:15:06 +00:00
mabashian
7ae9e13321 A better fix for the tab bottom border 2019-08-29 16:19:54 -04:00
beeankha
2fc7e93c6a Emit websocket for approval node timeout
...and update timeout_message to be more translation-friendly.
2019-08-29 14:30:33 -04:00
Ryan Petrello
88dfcaa439 cli: implement support for credential and notification association 2019-08-29 13:11:02 -04:00
mabashian
7c81ec0df5 Linting cleanup. Also fixed error thrown to console around passing Link to the DropdownItem component. 2019-08-29 11:18:34 -04:00
softwarefactory-project-zuul[bot]
9571801e9f Merge pull request #4347 from AlanCoding/no_read_role
Kill off all model can_read access methods

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-08-29 14:38:44 +00:00
softwarefactory-project-zuul[bot]
33f2b0bf1a Merge pull request #4610 from ryanpetrello/cli-cleanup-injectors-language
fix a few minor CLI bugs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-29 14:15:48 +00:00
softwarefactory-project-zuul[bot]
226d507013 Merge pull request #4619 from rooftopcellist/cloud_rh_settings
Add Settings for license & automation analytics creds

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-29 14:05:45 +00:00
Christian Adams
eacd356881 fix wording in settings for license & automation analytics creds 2019-08-29 09:32:50 -04:00
Ryan Petrello
a107a17bc9 fix a few minor CLI bugs
see: https://github.com/ansible/awx/issues/4608
2019-08-29 08:54:17 -04:00
softwarefactory-project-zuul[bot]
2918b6c927 Merge pull request #4264 from beeankha/workflow_pause_approve
Workflow Approval Nodes

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2019-08-28 22:25:39 +00:00
John Mitchell
56c6944049 add ui fields to configure tower in tower for automation analytics fields 2019-08-28 13:54:15 -04:00
Christian Adams
1a78c16adf add settings for license & automation analytics creds 2019-08-28 12:39:28 -04:00
Bianca Henderson
97d9c264f9 Merge pull request #14 from mabashian/workflow_pause_approve_cleanup_5
Styles cleanup
2019-08-28 10:14:43 -04:00
mabashian
f229418ae2 Styles cleanup 2019-08-28 10:00:41 -04:00
beeankha
073f6dbf07 Fix flake8 error 2019-08-28 09:33:15 -04:00
softwarefactory-project-zuul[bot]
3d4cd1b575 Merge pull request #4511 from AlexSCorey/multiSelecBug
Allows user to hit enter to create label, fixes console errors.

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-08-27 22:43:16 +00:00
Jake McDermott
04f7218b4a also make labels work for add view 2019-08-27 17:41:54 -04:00
Alex Corey
fbe6abfb53 Allows user to hit enter to create label, fixes console errors. 2019-08-27 17:37:23 -04:00
softwarefactory-project-zuul[bot]
8be46e43b4 Merge pull request #4600 from ryanpetrello/cli-json-inputs
cli: improve parsing of JSON inputs

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-27 20:33:51 +00:00
mabashian
5f1f4bd109 Update Patternfly and Axios deps 2019-08-27 16:21:24 -04:00
Ryan Petrello
23f75cf74a fix a bug introduced in rebase 2019-08-27 15:59:16 -04:00
Ryan Petrello
b9f75ecad7 update migration numbering for WF approval 2019-08-27 15:42:49 -04:00
beeankha
2ac1c3d1e1 Update timeout info on AWX docs. 2019-08-27 15:38:19 -04:00
Ryan Petrello
1eeab7e0d5 add approval timeout to the summary fields for WorkflowJobTemplateNodes 2019-08-27 15:38:18 -04:00
beeankha
459012e879 Fix 500 error on workflow_approvals endpoint 2019-08-27 15:38:17 -04:00
beeankha
2e58a47118 Minor change to fix rebase conflict. 2019-08-27 15:38:16 -04:00
beeankha
b2819793df Set view's permission classes to be more explicit 2019-08-27 15:38:16 -04:00
beeankha
ea509f518e Addressing comments, updating tests, etc. 2019-08-27 15:38:15 -04:00
mabashian
9f0307404e Fix loading pending approval count on login 2019-08-27 15:38:14 -04:00
beeankha
703de8f3c0 Edit minor typo 2019-08-27 15:38:14 -04:00
beeankha
b5c0f58137 Add test for approve node denial 2019-08-27 15:38:13 -04:00
beeankha
8b23ff71b4 Update/add more functional tests 2019-08-27 15:38:12 -04:00
beeankha
582bbda9c4 Fix bug in Activity Stream, add tests. 2019-08-27 15:38:11 -04:00
mabashian
3fa9497e3c Various bug fixes and minor ux enhancements 2019-08-27 15:38:10 -04:00
mabashian
5fc3b2c3f5 Add timed out text to workflow job node. Change timeout to minutes and seconds.
Remove workflow template badge in approvals drawer.
2019-08-27 15:38:09 -04:00
beeankha
9bbc14c5a1 Update AWX docs to include info about wf approvals 2019-08-27 15:38:09 -04:00
beeankha
aab04bcbb1 Fix accidental deletions, update docstrings...
... and update migration file for rebase.
2019-08-27 15:38:08 -04:00
beeankha
667fce5012 Fix flake8 errors, update doc strings, ...
... and return full object details when doing a POST to create new approval nodes.
2019-08-27 15:37:22 -04:00
Ryan Petrello
dd89e46ee6 change up a few activity stream and approval drawer issues 2019-08-27 15:36:32 -04:00
mabashian
aac8c9fb04 Rename workflow approval migration. Add approval option back to workflow node form. 2019-08-27 15:36:32 -04:00
beeankha
cf436eea37 Update RBAC for adding approval nodes 2019-08-27 15:36:31 -04:00
beeankha
f7d6f4538c Emit approve/deny status for websockets, update doc string + a comment 2019-08-27 15:36:30 -04:00
Ryan Petrello
761dad060c allow org/WF admins to create approval templates 2019-08-27 15:36:30 -04:00
mabashian
73485b220e fix jshint errors 2019-08-27 15:36:29 -04:00
Elijah DeLee
bdf4defdbe Add approval node logic to awxkit
Co-authored-by: <Apurva bakshiapurva93@gmail.com>
2019-08-27 15:36:29 -04:00
mabashian
adf621d2cf Timeout, socket and activity stream changes for workflow pause approve 2019-08-27 15:36:28 -04:00
beeankha
9186cb23a6 Update summary field for activity stream 2019-08-27 15:36:27 -04:00
beeankha
f6f6e5883a Update websockets for pending approvals, change timeout expiration to 2019-08-27 15:36:27 -04:00
Ryan Petrello
7814592285 when copying workflows w/ pause nodes, copy the WorkflowApprovalTemplate 2019-08-27 15:36:26 -04:00
Ryan Petrello
4a75edf549 fix a few nits w/ workflow approval activity stream records 2019-08-27 15:36:25 -04:00
beeankha
d9f3fed06f Update UJ/UJT endpoints, update approval RBAC, update approval timeout 2019-08-27 15:36:25 -04:00
beeankha
544a5063f3 Update timeout implementation, placeholder code for possible websocket support 2019-08-27 15:36:24 -04:00
beeankha
8c17990750 Activity stream and timeout
Update activity stream to show approval node info, add meaningful log
message for expired approval nodes in the Task Manager timeout
function.
2019-08-27 15:36:24 -04:00
Ryan Petrello
0522d45ab0 fixed a few issues related to approval role RBAC for normal users 2019-08-27 15:36:23 -04:00
beeankha
28289e85c1 Add timeout for workflow approval nodes 2019-08-27 15:36:22 -04:00
beeankha
5f82754a3f Clean up RBAC code 2019-08-27 15:36:22 -04:00
beeankha
296b4e830b Add more RBAC for approval nodes 2019-08-27 15:36:21 -04:00
mabashian
630f428d77 Cleanup a few jshint errors 2019-08-27 15:36:20 -04:00
mabashian
013792f0f8 Prompt bug cleanup. Filter workflow_approval jobs out of jobs list. Add initial support for timeout. 2019-08-27 15:36:20 -04:00
beeankha
3357c96774 Enable deletion of orphaned approval nodes
Update serializer to include workflow approval for activity stream
2019-08-27 15:36:19 -04:00
beeankha
64c94d478d Add more RBAC, filter out AJT/AJs from unified jobs lists
Comment out placeholder in serializer
2019-08-27 15:36:17 -04:00
beeankha
453e142635 Fix UJT-related error, add notification placeholders 2019-08-27 15:35:43 -04:00
beeankha
24c5404c25 Fix error related to workflow_approval_templates/N endpoint 2019-08-27 15:30:50 -04:00
mabashian
4a801c60b9 Cleanup and changes to the way approval templates are created 2019-08-27 15:30:49 -04:00
beeankha
294d6551b9 Polishing up work on new endpoint 2019-08-27 15:30:48 -04:00
beeankha
320284267c Add new endpoint for creation of approval nodes 2019-08-27 15:30:47 -04:00
mabashian
83f9681941 Fix jshint errors 2019-08-27 15:30:47 -04:00
mabashian
e0cdc4ff80 Approval drawer cleanup and workflow node form UX cleanup 2019-08-27 15:30:46 -04:00
mabashian
1d814beca1 Fix linting error 2019-08-27 15:30:45 -04:00
mabashian
0720857022 Add initial support for workflow pause approve 2019-08-27 15:30:44 -04:00
beeankha
82e0b2121b Add approve/deny endpoints, fix some typos 2019-08-27 15:30:43 -04:00
beeankha
d76e9125e8 Clean up redundancies 2019-08-27 15:30:42 -04:00
beeankha
9024a514a6 Add API endpoints for workflow approvals 2019-08-27 15:30:39 -04:00
beeankha
72a65f74fd Add migration file 2019-08-27 15:29:34 -04:00
beeankha
b88b1111bd Add workflow pause/approve node 2019-08-27 15:29:30 -04:00
Ryan Petrello
f22adca6f7 improve parsing of JSON inputs
see: https://github.com/ansible/awx/issues/4573
see: https://github.com/ansible/awx/issues/2371
2019-08-27 12:47:27 -04:00
softwarefactory-project-zuul[bot]
534c4e776a Merge pull request #4291 from jladdjr/templated_messages
Templated notifications

Reviewed-by: Jim Ladd
             https://github.com/jladdjr
2019-08-27 16:29:21 +00:00
softwarefactory-project-zuul[bot]
187360a8ad Merge pull request #4605 from ryanpetrello/cli-inventory-alias
cli: add an alias for `awx inventories`

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-27 15:40:18 +00:00
softwarefactory-project-zuul[bot]
8ae93848db Merge pull request #4564 from rooftopcellist/manifest_destiny
add collection version tracker & query info

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-27 15:09:17 +00:00
Ryan Petrello
036a04c918 cli: add an alias for awx inventories 2019-08-27 10:38:28 -04:00
softwarefactory-project-zuul[bot]
92b9176455 Merge pull request #4517 from jakemcdermott/fix-akit-shell-init
fix akit shell init when no credential config is provided

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-27 14:36:34 +00:00
softwarefactory-project-zuul[bot]
1a01fdb02d Merge pull request #4604 from ryanpetrello/host-not-hosts
cli: fix an awx CLI alias typo

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2019-08-27 14:36:30 +00:00
Christian Adams
78c0d531bc Adds versions to analytics collectors and manifest file.
- adds 'query_info.json' to contain collection metadata
  - adds 'manifest.json' to contain collection file version info
2019-08-27 10:14:14 -04:00
Ryan Petrello
5bd61823ab cli: fix an awx CLI alias typo
see: https://github.com/ansible/awx/issues/4603
2019-08-27 09:24:04 -04:00
softwarefactory-project-zuul[bot]
9e849ad3e6 Merge pull request #4596 from ryanpetrello/fix-cli-required-args
cli: fix a few bugs related to required OPTIONS

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-26 21:47:46 +00:00
softwarefactory-project-zuul[bot]
073c4322a3 Merge pull request #4582 from marshmalien/4233-playbook-field
Add playbook select and project field validation

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-26 21:20:13 +00:00
softwarefactory-project-zuul[bot]
38a5355574 Merge pull request #4591 from ryanpetrello/cli-command-help
cli: make --help work properly for custom commands

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-26 20:11:43 +00:00
softwarefactory-project-zuul[bot]
0bebc0febc Merge pull request #4594 from ryanpetrello/fix4565
cli: print a newline after HTTP JSON errors

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-26 20:05:07 +00:00
softwarefactory-project-zuul[bot]
c74f826e29 Merge pull request #4472 from rooftopcellist/collection_org_job_info
Send job & org data

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2019-08-26 19:44:08 +00:00
softwarefactory-project-zuul[bot]
5f02906b28 Merge pull request #4590 from ryanpetrello/workflow-job-creation
prevent POST on /api/v2/workflow_jobs/

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-26 19:44:04 +00:00
softwarefactory-project-zuul[bot]
0d8abba613 Merge pull request #4597 from rooftopcellist/fix_encryption_typo
fix typo in comment about encryption

Reviewed-by: awxbot
             https://github.com/awxbot
2019-08-26 19:37:22 +00:00
Ryan Petrello
ea36be3a0e cli: fix a few bugs related to required OPTIONS
see: https://github.com/ansible/awx/issues/4581
see: https://github.com/ansible/awx/issues/4583
see: https://github.com/ansible/awx/issues/4560
2019-08-26 15:25:28 -04:00
softwarefactory-project-zuul[bot]
7dd6306221 Merge pull request #4593 from ryanpetrello/fix-4567
cli: fix a bug when printing complex data structures w/ -f human

Reviewed-by: Elijah DeLee <kdelee@redhat.com>
             https://github.com/kdelee
2019-08-26 19:10:56 +00:00
softwarefactory-project-zuul[bot]
fbf19de993 Merge pull request #4592 from ryanpetrello/fix-4563
cli: remove --id flag from awx <resource> list

Reviewed-by: Elijah DeLee <kdelee@redhat.com>
             https://github.com/kdelee
2019-08-26 19:10:52 +00:00
Marliana Lara
b77160f575 Fix broken tests due to JobTemplateForm changes 2019-08-26 15:01:06 -04:00
Marliana Lara
156d03fa45 Add playbook select and project field validation 2019-08-26 15:00:59 -04:00
Ryan Petrello
6999d779a8 make --help work properly for custom commands
see: https://github.com/ansible/awx/issues/4559
2019-08-26 15:00:16 -04:00
Christian Adams
cf464c7cb1 fix typo in comment about encryption 2019-08-26 14:20:39 -04:00
Ryan Petrello
ce6905d54a cli: print a newline after HTTP JSON errors
see: https://github.com/ansible/awx/issues/4565
2019-08-26 12:44:00 -04:00
Ryan Petrello
1d2edc1d81 cli: fix a bug when printing complex data structures w/ -f human
see: https://github.com/ansible/awx/issues/4567
2019-08-26 12:41:35 -04:00
Ryan Petrello
f9230d9879 cli: remove --id flag from awx <resource> list
see: https://github.com/ansible/awx/issues/4563
2019-08-26 12:25:18 -04:00
Ryan Petrello
a89324defa prevent POST on /api/v2/workflow_jobs/ 2019-08-26 11:47:19 -04:00
softwarefactory-project-zuul[bot]
e19035079e Merge pull request #4557 from jlmitch5/fixPopoverClick
fix regression where clicking inside popover closed it

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-26 15:26:39 +00:00
Christian Adams
cd3645eb4d Send job & org data 2019-08-26 10:22:07 -04:00
softwarefactory-project-zuul[bot]
9baa9eee96 Merge pull request #4585 from ryanpetrello/system-job-creation
prevent POST on /api/v2/system_jobs/

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-26 13:50:45 +00:00
Keith Grant
901d41e261 show error for disallowed new lines in code mirror 2019-08-25 23:11:25 -07:00
Jim Ladd
a10ad58c75 Use custom webhook bodies as is (instead of as a sub-field in webhook) 2019-08-25 23:11:25 -07:00
Jim Ladd
774a310e10 Don't collect job_host_summaries if job is running 2019-08-25 23:11:25 -07:00
Jim Ladd
c8805cc55b No need to merge old/new notification messages if messages field is null 2019-08-25 23:11:25 -07:00
Jim Ladd
24a383c7c1 Set default messages (for each message type) to null 2019-08-25 23:11:25 -07:00
Jim Ladd
487276613f Fix issue where only one NT attached to UJT would be used to send notifications 2019-08-25 23:11:25 -07:00
Keith Grant
7a6e62c022 update e2e tests for disabled toggle switches 2019-08-25 23:11:24 -07:00
Jake McDermott
d068fef767 handle message validation errors 2019-08-25 23:11:24 -07:00
Jim Ladd
2b792573f8 set messages default 2019-08-25 23:11:24 -07:00
Jim Ladd
ec20081d74 bump migration 2019-08-25 23:11:24 -07:00
Jim Ladd
8158632344 render notification templates 2019-08-25 23:11:24 -07:00
Jim Ladd
1a1eab4dab create jinja context based on job serialization 2019-08-25 23:11:24 -07:00
Jim Ladd
13b9679496 save/validate messages 2019-08-25 23:11:24 -07:00
Jim Ladd
3bb0aa4eec serialize notification body 2019-08-25 23:11:23 -07:00
Jim Ladd
24c3903c30 add debug info for failed slack notification 2019-08-24 20:37:59 -07:00
Jim Ladd
7bf250ecfa show default messages in options 2019-08-24 20:37:59 -07:00
Jim Ladd
0ddc32a6dc sort notification_type 2019-08-24 20:37:58 -07:00
Jim Ladd
8ca79e3579 job notification data omits new host summary fields 2019-08-24 20:37:58 -07:00
Jim Ladd
ccdbd0510f Add support for grafana, rocketchat in awxkit 2019-08-24 20:37:58 -07:00
Jim Ladd
616db6bc51 Add support for messages field in awxkit 2019-08-24 20:37:58 -07:00
Jim Ladd
cb411cc3be Add messages field 2019-08-24 20:37:35 -07:00
Jim Ladd
efbaf46179 Docs update for notification templates 2019-08-23 17:43:20 -07:00
Keith Grant
5468624df5 fix ui lint errors 2019-08-23 17:43:20 -07:00
Keith Grant
15e6117472 fix webhook method default value 2019-08-23 17:43:20 -07:00
Keith Grant
62f31d6b3f fix console error on hidden syntax-highlight directive 2019-08-23 17:43:20 -07:00
Keith Grant
965dc79a0a update notifications UI for new default messages structure 2019-08-23 17:43:20 -07:00
Keith Grant
150de6a70b update notification messages for webhook/pagerduty 2019-08-23 17:43:20 -07:00
Keith Grant
56f04e0153 change custom notification message from checkbox to toggle 2019-08-23 17:43:20 -07:00
Keith Grant
1470fa61d5 open docs link in new tab 2019-08-23 17:43:20 -07:00
Keith Grant
1c79d21416 add custom notification message help text 2019-08-23 17:43:20 -07:00
Keith Grant
3c4862acfe preserve default notification messages for users with read-only access 2019-08-23 17:43:20 -07:00
Keith Grant
37b44fe77d fix template view for auditor/limited permissions 2019-08-23 17:43:20 -07:00
Keith Grant
191d18cec0 fix ui lint errors 2019-08-23 17:43:20 -07:00
Keith Grant
885c5050a0 re-init message templates on notification type change 2019-08-23 17:43:20 -07:00
Jim Ladd
03ebe44802 In UI, rename start to started 2019-08-23 17:43:20 -07:00
Keith Grant
0398ce0530 get default template messages from OPTIONS 2019-08-23 17:43:20 -07:00
Keith Grant
a56a6d7158 wire in custom template messages on edit form 2019-08-23 17:43:20 -07:00
Keith Grant
b80ca62072 add messages to Add Notification form payload 2019-08-23 17:43:20 -07:00
Keith Grant
fc4c9af86f fix empty template message after expanding 2019-08-23 17:43:20 -07:00
Keith Grant
0f19d98d84 set heights on syntax highlight inputs 2019-08-23 17:43:20 -07:00
Keith Grant
7b828d73be fix ids to support multiple syntax-highlights at once 2019-08-23 17:43:20 -07:00
Keith Grant
8a04cf0cb4 add syntax-highlight directive 2019-08-23 17:43:20 -07:00
Keith Grant
adf25c61a2 add custom notification message input fields 2019-08-23 17:43:20 -07:00
softwarefactory-project-zuul[bot]
2eaf62a62d Merge pull request #4558 from mabashian/4228-jobs-delete
Hook up delete on jobs list

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-23 21:14:55 +00:00
softwarefactory-project-zuul[bot]
4516e6400e Merge pull request #4525 from mabashian/4293-vars
Fixes issues with extra var prompting in workflow nodes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-23 21:09:21 +00:00
softwarefactory-project-zuul[bot]
72df2ca3a3 Merge pull request #4572 from mabashian/4474-datalist-width
Reverts data list toolbar back to expected width on normal lists

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-23 20:08:20 +00:00
Ryan Petrello
a949cc33f1 prevent POST on /api/v2/system_jobs/
SystemJobs should only be created by launching a SystemJobTemplate
2019-08-23 15:10:26 -04:00
softwarefactory-project-zuul[bot]
6e6676adb3 Merge pull request #4578 from ryanpetrello/awx-cli-install
fix install instructions for the AWX CLI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-23 17:02:09 +00:00
softwarefactory-project-zuul[bot]
49b840a996 Merge pull request #4577 from ansible/remove_job_status
Removing job_status from the docs because it doesn't exist.

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-23 16:35:34 +00:00
Ryan Petrello
150b3e6f6d fix install instructions for the AWX CLI 2019-08-23 11:34:55 -04:00
softwarefactory-project-zuul[bot]
90af9a9e33 Merge pull request #4576 from ryanpetrello/ssl-insecure-cli
suppress urllib3 insecure warnings in the CLI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-23 15:22:22 +00:00
Rebeccah Hunter
be0c36540e Removing job_status from the docs because it doesn't exist. 2019-08-23 10:53:23 -04:00
Ryan Petrello
70ce074f5a suppress urllib3 insecure warnings in the CLI 2019-08-23 10:11:59 -04:00
softwarefactory-project-zuul[bot]
39a96a620e Merge pull request #4562 from ryanpetrello/fix-required-cli-args
fix a formatting bug re: required arguments in the CLI

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-22 22:03:44 +00:00
softwarefactory-project-zuul[bot]
e13274c73f Merge pull request #4571 from ryanpetrello/v2-test-cleanup
clean up old v2 versioning in API tests

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-22 21:57:44 +00:00
Ryan Petrello
2e8be41111 fix a formatting bug re: required arguments in the CLI 2019-08-22 17:05:53 -04:00
mabashian
3079b54d31 Reverts data list toolbar back to 50/50 width on normal lists but maintains full width on lookups. 2019-08-22 15:34:30 -04:00
Ryan Petrello
4e6b0e1580 clean up old v2 versioning in API tests 2019-08-22 15:14:06 -04:00
Jake McDermott
94d6fcbe39 set default credentials when cred file not provided 2019-08-22 14:47:23 -04:00
John Mitchell
36229d92ee remove inadverdent debugger 2019-08-22 12:55:54 -04:00
mabashian
5549dac17d Hook up delete on jobs list. Add more comprehensive error handling on delete in organization and template lists. 2019-08-22 11:22:46 -04:00
John Mitchell
605c5784c8 fix regression where clicking inside popover closed it 2019-08-22 11:16:07 -04:00
softwarefactory-project-zuul[bot]
92bc608af3 Merge pull request #4535 from AlanCoding/null_ip
Allow gce host and public IP hostvars to be null

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-22 15:07:12 +00:00
softwarefactory-project-zuul[bot]
8566c30557 Merge pull request #4537 from jbradberry/fix-project-test
Fix asserts in test_project.py to use the id directly off of the job template

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-22 14:52:35 +00:00
softwarefactory-project-zuul[bot]
045578ce22 Merge pull request #4551 from rebeccahhh/devel
Remove extra warning when using garbage credentials

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-22 14:18:30 +00:00
Rebeccah Hunter
fb71b2699f removed tabbing 2019-08-22 09:41:32 -04:00
Rebeccah Hunter
af6e035c3b removed tabbing 2019-08-22 09:39:59 -04:00
softwarefactory-project-zuul[bot]
4a45a7e9c3 Merge pull request #4548 from ryanpetrello/more-cli-tweaks
more CLI tweaks

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-21 21:56:00 +00:00
Rebeccah Hunter
017274e2aa Removed extraneous warning when using garbage credentials for ssh_key_data
added in logic to check if there was an existing error before checking form field entry for ssh_key_unlock, also added a test to ensure that garbage data entered would not trigger the error message for both the incorrect ssh_key_data and the incorrect ssh_key_unlock, rather just the incorrect ssh_key_data
2019-08-21 17:01:51 -04:00
Ryan Petrello
44ff141c23 replace the (optional) tabulate dependency w/ a simple table printer 2019-08-21 15:54:47 -04:00
Ryan Petrello
ec5d471640 add an ad_hoc resource alias to the new CLI 2019-08-21 15:22:08 -04:00
mabashian
531a7b2c05 Add support for processing extra vars that come in string or object form. Small bug fixes for extra var corner cases in workflow nodes. 2019-08-21 13:34:41 -04:00
softwarefactory-project-zuul[bot]
1d05c21af4 Merge pull request #4544 from AlanCoding/rm_credential
Remove deprecated credential logic from create factory

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-21 16:45:07 +00:00
AlanCoding
a4f04cd534 remove deprecated credential logic from create factory 2019-08-21 10:40:38 -04:00
Bill Nottingham
444f024bb0 Fix display of indirect access permissions.
For indirect roles, we need to actually show the derived roles, not the
details of the role that gives us the derived roles. This means that
we can get multiple derived roles from a single indirect role, so
we have to expand the list.
2019-08-20 20:28:53 -04:00
softwarefactory-project-zuul[bot]
bccb54aec8 Merge pull request #4516 from ryanpetrello/py2
support the new CLI in py2 *and* py3

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-20 21:33:39 +00:00
Jeff Bradberry
ed1c667418 Fix asserts in test_project.py to use the id directly off of the job template
test_no_changing_overwrite_behavior_if_used, specifically.
2019-08-20 16:42:34 -04:00
softwarefactory-project-zuul[bot]
4bdbb88934 Merge pull request #4534 from ryanpetrello/nginx-server-version
hide nginx server version headers

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-20 19:20:37 +00:00
AlanCoding
85b351a0c8 Allow gce host and public IP hostvars to be null 2019-08-20 14:44:56 -04:00
softwarefactory-project-zuul[bot]
192fecad72 Merge pull request #4526 from jakemcdermott/update-gitignore
add akit config to gitignore

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-20 18:44:34 +00:00
Ryan Petrello
b82030b025 hide nginx server version headers 2019-08-20 14:34:04 -04:00
softwarefactory-project-zuul[bot]
8454adf8d4 Merge pull request #4490 from AlanCoding/wf_node_credential
Remove deprecated WFJT node credential field

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-20 18:23:49 +00:00
softwarefactory-project-zuul[bot]
e9df4ed800 Merge pull request #4435 from keithjgrant/4244-not-found-route
Add NotFound route handling

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-20 16:33:26 +00:00
Keith Grant
e1636b3ad4 add link back to dashboard from ContentError 2019-08-20 08:42:59 -07:00
Keith Grant
eeb86b3105 remove NotFoundError and use ContentError instead 2019-08-20 08:42:59 -07:00
Keith Grant
db1dddb95e fix redirect to login with expired session on org list & template list 2019-08-20 08:42:07 -07:00
Keith Grant
47357aea28 fix lint errors 2019-08-20 08:42:07 -07:00
Keith Grant
fe8df27811 add more meaningful 404 error screens 2019-08-20 08:42:07 -07:00
Keith Grant
256fc74676 add NotFound screen/route handling 2019-08-20 08:41:19 -07:00
Jake McDermott
2bda1db43e add akit config to gitignore 2019-08-20 11:10:08 -04:00
AlanCoding
4e99ad3e27 minor doc update 2019-08-20 10:37:41 -04:00
AlanCoding
f230da5437 update tests for credential removal 2019-08-20 10:37:41 -04:00
AlanCoding
b660800c5d remove deprecated WFJT node credential field 2019-08-20 10:37:41 -04:00
mabashian
4747be7014 Fixes bug in wf prompt modal by checking extra vars type before processing 2019-08-20 09:36:36 -04:00
mabashian
2de87dcef0 Fix prompt modal tab spacing when job launched from within jt form. 2019-08-20 09:35:19 -04:00
Ryan Petrello
80b4102aa9 support the new CLI in py2 *and* py3 2019-08-20 02:41:45 -04:00
softwarefactory-project-zuul[bot]
411667773a Merge pull request #4488 from jladdjr/docker_login_password_stdin
docker login: s/-p/--password-stdin/

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-19 23:22:05 +00:00
softwarefactory-project-zuul[bot]
ced5319ac9 Merge pull request #4512 from jlmitch5/projBranchFix
clear out branch/prompt on jt form when project changes

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-19 20:52:59 +00:00
John Mitchell
ef26f6a4c2 clear out branch/prompt on jt form when project changes 2019-08-19 14:16:01 -04:00
softwarefactory-project-zuul[bot]
b28655181d Merge pull request #4440 from mabashian/toggle-dynamics
Remove restriction on toggling dynamic hosts on/off from the host form view

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-19 16:42:17 +00:00
softwarefactory-project-zuul[bot]
2cdd007ed0 Merge pull request #4509 from saito-hideki/issue/tower/3679
Fixed form validation to JT survey minimum & maximum values

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-19 14:31:59 +00:00
softwarefactory-project-zuul[bot]
c963236a36 Merge pull request #4453 from ansible/e2e-cleanup
E2E websocket cleanup

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-19 14:09:31 +00:00
softwarefactory-project-zuul[bot]
2e762276bf Merge pull request #4507 from vrevelas/typo
Fix typo

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-08-19 13:07:26 +00:00
Hideki Saito
0f4de69e57 Fixed form validation to JT survey minimum & maximum values
- Fixed issue ansible/tower#3679

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-08-19 09:15:29 +00:00
vrevelas
1d1706665f Fix typo 2019-08-19 11:34:45 +03:00
softwarefactory-project-zuul[bot]
858f43fd2a Merge pull request #4489 from keithjgrant/4427-job-template-console-error
Fix default props for jt form

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-16 23:45:56 +00:00
Keith Grant
491287b1de fix default props for jt form 2019-08-16 19:11:07 -04:00
softwarefactory-project-zuul[bot]
de78d5d63b Merge pull request #4505 from marshmalien/awx-pf-jt-project-field
Add project single select input to job template form

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-16 21:57:24 +00:00
softwarefactory-project-zuul[bot]
ab45938d41 Merge pull request #4506 from rooftopcellist/fix_migrations
fix typo in migration name

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-16 18:24:41 +00:00
Christian Adams
a58a191071 fix typo in migration name 2019-08-16 13:46:41 -04:00
softwarefactory-project-zuul[bot]
2d7dc9aec7 Merge pull request #4493 from ryanpetrello/safeload
replace usage of FullLoader w/ safe_load

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-16 17:45:07 +00:00
Marliana Lara
45a69551f1 Change JT form project field into a single select input 2019-08-16 13:05:12 -04:00
softwarefactory-project-zuul[bot]
f7ea14107e Merge pull request #4503 from shanemcd/nit
Fix typo in migration filename

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-16 16:59:24 +00:00
softwarefactory-project-zuul[bot]
4dc97ac8d1 Merge pull request #3812 from skinlayers/devel
Add support for kubernetes nodeSelector, tolerations and affinity

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-16 16:36:56 +00:00
softwarefactory-project-zuul[bot]
165600b876 Merge pull request #4502 from rooftopcellist/token_description
Use consistent description types

Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
2019-08-16 16:27:41 +00:00
Shane McDonald
18a316646b Fix typo in migration filename 2019-08-16 10:29:34 -04:00
Ryan Petrello
39d0eb62e4 replace usage of FullLoader w/ safe_load 2019-08-16 10:13:27 -04:00
AlanCoding
d302f134ac Kill off all can_read access methods 2019-08-16 10:12:46 -04:00
Christian Adams
52f8a8a6e5 Use consistent description types 2019-08-16 09:25:03 -04:00
softwarefactory-project-zuul[bot]
e08e70efb4 Merge pull request #4498 from ryanpetrello/awx-cli-help
prevent `awx -h` CLI command from printing a scary connection error

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-15 18:19:01 +00:00
softwarefactory-project-zuul[bot]
89c41a5931 Merge pull request #4494 from kdelee/awxkit_remove_dateutil
Remove this dependency that we don't need

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-15 18:03:53 +00:00
Ryan Petrello
94235f4736 prevent awx -h CLI command from printing a scary connection error 2019-08-15 13:38:37 -04:00
softwarefactory-project-zuul[bot]
099a7f6cde Merge pull request #4495 from ryanpetrello/docker-for-mac-sdb
fix a bug in the sdb-listen setup

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-15 16:19:34 +00:00
Ryan Petrello
57d60e5b97 fix a bug in the sdb-listen setup
Docker for Mac recently renamed itself to Docker Desktop
2019-08-15 11:50:28 -04:00
Elijah DeLee
8efa0fc397 Remove this dependency that we don't need 2019-08-15 11:26:02 -04:00
softwarefactory-project-zuul[bot]
dc44e68980 Merge pull request #4479 from saito-hideki/issue/tower/3639
Fixed "DEFAULT ANSWER" to be properly deleted for Integer and Float types

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-15 14:54:46 +00:00
softwarefactory-project-zuul[bot]
65e359bdcf Merge pull request #4491 from ryanpetrello/remove-cli-termcolor
replace the termcolor dependency w/ a simple function

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-15 14:25:39 +00:00
Hideki Saito
f1a69e9357 Fixed "DEFAULT ANSWER" to be properly deleted for Integer and Float types
- Fixed issue ansible/tower#3639

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-08-15 10:24:17 -04:00
Ryan Petrello
224750c0d6 replace the termcolor dependency w/ a simple function 2019-08-15 09:54:01 -04:00
softwarefactory-project-zuul[bot]
2f658a4e5d Merge pull request #4305 from catjones9/jobTemplateAddButton
Adds Job Template Add Button to TemplatesList with link to add form

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-14 22:52:38 +00:00
catjones9
38a7fa5558 Linting errors
Signed-off-by: catjones9 <catjones@redhat.com>
2019-08-14 16:52:30 -04:00
catjones9
e591305dfe Changes conditional canAdd statement based on PR feedback
Signed-off-by: catjones9 <catjones@redhat.com>
2019-08-14 16:52:30 -04:00
catjones9
9e0d113063 Conditional Add Button on Template List screen
Signed-off-by: catjones9 <catjones@redhat.com>
2019-08-14 16:52:30 -04:00
softwarefactory-project-zuul[bot]
ad17bdc559 Merge pull request #4487 from ryanpetrello/many-groups-slowness
optimize a slow query in inventory script generation

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-14 20:32:01 +00:00
softwarefactory-project-zuul[bot]
c35fbd6853 Merge pull request #4483 from ryanpetrello/multi-owner
fix bug where cred org permission was not checked

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-14 19:54:57 +00:00
Jim Ladd
74623a33a2 docker login: s/-p/--password-stdin/ 2019-08-14 12:32:26 -07:00
softwarefactory-project-zuul[bot]
8df70f5412 Merge pull request #4471 from jakemcdermott/multicred-template-loading
add related credential loading needed for multicredential select

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-14 19:31:34 +00:00
Ryan Petrello
98e7ae5f9f optimize a slow query in inventory script generation
see: https://github.com/ansible/awx/issues/4461
2019-08-14 15:03:53 -04:00
softwarefactory-project-zuul[bot]
26637499d1 Merge pull request #4484 from chrismeyersfsu/fix-notification_password
do not expose the notification secret fields

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-14 18:45:08 +00:00
Jake McDermott
55376bfd13 load related credentials when editing 2019-08-14 14:15:24 -04:00
Jake McDermott
a8511f967b build details url once 2019-08-14 14:15:24 -04:00
Jake McDermott
e3d6ee6f9e move label requests to function 2019-08-14 14:15:24 -04:00
Jake McDermott
d05c1bdd6e move function comment into function 2019-08-14 14:15:24 -04:00
Jake McDermott
c96dfd101c use alias for type import 2019-08-14 14:15:24 -04:00
chris meyers
9fa4dac847 do not expose the notication secret fields 2019-08-14 13:58:47 -04:00
softwarefactory-project-zuul[bot]
7374732d9b Merge pull request #4482 from ryanpetrello/prometheus_errors
fix a bug in the API metrics endpoint

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-14 17:14:25 +00:00
AlanCoding
4831cde39f fix bug where cred org permission was not checked 2019-08-14 12:07:28 -04:00
softwarefactory-project-zuul[bot]
43d816b6e4 Merge pull request #4265 from AlanCoding/branch_feature_phase_2
Allow JT specification and prompting for project branch

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-14 14:56:19 +00:00
Ryan Petrello
a45c93ed47 fix a bug in the API metrics endpoint
The metrics JSON renderer shouldn't try to parse data that isn't
a string (generally, this represents things like HTTP 403)
2019-08-14 10:40:21 -04:00
softwarefactory-project-zuul[bot]
31308e3795 Merge pull request #4383 from marshmalien/4236-output-toolbar
Job Output - Pagination and Static List

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-13 21:38:25 +00:00
Marliana Lara
748bf63d4e Move job event line styles into a shared dir
Set a field to avoid setState warnings

Fix lint errors
2019-08-13 17:06:24 -04:00
Jake McDermott
2a926fffd9 set default timezone to UTC for test runs 2019-08-13 17:05:48 -04:00
Marliana Lara
475645f604 Add JobOutput tests 2019-08-13 17:05:47 -04:00
Jake McDermott
b2922792bc add function for testing output lines 2019-08-13 17:05:47 -04:00
Marliana Lara
74ef0e7abf Refactor MenuControls as a functional component
* Fix lint errors
2019-08-13 17:05:47 -04:00
Marliana Lara
2aa38e84dd Add guard clause to loadMoreRows and style tweaks 2019-08-13 17:05:46 -04:00
Jake McDermott
033308de69 add missing event placeholders and recompute heights on load 2019-08-13 17:05:46 -04:00
Jake McDermott
0a3633113e ensure results are always indexed by counter when loading new rows 2019-08-13 17:05:46 -04:00
Marliana Lara
161c7706bc Add InfiniteLoader to fetch rows as needed 2019-08-13 17:05:46 -04:00
Jake McDermott
40560e962f compute row height on-the-fly 2019-08-13 17:05:45 -04:00
Jake McDermott
474a2a48bb add job event component and sanitized html building for output lines 2019-08-13 17:05:45 -04:00
Marliana Lara
da92889323 WIP - react virtualizer 2019-08-13 17:05:45 -04:00
Marliana Lara
859c364fbe Add MenuControl tests 2019-08-13 17:05:44 -04:00
Marliana Lara
408b38174a Add job output menu controls component 2019-08-13 17:05:44 -04:00
softwarefactory-project-zuul[bot]
e3c6e245d6 Merge pull request #3623 from wenottingham/hello-you-are-being-audited
Allow mapping org auditors where we map org admins.

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-13 19:07:31 +00:00
softwarefactory-project-zuul[bot]
8fef029bc3 Merge pull request #4442 from mabashian/4225-sparkline-templates
Add Sparkline to templates list

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-13 18:14:24 +00:00
softwarefactory-project-zuul[bot]
8fbda8a773 Merge pull request #4469 from jakemcdermott/lookup-tests
refactor lookup tests

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-13 17:46:02 +00:00
Jake McDermott
245252ed11 refactor lookup tests 2019-08-13 13:13:12 -04:00
Bill Nottingham
bbf28f50bd Allow mapping org auditors where we map org admins. 2019-08-13 11:32:35 -04:00
softwarefactory-project-zuul[bot]
0cc9199f23 Merge pull request #4468 from ryanpetrello/more-awxkit-dep-cleanup
simplify awxkit dependencies

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-13 13:07:18 +00:00
AlanCoding
be21a8bcb4 Fix logic for turning off override behavior 2019-08-12 22:17:19 -04:00
John Mitchell
3df476e3f6 remove inadverdent duplicate CreateSelect2 call from playbook on jt edit form 2019-08-12 22:17:19 -04:00
AlanCoding
2f3aafe1bb Add collection setting toggle to UI
Additional API housekeeping, removing unused code

Treat default branch as no branch provided
2019-08-12 22:16:04 -04:00
John Mitchell
79a1dbc5a0 fix issue with interior scope declaration eslint error 2019-08-12 22:16:03 -04:00
AlanCoding
dc5d696238 avoid unnecessary checkout, more docs content 2019-08-12 22:16:03 -04:00
John Mitchell
139e8cde70 more ui work for branch and refspec on project/jt
- add refspec field to project
- update refspec and branch help text on project form
- add refspec field to job detail
- adjust form gen and ProcessErrors to show api errors for checkbox_groups correctly
- consolidate showPromptButton conditionals and fix the add/edit workflow node one for showing prompt when only branch is promptable
2019-08-12 22:16:03 -04:00
John Mitchell
13751e73f9 working commit 2019-08-12 22:16:02 -04:00
AlanCoding
03d72dd18a JT-branch docs and code cleanup
bump migration

fine tune validation of project allow_override
  return highly custom error message

Restore branch after syncs to address bugs
  encountered after changing scm_refspec

remove unused code to determine scm_revision

Check Ansible version before project update and
  do not install collections if Ansible version too old

Add docs related to project branch override
  New file specific to branch override and refspec
Complete docs on collections to reflect current
  implementation and give a folder tree example
Update clustering docs related to project syncs

Fix bug where git depth was ignored during the
  local clone from project folder to run folder

Fix bug where submodules were not copied
2019-08-12 22:16:02 -04:00
chris meyers
d785145c59 force proj sync when collections/requirements.yml
* Similar to roles/requirements.yml sync optimization logic.
2019-08-12 22:16:02 -04:00
AlanCoding
270bd19dbd Fix bugs with discovery of collection requirements
Addresses some cases where
  collection requirements do not exist
  collection requirements cannot be evaluated

Consolidate logic for roles and collection installs
2019-08-12 22:14:32 -04:00
chris meyers
cc6413c44c use ansible nightly
* ansible:devel now has ansible-galaxy collection support
2019-08-12 22:14:31 -04:00
chris meyers
4be65a0879 collections/requirements.yml support
* just like we support ansible-galaxy role install, support
ansible-galaxy collection install
2019-08-12 22:14:30 -04:00
AlanCoding
f1f57e45de Add scm_refspec field
Update migration syntax to Django 2

fix status bug where canceled switched to error
2019-08-12 22:13:57 -04:00
softwarefactory-project-zuul[bot]
845e3867a6 Merge pull request #4467 from ansible/e2e-debugging-help
Known E2E Issues

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-12 23:34:06 +00:00
softwarefactory-project-zuul[bot]
7fcfc88c82 Merge pull request #4460 from jakemcdermott/normalize-e2e-urls
remove extra and trailing slashes from e2e url settings

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-12 23:27:27 +00:00
Jake McDermott
61ca4278c8 remove extra and trailing slashes from url 2019-08-12 18:59:02 -04:00
Ryan Petrello
299fa3b6b4 simplify awxkit dependencies
- remove flake8 as an install requirements (it's only used for tests)
- vendor toposort, which is Apache 2.0 licensed (and very small)
- change websocket-client to a setuptools optional dependency, which you
  can install via:

  pip install "./awxkit[websockets]"

- add `jq` and `tabulate` under an additional optional setuptools
  dependency:

  pip install "./awxkit[formatting]"

- remove `cryptography`, which is only used for random RSA generation
  (unused by the CLI)
2019-08-12 17:27:57 -04:00
softwarefactory-project-zuul[bot]
0b112e5b8f Merge pull request #4465 from ryanpetrello/json-metrics
add support for Accept:application/json to /api/v2/metrics

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-12 20:26:16 +00:00
John Hill
121bc96108 Updating for the known MacOS High Sierra issue 2019-08-12 15:46:39 -04:00
Ryan Petrello
82f5072c7d add support for Accept:application/json to /api/v2/metrics
see: https://github.com/ansible/awx/issues/4144
2019-08-12 15:17:40 -04:00
softwarefactory-project-zuul[bot]
99357acf5d Merge pull request #4462 from AlanCoding/the_edge_of_unicode
Fix error due to randint inclusivity

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-12 19:02:04 +00:00
AlanCoding
3a5e609a11 Fix error due to randint inclusivity 2019-08-12 13:36:53 -04:00
softwarefactory-project-zuul[bot]
a776d0ba59 Merge pull request #4459 from ryanpetrello/cli-version
make awxkit have the same version as the AWX package

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-12 15:15:41 +00:00
John Mitchell
0c89c6c79e fix ui conditional for adding fields to jt edit save payload 2019-08-12 11:01:11 -04:00
AlanCoding
6baba10abe Add scm_revision to project updates and cleanup
Add validation around prompted scm_branch requiring
  project allow_override field to be true

Updated related process isolation docs

Fix invalid comarision in serializer

from PR review, clarify pre-check logging, minor docs additions
2019-08-12 11:01:10 -04:00
John Mitchell
76dcd57ac6 assorted UI work to support the new branch field
update project to have allow branch override checkbox
add new text input for branch field
adjust show/hide for branch and playbook jt fields
make playbook field allowed to add a new option not in the dropdown
update job results ui to show branch
update prompting to support new branch field
2019-08-12 11:01:10 -04:00
AlanCoding
ac86dc4fb9 Allow JTs to specify and prompt for SCM branch
Copy project folder each job run
  change cwd to private_data_dir, from proj
  do not add cwd to show_paths if it is
  a subdirectory of private_data_dir, which
  is already shown

Pass the job private_data_dir to the local
  project sync, and also add that directory
  to the project sync show paths

Add GitPython dep and use for job sync logic
  use this to manage shallow clone from desired
  commit, and to map branch to commit,
  and to assess necessity of project sync

Start on some validation change, but not all
  allow arbitrary playbooks with custom branch
2019-08-12 11:01:07 -04:00
Ryan Petrello
b90d1456b3 make awxkit have the same version as the AWX package 2019-08-12 09:42:04 -04:00
Gabriel Totusek
794808cd10 Fix compatibility with postgresql helm chart v6.0.0+ 2019-08-12 02:40:25 -07:00
Gabriel Totusek
d932a70eff Downgrade postgres helm chart to v5.3.13 2019-08-12 00:43:09 -07:00
Gabriel Totusek
90e5b0a12d Update postgres helm chart to v6.2.1 2019-08-11 23:16:43 -07:00
Gabriel Totusek
f705eba7ed Add support for kubernetes tolerations, nodeSelector, and affinity 2019-08-11 23:10:56 -07:00
John Hill
8341601c60 Adding Debugging section to e2e doc
First of many debugging, Troubleshooting, and FAQ tips
2019-08-11 22:06:55 -04:00
softwarefactory-project-zuul[bot]
28e3625066 Merge pull request #4455 from ryanpetrello/stdout-is-not-missing
remove awxkit logic for working around an old stdout handling bug

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-09 20:43:19 +00:00
Ryan Petrello
d92753f20a remove awxkit logic for working around an old stdout handling bug
related: https://github.com/ansible/awx/issues/200
2019-08-09 14:44:52 -04:00
softwarefactory-project-zuul[bot]
76a10991ae Merge pull request #4451 from ryanpetrello/awxkit
open source awxkit

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-09 16:10:47 +00:00
Daniel Sami
2064309182 e2e cleanup websockets 2019-08-09 11:32:26 -04:00
Ryan Petrello
adaa4148c6 include awxkit CI in zuul runs
additionally, fix up some flake8 failures
2019-08-09 10:07:40 -04:00
Ryan Petrello
9616cc6f78 import awxkit
Co-authored-by: Christopher Wang <cwang@ansible.com>
Co-authored-by: Jake McDermott <jmcdermott@ansible.com>
Co-authored-by: Jim Ladd <jladd@redhat.com>
Co-authored-by: Elijah DeLee <kdelee@redhat.com>
Co-authored-by: Alan Rominger <arominge@redhat.com>
Co-authored-by: Yanis Guenane <yanis@guenane.org>
2019-08-08 22:12:31 -04:00
softwarefactory-project-zuul[bot]
9b836abf1f Merge pull request #4444 from elyezer/app-token-e2e
Add app token e2e

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-08 18:50:34 +00:00
softwarefactory-project-zuul[bot]
3441d0cb46 Merge pull request #4441 from ansible/noretry
[WIP] Parameterize E2E Suite retries

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-08 17:56:22 +00:00
mabashian
3d98d98d3c Moves tooltip and link logic out to the sparkline from the job status icon 2019-08-08 11:53:47 -04:00
softwarefactory-project-zuul[bot]
860d83d798 Merge pull request #4437 from rooftopcellist/correct_insights_collection_setting
Fix NoneType path error with analytics collection

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-08 15:17:57 +00:00
John Hill
ce37bc9897 remove static definition and move to pipelines 2019-08-08 10:44:56 -04:00
Christian Adams
c37bf5e9f5 Fix NoneType path error with analytics collection 2019-08-07 16:19:05 -04:00
mabashian
fba0da4c58 Fix linting 2019-08-07 16:16:57 -04:00
Elyézer Rezende
e7a15d478d Add app token e2e 2019-08-07 15:56:06 -04:00
softwarefactory-project-zuul[bot]
d7c15a782f Merge pull request #4425 from mabashian/toggles
Swap text-based on and off toggles to non-text based

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-07 19:55:16 +00:00
mabashian
6a7481a27c Prettier again 2019-08-07 14:52:40 -04:00
mabashian
a57f2ca2bf Run prettier 2019-08-07 14:46:41 -04:00
mabashian
37e5b6b134 Add sparkline tests 2019-08-07 14:44:16 -04:00
John Hill
d5dd1719b6 Parameterize E2E Suite retries 2019-08-07 11:48:12 -04:00
mabashian
0bd9d4abaf Change awxSwitch class prefix to atSwitch to match component name 2019-08-07 11:22:28 -04:00
mabashian
993855f70a Remove restriction on toggling dynamic hosts on/off from the host form view. 2019-08-07 11:15:42 -04:00
mabashian
c71068fa1c Create at-switch directive. Use it in all the places 2019-08-07 11:10:08 -04:00
mabashian
c4700998af Swap text-based on and off toggles to non-text based 2019-08-07 11:05:58 -04:00
mabashian
19d2c8c634 Adds sparkline to templates list 2019-08-06 15:51:27 -04:00
softwarefactory-project-zuul[bot]
4f3f87ebc7 Merge pull request #4433 from AlanCoding/we_dont_do_that
Remove setting not actually customizable

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-06 19:47:55 +00:00
AlanCoding
63978f7d10 remove setting not actually customizable 2019-08-06 13:40:52 -04:00
softwarefactory-project-zuul[bot]
5ed2a38e1d Merge pull request #4423 from saimonn/typo-INSTALL-md
INSTALL.md: fix #post-build-2 href fragment

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-06 14:31:18 +00:00
softwarefactory-project-zuul[bot]
dbcc3c5733 Merge pull request #4420 from wenottingham/be-an-enabler
[RFC] Allow enable/disable of hosts in dynamic inventory from the UI.

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-05 17:29:17 +00:00
Bill Nottingham
b4f272a575 Catch another area where this toggle is set. 2019-08-05 12:06:41 -04:00
Simon Séhier
c17ce49e2e fix #post-build-2 href fragment 2019-08-05 17:29:36 +02:00
Bill Nottingham
8e1e33735a Allow enable/disable of hosts in dynamic inventory from the UI.
The API lets you do it, so we shouldn't block it from the UI.
2019-08-05 11:18:56 -04:00
softwarefactory-project-zuul[bot]
50c0867156 Merge pull request #4417 from ansible/stability-e2e
Stability for e2e websockets

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-05 13:16:45 +00:00
softwarefactory-project-zuul[bot]
5984b6235a Merge pull request #4403 from mabashian/3654-inv-status-popover
Fix summary popover on inventory list

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-03 16:11:21 +00:00
softwarefactory-project-zuul[bot]
481df40764 Merge pull request #4411 from mabashian/workflow-start-node-width
Makes workflow start node width dynamic to account for languages other than English

Reviewed-by: Michael Abashian
             https://github.com/mabashian
2019-08-03 13:43:58 +00:00
mabashian
521ecc883b Fix jshint errors 2019-08-03 09:26:50 -04:00
mabashian
688f14a0ee Fix summary popover on inventory list 2019-08-03 09:12:34 -04:00
mabashian
b3002e0b9d Makes workflow start node width dynamic to account for languages other than english 2019-08-03 09:11:20 -04:00
softwarefactory-project-zuul[bot]
9ab920cdb9 Merge pull request #4413 from AlexSCorey/multiSelectPatternFly
Multi-Select AWX-PF

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-02 22:37:27 +00:00
Alex Corey
8b35642b08 Fixes failing test and addresses PR issues 2019-08-02 17:37:58 -04:00
Alex Corey
74a1ebff32 Adds tests and refines chip interaction in MultiSelect component 2019-08-02 16:42:22 -04:00
Alex Corey
a577be906e Adds Multiselect functionality to labels on JTs 2019-08-02 16:42:22 -04:00
Daniel Sami
934d09e0de Stability for e2e websockets 2019-08-02 15:33:09 -04:00
softwarefactory-project-zuul[bot]
bb2474f56f Merge pull request #4415 from ryanpetrello/bubblewrap_aaaaaaaaaaarg
fix a bug that breaks isolated task execution

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-02 15:12:47 +00:00
Ryan Petrello
1388dec4b0 fix a bug that breaks isolated task execution 2019-08-02 07:48:46 -04:00
softwarefactory-project-zuul[bot]
9d2549b4b1 Merge pull request #4368 from jlmitch5/uiNextSearch
initial implementation of search in ui_next

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-01 20:51:48 +00:00
John Mitchell
c0dcba91f5 Update SEARCH.md 2019-08-01 16:21:19 -04:00
John Mitchell
2e777368bf Update SEARCH.md 2019-08-01 16:21:19 -04:00
John Mitchell
0276a37e8d small updates to qs syntax based on feedback 2019-08-01 16:21:19 -04:00
John Mitchell
30253d21fc assorted ui_next search phase 1 pr feedback updates
- remove unnecessary displayAll prop from ChipGroup
- update notification api fn to be 2 with no boolean param
- fix params passing to api functions
2019-08-01 16:21:19 -04:00
John Mitchell
f0ff5b190a update qs addParams/removeParams fns to take param object not string 2019-08-01 16:21:19 -04:00
John Mitchell
bdfeb2cb9c updates based on pr feedback
run prettier
update hasContentError to contentError in all the places
function naming updates
2019-08-01 16:21:19 -04:00
John Mitchell
357887417c working commit 2019-08-01 16:21:19 -04:00
John Mitchell
a58468ffee initial implementation of search in UI_next 2019-08-01 16:21:19 -04:00
softwarefactory-project-zuul[bot]
602ee856fa Merge pull request #4405 from AlanCoding/gce_token
Always provide gce token_uri

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-01 19:20:52 +00:00
AlanCoding
4399d9287d Always provide gce token_uri 2019-08-01 14:18:44 -04:00
softwarefactory-project-zuul[bot]
2faf69e3b5 Merge pull request #4410 from jbradberry/upgrade-django-2.2.4
Upgrade to django 2.2.4

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-01 17:58:53 +00:00
softwarefactory-project-zuul[bot]
008ea30c5f Merge pull request #4409 from ryanpetrello/bubblewrap_aaaaaaaaaaarg
attempt to properly clean up orphaned runner ansible_pi directories

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-01 16:03:22 +00:00
Ryan Petrello
cfeedb158e attempt to properly clean up runner ansible_pi directories 2019-08-01 11:21:38 -04:00
Jeff Bradberry
10200fced0 Add patch to the list of system packages installed into the container
since it is a requirement of the new updater.sh Python requirements script.
2019-08-01 10:41:49 -04:00
Jeff Bradberry
2926d0198d Bump the version of Django to 2.2.4
This is a security release.
2019-08-01 10:41:36 -04:00
softwarefactory-project-zuul[bot]
c742700a01 Merge pull request #4379 from saito-hideki/pr/fix_ui-devel-languages-1
Document UI building process for development environment to cover I18N static contents

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-01 12:13:50 +00:00
softwarefactory-project-zuul[bot]
3d5e072169 Merge pull request #4407 from mabashian/3929-notif-options-bold
Make notification form options regular font weight

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-01 12:04:49 +00:00
softwarefactory-project-zuul[bot]
772d087b6e Merge pull request #4404 from mabashian/4113-grafana
Fix js error thrown preventing creation of grafana notification

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-08-01 00:43:50 +00:00
mabashian
213df70419 Make notification form options regular font weight 2019-07-31 20:06:22 -04:00
softwarefactory-project-zuul[bot]
6a6d55fe41 Merge pull request #4317 from wenottingham/pexpect-the-requirements-inquisition
Remove pexpect, etc, from the ansible venv, that's now runner's problem.

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-31 21:45:41 +00:00
softwarefactory-project-zuul[bot]
a36b436414 Merge pull request #4401 from AlanCoding/no_prompting
Update docs to reflect field removals

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-31 20:33:31 +00:00
mabashian
94b5bb8cf9 Ensure variable exists before calling toString on it to fix js error thrown when creating grafana notification 2019-07-31 14:15:13 -04:00
Hideki Saito
8362aa71db Update tooling and UI development documentation to cover I18N
- Document steps for adding I18N in builds
- Add "clean-language" target to remove *.mo files

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-07-31 09:44:29 -04:00
AlanCoding
b3651ecf30 Update docs to reflect field removals 2019-07-31 08:58:39 -04:00
softwarefactory-project-zuul[bot]
4a35df9a1c Merge pull request #4399 from mabashian/3676-notif-menu
Show notification menu to users with notification_admin team role

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-30 22:46:07 +00:00
softwarefactory-project-zuul[bot]
416b2ef37a Merge pull request #4398 from mabashian/3644-launch-outside-click
Prevent clicks outside of prompt modal from closing the modal without saving

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-30 22:18:54 +00:00
Bill Nottingham
ad28e11502 Remove pexpect, etc, from the ansible venv, that's now runner's problem. 2019-07-30 17:09:12 -04:00
softwarefactory-project-zuul[bot]
815823adc0 Merge pull request #4363 from jomach/feature/updateGitVersion
[4362] git version is old and does not work with x509 certificates

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-30 21:07:24 +00:00
mabashian
a6c50f6d20 Fix unit test endpoint to match notif admin request endpoint 2019-07-30 16:52:52 -04:00
mabashian
df177d6dc3 Removes close behavior when clicking outside of modal and dialog components 2019-07-30 16:47:17 -04:00
mabashian
1121a2b623 Show notification menu to users with notification_admin team role 2019-07-30 16:18:39 -04:00
softwarefactory-project-zuul[bot]
f02aa3528e Merge pull request #4311 from wenottingham/pair-of-mikos
Update paramiko to a version that can work with any python-gssapi.

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-30 19:35:48 +00:00
mabashian
c1cf7b79e3 Rogue console be gone 2019-07-30 15:25:42 -04:00
mabashian
47c59d5211 Prevent clicks outside of prompt modal from closing the modal without saving. User will now need to explicity hit the X or Cancel buttons to close the modal prematurely. 2019-07-30 15:22:01 -04:00
Bill Nottingham
20f1ed4533 Update source tarball. 2019-07-30 12:09:51 -04:00
Bill Nottingham
fafe9ce4ea Update paramiko to a version that can work with any python-gssapi. 2019-07-30 12:09:48 -04:00
softwarefactory-project-zuul[bot]
6499f2b233 Merge pull request #4380 from saito-hideki/issue/4359
Add description to template and project list view

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-30 15:49:32 +00:00
softwarefactory-project-zuul[bot]
8c4aac3b6c Merge pull request #4396 from ryanpetrello/ldap-audit
properly set `is_system_auditor` on initial LDAP login

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-30 15:28:23 +00:00
Ryan Petrello
a47a2d8567 properly set is_system_auditor on initial LDAP login
django-auth-ldap recently changed its behavior at login to *delay* the
user.save() call:

b777321fb4

our current process of discovering and setting up the system auditor
role at LDAP login *relies* on the user having a primary key, so this
code now manually calls .save() to enforce one
2019-07-30 10:05:39 -04:00
softwarefactory-project-zuul[bot]
5d6916f69e Merge pull request #4391 from ryanpetrello/skip-empty-stdout
skip events w/ empty stdout when generating stdout downloads

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-30 13:48:07 +00:00
Hideki Saito
329b791908 Add description to template and project list view
- Fixed issue #4359

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-07-30 20:18:54 +09:00
Jorge Machado
76933ed889 * upgrade from git on containers
* agreed with terms of DCO 1.1

Signed-off-by: Jorge Machado <jorge@jmachado.me>
2019-07-30 07:04:04 +02:00
softwarefactory-project-zuul[bot]
c7bb0f10e1 Merge pull request #4385 from chrismeyersfsu/fix-home_dir
fake it till you make it!

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-29 17:47:36 +00:00
softwarefactory-project-zuul[bot]
7afa35af17 Merge pull request #4367 from keithjgrant/4232-single-select-lookup
Single select lookup

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-29 17:42:12 +00:00
softwarefactory-project-zuul[bot]
2e48718746 Merge pull request #4393 from marshmalien/4392-org-inv-link
Add link to organization inventory list

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-29 17:25:21 +00:00
softwarefactory-project-zuul[bot]
26a7ec97fa Merge pull request #4387 from keithjgrant/3565-insights-translation
Insights translation

Reviewed-by: Keith Grant
             https://github.com/keithjgrant
2019-07-29 16:46:35 +00:00
Marliana Lara
3c96968ee0 Add link to organization inventory list 2019-07-29 12:36:30 -04:00
chris meyers
9236fd2a53 fake it till you make it!
* The user awx is passed to the launch of our dev docker container. The
docker system automagically creates that user for us and sets the home
dir to /tmp in /etc/passwd. Many methods of detecting the user home dir
don't use that. Instead, they use the HOME env var. This is a half-way
solution that solves the problem of python expanding the ~ dir.
* If other things break because they determine the users home dir via
/etc/passwd entry then a more in-depth fix will be needed.
2019-07-29 09:58:47 -04:00
Ryan Petrello
79723cea21 skip events w/ empty stdout when generating stdout downloads
see: https://github.com/ansible/tower/issues/3677
2019-07-29 09:36:00 -04:00
softwarefactory-project-zuul[bot]
9cc23d5a71 Merge pull request #4388 from falcon78921/wip-awx-grammar
awx/ui: fixed minor grammar error in Survey form

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-29 12:49:47 +00:00
James McClune
bb92296478 awx/ui: fixed minor grammar error in Survey form
Signed-off-by: James McClune <jmcclune@mcclunetechnologies.net>
2019-07-27 15:24:24 -04:00
Keith Grant
3d3952c549 remove unnecessary scrollbar from Inventories Lookup 2019-07-26 16:24:48 -07:00
Keith Grant
276ed792a2 translate insights tooltip 2019-07-26 12:57:24 -07:00
softwarefactory-project-zuul[bot]
0ef97c497f Merge pull request #3851 from AlanCoding/ig_distinct
Remove duplicates from IG list

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-26 16:45:06 +00:00
Keith Grant
e903425785 mark button text for translation 2019-07-25 15:39:06 -07:00
softwarefactory-project-zuul[bot]
94e14ae6f8 Merge pull request #4378 from ryanpetrello/run-rabbit-run
don't filter out schedules that have a null `next_run`

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-25 21:34:03 +00:00
Ryan Petrello
e711d32ea2 don't filter out schedules that have a null next_run
when schedules are disabled, their `next_run` is unset; we should still
show them in this list view, just with an empty value in the `next_run`
column (they're disabled, so they'll never run)
2019-07-25 17:07:28 -04:00
softwarefactory-project-zuul[bot]
a5c5874e20 Merge pull request #4377 from ryanpetrello/fix-4376
fix a bug which can cause isolated artifact cleanup to fail

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-25 20:27:03 +00:00
Ryan Petrello
2608e8d47d fix a bug which can cause isolated artifact cleanup to fail
see: https://github.com/ansible/awx/issues/4376
2019-07-25 15:52:04 -04:00
softwarefactory-project-zuul[bot]
06260bdbaf Merge pull request #4374 from rooftopcellist/update_job_status_info
Update job status comments

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-25 19:36:43 +00:00
Christian Adams
670a184708 Update job status comments
- waiting and pending job descriptions were not accurate
2019-07-25 15:06:06 -04:00
softwarefactory-project-zuul[bot]
24b166aec9 Merge pull request #4375 from rooftopcellist/pending_jobs_metrics
add pending jobs and system level job status to metrics

Reviewed-by: Christian Adams <rooftopcellist@gmail.com>
             https://github.com/rooftopcellist
2019-07-25 18:56:23 +00:00
Christian Adams
11a6e98230 Add pending jobs and system level job status to metrics 2019-07-25 14:19:20 -04:00
AlanCoding
2c533edb3c remove duplicates from IG list 2019-07-25 10:20:25 -04:00
softwarefactory-project-zuul[bot]
128fa8947a Merge pull request #4124 from beeankha/webhook_enhancement
Webhook Custom HTTP Method + Basic Auth Support

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-24 21:06:23 +00:00
Jake McDermott
97f841057f fix method mapping for webhook notification add 2019-07-24 15:50:27 -04:00
softwarefactory-project-zuul[bot]
2ccb5ba4a7 Merge pull request #4372 from ryanpetrello/instance-metrics-hostname
include instance hostnames in metrics endpoint

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-24 18:18:06 +00:00
Ryan Petrello
f2996f1c89 include instance hostnames in metrics endpoint 2019-07-24 13:41:56 -04:00
beeankha
f7502eed2f Correct the comment in migration file 2019-07-24 08:59:32 -04:00
Jake McDermott
1fe18dc588 normalize http method choice values 2019-07-23 19:58:35 -04:00
Keith Grant
2c86d7400a remove duplicate type declaration; lint fixes 2019-07-23 12:22:44 -07:00
beeankha
7580491f1a Add migration file to define http_method explicitly 2019-07-23 14:52:26 -04:00
Keith Grant
2392e57d2f fix InventoriesLookup on new JT form; add DataListRadio tests 2019-07-23 10:49:28 -07:00
Keith Grant
bb5b255c28 updating job template tests 2019-07-23 10:49:28 -07:00
Keith Grant
5edc6deeae finish core InventoriesLookup core functionality 2019-07-23 10:49:28 -07:00
Keith Grant
c080346751 start on InventoriesLookup 2019-07-23 10:49:28 -07:00
softwarefactory-project-zuul[bot]
d9c2bd8ef3 Merge pull request #4364 from AlanCoding/azure_mo_data
Re-create lost data in Azure_rm imports

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-23 15:47:29 +00:00
Jake McDermott
37e73acb62 cleanup tooling 2019-07-23 11:47:19 -04:00
beeankha
04404c93db Enforce http_method restrictions via API 2019-07-23 11:47:19 -04:00
beeankha
6ef235dcd5 Enable auth header to send with just username field filled in 2019-07-23 11:47:19 -04:00
Jake McDermott
d66106d380 rename docker-notifications to docker-httpbin 2019-07-23 11:47:19 -04:00
beeankha
99737937cd No auth header sent if username/password fields are blank 2019-07-23 11:47:19 -04:00
beeankha
0a0b09b394 Update logic in send method to recognize password field in upgraded webhook notifications 2019-07-23 11:47:19 -04:00
Jake McDermott
2b74b6f9b6 add tooling for basic testing of notification webhooks 2019-07-23 11:47:19 -04:00
beeankha
6e9f74eb17 Updating tests, changing 'method' to 'http_method' 2019-07-23 11:47:19 -04:00
Jake McDermott
cc0310ccd4 add notification webhook fields 2019-07-23 11:47:19 -04:00
beeankha
52b01feafe Change init parameter name to 'http_method' to reduce ambiguity 2019-07-23 11:47:19 -04:00
beeankha
fbb3fd2799 Add custom HTTP method 2019-07-23 11:47:19 -04:00
beeankha
5071e1c75f Update webhook backend to take username/password 2019-07-23 11:47:19 -04:00
beeankha
6f030256f5 Add username and password fields to webhook backend 2019-07-23 11:47:19 -04:00
softwarefactory-project-zuul[bot]
0fff7465e8 Merge pull request #4360 from ryanpetrello/smart-inv-ignore-conflicts
replace the smart inventory membership lock with a new Django 2.2 flag

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-23 05:30:53 +00:00
AlanCoding
a0c7471110 Re-create lost data in Azure_rm imports 2019-07-22 15:32:24 -04:00
Ryan Petrello
1cedf244b7 replace the smart inventory membership lock with a new Django 2.2 flag 2019-07-22 11:11:36 -04:00
Ryan Petrello
f6c357659d Merge pull request #4348 from shanemcd/devel
Bump VERSION to 6.1.0
2019-07-18 14:26:18 -04:00
softwarefactory-project-zuul[bot]
8ccccfecf1 Merge pull request #4316 from keithjgrant/222-job-results-details
222 job results details

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-18 17:15:38 +00:00
Shane McDonald
2d7420317b Bump VERSION to 6.1.0 2019-07-18 13:08:52 -04:00
softwarefactory-project-zuul[bot]
6bdb106128 Merge pull request #4345 from jakemcdermott/fix-4302
fix reference to undefined prop for auditors

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-18 17:07:10 +00:00
softwarefactory-project-zuul[bot]
a128a94842 Merge pull request #4314 from mgs4332/memcached_image
Addition of inventory value for memcached image, allows for custom im…

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-18 16:20:37 +00:00
softwarefactory-project-zuul[bot]
f7a455bc83 Merge pull request #4346 from ansible/chrismeyersfsu-patch-1
Update collections.md

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-18 16:07:37 +00:00
softwarefactory-project-zuul[bot]
f51377ff85 Merge pull request #4339 from jbradberry/make-clean-test-dbs
Update the `make clean` command to clear out the parallelized sqlite3 files

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-18 15:51:24 +00:00
Chris Meyers
dc0862bbe7 Update collections.md 2019-07-18 11:12:51 -04:00
Jake McDermott
5b1350db75 fix reference to undefined prop for auditors 2019-07-18 10:21:50 -04:00
Scholl III, Michael G
12f564e4a3 Addition of inventory value for memcached image, allows for custom image locations for memcached to match other images 2019-07-18 09:24:44 -04:00
Keith Grant
0d7500d349 use unified jobs api to redirect to canonical url from /jobs/:id 2019-07-17 16:12:00 -07:00
Jeff Bradberry
d32394f1b6 Update the make clean command to clear out the parallelized sqlite3 files 2019-07-17 17:06:10 -04:00
softwarefactory-project-zuul[bot]
f5fee8e6e7 Merge pull request #4301 from chrismeyersfsu/tower_modules
Global collections path

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-17 20:11:25 +00:00
softwarefactory-project-zuul[bot]
9eb7042d8c Merge pull request #4072 from rambleraptor/gcp_env_vars
adding additional environment variables for gcp_compute + gcp modules

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-17 20:11:17 +00:00
chris meyers
9b95cc27c4 map in a global collections path 2019-07-17 15:36:09 -04:00
AlanCoding
2439aa409d Adjust inventory update env test to allow duplicate references
change gce injectors to not duplicate the credentials file
2019-07-17 12:30:13 -07:00
Alex Stephen
cb60f12b6b adding additional environment variables for gcp_compute + gcp modules 2019-07-17 12:30:12 -07:00
Keith Grant
2f9be4796a job detail style tweaks 2019-07-17 09:32:43 -07:00
Keith Grant
183bd4fa80 revert i18n on credential kind (API translates it) 2019-07-17 09:32:43 -07:00
Keith Grant
db4a964e64 run credential type through i18n 2019-07-17 09:32:43 -07:00
Keith Grant
761ed6dec0 prettier 2019-07-17 09:32:43 -07:00
Keith Grant
e3d67117e7 fix job detail breadcrumbs 2019-07-17 09:32:43 -07:00
Keith Grant
552164c25c flush out more type defs; JobDetail tests 2019-07-17 09:32:43 -07:00
Keith Grant
40f9b0dc7f add CredentialChip component 2019-07-17 09:32:43 -07:00
Keith Grant
eee1601528 job details: handle different job types 2019-07-17 09:32:43 -07:00
Keith Grant
da780c9d7c make VariablesInput detect whether value is JSON or YAML on init 2019-07-17 09:32:43 -07:00
Keith Grant
968cc8c79c add variables & artifacts to job detail 2019-07-17 09:32:43 -07:00
Keith Grant
4372e977f0 build basic job details 2019-07-17 09:32:43 -07:00
softwarefactory-project-zuul[bot]
41b0367627 Merge pull request #4337 from ryanpetrello/activity-stream-missing-jt
fix a 500 error for Activity Stream job records w/ a missing JT

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-17 16:17:53 +00:00
Ryan Petrello
c25dbb534f fix a 500 error for Activity Stream job records w/ a missing JT 2019-07-17 10:28:51 -04:00
softwarefactory-project-zuul[bot]
d0d08c2395 Merge pull request #4328 from jakemcdermott/nested-hashi-kv-v2-engine-names
support nested names for hashivault kv v2 secret engine

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-16 18:26:56 +00:00
softwarefactory-project-zuul[bot]
1242ee2b65 Merge pull request #4324 from keithjgrant/4218-lookup-toolbar-width
make lookup toolbar fill width of modal

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-16 18:18:46 +00:00
softwarefactory-project-zuul[bot]
7d0f062d9e Merge pull request #4333 from ansible/nightwatchxsl
Added nightwatch stylesheet to e2e

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-16 18:09:24 +00:00
Keith Grant
aea08eef6b make lookup toolbar fill width of modal 2019-07-16 13:36:38 -04:00
Daniel Sami
aef263fa6c Added nightwatch stylesheet to e2e 2019-07-16 13:34:54 -04:00
Jake McDermott
35d9a8f839 support nested engine names for hashivault kv v2 secret engine
Add a field to hashivault plugins for identifying the secret
backend (mount point). If no secret backend is provided, the
first part of the secret path is used.
2019-07-16 13:13:22 -04:00
softwarefactory-project-zuul[bot]
fef6e0b191 Merge pull request #4332 from ryanpetrello/roll-back-fedora
Roll back the dev environment to CentOS 7 and build a newer sqlite3

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-16 15:19:45 +00:00
Ryan Petrello
b620d8505a build and link a newer sqlite3 to make Django happy 2019-07-16 10:50:49 -04:00
softwarefactory-project-zuul[bot]
9fc1378fd1 Merge pull request #4304 from mabashian/3901-desc
Add host description to relevant lists

Reviewed-by: Michael Abashian
             https://github.com/mabashian
2019-07-16 14:29:43 +00:00
mabashian
b46db98b5a Removes some unused classes. Fix host desc ellipsis and responsiveness. Add desc to group hosts 2019-07-16 09:28:17 -04:00
Jose Ariza
14bdf8deb3 #3348 improved related listing on mobile
Signed-off-by: Jose Ariza <l.jlac001@gmail.com>
2019-07-16 09:28:17 -04:00
Jose Ariza
24df1d7be6 #3348 improved listing on mobile
Signed-off-by: Jose Ariza <l.jlac001@gmail.com>
2019-07-16 09:28:17 -04:00
Jose Ariza
40ead6f9d1 #3348 implemented suggested style changes
Signed-off-by: Jose Ariza <l.jlac001@gmail.com>
2019-07-16 09:28:17 -04:00
Jose Ariza
2a71232dd6 #3348 added description to host list on inventories related hosts
Signed-off-by: Jose Ariza <l.jlac001@gmail.com>
2019-07-16 09:28:17 -04:00
Jose Ariza
8b301f91ab #3348 added description to host list
Signed-off-by: Jose Ariza <l.jlac001@gmail.com>
2019-07-16 09:28:17 -04:00
Ryan Petrello
a4b2d6bf88 Revert "Change the devel containers to be based on Fedora instead of CentOS"
This reverts commit 7936dff188.
2019-07-16 09:18:24 -04:00
softwarefactory-project-zuul[bot]
b8b98b136b Merge pull request #4070 from jbradberry/upgrade-django-2.2
Upgrade Django to 2.2

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-15 22:56:22 +00:00
softwarefactory-project-zuul[bot]
c4b4b319c9 Merge pull request #4323 from keithjgrant/4248-tooltip-permissions-list
fix listed resources in delete tooltip

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-15 13:13:41 +00:00
Jeff Bradberry
dd8ca5acc4 Ensure that the Postgres client is installed 2019-07-12 16:22:52 -04:00
Jeff Bradberry
172864a3a1 Force the username and password to be strings under the Radius backend
The base Radius backend encodes them as utf-8 bytes, which causes the
User object that we create to get the repr of the username, including
the b prefix and single quotes, e.g. "b'foo'".
2019-07-12 15:11:22 -04:00
Jeff Bradberry
a691340986 Update authenticate method on auth backends to add required request param
This became mandatory in Django 2.1.
2019-07-12 15:11:22 -04:00
Jeff Bradberry
261f1427e9 Break up a too-long line in migrations 2019-07-12 15:11:22 -04:00
Jeff Bradberry
9383512772 Remove no longer needed check for override of WSGIHandler 2019-07-12 15:11:22 -04:00
Jeff Bradberry
2d81923e22 Fix up changes in fields in the migrations
Particularly the now-required on_delete parameter for ForeignKey and
OneToOneField.
2019-07-12 15:11:22 -04:00
Jeff Bradberry
1093a662f1 Fix a problem with a change in results from User.has_usable_password 2019-07-12 15:11:22 -04:00
Jeff Bradberry
210517eeb1 Fix a couple of tests trivially affected by the upgrades
- is_anonymous may no longer be called as a method, so no need to mock it
- the message on uniqueness constraint failures has apparently changed
2019-07-12 15:11:22 -04:00
Jeff Bradberry
2ffe3d9a85 Give the 4xx error handler views the correct positional arguments 2019-07-12 15:11:22 -04:00
Jeff Bradberry
6737bd4c19 Replace {} as field default values with the callable dict 2019-07-12 15:11:22 -04:00
Jeff Bradberry
29ad847544 Deal with a change in truncation of strings in Django
which now uses a proper ellipsis character instead of 3 dots.
2019-07-12 15:11:22 -04:00
Jeff Bradberry
b3ef2c928a Remove the custom add and remove methods from OrderedManyToManyDescriptor 2019-07-12 15:11:22 -04:00
Shane McDonald
7936dff188 Change the devel containers to be based on Fedora instead of CentOS
since we need a more recent version of sqlite.
2019-07-12 15:11:22 -04:00
Jeff Bradberry
43c552c7c6 Some flake8 changes 2019-07-12 15:11:21 -04:00
Jeff Bradberry
e0357d53f5 Bump Django to 2.2.2 2019-07-12 15:11:21 -04:00
Jeff Bradberry
beb1dd5ae7 Replace use of the deprecated staticfiles template library with static 2019-07-12 15:11:21 -04:00
Jeff Bradberry
d464df557b Fix another direct assignment of a sequence to a related manager 2019-07-12 15:11:21 -04:00
Jeff Bradberry
5e9f790554 Bump to Django 2.1.9 2019-07-12 15:11:21 -04:00
Jeff Bradberry
47b325896d Remove the django_db mark from TransactionTestCase classes
pytest-django's documentation indicates that it isn't necessary, and
it turns out in Django 2.0+ that this double application of the
transaction machinations was causing the Django ContentType table to
lose its items.
2019-07-12 15:11:21 -04:00
Jeff Bradberry
c85d58e28d The interactive flag for management commands doesn't seem to be a thing anymore 2019-07-12 15:11:21 -04:00
Jeff Bradberry
bcbb768dd3 Remove the use of the deprecated Field.rel attribute
Also, rename a number of variables named `rel` for ease of searching.
2019-07-12 15:11:21 -04:00
Jeff Bradberry
e0693d3746 is_anonymous and is_authenticated no longer support being called as methods 2019-07-12 15:11:21 -04:00
Jeff Bradberry
a6edc46cc3 Field.from_db_value no longer supports the context param in 2.0 2019-07-12 15:11:21 -04:00
Jeff Bradberry
f24b08316d Django's url resolver and pattern classes have been renamed in 2.0+
They are now URLResolver and URLPattern, respectively.  The API has
changed as well, but fortunately it looks like what we are doing here
doesn't depend on anything that was changed.
2019-07-12 15:11:21 -04:00
Jeff Bradberry
25c14382db Update the monkey patch of Django's column name digest to work with 2.0+
BaseDatabaseSchemaEditor no longer has a `_digest` classmethod,
instead there is a call out to a new `names_digest` utility function.
2019-07-12 15:11:21 -04:00
Jeff Bradberry
796d7bf67f Replace the use of the 3rd party jsonbfield library
which was just a backport of Django's built-in JSONField.  Also, bump
the version of django-jsonfield.
2019-07-12 15:11:21 -04:00
Jeff Bradberry
ddef41d394 Bump Django to 2.0.13
This is _very_ broken.
2019-07-12 15:11:21 -04:00
softwarefactory-project-zuul[bot]
c626f51dae Merge pull request #4319 from AlanCoding/azure_template_errors
Ignore Azure templating errors

Reviewed-by: Alan Rominger <arominge@redhat.com>
             https://github.com/AlanCoding
2019-07-12 19:00:36 +00:00
softwarefactory-project-zuul[bot]
a9bb1eba02 Merge pull request #4320 from jdekoning/ssh-machine-creds-fix
Insert signed public key in artifact_dir, fix for issue #4139

Reviewed-by: Ryan Petrello
             https://github.com/ryanpetrello
2019-07-12 18:37:57 +00:00
Keith Grant
b1c87c1793 fix listed resources in delete tooltip 2019-07-12 09:43:40 -07:00
AlanCoding
612205d56d Ignore Azure templating errors 2019-07-12 08:11:27 -04:00
Jaap de Koning
94b1455f40 Insert signed public key in artifact_dir, hacky fix for issue #4139
Signed-off-by: Jaap de Koning <jaap.de.koning@bigdatarepublic.nl>
2019-07-12 14:10:14 +02:00
softwarefactory-project-zuul[bot]
b26bd11924 Merge pull request #4315 from AlanCoding/old_migration_methods
Remove unused migration methods

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-12 02:11:08 +00:00
AlanCoding
287159296a remove unused migration methods 2019-07-11 16:09:38 -04:00
softwarefactory-project-zuul[bot]
23100094dc Merge pull request #4313 from ryanpetrello/fix-4162
Remove tooltips from host events in output

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-11 18:29:35 +00:00
softwarefactory-project-zuul[bot]
b2275c0490 Merge pull request #4312 from wenottingham/check-one-check-two
Add some minimal sanity checking before running the updater script.

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-11 16:55:56 +00:00
softwarefactory-project-zuul[bot]
d6dba784b1 Merge pull request #4285 from olia-dev/issue-4274
related #4274 - added option to verify server certificate with a specific CA

Reviewed-by: Jake McDermott <yo@jakemcdermott.me>
             https://github.com/jakemcdermott
2019-07-11 16:50:26 +00:00
Bill Nottingham
2a68ff49c1 Add some minimal sanity checking before running the updater script. 2019-07-11 12:12:22 -04:00
mabashian
0f8c59523a Remove tooltips from host events in output 2019-07-11 12:07:28 -04:00
softwarefactory-project-zuul[bot]
de02df4907 Merge pull request #4201 from beeankha/helper_method_in_serializer
Add Helper Method in Serializer for get_summary_fields

Reviewed-by: Yanis Guenane
             https://github.com/Spredzy
2019-07-10 14:28:04 +00:00
olia-dev
522dcf5ed3 related #4274 - moved function 'create_temporary_fifo' to 'awx/main/utils/common.py' and referenced it in other plugins (fixed errors) 2019-07-10 12:40:26 +02:00
olia-dev
b2d84a5d89 related #4274 - moved function 'create_temporary_fifo' to 'awx/main/utils/common.py' and referenced it in other plugins (fixed errors) 2019-07-10 12:39:57 +02:00
olia-dev
7b390fa2fc related #4274 - moved function 'create_temporary_fifo' to 'awx/main/utils/common.py' and referenced it in other plugins
Signed-off-by: olia-dev <olia-dev@ktah.net>
2019-07-10 11:41:21 +02:00
softwarefactory-project-zuul[bot]
557ec27303 Merge pull request #4251 from AlexSCorey/JTLaunchButton
Add Launch Button to Job Template Details

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 20:58:46 +00:00
softwarefactory-project-zuul[bot]
f47a37a96b Merge pull request #4259 from AlexSCorey/4216-OrgGetRequestDuplication
Removes duplicated GET request in Org.

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 18:44:09 +00:00
softwarefactory-project-zuul[bot]
74d8fca673 Merge pull request #4296 from pebbledavec/patch-1
Removed forwardslash that was breaking paginated workflow node requests.

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 18:40:34 +00:00
Alex Corey
7039f82d15 Only reload details whe navigating to details from another tab 2019-07-09 13:43:09 -04:00
softwarefactory-project-zuul[bot]
e34833c8cb Merge pull request #4300 from jakemcdermott/output-updown
get more events on page down or up when needed

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 17:12:27 +00:00
softwarefactory-project-zuul[bot]
f22314caaf Merge pull request #4257 from marshmalien/skeleton-template-add-form
Skeleton template add form

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 17:06:46 +00:00
Marliana Lara
fb0c82598f Address PR feedback 2019-07-09 12:37:50 -04:00
Jake McDermott
90f7e9375f get more events on page down or up when needed
when we page up or down, check if we've moved into the upper or lower
threshold of the scrollbar and request more events to show if we have.
2019-07-09 10:21:48 -04:00
softwarefactory-project-zuul[bot]
ccea920ea3 Merge pull request #4263 from fantashley/easy-custom-venvs
Add dynamic custom venv setup

Reviewed-by: Shane McDonald <me@shanemcd.com>
             https://github.com/shanemcd
2019-07-09 13:23:37 +00:00
softwarefactory-project-zuul[bot]
2d636806db Merge pull request #4123 from clushie/update_openstacksdk_dependencies
Fix outdated openstacksdk version and add pip-compile helper script

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 13:04:12 +00:00
softwarefactory-project-zuul[bot]
bda42332b7 Merge pull request #4295 from JakobP/bug/3857-improve-error-message
Fix #3857. More informative error message for job templates

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 13:00:05 +00:00
olia-dev
2ee03b552d related #4274 - added option to verify server certificate with a specific CA (fixed errors) 2019-07-09 14:14:29 +02:00
olia-dev
7a5efa1adc related #4274 - added option to verify server certificate with a specific CA 2019-07-09 13:59:11 +02:00
pebbledavec
2ff3b5d62c Removed forwardslash that was breaking paginated workflow node requests.
The forward-slash in getWorkflowJobTemplateNodes was incorrectly interpreted as part of the pagesize integer (and thereby throwing an exception) when a complex workflow spanned multiple pages of workflow nodes.
Resolves: #4261
Signed-off-by: Dave Compton <sircompo@gmail.com>
2019-07-09 12:50:40 +01:00
Jakob Pedersen
e23ee41082 Fix issue #3857 with a more informative error message when the usercan not post to /#/templates/add_job_template
The cause can be both missing permissions and no projects being available.

Related #3857

Signed-off-by: Jakob Pedersen <CONS_JPE@jysk.com>
2019-07-09 10:47:19 +02:00
softwarefactory-project-zuul[bot]
2aa32f61f8 Merge pull request #4290 from ryanpetrello/csp-false-positive
specify a ng-csp attribute so Angular doesn't autodetect

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-09 01:58:18 +00:00
Ashley Nelson
036e1ad82e Add dynamic custom venv setup
Add support for python3 venvs
2019-07-08 18:49:31 -05:00
Ryan Petrello
66321a6218 specify a ng-csp attribute so Angular doesn't autodetect
without this, we're getting a false positive log message about an unsafe
eval (which is *actually* just angular auto-detecting whether or not
eval is supported)
2019-07-08 17:32:41 -04:00
softwarefactory-project-zuul[bot]
1f31cc9394 Merge pull request #4101 from jbradberry/fix-4099
Include defined fields from all parent classes of a HybridDictField

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-08 21:15:11 +00:00
Jeff Bradberry
758ad164fe Include defined fields from all parent classes of a HybridDictField
since our settings registry adds a mixin class when doing validation on these.

related #4099
2019-07-08 16:05:03 -04:00
softwarefactory-project-zuul[bot]
be975fc051 Merge pull request #4283 from falcon78921/wip-awx-minor-fix
awx/ui: minor fix on Update on Project Update description

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-08 19:48:28 +00:00
softwarefactory-project-zuul[bot]
04ea39c315 Merge pull request #4282 from saito-hideki/issue/tower_3590
Fix to use "type" as the condition value for Machine credential to cover I18N

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-08 19:36:31 +00:00
beeankha
12e0c31fe6 Rename helper method 2019-07-08 15:03:35 -04:00
Hideki Saito
869d259433 Fix conditional values for handle internationalization
Fix the variable for checking the credential type from "name" to "kind"
 in order to correctly handle I18N.

Signed-off-by: Hideki Saito <saito@fgrep.org>
2019-07-08 15:03:35 -04:00
beeankha
0dba3f53b1 Add in schedule case to helper method, make Activity Stream link point to schedule page 2019-07-08 14:59:07 -04:00
beeankha
73c87f9512 Add helper method in order to reduce repetition 2019-07-08 14:59:07 -04:00
softwarefactory-project-zuul[bot]
7faff07bd9 Merge pull request #4279 from athenahealth/fix-csp-for-safari-websockets
Update Content Security Policy to allow websockets

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-08 18:00:42 +00:00
softwarefactory-project-zuul[bot]
ca83b62c21 Merge pull request #4277 from jainnikhil30/devel
add inventory name and id to meta vars

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-08 16:09:49 +00:00
olia-dev
f77298643f related #4274 - added option to verify server certificate with a specific CA 2019-07-08 10:39:42 +02:00
James McClune
8aa33b9b4a awx/ui: minor fix on Update on Project Update description
In the Inventory Source settings, one of the update options is titled
Update on Project Change. However, the tooltip is titled
Update on Project Update. Looking at the overall AWX codebase, I think
the definitions are fitted more towards Update on Project Update.

Signed-off-by: James McClune <jmcclune@mcclunetechnologies.net>
2019-07-07 23:36:54 -04:00
Jeff Byrnes
987cfed649 Update Content Security Policy to allow websockets
Per #4167 a reasonable CSP was put in place, but unfortunately this
broke WebSockets support in Safari.

This is a quick fix to return support immediately. A more secure
implemetation would be beneficial in the longer term, however.
2019-07-05 16:12:27 -04:00
softwarefactory-project-zuul[bot]
9b6644bc77 Merge pull request #4276 from ryanpetrello/ldap-tls-verify-off
fix a bug that breaks OPT_X_TLS_REQUIRE_CERT=0 for LDAP authentication

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-05 15:58:47 +00:00
jainnikhil30
88a4362a7a add inventory name and id to meta vars 2019-07-05 20:37:36 +05:30
Ryan Petrello
0dcbafaccb fix a bug that breaks OPT_X_TLS_REQUIRE_CERT=0 for LDAP authentication 2019-07-05 10:24:18 -04:00
Alex Corey
3b17170533 more concise conditions for api calls 2019-07-03 16:19:43 -04:00
Marliana Lara
7afaacb5e3 Add Job Template Add form skeleton and test 2019-07-03 15:44:52 -04:00
Marliana Lara
b06421b870 Rename TemplateForm to JobTemplateForm 2019-07-03 15:44:52 -04:00
Alex Corey
320581a6c0 Addresses PR issues 2019-07-03 12:43:40 -04:00
softwarefactory-project-zuul[bot]
d4f50896de Merge pull request #4260 from fantashley/fix-docker-module-name
Change to docker_service for compatibility

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-03 12:28:35 +00:00
softwarefactory-project-zuul[bot]
71812c66d2 Merge pull request #4118 from DanielDisisto/patch-1
Failing requirements update when scm_type != git

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-03 12:17:05 +00:00
softwarefactory-project-zuul[bot]
731d8c21e8 Merge pull request #4252 from ansible/jakemcdermott-fix-readme-snippet
fix README snippet

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-03 11:55:05 +00:00
DanielDisisto
3247983823 Failing requirements update when scm_type != git
The `git_result` variable is incorrectly checked as being `defined` vs. `not skipped`. This causes SVN (or any non-GIT) project update to fail consistently when `doesRequirementsExist.stat.exists` is true

Signed-off-by: DanielDisisto <daniel.disisto@didata.com.au>
2019-07-03 07:51:01 -04:00
Ashley Nelson
485536d4cf Change to docker_service for compatibility 2019-07-02 16:03:43 -05:00
softwarefactory-project-zuul[bot]
b37040a85c Merge pull request #4256 from ryanpetrello/inline-image-csp
allow data: images in our Content Security Policy

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-02 17:13:10 +00:00
Alex Corey
b5b38c1b79 addresses PR Issues 2019-07-02 12:36:13 -04:00
softwarefactory-project-zuul[bot]
84ad1cdfcd Merge pull request #4250 from kialam/fix-254-delete-last-elem-list-page
Fix 254 delete last elem list page

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-02 16:17:51 +00:00
Ryan Petrello
75a72637dd allow data: images in our Content Security Policy
support for custom login logos relies on data:image/*;base64
see: https://github.com/ansible/awx/issues/4253
2019-07-02 11:35:56 -04:00
Kia Lam
74e4c17b63 Address PR feedback and format. 2019-07-02 09:54:07 -04:00
softwarefactory-project-zuul[bot]
c65ae87d69 Merge pull request #4175 from jainnikhil30/devel
fix the hashivault v2 lookup

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-02 12:42:41 +00:00
Phileas Lebada
7feb6515e1 Bump openstacksdk version
Signed-off-by: github.com/clushie <47661139+clushie@users.noreply.github.com>
2019-07-02 13:56:26 +02:00
Phileas Lebada
d3b3b6e8f5 Add cosmetic change with updater.sh
Signed-off-by: github.com/clushie <47661139+clushie@users.noreply.github.com>
2019-07-02 13:56:26 +02:00
Phileas Lebada
48e02f373f Add pip-compile updater.sh script
Signed-off-by: github.com/clushie <47661139+clushie@users.noreply.github.com>
2019-07-02 13:56:26 +02:00
jainnikhil30
dbf8df479b use path instead of *path while dong the join 2019-07-02 07:55:35 -04:00
jainnikhil30
764947c1ae fix the hashivault v2 lookup 2019-07-02 07:55:32 -04:00
Jake McDermott
0b724682da fix README snippet 2019-07-01 19:50:16 -04:00
softwarefactory-project-zuul[bot]
4fb055345d Merge pull request #4199 from mabashian/264-notification-type-column
Show notification type in its own column

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-01 22:57:50 +00:00
Kia Lam
d3ed6ac73a Fix Template list as well. 2019-07-01 16:21:41 -04:00
Kia Lam
d22cafc42e Add unit test. 2019-07-01 16:20:38 -04:00
Kia Lam
58444a75b9 Fix Org list returning a 404 by redirecting user to current page.
- Update itemCount after an org has been successfully deleted.
- Update PaginatedDataList to get current page when the number of items has changed.
2019-07-01 16:20:38 -04:00
softwarefactory-project-zuul[bot]
7178c1d9e0 Merge pull request #4200 from ansible/jakemcdermott-contrib-formatter
run formatting check with ci

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-01 19:28:39 +00:00
Jake McDermott
945d9156a6 do formatting check with ci linter 2019-07-01 14:27:25 -04:00
Jake McDermott
bf86719412 add a note about running the formatter 2019-07-01 14:16:17 -04:00
mabashian
12c0b80102 Prettify files 2019-07-01 13:51:13 -04:00
mabashian
1d2c21249b Show notification type in its own column 2019-07-01 13:49:38 -04:00
softwarefactory-project-zuul[bot]
3371a6f386 Merge pull request #4188 from mabashian/awx-pf-migration
Pull beginning of new ui application using React and Patternfly into AWX

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-01 17:31:32 +00:00
softwarefactory-project-zuul[bot]
e79fbab737 Merge pull request #4196 from shanemcd/devel
Release 6.0.0

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
2019-07-01 17:03:29 +00:00
mabashian
8f74bad1c1 Roll back changes to test linting and unit test gating 2019-07-01 12:34:09 -04:00
mabashian
02d320de71 Commit to test linting and unit test gating 2019-07-01 12:04:45 -04:00
mabashian
5cb8bd34ac Adds make targets for linting/tests in ui_next. Modifies existing clean-ui target to clean ui_next as well. 2019-06-28 12:11:07 -04:00
mabashian
b457926b38 Update usage instructions since paths have changed 2019-06-28 10:50:49 -04:00
mabashian
55ce409a12 Run prettier on all the files in awx/ui_next 2019-06-28 09:26:11 -04:00
mabashian
051bbcaeb5 Remove gitignore from awx/ui_next and add rules to base gitignore 2019-06-28 09:23:45 -04:00
mabashian
2de5fbdac7 Merge awx-pf into awx 2019-06-28 09:09:52 -04:00
Michael Abashian
43592cbe00 Move everything to awx/ui_next (#297) 2019-06-27 11:11:58 -04:00
Michael Abashian
0a6fc8cb89 Fix for unit test failure in jt detail test where getting instance groups wasn't mocked (#296)
Fix for unit test failure in jt detail test where getting instance groups wasn't mocked.
2019-06-26 16:07:58 -04:00
Marliana Lara
5e6562023d Merge pull request #295 from marshmalien/job-template-directory-name
Job template directory name
2019-06-26 15:10:33 -04:00
Marliana Lara
14280ec53b Update launch button hover styles 2019-06-26 14:51:27 -04:00
Marliana Lara
edef496583 Update job template breadcrumb content 2019-06-26 14:49:10 -04:00
Marliana Lara
cfc0a4771f Update the JT Edit directory, file, and component names 2019-06-26 14:45:35 -04:00
Marliana Lara
f6ddb72482 Add key to ansible select options test 2019-06-26 14:41:38 -04:00
Michael Abashian
52851c57d8 Display details about network errors in alert modal and content error components (#288)
Display details about network errors in alert modal and content error components
2019-06-26 11:40:15 -04:00
Marliana Lara
a503529d05 Merge pull request #291 from marshmalien/skeleton-template-edit-form
Skeleton template edit form
2019-06-26 10:33:22 -04:00
Marliana Lara
a2a245c89e Add unique key prop to ansible select options 2019-06-26 10:21:34 -04:00
Marliana Lara
f3bf35311e Address PR feedback and merge conflicts 2019-06-25 16:29:55 -04:00
Marliana Lara
67d619f9cc Add template edit and form tests 2019-06-25 15:49:28 -04:00
Marliana Lara
463357c81e Add template edit form skeleton 2019-06-25 15:49:24 -04:00
Marliana Lara
7b3e5cd8d5 Refactor AnsibleSelect data prop to accept an array of option objects
* First custom_virtualenv in options list is always default
2019-06-25 15:47:42 -04:00
Alex Corey
ec1fa4dae6 240 jt details skeleton v2 (#273)
* adding package-lock.json

* deleted unsured file

* Adds a Bottom Border Component

* Updates dependencies

* Adds JT Details and tests for it

* merge and rebase

* addresses UI PR issues

* Addresses PR Issues and fixes failing tests.

* Updates to code, fixes package and package-lock.json addresses PR Issues

* fixes package files
2019-06-25 15:28:07 -04:00
Keith Grant
e49b9a202e Prettier configs (#281)
Add .prettierrc and update eslint configs
2019-06-25 11:26:44 -07:00
Jake McDermott
059fa9001a Merge pull request #287 from jakemcdermott/more-big-pr-fixups
misc cleanup from big prs
2019-06-24 10:22:33 -04:00
Jake McDermott
cc36b46925 remove network context mock 2019-06-21 12:15:59 -04:00
Jake McDermott
657a6f3a93 use top-level import aliases 2019-06-21 12:10:01 -04:00
Jake McDermott
9dda5404a0 add 'has' prefix to error booleans 2019-06-21 12:01:29 -04:00
Jake McDermott
c3823771a7 Merge pull request #269 from jakemcdermott/jobs-list-skeleton
job list skeleton
2019-06-21 11:54:16 -04:00
Jake McDermott
69426dee08 add basic test coverage for job list 2019-06-21 11:46:40 -04:00
Jake McDermott
22dbe5c0f9 add shared DataListCell component 2019-06-21 11:46:40 -04:00
Jake McDermott
d8452e1259 job list skeleton 2019-06-21 11:46:35 -04:00
Michael Abashian
cb50cdce0d Add support for launching job templates from the templates list (#277)
Add support for launching job templates from the templates list
2019-06-20 15:21:57 -04:00
Jake McDermott
cd672baa13 Merge pull request #284 from jakemcdermott/move-yaml-test
move yaml test to utils
2019-06-20 15:00:08 -04:00
Jake McDermott
30709d1ab2 Merge pull request #283 from jakemcdermott/has
prefix content error and loading booleans with 'has'
2019-06-20 14:59:52 -04:00
Jake McDermott
f382fce576 move yaml test to utils 2019-06-20 14:47:39 -04:00
Jake McDermott
36d2d03bc7 prefix content error and loading booleans with 'has' 2019-06-20 14:37:46 -04:00
Michael Abashian
b21e491075 Updates to contributing doc (#280) 2019-06-20 13:32:25 -04:00
Marliana Lara
740402e5a8 Merge pull request #279 from mabashian/templates-routes
Add basic routing for templates
2019-06-20 12:11:22 -04:00
Marliana Lara
5662d8b625 Remove Fragment 2019-06-20 12:01:43 -04:00
mabashian
af6ea1cc58 Notifications plural 2019-06-20 11:34:16 -04:00
mabashian
f185d80b05 Fix border bottom on tabs 2019-06-20 11:33:15 -04:00
mabashian
0a5f29ad22 Add basic routing for templates 2019-06-20 10:57:04 -04:00
Jake McDermott
3b7b27ea20 Merge pull request #276 from jlmitch5/testWatchFix
fix jest.config.js so `npm run test-watch` works
2019-06-20 08:25:56 -04:00
John Mitchell
7fee9e35c4 fix jest.config.js so npm run test-watch works 2019-06-19 16:41:19 -04:00
Jake McDermott
f33b343cd8 Merge pull request #274 from jakemcdermott/alias-top-level-imports
alias top-level imports
2019-06-19 13:09:26 -04:00
Jake McDermott
012852ec53 alias top-level imports 2019-06-19 11:45:57 -04:00
Michael Abashian
ee56e9ccfb Reorganize file locations/directory structure (#270)
Reorganize file locations
2019-06-19 11:41:14 -04:00
Keith Grant
e3cb8d0447 Add JSON/YAML components (#267)
Add CodeMirrorInput and VariablesField

Add components for syntax highlighting, YAML/JSON toggle
2019-06-18 12:32:22 -07:00
Marliana Lara
0b10ff7fe6 Merge pull request #268 from marshmalien/263-org-badge-count-styles
Group organization list user and member badges
2019-06-18 13:53:32 -04:00
Marliana Lara
c9a4cb7696 Reduce gap between organization list count badges 2019-06-18 12:07:08 -04:00
Michael Abashian
7a5cf4b81c Add support for deleting templates on templates list (#266)
Adds support for deleting templates from the templates list
2019-06-17 13:52:05 -04:00
Marliana Lara
4e45a3b365 Merge pull request #256 from marshmalien/skeleton-job-results
Skeleton job results
2019-06-17 11:48:14 -04:00
Marliana Lara
096f5fb324 Fix lint errors and pull in new content error and loading handler 2019-06-14 15:34:55 -04:00
Marliana Lara
416d30a189 Add close button to job detail and test 2019-06-14 14:46:48 -04:00
Marliana Lara
cda5cc25b8 Add Job results skeleton tests 2019-06-14 14:46:48 -04:00
Marliana Lara
508d8311dd Add Job results skeleton 2019-06-14 14:46:48 -04:00
Marliana Lara
54f9dd5e98 Add Job API model 2019-06-14 14:46:48 -04:00
Marliana Lara
4fe558392a Update organization card header and tabs to use styled-components 2019-06-14 14:46:42 -04:00
Jake McDermott
a98be1443b Merge pull request #255 from jakemcdermott/update-content-loading-and-errors
update content loading and error handling
2019-06-14 13:29:16 -04:00
Jake McDermott
e35f7acd05 add test coverage for auth utils 2019-06-14 13:01:02 -04:00
Jake McDermott
4aa4490933 add test coverage for api notification mixin 2019-06-14 13:00:50 -04:00
Jake McDermott
e72f0bcfd4 update content loading and error handling
unwind error handling

use auth cookie as source of truth, fetch config only when authenticated
2019-06-14 13:00:37 -04:00
Jake McDermott
534418c81a Merge pull request #262 from catjones9/organizations
Added Max Hosts field on Organizations Add/Edit form
2019-06-14 12:39:10 -04:00
catjones9
91b8aa90ff Added 'Max Hosts' field in the Add/Edit Organization view
* max hosts field is enabled is user is superuser, otherwise it is disabled and default is 0
 * OrganizationForm tests added for max hosts input
 * minMaxValue added in validators to validate user input for max hosts

Signed-off-by: catjones9 <catjones@redhat.com>
2019-06-13 18:43:34 -04:00
catjones9
5874becb00 Max Hosts shows up in Org Detail View
Signed-off-by: catjones9 <catjones@redhat.com>
2019-06-13 18:04:09 -04:00
Alex Corey
19b41743de 215 templates list skeleton (#251)
* adding package-lock.json

* deleted unsured file

* Removes and unused file

* Fixes errant styling change

* Fixes an error and uses a prop that PF recognizes

* Updates PR to use API Modules

*  Fixes PR Issues

* Addes tests to Templates

* Addresses PR Issues

* Revert package-lock.json
2019-06-13 11:08:05 -04:00
Michael Abashian
ffcb655038 Convert Tower logo/strings to AWX (#253)
Sets up awx logo and strings
2019-06-10 14:31:12 -04:00
Michael Abashian
2ae93261d1 api.js refactor using classes (#250)
Refactor api.js into an api module where endpoint specific models can be imported and used in components.
2019-06-07 15:48:09 -04:00
catjones9
a8c51670af Switched Selectable Card to styled components (#249)
* Switched Selectable Card to styled components
 * styles.scss in AddRole/ removed
 * styles.scss import in index.jsx removed

Signed-off-by: catjones9 <catjones@redhat.com>

* Addressed PR linter issues

Signed-off-by: catjones9 <catjones@redhat.com>

* Switched Indicator and Label to styled components

Signed-off-by: catjones9 <catjones@redhat.com>
2019-06-04 15:03:41 -04:00
kialam
5df424803f Merge pull request #211 from ansible/upgrade-node-v8-to-node-v10
Upgrade our packaging for NodeJS 10.
2019-06-04 10:54:24 -04:00
John Mitchell
241d7f57b7 Merge pull request #247 from jlmitch5/removeUnusedScssStyles
remove unused scss styles from app.scss
2019-06-04 10:30:44 -04:00
John Mitchell
9ba8feaec1 remove unused scss styles from app.scss 2019-06-03 10:20:13 -04:00
Alex Corey
886d29e111 Merge pull request #236 from AlexSCorey/SwitchToStyledComps
updates test issues caused by PF bump
2019-05-28 13:30:55 -04:00
Alex Corey
7452b82856 addresses PR issues 2019-05-28 13:13:42 -04:00
Alex Corey
b7b17b9176 updates test issues caused by PF bump 2019-05-28 11:42:17 -04:00
Keith Grant
29e17ac49e Standardize chip height (#213)
* make all chips the same size

* create DetailList, Detail components; clean up Chips, ChipGroup

* delete BasicChip in favor of <Chip isReadOnly>

* create our own ChipGroup to handle overflow
2019-05-28 08:49:03 -04:00
Keith Grant
189e12f8b3 Restore logo (#218)
* move tower logo svg into component

* switch to new logo in header & login screen
2019-05-23 13:47:41 -04:00
Keith Grant
cc2869d0c2 Merge pull request #214 from keithjgrant/200-trailing-slash-routing
Redirect to remove trailing slash from URL
2019-05-23 09:54:07 -04:00
Keith Grant
79d8b74221 redirect to remove trailing slash from URL 2019-05-23 08:29:08 -04:00
Jake McDermott
8d8d9292bc Merge pull request #212 from jakemcdermott/wait-for-element
add waitForElement helper
2019-05-22 10:52:14 -04:00
Jake McDermott
7965f94027 add waitForElement helper 2019-05-22 08:56:49 -04:00
Kia Lam
efc45ac1fa Upgrade our packaging for NodeJS 10.
- Update README.md
- Bump certain dependencies to fix vulnerabilities.
2019-05-20 16:07:33 -04:00
Keith Grant
6bfbcb35cd Merge pull request #208 from keithjgrant/toolbar-render-prop
use a render prop for PaginatedDataList toolbar
2019-05-20 06:16:48 -07:00
Keith Grant
8cd05679c2 extract out PaginatedDataListItem 2019-05-20 09:15:31 -04:00
Keith Grant
510d56b245 refactor PaginatedDataList to renderToolbar prop 2019-05-20 09:13:23 -04:00
Alex Corey
dc1bfaac3f Merge pull request #203 from AlexSCorey/178-AddOrgBtnV2
178 add org btn v2
2019-05-17 19:48:08 -04:00
Alex Corey
92d8948a83 updates tests 2019-05-17 15:32:04 -04:00
Alex Corey
d3cc1a8771 Adds AddOrgBtn to Orgs List empty state 2019-05-17 15:29:05 -04:00
Keith Grant
5df2b1f346 Merge pull request #207 from keithjgrant/126-pf-pagination
Convert to PF Pagination component
2019-05-17 11:01:03 -04:00
Keith Grant
7ff7517bdf change pagination drop direction to up 2019-05-17 07:47:17 -07:00
Keith Grant
957984d9e9 convert to PF Pagination component 2019-05-16 16:09:58 -04:00
John Mitchell
69a25bb092 Merge pull request #198 from jlmitch5/translationUpdate
utilize i18n correctly
2019-05-16 13:54:05 -04:00
John Mitchell
b45f3f6cab fix inadverdently added extra notification toggle from conflicts 2019-05-16 13:32:40 -04:00
John Mitchell
0f02daa64d run to generate po files 2019-05-16 12:53:56 -04:00
John Mitchell
001fc1293c fix lint error from removing api passing via props 2019-05-16 12:45:14 -04:00
John Mitchell
f4550900bb update tests based on i18n changes 2019-05-16 11:38:28 -04:00
John Mitchell
e2de8e4d5f update i18n contributing guidelines 2019-05-15 11:20:20 -04:00
John Mitchell
07664a05fd update awx-pf to use withI18n i18n._ and t exclusively 2019-05-15 11:20:00 -04:00
Keith Grant
4407aeac20 Add namespacing for query params (#205)
* use qs utils to namespace query params

* refactor Lookup and SelectResource Steps to use PaginatedDataList

* preserve query params when adding new ones

* require namespace for QS Configs
2019-05-15 10:06:14 -04:00
kialam
d59975c1ad Merge pull request #204 from ansible/use-styled-components
Use styled-components
2019-05-14 10:33:28 -04:00
Kia Lam
cc24d524ac Merge remote-tracking branch 'origin' into use-styled-components 2019-05-14 10:20:25 -04:00
Kia Lam
457c6287a2 General cleanup.
- Fix tests.
- Update snapshots.
- Remove old import statement.
- Add element ids for Sort and Search Components.
2019-05-13 18:42:26 -04:00
Kia Lam
3322123dd4 Remove defunct external stylesheet. 2019-05-13 18:42:26 -04:00
Kia Lam
a53509b359 Refactor DataListToolbar component. 2019-05-13 18:42:26 -04:00
Kia Lam
a87c6ddf1b Convert DataListToolbar to a styled-component. 2019-05-13 18:42:25 -04:00
Kia Lam
0ea4a4dedd Convert toolbar button components to styled-components. 2019-05-13 18:42:25 -04:00
Kia Lam
cc192246d9 Make Orgs List page responsive. 2019-05-13 18:42:08 -04:00
Marliana Lara
0b3245eab6 Merge pull request #201 from marshmalien/194-missing-header-dropdowns
Fix page header styles, search icon, and vertical separator
2019-05-13 16:23:48 -04:00
Marliana Lara
b640203f88 Fix page header styles, search icon, and vertical separator 2019-05-10 12:29:55 -04:00
Kia Lam
82c7052d6f Make Org Notifications page responsive. 2019-05-10 11:06:24 -04:00
Kia Lam
349a9c7cc2 Add styled-components library and its babel plugin. 💅 2019-05-10 11:03:16 -04:00
Keith Grant
e7ec1c6ef8 convert OrganizationList to use PaginatedDataList (#192)
* convert Org list to use PaginatedDataList

* add ToolbarAddButton, ToolbarDeleteButton

* pass full org into OrganizationListItem
2019-05-07 09:51:50 -04:00
Jake McDermott
a011896cc0 Update README.md 2019-05-06 11:11:27 -04:00
Alex Corey
a4899d4dbb Merge pull request #191 from AlexSCorey/175-BottomBorder
175 bottom border
2019-05-06 08:50:14 -04:00
Alex Corey
1200c23ebc addressing PR issues 2019-05-03 14:26:19 -04:00
Alex Corey
b8b2209335 add bottom border to org tabs 2019-05-03 10:27:48 -04:00
kialam
500765cea5 Merge pull request #186 from ansible/add-username-to-top-header-bar
Add logged in username to top level header bar.
2019-05-03 10:14:29 -04:00
Kia Lam
f14934f42c Translate tooltip block. 2019-05-03 09:59:10 -04:00
Alex Corey
a3fdb4aee3 add bottom border to tabs 2019-05-02 16:26:31 -04:00
Alex Corey
fed24ed6df Merge pull request #187 from AlexSCorey/177-UXImprovements
UX improvements
2019-05-02 16:22:13 -04:00
Alex Corey
c9c7d2c2a5 add tooltip proptype 2019-05-02 15:20:25 -04:00
Alex Corey
cc0b2bb5b4 added props to Proptypes 2019-05-02 15:12:04 -04:00
Alex Corey
e29710ebab Merge branch 'master' into 177-UXImprovements 2019-05-02 15:04:57 -04:00
Keith Grant
0ec274d13c Merge pull request #189 from keithjgrant/73-add-org-spacing
Adjust spacing for add/edit org form
2019-05-02 14:53:24 -04:00
Marliana Lara
0fc8179ca3 Merge pull request #190 from marshmalien/pf-base-css-import
Use recommended PatternFly Base CSS
2019-05-02 14:37:52 -04:00
Alex Corey
c6de6b8f25 added props to Proptypes 2019-05-02 14:34:17 -04:00
Marliana Lara
516aecf7de Use recommended PatternFly Base CSS 2019-05-02 11:43:13 -04:00
Keith Grant
eea3d72ffc add CardCloseButton tests 2019-05-02 10:02:45 -04:00
Keith Grant
1490235752 adjust spacing of org add/edit form, add CardCloseButton 2019-05-02 08:39:36 -04:00
Alex Corey
b136ce1e1d updating PR issues updated snapshot test 2019-05-01 15:48:08 -04:00
Alex Corey
f704f320b5 address pr issues 2019-05-01 14:42:59 -04:00
Alex Corey
c4a4275a89 updated snapshot of failing test 2019-05-01 14:42:00 -04:00
Alex Corey
64d4b71ec9 UX improvements 2019-05-01 14:42:00 -04:00
Keith Grant
1be496cfc1 Patternfly upgrade (#188)
* correct spacing after PF update

* update wizard layout/borders for PF upgrade
2019-05-01 13:50:00 -04:00
Alex Corey
420b19cfb9 Merge pull request #185 from AlexSCorey/AlexSCorey-deleteOrgsTest
Alex s corey delete orgs test
2019-04-30 13:22:35 -04:00
Kia Lam
5287af1b9f Add logged in username to top level header bar. 2019-04-30 11:05:08 -04:00
Alex Corey
f71421f60a removed orgsToDelete and fixed other tests 2019-04-30 10:22:25 -04:00
Alex Corey
f4da620c4d updating PR 2019-04-30 09:48:42 -04:00
Keith Grant
ffade973a9 upgrade to patternfly 2.x, pf/react-core 3.x (#184) 2019-04-30 08:19:19 -04:00
Alex Corey
1bae944b85 fix tests and function name changes 2019-04-29 17:29:40 -04:00
Alex Corey
33f7bf67e1 fix merge conflicts 2019-04-29 17:00:04 -04:00
Jake McDermott
6fe93f474f Merge pull request #181 from jakemcdermott/page-header-method-names
use 'handle' notation for header toolbar methods
2019-04-29 14:39:43 -04:00
Jake McDermott
bdad9ac8f9 use 'handle' notation for header toolbar methods
- 'handleFoo' is for methods defined on the component
- 'onFoo' is for naming function props that can be passed to the component from its parents
2019-04-29 14:32:56 -04:00
Jake McDermott
d74c3a09e5 Merge pull request #183 from jakemcdermott/test-fixup
fix unit and functional tests
2019-04-29 14:32:12 -04:00
Jake McDermott
ee5b4b072b fix unit and functional tests 2019-04-29 11:35:06 -04:00
Keith Grant
9d66b583b7 158 paginated data list (#180)
* working: rename OrganizationTeamsList to PaginatedDataList

* convert org notifications list fully to PaginatedDataList

* update NotificationList tests

* refactor org access to use PaginatedDataList

* update tests for org access refactor; fix pagination & sorting

* restore Add Role functionality to Org roles

* fix displayed text when list of items is empty

* preserve query params when navigating through pagination

* fix bugs after RBAC rebase

* fix lint errors, fix add org access button
2019-04-29 10:08:50 -04:00
Michael Abashian
3c06c97c32 Merge pull request #173 from mabashian/151-org-rbac
Add RBAC to org views (now with tests!)
2019-04-26 12:01:33 -04:00
mabashian
8cfe74a854 Code cleanup, renaming functions, use .all() on config promises 2019-04-26 11:02:16 -04:00
mabashian
e5dda696d7 Add new tests for rbac on some of the org pages 2019-04-24 10:10:14 -04:00
mabashian
82db7df6b3 Remove errant comment 2019-04-23 15:19:46 -04:00
mabashian
f57876b6d9 Fix existing test failures 2019-04-23 14:55:06 -04:00
mabashian
38bb4f3f3c Fix merge conflicts 2019-04-23 13:27:00 -04:00
mabashian
5ae7cbb43a Add RBAC to org views 2019-04-23 13:19:34 -04:00
Michael Abashian
1509ef3e80 Merge pull request #143 from mabashian/wizard-access-list
Add roles modal to org access list
2019-04-23 13:12:31 -04:00
mabashian
df87681e6d Fix linting errors 2019-04-23 12:20:08 -04:00
mabashian
621cc3f839 Fix rebase errors 2019-04-23 11:52:49 -04:00
mabashian
e8d73babaf Rebase and incorporates feedback 2019-04-23 10:01:03 -04:00
mabashian
9880f1e124 Removes the need to pass default search params to the select resource step 2019-04-23 10:01:03 -04:00
mabashian
a1002b03fa Add roles modal to org access list 2019-04-23 10:01:03 -04:00
Michael Abashian
47bdbddbeb Merge pull request #172 from jlmitch5/moveTestContext
PR for moving tests to using new mountWithContext helper
2019-04-23 09:58:15 -04:00
Michael Abashian
f7bd9af7a1 Merge branch 'master' into moveTestContext 2019-04-23 09:57:35 -04:00
John Mitchell
261980f18e update components tests to use mountWithContexts when relevant 2019-04-22 16:34:33 -04:00
John Mitchell
986641de9f Fix ORganizationTeams test 2019-04-22 16:33:12 -04:00
John Mitchell
6f789b661f Fix NotificationList tests 2019-04-22 15:43:47 -04:00
John Mitchell
667cbb0c20 update the rest of the organizations tests 2019-04-22 15:11:28 -04:00
Alex Corey
ec3be57539 Merge pull request #162 from AlexSCorey/128-UsePFTabs
Add PF's Tabs to Orgs Details page
2019-04-22 09:26:12 -04:00
John Mitchell
54499dbf69 update OrganizsationAccess and OrganizationAccessList w mountWithContexts 2019-04-18 17:18:19 -04:00
John Mitchell
a6f79c646d update organization add test to use mountWithContexts 2019-04-18 13:54:41 -04:00
John Mitchell
ce49cb9ba4 fix config context if value passed by props not getting overwritten 2019-04-18 13:53:05 -04:00
John Mitchell
5030eb35b6 migrate App.jsx to mountwithContext 2019-04-18 13:10:17 -04:00
Alex Corey
8fa9535b98 styling changes 2019-04-18 13:07:10 -04:00
Jake McDermott
db4734be85 Merge pull request #169 from ansible/jakemcdermott-only-coverage
don't use --watch by default when running tests
2019-04-18 11:29:54 -04:00
John Mitchell
e1333f5e00 move value by prop in providers to consistent interface 2019-04-18 10:52:35 -04:00
Keith Grant
ae72d8dce5 Context test tools (#168)
* add enzyme test helper with lingui provider

* add router context to enzyme test helper

* get 18n, router, & config contexts rendering together in enzyme helper

* add config context to enzyme helpers

* add network and dialog contexts to enzymeHelpers

* convert OrganizationForm tests to use new mountWithContexts helper

* default all context value keys to default unless provided

* document use of mountWithContexts()

* fix typo in CONTRIBUTING.md

* update Organizations to use mountWithContext
2019-04-18 10:03:06 -04:00
Alex Corey
2067718c0e fixed tests 2019-04-17 16:42:39 -04:00
Keith Grant
25db22e072 fix RoutedTabs tests
Signed-off-by: Alex Corey <alex.swansboro@gmail.com>
2019-04-17 16:20:24 -04:00
Alex Corey
ca6153c955 RoutedTabs is now a functional component 2019-04-17 13:51:09 -04:00
Alex Corey
76a7a76e81 refactoring and updating tests 2019-04-17 13:50:38 -04:00
Alex Corey
2daf202e52 addresses PR issues 2019-04-17 13:50:38 -04:00
Alex Corey
178d519f6e Remove unwanted committed file 2019-04-17 13:50:38 -04:00
Jake McDermott
a414c4e60e don't use --watch by default when running tests 2019-04-17 11:54:22 -04:00
Jake McDermott
7c2554be8c Merge pull request #165 from jakemcdermott/dependency-updates
update vulnerable dependencies
2019-04-16 09:40:28 -04:00
Jake McDermott
468a290ba6 update vulnerable dependencies 2019-04-16 09:14:14 -04:00
Michael Abashian
d6f91f8b2d Merge pull request #163 from mabashian/146-access-expand-collapse
Remove expand/collapse from org access list
2019-04-15 10:48:47 -04:00
mabashian
53f564068f Remove leftover isCompact references 2019-04-12 16:10:30 -04:00
mabashian
e11c2df6b6 Remove expand/collapse from org access list 2019-04-12 16:10:30 -04:00
John Mitchell
14c1b85127 Merge pull request #156 from jlmitch5/handleNetworkErrors
Handle network errors
2019-04-12 16:00:54 -04:00
John Mitchell
526b640329 fix translation marked org and org access list strings 2019-04-12 15:23:45 -04:00
John Mitchell
63894bf822 update Promise.all map functions to not be async 2019-04-12 14:35:35 -04:00
John Mitchell
b9e0b2e0ad update to correct grab handleHttpError from props instead of state 2019-04-12 14:35:18 -04:00
John Mitchell
83e6255ba4 update NotifyAndRedirect to function component 2019-04-11 17:16:42 -04:00
John Mitchell
09a950570e Update provider export syntax 2019-04-11 17:10:32 -04:00
John Mitchell
64aecb85fa move router setup to RootProvider 2019-04-11 17:07:46 -04:00
John Mitchell
85b9b4f896 add missing link to react docs about context 2019-04-11 16:18:08 -04:00
John Mitchell
a808462a3d remove test.only causing org access tests to skip 2019-04-11 12:40:27 -04:00
John Mitchell
b17fb8a596 Add handleHttpError prop to stop error from org detail test 2019-04-11 12:36:19 -04:00
John Mitchell
bab7095d67 Update qs path imports to include util 2019-04-11 12:00:39 -04:00
John Mitchell
e36320174c Add contrib docs based on context changes and move qs to util dir 2019-04-11 11:58:15 -04:00
John Mitchell
abc3733449 fix test after rebase of org teams update 2019-04-11 11:06:39 -04:00
John Mitchell
344713f938 fix unit tests for network handling 2019-04-11 10:42:33 -04:00
John Mitchell
ad0e409448 do 404 modal redirect on unknown routes 2019-04-11 10:42:00 -04:00
John Mitchell
81267c7212 update language and stylign for all warning/danger modals 2019-04-11 10:42:00 -04:00
John Mitchell
fa232a94bd update api calls to utilized network context 2019-04-11 10:41:59 -04:00
John Mitchell
722ae932ab update login modal to grab error from RootDialog 2019-04-11 10:38:54 -04:00
John Mitchell
aea4a04c66 add RootDialog and Network contexts, update app bootstrapping 2019-04-11 10:34:48 -04:00
John Mitchell
e20cf72dd6 add AlertModal component and update styling of delete confirmations 2019-04-11 10:34:48 -04:00
John Mitchell
af3419c2dd update eslint to allow short circuit ternary chains 2019-04-11 10:29:45 -04:00
Alex Corey
84f45d122d Merge pull request #160 from AlexSCorey/114-HeaderIcons
Adds tooltip to username and help icon
2019-04-10 16:39:20 -04:00
Alex Corey
c4ffc58228 addresses PR issues 2019-04-10 14:16:22 -04:00
Keith Grant
96906c2ece Merge pull request #157 from keithjgrant/145-org-teams-empty-state
Org teams empty state
2019-04-10 14:01:55 -04:00
Marliana Lara
0f2355f416 Merge pull request #159 from marshmalien/ux-org-list-links
Remove org list links and update label
2019-04-10 13:19:44 -04:00
Alex Corey
731da8049b Adds tooltip to username and help icon. 2019-04-10 10:48:56 -04:00
Keith Grant
909c5e77c4 rename all test files to *.test.js 2019-04-10 09:55:57 -04:00
Marliana Lara
2ab688932d Remove org list links 2019-04-09 11:37:43 -04:00
Keith Grant
70137dea5a fix tests for OrganizationTeams, OrganizationTeamsList 2019-04-08 10:59:26 -04:00
Marliana Lara
3d6790a419 Merge pull request #155 from marshmalien/ux-instance-groups-lookup-height
UX - Lookup static height
2019-04-08 10:40:20 -04:00
Marliana Lara
212d3d517d Replace lookup with patternfly's input group component and 'fix' the height 2019-04-05 15:39:14 -04:00
Alex Corey
09fd8e8106 Merge pull request #141 from AlexSCorey/48-deleteOrgs
Add alert for org. delete.
2019-04-05 12:39:38 -04:00
Alex Corey
c0b882d6fb fixes progress bar 2019-04-05 12:01:04 -04:00
Alex Corey
a42a1bfa17 Addresses PR feedback 2019-04-05 11:29:48 -04:00
Keith Grant
89ecddf662 refactor OrganizationTeams/OrganizationTeamsList 2019-04-05 10:52:52 -04:00
Alex Corey
de55ec1688 Add alert for org. delete. 2019-04-05 10:48:51 -04:00
Marliana Lara
2062124a92 Merge pull request #149 from marshmalien/org-details-ig-show-more-less
Update Org Details UX layout
2019-04-05 10:04:20 -04:00
Marliana Lara
868ad51158 Set static value to const variable 2019-04-05 09:58:19 -04:00
Keith Grant
c2a223bbb4 delete unused method 2019-04-04 09:17:33 -04:00
Marliana Lara
268d50a339 Update Org Details UX layout and add show more/less to instance groups field 2019-04-03 13:40:08 -04:00
Keith Grant
04bd4d973a Merge pull request #150 from keithjgrant/test-fix
update tests to match new ids
2019-04-03 13:38:01 -04:00
Keith Grant
8700f32ffc fix tests eslintrc 2019-04-03 13:29:25 -04:00
Keith Grant
9781c22c3f update tests to match new ids 2019-04-03 13:16:29 -04:00
Keith Grant
99b2350778 Merge pull request #144 from keithjgrant/120-add-org-form-cleanup
Refactor org add/edit forms with Formik
2019-04-03 09:15:03 -04:00
Keith Grant
0c63a57418 improve org form input ids 2019-04-03 09:13:26 -04:00
Keith Grant
3f2cc53992 fix tests eslintrc 2019-03-29 14:28:41 -04:00
Keith Grant
20f27f4062 make InstanceGroupsLookup tooltip customizable via prop 2019-03-29 14:22:09 -04:00
Keith Grant
40b88da9dd add FormRow component; rename unwrapped components with underscore 2019-03-29 13:50:17 -04:00
Keith Grant
2002d48bcc minor tweaks 2019-03-28 16:44:44 -04:00
Keith Grant
6353d5e410 update tests for org add/edit refactor 2019-03-28 13:02:04 -04:00
John Mitchell
cc0fd6beb6 fix openDeleteModal with button test 2019-03-28 10:42:17 -04:00
Alex Corey
f3a07753e6 Add alert for org. delete. 2019-03-28 10:29:55 -04:00
Keith Grant
64e933acb4 refactor out OrganizationForm; share between add & edit 2019-03-27 15:29:46 -04:00
Michael Abashian
77ab6ec044 Merge pull request #142 from mabashian/upgrade-pf-2.9.2
Upgrade pf react-core to 2.9.2
2019-03-27 13:49:39 -04:00
John Mitchell
4e80f05cdf Merge pull request #136 from jlmitch5/addOrgTeamsList
add org teams list
2019-03-27 11:30:59 -04:00
Alex Corey
ae622c4875 Merge pull request #139 from AlexSCorey/138-updateFunctionName
Fixes function naming
2019-03-27 11:05:18 -04:00
Keith Grant
40b2539626 rework org edit form to use Formik 2019-03-27 10:49:10 -04:00
Alex Corey
a430b5bf9a fixes function naming to match our naming convention in the org. notifications. 2019-03-26 18:08:09 -04:00
John Mitchell
aeed1d8ee9 one org teams rename spelling issue 2019-03-26 17:06:43 -04:00
John Mitchell
5419434daa rename org teams functions based on guide 2019-03-26 17:04:34 -04:00
mabashian
9b314a6f2f Upgrade pf react-core to 2.9.2 2019-03-26 11:49:41 -04:00
Keith Grant
02cd188c2f rename onX methods to handleX 2019-03-25 15:40:20 -04:00
Keith Grant
f3a6da20f6 create InstanceGroupsLookup for org add/edit forms 2019-03-25 11:59:14 -04:00
Keith Grant
f0c94c7e9c stub api in org add/edit tests 2019-03-25 11:56:29 -04:00
kialam
1cb2a95a47 Merge pull request #137 from ansible/document-naming-functions
Update contributing doc
2019-03-21 14:26:12 -04:00
John Mitchell
7e414ace5a add org teams list 2019-03-21 13:12:12 -04:00
Kia Lam
e3a6a20049 Update contributing doc to include:
- Method naming convention
- Initial Empty State convention
2019-03-21 12:51:23 -04:00
Michael Abashian
7bd8234edf Merge pull request #135 from mabashian/upgrade-pf
Upgrades pf deps to latest
2019-03-20 10:53:10 -04:00
mabashian
d30aed9231 Upgrades pf deps to latest 2019-03-19 16:41:26 -04:00
Michael Abashian
c288c5fcbe Merge pull request #134 from mabashian/toolbar-refactor-v2
Refactor of DataListToolbar v2
2019-03-19 14:16:04 -04:00
mabashian
fc80470e5d Normalize event callback function names in search and sort components 2019-03-19 14:01:39 -04:00
mabashian
3596d776fc Refactor of DataListToolbar. Creates a number of smaller components used by the toolbar. Adds support for passing in an add button node to the toolbar. 2019-03-19 14:01:39 -04:00
kialam
dbeef0a823 Merge pull request #123 from ansible/access-list-remove-role-functionality
Org Access List: add remove role functionality
2019-03-18 10:25:56 -04:00
Kia Lam
a4493cd02b Add empty initial states and adjust rendering logic. 2019-03-18 09:32:11 -04:00
Kia Lam
a5683fb354 Clear mocked methods after each test to prevent overlaps with other tests. 2019-03-14 10:41:28 -04:00
Kia Lam
518ecee53e Apply padding to Alert component. 2019-03-14 10:35:54 -04:00
Kia Lam
6bd5ee4201 Move test for AccessList. 2019-03-13 17:12:16 -04:00
Kia Lam
390832cc1a Rename AccessList to OrganizationAccessList and fix paths. 2019-03-13 16:46:50 -04:00
Kia Lam
c6d810621f Move AccessList out of components directory.
- The AccessList component is pretty specific to the Organization component, and given the structure and methods within it, is pretty context-specific and not a good candidate to be a re-useable component.
2019-03-13 16:37:03 -04:00
Alex Corey
0f6a40014e Merge pull request #129 from AlexSCorey/paginationTest
add pagination test
2019-03-13 16:21:01 -04:00
Alex Corey
91e4679311 adds test to ensure page size option dropdown is removed is no page size option is passed in. 2019-03-13 16:19:59 -04:00
Kia Lam
0495214f47 Address PR feedback. 2019-03-13 15:59:42 -04:00
Kia Lam
21156d1409 Merge remote-tracking branch 'origin' into access-list-remove-role-functionality 2019-03-13 15:43:30 -04:00
Kia Lam
198dfe7f2e Add unit test to check state when user tries to delete a role. 2019-03-13 14:44:12 -04:00
Keith Grant
e1ebcd51b0 Merge pull request #131 from keithjgrant/add-org-ux-improvements
UX improvements for Add Organization screen
2019-03-13 13:36:46 -04:00
Keith Grant
fe5821eb15 Merge pull request #132 from keithjgrant/org-notification-spacing
increase space next to organization notifications
2019-03-13 08:37:03 -04:00
Keith Grant
24f0fe2980 increase space next to organization notifications 2019-03-12 16:04:22 -04:00
Keith Grant
188eaede43 switch to PatternFly Tooltip everywhere 2019-03-12 15:24:36 -04:00
John Mitchell
bbb31eb478 fix pagination page input and componentDidUpdate tests 2019-03-12 15:03:21 -04:00
Alex Corey
d96b88e495 add pagination test 2019-03-12 12:28:42 -04:00
Keith Grant
601214f6d4 add close (x) button to Add Org screen 2019-03-12 11:48:29 -04:00
Keith Grant
5b3f5206c4 add tooltips to add organization form 2019-03-12 08:58:12 -04:00
Keith Grant
ecb7306c46 Adding organization: add inputs helper text 2019-03-11 14:41:46 -04:00
Kia Lam
3b65068258 Add remove role functionality. 2019-03-08 13:56:27 -05:00
Keith Grant
a3bea6d4a8 Merge pull request #122 from keithjgrant/fix-pagination-text
fix pagination text
2019-03-06 14:42:52 -05:00
Keith Grant
4d15df2b48 fix pagination text when items displayed matches number of items per page 2019-03-06 14:30:21 -05:00
kialam
e935776067 Merge pull request #121 from ansible/org-access-list
Organization Access List
2019-03-05 18:56:29 -05:00
Kia Lam
9f86fc2def Respond to PR feedback. 2019-03-05 12:01:06 -05:00
Kia Lam
35ecd83214 Some cosmetic changes.
- Reverse order of Expand/Compact icons in DataListToolbar to Compact/Expand.
- Make Expanded the default view for Access Lists.
- Make role badge styling closer to Chip component styling.
2019-03-04 14:38:58 -05:00
Kia Lam
86a92fefe7 Merge remote-tracking branch 'origin' into org-access-list 2019-03-01 10:37:44 -05:00
Kia Lam
bf7e6201a2 Refactor Access List.
- Derive Team Roles without making extra API call.
- Consistent variable naming convention use camelCase.
- More informative error display.
2019-03-01 10:12:36 -05:00
Kia Lam
a3a80bc23e Fix prop errors in unit tests. 2019-02-27 18:03:15 -05:00
Kia Lam
5659270d3e Add unit test for Access List component. 2019-02-27 17:30:02 -05:00
Marliana Lara
6f26383e06 Merge pull request #119 from marshmalien/org-edit
Add Org Edit View
2019-02-26 15:04:08 -05:00
Marliana Lara
053b21e832 Use ternary operator in Org Edit form 2019-02-26 14:21:27 -05:00
Kia Lam
1443625d89 Abstract out Access List as shared component. 2019-02-26 13:23:34 -05:00
Kia Lam
3cd54c45eb Add Access List to Orgs. 2019-02-26 08:39:13 -05:00
Marliana Lara
a7b51c526a Update Lookup chip test 2019-02-25 11:42:18 -05:00
Marliana Lara
ffefba9bf9 Fix bug where lookup parent state is not updated on toggleSelected 2019-02-25 11:05:42 -05:00
Marliana Lara
ff339e0eba Update org edit form layout and remove chip group component from lookup; 2019-02-25 09:15:21 -05:00
Marliana Lara
c3fc00c45a Add Organization Edit tests and fix Lookup unit tests 2019-02-22 14:53:47 -05:00
Marliana Lara
d2cf2c275b Add Organization Edit view 2019-02-22 14:53:17 -05:00
Marliana Lara
f1fefbf5f0 Add organization details patch and instance groups disassociate methods to api 2019-02-22 14:51:38 -05:00
Marliana Lara
b6eacbab86 Rename createInstanceGroups api method to associateInstanceGroup 2019-02-22 14:47:25 -05:00
Marliana Lara
92d3cb6dc4 Replace Lookup tags with pf-react Chip component 2019-02-22 14:35:58 -05:00
Michael Abashian
de3cc4637e Merge pull request #112 from mabashian/88-sort-filter-ig-modal
Adds sorting to IG lookup on org form
2019-02-20 15:53:47 -05:00
mabashian
e28776962d Fixes left margin on notifications tab 2019-02-20 14:52:11 -05:00
mabashian
87d9df5876 Fixes modal button margin and focus border on toolbar buttons 2019-02-20 13:28:06 -05:00
mabashian
56bd145f21 Adds sort to IG modal 2019-02-20 11:30:58 -05:00
mabashian
581ec8860b recompile strings to fix Foo being displayed instead of My View 2019-02-20 09:41:38 -05:00
Marliana Lara
1599d2c62c Merge pull request #110 from marshmalien/upgrade-patternfly
Upgrade @patternfly-next to @patternfly/patternfly
2019-02-20 09:29:07 -05:00
Marliana Lara
83982d5e2e Fix Modal footer button styles 2019-02-19 16:34:27 -05:00
Marliana Lara
8be8663665 Fix AnsibleSelect tests 2019-02-19 16:14:28 -05:00
Marliana Lara
740a9c1e61 Remove pf base css import and tweak styles 2019-02-19 16:10:50 -05:00
Marliana Lara
9229c8e724 Add translations to AnsibleSelect 2019-02-19 16:10:47 -05:00
Marliana Lara
7567a6b36a Fix Org Detail Action button margin 2019-02-19 16:05:47 -05:00
Marliana Lara
240d07b6d4 Refactor styles and remove patternfly utility classes 2019-02-19 16:05:45 -05:00
Marliana Lara
09107aef1f Amend LoginForm component to use updated helperText props for @patternfly/react-core 2.1.8 2019-02-19 16:04:48 -05:00
Marliana Lara
68225d191a Remove old BackgroundImageSrc tokens for @patternfly/react-core 2.1.8 2019-02-19 16:04:47 -05:00
Marliana Lara
58f273347c Remove heroImgSrc props for @patternfly/react-core 2.1.8 2019-02-19 16:04:47 -05:00
Marliana Lara
c4065a54bd Rename Select components to FormSelect for @patternfly/react-core 2.1.8 2019-02-19 16:04:45 -05:00
Marliana Lara
50ebf65178 Update @patternfly/patternfly-next references to @patternfly/patternfly 2019-02-19 16:00:11 -05:00
Marliana Lara
f5f67627db Update @patternfly/* dependencies
* Remove @patternfly/react-styles dependency
2019-02-19 16:00:11 -05:00
kialam
e0df011804 Merge pull request #109 from ansible/add-prop-checking
Add proptypes to shared components
2019-02-19 11:37:03 -05:00
kialam
f9d615fdee Fix unit tests. 2019-02-19 11:28:17 -05:00
kialam
da8c3f6c43 Enable submit button by default. 2019-02-19 10:24:26 -05:00
kialam
c3493b0539 Remove unused method. 2019-02-19 10:19:47 -05:00
kialam
bba1c4f5b6 Restore FormGroup to parent Add Org component for AnsibleSelect. 2019-02-19 10:18:03 -05:00
kialam
2a254ea538 Add typechecking to contributing guide. 2019-02-15 15:20:02 -05:00
kialam
b340d49cb7 Integrate proptypes for our shared components.
- Fix unit tests.
- Fix linter errors.
2019-02-15 15:08:52 -05:00
kialam
91f87b6d81 Merge pull request #106 from ansible/add-select-default-option
Add default option for AnsibleSelect dropdown.
2019-02-14 11:00:04 -05:00
kialam
7c009fc315 Update unit tests to use new props. 2019-02-14 10:53:53 -05:00
kialam
f09eb182c2 Merge remote-tracking branch 'origin/master' into add-select-default-option 2019-02-14 10:38:28 -05:00
John Mitchell
614116c90e Merge pull request #104 from jlmitch5/instanceGroupsPagination
add pagination to instance groups
2019-02-13 15:42:36 -05:00
John Mitchell
b4007c7e04 put FormGroup component in form instead of in AnsibleSelect component 2019-02-13 15:40:46 -05:00
kialam
1f07fc8494 Make default option selectable but return null value. 2019-02-13 15:39:29 -05:00
kialam
2b18cee9c0 Fix linter errors and add test to AnsibleSelect component. 2019-02-13 15:39:29 -05:00
kialam
97477b789a Add default option for AnsibleSelect dropdown. 2019-02-13 15:39:26 -05:00
John Mitchell
f2ab7f62b9 fix disabled of submit button 2019-02-13 15:09:14 -05:00
John Mitchell
35c94e9cd8 update selected to value in AnsibleSelect 2019-02-13 14:52:11 -05:00
John Mitchell
de658939c5 add default value to props destructure statement 2019-02-13 10:50:04 -05:00
John Mitchell
cbc1ae8875 fix tests based on AnsibleSelect fn name change 2019-02-13 10:34:32 -05:00
John Mitchell
c1381f7b98 incorporate feedback on instance groups pagination 2019-02-12 11:59:49 -05:00
John Mitchell
6431ec603f fix AnsibleSelect passing onChange callback 2019-02-12 11:53:22 -05:00
Marliana Lara
fb7ccdb726 Merge pull request #108 from marshmalien/remove-breadcrumb-text-style
Remove breadcrumb item capitalize text style
2019-02-12 11:32:14 -05:00
Marliana Lara
9619513017 Remove breadcrumb item capitalize text style 2019-02-12 11:18:28 -05:00
John Mitchell
c67088628f fix border color 2019-02-12 09:05:22 -05:00
John Mitchell
680d153a14 add pagination to instance groups lookup modal 2019-02-11 18:10:27 -05:00
Marliana Lara
cdc8b372f9 Merge pull request #105 from marshmalien/wrap-long-detail-descriptions
Wrap Org Details description field
2019-02-11 12:58:28 -05:00
Marliana Lara
0b7c643e75 Wrap Org Details description field 2019-02-11 12:21:34 -05:00
Marliana Lara
8e194baa66 Merge pull request #102 from marshmalien/style-tab-text
Update organization tab styles
2019-02-06 14:37:41 -05:00
Marliana Lara
df30a2e8d1 Update organization tab styles 2019-02-06 14:00:26 -05:00
Marliana Lara
241f8a8ac8 Merge pull request #100 from marshmalien/org-details
Add Organization Details view and tests
2019-02-06 12:04:46 -05:00
Marliana Lara
9d9b94c8c3 Increase label font-weight and vertically align labels and chips 2019-02-06 11:42:53 -05:00
John Mitchell
56c0ab97ed Merge pull request #99 from jlmitch5/addOrgEmptyListAndUpdateCSS
Add org empty list and update css
2019-02-05 11:52:36 -05:00
Marliana Lara
8846e1427e Add Organization Details view and test 2019-02-05 10:52:33 -05:00
John Mitchell
736f1e1775 update conditional showing of empty list component 2019-02-04 15:39:44 -05:00
John Mitchell
21bdd487e6 fix to tabs -- padding around and left most border 2019-01-30 16:32:42 -05:00
John Mitchell
4ce19a4b42 add empty list functionality to org list 2019-01-30 16:20:04 -05:00
John Mitchell
98cb8c6f6e update scss patternfly override file and add center empty list tweak 2019-01-30 16:20:04 -05:00
Michael Abashian
a2007b8e0c Merge pull request #98 from mabashian/selected-list
Adds selected list to lookup component
2019-01-30 15:58:14 -05:00
mabashian
0e9e17f957 Only update selected instance groups if the select button is clicked in the modal 2019-01-30 15:27:12 -05:00
mabashian
6ed36daef7 Fixes close button on tags in instance group form field 2019-01-30 12:59:22 -05:00
mabashian
5778c9cf05 Removes commented styles, use defined color variable in lockup 2019-01-30 12:46:00 -05:00
mabashian
2579e30ca1 Pulls in latest pf-react. Adds selected list component to org instance groups lookup 2019-01-30 12:46:00 -05:00
John Mitchell
701eb6afa5 Merge pull request #97 from jlmitch5/newPagination
New pagination
2019-01-30 12:16:21 -05:00
John Mitchell
e4d44efea2 reduce disabled background color to increase contrast w border 2019-01-30 12:14:48 -05:00
John Mitchell
3c0744629b update pagination component based on ux feedback 2019-01-29 12:50:29 -05:00
John Mitchell
990851aa3b wrap org list in Card for consistency between detail 2019-01-29 12:50:15 -05:00
Marliana Lara
65e369c0f3 Merge pull request #96 from marshmalien/refactor-url
Refactor Breadcrumbs, Tabs, routing
2019-01-28 12:02:23 -05:00
Marliana Lara
9048c34a7d Fix merge conflicts and linting errors 2019-01-25 16:49:46 -05:00
Marliana Lara
21298c8872 Add Breadcrumbs test 2019-01-25 16:42:09 -05:00
Marliana Lara
b820e411d3 Refactor breadcrumbs, tabs, routing.
* Cleanup previous params logic from Notificaitons list
* Add shared breadcrumbs and tabs components
* Structure Organization screens to render only cardBody content
* Add styles
* Fetch organization when location changes
2019-01-25 16:42:04 -05:00
John Mitchell
dd522c240e remove test debuggers 2019-01-25 16:17:58 -05:00
John Mitchell
54e79a93d9 Merge pull request #95 from jlmitch5/fixLinting
Fix linting
2019-01-25 16:16:55 -05:00
John Mitchell
02d7006ea4 fix tests 2019-01-25 15:22:32 -05:00
John Mitchell
7de89f6486 fix linting issues 2019-01-24 13:05:36 -05:00
John Mitchell
2588832629 remove debug flag from eslint 2019-01-24 12:08:39 -05:00
John Mitchell
f37bdba645 update eslint config and add eslint ignore 2019-01-24 11:36:18 -05:00
Michael Abashian
28b5d43e1f Merge pull request #93 from mabashian/63-org-notifications
Add notification list to org
2019-01-24 09:21:13 -05:00
mabashian
47719776f2 More cleanup based on pr feedback. Adds org notif list page and tests 2019-01-23 16:53:02 -05:00
mabashian
6c19d6ae4e Removes unnecessary fragment elements. Fixes vertical alignment on notif row item. Bind notification list functions to constructor 2019-01-23 14:13:51 -05:00
mabashian
c97dfeb725 Cleanup after change post... to create... 2019-01-21 15:46:11 -05:00
mabashian
2c19a5a1d7 Changed post to create in api.js. Removed capitalize text component in favor of css solution. Updates to empty list contents. Fixes padding on notifications list 2019-01-21 15:44:34 -05:00
mabashian
4f929c7052 Fix inadvertent merge conflict change 2019-01-21 13:30:15 -05:00
mabashian
58f99c8918 Adds notification list to orgs 2019-01-21 13:18:37 -05:00
kialam
3060abab1d Merge pull request #87 from ansible/lookup-form-component
Lookup form component
2019-01-16 13:32:28 -05:00
kialam
a70a0fa622 Bump Lookup component test coverage up. 2019-01-16 13:15:51 -05:00
kialam
7230b4bf8d Bump up unit test coverage for OrganizationAdd component. 2019-01-15 15:51:37 -05:00
kialam
fc32cf026f Address review feedback. 2019-01-15 15:15:17 -05:00
kialam
e8fe6fe33c Fix & Add unit tests. 2019-01-15 14:58:23 -05:00
kialam
215c23609c Hook up 'x' remove button; rename ListItem component. 2019-01-14 09:45:49 -05:00
kialam
c5cd659c83 Redirect user to org detail page after successful POST. 2019-01-08 16:09:30 -05:00
kialam
a1d1dc7a24 Style pop up modal 2019-01-08 15:56:37 -05:00
John Mitchell
a1419f0f20 Merge pull request #85 from jlmitch5/portalModeToMyView
update portal mode to my view and update translations
2019-01-08 14:00:54 -05:00
kialam
c085fc6751 Merge remote-tracking branch 'origin/master' into lookup-form-component 2019-01-08 13:47:06 -05:00
Marliana Lara
57b1c2c42c Merge pull request #86 from marshmalien/directory-structure
Move Organization screens and tests into new folder structure
2019-01-08 13:06:55 -05:00
kialam
395e30509b Fix linter and existing unit tests. 2019-01-07 17:17:22 -05:00
kialam
517ef8a2c9 Hook up add instance group functionality. 2019-01-07 16:56:39 -05:00
Marliana Lara
d040f063e9 Move Organization screens and tests into new folder structure 2019-01-07 15:33:27 -05:00
John Mitchell
e77efbfec2 update portal mode to my view and update translations 2019-01-07 15:23:31 -05:00
kialam
f34ec4be10 Merge remote-tracking branch 'origin/master' into lookup-form-component 2019-01-07 14:40:35 -05:00
Marliana Lara
f521fe5cbc Merge pull request #79 from marshmalien/org-breadcrumb-tabs
Org Breadcrumb and Tabs
2019-01-07 11:23:51 -05:00
Marliana Lara
2d3152ef41 Add translation and small css tweaks 2019-01-07 11:15:11 -05:00
kialam
c63896fbb6 Implement basic lookup modal component. 2019-01-07 10:09:35 -06:00
Marliana Lara
f76e9bddf9 Update org utils test 2019-01-07 10:52:50 -05:00
Marliana Lara
83e300636d Move Tab components out into component directory 2019-01-07 10:52:50 -05:00
Marliana Lara
913077c489 Update tab content and related badge links 2019-01-07 10:52:50 -05:00
Marliana Lara
e782be10b6 Add Tab styles 2019-01-07 10:52:50 -05:00
Marliana Lara
7406421d1b Add PF Breadcrumb components 2019-01-07 10:52:47 -05:00
Jake McDermott
976c490dc3 Merge pull request #84 from jakemcdermott/tests-fixup
add more unit and functional test coverage
2019-01-07 07:50:11 -05:00
Jake McDermott
a83e5e5675 add unit test coverage for DataListToolbar.jsx 2019-01-07 07:40:31 -05:00
Jake McDermott
8756da59fa add unit test coverage for TowerLogo.jsx 2019-01-07 07:40:25 -05:00
Jake McDermott
4936238344 add more unit test coverage for index.jsx 2019-01-07 07:40:19 -05:00
Jake McDermott
cb0367ac28 handle null error response 2019-01-07 07:40:12 -05:00
Jake McDermott
48e1fbfb38 add unit test coverage for AnsibleSelect.jsx 2019-01-07 07:40:06 -05:00
Jake McDermott
bbd94fa4f7 add functional test coverage for App.jsx 2019-01-07 07:39:59 -05:00
Jake McDermott
164464c595 add more test coverage for api client 2019-01-07 07:39:51 -05:00
Jake McDermott
5bff942110 pagination test fixup 2019-01-07 07:39:42 -05:00
Jake McDermott
6a7ba87a02 org-add fixup
re-adding a changeset I missed when resolving a merge conflict earlier
2019-01-07 07:39:31 -05:00
Jake McDermott
3f2e47b1b1 Merge pull request #82 from jakemcdermott/page-toolbar-tests
add some tests for page toolbar and background wrapper
2019-01-04 15:28:06 -05:00
Jake McDermott
df6877bb99 Merge pull request #83 from jakemcdermott/update-webpack-dev-server
update webpack-dev-server
2019-01-04 15:20:54 -05:00
Jake McDermott
b69522b5aa add basic test for background wrapper component 2019-01-04 15:20:32 -05:00
Jake McDermott
95861491cb add more tests for header toolbar 2019-01-04 15:20:22 -05:00
Jake McDermott
e07db0c05e update webpack-dev-server 2019-01-04 15:12:57 -05:00
Jake McDermott
8d62b7a2e3 Merge pull request #75 from ansible/contributing-guide
Add a contributing doc to our repo.
2019-01-03 22:24:31 -05:00
Jake McDermott
f6f6643622 Merge pull request #81 from jakemcdermott/update-and-refactor
wip - update to pf-react 1.43 and refactor some things
2019-01-03 19:37:16 -05:00
Jake McDermott
0d565eb3e3 add header toolbar test 2019-01-03 18:11:26 -05:00
Jake McDermott
23e34bcbbe remove config pass-through
removing this for the time being to giving the config Context a try
2019-01-03 18:00:20 -05:00
Jake McDermott
87101a487d use constructor bound methods for pagination 2019-01-03 17:54:07 -05:00
Jake McDermott
6446e45165 use constructor bound methods for org view 2019-01-03 17:54:04 -05:00
Jake McDermott
afcfd1640e use constructor bound methods for org list 2019-01-03 17:54:01 -05:00
Jake McDermott
e015558190 use constructor bound methods for data toolbar 2019-01-03 17:53:58 -05:00
Jake McDermott
e5cdea8daf use constructor bound methods for logo 2019-01-03 17:53:55 -05:00
Jake McDermott
5948ecce16 use constructor bound methods for nav group 2019-01-03 17:53:52 -05:00
Jake McDermott
24208197e8 use constructor bound methods for Login 2019-01-03 17:53:49 -05:00
Jake McDermott
dce50fe18b update route group params 2019-01-03 17:53:46 -05:00
Jake McDermott
3e201d3ca0 add config pass-through to inline render 2019-01-03 17:53:43 -05:00
Jake McDermott
4ccce4cc9e add header toolbar component and move About modal control to App 2019-01-03 17:53:40 -05:00
Jake McDermott
31d0347553 test fixup 2019-01-03 17:53:37 -05:00
Jake McDermott
8f4437e17e initialize and pass api client to subviews 2019-01-03 17:53:34 -05:00
Jake McDermott
a023df2c17 add inline rendering prop to app component 2019-01-03 17:53:31 -05:00
Jake McDermott
f2760ed91c use default patternfly breakpoint token name 2019-01-03 17:53:28 -05:00
Jake McDermott
9c6df68557 decouple App and Login components 2019-01-03 17:53:25 -05:00
Jake McDermott
6efd523db2 move wrapper / shared components out of App component 2019-01-03 17:53:21 -05:00
Jake McDermott
f975f9fa75 add background component 2019-01-03 17:53:18 -05:00
Jake McDermott
a2601d5f67 remove conditional redirect component 2019-01-03 17:53:08 -05:00
Jake McDermott
18505b35b8 add params for component routing 2019-01-03 17:53:05 -05:00
Jake McDermott
8bd85193ab fix login page test for @patternfly/react-core 1.43.5 2019-01-03 17:53:01 -05:00
Jake McDermott
70840841c1 update LoginPage param names for @patternfly/react-core 1.43.5 2019-01-03 17:52:58 -05:00
Jake McDermott
1c483a42c6 update @patternfly/react-core to 1.43.5 2019-01-03 17:52:53 -05:00
Jake McDermott
2254bdb0e1 make default dev server target overridable with env vars 2019-01-03 17:52:46 -05:00
Jake McDermott
23bb32b7ad Merge pull request #72 from ansible/react-context-api
Implement React Context API
2019-01-03 15:28:54 -05:00
kialam
e8924e8f6f Fix linter errors. 2019-01-03 15:20:46 -05:00
kialam
e77d81dd5b Lift config context one level higher.
- Refactor About component to use config context.
- Update About component unit tests.
2019-01-03 15:20:41 -05:00
kialam
a217a387c6 Use new lifecycle method to update component state.
- Use component state to handle rendering of Ansible Select dropdown based on the number of custom virtualenvs the API returns.
2019-01-03 15:20:35 -05:00
kialam
13680a436c Add unit tests for recent changes to App.jsx. 2019-01-03 15:20:30 -05:00
kialam
6c307726db Use setState instead of sessionStorage for config data. 2019-01-03 15:20:23 -05:00
kialam
9bc87b3e80 Implement React Context API
- Move API GET request to /v2/config out to the top level of our App.
- Store /v2/config response data in sessionStorage.
- Use Context API to pass down relevant data to Organizations component.
- Wrap our AnsibleSelect component as a context consumer and pass in the list of Ansible Environments of the logged in user.
- Clear sessionStorage object when user logs out.
- Update unit tests.
2019-01-03 15:20:08 -05:00
Jake McDermott
f678e158f8 Merge pull request #57 from jlmitch5/updateComponentTests
Update component tests and bump back up coverage
2019-01-03 13:52:28 -05:00
John Mitchell
11583dbff0 update pagination tests 2019-01-03 13:37:56 -05:00
John Mitchell
e48c734925 update datelisttoolbar test 2019-01-03 13:37:46 -05:00
John Mitchell
e25dcb2448 update app and towerlogo tests and remove stale code 2019-01-03 13:37:41 -05:00
John Mitchell
ebd09883fe update DataListToolbar component and tests 2019-01-03 13:37:31 -05:00
kialam
fefbb8fff8 Fix linter errors. 2019-01-02 09:19:11 -07:00
kialam
f5119e5d97 Lift config context one level higher.
- Refactor About component to use config context.
- Update About component unit tests.
2019-01-02 09:03:48 -07:00
kialam
5fcdd16f54 Use new lifecycle method to update component state.
- Use component state to handle rendering of Ansible Select dropdown based on the number of custom virtualenvs the API returns.
2018-12-22 09:03:44 -05:00
kialam
e30b198418 Remove duplicate REST call in add org component. 2018-12-21 11:56:39 -05:00
kialam
aaa9096b4e Add unit tests for recent changes to App.jsx. 2018-12-21 10:25:17 -05:00
kialam
4eb04b6f5c Use setState instead of sessionStorage for config data. 2018-12-21 10:20:07 -05:00
kialam
6dc11a926e Merge remote-tracking branch 'origin/master' into react-context-api 2018-12-21 10:16:50 -05:00
Michael Abashian
7f1c3c8c6a Update readme to fix display of unit test commands 2018-12-20 09:52:03 -05:00
kialam
fe857ad68b Merge remote-tracking branch 'origin/master' into react-context-api 2018-12-18 10:52:09 -05:00
kialam
fd513f704b Add a contributing doc to our repo. 2018-12-18 10:30:48 -05:00
kialam
46e9fcfda7 Merge pull request #53 from ansible/add-org-new
Basic Add Organization View
2018-12-17 17:14:05 -05:00
Michael Abashian
32378266bd Merge pull request #59 from mabashian/45-list-ux
Small ux changes on the org list based on feedback
2018-12-17 14:55:19 -05:00
kialam
ff0015e21d Hook up Cancel button
- Update unit tests.
- Add basic error handling for API requests in Add Orgs component.
2018-12-17 13:44:59 -05:00
mabashian
6ce88fdf4d Separates search dropdown items from sort dropdown items 2018-12-17 13:16:08 -05:00
mabashian
21cf1d85e3 Remove border-radius on add button 2018-12-17 12:40:20 -05:00
mabashian
d43f0cb2fc Removed extraneous style 2018-12-17 12:40:20 -05:00
mabashian
71ace1bc00 Small ux changes on the org list based on feedback 2018-12-17 12:40:20 -05:00
kialam
656e6d4f6a Add back missing style. 2018-12-17 12:39:41 -05:00
Jake McDermott
b375963165 Merge pull request #68 from ansible/refactor-nav
replace navitem generator with expandable navgroup component
2018-12-17 12:15:39 -05:00
kialam
b3b6e0515e Merge remote-tracking branch 'origin/add-org-new' into react-context-api 2018-12-17 11:59:46 -05:00
kialam
b8fc402d55 Implement React Context API
- Move API GET request to /v2/config out to the top level of our App.
- Store /v2/config response data in sessionStorage.
- Use Context API to pass down relevant data to Organizations component.
- Wrap our AnsibleSelect component as a context consumer and pass in the list of Ansible Environments of the logged in user.
- Clear sessionStorage object when user logs out.
- Update unit tests.
2018-12-17 11:44:11 -05:00
Michael Abashian
e58613b441 Merge pull request #70 from mabashian/69-hide-expand-collapse
Adds option to hide expand/collapse in toolbar and hides it for the org list
2018-12-17 11:40:24 -05:00
mabashian
14f1c4b652 Conditionally render rather than show expand/collapse 2018-12-17 11:28:34 -05:00
Jake McDermott
1bb86dbdf0 use beginning of location path name when checking for active items 2018-12-17 00:16:49 -05:00
Jake McDermott
3d730ef8d2 add basic unit test for expandable navgroup component 2018-12-17 00:16:31 -05:00
Jake McDermott
5d4aa56f4a refactor wrapped nav components to expandable nav group component 2018-12-16 23:40:54 -05:00
kialam
9292b21a41 Merge remote-tracking branch 'origin/master' into add-org-new 2018-12-14 10:14:36 -05:00
mabashian
4a8791693f Adds option to hide expand/collapse in toolbar and hides it for the org list 2018-12-14 09:55:59 -05:00
Jake McDermott
9114c16a97 refactor navitem factory function to wrapped router-hoc nav components 2018-12-14 04:05:29 -05:00
Michael Abashian
b2ba863569 Merge pull request #51 from mabashian/43-lingui
Add support for i18n using lingui
2018-12-13 16:56:16 -05:00
mabashian
ef9f9e902e Update readme with new npm command syntax 2018-12-12 13:17:07 -05:00
mabashian
ac8553df85 Pull messages from the correct location 2018-12-12 11:30:50 -05:00
mabashian
6adcac85a6 Moves locales out of src and into build dir. Changes npm commands from extract/compile to extract-strings/compile-strings 2018-12-12 11:28:29 -05:00
kialam
7ea5ea2ecd Merge pull request #55 from ansible/ansible-environment-dropdown
Basic Ansible Environment Select Component
2018-12-12 11:03:00 -05:00
kialam
44029c2191 Use object desctructuring. 2018-12-11 16:57:38 -05:00
kialam
9627a73978 Rename AnsibleEnvironmentSelect to AnsibleSelect
- Update references to the component.
2018-12-11 16:42:24 -05:00
kialam
9c7d449a4d Abstract out API get request to Add Org component.
- This makes it so we now have a generic select dropdown where we can pass data down as props.
2018-12-11 16:20:55 -05:00
kialam
d047bc876a Basic Ansible Environment Select Component
- Component conditionally renders based on # of virtual environments.
- User can add an Organization and associate it with a virtual environment.
2018-12-10 20:41:47 -05:00
kialam
27e13ca082 Add tests for Organization add view plus code refactoring. 2018-12-10 15:03:33 -05:00
kialam
9400bad990 Linter fixes. 2018-12-10 15:00:49 -05:00
kialam
1dd8175e11 Basic add organization functionality.
- Placeholders for Lookup Modal and Ansible Environment dropdown.
2018-12-10 15:00:16 -05:00
mabashian
356ad06d74 Add support for i18n using lingui 2018-12-10 10:17:00 -05:00
Marliana Lara
e736cfab36 Merge pull request #40 from marshmalien/side-nav-bug
Update active nav item based on url
2018-12-05 10:32:47 -05:00
Marliana Lara
a31ef24be6 Remove calling setState from render 2018-12-05 10:19:14 -05:00
John Mitchell
8f54ec681d Merge pull request #28 from jlmitch5/orgUrls
add routes and breadcrumbs for org detail/edit/related routes
2018-12-05 10:01:01 -05:00
John Mitchell
aaaf598ca1 remove commented out code in the data list toolbar 2018-12-05 09:57:11 -05:00
John Mitchell
00c9ae1376 update map function to be chained 2018-12-05 07:59:06 -05:00
John Mitchell
f83b59cb48 working commit of group and nav selection based on url 2018-12-05 07:59:06 -05:00
Marliana Lara
9341c4660c Update active nav item based on url 2018-12-05 07:58:59 -05:00
John Mitchell
e5320b6fa6 make current tab link replace instead of add new history item 2018-12-04 16:04:44 -05:00
John Mitchell
27542ea322 add tooltip test coverage 2018-12-04 15:27:43 -05:00
John Mitchell
3a8d95b03b working test commit 2018-12-04 14:46:18 -05:00
John Mitchell
aab6aa4ef9 working commit tests 2018-12-03 13:30:31 -05:00
John Mitchell
12c8267b12 update organizations structure and add unstyled sub routes and breadcrumbs 2018-12-03 13:30:30 -05:00
Michael Abashian
1e7ab9deed Merge pull request #30 from mabashian/update-pf-fix-login
Updates to login page after LoginPage and LoginForm components landed
2018-12-03 12:06:49 -05:00
mabashian
8f6b476388 Update sidebar override to ensure it is the same width as the masthead 2018-12-03 11:30:33 -05:00
mabashian
58d6e586cd Fixes login page after pf-react added LoginPage and LoginForm components 2018-11-29 16:50:56 -05:00
mabashian
7d2bc1c766 Bumps all patternfly versions to latest 2018-11-28 11:29:07 -05:00
Marliana Lara
07d2a1ed1e Merge pull request #23 from marshmalien/about-modal
Add help dropdown and about modal
2018-11-20 11:33:39 -05:00
Marliana Lara
6d315568d2 Add help dropdown and about modal 2018-11-19 22:53:05 -05:00
Jake McDermott
7fdf27eece Merge pull request #5 from ansible/pf4-table
basic pf4 data list, toolbar, pagination
2018-11-19 11:35:28 -05:00
Jake McDermott
4e6e715f1f add parametrized unit tests for querystring module 2018-11-18 22:50:21 -05:00
Jake McDermott
9979eddbcd add basic component test for pagination 2018-11-18 22:50:15 -05:00
Jake McDermott
de96f6cf8a check tooltip in organization functional test 2018-11-18 22:50:09 -05:00
Jake McDermott
9111948959 add basic component test for data list toolbar 2018-11-18 22:49:59 -05:00
Jake McDermott
e3a5f32b57 wip - pf4 data list and pagination 2018-11-18 22:49:50 -05:00
Jake McDermott
546d5d5587 Merge pull request #20 from ansible/async-await
Start using async-await
2018-11-13 13:38:26 -05:00
kialam
b0855ee33d Fix unhandled promise reject from jenkins. 2018-11-13 13:31:24 -05:00
kialam
03f6e52cf1 Address PR review comments. 2018-11-13 10:55:18 -05:00
kialam
44e9d3919d Update unit tests. 2018-11-13 09:46:43 -05:00
kialam
f520be71d6 Begin using async/await. 2018-11-12 13:24:17 -05:00
Jake McDermott
06470a0e65 Merge pull request #19 from jlmitch5/useCollapsedHeader
Use collapsed header
2018-11-09 21:28:18 -05:00
John Mitchell
5ea40efd3a update pages to utilize collapsed modifier for padding override 2018-11-09 17:31:40 -05:00
John Mitchell
4632383a33 update app component to utilize collapsing header and update style overrides 2018-11-09 17:30:48 -05:00
Jake McDermott
ea0f3a64b1 Merge pull request #16 from jlmitch5/indexJsxTestsAndRestructure
finish unit test coverage
2018-11-06 12:32:29 -05:00
John Mitchell
df57b144c4 fix logout in App.jsx and update test 2018-11-06 12:25:36 -05:00
John Mitchell
7b099578c8 update App.jsx and improve coverage
abstract LogoutButton to component
2018-11-02 17:47:59 -04:00
John Mitchell
08d2718f5e add about page tests 2018-11-02 17:46:43 -04:00
John Mitchell
96b8ab47c4 add TowerLogo tests 2018-11-02 16:34:02 -04:00
John Mitchell
07f6508402 move ConditionalRedirect test to components subfolder 2018-11-02 16:33:40 -04:00
John Mitchell
a670a73fd0 update file mock to return file name 2018-11-02 16:32:51 -04:00
John Mitchell
90d1ab88b1 and index.jsx tests 2018-11-02 13:45:11 -04:00
John Mitchell
19dcf5ed59 update unit test mocks and restructure test dir structure 2018-11-02 13:44:13 -04:00
Jake McDermott
90273247ac Merge pull request #14 from ansible/pagesTests
pages unit tests
2018-10-31 14:52:46 -04:00
John Mitchell
8a3b8823ee move login page test under pages and add tests for all pages stubs 2018-10-31 14:44:18 -04:00
John Mitchell
b40c81cc3d Merge pull request #10 from jlmitch5/loginPageTests
Add login page tests
2018-10-31 09:45:35 -07:00
John Mitchell
e53a6a91d6 remove setTimeout hack for testing api.login Login.jsx handlers 2018-10-31 12:04:59 -04:00
John Mitchell
55586b9b2a convert post-api.login code to using async/await for Login.jsx 2018-10-31 12:04:33 -04:00
John Mitchell
986d299961 move login back to using finally handler and update tests 2018-10-31 10:28:51 -04:00
John Mitchell
7c97989e84 add more login page tests 2018-10-31 09:56:35 -04:00
John Mitchell
ecd8427a51 fix eslint issues with app and conditional redirect tests 2018-10-31 09:56:28 -04:00
Jake McDermott
5c2e6244c6 Merge pull request #13 from jlmitch5/updateBuildSystem
Update build system
2018-10-30 17:34:07 -04:00
John Mitchell
fed7f51476 update build system
polyfill new js features before executing tests
move jest config to file, update transformation exclusion to be okay with axios module
rename enzyme.config.js to jest.setup.js
remove currently unused redux deps
update babel to 7, use env preset as opposed to deprecated stage preset
move .babelrc to newer, favored babel.config.js preset
update all babel preset and plugin packages to those name spaced under @babel
2018-10-30 17:25:29 -04:00
John Mitchell
3ccfc5905e Merge pull request #8 from jlmitch5/navUpdates
update navigation
2018-10-29 12:29:07 -07:00
John Mitchell
74d3e55908 bump patternfly dep versions 2018-10-29 13:58:56 -04:00
John Mitchell
557e619db6 update page navigation
fix issue with jerky close and expand of nav
update nav to use expandle headers
separate settings pages out into separate stup page components
2018-10-26 17:24:34 -04:00
John Mitchell
2dfbae79bd update patternfly style overrides 2018-10-26 17:23:37 -04:00
John Mitchell
fd28cff412 add additional patternfly react packages 2018-10-26 17:23:27 -04:00
Jake McDermott
ca0127d889 Merge pull request #7 from ansible/testing
add unit and functional testing to the app
2018-10-24 22:03:43 -04:00
John Mitchell
05d72ae8cf update webpack and package.json with index.jsx entrypoint 2018-10-24 21:55:59 -04:00
John Mitchell
1caa5b1c54 fix eslint errors 2018-10-24 21:51:35 -04:00
John Mitchell
2245d6a22e update LoginPage component and test pseudocode 2018-10-24 21:35:43 -04:00
John Mitchell
3e9a85a58b remove stale route redirection components 2018-10-24 21:35:14 -04:00
John Mitchell
51c58d5645 remove babel config.js to favor .babelrc file 2018-10-24 21:34:20 -04:00
John Mitchell
cfb89f1e31 working commit LoginPage.jsx tests 2018-10-24 21:16:24 -04:00
John Mitchell
fba1a5b71a fix App.jsx test misnamed variables 2018-10-24 21:15:08 -04:00
John Mitchell
79e68b1dbe add coverage report 2018-10-24 21:11:52 -04:00
John Mitchell
3938d49a1f refactor auth redirect and add ConditionalRedirect unit tests and App unit and functional tests 2018-10-24 16:53:16 -04:00
John Mitchell
0373058540 update api.js api client, and axios mock, and add api.js unit tests 2018-10-24 16:52:11 -04:00
John Mitchell
22112f3dd8 update package-lock.json with new jest and enzyme testing dependencies 2018-10-24 16:50:37 -04:00
John Mitchell
a76ac805f2 add jest and enzyme testing dependencies and update infrastructure configuration to make testing work 2018-10-24 16:50:08 -04:00
Jake McDermott
311346b77b Merge pull request #6 from ansible/nav-login-fixup
nav login fixup
2018-10-16 00:31:52 -04:00
Jake McDermott
05af4c7c53 nav login fixup 2018-10-16 00:30:14 -04:00
Jake McDermott
9f2b2b3456 adding pf assets / styles 2018-10-15 12:55:11 -04:00
Jake McDermott
0fbd0c941a Merge pull request #4 from ansible/nav-login-updates
Nav login updates
2018-10-15 12:49:27 -04:00
Jake McDermott
a54fb0e27d Nav and login updates 2018-10-15 12:44:29 -04:00
Jake McDermott
ff53a9c8ea move logo component to folder 2018-10-15 12:44:14 -04:00
Jake McDermott
070cec19df handle fonts and images differently in webpack config 2018-10-15 12:44:07 -04:00
Jake McDermott
f639f353ec update pf react version 2018-10-15 12:43:52 -04:00
Jake McDermott
ab94398889 Update README.md 2018-10-12 11:54:09 -04:00
Jake McDermott
13f6e63f75 Merge pull request #1 from ansible/nav
wip - one way of approaching nav
2018-10-12 11:23:03 -04:00
Jake McDermott
b31edef9b2 one way of approaching nav 2018-10-11 22:48:39 -04:00
Jake McDermott
b2ebbc6a0a use a few more pf-core components 2018-09-26 21:39:04 -04:00
Jake McDermott
d926378cf5 add .gitignore 2018-09-26 20:59:50 -04:00
Jake McDermott
f8a4b01da5 lint 2018-09-26 20:59:41 -04:00
Jake McDermott
0986ebef33 avoid port collision with other tooling 2018-09-26 18:11:29 -04:00
Jake McDermott
065813ebc0 make default configuration work with awx development api server 2018-09-26 18:06:30 -04:00
Jake McDermott
a73c1dd28e Update README.md 2018-09-26 14:50:15 -04:00
Jake McDermott
421aa09383 Update README.md 2018-09-26 14:31:28 -04:00
Jake McDermott
72af9c1405 Update README.md 2018-09-26 14:02:10 -04:00
Jake McDermott
1bfa8b19ff update readme 2018-09-26 13:57:10 -04:00
Jake McDermott
43f3b484f9 initial commit 2018-09-25 10:53:35 -04:00
1185 changed files with 91982 additions and 8109 deletions

12
.gitignore vendored
View File

@@ -28,6 +28,9 @@ awx/ui/build_test
awx/ui/client/languages
awx/ui/templates/ui/index.html
awx/ui/templates/ui/installing.html
awx/ui_next/node_modules/
awx/ui_next/coverage/
awx/ui_next/build/locales/_build
/tower-license
/tower-license/**
tools/prometheus/data
@@ -122,6 +125,7 @@ local/
requirements/vendor
.i18n_built
.idea/*
*credentials*.y*ml*
# AWX python libs populated by requirements.txt
awx/lib/.deps_built
@@ -129,4 +133,12 @@ awx/lib/site-packages
venv/*
use_dev_supervisor.txt
# Ansible module tests
awx_collection_test_venv/
awx_collection/*.tar.gz
awx_collection/galaxy.yml
.idea/*
*.unison.tmp
*.#

View File

@@ -134,6 +134,8 @@ Run the following to build the AWX UI:
```bash
(host) $ make ui-devel
```
See [the ui development documentation](awx/ui/README.md) for more information on using the frontend development, build, and test tooling.
### Running the environment
#### Start the containers
@@ -154,8 +156,8 @@ If you start a second terminal session, you can take a look at the running conta
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa4a75d6d77b gcr.io/ansible-tower-engineering/awx_devel:devel "/tini -- /bin/sh ..." 23 seconds ago Up 15 seconds 0.0.0.0:5555->5555/tcp, 0.0.0.0:6899-6999->6899-6999/tcp, 0.0.0.0:8013->8013/tcp, 0.0.0.0:8043->8043/tcp, 22/tcp, 0.0.0.0:8080->8080/tcp tools_awx_1
e4c0afeb548c postgres:9.6 "docker-entrypoint..." 26 seconds ago Up 23 seconds 5432/tcp tools_postgres_1
aa4a75d6d77b gcr.io/ansible-tower-engineering/awx_devel:devel "/tini -- /bin/sh ..." 23 seconds ago Up 15 seconds 0.0.0.0:5555->5555/tcp, 0.0.0.0:7899-7999->7899-7999/tcp, 0.0.0.0:8013->8013/tcp, 0.0.0.0:8043->8043/tcp, 22/tcp, 0.0.0.0:8080->8080/tcp tools_awx_1
e4c0afeb548c postgres:10 "docker-entrypoint..." 26 seconds ago Up 23 seconds 5432/tcp tools_postgres_1
0089699d5afd tools_logstash "/docker-entrypoin..." 26 seconds ago Up 25 seconds tools_logstash_1
4d4ff0ced266 memcached:alpine "docker-entrypoint..." 26 seconds ago Up 25 seconds 0.0.0.0:11211->11211/tcp tools_memcached_1
92842acd64cd rabbitmq:3-management "docker-entrypoint..." 26 seconds ago Up 24 seconds 4369/tcp, 5671-5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp tools_rabbitmq_1

View File

@@ -36,7 +36,7 @@ This document provides a guide for installing AWX.
- [PostgreSQL](#postgresql-1)
- [Proxy settings](#proxy-settings)
- [Start the build](#start-the-build-2)
- [Post build](#post-build-1)
- [Post build](#post-build-2)
- [Accessing AWX](#accessing-awx-2)
## Getting started
@@ -72,7 +72,7 @@ Before you can run a deployment, you'll need the following installed in your loc
The system that runs the AWX service will need to satisfy the following requirements
- At leasts 4GB of memory
- At least 4GB of memory
- At least 2 cpu cores
- At least 20GB of space
- Running Docker, Openshift, or Kubernetes
@@ -193,7 +193,7 @@ $ eval $(minishift docker-env)
By default, AWX will deploy a PostgreSQL pod inside of your cluster. You will need to create a [Persistent Volume Claim](https://docs.openshift.org/latest/dev_guide/persistent_volumes.html) which is named `postgresql` by default, and can be overridden by setting the `openshift_pg_pvc_name` variable. For testing and demo purposes, you may set `openshift_pg_emptydir=yes`.
If you wish to use an external database, in the inventory file, set the value of `pg_hostname`, and update `pg_username`, `pg_password`, `pg_database`, and `pg_port` with the connection information. When setting `pg_hostname` the installer will assume you have configured the database in that location and will not launch the postgresql pod.
If you wish to use an external database, in the inventory file, set the value of `pg_hostname`, and update `pg_username`, `pg_password`, `pg_admin_password`, `pg_database`, and `pg_port` with the connection information. When setting `pg_hostname` the installer will assume you have configured the database in that location and will not launch the postgresql pod.
### Start the build
@@ -503,7 +503,7 @@ If you wish to tag and push built images to a Docker registry, set the following
AWX requires access to a PostgreSQL database, and by default, one will be created and deployed in a container, and data will be persisted to a host volume. In this scenario, you must set the value of `postgres_data_dir` to a path that can be mounted to the container. When the container is stopped, the database files will still exist in the specified path.
If you wish to use an external database, in the inventory file, set the value of `pg_hostname`, and update `pg_username`, `pg_password`, `pg_database`, and `pg_port` with the connection information.
If you wish to use an external database, in the inventory file, set the value of `pg_hostname`, and update `pg_username`, `pg_password`, `pg_admin_password`, `pg_database`, and `pg_port` with the connection information.
### Start the build

View File

@@ -18,6 +18,7 @@ COMPOSE_TAG ?= $(GIT_BRANCH)
COMPOSE_HOST ?= $(shell hostname)
VENV_BASE ?= /venv
COLLECTION_VENV ?= /awx_devel/awx_collection_test_venv
SCL_PREFIX ?=
CELERY_SCHEDULE_FILE ?= /var/lib/awx/beat.db
@@ -59,20 +60,23 @@ UI_RELEASE_FLAG_FILE = awx/ui/.release_built
I18N_FLAG_FILE = .i18n_built
.PHONY: awx-link clean clean-tmp clean-venv requirements requirements_dev \
develop refresh adduser migrate dbchange dbshell runserver \
develop refresh adduser migrate dbchange runserver \
receiver test test_unit test_coverage coverage_html \
dev_build release_build release_clean sdist \
ui-docker-machine ui-docker ui-release ui-devel \
ui-test ui-deps ui-test-ci VERSION
# remove ui build artifacts
clean-ui:
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)
@@ -91,21 +95,27 @@ clean-schema:
rm -rf schema.json
rm -rf reference-schema.json
clean-languages:
rm -f $(I18N_FLAG_FILE)
find . -type f -regex ".*\.mo$$" -delete
# Remove temporary build files, compiled Python files.
clean: clean-ui clean-dist
clean: clean-ui clean-api clean-dist
rm -rf awx/public
rm -rf awx/lib/site-packages
rm -rf awx/job_status
rm -rf awx/job_output
rm -rf reports
rm -f awx/awx_test.sqlite3
rm -rf requirements/vendor
rm -rf tmp
rm -rf $(I18N_FLAG_FILE)
mkdir tmp
clean-api:
rm -rf build $(NAME)-$(VERSION) *.egg-info
find . -type f -regex ".*\.py[co]$$" -delete
find . -type d -name "__pycache__" -delete
rm -f awx/awx_test.sqlite3*
rm -rf requirements/vendor
# convenience target to assert environment variables are defined
guard-%:
@@ -179,7 +189,7 @@ requirements_awx: virtualenv_awx
cat requirements/requirements.txt requirements/requirements_git.txt | $(VENV_BASE)/awx/bin/pip install $(PIP_OPTIONS) --no-binary $(SRC_ONLY_PKGS) --ignore-installed -r /dev/stdin ; \
fi
echo "include-system-site-packages = true" >> $(VENV_BASE)/awx/lib/python$(PYTHON_VERSION)/pyvenv.cfg
#$(VENV_BASE)/awx/bin/pip uninstall --yes -r requirements/requirements_tower_uninstall.txt
$(VENV_BASE)/awx/bin/pip uninstall --yes -r requirements/requirements_tower_uninstall.txt
requirements_awx_dev:
$(VENV_BASE)/awx/bin/pip install -r requirements/requirements_dev.txt
@@ -239,10 +249,6 @@ migrate:
dbchange:
$(MANAGEMENT_COMMAND) makemigrations
# access database shell, asks for password
dbshell:
sudo -u postgres psql -d awx-dev
server_noattach:
tmux new-session -d -s awx 'exec make uwsgi'
tmux rename-window 'AWX'
@@ -369,8 +375,34 @@ test:
. $(VENV_BASE)/awx/bin/activate; \
fi; \
PYTHONDONTWRITEBYTECODE=1 py.test -p no:cacheprovider -n auto $(TEST_DIRS)
cd awxkit && $(VENV_BASE)/awx/bin/tox -re py2,py3
awx-manage check_migrations --dry-run --check -n 'vNNN_missing_migration_file'
prepare_collection_venv:
rm -rf $(COLLECTION_VENV)
mkdir $(COLLECTION_VENV)
ln -s /usr/lib/python2.7/site-packages/ansible $(COLLECTION_VENV)/ansible
$(VENV_BASE)/awx/bin/pip install --target=$(COLLECTION_VENV) git+https://github.com/ansible/tower-cli.git
COLLECTION_TEST_DIRS ?= awx_collection/test/awx
COLLECTION_PACKAGE ?= awx
COLLECTION_NAMESPACE ?= awx
test_collection:
@if [ "$(VENV_BASE)" ]; then \
. $(VENV_BASE)/awx/bin/activate; \
fi; \
PYTHONPATH=$(COLLECTION_VENV):/awx_devel/awx_collection:$PYTHONPATH py.test $(COLLECTION_TEST_DIRS)
flake8_collection:
flake8 awx_collection/ # Different settings, in main exclude list
test_collection_all: prepare_collection_venv test_collection flake8_collection
build_collection:
ansible-playbook -i localhost, awx_collection/template_galaxy.yml -e collection_package=$(COLLECTION_PACKAGE) -e collection_namespace=$(COLLECTION_NAMESPACE) -e collection_version=$(VERSION)
ansible-galaxy collection build awx_collection --output-path=awx_collection
test_unit:
@if [ "$(VENV_BASE)" ]; then \
. $(VENV_BASE)/awx/bin/activate; \
@@ -512,9 +544,36 @@ jshint: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) run --prefix awx/ui jshint
$(NPM_BIN) run --prefix awx/ui lint
ui-zuul-lint-and-test: $(UI_DEPS_FLAG_FILE)
$(NPM_BIN) run --prefix awx/ui jshint
$(NPM_BIN) run --prefix awx/ui lint
$(NPM_BIN) --prefix awx/ui run test:ci
$(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:
$(PYTHON) setup.py dev_build
@@ -546,8 +605,8 @@ setup-bundle-build:
mkdir -p $@
docker-auth:
if [ "$(IMAGE_REPOSITORY_AUTH)" ]; then \
docker login -u oauth2accesstoken -p "$(IMAGE_REPOSITORY_AUTH)" $(IMAGE_REPOSITORY_BASE); \
@if [ "$(IMAGE_REPOSITORY_AUTH)" ]; then \
echo "$(IMAGE_REPOSITORY_AUTH)" | docker login -u oauth2accesstoken --password-stdin $(IMAGE_REPOSITORY_BASE); \
fi;
# Docker isolated rampart
@@ -629,7 +688,7 @@ clean-elk:
docker rm tools_kibana_1
psql-container:
docker run -it --net tools_default --rm postgres:9.6 sh -c 'exec psql -h "postgres" -p "5432" -U postgres'
docker run -it --net tools_default --rm postgres:10 sh -c 'exec psql -h "postgres" -p "5432" -U postgres'
VERSION:
@echo "awx: $(VERSION)"

View File

@@ -1 +1 @@
6.0.0
8.0.0

View File

@@ -25,9 +25,8 @@ import hashlib
try:
import django
from django.utils.encoding import force_bytes
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.backends.base import schema
from django.db.backends.utils import names_digest
HAS_DJANGO = True
except ImportError:
HAS_DJANGO = False
@@ -37,30 +36,33 @@ if HAS_DJANGO is True:
# This line exists to make sure we don't regress on FIPS support if we
# upgrade Django; if you're upgrading Django and see this error,
# update the version check below, and confirm that FIPS still works.
if django.__version__ != '1.11.20':
raise RuntimeError("Django version other than 1.11.20 detected {}. \
Subclassing BaseDatabaseSchemaEditor is known to work for Django 1.11.20 \
and may not work in newer Django versions.".format(django.__version__))
# If operating in a FIPS environment, `hashlib.md5()` will raise a `ValueError`,
# but will support the `usedforsecurity` keyword on RHEL and Centos systems.
# Keep an eye on https://code.djangoproject.com/ticket/28401
target_version = '2.2.4'
if django.__version__ != target_version:
raise RuntimeError(
"Django version other than {target} detected: {current}. "
"Overriding `names_digest` is known to work for Django {target} "
"and may not work in other Django versions.".format(target=target_version,
current=django.__version__)
)
class FipsBaseDatabaseSchemaEditor(BaseDatabaseSchemaEditor):
@classmethod
def _digest(cls, *args):
try:
names_digest('foo', 'bar', 'baz', length=8)
except ValueError:
def names_digest(*args, length):
"""
Generates a 32-bit digest of a set of arguments that can be used to
shorten identifying names.
Generate a 32-bit digest of a set of arguments that can be used to shorten
identifying names. Support for use in FIPS environments.
"""
try:
h = hashlib.md5()
except ValueError:
h = hashlib.md5(usedforsecurity=False)
h = hashlib.md5(usedforsecurity=False)
for arg in args:
h.update(force_bytes(arg))
return h.hexdigest()[:8]
h.update(arg.encode())
return h.hexdigest()[:length]
schema.BaseDatabaseSchemaEditor = FipsBaseDatabaseSchemaEditor
schema.names_digest = names_digest
def find_commands(management_dir):
@@ -80,6 +82,16 @@ def find_commands(management_dir):
return commands
def oauth2_getattribute(self, attr):
# Custom method to override
# oauth2_provider.settings.OAuth2ProviderSettings.__getattribute__
from django.conf import settings
val = settings.OAUTH2_PROVIDER.get(attr)
if val is None:
val = object.__getattribute__(self, attr)
return val
def prepare_env():
# Update the default settings environment variable based on current mode.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'awx.settings.%s' % MODE)
@@ -91,6 +103,12 @@ def prepare_env():
# Monkeypatch Django find_commands to also work with .pyc files.
import django.core.management
django.core.management.find_commands = find_commands
# Monkeypatch Oauth2 toolkit settings class to check for settings
# in django.conf settings each time, not just once during import
import oauth2_provider.settings
oauth2_provider.settings.OAuth2ProviderSettings.__getattribute__ = oauth2_getattribute
# Use the AWX_TEST_DATABASE_* environment variables to specify the test
# database settings to use when management command is run as an external
# program via unit tests.

View File

@@ -38,12 +38,15 @@ register(
'OAUTH2_PROVIDER',
field_class=OAuth2ProviderField,
default={'ACCESS_TOKEN_EXPIRE_SECONDS': oauth2_settings.ACCESS_TOKEN_EXPIRE_SECONDS,
'AUTHORIZATION_CODE_EXPIRE_SECONDS': 600},
'AUTHORIZATION_CODE_EXPIRE_SECONDS': oauth2_settings.AUTHORIZATION_CODE_EXPIRE_SECONDS,
'REFRESH_TOKEN_EXPIRE_SECONDS': oauth2_settings.REFRESH_TOKEN_EXPIRE_SECONDS},
label=_('OAuth 2 Timeout Settings'),
help_text=_('Dictionary for customizing OAuth 2 timeouts, available items are '
'`ACCESS_TOKEN_EXPIRE_SECONDS`, the duration of access tokens in the number '
'of seconds, and `AUTHORIZATION_CODE_EXPIRE_SECONDS`, the duration of '
'authorization codes in the number of seconds.'),
'of seconds, `AUTHORIZATION_CODE_EXPIRE_SECONDS`, the duration of '
'authorization codes in the number of seconds, and `REFRESH_TOKEN_EXPIRE_SECONDS`, '
'the duration of refresh tokens, after expired access tokens, '
'in the number of seconds.'),
category=_('Authentication'),
category_slug='authentication',
)

View File

@@ -80,7 +80,7 @@ class OAuth2ProviderField(fields.DictField):
default_error_messages = {
'invalid_key_names': _('Invalid key names: {invalid_key_names}'),
}
valid_key_names = {'ACCESS_TOKEN_EXPIRE_SECONDS', 'AUTHORIZATION_CODE_EXPIRE_SECONDS'}
valid_key_names = {'ACCESS_TOKEN_EXPIRE_SECONDS', 'AUTHORIZATION_CODE_EXPIRE_SECONDS', 'REFRESH_TOKEN_EXPIRE_SECONDS'}
child = fields.IntegerField(min_value=1)
def to_internal_value(self, data):

View File

@@ -126,7 +126,7 @@ class FieldLookupBackend(BaseFilterBackend):
'''
RESERVED_NAMES = ('page', 'page_size', 'format', 'order', 'order_by',
'search', 'type', 'host_filter')
'search', 'type', 'host_filter', 'count_disabled', 'no_truncate')
SUPPORTED_LOOKUPS = ('exact', 'iexact', 'contains', 'icontains',
'startswith', 'istartswith', 'endswith', 'iendswith',

View File

@@ -34,7 +34,8 @@ from rest_framework.negotiation import DefaultContentNegotiation
# AWX
from awx.api.filters import FieldLookupBackend
from awx.main.models import (
UnifiedJob, UnifiedJobTemplate, User, Role, Credential
UnifiedJob, UnifiedJobTemplate, User, Role, Credential,
WorkflowJobTemplateNode, WorkflowApprovalTemplate
)
from awx.main.access import access_registry
from awx.main.utils import (
@@ -91,7 +92,7 @@ class LoggedLoginView(auth_views.LoginView):
ret = super(LoggedLoginView, self).post(request, *args, **kwargs)
current_user = getattr(request, 'user', None)
if request.user.is_authenticated:
logger.info(smart_text(u"User {} logged in.".format(self.request.user.username)))
logger.info(smart_text(u"User {} logged in from {}".format(self.request.user.username,request.META.get('REMOTE_ADDR', None))))
ret.set_cookie('userLoggedIn', 'true')
current_user = UserSerializer(self.request.user)
current_user = smart_text(JSONRenderer().render(current_user.data))
@@ -204,6 +205,9 @@ class APIView(views.APIView):
response['X-API-Query-Count'] = len(q_times)
response['X-API-Query-Time'] = '%0.3fs' % sum(q_times)
if getattr(self, 'deprecated', False):
response['Warning'] = '299 awx "This resource has been deprecated and will be removed in a future release."' # noqa
return response
def get_authenticate_header(self, request):
@@ -401,21 +405,21 @@ class ListAPIView(generics.ListAPIView, GenericAPIView):
continue
if getattr(field, 'related_model', None):
fields.add('{}__search'.format(field.name))
for rel in self.model._meta.related_objects:
name = rel.related_name
if isinstance(rel, OneToOneRel) and self.model._meta.verbose_name.startswith('unified'):
for related in self.model._meta.related_objects:
name = related.related_name
if isinstance(related, OneToOneRel) and self.model._meta.verbose_name.startswith('unified'):
# Add underscores for polymorphic subclasses for user utility
name = rel.related_model._meta.verbose_name.replace(" ", "_")
name = related.related_model._meta.verbose_name.replace(" ", "_")
if skip_related_name(name) or name.endswith('+'):
continue
fields.add('{}__search'.format(name))
m2m_rel = []
m2m_rel += self.model._meta.local_many_to_many
m2m_related = []
m2m_related += self.model._meta.local_many_to_many
if issubclass(self.model, UnifiedJobTemplate) and self.model != UnifiedJobTemplate:
m2m_rel += UnifiedJobTemplate._meta.local_many_to_many
m2m_related += UnifiedJobTemplate._meta.local_many_to_many
if issubclass(self.model, UnifiedJob) and self.model != UnifiedJob:
m2m_rel += UnifiedJob._meta.local_many_to_many
for relationship in m2m_rel:
m2m_related += UnifiedJob._meta.local_many_to_many
for relationship in m2m_related:
if skip_related_name(relationship.name):
continue
if relationship.related_model._meta.app_label != 'main':
@@ -488,9 +492,12 @@ class SubListAPIView(ParentMixin, ListAPIView):
parent = self.get_parent_object()
self.check_parent_access(parent)
qs = self.request.user.get_queryset(self.model).distinct()
sublist_qs = getattrd(parent, self.relationship).distinct()
sublist_qs = self.get_sublist_queryset(parent)
return qs & sublist_qs
def get_sublist_queryset(self, parent):
return getattrd(parent, self.relationship).distinct()
class DestroyAPIView(generics.DestroyAPIView):
@@ -882,6 +889,21 @@ class CopyAPIView(GenericAPIView):
create_kwargs[field.name] = CopyAPIView._decrypt_model_field_if_needed(
obj, field.name, field_val
)
# WorkflowJobTemplateNodes that represent an approval are *special*;
# when we copy them, we actually want to *copy* the UJT they point at
# rather than share the template reference between nodes in disparate
# workflows
if (
isinstance(obj, WorkflowJobTemplateNode) and
isinstance(getattr(obj, 'unified_job_template'), WorkflowApprovalTemplate)
):
new_approval_template, sub_objs = CopyAPIView.copy_model_obj(
None, None, WorkflowApprovalTemplate,
obj.unified_job_template, creater
)
create_kwargs['unified_job_template'] = new_approval_template
new_obj = model.objects.create(**create_kwargs)
logger.debug('Deep copy: Created new object {}({})'.format(
new_obj, model

View File

@@ -5,6 +5,8 @@ from collections import OrderedDict
# Django
from django.core.exceptions import PermissionDenied
from django.db.models.fields import PositiveIntegerField, BooleanField
from django.db.models.fields.related import ForeignKey
from django.http import Http404
from django.utils.encoding import force_text, smart_text
from django.utils.translation import ugettext_lazy as _
@@ -14,10 +16,13 @@ from rest_framework import exceptions
from rest_framework import metadata
from rest_framework import serializers
from rest_framework.relations import RelatedField, ManyRelatedField
from rest_framework.fields import JSONField as DRFJSONField
from rest_framework.request import clone_request
# AWX
from awx.main.fields import JSONField, ImplicitRoleField
from awx.main.models import InventorySource, NotificationTemplate
from awx.main.scheduler.kubernetes import PodManager
class Metadata(metadata.SimpleMetadata):
@@ -68,6 +73,8 @@ class Metadata(metadata.SimpleMetadata):
else:
for model_field in serializer.Meta.model._meta.fields:
if field.field_name == model_field.name:
if getattr(model_field, '__accepts_json__', None):
field_info['type'] = 'json'
field_info['filterable'] = True
break
else:
@@ -114,15 +121,48 @@ class Metadata(metadata.SimpleMetadata):
for (notification_type_name, notification_tr_name, notification_type_class) in NotificationTemplate.NOTIFICATION_TYPES:
field_info[notification_type_name] = notification_type_class.init_parameters
# Special handling of notification messages where the required properties
# are conditional on the type selected.
try:
view_model = field.context['view'].model
except (AttributeError, KeyError):
view_model = None
if view_model == NotificationTemplate and field.field_name == 'messages':
for (notification_type_name, notification_tr_name, notification_type_class) in NotificationTemplate.NOTIFICATION_TYPES:
field_info[notification_type_name] = notification_type_class.default_messages
# Update type of fields returned...
model_field = None
if serializer and hasattr(serializer, 'Meta') and hasattr(serializer.Meta, 'model'):
try:
model_field = serializer.Meta.model._meta.get_field(field.field_name)
except Exception:
pass
if field.field_name == 'type':
field_info['type'] = 'choice'
elif field.field_name == 'url':
elif field.field_name in ('url', 'custom_virtualenv', 'token'):
field_info['type'] = 'string'
elif field.field_name in ('related', 'summary_fields'):
field_info['type'] = 'object'
elif isinstance(field, PositiveIntegerField):
field_info['type'] = 'integer'
elif field.field_name in ('created', 'modified'):
field_info['type'] = 'datetime'
elif (
RelatedField in field.__class__.__bases__ or
isinstance(model_field, ForeignKey)
):
field_info['type'] = 'id'
elif (
isinstance(field, JSONField) or
isinstance(model_field, JSONField) or
isinstance(field, DRFJSONField) or
isinstance(getattr(field, 'model_field', None), JSONField)
):
field_info['type'] = 'json'
elif isinstance(model_field, BooleanField):
field_info['type'] = 'boolean'
return field_info
@@ -161,6 +201,9 @@ class Metadata(metadata.SimpleMetadata):
if not isinstance(meta, dict):
continue
if field == "pod_spec_override":
meta['default'] = PodManager().pod_definition
# Add type choices if available from the serializer.
if field == 'type' and hasattr(serializer, 'get_type_choices'):
meta['choices'] = serializer.get_type_choices()
@@ -213,6 +256,16 @@ class Metadata(metadata.SimpleMetadata):
if getattr(view, 'related_search_fields', None):
metadata['related_search_fields'] = view.related_search_fields
# include role names in metadata
roles = []
model = getattr(view, 'model', None)
if model:
for field in model._meta.get_fields():
if type(field) is ImplicitRoleField:
roles.append(field.name)
if len(roles) > 0:
metadata['object_roles'] = roles
from rest_framework import generics
if isinstance(view, generics.ListAPIView) and hasattr(view, 'paginator'):
metadata['max_page_size'] = view.paginator.max_page_size

View File

@@ -3,14 +3,28 @@
# Django REST Framework
from django.conf import settings
from django.core.paginator import Paginator as DjangoPaginator
from rest_framework import pagination
from rest_framework.response import Response
from rest_framework.utils.urls import replace_query_param
class DisabledPaginator(DjangoPaginator):
@property
def num_pages(self):
return 1
@property
def count(self):
return 200
class Pagination(pagination.PageNumberPagination):
page_size_query_param = 'page_size'
max_page_size = settings.MAX_PAGE_SIZE
count_disabled = False
def get_next_link(self):
if not self.page.has_next():
@@ -39,3 +53,17 @@ class Pagination(pagination.PageNumberPagination):
for pl in context['page_links']]
return context
def paginate_queryset(self, queryset, request, **kwargs):
self.count_disabled = 'count_disabled' in request.query_params
try:
if self.count_disabled:
self.django_paginator_class = DisabledPaginator
return super(Pagination, self).paginate_queryset(queryset, request, **kwargs)
finally:
self.django_paginator_class = DjangoPaginator
def get_paginated_response(self, data):
if self.count_disabled:
return Response({'results': data})
return super(Pagination, self).get_paginated_response(data)

View File

@@ -17,7 +17,7 @@ logger = logging.getLogger('awx.api.permissions')
__all__ = ['ModelAccessPermission', 'JobTemplateCallbackPermission', 'VariableDataPermission',
'TaskPermission', 'ProjectUpdatePermission', 'InventoryInventorySourcesUpdatePermission',
'UserPermission', 'IsSuperUser', 'InstanceGroupTowerPermission',]
'UserPermission', 'IsSuperUser', 'InstanceGroupTowerPermission', 'WorkflowApprovalPermission']
class ModelAccessPermission(permissions.BasePermission):
@@ -95,7 +95,7 @@ class ModelAccessPermission(permissions.BasePermission):
'''
# Don't allow anonymous users. 401, not 403, hence no raised exception.
if not request.user or request.user.is_anonymous():
if not request.user or request.user.is_anonymous:
return False
# Always allow superusers
@@ -196,6 +196,17 @@ class TaskPermission(ModelAccessPermission):
return False
class WorkflowApprovalPermission(ModelAccessPermission):
'''
Permission check used by workflow `approval` and `deny` views to determine
who has access to approve and deny paused workflow nodes
'''
def check_post_permissions(self, request, view, obj=None):
approval = get_object_or_400(view.model, pk=view.kwargs['pk'])
return check_user_access(request.user, view.model, 'approve_or_deny', approval)
class ProjectUpdatePermission(ModelAccessPermission):
'''
Permission check used by ProjectUpdateView to determine who can update projects
@@ -239,3 +250,7 @@ class InstanceGroupTowerPermission(ModelAccessPermission):
return False
return super(InstanceGroupTowerPermission, self).has_object_permission(request, view, obj)
class WebhookKeyPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return request.user.can_access(view.model, 'admin', obj, request.data)

View File

@@ -2,6 +2,7 @@
# All Rights Reserved.
from django.utils.safestring import SafeText
from prometheus_client.parser import text_string_to_metric_families
# Django REST Framework
from rest_framework import renderers
@@ -103,3 +104,21 @@ class AnsiTextRenderer(PlainTextRenderer):
class AnsiDownloadRenderer(PlainTextRenderer):
format = "ansi_download"
class PrometheusJSONRenderer(renderers.JSONRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
if isinstance(data, dict):
# HTTP errors are {'detail': ErrorDetail(string='...', code=...)}
return super(PrometheusJSONRenderer, self).render(
data, accepted_media_type, renderer_context
)
parsed_metrics = text_string_to_metric_families(data)
data = {}
for family in parsed_metrics:
for sample in family.samples:
data[sample[0]] = {"labels": sample[1], "value": sample[2]}
return super(PrometheusJSONRenderer, self).render(
data, accepted_media_type, renderer_context
)

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{% ifmeth GET %}
# List Roles for a Team:
{% ifmeth GET %}
Make a GET request to this resource to retrieve a list of roles associated with the selected team.
{% include "api/_list_common.md" %}

View File

@@ -1,6 +1,6 @@
{% ifmeth GET %}
# List Roles for a User:
{% ifmeth GET %}
Make a GET request to this resource to retrieve a list of roles associated with the selected user.
{% include "api/_list_common.md" %}

View File

@@ -0,0 +1,12 @@
Webhook Secret Key:
Make a GET request to this resource to obtain the secret key for a job
template or workflow job template configured to be triggered by
webhook events. The response will include the following fields:
* `webhook_key`: Secret key that needs to be copied and added to the
webhook configuration of the service this template will be receiving
webhook events from (string, read-only)
Make an empty POST request to this resource to generate a new
replacement `webhook_key`.

View File

@@ -1,7 +1,7 @@
# Copyright (c) 2017 Ansible, Inc.
# All Rights Reserved.
from django.conf.urls import url
from django.conf.urls import include, url
from awx.api.views import (
JobTemplateList,
@@ -45,6 +45,7 @@ urls = [
url(r'^(?P<pk>[0-9]+)/object_roles/$', JobTemplateObjectRolesList.as_view(), name='job_template_object_roles_list'),
url(r'^(?P<pk>[0-9]+)/labels/$', JobTemplateLabelList.as_view(), name='job_template_label_list'),
url(r'^(?P<pk>[0-9]+)/copy/$', JobTemplateCopy.as_view(), name='job_template_copy'),
url(r'^(?P<pk>[0-9]+)/', include('awx.api.urls.webhooks'), {'model_kwarg': 'job_templates'}),
]
__all__ = ['urls']

View File

@@ -18,6 +18,7 @@ from awx.api.views import (
OrganizationNotificationTemplatesErrorList,
OrganizationNotificationTemplatesStartedList,
OrganizationNotificationTemplatesSuccessList,
OrganizationNotificationTemplatesApprovalList,
OrganizationInstanceGroupsList,
OrganizationObjectRolesList,
OrganizationAccessList,
@@ -43,6 +44,8 @@ urls = [
name='organization_notification_templates_error_list'),
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', OrganizationNotificationTemplatesSuccessList.as_view(),
name='organization_notification_templates_success_list'),
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]+)/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'),

View File

@@ -14,6 +14,7 @@ from awx.api.views import (
ApiV2RootView,
ApiV2PingView,
ApiV2ConfigView,
ApiV2SubscriptionView,
AuthView,
UserMeList,
DashboardView,
@@ -71,6 +72,8 @@ from .instance import urls as instance_urls
from .instance_group import urls as instance_group_urls
from .oauth2 import urls as oauth2_urls
from .oauth2_root import urls as oauth2_root_urls
from .workflow_approval_template import urls as workflow_approval_template_urls
from .workflow_approval import urls as workflow_approval_urls
v2_urls = [
@@ -92,6 +95,7 @@ v2_urls = [
url(r'^metrics/$', MetricsView.as_view(), name='metrics_view'),
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'^auth/$', AuthView.as_view()),
url(r'^me/$', UserMeList.as_view(), name='user_me_list'),
url(r'^dashboard/$', DashboardView.as_view(), name='dashboard_view'),
@@ -131,8 +135,11 @@ v2_urls = [
url(r'^unified_job_templates/$', UnifiedJobTemplateList.as_view(), name='unified_job_template_list'),
url(r'^unified_jobs/$', UnifiedJobList.as_view(), name='unified_job_list'),
url(r'^activity_stream/', include(activity_stream_urls)),
url(r'^workflow_approval_templates/', include(workflow_approval_template_urls)),
url(r'^workflow_approvals/', include(workflow_approval_urls)),
]
app_name = 'api'
urlpatterns = [
url(r'^$', ApiRootView.as_view(), name='api_root_view'),

14
awx/api/urls/webhooks.py Normal file
View File

@@ -0,0 +1,14 @@
from django.conf.urls import url
from awx.api.views import (
WebhookKeyView,
GithubWebhookReceiver,
GitlabWebhookReceiver,
)
urlpatterns = [
url(r'^webhook_key/$', WebhookKeyView.as_view(), name='webhook_key'),
url(r'^github/$', GithubWebhookReceiver.as_view(), name='webhook_receiver_github'),
url(r'^gitlab/$', GitlabWebhookReceiver.as_view(), name='webhook_receiver_gitlab'),
]

View File

@@ -0,0 +1,21 @@
# Copyright (c) 2017 Ansible, Inc.
# All Rights Reserved.
from django.conf.urls import url
from awx.api.views import (
WorkflowApprovalList,
WorkflowApprovalDetail,
WorkflowApprovalApprove,
WorkflowApprovalDeny,
)
urls = [
url(r'^$', WorkflowApprovalList.as_view(), name='workflow_approval_list'),
url(r'^(?P<pk>[0-9]+)/$', WorkflowApprovalDetail.as_view(), name='workflow_approval_detail'),
url(r'^(?P<pk>[0-9]+)/approve/$', WorkflowApprovalApprove.as_view(), name='workflow_approval_approve'),
url(r'^(?P<pk>[0-9]+)/deny/$', WorkflowApprovalDeny.as_view(), name='workflow_approval_deny'),
]
__all__ = ['urls']

View File

@@ -0,0 +1,17 @@
# Copyright (c) 2017 Ansible, Inc.
# All Rights Reserved.
from django.conf.urls import url
from awx.api.views import (
WorkflowApprovalTemplateDetail,
WorkflowApprovalTemplateJobsList,
)
urls = [
url(r'^(?P<pk>[0-9]+)/$', WorkflowApprovalTemplateDetail.as_view(), name='workflow_approval_template_detail'),
url(r'^(?P<pk>[0-9]+)/approvals/$', WorkflowApprovalTemplateJobsList.as_view(), name='workflow_approval_template_jobs_list'),
]
__all__ = ['urls']

View File

@@ -1,7 +1,7 @@
# Copyright (c) 2017 Ansible, Inc.
# All Rights Reserved.
from django.conf.urls import url
from django.conf.urls import include, url
from awx.api.views import (
WorkflowJobTemplateList,
@@ -16,6 +16,7 @@ from awx.api.views import (
WorkflowJobTemplateNotificationTemplatesErrorList,
WorkflowJobTemplateNotificationTemplatesStartedList,
WorkflowJobTemplateNotificationTemplatesSuccessList,
WorkflowJobTemplateNotificationTemplatesApprovalList,
WorkflowJobTemplateAccessList,
WorkflowJobTemplateObjectRolesList,
WorkflowJobTemplateLabelList,
@@ -38,9 +39,12 @@ urls = [
name='workflow_job_template_notification_templates_error_list'),
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', WorkflowJobTemplateNotificationTemplatesSuccessList.as_view(),
name='workflow_job_template_notification_templates_success_list'),
url(r'^(?P<pk>[0-9]+)/notification_templates_approvals/$', WorkflowJobTemplateNotificationTemplatesApprovalList.as_view(),
name='workflow_job_template_notification_templates_approvals_list'),
url(r'^(?P<pk>[0-9]+)/access_list/$', WorkflowJobTemplateAccessList.as_view(), name='workflow_job_template_access_list'),
url(r'^(?P<pk>[0-9]+)/object_roles/$', WorkflowJobTemplateObjectRolesList.as_view(), name='workflow_job_template_object_roles_list'),
url(r'^(?P<pk>[0-9]+)/labels/$', WorkflowJobTemplateLabelList.as_view(), name='workflow_job_template_label_list'),
url(r'^(?P<pk>[0-9]+)/', include('awx.api.urls.webhooks'), {'model_kwarg': 'workflow_job_templates'}),
]
__all__ = ['urls']

View File

@@ -10,6 +10,7 @@ from awx.api.views import (
WorkflowJobTemplateNodeFailureNodesList,
WorkflowJobTemplateNodeAlwaysNodesList,
WorkflowJobTemplateNodeCredentialsList,
WorkflowJobTemplateNodeCreateApproval,
)
@@ -20,6 +21,7 @@ urls = [
url(r'^(?P<pk>[0-9]+)/failure_nodes/$', WorkflowJobTemplateNodeFailureNodesList.as_view(), name='workflow_job_template_node_failure_nodes_list'),
url(r'^(?P<pk>[0-9]+)/always_nodes/$', WorkflowJobTemplateNodeAlwaysNodesList.as_view(), name='workflow_job_template_node_always_nodes_list'),
url(r'^(?P<pk>[0-9]+)/credentials/$', WorkflowJobTemplateNodeCredentialsList.as_view(), name='workflow_job_template_node_credentials_list'),
url(r'^(?P<pk>[0-9]+)/create_approval_template/$', WorkflowJobTemplateNodeCreateApproval.as_view(), name='workflow_job_template_node_create_approval'),
]
__all__ = ['urls']

View File

@@ -91,7 +91,8 @@ from awx.main.redact import UriCleaner
from awx.api.permissions import (
JobTemplateCallbackPermission, TaskPermission, ProjectUpdatePermission,
InventoryInventorySourcesUpdatePermission, UserPermission,
InstanceGroupTowerPermission, VariableDataPermission
InstanceGroupTowerPermission, VariableDataPermission,
WorkflowApprovalPermission
)
from awx.api import renderers
from awx.api import serializers
@@ -118,6 +119,7 @@ from awx.api.views.organization import ( # noqa
OrganizationNotificationTemplatesErrorList,
OrganizationNotificationTemplatesStartedList,
OrganizationNotificationTemplatesSuccessList,
OrganizationNotificationTemplatesApprovalList,
OrganizationInstanceGroupsList,
OrganizationAccessList,
OrganizationObjectRolesList,
@@ -146,6 +148,12 @@ from awx.api.views.root import ( # noqa
ApiV2RootView,
ApiV2PingView,
ApiV2ConfigView,
ApiV2SubscriptionView,
)
from awx.api.views.webhooks import ( # noqa
WebhookKeyView,
GithubWebhookReceiver,
GitlabWebhookReceiver,
)
@@ -244,13 +252,6 @@ class DashboardView(APIView):
'total': hg_projects.count(),
'failed': hg_failed_projects.count()}
user_jobs = get_user_queryset(request.user, models.Job)
user_failed_jobs = user_jobs.filter(failed=True)
data['jobs'] = {'url': reverse('api:job_list', request=request),
'failure_url': reverse('api:job_list', request=request) + "?failed=True",
'total': user_jobs.count(),
'failed': user_failed_jobs.count()}
user_list = get_user_queryset(request.user, models.User)
team_list = get_user_queryset(request.user, models.Team)
credential_list = get_user_queryset(request.user, models.Credential)
@@ -839,8 +840,6 @@ class SystemJobEventsList(SubListAPIView):
return super(SystemJobEventsList, self).finalize_response(request, response, *args, **kwargs)
class ProjectUpdateCancel(RetrieveAPIView):
model = models.ProjectUpdate
@@ -2569,10 +2568,34 @@ class JobTemplateSurveySpec(GenericAPIView):
return Response(dict(error=_(
"The {min_or_max} limit in survey question {idx} expected to be integer."
).format(min_or_max=key, **context)))
if qtype in ['multiplechoice', 'multiselect'] and 'choices' not in survey_item:
return Response(dict(error=_(
"Survey question {idx} of type {survey_item[type]} must specify choices.".format(**context)
)))
# if it's a multiselect or multiple choice, it must have coices listed
# choices and defualts must come in as strings seperated by /n characters.
if qtype == 'multiselect' or qtype == 'multiplechoice':
if 'choices' in survey_item:
if isinstance(survey_item['choices'], str):
survey_item['choices'] = '\n'.join(choice for choice in survey_item['choices'].splitlines() if choice.strip() != '')
else:
return Response(dict(error=_(
"Survey question {idx} of type {survey_item[type]} must specify choices.".format(**context)
)))
# If there is a default string split it out removing extra /n characters.
# Note: There can still be extra newline characters added in the API, these are sanitized out using .strip()
if 'default' in survey_item:
if isinstance(survey_item['default'], str):
survey_item['default'] = '\n'.join(choice for choice in survey_item['default'].splitlines() if choice.strip() != '')
list_of_defaults = survey_item['default'].splitlines()
else:
list_of_defaults = survey_item['default']
if qtype == 'multiplechoice':
# Multiplechoice types should only have 1 default.
if len(list_of_defaults) > 1:
return Response(dict(error=_(
"Multiple Choice (Single Select) can only have one default value.".format(**context)
)))
if any(item not in survey_item['choices'] for item in list_of_defaults):
return Response(dict(error=_(
"Default choice must be answered from the choices listed.".format(**context)
)))
# Process encryption substitution
if ("default" in survey_item and isinstance(survey_item['default'], str) and
@@ -2997,7 +3020,7 @@ class WorkflowJobTemplateNodeChildrenBaseList(EnforceParentRelationshipMixin, Su
relationships = ['success_nodes', 'failure_nodes', 'always_nodes']
relationships.remove(self.relationship)
qs = functools.reduce(lambda x, y: (x | y),
(Q(**{'{}__in'.format(rel): [sub.id]}) for rel in relationships))
(Q(**{'{}__in'.format(r): [sub.id]}) for r in relationships))
if models.WorkflowJobTemplateNode.objects.filter(Q(pk=parent.id) & qs).exists():
return {"Error": _("Relationship not allowed.")}
@@ -3013,6 +3036,34 @@ class WorkflowJobTemplateNodeChildrenBaseList(EnforceParentRelationshipMixin, Su
return None
class WorkflowJobTemplateNodeCreateApproval(RetrieveAPIView):
model = models.WorkflowJobTemplateNode
serializer_class = serializers.WorkflowJobTemplateNodeCreateApprovalSerializer
permission_classes = []
def post(self, request, *args, **kwargs):
obj = self.get_object()
serializer = self.get_serializer(instance=obj, data=request.data)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
approval_template = obj.create_approval_template(**serializer.validated_data)
data = serializers.WorkflowApprovalTemplateSerializer(
approval_template,
context=self.get_serializer_context()
).data
return Response(data, status=status.HTTP_200_OK)
def check_permissions(self, request):
obj = self.get_object().workflow_job_template
if request.method == 'POST':
if not request.user.can_access(models.WorkflowJobTemplate, 'change', obj, request.data):
self.permission_denied(request)
else:
if not request.user.can_access(models.WorkflowJobTemplate, 'read', obj):
self.permission_denied(request)
class WorkflowJobTemplateNodeSuccessNodesList(WorkflowJobTemplateNodeChildrenBaseList):
relationship = 'success_nodes'
@@ -3090,6 +3141,17 @@ class WorkflowJobTemplateCopy(CopyAPIView):
data.update(messages)
return Response(data)
def _build_create_dict(self, obj):
"""Special processing of fields managed by char_prompts
"""
r = super(WorkflowJobTemplateCopy, self)._build_create_dict(obj)
field_names = set(f.name for f in obj._meta.get_fields())
for field_name, ask_field_name in obj.get_ask_mapping().items():
if field_name in r and field_name not in field_names:
r.setdefault('char_prompts', {})
r['char_prompts'][field_name] = r.pop(field_name)
return r
@staticmethod
def deep_copy_permission_check_func(user, new_objs):
for obj in new_objs:
@@ -3118,7 +3180,6 @@ class WorkflowJobTemplateLabelList(JobTemplateLabelList):
class WorkflowJobTemplateLaunch(RetrieveAPIView):
model = models.WorkflowJobTemplate
obj_permission_type = 'start'
serializer_class = serializers.WorkflowJobLaunchSerializer
@@ -3135,10 +3196,15 @@ class WorkflowJobTemplateLaunch(RetrieveAPIView):
extra_vars.setdefault(v, u'')
if extra_vars:
data['extra_vars'] = extra_vars
if obj.ask_inventory_on_launch:
data['inventory'] = obj.inventory_id
else:
data.pop('inventory', None)
modified_ask_mapping = models.WorkflowJobTemplate.get_ask_mapping()
modified_ask_mapping.pop('extra_vars')
for field_name, ask_field_name in obj.get_ask_mapping().items():
if not getattr(obj, ask_field_name):
data.pop(field_name, None)
elif field_name == 'inventory':
data[field_name] = getattrd(obj, "%s.%s" % (field_name, 'id'), None)
else:
data[field_name] = getattr(obj, field_name)
return data
def post(self, request, *args, **kwargs):
@@ -3252,6 +3318,11 @@ class WorkflowJobTemplateNotificationTemplatesSuccessList(WorkflowJobTemplateNot
relationship = 'notification_templates_success'
class WorkflowJobTemplateNotificationTemplatesApprovalList(WorkflowJobTemplateNotificationTemplatesAnyList):
relationship = 'notification_templates_approvals'
class WorkflowJobTemplateAccessList(ResourceAccessList):
model = models.User # needs to be User for AccessLists's
@@ -3287,7 +3358,7 @@ class WorkflowJobTemplateActivityStreamList(SubListAPIView):
Q(workflow_job_template_node__workflow_job_template=parent)).distinct()
class WorkflowJobList(ListCreateAPIView):
class WorkflowJobList(ListAPIView):
model = models.WorkflowJob
serializer_class = serializers.WorkflowJobListSerializer
@@ -3337,6 +3408,11 @@ class WorkflowJobNotificationsList(SubListAPIView):
relationship = 'notifications'
search_fields = ('subject', 'notification_type', 'body',)
def get_sublist_queryset(self, parent):
return self.model.objects.filter(Q(unifiedjob_notifications=parent) |
Q(unifiedjob_notifications__unified_job_node__workflow_job=parent,
unifiedjob_notifications__workflowapproval__isnull=False)).distinct()
class WorkflowJobActivityStreamList(SubListAPIView):
@@ -3692,12 +3768,23 @@ class JobEventList(ListAPIView):
serializer_class = serializers.JobEventSerializer
search_fields = ('stdout',)
def get_serializer_context(self):
context = super().get_serializer_context()
if self.request.query_params.get('no_truncate'):
context.update(no_truncate=True)
return context
class JobEventDetail(RetrieveAPIView):
model = models.JobEvent
serializer_class = serializers.JobEventSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context.update(no_truncate=True)
return context
class JobEventChildrenList(SubListAPIView):
@@ -3926,12 +4013,23 @@ class AdHocCommandEventList(ListAPIView):
serializer_class = serializers.AdHocCommandEventSerializer
search_fields = ('stdout',)
def get_serializer_context(self):
context = super().get_serializer_context()
if self.request.query_params.get('no_truncate'):
context.update(no_truncate=True)
return context
class AdHocCommandEventDetail(RetrieveAPIView):
model = models.AdHocCommandEvent
serializer_class = serializers.AdHocCommandEventSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context.update(no_truncate=True)
return context
class BaseAdHocCommandEventsList(SubListAPIView):
@@ -3975,7 +4073,7 @@ class AdHocCommandNotificationsList(SubListAPIView):
search_fields = ('subject', 'notification_type', 'body',)
class SystemJobList(ListCreateAPIView):
class SystemJobList(ListAPIView):
model = models.SystemJob
serializer_class = serializers.SystemJobListSerializer
@@ -4405,3 +4503,63 @@ for attr, value in list(locals().items()):
name = camelcase_to_underscore(attr)
view = value.as_view()
setattr(this_module, name, view)
class WorkflowApprovalTemplateDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPIView):
model = models.WorkflowApprovalTemplate
serializer_class = serializers.WorkflowApprovalTemplateSerializer
class WorkflowApprovalTemplateJobsList(SubListAPIView):
model = models.WorkflowApproval
serializer_class = serializers.WorkflowApprovalListSerializer
parent_model = models.WorkflowApprovalTemplate
relationship = 'approvals'
parent_key = 'workflow_approval_template'
class WorkflowApprovalList(ListCreateAPIView):
model = models.WorkflowApproval
serializer_class = serializers.WorkflowApprovalListSerializer
def get(self, request, *args, **kwargs):
return super(WorkflowApprovalList, self).get(request, *args, **kwargs)
class WorkflowApprovalDetail(UnifiedJobDeletionMixin, RetrieveDestroyAPIView):
model = models.WorkflowApproval
serializer_class = serializers.WorkflowApprovalSerializer
class WorkflowApprovalApprove(RetrieveAPIView):
model = models.WorkflowApproval
serializer_class = serializers.WorkflowApprovalViewSerializer
permission_classes = (WorkflowApprovalPermission,)
def post(self, request, *args, **kwargs):
obj = self.get_object()
if not request.user.can_access(models.WorkflowApproval, 'approve_or_deny', obj):
raise PermissionDenied(detail=_("User does not have permission to approve or deny this workflow."))
if obj.status != 'pending':
return Response({"error": _("This workflow step has already been approved or denied.")}, status=status.HTTP_400_BAD_REQUEST)
obj.approve(request)
return Response(status=status.HTTP_204_NO_CONTENT)
class WorkflowApprovalDeny(RetrieveAPIView):
model = models.WorkflowApproval
serializer_class = serializers.WorkflowApprovalViewSerializer
permission_classes = (WorkflowApprovalPermission,)
def post(self, request, *args, **kwargs):
obj = self.get_object()
if not request.user.can_access(models.WorkflowApproval, 'approve_or_deny', obj):
raise PermissionDenied(detail=_("User does not have permission to approve or deny this workflow."))
if obj.status != 'pending':
return Response({"error": _("This workflow step has already been approved or denied.")}, status=status.HTTP_400_BAD_REQUEST)
obj.deny(request)
return Response(status=status.HTTP_204_NO_CONTENT)

View File

@@ -70,12 +70,16 @@ class InventoryUpdateEventsList(SubListAPIView):
class InventoryScriptList(ListCreateAPIView):
deprecated = True
model = CustomInventoryScript
serializer_class = CustomInventoryScriptSerializer
class InventoryScriptDetail(RetrieveUpdateDestroyAPIView):
deprecated = True
model = CustomInventoryScript
serializer_class = CustomInventoryScriptSerializer
@@ -92,6 +96,8 @@ class InventoryScriptDetail(RetrieveUpdateDestroyAPIView):
class InventoryScriptObjectRolesList(SubListAPIView):
deprecated = True
model = Role
serializer_class = RoleSerializer
parent_model = CustomInventoryScript
@@ -105,6 +111,8 @@ class InventoryScriptObjectRolesList(SubListAPIView):
class InventoryScriptCopy(CopyAPIView):
deprecated = True
model = CustomInventoryScript
copy_return_serializer_class = CustomInventoryScriptSerializer

View File

@@ -31,9 +31,10 @@ class MetricsView(APIView):
swagger_topic = 'Metrics'
renderer_classes = [renderers.PlainTextRenderer,
renderers.PrometheusJSONRenderer,
renderers.BrowsableAPIRenderer,]
def get(self, request, format='txt'):
def get(self, request):
''' Show Metrics Details '''
if (request.user.is_superuser or request.user.is_system_auditor):
return Response(metrics().decode('UTF-8'))

View File

@@ -195,6 +195,11 @@ class OrganizationNotificationTemplatesSuccessList(OrganizationNotificationTempl
relationship = 'notification_templates_success'
class OrganizationNotificationTemplatesApprovalList(OrganizationNotificationTemplatesAnyList):
relationship = 'notification_templates_approvals'
class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
model = InstanceGroup

View File

@@ -17,6 +17,8 @@ from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
import requests
from awx.api.generics import APIView
from awx.main.ha import is_ha_environment
from awx.main.utils import (
@@ -124,6 +126,7 @@ class ApiVersionRootView(APIView):
data['activity_stream'] = reverse('api:activity_stream_list', request=request)
data['workflow_job_templates'] = reverse('api:workflow_job_template_list', request=request)
data['workflow_jobs'] = reverse('api:workflow_job_list', request=request)
data['workflow_approvals'] = reverse('api:workflow_approval_list', request=request)
data['workflow_job_template_nodes'] = reverse('api:workflow_job_template_node_list', request=request)
data['workflow_job_nodes'] = reverse('api:workflow_job_node_list', request=request)
return Response(data)
@@ -168,6 +171,45 @@ class ApiV2PingView(APIView):
return Response(response)
class ApiV2SubscriptionView(APIView):
permission_classes = (IsAuthenticated,)
name = _('Configuration')
swagger_topic = 'System Configuration'
def check_permissions(self, request):
super(ApiV2SubscriptionView, 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):
from awx.main.utils.common import get_licenser
data = request.data.copy()
if data.get('rh_password') == '$encrypted$':
data['rh_password'] = settings.REDHAT_PASSWORD
try:
user, pw = data.get('rh_username'), data.get('rh_password')
validated = get_licenser().validate_rh(user, pw)
if user:
settings.REDHAT_USERNAME = data['rh_username']
if pw:
settings.REDHAT_PASSWORD = data['rh_password']
except Exception as exc:
msg = _("Invalid License")
if (
isinstance(exc, requests.exceptions.HTTPError) and
getattr(getattr(exc, 'response', None), 'status_code', None) == 401
):
msg = _("The provided credentials are invalid (HTTP 401).")
if isinstance(exc, (ValueError, OSError)) and exc.args:
msg = exc.args[0]
logger.exception(smart_text(u"Invalid license submitted."),
extra=dict(actor=request.user.username))
return Response({"error": msg}, status=status.HTTP_400_BAD_REQUEST)
return Response(validated)
class ApiV2ConfigView(APIView):
permission_classes = (IsAuthenticated,)

247
awx/api/views/webhooks.py Normal file
View File

@@ -0,0 +1,247 @@
from hashlib import sha1
import hmac
import json
import logging
import urllib.parse
from django.utils.encoding import force_bytes
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from awx.api import serializers
from awx.api.generics import APIView, GenericAPIView
from awx.api.permissions import WebhookKeyPermission
from awx.main.models import Job, JobTemplate, WorkflowJob, WorkflowJobTemplate
logger = logging.getLogger('awx.api.views.webhooks')
class WebhookKeyView(GenericAPIView):
serializer_class = serializers.EmptySerializer
permission_classes = (WebhookKeyPermission,)
def get_queryset(self):
qs_models = {
'job_templates': JobTemplate,
'workflow_job_templates': WorkflowJobTemplate,
}
self.model = qs_models.get(self.kwargs['model_kwarg'])
return super().get_queryset()
def get(self, request, *args, **kwargs):
obj = self.get_object()
return Response({'webhook_key': obj.webhook_key})
def post(self, request, *args, **kwargs):
obj = self.get_object()
obj.rotate_webhook_key()
obj.save(update_fields=['webhook_key'])
return Response({'webhook_key': obj.webhook_key}, status=status.HTTP_201_CREATED)
class WebhookReceiverBase(APIView):
lookup_url_kwarg = None
lookup_field = 'pk'
permission_classes = (AllowAny,)
authentication_classes = ()
ref_keys = {}
def get_queryset(self):
qs_models = {
'job_templates': JobTemplate,
'workflow_job_templates': WorkflowJobTemplate,
}
model = qs_models.get(self.kwargs['model_kwarg'])
if model is None:
raise PermissionDenied
return model.objects.filter(webhook_service=self.service).exclude(webhook_key='')
def get_object(self):
queryset = self.get_queryset()
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = queryset.filter(**filter_kwargs).first()
if obj is None:
raise PermissionDenied
return obj
def get_event_type(self):
raise NotImplementedError
def get_event_guid(self):
raise NotImplementedError
def get_event_status_api(self):
raise NotImplementedError
def get_event_ref(self):
key = self.ref_keys.get(self.get_event_type(), '')
value = self.request.data
for element in key.split('.'):
try:
if element.isdigit():
value = value[int(element)]
else:
value = (value or {}).get(element)
except Exception:
value = None
if value == '0000000000000000000000000000000000000000': # a deleted ref
value = None
return value
def get_signature(self):
raise NotImplementedError
def check_signature(self, obj):
if not obj.webhook_key:
raise PermissionDenied
mac = hmac.new(force_bytes(obj.webhook_key), msg=force_bytes(self.request.body), digestmod=sha1)
logger.debug("header signature: %s", self.get_signature())
logger.debug("calculated signature: %s", force_bytes(mac.hexdigest()))
if not hmac.compare_digest(force_bytes(mac.hexdigest()), self.get_signature()):
raise PermissionDenied
@csrf_exempt
def post(self, request, *args, **kwargs):
# Ensure that the full contents of the request are captured for multiple uses.
request.body
logger.debug(
"headers: {}\n"
"data: {}\n".format(request.headers, request.data)
)
obj = self.get_object()
self.check_signature(obj)
event_type = self.get_event_type()
event_guid = self.get_event_guid()
event_ref = self.get_event_ref()
status_api = self.get_event_status_api()
kwargs = {
'unified_job_template_id': obj.id,
'webhook_service': obj.webhook_service,
'webhook_guid': event_guid,
}
if WorkflowJob.objects.filter(**kwargs).exists() or Job.objects.filter(**kwargs).exists():
# Short circuit if this webhook has already been received and acted upon.
logger.debug("Webhook previously received, returning without action.")
return Response({'message': _("Webhook previously received, aborting.")},
status=status.HTTP_202_ACCEPTED)
kwargs = {
'_eager_fields': {
'launch_type': 'webhook',
'webhook_service': obj.webhook_service,
'webhook_credential': obj.webhook_credential,
'webhook_guid': event_guid,
},
'extra_vars': json.dumps({
'tower_webhook_event_type': event_type,
'tower_webhook_event_guid': event_guid,
'tower_webhook_event_ref': event_ref,
'tower_webhook_status_api': status_api,
'tower_webhook_payload': request.data,
})
}
new_job = obj.create_unified_job(**kwargs)
new_job.signal_start()
return Response({'message': "Job queued."}, status=status.HTTP_202_ACCEPTED)
class GithubWebhookReceiver(WebhookReceiverBase):
service = 'github'
ref_keys = {
'pull_request': 'pull_request.head.sha',
'pull_request_review': 'pull_request.head.sha',
'pull_request_review_comment': 'pull_request.head.sha',
'push': 'after',
'release': 'release.tag_name',
'commit_comment': 'comment.commit_id',
'create': 'ref',
'page_build': 'build.commit',
}
def get_event_type(self):
return self.request.META.get('HTTP_X_GITHUB_EVENT')
def get_event_guid(self):
return self.request.META.get('HTTP_X_GITHUB_DELIVERY')
def get_event_status_api(self):
if self.get_event_type() != 'pull_request':
return
return self.request.data.get('pull_request', {}).get('statuses_url')
def get_signature(self):
header_sig = self.request.META.get('HTTP_X_HUB_SIGNATURE')
if not header_sig:
logger.debug("Expected signature missing from header key HTTP_X_HUB_SIGNATURE")
raise PermissionDenied
hash_alg, signature = header_sig.split('=')
if hash_alg != 'sha1':
logger.debug("Unsupported signature type, expected: sha1, received: {}".format(hash_alg))
raise PermissionDenied
return force_bytes(signature)
class GitlabWebhookReceiver(WebhookReceiverBase):
service = 'gitlab'
ref_keys = {
'Push Hook': 'checkout_sha',
'Tag Push Hook': 'checkout_sha',
'Merge Request Hook': 'object_attributes.last_commit.id',
}
def get_event_type(self):
return self.request.META.get('HTTP_X_GITLAB_EVENT')
def get_event_guid(self):
# GitLab does not provide a unique identifier on events, so construct one.
h = sha1()
h.update(force_bytes(self.request.body))
return h.hexdigest()
def get_event_status_api(self):
if self.get_event_type() != 'Merge Request Hook':
return
project = self.request.data.get('project', {})
repo_url = project.get('web_url')
if not repo_url:
return
parsed = urllib.parse.urlparse(repo_url)
return "{}://{}/api/v4/projects/{}/statuses/{}".format(
parsed.scheme, parsed.netloc, project['id'], self.get_event_ref())
def get_signature(self):
return force_bytes(self.request.META.get('HTTP_X_GITLAB_TOKEN') or '')
def check_signature(self, obj):
if not obj.webhook_key:
raise PermissionDenied
# GitLab only returns the secret token, not an hmac hash. Use
# the hmac `compare_digest` helper function to prevent timing
# analysis by attackers.
if not hmac.compare_digest(force_bytes(obj.webhook_key), self.get_signature()):
raise PermissionDenied

View File

@@ -10,8 +10,8 @@ from django.utils.translation import ugettext_lazy as _
# Django REST Framework
from rest_framework.fields import ( # noqa
BooleanField, CharField, ChoiceField, DictField, EmailField, IntegerField,
ListField, NullBooleanField
BooleanField, CharField, ChoiceField, DictField, EmailField,
IntegerField, ListField, NullBooleanField
)
logger = logging.getLogger('awx.conf.fields')
@@ -121,11 +121,14 @@ class URLField(CharField):
def __init__(self, **kwargs):
schemes = kwargs.pop('schemes', None)
regex = kwargs.pop('regex', None)
self.allow_plain_hostname = kwargs.pop('allow_plain_hostname', False)
super(URLField, self).__init__(**kwargs)
validator_kwargs = dict(message=_('Enter a valid URL'))
if schemes is not None:
validator_kwargs['schemes'] = schemes
if regex is not None:
validator_kwargs['regex'] = regex
self.validators.append(URLValidator(**validator_kwargs))
def to_representation(self, value):

View File

@@ -21,7 +21,8 @@ class Migration(migrations.Migration):
('modified', models.DateTimeField(default=None, editable=False)),
('key', models.CharField(max_length=255)),
('value', jsonfield.fields.JSONField(null=True)),
('user', models.ForeignKey(related_name='settings', default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('user', models.ForeignKey(related_name='settings', default=None, editable=False,
to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True)),
],
options={
'abstract': False,

View File

@@ -8,6 +8,7 @@ from awx.main.utils.encryption import decrypt_field
from awx.conf import fields
from awx.conf.registry import settings_registry
from awx.conf.models import Setting
from awx.sso import fields as sso_fields
@pytest.fixture
@@ -137,7 +138,7 @@ def test_setting_signleton_retrieve_hierachy(api_request, dummy_setting):
@pytest.mark.django_db
def test_setting_signleton_retrieve_readonly(api_request, dummy_setting):
def test_setting_singleton_retrieve_readonly(api_request, dummy_setting):
with dummy_setting(
'FOO_BAR',
field_class=fields.IntegerField,
@@ -183,6 +184,30 @@ def test_setting_singleton_update(api_request, dummy_setting):
assert response.data['FOO_BAR'] == 4
@pytest.mark.django_db
def test_setting_singleton_update_hybriddictfield_with_forbidden(api_request, dummy_setting):
# Some HybridDictField subclasses have a child of _Forbidden,
# indicating that only the defined fields can be filled in. Make
# sure that the _Forbidden validator doesn't get used for the
# fields. See also https://github.com/ansible/awx/issues/4099.
with dummy_setting(
'FOO_BAR',
field_class=sso_fields.SAMLOrgAttrField,
category='FooBar',
category_slug='foobar',
), mock.patch('awx.conf.views.handle_setting_changes'):
api_request(
'patch',
reverse('api:setting_singleton_detail', kwargs={'category_slug': 'foobar'}),
data={'FOO_BAR': {'saml_admin_attr': 'Admins', 'saml_attr': 'Orgs'}}
)
response = api_request(
'get',
reverse('api:setting_singleton_detail', kwargs={'category_slug': 'foobar'})
)
assert response.data['FOO_BAR'] == {'saml_admin_attr': 'Admins', 'saml_attr': 'Orgs'}
@pytest.mark.django_db
def test_setting_singleton_update_dont_change_readonly_fields(api_request, dummy_setting):
with dummy_setting(
@@ -206,7 +231,7 @@ def test_setting_singleton_update_dont_change_readonly_fields(api_request, dummy
@pytest.mark.django_db
def test_setting_singleton_update_dont_change_encripted_mark(api_request, dummy_setting):
def test_setting_singleton_update_dont_change_encrypted_mark(api_request, dummy_setting):
with dummy_setting(
'FOO_BAR',
field_class=fields.CharField,

View File

@@ -37,6 +37,7 @@ from awx.main.models import (
ProjectUpdateEvent, Role, Schedule, SystemJob, SystemJobEvent,
SystemJobTemplate, Team, UnifiedJob, UnifiedJobTemplate, WorkflowJob,
WorkflowJobNode, WorkflowJobTemplate, WorkflowJobTemplateNode,
WorkflowApproval, WorkflowApprovalTemplate,
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR, ROLE_SINGLETON_SYSTEM_AUDITOR
)
from awx.main.models.mixins import ResourceMixin
@@ -316,10 +317,19 @@ class BaseAccess(object):
validation_info['time_remaining'] = 99999999
validation_info['grace_period_remaining'] = 99999999
report_violation = lambda message: logger.error(message)
if (
validation_info.get('trial', False) is True or
validation_info['instance_count'] == 10 # basic 10 license
):
def report_violation(message):
raise PermissionDenied(message)
if check_expiration and validation_info.get('time_remaining', None) is None:
raise PermissionDenied(_("License is missing."))
if check_expiration and validation_info.get("grace_period_remaining") <= 0:
raise PermissionDenied(_("License has expired."))
elif check_expiration and validation_info.get("grace_period_remaining") <= 0:
report_violation(_("License has expired."))
free_instances = validation_info.get('free_instances', 0)
available_instances = validation_info.get('available_instances', 0)
@@ -327,11 +337,11 @@ class BaseAccess(object):
if add_host_name:
host_exists = Host.objects.filter(name=add_host_name).exists()
if not host_exists and free_instances == 0:
raise PermissionDenied(_("License count of %s instances has been reached.") % available_instances)
report_violation(_("License count of %s instances has been reached.") % available_instances)
elif not host_exists and free_instances < 0:
raise PermissionDenied(_("License count of %s instances has been exceeded.") % available_instances)
report_violation(_("License count of %s instances has been exceeded.") % available_instances)
elif not add_host_name and free_instances < 0:
raise PermissionDenied(_("Host count exceeds available instances."))
report_violation(_("Host count exceeds available instances."))
def check_org_host_limit(self, data, add_host_name=None):
validation_info = get_licenser().validate()
@@ -538,7 +548,7 @@ class InstanceGroupAccess(BaseAccess):
def filtered_queryset(self):
return InstanceGroup.objects.filter(
organization__in=Organization.accessible_pk_qs(self.user, 'admin_role'))
organization__in=Organization.accessible_pk_qs(self.user, 'admin_role')).distinct()
def can_add(self, data):
return self.user.is_superuser
@@ -651,7 +661,7 @@ class UserAccess(BaseAccess):
if obj.is_superuser and super_users.count() == 1:
# cannot delete the last active superuser
return False
if self.user.is_superuser:
if self.can_admin(obj, None, allow_orphans=True):
return True
return False
@@ -833,10 +843,6 @@ class InventoryAccess(BaseAccess):
def filtered_queryset(self, allowed=None, ad_hoc=None):
return self.model.accessible_objects(self.user, 'read_role')
@check_superuser
def can_read(self, obj):
return self.user in obj.read_role
@check_superuser
def can_use(self, obj):
return self.user in obj.use_role
@@ -906,9 +912,6 @@ class HostAccess(BaseAccess):
def filtered_queryset(self):
return self.model.objects.filter(inventory__in=Inventory.accessible_pk_qs(self.user, 'read_role'))
def can_read(self, obj):
return obj and self.user in obj.inventory.read_role
def can_add(self, data):
if not data: # So the browseable API will work
return Inventory.accessible_objects(self.user, 'admin_role').exists()
@@ -970,9 +973,6 @@ class GroupAccess(BaseAccess):
def filtered_queryset(self):
return Group.objects.filter(inventory__in=Inventory.accessible_pk_qs(self.user, 'read_role'))
def can_read(self, obj):
return obj and self.user in obj.inventory.read_role
def can_add(self, data):
if not data or 'inventory' not in data:
return False
@@ -1016,12 +1016,6 @@ class InventorySourceAccess(NotificationAttachMixin, BaseAccess):
def filtered_queryset(self):
return self.model.objects.filter(inventory__in=Inventory.accessible_pk_qs(self.user, 'read_role'))
def can_read(self, obj):
if obj and obj.inventory:
return self.user.can_access(Inventory, 'read', obj.inventory)
else:
return False
def can_add(self, data):
if not data or 'inventory' not in data:
return Organization.accessible_objects(self.user, 'admin_role').exists()
@@ -1114,9 +1108,6 @@ class CredentialTypeAccess(BaseAccess):
model = CredentialType
prefetch_related = ('created_by', 'modified_by',)
def can_read(self, obj):
return True
def can_use(self, obj):
return True
@@ -1158,25 +1149,26 @@ class CredentialAccess(BaseAccess):
def filtered_queryset(self):
return self.model.accessible_objects(self.user, 'read_role')
@check_superuser
def can_read(self, obj):
return self.user in obj.read_role
@check_superuser
def can_add(self, data):
if not data: # So the browseable API will work
return True
if data and data.get('user', None):
user_obj = get_object_from_data('user', User, data)
return bool(self.user == user_obj or UserAccess(self.user).can_admin(user_obj, None, check_setting=False))
if not bool(self.user == user_obj or UserAccess(self.user).can_admin(user_obj, None, check_setting=False)):
return False
if data and data.get('team', None):
team_obj = get_object_from_data('team', Team, data)
return check_user_access(self.user, Team, 'change', team_obj, None)
if not check_user_access(self.user, Team, 'change', team_obj, None):
return False
if data and data.get('organization', None):
organization_obj = get_object_from_data('organization', Organization, data)
return any([check_user_access(self.user, Organization, 'change', organization_obj, None),
self.user in organization_obj.credential_admin_role])
return False
if not any([check_user_access(self.user, Organization, 'change', organization_obj, None),
self.user in organization_obj.credential_admin_role]):
return False
if not any(data.get(key, None) for key in ('user', 'team', 'organization')):
return False # you have to provide 1 owner field
return True
@check_superuser
def can_use(self, obj):
@@ -1219,10 +1211,6 @@ class CredentialInputSourceAccess(BaseAccess):
return CredentialInputSource.objects.filter(
target_credential__in=Credential.accessible_pk_qs(self.user, 'read_role'))
@check_superuser
def can_read(self, obj):
return self.user in obj.target_credential.read_role
@check_superuser
def can_add(self, data):
return (
@@ -1971,10 +1959,6 @@ class WorkflowJobTemplateAccess(NotificationAttachMixin, BaseAccess):
def filtered_queryset(self):
return self.model.accessible_objects(self.user, 'read_role')
@check_superuser
def can_read(self, obj):
return self.user in obj.read_role
@check_superuser
def can_add(self, data):
'''
@@ -2372,13 +2356,18 @@ class UnifiedJobTemplateAccess(BaseAccess):
return self.model.objects.filter(
Q(pk__in=self.model.accessible_pk_qs(self.user, 'read_role')) |
Q(inventorysource__inventory__id__in=Inventory._accessible_pk_qs(
Inventory, self.user, 'read_role')))
Inventory, self.user, 'read_role'))
)
def can_start(self, obj, validate_license=True):
access_class = access_registry[obj.__class__]
access_instance = access_class(self.user)
return access_instance.can_start(obj, validate_license=validate_license)
def get_queryset(self):
return super(UnifiedJobTemplateAccess, self).get_queryset().filter(
workflowapprovaltemplate__isnull=True)
class UnifiedJobAccess(BaseAccess):
'''
@@ -2425,6 +2414,10 @@ class UnifiedJobAccess(BaseAccess):
)
return qs
def get_queryset(self):
return super(UnifiedJobAccess, self).get_queryset().filter(
workflowapproval__isnull=True)
class ScheduleAccess(BaseAccess):
'''
@@ -2486,14 +2479,6 @@ class NotificationTemplateAccess(BaseAccess):
Q(organization__in=self.user.auditor_of_organizations)
).distinct()
def can_read(self, obj):
if self.user.is_superuser or self.user.is_system_auditor:
return True
if obj.organization is not None:
if self.user in obj.organization.notification_admin_role or self.user in obj.organization.auditor_role:
return True
return False
@check_superuser
def can_add(self, data):
if not data:
@@ -2533,9 +2518,6 @@ class NotificationAccess(BaseAccess):
Q(notification_template__organization__in=self.user.auditor_of_organizations)
).distinct()
def can_read(self, obj):
return self.user.can_access(NotificationTemplate, 'read', obj.notification_template)
def can_delete(self, obj):
return self.user.can_access(NotificationTemplate, 'delete', obj.notification_template)
@@ -2550,10 +2532,6 @@ class LabelAccess(BaseAccess):
def filtered_queryset(self):
return self.model.objects.all()
@check_superuser
def can_read(self, obj):
return self.user in obj.organization.read_role
@check_superuser
def can_add(self, data):
if not data: # So the browseable API will work
@@ -2711,15 +2689,6 @@ class RoleAccess(BaseAccess):
result = result | super_qs
return result
def can_read(self, obj):
if not obj:
return False
if self.user.is_superuser or self.user.is_system_auditor:
return True
return Role.filter_visible_roles(
self.user, Role.objects.filter(pk=obj.id)).exists()
def can_add(self, obj, data):
# Unsupported for now
return False
@@ -2764,5 +2733,80 @@ class RoleAccess(BaseAccess):
return False
class WorkflowApprovalAccess(BaseAccess):
'''
A user can create a workflow approval if they are a superuser, an org admin
of the org connected to the workflow, or if they are assigned as admins to
the workflow.
A user can approve a workflow when they are:
- a superuser
- a workflow admin
- an organization admin
- any user who has explicitly been assigned the "approver" role
A user can see approvals if they have read access to the associated WorkflowJobTemplate.
'''
model = WorkflowApproval
prefetch_related = ('created_by', 'modified_by',)
def can_use(self, obj):
return True
def can_start(self, obj, validate_license=True):
return True
def filtered_queryset(self):
return self.model.objects.filter(
unified_job_node__workflow_job__unified_job_template__in=WorkflowJobTemplate.accessible_pk_qs(
self.user, 'read_role'))
def can_approve_or_deny(self, obj):
if (
(obj.workflow_job_template and self.user in obj.workflow_job_template.approval_role) or
self.user.is_superuser
):
return True
class WorkflowApprovalTemplateAccess(BaseAccess):
'''
A user can create a workflow approval if they are a superuser, an org admin
of the org connected to the workflow, or if they are assigned as admins to
the workflow.
A user can approve a workflow when they are:
- a superuser
- a workflow admin
- an organization admin
- any user who has explicitly been assigned the "approver" role at the workflow or organization level
A user can see approval templates if they have read access to the associated WorkflowJobTemplate.
'''
model = WorkflowApprovalTemplate
prefetch_related = ('created_by', 'modified_by',)
@check_superuser
def can_add(self, data):
if data is None: # Hide direct creation in API browser
return False
else:
return (self.check_related('workflow_approval_template', UnifiedJobTemplate, role_field='admin_role'))
def can_start(self, obj, validate_license=False):
# for copying WFJTs that contain approval nodes
if self.user.is_superuser:
return True
return self.user in obj.workflow_job_template.execute_role
def filtered_queryset(self):
return self.model.objects.filter(
workflowjobtemplatenodes__workflow_job_template__in=WorkflowJobTemplate.accessible_pk_qs(
self.user, 'read_role'))
for cls in BaseAccess.__subclasses__():
access_registry[cls.model] = cls

View File

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

View File

@@ -12,14 +12,14 @@ 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
from awx.main.analytics import register, table_version
'''
This module is used to define metrics collected by awx.main.analytics.gather()
Each function is decorated with a key name, and should return a data
structure that can be serialized to JSON
@register('something')
@register('something', '1.0')
def something(since):
# the generated archive will contain a `something.json` w/ this JSON
return {'some': 'json'}
@@ -31,7 +31,7 @@ data _since_ the last report date - i.e., new data in the last 24 hours)
'''
@register('config')
@register('config', '1.0')
def config(since):
license_info = get_license(show_key=False)
install_type = 'traditional'
@@ -62,7 +62,7 @@ def config(since):
}
@register('counts')
@register('counts', '1.0')
def counts(since):
counts = {}
for cls in (models.Organization, models.Team, models.User,
@@ -93,10 +93,11 @@ def counts(since):
counts['active_user_sessions'] = active_user_sessions
counts['active_anonymous_sessions'] = active_anonymous_sessions
counts['running_jobs'] = models.UnifiedJob.objects.exclude(launch_type='sync').filter(status__in=('running', 'waiting',)).count()
counts['pending_jobs'] = models.UnifiedJob.objects.exclude(launch_type='sync').filter(status__in=('pending',)).count()
return counts
@register('org_counts')
@register('org_counts', '1.0')
def org_counts(since):
counts = {}
for org in models.Organization.objects.annotate(num_users=Count('member_role__members', distinct=True),
@@ -108,7 +109,7 @@ def org_counts(since):
return counts
@register('cred_type_counts')
@register('cred_type_counts', '1.0')
def cred_type_counts(since):
counts = {}
for cred_type in models.CredentialType.objects.annotate(num_credentials=Count(
@@ -120,7 +121,7 @@ def cred_type_counts(since):
return counts
@register('inventory_counts')
@register('inventory_counts', '1.0')
def inventory_counts(since):
counts = {}
for inv in models.Inventory.objects.filter(kind='').annotate(num_sources=Count('inventory_sources', distinct=True),
@@ -140,7 +141,7 @@ def inventory_counts(since):
return counts
@register('projects_by_scm_type')
@register('projects_by_scm_type', '1.0')
def projects_by_scm_type(since):
counts = dict(
(t[0] or 'manual', 0)
@@ -159,8 +160,8 @@ def _get_isolated_datetime(last_check):
return last_check
@register('instance_info')
def instance_info(since):
@register('instance_info', '1.0')
def instance_info(since, include_hostnames=False):
info = {}
instances = models.Instance.objects.values_list('hostname').values(
'uuid', 'version', 'capacity', 'cpu', 'memory', 'managed_by_policy', 'hostname', 'last_isolated_check', 'enabled')
@@ -175,11 +176,13 @@ def instance_info(since):
'last_isolated_check': _get_isolated_datetime(instance['last_isolated_check']),
'enabled': instance['enabled']
}
if include_hostnames is True:
instance_info['hostname'] = instance['hostname']
info[instance['uuid']] = instance_info
return info
@register('job_counts')
@register('job_counts', '1.0')
def job_counts(since):
counts = {}
counts['total_jobs'] = models.UnifiedJob.objects.exclude(launch_type='sync').count()
@@ -189,7 +192,7 @@ def job_counts(since):
return counts
@register('job_instance_counts')
@register('job_instance_counts', '1.0')
def job_instance_counts(since):
counts = {}
job_types = models.UnifiedJob.objects.exclude(launch_type='sync').values_list(
@@ -204,7 +207,19 @@ def job_instance_counts(since):
return counts
@register('query_info', '1.0')
def query_info(since, collection_type):
query_info = {}
query_info['last_run'] = str(since)
query_info['current_time'] = str(now())
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.0')
@table_version('unified_jobs_table.csv', '1.0')
@table_version('unified_job_template_table.csv', '1.0')
def copy_tables(since, full_path):
def _copy_table(table, query, path):
file_path = os.path.join(path, table + '_table.csv')
@@ -233,10 +248,12 @@ def copy_tables(since, full_path):
WHERE main_jobevent.created > {}
ORDER BY main_jobevent.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
_copy_table(table='events', query=events_query, path=full_path)
unified_job_query = '''COPY (SELECT main_unifiedjob.id,
unified_job_query = '''COPY (SELECT main_unifiedjob.id,
main_unifiedjob.polymorphic_ctype_id,
django_content_type.model,
main_project.organization_id,
main_organization.name as organization_name,
main_unifiedjob.created,
main_unifiedjob.name,
main_unifiedjob.unified_job_template_id,
@@ -252,13 +269,16 @@ def copy_tables(since, full_path):
main_unifiedjob.elapsed,
main_unifiedjob.job_explanation,
main_unifiedjob.instance_group_id
FROM main_unifiedjob, django_content_type
WHERE main_unifiedjob.created > {} AND
main_unifiedjob.polymorphic_ctype_id = django_content_type.id AND
main_unifiedjob.launch_type != 'sync'
FROM main_unifiedjob
JOIN main_job ON main_unifiedjob.id = main_job.unifiedjob_ptr_id
JOIN django_content_type ON main_unifiedjob.polymorphic_ctype_id = django_content_type.id
JOIN main_project ON main_project.unifiedjobtemplate_ptr_id = main_job.project_id
JOIN main_organization ON main_organization.id = main_project.organization_id
WHERE main_unifiedjob.created > {}
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'"))
_copy_table(table='unified_jobs', query=unified_job_query, path=full_path)
unified_job_template_query = '''COPY (SELECT main_unifiedjobtemplate.id,
main_unifiedjobtemplate.polymorphic_ctype_id,
django_content_type.model,
@@ -279,4 +299,3 @@ def copy_tables(since, full_path):
ORDER BY main_unifiedjobtemplate.id ASC) TO STDOUT WITH CSV HEADER'''.format(since.strftime("'%Y-%m-%d %H:%M:%S'"))
_copy_table(table='unified_job_template', query=unified_job_template_query, path=full_path)
return

View File

@@ -5,10 +5,9 @@ import os
import os.path
import tempfile
import shutil
import subprocess
import requests
from django.conf import settings
from django.utils.encoding import smart_str
from django.utils.timezone import now, timedelta
from rest_framework.exceptions import PermissionDenied
@@ -18,11 +17,13 @@ from awx.main.access import access_registry
from awx.main.models.ha import TowerAnalyticsState
__all__ = ['register', 'gather', 'ship']
__all__ = ['register', 'gather', 'ship', 'table_version']
logger = logging.getLogger('awx.main.analytics')
manifest = dict()
def _valid_license():
try:
@@ -35,25 +36,37 @@ def _valid_license():
return True
def register(key):
def register(key, version):
"""
A decorator used to register a function as a metric collector.
Decorated functions should return JSON-serializable objects.
@register('projects_by_scm_type')
@register('projects_by_scm_type', 1)
def projects_by_scm_type():
return {'git': 5, 'svn': 1, 'hg': 0}
"""
def decorate(f):
f.__awx_analytics_key__ = key
f.__awx_analytics_version__ = version
return f
return decorate
def gather(dest=None, module=None):
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'):
"""
Gather all defined metrics and write them as JSON files in a .tgz
@@ -67,35 +80,49 @@ def gather(dest=None, module=None):
last_run = state.last_run
logger.debug("Last analytics run was: {}".format(last_run))
max_interval = now() - timedelta(days=7)
max_interval = now() - timedelta(weeks=4)
if last_run < max_interval or not last_run:
last_run = max_interval
if _valid_license() is False:
logger.exception("Invalid License provided, or No License Provided")
return "Error: Invalid License provided, or No License Provided"
if not settings.INSIGHTS_TRACKING_STATE:
logger.error("Insights analytics not enabled")
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
if module is None:
from awx.main.analytics import collectors
module = collectors
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__'):
key = func.__awx_analytics_key__
manifest['{}.json'.format(key)] = func.__awx_analytics_version__
path = '{}.json'.format(os.path.join(dest, key))
with open(path, 'w', encoding='utf-8') as f:
try:
json.dump(func(last_run), f)
if func.__name__ == 'query_info':
json.dump(func(last_run, collection_type=collection_type), f)
else:
json.dump(func(last_run), f)
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)
try:
collectors.copy_tables(since=last_run, full_path=dest)
except Exception:
@@ -117,30 +144,39 @@ def gather(dest=None, module=None):
def ship(path):
"""
Ship gathered metrics via the Insights agent
Ship gathered metrics to the Insights API
"""
if not path:
logger.error('Automation Analytics TAR not found')
return
if "Error:" in str(path):
return
try:
agent = 'insights-client'
if shutil.which(agent) is None:
logger.error('could not find {} on PATH'.format(agent))
return
logger.debug('shipping analytics file: {}'.format(path))
try:
cmd = [
agent, '--payload', path, '--content-type', settings.INSIGHTS_AGENT_MIME
]
output = smart_str(subprocess.check_output(cmd, timeout=60 * 5))
logger.debug(output)
# reset the `last_run` when data is shipped
run_now = now()
state = TowerAnalyticsState.get_solo()
state.last_run = run_now
state.save()
except subprocess.CalledProcessError:
logger.exception('{} failure:'.format(cmd))
except subprocess.TimeoutExpired:
logger.exception('{} timeout:'.format(cmd))
url = getattr(settings, 'AUTOMATION_ANALYTICS_URL', None)
if not url:
logger.error('AUTOMATION_ANALYTICS_URL is not set')
return
rh_user = getattr(settings, 'REDHAT_USERNAME', None)
rh_password = getattr(settings, 'REDHAT_PASSWORD', None)
if not rh_user:
return logger.error('REDHAT_USERNAME is not set')
if not rh_password:
return logger.error('REDHAT_PASSWORD is not set')
with open(path, 'rb') as f:
files = {'file': (os.path.basename(path), f, settings.INSIGHTS_AGENT_MIME)}
response = requests.post(url,
files=files,
verify="/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
auth=(rh_user, rh_password),
timeout=(31, 31))
if response.status_code != 202:
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)

View File

@@ -15,6 +15,7 @@ from awx.main.analytics.collectors import (
counts,
instance_info,
job_instance_counts,
job_counts,
)
@@ -36,11 +37,13 @@ INV_SCRIPT_COUNT = Gauge('awx_inventory_scripts_total', 'Number of invetory scri
USER_SESSIONS = Gauge('awx_sessions_total', 'Number of sessions', ['type',])
CUSTOM_VENVS = Gauge('awx_custom_virtualenvs_total', 'Number of virtualenvs')
RUNNING_JOBS = Gauge('awx_running_jobs_total', 'Number of running jobs on the Tower system')
PENDING_JOBS = Gauge('awx_pending_jobs_total', 'Number of pending jobs on the Tower system')
STATUS = Gauge('awx_status_total', 'Status of Job launched', ['status',])
INSTANCE_CAPACITY = Gauge('awx_instance_capacity', 'Capacity of each node in a Tower system', ['instance_uuid',])
INSTANCE_CPU = Gauge('awx_instance_cpu', 'CPU cores on each node in a Tower system', ['instance_uuid',])
INSTANCE_MEMORY = Gauge('awx_instance_memory', 'RAM (Kb) on each node in a Tower system', ['instance_uuid',])
INSTANCE_INFO = Info('awx_instance', 'Info about each node in a Tower system', ['instance_uuid',])
INSTANCE_CAPACITY = Gauge('awx_instance_capacity', 'Capacity of each node in a Tower system', ['hostname', 'instance_uuid',])
INSTANCE_CPU = Gauge('awx_instance_cpu', 'CPU cores on each node in a Tower system', ['hostname', 'instance_uuid',])
INSTANCE_MEMORY = Gauge('awx_instance_memory', 'RAM (Kb) on each node in a Tower system', ['hostname', 'instance_uuid',])
INSTANCE_INFO = Info('awx_instance', 'Info about each node in a Tower system', ['hostname', 'instance_uuid',])
INSTANCE_LAUNCH_TYPE = Gauge('awx_instance_launch_type_total', 'Type of Job launched', ['node', 'launch_type',])
INSTANCE_STATUS = Gauge('awx_instance_status_total', 'Status of Job launched', ['node', 'status',])
@@ -87,15 +90,21 @@ def metrics():
USER_SESSIONS.labels(type='user').set(current_counts['active_user_sessions'])
USER_SESSIONS.labels(type='anonymous').set(current_counts['active_anonymous_sessions'])
all_job_data = job_counts(None)
statuses = all_job_data.get('status', {})
for status, value in statuses.items():
STATUS.labels(status=status).set(value)
RUNNING_JOBS.set(current_counts['running_jobs'])
PENDING_JOBS.set(current_counts['pending_jobs'])
instance_data = instance_info(None)
for uuid in instance_data:
INSTANCE_CAPACITY.labels(instance_uuid=uuid).set(instance_data[uuid]['capacity'])
INSTANCE_CPU.labels(instance_uuid=uuid).set(instance_data[uuid]['cpu'])
INSTANCE_MEMORY.labels(instance_uuid=uuid).set(instance_data[uuid]['memory'])
INSTANCE_INFO.labels(instance_uuid=uuid).info({
instance_data = instance_info(None, include_hostnames=True)
for uuid, info in instance_data.items():
hostname = info['hostname']
INSTANCE_CAPACITY.labels(hostname=hostname, instance_uuid=uuid).set(instance_data[uuid]['capacity'])
INSTANCE_CPU.labels(hostname=hostname, instance_uuid=uuid).set(instance_data[uuid]['cpu'])
INSTANCE_MEMORY.labels(hostname=hostname, instance_uuid=uuid).set(instance_data[uuid]['memory'])
INSTANCE_INFO.labels(hostname=hostname, instance_uuid=uuid).info({
'enabled': str(instance_data[uuid]['enabled']),
'last_isolated_check': getattr(instance_data[uuid], 'last_isolated_check', 'None'),
'managed_by_policy': str(instance_data[uuid]['managed_by_policy']),

View File

@@ -2,12 +2,14 @@
import json
import logging
import os
from distutils.version import LooseVersion as Version
# Django
from django.utils.translation import ugettext_lazy as _
# Django REST Framework
from rest_framework import serializers
from rest_framework.fields import FloatField
# Tower
from awx.conf import fields, register, register_validate
@@ -124,6 +126,44 @@ register(
category_slug='system',
)
register(
'REDHAT_USERNAME',
field_class=fields.CharField,
default='',
allow_blank=True,
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
category=_('System'),
category_slug='system',
)
register(
'REDHAT_PASSWORD',
field_class=fields.CharField,
default='',
allow_blank=True,
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
category=_('System'),
category_slug='system',
)
register(
'AUTOMATION_ANALYTICS_URL',
field_class=fields.URLField,
default='https://example.com',
schemes=('http', 'https'),
allow_plain_hostname=True, # Allow hostname only without TLD.
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',
)
register(
'INSTALL_UUID',
field_class=fields.CharField,
@@ -260,6 +300,16 @@ register(
category_slug='jobs',
)
register(
'AWX_ISOLATED_HOST_KEY_CHECKING',
field_class=fields.BooleanField,
label=_('Isolated host key checking'),
help_text=_('When set to True, AWX will enforce strict host key checking for communication with isolated nodes.'),
category=_('Jobs'),
category_slug='jobs',
default=False
)
register(
'AWX_ISOLATED_KEY_GENERATION',
field_class=fields.BooleanField,
@@ -297,6 +347,53 @@ register(
category_slug='jobs',
)
register(
'AWX_RESOURCE_PROFILING_ENABLED',
field_class=fields.BooleanField,
default=False,
label=_('Enable detailed resource profiling on all playbook runs'),
help_text=_('If set, detailed resource profiling data will be collected on all jobs. '
'This data can be gathered with `sosreport`.'), # noqa
category=_('Jobs'),
category_slug='jobs',
)
register(
'AWX_RESOURCE_PROFILING_CPU_POLL_INTERVAL',
field_class=FloatField,
default='0.25',
label=_('Interval (in seconds) between polls for cpu usage.'),
help_text=_('Interval (in seconds) between polls for cpu usage. '
'Setting this lower than the default will affect playbook performance.'),
category=_('Jobs'),
category_slug='jobs',
required=False,
)
register(
'AWX_RESOURCE_PROFILING_MEMORY_POLL_INTERVAL',
field_class=FloatField,
default='0.25',
label=_('Interval (in seconds) between polls for memory usage.'),
help_text=_('Interval (in seconds) between polls for memory usage. '
'Setting this lower than the default will affect playbook performance.'),
category=_('Jobs'),
category_slug='jobs',
required=False,
)
register(
'AWX_RESOURCE_PROFILING_PID_POLL_INTERVAL',
field_class=FloatField,
default='0.25',
label=_('Interval (in seconds) between polls for PID count.'),
help_text=_('Interval (in seconds) between polls for PID count. '
'Setting this lower than the default will affect playbook performance.'),
category=_('Jobs'),
category_slug='jobs',
required=False,
)
register(
'AWX_TASK_ENV',
field_class=fields.KeyValueField,
@@ -312,12 +409,21 @@ register(
'INSIGHTS_TRACKING_STATE',
field_class=fields.BooleanField,
default=False,
label=_('Gather data for Automation Insights'),
help_text=_('Enables Tower to gather data on automation and send it to Red Hat Insights.'),
label=_('Gather data for Automation Analytics'),
help_text=_('Enables Tower to gather data on automation and send it to Red Hat.'),
category=_('System'),
category_slug='system',
)
register(
'PROJECT_UPDATE_VVV',
field_class=fields.BooleanField,
label=_('Run Project Updates With Higher Verbosity'),
help_text=_('Adds the CLI -vvv flag to ansible-playbook runs of project_update.yml used for project updates.'),
category=_('Jobs'),
category_slug='jobs',
)
register(
'AWX_ROLES_ENABLED',
field_class=fields.BooleanField,
@@ -328,6 +434,85 @@ register(
category_slug='jobs',
)
register(
'AWX_COLLECTIONS_ENABLED',
field_class=fields.BooleanField,
default=True,
label=_('Enable Collection(s) Download'),
help_text=_('Allows collections to be dynamically downloaded from a requirements.yml file for SCM projects.'),
category=_('Jobs'),
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(
'STDOUT_MAX_BYTES_DISPLAY',
field_class=fields.IntegerField,
@@ -568,6 +753,16 @@ register(
category=_('Logging'),
category_slug='logging',
)
register(
'LOG_AGGREGATOR_AUDIT',
field_class=fields.BooleanField,
allow_null=True,
default=False,
label=_('Enabled external log aggregation auditing'),
help_text=_('When enabled, all external logs emitted by Tower will also be written to /var/log/tower/external.log. This is an experimental setting intended to be used for debugging external log aggregation issues (and may be subject to change in the future).'), # noqa
category=_('Logging'),
category_slug='logging',
)
register(
@@ -598,4 +793,75 @@ 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_'
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
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, '')
galaxy_data = {}
for subfield in GALAXY_SERVER_FIELDS:
galaxy_data[subfield] = _new_value('{}{}'.format(prefix, subfield.upper()))
errors = {}
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

@@ -51,3 +51,7 @@ 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

@@ -24,7 +24,7 @@ def ws_connect(message):
headers = dict(message.content.get('headers', ''))
message.reply_channel.send({"accept": True})
message.content['method'] = 'FAKE'
if message.user.is_authenticated():
if message.user.is_authenticated:
message.reply_channel.send(
{"text": json.dumps({"accept": True, "user": message.user.id})}
)

View File

@@ -1,14 +1,14 @@
from .plugin import CredentialPlugin
import os
import stat
import tempfile
import threading
from urllib.parse import quote, urlencode, urljoin
from django.utils.translation import ugettext_lazy as _
import requests
# AWX
from awx.main.utils import (
create_temporary_fifo,
)
aim_inputs = {
'fields': [{
@@ -60,24 +60,6 @@ aim_inputs = {
}
def create_temporary_fifo(data):
"""Open fifo named pipe in a new thread using a temporary file path. The
thread blocks until data is read from the pipe.
Returns the path to the fifo.
:param data(bytes): Data to write to the pipe.
"""
path = os.path.join(tempfile.mkdtemp(), next(tempfile._get_candidate_names()))
os.mkfifo(path, stat.S_IRUSR | stat.S_IWUSR)
threading.Thread(
target=lambda p, d: open(p, 'wb').write(d),
args=(path, data)
).start()
return path
def aim_backend(**kwargs):
url = kwargs['url']
client_cert = kwargs.get('client_cert', None)
@@ -119,7 +101,7 @@ def aim_backend(**kwargs):
aim_plugin = CredentialPlugin(
'CyberArk AIM Secret Lookup',
'CyberArk AIM Central Credential Provider Lookup',
inputs=aim_inputs,
backend=aim_backend
)

View File

@@ -1,15 +1,16 @@
from .plugin import CredentialPlugin
import base64
import os
import stat
import tempfile
import threading
from urllib.parse import urljoin, quote_plus
from django.utils.translation import ugettext_lazy as _
import requests
# AWX
from awx.main.utils import (
create_temporary_fifo,
)
conjur_inputs = {
'fields': [{
@@ -51,24 +52,6 @@ conjur_inputs = {
}
def create_temporary_fifo(data):
"""Open fifo named pipe in a new thread using a temporary file path. The
thread blocks until data is read from the pipe.
Returns the path to the fifo.
:param data(bytes): Data to write to the pipe.
"""
path = os.path.join(tempfile.mkdtemp(), next(tempfile._get_candidate_names()))
os.mkfifo(path, stat.S_IRUSR | stat.S_IWUSR)
threading.Thread(
target=lambda p, d: open(p, 'wb').write(d),
args=(path, data)
).start()
return path
def conjur_backend(**kwargs):
url = kwargs['url']
api_key = kwargs['api_key']

View File

@@ -8,6 +8,10 @@ from .plugin import CredentialPlugin
import requests
from django.utils.translation import ugettext_lazy as _
# AWX
from awx.main.utils import (
create_temporary_fifo,
)
base_inputs = {
'fields': [{
@@ -22,12 +26,18 @@ base_inputs = {
'type': 'string',
'secret': True,
'help_text': _('The access token used to authenticate to the Vault server'),
}, {
'id': 'cacert',
'label': _('CA Certificate'),
'type': 'string',
'multiline': True,
'help_text': _('The CA certificate used to verify the SSL certificate of the Vault server')
}],
'metadata': [{
'id': 'secret_path',
'label': _('Path to Secret'),
'type': 'string',
'help_text': _('The path to the secret e.g., /some-engine/some-secret/'),
'help_text': _('The path to the secret stored in the secret backend e.g, /some/secret/')
}],
'required': ['url', 'token', 'secret_path'],
}
@@ -40,7 +50,12 @@ hashi_kv_inputs['fields'].append({
'help_text': _('API v1 is for static key/value lookups. API v2 is for versioned key/value lookups.'),
'default': 'v1',
})
hashi_kv_inputs['metadata'].extend([{
hashi_kv_inputs['metadata'] = [{
'id': 'secret_backend',
'label': _('Name of Secret Backend'),
'type': 'string',
'help_text': _('The name of the kv secret backend (if left empty, the first segment of the secret path will be used).')
}] + hashi_kv_inputs['metadata'] + [{
'id': 'secret_key',
'label': _('Key Name'),
'type': 'string',
@@ -50,7 +65,7 @@ hashi_kv_inputs['metadata'].extend([{
'label': _('Secret Version (v2 only)'),
'type': 'string',
'help_text': _('Used to specify a specific secret version (if left empty, the latest version will be used).'),
}])
}]
hashi_kv_inputs['required'].extend(['api_version', 'secret_key'])
hashi_ssh_inputs = copy.deepcopy(base_inputs)
@@ -75,36 +90,48 @@ hashi_ssh_inputs['required'].extend(['public_key', 'role'])
def kv_backend(**kwargs):
token = kwargs['token']
url = urljoin(kwargs['url'], 'v1')
url = kwargs['url']
secret_path = kwargs['secret_path']
secret_backend = kwargs.get('secret_backend', None)
secret_key = kwargs.get('secret_key', None)
cacert = kwargs.get('cacert', None)
api_version = kwargs['api_version']
request_kwargs = {'timeout': 30}
if cacert:
request_kwargs['verify'] = create_temporary_fifo(cacert.encode())
sess = requests.Session()
sess.headers['Authorization'] = 'Bearer {}'.format(token)
# Compatability header for older installs of Hashicorp Vault
sess.headers['X-Vault-Token'] = token
if api_version == 'v2':
params = {}
if kwargs.get('secret_version'):
params['version'] = kwargs['secret_version']
try:
mount_point, *path = pathlib.Path(secret_path.lstrip(os.sep)).parts
'/'.join(*path)
except Exception:
mount_point, path = secret_path, []
# https://www.vaultproject.io/api/secret/kv/kv-v2.html#read-secret-version
response = sess.get(
'/'.join([url, mount_point, 'data'] + path).rstrip('/'),
params=params,
timeout=30
)
response.raise_for_status()
json = response.json()['data']
request_kwargs['params'] = {'version': kwargs['secret_version']}
if secret_backend:
path_segments = [secret_backend, 'data', secret_path]
else:
try:
mount_point, *path = pathlib.Path(secret_path.lstrip(os.sep)).parts
'/'.join(path)
except Exception:
mount_point, path = secret_path, []
# https://www.vaultproject.io/api/secret/kv/kv-v2.html#read-secret-version
path_segments = [mount_point, 'data'] + path
else:
# https://www.vaultproject.io/api/secret/kv/kv-v1.html#read-secret
response = sess.get('/'.join([url, secret_path]).rstrip('/'), timeout=30)
response.raise_for_status()
json = response.json()
if secret_backend:
path_segments = [secret_backend, secret_path]
else:
path_segments = [secret_path]
request_url = urljoin(url, '/'.join(['v1'] + path_segments)).rstrip('/')
response = sess.get(request_url, **request_kwargs)
response.raise_for_status()
json = response.json()
if api_version == 'v2':
json = json['data']
if secret_key:
try:
@@ -121,20 +148,24 @@ def ssh_backend(**kwargs):
url = urljoin(kwargs['url'], 'v1')
secret_path = kwargs['secret_path']
role = kwargs['role']
cacert = kwargs.get('cacert', None)
request_kwargs = {'timeout': 30}
if cacert:
request_kwargs['verify'] = create_temporary_fifo(cacert.encode())
request_kwargs['json'] = {'public_key': kwargs['public_key']}
if kwargs.get('valid_principals'):
request_kwargs['json']['valid_principals'] = kwargs['valid_principals']
sess = requests.Session()
sess.headers['Authorization'] = 'Bearer {}'.format(token)
json = {
'public_key': kwargs['public_key']
}
if kwargs.get('valid_principals'):
json['valid_principals'] = kwargs['valid_principals']
# Compatability header for older installs of Hashicorp Vault
sess.headers['X-Vault-Token'] = token
# https://www.vaultproject.io/api/secret/ssh/index.html#sign-ssh-key
resp = sess.post(
'/'.join([url, secret_path, 'sign', role]).rstrip('/'),
json=json,
timeout=30
)
request_url = '/'.join([url, secret_path, 'sign', role]).rstrip('/')
resp = sess.post(request_url, **request_kwargs)
resp.raise_for_status()
return resp.json()['data']['signed_key']

View File

@@ -33,7 +33,11 @@ def reap(instance=None, status='failed', excluded_uuids=[]):
'''
Reap all jobs in waiting|running for this instance.
'''
me = instance or Instance.objects.me()
me = instance
if me is None:
(changed, me) = Instance.objects.get_or_register()
if changed:
logger.info("Registered tower node '{}'".format(me.hostname))
now = tz_now()
workflow_ctype_id = ContentType.objects.get_for_model(WorkflowJob).id
jobs = UnifiedJob.objects.filter(

View File

@@ -11,8 +11,9 @@ from jinja2 import Environment, StrictUndefined
from jinja2.exceptions import UndefinedError, TemplateSyntaxError
# Django
import django
from django.contrib.postgres.fields import JSONField as upstream_JSONBField
from django.core import exceptions as django_exceptions
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models.signals import (
post_save,
post_delete,
@@ -37,7 +38,6 @@ import jsonschema.exceptions
# Django-JSONField
from jsonfield import JSONField as upstream_JSONField
from jsonbfield.fields import JSONField as upstream_JSONBField
# DRF
from rest_framework import serializers
@@ -76,10 +76,10 @@ class JSONField(upstream_JSONField):
def db_type(self, connection):
return 'text'
def from_db_value(self, value, expression, connection, context):
def from_db_value(self, value, expression, connection):
if value in {'', None} and not self.null:
return {}
return super(JSONField, self).from_db_value(value, expression, connection, context)
return super(JSONField, self).from_db_value(value, expression, connection)
class JSONBField(upstream_JSONBField):
@@ -91,12 +91,12 @@ class JSONBField(upstream_JSONBField):
def get_db_prep_value(self, value, connection, prepared=False):
if connection.vendor == 'sqlite':
# sqlite (which we use for tests) does not support jsonb;
return json.dumps(value)
return json.dumps(value, cls=DjangoJSONEncoder)
return super(JSONBField, self).get_db_prep_value(
value, connection, prepared
)
def from_db_value(self, value, expression, connection, context):
def from_db_value(self, value, expression, connection):
# Work around a bug in django-jsonfield
# https://bitbucket.org/schinckel/django-jsonfield/issues/57/cannot-use-in-the-same-project-as-djangos
if isinstance(value, str):
@@ -112,14 +112,9 @@ class AutoSingleRelatedObjectDescriptor(ReverseOneToOneDescriptor):
def __get__(self, instance, instance_type=None):
try:
return super(AutoSingleRelatedObjectDescriptor,
self).__get__(instance, instance_type)
return super(AutoSingleRelatedObjectDescriptor, self).__get__(instance, instance_type)
except self.related.related_model.DoesNotExist:
obj = self.related.related_model(**{self.related.field.name: instance})
if self.related.field.rel.parent_link:
raise NotImplementedError('not supported with polymorphic!')
for f in instance._meta.local_fields:
setattr(obj, f.name, getattr(instance, f.name))
obj.save()
return obj
@@ -169,7 +164,7 @@ def is_implicit_parent(parent_role, child_role):
# The only singleton implicit parent is the system admin being
# a parent of the system auditor role
return bool(
child_role.singleton_name == ROLE_SINGLETON_SYSTEM_AUDITOR and
child_role.singleton_name == ROLE_SINGLETON_SYSTEM_AUDITOR and
parent_role.singleton_name == ROLE_SINGLETON_SYSTEM_ADMINISTRATOR
)
# Get the list of implicit parents that were defined at the class level.
@@ -453,21 +448,6 @@ class JSONSchemaField(JSONBField):
params={'value': value},
)
def get_db_prep_value(self, value, connection, prepared=False):
if connection.vendor == 'sqlite':
# sqlite (which we use for tests) does not support jsonb;
return json.dumps(value)
return super(JSONSchemaField, self).get_db_prep_value(
value, connection, prepared
)
def from_db_value(self, value, expression, connection, context):
# Work around a bug in django-jsonfield
# https://bitbucket.org/schinckel/django-jsonfield/issues/57/cannot-use-in-the-same-project-as-djangos
if isinstance(value, str):
return json.loads(value)
return value
@JSONSchemaField.format_checker.checks('vault_id')
def format_vault_id(value):
@@ -711,10 +691,12 @@ class CredentialInputField(JSONSchemaField):
if model_instance.has_encrypted_ssh_key_data and not value.get('ssh_key_unlock'):
errors['ssh_key_unlock'] = [_('must be set when SSH key is encrypted.')]
if all([
model_instance.inputs.get('ssh_key_data'),
value.get('ssh_key_unlock'),
not model_instance.has_encrypted_ssh_key_data
not model_instance.has_encrypted_ssh_key_data,
'ssh_key_data' not in errors
]):
errors['ssh_key_unlock'] = [_('should not be set when SSH key is not encrypted.')]
@@ -986,7 +968,7 @@ class OAuth2ClientSecretField(models.CharField):
encrypt_value(value), connection, prepared
)
def from_db_value(self, value, expression, connection, context):
def from_db_value(self, value, expression, connection):
if value and value.startswith('$encrypted$'):
return decrypt_value(get_encryption_key('value', pk=None), value)
return value
@@ -1022,38 +1004,6 @@ class OrderedManyToManyDescriptor(ManyToManyDescriptor):
'%s__position' % self.through._meta.model_name
)
def add(self, *objs):
# Django < 2 doesn't support this method on
# ManyToManyFields w/ an intermediary model
# We should be able to remove this code snippet when we
# upgrade Django.
# see: https://github.com/django/django/blob/stable/1.11.x/django/db/models/fields/related_descriptors.py#L926
if not django.__version__.startswith('1.'):
raise RuntimeError(
'This method is no longer necessary in Django>=2'
)
try:
self.through._meta.auto_created = True
super(OrderedManyRelatedManager, self).add(*objs)
finally:
self.through._meta.auto_created = False
def remove(self, *objs):
# Django < 2 doesn't support this method on
# ManyToManyFields w/ an intermediary model
# We should be able to remove this code snippet when we
# upgrade Django.
# see: https://github.com/django/django/blob/stable/1.11.x/django/db/models/fields/related_descriptors.py#L944
if not django.__version__.startswith('1.'):
raise RuntimeError(
'This method is no longer necessary in Django>=2'
)
try:
self.through._meta.auto_created = True
super(OrderedManyRelatedManager, self).remove(*objs)
finally:
self.through._meta.auto_created = False
return OrderedManyRelatedManager
return add_custom_queryset_to_many_related_manager(

View File

@@ -11,7 +11,9 @@ from django.conf import settings
import ansible_runner
import awx
from awx.main.utils import get_system_task_capacity
from awx.main.utils import (
get_system_task_capacity
)
from awx.main.queue import CallbackQueueDispatcher
logger = logging.getLogger('awx.isolated.manager')
@@ -29,7 +31,7 @@ def set_pythonpath(venv_libdir, env):
class IsolatedManager(object):
def __init__(self, cancelled_callback=None, check_callback=None):
def __init__(self, cancelled_callback=None, check_callback=None, pod_manager=None):
"""
:param cancelled_callback: a callable - which returns `True` or `False`
- signifying if the job has been prematurely
@@ -40,11 +42,29 @@ class IsolatedManager(object):
self.idle_timeout = max(60, 2 * settings.AWX_ISOLATED_CONNECTION_TIMEOUT)
self.started_at = None
self.captured_command_artifact = False
self.instance = None
self.pod_manager = pod_manager
def build_inventory(self, hosts):
if self.instance and self.instance.is_containerized:
inventory = {'all': {'hosts': {}}}
for host in hosts:
inventory['all']['hosts'][host] = {
"ansible_connection": "kubectl",
"ansible_kubectl_config": self.pod_manager.kube_config
}
else:
inventory = '\n'.join([
'{} ansible_ssh_user={}'.format(host, settings.AWX_ISOLATED_USERNAME)
for host in hosts
])
return inventory
def build_runner_params(self, hosts, verbosity=1):
env = dict(os.environ.items())
env['ANSIBLE_RETRY_FILES_ENABLED'] = 'False'
env['ANSIBLE_HOST_KEY_CHECKING'] = 'False'
env['ANSIBLE_HOST_KEY_CHECKING'] = str(settings.AWX_ISOLATED_HOST_KEY_CHECKING)
env['ANSIBLE_LIBRARY'] = os.path.join(os.path.dirname(awx.__file__), 'plugins', 'isolated')
set_pythonpath(os.path.join(settings.ANSIBLE_VENV_PATH, 'lib'), env)
@@ -69,17 +89,12 @@ class IsolatedManager(object):
else:
playbook_logger.info(runner_obj.stdout.read())
inventory = '\n'.join([
'{} ansible_ssh_user={}'.format(host, settings.AWX_ISOLATED_USERNAME)
for host in hosts
])
return {
'project_dir': os.path.abspath(os.path.join(
os.path.dirname(awx.__file__),
'playbooks'
)),
'inventory': inventory,
'inventory': self.build_inventory(hosts),
'envvars': env,
'finished_callback': finished_callback,
'verbosity': verbosity,
@@ -153,6 +168,12 @@ class IsolatedManager(object):
runner_obj = self.run_management_playbook('run_isolated.yml',
self.private_data_dir,
extravars=extravars)
if runner_obj.status == 'failed':
self.instance.result_traceback = runner_obj.stdout.read()
self.instance.save(update_fields=['result_traceback'])
return 'error', runner_obj.rc
return runner_obj.status, runner_obj.rc
def check(self, interval=None):
@@ -175,6 +196,7 @@ class IsolatedManager(object):
rc = None
last_check = time.time()
dispatcher = CallbackQueueDispatcher()
while status == 'failed':
canceled = self.cancelled_callback() if self.cancelled_callback else False
if not canceled and time.time() - last_check < interval:
@@ -279,7 +301,6 @@ class IsolatedManager(object):
def cleanup(self):
# If the job failed for any reason, make a last-ditch effort at cleanup
extravars = {
'private_data_dir': self.private_data_dir,
'cleanup_dirs': [
@@ -393,6 +414,7 @@ class IsolatedManager(object):
[instance.execution_node],
verbosity=min(5, self.instance.verbosity)
)
status, rc = self.dispatch(playbook, module, module_args)
if status == 'successful':
status, rc = self.check()

View File

@@ -0,0 +1,17 @@
# Copyright (c) 2015 Ansible, Inc.
# All Rights Reserved
from django.core.management.base import BaseCommand
from django.db import connection
class Command(BaseCommand):
"""Checks connection to the database, and prints out connection info if not connected"""
def handle(self, *args, **options):
with connection.cursor() as cursor:
cursor.execute("SELECT version()")
version = str(cursor.fetchone()[0])
return "Database Version: {}".format(version)

View File

@@ -1,6 +1,8 @@
# Copyright (c) 2015 Ansible, Inc.
# All Rights Reserved
import json
from awx.main.utils import get_licenser
from django.core.management.base import BaseCommand
@@ -8,6 +10,15 @@ from django.core.management.base import BaseCommand
class Command(BaseCommand):
"""Returns license type, e.g., 'enterprise', 'open', 'none'"""
def add_arguments(self, parser):
parser.add_argument('--data', dest='data', action='store_true',
help='verbose, prints the actual (sanitized) license')
def handle(self, *args, **options):
super(Command, self).__init__()
return get_licenser().validate().get('license_type', 'none')
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

@@ -11,8 +11,10 @@ class Command(BaseCommand):
help = 'Gather AWX analytics data'
def add_arguments(self, parser):
parser.add_argument('--dry-run', dest='dry-run', action='store_true',
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 via insights-client')
help='Enable to ship metrics to the Red Hat Cloud')
def init_logging(self):
self.logger = logging.getLogger('awx.main.analytics')
@@ -23,9 +25,14 @@ class Command(BaseCommand):
self.logger.propagate = False
def handle(self, *args, **options):
tgz = gather()
self.init_logging()
opt_ship = options.get('ship')
opt_dry_run = options.get('dry-run')
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)
if options.get('ship'):
if opt_ship:
ship(tgz)

View File

@@ -919,7 +919,8 @@ class Command(BaseCommand):
new_count = Host.objects.active_count()
if time_remaining <= 0 and not license_info.get('demo', False):
logger.error(LICENSE_EXPIRED_MESSAGE)
raise CommandError("License has expired!")
if license_info.get('trial', False) is True:
raise CommandError("License has expired!")
# special check for tower-type inventory sources
# but only if running the plugin
TOWER_SOURCE_FILES = ['tower.yml', 'tower.yaml']
@@ -936,7 +937,11 @@ class Command(BaseCommand):
logger.error(DEMO_LICENSE_MESSAGE % d)
else:
logger.error(LICENSE_MESSAGE % d)
raise CommandError('License count exceeded!')
if (
license_info.get('trial', False) is True or
license_info['instance_count'] == 10 # basic 10 license
):
raise CommandError('License count exceeded!')
def check_org_host_limit(self):
license_info = get_licenser().validate()

View File

@@ -33,6 +33,7 @@ class Command(BaseCommand):
]):
ssh_key = settings.AWX_ISOLATED_PRIVATE_KEY
env = dict(os.environ.items())
env['ANSIBLE_HOST_KEY_CHECKING'] = str(settings.AWX_ISOLATED_HOST_KEY_CHECKING)
set_pythonpath(os.path.join(settings.ANSIBLE_VENV_PATH, 'lib'), env)
res = ansible_runner.interface.run(
private_data_dir=path,

View File

@@ -221,8 +221,9 @@ class InstanceGroupManager(models.Manager):
elif t.status == 'running':
# Subtract capacity from all groups that contain the instance
if t.execution_node not in instance_ig_mapping:
logger.warning('Detected %s running inside lost instance, '
'may still be waiting for reaper.', t.log_format)
if not t.is_containerized:
logger.warning('Detected %s running inside lost instance, '
'may still be waiting for reaper.', t.log_format)
if t.instance_group:
impacted_groups = [t.instance_group.name]
else:

View File

@@ -73,7 +73,7 @@ class ActivityStreamMiddleware(threading.local, MiddlewareMixin):
super().__init__(get_response)
def process_request(self, request):
if hasattr(request, 'user') and hasattr(request.user, 'is_authenticated') and request.user.is_authenticated():
if hasattr(request, 'user') and request.user.is_authenticated:
user = request.user
else:
user = None

View File

@@ -44,7 +44,7 @@ class Migration(migrations.Migration):
('modified', models.DateTimeField(default=None, editable=False)),
('host_name', models.CharField(default='', max_length=1024, editable=False)),
('event', models.CharField(max_length=100, choices=[('runner_on_failed', 'Host Failed'), ('runner_on_ok', 'Host OK'), ('runner_on_unreachable', 'Host Unreachable'), ('runner_on_skipped', 'Host Skipped')])),
('event_data', jsonfield.fields.JSONField(default={}, blank=True)),
('event_data', jsonfield.fields.JSONField(default=dict, blank=True)),
('failed', models.BooleanField(default=False, editable=False)),
('changed', models.BooleanField(default=False, editable=False)),
('counter', models.PositiveIntegerField(default=0)),
@@ -62,7 +62,7 @@ class Migration(migrations.Migration):
('expires', models.DateTimeField(default=django.utils.timezone.now)),
('request_hash', models.CharField(default='', max_length=40, blank=True)),
('reason', models.CharField(default='', help_text='Reason the auth token was invalidated.', max_length=1024, blank=True)),
('user', models.ForeignKey(related_name='auth_tokens', to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(related_name='auth_tokens', on_delete=models.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
@@ -198,7 +198,7 @@ class Migration(migrations.Migration):
('created', models.DateTimeField(default=None, editable=False)),
('modified', models.DateTimeField(default=None, editable=False)),
('event', models.CharField(max_length=100, choices=[('runner_on_failed', 'Host Failed'), ('runner_on_ok', 'Host OK'), ('runner_on_error', 'Host Failure'), ('runner_on_skipped', 'Host Skipped'), ('runner_on_unreachable', 'Host Unreachable'), ('runner_on_no_hosts', 'No Hosts Remaining'), ('runner_on_async_poll', 'Host Polling'), ('runner_on_async_ok', 'Host Async OK'), ('runner_on_async_failed', 'Host Async Failure'), ('runner_on_file_diff', 'File Difference'), ('playbook_on_start', 'Playbook Started'), ('playbook_on_notify', 'Running Handlers'), ('playbook_on_no_hosts_matched', 'No Hosts Matched'), ('playbook_on_no_hosts_remaining', 'No Hosts Remaining'), ('playbook_on_task_start', 'Task Started'), ('playbook_on_vars_prompt', 'Variables Prompted'), ('playbook_on_setup', 'Gathering Facts'), ('playbook_on_import_for_host', 'internal: on Import for Host'), ('playbook_on_not_import_for_host', 'internal: on Not Import for Host'), ('playbook_on_play_start', 'Play Started'), ('playbook_on_stats', 'Playbook Complete')])),
('event_data', jsonfield.fields.JSONField(default={}, blank=True)),
('event_data', jsonfield.fields.JSONField(default=dict, blank=True)),
('failed', models.BooleanField(default=False, editable=False)),
('changed', models.BooleanField(default=False, editable=False)),
('host_name', models.CharField(default='', max_length=1024, editable=False)),
@@ -241,7 +241,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('instance', models.ForeignKey(to='main.Instance')),
('instance', models.ForeignKey(on_delete=models.CASCADE, to='main.Instance')),
],
),
migrations.CreateModel(
@@ -287,7 +287,7 @@ class Migration(migrations.Migration):
('created', models.DateTimeField(default=None, editable=False)),
('modified', models.DateTimeField(default=None, editable=False)),
('ldap_dn', models.CharField(default='', max_length=1024)),
('user', awx.main.fields.AutoOneToOneField(related_name='profile', editable=False, to=settings.AUTH_USER_MODEL)),
('user', awx.main.fields.AutoOneToOneField(related_name='profile', editable=False, on_delete=models.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
@@ -304,7 +304,7 @@ class Migration(migrations.Migration):
('dtend', models.DateTimeField(default=None, null=True, editable=False)),
('rrule', models.CharField(max_length=255)),
('next_run', models.DateTimeField(default=None, null=True, editable=False)),
('extra_data', jsonfield.fields.JSONField(default={}, blank=True)),
('extra_data', jsonfield.fields.JSONField(default=dict, blank=True)),
('created_by', models.ForeignKey(related_name="{u'class': 'schedule', u'app_label': 'main'}(class)s_created+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('modified_by', models.ForeignKey(related_name="{u'class': 'schedule', u'app_label': 'main'}(class)s_modified+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')),
@@ -343,7 +343,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=512)),
('old_pk', models.PositiveIntegerField(default=None, null=True, editable=False)),
('launch_type', models.CharField(default='manual', max_length=20, editable=False, choices=[('manual', 'Manual'), ('relaunch', 'Relaunch'), ('callback', 'Callback'), ('scheduled', 'Scheduled'), ('dependency', 'Dependency')])),
('cancel_flag', models.BooleanField(default=False, editable=False)),
('cancel_flag', models.BooleanField(blank=True, default=False, editable=False)),
('status', models.CharField(default='new', max_length=20, editable=False, choices=[('new', 'New'), ('pending', 'Pending'), ('waiting', 'Waiting'), ('running', 'Running'), ('successful', 'Successful'), ('failed', 'Failed'), ('error', 'Error'), ('canceled', 'Canceled')])),
('failed', models.BooleanField(default=False, editable=False)),
('started', models.DateTimeField(default=None, null=True, editable=False)),
@@ -351,7 +351,7 @@ class Migration(migrations.Migration):
('elapsed', models.DecimalField(editable=False, max_digits=12, decimal_places=3)),
('job_args', models.TextField(default='', editable=False, blank=True)),
('job_cwd', models.CharField(default='', max_length=1024, editable=False, blank=True)),
('job_env', jsonfield.fields.JSONField(default={}, editable=False, blank=True)),
('job_env', jsonfield.fields.JSONField(default=dict, editable=False, blank=True)),
('job_explanation', models.TextField(default='', editable=False, blank=True)),
('start_args', models.TextField(default='', editable=False, blank=True)),
('result_stdout_text', models.TextField(default='', editable=False, blank=True)),
@@ -380,7 +380,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='AdHocCommand',
fields=[
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJob')),
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJob')),
('job_type', models.CharField(default='run', max_length=64, choices=[('run', 'Run'), ('check', 'Check')])),
('limit', models.CharField(default='', max_length=1024, blank=True)),
('module_name', models.CharField(default='', max_length=1024, blank=True)),
@@ -394,7 +394,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='InventorySource',
fields=[
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJobTemplate')),
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJobTemplate')),
('source', models.CharField(default='', max_length=32, blank=True, choices=[('', 'Manual'), ('file', 'Local File, Directory or Script'), ('rax', 'Rackspace Cloud Servers'), ('ec2', 'Amazon EC2'), ('gce', 'Google Compute Engine'), ('azure', 'Microsoft Azure'), ('vmware', 'VMware vCenter'), ('openstack', 'OpenStack'), ('custom', 'Custom Script')])),
('source_path', models.CharField(default='', max_length=1024, editable=False, blank=True)),
('source_vars', models.TextField(default='', help_text='Inventory source variables in YAML or JSON format.', blank=True)),
@@ -411,7 +411,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='InventoryUpdate',
fields=[
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJob')),
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJob')),
('source', models.CharField(default='', max_length=32, blank=True, choices=[('', 'Manual'), ('file', 'Local File, Directory or Script'), ('rax', 'Rackspace Cloud Servers'), ('ec2', 'Amazon EC2'), ('gce', 'Google Compute Engine'), ('azure', 'Microsoft Azure'), ('vmware', 'VMware vCenter'), ('openstack', 'OpenStack'), ('custom', 'Custom Script')])),
('source_path', models.CharField(default='', max_length=1024, editable=False, blank=True)),
('source_vars', models.TextField(default='', help_text='Inventory source variables in YAML or JSON format.', blank=True)),
@@ -427,7 +427,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Job',
fields=[
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJob')),
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJob')),
('job_type', models.CharField(default='run', max_length=64, choices=[('run', 'Run'), ('check', 'Check'), ('scan', 'Scan')])),
('playbook', models.CharField(default='', max_length=1024, blank=True)),
('forks', models.PositiveIntegerField(default=0, blank=True)),
@@ -435,7 +435,7 @@ class Migration(migrations.Migration):
('verbosity', models.PositiveIntegerField(default=0, blank=True, choices=[(0, '0 (Normal)'), (1, '1 (Verbose)'), (2, '2 (More Verbose)'), (3, '3 (Debug)'), (4, '4 (Connection Debug)'), (5, '5 (WinRM Debug)')])),
('extra_vars', models.TextField(default='', blank=True)),
('job_tags', models.CharField(default='', max_length=1024, blank=True)),
('force_handlers', models.BooleanField(default=False)),
('force_handlers', models.BooleanField(blank=True, default=False)),
('skip_tags', models.CharField(default='', max_length=1024, blank=True)),
('start_at_task', models.CharField(default='', max_length=1024, blank=True)),
('become_enabled', models.BooleanField(default=False)),
@@ -448,7 +448,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='JobTemplate',
fields=[
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJobTemplate')),
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJobTemplate')),
('job_type', models.CharField(default='run', max_length=64, choices=[('run', 'Run'), ('check', 'Check'), ('scan', 'Scan')])),
('playbook', models.CharField(default='', max_length=1024, blank=True)),
('forks', models.PositiveIntegerField(default=0, blank=True)),
@@ -456,14 +456,14 @@ class Migration(migrations.Migration):
('verbosity', models.PositiveIntegerField(default=0, blank=True, choices=[(0, '0 (Normal)'), (1, '1 (Verbose)'), (2, '2 (More Verbose)'), (3, '3 (Debug)'), (4, '4 (Connection Debug)'), (5, '5 (WinRM Debug)')])),
('extra_vars', models.TextField(default='', blank=True)),
('job_tags', models.CharField(default='', max_length=1024, blank=True)),
('force_handlers', models.BooleanField(default=False)),
('force_handlers', models.BooleanField(blank=True, default=False)),
('skip_tags', models.CharField(default='', max_length=1024, blank=True)),
('start_at_task', models.CharField(default='', max_length=1024, blank=True)),
('become_enabled', models.BooleanField(default=False)),
('host_config_key', models.CharField(default='', max_length=1024, blank=True)),
('ask_variables_on_launch', models.BooleanField(default=False)),
('survey_enabled', models.BooleanField(default=False)),
('survey_spec', jsonfield.fields.JSONField(default={}, blank=True)),
('survey_spec', jsonfield.fields.JSONField(default=dict, blank=True)),
],
options={
'ordering': ('name',),
@@ -473,7 +473,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='Project',
fields=[
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJobTemplate')),
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJobTemplate')),
('local_path', models.CharField(help_text='Local path (relative to PROJECTS_ROOT) containing playbooks and related files for this project.', max_length=1024, blank=True)),
('scm_type', models.CharField(default='', max_length=8, verbose_name='SCM Type', blank=True, choices=[('', 'Manual'), ('git', 'Git'), ('hg', 'Mercurial'), ('svn', 'Subversion')])),
('scm_url', models.CharField(default='', max_length=1024, verbose_name='SCM URL', blank=True)),
@@ -492,7 +492,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='ProjectUpdate',
fields=[
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJob')),
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJob')),
('local_path', models.CharField(help_text='Local path (relative to PROJECTS_ROOT) containing playbooks and related files for this project.', max_length=1024, blank=True)),
('scm_type', models.CharField(default='', max_length=8, verbose_name='SCM Type', blank=True, choices=[('', 'Manual'), ('git', 'Git'), ('hg', 'Mercurial'), ('svn', 'Subversion')])),
('scm_url', models.CharField(default='', max_length=1024, verbose_name='SCM URL', blank=True)),
@@ -505,7 +505,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='SystemJob',
fields=[
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJob')),
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJob')),
('job_type', models.CharField(default='', max_length=32, blank=True, choices=[('cleanup_jobs', 'Remove jobs older than a certain number of days'), ('cleanup_activitystream', 'Remove activity stream entries older than a certain number of days'), ('cleanup_deleted', 'Purge previously deleted items from the database'), ('cleanup_facts', 'Purge and/or reduce the granularity of system tracking data')])),
('extra_vars', models.TextField(default='', blank=True)),
],
@@ -517,7 +517,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='SystemJobTemplate',
fields=[
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJobTemplate')),
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=django.db.models.deletion.CASCADE, serialize=False, to='main.UnifiedJobTemplate')),
('job_type', models.CharField(default='', max_length=32, blank=True, choices=[('cleanup_jobs', 'Remove jobs older than a certain number of days'), ('cleanup_activitystream', 'Remove activity stream entries older than a certain number of days'), ('cleanup_deleted', 'Purge previously deleted items from the database'), ('cleanup_facts', 'Purge and/or reduce the granularity of system tracking data')])),
],
bases=('main.unifiedjobtemplate', models.Model),
@@ -550,7 +550,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='unifiedjobtemplate',
name='polymorphic_ctype',
field=models.ForeignKey(related_name='polymorphic_main.unifiedjobtemplate_set+', editable=False, to='contenttypes.ContentType', null=True),
field=models.ForeignKey(related_name='polymorphic_main.unifiedjobtemplate_set+', editable=False, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', null=True),
),
migrations.AddField(
model_name='unifiedjobtemplate',
@@ -575,7 +575,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='unifiedjob',
name='polymorphic_ctype',
field=models.ForeignKey(related_name='polymorphic_main.unifiedjob_set+', editable=False, to='contenttypes.ContentType', null=True),
field=models.ForeignKey(related_name='polymorphic_main.unifiedjob_set+', editable=False, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', null=True),
),
migrations.AddField(
model_name='unifiedjob',
@@ -595,7 +595,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='schedule',
name='unified_job_template',
field=models.ForeignKey(related_name='schedules', to='main.UnifiedJobTemplate'),
field=models.ForeignKey(related_name='schedules', on_delete=django.db.models.deletion.CASCADE, to='main.UnifiedJobTemplate'),
),
migrations.AddField(
model_name='permission',
@@ -610,12 +610,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='joborigin',
name='unified_job',
field=models.OneToOneField(related_name='job_origin', to='main.UnifiedJob'),
field=models.OneToOneField(related_name='job_origin', on_delete=django.db.models.deletion.CASCADE, to='main.UnifiedJob'),
),
migrations.AddField(
model_name='inventory',
name='organization',
field=models.ForeignKey(related_name='inventories', to='main.Organization', help_text='Organization containing this inventory.'),
field=models.ForeignKey(related_name='inventories', on_delete=django.db.models.deletion.CASCADE, to='main.Organization', help_text='Organization containing this inventory.'),
),
migrations.AddField(
model_name='inventory',
@@ -625,7 +625,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='host',
name='inventory',
field=models.ForeignKey(related_name='hosts', to='main.Inventory'),
field=models.ForeignKey(related_name='hosts', on_delete=django.db.models.deletion.CASCADE, to='main.Inventory'),
),
migrations.AddField(
model_name='host',
@@ -650,7 +650,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='group',
name='inventory',
field=models.ForeignKey(related_name='groups', to='main.Inventory'),
field=models.ForeignKey(related_name='groups', on_delete=django.db.models.deletion.CASCADE, to='main.Inventory'),
),
migrations.AddField(
model_name='group',
@@ -680,12 +680,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='credential',
name='team',
field=models.ForeignKey(related_name='credentials', default=None, blank=True, to='main.Team', null=True),
field=models.ForeignKey(related_name='credentials', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.Team', null=True),
),
migrations.AddField(
model_name='credential',
name='user',
field=models.ForeignKey(related_name='credentials', default=None, blank=True, to=settings.AUTH_USER_MODEL, null=True),
field=models.ForeignKey(related_name='credentials', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to=settings.AUTH_USER_MODEL, null=True),
),
migrations.AddField(
model_name='adhoccommandevent',
@@ -774,7 +774,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='projectupdate',
name='project',
field=models.ForeignKey(related_name='project_updates', editable=False, to='main.Project'),
field=models.ForeignKey(related_name='project_updates', on_delete=django.db.models.deletion.CASCADE, editable=False, to='main.Project'),
),
migrations.AddField(
model_name='project',
@@ -814,12 +814,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='jobhostsummary',
name='job',
field=models.ForeignKey(related_name='job_host_summaries', editable=False, to='main.Job'),
field=models.ForeignKey(related_name='job_host_summaries', on_delete=django.db.models.deletion.CASCADE, editable=False, to='main.Job'),
),
migrations.AddField(
model_name='jobevent',
name='job',
field=models.ForeignKey(related_name='job_events', editable=False, to='main.Job'),
field=models.ForeignKey(related_name='job_events', on_delete=django.db.models.deletion.CASCADE, editable=False, to='main.Job'),
),
migrations.AddField(
model_name='job',
@@ -859,7 +859,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='inventoryupdate',
name='inventory_source',
field=models.ForeignKey(related_name='inventory_updates', editable=False, to='main.InventorySource'),
field=models.ForeignKey(related_name='inventory_updates', on_delete=django.db.models.deletion.CASCADE, editable=False, to='main.InventorySource'),
),
migrations.AddField(
model_name='inventoryupdate',
@@ -874,12 +874,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='inventorysource',
name='group',
field=awx.main.fields.AutoOneToOneField(related_name='inventory_source', null=True, default=None, editable=False, to='main.Group'),
field=awx.main.fields.AutoOneToOneField(related_name='inventory_source', on_delete=django.db.models.deletion.SET_NULL, null=True, default=None, editable=False, to='main.Group'),
),
migrations.AddField(
model_name='inventorysource',
name='inventory',
field=models.ForeignKey(related_name='inventory_sources', default=None, editable=False, to='main.Inventory', null=True),
field=models.ForeignKey(related_name='inventory_sources', on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to='main.Inventory', null=True),
),
migrations.AddField(
model_name='inventorysource',
@@ -916,7 +916,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='adhoccommandevent',
name='ad_hoc_command',
field=models.ForeignKey(related_name='ad_hoc_command_events', editable=False, to='main.AdHocCommand'),
field=models.ForeignKey(related_name='ad_hoc_command_events', on_delete=django.db.models.deletion.CASCADE, editable=False, to='main.AdHocCommand'),
),
migrations.AddField(
model_name='adhoccommand',

View File

@@ -13,7 +13,6 @@ from django.conf import settings
from django.utils.timezone import now
import jsonfield.fields
import jsonbfield.fields
import taggit.managers
@@ -144,7 +143,7 @@ class Migration(migrations.Migration):
('category', models.CharField(max_length=128)),
('value', models.TextField(blank=True)),
('value_type', models.CharField(max_length=12, choices=[('string', 'String'), ('int', 'Integer'), ('float', 'Decimal'), ('json', 'JSON'), ('bool', 'Boolean'), ('password', 'Password'), ('list', 'List')])),
('user', models.ForeignKey(related_name='settings', default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('user', models.ForeignKey(related_name='settings', default=None, editable=False, to=settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)),
],
),
# Notification changes
@@ -185,7 +184,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='notification',
name='notification_template',
field=models.ForeignKey(related_name='notifications', editable=False, to='main.NotificationTemplate'),
field=models.ForeignKey(related_name='notifications', editable=False, on_delete=models.CASCADE, to='main.NotificationTemplate'),
),
migrations.AddField(
model_name='activitystream',
@@ -239,8 +238,8 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('timestamp', models.DateTimeField(default=None, help_text='Date and time of the corresponding fact scan gathering time.', editable=False)),
('module', models.CharField(max_length=128)),
('facts', jsonbfield.fields.JSONField(default={}, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True)),
('host', models.ForeignKey(related_name='facts', to='main.Host', help_text='Host for the facts that the fact scan captured.')),
('facts', awx.main.fields.JSONBField(default=dict, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True)),
('host', models.ForeignKey(related_name='facts', to='main.Host', on_delete=models.CASCADE, help_text='Host for the facts that the fact scan captured.')),
],
),
migrations.AlterIndexTogether(
@@ -318,7 +317,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='project',
name='organization',
field=models.ForeignKey(related_name='projects', to='main.Organization', blank=True, null=True),
field=models.ForeignKey(related_name='projects', to='main.Organization', on_delete=models.CASCADE, blank=True, null=True),
),
migrations.AlterField(
model_name='team',
@@ -367,7 +366,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='credential',
name='organization',
field=models.ForeignKey(related_name='credentials', default=None, blank=True, to='main.Organization', null=True),
field=models.ForeignKey(related_name='credentials', on_delete=models.CASCADE, default=None, blank=True, to='main.Organization', null=True),
),
#
@@ -382,7 +381,7 @@ class Migration(migrations.Migration):
('members', models.ManyToManyField(related_name='roles', to=settings.AUTH_USER_MODEL)),
('parents', models.ManyToManyField(related_name='children', to='main.Role')),
('implicit_parents', models.TextField(default='[]')),
('content_type', models.ForeignKey(default=None, to='contenttypes.ContentType', null=True)),
('content_type', models.ForeignKey(default=None, to='contenttypes.ContentType', on_delete=models.CASCADE, null=True)),
('object_id', models.PositiveIntegerField(default=None, null=True)),
],
@@ -398,8 +397,8 @@ class Migration(migrations.Migration):
('role_field', models.TextField()),
('content_type_id', models.PositiveIntegerField()),
('object_id', models.PositiveIntegerField()),
('ancestor', models.ForeignKey(related_name='+', to='main.Role')),
('descendent', models.ForeignKey(related_name='+', to='main.Role')),
('ancestor', models.ForeignKey(on_delete=models.CASCADE, related_name='+', to='main.Role')),
('descendent', models.ForeignKey(on_delete=models.CASCADE, related_name='+', to='main.Role')),
],
options={
'db_table': 'main_rbac_role_ancestors',
@@ -569,7 +568,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=512)),
('created_by', models.ForeignKey(related_name="{u'class': 'label', u'app_label': 'main'}(class)s_created+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('modified_by', models.ForeignKey(related_name="{u'class': 'label', u'app_label': 'main'}(class)s_modified+", on_delete=django.db.models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('organization', models.ForeignKey(related_name='labels', to='main.Organization', help_text='Organization this label belongs to.')),
('organization', models.ForeignKey(related_name='labels', on_delete=django.db.models.deletion.CASCADE, to='main.Organization', help_text='Organization this label belongs to.')),
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')),
],
options={
@@ -599,12 +598,12 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='label',
name='organization',
field=models.ForeignKey(related_name='labels', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.Organization', help_text='Organization this label belongs to.', null=True),
field=models.ForeignKey(related_name='labels', on_delete=django.db.models.deletion.CASCADE, default=None, blank=True, to='main.Organization', help_text='Organization this label belongs to.', null=True),
),
migrations.AlterField(
model_name='label',
name='organization',
field=models.ForeignKey(related_name='labels', to='main.Organization', help_text='Organization this label belongs to.'),
field=models.ForeignKey(related_name='labels', on_delete=django.db.models.deletion.CASCADE, to='main.Organization', help_text='Organization this label belongs to.'),
),
# InventorySource Credential
migrations.AddField(
@@ -630,12 +629,12 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='credential',
name='deprecated_team',
field=models.ForeignKey(related_name='deprecated_credentials', default=None, blank=True, to='main.Team', null=True),
field=models.ForeignKey(related_name='deprecated_credentials', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.Team', null=True),
),
migrations.AlterField(
model_name='credential',
name='deprecated_user',
field=models.ForeignKey(related_name='deprecated_credentials', default=None, blank=True, to=settings.AUTH_USER_MODEL, null=True),
field=models.ForeignKey(related_name='deprecated_credentials', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to=settings.AUTH_USER_MODEL, null=True),
),
migrations.AlterField(
model_name='credential',

View File

@@ -116,7 +116,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='team',
name='organization',
field=models.ForeignKey(related_name='teams', to='main.Organization'),
field=models.ForeignKey(related_name='teams', on_delete=models.CASCADE, to='main.Organization'),
preserve_default=False,
),
] + _squashed.operations(SQUASHED_30, applied=True)

View File

@@ -74,7 +74,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='WorkflowJob',
fields=[
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJob')),
('unifiedjob_ptr', models.OneToOneField(parent_link=True, auto_created=True, on_delete=models.CASCADE, primary_key=True, serialize=False, to='main.UnifiedJob')),
('extra_vars', models.TextField(default='', blank=True)),
],
options={
@@ -100,7 +100,7 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='WorkflowJobTemplate',
fields=[
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='main.UnifiedJobTemplate')),
('unifiedjobtemplate_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, on_delete=models.CASCADE, serialize=False, to='main.UnifiedJobTemplate')),
('extra_vars', models.TextField(default='', blank=True)),
('admin_role', awx.main.fields.ImplicitRoleField(related_name='+', parent_role='singleton:system_administrator', to='main.Role', null='True')),
],
@@ -116,7 +116,7 @@ class Migration(migrations.Migration):
('failure_nodes', models.ManyToManyField(related_name='workflowjobtemplatenodes_failure', to='main.WorkflowJobTemplateNode', blank=True)),
('success_nodes', models.ManyToManyField(related_name='workflowjobtemplatenodes_success', to='main.WorkflowJobTemplateNode', blank=True)),
('unified_job_template', models.ForeignKey(related_name='workflowjobtemplatenodes', on_delete=django.db.models.deletion.SET_NULL, default=None, blank=True, to='main.UnifiedJobTemplate', null=True)),
('workflow_job_template', models.ForeignKey(related_name='workflow_job_template_nodes', default=None, blank=True, to='main.WorkflowJobTemplate', null=True)),
('workflow_job_template', models.ForeignKey(related_name='workflow_job_template_nodes', on_delete=models.SET_NULL, default=None, blank=True, to='main.WorkflowJobTemplate', null=True)),
],
options={
'abstract': False,
@@ -161,7 +161,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjobnode',
name='char_prompts',
field=jsonfield.fields.JSONField(default={}, blank=True),
field=jsonfield.fields.JSONField(default=dict, blank=True),
),
migrations.AddField(
model_name='workflowjobnode',
@@ -191,7 +191,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjobtemplatenode',
name='char_prompts',
field=jsonfield.fields.JSONField(default={}, blank=True),
field=jsonfield.fields.JSONField(default=dict, blank=True),
),
migrations.AddField(
model_name='workflowjobtemplatenode',
@@ -211,7 +211,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='workflowjobnode',
name='workflow_job',
field=models.ForeignKey(related_name='workflow_job_nodes', default=None, blank=True, to='main.WorkflowJob', null=True),
field=models.ForeignKey(related_name='workflow_job_nodes', on_delete=django.db.models.deletion.CASCADE, default=None, blank=True, to='main.WorkflowJob', null=True),
),
migrations.AlterField(
model_name='workflowjobtemplate',
@@ -227,12 +227,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='job',
name='artifacts',
field=jsonfield.fields.JSONField(default={}, editable=False, blank=True),
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AddField(
model_name='workflowjobnode',
name='ancestor_artifacts',
field=jsonfield.fields.JSONField(default={}, editable=False, blank=True),
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
),
# Job timeout settings
migrations.AddField(
@@ -397,7 +397,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjob',
name='survey_passwords',
field=jsonfield.fields.JSONField(default={}, editable=False, blank=True),
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AddField(
model_name='workflowjobtemplate',
@@ -407,33 +407,33 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjobtemplate',
name='survey_spec',
field=jsonfield.fields.JSONField(default={}, blank=True),
field=jsonfield.fields.JSONField(default=dict, blank=True),
),
# JSON field changes
migrations.AlterField(
model_name='adhoccommandevent',
name='event_data',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AlterField(
model_name='job',
name='artifacts',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AlterField(
model_name='job',
name='survey_passwords',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AlterField(
model_name='jobevent',
name='event_data',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AlterField(
model_name='jobtemplate',
name='survey_spec',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AlterField(
model_name='notification',
@@ -453,37 +453,37 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='schedule',
name='extra_data',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AlterField(
model_name='unifiedjob',
name='job_env',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AlterField(
model_name='workflowjob',
name='survey_passwords',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AlterField(
model_name='workflowjobnode',
name='ancestor_artifacts',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AlterField(
model_name='workflowjobnode',
name='char_prompts',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AlterField(
model_name='workflowjobtemplate',
name='survey_spec',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AlterField(
model_name='workflowjobtemplatenode',
name='char_prompts',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
# Job Project Update
migrations.AddField(

View File

@@ -55,12 +55,12 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='inventorysource',
name='deprecated_group',
field=models.OneToOneField(related_name='deprecated_inventory_source', null=True, default=None, to='main.Group'),
field=models.OneToOneField(related_name='deprecated_inventory_source', on_delete=models.CASCADE, null=True, default=None, to='main.Group'),
),
migrations.AlterField(
model_name='inventorysource',
name='inventory',
field=models.ForeignKey(related_name='inventory_sources', default=None, to='main.Inventory', null=True),
field=models.ForeignKey(related_name='inventory_sources', default=None, to='main.Inventory', on_delete=models.CASCADE, null=True),
),
# Smart Inventory
@@ -78,13 +78,13 @@ class Migration(migrations.Migration):
name='SmartInventoryMembership',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('host', models.ForeignKey(related_name='+', to='main.Host')),
('host', models.ForeignKey(related_name='+', on_delete=models.CASCADE, to='main.Host')),
],
),
migrations.AddField(
model_name='smartinventorymembership',
name='inventory',
field=models.ForeignKey(related_name='+', to='main.Inventory'),
field=models.ForeignKey(on_delete=models.CASCADE, related_name='+', to='main.Inventory'),
),
migrations.AddField(
model_name='host',
@@ -105,19 +105,19 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='inventory',
name='organization',
field=models.ForeignKey(related_name='inventories', on_delete=models.deletion.SET_NULL, to='main.Organization', help_text='Organization containing this inventory.', null=True),
field=models.ForeignKey(related_name='inventories', on_delete=models.SET_NULL, to='main.Organization', help_text='Organization containing this inventory.', null=True),
),
# Facts
migrations.AlterField(
model_name='fact',
name='facts',
field=awx.main.fields.JSONBField(default={}, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True),
field=awx.main.fields.JSONBField(default=dict, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True),
),
migrations.AddField(
model_name='host',
name='ansible_facts',
field=awx.main.fields.JSONBField(default={}, help_text='Arbitrary JSON structure of most recent ansible_facts, per-host.', blank=True),
field=awx.main.fields.JSONBField(default=dict, help_text='Arbitrary JSON structure of most recent ansible_facts, per-host.', blank=True),
),
migrations.AddField(
model_name='host',
@@ -148,12 +148,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='inventorysource',
name='source_project',
field=models.ForeignKey(related_name='scm_inventory_sources', default=None, blank=True, to='main.Project', help_text='Project containing inventory file used as source.', null=True),
field=models.ForeignKey(related_name='scm_inventory_sources', on_delete=models.CASCADE, default=None, blank=True, to='main.Project', help_text='Project containing inventory file used as source.', null=True),
),
migrations.AddField(
model_name='inventoryupdate',
name='source_project_update',
field=models.ForeignKey(related_name='scm_inventory_updates', default=None, blank=True, to='main.ProjectUpdate', help_text='Inventory files from this Project Update were used for the inventory update.', null=True),
field=models.ForeignKey(related_name='scm_inventory_updates', on_delete=models.CASCADE, default=None, blank=True, to='main.ProjectUpdate', help_text='Inventory files from this Project Update were used for the inventory update.', null=True),
),
migrations.AddField(
model_name='project',
@@ -200,7 +200,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='notificationtemplate',
name='organization',
field=models.ForeignKey(related_name='notification_templates', to='main.Organization', null=True),
field=models.ForeignKey(related_name='notification_templates', on_delete=models.CASCADE, to='main.Organization', null=True),
),
migrations.AlterUniqueTogether(
name='notificationtemplate',
@@ -312,7 +312,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='inventory',
name='insights_credential',
field=models.ForeignKey(related_name='insights_inventories', on_delete=models.deletion.SET_NULL, default=None, blank=True, to='main.Credential', help_text='Credentials to be used by hosts belonging to this inventory when accessing Red Hat Insights API.', null=True),
field=models.ForeignKey(related_name='insights_inventories', on_delete=models.SET_NULL, default=None, blank=True, to='main.Credential', help_text='Credentials to be used by hosts belonging to this inventory when accessing Red Hat Insights API.', null=True),
),
migrations.AlterField(
model_name='inventory',
@@ -382,10 +382,10 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=512)),
('kind', models.CharField(max_length=32, choices=[('ssh', 'Machine'), ('vault', 'Vault'), ('net', 'Network'), ('scm', 'Source Control'), ('cloud', 'Cloud'), ('insights', 'Insights')])),
('managed_by_tower', models.BooleanField(default=False, editable=False)),
('inputs', awx.main.fields.CredentialTypeInputField(default={}, blank=True, help_text='Enter inputs using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.')),
('injectors', awx.main.fields.CredentialTypeInjectorField(default={}, blank=True, help_text='Enter injectors using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.')),
('created_by', models.ForeignKey(related_name="{u'class': 'credentialtype', u'app_label': 'main'}(class)s_created+", on_delete=models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('modified_by', models.ForeignKey(related_name="{u'class': 'credentialtype', u'app_label': 'main'}(class)s_modified+", on_delete=models.deletion.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('inputs', awx.main.fields.CredentialTypeInputField(default=dict, blank=True, help_text='Enter inputs using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.')),
('injectors', awx.main.fields.CredentialTypeInjectorField(default=dict, blank=True, help_text='Enter injectors using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.')),
('created_by', models.ForeignKey(related_name="{u'class': 'credentialtype', u'app_label': 'main'}(class)s_created+", on_delete=models.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('modified_by', models.ForeignKey(related_name="{u'class': 'credentialtype', u'app_label': 'main'}(class)s_modified+", on_delete=models.SET_NULL, default=None, editable=False, to=settings.AUTH_USER_MODEL, null=True)),
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', blank=True, help_text='A comma-separated list of tags.', verbose_name='Tags')),
],
options={
@@ -399,23 +399,23 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='credential',
name='inputs',
field=awx.main.fields.CredentialInputField(default={}, blank=True),
field=awx.main.fields.CredentialInputField(default=dict, blank=True),
),
migrations.AddField(
model_name='credential',
name='credential_type',
field=models.ForeignKey(related_name='credentials', to='main.CredentialType', null=True),
field=models.ForeignKey(related_name='credentials', on_delete=models.CASCADE, to='main.CredentialType', null=True),
preserve_default=False,
),
migrations.AddField(
model_name='job',
name='vault_credential',
field=models.ForeignKey(related_name='jobs_as_vault_credential+', on_delete=models.deletion.SET_NULL, default=None, blank=True, to='main.Credential', null=True),
field=models.ForeignKey(related_name='jobs_as_vault_credential+', on_delete=models.SET_NULL, default=None, blank=True, to='main.Credential', null=True),
),
migrations.AddField(
model_name='jobtemplate',
name='vault_credential',
field=models.ForeignKey(related_name='jobtemplates_as_vault_credential+', on_delete=models.deletion.SET_NULL, default=None, blank=True, to='main.Credential', null=True),
field=models.ForeignKey(related_name='jobtemplates_as_vault_credential+', on_delete=models.SET_NULL, default=None, blank=True, to='main.Credential', null=True),
),
migrations.AddField(
model_name='job',
@@ -452,7 +452,7 @@ class Migration(migrations.Migration):
('name', models.CharField(unique=True, max_length=250)),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('controller', models.ForeignKey(related_name='controlled_groups', default=None, editable=False, to='main.InstanceGroup', help_text='Instance Group to remotely control this group.', null=True)),
('controller', models.ForeignKey(related_name='controlled_groups', on_delete=models.CASCADE, default=None, editable=False, to='main.InstanceGroup', help_text='Instance Group to remotely control this group.', null=True)),
('instances', models.ManyToManyField(help_text='Instances that are members of this InstanceGroup', related_name='rampart_groups', editable=False, to='main.Instance')),
],
),
@@ -464,7 +464,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='unifiedjob',
name='instance_group',
field=models.ForeignKey(on_delete=models.deletion.SET_NULL, default=None, blank=True, to='main.InstanceGroup', help_text='The Rampart/Instance group the job was run under', null=True),
field=models.ForeignKey(on_delete=models.SET_NULL, default=None, blank=True, to='main.InstanceGroup', help_text='The Rampart/Instance group the job was run under', null=True),
),
migrations.AddField(
model_name='unifiedjobtemplate',

View File

@@ -103,12 +103,12 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='credential',
name='credential_type',
field=models.ForeignKey(related_name='credentials', to='main.CredentialType', null=False, help_text='Specify the type of credential you want to create. Refer to the Ansible Tower documentation for details on each type.')
field=models.ForeignKey(related_name='credentials', to='main.CredentialType', on_delete=models.CASCADE, null=False, help_text='Specify the type of credential you want to create. Refer to the Ansible Tower documentation for details on each type.')
),
migrations.AlterField(
model_name='credential',
name='inputs',
field=awx.main.fields.CredentialInputField(default={}, help_text='Enter inputs using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.', blank=True),
field=awx.main.fields.CredentialInputField(default=dict, help_text='Enter inputs using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.', blank=True),
),
migrations.RemoveField(
model_name='job',

View File

@@ -20,7 +20,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='schedule',
name='char_prompts',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AddField(
model_name='schedule',
@@ -35,7 +35,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='schedule',
name='survey_passwords',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AddField(
model_name='workflowjobnode',
@@ -45,12 +45,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjobnode',
name='extra_data',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AddField(
model_name='workflowjobnode',
name='survey_passwords',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
migrations.AddField(
model_name='workflowjobtemplatenode',
@@ -60,12 +60,12 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjobtemplatenode',
name='extra_data',
field=awx.main.fields.JSONField(default={}, blank=True),
field=awx.main.fields.JSONField(default=dict, blank=True),
),
migrations.AddField(
model_name='workflowjobtemplatenode',
name='survey_passwords',
field=awx.main.fields.JSONField(default={}, editable=False, blank=True),
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
),
# Run data migration before removing the old credential field
migrations.RunPython(migration_utils.set_current_apps_for_migrations, migrations.RunPython.noop),
@@ -83,9 +83,9 @@ class Migration(migrations.Migration):
name='JobLaunchConfig',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extra_data', awx.main.fields.JSONField(blank=True, default={})),
('survey_passwords', awx.main.fields.JSONField(blank=True, default={}, editable=False)),
('char_prompts', awx.main.fields.JSONField(blank=True, default={})),
('extra_data', awx.main.fields.JSONField(blank=True, default=dict)),
('survey_passwords', awx.main.fields.JSONField(blank=True, default=dict, editable=False)),
('char_prompts', awx.main.fields.JSONField(blank=True, default=dict)),
('credentials', models.ManyToManyField(related_name='joblaunchconfigs', to='main.Credential')),
('inventory', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='joblaunchconfigs', to='main.Inventory')),
('job', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='launch_config', to='main.UnifiedJob')),
@@ -94,51 +94,51 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjobtemplate',
name='ask_variables_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_credential_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_diff_mode_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_inventory_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_job_type_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_limit_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_skip_tags_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_tags_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_variables_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AlterField(
model_name='jobtemplate',
name='ask_verbosity_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
]

View File

@@ -20,7 +20,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=None, editable=False)),
('modified', models.DateTimeField(default=None, editable=False)),
('event_data', awx.main.fields.JSONField(blank=True, default={})),
('event_data', awx.main.fields.JSONField(blank=True, default=dict)),
('uuid', models.CharField(default='', editable=False, max_length=1024)),
('counter', models.PositiveIntegerField(default=0, editable=False)),
('stdout', models.TextField(default='', editable=False)),
@@ -40,7 +40,7 @@ class Migration(migrations.Migration):
('created', models.DateTimeField(default=None, editable=False)),
('modified', models.DateTimeField(default=None, editable=False)),
('event', models.CharField(choices=[('runner_on_failed', 'Host Failed'), ('runner_on_ok', 'Host OK'), ('runner_on_error', 'Host Failure'), ('runner_on_skipped', 'Host Skipped'), ('runner_on_unreachable', 'Host Unreachable'), ('runner_on_no_hosts', 'No Hosts Remaining'), ('runner_on_async_poll', 'Host Polling'), ('runner_on_async_ok', 'Host Async OK'), ('runner_on_async_failed', 'Host Async Failure'), ('runner_item_on_ok', 'Item OK'), ('runner_item_on_failed', 'Item Failed'), ('runner_item_on_skipped', 'Item Skipped'), ('runner_retry', 'Host Retry'), ('runner_on_file_diff', 'File Difference'), ('playbook_on_start', 'Playbook Started'), ('playbook_on_notify', 'Running Handlers'), ('playbook_on_include', 'Including File'), ('playbook_on_no_hosts_matched', 'No Hosts Matched'), ('playbook_on_no_hosts_remaining', 'No Hosts Remaining'), ('playbook_on_task_start', 'Task Started'), ('playbook_on_vars_prompt', 'Variables Prompted'), ('playbook_on_setup', 'Gathering Facts'), ('playbook_on_import_for_host', 'internal: on Import for Host'), ('playbook_on_not_import_for_host', 'internal: on Not Import for Host'), ('playbook_on_play_start', 'Play Started'), ('playbook_on_stats', 'Playbook Complete'), ('debug', 'Debug'), ('verbose', 'Verbose'), ('deprecated', 'Deprecated'), ('warning', 'Warning'), ('system_warning', 'System Warning'), ('error', 'Error')], max_length=100)),
('event_data', awx.main.fields.JSONField(blank=True, default={})),
('event_data', awx.main.fields.JSONField(blank=True, default=dict)),
('failed', models.BooleanField(default=False, editable=False)),
('changed', models.BooleanField(default=False, editable=False)),
('uuid', models.CharField(default='', editable=False, max_length=1024)),
@@ -65,7 +65,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(default=None, editable=False)),
('modified', models.DateTimeField(default=None, editable=False)),
('event_data', awx.main.fields.JSONField(blank=True, default={})),
('event_data', awx.main.fields.JSONField(blank=True, default=dict)),
('uuid', models.CharField(default='', editable=False, max_length=1024)),
('counter', models.PositiveIntegerField(default=0, editable=False)),
('stdout', models.TextField(default='', editable=False)),

View File

@@ -17,7 +17,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjob',
name='char_prompts',
field=awx.main.fields.JSONField(blank=True, default={}),
field=awx.main.fields.JSONField(blank=True, default=dict),
),
migrations.AddField(
model_name='workflowjob',
@@ -27,7 +27,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='workflowjobtemplate',
name='ask_inventory_on_launch',
field=awx.main.fields.AskForField(default=False),
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AddField(
model_name='workflowjobtemplate',

View File

@@ -34,7 +34,7 @@ class Migration(migrations.Migration):
('modified', models.DateTimeField(default=None, editable=False)),
('description', models.TextField(blank=True, default='')),
('input_field_name', models.CharField(max_length=1024)),
('metadata', awx.main.fields.DynamicCredentialInputField(blank=True, default={})),
('metadata', awx.main.fields.DynamicCredentialInputField(blank=True, default=dict)),
('created_by', models.ForeignKey(default=None, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="{'class': 'credentialinputsource', 'model_name': 'credentialinputsource', 'app_label': 'main'}(class)s_created+", to=settings.AUTH_USER_MODEL)),
('modified_by', models.ForeignKey(default=None, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="{'class': 'credentialinputsource', 'model_name': 'credentialinputsource', 'app_label': 'main'}(class)s_modified+", to=settings.AUTH_USER_MODEL)),
('source_credential', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='target_input_sources', to='main.Credential')),

View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def add_webhook_notification_template_fields(apps, schema_editor):
# loop over all existing webhook notification templates and make
# sure they have the new "http_method" field filled in with "POST"
NotificationTemplate = apps.get_model('main', 'notificationtemplate')
webhooks = NotificationTemplate.objects.filter(notification_type='webhook')
for w in webhooks:
w.notification_configuration['http_method'] = 'POST'
w.save()
class Migration(migrations.Migration):
dependencies = [
('main', '0081_v360_notify_on_start'),
]
operations = [
migrations.RunPython(add_webhook_notification_template_fields, migrations.RunPython.noop),
]

View File

@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-14 15:08
from __future__ import unicode_literals
import awx.main.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0082_v360_webhook_http_method'),
]
operations = [
# Add fields for user-provided project refspec
migrations.AddField(
model_name='project',
name='scm_refspec',
field=models.CharField(blank=True, default='', help_text='For git projects, an additional refspec to fetch.', max_length=1024, verbose_name='SCM refspec'),
),
migrations.AddField(
model_name='projectupdate',
name='scm_refspec',
field=models.CharField(blank=True, default='', help_text='For git projects, an additional refspec to fetch.', max_length=1024, verbose_name='SCM refspec'),
),
# Add fields for job specification of project branch
migrations.AddField(
model_name='job',
name='scm_branch',
field=models.CharField(blank=True, default='', help_text='Branch to use in job run. Project default used if blank. Only allowed if project allow_override field is set to true.', max_length=1024),
),
migrations.AddField(
model_name='jobtemplate',
name='ask_scm_branch_on_launch',
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AddField(
model_name='jobtemplate',
name='scm_branch',
field=models.CharField(blank=True, default='', help_text='Branch to use in job run. Project default used if blank. Only allowed if project allow_override field is set to true.', max_length=1024),
),
migrations.AddField(
model_name='project',
name='allow_override',
field=models.BooleanField(default=False, help_text='Allow changing the SCM branch or revision in a job template that uses this project.'),
),
# Fix typo in help_text
migrations.AlterField(
model_name='project',
name='scm_update_cache_timeout',
field=models.PositiveIntegerField(blank=True, default=0, help_text='The number of seconds after the last project update ran that a new project update will be launched as a job dependency.'),
),
# Start tracking the fetched revision on project update model
migrations.AddField(
model_name='projectupdate',
name='scm_revision',
field=models.CharField(blank=True, default='', editable=False, help_text='The SCM Revision discovered by this update for the given project and branch.', max_length=1024, verbose_name='SCM Revision'),
),
]

View File

@@ -0,0 +1,19 @@
# Generated by Django 2.2.4 on 2019-08-16 13:22
from django.db import migrations, models
import awx
class Migration(migrations.Migration):
dependencies = [
('main', '0083_v360_job_branch_override'),
]
operations = [
migrations.AlterField(
model_name='oauth2accesstoken',
name='description',
field=models.TextField(blank=True, default=''),
),
]

View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-06-10 16:56
from __future__ import unicode_literals
from django.db import migrations, models
import awx.main.fields
import awx.main.models.notifications
class Migration(migrations.Migration):
dependencies = [
('main', '0084_v360_token_description'),
]
operations = [
migrations.AddField(
model_name='notificationtemplate',
name='messages',
field=awx.main.fields.JSONField(default=awx.main.models.notifications.NotificationTemplate.default_messages,
help_text='Optional custom messages for notification template.',
null=True,
blank=True),
),
migrations.AlterField(
model_name='notification',
name='notification_type',
field=models.CharField(choices=[('email', 'Email'), ('grafana', 'Grafana'), ('hipchat', 'HipChat'), ('irc', 'IRC'), ('mattermost', 'Mattermost'), ('pagerduty', 'Pagerduty'), ('rocketchat', 'Rocket.Chat'), ('slack', 'Slack'), ('twilio', 'Twilio'), ('webhook', 'Webhook')], max_length=32),
),
migrations.AlterField(
model_name='notificationtemplate',
name='notification_type',
field=models.CharField(choices=[('email', 'Email'), ('grafana', 'Grafana'), ('hipchat', 'HipChat'), ('irc', 'IRC'), ('mattermost', 'Mattermost'), ('pagerduty', 'Pagerduty'), ('rocketchat', 'Rocket.Chat'), ('slack', 'Slack'), ('twilio', 'Twilio'), ('webhook', 'Webhook')], max_length=32),
),
]

View File

@@ -0,0 +1,83 @@
# Generated by Django 2.2.4 on 2019-08-02 17:51
import awx.main.fields
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('main', '0085_v360_add_notificationtemplate_messages'),
]
operations = [
migrations.CreateModel(
name='WorkflowApprovalTemplate',
fields=[
('unifiedjobtemplate_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='main.UnifiedJobTemplate')),
('timeout', models.IntegerField(blank=True, default=0, help_text='The amount of time (in seconds) before the approval node expires and fails.')),
],
bases=('main.unifiedjobtemplate',),
),
migrations.AddField(
model_name='organization',
name='approval_role',
field=awx.main.fields.ImplicitRoleField(editable=False, null='True', on_delete=django.db.models.deletion.CASCADE, parent_role='admin_role', related_name='+', to='main.Role'),
preserve_default='True',
),
migrations.AddField(
model_name='workflowjobtemplate',
name='approval_role',
field=awx.main.fields.ImplicitRoleField(editable=False, null='True', on_delete=django.db.models.deletion.CASCADE, parent_role=['organization.approval_role', 'admin_role'], related_name='+', to='main.Role'),
preserve_default='True',
),
migrations.AlterField(
model_name='workflowjobnode',
name='unified_job_template',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workflowjobnodes', to='main.UnifiedJobTemplate'),
),
migrations.AlterField(
model_name='workflowjobtemplatenode',
name='unified_job_template',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workflowjobtemplatenodes', to='main.UnifiedJobTemplate'),
),
migrations.CreateModel(
name='WorkflowApproval',
fields=[
('unifiedjob_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='main.UnifiedJob')),
('workflow_approval_template', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='approvals', to='main.WorkflowApprovalTemplate')),
],
bases=('main.unifiedjob',),
),
migrations.AddField(
model_name='activitystream',
name='workflow_approval',
field=models.ManyToManyField(blank=True, to='main.WorkflowApproval'),
),
migrations.AddField(
model_name='activitystream',
name='workflow_approval_template',
field=models.ManyToManyField(blank=True, to='main.WorkflowApprovalTemplate'),
),
migrations.AlterField(
model_name='organization',
name='read_role',
field=awx.main.fields.ImplicitRoleField(editable=False, null='True', on_delete=django.db.models.deletion.CASCADE, parent_role=['member_role', 'auditor_role', 'execute_role', 'project_admin_role', 'inventory_admin_role', 'workflow_admin_role', 'notification_admin_role', 'credential_admin_role', 'job_template_admin_role', 'approval_role'], related_name='+', to='main.Role'),
),
migrations.AlterField(
model_name='workflowjobtemplate',
name='read_role',
field=awx.main.fields.ImplicitRoleField(editable=False, null='True', on_delete=django.db.models.deletion.CASCADE, parent_role=['singleton:system_auditor', 'organization.auditor_role', 'execute_role', 'admin_role', 'approval_role'], related_name='+', to='main.Role'),
),
migrations.AddField(
model_name='workflowapproval',
name='timeout',
field=models.IntegerField(blank=True, default=0, help_text='The amount of time (in seconds) before the approval node expires and fails.'),
),
migrations.AddField(
model_name='workflowapproval',
name='timed_out',
field=models.BooleanField(default=False, help_text='Shows when an approval node (with a timeout assigned to it) has timed out.'),
),
]

View File

@@ -0,0 +1,29 @@
# Generated by Django 2.2.4 on 2019-08-27 21:50
import awx.main.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('main', '0086_v360_workflow_approval'),
]
operations = [
migrations.AlterField(
model_name='credential',
name='inputs',
field=awx.main.fields.CredentialInputField(blank=True, default=dict, help_text='Enter inputs using either JSON or YAML syntax. Refer to the Ansible Tower documentation for example syntax.'),
),
migrations.AlterField(
model_name='credentialtype',
name='injectors',
field=awx.main.fields.CredentialTypeInjectorField(blank=True, default=dict, help_text='Enter injectors using either JSON or YAML syntax. Refer to the Ansible Tower documentation for example syntax.'),
),
migrations.AlterField(
model_name='credentialtype',
name='inputs',
field=awx.main.fields.CredentialTypeInputField(blank=True, default=dict, help_text='Enter inputs using either JSON or YAML syntax. Refer to the Ansible Tower documentation for example syntax.'),
),
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 2.2.4 on 2019-09-10 21:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0087_v360_update_credential_injector_help_text'),
]
operations = [
migrations.AlterField(
model_name='unifiedjob',
name='finished',
field=models.DateTimeField(db_index=True, default=None, editable=False, help_text='The date and time the job finished execution.', null=True),
),
migrations.AlterField(
model_name='unifiedjob',
name='launch_type',
field=models.CharField(choices=[('manual', 'Manual'), ('relaunch', 'Relaunch'), ('callback', 'Callback'), ('scheduled', 'Scheduled'), ('dependency', 'Dependency'), ('workflow', 'Workflow'), ('sync', 'Sync'), ('scm', 'SCM Update')], db_index=True, default='manual', editable=False, max_length=20),
),
migrations.AlterField(
model_name='unifiedjob',
name='created',
field=models.DateTimeField(db_index=True, default=None, editable=False),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 2.2.4 on 2019-09-12 13:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0088_v360_dashboard_optimizations'),
]
operations = [
migrations.AlterField(
model_name='jobevent',
name='event',
field=models.CharField(choices=[('runner_on_failed', 'Host Failed'), ('runner_on_start', 'Host Started'), ('runner_on_ok', 'Host OK'), ('runner_on_error', 'Host Failure'), ('runner_on_skipped', 'Host Skipped'), ('runner_on_unreachable', 'Host Unreachable'), ('runner_on_no_hosts', 'No Hosts Remaining'), ('runner_on_async_poll', 'Host Polling'), ('runner_on_async_ok', 'Host Async OK'), ('runner_on_async_failed', 'Host Async Failure'), ('runner_item_on_ok', 'Item OK'), ('runner_item_on_failed', 'Item Failed'), ('runner_item_on_skipped', 'Item Skipped'), ('runner_retry', 'Host Retry'), ('runner_on_file_diff', 'File Difference'), ('playbook_on_start', 'Playbook Started'), ('playbook_on_notify', 'Running Handlers'), ('playbook_on_include', 'Including File'), ('playbook_on_no_hosts_matched', 'No Hosts Matched'), ('playbook_on_no_hosts_remaining', 'No Hosts Remaining'), ('playbook_on_task_start', 'Task Started'), ('playbook_on_vars_prompt', 'Variables Prompted'), ('playbook_on_setup', 'Gathering Facts'), ('playbook_on_import_for_host', 'internal: on Import for Host'), ('playbook_on_not_import_for_host', 'internal: on Not Import for Host'), ('playbook_on_play_start', 'Play Started'), ('playbook_on_stats', 'Playbook Complete'), ('debug', 'Debug'), ('verbose', 'Verbose'), ('deprecated', 'Deprecated'), ('warning', 'Warning'), ('system_warning', 'System Warning'), ('error', 'Error')], max_length=100),
),
migrations.AlterField(
model_name='projectupdateevent',
name='event',
field=models.CharField(choices=[('runner_on_failed', 'Host Failed'), ('runner_on_start', 'Host Started'), ('runner_on_ok', 'Host OK'), ('runner_on_error', 'Host Failure'), ('runner_on_skipped', 'Host Skipped'), ('runner_on_unreachable', 'Host Unreachable'), ('runner_on_no_hosts', 'No Hosts Remaining'), ('runner_on_async_poll', 'Host Polling'), ('runner_on_async_ok', 'Host Async OK'), ('runner_on_async_failed', 'Host Async Failure'), ('runner_item_on_ok', 'Item OK'), ('runner_item_on_failed', 'Item Failed'), ('runner_item_on_skipped', 'Item Skipped'), ('runner_retry', 'Host Retry'), ('runner_on_file_diff', 'File Difference'), ('playbook_on_start', 'Playbook Started'), ('playbook_on_notify', 'Running Handlers'), ('playbook_on_include', 'Including File'), ('playbook_on_no_hosts_matched', 'No Hosts Matched'), ('playbook_on_no_hosts_remaining', 'No Hosts Remaining'), ('playbook_on_task_start', 'Task Started'), ('playbook_on_vars_prompt', 'Variables Prompted'), ('playbook_on_setup', 'Gathering Facts'), ('playbook_on_import_for_host', 'internal: on Import for Host'), ('playbook_on_not_import_for_host', 'internal: on Not Import for Host'), ('playbook_on_play_start', 'Play Started'), ('playbook_on_stats', 'Playbook Complete'), ('debug', 'Debug'), ('verbose', 'Verbose'), ('deprecated', 'Deprecated'), ('warning', 'Warning'), ('system_warning', 'System Warning'), ('error', 'Error')], max_length=100),
),
]

View File

@@ -0,0 +1,59 @@
# Generated by Django 2.2.2 on 2019-07-23 17:56
import awx.main.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0089_v360_new_job_event_types'),
]
operations = [
migrations.AddField(
model_name='workflowjobtemplate',
name='ask_limit_on_launch',
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AddField(
model_name='workflowjobtemplate',
name='ask_scm_branch_on_launch',
field=awx.main.fields.AskForField(blank=True, default=False),
),
migrations.AddField(
model_name='workflowjobtemplate',
name='char_prompts',
field=awx.main.fields.JSONField(blank=True, default=dict),
),
migrations.AlterField(
model_name='joblaunchconfig',
name='inventory',
field=models.ForeignKey(blank=True, default=None, help_text='Inventory applied as a prompt, assuming job template prompts for inventory', null=True, on_delete=models.deletion.SET_NULL, related_name='joblaunchconfigs', to='main.Inventory'),
),
migrations.AlterField(
model_name='schedule',
name='inventory',
field=models.ForeignKey(blank=True, default=None, help_text='Inventory applied as a prompt, assuming job template prompts for inventory', null=True, on_delete=models.deletion.SET_NULL, related_name='schedules', to='main.Inventory'),
),
migrations.AlterField(
model_name='workflowjob',
name='inventory',
field=models.ForeignKey(blank=True, default=None, help_text='Inventory applied as a prompt, assuming job template prompts for inventory', null=True, on_delete=models.deletion.SET_NULL, related_name='workflowjobs', to='main.Inventory'),
),
migrations.AlterField(
model_name='workflowjobnode',
name='inventory',
field=models.ForeignKey(blank=True, default=None, help_text='Inventory applied as a prompt, assuming job template prompts for inventory', null=True, on_delete=models.deletion.SET_NULL, related_name='workflowjobnodes', to='main.Inventory'),
),
migrations.AlterField(
model_name='workflowjobtemplate',
name='inventory',
field=models.ForeignKey(blank=True, default=None, help_text='Inventory applied as a prompt, assuming job template prompts for inventory', null=True, on_delete=models.deletion.SET_NULL, related_name='workflowjobtemplates', to='main.Inventory'),
),
migrations.AlterField(
model_name='workflowjobtemplatenode',
name='inventory',
field=models.ForeignKey(blank=True, default=None, help_text='Inventory applied as a prompt, assuming job template prompts for inventory', null=True, on_delete=models.deletion.SET_NULL, related_name='workflowjobtemplatenodes', to='main.Inventory'),
),
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 2.2.4 on 2019-09-11 13:44
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0090_v360_WFJT_prompts'),
]
operations = [
migrations.AddField(
model_name='organization',
name='notification_templates_approvals',
field=models.ManyToManyField(blank=True, related_name='organization_notification_templates_for_approvals', to='main.NotificationTemplate'),
),
migrations.AddField(
model_name='workflowjobtemplate',
name='notification_templates_approvals',
field=models.ManyToManyField(blank=True, related_name='workflowjobtemplate_notification_templates_for_approvals', to='main.NotificationTemplate'),
),
migrations.AlterField(
model_name='workflowjobnode',
name='do_not_run',
field=models.BooleanField(default=False, help_text='Indicates that a job will not be created when True. Workflow runtime semantics will mark this True if the node is in a path that will decidedly not be ran. A value of False means the node may not run.'),
),
]

View File

@@ -0,0 +1,49 @@
# Generated by Django 2.2.4 on 2019-09-12 14:49
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('main', '0091_v360_approval_node_notifications'),
]
operations = [
migrations.AddField(
model_name='jobtemplate',
name='webhook_credential',
field=models.ForeignKey(blank=True, help_text='Personal Access Token for posting back the status to the service API', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='jobtemplates', to='main.Credential'),
),
migrations.AddField(
model_name='jobtemplate',
name='webhook_key',
field=models.CharField(blank=True, help_text='Shared secret that the webhook service will use to sign requests', max_length=64),
),
migrations.AddField(
model_name='jobtemplate',
name='webhook_service',
field=models.CharField(blank=True, choices=[('github', 'GitHub'), ('gitlab', 'GitLab')], help_text='Service that webhook requests will be accepted from', max_length=16),
),
migrations.AddField(
model_name='workflowjobtemplate',
name='webhook_credential',
field=models.ForeignKey(blank=True, help_text='Personal Access Token for posting back the status to the service API', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workflowjobtemplates', to='main.Credential'),
),
migrations.AddField(
model_name='workflowjobtemplate',
name='webhook_key',
field=models.CharField(blank=True, help_text='Shared secret that the webhook service will use to sign requests', max_length=64),
),
migrations.AddField(
model_name='workflowjobtemplate',
name='webhook_service',
field=models.CharField(blank=True, choices=[('github', 'GitHub'), ('gitlab', 'GitLab')], help_text='Service that webhook requests will be accepted from', max_length=16),
),
migrations.AlterField(
model_name='unifiedjob',
name='launch_type',
field=models.CharField(choices=[('manual', 'Manual'), ('relaunch', 'Relaunch'), ('callback', 'Callback'), ('scheduled', 'Scheduled'), ('dependency', 'Dependency'), ('workflow', 'Workflow'), ('webhook', 'Webhook'), ('sync', 'Sync'), ('scm', 'SCM Update')], db_index=True, default='manual', editable=False, max_length=20),
),
]

View File

@@ -0,0 +1,27 @@
# Generated by Django 2.2.4 on 2019-09-12 14:50
from django.db import migrations, models
from awx.main.models import CredentialType
from awx.main.utils.common import set_current_apps
def setup_tower_managed_defaults(apps, schema_editor):
set_current_apps(apps)
CredentialType.setup_tower_managed_defaults()
class Migration(migrations.Migration):
dependencies = [
('main', '0092_v360_webhook_mixin'),
]
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')], max_length=32),
),
migrations.RunPython(setup_tower_managed_defaults),
]

View File

@@ -0,0 +1,44 @@
# Generated by Django 2.2.4 on 2019-09-12 14:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('main', '0093_v360_personal_access_tokens'),
]
operations = [
migrations.AddField(
model_name='job',
name='webhook_credential',
field=models.ForeignKey(blank=True, help_text='Personal Access Token for posting back the status to the service API', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='jobs', to='main.Credential'),
),
migrations.AddField(
model_name='job',
name='webhook_guid',
field=models.CharField(blank=True, help_text='Unique identifier of the event that triggered this webhook', max_length=128),
),
migrations.AddField(
model_name='job',
name='webhook_service',
field=models.CharField(blank=True, choices=[('github', 'GitHub'), ('gitlab', 'GitLab')], help_text='Service that webhook requests will be accepted from', max_length=16),
),
migrations.AddField(
model_name='workflowjob',
name='webhook_credential',
field=models.ForeignKey(blank=True, help_text='Personal Access Token for posting back the status to the service API', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='workflowjobs', to='main.Credential'),
),
migrations.AddField(
model_name='workflowjob',
name='webhook_guid',
field=models.CharField(blank=True, help_text='Unique identifier of the event that triggered this webhook', max_length=128),
),
migrations.AddField(
model_name='workflowjob',
name='webhook_service',
field=models.CharField(blank=True, choices=[('github', 'GitHub'), ('gitlab', 'GitLab')], help_text='Service that webhook requests will be accepted from', max_length=16),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 2.2.4 on 2019-10-04 00:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0094_v360_webhook_mixin2'),
]
operations = [
migrations.AlterField(
model_name='instance',
name='version',
field=models.CharField(blank=True, max_length=120),
),
]

View File

@@ -0,0 +1,38 @@
# Generated by Django 2.2.4 on 2019-09-16 23:50
from django.db import migrations, models
import django.db.models.deletion
from awx.main.models import CredentialType
from awx.main.utils.common import set_current_apps
def create_new_credential_types(apps, schema_editor):
set_current_apps(apps)
CredentialType.setup_tower_managed_defaults()
class Migration(migrations.Migration):
dependencies = [
('main', '0095_v360_increase_instance_version_length'),
]
operations = [
migrations.AddField(
model_name='instancegroup',
name='credential',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='instancegroups', to='main.Credential'),
),
migrations.AddField(
model_name='instancegroup',
name='pod_spec_override',
field=models.TextField(blank=True, default=''),
),
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')], max_length=32),
),
migrations.RunPython(create_new_credential_types)
]

View File

@@ -0,0 +1,21 @@
# Generated by Django 2.2.4 on 2019-10-11 15:40
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('main', '0096_v360_container_groups'),
]
operations = [
migrations.AddField(
model_name='workflowapproval',
name='approved_or_denied_by',
field=models.ForeignKey(default=None, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="{'class': 'workflowapproval', 'model_name': 'workflowapproval', 'app_label': 'main'}(class)s_approved+", to=settings.AUTH_USER_MODEL),
),
]

View File

@@ -0,0 +1,31 @@
# Generated by Django 2.2.4 on 2019-10-16 19:51
from django.db import migrations
from awx.main.models import CredentialType
def update_cyberark_aim_name(apps, schema_editor):
CredentialType.setup_tower_managed_defaults()
aim_types = apps.get_model('main', 'CredentialType').objects.filter(
namespace='aim'
).order_by('id')
if aim_types.count() == 2:
original, renamed = aim_types.all()
apps.get_model('main', 'Credential').objects.filter(
credential_type_id=original.id
).update(
credential_type_id=renamed.id
)
original.delete()
class Migration(migrations.Migration):
dependencies = [
('main', '0097_v360_workflowapproval_approved_or_denied_by'),
]
operations = [
migrations.RunPython(update_cyberark_aim_name)
]

View File

@@ -1,17 +1,11 @@
import logging
from time import time
from django.utils.encoding import smart_text
from django.db import transaction
from django.db.models import Q
from django.db.utils import IntegrityError
from collections import defaultdict
from awx.main.utils import getattrd
from awx.main.models.rbac import Role, batch_role_ancestor_rebuilding
logger = logging.getLogger('rbac_migrations')
def create_roles(apps, schema_editor):
'''
Implicit role creation happens in our post_save hook for all of our
@@ -41,465 +35,19 @@ def create_roles(apps, schema_editor):
obj.save()
def migrate_users(apps, schema_editor):
User = apps.get_model('auth', "User")
Role = apps.get_model('main', "Role")
ContentType = apps.get_model('contenttypes', "ContentType")
user_content_type = ContentType.objects.get_for_model(User)
for user in User.objects.iterator():
user.save()
try:
Role.objects.get(content_type=user_content_type, object_id=user.id)
logger.info(smart_text(u"found existing role for user: {}".format(user.username)))
except Role.DoesNotExist:
role = Role.objects.create(
role_field='admin_role',
content_type = user_content_type,
object_id = user.id
)
role.members.add(user)
logger.info(smart_text(u"migrating to new role for user: {}".format(user.username)))
if user.is_superuser:
if Role.objects.filter(singleton_name='system_administrator').exists():
sa_role = Role.objects.get(singleton_name='system_administrator')
else:
sa_role = Role.objects.create(
singleton_name='system_administrator',
role_field='system_administrator'
)
sa_role.members.add(user)
logger.warning(smart_text(u"added superuser: {}".format(user.username)))
def migrate_organization(apps, schema_editor):
Organization = apps.get_model('main', "Organization")
for org in Organization.objects.iterator():
for admin in org.deprecated_admins.all():
org.admin_role.members.add(admin)
logger.info(smart_text(u"added admin: {}, {}".format(org.name, admin.username)))
for user in org.deprecated_users.all():
org.member_role.members.add(user)
logger.info(smart_text(u"added member: {}, {}".format(org.name, user.username)))
def migrate_team(apps, schema_editor):
Team = apps.get_model('main', 'Team')
for t in Team.objects.iterator():
for user in t.deprecated_users.all():
t.member_role.members.add(user)
logger.info(smart_text(u"team: {}, added user: {}".format(t.name, user.username)))
def attrfunc(attr_path):
'''attrfunc returns a function that will
attempt to use the attr_path to access the attribute
of an instance that is passed in to the returned function.
Example:
get_org = attrfunc('inventory.organization')
org = get_org(JobTemplateInstance)
'''
def attr(inst):
return getattrd(inst, attr_path)
return attr
def _update_credential_parents(org, cred):
cred.organization = org
cred.save()
def _discover_credentials(instances, cred, orgfunc):
'''_discover_credentials will find shared credentials across
organizations. If a shared credential is found, it will duplicate
the credential, ensure the proper role permissions are added to the new
credential, and update any references from the old to the newly created
credential.
instances is a list of all objects that were matched when filtered
with cred.
orgfunc is a function that when called with an instance from instances
will produce an Organization object.
'''
orgs = defaultdict(list)
for inst in instances:
try:
orgs[orgfunc(inst)].append(inst)
except AttributeError:
# JobTemplate.inventory can be NULL sometimes, eg when an inventory
# has been deleted. This protects against that.
pass
if len(orgs) == 1:
try:
_update_credential_parents(orgfunc(instances[0]), cred)
except AttributeError:
# JobTemplate.inventory can be NULL sometimes, eg when an inventory
# has been deleted. This protects against that.
pass
else:
for pos, org in enumerate(orgs):
if pos == 0:
_update_credential_parents(org, cred)
else:
# Create a new credential
cred.pk = None
cred.organization = None
cred.save()
cred.admin_role, cred.use_role = None, None
for i in orgs[org]:
i.credential = cred
i.save()
_update_credential_parents(org, cred)
def migrate_credential(apps, schema_editor):
Credential = apps.get_model('main', "Credential")
JobTemplate = apps.get_model('main', 'JobTemplate')
Project = apps.get_model('main', 'Project')
InventorySource = apps.get_model('main', 'InventorySource')
for cred in Credential.objects.iterator():
results = [x for x in JobTemplate.objects.filter(Q(credential=cred) | Q(cloud_credential=cred), inventory__isnull=False).all()] + \
[x for x in InventorySource.objects.filter(credential=cred).all()]
if cred.deprecated_team is not None and results:
if len(results) == 1:
_update_credential_parents(results[0].inventory.organization, cred)
else:
_discover_credentials(results, cred, attrfunc('inventory.organization'))
logger.info(smart_text(u"added Credential(name={}, kind={}, host={}) at organization level".format(cred.name, cred.kind, cred.host)))
projs = Project.objects.filter(credential=cred).all()
if cred.deprecated_team is not None and projs:
if len(projs) == 1:
_update_credential_parents(projs[0].organization, cred)
else:
_discover_credentials(projs, cred, attrfunc('organization'))
logger.info(smart_text(u"added Credential(name={}, kind={}, host={}) at organization level".format(cred.name, cred.kind, cred.host)))
if cred.deprecated_team is not None:
cred.deprecated_team.admin_role.children.add(cred.admin_role)
cred.deprecated_team.member_role.children.add(cred.use_role)
cred.save()
logger.info(smart_text(u"added Credential(name={}, kind={}, host={}) at user level".format(cred.name, cred.kind, cred.host)))
elif cred.deprecated_user is not None:
cred.admin_role.members.add(cred.deprecated_user)
cred.save()
logger.info(smart_text(u"added Credential(name={}, kind={}, host={}) at user level".format(cred.name, cred.kind, cred.host, )))
else:
logger.warning(smart_text(u"orphaned credential found Credential(name={}, kind={}, host={}), superuser only".format(cred.name, cred.kind, cred.host, )))
def migrate_inventory(apps, schema_editor):
Inventory = apps.get_model('main', 'Inventory')
Permission = apps.get_model('main', 'Permission')
def role_from_permission(perm):
if perm.permission_type == 'admin':
return inventory.admin_role
elif perm.permission_type == 'read':
return inventory.read_role
elif perm.permission_type == 'write':
return inventory.update_role
elif perm.permission_type == 'check' or perm.permission_type == 'run' or perm.permission_type == 'create':
# These permission types are handled differntly in RBAC now, nothing to migrate.
return False
else:
return None
for inventory in Inventory.objects.iterator():
for perm in Permission.objects.filter(inventory=inventory):
role = None
execrole = None
role = role_from_permission(perm)
if role is None:
raise Exception(smart_text(u'Unhandled permission type for inventory: {}'.format( perm.permission_type)))
if perm.run_ad_hoc_commands:
execrole = inventory.use_role
if perm.team:
if role:
perm.team.member_role.children.add(role)
if execrole:
perm.team.member_role.children.add(execrole)
logger.info(smart_text(u'added Team({}) access to Inventory({})'.format(perm.team.name, inventory.name)))
if perm.user:
if role:
role.members.add(perm.user)
if execrole:
execrole.members.add(perm.user)
logger.info(smart_text(u'added User({}) access to Inventory({})'.format(perm.user.username, inventory.name)))
def migrate_projects(apps, schema_editor):
'''
I can see projects when:
X I am a superuser.
X I am an admin in an organization associated with the project.
X I am a user in an organization associated with the project.
X I am on a team associated with the project.
X I have been explicitly granted permission to run/check jobs using the
project.
X I created the project but it isn't associated with an organization
I can change/delete when:
X I am a superuser.
X I am an admin in an organization associated with the project.
X I created the project but it isn't associated with an organization
'''
Project = apps.get_model('main', 'Project')
Permission = apps.get_model('main', 'Permission')
JobTemplate = apps.get_model('main', 'JobTemplate')
# Migrate projects to single organizations, duplicating as necessary
for project in Project.objects.iterator():
original_project_name = project.name
project_orgs = project.deprecated_organizations.distinct().all()
if len(project_orgs) >= 1:
first_org = None
for org in project_orgs:
if first_org is None:
# For the first org, re-use our existing Project object, so don't do the below duplication effort
first_org = org
if len(project_orgs) > 1:
project.name = smart_text(u'{} - {}'.format(first_org.name, original_project_name))
project.organization = first_org
project.save()
else:
new_prj = Project.objects.create(
created = project.created,
modified = project.modified,
polymorphic_ctype_id = project.polymorphic_ctype_id,
description = project.description,
name = smart_text(u'{} - {}'.format(org.name, original_project_name)),
old_pk = project.old_pk,
created_by_id = project.created_by_id,
modified_by_id = project.modified_by_id,
scm_type = project.scm_type,
scm_url = project.scm_url,
scm_branch = project.scm_branch,
scm_clean = project.scm_clean,
scm_delete_on_update = project.scm_delete_on_update,
scm_delete_on_next_update = project.scm_delete_on_next_update,
scm_update_on_launch = project.scm_update_on_launch,
scm_update_cache_timeout = project.scm_update_cache_timeout,
credential = project.credential,
organization = org
)
if project.scm_type == "":
new_prj.local_path = project.local_path
new_prj.save()
for team in project.deprecated_teams.iterator():
new_prj.deprecated_teams.add(team)
logger.warning(smart_text(u'cloning Project({}) onto {} as Project({})'.format(original_project_name, org, new_prj)))
job_templates = JobTemplate.objects.filter(project=project, inventory__organization=org).all()
for jt in job_templates:
jt.project = new_prj
jt.save()
for perm in Permission.objects.filter(project=project):
Permission.objects.create(
created = perm.created,
modified = perm.modified,
created_by = perm.created_by,
modified_by = perm.modified_by,
description = perm.description,
name = perm.name,
user = perm.user,
team = perm.team,
project = new_prj,
inventory = perm.inventory,
permission_type = perm.permission_type,
run_ad_hoc_commands = perm.run_ad_hoc_commands,
)
# Migrate permissions
for project in Project.objects.iterator():
if project.organization is None and project.created_by is not None:
project.admin_role.members.add(project.created_by)
logger.warn(smart_text(u'adding Project({}) admin: {}'.format(project.name, project.created_by.username)))
for team in project.deprecated_teams.all():
team.member_role.children.add(project.read_role)
logger.info(smart_text(u'adding Team({}) access for Project({})'.format(team.name, project.name)))
for perm in Permission.objects.filter(project=project):
if perm.permission_type == 'create':
role = project.use_role
else:
role = project.read_role
if perm.team:
perm.team.member_role.children.add(role)
logger.info(smart_text(u'adding Team({}) access for Project({})'.format(perm.team.name, project.name)))
if perm.user:
role.members.add(perm.user)
logger.info(smart_text(u'adding User({}) access for Project({})'.format(perm.user.username, project.name)))
if project.organization is not None:
for user in project.organization.deprecated_users.all():
if not (project.use_role.members.filter(pk=user.id).exists() or project.admin_role.members.filter(pk=user.id).exists()):
project.read_role.members.add(user)
logger.info(smart_text(u'adding Organization({}) member access to Project({})'.format(project.organization.name, project.name)))
def migrate_job_templates(apps, schema_editor):
'''
NOTE: This must be run after orgs, inventory, projects, credential, and
users have been migrated
'''
'''
I can see job templates when:
X I am a superuser.
- I can read the inventory, project and credential (which means I am an
org admin or member of a team with access to all of the above).
- I have permission explicitly granted to check/deploy with the inventory
and project.
#This does not mean I would be able to launch a job from the template or
#edit the template.
- access.py can_read for JobTemplate enforces that you can only
see it if you can launch it, so the above imply launch too
'''
'''
Tower administrators, organization administrators, and project
administrators, within a project under their purview, may create and modify
new job templates for that project.
When editing a job template, they may select among the inventory groups and
credentials in the organization for which they have usage permissions, or
they may leave either blank to be selected at runtime.
Additionally, they may specify one or more users/teams that have execution
permission for that job template, among the users/teams that are a member
of that project.
That execution permission is valid irrespective of any explicit permissions
the user has or has not been granted to the inventory group or credential
specified in the job template.
'''
User = apps.get_model('auth', 'User')
JobTemplate = apps.get_model('main', 'JobTemplate')
Team = apps.get_model('main', 'Team')
Permission = apps.get_model('main', 'Permission')
Credential = apps.get_model('main', 'Credential')
jt_queryset = JobTemplate.objects.select_related('inventory', 'project', 'inventory__organization', 'execute_role')
for jt in jt_queryset.iterator():
if jt.inventory is None:
# If inventory is None, then only system admins and org admins can
# do anything with the JT in 2.4
continue
jt_permission_qs = Permission.objects.filter(
inventory=jt.inventory,
project=jt.project,
)
inventory_permission_qs = Permission.objects.filter(
inventory=jt.inventory,
project__isnull=True,
)
team_create_permissions = set(
jt_permission_qs
.filter(permission_type__in=['create'])
.values_list('team__id', flat=True)
)
team_run_permissions = set(
jt_permission_qs
.filter(permission_type__in=['check', 'run'] if jt.job_type == 'check' else ['run'])
.values_list('team__id', flat=True)
)
user_create_permissions = set(
jt_permission_qs
.filter(permission_type__in=['create'])
.values_list('user__id', flat=True)
)
user_run_permissions = set(
jt_permission_qs
.filter(permission_type__in=['check', 'run'] if jt.job_type == 'check' else ['run'])
.values_list('user__id', flat=True)
)
team_inv_permissions = defaultdict(set)
user_inv_permissions = defaultdict(set)
for user_id, team_id, inventory_id in inventory_permission_qs.values_list('user_id', 'team_id', 'inventory_id'):
if user_id:
user_inv_permissions[user_id].add(inventory_id)
if team_id:
team_inv_permissions[team_id].add(inventory_id)
for team in Team.objects.filter(id__in=team_create_permissions).iterator():
if jt.inventory.id in team_inv_permissions[team.id] and \
((not jt.credential and not jt.cloud_credential) or
Credential.objects.filter(deprecated_team=team, jobtemplates=jt).exists()):
team.member_role.children.add(jt.admin_role)
logger.info(smart_text(u'transfering admin access on JobTemplate({}) to Team({})'.format(jt.name, team.name)))
for team in Team.objects.filter(id__in=team_run_permissions).iterator():
if jt.inventory.id in team_inv_permissions[team.id] and \
((not jt.credential and not jt.cloud_credential) or
Credential.objects.filter(deprecated_team=team, jobtemplates=jt).exists()):
team.member_role.children.add(jt.execute_role)
logger.info(smart_text(u'transfering execute access on JobTemplate({}) to Team({})'.format(jt.name, team.name)))
for user in User.objects.filter(id__in=user_create_permissions).iterator():
cred = jt.credential or jt.cloud_credential
if (jt.inventory.id in user_inv_permissions[user.id] or
any([jt.inventory.id in team_inv_permissions[team.id] for team in user.deprecated_teams.all()])) and \
(not cred or cred.deprecated_user == user or
(cred.deprecated_team and cred.deprecated_team.deprecated_users.filter(pk=user.id).exists())):
jt.admin_role.members.add(user)
logger.info(smart_text(u'transfering admin access on JobTemplate({}) to User({})'.format(jt.name, user.username)))
for user in User.objects.filter(id__in=user_run_permissions).iterator():
cred = jt.credential or jt.cloud_credential
if (jt.inventory.id in user_inv_permissions[user.id] or
any([jt.inventory.id in team_inv_permissions[team.id] for team in user.deprecated_teams.all()])) and \
(not cred or cred.deprecated_user == user or
(cred.deprecated_team and cred.deprecated_team.deprecated_users.filter(pk=user.id).exists())):
jt.execute_role.members.add(user)
logger.info(smart_text(u'transfering execute access on JobTemplate({}) to User({})'.format(jt.name, user.username)))
def rebuild_role_hierarchy(apps, schema_editor):
logger.info('Computing role roots..')
start = time()
roots = Role.objects \
.all() \
.values_list('id', flat=True)
stop = time()
logger.info('Found %d roots in %f seconds, rebuilding ancestry map' % (len(roots), stop - start))
start = time()
Role.rebuild_role_ancestor_list(roots, [])
stop = time()
logger.info('Rebuild completed in %f seconds' % (stop - start))
logger.info('Done.')
def infer_credential_org_from_team(apps, schema_editor):
Credential = apps.get_model('main', "Credential")
for cred in Credential.objects.exclude(deprecated_team__isnull=True):
try:
with transaction.atomic():
_update_credential_parents(cred.deprecated_team.organization, cred)
except IntegrityError:
logger.info("Organization<{}> credential for old Team<{}> credential already created".format(cred.deprecated_team.organization.pk, cred.pk))
logger.info('Computing role roots..')
start = time()
roots = Role.objects \
.all() \
.values_list('id', flat=True)
stop = time()
logger.info('Found %d roots in %f seconds, rebuilding ancestry map' % (len(roots), stop - start))
start = time()
Role.rebuild_role_ancestor_list(roots, [])
stop = time()
logger.info('Rebuild completed in %f seconds' % (stop - start))
logger.info('Done.')
def delete_all_user_roles(apps, schema_editor):

View File

@@ -30,7 +30,7 @@ SQUASHED_30 = {
migrations.AddField(
model_name='job',
name='survey_passwords',
field=jsonfield.fields.JSONField(default={}, editable=False, blank=True),
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
),
],
'0031_v302_migrate_survey_passwords': [

View File

@@ -7,7 +7,8 @@ from django.db.models.signals import pre_delete # noqa
# AWX
from awx.main.models.base import ( # noqa
BaseModel, PrimordialModel, prevent_search, CLOUD_INVENTORY_SOURCES, VERBOSITY_CHOICES
BaseModel, PrimordialModel, prevent_search, accepts_json,
CLOUD_INVENTORY_SOURCES, VERBOSITY_CHOICES
)
from awx.main.models.unified_jobs import ( # noqa
UnifiedJob, UnifiedJobTemplate, StdoutMaxBytesExceeded
@@ -48,11 +49,14 @@ from awx.main.models.mixins import ( # noqa
TaskManagerJobMixin, TaskManagerProjectUpdateMixin,
TaskManagerUnifiedJobMixin,
)
from awx.main.models.notifications import Notification, NotificationTemplate # noqa
from awx.main.models.notifications import ( # noqa
Notification, NotificationTemplate,
JobNotificationMixin
)
from awx.main.models.label import Label # noqa
from awx.main.models.workflow import ( # noqa
WorkflowJob, WorkflowJobNode, WorkflowJobOptions, WorkflowJobTemplate,
WorkflowJobTemplateNode,
WorkflowJobTemplateNode, WorkflowApproval, WorkflowApprovalTemplate,
)
from awx.main.models.channels import ChannelGroup # noqa
from awx.api.versioning import reverse
@@ -62,24 +66,6 @@ from awx.main.models.oauth import ( # noqa
from oauth2_provider.models import Grant, RefreshToken # noqa -- needed django-oauth-toolkit model migrations
# Monkeypatch Django serializer to ignore django-taggit fields (which break
# the dumpdata command; see https://github.com/alex/django-taggit/issues/155).
from django.core.serializers.python import Serializer as _PythonSerializer
_original_handle_m2m_field = _PythonSerializer.handle_m2m_field
def _new_handle_m2m_field(self, obj, field):
try:
field.rel.through._meta
except AttributeError:
return
return _original_handle_m2m_field(self, obj, field)
_PythonSerializer.handle_m2m_field = _new_handle_m2m_field
# Add custom methods to User model for permissions checks.
from django.contrib.auth.models import User # noqa
from awx.main.access import ( # noqa
@@ -140,25 +126,29 @@ def user_is_system_auditor(user):
@user_is_system_auditor.setter
def user_is_system_auditor(user, tf):
if user.id:
if tf:
role = Role.singleton('system_auditor')
# must check if member to not duplicate activity stream
if user not in role.members.all():
role.members.add(user)
user._is_system_auditor = True
else:
role = Role.singleton('system_auditor')
if user in role.members.all():
role.members.remove(user)
user._is_system_auditor = False
if not user.id:
# If the user doesn't have a primary key yet (i.e., this is the *first*
# time they've logged in, and we've just created the new User in this
# request), we need one to set up the system auditor role
user.save()
if tf:
role = Role.singleton('system_auditor')
# must check if member to not duplicate activity stream
if user not in role.members.all():
role.members.add(user)
user._is_system_auditor = True
else:
role = Role.singleton('system_auditor')
if user in role.members.all():
role.members.remove(user)
user._is_system_auditor = False
User.add_to_class('is_system_auditor', user_is_system_auditor)
def user_is_in_enterprise_category(user, category):
ret = (category,) in user.enterprise_auth.all().values_list('provider') and not user.has_usable_password()
ret = (category,) in user.enterprise_auth.values_list('provider') and not user.has_usable_password()
# NOTE: this if-else block ensures existing enterprise users are still able to
# log in. Remove it in a future release
if category == 'radius':
@@ -213,6 +203,8 @@ activity_stream_registrar.connect(User)
activity_stream_registrar.connect(WorkflowJobTemplate)
activity_stream_registrar.connect(WorkflowJobTemplateNode)
activity_stream_registrar.connect(WorkflowJob)
activity_stream_registrar.connect(WorkflowApproval)
activity_stream_registrar.connect(WorkflowApprovalTemplate)
activity_stream_registrar.connect(OAuth2Application)
activity_stream_registrar.connect(OAuth2AccessToken)
@@ -223,4 +215,3 @@ prevent_search(RefreshToken._meta.get_field('token'))
prevent_search(OAuth2Application._meta.get_field('client_secret'))
prevent_search(OAuth2Application._meta.get_field('client_id'))
prevent_search(Grant._meta.get_field('code'))

View File

@@ -4,6 +4,7 @@
# Tower
from awx.api.versioning import reverse
from awx.main.fields import JSONField
from awx.main.models.base import accepts_json
# Django
from django.db import models
@@ -34,7 +35,7 @@ class ActivityStream(models.Model):
actor = models.ForeignKey('auth.User', null=True, on_delete=models.SET_NULL, related_name='activity_stream')
operation = models.CharField(max_length=13, choices=OPERATION_CHOICES)
timestamp = models.DateTimeField(auto_now_add=True)
changes = models.TextField(blank=True)
changes = accepts_json(models.TextField(blank=True))
deleted_actor = JSONField(null=True)
action_node = models.CharField(
blank=True,
@@ -66,6 +67,8 @@ class ActivityStream(models.Model):
workflow_job_node = models.ManyToManyField("WorkflowJobNode", blank=True)
workflow_job_template = models.ManyToManyField("WorkflowJobTemplate", blank=True)
workflow_job = models.ManyToManyField("WorkflowJob", blank=True)
workflow_approval_template = models.ManyToManyField("WorkflowApprovalTemplate", blank=True)
workflow_approval = models.ManyToManyField("WorkflowApproval", blank=True)
unified_job_template = models.ManyToManyField("UnifiedJobTemplate", blank=True, related_name='activity_stream_as_unified_job_template+')
unified_job = models.ManyToManyField("UnifiedJob", blank=True, related_name='activity_stream_as_unified_job+')
ad_hoc_command = models.ManyToManyField("AdHocCommand", blank=True)

View File

@@ -150,6 +150,14 @@ class AdHocCommand(UnifiedJob, JobNotificationMixin):
def supports_isolation(cls):
return True
@property
def is_containerized(self):
return bool(self.instance_group and self.instance_group.is_containerized)
@property
def can_run_containerized(self):
return True
def get_absolute_url(self, request=None):
return reverse('api:ad_hoc_command_detail', kwargs={'pk': self.pk}, request=request)

View File

@@ -408,3 +408,14 @@ def prevent_search(relation):
"""
setattr(relation, '__prevent_search__', True)
return relation
def accepts_json(relation):
"""
Used to mark a model field as allowing JSON e.g,. JobTemplate.extra_vars
This is *mostly* used as a way to provide type hints for certain fields
so that HTTP OPTIONS reports the type data we need for the CLI to allow
JSON/YAML input.
"""
setattr(relation, '__accepts_json__', True)
return relation

View File

@@ -64,7 +64,7 @@ def build_safe_env(env):
for k, v in safe_env.items():
if k == 'AWS_ACCESS_KEY_ID':
continue
elif k.startswith('ANSIBLE_') and not k.startswith('ANSIBLE_NET'):
elif k.startswith('ANSIBLE_') and not k.startswith('ANSIBLE_NET') and not k.startswith('ANSIBLE_GALAXY_SERVER'):
continue
elif hidden_re.search(k):
safe_env[k] = HIDDEN_PASSWORD
@@ -105,10 +105,9 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
)
inputs = CredentialInputField(
blank=True,
default={},
help_text=_('Enter inputs using either JSON or YAML syntax. Use the '
'radio button to toggle between the two. Refer to the '
'Ansible Tower documentation for example syntax.')
default=dict,
help_text=_('Enter inputs using either JSON or YAML syntax. '
'Refer to the Ansible Tower documentation for example syntax.')
)
admin_role = ImplicitRoleField(
parent_role=[
@@ -136,6 +135,10 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
def cloud(self):
return self.credential_type.kind == 'cloud'
@property
def kubernetes(self):
return self.credential_type.kind == 'kubernetes'
def get_absolute_url(self, request=None):
return reverse('api:credential_detail', kwargs={'pk': self.pk}, request=request)
@@ -152,7 +155,7 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
@property
def has_encrypted_ssh_key_data(self):
try:
ssh_key_data = decrypt_field(self, 'ssh_key_data')
ssh_key_data = self.get_input('ssh_key_data')
except AttributeError:
return False
@@ -323,8 +326,10 @@ class CredentialType(CommonModelNameNotUnique):
('net', _('Network')),
('scm', _('Source Control')),
('cloud', _('Cloud')),
('token', _('Personal Access Token')),
('insights', _('Insights')),
('external', _('External')),
('kubernetes', _('Kubernetes')),
)
kind = models.CharField(
@@ -343,17 +348,15 @@ class CredentialType(CommonModelNameNotUnique):
)
inputs = CredentialTypeInputField(
blank=True,
default={},
help_text=_('Enter inputs using either JSON or YAML syntax. Use the '
'radio button to toggle between the two. Refer to the '
'Ansible Tower documentation for example syntax.')
default=dict,
help_text=_('Enter inputs using either JSON or YAML syntax. '
'Refer to the Ansible Tower documentation for example syntax.')
)
injectors = CredentialTypeInjectorField(
blank=True,
default={},
help_text=_('Enter injectors using either JSON or YAML syntax. Use the '
'radio button to toggle between the two. Refer to the '
'Ansible Tower documentation for example syntax.')
default=dict,
help_text=_('Enter injectors using either JSON or YAML syntax. '
'Refer to the Ansible Tower documentation for example syntax.')
)
@classmethod
@@ -636,9 +639,6 @@ ManagedCredentialType(
'secret': True,
'ask_at_runtime': True
}],
'dependencies': {
'ssh_key_unlock': ['ssh_key_data'],
}
}
)
@@ -670,9 +670,6 @@ ManagedCredentialType(
'type': 'string',
'secret': True
}],
'dependencies': {
'ssh_key_unlock': ['ssh_key_data'],
}
}
)
@@ -741,7 +738,6 @@ ManagedCredentialType(
'secret': True,
}],
'dependencies': {
'ssh_key_unlock': ['ssh_key_data'],
'authorize_password': ['authorize'],
},
'required': ['username'],
@@ -978,6 +974,40 @@ ManagedCredentialType(
}
)
ManagedCredentialType(
namespace='github_token',
kind='token',
name=ugettext_noop('GitHub Personal Access Token'),
managed_by_tower=True,
inputs={
'fields': [{
'id': 'token',
'label': ugettext_noop('Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('This token needs to come from your profile settings in GitHub')
}],
'required': ['token'],
},
)
ManagedCredentialType(
namespace='gitlab_token',
kind='token',
name=ugettext_noop('GitLab Personal Access Token'),
managed_by_tower=True,
inputs={
'fields': [{
'id': 'token',
'label': ugettext_noop('Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('This token needs to come from your profile settings in GitLab')
}],
'required': ['token'],
},
)
ManagedCredentialType(
namespace='insights',
kind='insights',
@@ -1093,6 +1123,38 @@ ManagedCredentialType(
)
ManagedCredentialType(
namespace='kubernetes_bearer_token',
kind='kubernetes',
name=ugettext_noop('OpenShift or Kubernetes API Bearer Token'),
inputs={
'fields': [{
'id': 'host',
'label': ugettext_noop('OpenShift or Kubernetes API Endpoint'),
'type': 'string',
'help_text': ugettext_noop('The OpenShift or Kubernetes API Endpoint to authenticate with.')
},{
'id': 'bearer_token',
'label': ugettext_noop('API authentication bearer token.'),
'type': 'string',
'secret': True,
},{
'id': 'verify_ssl',
'label': ugettext_noop('Verify SSL'),
'type': 'boolean',
'default': True,
},{
'id': 'ssl_ca_cert',
'label': ugettext_noop('Certificate Authority data'),
'type': 'string',
'secret': True,
'multiline': True,
}],
'required': ['host', 'bearer_token'],
}
)
class CredentialInputSource(PrimordialModel):
class Meta:
@@ -1117,7 +1179,7 @@ class CredentialInputSource(PrimordialModel):
)
metadata = DynamicCredentialInputField(
blank=True,
default={}
default=dict
)
def clean_target_credential(self):

View File

@@ -28,10 +28,7 @@ def gce(cred, env, private_data_dir):
if 'INVENTORY_UPDATE_ID' not in env:
env['GCE_EMAIL'] = username
env['GCE_PROJECT'] = project
else:
# gcp_compute inventory plugin requires token_uri
# although it probably should not, since gce_modules do not
json_cred['token_uri'] = 'https://oauth2.googleapis.com/token'
json_cred['token_uri'] = 'https://oauth2.googleapis.com/token'
handle, path = tempfile.mkstemp(dir=private_data_dir)
f = os.fdopen(handle, 'w')
@@ -39,6 +36,14 @@ def gce(cred, env, private_data_dir):
f.close()
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
env['GCE_CREDENTIALS_FILE_PATH'] = path
env['GCP_SERVICE_ACCOUNT_FILE'] = path
# Handle env variables for new module types.
# This includes gcp_compute inventory plugin and
# all new gcp_* modules.
env['GCP_AUTH_KIND'] = 'serviceaccount'
env['GCP_PROJECT'] = project
env['GCP_ENV_TYPE'] = 'tower'
return path

View File

@@ -83,6 +83,7 @@ class BasePlaybookEvent(CreatedModifiedModel):
# - runner_on*
# - playbook_on_task_start (once for each task within a play)
# - runner_on_failed
# - runner_on_start
# - runner_on_ok
# - runner_on_error (not used for v2)
# - runner_on_skipped
@@ -102,6 +103,7 @@ class BasePlaybookEvent(CreatedModifiedModel):
EVENT_TYPES = [
# (level, event, verbose name, failed)
(3, 'runner_on_failed', _('Host Failed'), True),
(3, 'runner_on_start', _('Host Started'), False),
(3, 'runner_on_ok', _('Host OK'), False),
(3, 'runner_on_error', _('Host Failure'), True),
(3, 'runner_on_skipped', _('Host Skipped'), False),
@@ -149,7 +151,7 @@ class BasePlaybookEvent(CreatedModifiedModel):
)
event_data = JSONField(
blank=True,
default={},
default=dict,
)
failed = models.BooleanField(
default=False,
@@ -322,7 +324,10 @@ class BasePlaybookEvent(CreatedModifiedModel):
kwargs.pop('created', None)
sanitize_event_keys(kwargs, cls.VALID_KEYS)
workflow_job_id = kwargs.pop('workflow_job_id', None)
job_event = cls.objects.create(**kwargs)
if workflow_job_id:
setattr(job_event, 'workflow_job_id', workflow_job_id)
analytics_logger.info('Event data saved.', extra=dict(python_objects=dict(job_event=job_event)))
return job_event
@@ -394,7 +399,7 @@ class JobEvent(BasePlaybookEvent):
An event/message logged from the callback when running a job.
'''
VALID_KEYS = BasePlaybookEvent.VALID_KEYS + ['job_id']
VALID_KEYS = BasePlaybookEvent.VALID_KEYS + ['job_id', 'workflow_job_id']
class Meta:
app_label = 'main'
@@ -528,7 +533,7 @@ class JobEvent(BasePlaybookEvent):
class ProjectUpdateEvent(BasePlaybookEvent):
VALID_KEYS = BasePlaybookEvent.VALID_KEYS + ['project_update_id']
VALID_KEYS = BasePlaybookEvent.VALID_KEYS + ['project_update_id', 'workflow_job_id']
class Meta:
app_label = 'main'
@@ -567,7 +572,7 @@ class BaseCommandEvent(CreatedModifiedModel):
event_data = JSONField(
blank=True,
default={},
default=dict,
)
uuid = models.CharField(
max_length=1024,
@@ -614,7 +619,14 @@ class BaseCommandEvent(CreatedModifiedModel):
kwargs.pop('created', None)
sanitize_event_keys(kwargs, cls.VALID_KEYS)
return cls.objects.create(**kwargs)
kwargs.pop('workflow_job_id', None)
event = cls.objects.create(**kwargs)
if isinstance(event, AdHocCommandEvent):
analytics_logger.info(
'Event data saved.',
extra=dict(python_objects=dict(job_event=event))
)
return event
def get_event_display(self):
'''
@@ -622,13 +634,16 @@ class BaseCommandEvent(CreatedModifiedModel):
'''
return self.event
def get_event_display2(self):
return self.get_event_display()
def get_host_status_counts(self):
return create_host_status_counts(getattr(self, 'event_data', {}))
class AdHocCommandEvent(BaseCommandEvent):
VALID_KEYS = BaseCommandEvent.VALID_KEYS + ['ad_hoc_command_id', 'event']
VALID_KEYS = BaseCommandEvent.VALID_KEYS + ['ad_hoc_command_id', 'event', 'workflow_job_id']
class Meta:
app_label = 'main'
@@ -736,7 +751,7 @@ class AdHocCommandEvent(BaseCommandEvent):
class InventoryUpdateEvent(BaseCommandEvent):
VALID_KEYS = BaseCommandEvent.VALID_KEYS + ['inventory_update_id']
VALID_KEYS = BaseCommandEvent.VALID_KEYS + ['inventory_update_id', 'workflow_job_id']
class Meta:
app_label = 'main'

View File

@@ -18,7 +18,7 @@ from awx import __version__ as awx_application_version
from awx.api.versioning import reverse
from awx.main.managers import InstanceManager, InstanceGroupManager
from awx.main.fields import JSONField
from awx.main.models.base import BaseModel, HasEditsMixin
from awx.main.models.base import BaseModel, HasEditsMixin, prevent_search
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
@@ -59,7 +59,7 @@ class Instance(HasPolicyEditsMixin, BaseModel):
null=True,
editable=False,
)
version = models.CharField(max_length=24, blank=True)
version = models.CharField(max_length=120, blank=True)
capacity = models.PositiveIntegerField(
default=100,
editable=False,
@@ -176,6 +176,18 @@ class InstanceGroup(HasPolicyEditsMixin, BaseModel, RelatedJobsMixin):
null=True,
on_delete=models.CASCADE
)
credential = models.ForeignKey(
'Credential',
related_name='%(class)ss',
blank=True,
null=True,
default=None,
on_delete=models.SET_NULL,
)
pod_spec_override = prevent_search(models.TextField(
blank=True,
default='',
))
policy_instance_percentage = models.IntegerField(
default=0,
help_text=_("Percentage of Instances to automatically assign to this group")
@@ -218,6 +230,10 @@ class InstanceGroup(HasPolicyEditsMixin, BaseModel, RelatedJobsMixin):
def is_isolated(self):
return bool(self.controller)
@property
def is_containerized(self):
return bool(self.credential and self.credential.kubernetes)
'''
RelatedJobsMixin
'''
@@ -271,7 +287,8 @@ def schedule_policy_task():
@receiver(post_save, sender=InstanceGroup)
def on_instance_group_saved(sender, instance, created=False, raw=False, **kwargs):
if created or instance.has_policy_changes():
schedule_policy_task()
if not instance.is_containerized:
schedule_policy_task()
@receiver(post_save, sender=Instance)
@@ -282,7 +299,8 @@ def on_instance_saved(sender, instance, created=False, raw=False, **kwargs):
@receiver(post_delete, sender=InstanceGroup)
def on_instance_group_deleted(sender, instance, using, **kwargs):
schedule_policy_task()
if not instance.is_containerized:
schedule_policy_task()
@receiver(post_delete, sender=Instance)

View File

@@ -45,7 +45,7 @@ from awx.main.models.base import (
CommonModelNameNotUnique,
VarsDictProperty,
CLOUD_INVENTORY_SOURCES,
prevent_search
prevent_search, accepts_json
)
from awx.main.models.events import InventoryUpdateEvent
from awx.main.models.unified_jobs import UnifiedJob, UnifiedJobTemplate
@@ -93,11 +93,11 @@ class Inventory(CommonModelNameNotUnique, ResourceMixin, RelatedJobsMixin):
on_delete=models.SET_NULL,
null=True,
)
variables = models.TextField(
variables = accepts_json(models.TextField(
blank=True,
default='',
help_text=_('Inventory variables in JSON or YAML format.'),
)
))
has_active_failures = models.BooleanField(
default=False,
editable=False,
@@ -309,7 +309,7 @@ class Inventory(CommonModelNameNotUnique, ResourceMixin, RelatedJobsMixin):
# Now use in-memory maps to build up group info.
all_group_names = []
for group in self.groups.only('name', 'id', 'variables'):
for group in self.groups.only('name', 'id', 'variables', 'inventory_id'):
group_info = dict()
if group.id in group_hosts_map:
group_info['hosts'] = group_hosts_map[group.id]
@@ -608,11 +608,11 @@ class Host(CommonModelNameNotUnique, RelatedJobsMixin):
default='',
help_text=_('The value used by the remote inventory source to uniquely identify the host'),
)
variables = models.TextField(
variables = accepts_json(models.TextField(
blank=True,
default='',
help_text=_('Host variables in JSON or YAML format.'),
)
))
last_job = models.ForeignKey(
'Job',
related_name='hosts_as_last_job+',
@@ -650,7 +650,7 @@ class Host(CommonModelNameNotUnique, RelatedJobsMixin):
)
ansible_facts = JSONBField(
blank=True,
default={},
default=dict,
help_text=_('Arbitrary JSON structure of most recent ansible_facts, per-host.'),
)
ansible_facts_modified = models.DateTimeField(
@@ -796,11 +796,11 @@ class Group(CommonModelNameNotUnique, RelatedJobsMixin):
related_name='children',
blank=True,
)
variables = models.TextField(
variables = accepts_json(models.TextField(
blank=True,
default='',
help_text=_('Group variables in JSON or YAML format.'),
)
))
hosts = models.ManyToManyField(
'Host',
related_name='groups',
@@ -1501,7 +1501,7 @@ class InventorySource(UnifiedJobTemplate, InventorySourceOptions, CustomVirtualE
@classmethod
def _get_unified_job_field_names(cls):
return set(f.name for f in InventorySourceOptions._meta.fields) | set(
['name', 'description', 'schedule', 'credentials', 'inventory']
['name', 'description', 'credentials', 'inventory']
)
def save(self, *args, **kwargs):
@@ -1991,6 +1991,8 @@ class azure_rm(PluginFileInjector):
source_vars = inventory_update.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 []'},
@@ -2046,8 +2048,10 @@ class azure_rm(PluginFileInjector):
'provisioning_state': 'provisioning_state | title',
'computer_name': 'name',
'type': 'resource_type',
'private_ip': 'private_ipv4_addresses[0]',
'public_ip': 'public_ipv4_addresses[0]',
'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
@@ -2330,6 +2334,12 @@ class gce(PluginFileInjector):
ini_env_reference = 'GCE_INI_PATH'
base_injector = 'managed'
def get_plugin_env(self, *args, **kwargs):
ret = super(gce, self).get_plugin_env(*args, **kwargs)
# We need native jinja2 types so that ip addresses can give JSON null value
ret['ANSIBLE_JINJA2_NATIVE'] = str(True)
return ret
def get_script_env(self, inventory_update, private_data_dir, private_data_files):
env = super(gce, self).get_script_env(inventory_update, private_data_dir, private_data_files)
cred = inventory_update.get_cloud_credential()
@@ -2350,7 +2360,7 @@ class gce(PluginFileInjector):
'gce_name': 'name',
'gce_network': 'networkInterfaces[0].network.name',
'gce_private_ip': 'networkInterfaces[0].networkIP',
'gce_public_ip': 'networkInterfaces[0].accessConfigs[0].natIP',
'gce_public_ip': 'networkInterfaces[0].accessConfigs[0].natIP | default(None)',
'gce_status': 'status',
'gce_subnetwork': 'networkInterfaces[0].subnetwork.name',
'gce_tags': 'tags.get("items", [])',
@@ -2360,7 +2370,7 @@ class gce(PluginFileInjector):
'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'
'ansible_ssh_host': 'networkInterfaces[0].accessConfigs[0].natIP | default(networkInterfaces[0].networkIP)'
}
def inventory_as_dict(self, inventory_update, private_data_dir):

View File

@@ -27,7 +27,7 @@ from rest_framework.exceptions import ParseError
from awx.api.versioning import reverse
from awx.main.models.base import (
BaseModel, CreatedModifiedModel,
prevent_search,
prevent_search, accepts_json,
JOB_TYPE_CHOICES, VERBOSITY_CHOICES,
VarsDictProperty
)
@@ -39,7 +39,7 @@ from awx.main.models.notifications import (
NotificationTemplate,
JobNotificationMixin,
)
from awx.main.utils import parse_yaml_or_json, getattr_dne
from awx.main.utils import parse_yaml_or_json, getattr_dne, NullablePromptPseudoField
from awx.main.fields import ImplicitRoleField, JSONField, AskForField
from awx.main.models.mixins import (
ResourceMixin,
@@ -48,6 +48,8 @@ from awx.main.models.mixins import (
TaskManagerJobMixin,
CustomVirtualEnvMixin,
RelatedJobsMixin,
WebhookMixin,
WebhookTemplateMixin,
)
@@ -96,6 +98,13 @@ class JobOptions(BaseModel):
default='',
blank=True,
)
scm_branch = models.CharField(
max_length=1024,
default='',
blank=True,
help_text=_('Branch to use in job run. Project default used if blank. '
'Only allowed if project allow_override field is set to true.'),
)
forks = models.PositiveIntegerField(
blank=True,
default=0,
@@ -109,10 +118,10 @@ class JobOptions(BaseModel):
blank=True,
default=0,
)
extra_vars = prevent_search(models.TextField(
extra_vars = prevent_search(accepts_json(models.TextField(
blank=True,
default='',
))
)))
job_tags = models.CharField(
max_length=1024,
blank=True,
@@ -180,7 +189,7 @@ class JobOptions(BaseModel):
return needed
class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, ResourceMixin, CustomVirtualEnvMixin, RelatedJobsMixin):
class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, ResourceMixin, CustomVirtualEnvMixin, RelatedJobsMixin, WebhookTemplateMixin):
'''
A job template is a reusable job definition for applying a project (with
playbook) to an inventory source with a given credential.
@@ -234,6 +243,11 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
default=False,
allows_field='credentials'
)
ask_scm_branch_on_launch = AskForField(
blank=True,
default=False,
allows_field='scm_branch'
)
job_slice_count = models.PositiveIntegerField(
blank=True,
default=1,
@@ -259,7 +273,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
@classmethod
def _get_unified_job_field_names(cls):
return set(f.name for f in JobOptions._meta.fields) | set(
['name', 'description', 'schedule', 'survey_passwords', 'labels', 'credentials',
['name', 'description', 'survey_passwords', 'labels', 'credentials',
'job_slice_number', 'job_slice_count']
)
@@ -387,7 +401,21 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
# no-op case: Fields the same as template's value
# counted as neither accepted or ignored
continue
elif field_name == 'scm_branch' and old_value == '' and self.project and new_value == self.project.scm_branch:
# special case of "not provided" for branches
# job template does not provide branch, runs with default branch
continue
elif getattr(self, ask_field_name):
# Special case where prompts can be rejected based on project setting
if field_name == 'scm_branch':
if not self.project:
rejected_data[field_name] = new_value
errors_dict[field_name] = _('Project is missing.')
continue
if kwargs['scm_branch'] != self.project.scm_branch and not self.project.allow_override:
rejected_data[field_name] = new_value
errors_dict[field_name] = _('Project does not allow override of branch.')
continue
# accepted prompt
prompted_data[field_name] = new_value
else:
@@ -396,7 +424,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
# Not considered an error for manual launch, to support old
# behavior of putting them in ignored_fields and launching anyway
if 'prompts' not in exclude_errors:
errors_dict[field_name] = _('Field is not configured to prompt on launch.').format(field_name=field_name)
errors_dict[field_name] = _('Field is not configured to prompt on launch.')
if ('prompts' not in exclude_errors and
(not getattr(self, 'ask_credential_on_launch', False)) and
@@ -458,7 +486,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
return UnifiedJob.objects.filter(unified_job_template=self)
class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskManagerJobMixin, CustomVirtualEnvMixin):
class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskManagerJobMixin, CustomVirtualEnvMixin, WebhookMixin):
'''
A job applies a project (with playbook) to an inventory source with a given
credential. It represents a single invocation of ansible-playbook with the
@@ -485,7 +513,7 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
)
artifacts = JSONField(
blank=True,
default={},
default=dict,
editable=False,
)
scm_revision = models.CharField(
@@ -601,15 +629,17 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
@property
def task_impact(self):
# NOTE: We sorta have to assume the host count matches and that forks default to 5
from awx.main.models.inventory import Host
if self.launch_type == 'callback':
count_hosts = 2
else:
count_hosts = Host.objects.filter(inventory__jobs__pk=self.pk).count()
if self.job_slice_count > 1:
# Integer division intentional
count_hosts = (count_hosts + self.job_slice_count - self.job_slice_number) // self.job_slice_count
# If for some reason we can't count the hosts then lets assume the impact as forks
if self.inventory is not None:
count_hosts = self.inventory.hosts.count()
if self.job_slice_count > 1:
# Integer division intentional
count_hosts = (count_hosts + self.job_slice_count - self.job_slice_number) // self.job_slice_count
else:
count_hosts = 5 if self.forks == 0 else self.forks
return min(count_hosts, 5 if self.forks == 0 else self.forks) + 1
@property
@@ -640,11 +670,19 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
def processed_hosts(self):
return self._get_hosts(job_host_summaries__processed__gt=0)
@property
def ignored_hosts(self):
return self._get_hosts(job_host_summaries__ignored__gt=0)
@property
def rescued_hosts(self):
return self._get_hosts(job_host_summaries__rescued__gt=0)
def notification_data(self, block=5):
data = super(Job, self).notification_data()
all_hosts = {}
# NOTE: Probably related to job event slowness, remove at some point -matburt
if block:
if block and self.status != 'running':
summaries = self.job_host_summaries.all()
while block > 0 and not len(summaries):
time.sleep(1)
@@ -658,7 +696,9 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
failures=h.failures,
ok=h.ok,
processed=h.processed,
skipped=h.skipped)
skipped=h.skipped,
rescued=h.rescued,
ignored=h.ignored)
data.update(dict(inventory=self.inventory.name if self.inventory else None,
project=self.project.name if self.project else None,
playbook=self.playbook,
@@ -680,6 +720,14 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
return "$hidden due to Ansible no_log flag$"
return artifacts
@property
def can_run_containerized(self):
return any([ig for ig in self.preferred_instance_groups if ig.is_containerized])
@property
def is_containerized(self):
return bool(self.instance_group and self.instance_group.is_containerized)
@property
def preferred_instance_groups(self):
if self.project is not None and self.project.organization is not None:
@@ -803,25 +851,6 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
host.save()
# Add on aliases for the non-related-model fields
class NullablePromptPsuedoField(object):
"""
Interface for psuedo-property stored in `char_prompts` dict
Used in LaunchTimeConfig and submodels
"""
def __init__(self, field_name):
self.field_name = field_name
def __get__(self, instance, type=None):
return instance.char_prompts.get(self.field_name, None)
def __set__(self, instance, value):
if value in (None, {}):
instance.char_prompts.pop(self.field_name, None)
else:
instance.char_prompts[self.field_name] = value
class LaunchTimeConfigBase(BaseModel):
'''
Needed as separate class from LaunchTimeConfig because some models
@@ -842,12 +871,13 @@ class LaunchTimeConfigBase(BaseModel):
null=True,
default=None,
on_delete=models.SET_NULL,
help_text=_('Inventory applied as a prompt, assuming job template prompts for inventory')
)
# All standard fields are stored in this dictionary field
# This is a solution to the nullable CharField problem, specific to prompting
char_prompts = JSONField(
blank=True,
default={}
default=dict
)
def prompts_dict(self, display=False):
@@ -878,42 +908,14 @@ class LaunchTimeConfigBase(BaseModel):
data[prompt_name] = prompt_val
return data
def display_extra_vars(self):
'''
Hides fields marked as passwords in survey.
'''
if self.survey_passwords:
extra_vars = parse_yaml_or_json(self.extra_vars).copy()
for key, value in self.survey_passwords.items():
if key in extra_vars:
extra_vars[key] = value
return extra_vars
else:
return self.extra_vars
def display_extra_data(self):
return self.display_extra_vars()
@property
def _credential(self):
'''
Only used for workflow nodes to support backward compatibility.
'''
try:
return [cred for cred in self.credentials.all() if cred.credential_type.kind == 'ssh'][0]
except IndexError:
return None
@property
def credential(self):
'''
Returns an integer so it can be used as IntegerField in serializer
'''
cred = self._credential
if cred is not None:
return cred.pk
else:
return None
for field_name in JobTemplate.get_ask_mapping().keys():
if field_name == 'extra_vars':
continue
try:
LaunchTimeConfigBase._meta.get_field(field_name)
except FieldDoesNotExist:
setattr(LaunchTimeConfigBase, field_name, NullablePromptPseudoField(field_name))
class LaunchTimeConfig(LaunchTimeConfigBase):
@@ -927,11 +929,11 @@ class LaunchTimeConfig(LaunchTimeConfigBase):
# Special case prompting fields, even more special than the other ones
extra_data = JSONField(
blank=True,
default={}
default=dict
)
survey_passwords = prevent_search(JSONField(
blank=True,
default={},
default=dict,
editable=False,
))
# Credentials needed for non-unified job / unified JT models
@@ -948,14 +950,21 @@ class LaunchTimeConfig(LaunchTimeConfigBase):
def extra_vars(self, extra_vars):
self.extra_data = extra_vars
def display_extra_vars(self):
'''
Hides fields marked as passwords in survey.
'''
if hasattr(self, 'survey_passwords') and self.survey_passwords:
extra_vars = parse_yaml_or_json(self.extra_vars).copy()
for key, value in self.survey_passwords.items():
if key in extra_vars:
extra_vars[key] = value
return extra_vars
else:
return self.extra_vars
for field_name in JobTemplate.get_ask_mapping().keys():
if field_name == 'extra_vars':
continue
try:
LaunchTimeConfig._meta.get_field(field_name)
except FieldDoesNotExist:
setattr(LaunchTimeConfig, field_name, NullablePromptPsuedoField(field_name))
def display_extra_data(self):
return self.display_extra_vars()
class JobLaunchConfig(LaunchTimeConfig):

View File

@@ -1,31 +1,37 @@
# Python
import os
import json
from copy import copy, deepcopy
import json
import logging
import os
import requests
# Django
from django.apps import apps
from django.conf import settings
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User # noqa
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models.query import QuerySet
from django.utils.crypto import get_random_string
from django.utils.translation import ugettext_lazy as _
# AWX
from awx.main.models.base import prevent_search
from awx.main.models.rbac import (
Role, RoleAncestorEntry, get_roles_on_resource
)
from awx.main.utils import parse_yaml_or_json, get_custom_venv_choices
from awx.main.utils import parse_yaml_or_json, get_custom_venv_choices, get_licenser
from awx.main.utils.encryption import decrypt_value, get_encryption_key, is_encrypted
from awx.main.utils.polymorphic import build_polymorphic_ctypes_map
from awx.main.fields import JSONField, AskForField
from awx.main.constants import ACTIVE_STATES
logger = logging.getLogger('awx.main.models.mixins')
__all__ = ['ResourceMixin', 'SurveyJobTemplateMixin', 'SurveyJobMixin',
'TaskManagerUnifiedJobMixin', 'TaskManagerJobMixin', 'TaskManagerProjectUpdateMixin',
'TaskManagerInventoryUpdateMixin', 'CustomVirtualEnvMixin']
@@ -100,7 +106,7 @@ class SurveyJobTemplateMixin(models.Model):
)
survey_spec = prevent_search(JSONField(
blank=True,
default={},
default=dict,
))
ask_variables_on_launch = AskForField(
blank=True,
@@ -247,7 +253,7 @@ class SurveyJobTemplateMixin(models.Model):
else:
choice_list = copy(survey_element['choices'])
if isinstance(choice_list, str):
choice_list = choice_list.split('\n')
choice_list = [choice for choice in choice_list.splitlines() if choice.strip() != '']
for val in data[survey_element['variable']]:
if val not in choice_list:
errors.append("Value %s for '%s' expected to be one of %s." % (val, survey_element['variable'],
@@ -255,7 +261,7 @@ class SurveyJobTemplateMixin(models.Model):
elif survey_element['type'] == 'multiplechoice':
choice_list = copy(survey_element['choices'])
if isinstance(choice_list, str):
choice_list = choice_list.split('\n')
choice_list = [choice for choice in choice_list.splitlines() if choice.strip() != '']
if survey_element['variable'] in data:
if data[survey_element['variable']] not in choice_list:
errors.append("Value %s for '%s' expected to be one of %s." % (data[survey_element['variable']],
@@ -360,7 +366,7 @@ class SurveyJobMixin(models.Model):
survey_passwords = prevent_search(JSONField(
blank=True,
default={},
default=dict,
editable=False,
))
@@ -484,3 +490,138 @@ class RelatedJobsMixin(object):
return [dict(id=t[0], type=mapping[t[1]]) for t in jobs.values_list('id', 'polymorphic_ctype_id')]
class WebhookTemplateMixin(models.Model):
class Meta:
abstract = True
SERVICES = [
('github', "GitHub"),
('gitlab', "GitLab"),
]
webhook_service = models.CharField(
max_length=16,
choices=SERVICES,
blank=True,
help_text=_('Service that webhook requests will be accepted from')
)
webhook_key = prevent_search(models.CharField(
max_length=64,
blank=True,
help_text=_('Shared secret that the webhook service will use to sign requests')
))
webhook_credential = models.ForeignKey(
'Credential',
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='%(class)ss',
help_text=_('Personal Access Token for posting back the status to the service API')
)
def rotate_webhook_key(self):
self.webhook_key = get_random_string(length=50)
def save(self, *args, **kwargs):
update_fields = kwargs.get('update_fields')
if not self.pk or self._values_have_edits({'webhook_service': self.webhook_service}):
if self.webhook_service:
self.rotate_webhook_key()
else:
self.webhook_key = ''
if update_fields and 'webhook_service' in update_fields:
update_fields.add('webhook_key')
super().save(*args, **kwargs)
class WebhookMixin(models.Model):
class Meta:
abstract = True
SERVICES = WebhookTemplateMixin.SERVICES
webhook_service = models.CharField(
max_length=16,
choices=SERVICES,
blank=True,
help_text=_('Service that webhook requests will be accepted from')
)
webhook_credential = models.ForeignKey(
'Credential',
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='%(class)ss',
help_text=_('Personal Access Token for posting back the status to the service API')
)
webhook_guid = models.CharField(
blank=True,
max_length=128,
help_text=_('Unique identifier of the event that triggered this webhook')
)
def update_webhook_status(self, status):
if not self.webhook_credential:
logger.debug("No credential configured to post back webhook status, skipping.")
return
status_api = self.extra_vars_dict.get('tower_webhook_status_api')
if not status_api:
logger.debug("Webhook event did not have a status API endpoint associated, skipping.")
return
service_header = {
'github': ('Authorization', 'token {}'),
'gitlab': ('PRIVATE-TOKEN', '{}'),
}
service_statuses = {
'github': {
'pending': 'pending',
'successful': 'success',
'failed': 'failure',
'canceled': 'failure', # GitHub doesn't have a 'canceled' status :(
'error': 'error',
},
'gitlab': {
'pending': 'pending',
'running': 'running',
'successful': 'success',
'failed': 'failed',
'error': 'failed', # GitLab doesn't have an 'error' status distinct from 'failed' :(
'canceled': 'canceled',
},
}
statuses = service_statuses[self.webhook_service]
if status not in statuses:
logger.debug("Skipping webhook job status change: '{}'".format(status))
return
try:
license_type = get_licenser().validate().get('license_type')
data = {
'state': statuses[status],
'context': 'ansible/awx' if license_type == 'open' else 'ansible/tower',
'target_url': self.get_ui_url(),
}
k, v = service_header[self.webhook_service]
headers = {
k: v.format(self.webhook_credential.get_input('token')),
'Content-Type': 'application/json'
}
response = requests.post(status_api, data=json.dumps(data), headers=headers, timeout=30)
except Exception:
logger.exception("Posting webhook status caused an error.")
return
if response.status_code < 400:
logger.debug("Webhook status update sent.")
else:
logger.error(
"Posting webhook status failed, code: {}\n"
"{}\n"
"Payload sent: {}".format(response.status_code, response.text, json.dumps(data))
)

View File

@@ -2,7 +2,9 @@
# All Rights Reserved.
from copy import deepcopy
import datetime
import logging
import json
from django.db import models
from django.conf import settings
@@ -10,10 +12,12 @@ from django.core.mail.message import EmailMessage
from django.db import connection
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_str, force_text
from jinja2 import sandbox
from jinja2.exceptions import TemplateSyntaxError, UndefinedError, SecurityError
# AWX
from awx.api.versioning import reverse
from awx.main.models.base import CommonModelNameNotUnique, CreatedModifiedModel
from awx.main.models.base import CommonModelNameNotUnique, CreatedModifiedModel, prevent_search
from awx.main.utils import encrypt_field, decrypt_field, set_environ
from awx.main.notifications.email_backend import CustomEmailBackend
from awx.main.notifications.slack_backend import SlackBackend
@@ -45,7 +49,7 @@ class NotificationTemplate(CommonModelNameNotUnique):
('mattermost', _('Mattermost'), MattermostBackend),
('rocketchat', _('Rocket.Chat'), RocketChatBackend),
('irc', _('IRC'), IrcBackend)]
NOTIFICATION_TYPE_CHOICES = [(x[0], x[1]) for x in NOTIFICATION_TYPES]
NOTIFICATION_TYPE_CHOICES = sorted([(x[0], x[1]) for x in NOTIFICATION_TYPES])
CLASS_FOR_NOTIFICATION_TYPE = dict([(x[0], x[2]) for x in NOTIFICATION_TYPES])
class Meta:
@@ -66,7 +70,46 @@ class NotificationTemplate(CommonModelNameNotUnique):
choices=NOTIFICATION_TYPE_CHOICES,
)
notification_configuration = JSONField(blank=False)
notification_configuration = prevent_search(JSONField(blank=False))
def default_messages():
return {'started': None, 'success': None, 'error': None}
messages = JSONField(
null=True,
blank=True,
default=default_messages,
help_text=_('Optional custom messages for notification template.'))
def has_message(self, condition):
potential_template = self.messages.get(condition, {})
if potential_template == {}:
return False
if potential_template.get('message', {}) == {}:
return False
return True
def get_message(self, condition):
return self.messages.get(condition, {})
def build_notification_message(self, event_type, context):
env = sandbox.ImmutableSandboxedEnvironment()
templates = self.get_message(event_type)
msg_template = templates.get('message', {})
try:
notification_subject = env.from_string(msg_template).render(**context)
except (TemplateSyntaxError, UndefinedError, SecurityError):
notification_subject = ''
msg_body = templates.get('body', {})
try:
notification_body = env.from_string(msg_body).render(**context)
except (TemplateSyntaxError, UndefinedError, SecurityError):
notification_body = ''
return (notification_subject, notification_body)
def get_absolute_url(self, request=None):
return reverse('api:notification_template_detail', kwargs={'pk': self.pk}, request=request)
@@ -78,6 +121,26 @@ class NotificationTemplate(CommonModelNameNotUnique):
def save(self, *args, **kwargs):
new_instance = not bool(self.pk)
update_fields = kwargs.get('update_fields', [])
# preserve existing notification messages if not overwritten by new messages
if not new_instance:
old_nt = NotificationTemplate.objects.get(pk=self.id)
old_messages = old_nt.messages
new_messages = self.messages
if old_messages is not None and new_messages is not None:
for event in ['started', 'success', 'error']:
if not new_messages.get(event, {}) and old_messages.get(event, {}):
new_messages[event] = old_messages[event]
continue
if new_messages.get(event, {}) and old_messages.get(event, {}):
old_event_msgs = old_messages[event]
new_event_msgs = new_messages[event]
for msg_type in ['message', 'body']:
if msg_type not in new_event_msgs and old_event_msgs.get(msg_type, None):
new_event_msgs[msg_type] = old_event_msgs[msg_type]
new_messages.setdefault(event, None)
for field in filter(lambda x: self.notification_class.init_parameters[x]['type'] == "password",
self.notification_class.init_parameters):
if self.notification_configuration[field].startswith("$encrypted$"):
@@ -118,9 +181,10 @@ class NotificationTemplate(CommonModelNameNotUnique):
def send(self, subject, body):
for field in filter(lambda x: self.notification_class.init_parameters[x]['type'] == "password",
self.notification_class.init_parameters):
self.notification_configuration[field] = decrypt_field(self,
'notification_configuration',
subfield=field)
if field in self.notification_configuration:
self.notification_configuration[field] = decrypt_field(self,
'notification_configuration',
subfield=field)
recipients = self.notification_configuration.pop(self.notification_class.recipient_parameter)
if not isinstance(recipients, list):
recipients = [recipients]
@@ -200,56 +264,227 @@ class Notification(CreatedModifiedModel):
class JobNotificationMixin(object):
STATUS_TO_TEMPLATE_TYPE = {'succeeded': 'success',
'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',
{'host_status_counts': ['skipped', 'ok', 'changed', 'failures', 'dark']},
{'playbook_counts': ['play_count', 'task_count']},
{'summary_fields': [{'inventory': ['id', 'name', 'description', 'has_active_failures',
'total_hosts', 'hosts_with_active_failures', 'total_groups',
'groups_with_active_failures', 'has_inventory_sources',
'total_inventory_sources', 'inventory_sources_with_failures',
'organization_id', 'kind']},
{'project': ['id', 'name', 'description', 'status', 'scm_type']},
{'project_update': ['id', 'name', 'description', 'status', 'failed']},
{'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']},
{'source_workflow_job': ['description', 'elapsed', 'failed', 'id', 'name', 'status']}]}]
@classmethod
def context_stub(cls):
"""Returns a stub context that can be used for validating notification messages.
Context has the same structure as the context that will actually be used to render
a notification message."""
context = {'job': {'allow_simultaneous': False,
'controller_node': 'foo_controller',
'created': datetime.datetime(2018, 11, 13, 6, 4, 0, 0, tzinfo=datetime.timezone.utc),
'custom_virtualenv': 'my_venv',
'description': 'Sample job description',
'diff_mode': False,
'elapsed': 0.403018,
'execution_node': 'awx',
'failed': False,
'finished': False,
'force_handlers': False,
'forks': 0,
'host_status_counts': {'skipped': 1, 'ok': 5, 'changed': 3, 'failures': 0, 'dark': 0},
'id': 42,
'job_explanation': 'Sample job explanation',
'job_slice_count': 1,
'job_slice_number': 0,
'job_tags': '',
'job_type': 'run',
'launch_type': 'workflow',
'limit': 'bar_limit',
'modified': datetime.datetime(2018, 12, 13, 6, 4, 0, 0, tzinfo=datetime.timezone.utc),
'name': 'Stub JobTemplate',
'playbook_counts': {'play_count': 5, 'task_count': 10},
'playbook': 'ping.yml',
'scm_revision': '',
'skip_tags': '',
'start_at_task': '',
'started': '2019-07-29T17:38:14.137461Z',
'status': 'running',
'summary_fields': {'created_by': {'first_name': '',
'id': 1,
'last_name': '',
'username': 'admin'},
'instance_group': {'id': 1, 'name': 'tower'},
'inventory': {'description': 'Sample inventory description',
'groups_with_active_failures': 0,
'has_active_failures': False,
'has_inventory_sources': False,
'hosts_with_active_failures': 0,
'id': 17,
'inventory_sources_with_failures': 0,
'kind': '',
'name': 'Stub Inventory',
'organization_id': 121,
'total_groups': 0,
'total_hosts': 1,
'total_inventory_sources': 0},
'job_template': {'description': 'Sample job template description',
'id': 39,
'name': 'Stub JobTemplate'},
'labels': {'count': 0, 'results': []},
'project': {'description': 'Sample project description',
'id': 38,
'name': 'Stub project',
'scm_type': 'git',
'status': 'successful'},
'project_update': {'id': 5, 'name': 'Stub Project Update', 'description': 'Project Update',
'status': 'running', 'failed': False},
'unified_job_template': {'description': 'Sample unified job template description',
'id': 39,
'name': 'Stub Job Template',
'unified_job_type': 'job'},
'source_workflow_job': {'description': 'Sample workflow job description',
'elapsed': 0.000,
'failed': False,
'id': 88,
'name': 'Stub WorkflowJobTemplate',
'status': 'running'}},
'timeout': 0,
'type': 'job',
'url': '/api/v2/jobs/13/',
'use_fact_cache': False,
'verbosity': 0},
'job_friendly_name': 'Job',
'url': 'https://towerhost/#/jobs/playbook/1010',
'job_summary_dict': """{'url': 'https://towerhost/$/jobs/playbook/13',
'traceback': '',
'status': 'running',
'started': '2019-08-07T21:46:38.362630+00:00',
'project': 'Stub project',
'playbook': 'ping.yml',
'name': 'Stub Job Template',
'limit': '',
'inventory': 'Stub Inventory',
'id': 42,
'hosts': {},
'friendly_name': 'Job',
'finished': False,
'credential': 'Stub credential',
'created_by': 'admin'}"""}
return context
def context(self, serialized_job):
"""Returns a context that can be used for rendering notification messages.
Context contains whitelisted content retrieved from a serialized job object
(see JobNotificationMixin.JOB_FIELDS_WHITELIST), the job's friendly name,
and a url to the job run."""
context = {'job': {},
'job_friendly_name': self.get_notification_friendly_name(),
'url': self.get_ui_url(),
'job_summary_dict': json.dumps(self.notification_data(), indent=4)}
def build_context(node, fields, whitelisted_fields):
for safe_field in whitelisted_fields:
if type(safe_field) is dict:
field, whitelist_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)
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)
return context
def get_notification_templates(self):
raise RuntimeError("Define me")
def get_notification_friendly_name(self):
raise RuntimeError("Define me")
def _build_notification_message(self, status_str):
def notification_data(self):
raise RuntimeError("Define me")
def build_notification_message(self, nt, status):
env = sandbox.ImmutableSandboxedEnvironment()
from awx.api.serializers import UnifiedJobSerializer
job_serialization = UnifiedJobSerializer(self).to_representation(self)
context = self.context(job_serialization)
msg_template = body_template = None
if nt.messages:
templates = nt.messages.get(self.STATUS_TO_TEMPLATE_TYPE[status], {}) or {}
msg_template = templates.get('message', {})
body_template = templates.get('body', {})
if msg_template:
try:
notification_subject = env.from_string(msg_template).render(**context)
except (TemplateSyntaxError, UndefinedError, SecurityError):
notification_subject = ''
else:
notification_subject = u"{} #{} '{}' {}: {}".format(self.get_notification_friendly_name(),
self.id,
self.name,
status,
self.get_ui_url())
notification_body = self.notification_data()
notification_subject = u"{} #{} '{}' {}: {}".format(self.get_notification_friendly_name(),
self.id,
self.name,
status_str,
notification_body['url'])
notification_body['friendly_name'] = self.get_notification_friendly_name()
if body_template:
try:
notification_body['body'] = env.from_string(body_template).render(**context)
except (TemplateSyntaxError, UndefinedError, SecurityError):
notification_body['body'] = ''
return (notification_subject, notification_body)
def build_notification_succeeded_message(self):
return self._build_notification_message('succeeded')
def build_notification_failed_message(self):
return self._build_notification_message('failed')
def build_notification_running_message(self):
return self._build_notification_message('running')
def send_notification_templates(self, status_str):
def send_notification_templates(self, status):
from awx.main.tasks import send_notifications # avoid circular import
if status_str not in ['succeeded', 'failed', 'running']:
raise ValueError(_("status_str must be either running, succeeded or failed"))
if status not in ['running', 'succeeded', 'failed']:
raise ValueError(_("status must be either running, succeeded or failed"))
try:
notification_templates = self.get_notification_templates()
except Exception:
logger.warn("No notification template defined for emitting notification")
notification_templates = None
if notification_templates:
if status_str == 'succeeded':
notification_template_type = 'success'
elif status_str == 'running':
notification_template_type = 'started'
else:
notification_template_type = 'error'
all_notification_templates = set(notification_templates.get(notification_template_type, []))
if len(all_notification_templates):
try:
(notification_subject, notification_body) = getattr(self, 'build_notification_%s_message' % status_str)()
except AttributeError:
raise NotImplementedError("build_notification_%s_message() does not exist" % status_str)
return
def send_it():
send_notifications.delay([n.generate_notification(notification_subject, notification_body).id
for n in all_notification_templates],
if not notification_templates:
return
for nt in set(notification_templates.get(self.STATUS_TO_TEMPLATE_TYPE[status], [])):
try:
(notification_subject, notification_body) = self.build_notification_message(nt, status)
except AttributeError:
raise NotImplementedError("build_notification_message() does not exist" % status)
# Use kwargs to force late-binding
# https://stackoverflow.com/a/3431699/10669572
def send_it(local_nt=nt, local_subject=notification_subject, local_body=notification_body):
def _func():
send_notifications.delay([local_nt.generate_notification(local_subject, local_body).id],
job_id=self.id)
connection.on_commit(send_it)
return _func
connection.on_commit(send_it())

View File

@@ -3,7 +3,7 @@ import re
# Django
from django.core.validators import RegexValidator
from django.db import models
from django.db import models, connection
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
@@ -98,8 +98,7 @@ class OAuth2AccessToken(AbstractAccessToken):
related_name="%(app_label)s_%(class)s",
help_text=_('The user representing the token owner')
)
description = models.CharField(
max_length=200,
description = models.TextField(
default='',
blank=True,
)
@@ -122,7 +121,7 @@ class OAuth2AccessToken(AbstractAccessToken):
valid = super(OAuth2AccessToken, self).is_valid(scopes)
if valid:
self.last_used = now()
self.save(update_fields=['last_used'])
connection.on_commit(lambda: self.save(update_fields=['last_used']))
return valid
def save(self, *args, **kwargs):

View File

@@ -51,6 +51,11 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
default=0,
help_text=_('Maximum number of hosts allowed to be managed by this organization.'),
)
notification_templates_approvals = models.ManyToManyField(
"NotificationTemplate",
blank=True,
related_name='%(class)s_notification_templates_for_approvals'
)
admin_role = ImplicitRoleField(
parent_role='singleton:' + ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
@@ -87,7 +92,10 @@ class Organization(CommonModel, NotificationFieldsModel, ResourceMixin, CustomVi
'execute_role', 'project_admin_role',
'inventory_admin_role', 'workflow_admin_role',
'notification_admin_role', 'credential_admin_role',
'job_template_admin_role',],
'job_template_admin_role', 'approval_role',],
)
approval_role = ImplicitRoleField(
parent_role='admin_role',
)

View File

@@ -106,6 +106,13 @@ class ProjectOptions(models.Model):
verbose_name=_('SCM Branch'),
help_text=_('Specific branch, tag or commit to checkout.'),
)
scm_refspec = models.CharField(
max_length=1024,
blank=True,
default='',
verbose_name=_('SCM refspec'),
help_text=_('For git projects, an additional refspec to fetch.'),
)
scm_clean = models.BooleanField(
default=False,
help_text=_('Discard any local changes before syncing the project.'),
@@ -241,7 +248,7 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
SOFT_UNIQUE_TOGETHER = [('polymorphic_ctype', 'name', 'organization')]
FIELDS_TO_PRESERVE_AT_COPY = ['labels', 'instance_groups', 'credentials']
FIELDS_TO_DISCARD_AT_COPY = ['local_path']
FIELDS_TRIGGER_UPDATE = frozenset(['scm_url', 'scm_branch', 'scm_type'])
FIELDS_TRIGGER_UPDATE = frozenset(['scm_url', 'scm_branch', 'scm_type', 'scm_refspec'])
class Meta:
app_label = 'main'
@@ -261,9 +268,14 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
scm_update_cache_timeout = models.PositiveIntegerField(
default=0,
blank=True,
help_text=_('The number of seconds after the last project update ran that a new'
help_text=_('The number of seconds after the last project update ran that a new '
'project update will be launched as a job dependency.'),
)
allow_override = models.BooleanField(
default=False,
help_text=_('Allow changing the SCM branch or revision in a job template '
'that uses this project.'),
)
scm_revision = models.CharField(
max_length=1024,
@@ -317,7 +329,7 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
@classmethod
def _get_unified_job_field_names(cls):
return set(f.name for f in ProjectOptions._meta.fields) | set(
['name', 'description', 'schedule']
['name', 'description']
)
def save(self, *args, **kwargs):
@@ -471,6 +483,14 @@ class ProjectUpdate(UnifiedJob, ProjectOptions, JobNotificationMixin, TaskManage
choices=PROJECT_UPDATE_JOB_TYPE_CHOICES,
default='check',
)
scm_revision = models.CharField(
max_length=1024,
blank=True,
default='',
editable=False,
verbose_name=_('SCM Revision'),
help_text=_('The SCM Revision discovered by this update for the given project and branch.'),
)
def _get_parent_field_name(self):
return 'project'

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