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,967 @@
1
+ require 'mtncloud/cli/cli_command'
2
+
3
+ class MtnCloud::Cli::ContainersCommand
4
+ include MtnCloud::Cli::CliCommand
5
+ include MtnCloud::Cli::ProvisioningHelper
6
+ include MtnCloud::Cli::LogsHelper
7
+ include MtnCloud::Cli::InfrastructureHelper
8
+
9
+ set_command_name :containers
10
+ set_command_description "View and manage containers (nodes)."
11
+ register_subcommands :get, :stop, :start, :restart, :suspend, :eject, :action, :actions, :logs,
12
+ {:exec => :execution_request}, :clone_image, :import, :attach_floating_ip, :detach_floating_ip
13
+
14
+ def connect(opts)
15
+ @api_client = establish_remote_appliance_connection(opts)
16
+ @containers_interface = @api_client.containers
17
+ @instances_interface = @api_client.instances
18
+ @provision_types_interface = @api_client.provision_types
19
+ @logs_interface = @api_client.logs
20
+ @execution_request_interface = @api_client.execution_request
21
+ @clouds_interface = @api_client.clouds
22
+ @network_server_types_interface = @api_client.network_server_types
23
+ end
24
+
25
+ def handle(args)
26
+ handle_subcommand(args)
27
+ end
28
+
29
+ def get(args)
30
+ options = {}
31
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
32
+ opts.banner = subcommand_usage("[id]")
33
+ opts.on( nil, '--actions', "Display Available Actions" ) do
34
+ options[:include_available_actions] = true
35
+ end
36
+ opts.on( nil, '--costs', "Display Cost and Price" ) do
37
+ options[:include_costs] = true
38
+ end
39
+ opts.on('--refresh [SECONDS]', String, "Refresh until status is running,failed. Default interval is #{default_refresh_interval} seconds.") do |val|
40
+ options[:refresh_until_status] ||= "running,failed"
41
+ if !val.to_s.empty?
42
+ options[:refresh_interval] = val.to_f
43
+ end
44
+ end
45
+ opts.on('--refresh-until STATUS', String, "Refresh until a specified status is reached.") do |val|
46
+ options[:refresh_until_status] = val.to_s.downcase
47
+ end
48
+ build_standard_get_options(opts, options)
49
+ opts.footer = <<-EOT
50
+ Get details about a container.
51
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
52
+ If more than one [id] is given, the command will execute for each one sequentially.
53
+
54
+ Examples:
55
+ containers get 42
56
+ containers get 1 2 3
57
+ containers get 42 --refresh
58
+ containers get 42 --refresh 10 --refresh-until stopped
59
+ EOT
60
+ end
61
+ optparse.parse!(args)
62
+ verify_args!(args:args, optparse:optparse, min:1)
63
+ connect(options)
64
+ id_list = parse_id_list(args)
65
+ validate_container_ids!(id_list)
66
+ return run_command_for_each_arg(id_list) do |arg|
67
+ _get(arg, options)
68
+ end
69
+ end
70
+
71
+ def _get(arg, options)
72
+ @containers_interface.setopts(options)
73
+ if options[:dry_run]
74
+ print_dry_run @containers_interface.dry.get(arg.to_i)
75
+ return
76
+ end
77
+ #container = find_container_by_id(arg)
78
+ #return 1 if container.nil?
79
+ json_response = @containers_interface.get(arg.to_i)
80
+ container = json_response['container']
81
+ render_response(json_response, options, "container") do
82
+ # stats = json_response['stats'] || {}
83
+ stats = container['stats'] || {}
84
+
85
+ # load_balancers = stats = json_response['loadBalancers'] || {}
86
+
87
+ # todo: show as 'VM' instead of 'Container' maybe..err
88
+ # may need to fetch instance by id too..
89
+ # ${[null,'docker'].contains(instance?.layout?.provisionType?.code) ? 'CONTAINERS' : 'VMs'}
90
+
91
+ print_h1 "Container Details"
92
+ print cyan
93
+ description_cols = {
94
+ "ID" => 'id',
95
+ #"Name" => 'name',
96
+ "Name" => lambda {|it| it['server'] ? it['server']['name'] : '(no server)' }, # there is a server.displayName too?
97
+ "Type" => lambda {|it| it['containerType'] ? it['containerType']['name'] : '' },
98
+ "Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
99
+ # "Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
100
+ # "Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
101
+ "Instance" => lambda {|it| it['instance'] ? it['instance']['name'] : '' },
102
+ "Host" => lambda {|it| it['server'] ? it['server']['name'] : '' },
103
+ "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
104
+ "Location" => lambda {|it| format_container_connection_string(it) },
105
+ # "Description" => 'description',
106
+ # "Group" => lambda {|it| it['group'] ? it['group']['name'] : '' },
107
+ # "Cloud" => lambda {|it| it['cloud'] ? it['cloud']['name'] : '' },
108
+ # "Type" => lambda {|it| it['instanceType']['name'] },
109
+ # "Plan" => lambda {|it| it['plan'] ? it['plan']['name'] : '' },
110
+ # "Environment" => 'instanceContext',
111
+ # "Nodes" => lambda {|it| it['containers'] ? it['containers'].count : 0 },
112
+ # "Connection" => lambda {|it| format_container_connection_string(it) },
113
+ #"Account" => lambda {|it| it['account'] ? it['account']['name'] : '' },
114
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
115
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
116
+ "Status" => lambda {|it| format_container_status(it) }
117
+ }
118
+ print_description_list(description_cols, container)
119
+
120
+ if (stats)
121
+ print_h2 "Container Usage"
122
+ print_stats_usage(stats)
123
+ end
124
+
125
+ if options[:include_available_actions]
126
+ if (container["availableActions"])
127
+ print_h2 "Available Actions"
128
+ print as_pretty_table(container["availableActions"], [:name, :code])
129
+ print reset, "\n"
130
+ else
131
+ print "#{yellow}No available actions#{reset}\n\n"
132
+ end
133
+ end
134
+
135
+ if options[:include_costs]
136
+ print_h2 "Container Cost"
137
+ cost_columns = {
138
+ "Cost" => lambda {|it| it['hourlyCost'] ? format_money(it['hourlyCost'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
139
+ "Price" => lambda {|it| it['hourlyPrice'] ? format_money(it['hourlyPrice'], (it['currency'] || 'USD'), {sigdig:15}).to_s + ' per hour' : '' },
140
+ }
141
+ print_description_list(cost_columns, container)
142
+ end
143
+ print reset, "\n"
144
+ end
145
+ # refresh until a status is reached
146
+ if options[:refresh_until_status]
147
+ if options[:refresh_interval].nil? || options[:refresh_interval].to_f < 0
148
+ options[:refresh_interval] = default_refresh_interval
149
+ end
150
+ statuses = options[:refresh_until_status].to_s.downcase.split(",").collect {|s| s.strip }.select {|s| !s.to_s.empty? }
151
+ if !statuses.include?(container['status'])
152
+ print cyan
153
+ print cyan, "Refreshing in #{options[:refresh_interval] > 1 ? options[:refresh_interval].to_i : options[:refresh_interval]} seconds"
154
+ sleep_with_dots(options[:refresh_interval])
155
+ print "\n"
156
+ _get(arg, options)
157
+ end
158
+ end
159
+ return 0, nil
160
+ end
161
+
162
+
163
+ def stop(args)
164
+ options = {}
165
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
166
+ opts.banner = subcommand_usage("[id]")
167
+ build_standard_update_options(opts, options, [:auto_confirm])
168
+ opts.footer = <<-EOT
169
+ Stop a container.
170
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
171
+ If more than one [id] is given, the command will execute for each one sequentially.
172
+
173
+ Examples:
174
+ containers stop 42
175
+ containers stop 1 2 3 -y
176
+ EOT
177
+ end
178
+ optparse.parse!(args)
179
+ verify_args!(args:args, optparse:optparse, min:1)
180
+ connect(options)
181
+ id_list = parse_id_list(args)
182
+ validate_container_ids!(id_list)
183
+ confirm!("Are you sure you would like to stop #{id_list.size == 1 ? 'container' : 'containers'} #{anded_list(id_list)}?", options)
184
+ return run_command_for_each_arg(id_list) do |arg|
185
+ _stop(arg, options)
186
+ end
187
+ end
188
+
189
+ def _stop(container_id, options)
190
+ container = find_container_by_id(container_id) # could skip this since only id is supported
191
+ return 1 if container.nil?
192
+ @containers_interface.setopts(options)
193
+ if options[:dry_run]
194
+ print_dry_run @containers_interface.dry.stop(container['id'])
195
+ return 0
196
+ end
197
+ json_response = @containers_interface.stop(container['id'])
198
+ render_response(json_response, options) do
199
+ print green, "Stopping container #{container['id']}", reset, "\n"
200
+ end
201
+ return 0, nil
202
+ end
203
+
204
+ def start(args)
205
+ options = {}
206
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
207
+ opts.banner = subcommand_usage("[id]")
208
+ build_standard_update_options(opts, options, [:auto_confirm])
209
+ opts.footer = <<-EOT
210
+ Start a container.
211
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
212
+ If more than one [id] is given, the command will execute for each one sequentially.
213
+
214
+ Examples:
215
+ containers start 42
216
+ containers start 1 2 3 -y
217
+ EOT
218
+ end
219
+ optparse.parse!(args)
220
+ verify_args!(args:args, optparse:optparse, min:1)
221
+ connect(options)
222
+ id_list = parse_id_list(args)
223
+ validate_container_ids!(id_list)
224
+ confirm!("Are you sure you would like to start #{id_list.size == 1 ? 'container' : 'containers'} #{anded_list(id_list)}?", options)
225
+ return run_command_for_each_arg(id_list) do |arg|
226
+ _start(arg, options)
227
+ end
228
+ end
229
+
230
+ def _start(container_id, options)
231
+ container = find_container_by_id(container_id) # could skip this since only id is supported
232
+ return 1 if container.nil?
233
+ @containers_interface.setopts(options)
234
+ if options[:dry_run]
235
+ print_dry_run @containers_interface.dry.start(container['id'])
236
+ return 0
237
+ end
238
+ json_response = @containers_interface.start(container['id'])
239
+ render_response(json_response, options) do
240
+ print green, "Starting container #{container['id']}", reset, "\n"
241
+ end
242
+ return 0, nil
243
+ end
244
+
245
+ def restart(args)
246
+ options = {}
247
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
248
+ opts.banner = subcommand_usage("[id]")
249
+ build_standard_update_options(opts, options, [:auto_confirm])
250
+ opts.footer = <<-EOT
251
+ Restart a container.
252
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
253
+ If more than one [id] is given, the command will execute for each one sequentially.
254
+
255
+ Examples:
256
+ containers restart 42
257
+ containers restart 1 2 3 -y
258
+ EOT
259
+ end
260
+ optparse.parse!(args)
261
+ verify_args!(args:args, optparse:optparse, min:1)
262
+ connect(options)
263
+ id_list = parse_id_list(args)
264
+ validate_container_ids!(id_list)
265
+ confirm!("Are you sure you would like to restart #{id_list.size == 1 ? 'container' : 'containers'} #{anded_list(id_list)}?", options)
266
+ return run_command_for_each_arg(id_list) do |arg|
267
+ _restart(arg, options)
268
+ end
269
+ end
270
+
271
+ def _restart(container_id, options)
272
+ container = find_container_by_id(container_id) # could skip this since only id is supported
273
+ return 1 if container.nil?
274
+ @containers_interface.setopts(options)
275
+ if options[:dry_run]
276
+ print_dry_run @containers_interface.dry.restart(container['id'])
277
+ return 0
278
+ end
279
+ json_response = @containers_interface.restart(container['id'])
280
+ render_response(json_response, options) do
281
+ print green, "Restarting container #{container['id']}", reset, "\n"
282
+ end
283
+ return 0, nil
284
+ end
285
+
286
+ def suspend(args)
287
+ options = {}
288
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
289
+ opts.banner = subcommand_usage("[id]")
290
+ build_standard_update_options(opts, options, [:auto_confirm])
291
+ opts.footer = <<-EOT
292
+ Suspend a container.
293
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
294
+ If more than one [id] is given, the command will execute for each one sequentially.
295
+
296
+ Examples:
297
+ containers suspend 42
298
+ containers suspend 1 2 3 -y
299
+ EOT
300
+ end
301
+ optparse.parse!(args)
302
+ verify_args!(args:args, optparse:optparse, min:1)
303
+ connect(options)
304
+ id_list = parse_id_list(args)
305
+ validate_container_ids!(id_list)
306
+ confirm!("Are you sure you would like to suspend #{id_list.size == 1 ? 'container' : 'containers'} #{anded_list(id_list)}?", options)
307
+ return run_command_for_each_arg(id_list) do |arg|
308
+ _suspend(arg, options)
309
+ end
310
+ end
311
+
312
+ def _suspend(container_id, options)
313
+ container = find_container_by_id(container_id) # could skip this since only id is supported
314
+ return 1 if container.nil?
315
+ @containers_interface.setopts(options)
316
+ if options[:dry_run]
317
+ print_dry_run @containers_interface.dry.suspend(container['id'])
318
+ return 0
319
+ end
320
+ json_response = @containers_interface.suspend(container['id'])
321
+ render_response(json_response, options) do
322
+ print green, "Suspending container #{container['id']}", reset, "\n"
323
+ end
324
+ return 0, nil
325
+ end
326
+
327
+ def eject(args)
328
+ options = {}
329
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
330
+ opts.banner = subcommand_usage("[id]")
331
+ build_standard_update_options(opts, options, [:auto_confirm])
332
+ opts.footer = <<-EOT
333
+ Eject a container.
334
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
335
+ If more than one [id] is given, the command will execute for each one sequentially.
336
+
337
+ Examples:
338
+ containers eject 42
339
+ containers eject 1 2 3 -y
340
+ EOT
341
+ end
342
+ optparse.parse!(args)
343
+ verify_args!(args:args, optparse:optparse, min:1)
344
+ connect(options)
345
+ id_list = parse_id_list(args)
346
+ validate_container_ids!(id_list)
347
+ confirm!("Are you sure you would like to eject #{id_list.size == 1 ? 'container' : 'containers'} #{anded_list(id_list)}?", options)
348
+ return run_command_for_each_arg(id_list) do |arg|
349
+ _eject(arg, options)
350
+ end
351
+ end
352
+
353
+ def _eject(container_id, options)
354
+ container = find_container_by_id(container_id) # could skip this since only id is supported
355
+ return 1 if container.nil?
356
+ @containers_interface.setopts(options)
357
+ if options[:dry_run]
358
+ print_dry_run @containers_interface.dry.eject(container['id'])
359
+ return 0
360
+ end
361
+ json_response = @containers_interface.eject(container['id'])
362
+ render_response(json_response, options) do
363
+ print green, "Ejecting container #{container['id']}", reset, "\n"
364
+ end
365
+ return 0, nil
366
+ end
367
+
368
+ def actions(args)
369
+ options = {}
370
+ optparse = MtnCloud::Cli::OptionParser.new do|opts|
371
+ opts.banner = subcommand_usage("[id]")
372
+ build_standard_get_options(opts, options)
373
+ opts.footer = <<-EOT
374
+ List the actions available to specified container(s).
375
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
376
+
377
+ Examples:
378
+ containers actions 42
379
+ containers actions 1 2 3
380
+ EOT
381
+ end
382
+ optparse.parse!(args)
383
+ verify_args!(args:args, optparse:optparse, min:1)
384
+ connect(options)
385
+ id_list = parse_id_list(args)
386
+ validate_container_ids!(id_list)
387
+ containers = []
388
+ id_list.each do |container_id|
389
+ container = find_container_by_id(container_id)
390
+ if container.nil?
391
+ # return 1
392
+ else
393
+ containers << container
394
+ end
395
+ end
396
+ if containers.size != id_list.size
397
+ #puts_error "containers not found"
398
+ return 1
399
+ end
400
+ container_ids = containers.collect {|container| container["id"] }
401
+ # container = find_container_by_name_or_id(args[0])
402
+ @containers_interface.setopts(options)
403
+ if options[:dry_run]
404
+ print_dry_run @containers_interface.dry.available_actions(container_ids.size == 1 ? container_ids[0] : container_ids)
405
+ return 0
406
+ end
407
+ json_response = @containers_interface.available_actions(container_ids.size == 1 ? container_ids[0] : container_ids)
408
+ render_response(json_response, options) do
409
+ title = "Container Actions: #{anded_list(id_list)}"
410
+ print_h1 title
411
+ available_actions = json_response["actions"]
412
+ if (available_actions && available_actions.size > 0)
413
+ print as_pretty_table(available_actions, [:name, :code])
414
+ print reset, "\n"
415
+ else
416
+ if container_ids.size > 1
417
+ print "#{yellow}The specified containers have no available actions in common.#{reset}\n\n"
418
+ else
419
+ print "#{yellow}No available actions#{reset}\n\n"
420
+ end
421
+ end
422
+ end
423
+ return 0, nil
424
+ end
425
+
426
+ def action(args)
427
+ options = {}
428
+ action_id = nil
429
+ optparse = MtnCloud::Cli::OptionParser.new do|opts|
430
+ opts.banner = subcommand_usage("[id] -a CODE")
431
+ opts.on('-a', '--action CODE', "Container Action CODE to execute") do |val|
432
+ action_id = val.to_s
433
+ end
434
+ build_standard_update_options(opts, options, [:auto_confirm])
435
+ opts.footer = <<-EOT
436
+ Execute an action for a container or containers
437
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
438
+
439
+ Examples:
440
+ containers action 42 -a docker-remove-node
441
+ EOT
442
+ end
443
+ optparse.parse!(args)
444
+ verify_args!(args:args, optparse:optparse, min:1)
445
+ connect(options)
446
+ id_list = parse_id_list(args)
447
+ validate_container_ids!(id_list)
448
+ containers = []
449
+ id_list.each do |container_id|
450
+ container = find_container_by_id(container_id)
451
+ if container.nil?
452
+ # return 1
453
+ else
454
+ containers << container
455
+ end
456
+ end
457
+ if containers.size != id_list.size
458
+ #puts_error "containers not found"
459
+ return 1
460
+ end
461
+ container_ids = containers.collect {|container| container["id"] }
462
+
463
+ # figure out what action to run
464
+ # assume that the action is available for all the containers..
465
+ available_actions = containers.first['availableActions']
466
+ if available_actions.empty?
467
+ print_red_alert "Container #{container['id']} has no available actions"
468
+ if container_ids.size > 1
469
+ print_red_alert "The specified containers have no available actions in common"
470
+ else
471
+ print_red_alert "The specified container has no available actions"
472
+ end
473
+ return 1
474
+ end
475
+ container_action = nil
476
+ if action_id.nil?
477
+ available_actions_dropdown = available_actions.collect {|act| {'name' => act["name"], 'value' => act["code"]} } # already sorted
478
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'code', 'type' => 'select', 'fieldLabel' => 'Container Action', 'selectOptions' => available_actions_dropdown, 'required' => true, 'description' => 'Choose the container action to execute'}], options[:options])
479
+ action_id = v_prompt['code']
480
+ container_action = available_actions.find {|act| act['code'].to_s == action_id.to_s }
481
+ else
482
+ container_action = available_actions.find {|act| act['code'].to_s == action_id.to_s || act['name'].to_s.downcase == action_id.to_s.downcase }
483
+ action_id = container_action["code"] if container_action
484
+ end
485
+ if !container_action
486
+ # for testing bogus actions..
487
+ # container_action = {"id" => action_id, "name" => "Unknown"}
488
+ raise_command_error "Container Action '#{action_id}' not found."
489
+ end
490
+
491
+ action_display_name = "#{container_action['name']} [#{container_action['code']}]"
492
+ confirm!("Are you sure you would like to perform action #{action_display_name} on #{id_list.size == 1 ? 'container' : 'containers'} #{anded_list(id_list)}?", options)
493
+
494
+ # return run_command_for_each_arg(containers) do |arg|
495
+ # _action(arg, action_id, options)
496
+ # end
497
+ @containers_interface.setopts(options)
498
+ if options[:dry_run]
499
+ print_dry_run @containers_interface.dry.action(container_ids.size == 1 ? container_ids[0] : container_ids, action_id)
500
+ return 0
501
+ end
502
+ json_response = @containers_interface.action(container_ids.size == 1 ? container_ids[0] : container_ids, action_id)
503
+ render_response(json_response, options) do
504
+ print green, "Action #{action_display_name} performed on #{id_list.size == 1 ? 'container' : 'containers'} #{anded_list(id_list)}", reset, "\n"
505
+ end
506
+ return 0, nil
507
+ end
508
+
509
+ def logs(args)
510
+ options = {}
511
+ params = {}
512
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
513
+ opts.banner = subcommand_usage("[id]")
514
+ opts.on('--start TIMESTAMP','--start TIMESTAMP', "Start timestamp. Default is 30 days ago.") do |val|
515
+ options[:start] = parse_time(val) #.utc.iso8601
516
+ end
517
+ opts.on('--end TIMESTAMP','--end TIMESTAMP', "End timestamp. Default is now.") do |val|
518
+ options[:end] = parse_time(val) #.utc.iso8601
519
+ end
520
+ opts.on('--level VALUE', String, "Log Level. DEBUG,INFO,WARN,ERROR") do |val|
521
+ params['level'] = params['level'] ? [params['level'], val].flatten : [val]
522
+ end
523
+ opts.on('--table', '--table', "Format ouput as a table.") do
524
+ options[:table] = true
525
+ end
526
+ opts.on('-a', '--all', "Display all details: entire message." ) do
527
+ options[:details] = true
528
+ end
529
+ build_standard_list_options(opts, options)
530
+ opts.footer = <<-EOT
531
+ List logs for a container.
532
+ [id] is required. This is the id of a container. Supports multiple [id] arguments.
533
+
534
+ Examples:
535
+ containers logs 42 --level ERROR
536
+ EOT
537
+ end
538
+ optparse.parse!(args)
539
+ verify_args!(args:args, optparse:optparse, min:1)
540
+ connect(options)
541
+ id_list = parse_id_list(args)
542
+ validate_container_ids!(id_list)
543
+
544
+ containers = id_list # heh
545
+ params['level'] = params['level'].collect {|it| it.to_s.upcase }.join('|') if params['level'] # api works with INFO|WARN
546
+ params.merge!(parse_list_options(options))
547
+ params['query'] = params.delete('phrase') if params['phrase']
548
+ params[:order] = params[:direction] unless params[:direction].nil? # old api version expects order instead of direction
549
+ params['startMs'] = (options[:start].to_i * 1000) if options[:start]
550
+ params['endMs'] = (options[:end].to_i * 1000) if options[:end]
551
+ @logs_interface.setopts(options)
552
+ if options[:dry_run]
553
+ print_dry_run @logs_interface.dry.container_logs(containers, params)
554
+ return
555
+ end
556
+ json_response = @logs_interface.container_logs(containers, params)
557
+ render_response(json_response, options, "logs") do
558
+ logs = json_response
559
+ title = "Container Logs: #{containers.join(', ')}"
560
+ subtitles = parse_list_subtitles(options)
561
+ if options[:start]
562
+ subtitles << "Start: #{options[:start]}".strip
563
+ end
564
+ if options[:end]
565
+ subtitles << "End: #{options[:end]}".strip
566
+ end
567
+ if params[:query]
568
+ subtitles << "Search: #{params[:query]}".strip
569
+ end
570
+ if params['level']
571
+ subtitles << "Level: #{params['level']}"
572
+ end
573
+ logs = json_response['data'] || json_response['logs']
574
+ print_h1 title, subtitles, options
575
+ if logs.empty?
576
+ print "#{cyan}No logs found.#{reset}\n"
577
+ else
578
+ print format_log_records(logs, options)
579
+ print_results_pagination({'meta'=>{'total'=>(json_response['total']['value'] rescue json_response['total']),'size'=>logs.size,'max'=>(json_response['max'] || options[:max]),'offset'=>(json_response['offset'] || options[:offset] || 0)}})
580
+ end
581
+ print reset,"\n"
582
+ end
583
+ return 0, nil
584
+ end
585
+
586
+ def execution_request(args)
587
+ options = {}
588
+ params = {}
589
+ script_content = nil
590
+ do_refresh = true
591
+ optparse = MtnCloud::Cli::OptionParser.new do|opts|
592
+ opts.banner = subcommand_usage("[id] [options]")
593
+ opts.on('--script SCRIPT', "Script to be executed" ) do |val|
594
+ script_content = val
595
+ end
596
+ opts.on('--file FILE', "File containing the script. This can be used instead of --script" ) do |filename|
597
+ full_filename = File.expand_path(filename)
598
+ if File.exist?(full_filename)
599
+ script_content = File.read(full_filename)
600
+ else
601
+ print_red_alert "File not found: #{full_filename}"
602
+ exit 1
603
+ end
604
+ end
605
+ opts.on(nil, '--no-refresh', "Do not refresh until finished" ) do
606
+ do_refresh = false
607
+ end
608
+ #build_option_type_options(opts, options, add_user_source_option_types())
609
+ build_standard_update_options(opts, options)
610
+ opts.footer = <<-EOT
611
+ Execute an arbitrary command or script on a container.
612
+ [id] is required. This is the id of a container.
613
+ [script] is required and can be passed as --script of --file instead. This is the script that is to be executed.
614
+
615
+ Examples:
616
+ containers exec 42 "uname -a"
617
+ EOT
618
+ end
619
+ optparse.parse!(args)
620
+ connect(options)
621
+ verify_args!(args:args, optparse:optparse, count:1)
622
+
623
+
624
+ container = find_container_by_id(args[0])
625
+ return 1 if container.nil?
626
+ params['containerId'] = container['id']
627
+ # construct payload
628
+ payload = {}
629
+ if options[:payload]
630
+ payload = options[:payload]
631
+ else
632
+ payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
633
+ # prompt for Script
634
+ if script_content.nil?
635
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'script', 'type' => 'code-editor', 'fieldLabel' => 'Script', 'required' => true, 'description' => 'The script content'}], options[:options])
636
+ script_content = v_prompt['script']
637
+ end
638
+ payload['script'] = script_content
639
+ end
640
+ @execution_request_interface.setopts(options)
641
+ if options[:dry_run]
642
+ print_dry_run @execution_request_interface.dry.create(params, payload)
643
+ return 0
644
+ end
645
+ # do it
646
+ json_response = @execution_request_interface.create(params, payload)
647
+ # print and return result
648
+ render_response(json_response, options) do
649
+ execution_request = json_response['executionRequest']
650
+ print_green_success "Executing request #{execution_request['uniqueId']}"
651
+ if do_refresh
652
+ MtnCloud::Cli::ExecutionRequestCommand.new.handle(["get", execution_request['uniqueId'], "--refresh"]+ (options[:remote] ? ["-r",options[:remote]] : []))
653
+ else
654
+ MtnCloud::Cli::ExecutionRequestCommand.new.handle(["get", execution_request['uniqueId']]+ (options[:remote] ? ["-r",options[:remote]] : []))
655
+ end
656
+ end
657
+ return 0, nil
658
+ end
659
+
660
+ def import(args)
661
+ options = {}
662
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
663
+ opts.banner = subcommand_usage("[id] [image]")
664
+ opts.on( '--storage-provider VALUE', String, "Optional storage provider to use" ) do |val|
665
+ options[:options]['storageProviderId'] = val
666
+ end
667
+ build_standard_update_options(opts, options, [:auto_confirm])
668
+ opts.footer = <<-EOT
669
+ Import image template for a container.
670
+ [id] is required. This is the id of a container.
671
+ EOT
672
+ end
673
+ optparse.parse!(args)
674
+ verify_args!(args:args, optparse:optparse, count:1)
675
+ connect(options)
676
+ container = find_container_by_id(args[0])
677
+ return 1 if container.nil?
678
+ instance = find_instance_by_name_or_id(container['instance']['id'])
679
+ return 1 if instance.nil?
680
+ # need to GET provision type for exportServer == true
681
+ provision_type = load_container_provision_type(container, instance)
682
+ # todo: add this exportServer to the api too obviously (oh it is there.. but clone-image is not)
683
+ # if provision_type['exportServer'] != true
684
+ # raise_command_error "import is not supported by provision type #{provision_type['name']}"
685
+ # end
686
+ payload = parse_payload(options)
687
+ if payload.nil?
688
+ payload = parse_passed_options(options)
689
+ container_import_option_types = [
690
+ {'fieldName' => 'storageProviderId', 'type' => 'select', 'fieldLabel' => 'Storage Provider', 'optionSource' => 'storageProviders', 'required' => false, 'description' => 'Select Storage Provider.'}
691
+ ]
692
+ payload.deep_merge! MtnCloud::Cli::OptionTypes.prompt(container_import_option_types, options[:options], @api_client, {})
693
+ end
694
+ confirm!("Are you sure you would like to import container #{container['id']}?", options)
695
+ @containers_interface.setopts(options)
696
+ if options[:dry_run]
697
+ print_dry_run @containers_interface.dry.import(container['id'], payload)
698
+ return
699
+ end
700
+ json_response = @containers_interface.import(container['id'], payload)
701
+ render_response(json_response, options) do
702
+ print_green_success "Import initiated for container #{container['id']}"
703
+ end
704
+ return 0, nil
705
+ end
706
+
707
+ def clone_image(args)
708
+ options = {}
709
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
710
+ opts.banner = subcommand_usage("[id]")
711
+ opts.on( '--name VALUE', String, "Image Name (Template Name). Default is server name + timestamp" ) do |val|
712
+ options[:options]['templateName'] = val
713
+ end
714
+ opts.on( '--folder VALUE', String, "Folder externalId or '/' to use the root folder" ) do |val|
715
+ options[:options]['zoneFolder'] = val
716
+ end
717
+ build_standard_update_options(opts, options, [:auto_confirm])
718
+ opts.footer = <<-EOT
719
+ Clone to image (template) for a container.
720
+ [id] is required. This is the id of a container.
721
+ EOT
722
+ end
723
+ optparse.parse!(args)
724
+ verify_args!(args:args, optparse:optparse, count:1)
725
+ connect(options)
726
+ container = find_container_by_id(args[0])
727
+ return 1 if container.nil?
728
+ # need to GET provision type for hasFolders == true and cloneTemplte == true
729
+ instance = find_instance_by_name_or_id(container['instance']['id'])
730
+ return 1 if instance.nil?
731
+ provision_type = load_container_provision_type(container, instance)
732
+ # todo: add this cloneTemplate check to the api too obviously
733
+ # if provision_type['cloneTemplate'] != true
734
+ # raise_command_error "clone-image is not supported by provision type #{provision_type['name']}"
735
+ # end
736
+ payload = parse_payload(options)
737
+ if payload.nil?
738
+ payload = parse_passed_options(options)
739
+ if payload['templateName'].nil?
740
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'templateName', 'type' => 'text', 'fieldLabel' => 'Image Name', 'description' => 'Choose a name for the new image template. Default is the server name + timestamp'}], options[:options])
741
+ if v_prompt['templateName'].to_s != ''
742
+ payload['templateName'] = v_prompt['templateName']
743
+ end
744
+ end
745
+ #if provision_type['code'] == 'vmware'
746
+ if provision_type && provision_type["hasFolders"]
747
+ if payload['zoneFolder'].nil?
748
+ # vmwareFolders moved from /api/options/vmwareFolders to /api/options/vmware/vmwareFolders
749
+ folder_prompt = nil
750
+ begin
751
+ folder_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'zoneFolder', 'type' => 'select', 'optionSource' => 'vmwareFolders', 'optionSourceType' => 'vmware', 'fieldLabel' => 'Folder', 'description' => "Folder externalId or '/' to use the root folder", 'required' => true}], options[:options], @api_client, {siteId: instance['group']['id'], zoneId: instance['cloud']['id']})
752
+ rescue RestClient::Exception => e
753
+ MtnCloud::Logging::DarkPrinter.puts "Failed to load folder options" if MtnCloud::Logging.debug?
754
+ begin
755
+ folder_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'zoneFolder', 'type' => 'select', 'optionSource' => 'vmwareFolders', 'fieldLabel' => 'Folder', 'description' => "Folder externalId or '/' to use the root folder", 'required' => true}], options[:options], @api_client, {siteId: instance['group']['id'], zoneId: instance['cloud']['id']})
756
+ rescue RestClient::Exception => e2
757
+ MtnCloud::Logging::DarkPrinter.puts "Failed to load folder options from alternative endpoint too" if MtnCloud::Logging.debug?
758
+ end
759
+ end
760
+ if folder_prompt && folder_prompt['zoneFolder'].to_s != ''
761
+ payload['zoneFolder'] = folder_prompt['zoneFolder']
762
+ end
763
+ end
764
+ end
765
+ end
766
+ confirm!("Are you sure you would like to clone as image container #{container['id']}?", options)
767
+ @containers_interface.setopts(options)
768
+ if options[:dry_run]
769
+ print_dry_run @containers_interface.dry.clone_image(container['id'], payload)
770
+ return
771
+ end
772
+ json_response = @containers_interface.clone_image(container['id'], payload)
773
+ render_response(json_response, options) do
774
+ print_green_success "Clone Image initiated for container #{container['id']}"
775
+ end
776
+ return 0, nil
777
+ end
778
+
779
+ def attach_floating_ip(args)
780
+ options = {}
781
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
782
+ opts.banner = subcommand_usage("[id]")
783
+ opts.on('--ip ID', String, "Floating IP Address, in the format 'ip-ID'.") do |val|
784
+ options[:ip] = val
785
+ end
786
+ opts.on('--pool ID', String, "Floating IP Pool Identifier, in the format 'pool-ID'.") do |val|
787
+ options[:pool] = val
788
+ end
789
+ opts.on('--bandwidth VALUE', String, "Floating IP Bandidth (Mbit/s). Only cloud types Huawei and OpenTelekom support this option.") do |val|
790
+ options[:bandwidth] = val
791
+ end
792
+ build_standard_update_options(opts, options, [:auto_confirm])
793
+ opts.footer = <<-EOT
794
+ Attach a floating IP to a container.
795
+ [id] is required. This is the id of a container.
796
+ Only the following cloud types support this command: OpenStack, Huawei and OpenTelekom
797
+ EOT
798
+ end
799
+ optparse.parse!(args)
800
+ verify_args!(args:args, optparse:optparse, count:1)
801
+ connect(options)
802
+ container = find_container_by_id(args[0])
803
+ return 1 if container.nil?
804
+ network_server_type = load_container_network_server_type(container)
805
+ if !network_server_type['hasFloatingIps']
806
+ raise_command_error "Network Server Type #{network_server_type['name']} does support floating IPs."
807
+ end
808
+ payload = parse_payload(options)
809
+ if payload.nil?
810
+ payload = parse_passed_options(options)
811
+ attach_floating_ip_option_types = network_server_type['floatingIpTypes']
812
+ if attach_floating_ip_option_types && !attach_floating_ip_option_types.empty?
813
+ if options[:ip]
814
+ floating_ip = options[:ip].to_s.sub(/\Aip\-/i, '')
815
+ floating_ip = (floating_ip =~ /\A\d{1,}\Z/) ? "ip-#{floating_ip.to_s}" : floating_ip
816
+ options[:options]['config'] ||= {}
817
+ options[:options]['config']['osExternalNetworkId'] = floating_ip
818
+ elsif options[:pool]
819
+ floating_ip = options[:pool].to_s.sub(/\Apool\-/i, '')
820
+ floating_ip = (floating_ip =~ /\A\d{1,}\Z/) ? "pool-#{floating_ip.to_s}" : floating_ip
821
+ options[:options]['config'] ||= {}
822
+ options[:options]['config']['osExternalNetworkId'] = floating_ip
823
+ end
824
+ if options[:bandwidth]
825
+ options[:options]['config'] ||= {}
826
+ options[:options]['config']['floatingIpBandwidth'] = options[:bandwidth].to_i
827
+ end
828
+ #api_params = {zoneId: container['cloud'] ? container['cloud']['id'] : nil, resourcePoolId: container['resourcePool'] ? container['resourcePool']['id'] : nil}
829
+ api_params = {containerId: container['id']}
830
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt(attach_floating_ip_option_types, options[:options], @api_client, api_params)
831
+ # payload.deep_merge!({'container' => v_prompt})
832
+ payload.deep_merge!(v_prompt)
833
+ else
834
+ # raise_command_error "Network Server Type #{network_server_type['name']} does not defined any floating IP inputs."
835
+ end
836
+ end
837
+ confirm!("Are you sure you would like to attach this floating IP to container #{container['id']}?", options)
838
+ @containers_interface.setopts(options)
839
+ if options[:dry_run]
840
+ print_dry_run @containers_interface.dry.attach_floating_ip(container['id'], payload)
841
+ return
842
+ end
843
+ json_response = @containers_interface.attach_floating_ip(container['id'], payload)
844
+ render_response(json_response, options) do
845
+ print_green_success "Attaching floating IP to container #{container['id']}"
846
+ end
847
+ return 0, nil
848
+ end
849
+
850
+ def detach_floating_ip(args)
851
+ options = {}
852
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
853
+ opts.banner = subcommand_usage("[id]")
854
+ build_standard_update_options(opts, options, [:auto_confirm])
855
+ opts.footer = <<-EOT
856
+ Detach a floating IP from a container.
857
+ [id] is required. This is the id of a container.
858
+ Only the following cloud types support this command: OpenStack, Huawei and OpenTelekom
859
+ EOT
860
+ end
861
+ optparse.parse!(args)
862
+ verify_args!(args:args, optparse:optparse, count:1)
863
+ connect(options)
864
+ container = find_container_by_id(args[0])
865
+ return 1 if container.nil?
866
+ network_server_type = load_container_network_server_type(container)
867
+ if !network_server_type['hasFloatingIps']
868
+ raise_command_error "Network Type #{network_server_type['name']} does support floating IPs."
869
+ end
870
+ payload = parse_payload(options)
871
+ if payload.nil?
872
+ payload = parse_passed_options(options)
873
+ # prompt
874
+ end
875
+ confirm!("Are you sure you would like to detach the floating IP from container #{container['id']}?", options)
876
+ @containers_interface.setopts(options)
877
+ if options[:dry_run]
878
+ print_dry_run @containers_interface.dry.detach_floating_ip(container['id'], payload)
879
+ return
880
+ end
881
+ json_response = @containers_interface.detach_floating_ip(container['id'], payload)
882
+ render_response(json_response, options) do
883
+ print_green_success "Detaching floating IP from container #{container['id']}"
884
+ end
885
+ return 0, nil
886
+ end
887
+
888
+ private
889
+
890
+ def find_container_by_id(id)
891
+ begin
892
+ json_response = @containers_interface.get(id.to_i)
893
+ return json_response['container']
894
+ rescue RestClient::Exception => e
895
+ if e.response && e.response.code == 404
896
+ print_red_alert "Container not found by id #{id}"
897
+ return nil
898
+ else
899
+ raise e
900
+ end
901
+ end
902
+ end
903
+
904
+ def validate_container_ids!(id_list)
905
+ id_list.each { |id| validate_container_id!(id) }
906
+ end
907
+
908
+ def validate_container_id!(id)
909
+ if id.to_s =~ /\A\d{1,}\Z/
910
+ true
911
+ else
912
+ raise_command_error "[id] argument is invalid, expected a number and got '#{id}'" #, args, optparse
913
+ end
914
+ end
915
+
916
+ def load_container_provision_type(container, instance=nil)
917
+ if instance.nil?
918
+ instance = find_instance_by_name_or_id(container['instance']['id'])
919
+ return 1 if instance.nil?
920
+ end
921
+ # todo: should be returned by containers api too, get from instance for old api versions
922
+ provision_type_code = container['containerType']['provisionTypeCode'] rescue nil
923
+ provision_type_code = provision_type_code || container['provisionType']['code'] rescue nil
924
+ if provision_type_code.nil?
925
+ return load_instance_provision_type(instance)
926
+ end
927
+ provision_type = nil
928
+ if provision_type_code
929
+ provision_type = provision_types_interface.list({code:provision_type_code})['provisionTypes'][0]
930
+ if provision_type.nil?
931
+ raise_command_error "Provision Type not found by code #{provision_type_code}"
932
+ end
933
+ else
934
+ raise_command_error "Unable to determine provision type for container #{container['id']}"
935
+ end
936
+ return provision_type
937
+ end
938
+
939
+ def load_instance_provision_type(instance)
940
+ provision_type_code = instance['layout']['provisionTypeCode'] rescue nil
941
+ provision_type = nil
942
+ if provision_type_code
943
+ provision_type = provision_types_interface.list({code:provision_type_code})['provisionTypes'][0]
944
+ if provision_type.nil?
945
+ raise_command_error "Provision Type not found by code #{provision_type_code}"
946
+ end
947
+ else
948
+ raise_command_error "Unable to determine provision type for instance #{instance['id']}"
949
+ end
950
+ return provision_type
951
+ end
952
+
953
+ def load_container_network_server_type(container)
954
+ cloud = find_cloud_by_id(container['cloud']['id'])
955
+ network_server_type_code = cloud['networkServer']['type'] rescue nil
956
+ network_server_type = nil
957
+ if network_server_type_code
958
+ network_server_type = @network_server_types_interface.list({code:network_server_type_code})['networkServerTypes'][0]
959
+ if network_server_type.nil?
960
+ raise_command_error "Network Server Type not found by code #{network_server_type_code}"
961
+ end
962
+ else
963
+ raise_command_error "Unable to determine network server type for container #{container['id']}"
964
+ end
965
+ return network_server_type
966
+ end
967
+ end