morpheus-cli 5.3.2.2 → 5.4.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 (182) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +26 -1
  4. data/lib/morpheus/api/clouds_interface.rb +4 -11
  5. data/lib/morpheus/api/health_interface.rb +37 -3
  6. data/lib/morpheus/api/instances_interface.rb +18 -5
  7. data/lib/morpheus/api/load_balancer_pools_interface.rb +4 -4
  8. data/lib/morpheus/api/load_balancer_profiles_interface.rb +10 -0
  9. data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +4 -4
  10. data/lib/morpheus/api/network_dhcp_relays_interface.rb +36 -0
  11. data/lib/morpheus/api/network_dhcp_servers_interface.rb +36 -0
  12. data/lib/morpheus/api/network_edge_clusters_interface.rb +26 -0
  13. data/lib/morpheus/api/network_routers_interface.rb +21 -0
  14. data/lib/morpheus/api/network_servers_interface.rb +98 -0
  15. data/lib/morpheus/api/rest_interface.rb +2 -1
  16. data/lib/morpheus/api/roles_interface.rb +7 -0
  17. data/lib/morpheus/api/virtual_images_interface.rb +23 -2
  18. data/lib/morpheus/api/virtual_servers_interface.rb +9 -0
  19. data/lib/morpheus/cli/cli_command.rb +21 -14
  20. data/lib/morpheus/cli/cli_registry.rb +56 -2
  21. data/lib/morpheus/cli/{access_token_command.rb → commands/access_token_command.rb} +1 -1
  22. data/lib/morpheus/cli/{account_groups_command.rb → commands/account_groups_command.rb} +0 -8
  23. data/lib/morpheus/cli/{activity_command.rb → commands/activity_command.rb} +0 -0
  24. data/lib/morpheus/cli/commands/{standard/alias_command.rb → alias_command.rb} +0 -3
  25. data/lib/morpheus/cli/{appliance_settings_command.rb → commands/appliance_settings_command.rb} +0 -0
  26. data/lib/morpheus/cli/{approvals_command.rb → commands/approvals_command.rb} +0 -0
  27. data/lib/morpheus/cli/{apps.rb → commands/apps.rb} +3 -11
  28. data/lib/morpheus/cli/{archives_command.rb → commands/archives_command.rb} +0 -6
  29. data/lib/morpheus/cli/{backup_jobs_command.rb → commands/backup_jobs_command.rb} +0 -0
  30. data/lib/morpheus/cli/{backup_settings_command.rb → commands/backup_settings_command.rb} +0 -0
  31. data/lib/morpheus/cli/{backups_command.rb → commands/backups_command.rb} +0 -0
  32. data/lib/morpheus/cli/commands/{standard/benchmark_command.rb → benchmark_command.rb} +0 -3
  33. data/lib/morpheus/cli/{blueprints_command.rb → commands/blueprints_command.rb} +0 -0
  34. data/lib/morpheus/cli/{boot_scripts_command.rb → commands/boot_scripts_command.rb} +0 -3
  35. data/lib/morpheus/cli/{budgets_command.rb → commands/budgets_command.rb} +0 -0
  36. data/lib/morpheus/cli/commands/{standard/cat_command.rb → cat_command.rb} +0 -0
  37. data/lib/morpheus/cli/{catalog_item_types_command.rb → commands/catalog_item_types_command.rb} +0 -0
  38. data/lib/morpheus/cli/{certificates_command.rb → commands/certificates_command.rb} +0 -0
  39. data/lib/morpheus/cli/commands/change_password_command.rb +132 -0
  40. data/lib/morpheus/cli/{cloud_datastores_command.rb → commands/cloud_datastores_command.rb} +0 -4
  41. data/lib/morpheus/cli/{cloud_folders_command.rb → commands/cloud_folders_command.rb} +0 -4
  42. data/lib/morpheus/cli/{cloud_resource_pools_command.rb → commands/cloud_resource_pools_command.rb} +170 -138
  43. data/lib/morpheus/cli/{clouds.rb → commands/clouds.rb} +22 -47
  44. data/lib/morpheus/cli/{clusters.rb → commands/clusters.rb} +51 -39
  45. data/lib/morpheus/cli/commands/{standard/coloring_command.rb → coloring_command.rb} +0 -2
  46. data/lib/morpheus/cli/{containers_command.rb → commands/containers_command.rb} +0 -7
  47. data/lib/morpheus/cli/commands/{standard/curl_command.rb → curl_command.rb} +0 -3
  48. data/lib/morpheus/cli/{cypher_command.rb → commands/cypher_command.rb} +0 -1
  49. data/lib/morpheus/cli/{dashboard_command.rb → commands/dashboard_command.rb} +0 -2
  50. data/lib/morpheus/cli/commands/{standard/debug_command.rb → debug_command.rb} +0 -1
  51. data/lib/morpheus/cli/{deploy.rb → commands/deploy.rb} +0 -1
  52. data/lib/morpheus/cli/{deployments.rb → commands/deployments.rb} +0 -0
  53. data/lib/morpheus/cli/{deploys.rb → commands/deploys.rb} +0 -1
  54. data/lib/morpheus/cli/{doc.rb → commands/doc.rb} +1 -1
  55. data/lib/morpheus/cli/commands/{standard/echo_command.rb → echo_command.rb} +0 -2
  56. data/lib/morpheus/cli/commands/{standard/edit_profile_command.rb → edit_profile_command.rb} +15 -4
  57. data/lib/morpheus/cli/commands/{standard/edit_rc_command.rb → edit_rc_command.rb} +19 -3
  58. data/lib/morpheus/cli/{environments_command.rb → commands/environments_command.rb} +0 -5
  59. data/lib/morpheus/cli/{execute_schedules_command.rb → commands/execute_schedules_command.rb} +0 -0
  60. data/lib/morpheus/cli/{execution_request_command.rb → commands/execution_request_command.rb} +0 -2
  61. data/lib/morpheus/cli/commands/{standard/exit_command.rb → exit_command.rb} +0 -2
  62. data/lib/morpheus/cli/{file_copy_request_command.rb → commands/file_copy_request_command.rb} +0 -4
  63. data/lib/morpheus/cli/{forgot_password.rb → commands/forgot_password.rb} +0 -0
  64. data/lib/morpheus/cli/commands/{standard/get_prompt_command.rb → get_prompt_command.rb} +0 -3
  65. data/lib/morpheus/cli/{groups.rb → commands/groups.rb} +0 -7
  66. data/lib/morpheus/cli/{guidance_command.rb → commands/guidance_command.rb} +1 -1
  67. data/lib/morpheus/cli/{health_command.rb → commands/health_command.rb} +104 -19
  68. data/lib/morpheus/cli/commands/{standard/history_command.rb → history_command.rb} +0 -3
  69. data/lib/morpheus/cli/{hosts.rb → commands/hosts.rb} +0 -10
  70. data/lib/morpheus/cli/{image_builder_command.rb → commands/image_builder_command.rb} +2 -8
  71. data/lib/morpheus/cli/{instance_types.rb → commands/instance_types.rb} +0 -3
  72. data/lib/morpheus/cli/{instances.rb → commands/instances.rb} +364 -148
  73. data/lib/morpheus/cli/{integrations_command.rb → commands/integrations_command.rb} +0 -0
  74. data/lib/morpheus/cli/{invoices_command.rb → commands/invoices_command.rb} +118 -134
  75. data/lib/morpheus/cli/{jobs_command.rb → commands/jobs_command.rb} +0 -0
  76. data/lib/morpheus/cli/{key_pairs.rb → commands/key_pairs.rb} +0 -6
  77. data/lib/morpheus/cli/{library_cluster_layouts_command.rb → commands/library_cluster_layouts_command.rb} +20 -4
  78. data/lib/morpheus/cli/{library_container_scripts_command.rb → commands/library_container_scripts_command.rb} +0 -0
  79. data/lib/morpheus/cli/{library_container_templates_command.rb → commands/library_container_templates_command.rb} +0 -1
  80. data/lib/morpheus/cli/{library_container_types_command.rb → commands/library_container_types_command.rb} +0 -4
  81. data/lib/morpheus/cli/{library_instance_types_command.rb → commands/library_instance_types_command.rb} +0 -4
  82. data/lib/morpheus/cli/{library_layouts_command.rb → commands/library_layouts_command.rb} +0 -4
  83. data/lib/morpheus/cli/{library_option_lists_command.rb → commands/library_option_lists_command.rb} +3 -7
  84. data/lib/morpheus/cli/{library_option_types_command.rb → commands/library_option_types_command.rb} +0 -4
  85. data/lib/morpheus/cli/{library_spec_templates_command.rb → commands/library_spec_templates_command.rb} +0 -1
  86. data/lib/morpheus/cli/{library_upgrades_command.rb → commands/library_upgrades_command.rb} +0 -4
  87. data/lib/morpheus/cli/{license.rb → commands/license.rb} +0 -3
  88. data/lib/morpheus/cli/commands/load_balancer_pools.rb +111 -0
  89. data/lib/morpheus/cli/{load_balancer_types.rb → commands/load_balancer_types.rb} +0 -4
  90. data/lib/morpheus/cli/commands/load_balancer_virtual_servers.rb +136 -0
  91. data/lib/morpheus/cli/commands/load_balancers.rb +89 -0
  92. data/lib/morpheus/cli/commands/{standard/log_level_command.rb → log_level_command.rb} +0 -3
  93. data/lib/morpheus/cli/{log_settings_command.rb → commands/log_settings_command.rb} +0 -0
  94. data/lib/morpheus/cli/{login.rb → commands/login.rb} +0 -5
  95. data/lib/morpheus/cli/commands/logout.rb +63 -0
  96. data/lib/morpheus/cli/{logs_command.rb → commands/logs_command.rb} +0 -3
  97. data/lib/morpheus/cli/commands/{standard/man_command.rb → man_command.rb} +0 -2
  98. data/lib/morpheus/cli/{monitoring_alerts_command.rb → commands/monitoring_alerts_command.rb} +0 -7
  99. data/lib/morpheus/cli/{monitoring_apps_command.rb → commands/monitoring_apps_command.rb} +0 -1
  100. data/lib/morpheus/cli/{monitoring_checks_command.rb → commands/monitoring_checks_command.rb} +2 -1
  101. data/lib/morpheus/cli/{monitoring_contacts_command.rb → commands/monitoring_contacts_command.rb} +0 -7
  102. data/lib/morpheus/cli/{monitoring_groups_command.rb → commands/monitoring_groups_command.rb} +0 -1
  103. data/lib/morpheus/cli/{monitoring_incidents_command.rb → commands/monitoring_incidents_command.rb} +0 -1
  104. data/lib/morpheus/cli/commands/network_dhcp_relays_command.rb +416 -0
  105. data/lib/morpheus/cli/commands/network_dhcp_servers_command.rb +407 -0
  106. data/lib/morpheus/cli/{network_domains_command.rb → commands/network_domains_command.rb} +0 -4
  107. data/lib/morpheus/cli/commands/network_edge_clusters_command.rb +329 -0
  108. data/lib/morpheus/cli/commands/network_firewalls_command.rb +806 -0
  109. data/lib/morpheus/cli/{network_groups_command.rb → commands/network_groups_command.rb} +0 -4
  110. data/lib/morpheus/cli/{network_pool_servers_command.rb → commands/network_pool_servers_command.rb} +0 -4
  111. data/lib/morpheus/cli/{network_pools_command.rb → commands/network_pools_command.rb} +0 -4
  112. data/lib/morpheus/cli/{network_proxies_command.rb → commands/network_proxies_command.rb} +0 -4
  113. data/lib/morpheus/cli/{network_routers_command.rb → commands/network_routers_command.rb} +291 -12
  114. data/lib/morpheus/cli/{network_services_command.rb → commands/network_services_command.rb} +0 -4
  115. data/lib/morpheus/cli/commands/network_transport_zones_command.rb +452 -0
  116. data/lib/morpheus/cli/{networks_command.rb → commands/networks_command.rb} +21 -21
  117. data/lib/morpheus/cli/{packages_command.rb → commands/packages_command.rb} +0 -2
  118. data/lib/morpheus/cli/{ping.rb → commands/ping.rb} +0 -7
  119. data/lib/morpheus/cli/{policies_command.rb → commands/policies_command.rb} +0 -7
  120. data/lib/morpheus/cli/{power_schedules_command.rb → commands/power_schedules_command.rb} +0 -0
  121. data/lib/morpheus/cli/{preseed_scripts_command.rb → commands/preseed_scripts_command.rb} +0 -3
  122. data/lib/morpheus/cli/{price_sets_command.rb → commands/price_sets_command.rb} +0 -0
  123. data/lib/morpheus/cli/{prices_command.rb → commands/prices_command.rb} +0 -0
  124. data/lib/morpheus/cli/{processes_command.rb → commands/processes_command.rb} +0 -1
  125. data/lib/morpheus/cli/{projects_command.rb → commands/projects_command.rb} +0 -0
  126. data/lib/morpheus/cli/{provisioning_licenses_command.rb → commands/provisioning_licenses_command.rb} +0 -0
  127. data/lib/morpheus/cli/{provisioning_settings_command.rb → commands/provisioning_settings_command.rb} +0 -0
  128. data/lib/morpheus/cli/{recent_activity_command.rb → commands/recent_activity_command.rb} +0 -0
  129. data/lib/morpheus/cli/{remote.rb → commands/remote.rb} +1 -7
  130. data/lib/morpheus/cli/{reports_command.rb → commands/reports_command.rb} +0 -2
  131. data/lib/morpheus/cli/commands/{standard/rm_command.rb → rm_command.rb} +0 -0
  132. data/lib/morpheus/cli/{roles.rb → commands/roles.rb} +244 -39
  133. data/lib/morpheus/cli/{search_command.rb → commands/search_command.rb} +0 -0
  134. data/lib/morpheus/cli/{security_group_rules.rb → commands/security_group_rules.rb} +0 -5
  135. data/lib/morpheus/cli/{security_groups.rb → commands/security_groups.rb} +0 -6
  136. data/lib/morpheus/cli/{service_catalog_command.rb → commands/service_catalog_command.rb} +0 -0
  137. data/lib/morpheus/cli/{service_plans_command.rb → commands/service_plans_command.rb} +0 -0
  138. data/lib/morpheus/cli/commands/{standard/set_prompt_command.rb → set_prompt_command.rb} +0 -3
  139. data/lib/morpheus/cli/{setup.rb → commands/setup.rb} +0 -0
  140. data/lib/morpheus/cli/{shell.rb → commands/shell.rb} +2 -103
  141. data/lib/morpheus/cli/commands/{standard/sleep_command.rb → sleep_command.rb} +0 -2
  142. data/lib/morpheus/cli/commands/{standard/source_command.rb → source_command.rb} +0 -2
  143. data/lib/morpheus/cli/commands/{standard/ssl_verification_command.rb → ssl_verification_command.rb} +0 -3
  144. data/lib/morpheus/cli/{storage_providers_command.rb → commands/storage_providers_command.rb} +0 -4
  145. data/lib/morpheus/cli/{subnets_command.rb → commands/subnets_command.rb} +7 -6
  146. data/lib/morpheus/cli/{tasks.rb → commands/tasks.rb} +25 -6
  147. data/lib/morpheus/cli/commands/{standard/tee_command.rb → tee_command.rb} +0 -0
  148. data/lib/morpheus/cli/{tenants_command.rb → commands/tenants_command.rb} +0 -7
  149. data/lib/morpheus/cli/commands/{standard/update_command.rb → update_command.rb} +0 -1
  150. data/lib/morpheus/cli/{usage_command.rb → commands/usage_command.rb} +0 -0
  151. data/lib/morpheus/cli/{user_groups_command.rb → commands/user_groups_command.rb} +0 -1
  152. data/lib/morpheus/cli/{user_settings_command.rb → commands/user_settings_command.rb} +0 -0
  153. data/lib/morpheus/cli/{user_sources_command.rb → commands/user_sources_command.rb} +0 -1
  154. data/lib/morpheus/cli/{users.rb → commands/users.rb} +0 -7
  155. data/lib/morpheus/cli/{vdi_allocations_command.rb → commands/vdi_allocations_command.rb} +0 -0
  156. data/lib/morpheus/cli/{vdi_apps_command.rb → commands/vdi_apps_command.rb} +0 -0
  157. data/lib/morpheus/cli/{vdi_command.rb → commands/vdi_command.rb} +0 -0
  158. data/lib/morpheus/cli/{vdi_gateways_command.rb → commands/vdi_gateways_command.rb} +0 -0
  159. data/lib/morpheus/cli/{vdi_pools_command.rb → commands/vdi_pools_command.rb} +4 -1
  160. data/lib/morpheus/cli/commands/{standard/version_command.rb → version_command.rb} +0 -0
  161. data/lib/morpheus/cli/{virtual_images.rb → commands/virtual_images.rb} +251 -33
  162. data/lib/morpheus/cli/{whitelabel_settings_command.rb → commands/whitelabel_settings_command.rb} +0 -1
  163. data/lib/morpheus/cli/{whoami.rb → commands/whoami.rb} +0 -4
  164. data/lib/morpheus/cli/{wiki_command.rb → commands/wiki_command.rb} +0 -5
  165. data/lib/morpheus/cli/{workflows.rb → commands/workflows.rb} +0 -3
  166. data/lib/morpheus/cli/mixins/load_balancers_helper.rb +2 -2
  167. data/lib/morpheus/cli/mixins/logs_helper.rb +1 -1
  168. data/lib/morpheus/cli/mixins/print_helper.rb +1 -0
  169. data/lib/morpheus/cli/mixins/provisioning_helper.rb +155 -112
  170. data/lib/morpheus/cli/mixins/rest_command.rb +154 -52
  171. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +575 -0
  172. data/lib/morpheus/cli/option_parser.rb +25 -17
  173. data/lib/morpheus/cli/option_types.rb +96 -32
  174. data/lib/morpheus/cli/version.rb +1 -1
  175. data/lib/morpheus/cli.rb +5 -128
  176. data/lib/morpheus/terminal.rb +5 -6
  177. data/morpheus-cli.gemspec +1 -1
  178. metadata +156 -143
  179. data/lib/morpheus/cli/change_password_command.rb +0 -147
  180. data/lib/morpheus/cli/library.rb +0 -1
  181. data/lib/morpheus/cli/load_balancers.rb +0 -245
  182. data/lib/morpheus/cli/logout.rb +0 -81
