morpheus-cli 5.5.1.5 → 5.5.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +1 -1
  3. data/lib/morpheus/api/api_client.rb +25 -0
  4. data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
  5. data/lib/morpheus/api/body_io.rb +22 -0
  6. data/lib/morpheus/api/catalog_item_types_interface.rb +5 -1
  7. data/lib/morpheus/api/clients_interface.rb +41 -0
  8. data/lib/morpheus/api/clouds_interface.rb +21 -0
  9. data/lib/morpheus/api/instances_interface.rb +8 -1
  10. data/lib/morpheus/api/integrations_interface.rb +30 -0
  11. data/lib/morpheus/api/library_instance_types_interface.rb +15 -3
  12. data/lib/morpheus/api/network_pool_server_types_interface.rb +9 -0
  13. data/lib/morpheus/api/plugins_interface.rb +22 -0
  14. data/lib/morpheus/api/roles_interface.rb +20 -1
  15. data/lib/morpheus/api/security_package_types_interface.rb +9 -0
  16. data/lib/morpheus/api/security_packages_interface.rb +9 -0
  17. data/lib/morpheus/api/security_scans_interface.rb +9 -0
  18. data/lib/morpheus/api/servers_interface.rb +17 -17
  19. data/lib/morpheus/api/storage_providers_interface.rb +1 -1
  20. data/lib/morpheus/api/virtual_images_interface.rb +1 -23
  21. data/lib/morpheus/cli/cli_command.rb +81 -7
  22. data/lib/morpheus/cli/commands/apps.rb +28 -2
  23. data/lib/morpheus/cli/commands/archives_command.rb +2 -2
  24. data/lib/morpheus/cli/commands/blueprints_command.rb +16 -0
  25. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +34 -2
  26. data/lib/morpheus/cli/commands/clients_command.rb +338 -0
  27. data/lib/morpheus/cli/commands/clouds.rb +127 -1
  28. data/lib/morpheus/cli/commands/clusters.rb +42 -12
  29. data/lib/morpheus/cli/commands/curl_command.rb +114 -135
  30. data/lib/morpheus/cli/commands/hosts.rb +108 -11
  31. data/lib/morpheus/cli/commands/instances.rb +115 -14
  32. data/lib/morpheus/cli/commands/integrations_command.rb +215 -4
  33. data/lib/morpheus/cli/commands/invoices_command.rb +20 -11
  34. data/lib/morpheus/cli/commands/jobs_command.rb +299 -190
  35. data/lib/morpheus/cli/commands/library_cluster_layouts_command.rb +16 -2
  36. data/lib/morpheus/cli/commands/library_container_scripts_command.rb +14 -0
  37. data/lib/morpheus/cli/commands/library_container_templates_command.rb +131 -48
  38. data/lib/morpheus/cli/commands/library_container_types_command.rb +17 -4
  39. data/lib/morpheus/cli/commands/library_instance_types_command.rb +85 -7
  40. data/lib/morpheus/cli/commands/library_layouts_command.rb +32 -1
  41. data/lib/morpheus/cli/commands/library_option_lists_command.rb +30 -18
  42. data/lib/morpheus/cli/commands/library_option_types_command.rb +31 -14
  43. data/lib/morpheus/cli/commands/library_spec_templates_command.rb +14 -0
  44. data/lib/morpheus/cli/commands/library_upgrades_command.rb +2 -2
  45. data/lib/morpheus/cli/commands/network_pool_server_types.rb +20 -0
  46. data/lib/morpheus/cli/commands/network_pool_servers_command.rb +55 -158
  47. data/lib/morpheus/cli/commands/network_pools_command.rb +49 -23
  48. data/lib/morpheus/cli/commands/networks_command.rb +262 -45
  49. data/lib/morpheus/cli/commands/plugins.rb +213 -0
  50. data/lib/morpheus/cli/commands/price_sets_command.rb +27 -8
  51. data/lib/morpheus/cli/commands/prices_command.rb +17 -5
  52. data/lib/morpheus/cli/commands/processes_command.rb +2 -1
  53. data/lib/morpheus/cli/commands/remote.rb +7 -10
  54. data/lib/morpheus/cli/commands/roles.rb +924 -335
  55. data/lib/morpheus/cli/commands/search_command.rb +2 -0
  56. data/lib/morpheus/cli/commands/security_groups.rb +72 -84
  57. data/lib/morpheus/cli/commands/security_package_types.rb +32 -0
  58. data/lib/morpheus/cli/commands/security_packages.rb +84 -0
  59. data/lib/morpheus/cli/commands/security_scans.rb +107 -0
  60. data/lib/morpheus/cli/commands/service_plans_command.rb +16 -14
  61. data/lib/morpheus/cli/commands/subnets_command.rb +15 -1
  62. data/lib/morpheus/cli/commands/tasks.rb +34 -1
  63. data/lib/morpheus/cli/commands/tenants_command.rb +1 -1
  64. data/lib/morpheus/cli/commands/user_settings_command.rb +11 -2
  65. data/lib/morpheus/cli/commands/users.rb +50 -9
  66. data/lib/morpheus/cli/commands/virtual_images.rb +14 -0
  67. data/lib/morpheus/cli/commands/workflows.rb +14 -0
  68. data/lib/morpheus/cli/mixins/accounts_helper.rb +6 -5
  69. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +79 -0
  70. data/lib/morpheus/cli/mixins/jobs_helper.rb +4 -5
  71. data/lib/morpheus/cli/mixins/library_helper.rb +2 -0
  72. data/lib/morpheus/cli/mixins/logs_helper.rb +3 -0
  73. data/lib/morpheus/cli/mixins/monitoring_helper.rb +1 -1
  74. data/lib/morpheus/cli/mixins/print_helper.rb +29 -4
  75. data/lib/morpheus/cli/mixins/provisioning_helper.rb +38 -9
  76. data/lib/morpheus/cli/mixins/rest_command.rb +106 -8
  77. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +6 -2
  78. data/lib/morpheus/cli/option_types.rb +94 -25
  79. data/lib/morpheus/cli/version.rb +1 -1
  80. data/lib/morpheus/formatters.rb +10 -1
  81. metadata +15 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8637acf5e4ce4a0673114edf18f3b69604574905bf6507272411efb1abd6c684
