morpheus-cli 4.1.14 → 4.2

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +4 -0
  4. data/lib/morpheus/api/library_container_types_interface.rb +1 -1
  5. data/lib/morpheus/api/library_instance_types_interface.rb +7 -7
  6. data/lib/morpheus/api/library_layouts_interface.rb +1 -1
  7. data/lib/morpheus/api/network_routers_interface.rb +101 -0
  8. data/lib/morpheus/api/tasks_interface.rb +12 -14
  9. data/lib/morpheus/cli.rb +1 -0
  10. data/lib/morpheus/cli/apps.rb +15 -12
  11. data/lib/morpheus/cli/cli_command.rb +40 -2
  12. data/lib/morpheus/cli/clusters.rb +13 -7
  13. data/lib/morpheus/cli/cypher_command.rb +5 -2
  14. data/lib/morpheus/cli/hosts.rb +1 -1
  15. data/lib/morpheus/cli/instances.rb +21 -5
  16. data/lib/morpheus/cli/jobs_command.rb +83 -27
  17. data/lib/morpheus/cli/library_cluster_layouts_command.rb +12 -12
  18. data/lib/morpheus/cli/library_container_scripts_command.rb +52 -40
  19. data/lib/morpheus/cli/library_container_types_command.rb +2 -60
  20. data/lib/morpheus/cli/library_instance_types_command.rb +22 -1
  21. data/lib/morpheus/cli/library_layouts_command.rb +65 -65
  22. data/lib/morpheus/cli/library_option_lists_command.rb +72 -59
  23. data/lib/morpheus/cli/library_option_types_command.rb +30 -186
  24. data/lib/morpheus/cli/library_spec_templates_command.rb +39 -64
  25. data/lib/morpheus/cli/mixins/library_helper.rb +213 -0
  26. data/lib/morpheus/cli/mixins/provisioning_helper.rb +89 -37
  27. data/lib/morpheus/cli/mixins/whoami_helper.rb +16 -1
  28. data/lib/morpheus/cli/network_routers_command.rb +1281 -0
  29. data/lib/morpheus/cli/networks_command.rb +164 -72
  30. data/lib/morpheus/cli/option_types.rb +187 -73
  31. data/lib/morpheus/cli/price_sets_command.rb +4 -4
  32. data/lib/morpheus/cli/prices_command.rb +15 -15
  33. data/lib/morpheus/cli/remote.rb +3 -3
  34. data/lib/morpheus/cli/service_plans_command.rb +17 -8
  35. data/lib/morpheus/cli/tasks.rb +437 -169
  36. data/lib/morpheus/cli/version.rb +1 -1
  37. data/lib/morpheus/formatters.rb +8 -0
  38. metadata +6 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ed9f7ed5543846a64411f1e25133cad8df66ee4a2db836754f4733225d83962
4
- data.tar.gz: 859c8b97f7ca569359cb795462803da90c0ed624998c67cf358aa5b5ae8a7df5
3
+ metadata.gz: 65ef554015f7c79d475689f9b09d7a91e235c7feb992580f588e11c4c2fe36a5
4
+ data.tar.gz: 787e1ba5b1dbe066f8ab8e1fd47ec93372d9b68f5402ff4bcee3e1e7dbc62cfc
5
5
  SHA512:
6
- metadata.gz: c140d5c006c3bb4b179c8d763514b47cc8b36f8526cb60472f39043601054e5da55cadd79039ec02cf756e54fe36ae3358a5fb1029ca18a0eef9ed60eb5a1e51
7
- data.tar.gz: f81e24cbe8a4a62c46d33420baa43e9a599930ac2cc1066f05fac766fb82d0d96511dd2a06a99cd5b1b5f55edf56dc6a19a59004f7e997388d64ddf85b533b0d
6
+ metadata.gz: f21d7fef551d46c5e2f9465fdebc59b8b3c801d8a44474a299a2285234672206da64a0e68ca7d3b3f36eb1ee80279477ea1a0fc3b13c7ade10e72cbdde4bb3e8
7
+ data.tar.gz: 183b260af59171e6f0620864fc428245618506276cd350097396664a5f7609e866f4defcba7dd41f2f87a07ea292af42de57887b23736190c15ca46042977ea8
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.5.1
2
2
 
