morpheus-cli 5.3.2.3 → 5.4.1

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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/account_users_interface.rb +68 -0
  4. data/lib/morpheus/api/api_client.rb +75 -8
  5. data/lib/morpheus/api/audit_interface.rb +9 -0
  6. data/lib/morpheus/api/clouds_interface.rb +4 -11
  7. data/lib/morpheus/api/health_interface.rb +37 -3
  8. data/lib/morpheus/api/instances_interface.rb +39 -5
  9. data/lib/morpheus/api/load_balancer_monitors_interface.rb +9 -0
  10. data/lib/morpheus/api/load_balancer_profiles_interface.rb +9 -0
  11. data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +9 -0
  12. data/lib/morpheus/api/load_balancers_interface.rb +5 -0
  13. data/lib/morpheus/api/network_dhcp_relays_interface.rb +36 -0
  14. data/lib/morpheus/api/network_dhcp_servers_interface.rb +36 -0
  15. data/lib/morpheus/api/network_edge_clusters_interface.rb +26 -0
  16. data/lib/morpheus/api/network_routers_interface.rb +30 -0
  17. data/lib/morpheus/api/network_servers_interface.rb +98 -0
  18. data/lib/morpheus/api/network_static_routes_interface.rb +36 -0
  19. data/lib/morpheus/api/read_interface.rb +4 -3
  20. data/lib/morpheus/api/rest_interface.rb +5 -4
  21. data/lib/morpheus/api/roles_interface.rb +7 -0
  22. data/lib/morpheus/api/secondary_read_interface.rb +1 -1
  23. data/lib/morpheus/api/secondary_rest_interface.rb +19 -19
  24. data/lib/morpheus/api/storage_server_types_interface.rb +14 -0
  25. data/lib/morpheus/api/storage_servers_interface.rb +9 -0
  26. data/lib/morpheus/api/storage_volume_types_interface.rb +9 -0
  27. data/lib/morpheus/api/storage_volumes_interface.rb +9 -0
  28. data/lib/morpheus/api/users_interface.rb +16 -63
  29. data/lib/morpheus/api/virtual_images_interface.rb +23 -2
  30. data/lib/morpheus/api/virtual_servers_interface.rb +9 -0
  31. data/lib/morpheus/cli/cli_command.rb +274 -19
  32. data/lib/morpheus/cli/cli_registry.rb +56 -2
  33. data/lib/morpheus/cli/{access_token_command.rb → commands/access_token_command.rb} +1 -1
  34. data/lib/morpheus/cli/{account_groups_command.rb → commands/account_groups_command.rb} +0 -8
  35. data/lib/morpheus/cli/{activity_command.rb → commands/activity_command.rb} +0 -0
  36. data/lib/morpheus/cli/commands/{standard/alias_command.rb → alias_command.rb} +1 -4
  37. data/lib/morpheus/cli/{appliance_settings_command.rb → commands/appliance_settings_command.rb} +0 -0
  38. data/lib/morpheus/cli/{approvals_command.rb → commands/approvals_command.rb} +0 -0
  39. data/lib/morpheus/cli/{apps.rb → commands/apps.rb} +17 -89
  40. data/lib/morpheus/cli/{archives_command.rb → commands/archives_command.rb} +0 -6
  41. data/lib/morpheus/cli/commands/audit.rb +188 -0
  42. data/lib/morpheus/cli/{backup_jobs_command.rb → commands/backup_jobs_command.rb} +0 -0
  43. data/lib/morpheus/cli/{backup_settings_command.rb → commands/backup_settings_command.rb} +0 -0
  44. data/lib/morpheus/cli/{backups_command.rb → commands/backups_command.rb} +0 -0
  45. data/lib/morpheus/cli/commands/{standard/benchmark_command.rb → benchmark_command.rb} +0 -3
  46. data/lib/morpheus/cli/{blueprints_command.rb → commands/blueprints_command.rb} +1 -1
  47. data/lib/morpheus/cli/{boot_scripts_command.rb → commands/boot_scripts_command.rb} +0 -3
  48. data/lib/morpheus/cli/{budgets_command.rb → commands/budgets_command.rb} +0 -0
  49. data/lib/morpheus/cli/commands/{standard/cat_command.rb → cat_command.rb} +0 -0
  50. data/lib/morpheus/cli/{catalog_item_types_command.rb → commands/catalog_item_types_command.rb} +0 -0
  51. data/lib/morpheus/cli/{certificates_command.rb → commands/certificates_command.rb} +0 -0
  52. data/lib/morpheus/cli/commands/change_password_command.rb +132 -0
  53. data/lib/morpheus/cli/{cloud_datastores_command.rb → commands/cloud_datastores_command.rb} +0 -4
  54. data/lib/morpheus/cli/{cloud_folders_command.rb → commands/cloud_folders_command.rb} +0 -4
  55. data/lib/morpheus/cli/{cloud_resource_pools_command.rb → commands/cloud_resource_pools_command.rb} +170 -138
  56. data/lib/morpheus/cli/{clouds.rb → commands/clouds.rb} +22 -47
  57. data/lib/morpheus/cli/{clusters.rb → commands/clusters.rb} +86 -49
  58. data/lib/morpheus/cli/commands/{standard/coloring_command.rb → coloring_command.rb} +0 -2
  59. data/lib/morpheus/cli/{containers_command.rb → commands/containers_command.rb} +0 -7
  60. data/lib/morpheus/cli/commands/{standard/curl_command.rb → curl_command.rb} +0 -3
  61. data/lib/morpheus/cli/{cypher_command.rb → commands/cypher_command.rb} +0 -1
  62. data/lib/morpheus/cli/{dashboard_command.rb → commands/dashboard_command.rb} +0 -2
  63. data/lib/morpheus/cli/commands/{standard/debug_command.rb → debug_command.rb} +0 -1
  64. data/lib/morpheus/cli/{deploy.rb → commands/deploy.rb} +0 -1
  65. data/lib/morpheus/cli/{deployments.rb → commands/deployments.rb} +0 -0
  66. data/lib/morpheus/cli/{deploys.rb → commands/deploys.rb} +0 -1
  67. data/lib/morpheus/cli/{doc.rb → commands/doc.rb} +1 -1
  68. data/lib/morpheus/cli/commands/{standard/echo_command.rb → echo_command.rb} +0 -2
  69. data/lib/morpheus/cli/commands/{standard/edit_profile_command.rb → edit_profile_command.rb} +15 -4
  70. data/lib/morpheus/cli/commands/{standard/edit_rc_command.rb → edit_rc_command.rb} +19 -3
  71. data/lib/morpheus/cli/{environments_command.rb → commands/environments_command.rb} +0 -5
  72. data/lib/morpheus/cli/{execute_schedules_command.rb → commands/execute_schedules_command.rb} +0 -0
  73. data/lib/morpheus/cli/{execution_request_command.rb → commands/execution_request_command.rb} +0 -2
  74. data/lib/morpheus/cli/commands/{standard/exit_command.rb → exit_command.rb} +0 -2
  75. data/lib/morpheus/cli/{file_copy_request_command.rb → commands/file_copy_request_command.rb} +0 -4
  76. data/lib/morpheus/cli/{forgot_password.rb → commands/forgot_password.rb} +0 -0
  77. data/lib/morpheus/cli/commands/{standard/get_prompt_command.rb → get_prompt_command.rb} +0 -3
  78. data/lib/morpheus/cli/{groups.rb → commands/groups.rb} +0 -7
  79. data/lib/morpheus/cli/{guidance_command.rb → commands/guidance_command.rb} +1 -1
  80. data/lib/morpheus/cli/{health_command.rb → commands/health_command.rb} +104 -19
  81. data/lib/morpheus/cli/commands/{standard/history_command.rb → history_command.rb} +0 -3
  82. data/lib/morpheus/cli/{hosts.rb → commands/hosts.rb} +15 -25
  83. data/lib/morpheus/cli/{image_builder_command.rb → commands/image_builder_command.rb} +2 -8
  84. data/lib/morpheus/cli/{instance_types.rb → commands/instance_types.rb} +0 -3
  85. data/lib/morpheus/cli/{instances.rb → commands/instances.rb} +473 -150
  86. data/lib/morpheus/cli/{integrations_command.rb → commands/integrations_command.rb} +0 -0
  87. data/lib/morpheus/cli/{invoices_command.rb → commands/invoices_command.rb} +118 -134
  88. data/lib/morpheus/cli/{jobs_command.rb → commands/jobs_command.rb} +0 -0
  89. data/lib/morpheus/cli/{key_pairs.rb → commands/key_pairs.rb} +0 -6
  90. data/lib/morpheus/cli/{library_cluster_layouts_command.rb → commands/library_cluster_layouts_command.rb} +20 -4
  91. data/lib/morpheus/cli/{library_container_scripts_command.rb → commands/library_container_scripts_command.rb} +0 -0
  92. data/lib/morpheus/cli/{library_container_templates_command.rb → commands/library_container_templates_command.rb} +0 -1
  93. data/lib/morpheus/cli/{library_container_types_command.rb → commands/library_container_types_command.rb} +0 -4
  94. data/lib/morpheus/cli/{library_instance_types_command.rb → commands/library_instance_types_command.rb} +0 -4
  95. data/lib/morpheus/cli/{library_layouts_command.rb → commands/library_layouts_command.rb} +0 -4
  96. data/lib/morpheus/cli/{library_option_lists_command.rb → commands/library_option_lists_command.rb} +3 -7
  97. data/lib/morpheus/cli/{library_option_types_command.rb → commands/library_option_types_command.rb} +0 -4
  98. data/lib/morpheus/cli/{library_spec_templates_command.rb → commands/library_spec_templates_command.rb} +0 -1
  99. data/lib/morpheus/cli/{library_upgrades_command.rb → commands/library_upgrades_command.rb} +0 -4
  100. data/lib/morpheus/cli/{license.rb → commands/license.rb} +0 -3
  101. data/lib/morpheus/cli/commands/load_balancer_monitors.rb +71 -0
  102. data/lib/morpheus/cli/commands/load_balancer_pools.rb +91 -0
  103. data/lib/morpheus/cli/commands/load_balancer_profiles.rb +65 -0
  104. data/lib/morpheus/cli/{load_balancer_types.rb → commands/load_balancer_types.rb} +9 -8
  105. data/lib/morpheus/cli/commands/load_balancer_virtual_servers.rb +156 -0
  106. data/lib/morpheus/cli/commands/load_balancers.rb +176 -0
  107. data/lib/morpheus/cli/commands/{standard/log_level_command.rb → log_level_command.rb} +0 -3
  108. data/lib/morpheus/cli/{log_settings_command.rb → commands/log_settings_command.rb} +0 -0
  109. data/lib/morpheus/cli/{login.rb → commands/login.rb} +0 -5
  110. data/lib/morpheus/cli/commands/logout.rb +63 -0
  111. data/lib/morpheus/cli/{logs_command.rb → commands/logs_command.rb} +0 -3
  112. data/lib/morpheus/cli/commands/{standard/man_command.rb → man_command.rb} +0 -2
  113. data/lib/morpheus/cli/{monitoring_alerts_command.rb → commands/monitoring_alerts_command.rb} +0 -7
  114. data/lib/morpheus/cli/{monitoring_apps_command.rb → commands/monitoring_apps_command.rb} +0 -1
  115. data/lib/morpheus/cli/{monitoring_checks_command.rb → commands/monitoring_checks_command.rb} +2 -1
  116. data/lib/morpheus/cli/{monitoring_contacts_command.rb → commands/monitoring_contacts_command.rb} +0 -7
  117. data/lib/morpheus/cli/{monitoring_groups_command.rb → commands/monitoring_groups_command.rb} +0 -1
  118. data/lib/morpheus/cli/{monitoring_incidents_command.rb → commands/monitoring_incidents_command.rb} +0 -1
  119. data/lib/morpheus/cli/commands/network_dhcp_relays_command.rb +416 -0
  120. data/lib/morpheus/cli/commands/network_dhcp_servers_command.rb +407 -0
  121. data/lib/morpheus/cli/{network_domains_command.rb → commands/network_domains_command.rb} +0 -4
  122. data/lib/morpheus/cli/commands/network_edge_clusters_command.rb +329 -0
  123. data/lib/morpheus/cli/commands/network_firewalls_command.rb +823 -0
  124. data/lib/morpheus/cli/{network_groups_command.rb → commands/network_groups_command.rb} +0 -4
  125. data/lib/morpheus/cli/{network_pool_servers_command.rb → commands/network_pool_servers_command.rb} +0 -4
  126. data/lib/morpheus/cli/{network_pools_command.rb → commands/network_pools_command.rb} +0 -4
  127. data/lib/morpheus/cli/{network_proxies_command.rb → commands/network_proxies_command.rb} +0 -4
  128. data/lib/morpheus/cli/{network_routers_command.rb → commands/network_routers_command.rb} +387 -57
  129. data/lib/morpheus/cli/{network_services_command.rb → commands/network_services_command.rb} +0 -4
  130. data/lib/morpheus/cli/commands/network_static_routes_command.rb +446 -0
  131. data/lib/morpheus/cli/commands/network_transport_zones_command.rb +452 -0
  132. data/lib/morpheus/cli/{networks_command.rb → commands/networks_command.rb} +21 -21
  133. data/lib/morpheus/cli/commands/open_command.rb +30 -0
  134. data/lib/morpheus/cli/commands/options.rb +98 -0
  135. data/lib/morpheus/cli/{packages_command.rb → commands/packages_command.rb} +0 -2
  136. data/lib/morpheus/cli/{ping.rb → commands/ping.rb} +0 -7
  137. data/lib/morpheus/cli/{policies_command.rb → commands/policies_command.rb} +1 -8
  138. data/lib/morpheus/cli/{power_schedules_command.rb → commands/power_schedules_command.rb} +0 -0
  139. data/lib/morpheus/cli/{preseed_scripts_command.rb → commands/preseed_scripts_command.rb} +0 -3
  140. data/lib/morpheus/cli/{price_sets_command.rb → commands/price_sets_command.rb} +0 -0
  141. data/lib/morpheus/cli/{prices_command.rb → commands/prices_command.rb} +7 -7
  142. data/lib/morpheus/cli/{processes_command.rb → commands/processes_command.rb} +0 -1
  143. data/lib/morpheus/cli/{projects_command.rb → commands/projects_command.rb} +0 -0
  144. data/lib/morpheus/cli/{provisioning_licenses_command.rb → commands/provisioning_licenses_command.rb} +0 -0
  145. data/lib/morpheus/cli/{provisioning_settings_command.rb → commands/provisioning_settings_command.rb} +0 -0
  146. data/lib/morpheus/cli/{recent_activity_command.rb → commands/recent_activity_command.rb} +0 -0
  147. data/lib/morpheus/cli/{remote.rb → commands/remote.rb} +5 -9
  148. data/lib/morpheus/cli/{reports_command.rb → commands/reports_command.rb} +0 -2
  149. data/lib/morpheus/cli/commands/{standard/rm_command.rb → rm_command.rb} +0 -0
  150. data/lib/morpheus/cli/{roles.rb → commands/roles.rb} +245 -40
  151. data/lib/morpheus/cli/{search_command.rb → commands/search_command.rb} +0 -0
  152. data/lib/morpheus/cli/{security_group_rules.rb → commands/security_group_rules.rb} +0 -5
  153. data/lib/morpheus/cli/{security_groups.rb → commands/security_groups.rb} +0 -6
  154. data/lib/morpheus/cli/{service_catalog_command.rb → commands/service_catalog_command.rb} +0 -0
  155. data/lib/morpheus/cli/{service_plans_command.rb → commands/service_plans_command.rb} +0 -0
  156. data/lib/morpheus/cli/commands/{standard/set_prompt_command.rb → set_prompt_command.rb} +0 -3
  157. data/lib/morpheus/cli/{setup.rb → commands/setup.rb} +0 -0
  158. data/lib/morpheus/cli/{shell.rb → commands/shell.rb} +4 -105
  159. data/lib/morpheus/cli/commands/{standard/sleep_command.rb → sleep_command.rb} +0 -2
  160. data/lib/morpheus/cli/commands/{standard/source_command.rb → source_command.rb} +0 -2
  161. data/lib/morpheus/cli/commands/{standard/ssl_verification_command.rb → ssl_verification_command.rb} +0 -3
  162. data/lib/morpheus/cli/{storage_providers_command.rb → commands/storage_providers_command.rb} +0 -4
  163. data/lib/morpheus/cli/commands/storage_server_types.rb +50 -0
  164. data/lib/morpheus/cli/commands/storage_servers.rb +122 -0
  165. data/lib/morpheus/cli/commands/storage_volume_types.rb +50 -0
  166. data/lib/morpheus/cli/commands/storage_volumes.rb +103 -0
  167. data/lib/morpheus/cli/{subnets_command.rb → commands/subnets_command.rb} +7 -6
  168. data/lib/morpheus/cli/{tasks.rb → commands/tasks.rb} +25 -6
  169. data/lib/morpheus/cli/commands/{standard/tee_command.rb → tee_command.rb} +0 -0
  170. data/lib/morpheus/cli/{tenants_command.rb → commands/tenants_command.rb} +1 -8
  171. data/lib/morpheus/cli/commands/{standard/update_command.rb → update_command.rb} +0 -1
  172. data/lib/morpheus/cli/{usage_command.rb → commands/usage_command.rb} +0 -0
  173. data/lib/morpheus/cli/{user_groups_command.rb → commands/user_groups_command.rb} +1 -2
  174. data/lib/morpheus/cli/{user_settings_command.rb → commands/user_settings_command.rb} +2 -1
  175. data/lib/morpheus/cli/{user_sources_command.rb → commands/user_sources_command.rb} +1 -2
  176. data/lib/morpheus/cli/{users.rb → commands/users.rb} +28 -35
  177. data/lib/morpheus/cli/{vdi_allocations_command.rb → commands/vdi_allocations_command.rb} +0 -0
  178. data/lib/morpheus/cli/{vdi_apps_command.rb → commands/vdi_apps_command.rb} +0 -0
  179. data/lib/morpheus/cli/{vdi_command.rb → commands/vdi_command.rb} +0 -0
  180. data/lib/morpheus/cli/{vdi_gateways_command.rb → commands/vdi_gateways_command.rb} +0 -0
  181. data/lib/morpheus/cli/{vdi_pools_command.rb → commands/vdi_pools_command.rb} +4 -1
  182. data/lib/morpheus/cli/commands/{standard/version_command.rb → version_command.rb} +0 -0
  183. data/lib/morpheus/cli/commands/view.rb +102 -0
  184. data/lib/morpheus/cli/{virtual_images.rb → commands/virtual_images.rb} +251 -33
  185. data/lib/morpheus/cli/{whitelabel_settings_command.rb → commands/whitelabel_settings_command.rb} +0 -1
  186. data/lib/morpheus/cli/{whoami.rb → commands/whoami.rb} +0 -4
  187. data/lib/morpheus/cli/{wiki_command.rb → commands/wiki_command.rb} +0 -5
  188. data/lib/morpheus/cli/{workflows.rb → commands/workflows.rb} +0 -3
  189. data/lib/morpheus/cli/mixins/accounts_helper.rb +5 -5
  190. data/lib/morpheus/cli/mixins/load_balancers_helper.rb +26 -6
  191. data/lib/morpheus/cli/mixins/logs_helper.rb +1 -1
  192. data/lib/morpheus/cli/mixins/print_helper.rb +51 -18
  193. data/lib/morpheus/cli/mixins/processes_helper.rb +1 -2
  194. data/lib/morpheus/cli/mixins/provisioning_helper.rb +167 -110
  195. data/lib/morpheus/cli/mixins/rest_command.rb +268 -94
  196. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +668 -0
  197. data/lib/morpheus/cli/mixins/storage_servers_helper.rb +156 -0
  198. data/lib/morpheus/cli/mixins/storage_volumes_helper.rb +119 -0
  199. data/lib/morpheus/cli/option_parser.rb +25 -17
  200. data/lib/morpheus/cli/option_types.rb +137 -52
  201. data/lib/morpheus/cli/version.rb +1 -1
  202. data/lib/morpheus/cli.rb +6 -128
  203. data/lib/morpheus/ext/string.rb +29 -6
  204. data/lib/morpheus/routes.rb +238 -0
  205. data/lib/morpheus/terminal.rb +5 -6
  206. data/lib/morpheus/util.rb +6 -1
  207. data/morpheus-cli.gemspec +1 -1
  208. metadata +183 -149
  209. data/lib/morpheus/cli/change_password_command.rb +0 -147
  210. data/lib/morpheus/cli/library.rb +0 -1
  211. data/lib/morpheus/cli/load_balancers.rb +0 -245
  212. data/lib/morpheus/cli/logout.rb +0 -81