4
- data.tar.gz: 5cc836f09c1aa1cf164d5e7ae8fb3fa9a793cfbff0192543f45fe313404226ac
3
+ metadata.gz: 0161a73b2f75bfc74f92f94cb0acf5058cdfb4c307225315b8ed91ec198fae16
4
+ data.tar.gz: 9ae526229db5a69ba1f948e4903844761d2d26e46a354dcc3966d3c2e7538491
5
5
  SHA512:
6
- metadata.gz: c4adf8fb42bfe890394b8c988144ad9153f70e0ff1e4d2159b71557c14360b0b3dd1a11aff94409a8b4bbb61b17c27af5a6ebd61ff484182fd85812c5e0d5b0e
7
- data.tar.gz: '09af6071b1536a08fad258e3ff01330916a6e7a7c655359618d7f2ce9f00f24879b451a70cfd4ebf32498e7a048423addf9af472873fdcd5236ea04730d4fd3d'
6
+ metadata.gz: ea86420d90f1a3c95e6e63b181d27dada07884cf228e617d6031f09caa3d108126b0b2762ad3cb2da1bb8e8b4d816d0b065860d1bbb51d02490b9b25c250c23e
7
+ data.tar.gz: bf62144dc584582b82fcb825bebb26d083df76c2da7180f0b17260410ad84b1f761e5c7d7780711e4db3307ad3a5b71c8a338d35202c382d97ec5b373dee77a7
data/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  FROM ruby:2.7.5
2
2
 
3
- RUN gem install morpheus-cli -v 5.5.1.5
3
+ RUN gem install morpheus-cli -v 5.5.2
4
4
 
5
5
  ENTRYPOINT ["morpheus"]
@@ -2,6 +2,7 @@ require 'json'
2
2
  require 'uri'
3
3
  require 'cgi'
4
4
  require 'morpheus/rest_client'
5
+ #require 'morpheus/api/body_io'
5
6
  # require 'rest-client'
6
7
 
7
8
  class Morpheus::APIClient
@@ -672,6 +673,10 @@ class Morpheus::APIClient
672
673
  Morpheus::NetworkPoolServersInterface.new(common_interface_options).setopts(@options)