3
- RUN gem install morpheus-cli -v 4.1.13
3
+ RUN gem install morpheus-cli -v 4.2
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
@@ -534,6 +534,10 @@ class Morpheus::APIClient
534
534
  Morpheus::NetworkPoolIpsInterface.new(@access_token, @refresh_token, @expires_at, @base_url).setopts(@options)
535
535
  end
536
536
 
537
+ def network_routers
538
+ Morpheus::NetworkRoutersInterface.new(@access_token, @refresh_token, @expires_at, @base_url).setopts(@options)
539
+ end
540
+
537
541
  def network_services
538
542
  Morpheus::NetworkServicesInterface.new(@access_token, @refresh_token, @expires_at, @base_url).setopts(@options)
539
543
  end
@@ -51,7 +51,7 @@ class Morpheus::LibraryContainerTypesInterface < Morpheus::APIClient
51
51
  def build_url(layout_id=nil, id=nil)
52
52
  url = "#{@base_url}/api"
53
53
  if layout_id
54
- url += "/library/#{layout_id}/container-types"
54
+ url += "/library/layouts/#{layout_id}/container-types"
55
55
  else
56
56
  url += "/library/container-types"
57
57
  end
@@ -10,21 +10,21 @@ class Morpheus::LibraryInstanceTypesInterface < Morpheus::APIClient
10
10
 
11
11
  def get(id, params={})
12
12
  raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
13
- url = "#{@base_url}/api/library/#{id}"
13
+ url = "#{@base_url}/api/library/instance-types/#{id}"
14
14
  headers = { params: params, authorization: "Bearer #{@access_token}" }
15
15
  opts = {method: :get, url: url, headers: headers}
16
16
  execute(opts)
17
17
  end
18
18
 
19
19
  def list(params={})
20
- url = "#{@base_url}/api/library"
20
+ url = "#{@base_url}/api/library/instance-types"
21
21
  headers = { params: params, authorization: "Bearer #{@access_token}" }
22
22
  opts = {method: :get, url: url, headers: headers}
23
23
  execute(opts)
24
24
  end
25
25
 
26
26
  def create(options)
27
- url = "#{@base_url}/api/library"
27
+ url = "#{@base_url}/api/library/instance-types"
28
28
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
29
29
  payload = options
30
30
  opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
@@ -32,7 +32,7 @@ class Morpheus::LibraryInstanceTypesInterface < Morpheus::APIClient
32
32
  end
33
33
 
34
34
  def update(id, options)
35
- url = "#{@base_url}/api/library/#{id}"
35
+ url = "#{@base_url}/api/library/instance-types/#{id}"
36
36
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
37
37
  payload = options
38
38
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
@@ -40,14 +40,14 @@ class Morpheus::LibraryInstanceTypesInterface < Morpheus::APIClient
40
40
  end
41
41
 
42
42
  def toggle_featured(id, params={}, payload={})
