Merge pull request #4653 from AlanCoding/copy_sp

Refactor of /copy/ GET schema
This commit is contained in:
Alan Rominger
2017-01-11 14:57:50 -05:00
committed by GitHub
4 changed files with 57 additions and 25 deletions

View File

@@ -2906,10 +2906,16 @@ class WorkflowJobTemplateCopy(WorkflowsEnforcementMixin, GenericAPIView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
obj = self.get_object() obj = self.get_object()
data = {} can_copy, messages = request.user.can_access_with_errors(self.model, 'copy', obj)
copy_TF, messages = request.user.can_access_with_errors(self.model, 'copy', obj) data = OrderedDict([
data['can_copy'] = copy_TF ('can_copy', can_copy), ('can_copy_without_user_input', can_copy),
data['warnings'] = messages ('templates_unable_to_copy', [] if can_copy else ['all']),
('credentials_unable_to_copy', [] if can_copy else ['all']),
('inventories_unable_to_copy', [] if can_copy else ['all'])
])
if messages and can_copy:
data['can_copy_without_user_input'] = False
data.update(messages)
return Response(data) return Response(data)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):

View File

@@ -1043,7 +1043,7 @@ class JobTemplateAccess(BaseAccess):
Project.accessible_objects(self.user, 'use_role').exists() or Project.accessible_objects(self.user, 'use_role').exists() or
Inventory.accessible_objects(self.user, 'use_role').exists()) Inventory.accessible_objects(self.user, 'use_role').exists())
# if reference_obj is provided, determine if it can be coppied # if reference_obj is provided, determine if it can be copied
reference_obj = data.get('reference_obj', None) reference_obj = data.get('reference_obj', None)
if 'job_type' in data and data['job_type'] == PERM_INVENTORY_SCAN: if 'job_type' in data and data['job_type'] == PERM_INVENTORY_SCAN:
@@ -1537,22 +1537,28 @@ class WorkflowJobTemplateAccess(BaseAccess):
def can_copy(self, obj): def can_copy(self, obj):
if self.save_messages: if self.save_messages:
wfjt_errors = {} missing_ujt = []
missing_credentials = []
missing_inventories = []
qs = obj.workflow_job_template_nodes qs = obj.workflow_job_template_nodes
qs.select_related('unified_job_template', 'inventory', 'credential') qs.select_related('unified_job_template', 'inventory', 'credential')
for node in qs.all(): for node in qs.all():
node_errors = {} node_errors = {}
if node.inventory and self.user not in node.inventory.use_role: if node.inventory and self.user not in node.inventory.use_role:
node_errors['inventory'] = 'Prompted inventory %s can not be coppied.' % node.inventory.name missing_inventories.append(node.inventory.name)
if node.credential and self.user not in node.credential.use_role: if node.credential and self.user not in node.credential.use_role:
node_errors['credential'] = 'Prompted credential %s can not be coppied.' % node.credential.name missing_credentials.append(node.credential.name)
ujt = node.unified_job_template ujt = node.unified_job_template
if ujt and not self.user.can_access(UnifiedJobTemplate, 'start', ujt, validate_license=False): if ujt and not self.user.can_access(UnifiedJobTemplate, 'start', ujt, validate_license=False):
node_errors['unified_job_template'] = ( missing_ujt.append(ujt.name)
'Prompted %s %s can not be coppied.' % (ujt._meta.verbose_name_raw, ujt.name))
if node_errors: if node_errors:
wfjt_errors[node.id] = node_errors wfjt_errors[node.id] = node_errors
self.messages.update(wfjt_errors) if missing_ujt:
self.messages['templates_unable_to_copy'] = missing_ujt
if missing_credentials:
self.messages['credentials_unable_to_copy'] = missing_credentials
if missing_inventories:
self.messages['inventories_unable_to_copy'] = missing_inventories
return self.check_related('organization', Organization, {'reference_obj': obj}, mandatory=True) return self.check_related('organization', Organization, {'reference_obj': obj}, mandatory=True)

