morpheus-cli 5.5.2.2 → 5.5.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/Dockerfile +1 -1
  4. data/README.md +57 -4
  5. data/Rakefile +9 -0
  6. data/bin/morpheus +4 -4
  7. data/lib/morpheus/api/api_client.rb +20 -2
  8. data/lib/morpheus/api/appliance_settings_interface.rb +15 -0
  9. data/lib/morpheus/api/archive_buckets_interface.rb +1 -1
  10. data/lib/morpheus/api/archive_files_interface.rb +3 -3
  11. data/lib/morpheus/api/clients_interface.rb +2 -2
  12. data/lib/morpheus/api/clusters_interface.rb +8 -1
  13. data/lib/morpheus/api/containers_interface.rb +29 -16
  14. data/lib/morpheus/api/custom_instance_types_interface.rb +0 -2
  15. data/lib/morpheus/api/cypher_interface.rb +1 -2
  16. data/lib/morpheus/api/doc_interface.rb +8 -6
  17. data/lib/morpheus/api/file_copy_request_interface.rb +1 -1
  18. data/lib/morpheus/api/guidance_settings_interface.rb +17 -0
  19. data/lib/morpheus/api/health_interface.rb +1 -1
  20. data/lib/morpheus/api/image_builder_interface.rb +3 -3
  21. data/lib/morpheus/api/instances_interface.rb +25 -0
  22. data/lib/morpheus/api/logs_interface.rb +2 -4
  23. data/lib/morpheus/api/monitoring_interface.rb +6 -6
  24. data/lib/morpheus/api/monitoring_settings_interface.rb +25 -0
  25. data/lib/morpheus/api/network_server_groups_interface.rb +7 -0
  26. data/lib/morpheus/api/packages_interface.rb +1 -1
  27. data/lib/morpheus/api/reports_interface.rb +1 -1
  28. data/lib/morpheus/api/servers_interface.rb +9 -1
  29. data/lib/morpheus/api/storage_providers_interface.rb +2 -2
  30. data/lib/morpheus/api/virtual_images_interface.rb +1 -1
  31. data/lib/morpheus/api.rb +2 -0
  32. data/lib/morpheus/benchmarking.rb +1 -1
  33. data/lib/morpheus/cli/cli_command.rb +79 -37
  34. data/lib/morpheus/cli/cli_registry.rb +19 -10
  35. data/lib/morpheus/cli/commands/access_token_command.rb +1 -1
  36. data/lib/morpheus/cli/commands/appliance_settings_command.rb +57 -2
  37. data/lib/morpheus/cli/commands/apps.rb +1 -1
  38. data/lib/morpheus/cli/commands/archives_command.rb +25 -33
  39. data/lib/morpheus/cli/commands/backup_settings_command.rb +1 -1
  40. data/lib/morpheus/cli/commands/blueprints_command.rb +10 -21
  41. data/lib/morpheus/cli/commands/boot_scripts_command.rb +2 -2
  42. data/lib/morpheus/cli/commands/cat_command.rb +1 -1
  43. data/lib/morpheus/cli/commands/catalog_item_types_command.rb +18 -13
  44. data/lib/morpheus/cli/commands/clouds.rb +3 -3
  45. data/lib/morpheus/cli/commands/clusters.rb +154 -3
  46. data/lib/morpheus/cli/commands/containers_command.rb +398 -253
  47. data/lib/morpheus/cli/commands/cypher_command.rb +3 -0
  48. data/lib/morpheus/cli/commands/deployments.rb +1 -1
  49. data/lib/morpheus/cli/commands/deploys.rb +9 -9
  50. data/lib/morpheus/cli/commands/doc.rb +15 -16
  51. data/lib/morpheus/cli/commands/execution_request_command.rb +2 -2
  52. data/lib/morpheus/cli/commands/file_copy_request_command.rb +5 -5
  53. data/lib/morpheus/cli/commands/groups.rb +2 -2
  54. data/lib/morpheus/cli/commands/guidance_command.rb +2 -2
  55. data/lib/morpheus/cli/commands/guidance_settings.rb +148 -0
  56. data/lib/morpheus/cli/commands/health_command.rb +4 -4
  57. data/lib/morpheus/cli/commands/hosts.rb +43 -5
  58. data/lib/morpheus/cli/commands/image_builder_command.rb +1 -1
  59. data/lib/morpheus/cli/commands/instances.rb +419 -148
  60. data/lib/morpheus/cli/commands/integrations_command.rb +22 -20
  61. data/lib/morpheus/cli/commands/key_pairs.rb +2 -2
  62. data/lib/morpheus/cli/commands/library_container_scripts_command.rb +2 -2
  63. data/lib/morpheus/cli/commands/library_container_templates_command.rb +2 -2
  64. data/lib/morpheus/cli/commands/library_instance_types_command.rb +3 -3
  65. data/lib/morpheus/cli/commands/library_spec_templates_command.rb +2 -2
  66. data/lib/morpheus/cli/commands/log_settings_command.rb +1 -1
  67. data/lib/morpheus/cli/commands/login.rb +1 -1
  68. data/lib/morpheus/cli/commands/man_command.rb +32 -18
  69. data/lib/morpheus/cli/commands/monitoring_settings.rb +228 -0
  70. data/lib/morpheus/cli/commands/network_server_groups_command.rb +222 -0
  71. data/lib/morpheus/cli/commands/packages_command.rb +11 -11
  72. data/lib/morpheus/cli/commands/plugins.rb +1 -1
  73. data/lib/morpheus/cli/commands/policies_command.rb +4 -4
  74. data/lib/morpheus/cli/commands/preseed_scripts_command.rb +2 -2
  75. data/lib/morpheus/cli/commands/provisioning_settings_command.rb +1 -1
  76. data/lib/morpheus/cli/commands/remote.rb +1 -1
  77. data/lib/morpheus/cli/commands/reports_command.rb +13 -3
  78. data/lib/morpheus/cli/commands/security_groups.rb +1 -1
  79. data/lib/morpheus/cli/commands/shell.rb +40 -62
  80. data/lib/morpheus/cli/commands/snapshots.rb +3 -5
  81. data/lib/morpheus/cli/commands/source_command.rb +8 -16
  82. data/lib/morpheus/cli/commands/storage_providers_command.rb +7 -7
  83. data/lib/morpheus/cli/commands/tasks.rb +2 -2
  84. data/lib/morpheus/cli/commands/vdi_pools_command.rb +6 -6
  85. data/lib/morpheus/cli/commands/view.rb +5 -1
  86. data/lib/morpheus/cli/commands/whitelabel_settings_command.rb +5 -5
  87. data/lib/morpheus/cli/commands/whoami.rb +2 -2
  88. data/lib/morpheus/cli/credentials.rb +30 -8
  89. data/lib/morpheus/cli/dot_file.rb +8 -15
  90. data/lib/morpheus/cli/error_handler.rb +16 -0
  91. data/lib/morpheus/cli/errors.rb +8 -1
  92. data/lib/morpheus/cli/mixins/print_helper.rb +17 -13
  93. data/lib/morpheus/cli/mixins/provisioning_helper.rb +14 -12
  94. data/lib/morpheus/cli/mixins/rest_command.rb +23 -19
  95. data/lib/morpheus/cli/mixins/secondary_rest_command.rb +47 -24
  96. data/lib/morpheus/cli/option_parser.rb +5 -1
  97. data/lib/morpheus/cli/option_types.rb +59 -12
  98. data/lib/morpheus/cli/version.rb +1 -1
  99. data/lib/morpheus/cli.rb +26 -16
  100. data/lib/morpheus/ext/rest_client.rb +3 -2
  101. data/lib/morpheus/ext/string.rb +6 -4
  102. data/lib/morpheus/formatters.rb +1 -1
  103. data/lib/morpheus/logging.rb +4 -4
  104. data/lib/morpheus/morpkg.rb +4 -4
  105. data/lib/morpheus/rest_client.rb +2 -2
  106. data/lib/morpheus/routes.rb +41 -9
  107. data/lib/morpheus/terminal.rb +65 -16
  108. data/lib/morpheus.rb +1 -1
  109. data/morpheus-cli.gemspec +1 -0
  110. data/test/api/containers_interface_test.rb +68 -0
  111. data/test/api/doc_interface_test.rb +35 -0
  112. data/test/api/instances_interface_test.rb +22 -0
  113. data/test/api/whoami_interface_test.rb +14 -0
  114. data/test/cli/access_token_test.rb +36 -0
  115. data/test/cli/auth_test.rb +82 -0
  116. data/test/cli/cli_test.rb +48 -0
  117. data/test/cli/containers_test.rb +92 -0
  118. data/test/cli/doc_test.rb +35 -0
  119. data/test/cli/help_test.rb +25 -0
  120. data/test/cli/instances_test.rb +36 -0
  121. data/test/cli/man_test.rb +14 -0
  122. data/test/cli/remote_test.rb +89 -0
  123. data/test/cli/roles_test.rb +34 -0
  124. data/test/cli/shell_test.rb +81 -0
  125. data/test/cli/version_test.rb +23 -0
  126. data/test/cli/view_test.rb +55 -0
  127. data/test/cli/whoami_test.rb +17 -0
  128. data/test/morpheus_test.rb +16 -0
  129. data/test/test_case.rb +338 -0
  130. data/test/test_config.rb +137 -0
  131. data/test/test_data_helper.rb +97 -0
  132. metadata +67 -3