43
- url = "#{@base_url}/api/library/#{id}/toggle-featured"
43
+ url = "#{@base_url}/api/library/instance-types/#{id}/toggle-featured"
44
44
  headers = { :params => params, :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
45
45
  opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
46
46
  execute(opts)
47
47
  end
48
48
 
49
49
  def destroy(id, payload={})
50
- url = "#{@base_url}/api/library/#{id}"
50
+ url = "#{@base_url}/api/library/instance-types/#{id}"
51
51
  headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
52
52
  opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
53
53
  execute(opts)
@@ -55,7 +55,7 @@ class Morpheus::LibraryInstanceTypesInterface < Morpheus::APIClient
55
55
 
56
56
  # NOT json, multipart file upload
57
57
  def update_logo(id, logo_file)
58
- url = "#{@base_url}/api/library/#{id}/update-logo"
58
+ url = "#{@base_url}/api/library/instance-types/#{id}/update-logo"
59
59
  headers = { :params => {}, :authorization => "Bearer #{@access_token}"}
60
60
  payload = {}
61
61
  payload[:logo] = logo_file
@@ -51,7 +51,7 @@ class Morpheus::LibraryLayoutsInterface < Morpheus::APIClient
51
51
  def build_url(instance_type_id=nil, id=nil)
52
52
  url = "#{@base_url}/api"
53
53
  if instance_type_id
54
- url += "/library/#{instance_type_id}/layouts"
54
+ url += "/library/instance-types/#{instance_type_id}/layouts"
55
55
  else
56
56
  url += "/library/layouts"
57
57
  end
@@ -0,0 +1,101 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::NetworkRoutersInterface < Morpheus::APIClient
4
+ def initialize(access_token, refresh_token,expires_at = nil, base_url=nil)
5
+ @access_token = access_token
6
+ @refresh_token = refresh_token
7
+ @base_url = base_url
8
+ @expires_at = expires_at
9
+ end
10
+
11
+ def list(params={})
12
+ url = "#{@base_url}/api/networks/routers"
13
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
14
+ opts = {method: :get, url: url, headers: headers}
15
+ execute(opts)
16
+ end
17
+
18
+ def get(id, params={})
19
+ raise "#{self.class}.get() passed a blank id!" if id.to_s == ''
20
+ url = "#{@base_url}/api/networks/routers/#{id}"
21
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
22
+ opts = {method: :get, url: url, headers: headers}
23
+ execute(opts)
24
+ end
25
+
26
+ def create(payload)
27
+ url = "#{@base_url}/api/networks/routers"
28
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
29
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
30
+ execute(opts)
31
+ end
32
+
33
+ def update(id, payload)
34
+ url = "#{@base_url}/api/networks/routers/#{id}"
35
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
36
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
37
+ execute(opts)
38
+ end
39
+
40
+ def types(params={})
41
+ url = "#{@base_url}/api/network-router-types"
42
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json', params: params }
43
+ opts = {method: :get, url: url, headers: headers}
44
+ execute(opts)
45
+ end
46
+
47
+ def groups(params={})
48
+ url = "#{@base_url}/api/network-router-groups"
49
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json', params: params }
50
+ opts = {method: :get, url: url, headers: headers}
51
+ execute(opts)
52
+ end
53
+
54
+ def servers(type_id, params={})
55
+ url = "#{@base_url}/api/network-router-types/#{type_id}/servers"
56
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json', params: params }
57
+ opts = {method: :get, url: url, headers: headers}
58
+ execute(opts)
59
+ end
60
+
61
+ def destroy(id, payload={})
62
+ url = "#{@base_url}/api/networks/routers/#{id}"
63
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
64
+ opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
65
+ execute(opts)
66
+ end
67
+
68
+ def create_firewall_rule(router_id, payload={})
69
+ url = "#{@base_url}/api/networks/routers/#{router_id}/firewall-rules"
70
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
71
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
72
+ execute(opts)
73
+ end
74
+
75
+ def destroy_firewall_rule(router_id, rule_id, payload={})
76
+ url = "#{@base_url}/api/networks/routers/#{router_id}/firewall-rules/#{rule_id}"
77
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
78
+ opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
79
+ execute(opts)
80
+ end
81
+
82
+ def create_route(router_id, payload={})
83
+ url = "#{@base_url}/api/networks/routers/#{router_id}/routes"
84
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
85
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
86
+ execute(opts)
87
+ end
88
+
89
+ def destroy_route(router_id, rule_id, payload={})
90
+ url = "#{@base_url}/api/networks/routers/#{router_id}/routes/#{rule_id}"
91
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
92
+ opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
93
+ execute(opts)
94
+ end
95
+
96
+ def update_permissions(router_id, payload)
97
+ url = "#{@base_url}/api/networks/routers/#{router_id}/permissions"
98
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
99
+ execute(method: :put, url: url, headers: headers, payload: payload.to_json)
100
+ end
101
+ end
@@ -8,20 +8,6 @@ class Morpheus::TasksInterface < Morpheus::APIClient
8
8
  @expires_at = expires_at
9
9
  end
10
10
 
11
- def task_types(options={})
12
- url = "#{@base_url}/api/task-types"
13
- headers = { params: {}, authorization: "Bearer #{@access_token}" }
14
-
15
- if options.is_a?(Hash)
16
- headers[:params].merge!(options)
17
- elsif options.is_a?(Numeric)
18
- url = "#{@base_url}/api/task-types/#{options}"
19
- elsif options.is_a?(String)
20
- headers[:params]['name'] = options
21
- end
22
- execute(method: :get, url: url, headers: headers)
23
- end
24
-
25
11
  def list(params={})
26
12
  url = "#{@base_url}/api/tasks"
27
13
  headers = { params: params, authorization: "Bearer #{@access_token}" }
@@ -71,4 +57,16 @@ class Morpheus::TasksInterface < Morpheus::APIClient
71
57
  execute(method: :post, url: url, headers: headers, payload: payload.to_json)
72
58
  end
73
59
 
60
+ def list_types(params={})
61
+ url = "#{@base_url}/api/task-types"
62
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
63
+ execute(method: :get, url: url, headers: headers)
64
+ end
65
+
66
+ def get_type(id, params={})
67
+ url = "#{@base_url}/api/task-types/#{id}"
68
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
69
+ execute(method: :get, url: url, headers: headers)
70
+ end
71
+
74
72
  end
data/lib/morpheus/cli.rb CHANGED
@@ -139,6 +139,7 @@ module Morpheus
139
139
  load 'morpheus/cli/network_pool_servers_command.rb'
140
140
  load 'morpheus/cli/network_domains_command.rb'
141
141
  load 'morpheus/cli/network_proxies_command.rb'
142
+ load 'morpheus/cli/network_routers_command.rb'
142
143
  load 'morpheus/cli/cypher_command.rb'
143
144
  load 'morpheus/cli/image_builder_command.rb'
144
145
  load 'morpheus/cli/preseed_scripts_command.rb'
@@ -284,6 +284,7 @@ class Morpheus::Cli::Apps
284
284
 
285
285
  # Default Cloud
286
286
  cloud_id = nil
287
+ cloud = nil
287
288
  scoped_available_clouds = get_available_clouds(group['id'])
288
289
  if options[:cloud]
289
290
  cloud_id = options[:cloud]
@@ -361,16 +362,16 @@ class Morpheus::Cli::Apps
361
362
  end
362
363
 
363
364
  # Cloud
364
- cloud_id = nil
365
- v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'selectOptions' => scoped_available_clouds, 'defaultValue' => cloud ? cloud['name'] : nil}], options[:options])
366
- cloud_id = v_prompt['cloud'] unless v_prompt['cloud'].to_s.empty?
367
- if cloud_id
368
- # cloud = find_cloud_by_name_or_id_for_provisioning(group['id'], cloud_id)
369
- cloud = scoped_available_clouds.find {|it| it['name'] == cloud_id.to_s } || scoped_available_clouds.find {|it| it['id'].to_s == cloud_id.to_s }
370
- return 1 if cloud.nil?
371
- else
372
- # prompt still happens inside get_scoped_instance_config
373
- end
365
+ # cloud_id = nil
366
+ # v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'fieldLabel' => 'Cloud', 'type' => 'select', 'selectOptions' => scoped_available_clouds, 'defaultValue' => cloud ? cloud['name'] : nil}], options[:options])
367
+ # cloud_id = v_prompt['cloud'] unless v_prompt['cloud'].to_s.empty?
368
+ # if cloud_id
369
+ # # cloud = find_cloud_by_name_or_id_for_provisioning(group['id'], cloud_id)
370
+ # cloud = scoped_available_clouds.find {|it| it['name'] == cloud_id.to_s } || scoped_available_clouds.find {|it| it['id'].to_s == cloud_id.to_s }
371
+ # return 1 if cloud.nil?
372
+ # else
373
+ # # prompt still happens inside get_scoped_instance_config
374
+ # end
374
375
 
