morpheus-cli 2.9.4 → 2.10.0
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/lib/morpheus/api/apps_interface.rb +21 -17
- data/lib/morpheus/api/instances_interface.rb +10 -0
- data/lib/morpheus/cli/accounts.rb +0 -1
- data/lib/morpheus/cli/apps.rb +462 -320
- data/lib/morpheus/cli/dashboard_command.rb +0 -1
- data/lib/morpheus/cli/deploys.rb +0 -2
- data/lib/morpheus/cli/hosts.rb +124 -135
- data/lib/morpheus/cli/instance_types.rb +0 -2
- data/lib/morpheus/cli/instances.rb +204 -197
- data/lib/morpheus/cli/mixins/print_helper.rb +14 -0
- data/lib/morpheus/cli/mixins/provisioning_helper.rb +246 -0
- data/lib/morpheus/cli/recent_activity_command.rb +0 -1
- data/lib/morpheus/cli/users.rb +0 -1
- data/lib/morpheus/cli/version.rb +1 -1
- data/lib/morpheus/cli/whoami.rb +0 -1
- metadata +2 -2
@@ -72,6 +72,20 @@ module Morpheus::Cli::PrintHelper
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
def print_dry_run(request, payload)
|
76
|
+
print "\n" ,cyan, bold, "DRY RUN\n","==================", "\n\n", reset
|
77
|
+
print cyan
|
78
|
+
print "Request: ", "\n"
|
79
|
+
print reset
|
80
|
+
print request.to_s, "\n\n"
|
81
|
+
print cyan
|
82
|
+
print "JSON: ", "\n"
|
83
|
+
print reset
|
84
|
+
print JSON.pretty_generate(payload)
|
85
|
+
print "\n"
|
86
|
+
print reset
|
87
|
+
end
|
88
|
+
|
75
89
|
def required_blue_prompt
|
76
90
|
"#{cyan}|#{reset}"
|
77
91
|
end
|
@@ -8,6 +8,248 @@ module Morpheus::Cli::ProvisioningHelper
|
|
8
8
|
klass.send :include, Morpheus::Cli::PrintHelper
|
9
9
|
end
|
10
10
|
|
11
|
+
def get_available_groups(refresh=false)
|
12
|
+
if !@available_groups || refresh
|
13
|
+
option_results = @options_interface.options_for_source('groups',{})
|
14
|
+
@available_groups = option_results['data'].collect {|it|
|
15
|
+
{"id" => it["value"], "name" => it["name"], "value" => it["value"]}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
return @available_groups
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_available_clouds(group_id, refresh=false)
|
22
|
+
group = find_group_by_id(group_id)
|
23
|
+
if !group
|
24
|
+
return []
|
25
|
+
end
|
26
|
+
if !group["clouds"] || refresh
|
27
|
+
option_results = @options_interface.options_for_source('clouds', {groupId: group_id})
|
28
|
+
group["clouds"] = option_results['data'].collect {|it|
|
29
|
+
{"id" => it["value"], "name" => it["name"], "value" => it["value"], "zoneTypeId" => it["zoneTypeId"]}
|
30
|
+
}
|
31
|
+
end
|
32
|
+
return group["clouds"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_group_by_id(val)
|
36
|
+
groups = get_available_groups()
|
37
|
+
group = groups.find {|it| it["id"].to_s == val.to_s }
|
38
|
+
if !group
|
39
|
+
print_red_alert "Group not found by id #{val}"
|
40
|
+
exit 1
|
41
|
+
end
|
42
|
+
return group
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_group_by_name(val)
|
46
|
+
groups = get_available_groups()
|
47
|
+
group = groups.find {|it| it["name"].to_s.downcase == val.to_s.downcase }
|
48
|
+
if !group
|
49
|
+
print_red_alert "Group not found by name #{val}"
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
return group
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_group_from_options(options)
|
56
|
+
group = nil
|
57
|
+
if options[:group]
|
58
|
+
group = options[:group]
|
59
|
+
elsif options[:group_name]
|
60
|
+
group = find_group_by_name(options[:group_name])
|
61
|
+
elsif options[:group_id]
|
62
|
+
group = find_group_by_id(options[:group_id])
|
63
|
+
end
|
64
|
+
return group
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_cloud_by_id(group_id, val)
|
68
|
+
clouds = get_available_clouds(group_id)
|
69
|
+
cloud = clouds.find {|it| it["id"].to_s == val.to_s }
|
70
|
+
if !cloud
|
71
|
+
print_red_alert "Cloud not found by id #{val}"
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
return cloud
|
75
|
+
end
|
76
|
+
|
77
|
+
def find_cloud_by_name(group_id, val)
|
78
|
+
clouds = get_available_clouds(group_id)
|
79
|
+
cloud = clouds.find {|it| it["name"].to_s.downcase == val.to_s.downcase }
|
80
|
+
if !cloud
|
81
|
+
print_red_alert "Cloud not found by name #{val}"
|
82
|
+
exit 1
|
83
|
+
end
|
84
|
+
return cloud
|
85
|
+
end
|
86
|
+
|
87
|
+
def find_cloud_from_options(group_id, options)
|
88
|
+
cloud = nil
|
89
|
+
if options[:cloud]
|
90
|
+
cloud = options[:cloud]
|
91
|
+
elsif options[:cloud_name]
|
92
|
+
cloud = find_cloud_by_name(group_id, options[:cloud_name])
|
93
|
+
elsif options[:cloud_id]
|
94
|
+
cloud = find_cloud_by_id(group_id, options[:cloud_id])
|
95
|
+
end
|
96
|
+
return cloud
|
97
|
+
end
|
98
|
+
|
99
|
+
def find_instance_type_by_code(code)
|
100
|
+
results = @instance_types_interface.get({code: code})
|
101
|
+
if results['instanceTypes'].empty?
|
102
|
+
print_red_alert "Instance Type not found by code #{code}"
|
103
|
+
exit 1
|
104
|
+
end
|
105
|
+
return results['instanceTypes'][0]
|
106
|
+
end
|
107
|
+
|
108
|
+
# prompts user for all the configuartion options for a particular instance
|
109
|
+
# returns payload of data for a new instance
|
110
|
+
def prompt_new_instance(options={})
|
111
|
+
|
112
|
+
# Group
|
113
|
+
group_id = nil
|
114
|
+
group = find_group_from_options(options)
|
115
|
+
if group
|
116
|
+
group_id = group["id"]
|
117
|
+
else
|
118
|
+
# print_red_alert "Group not found or specified!"
|
119
|
+
# exit 1
|
120
|
+
group_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'group', 'type' => 'select', 'fieldLabel' => 'Group', 'selectOptions' => get_available_groups(), 'required' => true, 'description' => 'Select Group.'}],options[:options],@api_client,{})
|
121
|
+
group_id = cloud_prompt['group']
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
# Cloud
|
126
|
+
cloud_id = nil
|
127
|
+
cloud = find_cloud_from_options(group_id, options)
|
128
|
+
if cloud
|
129
|
+
cloud_id = cloud["id"]
|
130
|
+
else
|
131
|
+
# print_red_alert "Cloud not specified!"
|
132
|
+
# exit 1
|
133
|
+
cloud_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'cloud', 'type' => 'select', 'fieldLabel' => 'Cloud', 'selectOptions' => get_available_clouds(group_id), 'required' => true, 'description' => 'Select Cloud.'}],options[:options],@api_client,{groupId: group_id})
|
134
|
+
cloud_id = cloud_prompt['cloud']
|
135
|
+
end
|
136
|
+
|
137
|
+
# Instance Type
|
138
|
+
instance_type_code = nil
|
139
|
+
if options[:instance_type_code]
|
140
|
+
instance_type_code = options[:instance_type_code]
|
141
|
+
else
|
142
|
+
instance_type_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'type', 'type' => 'select', 'fieldLabel' => 'Type', 'optionSource' => 'instanceTypes', 'required' => true, 'description' => 'Select Instance Type.'}],options[:options],@api_client,{groupId: group_id})
|
143
|
+
instance_type_code = instance_type_prompt['type']
|
144
|
+
end
|
145
|
+
instance_type = find_instance_type_by_code(instance_type_code)
|
146
|
+
|
147
|
+
# Instance Name
|
148
|
+
|
149
|
+
instance_name = nil
|
150
|
+
if options[:instance_name]
|
151
|
+
instance_name = options[:instance_name]
|
152
|
+
else
|
153
|
+
name_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'name', 'fieldLabel' => 'Instance Name', 'type' => 'text', 'required' => options[:name_required]}], options[:options])
|
154
|
+
instance_name = name_prompt['name'] || ''
|
155
|
+
end
|
156
|
+
|
157
|
+
payload = {
|
158
|
+
:zoneId => cloud_id,
|
159
|
+
:instance => {
|
160
|
+
:name => instance_name,
|
161
|
+
:site => {
|
162
|
+
:id => group_id
|
163
|
+
},
|
164
|
+
:instanceType => {
|
165
|
+
:code => instance_type_code
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
# Description
|
171
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'description', 'fieldLabel' => 'Description', 'type' => 'text', 'required' => false}], options[:options])
|
172
|
+
payload[:instance][:description] = v_prompt['description'] if !v_prompt['description'].empty?
|
173
|
+
|
174
|
+
# Environment
|
175
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'instanceContext', 'fieldLabel' => 'Environment', 'type' => 'select', 'required' => false, 'selectOptions' => instance_context_options()}], options[:options])
|
176
|
+
payload[:instance][:instanceContext] = v_prompt['instanceContext'] if !v_prompt['instanceContext'].empty?
|
177
|
+
|
178
|
+
# Tags
|
179
|
+
v_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'tags', 'fieldLabel' => 'Tags', 'type' => 'text', 'required' => false}], options[:options])
|
180
|
+
payload[:instance][:tags] = v_prompt['tags'].split(',').collect {|it| it.to_s.strip }.compact.uniq if !v_prompt['tags'].empty?
|
181
|
+
|
182
|
+
|
183
|
+
# Version and Layout
|
184
|
+
|
185
|
+
version_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'version', 'type' => 'select', 'fieldLabel' => 'Version', 'optionSource' => 'instanceVersions', 'required' => true, 'skipSingleOption' => true, 'description' => 'Select which version of the instance type to be provisioned.'}],options[:options],@api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id']})
|
186
|
+
layout_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'layout', 'type' => 'select', 'fieldLabel' => 'Layout', 'optionSource' => 'layoutsForCloud', 'required' => true, 'description' => 'Select which configuration of the instance type to be provisioned.'}],options[:options],@api_client,{groupId: group_id, cloudId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
|
187
|
+
layout_id = layout_prompt['layout']
|
188
|
+
layout = instance_type['instanceTypeLayouts'].find{ |lt| lt['id'] == layout_id.to_i}
|
189
|
+
payload[:instance][:layout] = {id: layout['id']}
|
190
|
+
|
191
|
+
# prompt for service plan
|
192
|
+
service_plans_json = @instances_interface.service_plans({zoneId: cloud_id, layoutId: layout_id})
|
193
|
+
service_plans = service_plans_json["plans"]
|
194
|
+
service_plans_dropdown = service_plans.collect {|sp| {'name' => sp["name"], 'value' => sp["id"]} } # already sorted
|
195
|
+
plan_prompt = Morpheus::Cli::OptionTypes.prompt([{'fieldName' => 'servicePlan', 'type' => 'select', 'fieldLabel' => 'Plan', 'selectOptions' => service_plans_dropdown, 'required' => true, 'description' => 'Choose the appropriately sized plan for this instance'}],options[:options])
|
196
|
+
service_plan = service_plans.find {|sp| sp["id"] == plan_prompt['servicePlan'].to_i }
|
197
|
+
# todo: pick one of these three, let's go with the last one...
|
198
|
+
payload[:servicePlan] = service_plan["id"] # pre-2.10 appliances
|
199
|
+
payload[:instance][:plan] = {id: service_plan["id"]}
|
200
|
+
|
201
|
+
# prompt for volumes
|
202
|
+
volumes = prompt_volumes(service_plan, options, @api_client, {})
|
203
|
+
if !volumes.empty?
|
204
|
+
payload[:volumes] = volumes
|
205
|
+
end
|
206
|
+
|
207
|
+
if layout["provisionType"] && layout["provisionType"]["id"] && layout["provisionType"]["hasNetworks"]
|
208
|
+
# prompt for network interfaces (if supported)
|
209
|
+
begin
|
210
|
+
network_interfaces = prompt_network_interfaces(cloud_id, layout["provisionType"]["id"], options, @api_client)
|
211
|
+
if !network_interfaces.empty?
|
212
|
+
payload[:networkInterfaces] = network_interfaces
|
213
|
+
end
|
214
|
+
rescue RestClient::Exception => e
|
215
|
+
print_yellow_warning "Unable to load network options. Proceeding..."
|
216
|
+
print_rest_exception(e, options) if Morpheus::Logging.print_stacktrace?
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
type_payload = {}
|
222
|
+
if !layout['optionTypes'].nil? && !layout['optionTypes'].empty?
|
223
|
+
type_payload = Morpheus::Cli::OptionTypes.prompt(layout['optionTypes'],options[:options],@api_client,{groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
|
224
|
+
elsif !instance_type['optionTypes'].nil? && !instance_type['optionTypes'].empty?
|
225
|
+
type_payload = Morpheus::Cli::OptionTypes.prompt(instance_type['optionTypes'],options[:options],@api_client,{groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
|
226
|
+
end
|
227
|
+
if !type_payload['config'].nil?
|
228
|
+
payload.merge!(type_payload['config'])
|
229
|
+
end
|
230
|
+
|
231
|
+
provision_payload = {}
|
232
|
+
if !layout['provisionType'].nil? && !layout['provisionType']['optionTypes'].nil? && !layout['provisionType']['optionTypes'].empty?
|
233
|
+
instance_type_option_types = layout['provisionType']['optionTypes']
|
234
|
+
# remove volume options if volumes were configured
|
235
|
+
if !payload[:volumes].empty?
|
236
|
+
instance_type_option_types = reject_volume_option_types(instance_type_option_types)
|
237
|
+
end
|
238
|
+
# remove networkId option if networks were configured above
|
239
|
+
if !payload[:networkInterfaces].empty?
|
240
|
+
instance_type_option_types = reject_networking_option_types(instance_type_option_types)
|
241
|
+
end
|
242
|
+
provision_payload = Morpheus::Cli::OptionTypes.prompt(instance_type_option_types,options[:options],@api_client,{groupId: group_id, cloudId: cloud_id, zoneId: cloud_id, instanceTypeId: instance_type['id'], version: version_prompt['version']})
|
243
|
+
end
|
244
|
+
|
245
|
+
payload[:config] = provision_payload['config'] || {}
|
246
|
+
if provision_payload['server']
|
247
|
+
payload[:server] = provision_payload['server'] || {}
|
248
|
+
end
|
249
|
+
|
250
|
+
return payload
|
251
|
+
end
|
252
|
+
|
11
253
|
# This recreates the behavior of multi_disk.js
|
12
254
|
# returns array of volumes based on service plan options (plan_info)
|
13
255
|
def prompt_volumes(plan_info, options={}, api_client=nil, api_params={})
|
@@ -616,4 +858,8 @@ module Morpheus::Cli::ProvisioningHelper
|
|
616
858
|
}
|
617
859
|
end
|
618
860
|
|
861
|
+
def instance_context_options
|
862
|
+
[{'name' => 'Dev', 'value' => 'dev'}, {'name' => 'Test', 'value' => 'qa'}, {'name' => 'Staging', 'value' => 'staging'}, {'name' => 'Production', 'value' => 'production'}]
|
863
|
+
end
|
864
|
+
|
619
865
|
end
|
data/lib/morpheus/cli/users.rb
CHANGED
data/lib/morpheus/cli/version.rb
CHANGED
data/lib/morpheus/cli/whoami.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morpheus-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Estes
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-02-
|
13
|
+
date: 2017-02-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|