morpheus-cli 2.10.0 → 2.10.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.
- checksums.yaml +4 -4
- data/bin/morpheus +27 -32
- data/lib/morpheus/api/accounts_interface.rb +36 -47
- data/lib/morpheus/api/api_client.rb +141 -110
- data/lib/morpheus/api/app_templates_interface.rb +56 -72
- data/lib/morpheus/api/apps_interface.rb +111 -132
- data/lib/morpheus/api/auth_interface.rb +30 -0
- data/lib/morpheus/api/clouds_interface.rb +71 -76
- data/lib/morpheus/api/custom_instance_types_interface.rb +21 -46
- data/lib/morpheus/api/dashboard_interface.rb +10 -17
- data/lib/morpheus/api/deploy_interface.rb +60 -72
- data/lib/morpheus/api/deployments_interface.rb +53 -71
- data/lib/morpheus/api/groups_interface.rb +55 -45
- data/lib/morpheus/api/instance_types_interface.rb +19 -23
- data/lib/morpheus/api/instances_interface.rb +179 -177
- data/lib/morpheus/api/key_pairs_interface.rb +11 -17
- data/lib/morpheus/api/license_interface.rb +18 -23
- data/lib/morpheus/api/load_balancers_interface.rb +54 -69
- data/lib/morpheus/api/logs_interface.rb +25 -29
- data/lib/morpheus/api/options_interface.rb +13 -17
- data/lib/morpheus/api/provision_types_interface.rb +19 -22
- data/lib/morpheus/api/roles_interface.rb +75 -94
- data/lib/morpheus/api/security_group_rules_interface.rb +28 -37
- data/lib/morpheus/api/security_groups_interface.rb +39 -51
- data/lib/morpheus/api/servers_interface.rb +113 -115
- data/lib/morpheus/api/setup_interface.rb +31 -0
- data/lib/morpheus/api/task_sets_interface.rb +36 -38
- data/lib/morpheus/api/tasks_interface.rb +56 -69
- data/lib/morpheus/api/users_interface.rb +67 -76
- data/lib/morpheus/api/virtual_images_interface.rb +61 -61
- data/lib/morpheus/api/whoami_interface.rb +12 -15
- data/lib/morpheus/cli.rb +71 -60
- data/lib/morpheus/cli/accounts.rb +254 -315
- data/lib/morpheus/cli/alias_command.rb +219 -0
- data/lib/morpheus/cli/app_templates.rb +264 -272
- data/lib/morpheus/cli/apps.rb +608 -671
- data/lib/morpheus/cli/cli_command.rb +259 -21
- data/lib/morpheus/cli/cli_registry.rb +99 -14
- data/lib/morpheus/cli/clouds.rb +599 -372
- data/lib/morpheus/cli/config_file.rb +126 -0
- data/lib/morpheus/cli/credentials.rb +141 -117
- data/lib/morpheus/cli/dashboard_command.rb +48 -56
- data/lib/morpheus/cli/deployments.rb +254 -268
- data/lib/morpheus/cli/deploys.rb +150 -142
- data/lib/morpheus/cli/error_handler.rb +38 -0
- data/lib/morpheus/cli/groups.rb +551 -179
- data/lib/morpheus/cli/hosts.rb +862 -617
- data/lib/morpheus/cli/instance_types.rb +103 -95
- data/lib/morpheus/cli/instances.rb +1335 -1009
- data/lib/morpheus/cli/key_pairs.rb +82 -90
- data/lib/morpheus/cli/library.rb +498 -499
- data/lib/morpheus/cli/license.rb +83 -101
- data/lib/morpheus/cli/load_balancers.rb +314 -300
- data/lib/morpheus/cli/login.rb +66 -44
- data/lib/morpheus/cli/logout.rb +47 -46
- data/lib/morpheus/cli/mixins/accounts_helper.rb +69 -31
- data/lib/morpheus/cli/mixins/infrastructure_helper.rb +106 -0
- data/lib/morpheus/cli/mixins/print_helper.rb +181 -17
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +535 -458
- data/lib/morpheus/cli/mixins/whoami_helper.rb +2 -2
- data/lib/morpheus/cli/option_parser.rb +35 -0
- data/lib/morpheus/cli/option_types.rb +232 -192
- data/lib/morpheus/cli/recent_activity_command.rb +61 -65
- data/lib/morpheus/cli/remote.rb +446 -199
- data/lib/morpheus/cli/roles.rb +884 -906
- data/lib/morpheus/cli/security_group_rules.rb +213 -203
- data/lib/morpheus/cli/security_groups.rb +237 -192
- data/lib/morpheus/cli/shell.rb +338 -231
- data/lib/morpheus/cli/tasks.rb +326 -308
- data/lib/morpheus/cli/users.rb +457 -462
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/version_command.rb +16 -18
- data/lib/morpheus/cli/virtual_images.rb +526 -345
- data/lib/morpheus/cli/whoami.rb +125 -111
- data/lib/morpheus/cli/workflows.rb +338 -185
- data/lib/morpheus/formatters.rb +8 -1
- data/lib/morpheus/logging.rb +1 -1
- data/lib/morpheus/rest_client.rb +17 -8
- metadata +9 -3
- 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
|
-
|
12
|
-
|
13
|
-
end
|
10
|
+
set_command_name :'recent-activity'
|
11
|
+
set_command_hidden # remove once this is done
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
66
|
-
print cyan
|
67
|
-
|
68
|
-
print "\n"
|
69
|
-
puts "Coming soon.... see --json"
|
70
|
-
print "\n"
|
69
|
+
print reset,"\n"
|
71
70
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
data/lib/morpheus/cli/remote.rb
CHANGED
@@ -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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|