375
376
 
376
377
  # prompt for the cloud for this instance
@@ -380,7 +381,7 @@ class Morpheus::Cli::Apps
380
381
  # now configure an instance like normal, use the config as default options with :always_prompt
381
382
  instance_prompt_options = {}
382
383
  instance_prompt_options[:group] = group ? group['id'] : nil
383
- instance_prompt_options[:cloud] = cloud ? cloud['name'] : nil
384
+ #instance_prompt_options[:cloud] = cloud ? cloud['name'] : nil
384
385
  instance_prompt_options[:default_cloud] = cloud ? cloud['name'] : nil
385
386
  instance_prompt_options[:no_prompt] = options[:no_prompt]
386
387
  #instance_prompt_options[:always_prompt] = options[:no_prompt] != true # options[:always_prompt]
@@ -398,7 +399,9 @@ class Morpheus::Cli::Apps
398
399
  #instance_prompt_options[:name_required] = true
399
400
  instance_prompt_options[:instance_type_code] = instance_type_code
400
401
  # todo: an effort to render more useful help eg. -O Web.0.instance.name
401
- instance_prompt_options[:extra_field_context] = "#{tier_name}.#{instance_index}"
402
+ help_field_prefix = "#{tier_name}.#{instance_index}"
403
+ instance_prompt_options[:help_field_prefix] = help_field_prefix
404
+ instance_prompt_options[:options][:help_field_prefix] = help_field_prefix
402
405
  # this provisioning helper method handles all (most) of the parsing and prompting
