mirror of
https://github.com/ansible/awx.git
synced 2026-07-06 13:58:05 -02:30
Merge branch 'release_3.3.0' into prompt-cleanup-v2
This commit is contained in:
@@ -87,7 +87,11 @@ class InstanceManager(models.Manager):
|
|||||||
return node[0]
|
return node[0]
|
||||||
raise RuntimeError("No instance found with the current cluster host id")
|
raise RuntimeError("No instance found with the current cluster host id")
|
||||||
|
|
||||||
def register(self, uuid=settings.SYSTEM_UUID, hostname=settings.CLUSTER_HOST_ID):
|
def register(self, uuid=None, hostname=None):
|
||||||
|
if not uuid:
|
||||||
|
uuid = settings.SYSTEM_UUID
|
||||||
|
if not hostname:
|
||||||
|
hostname = settings.CLUSTER_HOST_ID
|
||||||
with advisory_lock('instance_registration_%s' % hostname):
|
with advisory_lock('instance_registration_%s' % hostname):
|
||||||
instance = self.filter(hostname=hostname)
|
instance = self.filter(hostname=hostname)
|
||||||
if instance.exists():
|
if instance.exists():
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ from awx.main.queue import CallbackQueueDispatcher
|
|||||||
from awx.main.expect import run, isolated_manager
|
from awx.main.expect import run, isolated_manager
|
||||||
from awx.main.utils import (get_ansible_version, get_ssh_version, decrypt_field, update_scm_url,
|
from awx.main.utils import (get_ansible_version, get_ssh_version, decrypt_field, update_scm_url,
|
||||||
check_proot_installed, build_proot_temp_dir, get_licenser,
|
check_proot_installed, build_proot_temp_dir, get_licenser,
|
||||||
wrap_args_with_proot, OutputEventFilter, ignore_inventory_computed_fields,
|
wrap_args_with_proot, OutputEventFilter, OutputVerboseFilter, ignore_inventory_computed_fields,
|
||||||
ignore_inventory_group_removal, get_type_for_model, extract_ansible_vars)
|
ignore_inventory_group_removal, get_type_for_model, extract_ansible_vars)
|
||||||
from awx.main.utils.reload import restart_local_services, stop_local_services
|
from awx.main.utils.reload import restart_local_services, stop_local_services
|
||||||
from awx.main.utils.pglock import advisory_lock
|
from awx.main.utils.pglock import advisory_lock
|
||||||
@@ -821,10 +821,11 @@ class BaseTask(LogErrorsTask):
|
|||||||
|
|
||||||
def get_stdout_handle(self, instance):
|
def get_stdout_handle(self, instance):
|
||||||
'''
|
'''
|
||||||
Return an virtual file object for capturing stdout and events.
|
Return an virtual file object for capturing stdout and/or events.
|
||||||
'''
|
'''
|
||||||
dispatcher = CallbackQueueDispatcher()
|
dispatcher = CallbackQueueDispatcher()
|
||||||
|
|
||||||
|
if isinstance(instance, (Job, AdHocCommand, ProjectUpdate)):
|
||||||
def event_callback(event_data):
|
def event_callback(event_data):
|
||||||
event_data.setdefault(self.event_data_key, instance.id)
|
event_data.setdefault(self.event_data_key, instance.id)
|
||||||
if 'uuid' in event_data:
|
if 'uuid' in event_data:
|
||||||
@@ -834,6 +835,12 @@ class BaseTask(LogErrorsTask):
|
|||||||
dispatcher.dispatch(event_data)
|
dispatcher.dispatch(event_data)
|
||||||
|
|
||||||
return OutputEventFilter(event_callback)
|
return OutputEventFilter(event_callback)
|
||||||
|
else:
|
||||||
|
def event_callback(event_data):
|
||||||
|
event_data.setdefault(self.event_data_key, instance.id)
|
||||||
|
dispatcher.dispatch(event_data)
|
||||||
|
|
||||||
|
return OutputVerboseFilter(event_callback)
|
||||||
|
|
||||||
def pre_run_hook(self, instance, **kwargs):
|
def pre_run_hook(self, instance, **kwargs):
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from StringIO import StringIO
|
|||||||
|
|
||||||
from six.moves import xrange
|
from six.moves import xrange
|
||||||
|
|
||||||
from awx.main.utils import OutputEventFilter
|
from awx.main.utils import OutputEventFilter, OutputVerboseFilter
|
||||||
|
|
||||||
MAX_WIDTH = 78
|
MAX_WIDTH = 78
|
||||||
EXAMPLE_UUID = '890773f5-fe6d-4091-8faf-bdc8021d65dd'
|
EXAMPLE_UUID = '890773f5-fe6d-4091-8faf-bdc8021d65dd'
|
||||||
@@ -145,3 +145,55 @@ def test_large_stdout_blob():
|
|||||||
f = OutputEventFilter(_callback)
|
f = OutputEventFilter(_callback)
|
||||||
for x in range(1024 * 10):
|
for x in range(1024 * 10):
|
||||||
f.write('x' * 1024)
|
f.write('x' * 1024)
|
||||||
|
|
||||||
|
|
||||||
|
def test_verbose_line_buffering():
|
||||||
|
events = []
|
||||||
|
|
||||||
|
def _callback(event_data):
|
||||||
|
events.append(event_data)
|
||||||
|
|
||||||
|
f = OutputVerboseFilter(_callback)
|
||||||
|
f.write('one two\r\n\r\n')
|
||||||
|
|
||||||
|
assert len(events) == 2
|
||||||
|
assert events[0]['start_line'] == 0
|
||||||
|
assert events[0]['end_line'] == 1
|
||||||
|
assert events[0]['stdout'] == 'one two'
|
||||||
|
|
||||||
|
assert events[1]['start_line'] == 1
|
||||||
|
assert events[1]['end_line'] == 2
|
||||||
|
assert events[1]['stdout'] == ''
|
||||||
|
|
||||||
|
f.write('three')
|
||||||
|
assert len(events) == 2
|
||||||
|
f.write('\r\nfou')
|
||||||
|
|
||||||
|
# three is not pushed to buffer until its line completes
|
||||||
|
assert len(events) == 3
|
||||||
|
assert events[2]['start_line'] == 2
|
||||||
|
assert events[2]['end_line'] == 3
|
||||||
|
assert events[2]['stdout'] == 'three'
|
||||||
|
|
||||||
|
f.write('r\r')
|
||||||
|
f.write('\nfi')
|
||||||
|
|
||||||
|
assert events[3]['start_line'] == 3
|
||||||
|
assert events[3]['end_line'] == 4
|
||||||
|
assert events[3]['stdout'] == 'four'
|
||||||
|
|
||||||
|
f.write('ve')
|
||||||
|
f.write('\r\n')
|
||||||
|
|
||||||
|
assert len(events) == 5
|
||||||
|
assert events[4]['start_line'] == 4
|
||||||
|
assert events[4]['end_line'] == 5
|
||||||
|
assert events[4]['stdout'] == 'five'
|
||||||
|
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
from pprint import pprint
|
||||||
|
pprint(events)
|
||||||
|
assert len(events) == 6
|
||||||
|
|
||||||
|
assert events[5]['event'] == 'EOF'
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ __all__ = ['get_object_or_400', 'get_object_or_403', 'camelcase_to_underscore',
|
|||||||
'copy_m2m_relationships', 'prefetch_page_capabilities', 'to_python_boolean',
|
'copy_m2m_relationships', 'prefetch_page_capabilities', 'to_python_boolean',
|
||||||
'ignore_inventory_computed_fields', 'ignore_inventory_group_removal',
|
'ignore_inventory_computed_fields', 'ignore_inventory_group_removal',
|
||||||
'_inventory_updates', 'get_pk_from_dict', 'getattrd', 'NoDefaultProvided',
|
'_inventory_updates', 'get_pk_from_dict', 'getattrd', 'NoDefaultProvided',
|
||||||
'get_current_apps', 'set_current_apps', 'OutputEventFilter',
|
'get_current_apps', 'set_current_apps', 'OutputEventFilter', 'OutputVerboseFilter',
|
||||||
'extract_ansible_vars', 'get_search_fields', 'get_system_task_capacity', 'get_cpu_capacity', 'get_mem_capacity',
|
'extract_ansible_vars', 'get_search_fields', 'get_system_task_capacity', 'get_cpu_capacity', 'get_mem_capacity',
|
||||||
'wrap_args_with_proot', 'build_proot_temp_dir', 'check_proot_installed', 'model_to_dict',
|
'wrap_args_with_proot', 'build_proot_temp_dir', 'check_proot_installed', 'model_to_dict',
|
||||||
'model_instance_diff', 'timestamp_apiformat', 'parse_yaml_or_json', 'RequireDebugTrueOrTest',
|
'model_instance_diff', 'timestamp_apiformat', 'parse_yaml_or_json', 'RequireDebugTrueOrTest',
|
||||||
@@ -1009,6 +1009,32 @@ class OutputEventFilter(object):
|
|||||||
self._current_event_data = None
|
self._current_event_data = None
|
||||||
|
|
||||||
|
|
||||||
|
class OutputVerboseFilter(OutputEventFilter):
|
||||||
|
'''
|
||||||
|
File-like object that dispatches stdout data.
|
||||||
|
Does not search for encoded job event data.
|
||||||
|
Use for unified job types that do not encode job event data.
|
||||||
|
'''
|
||||||
|
def write(self, data):
|
||||||
|
self._buffer.write(data)
|
||||||
|
|
||||||
|
# if the current chunk contains a line break
|
||||||
|
if data and '\n' in data:
|
||||||
|
# emit events for all complete lines we know about
|
||||||
|
lines = self._buffer.getvalue().splitlines(True) # keep ends
|
||||||
|
remainder = None
|
||||||
|
# if last line is not a complete line, then exclude it
|
||||||
|
if '\n' not in lines[-1]:
|
||||||
|
remainder = lines.pop()
|
||||||
|
# emit all complete lines
|
||||||
|
for line in lines:
|
||||||
|
self._emit_event(line)
|
||||||
|
self._buffer = StringIO()
|
||||||
|
# put final partial line back on buffer
|
||||||
|
if remainder:
|
||||||
|
self._buffer.write(remainder)
|
||||||
|
|
||||||
|
|
||||||
def is_ansible_variable(key):
|
def is_ansible_variable(key):
|
||||||
return key.startswith('ansible_')
|
return key.startswith('ansible_')
|
||||||
|
|
||||||
|
|||||||
@@ -301,8 +301,8 @@ def _register_ldap(append=None):
|
|||||||
register(
|
register(
|
||||||
'AUTH_LDAP{}_GROUP_TYPE_PARAMS'.format(append_str),
|
'AUTH_LDAP{}_GROUP_TYPE_PARAMS'.format(append_str),
|
||||||
field_class=fields.LDAPGroupTypeParamsField,
|
field_class=fields.LDAPGroupTypeParamsField,
|
||||||
label=_('LDAP Group Type'),
|
label=_('LDAP Group Type Parameters'),
|
||||||
help_text=_('Parameters to send the chosen group type.'),
|
help_text=_('Key value parameters to send the chosen group type init method.'),
|
||||||
category=_('LDAP'),
|
category=_('LDAP'),
|
||||||
category_slug='ldap',
|
category_slug='ldap',
|
||||||
default=collections.OrderedDict([
|
default=collections.OrderedDict([
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export default ['i18n', function(i18n) {
|
|||||||
"class": 'btn-danger btn-xs',
|
"class": 'btn-danger btn-xs',
|
||||||
awToolTip: i18n._('Copy inventory'),
|
awToolTip: i18n._('Copy inventory'),
|
||||||
dataPlacement: 'top',
|
dataPlacement: 'top',
|
||||||
ngShow: 'inventory.summary_fields.user_capabilities.edit'
|
ngShow: '!inventory.pending_deletion && inventory.summary_fields.user_capabilities.edit'
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
label: i18n._('View'),
|
label: i18n._('View'),
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ export default ['NotificationsList', 'i18n',
|
|||||||
dataTitle: i18n._('Ansible Environment'),
|
dataTitle: i18n._('Ansible Environment'),
|
||||||
dataContainer: 'body',
|
dataContainer: 'body',
|
||||||
dataPlacement: 'right',
|
dataPlacement: 'right',
|
||||||
ngDisabled: '!(organization_obj.summary_fields.user_capabilities.edit || canAdd)'
|
ngDisabled: '!(organization_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||||
|
ngShow: 'custom_virtualenvs_options.length > 0'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -52,17 +52,6 @@ export default ['i18n', 'NotificationsList', 'TemplateList',
|
|||||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd) || !canEditOrg',
|
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd) || !canEditOrg',
|
||||||
awLookupWhen: '(project_obj.summary_fields.user_capabilities.edit || canAdd) && canEditOrg'
|
awLookupWhen: '(project_obj.summary_fields.user_capabilities.edit || canAdd) && canEditOrg'
|
||||||
},
|
},
|
||||||
custom_virtualenv: {
|
|
||||||
label: i18n._('Ansible Environment'),
|
|
||||||
type: 'select',
|
|
||||||
defaultText: i18n._('Select Ansible Environment'),
|
|
||||||
ngOptions: 'venv for venv in custom_virtualenvs_options track by venv',
|
|
||||||
awPopOver: "<p>" + i18n._("Select the custom Python virtual environment for this project to run on.") + "</p>",
|
|
||||||
dataTitle: i18n._('Ansible Environment'),
|
|
||||||
dataContainer: 'body',
|
|
||||||
dataPlacement: 'right',
|
|
||||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
|
||||||
},
|
|
||||||
scm_type: {
|
scm_type: {
|
||||||
label: i18n._('SCM Type'),
|
label: i18n._('SCM Type'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
@@ -211,8 +200,21 @@ export default ['i18n', 'NotificationsList', 'TemplateList',
|
|||||||
dataTitle: i18n._('Cache Timeout'),
|
dataTitle: i18n._('Cache Timeout'),
|
||||||
dataPlacement: 'right',
|
dataPlacement: 'right',
|
||||||
dataContainer: "body",
|
dataContainer: "body",
|
||||||
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)'
|
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||||
}
|
subForm: 'sourceSubForm'
|
||||||
|
},
|
||||||
|
custom_virtualenv: {
|
||||||
|
label: i18n._('Ansible Environment'),
|
||||||
|
type: 'select',
|
||||||
|
defaultText: i18n._('Select Ansible Environment'),
|
||||||
|
ngOptions: 'venv for venv in custom_virtualenvs_options track by venv',
|
||||||
|
awPopOver: "<p>" + i18n._("Select the custom Python virtual environment for this project to run on.") + "</p>",
|
||||||
|
dataTitle: i18n._('Ansible Environment'),
|
||||||
|
dataContainer: 'body',
|
||||||
|
dataPlacement: 'right',
|
||||||
|
ngDisabled: '!(project_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||||
|
ngShow: 'custom_virtualenvs_options.length > 0'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
buttons: {
|
buttons: {
|
||||||
|
|||||||
@@ -395,9 +395,13 @@ export default ['$compile', 'Attr', 'Icon',
|
|||||||
}
|
}
|
||||||
if (field_action === 'pending_deletion') {
|
if (field_action === 'pending_deletion') {
|
||||||
innerTable += `<a ng-if='${list.iterator}.pending_deletion'>Pending Delete</a>`;
|
innerTable += `<a ng-if='${list.iterator}.pending_deletion'>Pending Delete</a>`;
|
||||||
}
|
} else if (field_action === 'submit') {
|
||||||
|
innerTable += `<at-launch-template template="${list.iterator}" ng-if="${list.iterator}.summary_fields.user_capabilities.start"></at-launch-template>`;
|
||||||
|
} else {
|
||||||
// Plug in Dropdown Component
|
// Plug in Dropdown Component
|
||||||
if (field_action === 'submit') {
|
if (field_action === 'submit' && list.fieldActions[field_action].relaunch === true) {
|
||||||
|
innerTable += `<at-relaunch job="${list.iterator}"></at-relaunch>`;
|
||||||
|
} else if (field_action === 'submit' && list.fieldActions[field_action].launch === true) {
|
||||||
innerTable += `<at-launch-template template="${list.iterator}" ng-if="${list.iterator}.summary_fields.user_capabilities.start"></at-launch-template>`;
|
innerTable += `<at-launch-template template="${list.iterator}" ng-if="${list.iterator}.summary_fields.user_capabilities.start"></at-launch-template>`;
|
||||||
} else {
|
} else {
|
||||||
fAction = list.fieldActions[field_action];
|
fAction = list.fieldActions[field_action];
|
||||||
@@ -453,6 +457,7 @@ export default ['$compile', 'Attr', 'Icon',
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
innerTable += "</div></td>\n";
|
innerTable += "</div></td>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
.at-Upgrade--panel {
|
.at-Upgrade--panel {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: @at-color-body-background-light;
|
background-color: @at-color-body-background-light;
|
||||||
|
border-radius: 10px;
|
||||||
color: @at-color-body-text;
|
color: @at-color-body-text;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
font-size: @at-font-size-jumbotron-text;
|
font-size: @at-font-size-jumbotron-text;
|
||||||
|
height: ~"calc(100vh - 40px)";
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-top: @at-space-10x;
|
margin: @at-space-4x;
|
||||||
padding: @at-space-10x;
|
padding: @at-space-10x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,8 @@ function(NotificationsList, i18n) {
|
|||||||
dataTitle: i18n._('Ansible Environment'),
|
dataTitle: i18n._('Ansible Environment'),
|
||||||
dataContainer: 'body',
|
dataContainer: 'body',
|
||||||
dataPlacement: 'right',
|
dataPlacement: 'right',
|
||||||
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)'
|
ngDisabled: '!(job_template_obj.summary_fields.user_capabilities.edit || canAdd)',
|
||||||
|
ngShow: 'custom_virtualenvs_options.length > 0'
|
||||||
},
|
},
|
||||||
instance_groups: {
|
instance_groups: {
|
||||||
label: i18n._('Instance Groups'),
|
label: i18n._('Instance Groups'),
|
||||||
|
|||||||
@@ -74,7 +74,8 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
let buildSendableNodeData = function() {
|
let buildSendableNodeData = function() {
|
||||||
// Create the node
|
// Create the node
|
||||||
let sendableNodeData = {
|
let sendableNodeData = {
|
||||||
unified_job_template: params.node.unifiedJobTemplate.id
|
unified_job_template: params.node.unifiedJobTemplate.id,
|
||||||
|
credential: _.get(params, 'node.originalNodeObj.credential') || null
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_.has(params, 'node.promptData.extraVars')) {
|
if (_.has(params, 'node.promptData.extraVars')) {
|
||||||
@@ -120,8 +121,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
if ($scope.totalIteratedNodes === $scope.treeData.data.totalNodes) {
|
if ($scope.totalIteratedNodes === $scope.treeData.data.totalNodes) {
|
||||||
// We're done recursing, lets move on
|
// We're done recursing, lets move on
|
||||||
completionCallback();
|
completionCallback();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (params.node.children && params.node.children.length > 0) {
|
if (params.node.children && params.node.children.length > 0) {
|
||||||
_.forEach(params.node.children, function(child) {
|
_.forEach(params.node.children, function(child) {
|
||||||
if (child.edgeType === "success") {
|
if (child.edgeType === "success") {
|
||||||
@@ -129,14 +129,12 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
node: child
|
node: child
|
||||||
}, completionCallback);
|
}, completionCallback);
|
||||||
}
|
} else if (child.edgeType === "failure") {
|
||||||
else if(child.edgeType === "failure") {
|
|
||||||
recursiveNodeUpdates({
|
recursiveNodeUpdates({
|
||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
node: child
|
node: child
|
||||||
}, completionCallback);
|
}, completionCallback);
|
||||||
}
|
} else if (child.edgeType === "always") {
|
||||||
else if(child.edgeType === "always") {
|
|
||||||
recursiveNodeUpdates({
|
recursiveNodeUpdates({
|
||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
node: child
|
node: child
|
||||||
@@ -193,8 +191,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
error.status
|
error.status
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (params.node.edited || !params.node.originalParentId || (params.node.originalParentId && params.parentId !== params.node.originalParentId)) {
|
if (params.node.edited || !params.node.originalParentId || (params.node.originalParentId && params.parentId !== params.node.originalParentId)) {
|
||||||
|
|
||||||
if (params.node.edited) {
|
if (params.node.edited) {
|
||||||
@@ -243,7 +240,6 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((params.node.originalParentId && params.parentId !== params.node.originalParentId) || params.node.originalEdge !== params.node.edgeType) {//beep
|
if ((params.node.originalParentId && params.parentId !== params.node.originalParentId) || params.node.originalEdge !== params.node.edgeType) {//beep
|
||||||
@@ -275,8 +271,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else if (!params.node.originalParentId && params.parentId) {
|
||||||
else if(!params.node.originalParentId && params.parentId) {
|
|
||||||
// This used to be a root node but is now not a root node
|
// This used to be a root node but is now not a root node
|
||||||
associateRequests.push({
|
associateRequests.push({
|
||||||
parentId: params.parentId,
|
parentId: params.parentId,
|
||||||
@@ -376,13 +371,6 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let credentialPromises = credentialRequests.map(function(request) {
|
|
||||||
return TemplatesService.postWorkflowNodeCredential({
|
|
||||||
id: request.id,
|
|
||||||
data: request.data
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
let editNodePromises = editRequests.map(function(request) {
|
let editNodePromises = editRequests.map(function(request) {
|
||||||
return TemplatesService.editWorkflowNode({
|
return TemplatesService.editWorkflowNode({
|
||||||
id: request.id,
|
id: request.id,
|
||||||
@@ -394,9 +382,16 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
return TemplatesService.deleteWorkflowJobTemplateNode(nodeId);
|
return TemplatesService.deleteWorkflowJobTemplateNode(nodeId);
|
||||||
});
|
});
|
||||||
|
|
||||||
$q.all(disassociatePromises.concat(editNodePromises, deletePromises, credentialPromises))
|
$q.all(disassociatePromises.concat(editNodePromises, deletePromises))
|
||||||
.then(function() {
|
.then(function() {
|
||||||
|
|
||||||
|
let credentialPromises = credentialRequests.map(function(request) {
|
||||||
|
return TemplatesService.postWorkflowNodeCredential({
|
||||||
|
id: request.id,
|
||||||
|
data: request.data
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
let associatePromises = associateRequests.map(function(request) {
|
let associatePromises = associateRequests.map(function(request) {
|
||||||
return TemplatesService.associateWorkflowNode({
|
return TemplatesService.associateWorkflowNode({
|
||||||
parentId: request.parentId,
|
parentId: request.parentId,
|
||||||
@@ -405,7 +400,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$q.all(associatePromises)
|
$q.all(associatePromises.concat(credentialPromises))
|
||||||
.then(function() {
|
.then(function() {
|
||||||
$scope.closeDialog();
|
$scope.closeDialog();
|
||||||
});
|
});
|
||||||
@@ -417,8 +412,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
node: child
|
node: child
|
||||||
}, completionCallback);
|
}, completionCallback);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
let deletePromises = $scope.treeData.data.deletedNodes.map(function(nodeId) {
|
let deletePromises = $scope.treeData.data.deletedNodes.map(function(nodeId) {
|
||||||
return TemplatesService.deleteWorkflowJobTemplateNode(nodeId);
|
return TemplatesService.deleteWorkflowJobTemplateNode(nodeId);
|
||||||
@@ -709,8 +703,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
|
|
||||||
watchForPromptChanges();
|
watchForPromptChanges();
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$scope.nodeBeingEdited.promptData = $scope.promptData = {
|
$scope.nodeBeingEdited.promptData = $scope.promptData = {
|
||||||
launchConf: launchConf,
|
launchConf: launchConf,
|
||||||
launchOptions: launchOptions,
|
launchOptions: launchOptions,
|
||||||
@@ -741,8 +734,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
$scope.workflowMakerFormConfig.activeTab = "inventory_sync";
|
$scope.workflowMakerFormConfig.activeTab = "inventory_sync";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if ($scope.selectedTemplate.type) {
|
||||||
else if($scope.selectedTemplate.type) {
|
|
||||||
switch ($scope.selectedTemplate.type) {
|
switch ($scope.selectedTemplate.type) {
|
||||||
case "job_template":
|
case "job_template":
|
||||||
$scope.workflowMakerFormConfig.activeTab = "jobs";
|
$scope.workflowMakerFormConfig.activeTab = "jobs";
|
||||||
@@ -862,8 +854,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
if ($scope.placeholderNode.isRoot) {
|
if ($scope.placeholderNode.isRoot) {
|
||||||
updateEdgeDropdownOptions(["always"]);
|
updateEdgeDropdownOptions(["always"]);
|
||||||
edgeType = {label: "Always", value: "always"};
|
edgeType = {label: "Always", value: "always"};
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// we need to update the possible edges based on any new siblings
|
// we need to update the possible edges based on any new siblings
|
||||||
let siblingConnectionTypes = WorkflowService.getSiblingConnectionTypes({
|
let siblingConnectionTypes = WorkflowService.getSiblingConnectionTypes({
|
||||||
tree: $scope.treeData.data,
|
tree: $scope.treeData.data,
|
||||||
@@ -889,8 +880,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
|
|
||||||
}
|
}
|
||||||
$scope.edgeType = edgeType;
|
$scope.edgeType = edgeType;
|
||||||
}
|
} else if ($scope.nodeBeingEdited) {
|
||||||
else if($scope.nodeBeingEdited) {
|
|
||||||
let siblingConnectionTypes = WorkflowService.getSiblingConnectionTypes({
|
let siblingConnectionTypes = WorkflowService.getSiblingConnectionTypes({
|
||||||
tree: $scope.treeData.data,
|
tree: $scope.treeData.data,
|
||||||
parentId: $scope.nodeBeingEdited.parent.id,
|
parentId: $scope.nodeBeingEdited.parent.id,
|
||||||
@@ -1021,8 +1011,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
|
|
||||||
watchForPromptChanges();
|
watchForPromptChanges();
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
$scope.promptData = {
|
$scope.promptData = {
|
||||||
launchConf: responses[1].data,
|
launchConf: responses[1].data,
|
||||||
launchOptions: responses[0].data,
|
launchOptions: responses[0].data,
|
||||||
@@ -1120,8 +1109,7 @@ export default ['$scope', 'WorkflowService', 'GetBasePath', 'TemplatesService',
|
|||||||
// Get the next page
|
// Get the next page
|
||||||
page++;
|
page++;
|
||||||
getNodes();
|
getNodes();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// This is the last page
|
// This is the last page
|
||||||
buildTreeFromNodes();
|
buildTreeFromNodes();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user