View File

@@ -120,13 +120,11 @@ class TestWorkflowJobAccess:
access = WorkflowJobTemplateAccess(rando, save_messages=True) access = WorkflowJobTemplateAccess(rando, save_messages=True)
assert not access.can_copy(wfjt) assert not access.can_copy(wfjt)
warnings = access.messages warnings = access.messages
assert 1 in warnings assert 'inventories_unable_to_copy' in warnings
assert 'inventory' in warnings[1]
def test_workflow_copy_warnings_jt(self, wfjt, rando, job_template): def test_workflow_copy_warnings_jt(self, wfjt, rando, job_template):
wfjt.workflow_job_template_nodes.create(unified_job_template=job_template) wfjt.workflow_job_template_nodes.create(unified_job_template=job_template)
access = WorkflowJobTemplateAccess(rando, save_messages=True) access = WorkflowJobTemplateAccess(rando, save_messages=True)
assert not access.can_copy(wfjt) assert not access.can_copy(wfjt)
warnings = access.messages warnings = access.messages
assert 1 in warnings assert 'templates_unable_to_copy' in warnings
assert 'unified_job_template' in warnings[1]

View File

@@ -220,7 +220,7 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest',
.then(function(result) { .then(function(result) {
if(result.data.can_copy) { if(result.data.can_copy) {
if(!result.data.warnings || _.isEmpty(result.data.warnings)) { if(result.data.can_copy_without_user_input) {
// Go ahead and copy the workflow - the user has full priveleges on all the resources // Go ahead and copy the workflow - the user has full priveleges on all the resources
TemplateCopyService.copyWorkflow(template.id) TemplateCopyService.copyWorkflow(template.id)
.then(function(result) { .then(function(result) {
@@ -235,18 +235,40 @@ export default ['$scope', '$rootScope', '$location', '$stateParams', 'Rest',
let bodyHtml = ` let bodyHtml = `
<div class="Prompt-bodyQuery"> <div class="Prompt-bodyQuery">
You may not have access to all resources used by this workflow. Resources that you don\'t have access to will not be copied and may result in an incomplete workflow. You do not have access to all resources used by this workflow. Resources that you don\'t have access to will not be copied and will result in an incomplete workflow.
</div> </div>
<div class="Prompt-bodyTarget">`; <div class="Prompt-bodyTarget">`;
// Go and grab all of the warning strings // List the unified job templates user can not access
_.forOwn(result.data.warnings, function(warning) { if (result.data.templates_unable_to_copy.length > 0) {
if(warning) { bodyHtml += '<div>Unified Job Templates that can not be copied<ul>';
_.forOwn(warning, function(warningString) { _.forOwn(result.data.templates_unable_to_copy, function(ujt) {
bodyHtml += '<div>' + warningString + '</div>'; if(ujt) {
}); bodyHtml += '<li>' + ujt + '</li>';
} }
} ); });
bodyHtml += '</ul></div>';
}
// List the prompted inventories user can not access
if (result.data.inventories_unable_to_copy.length > 0) {
bodyHtml += '<div>Node prompted inventories that can not be copied<ul>';
_.forOwn(result.data.inventories_unable_to_copy, function(inv) {
if(inv) {
bodyHtml += '<li>' + inv + '</li>';
}
});
bodyHtml += '</ul></div>';
}
// List the prompted credentials user can not access
if (result.data.credentials_unable_to_copy.length > 0) {
bodyHtml += '<div>Node prompted credentials that can not be copied<ul>';
_.forOwn(result.data.credentials_unable_to_copy, function(cred) {
if(cred) {
bodyHtml += '<li>' + cred + '</li>';
}
});
bodyHtml += '</ul></div>';
}
bodyHtml += '</div>'; bodyHtml += '</div>';