403
406
  instance_config_payload = prompt_new_instance(instance_prompt_options)
404
407
 
@@ -56,6 +56,11 @@ module Morpheus
56
56
  my_terminal.stdout.print(*msgs)
57
57
  end
58
58
 
59
+ def println(*msgs)
60
+ print(*msgs)
61
+ print "\n"
62
+ end
63
+
59
64
  def puts(*msgs)
60
65
  my_terminal.stdout.puts(*msgs)
61
66
  end
@@ -201,6 +206,26 @@ module Morpheus
201
206
  opts
202
207
  end
203
208
 
209
+ def build_standard_list_options(opts, options, includes=[], excludes=[])
210
+ build_common_options(opts, options, [:list, :query, :json, :yaml, :csv, :fields, :dry_run, :remote] + includes, excludes)
211
+ end
212
+
213
+ def build_standard_get_options(opts, options, includes=[], excludes=[])
214
+ build_common_options(opts, options, [:query, :json, :yaml, :csv, :fields, :dry_run, :remote] + includes, excludes)
215
+ end
216
+
217
+ def build_standard_add_options(opts, options, includes=[], excludes=[])
218
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote] + includes, excludes)
219
+ end
220
+
221
+ def build_standard_update_options(opts, options, includes=[], excludes=[])
222
+ build_common_options(opts, options, [:options, :payload, :json, :dry_run, :remote] + includes, excludes)
223
+ end
224
+
225
+ def build_standard_remove_options(opts, options, includes=[], excludes=[])
226
+ build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :quiet, :remote] + includes, excludes)
227
+ end
228
+
204
229
  # appends to the passed OptionParser all the generic options
205
230
  # @param opts [OptionParser] the option parser object being constructed
206
231
  # @param options [Hash] the output Hash that is to being modified
@@ -974,12 +999,25 @@ module Morpheus
974
999
  return subtitles
975
1000
  end
976
1001
 
977
- def parse_payload(options={})
1002
+ def parse_payload(options={}, object_key=nil)
978
1003
  payload = nil
979
1004
  if options[:payload]
980
1005
  payload = options[:payload]
981
1006
  # support -O OPTION switch on top of --payload
982
- payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol) }) if options[:options]
1007
+ apply_options(payload, options, object_key)
1008
+ end
1009
+ payload
1010
+ end
1011
+
1012
+ # support -O OPTION switch
1013
+ def apply_options(payload, options, object_key=nil)
1014
+ payload ||= {}
1015
+ if options[:options]
1016
+ if object_key
1017
+ payload.deep_merge!({object_key => options[:options].reject {|k,v| k.is_a?(Symbol)}})
1018
+ else
1019
+ payload.deep_merge!(options[:options].reject {|k,v| k.is_a?(Symbol)})
1020
+ end
983
1021
  end
984
1022
  payload
985
1023
  end
@@ -632,6 +632,10 @@ class Morpheus::Cli::Clusters
632
632
 
633
633
  server_payload.deep_merge!(Morpheus::Cli::OptionTypes.prompt(option_type_list, options[:options], @api_client, {zoneId: cloud['id'], siteId: group['id'], layoutId: layout['id']}))
634
634
 