@@ -0,0 +1,452 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::NetworkTransportZonesCommand
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::ProvisioningHelper
6
+ include Morpheus::Cli::WhoamiHelper
7
+
8
+ set_command_name :'network-transport-zones'
9
+ register_subcommands :list, :get, :add, :update, :remove
10
+
11
+ def connect(opts)
12
+ @api_client = establish_remote_appliance_connection(opts)
13
+ @account_interface = @api_client.accounts
14
+ @network_servers_interface = @api_client.network_servers
15
+ @options_interface = @api_client.options
16
+ end
17
+
18
+ def handle(args)
19
+ handle_subcommand(args)
20
+ end
21
+
22
+ def list(args)
23
+ options = {}
24
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
25
+ opts.banner = subcommand_usage("[server]")
26
+ build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote])
27
+ opts.footer = "List network transport zones." + "\n" +
28
+ "[server] is optional. This is the name or id of a network server."
29
+ end
30
+
31
+ optparse.parse!(args)
32
+ connect(options)
33
+
34
+ if args.count > 1
35
+ print_error Morpheus::Terminal.angry_prompt
36
+ puts_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
37
+ return 1
38
+ end
39
+
40
+ server_id = args.count > 0 ? args[0] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkServer', 'type' => 'select', 'fieldLabel' => 'Network Server', 'selectOptions' => search_network_servers.collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Network Server.'}],options[:options],@api_client,{})['networkServer']
41
+ server = find_network_server(server_id)
42
+ return 1 if server.nil?
43
+
44
+ _list(server, options)
45
+ end
46
+
47
+ def _list(server, options)
48
+ params = parse_list_options(options)
49
+ @network_servers_interface.setopts(options)
50
+
51
+ if options[:dry_run]
52
+ print_dry_run @network_servers_interface.dry.list_scopes(server['id'], params)
53
+ return
54
+ end
55
+
56
+ if server['type']['hasScopes']
57
+ json_response = @network_servers_interface.list_scopes(server['id'], params)
58
+ render_response(json_response, options, 'networkScopes') do
59
+ print_h1 "Network transport zones For: #{server['name']}"
60
+ print cyan
61
+ print_scopes(server, json_response['networkScopes'])
62
+ end
63
+ else
64
+ print_red_alert "Transport zones not supported for #{server['type']['name']}"
65
+ end
66
+ print reset
67
+ end
68
+
69
+ def get(args)
70
+ options = {}
71
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
72
+ opts.banner = subcommand_usage("[server] [transport zone]")
73
+ build_common_options(opts, options, [:json, :yaml, :csv, :fields, :dry_run, :remote])
74
+ opts.footer = "Display details on a network transport zone." + "\n" +
75
+ "[server] is optional. This is the name or id of a network server.\n" +
76
+ "[transport zone] is optional. This is the id of a network transport zone.\n"
77
+ end
78
+
79
+ optparse.parse!(args)
80
+ connect(options)
81
+
82
+ if args.count > 2
83
+ print_error Morpheus::Terminal.angry_prompt
84
+ puts_error "wrong number of arguments, expected 0-2 and got (#{args.count}) #{args.inspect}\n#{optparse}"
85
+ return 1
86
+ end
87
+
88
+ server_id = args.count > 0 ? args[0] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkServer', 'type' => 'select', 'fieldLabel' => 'Network Server', 'selectOptions' => search_network_servers.collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Network Server.'}],options[:options],@api_client,{})['networkServer']
89
+ server = find_network_server(server_id)
90
+ return 1 if server.nil?
91
+
92
+ scope_id = args.count > 1 ? args[1] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'rule', 'type' => 'select', 'fieldLabel' => 'Transport Zone', 'selectOptions' => search_scopes(server['id']).collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Transport Zone.'}],options[:options],@api_client,{})['rule']
93
+
94
+ _get(server, scope_id, options)
95
+ end
96
+
97
+ def _get(server, scope_id, options)
98
+ params = parse_list_options(options)
99
+ @network_servers_interface.setopts(options)
100
+
101
+ if options[:dry_run]
102
+ if scope_id.to_s =~ /\A\d{1,}\Z/
103
+ print_dry_run @network_servers_interface.dry.get_scope(server['id'], scope_id.to_i, params)
104
+ else
105
+ print_dry_run @network_servers_interface.dry.list_scopes(server['id'], {name: scope_id}, params)
106
+ end
107
+ return
108
+ end
109
+
110
+ if server['type']['hasScopes']
111
+ scope = find_scope(server['id'], scope_id)
112
+
113
+ return 1 if scope.nil?
114
+
115
+ render_response({networkScope: scope}, options, 'networkScope') do
116
+ print_h1 "Network Transport Zone Details"
117
+ print cyan
118
+
119
+ description_cols = {
120
+ "ID" => lambda {|it| it['id']},
121
+ "Name" => lambda {|it| it['name']},
122
+ "Description" => lambda {|it| it['description']},
123
+ "Status" => lambda {|it| it['status']}
124
+ }
125
+
126
+ if is_master_account
127
+ description_cols["Visibility"] = lambda {|it| it['visibility']}
128
+ description_cols["Tenants"] = lambda {|it| it['tenants'].collect {|tenant| tenant['name']}.join(', ')}
129
+ end
130
+
131
+ server['type']['scopeOptionTypes'].reject {|it| it['type'] == 'hidden'}.sort_by {|it| it['displayOrder']}.each do |option_type|
132
+ description_cols[option_type['fieldLabel']] = lambda {|it| Morpheus::Cli::OptionTypes.get_option_value(it, option_type, true)}
133
+ end
134
+ print_description_list(description_cols, scope)
135
+ end
136
+ else
137
+ print_red_alert "Transport zones not supported for #{server['type']['name']}"
138
+ end
139
+ println reset
140
+ end
141
+
142
+ def add(args)
143
+ options = {:options=>{}}
144
+ params = {}
145
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
146
+ opts.banner = subcommand_usage("[server]")
147
+ opts.on('-n', '--name VALUE', String, "Name" ) do |val|
148
+ options[:options]['name'] = val.to_s
149
+ end
150
+ opts.on('-D', '--description VALUE', String, "Description") do |val|
151
+ options[:options]['description'] = val.to_s
152
+ end
153
+ add_perms_options(opts, options, ['plans', 'groups'])
154
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
155
+ opts.footer = "Create a network transport zone." + "\n" +
156
+ "[server] is optional. This is the name or id of a network server.\n";
157
+ end
158
+ optparse.parse!(args)
159
+ connect(options)
160
+
161
+ if args.count > 1
162
+ print_error Morpheus::Terminal.angry_prompt
163
+ puts_error "wrong number of arguments, expected 0-1 and got (#{args.count}) #{args.inspect}\n#{optparse}"
164
+ return 1
165
+ end
166
+
167
+ server_id = args.count > 0 ? args[0] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkServer', 'type' => 'select', 'fieldLabel' => 'Network Server', 'selectOptions' => search_network_servers.collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Network Server.'}],options[:options],@api_client,{})['networkServer']
168
+ server = find_network_server(server_id)
169
+ return 1 if server.nil?
170
+
171
+ if !server['type']['hasScopes']
172
+ print_red_alert "Transport zones not supported for #{server['type']['name']}"
173
+ return 1
174
+ end
175
+
176
+ if options[:payload]
177
+ payload = options[:payload]
178
+ else
179
+ params['name'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'type' => 'text', 'fieldLabel' => 'Name', 'required' => true, 'description' => 'Name.'}],options[:options],@api_client,{})['name']
180
+ params['description'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'type' => 'text', 'fieldLabel' => 'Description', 'required' => false, 'description' => 'Description.'}],options[:options],@api_client,{})['description']
181
+
182
+ option_types = server['type']['scopeOptionTypes'].sort_by {|it| it['displayOrder']}
183
+
184
+ # prompt options
185
+ option_result = Morpheus::Cli::OptionTypes.prompt(option_types, options[:options].deep_merge({:context_map => {'scope' => ''}}), @api_client, {'networkServerId' => server['id']}, nil, true)
186
+
187
+ # prompt permissions
188
+ perms = prompt_permissions(options, ['plans', 'groups'])
189
+ perms = {'visibility' => perms['resourcePool']['visibility'], 'tenants' => perms['tenantPermissions']['accounts'].collect {|it| {'id' => it}}}
190
+ payload = {'networkScope' => params.deep_merge(option_result).deep_merge(perms)}
191
+ end
192
+
193
+ @network_servers_interface.setopts(options)
194
+
195
+ if options[:dry_run]
196
+ print_dry_run @network_servers_interface.dry.create_scope(server['id'], payload)
197
+ return
198
+ end
199
+
200
+ json_response = @network_servers_interface.create_scope(server['id'], payload)
201
+ render_response(json_response, options, 'networkScope') do
202
+ print_green_success "\nAdded Network Transport Zone #{json_response['id']}\n"
203
+ _get(server, json_response['id'], options)
204
+ end
205
+ end
206
+
207
+ def update(args)
208
+ options = {:options=>{}}
209
+ params = {}
210
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
211
+ opts.banner = subcommand_usage("[server] [transport zone]")
212
+ opts.on('-n', '--name VALUE', String, "Name" ) do |val|
213
+ options[:options]['name'] = val.to_s
214
+ end
215
+ opts.on('-D', '--description VALUE', String, "Description") do |val|
216
+ options[:options]['description'] = val.to_s
217
+ end
218
+ add_perms_options(opts, options, ['plans', 'groups'])
219
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote])
220
+ opts.footer = "Update a network transport zone.\n" +
221
+ "[server] is optional. This is the name or id of an existing network server.\n" +
222
+ "[transport zone] is optional. This is the name or id of an existing network transport zone."
223
+ end
224
+ optparse.parse!(args)
225
+ if args.count > 2
226
+ raise_command_error "wrong number of arguments, expected 0-2 and got (#{args.count}) #{args}\n#{optparse}"
227
+ end
228
+ connect(options)
229
+
230
+ server_id = args.count > 0 ? args[0] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkServer', 'type' => 'select', 'fieldLabel' => 'Network Server', 'selectOptions' => search_network_servers.collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Network Server.'}],options[:options],@api_client,{})['networkServer']
231
+ server = find_network_server(server_id)
232
+ return 1 if server.nil?
233
+
234
+ if !server['type']['hasScopes']
235
+ print_red_alert "Transport zones not supported for #{server['type']['name']}"
236
+ return 1
237
+ end
238
+
239
+ scope_id = args.count > 1 ? args[1] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'scope', 'type' => 'select', 'fieldLabel' => 'Transport Zone', 'selectOptions' => search_scopes(server['id']).collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Transport Zone.'}],options[:options],@api_client,{})['scope']
240
+ scope = find_scope(server['id'], scope_id)
241
+ return 1 if scope.nil?
242
+
243
+ payload = parse_payload(options) || {'networkScope' => params}
244
+ payload['networkScope'].deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options] && !payload['networkScope'].nil?
245
+
246
+ if !options[:visibility].nil?
247
+ payload['networkScope']['visibility'] = options[:visibility]
248
+ end
249
+ if !options[:tenants].nil?
250
+ payload['networkScope']['tenants'] = options[:tenants].collect {|id| {id: id.to_i}}
251
+ end
252
+
253
+ if payload['networkScope'].empty?
254
+ option_types = server['type']['scopeOptionTypes'].sort_by {|it| it['displayOrder']}
255
+ print_green_success "Nothing to update"
256
+ println cyan
257
+ edit_option_types = option_types.reject {|it| !it['editable'] || !it['showOnEdit']}
258
+
259
+ if edit_option_types.count > 0
260
+ print Morpheus::Cli::OptionTypes.display_option_types_help(
261
+ option_types,
262
+ {:include_context => true, :context_map => {'scope' => ''}, :color => cyan, :title => "Available Transport Zone Options"}
263
+ )
264
+ end
265
+ exit 1
266
+ end
267
+
268
+ #payload = {'networkScope' => scope.deep_merge(payload['networkScope'])}
269
+
270
+ @network_servers_interface.setopts(options)
271
+
272
+ if options[:dry_run]
273
+ print_dry_run @network_servers_interface.dry.update_scope(server['id'], scope['id'], payload)
274
+ return
275
+ end
276
+
277
+ json_response = @network_servers_interface.update_scope(server['id'], scope['id'], payload)
278
+ render_response(json_response, options, 'networkScope') do
279
+ print_green_success "\nUpdated Network Transport Zone #{scope['id']}\n"
280
+ _get(server, scope['id'], options)
281
+ end
282
+ end
283
+
284
+ def remove(args)
285
+ options = {}
286
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
287
+ opts.banner = subcommand_usage("[server] [transport zone]")
288
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote])
289
+ opts.footer = "Delete a network transport zone.\n" +
290
+ "[server] is optional. This is the name or id of an existing network server.\n" +
291
+ "[transport zone] is optional. This is the name or id of an existing network transport zone."
292
+ end
293
+ optparse.parse!(args)
294
+ if args.count > 2
295
+ raise_command_error "wrong number of arguments, expected 0-2 and got (#{args.count}) #{args}\n#{optparse}"
296
+ end
297
+ connect(options)
298
+
299
+ server_id = args.count > 0 ? args[0] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'networkServer', 'type' => 'select', 'fieldLabel' => 'Network Server', 'selectOptions' => search_network_servers.collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Network Server.'}],options[:options],@api_client,{})['networkServer']
300
+ server = find_network_server(server_id)
301
+ return 1 if server.nil?
302
+
303
+ if !server['type']['hasScopes']
304
+ print_red_alert "Transport zones not supported for #{server['type']['name']}"
305
+ return 1
306
+ end
307
+
308
+ scope_id = args.count > 1 ? args[1] : Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'scope', 'type' => 'select', 'fieldLabel' => 'Transport Zone', 'selectOptions' => search_scopes(server['id']).collect {|it| {'name' => it['name'], 'value' => it['id']}}, 'required' => true, 'description' => 'Select Transport Zone.'}],options[:options],@api_client,{})['scope']
309
+ scope = find_scope(server['id'], scope_id)
310
+ return 1 if scope.nil?
311
+
312
+ unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove the network transport zone '#{scope['name']}' from server '#{server['name']}'?", options)
313
+ return 9, "aborted command"
314
+ end
315
+
316
+ @network_servers_interface.setopts(options)
317
+
318
+ if options[:dry_run]
319
+ print_dry_run @network_servers_interface.dry.destroy_scope(server['id'], scope['id'])
320
+ return
321
+ end
322
+ json_response = @network_servers_interface.destroy_scope(server['id'], scope['id'])
323
+ render_response(json_response, options, 'networkScope') do
324
+ print_green_success "\nDeleted Network Transport Zone #{scope['name']}\n"
325
+ _list(server, options)
326
+ end
327
+ end
328
+
329
+ private
330
+
331
+ def print_scopes(server, scopes)
332
+ if scopes.count > 0
333
+ cols = [:id, :name, :description, :status]
334
+ server['type']['scopeOptionTypes'].sort_by {|it| it['displayOrder']}.each do |option_type|
335
+ cols << option_type['fieldLabel']
336
+ end
337
+ cols += [:visibility, :tenants] if is_master_account
338
+ rows = scopes.collect do |it|
339
+ row = {
340
+ id: it['id'],
341
+ name: it['name'],
342
+ description: it['description'],
343
+ status: it['statusMessage'],
344
+ }
345
+ server['type']['scopeOptionTypes'].sort_by {|it| it['displayOrder']}.each do |option_type|
346
+ row[option_type['fieldLabel']] = Morpheus::Cli::OptionTypes.get_option_value(it, option_type, true)
347
+ end
348
+ if is_master_account
349
+ row = row.merge({
350
+ visibility: it['visibility'],
351
+ tenants: it['tenants'].collect {|it| it['name']}.join(', ')
352
+ })
353
+ end
354
+ row
355
+ end
356
+ puts as_pretty_table(rows, cols)
357
+ else
358
+ println "No transport zones\n"
359
+ end
360
+ end
361
+
362
+ def find_network_server(val)
363
+ if val.to_s =~ /\A\d{1,}\Z/
364
+ return find_network_server_by_id(val)
365
+ else
366
+ if server = find_network_server_by_name(val)
367
+ return find_network_server_by_id(server['id'])
368
+ end
369
+ end
370
+ end
371
+
372
+ def find_network_server_by_id(id)
373
+ begin
374
+ json_response = @network_servers_interface.get(id.to_i)
375
+ return json_response['networkServer']
376
+ rescue RestClient::Exception => e
377
+ if e.response && e.response.code == 404
378
+ print_red_alert "Network Server not found by id #{id}"
379
+ return nil
380
+ else
381
+ raise e
382
+ end
383
+ end
384
+ end
385
+
386
+ def find_network_server_by_name(name)
387
+ servers = search_network_servers(name)
388
+ if servers.empty?
389
+ print_red_alert "Network Server not found by name #{name}"
390
+ return nil
391
+ elsif servers.size > 1
392
+ print_red_alert "#{servers.size} network servers found by name #{name}"
393
+ rows = servers.collect do |it|
394
+ {id: it['id'], name: it['name']}
395
+ end
396
+ puts as_pretty_table(rows, [:id, :name], {color:red})
397
+ return nil
398
+ else
399
+ return servers[0]
400
+ end
401
+ end
402
+
403
+ def search_network_servers(phrase = nil)
404
+ @network_servers_interface.list(phrase ? {phrase: phrase.to_s} : {})['networkServers']
405
+ end
406
+
407
+ def find_scope(server_id, val)
408
+ if val.to_s =~ /\A\d{1,}\Z/
409
+ return find_scope_by_id(server_id, val)
410
+ else
411
+ if scope = find_scope_by_name(server_id, val)
412
+ return find_scope_by_id(server_id, scope['id'])
413
+ end
414
+ end
415
+ end
416
+
417
+ def find_scope_by_id(server_id, scope_id)
418
+ begin
419
+ json_response = @network_servers_interface.get_scope(server_id, scope_id.to_i)
420
+ return json_response['networkScope']
421
+ rescue RestClient::Exception => e
422
+ if e.response && e.response.code == 404
423
+ print_red_alert "Network transport zone not found by id #{scope_id}"
424
+ return nil
425
+ else
426
+ raise e
427
+ end
428
+ end
429
+ end
430
+
431
+ def find_scope_by_name(server_id, name)
432
+ scopes = search_scopes(server_id, name)
433
+ if scopes.empty?
434
+ print_red_alert "Network transport zone not found by name #{name}"
435
+ return nil
436
+ elsif scopes.size > 1
437
+ print_red_alert "#{scopes.size} network transport zones found by name #{name}"
438
+ rows = scopes.collect do |it|
439
+ {id: it['id'], name: it['name']}
440
+ end
441
+ puts as_pretty_table(rows, [:id, :name], {color:red})
442
+ return nil
443
+ else
444
+ return scopes[0]
445
+ end
446
+ end
447
+
448
+ def search_scopes(server_id, phrase = nil)
449
+ @network_servers_interface.list_scopes(server_id, phrase ? {phrase: phrase.to_s} : {})['networkScopes']
450
+ end
451
+
452
+ end
@@ -1,8 +1,4 @@
1
- require 'rest_client'
2
- require 'optparse'
3
- require 'filesize'
4
1
  require 'morpheus/cli/cli_command'