@@ -0,0 +1,575 @@
1
+ # SecondaryRestCommand is a mixin for Morpheus::Cli command classes.
2
+ # for resources that are secondary to some parent resource.
3
+ # Provides basic CRUD commands: list, get, add, update, remove
4
+ # The parent resource is specified as the first argument for all the comments.
5
+ #
6
+ # Example of a SecondaryRestCommand for `morpheus load-balancer-virtual-servers`.
7
+ #
8
+ # class Morpheus::Cli::LoadBalancerVirtualServers
9
+ #
10
+ # include Morpheus::Cli::CliCommand
11
+ # include Morpheus::Cli::RestCommand
12
+ # include Morpheus::Cli::SecondaryRestCommand
13
+ # include Morpheus::Cli::LoadBalancersHelper
14
+ #
15
+ # set_command_name :'load-balancer-virtual-servers'
16
+ # register_subcommands :list, :get, :add, :update, :remove
17
+ #
18
+ # register_interfaces :load_balancer_virtual_servers,
19
+ # :load_balancers, :load_balancer_types
20
+ #
21
+ # set_rest_parent_name :load_balancers
22
+ #
23
+ # end
24
+ #
25
+ module Morpheus::Cli::SecondaryRestCommand
26
+ def self.included(base)
27
+ base.extend ClassMethods
28
+ end
29
+
30
+ module ClassMethods
31
+
32
+ ## duplicated the rest_* settings with rest_parent_*, for defining the parent resource
33
+
34
+ # rest_parent_name is the rest_name for the parent
35
+ def rest_parent_name
36
+ @rest_parent_name || default_rest_parent_name
37
+ end
38
+
39
+ def default_rest_parent_name
40
+ words = rest_name.split("_")
41
+ if words.size > 1
42
+ words.pop
43
+ return words.join("_") + "s"
44
+ else
45
+ # this wont happen, default wont make sense in this scenario
46
+ # "parent_" + rest_name
47
+ raise "Unable to determine default_rest_parent_name for rest_name: #{rest_name}, class: #{self}"
48
+ end
49
+ end
50
+
51
+ def rest_parent_name=(v)
52
+ @rest_parent_name = v.to_s
53
+ end
54
+
55
+ alias :set_rest_parent_name :rest_parent_name=
56
+ alias :set_rest_parent :rest_parent_name=
57
+ #alias :rest_parent= :rest_parent_name=
58
+
59
+ # rest_parent_key is the singular name of the resource eg. "neat_thing"
60
+ def rest_parent_key
61
+ @rest_parent_key || default_rest_parent_key
62
+ end
63
+
64
+ def default_rest_parent_key
65
+ rest_parent_name.chomp("s")
66
+ end
67
+
68
+ def rest_parent_key=(v)
69
+ @rest_parent_key = v.to_s
70
+ end
71
+
72
+ alias :set_rest_parent_key :rest_parent_key=
73
+
74
+ def rest_parent_arg
75
+ @rest_parent_arg || default_rest_parent_arg
76
+ end
77
+
78
+ def default_rest_parent_arg
79
+ rest_parent_key.to_s.gsub("_", " ")
80
+ end
81
+
82
+ def rest_parent_arg=(v)
83
+ @rest_parent_arg = v.to_s
84
+ end
85
+
86
+ alias :set_rest_parent_arg :rest_parent_arg=
87
+
88
+ # rest_parent_label is the capitalized resource label eg. "Neat Thing"
89
+ def rest_parent_label
90
+ @rest_parent_label || default_rest_parent_label
91
+ end
92
+
93
+ def default_rest_parent_label
94
+ rest_parent_key.to_s.split("_").collect {|it| it.to_s.capitalize }.join(" ")
95
+ end
96
+
97
+ def rest_parent_label=(v)
98
+ @rest_parent_label = v.to_s
99
+ end
100
+
101
+ alias :set_rest_parent_label :rest_parent_label=
102
+
103
+ # the plural version of the label eg. "Neat Things"
104
+ def rest_parent_label_plural
105
+ @rest_parent_label_plural || default_rest_parent_label_plural
106
+ end
107
+
108
+ def default_rest_parent_label_plural
109
+ #rest_parent_name.to_s.split("_").collect {|it| it.to_s.capitalize }.join(" ")
110
+ rest_parent_label.to_s.pluralize
111
+ end
112
+
113
+ def rest_parent_label_plural=(v)
114
+ @rest_parent_label_plural = v.to_s
115
+ end
116
+
117
+ alias :set_rest_parent_label_plural :rest_parent_label_plural=
118
+
119
+ # the name of the default interface, matches the rest name eg. "neat_things"
120
+ def rest_parent_interface_name
121
+ @rest_parent_interface_name || default_rest_parent_interface_name
122
+ end
123
+
124
+ def default_rest_parent_interface_name
125
+ rest_parent_name
126
+ end
127
+
128
+ def rest_parent_interface_name=(v)
129
+ @rest_parent_interface_name = v.to_s
130
+ end
131
+
132
+ alias :set_rest_parent_interface_name :rest_parent_interface_name=
133
+
134
+ end
135
+
136
+ ## duplicated the rest_* settings with rest_parent, for the parents resource
137
+
138
+ def rest_parent_name
139
+ self.class.rest_parent_name
140
+ end
141
+
142
+ def rest_parent_key
143
+ self.class.rest_parent_key
144
+ end
145
+
146
+ def rest_parent_arg
147
+ self.class.rest_parent_arg
148
+ end
149
+
150
+ def rest_parent_label
151
+ self.class.rest_parent_label
152
+ end
153
+
154
+ def rest_parent_label_plural
155
+ self.class.rest_parent_label_plural
156
+ end
157
+
158
+ def rest_parent_interface_name
159
+ self.class.rest_parent_interface_name # || "@#{rest_parent_name}_interface"
160
+ end
161
+
162
+ def rest_parent_interface
163
+ instance_variable_get("@#{rest_parent_interface_name}_interface")
164
+ end
165
+
166
+ def rest_parent_object_key
167
+ self.send("#{rest_parent_key}_object_key")
168
+ end
169
+
170
+ def rest_parent_list_key
171
+ self.send("#{rest_parent_key}_list_key")
172
+ end
173
+
174
+ def rest_parent_column_definitions
175
+ self.send("#{rest_parent_key}_column_definitions")
176
+ end
177
+
178
+ def rest_parent_list_column_definitions
179
+ self.send("#{rest_parent_key}_list_column_definitions")
180
+ end
181
+
182
+ def rest_parent_find_by_name_or_id(name)
183
+ return self.send("find_#{rest_parent_key}_by_name_or_id", name)
184
+ end
185
+
186
+ def registered_interfaces
187
+ self.class.registered_interfaces
188
+ end
189
+
190
+ def list(args)
191
+ parent_id, parent_record = nil, nil
192
+ params = {}
193
+ options = {}
194
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
195
+ opts.banner = subcommand_usage("[#{rest_parent_arg}] [search]")
196
+ build_standard_list_options(opts, options)
197
+ opts.footer = <<-EOT
198
+ List #{rest_label_plural.downcase}.
199
+ [#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
200
+ [search] is optional. This is a search phrase to filter the results.
201
+ EOT
202
+ end
203
+ optparse.parse!(args)
204
+ parent_id = args[0]
205
+ if args[1] # && rest_has_name
206
+ record_name = args[1]
207
+ end
208
+ verify_args!(args:args, optparse:optparse, min:1)
209
+ if args.count > 1
210
+ options[:phrase] = args[1..-1].join(" ")
211
+ end
212
+ connect(options)
213
+ parent_record = rest_parent_find_by_name_or_id(parent_id)
214
+ if parent_record.nil?
215
+ raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
216
+ end
217
+ parent_id = parent_record['id']
218
+ params.merge!(parse_list_options(options))
219
+ rest_interface.setopts(options)
220
+ if options[:dry_run]
221
+ print_dry_run rest_interface.dry.list(parent_id, params)
222
+ return
223
+ end
224
+ json_response = rest_interface.list(parent_id, params)
225
+ render_response(json_response, options, rest_list_key) do
226
+ records = json_response[rest_list_key]
227
+ print_h1 "Morpheus #{rest_label_plural}"
228
+ if records.nil? || records.empty?
229
+ print cyan,"No #{rest_label_plural.downcase} found.",reset,"\n"
230
+ else
231
+ print as_pretty_table(records, rest_list_column_definitions.upcase_keys!, options)
232
+ print_results_pagination(json_response) if json_response['meta']
233
+ end
234
+ print reset,"\n"
235
+ end
236
+ return 0, nil
237
+ end
238
+
239
+ def get(args)
240
+ params = {}
241
+ options = {}
242
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
243
+ opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}]")
244
+ build_standard_get_options(opts, options)
245
+ opts.footer = <<-EOT
246
+ Get details about #{a_or_an(rest_label)} #{rest_label.downcase}.
247
+ [#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
248
+ [#{rest_arg}] is required. This is the name or id of #{a_or_an(rest_label)} #{rest_label.downcase}.
249
+ EOT
250
+ end
251
+ optparse.parse!(args)
252
+ verify_args!(args:args, optparse:optparse, min:2)
253
+ connect(options)
254
+ parent_id = args[0]
255
+ parent_record = rest_parent_find_by_name_or_id(parent_id)
256
+ if parent_record.nil?
257
+ raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
258
+ end
259
+ parent_id = parent_record['id']
260
+ params.merge!(parse_query_options(options))
261
+ id_list = parse_id_list(args[1..-1])
262
+ return run_command_for_each_arg(id_list) do |arg|
263
+ _get(parent_id, arg, params, options)
264
+ end
265
+ end
266
+
267
+ def _get(parent_id, id, params, options)
268
+ if id !~ /\A\d{1,}\Z/
269
+ record = rest_find_by_name_or_id(id)
270
+ if record.nil?
271
+ raise_command_error "#{rest_label} not found for name '#{id}'"
272
+ end
273
+ id = record['id']
274
+ end
275
+ rest_interface.setopts(options)
276
+ if options[:dry_run]
277
+ print_dry_run rest_interface.dry.get(id, params)
278
+ return
279
+ end
280
+ json_response = rest_interface.get(id, params)
281
+ render_response_for_get(json_response, options)
282
+ return 0, nil
283
+ end
284
+
285
+ def render_response_for_get(json_response, options)
286
+ render_response(json_response, options, rest_object_key) do
287
+ record = json_response[rest_object_key]
288
+ print_h1 rest_label, [], options
289
+ print cyan
290
+ print_description_list(rest_column_definitions, record, options)
291
+ # show config settings...
292
+ if record['optionTypes'] && record['optionTypes'].size > 0
293
+ print_h2 "Option Types", options
294
+ print format_option_types_table(record['optionTypes'], options, rest_object_key)
295
+ end
296
+ print reset,"\n"
297
+ end
298
+ end
299
+
300
+ def add(args)
301
+ parent_id, parent_record = nil, nil
302
+ record_type_id = nil
303
+ options = {}
304
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
305
+ if rest_has_type
306
+ opts.on( '-t', "--#{rest_type_arg} TYPE", "#{rest_type_label}" ) do |val|
307
+ record_type_id = val
308
+ end
309
+ end
310
+ if self.class.method_defined?("add_#{rest_key}_option_types")
311
+ build_option_type_options(opts, options, self.send("add_#{rest_key}_option_types"))
312
+ end
313
+ if self.class.method_defined?("add_#{rest_key}_advanced_option_types")
314
+ build_option_type_options(opts, options, self.send("add_#{rest_key}_advanced_option_types"))
315
+ end
316
+ build_standard_add_options(opts, options)
317
+ opts.footer = <<-EOT
318
+ Create a new #{rest_label.downcase}.
319
+ [#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
320
+ [#{rest_arg}] is required. This is the name of the new #{rest_label.downcase}.
321
+ EOT
322
+ end
323
+ optparse.parse!(args)
324
+ verify_args!(args:args, optparse:optparse, min:1, max: 2)
325
+ # todo: make supporting args[0] optional and more flexible
326
+ # for now args[0] is assumed to be the 'name'
327
+ record_name = nil
328
+ parent_id = args[0]
329
+ if args[1] # && rest_has_name
330
+ record_name = args[1]
331
+ end
332
+ connect(options)
333
+ # load parent record
334
+ # todo: prompt instead of error
335
+ parent_record = rest_parent_find_by_name_or_id(parent_id)
336
+ if parent_record.nil?
337
+ raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
338
+ end
339
+ parent_id = parent_record['id']
340
+ # load or prompt for type
341
+ if rest_has_type
342
+ if record_type_id.nil?
343
+ #raise_command_error "#{rest_type_label} is required.\n#{optparse}"
344
+ type_list = rest_type_interface.list({max:10000})[rest_type_list_key]
345
+ type_dropdown_options = type_list.collect {|it| {'name' => it['name'], 'value' => it['code']} }
346
+ record_type_id = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => rest_type_label, 'type' => 'select', 'selectOptions' => type_dropdown_options, 'required' => true}], options[:options], @api_client)['type']
347
+ end
348
+ record_type = rest_type_find_by_name_or_id(record_type_id)
349
+ if record_type.nil?
350
+ raise_command_error "#{rest_type_label} not found for '#{record_type_id}'.\n#{optparse}"
351
+ end
352
+ end
353
+ passed_options = parse_passed_options(options)
354
+ payload = {}
355
+ if options[:payload]
356
+ payload = options[:payload]
357
+ payload.deep_merge!({rest_object_key => passed_options})
358
+ else
359
+ record_payload = {}
360
+ if record_name
361
+ record_payload['name'] = record_name
362
+ options[:options]['name'] = record_name # injected for prompt
363
+ end
364
+ if rest_has_type && record_type
365
+ # record_payload['type'] = {'code' => record_type['code']}
366
+ record_payload['type'] = record_type['code']
367
+ options[:options]['type'] = record_type['code'] # injected for prompt
368
+ # initialize params for loading optionSource data
369
+ options[:params] ||= {}
370
+ options[:params]['type'] = record_type['code']
371
+ end
372
+ record_payload.deep_merge!(passed_options)
373
+ if self.class.method_defined?("add_#{rest_key}_option_types")
374
+ add_option_types = self.send("add_#{rest_key}_option_types")
375
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(add_option_types, options[:options], @api_client, options[:params])
376
+ v_prompt.deep_compact!
377
+ v_prompt.booleanize! # 'on' => true
378
+ record_payload.deep_merge!(v_prompt)
379
+ end
380
+ # options by type
381
+ my_option_types = record_type ? record_type['optionTypes'] : nil
382
+ if my_option_types && !my_option_types.empty?
383
+ # remove redundant fieldContext
384
+ my_option_types.each do |option_type|
385
+ if option_type['fieldContext'] == rest_object_key
386
+ option_type['fieldContext'] = nil
387
+ end
388
+ end
389
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, options[:params])
390
+ v_prompt.deep_compact!
391
+ v_prompt.booleanize! # 'on' => true
392
+ record_payload.deep_merge!(v_prompt)
393
+ end
394
+ # advanced options (uses no_prompt)
395
+ if self.class.method_defined?("add_#{rest_key}_advanced_option_types")
396
+ add_advanced_option_types = self.send("add_#{rest_key}_advanced_option_types")
397
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(add_advanced_option_types, options[:options], @api_client, options[:params])
398
+ v_prompt.deep_compact!
399
+ v_prompt.booleanize! # 'on' => true
400
+ record_payload.deep_merge!(v_prompt)
401
+ end
402
+ payload[rest_object_key] = record_payload
403
+ end
404
+ rest_interface.setopts(options)
405
+ if options[:dry_run]
406
+ print_dry_run rest_interface.dry.create(parent_id, payload)
407
+ return
408
+ end
409
+ json_response = rest_interface.create(parent_id, payload)
410
+ render_response(json_response, options, rest_object_key) do
411
+ record = json_response[rest_object_key]
412
+ print_green_success "Added #{rest_label.downcase} #{record['name'] || record['id']}"
413
+ return _get(parent_id, record["id"], {}, options)
414
+ end
415
+ return 0, nil
416
+ end
417
+
418
+ def update(args)
419
+ parent_id = args[0]
420
+ id = args[1]
421
+ record_type = nil
422
+ record_type_id = nil
423
+ options = {}
424
+ params = {}
425
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
426
+ opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}] [options]")
427
+ if self.class.method_defined?("update_#{rest_key}_option_types")
428
+ build_option_type_options(opts, options, self.send("update_#{rest_key}_option_types"))
429
+ end
430
+ if self.class.method_defined?("update_#{rest_key}_advanced_option_types")
431
+ build_option_type_options(opts, options, self.send("update_#{rest_key}_advanced_option_types"))
432
+ end
433
+ build_standard_update_options(opts, options)
434
+ opts.footer = <<-EOT
435
+ Update an existing #{rest_label.downcase}.
436
+ [#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
437
+ [#{rest_arg}] is required. This is the name or id of #{a_or_an(rest_label)} #{rest_label.downcase}.
438
+ EOT
439
+ end
440
+ optparse.parse!(args)
441
+ verify_args!(args:args, optparse:optparse, count:2)
442
+ parent_record = rest_parent_find_by_name_or_id(parent_id)
443
+ if parent_record.nil?
444
+ raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
445
+ end
446
+ parent_id = parent_record['id']
447
+ connect(options)
448
+ record = rest_find_by_name_or_id(id)
449
+ if record.nil?
450
+ return 1, "#{rest_name} not found for '#{id}'"
451
+ end
452
+ # load type so we can prompt for those option types
453
+ if rest_has_type
454
+ record_type_id = record['type']['id']
455
+ record_type = rest_type_find_by_name_or_id(record_type_id)
456
+ if record_type.nil?
457
+ raise_command_error "#{rest_type_label} not found for '#{record_type_id}'.\n#{optparse}"
458
+ end
459
+ end
460
+ passed_options = parse_passed_options(options)
461
+ payload = {}
462
+ if options[:payload]
463
+ payload = options[:payload]
464
+ payload.deep_merge!({rest_object_key => passed_options}) unless passed_options.empty?
465
+ else
466
+ record_payload = passed_options
467
+ if rest_has_type && record_type
468
+ # inject type to options for prompting
469
+ # record_payload['type'] = record_type['code']
470
+ # options[:options]['type'] = record_type['code']
471
+ # initialize params for loading optionSource data
472
+ options[:params] ||= {}
473
+ options[:params]['type'] = record_type['code']
474
+ end
475
+ # update options without prompting by default
476
+ if self.class.method_defined?("update_#{rest_key}_option_types")
477
+ update_option_types = self.send("update_#{rest_key}_option_types")
478
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_option_types, options[:options], @api_client, options[:params])
479
+ v_prompt.deep_compact!
480
+ v_prompt.booleanize! # 'on' => true
481
+ record_payload.deep_merge!(v_prompt)
482
+ end
483
+ # options by type
484
+ my_option_types = record_type ? record_type['optionTypes'] : nil
485
+ if my_option_types && !my_option_types.empty?
486
+ # remove redundant fieldContext
487
+ # make them optional for updates
488
+ # todo: use current value as default instead of just making things optioanl
489
+ # maybe new prompt() options like {:mode => :edit, :object => storage_server} or something
490
+ my_option_types.each do |option_type|
491
+ if option_type['fieldContext'] == rest_object_key
492
+ option_type['fieldContext'] = nil
493
+ end
494
+ option_type.delete('required')
495
+ option_type.delete('defaultValue')
496
+ end
497
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(my_option_types, options[:options], @api_client, options[:params])
498
+ v_prompt.deep_compact!
499
+ v_prompt.booleanize! # 'on' => true
500
+ record_payload.deep_merge!(v_prompt)
501
+ end
502
+ # advanced options
503
+ if self.class.method_defined?("update_#{rest_key}_advanced_option_types")
504
+ update_advanced_option_types = self.send("update_#{rest_key}_advanced_option_types")
505
+ v_prompt = Morpheus::Cli::OptionTypes.no_prompt(update_advanced_option_types, options[:options], @api_client, options[:params])
506
+ v_prompt.deep_compact!
507
+ v_prompt.booleanize! # 'on' => true
508
+ record_payload.deep_merge!(v_prompt)
509
+ end
510
+ # remove empty config, compact could hanlde this
511
+ if record_payload['config'] && record_payload['config'].empty?
512
+ record_payload.delete('config')
513
+ end
514
+ # prevent updating with empty payload
515
+ if record_payload.empty?
516
+ raise_command_error "Specify at least one option to update.\n#{optparse}"
517
+ end
518
+ payload[rest_object_key] = record_payload
519
+ end
520
+ rest_interface.setopts(options)
521
+ if options[:dry_run]
522
+ print_dry_run rest_interface.dry.update(parent_id, record['id'], payload)
523
+ return
524
+ end
525
+ json_response = rest_interface.update(parent_id, record['id'], payload)
526
+ render_response(json_response, options, rest_object_key) do
527
+ print_green_success "Updated #{rest_label.downcase} #{record['name'] || record['id']}"
528
+ _get(parent_id, record["id"], {}, options)
529
+ end
530
+ return 0, nil
531
+ end
532
+
533
+ def remove(args)
534
+ parent_id = args[0]
535
+ id = args[1]
536
+ params = {}
537
+ options = {}
538
+ optparse = Morpheus::Cli::OptionParser.new do |opts|
539
+ opts.banner = subcommand_usage("[#{rest_parent_arg}] [#{rest_arg}]")
540
+ build_standard_remove_options(opts, options)
541
+ opts.footer = <<-EOT
542
+ Delete an existing #{rest_label.downcase}.
543
+ [#{rest_parent_arg}] is required. This is the name or id of #{a_or_an(rest_parent_label)} #{rest_parent_label.downcase}.
544
+ [#{rest_arg}] is required. This is the name or id of #{a_or_an(rest_label)} #{rest_label.downcase}.
545
+ EOT
546
+ end
547
+ optparse.parse!(args)
548
+ verify_args!(args:args, optparse:optparse, count:2)
549
+ connect(options)
550
+ parent_record = rest_parent_find_by_name_or_id(parent_id)
551
+ if parent_record.nil?
552
+ raise_command_error "#{rest_parent_label} not found for '#{parent_id}'.\n#{optparse}"
553
+ end
554
+ record = rest_find_by_name_or_id(id)
555
+ if record.nil?
556
+ return 1, "#{rest_name} not found for '#{id}'"
557
+ end
558
+ unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the #{rest_label.downcase} #{record['name'] || record['id']}?")
559
+ return 9, "aborted"
560
+ end
561
+ params.merge!(parse_query_options(options))
562
+ rest_interface.setopts(options)
563
+ if options[:dry_run]
564
+ print_dry_run rest_interface.dry.destroy(parent_id, record['id'])
565
+ return 0, nil
566
+ end
567
+ json_response = rest_interface.destroy(parent_id, record['id'], params)
568
+ render_response(json_response, options) do
569
+ print_green_success "Removed #{rest_label.downcase} #{record['name'] || record['id']}"
570
+ end
571
+ return 0, nil
572
+ end
573
+
574
+ end
575
+
@@ -32,27 +32,35 @@ module Morpheus
32
32
  #out << "Options:\n"
33
33
  # the default way..
34
34
  # out << summarize().join("")
35
-
36
35
  # super hacky, should be examining the option, not the fully formatted description
37
36
  my_summaries = summarize()
38
- summarize().each do |opt_description|
39
- is_hidden = (@hidden_options || []).find { |hidden_switch|
40
- # opt_description.include?("--#{hidden_switch}")
41
- if hidden_switch.start_with?("-")
42
- opt_description.to_s.strip.start_with?("#{hidden_switch} ")
43
- else
44
- opt_description.to_s.strip.start_with?("--#{hidden_switch} ")
45
- end
46
- }
47
- if is_hidden
48
- if opts[:show_hidden_options]
49
- # out << opt_description + " (hidden)"
50
- out << opt_description
37
+ if opts[:show_hidden_options]
38
+ my_summaries.each do |full_line|
39
+ out << full_line
40
+ end
41
+ else
42
+ on_hidden_option = false
43
+ my_summaries.each do |full_line|
44
+ opt_description = full_line.to_s.strip
45
+ if opt_description.start_with?("-")
46
+ is_hidden = (@hidden_options || []).find { |hidden_switch|
47
+ if hidden_switch.start_with?("-")
48
+ opt_description.start_with?("#{hidden_switch} ")
49
+ else
50
+ opt_description.start_with?("--#{hidden_switch} ")
51
+ end
52
+ }
53
+ if is_hidden
54
+ on_hidden_option = true
55
+ else
56
+ on_hidden_option = false
57
+ out << full_line
58
+ end
51
59
  else
52
- # hidden
60
+ if on_hidden_option == false
61
+ out << full_line
62
+ end
53
63
  end
54
- else
55
- out << opt_description
56
64
  end
57
65
  end
58
66
  end