morpheus-cli 2.10.0 → 2.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/bin/morpheus +27 -32
  3. data/lib/morpheus/api/accounts_interface.rb +36 -47
  4. data/lib/morpheus/api/api_client.rb +141 -110
  5. data/lib/morpheus/api/app_templates_interface.rb +56 -72
  6. data/lib/morpheus/api/apps_interface.rb +111 -132
  7. data/lib/morpheus/api/auth_interface.rb +30 -0
  8. data/lib/morpheus/api/clouds_interface.rb +71 -76
  9. data/lib/morpheus/api/custom_instance_types_interface.rb +21 -46
  10. data/lib/morpheus/api/dashboard_interface.rb +10 -17
  11. data/lib/morpheus/api/deploy_interface.rb +60 -72
  12. data/lib/morpheus/api/deployments_interface.rb +53 -71
  13. data/lib/morpheus/api/groups_interface.rb +55 -45
  14. data/lib/morpheus/api/instance_types_interface.rb +19 -23
  15. data/lib/morpheus/api/instances_interface.rb +179 -177
  16. data/lib/morpheus/api/key_pairs_interface.rb +11 -17
  17. data/lib/morpheus/api/license_interface.rb +18 -23
  18. data/lib/morpheus/api/load_balancers_interface.rb +54 -69
  19. data/lib/morpheus/api/logs_interface.rb +25 -29
  20. data/lib/morpheus/api/options_interface.rb +13 -17
  21. data/lib/morpheus/api/provision_types_interface.rb +19 -22
  22. data/lib/morpheus/api/roles_interface.rb +75 -94
  23. data/lib/morpheus/api/security_group_rules_interface.rb +28 -37
  24. data/lib/morpheus/api/security_groups_interface.rb +39 -51
  25. data/lib/morpheus/api/servers_interface.rb +113 -115
  26. data/lib/morpheus/api/setup_interface.rb +31 -0
  27. data/lib/morpheus/api/task_sets_interface.rb +36 -38
  28. data/lib/morpheus/api/tasks_interface.rb +56 -69
  29. data/lib/morpheus/api/users_interface.rb +67 -76
  30. data/lib/morpheus/api/virtual_images_interface.rb +61 -61
  31. data/lib/morpheus/api/whoami_interface.rb +12 -15
  32. data/lib/morpheus/cli.rb +71 -60
  33. data/lib/morpheus/cli/accounts.rb +254 -315
  34. data/lib/morpheus/cli/alias_command.rb +219 -0
  35. data/lib/morpheus/cli/app_templates.rb +264 -272
  36. data/lib/morpheus/cli/apps.rb +608 -671
  37. data/lib/morpheus/cli/cli_command.rb +259 -21
  38. data/lib/morpheus/cli/cli_registry.rb +99 -14
  39. data/lib/morpheus/cli/clouds.rb +599 -372
  40. data/lib/morpheus/cli/config_file.rb +126 -0
  41. data/lib/morpheus/cli/credentials.rb +141 -117
  42. data/lib/morpheus/cli/dashboard_command.rb +48 -56
  43. data/lib/morpheus/cli/deployments.rb +254 -268
  44. data/lib/morpheus/cli/deploys.rb +150 -142
  45. data/lib/morpheus/cli/error_handler.rb +38 -0
  46. data/lib/morpheus/cli/groups.rb +551 -179
  47. data/lib/morpheus/cli/hosts.rb +862 -617
  48. data/lib/morpheus/cli/instance_types.rb +103 -95
  49. data/lib/morpheus/cli/instances.rb +1335 -1009
  50. data/lib/morpheus/cli/key_pairs.rb +82 -90
  51. data/lib/morpheus/cli/library.rb +498 -499
  52. data/lib/morpheus/cli/license.rb +83 -101
  53. data/lib/morpheus/cli/load_balancers.rb +314 -300
  54. data/lib/morpheus/cli/login.rb +66 -44
  55. data/lib/morpheus/cli/logout.rb +47 -46
  56. data/lib/morpheus/cli/mixins/accounts_helper.rb +69 -31
  57. data/lib/morpheus/cli/mixins/infrastructure_helper.rb +106 -0
  58. data/lib/morpheus/cli/mixins/print_helper.rb +181 -17
  59. data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -458
  60. data/lib/morpheus/cli/mixins/whoami_helper.rb +2 -2
  61. data/lib/morpheus/cli/option_parser.rb +35 -0
  62. data/lib/morpheus/cli/option_types.rb +232 -192
  63. data/lib/morpheus/cli/recent_activity_command.rb +61 -65
  64. data/lib/morpheus/cli/remote.rb +446 -199
  65. data/lib/morpheus/cli/roles.rb +884 -906
  66. data/lib/morpheus/cli/security_group_rules.rb +213 -203
  67. data/lib/morpheus/cli/security_groups.rb +237 -192
  68. data/lib/morpheus/cli/shell.rb +338 -231
  69. data/lib/morpheus/cli/tasks.rb +326 -308
  70. data/lib/morpheus/cli/users.rb +457 -462
  71. data/lib/morpheus/cli/version.rb +1 -1
  72. data/lib/morpheus/cli/version_command.rb +16 -18
  73. data/lib/morpheus/cli/virtual_images.rb +526 -345
  74. data/lib/morpheus/cli/whoami.rb +125 -111
  75. data/lib/morpheus/cli/workflows.rb +338 -185
  76. data/lib/morpheus/formatters.rb +8 -1
  77. data/lib/morpheus/logging.rb +1 -1
  78. data/lib/morpheus/rest_client.rb +17 -8
  79. metadata +9 -3
  80. data/lib/morpheus/api/custom_instance_types.rb +0 -55
