mtncloud-cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +20 -0
  3. data/.github/pull_request_template.md +14 -0
  4. data/.github/workflows/ci.yml +56 -0
  5. data/.github/workflows/release.yml +46 -0
  6. data/.gitignore +25 -0
  7. data/CLAUDE.md +24 -0
  8. data/CONTRIBUTING.md +91 -0
  9. data/Dockerfile +19 -0
  10. data/Gemfile +4 -0
  11. data/LICENSE.txt +23 -0
  12. data/README.md +187 -0
  13. data/Rakefile +26 -0
  14. data/bin/mcs +3 -0
  15. data/bin/mtncloud +27 -0
  16. data/lib/mtncloud/api/account_groups_interface.rb +48 -0
  17. data/lib/mtncloud/api/account_users_interface.rb +68 -0
  18. data/lib/mtncloud/api/accounts_interface.rb +9 -0
  19. data/lib/mtncloud/api/activity_interface.rb +9 -0
  20. data/lib/mtncloud/api/affinity_groups_interface.rb +46 -0
  21. data/lib/mtncloud/api/api_client.rb +1091 -0
  22. data/lib/mtncloud/api/appliance_settings_interface.rb +49 -0
  23. data/lib/mtncloud/api/approvals_interface.rb +32 -0
  24. data/lib/mtncloud/api/apps_interface.rb +180 -0
  25. data/lib/mtncloud/api/archive_buckets_interface.rb +116 -0
  26. data/lib/mtncloud/api/archive_files_interface.rb +173 -0
  27. data/lib/mtncloud/api/audit_interface.rb +9 -0
  28. data/lib/mtncloud/api/auth_interface.rb +58 -0
  29. data/lib/mtncloud/api/backup_jobs_interface.rb +13 -0
  30. data/lib/mtncloud/api/backup_restores_interface.rb +27 -0
  31. data/lib/mtncloud/api/backup_results_interface.rb +32 -0
  32. data/lib/mtncloud/api/backup_service_types_interface.rb +9 -0
  33. data/lib/mtncloud/api/backup_services_interface.rb +9 -0
  34. data/lib/mtncloud/api/backup_settings_interface.rb +20 -0
  35. data/lib/mtncloud/api/backup_types_interface.rb +9 -0
  36. data/lib/mtncloud/api/backups_interface.rb +21 -0
  37. data/lib/mtncloud/api/billing_interface.rb +34 -0
  38. data/lib/mtncloud/api/blueprints_interface.rb +70 -0
  39. data/lib/mtncloud/api/body_io.rb +22 -0
  40. data/lib/mtncloud/api/budgets_interface.rb +48 -0
  41. data/lib/mtncloud/api/catalog_item_types_interface.rb +29 -0
  42. data/lib/mtncloud/api/certificate_types_interface.rb +14 -0
  43. data/lib/mtncloud/api/certificates_interface.rb +9 -0
  44. data/lib/mtncloud/api/clients_interface.rb +41 -0
  45. data/lib/mtncloud/api/cloud_datastores_interface.rb +48 -0
  46. data/lib/mtncloud/api/cloud_folders_interface.rb +41 -0
  47. data/lib/mtncloud/api/cloud_policies_interface.rb +41 -0
  48. data/lib/mtncloud/api/cloud_resource_pools_interface.rb +66 -0
  49. data/lib/mtncloud/api/clouds_interface.rb +217 -0
  50. data/lib/mtncloud/api/clusters_interface.rb +471 -0
  51. data/lib/mtncloud/api/containers_interface.rb +145 -0
  52. data/lib/mtncloud/api/credential_types_interface.rb +9 -0
  53. data/lib/mtncloud/api/credentials_interface.rb +9 -0
  54. data/lib/mtncloud/api/custom_instance_types_interface.rb +99 -0
  55. data/lib/mtncloud/api/cypher_interface.rb +51 -0
  56. data/lib/mtncloud/api/dashboard_interface.rb +14 -0
  57. data/lib/mtncloud/api/datastores_interface.rb +21 -0
  58. data/lib/mtncloud/api/deploy_interface.rb +44 -0
  59. data/lib/mtncloud/api/deployments_interface.rb +79 -0
  60. data/lib/mtncloud/api/distributed_workers_interface.rb +41 -0
  61. data/lib/mtncloud/api/email_templates_interface.rb +53 -0
  62. data/lib/mtncloud/api/environments_interface.rb +48 -0
  63. data/lib/mtncloud/api/execute_schedules_interface.rb +71 -0
  64. data/lib/mtncloud/api/execution_request_interface.rb +27 -0
  65. data/lib/mtncloud/api/file_copy_request_interface.rb +68 -0
  66. data/lib/mtncloud/api/forgot_password_interface.rb +17 -0
  67. data/lib/mtncloud/api/group_policies_interface.rb +41 -0
  68. data/lib/mtncloud/api/groups_interface.rb +73 -0
  69. data/lib/mtncloud/api/guidance_interface.rb +44 -0
  70. data/lib/mtncloud/api/guidance_settings_interface.rb +17 -0
  71. data/lib/mtncloud/api/health_interface.rb +100 -0
  72. data/lib/mtncloud/api/host_vm_groups_interface.rb +37 -0
  73. data/lib/mtncloud/api/hub_interface.rb +25 -0
  74. data/lib/mtncloud/api/image_builder_boot_scripts_interface.rb +41 -0
  75. data/lib/mtncloud/api/image_builder_image_builds_interface.rb +73 -0
  76. data/lib/mtncloud/api/image_builder_interface.rb +20 -0
  77. data/lib/mtncloud/api/image_builder_preseed_scripts_interface.rb +41 -0
  78. data/lib/mtncloud/api/instance_types_interface.rb +20 -0
  79. data/lib/mtncloud/api/instances_interface.rb +453 -0
  80. data/lib/mtncloud/api/integration_types_interface.rb +14 -0
  81. data/lib/mtncloud/api/integrations_interface.rb +74 -0
  82. data/lib/mtncloud/api/invoice_line_items_interface.rb +9 -0
  83. data/lib/mtncloud/api/invoices_interface.rb +28 -0
  84. data/lib/mtncloud/api/jobs_interface.rb +83 -0
  85. data/lib/mtncloud/api/key_pairs_interface.rb +57 -0
  86. data/lib/mtncloud/api/library_cluster_layouts_interface.rb +47 -0
  87. data/lib/mtncloud/api/library_cluster_packages_interface.rb +60 -0
  88. data/lib/mtncloud/api/library_container_scripts_interface.rb +43 -0
  89. data/lib/mtncloud/api/library_container_templates_interface.rb +43 -0
  90. data/lib/mtncloud/api/library_container_types_interface.rb +59 -0
  91. data/lib/mtncloud/api/library_container_upgrades_interface.rb +60 -0
  92. data/lib/mtncloud/api/library_instance_types_interface.rb +74 -0
  93. data/lib/mtncloud/api/library_layouts_interface.rb +69 -0
  94. data/lib/mtncloud/api/library_operating_systems_interface.rb +63 -0
  95. data/lib/mtncloud/api/library_spec_template_types_interface.rb +43 -0
  96. data/lib/mtncloud/api/library_spec_templates_interface.rb +43 -0
  97. data/lib/mtncloud/api/license_interface.rb +30 -0
  98. data/lib/mtncloud/api/load_balancer_monitors_interface.rb +9 -0
  99. data/lib/mtncloud/api/load_balancer_pool_nodes_interface.rb +8 -0
  100. data/lib/mtncloud/api/load_balancer_pools_interface.rb +9 -0
  101. data/lib/mtncloud/api/load_balancer_pools_secondary_interface.rb +9 -0
  102. data/lib/mtncloud/api/load_balancer_profiles_interface.rb +9 -0
  103. data/lib/mtncloud/api/load_balancer_types_interface.rb +9 -0
  104. data/lib/mtncloud/api/load_balancer_virtual_servers_interface.rb +18 -0
  105. data/lib/mtncloud/api/load_balancers_interface.rb +14 -0
  106. data/lib/mtncloud/api/log_settings_interface.rb +44 -0
  107. data/lib/mtncloud/api/logs_interface.rb +37 -0
  108. data/lib/mtncloud/api/migrations_interface.rb +49 -0
  109. data/lib/mtncloud/api/monitoring_alerts_interface.rb +39 -0
  110. data/lib/mtncloud/api/monitoring_apps_interface.rb +69 -0
  111. data/lib/mtncloud/api/monitoring_checks_interface.rb +103 -0
  112. data/lib/mtncloud/api/monitoring_contacts_interface.rb +41 -0
  113. data/lib/mtncloud/api/monitoring_groups_interface.rb +77 -0
  114. data/lib/mtncloud/api/monitoring_incidents_interface.rb +107 -0
  115. data/lib/mtncloud/api/monitoring_interface.rb +35 -0
  116. data/lib/mtncloud/api/monitoring_settings_interface.rb +21 -0
  117. data/lib/mtncloud/api/network_dhcp_relays_interface.rb +36 -0
  118. data/lib/mtncloud/api/network_dhcp_servers_interface.rb +36 -0
  119. data/lib/mtncloud/api/network_domain_records_interface.rb +41 -0
  120. data/lib/mtncloud/api/network_domains_interface.rb +41 -0
  121. data/lib/mtncloud/api/network_edge_clusters_interface.rb +26 -0
  122. data/lib/mtncloud/api/network_floating_ips_interface.rb +40 -0
  123. data/lib/mtncloud/api/network_groups_interface.rb +41 -0
  124. data/lib/mtncloud/api/network_pool_ips_interface.rb +41 -0
  125. data/lib/mtncloud/api/network_pool_server_types_interface.rb +9 -0
  126. data/lib/mtncloud/api/network_pool_servers_interface.rb +48 -0
  127. data/lib/mtncloud/api/network_pools_interface.rb +41 -0
  128. data/lib/mtncloud/api/network_proxies_interface.rb +41 -0
  129. data/lib/mtncloud/api/network_routers_interface.rb +181 -0
  130. data/lib/mtncloud/api/network_security_server_types_interface.rb +9 -0
  131. data/lib/mtncloud/api/network_security_servers_interface.rb +27 -0
  132. data/lib/mtncloud/api/network_server_groups_interface.rb +7 -0
  133. data/lib/mtncloud/api/network_server_types_interface.rb +9 -0
  134. data/lib/mtncloud/api/network_servers_interface.rb +102 -0
  135. data/lib/mtncloud/api/network_services_interface.rb +63 -0
  136. data/lib/mtncloud/api/network_static_routes_interface.rb +36 -0
  137. data/lib/mtncloud/api/network_subnets_interface.rb +42 -0
  138. data/lib/mtncloud/api/network_types_interface.rb +20 -0
  139. data/lib/mtncloud/api/networks_interface.rb +48 -0
  140. data/lib/mtncloud/api/option_type_forms_interface.rb +9 -0
  141. data/lib/mtncloud/api/option_type_lists_interface.rb +53 -0
  142. data/lib/mtncloud/api/option_types_interface.rb +41 -0
  143. data/lib/mtncloud/api/options_interface.rb +17 -0
  144. data/lib/mtncloud/api/packages_interface.rb +112 -0
  145. data/lib/mtncloud/api/ping_interface.rb +22 -0
  146. data/lib/mtncloud/api/plugins_interface.rb +22 -0
  147. data/lib/mtncloud/api/policies_interface.rb +56 -0
  148. data/lib/mtncloud/api/power_schedules_interface.rb +71 -0
  149. data/lib/mtncloud/api/price_sets_interface.rb +39 -0
  150. data/lib/mtncloud/api/prices_interface.rb +71 -0
  151. data/lib/mtncloud/api/processes_interface.rb +40 -0
  152. data/lib/mtncloud/api/projects_interface.rb +33 -0
  153. data/lib/mtncloud/api/provision_types_interface.rb +24 -0
  154. data/lib/mtncloud/api/provisioning_license_types_interface.rb +31 -0
  155. data/lib/mtncloud/api/provisioning_licenses_interface.rb +60 -0
  156. data/lib/mtncloud/api/provisioning_settings_interface.rb +26 -0
  157. data/lib/mtncloud/api/read_interface.rb +24 -0
  158. data/lib/mtncloud/api/reports_interface.rb +70 -0
  159. data/lib/mtncloud/api/resource_pool_groups_interface.rb +51 -0
  160. data/lib/mtncloud/api/rest_interface.rb +37 -0
  161. data/lib/mtncloud/api/roles_interface.rb +151 -0
  162. data/lib/mtncloud/api/scale_thresholds_interface.rb +9 -0
  163. data/lib/mtncloud/api/search_interface.rb +13 -0
  164. data/lib/mtncloud/api/secondary_read_interface.rb +25 -0
  165. data/lib/mtncloud/api/secondary_rest_interface.rb +42 -0
  166. data/lib/mtncloud/api/security_group_rules_interface.rb +35 -0
  167. data/lib/mtncloud/api/security_groups_interface.rb +56 -0
  168. data/lib/mtncloud/api/security_package_types_interface.rb +9 -0
  169. data/lib/mtncloud/api/security_packages_interface.rb +9 -0
  170. data/lib/mtncloud/api/security_scans_interface.rb +9 -0
  171. data/lib/mtncloud/api/server_devices_interface.rb +30 -0
  172. data/lib/mtncloud/api/server_types_interface.rb +20 -0
  173. data/lib/mtncloud/api/servers_interface.rb +230 -0
  174. data/lib/mtncloud/api/service_catalog_interface.rb +89 -0
  175. data/lib/mtncloud/api/service_plans_interface.rb +62 -0
  176. data/lib/mtncloud/api/setup_interface.rb +46 -0
  177. data/lib/mtncloud/api/snapshots_interface.rb +19 -0
  178. data/lib/mtncloud/api/storage_datastores_interface.rb +44 -0
  179. data/lib/mtncloud/api/storage_providers_interface.rb +151 -0
  180. data/lib/mtncloud/api/storage_server_types_interface.rb +14 -0
  181. data/lib/mtncloud/api/storage_servers_interface.rb +9 -0
  182. data/lib/mtncloud/api/storage_volume_types_interface.rb +9 -0
  183. data/lib/mtncloud/api/storage_volumes_interface.rb +24 -0
  184. data/lib/mtncloud/api/subnet_types_interface.rb +20 -0
  185. data/lib/mtncloud/api/subnets_interface.rb +41 -0
  186. data/lib/mtncloud/api/support_bundles_interface.rb +46 -0
  187. data/lib/mtncloud/api/system_types_interface.rb +13 -0
  188. data/lib/mtncloud/api/systems_interface.rb +55 -0
  189. data/lib/mtncloud/api/task_sets_interface.rb +52 -0
  190. data/lib/mtncloud/api/tasks_interface.rb +66 -0
  191. data/lib/mtncloud/api/tokens_interface.rb +39 -0
  192. data/lib/mtncloud/api/usage_interface.rb +18 -0
  193. data/lib/mtncloud/api/user_groups_interface.rb +59 -0
  194. data/lib/mtncloud/api/user_settings_interface.rb +90 -0
  195. data/lib/mtncloud/api/user_sources_interface.rb +99 -0
  196. data/lib/mtncloud/api/users_interface.rb +33 -0
  197. data/lib/mtncloud/api/vdi_allocations_interface.rb +9 -0
  198. data/lib/mtncloud/api/vdi_apps_interface.rb +9 -0
  199. data/lib/mtncloud/api/vdi_gateways_interface.rb +9 -0
  200. data/lib/mtncloud/api/vdi_interface.rb +28 -0
  201. data/lib/mtncloud/api/vdi_pools_interface.rb +19 -0
  202. data/lib/mtncloud/api/virtual_images_interface.rb +210 -0
  203. data/lib/mtncloud/api/virtual_servers_interface.rb +9 -0
  204. data/lib/mtncloud/api/virtual_switches_interface.rb +9 -0
  205. data/lib/mtncloud/api/whitelabel_settings_interface.rb +57 -0
  206. data/lib/mtncloud/api/whoami_interface.rb +13 -0
  207. data/lib/mtncloud/api/wiki_interface.rb +48 -0
  208. data/lib/mtncloud/api.rb +12 -0
  209. data/lib/mtncloud/benchmarking.rb +259 -0
  210. data/lib/mtncloud/cli/cli_command.rb +2281 -0
  211. data/lib/mtncloud/cli/cli_registry.rb +337 -0
  212. data/lib/mtncloud/cli/commands/access_token_command.rb +201 -0
  213. data/lib/mtncloud/cli/commands/account_groups_command.rb +530 -0
  214. data/lib/mtncloud/cli/commands/activity_command.rb +149 -0
  215. data/lib/mtncloud/cli/commands/affinity_groups_command.rb +554 -0
  216. data/lib/mtncloud/cli/commands/alias_command.rb +278 -0
  217. data/lib/mtncloud/cli/commands/appliance_settings_command.rb +382 -0
  218. data/lib/mtncloud/cli/commands/approvals_command.rb +236 -0
  219. data/lib/mtncloud/cli/commands/apps.rb +2549 -0
  220. data/lib/mtncloud/cli/commands/archives_command.rb +2161 -0
  221. data/lib/mtncloud/cli/commands/audit.rb +188 -0
  222. data/lib/mtncloud/cli/commands/backup_jobs_command.rb +366 -0
  223. data/lib/mtncloud/cli/commands/backup_restores_command.rb +144 -0
  224. data/lib/mtncloud/cli/commands/backup_results_command.rb +149 -0
  225. data/lib/mtncloud/cli/commands/backup_services_command.rb +44 -0
  226. data/lib/mtncloud/cli/commands/backup_settings_command.rb +184 -0
  227. data/lib/mtncloud/cli/commands/backup_types_command.rb +53 -0
  228. data/lib/mtncloud/cli/commands/backups_command.rb +674 -0
  229. data/lib/mtncloud/cli/commands/benchmark_command.rb +458 -0
  230. data/lib/mtncloud/cli/commands/blueprints_command.rb +2297 -0
  231. data/lib/mtncloud/cli/commands/boot_scripts_command.rb +379 -0
  232. data/lib/mtncloud/cli/commands/budgets_command.rb +754 -0
  233. data/lib/mtncloud/cli/commands/cat_command.rb +45 -0
  234. data/lib/mtncloud/cli/commands/catalog_item_types_command.rb +858 -0
  235. data/lib/mtncloud/cli/commands/certificates_command.rb +575 -0
  236. data/lib/mtncloud/cli/commands/change_password_command.rb +132 -0
  237. data/lib/mtncloud/cli/commands/clients_command.rb +331 -0
  238. data/lib/mtncloud/cli/commands/cloud_datastores_command.rb +543 -0
  239. data/lib/mtncloud/cli/commands/cloud_folders_command.rb +512 -0
  240. data/lib/mtncloud/cli/commands/cloud_resource_pools_command.rb +870 -0
  241. data/lib/mtncloud/cli/commands/clouds.rb +2037 -0
  242. data/lib/mtncloud/cli/commands/clouds_types.rb +140 -0
  243. data/lib/mtncloud/cli/commands/cluster_types.rb +179 -0
  244. data/lib/mtncloud/cli/commands/clusters.rb +5855 -0
  245. data/lib/mtncloud/cli/commands/coloring_command.rb +82 -0
  246. data/lib/mtncloud/cli/commands/containers_command.rb +967 -0
  247. data/lib/mtncloud/cli/commands/credential_types_command.rb +36 -0
  248. data/lib/mtncloud/cli/commands/credentials_command.rb +124 -0
  249. data/lib/mtncloud/cli/commands/curl_command.rb +168 -0
  250. data/lib/mtncloud/cli/commands/cypher_command.rb +587 -0
  251. data/lib/mtncloud/cli/commands/dashboard_command.rb +300 -0
  252. data/lib/mtncloud/cli/commands/debug_command.rb +75 -0
  253. data/lib/mtncloud/cli/commands/deploy.rb +485 -0
  254. data/lib/mtncloud/cli/commands/deployments.rb +923 -0
  255. data/lib/mtncloud/cli/commands/deploys.rb +485 -0
  256. data/lib/mtncloud/cli/commands/distributed_workers_command.rb +282 -0
  257. data/lib/mtncloud/cli/commands/echo_command.rb +61 -0
  258. data/lib/mtncloud/cli/commands/edit_profile_command.rb +57 -0
  259. data/lib/mtncloud/cli/commands/edit_rc_command.rb +77 -0
  260. data/lib/mtncloud/cli/commands/email_templates_command.rb +373 -0
  261. data/lib/mtncloud/cli/commands/environments_command.rb +401 -0
  262. data/lib/mtncloud/cli/commands/execute_schedules_command.rb +735 -0
  263. data/lib/mtncloud/cli/commands/execution_request_command.rb +333 -0
  264. data/lib/mtncloud/cli/commands/exit_command.rb +34 -0
  265. data/lib/mtncloud/cli/commands/file_copy_request_command.rb +352 -0
  266. data/lib/mtncloud/cli/commands/forgot_password.rb +133 -0
  267. data/lib/mtncloud/cli/commands/get_prompt_command.rb +36 -0
  268. data/lib/mtncloud/cli/commands/groups.rb +818 -0
  269. data/lib/mtncloud/cli/commands/guidance_command.rb +529 -0
  270. data/lib/mtncloud/cli/commands/guidance_settings.rb +148 -0
  271. data/lib/mtncloud/cli/commands/health_command.rb +1046 -0
  272. data/lib/mtncloud/cli/commands/history_command.rb +60 -0
  273. data/lib/mtncloud/cli/commands/host_vm_groups_command.rb +423 -0
  274. data/lib/mtncloud/cli/commands/hosts.rb +2986 -0
  275. data/lib/mtncloud/cli/commands/hub.rb +215 -0
  276. data/lib/mtncloud/cli/commands/image_builder_command.rb +1197 -0
  277. data/lib/mtncloud/cli/commands/instance_types.rb +163 -0
  278. data/lib/mtncloud/cli/commands/instances.rb +5813 -0
  279. data/lib/mtncloud/cli/commands/integrations_command.rb +1412 -0
  280. data/lib/mtncloud/cli/commands/invoices_command.rb +1151 -0
  281. data/lib/mtncloud/cli/commands/jobs_command.rb +998 -0
  282. data/lib/mtncloud/cli/commands/key_pairs.rb +470 -0
  283. data/lib/mtncloud/cli/commands/library_cluster_layouts_command.rb +901 -0
  284. data/lib/mtncloud/cli/commands/library_cluster_packages_command.rb +552 -0
  285. data/lib/mtncloud/cli/commands/library_container_scripts_command.rb +446 -0
  286. data/lib/mtncloud/cli/commands/library_container_templates_command.rb +526 -0
  287. data/lib/mtncloud/cli/commands/library_container_types_command.rb +698 -0
  288. data/lib/mtncloud/cli/commands/library_forms_command.rb +625 -0
  289. data/lib/mtncloud/cli/commands/library_instance_types_command.rb +668 -0
  290. data/lib/mtncloud/cli/commands/library_layouts_command.rb +849 -0
  291. data/lib/mtncloud/cli/commands/library_operating_systems_command.rb +671 -0
  292. data/lib/mtncloud/cli/commands/library_option_lists_command.rb +503 -0
  293. data/lib/mtncloud/cli/commands/library_option_types_command.rb +329 -0
  294. data/lib/mtncloud/cli/commands/library_spec_templates_command.rb +547 -0
  295. data/lib/mtncloud/cli/commands/library_upgrades_command.rb +596 -0
  296. data/lib/mtncloud/cli/commands/license.rb +475 -0
  297. data/lib/mtncloud/cli/commands/load_balancer_monitors.rb +70 -0
  298. data/lib/mtncloud/cli/commands/load_balancer_pool_nodes.rb +87 -0
  299. data/lib/mtncloud/cli/commands/load_balancer_pools.rb +129 -0
  300. data/lib/mtncloud/cli/commands/load_balancer_profiles.rb +64 -0
  301. data/lib/mtncloud/cli/commands/load_balancer_types.rb +38 -0
  302. data/lib/mtncloud/cli/commands/load_balancer_virtual_servers.rb +147 -0
  303. data/lib/mtncloud/cli/commands/load_balancers.rb +189 -0
  304. data/lib/mtncloud/cli/commands/log_level_command.rb +54 -0
  305. data/lib/mtncloud/cli/commands/log_settings_command.rb +443 -0
  306. data/lib/mtncloud/cli/commands/login.rb +148 -0
  307. data/lib/mtncloud/cli/commands/logout.rb +63 -0
  308. data/lib/mtncloud/cli/commands/logs_command.rb +140 -0
  309. data/lib/mtncloud/cli/commands/man_command.rb +409 -0
  310. data/lib/mtncloud/cli/commands/migrations.rb +453 -0
  311. data/lib/mtncloud/cli/commands/monitoring_alerts_command.rb +791 -0
  312. data/lib/mtncloud/cli/commands/monitoring_apps_command.rb +716 -0
  313. data/lib/mtncloud/cli/commands/monitoring_checks_command.rb +766 -0
  314. data/lib/mtncloud/cli/commands/monitoring_contacts_command.rb +339 -0
  315. data/lib/mtncloud/cli/commands/monitoring_groups_command.rb +674 -0
  316. data/lib/mtncloud/cli/commands/monitoring_incidents_command.rb +835 -0
  317. data/lib/mtncloud/cli/commands/monitoring_settings.rb +212 -0
  318. data/lib/mtncloud/cli/commands/network_dhcp_relays_command.rb +375 -0
  319. data/lib/mtncloud/cli/commands/network_dhcp_servers_command.rb +366 -0
  320. data/lib/mtncloud/cli/commands/network_domains_command.rb +896 -0
  321. data/lib/mtncloud/cli/commands/network_edge_clusters_command.rb +288 -0
  322. data/lib/mtncloud/cli/commands/network_firewalls_command.rb +783 -0
  323. data/lib/mtncloud/cli/commands/network_floating_ips.rb +147 -0
  324. data/lib/mtncloud/cli/commands/network_groups_command.rb +654 -0
  325. data/lib/mtncloud/cli/commands/network_pool_server_types.rb +20 -0
  326. data/lib/mtncloud/cli/commands/network_pool_servers_command.rb +318 -0
  327. data/lib/mtncloud/cli/commands/network_pools_command.rb +903 -0
  328. data/lib/mtncloud/cli/commands/network_proxies_command.rb +578 -0
  329. data/lib/mtncloud/cli/commands/network_routers_command.rb +2628 -0
  330. data/lib/mtncloud/cli/commands/network_security_server_types.rb +20 -0
  331. data/lib/mtncloud/cli/commands/network_server_groups_command.rb +222 -0
  332. data/lib/mtncloud/cli/commands/network_server_types_command.rb +20 -0
  333. data/lib/mtncloud/cli/commands/network_servers_command.rb +398 -0
  334. data/lib/mtncloud/cli/commands/network_services_command.rb +198 -0
  335. data/lib/mtncloud/cli/commands/network_static_routes_command.rb +451 -0
  336. data/lib/mtncloud/cli/commands/network_transport_zones_command.rb +412 -0
  337. data/lib/mtncloud/cli/commands/networks_command.rb +1692 -0
  338. data/lib/mtncloud/cli/commands/open_command.rb +30 -0
  339. data/lib/mtncloud/cli/commands/options.rb +231 -0
  340. data/lib/mtncloud/cli/commands/packages_command.rb +822 -0
  341. data/lib/mtncloud/cli/commands/ping.rb +242 -0
  342. data/lib/mtncloud/cli/commands/plugins.rb +214 -0
  343. data/lib/mtncloud/cli/commands/policies_command.rb +990 -0
  344. data/lib/mtncloud/cli/commands/power_schedules_command.rb +731 -0
  345. data/lib/mtncloud/cli/commands/preseed_scripts_command.rb +378 -0
  346. data/lib/mtncloud/cli/commands/price_sets_command.rb +557 -0
  347. data/lib/mtncloud/cli/commands/prices_command.rb +692 -0
  348. data/lib/mtncloud/cli/commands/processes_command.rb +469 -0
  349. data/lib/mtncloud/cli/commands/projects_command.rb +537 -0
  350. data/lib/mtncloud/cli/commands/provisioning_licenses_command.rb +509 -0
  351. data/lib/mtncloud/cli/commands/provisioning_settings_command.rb +238 -0
  352. data/lib/mtncloud/cli/commands/recent_activity_command.rb +171 -0
  353. data/lib/mtncloud/cli/commands/remote.rb +1818 -0
  354. data/lib/mtncloud/cli/commands/reports_command.rb +724 -0
  355. data/lib/mtncloud/cli/commands/resource_pool_groups_command.rb +586 -0
  356. data/lib/mtncloud/cli/commands/rm_command.rb +14 -0
  357. data/lib/mtncloud/cli/commands/roles.rb +3120 -0
  358. data/lib/mtncloud/cli/commands/scale_thresholds.rb +103 -0
  359. data/lib/mtncloud/cli/commands/search_command.rb +184 -0
  360. data/lib/mtncloud/cli/commands/security_group_rules.rb +230 -0
  361. data/lib/mtncloud/cli/commands/security_groups.rb +1294 -0
  362. data/lib/mtncloud/cli/commands/security_package_types.rb +32 -0
  363. data/lib/mtncloud/cli/commands/security_packages.rb +84 -0
  364. data/lib/mtncloud/cli/commands/security_scans.rb +107 -0
  365. data/lib/mtncloud/cli/commands/self_service_command.rb +17 -0
  366. data/lib/mtncloud/cli/commands/server_devices_command.rb +207 -0
  367. data/lib/mtncloud/cli/commands/service_catalog_command.rb +1528 -0
  368. data/lib/mtncloud/cli/commands/service_plans_command.rb +895 -0
  369. data/lib/mtncloud/cli/commands/set_prompt_command.rb +51 -0
  370. data/lib/mtncloud/cli/commands/setup.rb +423 -0
  371. data/lib/mtncloud/cli/commands/shell.rb +717 -0
  372. data/lib/mtncloud/cli/commands/sleep_command.rb +43 -0
  373. data/lib/mtncloud/cli/commands/snapshots.rb +156 -0
  374. data/lib/mtncloud/cli/commands/source_command.rb +30 -0
  375. data/lib/mtncloud/cli/commands/ssl_verification_command.rb +47 -0
  376. data/lib/mtncloud/cli/commands/storage_datastores.rb +457 -0
  377. data/lib/mtncloud/cli/commands/storage_providers_command.rb +1401 -0
  378. data/lib/mtncloud/cli/commands/storage_server_types.rb +45 -0
  379. data/lib/mtncloud/cli/commands/storage_servers.rb +116 -0
  380. data/lib/mtncloud/cli/commands/storage_volume_types.rb +45 -0
  381. data/lib/mtncloud/cli/commands/storage_volumes.rb +236 -0
  382. data/lib/mtncloud/cli/commands/subnets_command.rb +819 -0
  383. data/lib/mtncloud/cli/commands/support_bundles_command.rb +606 -0
  384. data/lib/mtncloud/cli/commands/systems.rb +1203 -0
  385. data/lib/mtncloud/cli/commands/tasks.rb +1391 -0
  386. data/lib/mtncloud/cli/commands/tee_command.rb +14 -0
  387. data/lib/mtncloud/cli/commands/tenants_command.rb +315 -0
  388. data/lib/mtncloud/cli/commands/tokens_command.rb +391 -0
  389. data/lib/mtncloud/cli/commands/update_command.rb +46 -0
  390. data/lib/mtncloud/cli/commands/usage_command.rb +203 -0
  391. data/lib/mtncloud/cli/commands/user_groups_command.rb +512 -0
  392. data/lib/mtncloud/cli/commands/user_settings_command.rb +849 -0
  393. data/lib/mtncloud/cli/commands/user_sources_command.rb +1065 -0
  394. data/lib/mtncloud/cli/commands/users.rb +897 -0
  395. data/lib/mtncloud/cli/commands/vdi_allocations_command.rb +159 -0
  396. data/lib/mtncloud/cli/commands/vdi_apps_command.rb +317 -0
  397. data/lib/mtncloud/cli/commands/vdi_command.rb +359 -0
  398. data/lib/mtncloud/cli/commands/vdi_gateways_command.rb +290 -0
  399. data/lib/mtncloud/cli/commands/vdi_pools_command.rb +574 -0
  400. data/lib/mtncloud/cli/commands/version_command.rb +38 -0
  401. data/lib/mtncloud/cli/commands/view.rb +107 -0
  402. data/lib/mtncloud/cli/commands/virtual_images.rb +1362 -0
  403. data/lib/mtncloud/cli/commands/virtual_switches_command.rb +336 -0
  404. data/lib/mtncloud/cli/commands/whitelabel_settings_command.rb +653 -0
  405. data/lib/mtncloud/cli/commands/whoami.rb +323 -0
  406. data/lib/mtncloud/cli/commands/wiki_command.rb +448 -0
  407. data/lib/mtncloud/cli/commands/workflows.rb +1022 -0
  408. data/lib/mtncloud/cli/credentials.rb +482 -0
  409. data/lib/mtncloud/cli/dot_file.rb +180 -0
  410. data/lib/mtncloud/cli/error_handler.rb +307 -0
  411. data/lib/mtncloud/cli/errors.rb +53 -0
  412. data/lib/mtncloud/cli/expression_parser.rb +153 -0
  413. data/lib/mtncloud/cli/mixins/accounts_helper.rb +484 -0
  414. data/lib/mtncloud/cli/mixins/affinity_helper.rb +118 -0
  415. data/lib/mtncloud/cli/mixins/backups_helper.rb +200 -0
  416. data/lib/mtncloud/cli/mixins/deployments_helper.rb +163 -0
  417. data/lib/mtncloud/cli/mixins/execution_request_helper.rb +50 -0
  418. data/lib/mtncloud/cli/mixins/infrastructure_helper.rb +966 -0
  419. data/lib/mtncloud/cli/mixins/jobs_helper.rb +202 -0
  420. data/lib/mtncloud/cli/mixins/library_helper.rb +539 -0
  421. data/lib/mtncloud/cli/mixins/load_balancers_helper.rb +176 -0
  422. data/lib/mtncloud/cli/mixins/logs_helper.rb +131 -0
  423. data/lib/mtncloud/cli/mixins/monitoring_helper.rb +876 -0
  424. data/lib/mtncloud/cli/mixins/networks_helper.rb +62 -0
  425. data/lib/mtncloud/cli/mixins/operations_helper.rb +41 -0
  426. data/lib/mtncloud/cli/mixins/option_source_helper.rb +254 -0
  427. data/lib/mtncloud/cli/mixins/print_helper.rb +1631 -0
  428. data/lib/mtncloud/cli/mixins/processes_helper.rb +286 -0
  429. data/lib/mtncloud/cli/mixins/prompt_helper.rb +136 -0
  430. data/lib/mtncloud/cli/mixins/provisioning_helper.rb +2963 -0
  431. data/lib/mtncloud/cli/mixins/remote_helper.rb +139 -0
  432. data/lib/mtncloud/cli/mixins/rest_command.rb +994 -0
  433. data/lib/mtncloud/cli/mixins/secondary_rest_command.rb +700 -0
  434. data/lib/mtncloud/cli/mixins/storage_servers_helper.rb +93 -0
  435. data/lib/mtncloud/cli/mixins/storage_volumes_helper.rb +76 -0
  436. data/lib/mtncloud/cli/mixins/vdi_helper.rb +246 -0
  437. data/lib/mtncloud/cli/mixins/whoami_helper.rb +73 -0
  438. data/lib/mtncloud/cli/option_parser.rb +127 -0
  439. data/lib/mtncloud/cli/option_types.rb +1622 -0
  440. data/lib/mtncloud/cli/version.rb +6 -0
  441. data/lib/mtncloud/cli.rb +105 -0
  442. data/lib/mtncloud/currency.rb +184 -0
  443. data/lib/mtncloud/ext/hash.rb +109 -0
  444. data/lib/mtncloud/ext/nil_class.rb +5 -0
  445. data/lib/mtncloud/ext/rest_client.rb +37 -0
  446. data/lib/mtncloud/ext/string.rb +66 -0
  447. data/lib/mtncloud/formatters.rb +511 -0
  448. data/lib/mtncloud/logging.rb +185 -0
  449. data/lib/mtncloud/morpkg.rb +119 -0
  450. data/lib/mtncloud/rest_client.rb +104 -0
  451. data/lib/mtncloud/routes.rb +304 -0
  452. data/lib/mtncloud/terminal.rb +528 -0
  453. data/lib/mtncloud/util.rb +29 -0
  454. data/lib/mtncloud.rb +5 -0
  455. data/mtncloud-cli.gemspec +38 -0
  456. data/test/api/affinity_groups_interface_test.rb +43 -0
  457. data/test/api/clients_interface_test.rb +23 -0
  458. data/test/api/clouds_interface_test.rb +67 -0
  459. data/test/api/containers_interface_test.rb +68 -0
  460. data/test/api/host_vm_groups_interface_test.rb +35 -0
  461. data/test/api/instances_interface_test.rb +22 -0
  462. data/test/api/network_routers_interface_test.rb +22 -0
  463. data/test/api/systems_interface_test.rb +26 -0
  464. data/test/api/whoami_interface_test.rb +14 -0
  465. data/test/branding_test.rb +160 -0
  466. data/test/cli/access_token_test.rb +36 -0
  467. data/test/cli/affinity_groups_cloud_cluster_scope_test.rb +270 -0
  468. data/test/cli/affinity_groups_cluster_scope_test.rb +171 -0
  469. data/test/cli/affinity_groups_test.rb +57 -0
  470. data/test/cli/affinity_groups_violations_scope_test.rb +141 -0
  471. data/test/cli/affinity_helper_test.rb +367 -0
  472. data/test/cli/auth_test.rb +88 -0
  473. data/test/cli/backups_test.rb +212 -0
  474. data/test/cli/cli_test.rb +48 -0
  475. data/test/cli/clients_test.rb +45 -0
  476. data/test/cli/clusters_uuid_test.rb +146 -0
  477. data/test/cli/containers_test.rb +92 -0
  478. data/test/cli/distributed_workers_test.rb +68 -0
  479. data/test/cli/help_test.rb +25 -0
  480. data/test/cli/host_vm_groups_cluster_scope_test.rb +187 -0
  481. data/test/cli/host_vm_groups_test.rb +63 -0
  482. data/test/cli/infrastructure_helper_cluster_resolver_test.rb +250 -0
  483. data/test/cli/instances_test.rb +37 -0
  484. data/test/cli/man_test.rb +14 -0
  485. data/test/cli/migrations_test.rb +39 -0
  486. data/test/cli/network_routers_test.rb +65 -0
  487. data/test/cli/remote_test.rb +89 -0
  488. data/test/cli/roles_test.rb +47 -0
  489. data/test/cli/shell_test.rb +81 -0
  490. data/test/cli/storage_volumes_test.rb +79 -0
  491. data/test/cli/systems_test.rb +206 -0
  492. data/test/cli/version_test.rb +23 -0
  493. data/test/cli/view_test.rb +55 -0
  494. data/test/cli/whoami_test.rb +17 -0
  495. data/test/mtncloud_test.rb +16 -0
  496. data/test/test_case.rb +342 -0
  497. data/test/test_config.rb +137 -0
  498. data/test/test_data_helper.rb +97 -0
  499. metadata +807 -0