635
+ # Worker count
636
+ default_node_count = layout['computeServers'] ? (layout['computeServers'].find {|it| it['nodeType'] == 'worker'} || {'nodeCount' => 3})['nodeCount'] : 3
637
+ server_payload['nodeCount'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => "nodeCount", 'type' => 'number', 'fieldLabel' => "#{cluster_type['code'].include?('docker') ? 'Host' : 'Worker'} Count", 'required' => true, 'defaultValue' => default_node_count}], options[:options], @api_client, {}, options[:no_prompt])["nodeCount"]
638
+
635
639
  # Create User
636
640
  if !options[:createUser].nil?
637
641
  server_payload['config']['createUser'] = options[:createUser]
@@ -1106,6 +1110,8 @@ class Morpheus::Cli::Clusters
1106
1110
  else
1107
1111
  server_payload = {'config' => {}}
1108
1112
 
1113
+ cluster_type = find_cluster_type_by_id(cluster['type']['id'])
1114
+
1109
1115
  # If not available add set type return
1110
1116
  layout = find_layout_by_id(cluster['layout']['id'])
1111
1117
 
@@ -1191,6 +1197,10 @@ class Morpheus::Cli::Clusters
1191
1197
  # Security Groups
1192
1198
  server_payload['securityGroups'] = prompt_security_groups_by_cloud(cloud, provision_type, resource_pool, options)
1193
1199
 
1200
+ # Worker count
1201
+ default_node_count = layout['computeServers'] ? (layout['computeServers'].find {|it| it['nodeType'] == 'worker'} || {'nodeCount' => 3})['nodeCount'] : 3
1202
+ server_payload['nodeCount'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => "nodeCount", 'type' => 'number', 'fieldLabel' => "#{cluster_type['code'].include?('docker') ? 'Host' : 'Worker'} Count", 'required' => true, 'defaultValue' => default_node_count}], options[:options], @api_client, {}, options[:no_prompt])["nodeCount"]
1203
+
1194
1204
  # Options / Custom Config
1195
1205
  option_type_list = (server_type['optionTypes'].reject { |type|
1196
1206
  !type['enabled'] || type['fieldComponent'] ||
@@ -3681,13 +3691,6 @@ class Morpheus::Cli::Clusters
3681
3691
  @clouds_interface.cloud_type(zone_type_id)['zoneType']['provisionTypes'].first rescue nil
3682
3692
  end
3683
3693
 
3684
- def current_user(refresh=false)
3685
- if !@current_user || refresh
3686
- load_whoami
3687
- end
3688
- @current_user
3689
- end
3690
-
3691
3694
  def load_group(options)
3692
3695
  # Group / Site
3693
3696
  group_id = nil
@@ -3777,6 +3780,9 @@ class Morpheus::Cli::Clusters
3777
3780
  opts.on( '-p', '--plan PLAN', "Service Plan") do |val|
3778
3781
  options[:servicePlan] = val
3779
3782
  end
3783
+ opts.on( '-n', '--worker-count VALUE', String, "Worker / host count") do |val|
3784
+ options[:options]['nodeCount'] = val
3785
+ end
3780
3786
  opts.on('--max-memory VALUE', String, "Maximum Memory (MB)") do |val|
3781
3787
  options[:maxMemory] = val
3782
3788
  end
@@ -294,13 +294,14 @@ EOT
294
294
  connect(options)
295
295
 
296
296
  # parse arguments like [value] or [k=v]
297
- item_key = args[0]
298
- item_value = args[1]
299
297
  if args.count == 0
300
298
  # prompt for key and value
301
299
  elsif args.count == 1
300
+ item_key = args[0]
302
301
  # prompt for value
303
302
  elsif args.count == 2
303
+ item_key = args[0]
304
+ item_value = args[1]
304
305
  # expecting [value] or [k=v]
305
306
  item_value_object = {}
306
307
  item_value_pair = item_value.split("=")
@@ -311,6 +312,8 @@ EOT
311
312
  # item_value = item_value
312
313
  end
313
314
  elsif args.count > 2
315
+ item_key = args[0]
316
+ item_value = args[1]
314
317
  # expecting [k=v] [k=v]
315
318
  item_value_object = {}
316
319
  args[1..(args.size-1)].each do |arg|