morpheus-cli 5.3.0.3 → 5.3.2.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.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/README.md +1 -3
- data/lib/morpheus/api/account_groups_interface.rb +0 -6
- data/lib/morpheus/api/accounts_interface.rb +4 -36
- data/lib/morpheus/api/api_client.rb +167 -119
- data/lib/morpheus/api/appliance_settings_interface.rb +6 -9
- data/lib/morpheus/api/approvals_interface.rb +5 -8
- data/lib/morpheus/api/apps_interface.rb +0 -7
- data/lib/morpheus/api/archive_buckets_interface.rb +9 -16
- data/lib/morpheus/api/archive_files_interface.rb +0 -6
- data/lib/morpheus/api/auth_interface.rb +4 -4
- data/lib/morpheus/api/backup_settings_interface.rb +5 -8
- data/lib/morpheus/api/blueprints_interface.rb +1 -7
- data/lib/morpheus/api/budgets_interface.rb +0 -6
- data/lib/morpheus/api/certificate_types_interface.rb +14 -0
- data/lib/morpheus/api/certificates_interface.rb +9 -0
- data/lib/morpheus/api/cloud_datastores_interface.rb +0 -6
- data/lib/morpheus/api/cloud_folders_interface.rb +1 -7
- data/lib/morpheus/api/cloud_policies_interface.rb +0 -6
- data/lib/morpheus/api/cloud_resource_pools_interface.rb +0 -6
- data/lib/morpheus/api/clouds_interface.rb +0 -6
- data/lib/morpheus/api/clusters_interface.rb +39 -42
- data/lib/morpheus/api/containers_interface.rb +0 -6
- data/lib/morpheus/api/custom_instance_types_interface.rb +0 -6
- data/lib/morpheus/api/cypher_interface.rb +0 -6
- data/lib/morpheus/api/datastores_interface.rb +4 -7
- data/lib/morpheus/api/deploy_interface.rb +1 -6
- data/lib/morpheus/api/environments_interface.rb +0 -6
- data/lib/morpheus/api/execute_schedules_interface.rb +0 -6
- data/lib/morpheus/api/execution_request_interface.rb +0 -6
- data/lib/morpheus/api/file_copy_request_interface.rb +2 -9
- data/lib/morpheus/api/group_policies_interface.rb +0 -6
- data/lib/morpheus/api/groups_interface.rb +0 -7
- data/lib/morpheus/api/guidance_interface.rb +9 -12
- data/lib/morpheus/api/health_interface.rb +0 -6
- data/lib/morpheus/api/image_builder_boot_scripts_interface.rb +0 -6
- data/lib/morpheus/api/image_builder_image_builds_interface.rb +0 -6
- data/lib/morpheus/api/image_builder_interface.rb +3 -9
- data/lib/morpheus/api/image_builder_preseed_scripts_interface.rb +0 -6
- data/lib/morpheus/api/instance_types_interface.rb +0 -7
- data/lib/morpheus/api/instances_interface.rb +8 -19
- data/lib/morpheus/api/integration_types_interface.rb +14 -0
- data/lib/morpheus/api/integrations_interface.rb +36 -21
- data/lib/morpheus/api/invoice_line_items_interface.rb +4 -9
- data/lib/morpheus/api/jobs_interface.rb +11 -14
- data/lib/morpheus/api/key_pairs_interface.rb +0 -6
- data/lib/morpheus/api/library_cluster_layouts_interface.rb +0 -6
- data/lib/morpheus/api/library_container_scripts_interface.rb +0 -6
- data/lib/morpheus/api/library_container_templates_interface.rb +0 -6
- data/lib/morpheus/api/library_container_types_interface.rb +0 -6
- data/lib/morpheus/api/library_container_upgrades_interface.rb +0 -6
- data/lib/morpheus/api/library_instance_types_interface.rb +0 -6
- data/lib/morpheus/api/library_layouts_interface.rb +0 -6
- data/lib/morpheus/api/library_spec_template_types_interface.rb +0 -6
- data/lib/morpheus/api/library_spec_templates_interface.rb +0 -6
- data/lib/morpheus/api/license_interface.rb +0 -6
- data/lib/morpheus/api/load_balancer_pools_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_types_interface.rb +9 -0
- data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +9 -0
- data/lib/morpheus/api/load_balancers_interface.rb +4 -59
- data/lib/morpheus/api/log_settings_interface.rb +9 -12
- data/lib/morpheus/api/logs_interface.rb +0 -6
- data/lib/morpheus/api/monitoring_alerts_interface.rb +0 -6
- data/lib/morpheus/api/monitoring_apps_interface.rb +0 -6
- data/lib/morpheus/api/monitoring_checks_interface.rb +0 -6
- data/lib/morpheus/api/monitoring_contacts_interface.rb +0 -6
- data/lib/morpheus/api/monitoring_groups_interface.rb +0 -6
- data/lib/morpheus/api/monitoring_incidents_interface.rb +0 -6
- data/lib/morpheus/api/monitoring_interface.rb +6 -12
- data/lib/morpheus/api/network_domain_records_interface.rb +0 -6
- data/lib/morpheus/api/network_domains_interface.rb +0 -6
- data/lib/morpheus/api/network_groups_interface.rb +0 -6
- data/lib/morpheus/api/network_pool_ips_interface.rb +0 -6
- data/lib/morpheus/api/network_pool_servers_interface.rb +0 -6
- data/lib/morpheus/api/network_pools_interface.rb +0 -6
- data/lib/morpheus/api/network_proxies_interface.rb +0 -6
- data/lib/morpheus/api/network_routers_interface.rb +56 -6
- data/lib/morpheus/api/network_security_servers_interface.rb +6 -9
- data/lib/morpheus/api/network_services_interface.rb +14 -14
- data/lib/morpheus/api/network_subnets_interface.rb +0 -6
- data/lib/morpheus/api/network_types_interface.rb +1 -7
- data/lib/morpheus/api/networks_interface.rb +0 -6
- data/lib/morpheus/api/option_type_lists_interface.rb +18 -12
- data/lib/morpheus/api/option_types_interface.rb +0 -6
- data/lib/morpheus/api/options_interface.rb +0 -6
- data/lib/morpheus/api/packages_interface.rb +0 -6
- data/lib/morpheus/api/policies_interface.rb +1 -8
- data/lib/morpheus/api/power_schedules_interface.rb +0 -6
- data/lib/morpheus/api/price_sets_interface.rb +8 -11
- data/lib/morpheus/api/prices_interface.rb +12 -15
- data/lib/morpheus/api/processes_interface.rb +0 -6
- data/lib/morpheus/api/provision_types_interface.rb +0 -6
- data/lib/morpheus/api/provisioning_license_types_interface.rb +0 -6
- data/lib/morpheus/api/provisioning_licenses_interface.rb +0 -6
- data/lib/morpheus/api/provisioning_settings_interface.rb +6 -9
- data/lib/morpheus/api/read_interface.rb +23 -0
- data/lib/morpheus/api/reports_interface.rb +0 -6
- data/lib/morpheus/api/rest_interface.rb +12 -10
- data/lib/morpheus/api/roles_interface.rb +7 -6
- data/lib/morpheus/api/secondary_read_interface.rb +25 -0
- data/lib/morpheus/api/secondary_rest_interface.rb +42 -0
- data/lib/morpheus/api/security_group_rules_interface.rb +0 -7
- data/lib/morpheus/api/security_groups_interface.rb +0 -6
- data/lib/morpheus/api/server_types_interface.rb +0 -6
- data/lib/morpheus/api/servers_interface.rb +7 -6
- data/lib/morpheus/api/service_plans_interface.rb +11 -14
- data/lib/morpheus/api/storage_providers_interface.rb +9 -16
- data/lib/morpheus/api/subnet_types_interface.rb +1 -7
- data/lib/morpheus/api/subnets_interface.rb +0 -6
- data/lib/morpheus/api/task_sets_interface.rb +0 -6
- data/lib/morpheus/api/tasks_interface.rb +0 -6
- data/lib/morpheus/api/user_groups_interface.rb +0 -6
- data/lib/morpheus/api/user_settings_interface.rb +38 -18
- data/lib/morpheus/api/user_sources_interface.rb +0 -6
- data/lib/morpheus/api/users_interface.rb +0 -6
- data/lib/morpheus/api/vdi_allocations_interface.rb +9 -0
- data/lib/morpheus/api/vdi_apps_interface.rb +9 -0
- data/lib/morpheus/api/vdi_gateways_interface.rb +9 -0
- data/lib/morpheus/api/vdi_interface.rb +28 -0
- data/lib/morpheus/api/vdi_pools_interface.rb +19 -0
- data/lib/morpheus/api/virtual_images_interface.rb +0 -6
- data/lib/morpheus/api/whitelabel_settings_interface.rb +8 -11
- data/lib/morpheus/api/wiki_interface.rb +0 -6
- data/lib/morpheus/cli.rb +10 -2
- data/lib/morpheus/cli/access_token_command.rb +1 -1
- data/lib/morpheus/cli/account_groups_command.rb +4 -4
- data/lib/morpheus/cli/apps.rb +68 -84
- data/lib/morpheus/cli/archives_command.rb +5 -5
- data/lib/morpheus/cli/blueprints_command.rb +5 -5
- data/lib/morpheus/cli/boot_scripts_command.rb +1 -1
- data/lib/morpheus/cli/catalog_item_types_command.rb +13 -13
- data/lib/morpheus/cli/certificates_command.rb +575 -0
- data/lib/morpheus/cli/change_password_command.rb +4 -4
- data/lib/morpheus/cli/cli_command.rb +72 -16
- data/lib/morpheus/cli/clouds.rb +3 -2
- data/lib/morpheus/cli/clusters.rb +3 -3
- data/lib/morpheus/cli/commands/standard/man_command.rb +4 -5
- data/lib/morpheus/cli/credentials.rb +4 -11
- data/lib/morpheus/cli/environments_command.rb +1 -1
- data/lib/morpheus/cli/execute_schedules_command.rb +3 -3
- data/lib/morpheus/cli/hosts.rb +253 -232
- data/lib/morpheus/cli/image_builder_command.rb +6 -6
- data/lib/morpheus/cli/instance_types.rb +1 -1
- data/lib/morpheus/cli/instances.rb +229 -219
- data/lib/morpheus/cli/integrations_command.rb +1155 -42
- data/lib/morpheus/cli/invoices_command.rb +75 -67
- data/lib/morpheus/cli/key_pairs.rb +2 -2
- data/lib/morpheus/cli/library_cluster_layouts_command.rb +2 -3
- data/lib/morpheus/cli/library_container_scripts_command.rb +4 -5
- data/lib/morpheus/cli/library_container_templates_command.rb +5 -1
- data/lib/morpheus/cli/library_container_types_command.rb +8 -9
- data/lib/morpheus/cli/library_instance_types_command.rb +6 -7
- data/lib/morpheus/cli/library_layouts_command.rb +9 -5
- data/lib/morpheus/cli/library_option_lists_command.rb +72 -20
- data/lib/morpheus/cli/library_option_types_command.rb +8 -4
- data/lib/morpheus/cli/library_spec_templates_command.rb +3 -4
- data/lib/morpheus/cli/library_upgrades_command.rb +6 -6
- data/lib/morpheus/cli/license.rb +2 -2
- data/lib/morpheus/cli/load_balancer_types.rb +37 -0
- data/lib/morpheus/cli/load_balancers.rb +149 -314
- data/lib/morpheus/cli/log_settings_command.rb +7 -3
- data/lib/morpheus/cli/login.rb +10 -1
- data/lib/morpheus/cli/mixins/load_balancers_helper.rb +156 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +44 -18
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +4 -4
- data/lib/morpheus/cli/mixins/rest_command.rb +657 -0
- data/lib/morpheus/cli/mixins/vdi_helper.rb +246 -0
- data/lib/morpheus/cli/network_routers_command.rb +1187 -176
- data/lib/morpheus/cli/networks_command.rb +195 -102
- data/lib/morpheus/cli/option_types.rb +66 -71
- data/lib/morpheus/cli/policies_command.rb +0 -1
- data/lib/morpheus/cli/power_schedules_command.rb +3 -3
- data/lib/morpheus/cli/preseed_scripts_command.rb +1 -1
- data/lib/morpheus/cli/remote.rb +2 -2
- data/lib/morpheus/cli/reports_command.rb +4 -1
- data/lib/morpheus/cli/roles.rb +224 -64
- data/lib/morpheus/cli/security_group_rules.rb +1 -1
- data/lib/morpheus/cli/setup.rb +0 -1
- data/lib/morpheus/cli/subnets_command.rb +11 -2
- data/lib/morpheus/cli/tenants_command.rb +21 -23
- data/lib/morpheus/cli/user_groups_command.rb +3 -3
- data/lib/morpheus/cli/user_settings_command.rb +268 -57
- data/lib/morpheus/cli/user_sources_command.rb +3 -3
- data/lib/morpheus/cli/users.rb +3 -3
- data/lib/morpheus/cli/vdi_allocations_command.rb +159 -0
- data/lib/morpheus/cli/vdi_apps_command.rb +317 -0
- data/lib/morpheus/cli/vdi_command.rb +359 -0
- data/lib/morpheus/cli/vdi_gateways_command.rb +290 -0
- data/lib/morpheus/cli/vdi_pools_command.rb +571 -0
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/virtual_images.rb +1 -1
- data/lib/morpheus/cli/whoami.rb +0 -15
- data/lib/morpheus/cli/wiki_command.rb +1 -1
- data/lib/morpheus/ext/string.rb +41 -0
- data/lib/morpheus/formatters.rb +4 -0
- data/lib/morpheus/rest_client.rb +30 -0
- data/lib/morpheus/terminal.rb +15 -7
- metadata +27 -2
|
@@ -46,15 +46,29 @@ module Morpheus
|
|
|
46
46
|
if options[:help_field_prefix]
|
|
47
47
|
option_type[:help_field_prefix] = options[:help_field_prefix]
|
|
48
48
|
end
|
|
49
|
+
# a lot of optionTypes have fieldGroup:'Options' instead of 'default'
|
|
50
|
+
if option_type['fieldGroup'].to_s.downcase == 'options'
|
|
51
|
+
option_type['fieldGroup'] = 'default'
|
|
52
|
+
end
|
|
49
53
|
end
|
|
50
54
|
# puts "Options Prompt #{options}"
|
|
51
|
-
#
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
# Sort options by default, group, advanced
|
|
56
|
+
cur_field_group = 'default'
|
|
57
|
+
(
|
|
58
|
+
option_types.reject {|it| (it['fieldGroup'] || 'default') != 'default'}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i} +
|
|
59
|
+
option_types.reject {|it| ['default', 'advanced'].include?(it['fieldGroup'] || 'default')}.sort{|a,b| a['displayOrder'] <=> b['displayOrder']}.group_by{|it| it['fieldGroup']}.values.collect { |it| it.sort{|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}}.flatten +
|
|
60
|
+
option_types.reject {|it| it['fieldGroup'] != 'advanced'}.sort {|a,b| a['displayOrder'].to_i <=> b['displayOrder'].to_i}
|
|
61
|
+
).each do |option_type|
|
|
54
62
|
context_map = results
|
|
55
63
|
value = nil
|
|
56
64
|
value_found=false
|
|
57
65
|
|
|
66
|
+
if cur_field_group != (option_type['fieldGroup'] || 'default')
|
|
67
|
+
cur_field_group = option_type['fieldGroup']
|
|
68
|
+
cur_field_group = cur_field_group.to_s.sub(/options\Z/i, "").strip # avoid "ADVANCED OPTION OPTIONS"
|
|
69
|
+
print "\n#{cur_field_group.upcase} OPTIONS\n#{"=" * ("#{cur_field_group} OPTIONS".length)}\n\n"
|
|
70
|
+
end
|
|
71
|
+
|
|
58
72
|
# How about this instead?
|
|
59
73
|
# option_type = option_type.clone
|
|
60
74
|
# field_key = [option_type['fieldContext'], option_type['fieldName']].select {|it| it && it != '' }.join('.')
|
|
@@ -78,46 +92,39 @@ module Morpheus
|
|
|
78
92
|
if !option_type['visibleOnCode'].to_s.empty?
|
|
79
93
|
visible_option_check_value = option_type['visibleOnCode']
|
|
80
94
|
end
|
|
95
|
+
|
|
81
96
|
if !visible_option_check_value.to_s.empty?
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
depends_on_values = []
|
|
88
|
-
if depends_on_value.size > 0
|
|
89
|
-
# strip parenthesis
|
|
90
|
-
if depends_on_value[0] && depends_on_value[0].chr == "("
|
|
91
|
-
depends_on_value = depends_on_value[1..-1]
|
|
92
|
-
end
|
|
93
|
-
depends_on_value.chomp(")")
|
|
94
|
-
depends_on_values = depends_on_value.split("|").collect { |it| it.strip }
|
|
95
|
-
end
|
|
96
|
-
depends_on_option_type = option_types.find {|it| it["code"] == depends_on_code }
|
|
97
|
-
if !depends_on_option_type
|
|
98
|
-
depends_on_option_type = option_types.find {|it|
|
|
99
|
-
(it['fieldContext'] ? "#{it['fieldContext']}.#{it['fieldName']}" : it['fieldName']) == depends_on_code
|
|
100
|
-
}
|
|
97
|
+
match_type = 'any'
|
|
98
|
+
|
|
99
|
+
if visible_option_check_value.include?('::')
|
|
100
|
+
match_type = 'all' if visible_option_check_value.start_with?('matchAll')
|
|
101
|
+
visible_option_check_value = visible_option_check_value[visible_option_check_value.index('::') + 2..-1]
|
|
101
102
|
end
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
103
|
+
|
|
104
|
+
found_dep_value = match_type == 'all' ? true : false
|
|
105
|
+
visible_option_check_value.split(',').each do |value|
|
|
106
|
+
parts = value.split(':')
|
|
107
|
+
depends_on_code = parts[0]
|
|
108
|
+
depends_on_value = parts.count > 1 ? parts[1].to_s.strip : '.'
|
|
109
|
+
depends_on_option_type = option_types.find {|it| it["code"] == depends_on_code }
|
|
110
|
+
if !depends_on_option_type
|
|
111
|
+
depends_on_option_type = option_types.find {|it|
|
|
112
|
+
(it['fieldContext'] ? "#{it['fieldContext']}.#{it['fieldName']}" : it['fieldName']) == depends_on_code
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
if depends_on_option_type
|
|
117
|
+
depends_on_field_key = depends_on_option_type['fieldContext'].nil? || depends_on_option_type['fieldContext'].empty? ? "#{depends_on_option_type['fieldName']}" : "#{depends_on_option_type['fieldContext']}.#{depends_on_option_type['fieldName']}"
|
|
118
|
+
field_value = get_object_value(results, depends_on_field_key) || get_object_value(options, depends_on_field_key)
|
|
119
|
+
|
|
120
|
+
if !field_value.nil? && field_value.match?(depends_on_value)
|
|
121
|
+
found_dep_value = true if match_type != 'all'
|
|
122
|
+
else
|
|
123
|
+
found_dep_value = false if match_type == 'all'
|
|
116
124
|
end
|
|
117
125
|
end
|
|
118
|
-
else
|
|
119
|
-
# could not find the dependent option type, proceed and prompt
|
|
120
126
|
end
|
|
127
|
+
next if !found_dep_value
|
|
121
128
|
end
|
|
122
129
|
|
|
123
130
|
cur_namespace = options
|
|
@@ -139,7 +146,9 @@ module Morpheus
|
|
|
139
146
|
value = cur_namespace[field_name]
|
|
140
147
|
input_value = ['select', 'multiSelect','typeahead', 'multiTypeahead'].include?(option_type['type']) && option_type['fieldInput'] ? cur_namespace[option_type['fieldInput']] : nil
|
|
141
148
|
if option_type['type'] == 'number'
|
|
142
|
-
|
|
149
|
+
if !value.to_s.empty?
|
|
150
|
+
value = value.to_s.include?('.') ? value.to_f : value.to_i
|
|
151
|
+
end
|
|
143
152
|
# these select prompts should just fall down through below, with the extra params no_prompt, use_value
|
|
144
153
|
elsif option_type['type'] == 'select'
|
|
145
154
|
value = select_prompt(option_type.merge({'defaultValue' => value, 'defaultInputValue' => input_value}), api_client, (option_type['noParams'] ? {} : (api_params || {}).merge(results)), true)
|
|
@@ -265,30 +274,13 @@ module Morpheus
|
|
|
265
274
|
|
|
266
275
|
if option_type['type'] == 'multiSelect'
|
|
267
276
|
value = [value] if !value.nil? && !value.is_a?(Array)
|
|
268
|
-
parent_context_map[parent_ns] = value
|
|
269
|
-
else
|
|
270
|
-
context_map[field_name] = value
|
|
277
|
+
# parent_context_map[parent_ns] = value
|
|
271
278
|
end
|
|
279
|
+
context_map[field_name] = value
|
|
272
280
|
end
|
|
273
281
|
results
|
|
274
282
|
end
|
|
275
283
|
|
|
276
|
-
def self.grails_params(data, context=nil)
|
|
277
|
-
params = {}
|
|
278
|
-
data.each do |k,v|
|
|
279
|
-
if v.is_a?(Hash)
|
|
280
|
-
params.merge!(grails_params(v, context ? "#{context}.#{k.to_s}" : k))
|
|
281
|
-
else
|
|
282
|
-
if context
|
|
283
|
-
params["#{context}.#{k.to_s}"] = v
|
|
284
|
-
else
|
|
285
|
-
params[k.to_s] = v
|
|
286
|
-
end
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
|
-
return params
|
|
290
|
-
end
|
|
291
|
-
|
|
292
284
|
def self.radio_prompt(option_type)
|
|
293
285
|
value_found = false
|
|
294
286
|
value = nil
|
|
@@ -330,7 +322,9 @@ module Morpheus
|
|
|
330
322
|
print "#{option_type['fieldLabel']}#{option_type['fieldAddOn'] ? ('(' + option_type['fieldAddOn'] + ') ') : '' }#{!option_type['required'] ? ' (optional)' : ''}#{!option_type['defaultValue'].to_s.empty? ? ' ['+option_type['defaultValue'].to_s+']' : ''}: "
|
|
331
323
|
input = $stdin.gets.chomp!
|
|
332
324
|
value = input.empty? ? option_type['defaultValue'] : input
|
|
333
|
-
|
|
325
|
+
if !value.to_s.empty?
|
|
326
|
+
value = value.to_s.include?('.') ? value.to_f : value.to_i
|
|
327
|
+
end
|
|
334
328
|
if input == '?'
|
|
335
329
|
help_prompt(option_type)
|
|
336
330
|
elsif !value.nil? || option_type['required'] != true
|
|
@@ -363,7 +357,7 @@ module Morpheus
|
|
|
363
357
|
if option_type['selectOptions']
|
|
364
358
|
# calculate from inline lambda
|
|
365
359
|
if option_type['selectOptions'].is_a?(Proc)
|
|
366
|
-
select_options = option_type['selectOptions'].call(api_client,
|
|
360
|
+
select_options = option_type['selectOptions'].call(api_client, api_params || {})
|
|
367
361
|
else
|
|
368
362
|
# todo: better type validation
|
|
369
363
|
select_options = option_type['selectOptions']
|
|
@@ -371,13 +365,13 @@ module Morpheus
|
|
|
371
365
|
elsif option_type['optionSource']
|
|
372
366
|
# calculate from inline lambda
|
|
373
367
|
if option_type['optionSource'].is_a?(Proc)
|
|
374
|
-
select_options = option_type['optionSource'].call(api_client,
|
|
368
|
+
select_options = option_type['optionSource'].call(api_client, api_params || {})
|
|
375
369
|
elsif option_type['optionSource'] == 'list'
|
|
376
370
|
# /api/options/list is a special action for custom OptionTypeLists, just need to pass the optionTypeId parameter
|
|
377
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
|
371
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {}.merge({'optionTypeId' => option_type['id']}))
|
|
378
372
|
else
|
|
379
373
|
# remote optionSource aka /api/options/$optionSource?
|
|
380
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
|
374
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {})
|
|
381
375
|
end
|
|
382
376
|
else
|
|
383
377
|
raise "option '#{field_key}' is type: 'select' and missing selectOptions or optionSource!"
|
|
@@ -571,6 +565,7 @@ module Morpheus
|
|
|
571
565
|
# looking for help with this input
|
|
572
566
|
if input == '?'
|
|
573
567
|
help_prompt(option_type)
|
|
568
|
+
select_options = load_options(option_type, api_client, api_params)
|
|
574
569
|
display_select_options(option_type, select_options) unless select_options.empty?
|
|
575
570
|
next
|
|
576
571
|
end
|
|
@@ -597,7 +592,7 @@ module Morpheus
|
|
|
597
592
|
# actually that is redundant, it should already be filtered to matches
|
|
598
593
|
# and can just do this:
|
|
599
594
|
# select_option = select_options.size == 1 ? select_options[0] : nil
|
|
600
|
-
select_option = select_options.find{|b| (b[value_field] && (b[value_field].to_s == input.to_s)) || ((b[value_field].nil? || b[value_field]
|
|
595
|
+
select_option = select_options.find{|b| (b[value_field] && (b[value_field].to_s == input.to_s)) || ((b[value_field].nil? || b[value_field] == "") && (input == "")) }
|
|
601
596
|
if select_option.nil?
|
|
602
597
|
select_option = select_options.find{|b| b['name'] && b['name'] == input }
|
|
603
598
|
end
|
|
@@ -888,7 +883,7 @@ module Morpheus
|
|
|
888
883
|
if option_type['selectOptions']
|
|
889
884
|
# calculate from inline lambda
|
|
890
885
|
if option_type['selectOptions'].is_a?(Proc)
|
|
891
|
-
select_options = option_type['selectOptions'].call(api_client,
|
|
886
|
+
select_options = option_type['selectOptions'].call(api_client, api_params || {})
|
|
892
887
|
else
|
|
893
888
|
select_options = option_type['selectOptions']
|
|
894
889
|
end
|
|
@@ -903,13 +898,13 @@ module Morpheus
|
|
|
903
898
|
elsif option_type['optionSource']
|
|
904
899
|
# calculate from inline lambda
|
|
905
900
|
if option_type['optionSource'].is_a?(Proc)
|
|
906
|
-
select_options = option_type['optionSource'].call(api_client,
|
|
901
|
+
select_options = option_type['optionSource'].call(api_client, api_params || {})
|
|
907
902
|
elsif option_type['optionSource'] == 'list'
|
|
908
903
|
# /api/options/list is a special action for custom OptionTypeLists, just need to pass the optionTypeId parameter
|
|
909
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
|
904
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {}.merge({'optionTypeId' => option_type['id']}))
|
|
910
905
|
else
|
|
911
906
|
# remote optionSource aka /api/options/$optionSource?
|
|
912
|
-
select_options = load_source_options(option_type['optionSource'], api_client,
|
|
907
|
+
select_options = load_source_options(option_type['optionSource'], option_type['optionSourceType'], api_client, api_params || {})
|
|
913
908
|
end
|
|
914
909
|
else
|
|
915
910
|
raise "option '#{field_key}' is type: 'typeahead' and missing selectOptions or optionSource!"
|
|
@@ -935,8 +930,8 @@ module Morpheus
|
|
|
935
930
|
end
|
|
936
931
|
|
|
937
932
|
|
|
938
|
-
def self.load_source_options(source,api_client,params)
|
|
939
|
-
api_client.options.options_for_source(source,params)['data']
|
|
933
|
+
def self.load_source_options(source,sourceType,api_client,params)
|
|
934
|
+
api_client.options.options_for_source("#{sourceType ? "#{sourceType}/" : ''}#{source}",params)['data']
|
|
940
935
|
end
|
|
941
936
|
|
|
942
937
|
def self.format_select_options_help(opt, select_options = [], paging = nil)
|
|
@@ -951,7 +946,7 @@ module Morpheus
|
|
|
951
946
|
out = ""
|
|
952
947
|
out << "\n"
|
|
953
948
|
out << "#{header}\n"
|
|
954
|
-
out << "
|
|
949
|
+
out << "#{'=' * header.length}\n"
|
|
955
950
|
select_options.each do |option|
|
|
956
951
|
out << " * #{option['name']} [#{option['value']}]\n"
|
|
957
952
|
end
|
|
@@ -26,7 +26,6 @@ class Morpheus::Cli::PoliciesCommand
|
|
|
26
26
|
|
|
27
27
|
def connect(opts)
|
|
28
28
|
@api_client = establish_remote_appliance_connection(opts)
|
|
29
|
-
# @policies_interface = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url).policies
|
|
30
29
|
@policies_interface = @api_client.policies
|
|
31
30
|
@group_policies_interface = @api_client.group_policies
|
|
32
31
|
@cloud_policies_interface = @api_client.cloud_policies
|
|
@@ -13,9 +13,9 @@ class Morpheus::Cli::PowerSchedulesCommand
|
|
|
13
13
|
|
|
14
14
|
def connect(opts)
|
|
15
15
|
@api_client = establish_remote_appliance_connection(opts)
|
|
16
|
-
@power_schedules_interface =
|
|
17
|
-
@instances_interface =
|
|
18
|
-
@servers_interface =
|
|
16
|
+
@power_schedules_interface = @api_client.power_schedules
|
|
17
|
+
@instances_interface = @api_client.instances
|
|
18
|
+
@servers_interface = @api_client.servers
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def handle(args)
|
|
@@ -23,7 +23,7 @@ class Morpheus::Cli::PreseedScriptsCommand
|
|
|
23
23
|
|
|
24
24
|
def connect(opts)
|
|
25
25
|
@api_client = establish_remote_appliance_connection(opts)
|
|
26
|
-
@image_builder_interface =
|
|
26
|
+
@image_builder_interface = @api_client.image_builder
|
|
27
27
|
@preseed_scripts_interface = @image_builder_interface.preseed_scripts
|
|
28
28
|
end
|
|
29
29
|
|
data/lib/morpheus/cli/remote.rb
CHANGED
|
@@ -1337,7 +1337,7 @@ EOT
|
|
|
1337
1337
|
include Term::ANSIColor
|
|
1338
1338
|
|
|
1339
1339
|
# for caching the the contents of YAML file $home/appliances
|
|
1340
|
-
# it is structured like :appliance_name => {:host => "
|
|
1340
|
+
# it is structured like :appliance_name => {:host => "https://api.gomorpheus.com", :active => true}
|
|
1341
1341
|
# not named @@appliances to avoid confusion with the instance variable . This is also a command class...
|
|
1342
1342
|
@@appliance_config = nil
|
|
1343
1343
|
|
|
@@ -1700,7 +1700,7 @@ EOT
|
|
|
1700
1700
|
# wtf, no url...
|
|
1701
1701
|
return appliance, json_response
|
|
1702
1702
|
else
|
|
1703
|
-
setup_interface = Morpheus::SetupInterface.new({url:appliance_url, verify_ssl:
|
|
1703
|
+
setup_interface = Morpheus::SetupInterface.new({url:appliance_url, verify_ssl: !appliance[:insecure], timeout: timeout})
|
|
1704
1704
|
start_time = Time.now
|
|
1705
1705
|
begin
|
|
1706
1706
|
json_response = setup_interface.check(params)
|
|
@@ -368,7 +368,6 @@ class Morpheus::Cli::ReportsCommand
|
|
|
368
368
|
do_mkdir = false
|
|
369
369
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
370
370
|
opts.banner = subcommand_usage("[id] [file]")
|
|
371
|
-
build_common_options(opts, options, [:dry_run, :remote])
|
|
372
371
|
opts.on( '--format VALUE', String, "Report Format for exported file, json or csv. Default is json." ) do |val|
|
|
373
372
|
report_format = val
|
|
374
373
|
end
|
|
@@ -379,6 +378,7 @@ class Morpheus::Cli::ReportsCommand
|
|
|
379
378
|
opts.on( '-p', '--mkdir', "Create missing directories for [local-file] if they do not exist." ) do
|
|
380
379
|
do_mkdir = true
|
|
381
380
|
end
|
|
381
|
+
build_common_options(opts, options, [:dry_run, :remote])
|
|
382
382
|
opts.footer = "Export a report result as json or csv." + "\n" +
|
|
383
383
|
"[id] is required. This is id of the report result." + "\n" +
|
|
384
384
|
"[file] is required. This is local destination for the downloaded file."
|
|
@@ -394,6 +394,9 @@ class Morpheus::Cli::ReportsCommand
|
|
|
394
394
|
|
|
395
395
|
outfile = args[1]
|
|
396
396
|
outfile = File.expand_path(outfile)
|
|
397
|
+
if outfile =~ /\.csv\Z/i
|
|
398
|
+
report_format = "csv"
|
|
399
|
+
end
|
|
397
400
|
|
|
398
401
|
if Dir.exists?(outfile)
|
|
399
402
|
print_red_alert "[file] is invalid. It is the name of an existing directory: #{outfile}"
|
data/lib/morpheus/cli/roles.rb
CHANGED
|
@@ -13,21 +13,21 @@ class Morpheus::Cli::Roles
|
|
|
13
13
|
include Morpheus::Cli::AccountsHelper
|
|
14
14
|
include Morpheus::Cli::ProvisioningHelper
|
|
15
15
|
include Morpheus::Cli::WhoamiHelper
|
|
16
|
-
register_subcommands :list, :get, :add, :update, :remove, :'list-permissions', :'update-feature-access', :'update-global-group-access', :'update-group-access', :'update-global-cloud-access', :'update-cloud-access', :'update-global-instance-type-access', :'update-instance-type-access', :'update-global-blueprint-access', :'update-blueprint-access', :'update-global-catalog-item-type-access', :'update-catalog-item-type-access', :'update-persona-access'
|
|
16
|
+
register_subcommands :list, :get, :add, :update, :remove, :'list-permissions', :'update-feature-access', :'update-global-group-access', :'update-group-access', :'update-global-cloud-access', :'update-cloud-access', :'update-global-instance-type-access', :'update-instance-type-access', :'update-global-blueprint-access', :'update-blueprint-access', :'update-global-catalog-item-type-access', :'update-catalog-item-type-access', :'update-persona-access', :'update-global-vdi-pool-access', :'update-vdi-pool-access'
|
|
17
17
|
alias_subcommand :details, :get
|
|
18
18
|
set_default_subcommand :list
|
|
19
19
|
|
|
20
20
|
def connect(opts)
|
|
21
21
|
@api_client = establish_remote_appliance_connection(opts)
|
|
22
|
-
@whoami_interface =
|
|
23
|
-
@users_interface =
|
|
24
|
-
@accounts_interface =
|
|
25
|
-
@roles_interface =
|
|
26
|
-
@groups_interface =
|
|
27
|
-
@options_interface =
|
|
28
|
-
@instances_interface =
|
|
29
|
-
@instance_types_interface =
|
|
30
|
-
@blueprints_interface =
|
|
22
|
+
@whoami_interface = @api_client.whoami
|
|
23
|
+
@users_interface = @api_client.users
|
|
24
|
+
@accounts_interface = @api_client.accounts
|
|
25
|
+
@roles_interface = @api_client.roles
|
|
26
|
+
@groups_interface = @api_client.groups
|
|
27
|
+
@options_interface = @api_client.options
|
|
28
|
+
@instances_interface = @api_client.instances
|
|
29
|
+
@instance_types_interface = @api_client.instance_types
|
|
30
|
+
@blueprints_interface = @api_client.blueprints
|
|
31
31
|
@active_group_id = Morpheus::Cli::Groups.active_groups[@appliance_name]
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -102,19 +102,23 @@ class Morpheus::Cli::Roles
|
|
|
102
102
|
options[:include_blueprint_access] = true
|
|
103
103
|
end
|
|
104
104
|
opts.on(nil,'--catalog-item-type-access', "Display Catalog Item Type Access") do
|
|
105
|
-
options[:
|
|
105
|
+
options[:include_catalog_item_type_access] = true
|
|
106
106
|
end
|
|
107
107
|
opts.on(nil,'--personas', "Display Persona Access") do
|
|
108
108
|
options[:include_personas_access] = true
|
|
109
109
|
end
|
|
110
|
+
opts.on(nil,'--vdi-pool-access', "Display VDI Pool Access") do
|
|
111
|
+
options[:include_vdi_pool_access] = true
|
|
112
|
+
end
|
|
110
113
|
opts.on('-a','--all', "Display All Access Lists") do
|
|
111
114
|
options[:include_feature_access] = true
|
|
112
115
|
options[:include_group_access] = true
|
|
113
116
|
options[:include_cloud_access] = true
|
|
114
117
|
options[:include_instance_type_access] = true
|
|
115
118
|
options[:include_blueprint_access] = true
|
|
116
|
-
options[:
|
|
119
|
+
options[:include_catalog_item_type_access] = true
|
|
117
120
|
options[:include_personas_access] = true
|
|
121
|
+
options[:include_vdi_pool_access] = true
|
|
118
122
|
end
|
|
119
123
|
build_standard_get_options(opts, options)
|
|
120
124
|
opts.footer = <<-EOT
|
|
@@ -206,9 +210,9 @@ EOT
|
|
|
206
210
|
rows = rows.select {|row| row[:code].to_s =~ phrase_regexp || row[:name].to_s =~ phrase_regexp }
|
|
207
211
|
end
|
|
208
212
|
print as_pretty_table(rows, [:code, :name, :access], options)
|
|
209
|
-
print reset,"\n"
|
|
213
|
+
# print reset,"\n"
|
|
210
214
|
else
|
|
211
|
-
print cyan,"Use --permissions to list permissions","\n"
|
|
215
|
+
print cyan,"Use --permissions to list feature permissions","\n"
|
|
212
216
|
end
|
|
213
217
|
|
|
214
218
|
has_group_access = true
|
|
@@ -220,6 +224,7 @@ EOT
|
|
|
220
224
|
"Instance Types" => lambda {|it| get_access_string(it['globalInstanceTypeAccess']) },
|
|
221
225
|
"Blueprints" => lambda {|it| get_access_string(it['globalAppTemplateAccess'] || it['globalBlueprintAccess']) },
|
|
222
226
|
"Catalog Item Types" => lambda {|it| get_access_string(it['globalCatalogItemTypeAccess']) },
|
|
227
|
+
"VDI Pools" => lambda {|it| get_access_string(it['globalVdiPoolAccess']) },
|
|
223
228
|
}
|
|
224
229
|
if role['roleType'].to_s.downcase == 'account'
|
|
225
230
|
global_access_columns.delete("Groups")
|
|
@@ -228,7 +233,7 @@ EOT
|
|
|
228
233
|
global_access_columns.delete("Clouds")
|
|
229
234
|
has_cloud_access = false
|
|
230
235
|
end
|
|
231
|
-
|
|
236
|
+
print as_pretty_table([json_response], global_access_columns, options)
|
|
232
237
|
|
|
233
238
|
if has_group_access
|
|
234
239
|
#print_h2 "Group Access: #{get_access_string(json_response['globalSiteAccess'])}", options
|
|
@@ -246,7 +251,7 @@ EOT
|
|
|
246
251
|
else
|
|
247
252
|
print cyan,"Use -g, --group-access to list custom access","\n"
|
|
248
253
|
end
|
|
249
|
-
print reset,"\n"
|
|
254
|
+
# print reset,"\n"
|
|
250
255
|
else
|
|
251
256
|
# print "\n"
|
|
252
257
|
# print cyan,bold,"Group Access: #{get_access_string(json_response['globalSiteAccess'])}",reset,"\n"
|
|
@@ -270,7 +275,7 @@ EOT
|
|
|
270
275
|
else
|
|
271
276
|
print cyan,"Use -c, --cloud-access to list custom access","\n"
|
|
272
277
|
end
|
|
273
|
-
print reset,"\n"
|
|
278
|
+
# print reset,"\n"
|
|
274
279
|
else
|
|
275
280
|
# print "\n"
|
|
276
281
|
# print cyan,bold,"Cloud Access: #{get_access_string(json_response['globalZoneAccess'])}",reset,"\n"
|
|
@@ -293,7 +298,7 @@ EOT
|
|
|
293
298
|
else
|
|
294
299
|
print cyan,"Use -i, --instance-type-access to list custom access","\n"
|
|
295
300
|
end
|
|
296
|
-
print reset,"\n"
|
|
301
|
+
# print reset,"\n"
|
|
297
302
|
else
|
|
298
303
|
# print "\n"
|
|
299
304
|
# print cyan,bold,"Instance Type Access: #{get_access_string(json_response['globalInstanceTypeAccess'])}",reset,"\n"
|
|
@@ -317,7 +322,7 @@ EOT
|
|
|
317
322
|
else
|
|
318
323
|
print cyan,"Use -b, --blueprint-access to list custom access","\n"
|
|
319
324
|
end
|
|
320
|
-
print reset,"\n"
|
|
325
|
+
# print reset,"\n"
|
|
321
326
|
else
|
|
322
327
|
# print "\n"
|
|
323
328
|
# print cyan,bold,"Blueprint Access: #{get_access_string(json_response['globalAppTemplateAccess'])}",reset,"\n"
|
|
@@ -331,7 +336,7 @@ EOT
|
|
|
331
336
|
# print "\n"
|
|
332
337
|
if catalog_item_type_global_access == 'custom'
|
|
333
338
|
print_h2 "Catalog Item Type Access", options
|
|
334
|
-
if options[:
|
|
339
|
+
if options[:include_catalog_item_type_access]
|
|
335
340
|
rows = catalog_item_type_permissions.collect do |it|
|
|
336
341
|
{
|
|
337
342
|
name: it['name'],
|
|
@@ -350,6 +355,7 @@ EOT
|
|
|
350
355
|
|
|
351
356
|
persona_permissions = json_response['personaPermissions'] || json_response['personas'] || []
|
|
352
357
|
# if options[:include_personas_access]
|
|
358
|
+
print cyan
|
|
353
359
|
if persona_permissions
|
|
354
360
|
print_h2 "Persona Access", options
|
|
355
361
|
rows = persona_permissions.collect do |it|
|
|
@@ -358,13 +364,34 @@ EOT
|
|
|
358
364
|
access: format_access_string(it['access'], ["none","read","full"]),
|
|
359
365
|
}
|
|
360
366
|
end
|
|
361
|
-
print as_pretty_table(rows, [:name, :access], options)
|
|
362
|
-
print reset,"\n"
|
|
367
|
+
print as_pretty_table(rows, [:name, :access], options)
|
|
363
368
|
end
|
|
364
369
|
|
|
365
370
|
# print reset,"\n"
|
|
366
371
|
|
|
372
|
+
vdi_pool_global_access = json_response['globalVdiPoolAccess']
|
|
373
|
+
vdi_pool_permissions = json_response['vdiPoolPermissions'] || []
|
|
374
|
+
print cyan
|
|
375
|
+
if vdi_pool_global_access == 'custom'
|
|
376
|
+
print_h2 "VDI Pool Access", options
|
|
377
|
+
if options[:include_vdi_pool_access]
|
|
378
|
+
rows = vdi_pool_permissions.collect do |it|
|
|
379
|
+
{
|
|
380
|
+
name: it['name'],
|
|
381
|
+
access: format_access_string(it['access'], ["none","read","full"]),
|
|
382
|
+
}
|
|
383
|
+
end
|
|
384
|
+
print as_pretty_table(rows, [:name, :access], options)
|
|
385
|
+
else
|
|
386
|
+
print cyan,"Use --vdi-pool-access to list custom access","\n"
|
|
387
|
+
end
|
|
388
|
+
else
|
|
389
|
+
# print "\n"
|
|
390
|
+
# print cyan,bold,"VDI Pool Access: #{get_access_string(json_response['globalVdiPoolAccess'])}",reset,"\n"
|
|
391
|
+
end
|
|
392
|
+
|
|
367
393
|
end
|
|
394
|
+
print reset,"\n"
|
|
368
395
|
|
|
369
396
|
return 0, nil
|
|
370
397
|
end
|
|
@@ -520,7 +547,7 @@ EOT
|
|
|
520
547
|
end
|
|
521
548
|
|
|
522
549
|
# v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'optionSource' => 'personas', 'description' => 'Default Persona'}], options[:options], @api_client)
|
|
523
|
-
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' =>
|
|
550
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' => get_persona_select_options(), 'description' => 'Default Persona'}], options[:options], @api_client)
|
|
524
551
|
role_payload['defaultPersona'] = {'code' => v_prompt['defaultPersona']} unless v_prompt['defaultPersona'].to_s.strip.empty?
|
|
525
552
|
|
|
526
553
|
payload = {"role" => role_payload}
|
|
@@ -782,14 +809,14 @@ EOT
|
|
|
782
809
|
def update_group_access(args)
|
|
783
810
|
options = {}
|
|
784
811
|
name = nil
|
|
785
|
-
|
|
812
|
+
group_id = nil
|
|
786
813
|
access_value = nil
|
|
787
814
|
do_all = false
|
|
788
815
|
allowed_access_values = ['full', 'read', 'none']
|
|
789
816
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
790
817
|
opts.banner = subcommand_usage("[role] [group] [access]")
|
|
791
818
|
opts.on( '-g', '--group GROUP', "Group name or id" ) do |val|
|
|
792
|
-
|
|
819
|
+
group_id = val
|
|
793
820
|
end
|
|
794
821
|
opts.on( nil, '--all', "Update all groups at once." ) do
|
|
795
822
|
do_all = true
|
|
@@ -845,9 +872,8 @@ EOT
|
|
|
845
872
|
end
|
|
846
873
|
|
|
847
874
|
group = nil
|
|
848
|
-
group_id = nil
|
|
849
875
|
if !do_all
|
|
850
|
-
group = find_group_by_name_or_id_for_provisioning(
|
|
876
|
+
group = find_group_by_name_or_id_for_provisioning(group_id)
|
|
851
877
|
return 1 if group.nil?
|
|
852
878
|
group_id = group['id']
|
|
853
879
|
end
|
|
@@ -932,15 +958,14 @@ EOT
|
|
|
932
958
|
|
|
933
959
|
def update_cloud_access(args)
|
|
934
960
|
options = {}
|
|
935
|
-
|
|
961
|
+
cloud_id = nil
|
|
936
962
|
access_value = nil
|
|
937
963
|
do_all = false
|
|
938
964
|
allowed_access_values = ['full', 'read', 'none']
|
|
939
965
|
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
940
966
|
opts.banner = subcommand_usage("[name]")
|
|
941
967
|
opts.on( '-c', '--cloud CLOUD', "Cloud name or id" ) do |val|
|
|
942
|
-
|
|
943
|
-
cloud_name = val
|
|
968
|
+
cloud_id = val
|
|
944
969
|
end
|
|
945
970
|
opts.on( nil, '--all', "Update all clouds at once." ) do
|
|
946
971
|
do_all = true
|
|
@@ -948,9 +973,6 @@ EOT
|
|
|
948
973
|
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
|
949
974
|
access_value = val
|
|
950
975
|
end
|
|
951
|
-
opts.on( '-g', '--group GROUP', "Group to find cloud in" ) do |val|
|
|
952
|
-
options[:group] = val
|
|
953
|
-
end
|
|
954
976
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
|
955
977
|
opts.footer = "Update role access for a cloud or all clouds.\n" +
|
|
956
978
|
"[role] is required. This is the name or id of a role.\n" +
|
|
@@ -998,23 +1020,11 @@ EOT
|
|
|
998
1020
|
exit 1
|
|
999
1021
|
end
|
|
1000
1022
|
|
|
1001
|
-
|
|
1002
|
-
group_id = nil
|
|
1003
|
-
cloud_id = nil
|
|
1023
|
+
cloud = nil
|
|
1004
1024
|
if !do_all
|
|
1005
|
-
|
|
1006
|
-
if
|
|
1007
|
-
|
|
1008
|
-
group_id = group['id']
|
|
1009
|
-
else
|
|
1010
|
-
group_id = @active_group_id
|
|
1011
|
-
end
|
|
1012
|
-
if group_id.nil?
|
|
1013
|
-
print_red_alert "Group not found or specified!"
|
|
1014
|
-
return 1
|
|
1015
|
-
end
|
|
1016
|
-
cloud_id = find_cloud_id_by_name(group_id, cloud_name)
|
|
1017
|
-
return 1 if cloud_id.nil?
|
|
1025
|
+
cloud = find_cloud_by_name_or_id_for_provisioning(nil, cloud_id)
|
|
1026
|
+
return 1 if cloud.nil?
|
|
1027
|
+
cloud_id = cloud['id']
|
|
1018
1028
|
end
|
|
1019
1029
|
params = {}
|
|
1020
1030
|
if do_all
|
|
@@ -1037,7 +1047,7 @@ EOT
|
|
|
1037
1047
|
if do_all
|
|
1038
1048
|
print_green_success "Role #{role['authority']} access updated for all clouds"
|
|
1039
1049
|
else
|
|
1040
|
-
print_green_success "Role #{role['authority']} access updated for cloud
|
|
1050
|
+
print_green_success "Role #{role['authority']} access updated for cloud #{cloud['name']}"
|
|
1041
1051
|
end
|
|
1042
1052
|
end
|
|
1043
1053
|
return 0
|
|
@@ -1534,7 +1544,7 @@ EOT
|
|
|
1534
1544
|
build_common_options(opts, options, [:json, :dry_run, :remote])
|
|
1535
1545
|
opts.footer = "Update role access for a persona or all personas.\n" +
|
|
1536
1546
|
"[role] is required. This is the name or id of a role.\n" +
|
|
1537
|
-
"--persona or --all is required. This is the code of a persona. Service Catalog or
|
|
1547
|
+
"--persona or --all is required. This is the code of a persona. Service Catalog, Standard, or Virtual Desktop\n" +
|
|
1538
1548
|
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
|
1539
1549
|
end
|
|
1540
1550
|
optparse.parse!(args)
|
|
@@ -1606,6 +1616,160 @@ EOT
|
|
|
1606
1616
|
end
|
|
1607
1617
|
end
|
|
1608
1618
|
|
|
1619
|
+
def update_global_vdi_pool_access(args)
|
|
1620
|
+
usage = "Usage: morpheus roles update-global-vdi-pool-access [role] [full|custom|none]"
|
|
1621
|
+
options = {}
|
|
1622
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
1623
|
+
opts.banner = subcommand_usage("[role] [full|custom|none]")
|
|
1624
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
|
1625
|
+
end
|
|
1626
|
+
optparse.parse!(args)
|
|
1627
|
+
verify_args!(args:args, optparse:optparse, count: 2)
|
|
1628
|
+
name = args[0]
|
|
1629
|
+
access_value = args[1].to_s.downcase
|
|
1630
|
+
if !['full', 'custom', 'none'].include?(access_value)
|
|
1631
|
+
raise_command_error("invalid access value: #{args[1]}", optparse)
|
|
1632
|
+
end
|
|
1633
|
+
|
|
1634
|
+
|
|
1635
|
+
connect(options)
|
|
1636
|
+
begin
|
|
1637
|
+
account = find_account_from_options(options)
|
|
1638
|
+
account_id = account ? account['id'] : nil
|
|
1639
|
+
role = find_role_by_name_or_id(account_id, name)
|
|
1640
|
+
exit 1 if role.nil?
|
|
1641
|
+
# note: VdiPools being plural is odd, the others are singular
|
|
1642
|
+
params = {permissionCode: 'VdiPools', access: access_value}
|
|
1643
|
+
@roles_interface.setopts(options)
|
|
1644
|
+
if options[:dry_run]
|
|
1645
|
+
print_dry_run @roles_interface.dry.update_permission(account_id, role['id'], params)
|
|
1646
|
+
return
|
|
1647
|
+
end
|
|
1648
|
+
json_response = @roles_interface.update_permission(account_id, role['id'], params)
|
|
1649
|
+
|
|
1650
|
+
if options[:json]
|
|
1651
|
+
print JSON.pretty_generate(json_response)
|
|
1652
|
+
print "\n"
|
|
1653
|
+
else
|
|
1654
|
+
print_green_success "Role #{role['authority']} global vdi pool access updated"
|
|
1655
|
+
end
|
|
1656
|
+
rescue RestClient::Exception => e
|
|
1657
|
+
print_rest_exception(e, options)
|
|
1658
|
+
exit 1
|
|
1659
|
+
end
|
|
1660
|
+
end
|
|
1661
|
+
|
|
1662
|
+
def update_vdi_pool_access(args)
|
|
1663
|
+
options = {}
|
|
1664
|
+
vdi_pool_id = nil
|
|
1665
|
+
access_value = nil
|
|
1666
|
+
do_all = false
|
|
1667
|
+
allowed_access_values = ['full', 'none']
|
|
1668
|
+
optparse = Morpheus::Cli::OptionParser.new do |opts|
|
|
1669
|
+
opts.banner = subcommand_usage("[role] [vdi-pool] [access]")
|
|
1670
|
+
opts.on( '--vdi-pool ID', String, "VDI Pool ID or Name" ) do |val|
|
|
1671
|
+
vdi_pool_id = val
|
|
1672
|
+
end
|
|
1673
|
+
opts.on( nil, '--all', "Update all VDI pools at once." ) do
|
|
1674
|
+
do_all = true
|
|
1675
|
+
end
|
|
1676
|
+
opts.on( '--access VALUE', String, "Access value [#{allowed_access_values.join('|')}]" ) do |val|
|
|
1677
|
+
access_value = val
|
|
1678
|
+
end
|
|
1679
|
+
build_common_options(opts, options, [:json, :dry_run, :remote])
|
|
1680
|
+
opts.footer = "Update role access for a VDI pool or all VDI pools.\n" +
|
|
1681
|
+
"[role] is required. This is the name or id of a role.\n" +
|
|
1682
|
+
"--vdi-pool or --all is required. This is the name or id of a VDI pool.\n" +
|
|
1683
|
+
"--access is required. This is the new access value. #{anded_list(allowed_access_values)}"
|
|
1684
|
+
end
|
|
1685
|
+
optparse.parse!(args)
|
|
1686
|
+
|
|
1687
|
+
# usage: update-vdi-pool-access [role] [access] --all
|
|
1688
|
+
# update-vdi-pool-access [role] [vdi-pool] [access]
|
|
1689
|
+
name = args[0]
|
|
1690
|
+
if do_all
|
|
1691
|
+
verify_args!(args:args, optparse:optparse, min:1, max:2)
|
|
1692
|
+
access_value = args[1] if args[1]
|
|
1693
|
+
else
|
|
1694
|
+
verify_args!(args:args, optparse:optparse, min:1, max:3)
|
|
1695
|
+
vdi_pool_id = args[1] if args[1]
|
|
1696
|
+
access_value = args[2] if args[2]
|
|
1697
|
+
end
|
|
1698
|
+
if !vdi_pool_id && !do_all
|
|
1699
|
+
raise_command_error("missing required argument: [vdi-pool] or --all", optparse)
|
|
1700
|
+
end
|
|
1701
|
+
if !access_value
|
|
1702
|
+
raise_command_error("missing required argument: [access]", optparse)
|
|
1703
|
+
end
|
|
1704
|
+
access_value = access_value.to_s.downcase
|
|
1705
|
+
if !allowed_access_values.include?(access_value)
|
|
1706
|
+
raise_command_error("invalid access value: #{access_value}", optparse)
|
|
1707
|
+
puts optparse
|
|
1708
|
+
return 1
|
|
1709
|
+
end
|
|
1710
|
+
|
|
1711
|
+
connect(options)
|
|
1712
|
+
begin
|
|
1713
|
+
account = find_account_from_options(options)
|
|
1714
|
+
account_id = account ? account['id'] : nil
|
|
1715
|
+
role = find_role_by_name_or_id(account_id, name)
|
|
1716
|
+
return 1 if role.nil?
|
|
1717
|
+
|
|
1718
|
+
role_json = @roles_interface.get(account_id, role['id'])
|
|
1719
|
+
vdi_pool_global_access = role_json['globalVdiPoolAccess']
|
|
1720
|
+
vdi_pool_permissions = role_json['vdiPoolPermissions'] || []
|
|
1721
|
+
if vdi_pool_global_access != 'custom'
|
|
1722
|
+
print "\n", red, "Global VDI Pool Access is currently: #{vdi_pool_global_access.to_s.capitalize}"
|
|
1723
|
+
print "\n", "You must first set it to Custom via `morpheus roles update-global-vdi-pool-access \"#{name}\" custom`"
|
|
1724
|
+
print "\n\n", reset
|
|
1725
|
+
return 1
|
|
1726
|
+
end
|
|
1727
|
+
|
|
1728
|
+
# hacky, but support name or code lookup via the list returned in the show payload
|
|
1729
|
+
vdi_pool = nil
|
|
1730
|
+
if !do_all
|
|
1731
|
+
if vdi_pool_id.to_s =~ /\A\d{1,}\Z/
|
|
1732
|
+
vdi_pool = vdi_pool_permissions.find {|b| b['id'] == vdi_pool_id.to_i }
|
|
1733
|
+
else
|
|
1734
|
+
vdi_pool = vdi_pool_permissions.find {|b| b['name'] == vdi_pool_id }
|
|
1735
|
+
end
|
|
1736
|
+
if vdi_pool.nil?
|
|
1737
|
+
print_red_alert "VDI Pool not found: '#{vdi_pool_id}'"
|
|
1738
|
+
return 1
|
|
1739
|
+
end
|
|
1740
|
+
end
|
|
1741
|
+
|
|
1742
|
+
params = {}
|
|
1743
|
+
if do_all
|
|
1744
|
+
params['allVdiPools'] = true
|
|
1745
|
+
else
|
|
1746
|
+
params['vdiPoolId'] = vdi_pool['id']
|
|
1747
|
+
end
|
|
1748
|
+
params['access'] = access_value
|
|
1749
|
+
@roles_interface.setopts(options)
|
|
1750
|
+
if options[:dry_run]
|
|
1751
|
+
print_dry_run @roles_interface.dry.update_vdi_pool(account_id, role['id'], params)
|
|
1752
|
+
return
|
|
1753
|
+
end
|
|
1754
|
+
json_response = @roles_interface.update_vdi_pool(account_id, role['id'], params)
|
|
1755
|
+
|
|
1756
|
+
if options[:json]
|
|
1757
|
+
print JSON.pretty_generate(json_response)
|
|
1758
|
+
print "\n"
|
|
1759
|
+
else
|
|
1760
|
+
if do_all
|
|
1761
|
+
print_green_success "Role #{role['authority']} access updated for all VDI pools"
|
|
1762
|
+
else
|
|
1763
|
+
print_green_success "Role #{role['authority']} access updated for VDI pool #{vdi_pool['name']}"
|
|
1764
|
+
end
|
|
1765
|
+
end
|
|
1766
|
+
return 0
|
|
1767
|
+
rescue RestClient::Exception => e
|
|
1768
|
+
print_rest_exception(e, options)
|
|
1769
|
+
exit 1
|
|
1770
|
+
end
|
|
1771
|
+
end
|
|
1772
|
+
|
|
1609
1773
|
private
|
|
1610
1774
|
|
|
1611
1775
|
def add_role_option_types
|
|
@@ -1616,7 +1780,7 @@ EOT
|
|
|
1616
1780
|
{'fieldName' => 'baseRole', 'fieldLabel' => 'Copy From Role', 'type' => 'text'},
|
|
1617
1781
|
{'fieldName' => 'multitenant', 'fieldLabel' => 'Multitenant', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'A Multitenant role is automatically copied into all existing subaccounts as well as placed into a subaccount when created. Useful for providing a set of predefined roles a Customer can use'},
|
|
1618
1782
|
{'fieldName' => 'multitenantLocked', 'fieldLabel' => 'Multitenant Locked', 'type' => 'checkbox', 'defaultValue' => 'off', 'description' => 'Prevents subtenants from branching off this role/modifying it. '},
|
|
1619
|
-
{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' =>
|
|
1783
|
+
{'fieldName' => 'defaultPersona', 'fieldLabel' => 'Default Persona', 'type' => 'select', 'selectOptions' => get_persona_select_options(), 'description' => 'Default Persona'}
|
|
1620
1784
|
]
|
|
1621
1785
|
end
|
|
1622
1786
|
|
|
@@ -1624,20 +1788,16 @@ EOT
|
|
|
1624
1788
|
add_role_option_types.reject {|it| ['roleType', 'baseRole'].include?(it['fieldName']) }
|
|
1625
1789
|
end
|
|
1626
1790
|
|
|
1627
|
-
|
|
1628
|
-
def find_cloud_id_by_name(group_id, name)
|
|
1629
|
-
option_results = @options_interface.options_for_source('clouds', {groupId: group_id})
|
|
1630
|
-
match = option_results['data'].find { |grp| grp['value'].to_s == name.to_s || grp['name'].downcase == name.downcase}
|
|
1631
|
-
if match.nil?
|
|
1632
|
-
print_red_alert "Cloud not found by name #{name}"
|
|
1633
|
-
return nil
|
|
1634
|
-
else
|
|
1635
|
-
return match['value']
|
|
1636
|
-
end
|
|
1637
|
-
end
|
|
1638
|
-
|
|
1639
1791
|
def role_type_options
|
|
1640
1792
|
[{'name' => 'User Role', 'value' => 'user'}, {'name' => 'Account Role', 'value' => 'account'}]
|
|
1641
1793
|
end
|
|
1642
1794
|
|
|
1795
|
+
def get_persona_select_options
|
|
1796
|
+
[
|
|
1797
|
+
{'name'=>'Service Catalog','value'=>'serviceCatalog'},
|
|
1798
|
+
{'name'=>'Standard','value'=>'standard'},
|
|
1799
|
+
{'name'=>'Virtual Desktop','value'=>'vdi'}
|
|
1800
|
+
]
|
|
1801
|
+
end
|
|
1802
|
+
|
|
1643
1803
|
end
|