@@ -0,0 +1,998 @@
1
+ require 'mtncloud/cli/cli_command'
2
+
3
+ class MtnCloud::Cli::JobsCommand
4
+ include MtnCloud::Cli::CliCommand
5
+ include MtnCloud::Cli::JobsHelper
6
+ include MtnCloud::Cli::AccountsHelper
7
+
8
+ set_command_name :'jobs'
9
+
10
+ register_subcommands :list, :get, :add, :update, :execute, :remove
11
+ register_subcommands :list_executions, :get_execution, :get_execution_event
12
+ set_default_subcommand :list
13
+
14
+ def connect(opts)
15
+ @api_client = establish_remote_appliance_connection(opts)
16
+ @jobs_interface = @api_client.jobs
17
+ @options_interface = @api_client.options
18
+ @tasks_interface = @api_client.tasks
19
+ @task_sets_interface = @api_client.task_sets
20
+ @instances_interface = @api_client.instances
21
+ @servers_interface = @api_client.servers
22
+ @containers_interface = @api_client.containers
23
+ @execute_schedules_interface = @api_client.execute_schedules
24
+ end
25
+
26
+ def handle(args)
27
+ handle_subcommand(args)
28
+ end
29
+
30
+ def list(args)
31
+ options = {}
32
+ options[:show_stats] = true
33
+ params = {}
34
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
35
+ opts.banner = subcommand_usage()
36
+ opts.on("--source [all|user|discovered]", String, "Filters job based upon specified source. Default is all") do |val|
37
+ options[:source] = val.to_s
38
+ end
39
+ opts.on("--internal [true|false]", String, "Filters job based on internal flag. Internal jobs are excluded by default.") do |val|
40
+ params["internalOnly"] = (val.to_s != "false")
41
+ end
42
+ opts.on("--stats [true|false]", String, "Hide Execution Stats. Job statistics are displayed by default.") do |val|
43
+ options[:show_stats] = (val.to_s != "false")
44
+ end
45
+ opts.on('-l', '--labels LABEL', String, "Filter by labels, can match any of the values") do |val|
46
+ add_query_parameter(params, 'labels', parse_labels(val))
47
+ end
48
+ opts.on('--all-labels LABEL', String, "Filter by labels, must match all of the values") do |val|
49
+ add_query_parameter(params, 'allLabels', parse_labels(val))
50
+ end
51
+ build_standard_list_options(opts, options)
52
+ opts.footer = "List jobs."
53
+ end
54
+ optparse.parse!(args)
55
+ connect(options)
56
+ # verify_args!(args:args, optparse:optparse, count:0)
57
+ if args.count > 0
58
+ options[:phrase] = args.join(" ")
59
+ end
60
+ params.merge!(parse_list_options(options))
61
+ if !options[:source].nil?
62
+ if !['all', 'user', 'discovered', 'sync'].include?(options[:source])
63
+ raise_command_error("Invalid source filter #{options[:source]}", args, optparse)
64
+ end
65
+ params['itemSource'] = options[:source] == 'discovered' ? 'sync' : options[:source]
66
+ end
67
+ @jobs_interface.setopts(options)
68
+ if options[:dry_run]
69
+ print_dry_run @jobs_interface.dry.list(params)
70
+ return
71
+ end
72
+ json_response = @jobs_interface.list(params)
73
+ jobs = json_response['jobs']
74
+ render_response(json_response, options, 'jobs') do
75
+ title = "Jobs"
76
+ subtitles = []
77
+ subtitles += parse_list_subtitles(options)
78
+ if params["internalOnly"]
79
+ subtitles << "internalOnly: #{params['internalOnly']}"
80
+ end
81
+ print_h1 title, subtitles, options
82
+ if jobs.empty?
83
+ print cyan,"No jobs found.",reset,"\n"
84
+ else
85
+ columns = {
86
+ "ID" => 'id',
87
+ "Type" => lambda {|job| job['type'] ? job['type']['name'] : '' },
88
+ "Name" => 'name',
89
+ "Labels" => lambda {|it| format_list(it['labels'], '', 3) rescue '' },
90
+ "Details" => lambda {|job| job['jobSummary'] },
91
+ "Enabled" => lambda {|job| "#{job['enabled'] ? '' : yellow}#{format_boolean(job['enabled'])}#{cyan}" },
92
+ # "Date Created" => lambda {|job| format_local_dt(job['dateCreated']) },
93
+ # "Last Updated" => lambda {|job| format_local_dt(job['lastUpdated']) },
94
+ "Last Run" => lambda {|job| format_local_dt(job['lastRun']) },
95
+ "Next Run" => lambda {|job| job['enabled'] && job['scheduleMode'] && job['scheduleMode'] != 'manual' ? format_local_dt(job['nextFire']) : '' },
96
+ "Last Result" => lambda {|job| format_job_status(job['lastResult']) },
97
+ }
98
+ print as_pretty_table(jobs, columns.upcase_keys!, options)
99
+ print_results_pagination(json_response)
100
+ if options[:show_stats]
101
+ if stats = json_response['stats']
102
+ label_width = 17
103
+
104
+ print_h2 "Execution Stats - Last 7 Days"
105
+ print cyan
106
+
107
+ print "Jobs".rjust(label_width, ' ') + ": #{stats['jobCount']}\n"
108
+ print "Executions Today".rjust(label_width, ' ') + ": #{stats['todayCount']}\n"
109
+ print "Daily Executions".rjust(label_width, ' ') + ": " + stats['executionsPerDay'].join(' | ') + "\n"
110
+ print "Total Executions".rjust(label_width, ' ') + ": #{stats['execCount']}\n"
111
+ print "Completed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execSuccessRate'].to_f, 100, {bar_color:green}) + "#{stats['execSuccess']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
112
+ print "Failed".rjust(label_width, ' ') + ": " + generate_usage_bar(stats['execFailedRate'].to_f, 100, {bar_color:red}) + "#{stats['execFailed']}".rjust(15, ' ') + " of " + "#{stats['execCount']}".ljust(15, ' ') + "\n#{cyan}"
113
+ end
114
+ print reset,"\n"
115
+ end
116
+ end
117
+ print reset,"\n"
118
+ end
119
+ if jobs.empty?
120
+ return 1, "no jobs found"
121
+ else
122
+ return 0, nil
123
+ end
124
+ end
125
+
126
+ def get(args)
127
+ options = {}
128
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
129
+ opts.banner = subcommand_usage("[job] [max-exec-count]")
130
+ build_standard_get_options(opts, options)
131
+ opts.footer = "Get details about a job.\n" +
132
+ "[job] is required. Job ID or name.\n" +
133
+ "[max-exec-count] is optional. Specified max # of most recent executions. Defaults is 3"
134
+ end
135
+ optparse.parse!(args)
136
+ if args.count < 1
137
+ raise_command_error "wrong number of arguments, expected 1-N and got (#{args.count}) #{args}\n#{optparse}"
138
+ end
139
+ connect(options)
140
+ return _get(args[0], options, args.count > 1 ? args[1].to_i : nil)
141
+ end
142
+
143
+ def _get(job_id, options = {}, max_execs = 3)
144
+ @jobs_interface.setopts(options)
145
+
146
+ if !(job_id.to_s =~ /\A\d{1,}\Z/)
147
+ job = find_by_name_or_id('job', job_id)
148
+
149
+ if !job
150
+ print_red_alert "Job #{job_id} not found"
151
+ exit 1
152
+ end
153
+ job_id = job['id']
154
+ end
155
+
156
+ max_execs = 3 if max_execs.nil?
157
+
158
+ params = {'includeExecCount' => max_execs}
159
+
160
+ if options[:dry_run]
161
+ print_dry_run @jobs_interface.dry.get(job_id, params)
162
+ return
163
+ end
164
+ json_response = @jobs_interface.get(job_id, params)
165
+ render_response(json_response, options, 'job') do
166
+ job = json_response['job']
167
+ schedule_name = ''
168
+ if !job['scheduleMode'].nil?
169
+ if job['scheduleMode'] == 'manual'
170
+ schedule_name = 'Manual'
171
+ elsif job['scheduleMode'].to_s.downcase == 'datetime'
172
+ schedule_name = ("Date and Time - " + (format_local_dt(job['dateTime']).to_s rescue 'n/a'))
173
+ elsif job['scheduleMode'].to_s == ''
174
+ schedule_name = 'n/a' # should not happen
175
+ else
176
+ begin
177
+ schedule = @execute_schedules_interface.get(job['scheduleMode'])['schedule']
178
+ schedule_name = schedule ? schedule['name'] : ''
179
+ rescue => ex
180
+ MtnCloud::Logging::DarkPrinter.puts "Failed to load schedule name" if MtnCloud::Logging.debug?
181
+ schedule_name = 'n/a'
182
+ end
183
+ end
184
+ end
185
+ title = "Job"
186
+ subtitles = []
187
+ subtitles += parse_list_subtitles(options)
188
+ print_h1 title, subtitles
189
+ print cyan
190
+ description_cols = [
191
+ {"ID" => lambda {|it| it['id'] } },
192
+ {"Name" => lambda {|it| it['name']} },
193
+ {"Labels" => lambda {|it| format_list(it['labels'], '', 3) rescue '' } },
194
+ {"Job Type" => lambda {|it| it['type']['name']} },
195
+ {"Enabled" => lambda {|it| format_boolean(it['enabled'])} },
196
+ job['workflow'] ? {'Task' => lambda {|it| (it['workflow']['name'] rescue nil) || it['jobSummary']} } : nil,
197
+ job['task'] ? {'Workflow' => lambda {|it| (it['task']['name'] rescue nil) || it['jobSummary']} } : nil,
198
+ job['securityPackage'] ? {'Security Package' => lambda {|it| (it['securityPackage']['name'] rescue nil) || it['jobSummary']} } : nil,
199
+ job['securityPackage'] ? {'Scan Checklist' => lambda {|it| (it['scanPath'] rescue nil)} } : nil,
200
+ job['securityPackage'] ? {'Security Profile' => lambda {|it| (it['securityProfile'] rescue nil)} } : nil,
201
+ {"Schedule" => lambda {|it| schedule_name} }
202
+ ].compact
203
+
204
+ if job['targetType']
205
+ description_cols << {"Context Type" => lambda {|it| it['targetType'] == 'appliance' ? 'None' : it['targetType'] } }
206
+
207
+ if job['targetType'] != 'appliance'
208
+ description_cols << {"Context #{job['targetType'].capitalize}#{job['targets'].count > 1 ? 's' : ''}" => lambda {|it| it['targets'].collect {|it| it['name']}.join(', ')} }
209
+ end
210
+ end
211
+
212
+ print_description_list(description_cols, job)
213
+
214
+ # config = job['config']
215
+ # # prune config of stuff that user does not xare about
216
+ # config = config.reject! {|k,v| ["configList","workflowId","taskId","securitySpecId", "customConfig"].include?(k) }
217
+ # if config && !config.empty?
218
+ # print_h2 "Configuration"
219
+ # print_description_list(config.keys, config)
220
+ # print reset,"\n"
221
+ # end
222
+
223
+ if max_execs != 0
224
+ print_h2 "Recent Executions"
225
+ print_job_executions(json_response['executions']['jobExecutions'], options)
226
+
227
+ if json_response['executions']['meta'] && json_response['executions']['meta']['total'] > max_execs
228
+ print_results_pagination(json_response['executions'])
229
+ end
230
+ end
231
+ print reset,"\n"
232
+ end
233
+ return 0, nil
234
+ end
235
+
236
+ def add(args)
237
+ options = {}
238
+ params = {}
239
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
240
+ opts.banner = subcommand_usage( "[name]")
241
+ opts.on("--name NAME", String, "Updates job name") do |val|
242
+ params['name'] = val.to_s
243
+ end
244
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
245
+ params['labels'] = parse_labels(val)
246
+ end
247
+ opts.on('-a', '--active [on|off]', String, "Can be used to enable / disable the job. Default is on") do |val|
248
+ params['enabled'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
249
+ end
250
+ opts.on('--type [TYPE]', String, "Job Type Name, Code or ID. The available types are \"Security Scan Job\", \"Task Job\", and \"Workflow Job\"") do |val|
251
+ options[:type] = val
252
+ end
253
+ opts.on('-t', '--task [TASK]', String, "Task ID or name, assigns task to job. This sets the job type to \"Task Job\".") do |val|
254
+ if options[:workflow]
255
+ raise_command_error "Options --task and --workflow are incompatible"
256
+ elsif options[:security_package]
257
+ raise_command_error "Options --task and --security-package are incompatible"
258
+ else
259
+ options[:task] = val
260
+ end
261
+ options[:type] = 'morpheus.task'
262
+ end
263
+ opts.on('-w', '--workflow [WORKFLOW]', String, "Workflow ID or name, assigns workflow to job. This sets the job type to \"Workflow Job\".") do |val|
264
+ if options[:task]
265
+ raise_command_error "Options --workflow and --task are incompatible"
266
+ elsif options[:security_package]
267
+ raise_command_error "Options --workflow and --security-package are incompatible"
268
+ else
269
+ options[:workflow] = val
270
+ end
271
+ options[:type] = 'morpheus.workflow'
272
+ end
273
+ opts.on('--security-package [PACKAGE]', String, "Security Package ID or name, assigns security package to job. This sets the job type to \"Security Scan Job\".") do |val|
274
+ if options[:workflow]
275
+ raise_command_error "Options --security-package and --workflow are incompatible"
276
+ elsif options[:task]
277
+ raise_command_error "Options --security-package and --workflow are incompatible"
278
+ else
279
+ options[:security_package] = val
280
+ end
281
+ options[:type] = 'morpheus.securityScan'
282
+ end
283
+ opts.on('--context-type [TYPE]', String, "Context type (instance|instance-label|server|server-label|none). Default is none") do |val|
284
+ val = val.to_s.downcase
285
+ params['targetType'] = (val == 'none' ? 'appliance' : val)
286
+ end
287
+ opts.on('--target-type [TYPE]', String, "alias for --context-type") do |val|
288
+ val = val.to_s.downcase
289
+ params['targetType'] = (val == 'none' ? 'appliance' : val)
290
+ end
291
+ opts.add_hidden_option('--target-type')
292
+ opts.on('--instances [LIST]', Array, "Context instances(s), comma separated list of instance IDs. Incompatible with --servers") do |list|
293
+ params['targetType'] = 'instance'
294
+ params['targets'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq.collect {|it| {'refId' => it.to_i}}
295
+ end
296
+ opts.on('--instance-label LABEL', String, "Instance Label") do |val|
297
+ if params['targetType'] && params['targetType'] != 'instance-label'
298
+ raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{params['targetType']})")
299
+ end
300
+ params['targetType'] = 'instance-label'
301
+ params['instanceLabel'] = val
302
+ end
303
+ opts.on('--servers [LIST]', Array, "Context server(s), comma separated list of server IDs. Incompatible with --instances") do |list|
304
+ params['targetType'] = 'server'
305
+ params['targets'] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip }.compact.uniq.collect {|it| {'refId' => it.to_i}}
306
+ end
307
+ opts.on('--server-label LABEL', String, "Server Label") do |val|
308
+ if params['targetType'] && params['targetType'] != 'server-label'
309
+ raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{params['targetType']})")
310
+ end
311
+ params['targetType'] = 'server-label'
312
+ params['serverLabel'] = val
313
+ end
314
+ opts.on('-S', '--schedule [SCHEDULE]', String, "Job execution schedule type name or ID") do |val|
315
+ options[:schedule] = val
316
+ end
317
+ opts.on('--config [TEXT]', String, "Custom config") do |val|
318
+ params['customConfig'] = val.to_s
319
+ end
320
+ opts.on('-R', '--run [on|off]', String, "Can be used to run the job now.") do |val|
321
+ params['run'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
322
+ end
323
+ opts.on('--date-time DATETIME', String, "Can be used to run schedule at a specific date and time. Use UTC time in the format 2020-02-15T05:00:00Z. This sets scheduleMode to 'dateTime'.") do |val|
324
+ options[:schedule] = 'dateTime'
325
+ params['dateTime'] = val.to_s
326
+ end
327
+ opts.on('--scan-checklist [VALUE]', String, "Scan Checklist. Only applicable to the security scan job type") do |val|
328
+ # params['config'] ||= {}
329
+ # params['config']['scanPath'] = val.to_s
330
+ params['scanPath'] = val.to_s
331
+ end
332
+ opts.on('--security-profile [VALUE]', String, "Security Profile. Only applicable to the security scan job type") do |val|
333
+ # params['config'] ||= {}
334
+ # params['config']['securityProfile'] = val.to_s
335
+ params['securityProfile'] = val.to_s
336
+ end
337
+ build_standard_add_options(opts, options)
338
+ opts.footer = "Create job."
339
+ end
340
+ optparse.parse!(args)
341
+ connect(options)
342
+ verify_args!(args:args, optparse:optparse, max:1)
343
+
344
+ if options[:payload]
345
+ payload = parse_payload(options, 'job')
346
+ else
347
+ apply_options(params, options)
348
+
349
+ # name
350
+ params['name'] = params['name'] || args[0] || name = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Job Name', 'required' => true, 'description' => 'Job Name.'}],options[:options],@api_client,{})['name']
351
+
352
+ # type id is needed to load the options right now..
353
+ job_type = nil
354
+ job_types = get_available_job_types()
355
+ if options[:task].nil? && options[:workflow].nil? && options[:security_package].nil?
356
+ if options[:type]
357
+ # match on value (id) or code or name
358
+ job_type = job_types.find {|it| it['value'].to_s.downcase == options[:type].to_s.downcase } || job_types.find {|it| it['code'].to_s.downcase == options[:type].to_s.downcase } || job_types.find {|it| it['name'].to_s.downcase == options[:type].to_s.downcase || it['name'].to_s.downcase == "#{options[:type]} Job".to_s.downcase }
359
+ if job_type.nil?
360
+ raise_command_error "Job Type not found for '#{options[:type]}'"
361
+ end
362
+ else
363
+ # prompt
364
+ job_type_id = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'jobType', 'type' => 'select', 'fieldLabel' => 'Job Type', 'selectOptions' => job_types, 'required' => true, 'description' => 'Select Job Type.'}],options[:options],@api_client,{})['jobType']
365
+ job_type = job_types.find {|it| it['value'] == job_type_id}
366
+ end
367
+
368
+ # prompt task / workflow / securityPackage
369
+ if job_type['code'] == 'morpheus.task'
370
+ params['task'] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'task.id', 'fieldLabel' => 'Task', 'type' => 'select', 'required' => true, 'optionSource' => 'tasks'}], options[:options], @api_client, {})['task']
371
+ elsif job_type['code'] == 'morpheus.workflow'
372
+ params['workflow'] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'workflow.id', 'fieldLabel' => 'Workflow', 'type' => 'select', 'required' => true, 'optionSource' => 'operationTaskSets'}], options[:options], @api_client, {})['workflow']
373
+ elsif job_type['code'] == 'morpheus.securityScan'
374
+ params['securityPackage'] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'securityPackage.id', 'fieldLabel' => 'Security Package', 'type' => 'select', 'required' => true, 'optionSource' => 'securityPackages'}], options[:options], @api_client, {})['securityPackage']
375
+ end
376
+ # type is not even included in the payload? lol
377
+ # params["type"] = {"code" => job_type["code"]}
378
+ end
379
+
380
+ # task
381
+ if !options[:task].nil?
382
+ task = find_by_name_or_id('task', options[:task])
383
+
384
+ if task.nil?
385
+ print_red_alert "Task #{options[:task]} not found"
386
+ exit 1
387
+ end
388
+ params['task'] = {'id' => task['id']}
389
+ job_type = job_types.find {|it| it['code'] == 'morpheus.task' } # || raise_command_error "Unable to find job type for 'morpheus.task'"
390
+ end
391
+
392
+ # workflow
393
+ task_set = nil
394
+ if !options[:workflow].nil?
395
+ task_set = find_by_name_or_id('task_set', options[:workflow])
396
+
397
+ if task_set.nil?
398
+ print_red_alert "Workflow #{options[:workflow]} not found"
399
+ exit 1
400
+ end
401
+ params['workflow'] = {'id' => task_set['id']}
402
+ job_type = job_types.find {|it| it['code'] == 'morpheus.workflow' } # || raise_command_error "Unable to find job type for 'morpheus.workflow'"
403
+ end
404
+ # load workflow if we havent yet
405
+ if (params['workflow'] && params['workflow']['id']) && task_set.nil?
406
+ task_set = find_by_name_or_id('task_set', params['workflow']['id'])
407
+ if task_set.nil?
408
+ print_red_alert "Workflow #{params['workflow']['id']} not found"
409
+ exit 1
410
+ end
411
+ end
412
+ # prompt for custom options for workflow
413
+ custom_option_types = task_set ? task_set['optionTypes'] : nil
414
+ if custom_option_types && custom_option_types.size() > 0
415
+ # they are all returned in a single array right now, so skip prompting for the jobType optionTypes
416
+ custom_option_types.reject! { |it| it['code'] && it['code'].include?('job.type') }
417
+ custom_option_types = custom_option_types.collect {|it|
418
+ it['fieldContext'] = 'customOptions'
419
+ it
420
+ }
421
+ custom_options = MtnCloud::Cli::OptionTypes.prompt(custom_option_types, options[:options], @api_client, {})
422
+ params['customOptions'] = custom_options['customOptions']
423
+ end
424
+
425
+ # security package
426
+ if !options[:security_package].nil?
427
+ # task = find_by_name_or_id('securityPackage', options[:security_package])
428
+ security_package = nil
429
+ if (options[:security_package].to_s =~ /\A\d{1,}\Z/)
430
+ security_package = @options_interface.options_for_source('securityPackages', {})['data'].find {|it| it['value'] == options[:security_package].to_i }['value']
431
+ else
432
+ security_package = @options_interface.options_for_source('securityPackages', {})['data'].find {|it| it['name'].to_s.downcase == options[:security_package].to_s.downcase }['value']
433
+ end
434
+ if security_package.nil?
435
+ print_red_alert "Security Package #{options[:security_package]} not found"
436
+ exit 1
437
+ end
438
+ params['securityPackage'] = {'id' => security_package['id']}
439
+ job_type = job_types.find {|it| it['code'] == 'morpheus.securityScan' } # || raise_command_error "Unable to find job type for 'morpheus.workflow'"
440
+ end
441
+
442
+ # load options based upon job type + task / workflow / securityPackage
443
+ job_options = @jobs_interface.options(job_type['id'], {'taskId' => params['task'] ? params['task']['id'] : nil, 'workflowId' => params['workflow'] ? params['workflow']['id'] : nil, 'securityPackageId' => params['securityPackage'] ? params['securityPackage']['id'] : nil})
444
+
445
+ # securityScan options
446
+ if job_type['code'] == 'morpheus.securityScan'
447
+ job_type_option_types = [
448
+ {'fieldName' => 'scanPath', 'fieldLabel' => "Scan Checklist", 'type' => 'text', 'required' => true, 'displayOrder' => 20},
449
+ {'fieldName' => 'securityProfile', 'fieldLabel' => "Security Profile", 'type' => 'text', 'required' => true, 'displayOrder' => 21}
450
+ ]
451
+ #job_type_option_types = job_options['optionTypes'] || []
452
+ # reject securitySpecId because already prompted for securityPackage above,
453
+ # and it is passed as securityPackage.id instead of config.securitySpecId
454
+ # also remove config context because jobs return this configuration at the level too
455
+ #job_type_option_types.reject! {|it| it['fieldName'] == "securitySpecId" }
456
+ #job_type_option_types = job_type_option_types.collect {|it| it.delete("fieldContext") if it["fieldContext"] == "config" }
457
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt(job_type_option_types, options[:options], @api_client, {})
458
+ v_prompt.deep_compact!
459
+ params.deep_merge!(v_prompt)
460
+ end
461
+
462
+ # context type
463
+ if params['targetType'].nil?
464
+ params['targetType'] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'targetType', 'fieldLabel' => 'Context Type', 'type' => 'select', 'required' => true, 'selectOptions' => job_options['targetTypes'], 'defaultValue' => job_options['targetTypes'].first['name']}], options[:options], @api_client, {})['targetType']
465
+ end
466
+
467
+ # contexts
468
+ if ['instance', 'server'].include?(params['targetType']) && (params['targets'].nil? || params['targets'].empty?)
469
+ targets = []
470
+ if params['targetType'] == 'instance'
471
+ avail_targets = @instances_interface.list({max:10000})['instances'].collect {|it| {'name' => it['name'], 'value' => it['id']}}
472
+ else
473
+ avail_targets = @servers_interface.list({max:10000, 'vmHypervisor' => nil, 'containerHypervisor' => nil})['servers'].collect {|it| {'name' => it['name'], 'value' => it['id']}}
474
+ end
475
+ target_id = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'target', 'fieldLabel' => "Context #{params['targetType'].capitalize}", 'type' => 'select', 'required' => true, 'selectOptions' => avail_targets}], options[:options], @api_client, {}, options[:no_prompt], true)['target']
476
+ targets << target_id
477
+ avail_targets.reject! {|it| it['value'] == target_id}
478
+
479
+ while !target_id.nil? && !avail_targets.empty? && MtnCloud::Cli::OptionTypes.confirm("Add another context #{params['targetType']}?", {:default => false})
480
+ target_id = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'target', 'fieldLabel' => "Context #{params['targetType'].capitalize}", 'type' => 'select', 'required' => false, 'selectOptions' => avail_targets}], options[:options], @api_client, {}, options[:no_prompt], true)['target']
481
+
482
+ if !target_id.nil?
483
+ targets << target_id
484
+ avail_targets.reject! {|it| it['value'] == target_id}
485
+ end
486
+ end
487
+ params['targets'] = targets.collect {|it| {'refId' => it}}
488
+ elsif params['targetType'] == 'instance-label'
489
+ if params['instanceLabel'].nil?
490
+ params['instanceLabel'] = MtnCloud::Cli::OptionTypes.prompt([{'switch' => 'instance-label', 'fieldName' => 'instanceLabel', 'fieldLabel' => 'Instance Label', 'type' => 'text', 'required' => true, 'description' => 'Instance Label'}], options[:options], @api_client)['instanceLabel']
491
+ end
492
+ elsif params['targetType'] == 'server-label'
493
+ if params['serverLabel'].nil?
494
+ params['serverLabel'] = MtnCloud::Cli::OptionTypes.prompt([{'switch' => 'server-label', 'fieldName' => 'serverLabel', 'fieldLabel' => 'Server Label', 'type' => 'text', 'required' => true, 'description' => 'Server Label'}], options[:options], @api_client)['serverLabel']
495
+ end
496
+ end
497
+ # schedule
498
+ if options[:schedule].nil?
499
+ options[:schedule] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'scheduleMode', 'fieldLabel' => "Schedule", 'type' => 'select', 'required' => true, 'selectOptions' => job_options['schedules'], 'defaultValue' => job_options['schedules'].first['name']}], options[:options], @api_client, {})['scheduleMode']
500
+ params['scheduleMode'] = options[:schedule]
501
+ end
502
+
503
+ if options[:schedule] == 'manual'
504
+ # cool
505
+ elsif options[:schedule].to_s.downcase == 'datetime'
506
+ # prompt for dateTime
507
+ if params['dateTime'].nil?
508
+ params['dateTime'] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'dateTime', 'fieldLabel' => "Date and Time", 'type' => 'text', 'required' => true}], options[:options], @api_client, {}, options[:no_prompt], true)['dateTime']
509
+ end
510
+ elsif options[:schedule].to_s != ''
511
+ # ok they passed a schedule name or id
512
+ schedule = job_options['schedules'].find {|it| it['name'] == options[:schedule] || it['value'] == options[:schedule].to_i}
513
+
514
+ if schedule.nil?
515
+ print_red_alert "Schedule #{options[:schedule]} not found"
516
+ exit 1
517
+ end
518
+ options[:schedule] = schedule['value']
519
+ end
520
+ params['scheduleMode'] = options[:schedule]
521
+
522
+ # custom config
523
+ if params['customConfig'].nil? && job_options['allowCustomConfig']
524
+ params['customConfig'] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'config', 'fieldLabel' => "Custom Config", 'type' => 'text', 'required' => false}], options[:options], @api_client, {})['config']
525
+ end
526
+ payload = {'job' => params}
527
+ end
528
+
529
+ @jobs_interface.setopts(options)
530
+ if options[:dry_run]
531
+ print_dry_run @jobs_interface.dry.create(payload)
532
+ return
533
+ end
534
+ json_response = @jobs_interface.create(payload)
535
+ job = json_response['job'] || payload["job"] # api only recently started returning job!
536
+ render_response(json_response, options, 'job') do
537
+ # print_green_success "Job created"
538
+ print_green_success "Added job #{job['name']}"
539
+ _get(job['id'], options)
540
+ end
541
+ end
542
+
543
+ def update(args)
544
+ options = {}
545
+ params = {}
546
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
547
+ opts.banner = subcommand_usage( "[job]")
548
+ opts.on("--name NAME", String, "Updates job name") do |val|
549
+ params['name'] = val.to_s
550
+ end
551
+ opts.on('-l', '--labels [LIST]', String, "Labels") do |val|
552
+ params['labels'] = parse_labels(val)
553
+ end
554
+ opts.on('-a', '--active [on|off]', String, "Can be used to enable / disable the job. Default is on") do |val|
555
+ params['enabled'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
556
+ end
557
+ opts.on('-t', '--task [TASK]', String, "Task ID or name, assigns task to job. Only compatible with workflow job type.") do |val|
558
+ if options[:workflow]
559
+ raise_command_error "Options --task and --workflow are incompatible"
560
+ elsif options[:security_package]
561
+ raise_command_error "Options --task and --security-package are incompatible"
562
+ else
563
+ options[:task] = val
564
+ end
565
+ end
566
+ opts.on('-w', '--workflow [WORKFLOW]', String, "Workflow ID or name, assigns workflow to job. Only compatible with security scan job type.") do |val|
567
+ if options[:task]
568
+ raise_command_error "Options --workflow and --task are incompatible"
569
+ elsif options[:security_package]
570
+ raise_command_error "Options --workflow and --security-package are incompatible"
571
+ else
572
+ options[:workflow] = val
573
+ end
574
+ end
575
+ opts.on('--security-package [PACKAGE]', String, "Security Package ID or name, assigns security package to job. Only compatible with security scan job type.") do |val|
576
+ if options[:workflow]
577
+ raise_command_error "Options --security-package and --workflow are incompatible"
578
+ elsif options[:task]
579
+ raise_command_error "Options --security-package and --workflow are incompatible"
580
+ else
581
+ options[:security_package] = val
582
+ end
583
+ end
584
+ opts.on('--context-type [TYPE]', String, "Context type (instance|instance-label|server|server-label|none). Default is none") do |val|
585
+ val = val.to_s.downcase
586
+ params['targetType'] = (val == 'none' ? 'appliance' : val)
587
+ end
588
+ opts.on('--target-type [TYPE]', String, "alias for --context-type") do |val|
589
+ val = val.to_s.downcase
590
+ params['targetType'] = (val == 'none' ? 'appliance' : val)
591
+ end
592
+ opts.add_hidden_option('--target-type')
593
+ opts.on('--instances [LIST]', Array, "Context instances(s), comma separated list of instance IDs. Incompatible with --servers") do |list|
594
+ params['targetType'] = 'instance'
595
+ options[:targets] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip.to_i }.compact.uniq.collect {|it| {'refId' => it.to_i}}
596
+ end
597
+ opts.on('--instance-label LABEL', String, "Instance Label") do |val|
598
+ if params['targetType'] && params['targetType'] != 'instance-label'
599
+ raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{params['targetType']})")
600
+ end
601
+ params['targetType'] = 'instance-label'
602
+ params['instanceLabel'] = val
603
+ end
604
+ opts.on('--servers [LIST]', Array, "Context server(s), comma separated list of server IDs. Incompatible with --instances") do |list|
605
+ params['targetType'] = 'server'
606
+ options[:targets] = list.collect {|it| it.to_s.strip.empty? ? nil : it.to_s.strip.to_i }.compact.uniq.collect {|it| {'refId' => it.to_i}}
607
+ end
608
+ opts.on('--server-label LABEL', String, "Server Label") do |val|
609
+ if params['targetType'] && params['targetType'] != 'server-label'
610
+ raise ::OptionParser::InvalidOption.new("cannot be combined with another context (#{params['targetType']})")
611
+ end
612
+ params['targetType'] = 'server-label'
613
+ params['serverLabel'] = val
614
+ end
615
+ opts.on('--schedule [SCHEDULE]', String, "Job execution schedule type name or ID") do |val|
616
+ options[:schedule] = val
617
+ end
618
+ opts.on('--config [TEXT]', String, "Custom config") do |val|
619
+ params['customConfig'] = val.to_s
620
+ end
621
+ opts.on('-R', '--run [on|off]', String, "Can be used to run the job now.") do |val|
622
+ params['run'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s == '1' || val.to_s == ''
623
+ end
624
+ opts.on('--date-time DATETIME', String, "Can be used to run schedule at a specific date and time. Use UTC time in the format 2020-02-15T05:00:00Z. This sets scheduleMode to 'dateTime'.") do |val|
625
+ options[:schedule] = 'dateTime'
626
+ params['dateTime'] = val.to_s
627
+ end
628
+ build_standard_update_options(opts, options)
629
+ opts.footer = "Update job.\n" +
630
+ "[job] is required. Job ID or name"
631
+ end
632
+ optparse.parse!(args)
633
+ connect(options)
634
+ verify_args!(args:args, optparse:optparse, count:1)
635
+
636
+ job = find_by_name_or_id('job', args[0])
637
+
638
+ if job.nil?
639
+ print_red_alert "Job #{args[0]} not found"
640
+ exit 1
641
+ end
642
+
643
+ if options[:payload]
644
+ payload = parse_payload(options, 'job')
645
+ else
646
+ apply_options(params, options)
647
+
648
+ job_type_id = job['type']['id']
649
+
650
+ if !options[:task].nil?
651
+ task = find_by_name_or_id('task', options[:task])
652
+
653
+ if task.nil?
654
+ print_red_alert "Task #{options[:task]} not found"
655
+ exit 1
656
+ end
657
+ params['task'] = {'id': task['id']}
658
+ job_type_id = load_job_type_id_by_code('morpheus.task')
659
+ end
660
+
661
+ if !options[:workflow].nil?
662
+ task_set = find_by_name_or_id('task_set', options[:workflow])
663
+
664
+ if task_set.nil?
665
+ print_red_alert "Workflow #{options[:workflow]} not found"
666
+ exit 1
667
+ end
668
+ params['workflow'] = {'id': task_set['id']}
669
+ job_type_id = load_job_type_id_by_code('morpheus.workflow')
670
+ end
671
+
672
+ if !options[:targets].nil? && ['instance', 'server'].include?(params['targetType'])
673
+ params['targets'] = []
674
+ target_type = params['targetType'] || job['targetType']
675
+ options[:targets].collect do |it|
676
+ target = find_by_name_or_id(target_type, it['refId'])
677
+
678
+ if target.nil?
679
+ print_red_alert "Context #{target_type} #{it['refId']} not found"
680
+ exit 1
681
+ end
682
+ params['targets'] << it
683
+ end
684
+ end
685
+
686
+ if !options[:schedule].nil?
687
+ if options[:schedule] != 'manual' && options[:schedule].to_s.downcase != 'datetime'
688
+ job_options = @jobs_interface.options(job_type_id)
689
+ schedule = job_options['schedules'].find {|it| it['name'] == options[:schedule] || it['value'] == options[:schedule].to_i}
690
+
691
+ if schedule.nil?
692
+ print_red_alert "Schedule #{options[:schedule]} not found"
693
+ exit 1
694
+ end
695
+ options[:schedule] = schedule['value']
696
+ end
697
+ params['scheduleMode'] = options[:schedule]
698
+ end
699
+
700
+
701
+ # schedule
702
+ if !options[:schedule].nil?
703
+
704
+
705
+ if options[:schedule] == 'manual'
706
+ # cool
707
+ elsif options[:schedule].to_s.downcase == 'datetime'
708
+ # prompt for dateTime
709
+ if params['dateTime'].nil?
710
+ raise_command_error "--date-time is required for schedule '#{options[:schedule]}'\n#{optparse}"
711
+ end
712
+ elsif options[:schedule].to_s != ''
713
+ job_options = @jobs_interface.options(job_type_id)
714
+ options[:schedule] = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'schedule', 'fieldLabel' => "Schedule", 'type' => 'select', 'required' => true, 'selectOptions' => job_options['schedules'], 'defaultValue' => job_options['schedules'].first['name']}], options[:options], @api_client, {})['schedule']
715
+ params['scheduleMode'] = options[:schedule]
716
+ # ok they passed a schedule name or id
717
+ schedule = job_options['schedules'].find {|it| it['name'] == options[:schedule] || it['value'] == options[:schedule].to_i}
718
+
719
+ if schedule.nil?
720
+ print_red_alert "Schedule #{options[:schedule]} not found"
721
+ exit 1
722
+ end
723
+ options[:schedule] = schedule['value']
724
+ end
725
+ end
726
+
727
+ payload = {'job' => params}
728
+ end
729
+
730
+ if payload['job'].nil? || payload['job'].empty?
731
+ print_green_success "Nothing to update"
732
+ exit 1
733
+ end
734
+
735
+ @jobs_interface.setopts(options)
736
+ if options[:dry_run]
737
+ print_dry_run @jobs_interface.dry.update(job['id'], payload)
738
+ return
739
+ end
740
+ json_response = @jobs_interface.update(job['id'], payload)
741
+ job = json_response["job"] || job # api only recently started returning job!
742
+ render_response(json_response, options, 'job') do
743
+ print_green_success "Updated job #{job['name']}"
744
+ _get(job['id'], options)
745
+ end
746
+ end
747
+
748
+ def execute(args)
749
+ options = {}
750
+ params = {}
751
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
752
+ opts.banner = subcommand_usage( "[job]")
753
+ opts.on('--config [TEXT]', String, "Custom config") do |val|
754
+ params['customConfig'] = val.to_s
755
+ end
756
+ build_common_options(opts, options, [:json, :dry_run, :remote])
757
+ opts.footer = "Run job.\n" +
758
+ "[job] is required. Job ID or name"
759
+ end
760
+ optparse.parse!(args)
761
+ connect(options)
762
+ if args.count != 1
763
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
764
+ return 1
765
+ end
766
+
767
+ begin
768
+ job = find_by_name_or_id('job', args[0])
769
+
770
+ if job.nil?
771
+ print_red_alert "Job #{args[0]} not found"
772
+ exit 1
773
+ end
774
+
775
+ @jobs_interface.setopts(options)
776
+ if options[:dry_run]
777
+ print_dry_run @jobs_interface.dry.execute_job(job['id'], params)
778
+ return
779
+ end
780
+
781
+ json_response = @jobs_interface.execute_job(job['id'], params)
782
+
783
+ if options[:json]
784
+ puts as_json(json_response, options)
785
+ elsif !options[:quiet]
786
+ if json_response['success']
787
+ print_green_success "Job queued for execution"
788
+ _get(job['id'], options)
789
+ else
790
+ print_red_alert "Error executing job: #{json_response['msg'] || json_response['errors']}"
791
+ end
792
+ end
793
+ return 0
794
+ rescue RestClient::Exception => e
795
+ print_rest_exception(e, options)
796
+ exit 1
797
+ end
798
+ end
799
+
800
+ def remove(args)
801
+ options = {}
802
+ params = {}
803
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
804
+ opts.banner = subcommand_usage( "[job]")
805
+ build_standard_remove_options(opts, options)
806
+ opts.footer = "Remove job.\n" +
807
+ "[job] is required. Job ID or name"
808
+ end
809
+ optparse.parse!(args)
810
+ connect(options)
811
+ verify_args!(args:args, optparse:optparse, count:1)
812
+ job = find_by_name_or_id('job', args[0])
813
+ if job.nil?
814
+ print_red_alert "Job #{args[0]} not found"
815
+ exit 1
816
+ end
817
+ unless options[:yes] || ::MtnCloud::Cli::OptionTypes::confirm("Are you sure you would like to remove the job '#{job['name']}'?", options)
818
+ return 9, "aborted command"
819
+ end
820
+ @jobs_interface.setopts(options)
821
+ if options[:dry_run]
822
+ print_dry_run @jobs_interface.dry.destroy(job['id'], params)
823
+ return
824
+ end
825
+ json_response = @jobs_interface.destroy(job['id'], params)
826
+ render_response(json_response, options) do
827
+ print_green_success "Job #{job['name']} removed"
828
+ end
829
+ return 0, nil
830
+ end
831
+
832
+ def list_executions(args)
833
+ options = {}
834
+ params = {}
835
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
836
+ opts.banner = subcommand_usage("[job]")
837
+ opts.on('--job JOB', String, "Filter by Job ID or name.") do |val|
838
+ options[:job] = val
839
+ end
840
+ opts.on("--internal [true|false]", String, "Filters executions based on internal flag. Internal executions are excluded by default.") do |val|
841
+ params["internalOnly"] = (val.to_s != "false")
842
+ end
843
+ opts.on("--automation [true|false]", String, "Filters executions based on automation flag. Non-automation executions include ansible and kubernetes job types.") do |val|
844
+ params["automation"] = (val.to_s != "false")
845
+ end
846
+ build_standard_list_options(opts, options, [:details])
847
+ opts.footer = "List job executions.\n" +
848
+ "[job] is optional. Job ID or name to filter executions."
849
+
850
+ end
851
+ optparse.parse!(args)
852
+ connect(options)
853
+ # verify_args!(args:args, optparse:optparse, max:1)
854
+ if args.count > 0
855
+ options[:job] = args.join(" ")
856
+ end
857
+
858
+ params.merge!(parse_list_options(options))
859
+
860
+ if options[:job]
861
+ job = find_by_name_or_id('job', options[:job])
862
+ if job.nil?
863
+ raise_command_error "Job #{options[:job]} not found"
864
+ end
865
+ params['jobId'] = job['id']
866
+ end
867
+
868
+ @jobs_interface.setopts(options)
869
+ if options[:dry_run]
870
+ print_dry_run @jobs_interface.dry.list_executions(params)
871
+ return
872
+ end
873
+ json_response = @jobs_interface.list_executions(params)
874
+ job_executions = json_response['jobExecutions']
875
+ render_response(json_response, options, 'jobExecutions') do
876
+ title = "Job Executions"
877
+ subtitles = job ? ["Job: #{job['name']}"] : []
878
+ subtitles += parse_list_subtitles(options)
879
+ if params["internalOnly"]
880
+ subtitles << "internalOnly: #{params['internalOnly']}"
881
+ end
882
+ if !params["automation"].nil?
883
+ subtitles << "automation: #{params['automation']}"
884
+ end
885
+ print_h1 title, subtitles, options
886
+ print_job_executions(job_executions, options)
887
+ print_results_pagination(json_response) unless job_executions.size == 0
888
+ print reset,"\n"
889
+ end
890
+ return 0, nil
891
+ end
892
+
893
+ def get_execution(args)
894
+ options = {}
895
+ params = {}
896
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
897
+ opts.banner = subcommand_usage("[id]")
898
+ build_standard_get_options(opts, options, [:details])
899
+ opts.footer = "Get details about a job.\n" +
900
+ "[id] is required. Job execution ID."
901
+ end
902
+ optparse.parse!(args)
903
+ if args.count != 1
904
+ raise_command_error "wrong number of arguments, expected 1 and got (#{args.count}) #{args}\n#{optparse}"
905
+ end
906
+ connect(options)
907
+
908
+ @jobs_interface.setopts(options)
909
+ if options[:dry_run]
910
+ print_dry_run @jobs_interface.dry.get_execution(args[0], params)
911
+ return
912
+ end
913
+ json_response = @jobs_interface.get_execution(args[0], params)
914
+ render_response(json_response, options, 'jobExecution') do
915
+ print_h1 "Job Execution", [], options
916
+ print_job_execution(json_response['jobExecution'], options)
917
+ end
918
+ return 0, nil
919
+ end
920
+
921
+ def get_execution_event(args)
922
+ options = {}
923
+ params = {}
924
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
925
+ opts.banner = subcommand_usage("[id] [event]")
926
+ build_standard_get_options(opts, options)
927
+ opts.footer = "Get details about a job.\n" +
928
+ "[id] is required. Job execution ID.\n" +
929
+ "[event] is required. Process event ID."
930
+ end
931
+ optparse.parse!(args)
932
+ if args.count != 2
933
+ raise_command_error "wrong number of arguments, expected 2 and got (#{args.count}) #{args}\n#{optparse}"
934
+ end
935
+ connect(options)
936
+
937
+ begin
938
+ @jobs_interface.setopts(options)
939
+
940
+ if options[:dry_run]
941
+ print_dry_run @jobs_interface.dry.get_execution_event(args[0].to_i, args[1].to_i, params)
942
+ return
943
+ end
944
+ json_response = @jobs_interface.get_execution_event(args[0].to_i, args[1].to_i, params)
945
+
946
+ render_result = render_with_format(json_response, options, 'processEvent')
947
+ return 0 if render_result
948
+
949
+ title = "Job Execution Event"
950
+ subtitles = []
951
+ subtitles += parse_list_subtitles(options)
952
+ print_h1 title, subtitles
953
+
954
+ event = json_response['processEvent']
955
+ event_data = get_process_event_data(event)
956
+ description_cols = {
957
+ "ID" => lambda {|it| it[:id]},
958
+ "Description" => lambda {|it| it[:description]},
959
+ "Start Date" => lambda {|it| it[:start_date]},
960
+ "Created By" => lambda {|it| it[:created_by]},
961
+ "Duration" => lambda {|it| it[:duration]},
962
+ "Status" => lambda {|it| it[:status]}
963
+ }
964
+
965
+ print_description_list(description_cols, event_data)
966
+
967
+ if event_data[:output] && event_data[:output].strip.length > 0
968
+ print_h2 "Output"
969
+ print event['output']
970
+ end
971
+ if event_data[:error] && event_data[:error].strip.length > 0
972
+ print_h2 "Error"
973
+ print red
974
+ print event['message'] || event['error']
975
+ print reset
976
+ end
977
+ print reset,"\n"
978
+ return 0
979
+ rescue RestClient::Exception => e
980
+ print_rest_exception(e, options)
981
+ exit 1
982
+ end
983
+ end
984
+
985
+ private
986
+
987
+ def get_available_job_types()
988
+ job_types = @options_interface.options_for_source('jobTypes', {})['data']
989
+ # the jobType code has this ".jobType" added to the end for ui translation or something..
990
+ job_types.each do |jt|
991
+ # jt['msgCode'] = jt['code']
992
+ jt['code'] = jt['code'].sub(/\.jobType\Z/,'')
993
+ # set id for convenience
994
+ jt['id'] = jt['value'] if !jt['id'] && jt['value']
995
+ end
996
+ job_types
997
+ end
998
+ end