@@ -0,0 +1,222 @@
1
+ require 'morpheus/cli/cli_command'
2
+
3
+ class Morpheus::Cli::NetworkServerGroups
4
+ include Morpheus::Cli::CliCommand
5
+ include Morpheus::Cli::WhoamiHelper
6
+ include Morpheus::Cli::RestCommand
7
+ include Morpheus::Cli::SecondaryRestCommand
8
+ include Morpheus::Cli::ProvisioningHelper
9
+
10
+ set_command_description "View and manage network server groups."
11
+ set_command_name :'network-server-groups'
12
+ register_subcommands :list, :get, :add, :update, :remove
13
+ register_interfaces :network_servers, :network_server_groups, :accounts
14
+ set_rest_perms_config({enabled:true, excludes:['groups', 'plans', 'visibility', 'resource'], context: 'permissions'})
15
+
16
+ protected
17
+
18
+ NSXT_CRITERIA_TYPES = ['Condition', 'NestedExpression'] unless defined? NSXT_CRITERIA_TYPES
19
+ NSXT_MEMBER_TYPES = ['Path', 'ExternalID'] unless defined? NSXT_MEMBER_TYPES
20
+ NSXT_IP_TYPES = ['IPAddress', 'MACAddress'] unless defined? NSXT_IP_TYPES
21
+ NSXT_AD_GROUP_TYPES = ['IdentityGroup'] unless defined? NSXT_AD_GROUP_TYPES
22
+
23
+ def network_server_group_list_key
24
+ 'groups'
25
+ end
26
+
27
+ def network_server_group_object_key
28
+ 'group'
29
+ end
30
+
31
+ def network_server_group_field_context
32
+ network_server_group_object_key
33
+ end
34
+
35
+ def load_option_types_for_network_server_group(record_type, parent_record)
36
+ parent_record['type']['groupOptionTypes']
37
+ end
38
+
39
+ def network_server_group_list_column_definitions(options)
40
+ if options[:parent_record]['type']['code'] == 'nsx-t'
41
+ members_lambda = lambda do |group|
42
+ members = []
43
+ {
44
+ 'Criteria' => NSXT_CRITERIA_TYPES,
45
+ 'Members' => NSXT_MEMBER_TYPES,
46
+ 'IPS / MACS' => NSXT_IP_TYPES,
47
+ 'AD Groups' => NSXT_AD_GROUP_TYPES
48
+ }.each do |label, types|
49
+ if (count = group['members'].select{|member| types.include?(member['type'])}.count) > 0
50
+ members << "#{count} #{label}"
51
+ end
52
+ end
53
+ members.join(', ')
54
+ end
55
+ else
56
+ members_lambda = lambda do |group|
57
+ group['members'].collect{|member| member['type']}.join(', ')
58
+ end
59
+ end
60
+
61
+ columns = {
62
+ 'ID' => 'id',
63
+ 'Name' => 'name',
64
+ 'Description' => {:label => 'Description', :max_width => 50, :display_method => lambda {|group| group['description']}},
65
+ 'Members' => members_lambda
66
+ }
67
+
68
+ if is_master_account
69
+ columns['Visibility'] = lambda {|it| it['visibility'].capitalize}
70
+ columns['Tenants'] = lambda do |it|
71
+ tenants = []
72
+ if it['permissions'] and it['permissions']['tenantPermissions']
73
+ tenants = @accounts_interface.list({:ids => it['permissions']['tenantPermissions']['accounts']})['accounts'].collect{|account| account['name']}
74
+ end
75
+ tenants.join(', ')
76
+ end
77
+ end
78
+ columns
79
+ end
80
+
81
+ def network_server_group_column_definitions(options)
82
+ if options[:parent_record]['type']['code'] == 'nsx-t'
83
+ tags_lambda = lambda{|group|
84
+ (group['tags'] || []).collect{|tag|
85
+ "#{tag['name']}#{(tag['value'] || '').length > 0 ? " (scope: #{tag['value']})" : ''}"
86
+ }.join(', ')
87
+ }
88
+ else
89
+ tags_lambda = lambda {|group| group['tags'] ? format_metadata(group['tags']) : '' }
90
+ end
91
+ columns = {
92
+ "ID" => 'id',
93
+ "Name" => 'name',
94
+ "Description" => 'description',
95
+ "Tags" => tags_lambda
96
+ }
97
+ columns
98
+ end
99
+
100
+ def network_server_group_add_prompt(record_payload, record_type, parent_record, options)
101
+ unless parent_record['type']['code'] != 'nsx-t' or options[:no_prompt]
102
+ nsxt_add_prompt(record_payload, record_type, parent_record, options)
103
+ end
104
+ end
105
+
106
+ def nsxt_add_prompt(record_payload, record_type, parent_record, options)
107
+ # criteria
108
+ criteria = []
109
+ while criteria.count < 5 && Morpheus::Cli::OptionTypes.confirm("Add#{criteria.count == 0 ? '': ' another'} criteria?", {:default => false})
110
+ if true #members.count == 0 or members.last['memberValue'] == 'OR' # Can't have nested follow AND conjunction
111
+ type = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'fieldLabel' => 'Criteria Type', 'type' => 'select', 'selectOptions' => ['Condition', 'Nested Expression'].map{|it| {'name' => it, 'value' => it.sub(' ', '')}}, 'required' => true, 'defaultValue' => 'Condition'}], options[:options])['type']
112
+ end
113
+ prompt_condition = lambda do
114
+ compare_type = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'memberType', 'fieldLabel' => 'Criteria Item', 'type' => 'select', 'selectOptions' => ['Virtual Machine', 'Segment Port', 'Segment', 'IP Set'].map{|it| {'name' => it, 'value' => it.sub(' ', '')}}, 'required' => true, 'defaultValue' => 'VirtualMachine'}], options[:options])['memberType']
115
+ compare_key = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'key', 'fieldLabel' => "#{compare_type} Field", 'type' => 'select', 'selectOptions' => (compare_type == 'VirtualMachine' ? ['Name', 'Tag', 'OS Name', 'Computer Name'] : ['Tag'] ).map{|it| {'name' => it, 'value' => it.sub(' ', '')}}, 'required' => true, 'defaultValue' => 'Tag'}], options[:options])['key']
116
+ compare_operator = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'operator', 'fieldLabel' => "#{compare_key} Operator", 'type' => 'select', 'selectOptions' => (compare_type == 'VirtualMachine' ? ['Equals', 'Contains', 'Starts With', 'Ends With'] : ['Equals']).map{|it| {'name' => it, 'value' => it.sub(' ', '').upcase}}, 'required' => true, 'defaultValue' => 'EQUALS'}], options[:options])['operator']
117
+ compare_value = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'value', 'type' => 'text', 'fieldLabel' => "#{compare_key} Value", 'required' => true, 'description' => 'Value to compare.'}], options[:options])['value']
118
+ compare_scope = nil
119
+ if compare_key == 'Tag'
120
+ compare_scope = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'scope', 'type' => 'text', 'fieldLabel' => "#{compare_key} Scope", 'required' => false}], options[:options], @api_client, {}, false, true)['scope']
121
+ end
122
+ compare_expr = {key: compare_key, operator: compare_operator, value: compare_value}
123
+ compare_expr.merge!({scope: compare_scope}) if compare_scope
124
+ {'type' => 'Condition', 'memberType' => compare_type, 'memberExpression' => JSON.generate(compare_expr)}
125
+ end
126
+
127
+ if criteria.count > 0
128
+ criteria.last['memberValue'] = 'OR'
129
+ end
130
+
131
+ if type == 'Condition'
132
+ prev_criteria = criteria.count > 0 ? criteria.last : nil
133
+ criteria << prompt_condition.call
134
+ if prev_criteria and prev_criteria['type'] != 'NestedExpression' and prev_criteria['memberType'] == criteria.last['memberType']
135
+ prev_criteria['memberValue'] = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'memberValue', 'fieldLabel' => 'And/Or', 'type' => 'select', 'selectOptions' => ['and', 'or'].map{|it| {'name' => it, 'value' => it.upcase}}, 'required' => true, 'defaultValue' => 'AND', 'description' => 'Conjunction to use between this condition and the previous condition'}], options[:options])['memberValue']
136
+ end
137
+ else
138
+ # just prompt for conditions w/
139
+ nested_members = [prompt_condition.call]
140
+ while nested_members.count < 5 && Morpheus::Cli::OptionTypes.confirm("Add another criteria to nested expression?", {:default => false})
141
+ nested_members.last['memberValue'] = 'AND'
142
+ nested_members << prompt_condition.call
143
+ end
144
+ criteria << {'type' => type, 'members' => nested_members}
145
+ end
146
+ end
147
+
148
+ members = []
149
+ while members.count < 500 && Morpheus::Cli::OptionTypes.confirm("Add#{members.count == 0 ? '': ' another'} member?", {:default => false})
150
+ member_type = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'memberType', 'fieldLabel' => 'Member Type', 'type' => 'select', 'selectOptions' => ['Group', 'Segment', 'Segment Port', 'Virtual Network Interface', 'Virtual Machine', 'Physical Server'].map{|it| {'name' => it, 'value' => it.gsub(' ', '')}}, 'required' => true, 'defaultValue' => 'Group'}], options[:options])['memberType']
151
+ member_value = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'memberValue', 'fieldLabel' => member_type, 'type' => 'select', 'optionSource' => 'nsxtGroupMembers', 'optionSourceType' => 'nsxt', 'required' => true}], options[:options], @api_client, {networkServerId: parent_record['id'], memberType: member_type}, false, true)['memberValue']
152
+ type = ['Group', 'Segment', 'SegmentPort'].include?(member_type) ? 'Path' : 'ExternalID'
153
+ members << {'type' => type, 'memberType' => member_type, 'memberValue' => member_value}
154
+ end
155
+
156
+ # ip/mac
157
+ ips = []
158
+ while members.count + ips.count < 500 && Morpheus::Cli::OptionTypes.confirm("Add#{ips.count == 0 ? '': ' another'} IP/MAC address?", {:default => false})
159
+ member_value = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'ipAddress', 'type' => 'text', 'fieldLabel' => "IP/MAC Address", 'required' => true, 'description' => 'Enter an IP or MAC address. x.x.x.x'}], options[:options])['ipAddress']
160
+ type = member_value.match(/[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5}/) ? 'MACAddress' : 'IPAddress'
161
+ ips << {'type' => type, 'memberValue' => member_value}
162
+ end
163
+
164
+ # ad groups
165
+ ad_groups = []
166
+ while members.count + ips.count + ad_groups.count < 500 && Morpheus::Cli::OptionTypes.confirm("Add#{ad_groups.count == 0 ? '': ' another'} AD Group?", {:default => false})
167
+ member_value = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'identityGroup', 'type' => 'select', 'optionSource' => 'nsxtIdentityGroups', 'optionSourceType' => 'nsxt', 'required' => true, 'fieldLabel' => "AD Group"}], options[:options], @api_client, {networkServerId: parent_record['id'], memberType: member_type}, false, true)['identityGroup']
168
+ ad_groups << {'type' => 'IdentityGroup', 'memberValue' => member_value}
169
+ end
170
+
171
+ record_payload['members'] = criteria + members + ips + ad_groups
172
+ record_payload
173
+ end
174
+
175
+ def render_response_details_for_get(record, options)
176
+ if options[:parent_record]['type']['code'] == 'nsx-t'
177
+ members = record['members'].select{|member| NSXT_CRITERIA_TYPES.include?(member['type'])}
178
+ if members.count > 0
179
+ cond_criteria = lambda do |member|
180
+ expr = JSON.parse(member['memberExpression'])
181
+ "#{member['memberType']} #{expr['key']} #{expr['operator']} #{expr['value']}#{expr['scope'].nil? ? '' : " w/ #{expr['scope']} scope"}"
182
+ end
183
+ criteria_parts = []
184
+ members.each_with_index do |member, index|
185
+ if member['type'] == 'NestedExpression'
186
+ criteria_parts << "("
187
+ member['members'].each do |child_member|
188
+ criteria_parts << " #{cond_criteria.call(child_member)}"
189
+ criteria_parts << " #{child_member['memberValue']}"
190
+ end
191
+ criteria_parts.pop # remove last conjunction
192
+ criteria_parts << ")"
193
+ else
194
+ criteria_parts << cond_criteria.call(member)
195
+ criteria_parts << member['memberValue']
196
+ end
197
+ end
198
+ criteria_parts.pop if ['AND', 'OR'].include?(criteria_parts.last) # remove last conjunction
199
+ print_h2 "Criteria (#{members.count})", options
200
+ print "#{cyan}#{criteria_parts.join("\n")}\n"
201
+ end
202
+
203
+ members = record['members'].select{|member| NSXT_MEMBER_TYPES.include?(member['type'])}
204
+ if members.count > 0
205
+ print_h2 "Members (#{members.count})", options
206
+ print as_pretty_table(members, {'Type' => 'memberType', 'Path/ExternalID' => 'memberValue'}, options)
207
+ end
208
+
209
+ members = record['members'].select{|member| NSXT_IP_TYPES.include?(member['type'])}
210
+ if members.count > 0
211
+ print_h2 "IP/MAC Addresses (#{members.count})", options
212
+ print "#{cyan}#{members.collect{|member| "#{member['memberValue']}"}.join("\n")}\n"
213
+ end
214
+
215
+ members = record['members'].select{|member| NSXT_AD_GROUP_TYPES.include?(member['type'])}
216
+ if members.count > 0
217
+ print_h2 "AD Groups (#{members.count})", options
218
+ print "#{cyan}#{members.collect{|member| "#{member['memberValue']}"}.join("\n")}\n"
219
+ end
220
+ end
221
+ end
222
+ end
@@ -386,7 +386,7 @@ class Morpheus::Cli::PackagesCommand
386
386
  puts_error "bad argument: [morpkg-file]\nFile '#{local_file_path}' is invalid.\n#{optparse}"
