morpheus-cli 5.3.2.1 → 5.3.4

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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +12 -0
  4. data/lib/morpheus/api/clouds_interface.rb +4 -11
  5. data/lib/morpheus/api/instances_interface.rb +18 -5
  6. data/lib/morpheus/api/load_balancer_pools_interface.rb +4 -4
  7. data/lib/morpheus/api/load_balancer_profiles_interface.rb +10 -0
  8. data/lib/morpheus/api/load_balancer_virtual_servers_interface.rb +4 -4
  9. data/lib/morpheus/api/network_routers_interface.rb +21 -0
  10. data/lib/morpheus/api/network_servers_interface.rb +42 -0
  11. data/lib/morpheus/api/rest_interface.rb +2 -1
  12. data/lib/morpheus/api/virtual_images_interface.rb +23 -2
  13. data/lib/morpheus/api/virtual_servers_interface.rb +9 -0
  14. data/lib/morpheus/cli/apps.rb +3 -2
  15. data/lib/morpheus/cli/cli_command.rb +14 -6
  16. data/lib/morpheus/cli/cli_registry.rb +55 -2
  17. data/lib/morpheus/cli/cloud_resource_pools_command.rb +170 -134
  18. data/lib/morpheus/cli/clouds.rb +22 -40
  19. data/lib/morpheus/cli/clusters.rb +51 -33
  20. data/lib/morpheus/cli/hosts.rb +0 -1
  21. data/lib/morpheus/cli/instances.rb +372 -150
  22. data/lib/morpheus/cli/invoices_command.rb +117 -133
  23. data/lib/morpheus/cli/library_cluster_layouts_command.rb +20 -0
  24. data/lib/morpheus/cli/library_option_lists_command.rb +3 -3
  25. data/lib/morpheus/cli/load_balancer_pools.rb +111 -0
  26. data/lib/morpheus/cli/load_balancer_virtual_servers.rb +136 -0
  27. data/lib/morpheus/cli/load_balancers.rb +0 -155
  28. data/lib/morpheus/cli/mixins/load_balancers_helper.rb +2 -2
  29. data/lib/morpheus/cli/mixins/provisioning_helper.rb +155 -112
  30. data/lib/morpheus/cli/mixins/rest_command.rb +53 -37
  31. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +488 -0
  32. data/lib/morpheus/cli/monitoring_checks_command.rb +2 -0
  33. data/lib/morpheus/cli/network_routers_command.rb +291 -7
  34. data/lib/morpheus/cli/network_scopes_command.rb +442 -0
  35. data/lib/morpheus/cli/networks_command.rb +3 -3
  36. data/lib/morpheus/cli/option_parser.rb +25 -17
  37. data/lib/morpheus/cli/option_types.rb +42 -15
  38. data/lib/morpheus/cli/subnets_command.rb +7 -2
  39. data/lib/morpheus/cli/tasks.rb +25 -2
  40. data/lib/morpheus/cli/vdi_pools_command.rb +4 -1
  41. data/lib/morpheus/cli/version.rb +1 -1
  42. data/lib/morpheus/cli/virtual_images.rb +251 -29
  43. data/lib/morpheus/cli.rb +9 -1
  44. data/morpheus-cli.gemspec +1 -1
  45. metadata +11 -4
