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,1401 @@
1
+ require 'mtncloud/cli/cli_command'
2
+
3
+ class MtnCloud::Cli::StorageProvidersCommand
4
+ include MtnCloud::Cli::CliCommand
5
+ include MtnCloud::Cli::InfrastructureHelper
6
+
7
+ set_command_name :'storage-buckets'
8
+
9
+ register_subcommands :list, :get, :add, :update, :remove
10
+ # file commands
11
+ register_subcommands :'list-files' => :list_files
12
+ register_subcommands :'ls' => :ls
13
+ #register_subcommands :'file' => :get_file
14
+ # register_subcommands :'history' => :file_history
15
+ register_subcommands :'upload' => :upload_file
16
+ register_subcommands :'download' => :download_file
17
+ register_subcommands :'read' => :read_file
18
+ register_subcommands :'remove-file' => :remove_file
19
+ register_subcommands :'rm' => :remove_file
20
+
21
+ # set_default_subcommand :list
22
+
23
+ def initialize()
24
+ # @appliance_name, @appliance_url = MtnCloud::Cli::Remote.active_appliance
25
+ end
26
+
27
+ def connect(opts)
28
+ @api_client = establish_remote_appliance_connection(opts)
29
+ @storage_providers_interface = @api_client.storage_providers
30
+ @storage_servers_interface = @api_client.storage_servers
31
+ @clouds_interface = @api_client.clouds
32
+ @options_interface = @api_client.options
33
+ end
34
+
35
+ def handle(args)
36
+ handle_subcommand(args)
37
+ end
38
+
39
+ def list(args)
40
+ options = {}
41
+ params = {}
42
+ ref_ids = []
43
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
44
+ opts.banner = subcommand_usage("[search]")
45
+ build_standard_list_options(opts, options)
46
+ opts.footer = "List storage buckets."
47
+ end
48
+ optparse.parse!(args)
49
+ connect(options)
50
+ if args.count > 0
51
+ options[:phrase] = args.join(" ")
52
+ end
53
+ params.merge!(parse_list_options(options))
54
+ @storage_providers_interface.setopts(options)
55
+ if options[:dry_run]
56
+ print_dry_run @storage_providers_interface.dry.list(params)
57
+ return
58
+ end
59
+ json_response = @storage_providers_interface.list(params)
60
+ storage_buckets = json_response['storageBuckets']
61
+ render_response(json_response, options, 'storageBuckets') do
62
+ print_h1 "Storage Buckets", parse_list_subtitles(options), options
63
+ if storage_buckets.empty?
64
+ print cyan,"No storage buckets found.",reset,"\n"
65
+ else
66
+ print as_pretty_table(storage_buckets, storage_bucket_column_definitions.upcase_keys!, options)
67
+ print_results_pagination(json_response)
68
+ end
69
+ print reset,"\n"
70
+ end
71
+ if storage_buckets.empty?
72
+ return 1, "no storage buckets found"
73
+ else
74
+ return 0, nil
75
+ end
76
+ end
77
+
78
+ def get(args)
79
+ options = {}
80
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
81
+ opts.banner = subcommand_usage("[storage-bucket]")
82
+ build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
83
+ opts.footer = "Get details about a storage bucket." + "\n" +
84
+ "[storage-bucket] is required. This is the name or id of a storage bucket."
85
+ end
86
+ optparse.parse!(args)
87
+ if args.count != 1
88
+ print_error MtnCloud::Terminal.angry_prompt
89
+ puts_error "#{command_name} missing argument: [storage-bucket]\n#{optparse}"
90
+ return 1
91
+ end
92
+ connect(options)
93
+ begin
94
+ @storage_providers_interface.setopts(options)
95
+ if options[:dry_run]
96
+ if args[0].to_s =~ /\A\d{1,}\Z/
97
+ print_dry_run @storage_providers_interface.dry.get(args[0].to_i)
98
+ else
99
+ print_dry_run @storage_providers_interface.dry.list({name:args[0]})
100
+ end
101
+ return
102
+ end
103
+ storage_provider = find_storage_provider_by_name_or_id(args[0])
104
+ return 1 if storage_provider.nil?
105
+ json_response = {'storageBucket' => storage_provider} # skip redundant request
106
+ # json_response = @storage_providers_interface.get(storage_provider['id'])
107
+ storage_provider = json_response['storageBucket']
108
+ if options[:json]
109
+ puts as_json(json_response, options, "storageBucket")
110
+ return 0
111
+ elsif options[:yaml]
112
+ puts as_yaml(json_response, options, "storageBucket")
113
+ return 0
114
+ elsif options[:csv]
115
+ puts records_as_csv([storage_provider], options)
116
+ return 0
117
+ end
118
+ print_h1 "Storage Bucket Details"
119
+ print cyan
120
+ description_cols = {
121
+ "ID" => 'id',
122
+ "Name" => lambda {|it| it['name'] },
123
+ "Provider Type" => lambda {|it| format_storage_provider_type(it) },
124
+ "Bucket Name" => lambda {|it| format_bucket_name(it) },
125
+ "Default Backup Target" => lambda {|it| it['defaultBackupTarget'] ? 'Yes' : 'No' },
126
+ "Default Deployment Target" => lambda {|it| it['defaultDeploymentTarget'] ? 'Yes' : 'No' },
127
+ "Default Virtual Image Store" => lambda {|it| it['defaultVirtualImageTarget'] ? 'Yes' : 'No' },
128
+ "Archive Snapshots" => lambda {|it| it['copyToStore'] ? 'Yes' : 'No' }
129
+ }
130
+ print_description_list(description_cols, storage_provider)
131
+ print reset,"\n"
132
+ return 0
133
+ rescue RestClient::Exception => e
134
+ print_rest_exception(e, options)
135
+ return 1
136
+ end
137
+ end
138
+
139
+ def add(args)
140
+ options = {}
141
+ ip_range_list = nil
142
+ create_bucket = nil
143
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
144
+ opts.banner = subcommand_usage()
145
+ opts.on('--name VALUE', String, "Name for this storage bucket") do |val|
146
+ options['name'] = val
147
+ end
148
+ opts.on('--type code', String, "Storage Bucket Type Code") do |val|
149
+ options['providerType'] = val
150
+ end
151
+ opts.on('--bucket-name VALUE', String, "Bucket Name") do |val|
152
+ options['bucketName'] = val
153
+ end
154
+ opts.on('--default-backup-target [on|off]', String, "Default Backup Target") do |val|
155
+ options['defaultBackupTarget'] = val.to_s == 'on' || val.to_s == 'true'
156
+ end
157
+ opts.on('--default-deployment-target [on|off]', String, "Default Deployment Target") do |val|
158
+ options['defaultDeploymentTarget'] = val.to_s == 'on' || val.to_s == 'true'
159
+ end
160
+ opts.on('--default-virtual-image-target [on|off]', String, "Default Virtual Image Store") do |val|
161
+ options['defaultVirtualImageTarget'] = val.to_s == 'on' || val.to_s == 'true'
162
+ end
163
+ opts.on('--copy-to-store [on|off]', String, "Archive Snapshots") do |val|
164
+ options['copyToStore'] = val.to_s == 'on' || val.to_s == 'true'
165
+ end
166
+ #opts.on('--create-bucket [on|off]', String, "Create Bucket") do |val|
167
+ # create_bucket = val.to_s == 'on' || val.to_s == 'true' || val.nil?
168
+ #end
169
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :quiet, :remote])
170
+ opts.footer = "Create a new storage bucket." + "\n" +
171
+ "[name] is required and can be passed as --name instead."
172
+ end
173
+ optparse.parse!(args)
174
+ if args.count > 1
175
+ print_error MtnCloud::Terminal.angry_prompt
176
+ puts_error "wrong number of arguments, expected 0-1 and got #{args.count}\n#{optparse}"
177
+ return 1
178
+ end
179
+ connect(options)
180
+ begin
181
+ # merge -O options into normally parsed options
182
+ options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
183
+
184
+ # support [name] as first argument
185
+ if args[0]
186
+ options['name'] = args[0]
187
+ end
188
+
189
+ # construct payload
190
+ payload = nil
191
+ if options[:payload]
192
+ payload = options[:payload]
193
+ else
194
+ # prompt for storage bucket options
195
+ payload = {
196
+ 'storageBucket' => {
197
+ # 'config' => {}
198
+ }
199
+ }
200
+
201
+ # allow arbitrary -O options
202
+ payload['storageBucket'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
203
+
204
+ # Name
205
+ if options['name']
206
+ payload['storageBucket']['name'] = options['name']
207
+ else
208
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Name', 'type' => 'text', 'required' => true, 'description' => 'Name for this storage bucket.'}], options)
209
+ payload['storageBucket']['name'] = v_prompt['name']
210
+ end
211
+
212
+ # Storage Bucket Type
213
+ storage_provider_type_code = nil
214
+ if options['type']
215
+ storage_provider_type_code = options['type'].to_s
216
+ elsif options['providerType']
217
+ storage_provider_type_code = options['providerType'].to_s
218
+ else
219
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'providerType',
220
+ 'fieldLabel' => 'Provider Type',
221
+ 'type' => 'select',
222
+ 'selectOptions' => get_storage_provider_types(),
223
+ 'required' => true,
224
+ 'description' => 'Choose a storage bucket type.'}],
225
+ options, @api_client, {})
226
+ storage_provider_type_code = v_prompt['providerType'] unless v_prompt['providerType'].nil?
227
+ end
228
+ if storage_provider_type_code == 'amazonS3'
229
+ payload['storageBucket']['providerType'] = 's3' # cloud provided amazonS3
230
+ else
231
+ payload['storageBucket']['providerType'] = storage_provider_type_code
232
+ end
233
+
234
+ # Storage Service (only for amazonS3)
235
+ storage_server_type_id = nil
236
+ storage_server_id = nil
237
+ if storage_provider_type_code == 'amazonS3'
238
+ storage_server_type = @api_client.storage_server_types.list({max:1000})['storageServerTypes'].find {|it| it['code'].downcase == storage_provider_type_code.downcase }
239
+ if options['storageServer']
240
+ storage_server_id = options['storageServer']
241
+ else
242
+ if storage_server_type.nil?
243
+ raise_command_error "error: no storage server type found for amazonS3"
244
+ end
245
+ MtnCloud::Logging::DarkPrinter.puts "Finding storage services..." if MtnCloud::Logging.debug?
246
+ storage_server_options = @storage_servers_interface.list({max:1000, 'typeId': storage_server_type['id']})['storageServers'].collect {|it| {'name' => it['name'], 'value' => it['id'] } }
247
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'storageServer',
248
+ 'fieldLabel' => 'Storage Server',
249
+ 'type' => 'select',
250
+ 'selectOptions' => storage_server_options,
251
+ 'required' => true,
252
+ 'description' => 'Choose a connected storage service.'}], options, @api_client, {})
253
+ storage_server_id = v_prompt['storageServer'] unless v_prompt['storageServer'].nil?
254
+ end
255
+ payload['storageBucket']['storageServer'] = storage_server_id.to_s # api before 8.0.11 expects a string instead of a number, oooof
256
+ end
257
+
258
+ # Provider Type Specific Options
259
+ provider_type_option_types = nil
260
+ if storage_provider_type_code == 's3'
261
+ # print_h2 "Amazon S3 Options"
262
+ provider_type_option_types = [
263
+ {'fieldContext' => 'config', 'fieldName' => 'accessKey', 'fieldLabel' => 'Access Key', 'type' => 'text', 'required' => true, 'description' => ''},
264
+ {'fieldContext' => 'config', 'fieldName' => 'secretKey', 'fieldLabel' => 'Secret Key', 'type' => 'password', 'required' => true, 'description' => ''},
265
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
266
+ {'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
267
+ {'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => false, 'description' => 'Optional Amazon region if creating a new bucket.'},
268
+ {'fieldContext' => 'config', 'fieldName' => 'endpoint', 'fieldLabel' => 'Endpoint URL', 'type' => 'text', 'required' => false, 'description' => 'Optional endpoint URL if pointing to an object store other than amazon that mimics the Amazon S3 APIs.'}
269
+ ]
270
+ elsif storage_provider_type_code == 'amazonS3'
271
+ # print_h2 "Amazon S3 Provided by Cloud Options"
272
+ provider_type_option_types = [
273
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
274
+ {'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
275
+ {'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => false, 'description' => 'Optional Amazon region if creating a new bucket.'},
276
+ {'fieldContext' => 'config', 'fieldName' => 'endpoint', 'fieldLabel' => 'Endpoint URL', 'type' => 'text', 'required' => false, 'description' => 'Optional endpoint URL if pointing to an object store other than amazon that mimics the Amazon S3 APIs.'}
277
+ ]
278
+
279
+ elsif storage_provider_type_code == 'azure'
280
+ # print_h2 "Azure Options"
281
+ provider_type_option_types = [
282
+ {'fieldContext' => 'config', 'fieldName' => 'storageAccount', 'fieldLabel' => 'Storage Account', 'type' => 'text', 'required' => true, 'description' => ''},
283
+ {'fieldContext' => 'config', 'fieldName' => 'storageKey', 'fieldLabel' => 'Storage Key', 'type' => 'password', 'required' => true, 'description' => ''},
284
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
285
+ {'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
286
+ ]
287
+ elsif storage_provider_type_code == 'alibaba'
288
+ # print_h2 "Alibaba Options"
289
+ provider_type_option_types = [
290
+ {'fieldContext' => 'config', 'fieldName' => 'accessKey', 'fieldLabel' => 'Access Key', 'type' => 'text', 'required' => true, 'description' => ''},
291
+ {'fieldContext' => 'config', 'fieldName' => 'secretKey', 'fieldLabel' => 'Secret Key', 'type' => 'password', 'required' => true, 'description' => ''},
292
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
293
+ {'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
294
+ {'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => false, 'description' => 'Optional Alibaba region if creating a new bucket.'}
295
+ ]
296
+ elsif storage_provider_type_code == 'cifs'
297
+ # print_h2 "CIFS Options"
298
+ provider_type_option_types = [
299
+ {'fieldContext' => 'config', 'fieldName' => 'host', 'fieldLabel' => 'Host', 'type' => 'text', 'required' => true, 'description' => ''},
300
+ {'fieldContext' => 'config', 'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'description' => ''},
301
+ {'fieldContext' => 'config', 'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'description' => ''},
302
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''}
303
+ ]
304
+ elsif storage_provider_type_code == 'local'
305
+ # print_h2 "Local Storage Options"
306
+ provider_type_option_types = [
307
+ {'fieldContext' => 'config', 'fieldName' => 'basePath', 'fieldLabel' => 'Storage Path', 'type' => 'text', 'required' => true, 'description' => ''},
308
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'hidden', 'required' => true, 'description' => '', 'defaultValue' => '.'}
309
+ ]
310
+ elsif storage_provider_type_code == 'nfs'
311
+ # print_h2 "NFSv3 Options"
312
+ provider_type_option_types = [
313
+ {'fieldContext' => 'config', 'fieldName' => 'host', 'fieldLabel' => 'Host', 'type' => 'text', 'required' => true, 'description' => ''},
314
+ {'fieldContext' => 'config', 'fieldName' => 'exportFolder', 'fieldLabel' => 'Export Folder', 'type' => 'text', 'required' => false, 'description' => ''},
315
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'hidden', 'required' => true, 'description' => '', 'defaultValue' => '/'}
316
+ ]
317
+ elsif storage_provider_type_code == 'openstack'
318
+ # print_h2 "Openstack Swift Options"
319
+ provider_type_option_types = [
320
+ {'fieldContext' => 'config', 'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'description' => ''},
321
+ {'fieldContext' => 'config', 'fieldName' => 'apiKey', 'fieldLabel' => 'API Key', 'type' => 'password', 'required' => true, 'description' => ''},
322
+ {'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => true, 'description' => ''},
323
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
324
+ {'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'},
325
+ {'fieldContext' => 'config', 'fieldName' => 'identityUrl', 'fieldLabel' => 'Identity URL', 'type' => 'text', 'required' => true, 'description' => ''},
326
+ ]
327
+ elsif storage_provider_type_code == 'rackspace'
328
+ # print_h2 "Rackspace CDN Options"
329
+ provider_type_option_types = [
330
+ {'fieldContext' => 'config', 'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'description' => ''},
331
+ {'fieldContext' => 'config', 'fieldName' => 'apiKey', 'fieldLabel' => 'API Key', 'type' => 'password', 'required' => true, 'description' => ''},
332
+ {'fieldContext' => 'config', 'fieldName' => 'region', 'fieldLabel' => 'Region', 'type' => 'text', 'required' => true, 'description' => ''},
333
+ {'fieldName' => 'bucketName', 'fieldLabel' => 'Bucket Name', 'type' => 'text', 'required' => true, 'description' => ''},
334
+ {'fieldName' => 'createBucket', 'fieldLabel' => 'Create Bucket', 'type' => 'checkbox', 'required' => false, 'defaultValue' => false, 'description' => 'Create the bucket if it does not exist.'}
335
+ ]
336
+ else
337
+ puts "warning: unrecognized storage bucket type: '#{storage_provider_type_code}'"
338
+ end
339
+ if provider_type_option_types
340
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt(provider_type_option_types, options, @api_client, {})
341
+ payload['storageBucket'].deep_merge!(v_prompt)
342
+ end
343
+
344
+ # Default Backup Target
345
+ if options['defaultBackupTarget'] != nil
346
+ payload['storageBucket']['defaultBackupTarget'] = options['defaultBackupTarget']
347
+ else
348
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'defaultBackupTarget', 'fieldLabel' => 'Default Backup Target', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'off'}], options)
349
+ payload['storageBucket']['defaultBackupTarget'] = (v_prompt['defaultBackupTarget'].to_s == 'on') unless v_prompt['defaultBackupTarget'].nil?
350
+ end
351
+
352
+ # Archive Snapshots
353
+ if options['copyToStore'] != nil
354
+ payload['storageBucket']['copyToStore'] = options['copyToStore']
355
+ else
356
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'copyToStore', 'fieldLabel' => 'Archive Snapshots', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'on'}], options)
357
+ payload['storageBucket']['copyToStore'] = (v_prompt['copyToStore'].to_s == 'on') unless v_prompt['copyToStore'].nil?
358
+ end
359
+
360
+ # Default Deployment Target
361
+ if options['defaultDeploymentTarget'] != nil
362
+ payload['storageBucket']['defaultDeploymentTarget'] = options['defaultDeploymentTarget']
363
+ else
364
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'defaultDeploymentTarget', 'fieldLabel' => 'Default Deployment Target', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'off'}], options)
365
+ payload['storageBucket']['defaultDeploymentTarget'] = (v_prompt['defaultDeploymentTarget'].to_s == 'on') unless v_prompt['defaultDeploymentTarget'].nil?
366
+ end
367
+
368
+ # Default Virtual Image Store
369
+ if options['defaultVirtualImageTarget'] != nil
370
+ payload['storageBucket']['defaultVirtualImageTarget'] = options['defaultVirtualImageTarget']
371
+ else
372
+ v_prompt = MtnCloud::Cli::OptionTypes.prompt([{'fieldName' => 'defaultVirtualImageTarget', 'fieldLabel' => 'Default Virtual Image Store', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => 'off'}], options)
373
+ payload['storageBucket']['defaultVirtualImageTarget'] = (v_prompt['defaultVirtualImageTarget'].to_s == 'on') unless v_prompt['defaultVirtualImageTarget'].nil?
374
+ end
375
+ #if create_bucket
376
+ # payload['createBucket'] = true
377
+ #end
378
+ if payload['storageBucket']['createBucket'] == 'on'
379
+ payload['storageBucket']['createBucket'] = true
380
+ end
381
+ end
382
+
383
+ @storage_providers_interface.setopts(options)
384
+ if options[:dry_run]
385
+ print_dry_run @storage_providers_interface.dry.create(payload)
386
+ return
387
+ end
388
+ json_response = @storage_providers_interface.create(payload)
389
+ if options[:json]
390
+ print JSON.pretty_generate(json_response)
391
+ print "\n"
392
+ elsif !options[:quiet]
393
+ storage_provider = json_response['storageBucket']
394
+ print_green_success "Added storage bucket #{storage_provider['name']}"
395
+ get([storage_provider['id']])
396
+ end
397
+ return 0
398
+ rescue RestClient::Exception => e
399
+ print_rest_exception(e, options)
400
+ exit 1
401
+ end
402
+ end
403
+
404
+ def update(args)
405
+ options = {}
406
+ ip_range_list = nil
407
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
408
+ opts.banner = subcommand_usage("[storage-bucket] [options]")
409
+ opts.on('--name VALUE', String, "Name for this storage bucket") do |val|
410
+ options['name'] = val
411
+ end
412
+ opts.on('--type code', String, "Storage Bucket Type Code") do |val|
413
+ options['providerType'] = val
414
+ end
415
+ opts.on('--bucket-name VALUE', String, "Bucket Name") do |val|
416
+ options['bucketName'] = val
417
+ end
418
+ opts.on('--default-backup-target [on|off]', String, "Default Backup Target") do |val|
419
+ options['defaultBackupTarget'] = val.to_s == 'on' || val.to_s == 'true'
420
+ end
421
+ opts.on('--default-deployment-target [on|off]', String, "Default Deployment Target") do |val|
422
+ options['defaultDeploymentTarget'] = val.to_s == 'on' || val.to_s == 'true'
423
+ end
424
+ opts.on('--default-virtual-image-target [on|off]', String, "Default Virtual Image Store") do |val|
425
+ options['defaultVirtualImageTarget'] = val.to_s == 'on' || val.to_s == 'true'
426
+ end
427
+ opts.on('--copy-to-store [on|off]', String, "Archive Snapshots") do |val|
428
+ options['copyToStore'] = val.to_s == 'on' || val.to_s == 'true'
429
+ end
430
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
431
+ opts.footer = "Update a storage bucket." + "\n" +
432
+ "[storage-bucket] is required. This is the id of a storage bucket."
433
+ end
434
+ optparse.parse!(args)
435
+ if args.count != 1
436
+ print_error MtnCloud::Terminal.angry_prompt
437
+ puts_error "wrong number of arguments, expected 1 and got #{args.count}\n#{optparse}"
438
+ return 1
439
+ end
440
+ connect(options)
441
+
442
+ begin
443
+ storage_provider = find_storage_provider_by_name_or_id(args[0])
444
+ return 1 if storage_provider.nil?
445
+
446
+ # merge -O options into normally parsed options
447
+ options.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
448
+
449
+ # construct payload
450
+ payload = nil
451
+ if options[:payload]
452
+ payload = options[:payload]
453
+ else
454
+ # prompt for storage bucket options
455
+ # preserve previous config settings
456
+ payload = {
457
+ 'storageBucket' => {
458
+ 'config' => storage_provider['config']
459
+ }
460
+ }
461
+
462
+ # allow arbitrary -O options
463
+ payload['storageBucket'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
464
+
465
+ # Name
466
+ if options['name']
467
+ payload['storageBucket']['name'] = options['name']
468
+ end
469
+
470
+ # Default Backup Target
471
+ if options['defaultBackupTarget'] != nil
472
+ payload['storageBucket']['defaultBackupTarget'] = options['defaultBackupTarget']
473
+ end
474
+
475
+ # Archive Snapshots
476
+ if options['copyToStore'] != nil
477
+ payload['storageBucket']['copyToStore'] = options['copyToStore']
478
+ end
479
+
480
+ # Default Deployment Target
481
+ if options['defaultDeploymentTarget'] != nil
482
+ payload['storageBucket']['defaultDeploymentTarget'] = options['defaultDeploymentTarget']
483
+ end
484
+
485
+ # Default Virtual Image Store
486
+ if options['defaultVirtualImageTarget'] != nil
487
+ payload['storageBucket']['defaultVirtualImageTarget'] = options['defaultVirtualImageTarget']
488
+ end
489
+
490
+ if payload['storageBucket']['createBucket'] == 'on'
491
+ payload['storageBucket']['createBucket'] = true
492
+ end
493
+ end
494
+ @storage_providers_interface.setopts(options)
495
+ if options[:dry_run]
496
+ print_dry_run @storage_providers_interface.dry.update(storage_provider["id"], payload)
497
+ return
498
+ end
499
+ json_response = @storage_providers_interface.update(storage_provider["id"], payload)
500
+ if options[:json]
501
+ puts as_json(json_response)
502
+ else
503
+ storage_provider = json_response['storageBucket']
504
+ print_green_success "Updated storage bucket #{storage_provider['name']}"
505
+ get([storage_provider['id']])
506
+ end
507
+ return 0
508
+ rescue RestClient::Exception => e
509
+ print_rest_exception(e, options)
510
+ return 1
511
+ end
512
+ end
513
+
514
+ def remove(args)
515
+ options = {}
516
+ params = {:removeResources => 'on'}
517
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
518
+ opts.banner = subcommand_usage("[storage-bucket]")
519
+ opts.on('--remove-resources [on|off]', ['on','off'], "Remove From Server. Default is on.") do |val|
520
+ params[:removeResources] = val.nil? ? 'on' : val
521
+ end
522
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
523
+ opts.footer = "Delete a storage bucket." + "\n" +
524
+ "[storage-bucket] is required. This is the name or id of a storage bucket."
525
+ end
526
+ optparse.parse!(args)
527
+
528
+ if args.count < 1
529
+ print_error MtnCloud::Terminal.angry_prompt
530
+ puts_error "#{command_name} missing argument: [storage-bucket]\n#{optparse}"
531
+ return 1
532
+ end
533
+
534
+ connect(options)
535
+ begin
536
+ storage_provider = find_storage_provider_by_name_or_id(args[0])
537
+ return 1 if storage_provider.nil?
538
+
539
+ unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to delete the storage bucket: #{storage_provider['name']}?")
540
+ return 9, "aborted command"
541
+ end
542
+ @storage_providers_interface.setopts(options)
543
+ if options[:dry_run]
544
+ print_dry_run @storage_providers_interface.dry.destroy(storage_provider['id'], params)
545
+ return 0
546
+ end
547
+ json_response = @storage_providers_interface.destroy(storage_provider['id'], params)
548
+ if options[:json]
549
+ print JSON.pretty_generate(json_response)
550
+ print "\n"
551
+ else
552
+ print_green_success "Removed storage bucket #{storage_provider['name']}"
553
+ # list([])
554
+ end
555
+ return 0
556
+ rescue RestClient::Exception => e
557
+ print_rest_exception(e, options)
558
+ return 1
559
+ end
560
+ end
561
+
562
+ def list_files(args)
563
+ options = {}
564
+ params = {}
565
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
566
+ opts.banner = subcommand_usage("[provider:/path]")
567
+ opts.on('-a', '--all', "Show all files, including subdirectories under the /path.") do
568
+ params[:fullTree] = true
569
+ end
570
+ build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run])
571
+ opts.footer = "List files in a storage bucket. \nInclude [/path] to show files under a directory."
572
+ end
573
+ optparse.parse!(args)
574
+ if args.count < 1 || args.count > 2
575
+ print_error MtnCloud::Terminal.angry_prompt
576
+ puts_error "#{command_name} list-files expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
577
+ return 1
578
+ end
579
+ storage_provider_id, search_file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
580
+ connect(options)
581
+ begin
582
+ storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
583
+ return 1 if storage_provider.nil?
584
+ params.merge!(parse_list_options(options))
585
+ [:fullTree].each do |k|
586
+ params[k] = options[k] unless options[k].nil?
587
+ end
588
+ @storage_providers_interface.setopts(options)
589
+ if options[:dry_run]
590
+ print_dry_run @storage_providers_interface.dry.list_files(storage_provider['id'], search_file_path, params)
591
+ return
592
+ end
593
+ json_response = @storage_providers_interface.list_files(storage_provider['id'], search_file_path, params)
594
+ storage_files = json_response['storageFiles']
595
+ # storage_provider = json_response['storageBucket']
596
+ if options[:json]
597
+ print JSON.pretty_generate(json_response)
598
+ return
599
+ end
600
+ if options[:json]
601
+ puts as_json(json_response, options, "storageFiles")
602
+ return 0
603
+ elsif options[:yaml]
604
+ puts as_yaml(json_response, options, "storageFiles")
605
+ return 0
606
+ elsif options[:csv]
607
+ puts records_as_csv(json_response['storageFiles'], options)
608
+ return 0
609
+ end
610
+ print_h1 "Storage Files", ["#{storage_provider['name']}:#{search_file_path}"]
611
+ print cyan
612
+ description_cols = {
613
+ "ID" => 'id',
614
+ "Name" => 'name',
615
+ # "Bucket Name" => 'bucketName',
616
+ #"Path" => lambda {|it| search_file_path }
617
+ }
618
+ #print_description_list(description_cols, storage_provider)
619
+ #print "\n"
620
+ #print_h2 "Path: #{search_file_path}"
621
+ # print "Directory: #{search_file_path}"
622
+ if storage_files && storage_files.size > 0
623
+ print_storage_files_table(storage_files, {fullTree: params[:fullTree]})
624
+ #print_results_pagination(json_response, {:label => "file", :n_label => "files"})
625
+ print reset, "\n"
626
+ return 0
627
+ else
628
+ # puts "No files found for path #{search_file_path}"
629
+ if search_file_path.empty? || search_file_path == "/"
630
+ puts "This storage bucket has no files."
631
+ print reset,"\n"
632
+ return 0
633
+ else
634
+ puts "No files found for path #{search_file_path}"
635
+ print reset,"\n"
636
+ return 1
637
+ end
638
+ end
639
+ rescue RestClient::Exception => e
640
+ print_rest_exception(e, options)
641
+ return 1
642
+ end
643
+ end
644
+
645
+ def ls(args)
646
+ options = {}
647
+ params = {}
648
+ do_one_file_per_line = false
649
+ do_long_format = false
650
+ do_human_bytes = false
651
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
652
+ opts.banner = subcommand_usage("[bucket/path]")
653
+ opts.on('-a', '--all', "Show all files, including subdirectories under the /path.") do
654
+ params[:fullTree] = true
655
+ do_one_file_per_line = true
656
+ end
657
+ opts.on('-l', '--long', "Lists files in the long format, which contains lots of useful information, e.g. the exact size of the file, the file type, and when it was last modified.") do
658
+ do_long_format = true
659
+ do_one_file_per_line
660
+ end
661
+ opts.on('-H', '--human', "Humanized file sizes. The default is just the number of bytes.") do
662
+ do_human_bytes = true
663
+ end
664
+ opts.on('-1', '--oneline', "One file per line. The default delimiter is a single space.") do
665
+ do_one_file_per_line = true
666
+ end
667
+ build_common_options(opts, options, [:list, :json, :fields, :dry_run])
668
+ opts.footer = "Print filenames for a given location.\nPass storage location in the format bucket/path."
669
+ end
670
+ optparse.parse!(args)
671
+ if args.count < 1 || args.count > 2
672
+ print_error MtnCloud::Terminal.angry_prompt
673
+ puts_error "#{command_name} ls expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
674
+ return 1
675
+ end
676
+ storage_provider_id, search_file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
677
+ connect(options)
678
+ begin
679
+ storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
680
+ return 1 if storage_provider.nil?
681
+ params.merge!(parse_list_options(options))
682
+ [:fullTree].each do |k|
683
+ params[k] = options[k] unless options[k].nil?
684
+ end
685
+ @storage_providers_interface.setopts(options)
686
+ if options[:dry_run]
687
+ print_dry_run @storage_providers_interface.dry.list_files(storage_provider['id'], search_file_path, params)
688
+ return 0
689
+ end
690
+ json_response = @storage_providers_interface.list_files(storage_provider['id'], search_file_path, params)
691
+ if options[:json]
692
+ puts as_json(json_response, options, "storageFiles")
693
+ # no files is an error condition for this command
694
+ if !json_response['storageFiles'] || json_response['storageFiles'].size == 0
695
+ return 1
696
+ end
697
+ return 0
698
+ end
699
+ #storage_provider = json_response['storageBucket'] # yep, this is returned too
700
+ storage_files = json_response['storageFiles']
701
+ # print_h2 "Directory: #{search_file_path}"
702
+ # print "Directory: #{search_file_path}"
703
+ if storage_files && storage_files.size > 0
704
+ if do_long_format
705
+ # ls long format
706
+ # owner groups filesize type filename
707
+ now = Time.now
708
+ storage_files.each do |storage_file|
709
+ # -rw-r--r-- 1 jdickson staff 1361 Oct 23 08:00 voltron_2.10.log
710
+ file_color = cyan # reset
711
+ if storage_file['isDirectory']
712
+ file_color = blue
713
+ end
714
+ file_info = []
715
+ # Number of links
716
+ # file_info << file["linkCount"].to_i + 1
717
+ # Owner
718
+ owner_str = ""
719
+ if storage_file['owner']
720
+ owner_str = storage_file['owner']['name']
721
+ elsif storage_provider['owner']
722
+ owner_str = storage_provider['owner']['name']
723
+ else
724
+ owner_str = "noone"
725
+ end
726
+ #file_info << truncate_string(owner_str, 15).ljust(15, " ")
727
+ # Group (Tenants)
728
+ groups_str = ""
729
+ if storage_file['visibility'] == 'public'
730
+ # this is confusing because of Public URL (isPublic) setting
731
+ groups_str = "public"
732
+ else
733
+ if storage_file['accounts'].instance_of?(Array) && storage_file['accounts'].size > 0
734
+ # groups_str = storage_file['accounts'].collect {|it| it['name'] }.join(',')
735
+ groups_str = (storage_file['accounts'].size == 1) ? "#{storage_file['accounts'][0]['name']}" : "#{storage_file['accounts'].size} tenants"
736
+ elsif storage_provider['accounts'].instance_of?(Array) && storage_provider['accounts'].size > 0
737
+ # groups_str = storage_provider['accounts'].collect {|it| it['name'] }.join(',')
738
+ groups_str = (storage_provider['accounts'].size == 1) ? "#{storage_provider['accounts'][0]['name']}" : "#{storage_provider['accounts'].size} tenants"
739
+ else
740
+ groups_str = owner_str
741
+ end
742
+ end
743
+ #file_info << truncate_string(groups_str, 15).ljust(15, " ")
744
+ # File Type
745
+ content_type = storage_file['contentType'].to_s
746
+ if storage_file['isDirectory']
747
+ content_type = "directory"
748
+ else
749
+ content_type = storage_file['contentType'].to_s
750
+ end
751
+ file_info << content_type.ljust(25, " ")
752
+ filesize_str = ""
753
+ if do_human_bytes
754
+ # filesize_str = format_bytes(storage_file['contentLength'])
755
+ filesize_str = format_bytes_short(storage_file['contentLength'])
756
+ else
757
+ filesize_str = storage_file['contentLength'].to_i.to_s
758
+ end
759
+ # file_info << filesize_str.ljust(12, " ")
760
+ file_info << filesize_str.ljust(7, " ")
761
+ mtime = ""
762
+ last_updated = parse_time(storage_file['dateModified'])
763
+ if last_updated
764
+ if last_updated.year == now.year
765
+ mtime = format_local_dt(last_updated, {format: "%b %e %H:%M"})
766
+ else
767
+ mtime = format_local_dt(last_updated, {format: "%b %e %Y"})
768
+ end
769
+ end
770
+ file_info << mtime.ljust(12, " ")
771
+ fn = format_filename(storage_file['name'], {fullTree: params[:fullTree]})
772
+ file_info << file_color + fn.to_s + cyan
773
+ print cyan, file_info.join(" "), reset, "\n"
774
+ end
775
+ else
776
+ file_names = storage_files.collect do |storage_file|
777
+ file_color = cyan # reset
778
+ if storage_file['isDirectory']
779
+ file_color = blue
780
+ end
781
+ fn = format_filename(storage_file['name'], {fullTree: params[:fullTree]})
782
+ file_color + fn.to_s + reset
783
+ end
784
+ if do_one_file_per_line
785
+ print file_names.join("\n")
786
+ else
787
+ print file_names.join("\t")
788
+ end
789
+ print "\n"
790
+ end
791
+ else
792
+ print_error yellow, "No files found for path: #{search_file_path}", reset, "\n"
793
+ return 1
794
+ end
795
+
796
+ return 0
797
+ rescue RestClient::Exception => e
798
+ print_rest_exception(e, options)
799
+ return 1
800
+ end
801
+ end
802
+
803
+ # def get_file(args)
804
+ # todo...
805
+ # end
806
+
807
+ def upload_file(args)
808
+ options = {}
809
+ query_params = {}
810
+ do_recursive = false
811
+ ignore_regexp = nil
812
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
813
+ opts.banner = subcommand_usage("[local-file] [provider:/path]")
814
+ # opts.on('--filename FILEPATH', String, "Remote file path for the file or folder being uploaded, this is an alternative to [remote-file-path]." ) do |val|
815
+ # options['type'] = val
816
+ # end
817
+ opts.on( '-R', '--recursive', "Upload a directory and all of its files. This must be passed if [local-file] is a directory." ) do
818
+ do_recursive = true
819
+ end
820
+ opts.on('--ignore-files PATTERN', String, "Pattern of files to be ignored when uploading a directory." ) do |val|
821
+ ignore_regexp = /#{Regexp.escape(val)}/
822
+ end
823
+ opts.footer = "Upload a local file or folder to a storage bucket. " +
824
+ "\nThe first argument [local-file] should be the path of a local file or directory." +
825
+ "\nThe second argument [provider:/path] should contain the name or id of the provider." +
826
+ "\nThe [:/path] component is optional and can be used to specify the destination of the uploaded file or folder." +
827
+ "\nThe default destination is the same name as the [local-file], under the root directory '/'. " +
828
+ "\nThis will overwrite any existing remote files that match the destination /path."
829
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
830
+ end
831
+ optparse.parse!(args)
832
+
833
+ if args.count != 2
834
+ print_error MtnCloud::Terminal.angry_prompt
835
+ puts_error "#{command_name} upload expects 2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
836
+ return 1
837
+ end
838
+ # validate local file path
839
+ local_file_path = File.expand_path(args[0].squeeze('/'))
840
+ if local_file_path == "" || local_file_path == "/" || local_file_path == "."
841
+ print_error MtnCloud::Terminal.angry_prompt
842
+ puts_error "#{command_name} missing argument: [local-file]\n#{optparse}"
843
+ return 1
844
+ end
845
+ if !File.exist?(local_file_path)
846
+ print_error MtnCloud::Terminal.angry_prompt
847
+ puts_error "#{command_name} bad argument: [local-file]\nFile '#{local_file_path}' was not found.\n#{optparse}"
848
+ return 1
849
+ end
850
+
851
+ # validate provider:/path
852
+ storage_provider_id, remote_file_path = parse_storage_provider_id_and_file_path(args[1], args[2])
853
+
854
+ # if local_file_path.include?('../') # || options[:yes]
855
+ # raise_command_error "Sorry, you may not use relative paths in your local filepath."
856
+ # end
857
+
858
+ # validate provider name (or id)
859
+ if !storage_provider_id
860
+ print_error MtnCloud::Terminal.angry_prompt
861
+ puts_error "#{command_name} missing argument: [provider]\n#{optparse}"
862
+ return 1
863
+ end
864
+
865
+ # strip leading slash of remote name
866
+ # if remote_file_path[0].chr == "/"
867
+ # remote_file_path = remote_file_path[1..-1]
868
+ # end
869
+
870
+ if remote_file_path.include?('./') # || options[:yes]
871
+ raise_command_error "Sorry, you may not use relative paths in your remote filepath."
872
+ end
873
+
874
+ # if !options[:yes]
875
+ scary_local_paths = ["/", "/root", "C:\\"]
876
+ if scary_local_paths.include?(local_file_path)
877
+ unless MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to upload all the files in local directory '#{local_file_path}' !?")
878
+ return 9, "aborted command"
879
+ end
880
+ end
881
+ # end
882
+
883
+ connect(options)
884
+ begin
885
+ storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
886
+ return 1 if storage_provider.nil?
887
+
888
+ # how many files we dealing with?
889
+ files_to_upload = []
890
+ if File.directory?(local_file_path)
891
+ # upload directory
892
+ if !do_recursive
893
+ print_error MtnCloud::Terminal.angry_prompt
894
+ puts_error "bad argument: '#{local_file_path}' is a directory. Use -R or --recursive to upload a directory.\n#{optparse}"
895
+ return 1
896
+ end
897
+ found_files = Dir.glob("#{local_file_path}/**/*")
898
+ # note: api call for directories is not needed
899
+ found_files = found_files.select {|file| File.file?(file) }
900
+ if ignore_regexp
901
+ found_files = found_files.reject {|it| it =~ ignore_regexp}
902
+ end
903
+ files_to_upload = found_files
904
+
905
+ if files_to_upload.size == 0
906
+ print_error MtnCloud::Terminal.angry_prompt
907
+ puts_error "bad argument: Local directory '#{local_file_path}' contains 0 files."
908
+ return 1
909
+ end
910
+
911
+ unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to upload directory #{local_file_path} (#{files_to_upload.size} files) to #{storage_provider['name']}:#{remote_file_path}?")
912
+ return 9, "aborted command"
913
+ end
914
+
915
+ if !options[:yes]
916
+ if files_to_upload.size > 100
917
+ unless MtnCloud::Cli::OptionTypes.confirm("Are you REALLY sure you want to upload #{files_to_upload.size} files ?")
918
+ return 9, "aborted command"
919
+ end
920
+ end
921
+ end
922
+
923
+ # local_dirname = File.dirname(local_file_path)
924
+ # local_basename = File.basename(local_file_path)
925
+ upload_file_list = []
926
+ files_to_upload.each do |file|
927
+ destination = file.sub(local_file_path, (remote_file_path || "")).squeeze('/')
928
+ upload_file_list << {file: file, destination: destination}
929
+ end
930
+ @storage_providers_interface.setopts(options)
931
+ if options[:dry_run]
932
+ # print_h1 "DRY RUN"
933
+ print "\n",cyan, bold, "Uploading #{upload_file_list.size} Files...", reset, "\n"
934
+ upload_file_list.each do |obj|
935
+ file, destination = obj[:file], obj[:destination]
936
+ #print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination} DRY RUN", reset, "\n"
937
+ print_dry_run @storage_providers_interface.dry.upload_file(storage_provider['id'], file, destination)
938
+ print "\n"
939
+ end
940
+ return 0
941
+ end
942
+
943
+ print "\n",cyan, bold, "Uploading #{upload_file_list.size} Files...", reset, "\n"
944
+ bad_upload_responses = []
945
+ upload_file_list.each do |obj|
946
+ file, destination = obj[:file], obj[:destination]
947
+ print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination}", reset
948
+ upload_response = @storage_providers_interface.upload_file(storage_provider['id'], file, destination)
949
+ if upload_response['success']
950
+ print bold," #{green}SUCCESS#{reset}"
951
+ else
952
+ print bold," #{red}ERROR#{reset}"
953
+ if upload_response['msg']
954
+ bad_upload_responses << upload_response
955
+ print " #{upload_response['msg']}#{reset}"
956
+ end
957
+ end
958
+ print "\n"
959
+ end
960
+ if bad_upload_responses.size > 0
961
+ print cyan, bold, "Completed Upload of #{upload_file_list.size} Files. #{red}#{bad_upload_responses.size} Errors!", reset, "\n"
962
+ else
963
+ print cyan, bold, "Completed Upload of #{upload_file_list.size} Files!", reset, "\n"
964
+ end
965
+
966
+ else
967
+
968
+ # upload file
969
+ if !File.exist?(local_file_path) && !File.file?(local_file_path)
970
+ print_error MtnCloud::Terminal.angry_prompt
971
+ puts_error "#{command_name} bad argument: [local-file]\nFile '#{local_file_path}' was not found.\n#{optparse}"
972
+ return 1
973
+ end
974
+
975
+ # local_dirname = File.dirname(local_file_path)
976
+ # local_basename = File.basename(local_file_path)
977
+
978
+ file = local_file_path
979
+ destination = File.basename(file)
980
+ if remote_file_path[-1].chr == "/"
981
+ # work like `cp`, and place into the directory
982
+ destination = remote_file_path + File.basename(file)
983
+ elsif remote_file_path
984
+ # renaming file
985
+ destination = remote_file_path
986
+ end
987
+ destination = destination.squeeze('/')
988
+
989
+ unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to upload #{local_file_path} to #{storage_provider['name']}:#{destination}?")
990
+ return 9, "aborted command"
991
+ end
992
+ @storage_providers_interface.setopts(options)
993
+ if options[:dry_run]
994
+ #print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination} DRY RUN", reset, "\n"
995
+ # print_h1 "DRY RUN"
996
+ print_dry_run @storage_providers_interface.dry.upload_file(storage_provider['id'], file, destination)
997
+ print "\n"
998
+ return 0
999
+ end
1000
+
1001
+ print cyan,bold, " - Uploading #{file} to #{storage_provider_id}:#{destination}", reset
1002
+ upload_response = @storage_providers_interface.upload_file(storage_provider['id'], file, destination)
1003
+ if upload_response['success']
1004
+ print bold," #{green}Success#{reset}"
1005
+ else
1006
+ print bold," #{red}Error#{reset}"
1007
+ if upload_response['msg']
1008
+ print " #{upload_response['msg']}#{reset}"
1009
+ end
1010
+ end
1011
+ print "\n"
1012
+
1013
+ end
1014
+ #print cyan, bold, "Upload Complete!", reset, "\n"
1015
+
1016
+ return 0
1017
+ rescue RestClient::Exception => e
1018
+ print_rest_exception(e, options)
1019
+ return 1
1020
+ end
1021
+ end
1022
+
1023
+ def download_file(args)
1024
+ full_command_string = "#{command_name} download #{args.join(' ')}".strip
1025
+ options = {}
1026
+ outfile = nil
1027
+ do_overwrite = false
1028
+ do_mkdir = false
1029
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
1030
+ opts.banner = subcommand_usage("[provider:/path] [local-file]")
1031
+ opts.on( '-f', '--force', "Overwrite existing [local-file] if it exists." ) do
1032
+ do_overwrite = true
1033
+ # do_mkdir = true
1034
+ end
1035
+ opts.on( '-p', '--mkdir', "Create missing directories for [local-file] if they do not exist." ) do
1036
+ do_mkdir = true
1037
+ end
1038
+ build_common_options(opts, options, [:dry_run, :quiet])
1039
+ opts.footer = "Download a file or directory.\n" +
1040
+ "[provider:/path] is required. This is the name or id of the provider and /path the file or folder to be downloaded.\n" +
1041
+ "[local-file] is required. This is the full local filepath for the downloaded file.\n" +
1042
+ "Directories will be downloaded as a .zip file, so you'll want to specify a [local-file] with a .zip extension."
1043
+ end
1044
+ optparse.parse!(args)
1045
+ if args.count < 2 || args.count > 3
1046
+ print_error MtnCloud::Terminal.angry_prompt
1047
+ puts_error "#{command_name} download expects 2-3 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
1048
+ return 1
1049
+ end
1050
+ storage_provider_id = nil
1051
+ local = nil
1052
+ outfile = nil
1053
+ if args.count == 3
1054
+ storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
1055
+ outfile = args[2]
1056
+ else
1057
+ storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0])
1058
+ outfile = args[1]
1059
+ end
1060
+ connect(options)
1061
+ begin
1062
+ storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
1063
+ return 1 if storage_provider.nil?
1064
+
1065
+ file_path = file_path.squeeze('/')
1066
+ outfile = File.expand_path(outfile)
1067
+ if Dir.exist?(outfile)
1068
+ outfile = File.join(outfile, File.basename(file_path))
1069
+ end
1070
+ if Dir.exist?(outfile)
1071
+ print_red_alert "[local-file] is invalid. It is the name of an existing directory: #{outfile}"
1072
+ return 1
1073
+ end
1074
+ destination_dir = File.dirname(outfile)
1075
+ if !Dir.exist?(destination_dir)
1076
+ if do_mkdir
1077
+ print cyan,"Creating local directory #{destination_dir}",reset,"\n"
1078
+ FileUtils.mkdir_p(destination_dir)
1079
+ else
1080
+ print_red_alert "[local-file] is invalid. Directory not found: #{destination_dir}"
1081
+ return 1
1082
+ end
1083
+ end
1084
+ if File.exist?(outfile)
1085
+ if do_overwrite
1086
+ # uhh need to be careful wih the passed filepath here..
1087
+ # don't delete, just overwrite.
1088
+ # File.delete(outfile)
1089
+ else
1090
+ print_error MtnCloud::Terminal.angry_prompt
1091
+ puts_error "[local-file] is invalid. File already exists: #{outfile}", "Use -f to overwrite the existing file."
1092
+ # puts_error optparse
1093
+ return 1
1094
+ end
1095
+ end
1096
+ begin
1097
+ @storage_providers_interface.setopts(options)
1098
+ if options[:dry_run]
1099
+ print_dry_run @storage_providers_interface.dry.download_file_chunked(storage_provider['id'], file_path, outfile), full_command_string
1100
+ return 0
1101
+ end
1102
+ if !options[:quiet]
1103
+ print cyan + "Downloading archive file #{storage_provider['name']}:#{file_path} to #{outfile} ... "
1104
+ end
1105
+
1106
+ http_response = @storage_providers_interface.download_file_chunked(storage_provider['id'], file_path, outfile)
1107
+
1108
+ # FileUtils.chmod(0600, outfile)
1109
+ success = http_response.code.to_i == 200
1110
+ if success
1111
+ if !options[:quiet]
1112
+ print green + "SUCCESS" + reset + "\n"
1113
+ end
1114
+ return 0
1115
+ else
1116
+ if !options[:quiet]
1117
+ print red + "ERROR" + reset + " HTTP #{http_response.code}" + "\n"
1118
+ end
1119
+ # F it, just remove a bad result
1120
+ if File.exist?(outfile) && File.file?(outfile)
1121
+ MtnCloud::Logging::DarkPrinter.puts "Deleting bad file download: #{outfile}" if MtnCloud::Logging.debug?
1122
+ File.delete(outfile)
1123
+ end
1124
+ if options[:debug]
1125
+ puts_error http_response.inspect
1126
+ end
1127
+ return 1
1128
+ end
1129
+ rescue RestClient::Exception => e
1130
+ # this is not reached
1131
+ if e.response && e.response.code == 404
1132
+ print_red_alert "Storage file not found by path #{file_path}"
1133
+ return nil
1134
+ else
1135
+ raise e
1136
+ end
1137
+ end
1138
+ rescue RestClient::Exception => e
1139
+ print_rest_exception(e, options)
1140
+ return 1
1141
+ end
1142
+
1143
+ end
1144
+
1145
+ def read_file(args)
1146
+ full_command_string = "#{command_name} read #{args.join(' ')}".strip
1147
+ options = {}
1148
+ outfile = nil
1149
+ do_overwrite = false
1150
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
1151
+ opts.banner = subcommand_usage("[provider:/path]")
1152
+ build_common_options(opts, options, [:dry_run])
1153
+ opts.footer = "Print the contents of a storage file.\n" +
1154
+ "[provider:/path] is required. This is the name or id of the provider and /path the file or folder to be downloaded.\n" +
1155
+ "This confirmation can be skipped with the -y option."
1156
+ end
1157
+ optparse.parse!(args)
1158
+ if args.count < 1 || args.count > 2
1159
+ print_error MtnCloud::Terminal.angry_prompt
1160
+ puts_error "#{command_name} read expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
1161
+ return 1
1162
+ end
1163
+ connect(options)
1164
+ begin
1165
+ storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
1166
+ storage_provider = find_storage_provider_by_name_or_id(storage_provider_id)
1167
+ return 1 if storage_provider.nil?
1168
+
1169
+ file_path = file_path.squeeze('/')
1170
+ @storage_providers_interface.setopts(options)
1171
+ if options[:dry_run]
1172
+ print_dry_run @storage_providers_interface.dry.download_file(storage_provider['id'], file_path), full_command_string
1173
+ return 1
1174
+ end
1175
+ file_response = @storage_providers_interface.download_file(storage_provider['id'], file_path)
1176
+ puts file_response.body.to_s
1177
+ return 0
1178
+ rescue RestClient::Exception => e
1179
+ print_rest_exception(e, options)
1180
+ return 1
1181
+ end
1182
+
1183
+ end
1184
+
1185
+ def remove_file(args)
1186
+ options = {}
1187
+ query_params = {}
1188
+ do_recursive = false
1189
+ optparse = MtnCloud::Cli::OptionParser.new do |opts|
1190
+ opts.banner = subcommand_usage("[provider:/path]")
1191
+ opts.on( '-R', '--recursive', "Delete a directory and all of its files. This must be passed if specifying a directory." ) do
1192
+ do_recursive = true
1193
+ end
1194
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run])
1195
+ opts.footer = "Delete a storage file or directory."
1196
+ end
1197
+ optparse.parse!(args)
1198
+ # consider only allowing args.count == 1 here in the format [provider:/path]
1199
+ if args.count < 1 || args.count > 2
1200
+ print_error MtnCloud::Terminal.angry_prompt
1201
+ puts_error "#{command_name} remove-file expects 1-2 arguments and received #{args.count}: #{args.join(' ')}\n#{optparse}"
1202
+ return 1
1203
+ end
1204
+ storage_provider_id, file_path = parse_storage_provider_id_and_file_path(args[0], args[1])
1205
+ connect(options)
1206
+ begin
1207
+
1208
+ storage_file = find_storage_file_by_bucket_and_path(storage_provider_id, file_path)
1209
+ return 1 if storage_file.nil?
1210
+ if storage_file['isDirectory']
1211
+ if !do_recursive
1212
+ print_error MtnCloud::Terminal.angry_prompt
1213
+ puts_error "bad argument: '#{file_path}' is a directory. Use -R or --recursive to delete a directory.\n#{optparse}"
1214
+ return 1
1215
+ end
1216
+ unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to delete the directory: #{args[0]}?")
1217
+ return 9, "aborted command"
1218
+ end
1219
+ else
1220
+ unless options[:yes] || MtnCloud::Cli::OptionTypes.confirm("Are you sure you want to delete the file: #{args[0]}?")
1221
+ return 9, "aborted command"
1222
+ end
1223
+ end
1224
+ @storage_providers_interface.setopts(options)
1225
+ if options[:dry_run]
1226
+ print_dry_run @storage_files_interface.dry.destroy(storage_file['id'], query_params)
1227
+ return 0
1228
+ end
1229
+ json_response = @storage_files_interface.destroy(storage_file['id'], query_params)
1230
+ if options[:json]
1231
+ print JSON.pretty_generate(json_response)
1232
+ print "\n"
1233
+ else
1234
+ print_green_success "Removed file #{args[0]}"
1235
+ end
1236
+ return 0
1237
+
1238
+ rescue RestClient::Exception => e
1239
+ print_rest_exception(e, options)
1240
+ return 1
1241
+ end
1242
+
1243
+ end
1244
+
1245
+ private
1246
+
1247
+ def storage_bucket_column_definitions()
1248
+ {
1249
+ "ID" => 'id',
1250
+ "Name" => 'name',
1251
+ # "Description" => 'description',
1252
+ "Provider Type" => lambda {|it| format_storage_provider_type(it) },
1253
+ "Bucket Name" => lambda {|it| format_bucket_name(it) },
1254
+ # "Source" => lambda {|it| it['source'] },
1255
+ "Backups" => lambda {|it| format_boolean(it['defaultBackupTarget']) },
1256
+ "Deployments" => lambda {|it| format_boolean(it['defaultDeploymentTarget']) },
1257
+ "Virtual Images" => lambda {|it| format_boolean(it['defaultVirtualImageTarget']) },
1258
+ # "Archive Snapshots" => lambda {|it| format_boolean(it['copyToStore']) },
1259
+ # "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
1260
+ # "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) },
1261
+ }
1262
+ end
1263
+
1264
+ def get_storage_provider_types()
1265
+ [
1266
+ {'name' => 'Amazon S3', 'value' => 'amazonS3'},
1267
+ {'name' => 'Alibaba', 'value' => 'alibaba'},
1268
+ {'name' => 'Azure', 'value' => 'azure'},
1269
+ {'name' => 'CIFS', 'value' => 'cifs'},
1270
+ {'name' => 'Local Storage', 'value' => 'local'},
1271
+ {'name' => 'NFSv3', 'value' => 'nfs'},
1272
+ {'name' => 'Openstack Swift', 'value' => 'openstack'},
1273
+ {'name' => 'Rackspace CDN', 'value' => 'rackspace'},
1274
+ {'name' => 'S3', 'value' => 's3'},
1275
+ ]
1276
+ end
1277
+
1278
+ def find_storage_provider_by_name_or_id(val)
1279
+ if val.to_s =~ /\A\d{1,}\Z/
1280
+ return find_storage_provider_by_id(val)
1281
+ else
1282
+ return find_storage_provider_by_name(val)
1283
+ end
1284
+ end
1285
+
1286
+ def find_storage_provider_by_id(id)
1287
+ begin
1288
+ json_response = @storage_providers_interface.get(id.to_i)
1289
+ return json_response['storageBucket']
1290
+ rescue RestClient::Exception => e
1291
+ if e.response && e.response.code == 404
1292
+ print_red_alert "Storage Bucket not found by id #{id}"
1293
+ return nil
1294
+ else
1295
+ raise e
1296
+ end
1297
+ end
1298
+ end
1299
+
1300
+ def find_storage_provider_by_name(name)
1301
+ json_response = @storage_providers_interface.list({name: name.to_s})
1302
+ storage_providers = json_response['storageBuckets']
1303
+ if storage_providers.empty?
1304
+ print_red_alert "Storage Bucket not found by name #{name}"
1305
+ return nil
1306
+ elsif storage_providers.size > 1
1307
+ print_red_alert "#{storage_providers.size} storage buckets found by name #{name}"
1308
+ rows = storage_providers.collect do |it|
1309
+ {id: it['id'], name: it['name']}
1310
+ end
1311
+ puts as_pretty_table(rows, [:id, :name], {color:red})
1312
+ return nil
1313
+ else
1314
+ return storage_providers[0]
1315
+ end
1316
+ end
1317
+
1318
+ def format_bucket_name(storage_provider)
1319
+ if storage_provider['providerType'] == 'local'
1320
+ storage_provider['config'] ? storage_provider['config']['basePath'] : ''
1321
+ else
1322
+ storage_provider['bucketName']
1323
+ end
1324
+ end
1325
+
1326
+ def format_storage_provider_type(storage_provider)
1327
+ storage_provider['providerType'].to_s.capitalize
1328
+ end
1329
+
1330
+ # parse_storage_provider_id_and_file_path() provides flexible argument formats for provider and path
1331
+ # it looks for [provider:/path] or [provider] [path]
1332
+ # @param delim [String] Default is a comma and any surrounding white space.
1333
+ # @return [Array] 2 elements, provider name (or id) and the file path.
1334
+ # The default file path is "/".
1335
+ # Examples:
1336
+ # parse_storage_provider_id_and_file_path("test") == ["test", "/"]
1337
+ # parse_storage_provider_id_and_file_path("test:/global.cfg") == ["test", "/global.cfg"]
1338
+ # parse_storage_provider_id_and_file_path("test:/node1/node.cfg") == ["test", "/node1/node.cfg"]
1339
+ # parse_storage_provider_id_and_file_path("test/node1/node.cfg") == ["test", "/node1/node.cfg"]
1340
+ # parse_storage_provider_id_and_file_path("test", "node1/node.cfg") == ["test", "/node1/node.cfg"]
1341
+ #
1342
+ def parse_storage_provider_id_and_file_path(*args)
1343
+ if args.size < 1 || args.size > 2
1344
+ return nil, nil
1345
+ end
1346
+ if !args[0]
1347
+ return nil, nil
1348
+ end
1349
+ full_path = args[0].to_s
1350
+ if args[1]
1351
+ if full_path.include?(":")
1352
+ full_path = "#{full_path}/#{args[1]}"
1353
+ else
1354
+ full_path = "#{full_path}:#{args[1]}"
1355
+ end
1356
+ end
1357
+ # ok fine, allow just id/filePath, without a colon.
1358
+ if !full_path.include?(":") && full_path.include?("/")
1359
+ path_elements = full_path.split("/")
1360
+ full_path = path_elements[0] + ":" + path_elements[1..-1].join("/")
1361
+ end
1362
+ uri_elements = full_path.split(":")
1363
+ storage_provider_id = uri_elements[0]
1364
+ file_path = uri_elements[1..-1].join("/") # [1]
1365
+ file_path = "/#{file_path}".squeeze("/")
1366
+ return storage_provider_id, file_path
1367
+ end
1368
+
1369
+ def format_filename(filename, options={})
1370
+ if options[:fullTree]
1371
+ filename.to_s
1372
+ else
1373
+ filename.to_s.split('/').last()
1374
+ end
1375
+ end
1376
+
1377
+ def print_storage_files_table(storage_files, options={})
1378
+ table_color = options[:color] || cyan
1379
+ rows = storage_files.collect do |storage_file|
1380
+ {
1381
+ id: storage_file['id'],
1382
+ name: format_filename(storage_file['name'], options),
1383
+ type: storage_file['isDirectory'] ? 'directory' : (storage_file['contentType']),
1384
+ size: storage_file['isDirectory'] ? '' : format_bytes(storage_file['contentLength']),
1385
+ lastUpdated: format_local_dt(storage_file['dateModified'])
1386
+ }
1387
+ end
1388
+ columns = [
1389
+ # :id,
1390
+ {:name => {:display_name => "File".upcase} },
1391
+ :type,
1392
+ :size,
1393
+ # {:dateCreated => {:display_name => "Date Created"} },
1394
+ {:lastUpdated => {:display_name => "Last Modified".upcase} }
1395
+ ]
1396
+ print table_color
1397
+ print as_pretty_table(rows, columns, options)
1398
+ print reset
1399
+ end
1400
+
1401
+ end