5
- require 'morpheus/cli/mixins/infrastructure_helper'
6
2
 
7
3
  class Morpheus::Cli::NetworksCommand
8
4
  include Morpheus::Cli::CliCommand
@@ -510,7 +506,7 @@ class Morpheus::Cli::NetworksCommand
510
506
  print_red_alert "Network Type not found by id '#{network_type_id}'"
511
507
  return 1
512
508
  end
513
-
509
+
514
510
  if network_type['hasNetworkServer']
515
511
  api_params = {networkType: {id: network_type['id']}}
516
512
 
@@ -617,9 +613,10 @@ class Morpheus::Cli::NetworksCommand
617
613
  if network_type_option_types && network_type_option_types.size > 0
618
614
  api_params = {}
619
615
  api_params['network.site.id'] = group ? group['id'] : 'shared'
616
+ api_params['network.zone.id'] = cloud['id'] if !cloud.nil?
620
617
  api_params['network.type.id'] = network_type['id']
621
618
  api_params['network.networkServer.id'] = network_server_id if !network_server_id.nil?
622
- network_type_params = Morpheus::Cli::OptionTypes.prompt(network_type_option_types,options[:options],@api_client, api_params)
619
+ network_type_params = Morpheus::Cli::OptionTypes.prompt(network_type_option_types,(options[:options] || {}).merge(payload),@api_client, api_params)
623
620
  # network context options belong at network level and not network.network