@@ -1,82 +1,78 @@
1
1
  require 'optparse'
2
2
  require 'morpheus/cli/cli_command'
3
+ require 'morpheus/cli/mixins/accounts_helper'
3
4
  require 'json'
4
5
 
5
6
  class Morpheus::Cli::RecentActivityCommand
6
7
  include Morpheus::Cli::CliCommand
7
-
8
- cli_command_name :'recent-activity'
9
- cli_command_hidden # remove once this is done
8
+ include Morpheus::Cli::AccountsHelper
10
9
 
11
- def initialize()
12
- @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
13
- end
10
+ set_command_name :'recent-activity'
11
+ set_command_hidden # remove once this is done
14
12
 
15
- def connect(opts)
16
- @access_token = Morpheus::Cli::Credentials.new(@appliance_name,@appliance_url).load_saved_credentials()
17
- if @access_token.empty?
18
- print_red_alert "Invalid Credentials. Unable to acquire access token. Please verify your credentials and try again."
19
- exit 1
20
- end
21
- @api_client = Morpheus::APIClient.new(@access_token,nil,nil, @appliance_url)
22
- @dashboard_interface = @api_client.dashboard
23
- end
13
+ def initialize()
14
+ # @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
15
+ end
24
16
 
25
- def usage
26
- "Usage: morpheus recent-activity"
27
- end
17
+ def connect(opts)
18
+ @api_client = establish_remote_appliance_connection(opts)
19
+ @dashboard_interface = @api_client.dashboard
20
+ @accounts_interface = @api_client.accounts
21
+ end
28
22
 
29
- def handle(args)
30
- list(args)
31
- end
32
-
33
- def list(args)
34
- options = {}
35
- optparse = OptionParser.new do|opts|
36
- opts.banner = usage
37
- opts.on(nil,'--start', "Start timestamp. Default is 30 days ago.") do |val|
38
- options[:start_ts] = val
39
- end
40
- opts.on(nil,'--end', "End timestamp. Default is now.") do |val|
41
- options[:end_ts] = val
42
- end
43
- build_common_options(opts, options, [:list, :json])
44
- end
45
- optparse.parse(args)
23
+ def usage
24
+ "Usage: morpheus #{command_name}"
25
+ end
46
26
 
47
- connect(options)
48
- begin
49
-
50
- params = {}
51
- [:phrase, :offset, :max, :sort, :direction, :start, :end].each do |k|
52
- params[k] = options[k] unless options[k].nil?
53
- end
27
+ def handle(args)
28
+ list(args)
29
+ end
30
+ def list(args)
31
+ options = {}
32
+ optparse = OptionParser.new do|opts|
33
+ opts.banner = usage
34
+ opts.on('--start TIMESTAMP','--start TIMESTAMP', "Start timestamp. Default is 30 days ago.") do |val|
35
+ options[:start] = parse_time(val).iso8601
36
+ end
37
+ opts.on('--end TIMESTAMP','--end TIMESTAMP', "End timestamp. Default is now.") do |val|
38
+ options[:end] = parse_time(val).iso8601
39
+ end
40
+ build_common_options(opts, options, [:account, :list, :json, :dry_run])
41
+ end
42
+ optparse.parse!(args)
43
+ connect(options)
44
+ begin
45
+ account = find_account_from_options(options)
46
+ account_id = account ? account['id'] : nil
47
+ params = {}
48
+ [:phrase, :offset, :max, :sort, :direction, :start, :end].each do |k|
49
+ params[k] = options[k] unless options[k].nil?
50
+ end
51
+ if options[:dry_run]
52
+ print_dry_run @dashboard_interface.dry.recent_activity(account_id, params)
53
+ return
54
+ end
55
+ json_response = @dashboard_interface.recent_activity(account_id, params)
56
+ if options[:json]
57
+ print JSON.pretty_generate(json_response)
58
+ print "\n"
59
+ else
54
60
 