@@ -0,0 +1,111 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::LoadBalancerPools
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::RestCommand
6
+ include Morpheus::Cli::LoadBalancersHelper
7
+
8
+ set_command_hidden # hide until ready
9
+ set_command_name :'load-balancer-pools'
10
+ register_subcommands :list, :get, :add, :update, :remove
11
+
12
+ register_interfaces :load_balancer_pools,
13
+ :load_balancers, :load_balancer_pools
14
+
15
+ protected
16
+
17
+ def load_balancer_pool_list_column_definitions()
18
+ {
19
+ "ID" => 'id',
20
+ "Name" => 'name',
21
+ "Balancer Mode" => lambda {|it| it['vipBalance'] },
22
+ "LB" => lambda {|it| it['loadBalancer'] ? it['loadBalancer']['name'] : '' },
23
+ }
24
+ end
25
+
26
+ def load_balancer_pool_column_definitions()
27
+ {
28
+ "ID" => 'id',
29
+ "Name" => 'name',
30
+ "Description" => 'description',
31
+ "Balancer Mode" => lambda {|it| it['vipBalance'] },
32
+ "LB" => lambda {|it| it['loadBalancer'] ? it['loadBalancer']['name'] : '' },
33
+ # todo: more properties to show here
34
+ "Status" => lambda {|it| format_load_balancer_pool_status(it) },
35
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
36
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
37
+ }
38
+ end
39
+
40
+ def load_balancer_pool_object_key
41
+ 'loadBalancerPool'
42
+ end
43
+
44
+ def load_balancer_pool_list_key
45
+ 'loadBalancerPools'
46
+ end
47
+
48
+ def load_balancer_pool_label
49
+ 'Load Balancer Pool'
50
+ end
51
+
52
+ def load_balancer_pool_label_plural
53
+ 'Load Balancer Pools'
54
+ end
55
+
56
+ def find_load_balancer_pool_by_name_or_id(val)
57
+ if val.to_s =~ /\A\d{1,}\Z/
58
+ return find_load_balancer_pool_by_id(val)
59
+ else
60
+ return find_load_balancer_pool_by_name(val)
61
+ end
62
+ end
63
+
64
+ def find_load_balancer_pool_by_id(id)
65
+ begin
66
+ json_response = load_balancer_pools_interface.get(id.to_i)
67
+ return json_response[load_balancer_pool_object_key]
68
+ rescue RestClient::Exception => e
69
+ if e.response && e.response.code == 404
70
+ print_red_alert "#{load_balancer_pool_label} not found by id #{id}"
71
+ return nil
72
+ else
73
+ raise e
74
+ end
75
+ end
76
+ end
77
+
78
+ def find_load_balancer_pool_by_name(name)
79
+ json_response = load_balancer_pools_interface.list({name: name.to_s})
80
+ load_balancer_pools = json_response[load_balancer_pool_list_key]
81
+ if load_balancer_pools.empty?
82
+ print_red_alert "#{load_balancer_pool_label_plural} not found by name #{name}"
83
+ return load_balancer_pools
84
+ elsif load_balancer_pools.size > 1
85
+ print_red_alert "#{load_balancer_pools.size} #{load_balancer_pool_label_plural.downcase} found by name #{name}"
86
+ rows = load_balancer_pools.collect do |it|
87
+ {id: it['id'], name: it['name']}
88
+ end
89
+ puts as_pretty_table(rows, [:id, :name], {color:red})
90
+ return nil
91
+ else
92
+ return load_balancer_pools[0]
93
+ end
94
+ end
95
+
96
+ def format_load_balancer_pool_status(pool, return_color=cyan)
97
+ out = ""
98
+ status_string = pool['vipStatus'] || pool['status']
99
+ if status_string.nil? || status_string.empty? || status_string == "unknown"
100
+ out << "#{white}UNKNOWN#{return_color}"
101
+ elsif status_string == 'ok'
102
+ out << "#{green}#{status_string.upcase}#{return_color}"
103
+ elsif status_string == 'syncing'
104
+ out << "#{yellow}#{status_string.upcase}#{return_color}"
105
+ else
106
+ out << "#{red}#{status_string ? status_string.upcase : 'N/A'}#{pool['statusMessage'] ? "#{return_color} - #{pool['statusMessage']}" : ''}#{return_color}"
107
+ end
108
+ out
109
+ end
110
+
111
+ end
@@ -0,0 +1,136 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::LoadBalancerVirtualServers
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::RestCommand
6
+ # include Morpheus::Cli::SecondaryRestCommand
7
+ include Morpheus::Cli::LoadBalancersHelper
8
+
9
+ set_command_hidden # hide until ready
10
+ set_command_name :'load-balancer-virtual-servers'
11
+ register_subcommands :list, :get, :add, :update, :remove
12
+
13
+ register_interfaces :load_balancer_virtual_servers,
14
+ :load_balancers, :load_balancer_types
15
+
16
+ # set_rest_parent_name :load_balancers
17
+
18
+ # set_rest_interface_name :load_balancer_virtual_servers
19
+ # set_parent_rest_interface_name :load_balancers
20
+
21
+ # todo: a configurable way to load the optionTypes
22
+ # option_types = loadBalancer['vipOptionTypes']
23
+ # set_rest_has_type true
24
+ # set_rest_type :load_balancer_virtual_server_types
25
+
26
+ set_rest_arg 'vipName'
27
+
28
+ protected
29
+
30
+ def load_balancer_virtual_server_list_column_definitions()
31
+ {
32
+ "ID" => 'id',
33
+ "Name" => 'vipName',
34
+ "LB" => lambda {|it| it['loadBalancer'] ? it['loadBalancer']['name'] : '' },
35
+ # "Description" => 'description',
36
+ "Instance" => lambda {|it| it['instance'] ? it['instance']['name'] : '(Unassigned)' },
37
+ "Hostname" => lambda {|it| it['vipHostname'] },
38
+ "VIP" => lambda {|it| it['vipAddress'] },
39
+ "Protocol" => lambda {|it| it['vipProtocol'] },
40
+ "Port" => lambda {|it| it['vipPort'] },
41
+ "SSL" => lambda {|it| format_boolean(it['sslEnabled']) },
42
+ "Status" => lambda {|it| format_virtual_server_status(it) },
43
+ }
44
+ end
45
+
46
+ def load_balancer_virtual_server_column_definitions()
47
+ {
48
+ "ID" => 'id',
49
+ "Name" => 'vipName',
50
+ "Description" => 'description',
51
+ "LB" => lambda {|it| it['loadBalancer'] ? it['loadBalancer']['name'] : '' },
52
+ "Instance" => lambda {|it| it['instance'] ? it['instance']['name'] : '(Unassigned)' },
53
+ "Hostname" => lambda {|it| it['vipHostname'] },
54
+ "VIP" => lambda {|it| it['vipAddress'] },
55
+ "Protocol" => lambda {|it| it['vipProtocol'] },
56
+ "Port" => lambda {|it| it['vipPort'] },
57
+ "SSL" => lambda {|it| format_boolean(it['sslEnabled']) },
58
+ # todo: more properties to show here
59
+ "Status" => lambda {|it| format_virtual_server_status(it) },
60
+ "Created" => lambda {|it| format_local_dt(it['dateCreated']) },
61
+ "Updated" => lambda {|it| format_local_dt(it['lastUpdated']) }
62
+ }
63
+ end
64
+
65
+ def load_balancer_virtual_server_object_key
66
+ 'virtualServer'
67
+ end
68
+
69
+ def load_balancer_virtual_server_list_key
70
+ 'virtualServers'
71
+ end
72
+
73
+ def load_balancer_virtual_server_label
74
+ 'Virtual Server'
75
+ end
76
+
77
+ def load_balancer_virtual_server_label_plural
78
+ 'Virtual Servers'
79
+ end
80
+
81
+ def find_load_balancer_virtual_server_by_name_or_id(val)
82
+ if val.to_s =~ /\A\d{1,}\Z/
83
+ return find_load_balancer_virtual_server_by_id(val)
84
+ else
85
+ return find_load_balancer_virtual_server_by_name(val)
86
+ end
87
+ end
88
+
89
+ def find_load_balancer_virtual_server_by_id(id)
90
+ begin
91
+ json_response = load_balancer_virtual_servers_interface.get(id.to_i)
92
+ return json_response[load_balancer_virtual_server_object_key]
93
+ rescue RestClient::Exception => e
94
+ if e.response && e.response.code == 404
95
+ print_red_alert "#{load_balancer_virtual_server_label} not found by id #{id}"
96
+ return nil
97
+ else
98
+ raise e
99
+ end
100
+ end
101
+ end
102
+
103
+ def find_load_balancer_virtual_server_by_name(name)
104
+ json_response = load_balancer_virtual_servers_interface.list({name: name.to_s})
105
+ load_balancer_virtual_servers = json_response[load_balancer_virtual_server_list_key]
106
+ if load_balancer_virtual_servers.empty?
107
+ print_red_alert "#{load_balancer_virtual_server_label_plural} not found by name #{name}"
108
+ return load_balancer_virtual_servers
109
+ elsif load_balancer_virtual_servers.size > 1
110
+ print_red_alert "#{load_balancer_virtual_servers.size} #{load_balancer_virtual_server_label_plural.downcase} found by name #{name}"
111
+ rows = load_balancer_virtual_servers.collect do |it|
112
+ {id: it['id'], name: it['name']}
113
+ end
114
+ puts as_pretty_table(rows, [:id, :name], {color:red})
115
+ return nil
116
+ else
117
+ return load_balancer_virtual_servers[0]
118
+ end
119
+ end
120
+
121
+ def format_virtual_server_status(virtual_server, return_color=cyan)
122
+ out = ""
123
+ status_string = virtual_server['vipStatus'] || virtual_server['status']
124
+ if status_string.nil? || status_string.empty? || status_string == "unknown"
125
+ out << "#{white}UNKNOWN#{return_color}"
126
+ elsif status_string == 'ok'
127
+ out << "#{green}#{status_string.upcase}#{return_color}"
128
+ elsif status_string == 'syncing'
129
+ out << "#{yellow}#{status_string.upcase}#{return_color}"
130
+ else
131
+ out << "#{red}#{status_string ? status_string.upcase : 'N/A'}#{virtual_server['statusMessage'] ? "#{return_color} - #{virtual_server['statusMessage']}" : ''}#{return_color}"
132
+ end
133
+ out
134
+ end
135
+
136
+ end
@@ -42,161 +42,6 @@ class Morpheus::Cli::LoadBalancers
42
42
  end