387
387
  return 1
388
388
  end
389
- if !File.exists?(local_file_path)
389
+ if !File.exist?(local_file_path)
390
390
  print_error Morpheus::Terminal.angry_prompt
391
391
  puts_error "bad argument: [morpkg-file]\nFile '#{local_file_path}' was not found.\n"
392
392
  return 1
@@ -545,7 +545,7 @@ class Morpheus::Cli::PackagesCommand
545
545
  end
546
546
  end
547
547
  outfile = File.expand_path(outfile)
548
- if Dir.exists?(outfile)
548
+ if Dir.exist?(outfile)
549
549
  puts_error "#{Morpheus::Terminal.angry_prompt}--file is invalid. It is the name of an existing directory: #{outfile}"
550
550
  return 1
551
551
  end
@@ -554,7 +554,7 @@ class Morpheus::Cli::PackagesCommand
554
554
  outfile << ".morpkg"
555
555
  end
556
556
  destination_dir = File.dirname(outfile)
557
- if !Dir.exists?(destination_dir)
557
+ if !Dir.exist?(destination_dir)
558
558
  if do_mkdir
559
559
  print cyan,"Creating local directory #{destination_dir}",reset,"\n"
560
560
  FileUtils.mkdir_p(destination_dir)
@@ -563,7 +563,7 @@ class Morpheus::Cli::PackagesCommand
563
563
  return 1
