2 * Copyright © 2019 IBM.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.ccsdk.cds.blueprintsprocessor.functions.ansible.executor
19 import com.fasterxml.jackson.databind.JsonNode
20 import com.fasterxml.jackson.databind.ObjectMapper
23 import kotlinx.coroutines.runBlocking
24 import org.junit.Assert.assertEquals
25 import org.junit.Assert.assertTrue
27 import org.junit.runner.RunWith
28 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
29 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StepData
30 import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BluePrintRestLibPropertyService
31 import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService
32 import org.onap.ccsdk.cds.blueprintsprocessor.rest.service.BlueprintWebClientService.WebClientResponse
33 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
34 import org.onap.ccsdk.cds.controllerblueprints.core.putJsonElement
35 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
36 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
37 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
38 import org.springframework.test.context.TestPropertySource
39 import org.springframework.test.context.junit4.SpringRunner
41 @RunWith(SpringRunner::class)
42 @TestPropertySource(locations = ["classpath:application-test.properties"])
43 @Suppress("SameParameterValue")
44 class ComponentRemoteAnsibleExecutorTest {
46 private val webClientService = mockk<BlueprintWebClientService>()
49 private const val jtId = 9
50 private const val jobId = 223
52 private val mapper = ObjectMapper()
54 // IMPORTANT: must match the corresponding properties blueprintsprocessor.restclient.awx.* on
55 // "application-test.properties"
56 private const val endpointSelector = """{
58 "url": "http://142.44.184.236",
59 "token": "Bearer J9gEtMDqf7P4YsJ7444fioY9VAhLDIs1"
64 fun testComponentRemoteAnsibleExecutor() {
67 webClientService.exchangeResource("GET", "/api/v2/job_templates/hello_world_job_template/", "")
68 } returns WebClientResponse(200, getJobTemplates(jtId))
70 webClientService.exchangeResource("GET", "/api/v2/job_templates/$jtId/launch/", "")
71 } returns WebClientResponse(200, getJobTemplateLaunch(jtId))
73 webClientService.exchangeResource("GET", "/api/v2/inventories/?name=Demo+Inventory", "")
74 } returns WebClientResponse(200, getInventory())
76 webClientService.exchangeResource("POST", "/api/v2/job_templates/$jtId/launch/",
77 """{"inventory":1,"extra_vars":{"site_id":"3 - Belmont","tor_group":"vEPC"}}""")
78 } returns WebClientResponse(201, newJobTemplateLaunch(jtId, jobId))
80 webClientService.exchangeResource("GET", "/api/v2/jobs/$jobId/", "")
82 WebClientResponse(200, getJobStatus1(jtId, jobId)),
83 WebClientResponse(200, getJobStatus2(jtId, jobId)),
84 WebClientResponse(200, getJobStatus3(jtId, jobId)),
85 WebClientResponse(200, getJobStatus4(jtId, jobId))
88 webClientService.exchangeResource("GET", "/api/v2/jobs/$jobId/stdout/?format=txt", "",
89 mapOf("Accept" to "text/plain"))
90 } returns WebClientResponse(200, getReport())
91 val selector = mapper.readTree(endpointSelector)
92 val bluePrintRestLibPropertyService = mockk<BluePrintRestLibPropertyService>()
93 every { bluePrintRestLibPropertyService.blueprintWebClientService(selector) } returns webClientService
94 val awxRemoteExecutor = ComponentRemoteAnsibleExecutor(bluePrintRestLibPropertyService, mapper)
95 awxRemoteExecutor.checkDelay = 1
97 val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
98 "payload/requests/sample-remote-ansible-request.json",
99 ExecutionServiceInput::class.java)!!
101 val bluePrintRuntimeService = createBlueprintRuntimeService(awxRemoteExecutor, executionServiceInput)
105 awxRemoteExecutor.applyNB(executionServiceInput)
109 assertTrue(bluePrintRuntimeService.getBluePrintError().errors.isEmpty())
113 fun `handle unknown inventory`() {
116 webClientService.exchangeResource("GET", "/api/v2/job_templates/hello_world_job_template/", "")
117 } returns WebClientResponse(200, getJobTemplates(jtId))
119 webClientService.exchangeResource("GET", "/api/v2/job_templates/$jtId/launch/", "")
120 } returns WebClientResponse(200, getJobTemplateLaunch(jtId))
122 webClientService.exchangeResource("GET", "/api/v2/inventories/?name=Demo+Inventory", "")
123 } returns WebClientResponse(404, "")
124 val selector = mapper.readTree(endpointSelector)
125 val bluePrintRestLibPropertyService = mockk<BluePrintRestLibPropertyService>()
126 every { bluePrintRestLibPropertyService.blueprintWebClientService(selector) } returns webClientService
127 val awxRemoteExecutor = ComponentRemoteAnsibleExecutor(bluePrintRestLibPropertyService, mapper)
128 awxRemoteExecutor.checkDelay = 1
130 val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
131 "payload/requests/remote-ansible-request-full.json",
132 ExecutionServiceInput::class.java)!!
134 val bluePrintRuntimeService = createBlueprintRuntimeService(awxRemoteExecutor, executionServiceInput)
138 awxRemoteExecutor.applyNB(executionServiceInput)
142 val errors = bluePrintRuntimeService.getBluePrintError().errors
143 assertEquals(1, errors.size)
147 fun `handle failure on job submission`() {
150 webClientService.exchangeResource("GET", "/api/v2/job_templates/hello_world_job_template/", "")
151 } returns WebClientResponse(200, getJobTemplates(jtId))
153 webClientService.exchangeResource("GET", "/api/v2/job_templates/$jtId/launch/", "")
154 } returns WebClientResponse(200, getJobTemplateLaunch(jtId))
156 webClientService.exchangeResource("GET", "/api/v2/inventories/?name=Demo+Inventory", "")
157 } returns WebClientResponse(200, getInventory())
159 webClientService.exchangeResource("POST", "/api/v2/job_templates/$jtId/launch/",
160 """{"limit":"123","tags":"some-tag","skip_tags":"some-skip-tag","inventory":1,"extra_vars":{"site_id":"3 - Belmont","tor_group":"vEPC"}}""")
161 } returns WebClientResponse(500, "")
162 val selector = mapper.readTree(endpointSelector)
163 val bluePrintRestLibPropertyService = mockk<BluePrintRestLibPropertyService>()
164 every { bluePrintRestLibPropertyService.blueprintWebClientService(selector) } returns webClientService
165 val awxRemoteExecutor = ComponentRemoteAnsibleExecutor(bluePrintRestLibPropertyService, mapper)
166 awxRemoteExecutor.checkDelay = 1
168 val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
169 "payload/requests/remote-ansible-request-full.json",
170 ExecutionServiceInput::class.java)!!
172 val bluePrintRuntimeService = createBlueprintRuntimeService(awxRemoteExecutor, executionServiceInput)
176 awxRemoteExecutor.applyNB(executionServiceInput)
180 val errors = bluePrintRuntimeService.getBluePrintError().errors
181 assertEquals(1, errors.size)
184 private fun createBlueprintRuntimeService(awxRemoteExecutor: ComponentRemoteAnsibleExecutor, executionServiceInput: ExecutionServiceInput): BluePrintRuntimeService<MutableMap<String, JsonNode>> {
185 val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime("123456-1000",
186 "./../../../../components/model-catalog/blueprint-model/test-blueprint/remote_ansible")
187 awxRemoteExecutor.bluePrintRuntimeService = bluePrintRuntimeService
189 val workflowName = executionServiceInput.actionIdentifiers.actionName
191 // Assign Workflow inputs
192 val input = executionServiceInput.payload.get("$workflowName-request")
193 bluePrintRuntimeService.assignWorkflowInputs(workflowName, input)
195 val stepMetaData: MutableMap<String, JsonNode> = hashMapOf()
196 stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "execute-remote-ansible")
197 stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_INTERFACE, "ComponentRemoteAnsibleExecutor")
198 stepMetaData.putJsonElement(BluePrintConstants.PROPERTY_CURRENT_OPERATION, "process")
200 val stepInputData = StepData().apply {
201 name = "execute-remote-ansible"
202 properties = stepMetaData
204 executionServiceInput.stepData = stepInputData
205 return bluePrintRuntimeService
208 private fun getJobTemplates(jtId: Int) = """{
210 "type": "job_template",
211 "url": "/api/v2/job_templates/$jtId/",
213 "named_url": "/api/v2/job_templates/hello_world_job_template/",
214 "created_by": "/api/v2/users/1/",
215 "modified_by": "/api/v2/users/1/",
216 "labels": "/api/v2/job_templates/$jtId/labels/",
217 "inventory": "/api/v2/inventories/1/",
218 "project": "/api/v2/projects/8/",
219 "extra_credentials": "/api/v2/job_templates/$jtId/extra_credentials/",
220 "credentials": "/api/v2/job_templates/$jtId/credentials/",
221 "last_job": "/api/v2/jobs/222/",
222 "jobs": "/api/v2/job_templates/$jtId/jobs/",
223 "schedules": "/api/v2/job_templates/$jtId/schedules/",
224 "activity_stream": "/api/v2/job_templates/$jtId/activity_stream/",
225 "launch": "/api/v2/job_templates/$jtId/launch/",
226 "notification_templates_any": "/api/v2/job_templates/$jtId/notification_templates_any/",
227 "notification_templates_success": "/api/v2/job_templates/$jtId/notification_templates_success/",
228 "notification_templates_error": "/api/v2/job_templates/$jtId/notification_templates_error/",
229 "access_list": "/api/v2/job_templates/$jtId/access_list/",
230 "survey_spec": "/api/v2/job_templates/$jtId/survey_spec/",
231 "object_roles": "/api/v2/job_templates/$jtId/object_roles/",
232 "instance_groups": "/api/v2/job_templates/$jtId/instance_groups/",
233 "slice_workflow_jobs": "/api/v2/job_templates/$jtId/slice_workflow_jobs/",
234 "copy": "/api/v2/job_templates/$jtId/copy/"
239 "name": "Demo Inventory",
241 "has_active_failures": false,
243 "hosts_with_active_failures": 0,
245 "groups_with_active_failures": 0,
246 "has_inventory_sources": false,
247 "total_inventory_sources": 0,
248 "inventory_sources_with_failures": 0,
249 "organization_id": 1,
254 "name": "cds_playbooks",
255 "description": "CDS - cds_playbooks Project",
261 "name": "hello_world_job_template",
262 "description": "hello_world Runner Job Template",
263 "finished": "2019-06-12T11:20:27.892787Z",
264 "status": "successful",
269 "name": "hello_world_job_template",
270 "description": "hello_world Runner Job Template",
271 "status": "successful",
288 "description": "Can manage all aspects of the job template",
293 "description": "May run the job template",
298 "description": "May view settings for the job template",
303 "user_capabilities": {
321 "status": "successful",
322 "finished": "2019-06-12T11:20:27.892787Z",
327 "status": "successful",
328 "finished": "2019-06-03T18:27:19.114796Z",
333 "status": "successful",
334 "finished": "2019-06-03T18:26:53.606618Z",
339 "status": "successful",
340 "finished": "2019-06-03T18:24:36.072943Z",
345 "status": "successful",
346 "finished": "2019-06-03T18:17:50.616528Z",
351 "status": "successful",
352 "finished": "2019-06-03T18:04:42.995611Z",
357 "status": "successful",
358 "finished": "2019-06-03T17:47:13.983951Z",
363 "status": "successful",
364 "finished": "2019-05-30T15:47:55.700161Z",
369 "status": "successful",
370 "finished": "2019-05-29T14:46:51.615926Z",
375 "status": "successful",
376 "finished": "2019-05-27T20:23:58.656709Z",
380 "extra_credentials": [],
383 "created": "2019-05-21T19:28:05.953730Z",
384 "modified": "2019-05-21T20:06:55.728697Z",
385 "name": "hello_world_job_template",
386 "description": "hello_world Runner Job Template",
390 "playbook": "hello_world.yml",
396 "force_handlers": false,
400 "use_fact_cache": false,
401 "last_job_run": "2019-06-12T11:20:27.892787Z",
402 "last_job_failed": false,
403 "next_job_run": null,
404 "status": "successful",
405 "host_config_key": "",
406 "ask_diff_mode_on_launch": false,
407 "ask_variables_on_launch": true,
408 "ask_limit_on_launch": true,
409 "ask_tags_on_launch": true,
410 "ask_skip_tags_on_launch": true,
411 "ask_job_type_on_launch": false,
412 "ask_verbosity_on_launch": false,
413 "ask_inventory_on_launch": true,
414 "ask_credential_on_launch": true,
415 "survey_enabled": true,
416 "become_enabled": false,
418 "allow_simultaneous": false,
419 "custom_virtualenv": null,
420 "job_slice_count": 1,
422 "vault_credential": null
425 private fun getJobTemplateLaunch(jtId: Int) = """{
426 "can_start_without_user_input": false,
427 "passwords_needed_to_start": [],
428 "ask_variables_on_launch": true,
429 "ask_tags_on_launch": true,
430 "ask_diff_mode_on_launch": false,
431 "ask_skip_tags_on_launch": true,
432 "ask_job_type_on_launch": false,
433 "ask_limit_on_launch": true,
434 "ask_verbosity_on_launch": false,
435 "ask_inventory_on_launch": true,
436 "ask_credential_on_launch": true,
437 "survey_enabled": true,
438 "variables_needed_to_start": [
442 "credential_needed_to_start": false,
443 "inventory_needed_to_start": false,
444 "job_template_data": {
445 "name": "hello_world_job_template",
447 "description": "hello_world Runner Job Template"
458 "name": "Demo Inventory",
464 private fun getInventory() = """{
472 "url": "/api/v2/inventories/1/",
474 "created_by": "/api/v2/users/1/",
475 "modified_by": "/api/v2/users/1/",
476 "hosts": "/api/v2/inventories/1/hosts/",
477 "groups": "/api/v2/inventories/1/groups/",
478 "root_groups": "/api/v2/inventories/1/root_groups/",
479 "variable_data": "/api/v2/inventories/1/variable_data/",
480 "script": "/api/v2/inventories/1/script/",
481 "tree": "/api/v2/inventories/1/tree/",
482 "inventory_sources": "/api/v2/inventories/1/inventory_sources/",
483 "update_inventory_sources": "/api/v2/inventories/1/update_inventory_sources/",
484 "activity_stream": "/api/v2/inventories/1/activity_stream/",
485 "job_templates": "/api/v2/inventories/1/job_templates/",
486 "ad_hoc_commands": "/api/v2/inventories/1/ad_hoc_commands/",
487 "access_list": "/api/v2/inventories/1/access_list/",
488 "object_roles": "/api/v2/inventories/1/object_roles/",
489 "instance_groups": "/api/v2/inventories/1/instance_groups/",
490 "copy": "/api/v2/inventories/1/copy/",
491 "organization": "/api/v2/organizations/1/"
513 "description": "Can manage all aspects of the inventory",
518 "description": "May update project or inventory or group using the configured source update system",
523 "description": "May run ad hoc commands on an inventory",
528 "description": "Can use the inventory in a job template",
533 "description": "May view settings for the inventory",
538 "user_capabilities": {
545 "created": "2019-05-21T15:45:31.954359Z",
546 "modified": "2019-05-21T15:45:31.954378Z",
547 "name": "Demo Inventory",
553 "has_active_failures": false,
555 "hosts_with_active_failures": 0,
557 "groups_with_active_failures": 0,
558 "has_inventory_sources": false,
559 "total_inventory_sources": 0,
560 "inventory_sources_with_failures": 0,
561 "insights_credential": null,
562 "pending_deletion": false
567 private fun newJobTemplateLaunch(jtId: Int, jobId: Int) = """{
569 "ignored_fields": {},
572 "url": "/api/v2/jobs/$jobId/",
574 "created_by": "/api/v2/users/1/",
575 "modified_by": "/api/v2/users/1/",
576 "labels": "/api/v2/jobs/$jobId/labels/",
577 "inventory": "/api/v2/inventories/1/",
578 "project": "/api/v2/projects/8/",
579 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
580 "credentials": "/api/v2/jobs/$jobId/credentials/",
581 "unified_job_template": "/api/v2/job_templates/$jtId/",
582 "stdout": "/api/v2/jobs/$jobId/stdout/",
583 "job_events": "/api/v2/jobs/$jobId/job_events/",
584 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
585 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
586 "notifications": "/api/v2/jobs/$jobId/notifications/",
587 "job_template": "/api/v2/job_templates/$jtId/",
588 "cancel": "/api/v2/jobs/$jobId/cancel/",
589 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
590 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
595 "name": "Demo Inventory",
597 "has_active_failures": false,
599 "hosts_with_active_failures": 0,
601 "groups_with_active_failures": 0,
602 "has_inventory_sources": false,
603 "total_inventory_sources": 0,
604 "inventory_sources_with_failures": 0,
605 "organization_id": 1,
610 "name": "cds_playbooks",
611 "description": "CDS - cds_playbooks Project",
617 "name": "hello_world_job_template",
618 "description": "hello_world Runner Job Template"
620 "unified_job_template": {
622 "name": "hello_world_job_template",
623 "description": "hello_world Runner Job Template",
624 "unified_job_type": "job"
638 "user_capabilities": {
646 "extra_credentials": [],
649 "created": "2019-06-12T11:21:26.891986Z",
650 "modified": "2019-06-12T11:21:27.016410Z",
651 "name": "hello_world_job_template",
652 "description": "hello_world Runner Job Template",
656 "playbook": "hello_world.yml",
660 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
662 "force_handlers": false,
666 "use_fact_cache": false,
667 "unified_job_template": $jtId,
668 "launch_type": "manual",
677 "job_explanation": "",
678 "execution_node": "",
679 "controller_node": "",
680 "result_traceback": "",
681 "event_processing_finished": false,
682 "job_template": $jtId,
683 "passwords_needed_to_start": [],
684 "ask_diff_mode_on_launch": false,
685 "ask_variables_on_launch": true,
686 "ask_limit_on_launch": true,
687 "ask_tags_on_launch": true,
688 "ask_skip_tags_on_launch": true,
689 "ask_job_type_on_launch": false,
690 "ask_verbosity_on_launch": false,
691 "ask_inventory_on_launch": true,
692 "ask_credential_on_launch": true,
693 "allow_simultaneous": false,
696 "instance_group": null,
698 "job_slice_number": 0,
699 "job_slice_count": 1,
701 "vault_credential": null
704 private fun getJobStatus1(jtId: Int, jobId: Int) = """{
707 "url": "/api/v2/jobs/$jobId/",
709 "created_by": "/api/v2/users/1/",
710 "labels": "/api/v2/jobs/$jobId/labels/",
711 "inventory": "/api/v2/inventories/1/",
712 "project": "/api/v2/projects/8/",
713 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
714 "credentials": "/api/v2/jobs/$jobId/credentials/",
715 "unified_job_template": "/api/v2/job_templates/$jtId/",
716 "stdout": "/api/v2/jobs/$jobId/stdout/",
717 "job_events": "/api/v2/jobs/$jobId/job_events/",
718 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
719 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
720 "notifications": "/api/v2/jobs/$jobId/notifications/",
721 "job_template": "/api/v2/job_templates/$jtId/",
722 "cancel": "/api/v2/jobs/$jobId/cancel/",
723 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
724 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
729 "name": "Demo Inventory",
731 "has_active_failures": false,
733 "hosts_with_active_failures": 0,
735 "groups_with_active_failures": 0,
736 "has_inventory_sources": false,
737 "total_inventory_sources": 0,
738 "inventory_sources_with_failures": 0,
739 "organization_id": 1,
744 "name": "cds_playbooks",
745 "description": "CDS - cds_playbooks Project",
751 "name": "hello_world_job_template",
752 "description": "hello_world Runner Job Template"
754 "unified_job_template": {
756 "name": "hello_world_job_template",
757 "description": "hello_world Runner Job Template",
758 "unified_job_type": "job"
770 "user_capabilities": {
778 "extra_credentials": [],
781 "created": "2019-06-12T11:21:26.891986Z",
782 "modified": "2019-06-12T11:21:27.355185Z",
783 "name": "hello_world_job_template",
784 "description": "hello_world Runner Job Template",
788 "playbook": "hello_world.yml",
792 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
794 "force_handlers": false,
798 "use_fact_cache": false,
799 "unified_job_template": $jtId,
800 "launch_type": "manual",
809 "job_explanation": "",
810 "execution_node": "awx",
811 "controller_node": "",
812 "result_traceback": "",
813 "event_processing_finished": false,
814 "job_template": $jtId,
815 "passwords_needed_to_start": [],
816 "ask_diff_mode_on_launch": false,
817 "ask_variables_on_launch": true,
818 "ask_limit_on_launch": true,
819 "ask_tags_on_launch": true,
820 "ask_skip_tags_on_launch": true,
821 "ask_job_type_on_launch": false,
822 "ask_verbosity_on_launch": false,
823 "ask_inventory_on_launch": true,
824 "ask_credential_on_launch": true,
825 "allow_simultaneous": false,
830 "job_slice_number": 0,
831 "job_slice_count": 1,
832 "host_status_counts": {},
837 "custom_virtualenv": null,
839 "vault_credential": null
842 private fun getJobStatus2(jtId: Int, jobId: Int) = """{
845 "url": "/api/v2/jobs/$jobId/",
847 "created_by": "/api/v2/users/1/",
848 "labels": "/api/v2/jobs/$jobId/labels/",
849 "inventory": "/api/v2/inventories/1/",
850 "project": "/api/v2/projects/8/",
851 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
852 "credentials": "/api/v2/jobs/$jobId/credentials/",
853 "unified_job_template": "/api/v2/job_templates/$jtId/",
854 "stdout": "/api/v2/jobs/$jobId/stdout/",
855 "job_events": "/api/v2/jobs/$jobId/job_events/",
856 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
857 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
858 "notifications": "/api/v2/jobs/$jobId/notifications/",
859 "job_template": "/api/v2/job_templates/$jtId/",
860 "cancel": "/api/v2/jobs/$jobId/cancel/",
861 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
862 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
867 "name": "Demo Inventory",
869 "has_active_failures": false,
871 "hosts_with_active_failures": 0,
873 "groups_with_active_failures": 0,
874 "has_inventory_sources": false,
875 "total_inventory_sources": 0,
876 "inventory_sources_with_failures": 0,
877 "organization_id": 1,
882 "name": "cds_playbooks",
883 "description": "CDS - cds_playbooks Project",
889 "name": "hello_world_job_template",
890 "description": "hello_world Runner Job Template"
892 "unified_job_template": {
894 "name": "hello_world_job_template",
895 "description": "hello_world Runner Job Template",
896 "unified_job_type": "job"
908 "user_capabilities": {
916 "extra_credentials": [],
919 "created": "2019-06-12T11:21:26.891986Z",
920 "modified": "2019-06-12T11:21:27.355185Z",
921 "name": "hello_world_job_template",
922 "description": "hello_world Runner Job Template",
926 "playbook": "hello_world.yml",
930 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
932 "force_handlers": false,
936 "use_fact_cache": false,
937 "unified_job_template": $jtId,
938 "launch_type": "manual",
941 "started": "2019-06-12T11:21:27.510766Z",
943 "elapsed": 10.862184,
944 "job_args": "[\"ansible-playbook\", \"-u\", \"root\", \"-i\", \"/tmp/awx_223_ft8hu4p4/tmptmtwllu4\", \"-e\", \"@/tmp/awx_223_ft8hu4p4/env/extravars\", \"hello_world.yml\"]",
945 "job_cwd": "/var/lib/awx/projects/cds_playbooks_folder",
948 "LC_ALL": "en_US.UTF-8",
949 "VIRTUAL_ENV": "/var/lib/awx/venv/ansible",
950 "PATH": "/var/lib/awx/venv/ansible/bin:/var/lib/awx/venv/awx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
951 "SUPERVISOR_GROUP_NAME": "tower-processes",
952 "PWD": "/var/lib/awx",
953 "LANG": "en_US.UTF-8",
955 "SUPERVISOR_ENABLED": "1",
956 "HOME": "/var/lib/awx",
958 "LANGUAGE": "en_US.UTF-8",
959 "LC_CTYPE": "en_US.UTF-8",
960 "SUPERVISOR_PROCESS_NAME": "dispatcher",
961 "SUPERVISOR_SERVER_URL": "unix:///tmp/supervisor.sock",
962 "DJANGO_SETTINGS_MODULE": "awx.settings.production",
963 "DJANGO_LIVE_TEST_SERVER_ADDRESS": "localhost:9013-9199",
965 "ANSIBLE_FORCE_COLOR": "True",
966 "ANSIBLE_HOST_KEY_CHECKING": "False",
967 "ANSIBLE_INVENTORY_UNPARSED_FAILED": "True",
968 "ANSIBLE_PARAMIKO_RECORD_HOST_KEYS": "False",
969 "ANSIBLE_VENV_PATH": "/var/lib/awx/venv/ansible",
970 "AWX_PRIVATE_DATA_DIR": "/tmp/awx_223_ft8hu4p4",
971 "PYTHONPATH": "/var/lib/awx/venv/ansible/lib/python2.7/site-packages:/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/lib:",
974 "PROJECT_REVISION": "",
975 "ANSIBLE_RETRY_FILES_ENABLED": "False",
976 "MAX_EVENT_RES": "700000",
977 "ANSIBLE_CALLBACK_PLUGINS": "/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/plugins/callback",
978 "AWX_HOST": "https://towerhost",
979 "ANSIBLE_SSH_CONTROL_PATH_DIR": "/tmp/awx_223_ft8hu4p4/cp",
980 "ANSIBLE_STDOUT_CALLBACK": "awx_display",
981 "AWX_ISOLATED_DATA_DIR": "/tmp/awx_223_ft8hu4p4/artifacts/$jobId"
983 "job_explanation": "",
984 "execution_node": "awx",
985 "controller_node": "",
986 "result_traceback": "",
987 "event_processing_finished": false,
988 "job_template": $jtId,
989 "passwords_needed_to_start": [],
990 "ask_diff_mode_on_launch": false,
991 "ask_variables_on_launch": true,
992 "ask_limit_on_launch": true,
993 "ask_tags_on_launch": true,
994 "ask_skip_tags_on_launch": true,
995 "ask_job_type_on_launch": false,
996 "ask_verbosity_on_launch": false,
997 "ask_inventory_on_launch": true,
998 "ask_credential_on_launch": true,
999 "allow_simultaneous": false,
1002 "instance_group": 1,
1004 "job_slice_number": 0,
1005 "job_slice_count": 1,
1006 "host_status_counts": {},
1007 "playbook_counts": {
1011 "custom_virtualenv": "/var/lib/awx/venv/ansible",
1013 "vault_credential": null
1016 private fun getJobStatus3(jtId: Int, jobId: Int) = """{
1019 "url": "/api/v2/jobs/$jobId/",
1021 "created_by": "/api/v2/users/1/",
1022 "labels": "/api/v2/jobs/$jobId/labels/",
1023 "inventory": "/api/v2/inventories/1/",
1024 "project": "/api/v2/projects/8/",
1025 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
1026 "credentials": "/api/v2/jobs/$jobId/credentials/",
1027 "unified_job_template": "/api/v2/job_templates/$jtId/",
1028 "stdout": "/api/v2/jobs/$jobId/stdout/",
1029 "job_events": "/api/v2/jobs/$jobId/job_events/",
1030 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
1031 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
1032 "notifications": "/api/v2/jobs/$jobId/notifications/",
1033 "job_template": "/api/v2/job_templates/$jtId/",
1034 "cancel": "/api/v2/jobs/$jobId/cancel/",
1035 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
1036 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
1041 "name": "Demo Inventory",
1043 "has_active_failures": false,
1045 "hosts_with_active_failures": 0,
1047 "groups_with_active_failures": 0,
1048 "has_inventory_sources": false,
1049 "total_inventory_sources": 0,
1050 "inventory_sources_with_failures": 0,
1051 "organization_id": 1,
1056 "name": "cds_playbooks",
1057 "description": "CDS - cds_playbooks Project",
1063 "name": "hello_world_job_template",
1064 "description": "hello_world Runner Job Template"
1066 "unified_job_template": {
1068 "name": "hello_world_job_template",
1069 "description": "hello_world Runner Job Template",
1070 "unified_job_type": "job"
1078 "username": "admin",
1082 "user_capabilities": {
1090 "extra_credentials": [],
1093 "created": "2019-06-12T11:21:26.891986Z",
1094 "modified": "2019-06-12T11:21:27.355185Z",
1095 "name": "hello_world_job_template",
1096 "description": "hello_world Runner Job Template",
1100 "playbook": "hello_world.yml",
1104 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
1106 "force_handlers": false,
1108 "start_at_task": "",
1110 "use_fact_cache": false,
1111 "unified_job_template": $jtId,
1112 "launch_type": "manual",
1113 "status": "running",
1115 "started": "2019-06-12T11:21:27.510766Z",
1117 "elapsed": 21.297881,
1118 "job_args": "[\"ansible-playbook\", \"-u\", \"root\", \"-i\", \"/tmp/awx_223_ft8hu4p4/tmptmtwllu4\", \"-e\", \"@/tmp/awx_223_ft8hu4p4/env/extravars\", \"hello_world.yml\"]",
1119 "job_cwd": "/var/lib/awx/projects/cds_playbooks_folder",
1122 "LC_ALL": "en_US.UTF-8",
1123 "VIRTUAL_ENV": "/var/lib/awx/venv/ansible",
1124 "PATH": "/var/lib/awx/venv/ansible/bin:/var/lib/awx/venv/awx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
1125 "SUPERVISOR_GROUP_NAME": "tower-processes",
1126 "PWD": "/var/lib/awx",
1127 "LANG": "en_US.UTF-8",
1129 "SUPERVISOR_ENABLED": "1",
1130 "HOME": "/var/lib/awx",
1132 "LANGUAGE": "en_US.UTF-8",
1133 "LC_CTYPE": "en_US.UTF-8",
1134 "SUPERVISOR_PROCESS_NAME": "dispatcher",
1135 "SUPERVISOR_SERVER_URL": "unix:///tmp/supervisor.sock",
1136 "DJANGO_SETTINGS_MODULE": "awx.settings.production",
1137 "DJANGO_LIVE_TEST_SERVER_ADDRESS": "localhost:9013-9199",
1139 "ANSIBLE_FORCE_COLOR": "True",
1140 "ANSIBLE_HOST_KEY_CHECKING": "False",
1141 "ANSIBLE_INVENTORY_UNPARSED_FAILED": "True",
1142 "ANSIBLE_PARAMIKO_RECORD_HOST_KEYS": "False",
1143 "ANSIBLE_VENV_PATH": "/var/lib/awx/venv/ansible",
1144 "AWX_PRIVATE_DATA_DIR": "/tmp/awx_223_ft8hu4p4",
1145 "PYTHONPATH": "/var/lib/awx/venv/ansible/lib/python2.7/site-packages:/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/lib:",
1147 "INVENTORY_ID": "1",
1148 "PROJECT_REVISION": "",
1149 "ANSIBLE_RETRY_FILES_ENABLED": "False",
1150 "MAX_EVENT_RES": "700000",
1151 "ANSIBLE_CALLBACK_PLUGINS": "/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/plugins/callback",
1152 "AWX_HOST": "https://towerhost",
1153 "ANSIBLE_SSH_CONTROL_PATH_DIR": "/tmp/awx_223_ft8hu4p4/cp",
1154 "ANSIBLE_STDOUT_CALLBACK": "awx_display",
1155 "AWX_ISOLATED_DATA_DIR": "/tmp/awx_223_ft8hu4p4/artifacts/$jobId"
1157 "job_explanation": "",
1158 "execution_node": "awx",
1159 "controller_node": "",
1160 "result_traceback": "",
1161 "event_processing_finished": false,
1162 "job_template": $jtId,
1163 "passwords_needed_to_start": [],
1164 "ask_diff_mode_on_launch": false,
1165 "ask_variables_on_launch": true,
1166 "ask_limit_on_launch": true,
1167 "ask_tags_on_launch": true,
1168 "ask_skip_tags_on_launch": true,
1169 "ask_job_type_on_launch": false,
1170 "ask_verbosity_on_launch": false,
1171 "ask_inventory_on_launch": true,
1172 "ask_credential_on_launch": true,
1173 "allow_simultaneous": false,
1176 "instance_group": 1,
1178 "job_slice_number": 0,
1179 "job_slice_count": 1,
1180 "host_status_counts": {},
1181 "playbook_counts": {
1185 "custom_virtualenv": "/var/lib/awx/venv/ansible",
1187 "vault_credential": null
1190 private fun getJobStatus4(jtId: Int, jobId: Int) = """{
1193 "url": "/api/v2/jobs/$jobId/",
1195 "created_by": "/api/v2/users/1/",
1196 "labels": "/api/v2/jobs/$jobId/labels/",
1197 "inventory": "/api/v2/inventories/1/",
1198 "project": "/api/v2/projects/8/",
1199 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
1200 "credentials": "/api/v2/jobs/$jobId/credentials/",
1201 "unified_job_template": "/api/v2/job_templates/$jtId/",
1202 "stdout": "/api/v2/jobs/$jobId/stdout/",
1203 "job_events": "/api/v2/jobs/$jobId/job_events/",
1204 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
1205 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
1206 "notifications": "/api/v2/jobs/$jobId/notifications/",
1207 "job_template": "/api/v2/job_templates/$jtId/",
1208 "cancel": "/api/v2/jobs/$jobId/cancel/",
1209 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
1210 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
1215 "name": "Demo Inventory",
1217 "has_active_failures": false,
1219 "hosts_with_active_failures": 0,
1221 "groups_with_active_failures": 0,
1222 "has_inventory_sources": false,
1223 "total_inventory_sources": 0,
1224 "inventory_sources_with_failures": 0,
1225 "organization_id": 1,
1230 "name": "cds_playbooks",
1231 "description": "CDS - cds_playbooks Project",
1237 "name": "hello_world_job_template",
1238 "description": "hello_world Runner Job Template"
1240 "unified_job_template": {
1242 "name": "hello_world_job_template",
1243 "description": "hello_world Runner Job Template",
1244 "unified_job_type": "job"
1252 "username": "admin",
1256 "user_capabilities": {
1264 "extra_credentials": [],
1267 "created": "2019-06-12T11:21:26.891986Z",
1268 "modified": "2019-06-12T11:21:27.355185Z",
1269 "name": "hello_world_job_template",
1270 "description": "hello_world Runner Job Template",
1274 "playbook": "hello_world.yml",
1278 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
1280 "force_handlers": false,
1282 "start_at_task": "",
1284 "use_fact_cache": false,
1285 "unified_job_template": $jtId,
1286 "launch_type": "manual",
1287 "status": "successful",
1289 "started": "2019-06-12T11:21:27.510766Z",
1290 "finished": "2019-06-12T11:21:48.993385Z",
1292 "job_args": "[\"ansible-playbook\", \"-u\", \"root\", \"-i\", \"/tmp/awx_223_ft8hu4p4/tmptmtwllu4\", \"-e\", \"@/tmp/awx_223_ft8hu4p4/env/extravars\", \"hello_world.yml\"]",
1293 "job_cwd": "/var/lib/awx/projects/cds_playbooks_folder",
1296 "LC_ALL": "en_US.UTF-8",
1297 "VIRTUAL_ENV": "/var/lib/awx/venv/ansible",
1298 "PATH": "/var/lib/awx/venv/ansible/bin:/var/lib/awx/venv/awx/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
1299 "SUPERVISOR_GROUP_NAME": "tower-processes",
1300 "PWD": "/var/lib/awx",
1301 "LANG": "en_US.UTF-8",
1303 "SUPERVISOR_ENABLED": "1",
1304 "HOME": "/var/lib/awx",
1306 "LANGUAGE": "en_US.UTF-8",
1307 "LC_CTYPE": "en_US.UTF-8",
1308 "SUPERVISOR_PROCESS_NAME": "dispatcher",
1309 "SUPERVISOR_SERVER_URL": "unix:///tmp/supervisor.sock",
1310 "DJANGO_SETTINGS_MODULE": "awx.settings.production",
1311 "DJANGO_LIVE_TEST_SERVER_ADDRESS": "localhost:9013-9199",
1313 "ANSIBLE_FORCE_COLOR": "True",
1314 "ANSIBLE_HOST_KEY_CHECKING": "False",
1315 "ANSIBLE_INVENTORY_UNPARSED_FAILED": "True",
1316 "ANSIBLE_PARAMIKO_RECORD_HOST_KEYS": "False",
1317 "ANSIBLE_VENV_PATH": "/var/lib/awx/venv/ansible",
1318 "AWX_PRIVATE_DATA_DIR": "/tmp/awx_223_ft8hu4p4",
1319 "PYTHONPATH": "/var/lib/awx/venv/ansible/lib/python2.7/site-packages:/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/lib:",
1321 "INVENTORY_ID": "1",
1322 "PROJECT_REVISION": "",
1323 "ANSIBLE_RETRY_FILES_ENABLED": "False",
1324 "MAX_EVENT_RES": "700000",
1325 "ANSIBLE_CALLBACK_PLUGINS": "/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/plugins/callback",
1326 "AWX_HOST": "https://towerhost",
1327 "ANSIBLE_SSH_CONTROL_PATH_DIR": "/tmp/awx_223_ft8hu4p4/cp",
1328 "ANSIBLE_STDOUT_CALLBACK": "awx_display",
1329 "AWX_ISOLATED_DATA_DIR": "/tmp/awx_223_ft8hu4p4/artifacts/$jobId"
1331 "job_explanation": "",
1332 "execution_node": "awx",
1333 "controller_node": "",
1334 "result_traceback": "",
1335 "event_processing_finished": true,
1336 "job_template": $jtId,
1337 "passwords_needed_to_start": [],
1338 "ask_diff_mode_on_launch": false,
1339 "ask_variables_on_launch": true,
1340 "ask_limit_on_launch": true,
1341 "ask_tags_on_launch": true,
1342 "ask_skip_tags_on_launch": true,
1343 "ask_job_type_on_launch": false,
1344 "ask_verbosity_on_launch": false,
1345 "ask_inventory_on_launch": true,
1346 "ask_credential_on_launch": true,
1347 "allow_simultaneous": false,
1350 "instance_group": 1,
1352 "job_slice_number": 0,
1353 "job_slice_count": 1,
1354 "host_status_counts": {
1357 "playbook_counts": {
1361 "custom_virtualenv": "/var/lib/awx/venv/ansible",
1363 "vault_credential": null
1366 private fun getReport() = """
1368 PLAY [Hello World Sample] ******************************************************
1370 TASK [Gathering Facts] *********************************************************
1373 TASK [Hello Message] ***********************************************************
1374 ok: [localhost] => {
1375 "msg": "Hello World!"
1378 PLAY RECAP *********************************************************************
1379 localhost : ok=2 changed=0 unreachable=0 failed=0