673
674
  end
674
675
 
676
+ def network_pool_server_types
677
+ Morpheus::NetworkPoolServerTypesInterface.new(common_interface_options).setopts(@options)
678
+ end
679
+
675
680
  def network_domains
676
681
  Morpheus::NetworkDomainsInterface.new(common_interface_options).setopts(@options)
677
682
  end
@@ -756,6 +761,10 @@ class Morpheus::APIClient
756
761
  Morpheus::PackagesInterface.new(common_interface_options).setopts(@options)
757
762
  end
758
763
 
764
+ def plugins
765
+ Morpheus::PluginsInterface.new(common_interface_options).setopts(@options)
766
+ end
767
+
759
768
  def cypher
760
769
  Morpheus::CypherInterface.new(common_interface_options).setopts(@options)
761
770
  end
@@ -912,6 +921,22 @@ class Morpheus::APIClient
912
921
  Morpheus::CredentialTypesInterface.new(common_interface_options).setopts(@options)
913
922
  end
914
923
 
924
+ def clients
925
+ Morpheus::ClientsInterface.new(common_interface_options).setopts(@options)
926
+ end
927
+
928
+ def security_packages
929
+ Morpheus::SecurityPackagesInterface.new(common_interface_options).setopts(@options)
930
+ end
931
+
932
+ def security_package_types
933
+ Morpheus::SecurityPackageTypesInterface.new(common_interface_options).setopts(@options)
934
+ end
935
+
936
+ def security_scans
937
+ Morpheus::SecurityScansInterface.new(common_interface_options).setopts(@options)
938
+ end
939
+
915
940
  def rest(endpoint)
916
941
  Morpheus::RestInterface.new(common_interface_options).setopts(@options.merge({base_path: "#{@base_url}/api/#{endpoint}"}))
917
942
  end
@@ -42,7 +42,7 @@ class Morpheus::ArchiveBucketsInterface < Morpheus::APIClient
42
42
  if file_path.to_s.strip == "/"
43
43
  file_path = ""
44
44
  end
45
- url = "#{@base_url}/api/archives/buckets/#{CGI::escape(id.to_s)}" + "/files/#{CGI::escape(file_path)}".squeeze('/')
45
+ url = "#{@base_url}/api/archives/buckets/#{CGI::escape(id.to_s)}" + "/files/#{escape_filepath(file_path)}".squeeze('/')
46
46
  headers = { params: params, authorization: "Bearer #{@access_token}" }
47
47
  opts = {method: :get, url: url, headers: headers}
48
48
  execute(opts)
@@ -0,0 +1,22 @@
1
+ require 'forwardable'
2
+
3
+ # wrapper class for input stream so that HTTP doesn't blow up when using it
4
+ # ie. calling size() and rewind()
5
+ class Morpheus::BodyIO
6
+ extend Forwardable
7
+
8
+ def initialize(io)
9
+ @io = io
10
+ end
11
+
12
+ def size
13
+ 0
14
+ end
15
+
16
+ def rewind
17
+ nil
18
+ end
19
+
20
+ def_delegators :@io, :read, :readpartial, :write
21
+
22
+ end
@@ -19,7 +19,11 @@ class Morpheus::CatalogItemTypesInterface < Morpheus::RestInterface
19
19
  if dark_logo_file
20
20
  payload["catalogItemType"]["darkLogo"] = dark_logo_file
21
21
  end
22
- payload[:multipart] = true
22
+ if logo_file.is_a?(File) || dark_logo_file.is_a?(File)
23
+ payload[:multipart] = true
24
+ else
25
+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
26
+ end
23
27
  execute(method: :put, url: url, headers: headers, payload: payload)
24
28
  end
25
29
 