564
564
  end
565
565
  end
566
- if File.exists?(outfile)
566
+ if File.exist?(outfile)
567
567
  if do_overwrite
568
568
  # uhh need to be careful wih the passed filepath here..
569
569
  # don't delete, just overwrite.
@@ -598,7 +598,7 @@ class Morpheus::Cli::PackagesCommand
598
598
 
599
599
  if do_unzip
600
600
  package_dir = File.join(File.dirname(outfile), File.basename(outfile).sub(/\.morpkg\Z/, ''))
601
- if File.exists?(package_dir)
601
+ if File.exist?(package_dir)
602
602
  print cyan,"Deleting existing directory #{package_dir}",reset,"\n"
603
603
  FileUtils.rm_rf(package_dir)
604
604
  end
@@ -619,7 +619,7 @@ class Morpheus::Cli::PackagesCommand
619
619
  #response_body = (http_response.body.kind_of?(Net::ReadAdapter) ? "" : http_response.body)
620
620
  end
621
621
  # F it, just remove a bad result
622
- if File.exists?(outfile) && File.file?(outfile)
622
+ if File.exist?(outfile) && File.file?(outfile)
623
623
  Morpheus::Logging::DarkPrinter.puts "Deleting bad file download: #{outfile}" if Morpheus::Logging.debug?