55
- json_response = @dashboard_interface.recent_activity(params)
56
-
57
- if options[:json]
58
- print JSON.pretty_generate(json_response)
59
- print "\n"
60
- else
61
-
61
+ # todo: impersonate command and show that info here
62
62
 
63
- # todo: impersonate command and show that info here
63
+ print "\n" ,cyan, bold, "Dashboard\n","==================", reset, "\n\n"
64
+ print cyan
65
+ print "\n"
66
+ puts "Coming soon.... see --json"
67
+ print "\n"
64
68
 
65
- print "\n" ,cyan, bold, "Dashboard\n","==================", reset, "\n\n"
66
- print cyan
67
-
68
- print "\n"
69
- puts "Coming soon.... see --json"
70
- print "\n"
69
+ print reset,"\n"
71
70
 
72
- print reset,"\n"
73
-
74
- end
75
- rescue RestClient::Exception => e
76
- print_rest_exception(e, options)
77
- exit 1
78
- end
79
- end
80
-
71
+ end
72
+ rescue RestClient::Exception => e
73
+ print_rest_exception(e, options)
74
+ exit 1
75
+ end
76
+ end
81
77
 
82
78
  end
@@ -1,3 +1,4 @@
1
+ require 'fileutils'
1
2
  require 'yaml'
2
3
  require 'io/console'
3
4
  require 'rest_client'
@@ -6,203 +7,449 @@ require 'morpheus/cli/cli_command'
6
7
 
7
8
 
8
9
  class Morpheus::Cli::Remote