43
43
  end
44
44
 
45
- =begin
46
-
47
- # now using RestCommand
48
-
49
- def add(args)
50
- lb_type_name = nil
51
- options = {}
52
- optparse = Morpheus::Cli::OptionParser.new do |opts|
53
- opts.banner = subcommand_usage("[name] -t LB_TYPE")
54
- opts.on( '-t', '--type CODE', "Load Balancer Type" ) do |val|
55
- lb_type_name = val
56
- end
57
- #build_option_type_options(opts, options, add_load_balancer_option_types)
58
- build_standard_add_options(opts, options)
59
- end
60
- optparse.parse!(args)
61
- lb_name = args[0]
62
- # verify_args!(args:args, optparse:optparse, min:0, max: 1)
63
- verify_args!(args:args, optparse:optparse, min:1, max: 1)
64
- if lb_type_name.nil?
65
- raise_command_error "Load Balancer Type is required.\n#{optparse}"
66
- puts optparse
67
- exit 1
68
- end
69
- connect(options)
70
- lb_type = load_balancer_type_for_name_or_id(lb_type_name)
71
- if lb_type.nil?
72
- print_red_alert "LB Type #{lb_type_name} not found!"
73
- exit 1
74
- end
75
- passed_options = parse_passed_options(options)
76
- payload = {}
77
- if options[:payload]
78
- payload = options[:payload]
79
- payload.deep_merge!({load_balancer_object_key => passed_options})
80
- else
81
- load_balancer_payload = {'name' => lb_name, 'type' => {'code' => lb_type['code'], 'id' => lb_type['id']}}
82
- load_balancer_payload.deep_merge!({load_balancer_object_key => passed_options})
83
- # options by type
84
- my_option_types = lb_type['optionTypes']
85
- if my_option_types && !my_option_types.empty?
86
- v_prompt = Morpheus::Cli::OptionTypes.prompt(my_option_types, options[:options], @api_client, options[:params])
87
- v_prompt.deep_compact!
88
- load_balancer_payload.deep_merge!(v_prompt)
89
- end
90
- payload[load_balancer_object_key] = load_balancer_payload
91
- end
92
- @load_balancers_interface.setopts(options)
93
- if options[:dry_run]
94
- print_dry_run @load_balancers_interface.dry.create(payload)
95
- return
96
- end
97
- json_response = @load_balancers_interface.create(payload)
98
- render_response(json_response, options, load_balancer_object_key) do
99
- load_balancer = json_response[load_balancer_object_key]
100
- print_green_success "Added load balancer #{load_balancer['name']}"
101
- return _get(load_balancer["id"], {}, options)
102
- end
103
- return 0, nil
104
- end
105
-
106
- def update(args)
107
- lb_name = args[0]
108
- options = {}
109
- account_name = nil
110
- optparse = Morpheus::Cli::OptionParser.new do |opts|
111
- opts.banner = subcommand_usage("[lb] [options]")
112
- build_standard_update_options(opts, options)
113
- end
114
- optparse.parse!(args)
115
- if args.count < 1
116
- puts optparse
117
- exit 1
118
- end
119
- connect(options)
120
-
121
- passed_options = parse_passed_options(options)
122
- payload = nil
123
- if options[:payload]
124
- payload = options[:payload]
125
- payload.deep_merge!({load_balancer_object_key => passed_options}) unless passed_options.empty?
126
- else
127
- load_balancer_payload = passed_options
128
- if tenants_list
129
- load_balancer_payload['accounts'] = tenants_list
130
- end
131
- # metadata tags
132
- if options[:tags]
133
- load_balancer_payload['tags'] = parse_metadata(options[:tags])
134
- else
135
- # tags = prompt_metadata(options)
136
- # payload[load_balancer_object_key]['tags'] = tags of tags
137
- end
138
- # metadata tags
139
- if options[:add_tags]
140
- load_balancer_payload['addTags'] = parse_metadata(options[:add_tags])
141
- end
142
- if options[:remove_tags]
143
- load_balancer_payload['removeTags'] = parse_metadata(options[:remove_tags])
144
- end
145
- if load_balancer_payload.empty?
146
- raise_command_error "Specify at least one option to update.\n#{optparse}"
147
- end
148
- payload = {'virtualImage' => load_balancer_payload}
149
- end
150
- @load_balancers_interface.setopts(options)
151
- if options[:dry_run]
152
- print_dry_run @load_balancers_interface.dry.update(load_balancer['id'], payload)
153
- return
154
- end
155
- json_response = @load_balancers_interface.update(load_balancer['id'], payload)
156
- render_response(json_response, options, 'virtualImage') do
157
- print_green_success "Updated virtual image #{load_balancer['name']}"
158
- _get(load_balancer["id"], {}, options)
159
- end
160
- return 0, nil
161
- end
162
-
163
- def remove(args)
164
- lb_name = args[0]
165
- options = {}
166
- optparse = Morpheus::Cli::OptionParser.new do |opts|
167
- opts.banner = subcommand_usage("[name]")
168
- build_common_options(opts, options, [:auto_confirm, :json, :dry_run, :remote])
169
- end
170
- optparse.parse!(args)
171
- if args.count < 1
172
- puts optparse
173
- exit 1
174
- end
175
- connect(options)
176
- begin
177
- lb = find_load_balancer_by_name_or_id(lb_name)
178
- exit 1 if lb.nil?
179
- unless options[:yes] || Morpheus::Cli::OptionTypes.confirm("Are you sure you want to delete the load balancer #{lb['name']}?")
180
- exit
181
- end
182
- @load_balancers_interface.setopts(options)
183
- if options[:dry_run]
184
- print_dry_run @load_balancers_interface.dry.destroy(lb['id'])
185
- return
186
- end
187
- json_response = @load_balancers_interface.destroy(lb['id'])
188
- if options[:json]
189
- print JSON.pretty_generate(json_response), "\n"
190
- else
191
- print "\n", cyan, "Load Balancer #{lb['name']} removed", reset, "\n\n"
192
- end
193
- rescue RestClient::Exception => e
194
- print_rest_exception(e, options)
195
- exit 1
196
- end
197
- end
198
- =end
199
-
200
45
  # deprecated, to be removed in the future.
201
46
  def types(args)
202
47
  print_error yellow,"[DEPRECATED] The command `load-balancers types` is deprecated and replaced by `load-balancer-types list`.",reset,"\n"
@@ -34,7 +34,7 @@ module Morpheus::Cli::LoadBalancersHelper
34
34
  'Load Balancer'
35
35
  end
36
36
 
37
- def load_balancer_plural_label
37
+ def load_balancer_label_plural
38
38
  'Load Balancers'
39
39
  end
40
40
 
@@ -50,7 +50,7 @@ module Morpheus::Cli::LoadBalancersHelper
50
50
  'Load Balancer Type'
51
51
  end
52
52
 
53
- def load_balancer_type_plural_label
53
+ def load_balancer_type_label_plural
54
54
  'Load Balancer Types'
55
55
  end
56
56