624
624
  File.delete(outfile)
625
625
  end
@@ -687,7 +687,7 @@ class Morpheus::Cli::PackagesCommand
687
687
  begin
688
688
  # validate source
689
689
  source_directory = File.expand_path(source_directory)
690
- if !File.exists?(source_directory)
690
+ if !File.exist?(source_directory)
691
691
  puts_error "#{Morpheus::Terminal.angry_prompt}[source] is invalid. Directory not found: #{source_directory}"
692
692
  return 1
693
693
  end
@@ -718,7 +718,7 @@ class Morpheus::Cli::PackagesCommand
718
718
  else
719
719
  outfile = File.expand_path(outfile)
720
720
  end
721
- if Dir.exists?(outfile)
721
+ if Dir.exist?(outfile)
722
722
  puts_error "#{Morpheus::Terminal.angry_prompt}[target] is invalid. It is the name of an existing directory: #{outfile}"
723
723
  return 1
724
724
  end
@@ -727,7 +727,7 @@ class Morpheus::Cli::PackagesCommand
727
727
  outfile << ".morpkg"
728
728
  end
729
729
  destination_dir = File.dirname(outfile)
730
- if !Dir.exists?(destination_dir)
730
+ if !Dir.exist?(destination_dir)
731
731
  if do_mkdir