9
- include Morpheus::Cli::CliCommand
10
-
11
- def initialize()
12
- @appliances = ::Morpheus::Cli::Remote.load_appliance_file
13
- end
14
-
15
- def handle(args)
16
- if args.empty?
17
- puts "\nUsage: morpheus remote [list,add,remove,use] [name] [host]\n\n"
18
- return
19
- end
20
-
21
- case args[0]
22
- when 'list'
23
- list(args[1..-1])
24
- when 'add'
25
- add(args[1..-1])
26
- when 'remove'
27
- remove(args[1..-1])
28
- when 'use'
29
- use(args[1..-1])
30
- else
31
- puts "\nUsage: morpheus remote [list,add,remove,use] [name] [host]\n\n"
32
- end
33
- end
34
-
35
- def list(args)
36
- options = {}
37
- optparse = OptionParser.new do|opts|
38
- opts.banner = "Usage: morpheus remote list"
39
- build_common_options(opts, options, [])
40
- end
41
- optparse.parse(args)
42
-
43
- print "\n" ,cyan, bold, "Morpheus Appliances\n","==================", reset, "\n\n"
44
- # print red, bold, "red bold", reset, "\n"
45
- if @appliances == nil || @appliances.empty?
46
- puts yellow,"No remote appliances configured.",reset
47
- else
48
- rows = @appliances.collect do |app_name, v|
49
- {
50
- active: (v[:active] ? "=>" : ""),
51
- name: app_name,
52
- host: v[:host]
53
- }
54
- end
55
- print cyan
56
- tp rows, {:active => {:display_name => ""}}, {:name => {:width => 16}}, {:host => {:width => 40}}
57
- print reset
58
-
59
- # @appliances.each do |app_name, v|
60
- # print cyan
61
- # if v[:active] == true
62
- # print bold, "=> #{app_name}\t#{v[:host]}",reset,"\n"
63
- # else
64
- # print "= #{app_name}\t#{v[:host]}",reset,"\n"
65
- # end
66
- # end
67
-
68
- print "\n\n# => - current\n\n"
69
- end
70
- end
71
-
72
- def add(args)
73
- options = {}
74
- optparse = OptionParser.new do|opts|
75
- opts.banner = "Usage: morpheus remote add [name] [host] [--default]"
76
- build_common_options(opts, options, [])
77
- opts.on( '-d', '--default', "Make this the default remote appliance" ) do
78
- options[:default] = true
79
- end
80
- end
81
- optparse.parse(args)
82
- if args.count < 2
83
- puts "\n#{optparse.banner}\n\n"
84
- return
85
- end
86
-
87
- name = args[0].to_sym
88
- if @appliances[name] != nil
89
- print red, "Remote appliance already configured for #{args[0]}", reset, "\n"
90
- else
91
- @appliances[name] = {
92
- host: args[1],
93
- active: false
94
- }
95
- if options[:default] == true
96
- set_active_appliance name
97
- end
98
- end
99
- ::Morpheus::Cli::Remote.save_appliances(@appliances)
100
- list([])
101
- end
102
-
103
- def remove(args)
104
- options = {}
105
- optparse = OptionParser.new do|opts|
106
- opts.banner = "Usage: morpheus remote remove [name]"
107
- build_common_options(opts, options, [])
108
- opts.on( '-d', '--default', "Make this the default remote appliance" ) do
109
- options[:default] = true
110
- end
111
- end
112
- optparse.parse(args)
113
- if args.empty?
114
- puts "\n#{optparse.banner}\n\n"
115
- return
116
- end
117
-
118
- name = args[0].to_sym
119
- if @appliances[name] == nil
120
- print red, "Remote appliance not configured for #{args[0]}", reset, "\n"
121
- else
122
- active = false
123
- if @appliances[name][:active]
124
- active = true
125
- end
126
- @appliances.delete(name)
127
- if active && !@appliances.empty?
128
- @appliances[@appliances.keys.first][:active] = true
129
- end
130
- end
131
- ::Morpheus::Cli::Remote.save_appliances(@appliances)
132
- list([])
133
- end
134
-
135
- def use(args)
136
- options = {}
137
- optparse = OptionParser.new do|opts|
138
- opts.banner = "Usage: morpheus remote use [name]"
139
- build_common_options(opts, options, [])
140
- opts.on( '-d', '--default', "Make this the default remote appliance. This does the same thing as remote use." ) do
141
- options[:default] = true
142
- end
143
- end
144
- optparse.parse(args)
145
- if args.empty?
146
- puts "\n#{optparse.banner}\n\n"
147
- return
148
- end
149
-
150
- name = args[0].to_sym
151
- if @appliances[name] == nil
152
- print red, "Remote appliance not configured for #{args[0]}", reset, "\n"
153
- else
154
- set_active_appliance name
155
- end
156
- ::Morpheus::Cli::Remote.save_appliances(@appliances)
157
- list([])
158
- @@appliance = nil
159
- end
160
-
161
- def set_active_appliance(name)
162
- @appliances.each do |k,v|
163
- if k == name
164
- v[:active] = true
165
- else
166
- v[:active] = false
167
- end
168
- end
169
- end
170
-
171
- # Provides the current active appliance url information
172
- def self.active_appliance
173
- if !defined?(@@appliance) || @@appliance.nil?
174
- @@appliance = load_appliance_file.select { |k,v| v[:active] == true}
175
- end
176
- return @@appliance.keys[0], @@appliance[@@appliance.keys[0]][:host]
177
- end
178
-
179
-
180
-
181
- def self.load_appliance_file
182
- remote_file = appliances_file_path
183
- if File.exist? remote_file
184
- return YAML.load_file(remote_file)
185
- else
186
- return {}
187
- # return {
188
- # morpheus: {
189
- # host: 'https://api.gomorpheus.com',
190
- # active: true
191
- # }
192
- # }
193
- end
194
- end
195
-
196
- def self.appliances_file_path
197
- home_dir = Dir.home
198
- morpheus_dir = File.join(home_dir,".morpheus")
199
- if !Dir.exist?(morpheus_dir)
200
- Dir.mkdir(morpheus_dir)
201
- end
202
- return File.join(morpheus_dir,"appliances")
203
- end
204
-
205
- def self.save_appliances(appliance_map)
206
- File.open(appliances_file_path, 'w') {|f| f.write appliance_map.to_yaml } #Store
207
- end
10
+ include Morpheus::Cli::CliCommand
11
+
12
+ register_subcommands :list, :add, :remove, :use, :unuse, {:current => :print_current}, :setup
13
+ set_default_subcommand :list
14
+
15
+ def initialize()
16
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
17
+ end
18
+
19
+ def handle(args)
20
+ if args.count == 0
21
+ list(args)
22
+ else
23
+ handle_subcommand(args)
24
+ end
25
+ end
26
+
27
+ def list(args)
28
+ options = {}
29
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
30
+ opts.banner = subcommand_usage()
31
+ build_common_options(opts, options, [])
32
+ opts.footer = "This outputs a list of the remote appliances.\n" +
33
+ "It also displays the current active appliance.\n" +
34
+ "The shortcut `remote` can be used instead of `remote list`."
35
+ end
36
+ optparse.parse!(args)
37
+ @appliances = ::Morpheus::Cli::Remote.appliances
38
+ if @appliances == nil || @appliances.empty?
39
+ print yellow,"No remote appliances configured, see `remote add`",reset,"\n"
40
+ else
41
+ rows = @appliances.collect do |app_name, v|
42
+ {
43
+ active: (v[:active] ? "=>" : ""),
44
+ name: app_name,
45
+ host: v[:host]
46
+ }
47
+ end
48
+ print "\n" ,cyan, bold, "Morpheus Appliances\n","==================", reset, "\n\n"
49
+ print cyan
50
+ tp rows, {:active => {:display_name => ""}}, {:name => {:width => 16}}, {:host => {:width => 40}}
51
+ print reset
52
+ if @appliance_name
53
+ #unless @appliances.keys.size == 1
54
+ print cyan, "\n# => Currently using #{@appliance_name}\n", reset
55
+ #end
56
+ else
57
+ print "\n# => No active remote appliance, see `remote use`\n", reset
58
+ end
59
+ print "\n" # meh
60
+ end
61
+ end
62
+
63
+ def add(args)
64
+ options = {}
65
+ use_it = false
66
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
67
+ opts.banner = subcommand_usage("[name] [url]")
68
+ build_common_options(opts, options, [])
69
+ opts.on( '--use', '--use', "Make this the current remote appliance" ) do
70
+ use_it = true
71
+ end
72
+ # let's free up the -d switch for global options, maybe?
73
+ opts.on( '-d', '--default', "Does the same thing as --use" ) do
74
+ use_it = true
75
+ end
76
+ # todo: use Morpheus::Cli::OptionParser < OptionParser
77
+ # opts.on('-h', '--help', "Prints this help" ) do
78
+ # hidden_switches = ["--default"]
79
+ # good_opts = opts.to_s.split("\n").delete_if { |line| hidden_switches.find {|it| line =~ /#{Regexp.escape(it)}/ } }.join("\n")
80
+ # puts good_opts
81
+ # exit
82
+ # end
83
+ opts.footer = "This will add a new appliance to your list.\n" +
84
+ "If it's first one, it will be made the current active appliance."
85
+ end
86
+ optparse.parse!(args)
87
+ if args.count < 2
88
+ puts optparse
89
+ exit 1
90
+ end
91
+
92
+ new_appliance_name = args[0].to_sym
93
+ url = args[1]
94
+ if url !~ /^https?\:\/\//
95
+ print red, "The specified appliance url is invalid: '#{args[1]}'", reset, "\n"
96
+ puts optparse
97
+ exit 1
98
+ end
99
+ # maybe a ping here would be cool
100
+ @appliances = ::Morpheus::Cli::Remote.appliances
101
+ if @appliances.keys.empty?
102
+ use_it = true
103
+ end
104
+ if @appliances[new_appliance_name] != nil
105
+ print red, "Remote appliance already configured with the name '#{args[0]}'", reset, "\n"
106
+ else
107
+ @appliances[new_appliance_name] = {
108
+ host: url,
109
+ active: use_it
110
+ }
111
+ ::Morpheus::Cli::Remote.save_appliances(@appliances)
112
+ if use_it
113
+ #Morpheus::Cli::Remote.set_active_appliance(new_appliance_name)
114
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
115
+ end
116
+ end
117
+ #list([])
118
+ end
119
+
120
+ def remove(args)
121
+ options = {}
122
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
123
+ opts.banner = subcommand_usage("[name]")
124
+ opts.on( '-d', '--default', "Make this the default remote appliance" ) do
125
+ options[:default] = true
126
+ end
127
+ opts.footer = "This will delete an appliance from your list."
128
+ build_common_options(opts, options, [:auto_confirm])
129
+ end
130
+ optparse.parse!(args)
131
+ if args.empty?
132
+ puts optparse
133
+ exit 1
134
+ end
135
+ @appliances = ::Morpheus::Cli::Remote.appliances
136
+ appliance_name = args[0].to_sym
137
+ if @appliances[appliance_name] == nil
138
+ print red, "Remote appliance not found by the name '#{args[0]}'", reset, "\n"
139
+ else
140
+ unless options[:yes] || ::Morpheus::Cli::OptionTypes::confirm("Are you sure you would like to remove this remote appliance '#{appliance_name}'?", options)
141
+ exit 1
142
+ end
143
+ @appliances.delete(appliance_name)
144
+ ::Morpheus::Cli::Remote.save_appliances(@appliances)
145
+ # todo: also delete credentials and groups[appliance_name]
146
+ ::Morpheus::Cli::Groups.clear_active_group(appliance_name) # rescue nil
147
+ # this should be a class method too
148
+ #::Morpheus::Cli::Credentials.clear_saved_credentials(appliance_name)
149
+ ::Morpheus::Cli::Credentials.new(appliance_name, nil).clear_saved_credentials(appliance_name) # rescue nil
150
+ #list([])
151
+ end
152
+ end
153
+
154
+ def use(args)
155
+ options = {}
156
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
157
+ opts.banner = subcommand_usage("[name]")
158
+ build_common_options(opts, options, [])
159
+ opts.footer = "This allows you to switch between your different appliances."
160
+ end
161
+ optparse.parse!(args)
162
+ if args.count < 1
163
+ puts optparse
164
+ exit 1
165
+ end
166
+ new_appliance_name = args[0].to_sym
167
+ @appliances = ::Morpheus::Cli::Remote.appliances
168
+ if @appliance_name && @appliance_name.to_s == new_appliance_name.to_s
169
+ print reset,"Already using the appliance '#{args[0]}'","\n",reset
170
+ else
171
+ if @appliances[new_appliance_name] == nil
172
+ print red, "Remote appliance not found by the name '#{args[0]}'", reset, "\n"
173
+ return false
174
+ else
175
+ Morpheus::Cli::Remote.set_active_appliance(new_appliance_name)
176
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
177
+ #print cyan,"Switched to using appliance #{args[0]}","\n",reset
178
+ #list([])
179
+ end
180
+ end
181
+ end
182
+
183
+ def unuse(args)
184
+ options = {}
185
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
186
+ opts.banner = subcommand_usage()
187
+ opts.footer = "" +
188
+ "This will switch to no active appliance.\n" +
189
+ "You will need to use an appliance again, or pass the --remote option to your commands..\n"
190
+ build_common_options(opts, options, [])
191
+ end
192
+ optparse.parse!(args)
193
+ @appliance_name, @appliance_url = Morpheus::Cli::Remote.active_appliance
194
+ if @appliance_name
195
+ Morpheus::Cli::Remote.clear_active_appliance()
196
+ @appliance_name, @appliance_url = nil, nil
197
+ return true
198
+ else
199
+ puts "You are not using any appliance"
200
+ return false
201
+ end
202
+ end
203
+
204
+ def print_current(args)
205
+ options = {}
206
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
207
+ opts.banner = subcommand_usage()
208
+ build_common_options(opts, options, [:json])
209
+ end
210
+ optparse.parse!(args)
211
+
212
+ if @appliance_name
213
+ print cyan, @appliance_name,"\n",reset
214
+ else
215
+ print yellow, "No active appliance, see `remote use`\n", reset
216
+ return false
217
+ end
218
+ end
219
+
220
+ # this is a wizard that walks through the /api/setup controller
221
+ # it only needs to be used once to initialize a new appliance
222
+ def setup(args)
223
+ options = {}
224
+ optparse = Morpheus::Cli::OptionParser.new do|opts|
225
+ opts.banner = subcommand_usage()
226
+ build_common_options(opts, options, [:options, :json, :dry_run])
227
+ opts.footer = "This can be used to initialize a new appliance.\n" +
228
+ "You will be prompted to create the master account.\n" +
229
+ "This is only available on a new, freshly installed, remote appliance."
230
+ end
231
+ optparse.parse!(args)
232
+
233
+ if !@appliance_name
234
+ print yellow, "No active appliance, see `remote use`\n", reset
235
+ return false
236
+ end
237
+
238
+ # this works without any authentication!
239
+ # it will allow anyone to use it, if there are no users/accounts in the system.
240
+ #@api_client = establish_remote_appliance_connection(options)
241
+ #@setup_interface = @api_client.setup
242
+ @setup_interface = Morpheus::SetupInterface.new(@appliance_url)
243
+ appliance_status_json = nil
244
+ begin
245
+ appliance_status_json = @setup_interface.get()
246
+ if appliance_status_json['success'] != true
247
+ print red, "Setup not available for appliance #{@appliance_name} - #{@appliance_url}.\n", reset
248
+ print red, "#{appliance_status_json['msg']}\n", reset
249
+ return false
250
+ end
251
+ rescue RestClient::Exception => e
252
+ print_rest_exception(e, options)
253
+ return false
254
+ end
255
+
256
+ payload = {}
257
+
258
+ if appliance_status_json['hubRegistrationEnabled']
259
+ link = File.join(@appliance_url, '/setup')
260
+ print red, "Sorry, setup with hub registration is not yet available.\n", reset
261
+ print "You can use the UI to setup your appliance.\n"
262
+ print "Go to #{link}\n", reset
263
+ # if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
264
+ # system "start #{link}"
265
+ # elsif RbConfig::CONFIG['host_os'] =~ /darwin/
266
+ # system "open #{link}"
267
+ # elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
268
+ # system "xdg-open #{link}"
269
+ # end
270
+ return false
271
+ else
272
+ print "\n" ,cyan, bold, "Morpheus Appliance Setup", "\n", "==================", reset, "\n\n"
273
+
274
+ puts "It looks like you're the first one here."
275
+ puts "Let's initialize your remote appliance at #{@appliance_url}"
276
+
277
+
278
+
279
+ # Master Account
280
+ print "\n" ,cyan, bold, "Create Master account", "\n", "==================", reset, "\n\n"
281
+ account_option_types = [
282
+ {'fieldName' => 'accountName', 'fieldLabel' => 'Master Account Name', 'type' => 'text', 'required' => true, 'displayOrder' => 1},
283
+ ]
284
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(account_option_types, options[:options])
285
+ payload.merge!(v_prompt)
286
+
287
+ # Master User
288
+ print "\n" ,cyan, bold, "Create Master User", "\n", "==================", reset, "\n\n"
289
+ user_option_types = [
290
+ {'fieldName' => 'firstName', 'fieldLabel' => 'First Name', 'type' => 'text', 'required' => false, 'displayOrder' => 1},
291
+ {'fieldName' => 'lastName', 'fieldLabel' => 'Last Name', 'type' => 'text', 'required' => false, 'displayOrder' => 2},
292
+ {'fieldName' => 'username', 'fieldLabel' => 'Username', 'type' => 'text', 'required' => true, 'displayOrder' => 3},
293
+ {'fieldName' => 'email', 'fieldLabel' => 'Email', 'type' => 'text', 'required' => true, 'displayOrder' => 4},
294
+ ]
295
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(user_option_types, options[:options])
296
+ payload.merge!(v_prompt)
297
+
298
+ # Password prompt with re-prompting if no match
299
+ password_option_types = [
300
+ {'fieldName' => 'password', 'fieldLabel' => 'Password', 'type' => 'password', 'required' => true, 'displayOrder' => 6},
301
+ {'fieldName' => 'passwordConfirmation', 'fieldLabel' => 'Confirm Password', 'type' => 'password', 'required' => true, 'displayOrder' => 7},
302
+ ]
303
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(password_option_types, options[:options])
304
+ while v_prompt['passwordConfirmation'] != v_prompt['password']
305
+ print red, "Password confirmation does not match. Re-enter your new password.", reset, "\n"
306
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(password_option_types, options[:options])
307
+ end
308
+ payload.merge!(v_prompt)
309
+
310
+ # Extra settings
311
+ print "\n" ,cyan, bold, "Initial Setup", "\n", "==================", reset, "\n\n"
312
+ extra_option_types = [
313
+ {'fieldName' => 'applianceName', 'fieldLabel' => 'Appliance Name', 'type' => 'text', 'required' => true, 'defaultValue' => nil},
314
+ {'fieldName' => 'applianceUrl', 'fieldLabel' => 'Appliance URL', 'type' => 'text', 'required' => true, 'defaultValue' => appliance_status_json['applianceUrl']},
315
+ {'fieldName' => 'backups', 'fieldLabel' => 'Enable Backups', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'off'},
316
+ {'fieldName' => 'monitoring', 'fieldLabel' => 'Enable Monitoring', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on'},
317
+ {'fieldName' => 'logs', 'fieldLabel' => 'Enable Logs', 'type' => 'checkbox', 'required' => false, 'defaultValue' => 'on'}
318
+ ]
319
+ v_prompt = Morpheus::Cli::OptionTypes.prompt(extra_option_types, options[:options])
320
+ payload.merge!(v_prompt)
321
+
322
+ begin
323
+ if options[:dry_run]
324
+ print_dry_run @setup_interface.dry.init(payload)
325
+ return
326
+ end
327
+ if !options[:json]
328
+ print "Initializing the appliance...\n"
329
+ end
330
+ json_response = @setup_interface.init(payload)
331
+ rescue RestClient::Exception => e
332
+ print_rest_exception(e, options)
333
+ return false
334
+ end
335
+
336
+ if options[:json]
337
+ print JSON.pretty_generate(json_response)
338
+ print "\n"
339
+ return
340
+ end
341
+ print "\n"
342
+ print cyan, "You have successfully setup the appliance.\n"
343
+ #print cyan, "You may now login with the command `login`.\n"
344
+ # uh, just use Credentials.login(username, password, {save: true})
345
+ cmd_res = Morpheus::Cli::Login.new.login(['--username', payload['username'], '--password', payload['password'], '-q'])
346
+ # print "\n"
347
+ print cyan, "You are now logged in as the System Admin #{payload['username']}.\n"
348
+ print reset
349
+ #print "\n"
350
+
351
+ if ::Morpheus::Cli::OptionTypes::confirm("Would you like to apply your License Key now?", options.merge({:default => true}))
352
+ cmd_res = Morpheus::Cli::License.new.apply([])
353
+ # license_is_valid = cmd_res != false
354
+ end
355
+
356
+ if ::Morpheus::Cli::OptionTypes::confirm("Do you want to create the first group now?", options.merge({:default => true}))
357
+ cmd_res = Morpheus::Cli::Groups.new.add(['--use'])
358
+
359
+ #print "\n"
360
+
361
+ # if cmd_res !=
362
+ if ::Morpheus::Cli::OptionTypes::confirm("Do you want to create the first cloud now?", options.merge({:default => true}))
363
+ cmd_res = Morpheus::Cli::Clouds.new.add([])
364
+ #print "\n"
365
+ end
366
+ # end
367
+ end
368
+ print "\n",reset
369
+
370
+ end
371
+ end
372
+
373
+ class << self
374
+ include Term::ANSIColor
375
+
376
+ # for caching the the contents of YAML file $home/appliances
377
+ # it is structured like :appliance_name => {:host => "htt[://api.gomorpheus.com", :active => true}
378
+ # not named @@appliances to avoid confusion with the instance variable . This is also a command class...
379
+ @@appliance_config = nil
380
+ #@@current_appliance = nil
381
+
382
+
383
+
384
+ def appliances
385
+ self.appliance_config
386
+ end
387
+
388
+ def appliance_config
389
+ @@appliance_config ||= load_appliance_file || {}
390
+ end
391
+
392
+ # Returns two things, the remote appliance name and url
393
+ def active_appliance
394
+ if self.appliances.empty?
395
+ return nil, nil
396
+ end
397
+ app_name, app_map = self.appliances.find {|k,v| v[:active] == true }
398
+ if app_name
399
+ return app_name, app_map[:host]
400
+ else
401
+ return app_name, nil
402
+ end
403
+ end
404
+
405
+ def set_active_appliance(name)
406
+ new_appliances = self.appliances
407
+ new_appliances.each do |k,v|
408
+ is_match = (name ? (k == name.to_sym) : false)
409
+ if is_match
410
+ v[:active] = true
411
+ else
412
+ v[:active] = false
413
+ end
414
+ end
415
+ save_appliances(new_appliances)
416
+ end
417
+
418
+ def clear_active_appliance
419
+ new_appliances = self.appliances
420
+ new_appliances.each do |k,v|
421
+ v[:active] = false
422
+ end
423
+ save_appliances(new_appliances)
424
+ end
425
+
426
+ def load_appliance_file
427
+ fn = appliances_file_path
428
+ if File.exist? fn
429
+ print "#{dark} #=> loading appliances file #{fn}#{reset}\n" if Morpheus::Logging.debug?
430
+ return YAML.load_file(fn)
431
+ else
432
+ return {}
433
+ # return {
434
+ # morpheus: {
435
+ # host: 'https://api.gomorpheus.com',
436
+ # active: true
437
+ # }
438
+ # }
439
+ end
440
+ end
441
+
442
+ def appliances_file_path
443
+ File.join(Morpheus::Cli.home_directory,"appliances")
444
+ end
445
+
446
+ def save_appliances(new_config)
447
+ File.open(appliances_file_path, 'w') {|f| f.write new_config.to_yaml } #Store
448
+ FileUtils.chmod(0600, appliances_file_path)
449
+ #@@appliance_config = load_appliance_file
450
+ @@appliance_config = new_config
451
+ end
452
+
453
+ end
454
+
208
455
  end