mirror of
https://github.com/ansible/awx.git
synced 2026-03-04 18:21:03 -03:30
Merge pull request #2571 from ryanpetrello/devel
Merge remote-tracking branch 'release_3.3.1' into devel Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
1
Makefile
1
Makefile
@@ -600,7 +600,6 @@ docker-compose-cluster-elk: docker-auth
|
|||||||
minishift-dev:
|
minishift-dev:
|
||||||
ansible-playbook -i localhost, -e devtree_directory=$(CURDIR) tools/clusterdevel/start_minishift_dev.yml
|
ansible-playbook -i localhost, -e devtree_directory=$(CURDIR) tools/clusterdevel/start_minishift_dev.yml
|
||||||
|
|
||||||
|
|
||||||
clean-elk:
|
clean-elk:
|
||||||
docker stop tools_kibana_1
|
docker stop tools_kibana_1
|
||||||
docker stop tools_logstash_1
|
docker stop tools_logstash_1
|
||||||
|
|||||||
@@ -2130,6 +2130,7 @@ class HostFactVersionsList(SystemTrackingEnforcementMixin, ParentMixin, ListAPIV
|
|||||||
serializer_class = FactVersionSerializer
|
serializer_class = FactVersionSerializer
|
||||||
parent_model = Host
|
parent_model = Host
|
||||||
search_fields = ('facts',)
|
search_fields = ('facts',)
|
||||||
|
deprecated = True
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
from_spec = self.request.query_params.get('from', None)
|
from_spec = self.request.query_params.get('from', None)
|
||||||
@@ -2155,6 +2156,7 @@ class HostFactCompareView(SystemTrackingEnforcementMixin, SubDetailAPIView):
|
|||||||
model = Fact
|
model = Fact
|
||||||
parent_model = Host
|
parent_model = Host
|
||||||
serializer_class = FactSerializer
|
serializer_class = FactSerializer
|
||||||
|
deprecated = True
|
||||||
|
|
||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
datetime_spec = request.query_params.get('datetime', None)
|
datetime_spec = request.query_params.get('datetime', None)
|
||||||
@@ -4175,6 +4177,11 @@ class JobRelaunch(RetrieveAPIView):
|
|||||||
'Cannot relaunch because previous job had 0 {status_value} hosts.'
|
'Cannot relaunch because previous job had 0 {status_value} hosts.'
|
||||||
).format(status_value=retry_hosts)}, status=status.HTTP_400_BAD_REQUEST)
|
).format(status_value=retry_hosts)}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
copy_kwargs['limit'] = ','.join(retry_host_list)
|
copy_kwargs['limit'] = ','.join(retry_host_list)
|
||||||
|
limit_length = len(copy_kwargs['limit'])
|
||||||
|
if limit_length > 1024:
|
||||||
|
return Response({'limit': _(
|
||||||
|
'Cannot relaunch because the limit length {limit_length} exceeds the max of {limit_max}.'
|
||||||
|
).format(limit_length=limit_length, limit_max=1024)}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
new_job = obj.copy_unified_job(**copy_kwargs)
|
new_job = obj.copy_unified_job(**copy_kwargs)
|
||||||
result = new_job.signal_start(**serializer.validated_data['credential_passwords'])
|
result = new_job.signal_start(**serializer.validated_data['credential_passwords'])
|
||||||
|
|||||||
18
awx/conf/migrations/0006_v331_ldap_group_type.py
Normal file
18
awx/conf/migrations/0006_v331_ldap_group_type.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# AWX
|
||||||
|
from awx.conf.migrations._ldap_group_type import fill_ldap_group_type_params
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('conf', '0005_v330_rename_two_session_settings'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(fill_ldap_group_type_params),
|
||||||
|
]
|
||||||
30
awx/conf/migrations/_ldap_group_type.py
Normal file
30
awx/conf/migrations/_ldap_group_type.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils.timezone import now
|
||||||
|
|
||||||
|
|
||||||
|
def fill_ldap_group_type_params(apps, schema_editor):
|
||||||
|
group_type = settings.AUTH_LDAP_GROUP_TYPE
|
||||||
|
Setting = apps.get_model('conf', 'Setting')
|
||||||
|
|
||||||
|
group_type_params = {'name_attr': 'cn', 'member_attr': 'member'}
|
||||||
|
qs = Setting.objects.filter(key='AUTH_LDAP_GROUP_TYPE_PARAMS')
|
||||||
|
entry = None
|
||||||
|
if qs.exists():
|
||||||
|
entry = qs[0]
|
||||||
|
group_type_params = entry.value
|
||||||
|
else:
|
||||||
|
entry = Setting(key='AUTH_LDAP_GROUP_TYPE_PARAMS',
|
||||||
|
value=group_type_params,
|
||||||
|
created=now(),
|
||||||
|
modified=now())
|
||||||
|
|
||||||
|
init_attrs = set(inspect.getargspec(group_type.__init__).args[1:])
|
||||||
|
for k in group_type_params.keys():
|
||||||
|
if k not in init_attrs:
|
||||||
|
del group_type_params[k]
|
||||||
|
|
||||||
|
entry.value = group_type_params
|
||||||
|
entry.save()
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
# Python
|
# Python
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
@@ -129,6 +130,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
sys.stderr.write("This command has been deprecated and will be removed in a future release.\n")
|
||||||
if not feature_enabled('system_tracking'):
|
if not feature_enabled('system_tracking'):
|
||||||
raise CommandError("The System Tracking feature is not enabled for your instance")
|
raise CommandError("The System Tracking feature is not enabled for your instance")
|
||||||
cleanup_facts = CleanupFacts()
|
cleanup_facts = CleanupFacts()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -12,10 +13,31 @@ from django.conf import settings
|
|||||||
|
|
||||||
# Kombu
|
# Kombu
|
||||||
from kombu import Connection, Exchange, Producer
|
from kombu import Connection, Exchange, Producer
|
||||||
|
from kombu.serialization import registry
|
||||||
|
|
||||||
__all__ = ['CallbackQueueDispatcher']
|
__all__ = ['CallbackQueueDispatcher']
|
||||||
|
|
||||||
|
|
||||||
|
# use a custom JSON serializer so we can properly handle !unsafe and !vault
|
||||||
|
# objects that may exist in events emitted by the callback plugin
|
||||||
|
# see: https://github.com/ansible/ansible/pull/38759
|
||||||
|
class AnsibleJSONEncoder(json.JSONEncoder):
|
||||||
|
|
||||||
|
def default(self, o):
|
||||||
|
if getattr(o, 'yaml_tag', None) == '!vault':
|
||||||
|
return o.data
|
||||||
|
return super(AnsibleJSONEncoder, self).default(o)
|
||||||
|
|
||||||
|
|
||||||
|
registry.register(
|
||||||
|
'json-ansible',
|
||||||
|
lambda obj: json.dumps(obj, cls=AnsibleJSONEncoder),
|
||||||
|
lambda obj: json.loads(obj),
|
||||||
|
content_type='application/json',
|
||||||
|
content_encoding='utf-8'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CallbackQueueDispatcher(object):
|
class CallbackQueueDispatcher(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -41,7 +63,7 @@ class CallbackQueueDispatcher(object):
|
|||||||
|
|
||||||
producer = Producer(self.connection)
|
producer = Producer(self.connection)
|
||||||
producer.publish(obj,
|
producer.publish(obj,
|
||||||
serializer='json',
|
serializer='json-ansible',
|
||||||
compression='bzip2',
|
compression='bzip2',
|
||||||
exchange=self.exchange,
|
exchange=self.exchange,
|
||||||
declare=[self.exchange],
|
declare=[self.exchange],
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ function InstancesController ($scope, $state, $http, models, strings, Dataset, P
|
|||||||
};
|
};
|
||||||
|
|
||||||
vm.toggle = (toggled) => {
|
vm.toggle = (toggled) => {
|
||||||
const instance = _.find(vm.instances, 'id', toggled.id);
|
const instance = _.find(vm.instances, ['id', toggled.id]);
|
||||||
instance.enabled = !instance.enabled;
|
instance.enabled = !instance.enabled;
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
|
|||||||
@@ -243,6 +243,15 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
|||||||
|
|
||||||
let jobTemplate = new JobTemplate();
|
let jobTemplate = new JobTemplate();
|
||||||
|
|
||||||
|
const codeMirrorExtraVars = () => {
|
||||||
|
ParseTypeChange({
|
||||||
|
scope: $scope,
|
||||||
|
variable: 'extraVars',
|
||||||
|
parse_variable: 'parseType',
|
||||||
|
field_id: 'SchedulerForm-extraVars'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Rest.setUrl(scheduleResolve.related.credentials);
|
Rest.setUrl(scheduleResolve.related.credentials);
|
||||||
|
|
||||||
$q.all([jobTemplate.optionsLaunch(ParentObject.id), jobTemplate.getLaunch(ParentObject.id), Rest.get()])
|
$q.all([jobTemplate.optionsLaunch(ParentObject.id), jobTemplate.getLaunch(ParentObject.id), Rest.get()])
|
||||||
@@ -312,21 +321,10 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
|||||||
|
|
||||||
prompts.credentials.value = defaultCredsWithoutOverrides.concat(scheduleCredentials);
|
prompts.credentials.value = defaultCredsWithoutOverrides.concat(scheduleCredentials);
|
||||||
|
|
||||||
if (launchConf.ask_variables_on_launch) {
|
// the extra vars codemirror is ONLY shown if the
|
||||||
// the extra vars codemirror is ONLY shown if the
|
// schedule is for a JT and the JT has
|
||||||
// schedule is for a JT and the JT has
|
// ask_variables_on_launch = true
|
||||||
// ask_variables_on_launch = true.
|
$scope.noVars = !launchConf.ask_variables_on_launch;
|
||||||
$scope.extraVars = ParentObject.extra_vars === '' ? '---' : ParentObject.extra_vars;
|
|
||||||
$scope.noVars = false;
|
|
||||||
ParseTypeChange({
|
|
||||||
scope: $scope,
|
|
||||||
variable: 'extraVars',
|
|
||||||
parse_variable: 'parseType',
|
|
||||||
field_id: 'SchedulerForm-extraVars'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$scope.noVars = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!launchConf.survey_enabled &&
|
if (!launchConf.survey_enabled &&
|
||||||
!launchConf.ask_inventory_on_launch &&
|
!launchConf.ask_inventory_on_launch &&
|
||||||
@@ -343,6 +341,10 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
|||||||
launchConf.passwords_needed_to_start.length === 0 &&
|
launchConf.passwords_needed_to_start.length === 0 &&
|
||||||
launchConf.variables_needed_to_start.length === 0) {
|
launchConf.variables_needed_to_start.length === 0) {
|
||||||
$scope.showPromptButton = false;
|
$scope.showPromptButton = false;
|
||||||
|
|
||||||
|
if (launchConf.ask_variables_on_launch) {
|
||||||
|
codeMirrorExtraVars();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$scope.showPromptButton = true;
|
$scope.showPromptButton = true;
|
||||||
|
|
||||||
@@ -368,13 +370,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
|||||||
|
|
||||||
$scope.extraVars = (processed.extra_data === '' || _.isEmpty(processed.extra_data)) ? '---' : '---\n' + jsyaml.safeDump(processed.extra_data);
|
$scope.extraVars = (processed.extra_data === '' || _.isEmpty(processed.extra_data)) ? '---' : '---\n' + jsyaml.safeDump(processed.extra_data);
|
||||||
|
|
||||||
ParseTypeChange({
|
codeMirrorExtraVars();
|
||||||
scope: $scope,
|
|
||||||
variable: 'extraVars',
|
|
||||||
parse_variable: 'parseType',
|
|
||||||
field_id: 'SchedulerForm-extraVars',
|
|
||||||
readOnly: !$scope.schedule_obj.summary_fields.user_capabilities.edit
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.promptData = {
|
$scope.promptData = {
|
||||||
launchConf: launchConf,
|
launchConf: launchConf,
|
||||||
@@ -397,6 +393,7 @@ function($filter, $state, $stateParams, Wait, $scope, moment,
|
|||||||
watchForPromptChanges();
|
watchForPromptChanges();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
codeMirrorExtraVars();
|
||||||
$scope.promptData = {
|
$scope.promptData = {
|
||||||
launchConf: launchConf,
|
launchConf: launchConf,
|
||||||
launchOptions: launchOptions,
|
launchOptions: launchOptions,
|
||||||
|
|||||||
@@ -15,12 +15,11 @@ export default ['$scope', '$stateParams', '$state', '$filter', 'GetBasePath', 'Q
|
|||||||
"<i class=\"fa fa-angle-down DashboardGraphs-filterIcon\"></i>\n");
|
"<i class=\"fa fa-angle-down DashboardGraphs-filterIcon\"></i>\n");
|
||||||
|
|
||||||
if ($scope.querySet){
|
if ($scope.querySet){
|
||||||
let origQuerySet = _.cloneDeep($scope.querySet);
|
$scope.querySet = _.merge($scope.querySet, { page_size: `${pageSize}`});
|
||||||
queryset = _.merge(origQuerySet, { page_size: pageSize });
|
|
||||||
} else {
|
} else {
|
||||||
queryset = _.merge($stateParams[`${$scope.iterator}_search`], { page_size: pageSize, page: 1 });
|
$scope.querySet = _.merge($stateParams[`${$scope.iterator}_search`], { page_size: `${pageSize}`});
|
||||||
}
|
}
|
||||||
$scope.toPage();
|
$scope.toPage(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toPage = function(page) {
|
$scope.toPage = function(page) {
|
||||||
|
|||||||
@@ -499,7 +499,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
|||||||
|
|
||||||
$scope.$watch('selectedTemplate', () => {
|
$scope.$watch('selectedTemplate', () => {
|
||||||
$scope.job_templates.forEach(function(row, i) {
|
$scope.job_templates.forEach(function(row, i) {
|
||||||
if(_.has($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
if(_.hasIn($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
||||||
$scope.job_templates[i].checked = 1;
|
$scope.job_templates[i].checked = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -576,7 +576,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
|||||||
|
|
||||||
$scope.$watch('selectedTemplate', () => {
|
$scope.$watch('selectedTemplate', () => {
|
||||||
$scope.workflow_inventory_sources.forEach(function(row, i) {
|
$scope.workflow_inventory_sources.forEach(function(row, i) {
|
||||||
if(_.has($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
if(_.hasIn($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
||||||
$scope.workflow_inventory_sources[i].checked = 1;
|
$scope.workflow_inventory_sources[i].checked = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -653,7 +653,7 @@ angular.module('templates', [surveyMaker.name, jobTemplates.name, labels.name, p
|
|||||||
|
|
||||||
$scope.$watch('selectedTemplate', () => {
|
$scope.$watch('selectedTemplate', () => {
|
||||||
$scope.projects.forEach(function(row, i) {
|
$scope.projects.forEach(function(row, i) {
|
||||||
if(_.has($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
if(_.hasIn($scope, 'selectedTemplate.id') && row.id === $scope.selectedTemplate.id) {
|
||||||
$scope.projects[i].checked = 1;
|
$scope.projects[i].checked = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -11,17 +11,22 @@ SOSREPORT_TOWER_COMMANDS = [
|
|||||||
"supervisorctl status", # tower process status
|
"supervisorctl status", # tower process status
|
||||||
"rabbitmqctl status",
|
"rabbitmqctl status",
|
||||||
"rabbitmqctl cluster_status",
|
"rabbitmqctl cluster_status",
|
||||||
"/var/lib/awx/venv/awx/bin/pip freeze", # pip package list
|
"/var/lib/awx/venv/awx/bin/pip freeze", # pip package list
|
||||||
"/var/lib/awx/venv/ansible/bin/pip freeze", # pip package list
|
"/var/lib/awx/venv/awx/bin/pip freeze -l", # pip package list without globally-installed packages
|
||||||
|
"/var/lib/awx/venv/ansible/bin/pip freeze", # pip package list
|
||||||
|
"/var/lib/awx/venv/ansible/bin/pip freeze -l", # pip package list without globally-installed packages
|
||||||
"tree -d /var/lib/awx", # show me the dirs
|
"tree -d /var/lib/awx", # show me the dirs
|
||||||
"ls -ll /var/lib/awx", # check permissions
|
"ls -ll /var/lib/awx", # check permissions
|
||||||
"ls -ll /var/lib/awx/venv", # list all venvs
|
"ls -ll /var/lib/awx/venv", # list all venvs
|
||||||
"ls -ll /etc/tower"
|
"ls -ll /etc/tower",
|
||||||
|
"umask -p" # check current umask
|
||||||
]
|
]
|
||||||
|
|
||||||
SOSREPORT_TOWER_DIRS = [
|
SOSREPORT_TOWER_DIRS = [
|
||||||
"/etc/tower/",
|
"/etc/tower/",
|
||||||
"/etc/ansible/",
|
"/etc/ansible/",
|
||||||
|
"/etc/supervisord.d/",
|
||||||
|
"/etc/nginx/",
|
||||||
"/var/log/tower",
|
"/var/log/tower",
|
||||||
"/var/log/nginx",
|
"/var/log/nginx",
|
||||||
"/var/log/rabbitmq",
|
"/var/log/rabbitmq",
|
||||||
|
|||||||
Reference in New Issue
Block a user