732
732
  print cyan,"Creating local directory #{destination_dir}",reset,"\n"
733
733
  FileUtils.mkdir_p(destination_dir)
@@ -736,7 +736,7 @@ class Morpheus::Cli::PackagesCommand
736
736
  return 1
737
737
  end
738
738
  end
739
- if File.exists?(outfile)
739
+ if File.exist?(outfile)
740
740
  if do_overwrite
741
741
  # uhh need to be careful wih the passed filepath here..
742
742
  # don't delete, just overwrite.
@@ -783,7 +783,7 @@ class Morpheus::Cli::PackagesCommand
783
783
  end
784
784
  end
785
785
  # F it, just remove a bad result
786
- # if File.exists?(outfile) && File.file?(outfile)
786
+ # if File.exist?(outfile) && File.file?(outfile)
787
787
  # Morpheus::Logging::DarkPrinter.puts "Deleting bad build file: #{outfile}" if Morpheus::Logging.debug?
788
788
  # File.delete(outfile)
789
789
  # end
@@ -30,7 +30,7 @@ EOT
30
30
  connect(options)
31
31
  filename = args[0]
32
32
  filename = File.expand_path(filename)
33
- if !File.exists?(filename)
33
+ if !File.exist?(filename)
34
34
  raise_command_error "File not found: #{filename}"
