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>()
50 private const val jtId = 9
51 private const val jobId = 223
53 private val mapper = ObjectMapper()
55 // IMPORTANT: must match the corresponding properties blueprintsprocessor.restclient.awx.* on
56 // "application-test.properties"
57 private const val endpointSelector = """{
59 "url": "http://142.44.184.236",
60 "token": "Bearer J9gEtMDqf7P4YsJ7444fioY9VAhLDIs1"
65 fun testComponentRemoteAnsibleExecutor() {
68 webClientService.exchangeResource("GET", "/api/v2/job_templates/hello_world_job_template/", "")
69 } returns WebClientResponse(200, getJobTemplates(jtId))
71 webClientService.exchangeResource("GET", "/api/v2/job_templates/$jtId/launch/", "")
72 } returns WebClientResponse(200, getJobTemplateLaunch(jtId))
74 webClientService.exchangeResource("GET", "/api/v2/inventories/?name=Demo+Inventory", "")
75 } returns WebClientResponse(200, getInventory())
77 webClientService.exchangeResource(
78 "POST", "/api/v2/job_templates/$jtId/launch/",
79 """{"inventory":1,"extra_vars":{"site_id":"3 - Belmont","tor_group":"vEPC"}}"""
81 } returns WebClientResponse(201, newJobTemplateLaunch(jtId, jobId))
83 webClientService.exchangeResource("GET", "/api/v2/jobs/$jobId/", "")
85 WebClientResponse(200, getJobStatus1(jtId, jobId)),
86 WebClientResponse(200, getJobStatus2(jtId, jobId)),
87 WebClientResponse(200, getJobStatus3(jtId, jobId)),
88 WebClientResponse(200, getJobStatus4(jtId, jobId))
91 webClientService.exchangeResource(
92 "GET", "/api/v2/jobs/$jobId/stdout/?format=txt", "",
93 mapOf("Accept" to "text/plain")
95 } returns WebClientResponse(200, getReport())
96 val selector = mapper.readTree(endpointSelector)
97 val bluePrintRestLibPropertyService = mockk<BlueprintRestLibPropertyService>()
98 every { bluePrintRestLibPropertyService.blueprintWebClientService(selector) } returns webClientService
99 val awxRemoteExecutor = ComponentRemoteAnsibleExecutor(bluePrintRestLibPropertyService, mapper)
100 awxRemoteExecutor.checkDelay = 1
102 val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
103 "payload/requests/sample-remote-ansible-request.json",
104 ExecutionServiceInput::class.java
107 val bluePrintRuntimeService = createBlueprintRuntimeService(awxRemoteExecutor, executionServiceInput)
111 awxRemoteExecutor.applyNB(executionServiceInput)
115 assertTrue(bluePrintRuntimeService.getBlueprintError().allErrors().isEmpty())
119 fun `handle unknown inventory`() {
122 webClientService.exchangeResource("GET", "/api/v2/job_templates/hello_world_job_template/", "")
123 } returns WebClientResponse(200, getJobTemplates(jtId))
125 webClientService.exchangeResource("GET", "/api/v2/job_templates/$jtId/launch/", "")
126 } returns WebClientResponse(200, getJobTemplateLaunch(jtId))
128 webClientService.exchangeResource("GET", "/api/v2/inventories/?name=Demo+Inventory", "")
129 } returns WebClientResponse(404, "")
130 val selector = mapper.readTree(endpointSelector)
131 val bluePrintRestLibPropertyService = mockk<BlueprintRestLibPropertyService>()
132 every { bluePrintRestLibPropertyService.blueprintWebClientService(selector) } returns webClientService
133 val awxRemoteExecutor = ComponentRemoteAnsibleExecutor(bluePrintRestLibPropertyService, mapper)
134 awxRemoteExecutor.checkDelay = 1
136 val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
137 "payload/requests/remote-ansible-request-full.json",
138 ExecutionServiceInput::class.java
141 val bluePrintRuntimeService = createBlueprintRuntimeService(awxRemoteExecutor, executionServiceInput)
145 awxRemoteExecutor.applyNB(executionServiceInput)
149 val errors = bluePrintRuntimeService.getBlueprintError().allErrors()
150 assertEquals(1, errors.size)
154 fun `handle failure on job submission`() {
157 webClientService.exchangeResource("GET", "/api/v2/job_templates/hello_world_job_template/", "")
158 } returns WebClientResponse(200, getJobTemplates(jtId))
160 webClientService.exchangeResource("GET", "/api/v2/job_templates/$jtId/launch/", "")
161 } returns WebClientResponse(200, getJobTemplateLaunch(jtId))
163 webClientService.exchangeResource("GET", "/api/v2/inventories/?name=Demo+Inventory", "")
164 } returns WebClientResponse(200, getInventory())
166 webClientService.exchangeResource(
167 "POST", "/api/v2/job_templates/$jtId/launch/",
168 """{"limit":"123","tags":"some-tag","skip_tags":"some-skip-tag","inventory":1,"extra_vars":{"site_id":"3 - Belmont","tor_group":"vEPC"}}"""
170 } returns WebClientResponse(500, "")
171 val selector = mapper.readTree(endpointSelector)
172 val bluePrintRestLibPropertyService = mockk<BlueprintRestLibPropertyService>()
173 every { bluePrintRestLibPropertyService.blueprintWebClientService(selector) } returns webClientService
174 val awxRemoteExecutor = ComponentRemoteAnsibleExecutor(bluePrintRestLibPropertyService, mapper)
175 awxRemoteExecutor.checkDelay = 1
177 val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
178 "payload/requests/remote-ansible-request-full.json",
179 ExecutionServiceInput::class.java
182 val bluePrintRuntimeService = createBlueprintRuntimeService(awxRemoteExecutor, executionServiceInput)
186 awxRemoteExecutor.applyNB(executionServiceInput)
190 val errors = bluePrintRuntimeService.getBlueprintError().allErrors()
191 assertEquals(1, errors.size)
194 private fun createBlueprintRuntimeService(
195 awxRemoteExecutor: ComponentRemoteAnsibleExecutor,
196 executionServiceInput: ExecutionServiceInput
197 ): BlueprintRuntimeService<MutableMap<String, JsonNode>> {
198 val bluePrintRuntimeService = BlueprintMetadataUtils.bluePrintRuntime(
200 "./../../../../components/model-catalog/blueprint-model/test-blueprint/remote_ansible"
202 awxRemoteExecutor.bluePrintRuntimeService = bluePrintRuntimeService
204 val workflowName = executionServiceInput.actionIdentifiers.actionName
206 // Assign Workflow inputs
207 val input = executionServiceInput.payload.get("$workflowName-request")
208 bluePrintRuntimeService.assignWorkflowInputs(workflowName, input)
210 val stepMetaData: MutableMap<String, JsonNode> = hashMapOf()
211 stepMetaData.putJsonElement(BlueprintConstants.PROPERTY_CURRENT_NODE_TEMPLATE, "execute-remote-ansible")
212 stepMetaData.putJsonElement(BlueprintConstants.PROPERTY_CURRENT_INTERFACE, "ComponentRemoteAnsibleExecutor")
213 stepMetaData.putJsonElement(BlueprintConstants.PROPERTY_CURRENT_OPERATION, "process")
215 val stepInputData = StepData().apply {
216 name = "execute-remote-ansible"
217 properties = stepMetaData
219 executionServiceInput.stepData = stepInputData
220 return bluePrintRuntimeService
223 private fun getJobTemplates(jtId: Int) = """{
225 "type": "job_template",
226 "url": "/api/v2/job_templates/$jtId/",
228 "named_url": "/api/v2/job_templates/hello_world_job_template/",
229 "created_by": "/api/v2/users/1/",
230 "modified_by": "/api/v2/users/1/",
231 "labels": "/api/v2/job_templates/$jtId/labels/",
232 "inventory": "/api/v2/inventories/1/",
233 "project": "/api/v2/projects/8/",
234 "extra_credentials": "/api/v2/job_templates/$jtId/extra_credentials/",
235 "credentials": "/api/v2/job_templates/$jtId/credentials/",
236 "last_job": "/api/v2/jobs/222/",
237 "jobs": "/api/v2/job_templates/$jtId/jobs/",
238 "schedules": "/api/v2/job_templates/$jtId/schedules/",
239 "activity_stream": "/api/v2/job_templates/$jtId/activity_stream/",
240 "launch": "/api/v2/job_templates/$jtId/launch/",
241 "notification_templates_any": "/api/v2/job_templates/$jtId/notification_templates_any/",
242 "notification_templates_success": "/api/v2/job_templates/$jtId/notification_templates_success/",
243 "notification_templates_error": "/api/v2/job_templates/$jtId/notification_templates_error/",
244 "access_list": "/api/v2/job_templates/$jtId/access_list/",
245 "survey_spec": "/api/v2/job_templates/$jtId/survey_spec/",
246 "object_roles": "/api/v2/job_templates/$jtId/object_roles/",
247 "instance_groups": "/api/v2/job_templates/$jtId/instance_groups/",
248 "slice_workflow_jobs": "/api/v2/job_templates/$jtId/slice_workflow_jobs/",
249 "copy": "/api/v2/job_templates/$jtId/copy/"
254 "name": "Demo Inventory",
256 "has_active_failures": false,
258 "hosts_with_active_failures": 0,
260 "groups_with_active_failures": 0,
261 "has_inventory_sources": false,
262 "total_inventory_sources": 0,
263 "inventory_sources_with_failures": 0,
264 "organization_id": 1,
269 "name": "cds_playbooks",
270 "description": "CDS - cds_playbooks Project",
276 "name": "hello_world_job_template",
277 "description": "hello_world Runner Job Template",
278 "finished": "2019-06-12T11:20:27.892787Z",
279 "status": "successful",
284 "name": "hello_world_job_template",
285 "description": "hello_world Runner Job Template",
286 "status": "successful",
303 "description": "Can manage all aspects of the job template",
308 "description": "May run the job template",
313 "description": "May view settings for the job template",
318 "user_capabilities": {
336 "status": "successful",
337 "finished": "2019-06-12T11:20:27.892787Z",
342 "status": "successful",
343 "finished": "2019-06-03T18:27:19.114796Z",
348 "status": "successful",
349 "finished": "2019-06-03T18:26:53.606618Z",
354 "status": "successful",
355 "finished": "2019-06-03T18:24:36.072943Z",
360 "status": "successful",
361 "finished": "2019-06-03T18:17:50.616528Z",
366 "status": "successful",
367 "finished": "2019-06-03T18:04:42.995611Z",
372 "status": "successful",
373 "finished": "2019-06-03T17:47:13.983951Z",
378 "status": "successful",
379 "finished": "2019-05-30T15:47:55.700161Z",
384 "status": "successful",
385 "finished": "2019-05-29T14:46:51.615926Z",
390 "status": "successful",
391 "finished": "2019-05-27T20:23:58.656709Z",
395 "extra_credentials": [],
398 "created": "2019-05-21T19:28:05.953730Z",
399 "modified": "2019-05-21T20:06:55.728697Z",
400 "name": "hello_world_job_template",
401 "description": "hello_world Runner Job Template",
405 "playbook": "hello_world.yml",
411 "force_handlers": false,
415 "use_fact_cache": false,
416 "last_job_run": "2019-06-12T11:20:27.892787Z",
417 "last_job_failed": false,
418 "next_job_run": null,
419 "status": "successful",
420 "host_config_key": "",
421 "ask_diff_mode_on_launch": false,
422 "ask_variables_on_launch": true,
423 "ask_limit_on_launch": true,
424 "ask_tags_on_launch": true,
425 "ask_skip_tags_on_launch": true,
426 "ask_job_type_on_launch": false,
427 "ask_verbosity_on_launch": false,
428 "ask_inventory_on_launch": true,
429 "ask_credential_on_launch": true,
430 "survey_enabled": true,
431 "become_enabled": false,
433 "allow_simultaneous": false,
434 "custom_virtualenv": null,
435 "job_slice_count": 1,
437 "vault_credential": null
440 private fun getJobTemplateLaunch(jtId: Int) = """{
441 "can_start_without_user_input": false,
442 "passwords_needed_to_start": [],
443 "ask_variables_on_launch": true,
444 "ask_tags_on_launch": true,
445 "ask_diff_mode_on_launch": false,
446 "ask_skip_tags_on_launch": true,
447 "ask_job_type_on_launch": false,
448 "ask_limit_on_launch": true,
449 "ask_verbosity_on_launch": false,
450 "ask_inventory_on_launch": true,
451 "ask_credential_on_launch": true,
452 "survey_enabled": true,
453 "variables_needed_to_start": [
457 "credential_needed_to_start": false,
458 "inventory_needed_to_start": false,
459 "job_template_data": {
460 "name": "hello_world_job_template",
462 "description": "hello_world Runner Job Template"
473 "name": "Demo Inventory",
479 private fun getInventory() = """{
487 "url": "/api/v2/inventories/1/",
489 "created_by": "/api/v2/users/1/",
490 "modified_by": "/api/v2/users/1/",
491 "hosts": "/api/v2/inventories/1/hosts/",
492 "groups": "/api/v2/inventories/1/groups/",
493 "root_groups": "/api/v2/inventories/1/root_groups/",
494 "variable_data": "/api/v2/inventories/1/variable_data/",
495 "script": "/api/v2/inventories/1/script/",
496 "tree": "/api/v2/inventories/1/tree/",
497 "inventory_sources": "/api/v2/inventories/1/inventory_sources/",
498 "update_inventory_sources": "/api/v2/inventories/1/update_inventory_sources/",
499 "activity_stream": "/api/v2/inventories/1/activity_stream/",
500 "job_templates": "/api/v2/inventories/1/job_templates/",
501 "ad_hoc_commands": "/api/v2/inventories/1/ad_hoc_commands/",
502 "access_list": "/api/v2/inventories/1/access_list/",
503 "object_roles": "/api/v2/inventories/1/object_roles/",
504 "instance_groups": "/api/v2/inventories/1/instance_groups/",
505 "copy": "/api/v2/inventories/1/copy/",
506 "organization": "/api/v2/organizations/1/"
528 "description": "Can manage all aspects of the inventory",
533 "description": "May update project or inventory or group using the configured source update system",
538 "description": "May run ad hoc commands on an inventory",
543 "description": "Can use the inventory in a job template",
548 "description": "May view settings for the inventory",
553 "user_capabilities": {
560 "created": "2019-05-21T15:45:31.954359Z",
561 "modified": "2019-05-21T15:45:31.954378Z",
562 "name": "Demo Inventory",
568 "has_active_failures": false,
570 "hosts_with_active_failures": 0,
572 "groups_with_active_failures": 0,
573 "has_inventory_sources": false,
574 "total_inventory_sources": 0,
575 "inventory_sources_with_failures": 0,
576 "insights_credential": null,
577 "pending_deletion": false
582 private fun newJobTemplateLaunch(jtId: Int, jobId: Int) = """{
584 "ignored_fields": {},
587 "url": "/api/v2/jobs/$jobId/",
589 "created_by": "/api/v2/users/1/",
590 "modified_by": "/api/v2/users/1/",
591 "labels": "/api/v2/jobs/$jobId/labels/",
592 "inventory": "/api/v2/inventories/1/",
593 "project": "/api/v2/projects/8/",
594 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
595 "credentials": "/api/v2/jobs/$jobId/credentials/",
596 "unified_job_template": "/api/v2/job_templates/$jtId/",
597 "stdout": "/api/v2/jobs/$jobId/stdout/",
598 "job_events": "/api/v2/jobs/$jobId/job_events/",
599 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
600 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
601 "notifications": "/api/v2/jobs/$jobId/notifications/",
602 "job_template": "/api/v2/job_templates/$jtId/",
603 "cancel": "/api/v2/jobs/$jobId/cancel/",
604 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
605 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
610 "name": "Demo Inventory",
612 "has_active_failures": false,
614 "hosts_with_active_failures": 0,
616 "groups_with_active_failures": 0,
617 "has_inventory_sources": false,
618 "total_inventory_sources": 0,
619 "inventory_sources_with_failures": 0,
620 "organization_id": 1,
625 "name": "cds_playbooks",
626 "description": "CDS - cds_playbooks Project",
632 "name": "hello_world_job_template",
633 "description": "hello_world Runner Job Template"
635 "unified_job_template": {
637 "name": "hello_world_job_template",
638 "description": "hello_world Runner Job Template",
639 "unified_job_type": "job"
653 "user_capabilities": {
661 "extra_credentials": [],
664 "created": "2019-06-12T11:21:26.891986Z",
665 "modified": "2019-06-12T11:21:27.016410Z",
666 "name": "hello_world_job_template",
667 "description": "hello_world Runner Job Template",
671 "playbook": "hello_world.yml",
675 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
677 "force_handlers": false,
681 "use_fact_cache": false,
682 "unified_job_template": $jtId,
683 "launch_type": "manual",
692 "job_explanation": "",
693 "execution_node": "",
694 "controller_node": "",
695 "result_traceback": "",
696 "event_processing_finished": false,
697 "job_template": $jtId,
698 "passwords_needed_to_start": [],
699 "ask_diff_mode_on_launch": false,
700 "ask_variables_on_launch": true,
701 "ask_limit_on_launch": true,
702 "ask_tags_on_launch": true,
703 "ask_skip_tags_on_launch": true,
704 "ask_job_type_on_launch": false,
705 "ask_verbosity_on_launch": false,
706 "ask_inventory_on_launch": true,
707 "ask_credential_on_launch": true,
708 "allow_simultaneous": false,
711 "instance_group": null,
713 "job_slice_number": 0,
714 "job_slice_count": 1,
716 "vault_credential": null
719 private fun getJobStatus1(jtId: Int, jobId: Int) = """{
722 "url": "/api/v2/jobs/$jobId/",
724 "created_by": "/api/v2/users/1/",
725 "labels": "/api/v2/jobs/$jobId/labels/",
726 "inventory": "/api/v2/inventories/1/",
727 "project": "/api/v2/projects/8/",
728 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
729 "credentials": "/api/v2/jobs/$jobId/credentials/",
730 "unified_job_template": "/api/v2/job_templates/$jtId/",
731 "stdout": "/api/v2/jobs/$jobId/stdout/",
732 "job_events": "/api/v2/jobs/$jobId/job_events/",
733 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
734 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
735 "notifications": "/api/v2/jobs/$jobId/notifications/",
736 "job_template": "/api/v2/job_templates/$jtId/",
737 "cancel": "/api/v2/jobs/$jobId/cancel/",
738 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
739 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
744 "name": "Demo Inventory",
746 "has_active_failures": false,
748 "hosts_with_active_failures": 0,
750 "groups_with_active_failures": 0,
751 "has_inventory_sources": false,
752 "total_inventory_sources": 0,
753 "inventory_sources_with_failures": 0,
754 "organization_id": 1,
759 "name": "cds_playbooks",
760 "description": "CDS - cds_playbooks Project",
766 "name": "hello_world_job_template",
767 "description": "hello_world Runner Job Template"
769 "unified_job_template": {
771 "name": "hello_world_job_template",
772 "description": "hello_world Runner Job Template",
773 "unified_job_type": "job"
785 "user_capabilities": {
793 "extra_credentials": [],
796 "created": "2019-06-12T11:21:26.891986Z",
797 "modified": "2019-06-12T11:21:27.355185Z",
798 "name": "hello_world_job_template",
799 "description": "hello_world Runner Job Template",
803 "playbook": "hello_world.yml",
807 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
809 "force_handlers": false,
813 "use_fact_cache": false,
814 "unified_job_template": $jtId,
815 "launch_type": "manual",
824 "job_explanation": "",
825 "execution_node": "awx",
826 "controller_node": "",
827 "result_traceback": "",
828 "event_processing_finished": false,
829 "job_template": $jtId,
830 "passwords_needed_to_start": [],
831 "ask_diff_mode_on_launch": false,
832 "ask_variables_on_launch": true,
833 "ask_limit_on_launch": true,
834 "ask_tags_on_launch": true,
835 "ask_skip_tags_on_launch": true,
836 "ask_job_type_on_launch": false,
837 "ask_verbosity_on_launch": false,
838 "ask_inventory_on_launch": true,
839 "ask_credential_on_launch": true,
840 "allow_simultaneous": false,
845 "job_slice_number": 0,
846 "job_slice_count": 1,
847 "host_status_counts": {},
852 "custom_virtualenv": null,
854 "vault_credential": null
857 private fun getJobStatus2(jtId: Int, jobId: Int) = """{
860 "url": "/api/v2/jobs/$jobId/",
862 "created_by": "/api/v2/users/1/",
863 "labels": "/api/v2/jobs/$jobId/labels/",
864 "inventory": "/api/v2/inventories/1/",
865 "project": "/api/v2/projects/8/",
866 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
867 "credentials": "/api/v2/jobs/$jobId/credentials/",
868 "unified_job_template": "/api/v2/job_templates/$jtId/",
869 "stdout": "/api/v2/jobs/$jobId/stdout/",
870 "job_events": "/api/v2/jobs/$jobId/job_events/",
871 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
872 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
873 "notifications": "/api/v2/jobs/$jobId/notifications/",
874 "job_template": "/api/v2/job_templates/$jtId/",
875 "cancel": "/api/v2/jobs/$jobId/cancel/",
876 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
877 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
882 "name": "Demo Inventory",
884 "has_active_failures": false,
886 "hosts_with_active_failures": 0,
888 "groups_with_active_failures": 0,
889 "has_inventory_sources": false,
890 "total_inventory_sources": 0,
891 "inventory_sources_with_failures": 0,
892 "organization_id": 1,
897 "name": "cds_playbooks",
898 "description": "CDS - cds_playbooks Project",
904 "name": "hello_world_job_template",
905 "description": "hello_world Runner Job Template"
907 "unified_job_template": {
909 "name": "hello_world_job_template",
910 "description": "hello_world Runner Job Template",
911 "unified_job_type": "job"
923 "user_capabilities": {
931 "extra_credentials": [],
934 "created": "2019-06-12T11:21:26.891986Z",
935 "modified": "2019-06-12T11:21:27.355185Z",
936 "name": "hello_world_job_template",
937 "description": "hello_world Runner Job Template",
941 "playbook": "hello_world.yml",
945 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
947 "force_handlers": false,
951 "use_fact_cache": false,
952 "unified_job_template": $jtId,
953 "launch_type": "manual",
956 "started": "2019-06-12T11:21:27.510766Z",
958 "elapsed": 10.862184,
959 "job_args": "[\"ansible-playbook\", \"-u\", \"root\", \"-i\", \"/tmp/awx_223_ft8hu4p4/tmptmtwllu4\", \"-e\", \"@/tmp/awx_223_ft8hu4p4/env/extravars\", \"hello_world.yml\"]",
960 "job_cwd": "/var/lib/awx/projects/cds_playbooks_folder",
963 "LC_ALL": "en_US.UTF-8",
964 "VIRTUAL_ENV": "/var/lib/awx/venv/ansible",
965 "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",
966 "SUPERVISOR_GROUP_NAME": "tower-processes",
967 "PWD": "/var/lib/awx",
968 "LANG": "en_US.UTF-8",
970 "SUPERVISOR_ENABLED": "1",
971 "HOME": "/var/lib/awx",
973 "LANGUAGE": "en_US.UTF-8",
974 "LC_CTYPE": "en_US.UTF-8",
975 "SUPERVISOR_PROCESS_NAME": "dispatcher",
976 "SUPERVISOR_SERVER_URL": "unix:///tmp/supervisor.sock",
977 "DJANGO_SETTINGS_MODULE": "awx.settings.production",
978 "DJANGO_LIVE_TEST_SERVER_ADDRESS": "localhost:9013-9199",
980 "ANSIBLE_FORCE_COLOR": "True",
981 "ANSIBLE_HOST_KEY_CHECKING": "False",
982 "ANSIBLE_INVENTORY_UNPARSED_FAILED": "True",
983 "ANSIBLE_PARAMIKO_RECORD_HOST_KEYS": "False",
984 "ANSIBLE_VENV_PATH": "/var/lib/awx/venv/ansible",
985 "AWX_PRIVATE_DATA_DIR": "/tmp/awx_223_ft8hu4p4",
986 "PYTHONPATH": "/var/lib/awx/venv/ansible/lib/python2.7/site-packages:/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/lib:",
989 "PROJECT_REVISION": "",
990 "ANSIBLE_RETRY_FILES_ENABLED": "False",
991 "MAX_EVENT_RES": "700000",
992 "ANSIBLE_CALLBACK_PLUGINS": "/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/plugins/callback",
993 "AWX_HOST": "https://towerhost",
994 "ANSIBLE_SSH_CONTROL_PATH_DIR": "/tmp/awx_223_ft8hu4p4/cp",
995 "ANSIBLE_STDOUT_CALLBACK": "awx_display",
996 "AWX_ISOLATED_DATA_DIR": "/tmp/awx_223_ft8hu4p4/artifacts/$jobId"
998 "job_explanation": "",
999 "execution_node": "awx",
1000 "controller_node": "",
1001 "result_traceback": "",
1002 "event_processing_finished": false,
1003 "job_template": $jtId,
1004 "passwords_needed_to_start": [],
1005 "ask_diff_mode_on_launch": false,
1006 "ask_variables_on_launch": true,
1007 "ask_limit_on_launch": true,
1008 "ask_tags_on_launch": true,
1009 "ask_skip_tags_on_launch": true,
1010 "ask_job_type_on_launch": false,
1011 "ask_verbosity_on_launch": false,
1012 "ask_inventory_on_launch": true,
1013 "ask_credential_on_launch": true,
1014 "allow_simultaneous": false,
1017 "instance_group": 1,
1019 "job_slice_number": 0,
1020 "job_slice_count": 1,
1021 "host_status_counts": {},
1022 "playbook_counts": {
1026 "custom_virtualenv": "/var/lib/awx/venv/ansible",
1028 "vault_credential": null
1031 private fun getJobStatus3(jtId: Int, jobId: Int) = """{
1034 "url": "/api/v2/jobs/$jobId/",
1036 "created_by": "/api/v2/users/1/",
1037 "labels": "/api/v2/jobs/$jobId/labels/",
1038 "inventory": "/api/v2/inventories/1/",
1039 "project": "/api/v2/projects/8/",
1040 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
1041 "credentials": "/api/v2/jobs/$jobId/credentials/",
1042 "unified_job_template": "/api/v2/job_templates/$jtId/",
1043 "stdout": "/api/v2/jobs/$jobId/stdout/",
1044 "job_events": "/api/v2/jobs/$jobId/job_events/",
1045 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
1046 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
1047 "notifications": "/api/v2/jobs/$jobId/notifications/",
1048 "job_template": "/api/v2/job_templates/$jtId/",
1049 "cancel": "/api/v2/jobs/$jobId/cancel/",
1050 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
1051 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
1056 "name": "Demo Inventory",
1058 "has_active_failures": false,
1060 "hosts_with_active_failures": 0,
1062 "groups_with_active_failures": 0,
1063 "has_inventory_sources": false,
1064 "total_inventory_sources": 0,
1065 "inventory_sources_with_failures": 0,
1066 "organization_id": 1,
1071 "name": "cds_playbooks",
1072 "description": "CDS - cds_playbooks Project",
1078 "name": "hello_world_job_template",
1079 "description": "hello_world Runner Job Template"
1081 "unified_job_template": {
1083 "name": "hello_world_job_template",
1084 "description": "hello_world Runner Job Template",
1085 "unified_job_type": "job"
1093 "username": "admin",
1097 "user_capabilities": {
1105 "extra_credentials": [],
1108 "created": "2019-06-12T11:21:26.891986Z",
1109 "modified": "2019-06-12T11:21:27.355185Z",
1110 "name": "hello_world_job_template",
1111 "description": "hello_world Runner Job Template",
1115 "playbook": "hello_world.yml",
1119 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
1121 "force_handlers": false,
1123 "start_at_task": "",
1125 "use_fact_cache": false,
1126 "unified_job_template": $jtId,
1127 "launch_type": "manual",
1128 "status": "running",
1130 "started": "2019-06-12T11:21:27.510766Z",
1132 "elapsed": 21.297881,
1133 "job_args": "[\"ansible-playbook\", \"-u\", \"root\", \"-i\", \"/tmp/awx_223_ft8hu4p4/tmptmtwllu4\", \"-e\", \"@/tmp/awx_223_ft8hu4p4/env/extravars\", \"hello_world.yml\"]",
1134 "job_cwd": "/var/lib/awx/projects/cds_playbooks_folder",
1137 "LC_ALL": "en_US.UTF-8",
1138 "VIRTUAL_ENV": "/var/lib/awx/venv/ansible",
1139 "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",
1140 "SUPERVISOR_GROUP_NAME": "tower-processes",
1141 "PWD": "/var/lib/awx",
1142 "LANG": "en_US.UTF-8",
1144 "SUPERVISOR_ENABLED": "1",
1145 "HOME": "/var/lib/awx",
1147 "LANGUAGE": "en_US.UTF-8",
1148 "LC_CTYPE": "en_US.UTF-8",
1149 "SUPERVISOR_PROCESS_NAME": "dispatcher",
1150 "SUPERVISOR_SERVER_URL": "unix:///tmp/supervisor.sock",
1151 "DJANGO_SETTINGS_MODULE": "awx.settings.production",
1152 "DJANGO_LIVE_TEST_SERVER_ADDRESS": "localhost:9013-9199",
1154 "ANSIBLE_FORCE_COLOR": "True",
1155 "ANSIBLE_HOST_KEY_CHECKING": "False",
1156 "ANSIBLE_INVENTORY_UNPARSED_FAILED": "True",
1157 "ANSIBLE_PARAMIKO_RECORD_HOST_KEYS": "False",
1158 "ANSIBLE_VENV_PATH": "/var/lib/awx/venv/ansible",
1159 "AWX_PRIVATE_DATA_DIR": "/tmp/awx_223_ft8hu4p4",
1160 "PYTHONPATH": "/var/lib/awx/venv/ansible/lib/python2.7/site-packages:/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/lib:",
1162 "INVENTORY_ID": "1",
1163 "PROJECT_REVISION": "",
1164 "ANSIBLE_RETRY_FILES_ENABLED": "False",
1165 "MAX_EVENT_RES": "700000",
1166 "ANSIBLE_CALLBACK_PLUGINS": "/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/plugins/callback",
1167 "AWX_HOST": "https://towerhost",
1168 "ANSIBLE_SSH_CONTROL_PATH_DIR": "/tmp/awx_223_ft8hu4p4/cp",
1169 "ANSIBLE_STDOUT_CALLBACK": "awx_display",
1170 "AWX_ISOLATED_DATA_DIR": "/tmp/awx_223_ft8hu4p4/artifacts/$jobId"
1172 "job_explanation": "",
1173 "execution_node": "awx",
1174 "controller_node": "",
1175 "result_traceback": "",
1176 "event_processing_finished": false,
1177 "job_template": $jtId,
1178 "passwords_needed_to_start": [],
1179 "ask_diff_mode_on_launch": false,
1180 "ask_variables_on_launch": true,
1181 "ask_limit_on_launch": true,
1182 "ask_tags_on_launch": true,
1183 "ask_skip_tags_on_launch": true,
1184 "ask_job_type_on_launch": false,
1185 "ask_verbosity_on_launch": false,
1186 "ask_inventory_on_launch": true,
1187 "ask_credential_on_launch": true,
1188 "allow_simultaneous": false,
1191 "instance_group": 1,
1193 "job_slice_number": 0,
1194 "job_slice_count": 1,
1195 "host_status_counts": {},
1196 "playbook_counts": {
1200 "custom_virtualenv": "/var/lib/awx/venv/ansible",
1202 "vault_credential": null
1205 private fun getJobStatus4(jtId: Int, jobId: Int) = """{
1208 "url": "/api/v2/jobs/$jobId/",
1210 "created_by": "/api/v2/users/1/",
1211 "labels": "/api/v2/jobs/$jobId/labels/",
1212 "inventory": "/api/v2/inventories/1/",
1213 "project": "/api/v2/projects/8/",
1214 "extra_credentials": "/api/v2/jobs/$jobId/extra_credentials/",
1215 "credentials": "/api/v2/jobs/$jobId/credentials/",
1216 "unified_job_template": "/api/v2/job_templates/$jtId/",
1217 "stdout": "/api/v2/jobs/$jobId/stdout/",
1218 "job_events": "/api/v2/jobs/$jobId/job_events/",
1219 "job_host_summaries": "/api/v2/jobs/$jobId/job_host_summaries/",
1220 "activity_stream": "/api/v2/jobs/$jobId/activity_stream/",
1221 "notifications": "/api/v2/jobs/$jobId/notifications/",
1222 "job_template": "/api/v2/job_templates/$jtId/",
1223 "cancel": "/api/v2/jobs/$jobId/cancel/",
1224 "create_schedule": "/api/v2/jobs/$jobId/create_schedule/",
1225 "relaunch": "/api/v2/jobs/$jobId/relaunch/"
1230 "name": "Demo Inventory",
1232 "has_active_failures": false,
1234 "hosts_with_active_failures": 0,
1236 "groups_with_active_failures": 0,
1237 "has_inventory_sources": false,
1238 "total_inventory_sources": 0,
1239 "inventory_sources_with_failures": 0,
1240 "organization_id": 1,
1245 "name": "cds_playbooks",
1246 "description": "CDS - cds_playbooks Project",
1252 "name": "hello_world_job_template",
1253 "description": "hello_world Runner Job Template"
1255 "unified_job_template": {
1257 "name": "hello_world_job_template",
1258 "description": "hello_world Runner Job Template",
1259 "unified_job_type": "job"
1267 "username": "admin",
1271 "user_capabilities": {
1279 "extra_credentials": [],
1282 "created": "2019-06-12T11:21:26.891986Z",
1283 "modified": "2019-06-12T11:21:27.355185Z",
1284 "name": "hello_world_job_template",
1285 "description": "hello_world Runner Job Template",
1289 "playbook": "hello_world.yml",
1293 "extra_vars": "{\"tor_group\": \"vEPC\", \"site_id\": \"3 - Belmont\"}",
1295 "force_handlers": false,
1297 "start_at_task": "",
1299 "use_fact_cache": false,
1300 "unified_job_template": $jtId,
1301 "launch_type": "manual",
1302 "status": "successful",
1304 "started": "2019-06-12T11:21:27.510766Z",
1305 "finished": "2019-06-12T11:21:48.993385Z",
1307 "job_args": "[\"ansible-playbook\", \"-u\", \"root\", \"-i\", \"/tmp/awx_223_ft8hu4p4/tmptmtwllu4\", \"-e\", \"@/tmp/awx_223_ft8hu4p4/env/extravars\", \"hello_world.yml\"]",
1308 "job_cwd": "/var/lib/awx/projects/cds_playbooks_folder",
1311 "LC_ALL": "en_US.UTF-8",
1312 "VIRTUAL_ENV": "/var/lib/awx/venv/ansible",
1313 "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",
1314 "SUPERVISOR_GROUP_NAME": "tower-processes",
1315 "PWD": "/var/lib/awx",
1316 "LANG": "en_US.UTF-8",
1318 "SUPERVISOR_ENABLED": "1",
1319 "HOME": "/var/lib/awx",
1321 "LANGUAGE": "en_US.UTF-8",
1322 "LC_CTYPE": "en_US.UTF-8",
1323 "SUPERVISOR_PROCESS_NAME": "dispatcher",
1324 "SUPERVISOR_SERVER_URL": "unix:///tmp/supervisor.sock",
1325 "DJANGO_SETTINGS_MODULE": "awx.settings.production",
1326 "DJANGO_LIVE_TEST_SERVER_ADDRESS": "localhost:9013-9199",
1328 "ANSIBLE_FORCE_COLOR": "True",
1329 "ANSIBLE_HOST_KEY_CHECKING": "False",
1330 "ANSIBLE_INVENTORY_UNPARSED_FAILED": "True",
1331 "ANSIBLE_PARAMIKO_RECORD_HOST_KEYS": "False",
1332 "ANSIBLE_VENV_PATH": "/var/lib/awx/venv/ansible",
1333 "AWX_PRIVATE_DATA_DIR": "/tmp/awx_223_ft8hu4p4",
1334 "PYTHONPATH": "/var/lib/awx/venv/ansible/lib/python2.7/site-packages:/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/lib:",
1336 "INVENTORY_ID": "1",
1337 "PROJECT_REVISION": "",
1338 "ANSIBLE_RETRY_FILES_ENABLED": "False",
1339 "MAX_EVENT_RES": "700000",
1340 "ANSIBLE_CALLBACK_PLUGINS": "/var/lib/awx/venv/awx/lib64/python3.6/site-packages/awx/plugins/callback",
1341 "AWX_HOST": "https://towerhost",
1342 "ANSIBLE_SSH_CONTROL_PATH_DIR": "/tmp/awx_223_ft8hu4p4/cp",
1343 "ANSIBLE_STDOUT_CALLBACK": "awx_display",
1344 "AWX_ISOLATED_DATA_DIR": "/tmp/awx_223_ft8hu4p4/artifacts/$jobId"
1346 "job_explanation": "",
1347 "execution_node": "awx",
1348 "controller_node": "",
1349 "result_traceback": "",
1350 "event_processing_finished": true,
1351 "job_template": $jtId,
1352 "passwords_needed_to_start": [],
1353 "ask_diff_mode_on_launch": false,
1354 "ask_variables_on_launch": true,
1355 "ask_limit_on_launch": true,
1356 "ask_tags_on_launch": true,
1357 "ask_skip_tags_on_launch": true,
1358 "ask_job_type_on_launch": false,
1359 "ask_verbosity_on_launch": false,
1360 "ask_inventory_on_launch": true,
1361 "ask_credential_on_launch": true,
1362 "allow_simultaneous": false,
1365 "instance_group": 1,
1367 "job_slice_number": 0,
1368 "job_slice_count": 1,
1369 "host_status_counts": {
1372 "playbook_counts": {
1376 "custom_virtualenv": "/var/lib/awx/venv/ansible",
1378 "vault_credential": null
1381 private fun getReport() = """
1383 PLAY [Hello World Sample] ******************************************************
1385 TASK [Gathering Facts] *********************************************************
1388 TASK [Hello Message] ***********************************************************
1389 ok: [localhost] => {
1390 "msg": "Hello World!"
1393 PLAY RECAP *********************************************************************
1394 localhost : ok=2 changed=0 unreachable=0 failed=0