624
621
  network_context_params = network_type_params.delete('network')
625
622
  payload['network'].deep_merge!(network_context_params) if network_context_params
@@ -627,7 +624,7 @@ class Morpheus::Cli::NetworksCommand
627
624
  end
628
625
 
629
626
  # Active
630
- if options['active'].nil?
627
+ if options['active'].nil? && payload['network']['active'].nil?
631
628
  v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'active', 'fieldLabel' => 'Active', 'type' => 'checkbox', 'required' => false, 'description' => '', 'defaultValue' => true}], options)
632
629
  payload['network']['active'] = v_prompt['active']
633
630
  else
@@ -635,7 +632,7 @@ class Morpheus::Cli::NetworksCommand
635
632
  end
636
633
 
637
634
  # DHCP Server
638
- if network_type['dhcpServerEditable']
635
+ if network_type['dhcpServerEditable'] && payload['network']['dhcpServer'].nil?
639
636
  if options['dhcpServer'] != nil
640
637
  payload['network']['dhcpServer'] = options['dhcpServer']
641
638
  else
@@ -645,23 +642,24 @@ class Morpheus::Cli::NetworksCommand
645
642
  end
646
643
 
647
644
  # Allow IP Override
648
- if options['allowStaticOverride'] != nil
649
- payload['network']['allowStaticOverride'] = options['allowStaticOverride']
650
- else
651
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'allowStaticOverride', 'fieldLabel' => 'Allow IP Override', 'type' => 'checkbox', 'required' => false, 'description' => ''}], options)
652
- payload['network']['allowStaticOverride'] = v_prompt['allowStaticOverride']
645
+ if network_type['staticOverrideEditable'] && payload['network']['allowStaticOverride'].nil?
646
+ if options['allowStaticOverride'] != nil
647
+ payload['network']['allowStaticOverride'] = options['allowStaticOverride']
648
+ else
649
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'allowStaticOverride', 'fieldLabel' => 'Allow IP Override', 'type' => 'checkbox', 'required' => false, 'description' => ''}], options)
650
+ payload['network']['allowStaticOverride'] = v_prompt['allowStaticOverride']
651
+ end
653
652
  end