@@ -0,0 +1,41 @@
1
+ require 'morpheus/api/api_client'
2
+
3
+ class Morpheus::ClientsInterface < Morpheus::APIClient
4
+
5
+ def list(params={}, headers={})
6
+ url = "#{@base_url}/api/clients"
7
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
8
+ opts = {method: :get, url: url, headers: headers}
9
+ execute(opts)
10
+ end
11
+
12
+ def get(id, params={})
13
+ raise "#{self.class}.get() passed a blank name!" if id.to_s == ''
14
+ url = "#{@base_url}/api/clients/#{id}"
15
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
16
+ opts = {method: :get, url: url, headers: headers}
17
+ execute(opts)
18
+ end
19
+
20
+ def create(payload)
21
+ url = "#{@base_url}/api/clients"
22
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
23
+ opts = {method: :post, url: url, headers: headers, payload: payload.to_json}
24
+ execute(opts)
25
+ end
26
+
27
+ def update(id, payload)
28
+ url = "#{@base_url}/api/clients/#{id}"
29
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
30
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
31
+ execute(opts)
32
+ end
33
+
34
+ def destroy(id, params={})
35
+ url = "#{@base_url}/api/clients/#{id}"
36
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
37
+ opts = {method: :delete, url: url, headers: headers}
38
+ execute(opts)
39
+ end
40
+
41
+ end
@@ -116,4 +116,25 @@ class Morpheus::CloudsInterface < Morpheus::APIClient
116
116
  execute(opts)
117
117
  end
118
118
 
119
+ # NOT json, multipart file upload
120
+ def update_logo(id, logo_file, dark_logo_file=nil)
121
+ url = "#{@base_url}/api/zones/#{id}/update-logo"
122
+ headers = { :params => {}, :authorization => "Bearer #{@access_token}"}
123
+ payload = {}
124
+ # payload["zone"] = {}
125
+ if logo_file
126
+ # payload["zone"]["logo"] = logo_file
127
+ payload["logo"] = logo_file
128
+ end
129
+ if dark_logo_file
130
+ # payload["instanceType"]["darkLogo"] = dark_logo_file
131
+ payload["darkLogo"] = dark_logo_file
132
+ end
133
+ if logo_file.is_a?(File) || dark_logo_file.is_a?(File)
134
+ payload[:multipart] = true
135
+ else
136
+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
137
+ end
138
+ execute(method: :post, url: url, headers: headers, payload: payload)
139
+ end
119
140
  end
@@ -367,6 +367,13 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
367
367
  execute(opts)
368
368
  end
369
369
 