35
35
  elsif !File.file?(filename)
36
36
  raise_command_error "File is a directory: #{filename}"
@@ -334,7 +334,7 @@ class Morpheus::Cli::PoliciesCommand
334
334
  options['eachUser'] = val.to_s == 'on' || val.to_s == 'true' || val.to_s.empty?
335
335
  end
336
336
 
337
- opts.on('-t', '--type ID', "Policy Type Name or ID") do |val|
337
+ opts.on('-t', '--type ID', "Policy Type Name, Code or ID") do |val|
338
338
  options['type'] = val
339
339
  end
340
340
  opts.on('--name VALUE', String, "Name for this policy") do |val|
@@ -417,7 +417,7 @@ class Morpheus::Cli::PoliciesCommand
417
417
  print_red_alert "No available policy types found!"
418
418
  return 1
419
419
  end
420
- policy_types_dropdown = available_policy_types.collect {|it| {'name' => it['name'], 'value' => it['id']} }
420
+ policy_types_dropdown = available_policy_types.collect {|it| {'name' => it['name'], 'value' => it['code'], 'id' => it['id']} }
421
421
  policy_type_id = nil
422
422
  policy_type = nil
423
423
  if options['type']
@@ -497,7 +497,7 @@ class Morpheus::Cli::PoliciesCommand
497
497
  payload['policy']['config'] = options['config']
498
498
  elsif options['configFile']
499
499
  config_file = File.expand_path(options['configFile'])
500
- if !File.exists?(config_file) || !File.file?(config_file)
500
+ if !File.exist?(config_file) || !File.file?(config_file)
501
501
  print_red_alert "File not found: #{config_file}"
502
502
  return false
503
503
  end
@@ -637,7 +637,7 @@ class Morpheus::Cli::PoliciesCommand
637
637
  payload['policy']['config'] = options['config']
638
638
  elsif options['configFile']
639
639
  config_file = File.expand_path(options['configFile'])
640
- if !File.exists?(config_file) || !File.file?(config_file)
640
+ if !File.exist?(config_file) || !File.file?(config_file)
641
641
  print_red_alert "File not found: #{config_file}"
642
642
  return false
643
643
  end
