morpheus-cli 5.5.2.2 → 5.5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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