370
+ def update_network_label(network_id, instance_id, payload)
371
+ url = "#{@base_url}/api/instances/#{instance_id}/networkInterfaces/#{network_id}"
372
+ headers = {authorization: "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
373
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
374
+ execute(opts)
375
+ end
376
+
370
377
  def deploys(id, params)
371
378
  # todo: make this plural??
372
379
  execute(method: :get, url: "/api/instances/#{id}/deploy", params: params)
@@ -408,7 +415,7 @@ class Morpheus::InstancesInterface < Morpheus::APIClient
408
415
  end
409
416
 
410
417
  def remove_from_control(ids, params={})
411
- url = "#{@base_url}/api/instances/removeFromControl"
418
+ url = "#{@base_url}/api/instances/remove-from-control"
412
419
  payload = { ids: ids }
413
420
  headers = { :params => params,:authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
414
421
  opts = {method: :delete, url: url, headers: headers, payload: payload.to_json}
@@ -41,4 +41,34 @@ class Morpheus::IntegrationsInterface < Morpheus::RestInterface
41
41
  execute(method: :delete, url: "#{base_path}/#{id}/objects/#{obj_id}", params: params, headers: headers)
42
42
  end
43
43
 
44
+ ## Integration Inventory Item CRUD
45
+
46
+ def list_inventory(id, params={}, headers={})
47
+ validate_id!(id)
48
+ execute(method: :get, url: "#{base_path}/#{id}/inventory", params: params, headers: headers)
49
+ end
50
+
51
+ def get_inventory(id, inventory_id, params={}, headers={})
52
+ validate_id!(id)
53
+ validate_id!(inventory_id)
54
+ execute(method: :get, url: "#{base_path}/#{id}/inventory/#{inventory_id}", params: params, headers: headers)
55
+ end
56
+
57
+ # def create_inventory(id, payload, params={}, headers={})
58
+ # validate_id!(id)
59
+ # execute(method: :post, url: "#{base_path}/#{id}/inventory", params: params, payload: payload, headers: headers)
60
+ # end
61
+
62
+ def update_inventory(id, inventory_id, payload, params={}, headers={})
63
+ validate_id!(id)
64
+ validate_id!(inventory_id)
65
+ execute(method: :put, url: "#{base_path}/#{id}/inventory/#{inventory_id}", params: params, payload: payload, headers: headers)
66
+ end
67
+
68
+ # def destroy_inventory(id, inventory_id, params = {}, headers={})
69
+ # validate_id!(id)
70
+ # validate_id!(inventory_id)
71
+ # execute(method: :delete, url: "#{base_path}/#{id}/inventory/#{inventory_id}", params: params, headers: headers)
72
+ # end
73
+
44
74
  end
@@ -50,12 +50,24 @@ class Morpheus::LibraryInstanceTypesInterface < Morpheus::APIClient
50
50
  end
51
51
 
52
52
  # NOT json, multipart file upload
53
- def update_logo(id, logo_file)
53
+ def update_logo(id, logo_file, dark_logo_file=nil)
54
54
  url = "#{@base_url}/api/library/#{id}/update-logo"
55
55
  headers = { :params => {}, :authorization => "Bearer #{@access_token}"}
56
56
  payload = {}
57
- payload[:logo] = logo_file
58
- payload[:multipart] = true
57
+ # payload["instanceType"] = {}
58
+ if logo_file
59
+ # payload["instanceType"]["logo"] = logo_file
60
+ payload["logo"] = logo_file
61
+ end
62
+ if dark_logo_file
63
+ # payload["instanceType"]["darkLogo"] = dark_logo_file
64
+ payload["darkLogo"] = dark_logo_file
65
+ end
66
+ if logo_file.is_a?(File) || dark_logo_file.is_a?(File)
67
+ payload[:multipart] = true
68
+ else
69
+ headers['Content-Type'] = 'application/x-www-form-urlencoded'
70
+ end
59
71
  execute(method: :post, url: url, headers: headers, payload: payload)
60
72
  end
61
73
 
@@ -0,0 +1,9 @@
1
+ require 'morpheus/api/read_interface'
2
+
3
+ class Morpheus::NetworkPoolServerTypesInterface < Morpheus::ReadInterface
4
+
5
+ def base_path
6
+ "/api/networks/pool-server-types"
7
+ end
8
+
9
+ end
@@ -0,0 +1,22 @@
1
+ require 'morpheus/api/rest_interface'
2
+
3
+ class Morpheus::PluginsInterface < Morpheus::RestInterface
4
+
5
+ def base_path
6
+ "/api/plugins"
7
+ end
8
+
9
+ # upload a file with content-type: multipart
10
+ def upload(local_file, params={}, headers={})
11
+ url = "#{base_path}/upload"
12
+ payload = {}
13
+ payload[:multipart] = true
14
+ payload["plugin"] = local_file
15
+ execute(method: :post, url: url, params: params, payload: payload, headers: headers, timeout: 172800)
16
+ end
17
+
18
+ def check_updates(payload={}, params={}, headers={})
19
+ execute(method: :post, url: "#{base_path}/check-updates", params: params, payload: payload, headers: headers)
20
+ end
21
+
22
+ end
@@ -11,7 +11,12 @@ class Morpheus::RolesInterface < Morpheus::APIClient
11
11
 
12
12
  def list(account_id, options={})
13
13
  url = build_url(account_id)
14
- headers = { params: {}, authorization: "Bearer #{@access_token}" }
14
+ params = {}
15
+ if account_id
16
+ params['tenant'] = account_id
17
+ end
18
+
19
+ headers = { params: params, authorization: "Bearer #{@access_token}" }
15
20
  headers[:params].merge!(options)
16
21
  execute(method: :get, url: url, headers: headers)
17
22
  end
@@ -99,6 +104,20 @@ class Morpheus::RolesInterface < Morpheus::APIClient
99
104
  execute(method: :put, url: url, headers: headers, payload: payload.to_json)
100
105
  end
101
106
 
107
+ def update_task(account_id, id, options)
108
+ url = build_url(account_id, id) + "/update-task"
109
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
110
+ payload = options
111
+ execute(method: :put, url: url, headers: headers, payload: payload.to_json)
112
+ end
113
+
114
+ def update_task_set(account_id, id, options)
115
+ url = build_url(account_id, id) + "/update-task-set"
116
+ headers = { :authorization => "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
117
+ payload = options
118
+ execute(method: :put, url: url, headers: headers, payload: payload.to_json)
119
+ end
120
+
102
121
  private
103
122
 
104
123
  def build_url(account_id=nil, role_id=nil)
@@ -0,0 +1,9 @@
1
+ require 'morpheus/api/read_interface'
2
+
3
+ class Morpheus::SecurityPackageTypesInterface < Morpheus::ReadInterface
4
+
5
+ def base_path
6
+ "/api/security-package-types"
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'morpheus/api/rest_interface'
2
+
3
+ class Morpheus::SecurityPackagesInterface < Morpheus::RestInterface
4
+
5
+ def base_path
6
+ "/api/security-packages"
7
+ end
8
+
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'morpheus/api/rest_interface'
2
+
3
+ class Morpheus::SecurityScansInterface < Morpheus::RestInterface
4
+
5
+ def base_path
6
+ "/api/security-scans"
7
+ end
8
+
9
+ end
@@ -2,25 +2,17 @@ require 'morpheus/api/api_client'
2
2
 
3
3
  class Morpheus::ServersInterface < Morpheus::APIClient
4
4
 
5
- def get(options=nil)
6
- url = "#{@base_url}/api/servers"
7
- headers = { params: {}, authorization: "Bearer #{@access_token}" }
8
- if options.is_a?(Hash)
9
- headers[:params].merge!(options)
10
- elsif options.is_a?(Numeric)
11
- url = "#{@base_url}/api/servers/#{options}"
12
- elsif options.is_a?(String)
13
- headers[:params]['name'] = options
14
- end
15
- opts = {method: :get, url: url, headers: headers}
16
- execute(opts)
5
+ def base_path
6
+ "/api/servers"
17
7
  end
18
8
 
19
- def list(params={})
20
- url = "#{@base_url}/api/servers"
21
- headers = { params: params, authorization: "Bearer #{@access_token}" }
22
- opts = {method: :get, url: url, headers: headers}
23
- execute(opts)
9
+ def list(params={}, headers={})
10
+ execute(method: :get, url: "#{base_path}", params: params, headers: headers)
11
+ end
12
+
13
+ def get(id, params={}, headers={})
14
+ validate_id!(id)
15
+ execute(method: :get, url: "#{base_path}/#{id}", params: params, headers: headers)
24
16
  end
25
17
 
26
18
  def create(options)
@@ -184,4 +176,12 @@ class Morpheus::ServersInterface < Morpheus::APIClient
184
176
  execute(opts)
185
177
  end
186
178
 
179
+ def update_network_label(network_id, server_id, payload)
180
+ url = "#{@base_url}/api/servers/#{server_id}/networkInterfaces/#{network_id}"
181
+ headers = {authorization: "Bearer #{@access_token}", 'Content-Type' => 'application/json' }
182
+ opts = {method: :put, url: url, headers: headers, payload: payload.to_json}
183
+ execute(opts)
184
+ end
185
+
186
+
187
187
  end
@@ -42,7 +42,7 @@ class Morpheus::StorageProvidersInterface < Morpheus::APIClient
42
42
  if file_path.to_s.strip == "/"
43
43
  file_path = ""
44
44
  end
45
- url = "#{@base_url}/api/storage/buckets/#{CGI::escape(id.to_s)}" + "/files/#{CGI::escape(file_path)}".squeeze('/')
45
+ url = "#{@base_url}/api/storage/buckets/#{CGI::escape(id.to_s)}" + "/files/#{escape_filepath(file_path)}".squeeze('/')
46
46
  headers = { params: params, authorization: "Bearer #{@access_token}" }
47
47
  opts = {method: :get, url: url, headers: headers}
48
48
  execute(opts)
@@ -1,7 +1,6 @@
1
1
  require 'morpheus/api/api_client'
2
2
  require 'http'
3
3
  require 'zlib'
4
- require 'forwardable'
5
4
 
6
5
  class Morpheus::VirtualImagesInterface < Morpheus::APIClient
7
6
 
@@ -61,27 +60,6 @@ class Morpheus::VirtualImagesInterface < Morpheus::APIClient
61
60
  # execute(method: :post, url: url, headers: headers, payload: payload)
62
61
  # end
63
62
 
64
- # wrapper class for input stream so that HTTP doesn't blow up when using it
65
- # ie. calling size() and rewind()
66
- class BodyIO
67
- extend Forwardable
68
-
69
- def initialize(io)
70
- @io = io
71
- end
72
-
73
- def size
74
- 0
75
- end
76
-
77
- def rewind
78
- nil
79
- end
80
-
81
- def_delegators :@io, :read, :readpartial, :write
82
-
83
- end
84
-
85
63
  # no multipart
86
64
  def upload(id, image_file, filename=nil, do_gzip=false)
87
65
  filename = filename || File.basename(image_file)
@@ -132,7 +110,7 @@ class Morpheus::VirtualImagesInterface < Morpheus::APIClient
132
110
  end
133
111
  gz.close
134
112
  }
135
- http_opts[:body] = BodyIO.new(rd)
113
+ http_opts[:body] = Morpheus::BodyIO.new(rd)
136
114
  response = http.post(url, http_opts)
137
115
  else
138
116
  if @dry_run
@@ -114,8 +114,8 @@ module Morpheus
114
114
  [id_list].flatten.collect {|it| it ? it.to_s.split(delim) : nil }.flatten.compact
115
115
  end
116
116
 
117
- def parse_bytes_param(bytes_param, option, assumed_unit = nil)
118
- if bytes_param && bytes_param.to_f > 0
117
+ def parse_bytes_param(bytes_param, option, assumed_unit = nil, allow_zero = false)
118
+ if bytes_param && ( bytes_param.to_f > 0 || ( allow_zero && bytes_param.to_i == 0 ))
119
119
  bytes_param.upcase!
120
120
  multiplier = 1
121
121
  unit = nil
@@ -151,6 +151,10 @@ module Morpheus
151
151
 
152
152
  # add each one to the OptionParser
153
153
  option_types.each do |option_type|
154
+ # skip hidden types
155
+ if option_type['type'] == 'hidden'
156
+ next
157
+ end
154
158
  if option_type['fieldName'].empty?
155
159
  puts_error "Missing fieldName for option type: #{option_type}" if Morpheus::Logging.debug?
156
160
  next
@@ -268,6 +272,10 @@ module Morpheus
268
272
  build_standard_delete_options(opts, options, includes, excludes)
269
273
  end
270
274
 
275
+ def build_standard_api_options(opts, options, includes=[], excludes=[])
276
+ build_common_options(opts, options, includes + [:query, :options, :payload, :json, :yaml, :csv, :fields, :select, :delim, :quiet, :dry_run, :remote], excludes)
277
+ end
278
+
271
279
  # number of decimal places to show with curreny
272
280
  def default_sigdig
273
281
  2
@@ -500,10 +508,14 @@ module Morpheus
500
508
  end
501
509
  end
502
510
 
503
- opts.on( '-D', '--desc', "Reverse Sort Order" ) do |v|
511
+ opts.on( '-D', '--desc', "Descending Sort Direction." ) do |v|
504
512
  options[:direction] = "desc"
505
513
  end
506
514
 
515
+ opts.on( "--reverse", "Reverse order of results. This invert is done by the client, not necessarily the entire dataset." ) do
516
+ options[:reverse] = true
517
+ end
518
+
507
519
  # arbitrary query parameters in the format -Q "category=web&phrase=nginx"
508
520
  # opts.on( '-Q', '--query PARAMS', "Query parameters. PARAMS format is 'foo=bar&category=web'" ) do |val|
509
521
  # options[:query_filters_raw] = val
@@ -743,6 +755,7 @@ module Morpheus
743
755
  options[:include_fields] = val
744
756
  end
745
757
  end
758
+ opts.add_hidden_option('-F, --old-fields') if opts.is_a?(Morpheus::Cli::OptionParser)
746
759
  opts.on('--raw-fields [x,y,z]', String, "Raw fields filters output like --fields except the properties [x,y,z] must be specified from the root of the response instead of relative to the the list or object context for this particular resource.") do |val|
747
760
  if val.size == 1 && val[0].downcase == 'all'
748
761
  options[:all_fields] = true
@@ -1271,6 +1284,23 @@ module Morpheus
1271
1284
  params.merge!(parse_query_options(options))
1272
1285
  end
1273
1286
 
1287
+ # Add a name=value query parameter, building an array if there is more than one
1288
+ # @param [Hash] params the query parameter map to append to
1289
+ # @param [String] key the parameter name
1290
+ # @param [Object] value the parameter value
1291
+ def add_query_parameter(params, key, value)
1292
+ # key = key.to_s
1293
+ if params.key?(key) && !params[key].nil?
1294
+ if !params[key].is_a?(Array)
1295
+ params[key] = [params[key]]
1296
+ end
1297
+ params[key] << value
1298
+ else
1299
+ params[key] = value
1300
+ end
1301
+ params
1302
+ end
1303
+
1274
1304
  # The default way to parse options for the get command
1275
1305
  # @param type [string]
1276
1306
  # @param options [Hash] The command options
@@ -1371,6 +1401,38 @@ module Morpheus
1371
1401
  payload
1372
1402
  end
1373
1403
 
1404
+ def build_payload(options, object_key=nil)
1405
+ payload = {}
1406
+ if options[:payload]
1407
+ parse_payload(options, object_key)
1408
+ else
1409
+ apply_options(payload, options, object_key)
1410
+ end
1411
+ return payload
1412
+ end
1413
+
1414
+ def parse_array(val, opts={})
1415
+ opts = {strip:true, allow_blank:false}.merge(opts)
1416
+ values = []
1417
+ if val.is_a?(Array)
1418
+ values = val
1419
+ else
1420
+ # parse csv and strip white space by default
1421
+ values = val.to_s.split(",")#.collect {|it| it.to_s.strip }
1422
+ if opts[:strip]
1423
+ values = values.collect {|it| it.to_s.strip }
1424
+ end
1425
+ if !opts[:allow_blank]
1426
+ values.reject! {|it| it.to_s.strip.empty? }
1427
+ end
1428
+ end
1429
+ values
1430
+ end
1431
+
1432
+ def parse_labels(val)
1433
+ parse_array(val, {strip:true, allow_blank:false})
1434
+ end
1435
+
1374
1436
  # support -O OPTION switch
1375
1437
  def apply_options(payload, options, object_key=nil)
1376
1438
  payload ||= {}
@@ -1528,8 +1590,20 @@ module Morpheus
1528
1590
  end
1529
1591
  begin
1530
1592
  json_response = interface.get(*ids)
1531
- return json_response[object_key]
1532
- rescue Exception => e
1593
+ if !json_response.key?(object_key)
1594
+ # maybe just use the first key like this:
1595
+ # object_key = json_response.keys.find { |k| json_response[k].is_a?(Hash) }
1596
+ #puts_error(json_response) if Morpheus::Logging.debug?
1597
+ raise "API response is missing object property '#{object_key}'"
1598
+ end
1599
+ record = json_response[object_key]
1600
+ if record.nil?
1601
+ print_red_alert "#{label} not found in API response (#{object_key})"
1602
+ return nil
1603
+ else
1604
+ return json_response[object_key]
1605
+ end
1606
+ rescue ::RestClient::Exception => e
1533
1607
  if e.response && e.response.code == 404
1534
1608
  print_red_alert "#{label} not found by id #{ids.last}"
1535
1609
  return nil
@@ -1593,7 +1667,7 @@ module Morpheus
1593
1667
  if !json_response.key?(list_key)
1594
1668
  # maybe just use the first key like this:
1595
1669
  # list_key = json_response.keys.find { |k| json_response[k].is_a?(Array) }
1596
- # print_error(json_response) if Morpheus::Logging.debug?
1670
+ # puts_error(json_response) if Morpheus::Logging.debug?
1597
1671
  raise "API response is missing list property '#{list_key}'"
1598
1672
  end
1599
1673
  return json_response[list_key]
@@ -1624,7 +1698,7 @@ module Morpheus
1624
1698
  if !json_response.key?(object_key)
1625
1699
  # maybe just use the first key like this:
1626
1700
  # object_key = json_response.keys.find { |k| json_response[k].is_a?(Hash) }
1627
- # print_error(json_response) if Morpheus::Logging.debug?
1701
+ # puts_error(json_response) if Morpheus::Logging.debug?
1628
1702
  raise "API response is missing object property '#{object_key}'"
1629
1703
  end
1630
1704
  return json_response[object_key]