@@ -172,7 +172,7 @@ class Morpheus::Cli::PreseedScriptsCommand
172
172
  params = Morpheus::Cli::OptionTypes.prompt(my_options, options[:options], @api_client, options[:params])
173
173
  script_file = params.delete('file')
174
174
  if script_file
175
- if !File.exists?(script_file)
175
+ if !File.exist?(script_file)
176
176
  print_red_alert "File not found: #{script_file}"
177
177
  return 1
178
178
  end
@@ -243,7 +243,7 @@ class Morpheus::Cli::PreseedScriptsCommand
243
243
  # params = Morpheus::Cli::OptionTypes.prompt(my_options, options[:options], @api_client, options[:params])
244
244
  script_file = params.delete('file')
245
245
  if script_file
246
- if !File.exists?(script_file)
246
+ if !File.exist?(script_file)
247
247
  print_red_alert "File not found: #{script_file}"
248
248
  return 1
249
249
  end
@@ -83,7 +83,7 @@ class Morpheus::Cli::ProvisioningSettingsCommand
83
83
  "Default Blueprint Type" => lambda {|it| it['defaultTemplateType'] ? it['defaultTemplateType']['name'].capitalize : 'Morpheus'}
84
84
  }
85
85
  print_description_list(description_cols, settings)
86
- print reset "\n"
86
+ print reset, "\n"
87
87
  return 0
88
88
  rescue RestClient::Exception => e
89
89
  print_rest_exception(e, options)
@@ -1512,7 +1512,7 @@ EOT
1512
1512
 
1513
1513
  def save_appliances(new_config)
1514
1514
  fn = appliances_file_path
1515
- if !Dir.exists?(File.dirname(fn))
1515
+ if !Dir.exist?(File.dirname(fn))
1516
1516
  FileUtils.mkdir_p(File.dirname(fn))
1517
1517
  end
1518
1518
  File.open(fn, 'w') {|f| f.write new_config.to_yaml } #Store
@@ -303,6 +303,16 @@ class Morpheus::Cli::ReportsCommand
303
303
 
304
304
  end
305
305
 
306
+ if payload['report']['startMonth'].size > 7 || payload['report']['endMonth'].size > 7
307
+ print_green_success "The CLI generates a query that will use only month and year. However, the API does support yyyy-mm-dd from a previous version of Morpheus.\nReplace startMonth/endMonth keys with startDate,endDate ie:"
308
+ payload['report'].delete('startMonth')
309
+ payload['report'].delete('endMonth')
310
+ payload['report']['startDate'] = 'yyyy-mm-dd'
311
+ payload['report']['endDate'] = 'yyyy-mm-dd'
312
+ print_dry_run @reports_interface.dry.create(payload)
313
+ return 0
314
+ end
315
+
306
316
  @reports_interface.setopts(options)
307
317
  if options[:dry_run]
308
318
  print_dry_run @reports_interface.dry.create(payload)
@@ -396,12 +406,12 @@ class Morpheus::Cli::ReportsCommand
396
406
  report_format = "csv"
397
407
  end
398
408
 
399
- if Dir.exists?(outfile)
409
+ if Dir.exist?(outfile)
400
410
  print_red_alert "[file] is invalid. It is the name of an existing directory: #{outfile}"
401
411
  return 1
402
412
  end
403
413
  destination_dir = File.dirname(outfile)
404
- if !Dir.exists?(destination_dir)
414
+ if !Dir.exist?(destination_dir)
405
415
  if do_mkdir
406
416
  print cyan,"Creating local directory #{destination_dir}",reset,"\n"
407
417
  FileUtils.mkdir_p(destination_dir)
@@ -410,7 +420,7 @@ class Morpheus::Cli::ReportsCommand
410
420
  return 1
411
421
  end
412
422
  end
413
- if File.exists?(outfile)
423
+ if File.exist?(outfile)
414
424
  if do_overwrite
415
425
  # uhh need to be careful wih the passed filepath here..
416
426
  # don't delete, just overwrite.
@@ -1156,7 +1156,7 @@ class Morpheus::Cli::SecurityGroups
1156
1156
 
1157
1157
  def self.save_security_group(new_config)
1158
1158
  fn = security_group_file_path
1159
- if !Dir.exists?(File.dirname(fn))
1159
+ if !Dir.exist?(File.dirname(fn))
1160
1160
  FileUtils.mkdir_p(File.dirname(fn))
1161
1161
  end
1162
1162
  File.open(fn, 'w') {|f| f.write new_config.to_yaml } #Store