654
653
 
655
654
  ## IPAM Options
656
655
 
657
656
  # Network Pool
658
- if network_type['canAssignPool']
657
+ if network_type['canAssignPool'] && payload['network']['pool'].nil?
659
658
  if options['pool']
660
659
  payload['network']['pool'] = options['pool'].to_i
661
660
  else
662
661
  # todo: select dropdown
663
- # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'pool', 'fieldLabel' => 'Network Pool', 'type' => 'select', 'optionSource' => 'networkPools', 'required' => false, 'description' => ''}], options, @api_client, {zoneId: cloud['id']})
664
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'pool', 'fieldLabel' => 'Network Pool', 'type' => 'text', 'required' => false, 'description' => ''}], options)
662
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'pool', 'fieldLabel' => 'Network Pool', 'type' => 'select', 'optionSource' => 'networkPools', 'required' => false, 'description' => ''}], options, @api_client, api_params)
665
663
  payload['network']['pool'] = v_prompt['pool'].to_i if v_prompt['pool']
666
664
  end
667
665
  end
@@ -669,11 +667,13 @@ class Morpheus::Cli::NetworksCommand
669
667
  ## Advanced Options
670
668
 
671
669
  # Network Domain
672
- if options['domain']
673
- payload['network']['networkDomain'] = {'id' => options['domain'].to_i}
674
- else
675
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'domain', 'fieldLabel' => 'Network Domain', 'type' => 'select', 'optionSource' => 'networkDomains', 'required' => false, 'description' => ''}], options, @api_client)
676
- payload['network']['networkDomain'] = {'id' => v_prompt['domain'].to_i} unless v_prompt['domain'].to_s.empty?
670
+ if network_type['networkDomainEditable'] && payload['network']['networkDomain'].nil?
671
+ if options['domain']
672
+ payload['network']['networkDomain'] = {'id' => options['domain'].to_i}
673
+ else
674
+ v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'domain', 'fieldLabel' => 'Network Domain', 'type' => 'select', 'optionSource' => 'networkDomains', 'required' => false, 'description' => ''}], options, @api_client)
675
+ payload['network']['networkDomain'] = {'id' => v_prompt['domain'].to_i} unless v_prompt['domain'].to_s.empty?
676
+ end
677
677
  end
678
678
 
679
679
  # Search Domains
@@ -0,0 +1,30 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ # This is for opening a file
4
+ class Morpheus::Cli::OpenCommand
5
+ include Morpheus::Cli::CliCommand
6
+ set_command_name :open
7
+ set_command_hidden
8
+
9
+ def handle(args)
10
+ append_newline = true
11
+ options = {}
12
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
13
+ opts.banner = "Usage: morpheus #{command_name} [file ...]"
14
+ build_common_options(opts, options, [:dry_run])
15
+ opts.footer = "Open file(s)." + "\n" +
16
+ "[file] is required. This is the name of a file. Supports many [file] arguments."
17
+ end
18
+ optparse.parse!(args)
19
+ verify_args!(args:args, optparse:optparse, min: 1)
20
+ open_args = args.join(" ")
21
+ if options[:dry_run]
22
+ print "\n"
23
+ print "#{cyan}#{bold}#{dark}SYSTEM COMMAND#{reset}\n"
24
+ puts Morpheus::Util.open_url_command(open_args)
25
+ return 0, nil
26
+ end
27
+ return Morpheus::Util.open_url(open_args)
28
+ end
29
+
30
+ end