MuranoCLI 2.2.4 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.agignore +3 -0
- data/.gitignore +18 -1
- data/.rubocop.yml +222 -0
- data/.trustme.sh +185 -0
- data/.trustme.vim +24 -0
- data/Gemfile +23 -4
- data/LICENSE.txt +1 -1
- data/MuranoCLI.gemspec +43 -8
- data/README.markdown +9 -11
- data/Rakefile +187 -143
- data/TODO.taskpaper +2 -2
- data/bin/murano +51 -52
- data/docs/basic_example.rst +436 -0
- data/docs/completions/murano_completion-bash +3484 -0
- data/docs/demo.md +32 -32
- data/docs/develop.rst +391 -0
- data/lib/MrMurano.rb +21 -7
- data/lib/MrMurano/Account.rb +159 -174
- data/lib/MrMurano/Business.rb +381 -0
- data/lib/MrMurano/Config-Migrate.rb +32 -26
- data/lib/MrMurano/Config.rb +407 -128
- data/lib/MrMurano/Content.rb +191 -0
- data/lib/MrMurano/Gateway.rb +489 -0
- data/lib/MrMurano/Keystore.rb +48 -0
- data/lib/MrMurano/Passwords.rb +103 -0
- data/lib/MrMurano/ProjectFile.rb +121 -79
- data/lib/MrMurano/ReCommander.rb +114 -10
- data/lib/MrMurano/Setting.rb +90 -0
- data/lib/MrMurano/Solution-ServiceConfig.rb +89 -45
- data/lib/MrMurano/Solution-Services.rb +461 -166
- data/lib/MrMurano/Solution-Users.rb +70 -31
- data/lib/MrMurano/Solution.rb +372 -13
- data/lib/MrMurano/SolutionId.rb +73 -0
- data/lib/MrMurano/SyncRoot.rb +137 -0
- data/lib/MrMurano/SyncUpDown.rb +594 -284
- data/lib/MrMurano/Webservice-Cors.rb +71 -0
- data/lib/MrMurano/Webservice-Endpoint.rb +234 -0
- data/lib/MrMurano/Webservice-File.rb +193 -0
- data/lib/MrMurano/Webservice.rb +51 -0
- data/lib/MrMurano/commands.rb +18 -15
- data/lib/MrMurano/commands/business.rb +300 -6
- data/lib/MrMurano/commands/completion-bash.erb +166 -0
- data/lib/MrMurano/commands/{zshcomplete.erb → completion-zsh.erb} +0 -0
- data/lib/MrMurano/commands/completion.rb +76 -39
- data/lib/MrMurano/commands/config.rb +108 -44
- data/lib/MrMurano/commands/content.rb +115 -72
- data/lib/MrMurano/commands/cors.rb +29 -14
- data/lib/MrMurano/commands/devices.rb +286 -0
- data/lib/MrMurano/commands/domain.rb +52 -12
- data/lib/MrMurano/commands/gb.rb +24 -9
- data/lib/MrMurano/commands/globals.rb +64 -0
- data/lib/MrMurano/commands/init.rb +377 -155
- data/lib/MrMurano/commands/keystore.rb +92 -82
- data/lib/MrMurano/commands/link.rb +300 -0
- data/lib/MrMurano/commands/login.rb +74 -11
- data/lib/MrMurano/commands/logs.rb +63 -32
- data/lib/MrMurano/commands/mock.rb +57 -29
- data/lib/MrMurano/commands/password.rb +57 -39
- data/lib/MrMurano/commands/postgresql.rb +127 -94
- data/lib/MrMurano/commands/settings.rb +203 -0
- data/lib/MrMurano/commands/show.rb +79 -38
- data/lib/MrMurano/commands/solution.rb +423 -5
- data/lib/MrMurano/commands/solution_picker.rb +547 -0
- data/lib/MrMurano/commands/status.rb +195 -61
- data/lib/MrMurano/commands/sync.rb +78 -39
- data/lib/MrMurano/commands/timeseries.rb +71 -55
- data/lib/MrMurano/commands/tsdb.rb +113 -87
- data/lib/MrMurano/commands/usage.rb +57 -15
- data/lib/MrMurano/hash.rb +100 -10
- data/lib/MrMurano/http.rb +187 -43
- data/lib/MrMurano/makePretty.rb +16 -14
- data/lib/MrMurano/optparse.rb +2178 -0
- data/lib/MrMurano/progress.rb +138 -0
- data/lib/MrMurano/schema/resource-v1.0.0.yaml +32 -0
- data/lib/MrMurano/template/projectFile.murano.erb +16 -13
- data/lib/MrMurano/verbosing.rb +166 -29
- data/lib/MrMurano/version.rb +30 -1
- data/spec/Account-Passwords_spec.rb +21 -4
- data/spec/Account_spec.rb +69 -146
- data/spec/Business_spec.rb +290 -0
- data/spec/ConfigFile_spec.rb +1 -0
- data/spec/ConfigMigrate_spec.rb +12 -8
- data/spec/Config_spec.rb +40 -34
- data/spec/Content_spec.rb +363 -0
- data/spec/GatewayBase_spec.rb +54 -0
- data/spec/GatewayDevice_spec.rb +321 -0
- data/spec/GatewayResource_spec.rb +266 -0
- data/spec/GatewaySettings_spec.rb +120 -0
- data/spec/Http_spec.rb +18 -8
- data/spec/Mock_spec.rb +2 -2
- data/spec/ProjectFile_spec.rb +25 -14
- data/spec/Setting_spec.rb +110 -0
- data/spec/Solution-ServiceConfig_spec.rb +44 -5
- data/spec/Solution-ServiceEventHandler_spec.rb +23 -14
- data/spec/Solution-ServiceModules_spec.rb +47 -37
- data/spec/Solution-UsersRoles_spec.rb +10 -8
- data/spec/Solution_spec.rb +17 -8
- data/spec/SyncRoot_spec.rb +46 -20
- data/spec/SyncUpDown_spec.rb +437 -201
- data/spec/Verbosing_spec.rb +12 -4
- data/spec/{Solution-Cors_spec.rb → Webservice-Cors_spec.rb} +23 -20
- data/spec/{Solution-Endpoint_spec.rb → Webservice-Endpoint_spec.rb} +43 -41
- data/spec/{Solution-File_spec.rb → Webservice-File_spec.rb} +44 -33
- data/spec/Webservice-Setting_spec.rb +89 -0
- data/spec/_workspace.rb +4 -4
- data/spec/cmd_business_spec.rb +9 -4
- data/spec/cmd_common.rb +44 -1
- data/spec/cmd_content_spec.rb +43 -17
- data/spec/cmd_cors_spec.rb +4 -4
- data/spec/cmd_device_spec.rb +61 -16
- data/spec/cmd_domain_spec.rb +29 -6
- data/spec/cmd_init_spec.rb +281 -126
- data/spec/cmd_keystore_spec.rb +3 -3
- data/spec/cmd_link_spec.rb +98 -0
- data/spec/cmd_password_spec.rb +1 -1
- data/spec/cmd_setting_application_spec.rb +260 -0
- data/spec/cmd_setting_product_spec.rb +220 -0
- data/spec/cmd_status_spec.rb +223 -114
- data/spec/cmd_syncdown_spec.rb +115 -35
- data/spec/cmd_syncup_spec.rb +68 -15
- data/spec/cmd_usage_spec.rb +35 -8
- data/spec/fixtures/dumped_config +6 -4
- data/spec/fixtures/gateway_resource_files/resources.notyaml +12 -0
- data/spec/fixtures/gateway_resource_files/resources.yaml +13 -0
- data/spec/fixtures/gateway_resource_files/resources_invalid.yaml +13 -0
- data/spec/fixtures/mrmuranorc_deleted_bob +0 -2
- data/spec/fixtures/product_spec_files/lightbulb.yaml +20 -13
- data/spec/fixtures/{syncable_content → syncable_conflict}/services/devdata.lua +1 -1
- data/spec/fixtures/{syncable_content → syncable_conflict}/services/timers.lua +0 -0
- data/spec/spec_helper.rb +5 -0
- metadata +262 -171
- data/bin/mr +0 -8
- data/lib/MrMurano/Product-1P-Device.rb +0 -145
- data/lib/MrMurano/Product-Resources.rb +0 -205
- data/lib/MrMurano/Product.rb +0 -358
- data/lib/MrMurano/Solution-Cors.rb +0 -47
- data/lib/MrMurano/Solution-Endpoint.rb +0 -191
- data/lib/MrMurano/Solution-File.rb +0 -166
- data/lib/MrMurano/commands/assign.rb +0 -57
- data/lib/MrMurano/commands/businessList.rb +0 -45
- data/lib/MrMurano/commands/product.rb +0 -14
- data/lib/MrMurano/commands/productCreate.rb +0 -39
- data/lib/MrMurano/commands/productDelete.rb +0 -33
- data/lib/MrMurano/commands/productDevice.rb +0 -87
- data/lib/MrMurano/commands/productDeviceIdCmds.rb +0 -89
- data/lib/MrMurano/commands/productList.rb +0 -45
- data/lib/MrMurano/commands/productWrite.rb +0 -27
- data/lib/MrMurano/commands/solutionCreate.rb +0 -41
- data/lib/MrMurano/commands/solutionDelete.rb +0 -34
- data/lib/MrMurano/commands/solutionList.rb +0 -45
- data/spec/ProductBase_spec.rb +0 -113
- data/spec/ProductContent_spec.rb +0 -162
- data/spec/ProductResources_spec.rb +0 -329
- data/spec/Product_1P_Device_spec.rb +0 -202
- data/spec/Product_1P_RPC_spec.rb +0 -175
- data/spec/Product_spec.rb +0 -153
- data/spec/Solution-ServiceDevice_spec.rb +0 -176
- data/spec/cmd_assign_spec.rb +0 -51
@@ -1,67 +1,105 @@
|
|
1
|
+
# Last Modified: 2017.08.16 /coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2016-2017 Exosite LLC.
|
5
|
+
# License: MIT. See LICENSE.txt.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
require 'MrMurano/verbosing'
|
9
|
+
require 'MrMurano/Business'
|
10
|
+
require 'MrMurano/ReCommander'
|
11
|
+
require 'MrMurano/Solution'
|
1
12
|
|
2
13
|
command 'show' do |c|
|
3
14
|
c.syntax = %(murano show)
|
4
15
|
c.summary = %(Show readable information about the current configuration)
|
5
|
-
c.description = %(
|
6
|
-
|
7
|
-
|
16
|
+
c.description = %(
|
17
|
+
Show readable information about the current configuration.
|
18
|
+
).strip
|
19
|
+
c.project_not_required = true
|
8
20
|
|
9
|
-
|
21
|
+
c.action do |args, _options|
|
22
|
+
if args.include?('help')
|
10
23
|
::Commander::UI.enable_paging
|
11
24
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
12
25
|
else
|
13
|
-
acc = MrMurano::Account.
|
26
|
+
acc = MrMurano::Account.instance
|
27
|
+
biz = MrMurano::Business.new
|
14
28
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
29
|
+
selected_business = nil
|
30
|
+
selected_business_id = $cfg['business.id']
|
31
|
+
unless selected_business_id.to_s.empty?
|
32
|
+
acc.businesses.each do |sol|
|
33
|
+
selected_business = sol if sol.bizid == selected_business_id
|
34
|
+
end
|
19
35
|
end
|
20
36
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
37
|
+
selected_application = nil
|
38
|
+
selected_application_id = $cfg['application.id']
|
39
|
+
unless selected_application_id.to_s.empty?
|
40
|
+
MrMurano::Verbose.whirly_start('Fetching Applications...')
|
41
|
+
biz.applications.each do |sol|
|
42
|
+
selected_application = sol if sol.apiId == selected_application_id
|
43
|
+
end
|
44
|
+
MrMurano::Verbose.whirly_stop
|
25
45
|
end
|
26
46
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
47
|
+
selected_product = nil
|
48
|
+
selected_product_id = $cfg['product.id']
|
49
|
+
unless selected_product_id.to_s.empty?
|
50
|
+
MrMurano::Verbose.whirly_start('Fetching Products...')
|
51
|
+
biz.products.each do |sol|
|
52
|
+
selected_product = sol if sol.apiId == selected_product_id
|
53
|
+
end
|
54
|
+
MrMurano::Verbose.whirly_stop
|
31
55
|
end
|
32
56
|
|
33
|
-
if $cfg['user.name']
|
57
|
+
if $cfg['user.name']
|
34
58
|
puts %(user: #{$cfg['user.name']})
|
35
59
|
else
|
36
60
|
puts 'no user selected'
|
37
61
|
end
|
38
62
|
|
39
|
-
if
|
40
|
-
puts %(business: #{
|
63
|
+
if selected_business
|
64
|
+
puts %(business: #{selected_business.name})
|
41
65
|
else
|
42
|
-
puts 'no business selected'
|
66
|
+
#puts 'no business selected'
|
67
|
+
MrMurano::Verbose.error MrMurano::Business.missing_business_id_msg
|
43
68
|
end
|
44
69
|
|
45
|
-
|
46
|
-
|
70
|
+
id_not_in_biz = false
|
71
|
+
|
72
|
+
# E.g., {:bizid=>"ABC", :type=>"application", :apiId=>"XXX", :sid=>"XXX",
|
73
|
+
# :name=>"ABC", :domain=>"ABC.apps.exosite.io" }
|
74
|
+
if selected_application
|
75
|
+
puts %(application: https://#{selected_application.domain})
|
76
|
+
elsif selected_application_id
|
77
|
+
#puts 'selected application not in business'
|
78
|
+
puts "application ID from config is not in business (#{selected_application_id})"
|
79
|
+
id_not_in_biz = true
|
80
|
+
elsif !selected_business
|
81
|
+
puts 'application ID depends on business ID'
|
47
82
|
else
|
48
|
-
|
49
|
-
|
50
|
-
else
|
51
|
-
puts 'no product selected'
|
52
|
-
end
|
83
|
+
#puts 'no application selected'
|
84
|
+
puts 'application ID not found in config'
|
53
85
|
end
|
54
86
|
|
55
|
-
|
56
|
-
|
87
|
+
# E.g., {:bizid=>"ABC", :type=>"product", :apiId=>"XXX", :sid=>"XXX",
|
88
|
+
# :name=>"ABC", :domain=>"ABC.m2.exosite.io" }
|
89
|
+
if selected_product
|
90
|
+
puts %(product: #{selected_product.name})
|
91
|
+
elsif selected_product_id
|
92
|
+
#puts 'selected product not in business'
|
93
|
+
puts "product ID from config is not in business (#{selected_product_id})"
|
94
|
+
id_not_in_biz = true
|
95
|
+
elsif !selected_business
|
96
|
+
puts 'product ID depends on business ID'
|
57
97
|
else
|
58
|
-
|
59
|
-
|
60
|
-
else
|
61
|
-
puts 'no solution selected'
|
62
|
-
end
|
98
|
+
#puts 'no product selected'
|
99
|
+
puts 'product ID not found in config'
|
63
100
|
end
|
64
101
|
|
102
|
+
MrMurano::SolutionBase.warn_configfile_env_maybe if id_not_in_biz
|
65
103
|
end
|
66
104
|
end
|
67
105
|
end
|
@@ -69,12 +107,15 @@ end
|
|
69
107
|
command 'show location' do |c|
|
70
108
|
c.syntax = %(murano show location)
|
71
109
|
c.summary = %(Show readable location information)
|
72
|
-
c.description = %(
|
110
|
+
c.description = %(
|
111
|
+
Show readable information about the current configuration.
|
112
|
+
).strip
|
113
|
+
c.project_not_required = true
|
73
114
|
|
74
|
-
c.action do |args,
|
115
|
+
c.action do |args, _options|
|
116
|
+
c.verify_arg_count!(args)
|
75
117
|
puts %(base: #{$cfg['location.base']})
|
76
118
|
$cfg['location'].each { |key, value| puts %(#{key}: #{$cfg['location.base']}/#{value}) }
|
77
119
|
end
|
78
120
|
end
|
79
121
|
|
80
|
-
# vim: set ai et sw=2 ts=2 :
|
@@ -1,14 +1,432 @@
|
|
1
|
+
# Last Modified: 2017.08.17 /coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2016-2017 Exosite LLC.
|
5
|
+
# License: MIT. See LICENSE.txt.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
require 'MrMurano/verbosing'
|
9
|
+
require 'MrMurano/Account'
|
10
|
+
require 'MrMurano/ReCommander'
|
1
11
|
require 'MrMurano/SubCmdGroupContext'
|
12
|
+
require 'MrMurano/commands/business'
|
13
|
+
require 'MrMurano/commands/solution_picker'
|
2
14
|
|
3
15
|
command :solution do |c|
|
4
|
-
c.syntax = %
|
5
|
-
c.summary = %
|
6
|
-
c.description = %
|
16
|
+
c.syntax = %(murano solution)
|
17
|
+
c.summary = %(About solution)
|
18
|
+
c.description = %(
|
19
|
+
Commands for working with Application and Product solutions.
|
20
|
+
).strip
|
21
|
+
c.project_not_required = true
|
7
22
|
|
8
|
-
c.action do |
|
23
|
+
c.action do |_args, _options|
|
9
24
|
::Commander::UI.enable_paging
|
10
25
|
say MrMurano::SubCmdGroupHelp.new(c).get_help
|
11
26
|
end
|
12
27
|
end
|
13
28
|
|
14
|
-
#
|
29
|
+
# *** Create solution.
|
30
|
+
# --------------------
|
31
|
+
|
32
|
+
command 'solution create' do |c|
|
33
|
+
c.syntax = %(murano solution create [--options] <solution-name>)
|
34
|
+
c.summary = %(Create a new solution)
|
35
|
+
c.description = %(
|
36
|
+
Create a new solution in the current business.
|
37
|
+
).strip
|
38
|
+
c.project_not_required = true
|
39
|
+
|
40
|
+
# Add flag: --type [application|product].
|
41
|
+
cmd_add_solntype_pickers(c, exclude_all: true)
|
42
|
+
|
43
|
+
c.option('--save', %(Save new solution ID to config))
|
44
|
+
|
45
|
+
c.action do |args, options|
|
46
|
+
c.verify_arg_count!(args, 1)
|
47
|
+
cmd_defaults_solntype_pickers(options, :application)
|
48
|
+
|
49
|
+
biz = MrMurano::Business.new
|
50
|
+
biz.must_business_id!
|
51
|
+
|
52
|
+
if args.count.zero?
|
53
|
+
sol = biz.solution_from_type!(options.type)
|
54
|
+
name = solution_ask_for_name(sol)
|
55
|
+
names = [name]
|
56
|
+
else
|
57
|
+
names = args
|
58
|
+
end
|
59
|
+
|
60
|
+
# MAYBE: Support making multiple solutions.
|
61
|
+
if names.length > 1
|
62
|
+
MrMurano::Verbose.error('Can only make one solution at a time')
|
63
|
+
exit 2
|
64
|
+
end
|
65
|
+
|
66
|
+
sol = biz.new_solution!(names.first, options.type)
|
67
|
+
|
68
|
+
if options.save
|
69
|
+
section = options.type.to_s
|
70
|
+
$cfg.set("#{section}.id", sol.sid)
|
71
|
+
$cfg.set("#{section}.name", sol.name)
|
72
|
+
end
|
73
|
+
|
74
|
+
biz.outf(sol.sid)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
alias_command 'create application', 'solution create', '--type', 'application'
|
78
|
+
alias_command 'create product', 'solution create', '--type', 'product'
|
79
|
+
alias_command 'application create', 'solution create', '--type', 'application'
|
80
|
+
alias_command 'product create', 'solution create', '--type', 'product'
|
81
|
+
|
82
|
+
# *** Delete solution(s).
|
83
|
+
# -----------------------
|
84
|
+
|
85
|
+
command 'solution delete' do |c|
|
86
|
+
c.syntax = %(murano solution delete [--options] [<name-or-ID,...>])
|
87
|
+
c.summary = %(Delete a solution)
|
88
|
+
c.description = %(
|
89
|
+
Delete a solution from the business.
|
90
|
+
).strip
|
91
|
+
c.project_not_required = true
|
92
|
+
|
93
|
+
# Add flag: --type [application|product|all].
|
94
|
+
cmd_add_solntype_pickers(c)
|
95
|
+
|
96
|
+
# Add --id and --name options.
|
97
|
+
cmd_options_add_id_and_name(c)
|
98
|
+
|
99
|
+
# Add soln pickers: --application* and --product*
|
100
|
+
cmd_option_application_pickers(c)
|
101
|
+
cmd_option_product_pickers(c)
|
102
|
+
|
103
|
+
c.option('--recursive', %(If a solution is not specified, find all solutions and prompt before deleting.))
|
104
|
+
c.option('-y', '--[no-]yes', %(Answer "yes" to all prompts and run non-interactively))
|
105
|
+
|
106
|
+
c.action do |args, options|
|
107
|
+
# SKIP: c.verify_arg_count!(args)
|
108
|
+
cmd_defaults_solntype_pickers(options)
|
109
|
+
cmd_defaults_id_and_name(options)
|
110
|
+
# Set all: true, so that cmd_solution_del_get_names_and_ids finds 'em all.
|
111
|
+
options.default(all: true)
|
112
|
+
|
113
|
+
biz = MrMurano::Business.new
|
114
|
+
biz.must_business_id!
|
115
|
+
|
116
|
+
nmorids = cmd_solution_del_get_names_and_ids!(biz, args, options)
|
117
|
+
|
118
|
+
n_deleted = 0
|
119
|
+
n_faulted = 0
|
120
|
+
|
121
|
+
nmorids.each do |name_or_id|
|
122
|
+
next unless biz.cmd_confirm_delete!(
|
123
|
+
name_or_id[0], options.yes, "Skipping #{name_or_id[0]}!"
|
124
|
+
) do |confirmed|
|
125
|
+
confirmed
|
126
|
+
end
|
127
|
+
m_deleted, m_faulted = solution_delete(
|
128
|
+
name_or_id[0], use_sol: name_or_id[2], type: options.type, yes: options.yes
|
129
|
+
)
|
130
|
+
n_deleted += m_deleted
|
131
|
+
n_faulted += m_faulted
|
132
|
+
end
|
133
|
+
# Print results if something happened and was recursive (otherwise
|
134
|
+
# behave like, say, /bin/rm, and just be silent on success).
|
135
|
+
solution_delete_report(n_deleted, n_faulted) if options.recursive
|
136
|
+
end
|
137
|
+
end
|
138
|
+
alias_command 'delete application', 'solution delete', '--type', 'application'
|
139
|
+
alias_command 'delete product', 'solution delete', '--type', 'product'
|
140
|
+
alias_command 'application delete', 'solution delete', '--type', 'application'
|
141
|
+
alias_command 'product delete', 'solution delete', '--type', 'product'
|
142
|
+
|
143
|
+
def cmd_solution_del_get_names_and_ids!(biz, args, options)
|
144
|
+
nmorids = []
|
145
|
+
if args.count.zero?
|
146
|
+
if any_solution_pickers!(options)
|
147
|
+
exit_cmd_not_recursive!(options)
|
148
|
+
elsif !options.recursive
|
149
|
+
MrMurano::Verbose.error(
|
150
|
+
'Please specify the name or ID of the solution to delete, or use --recursive.'
|
151
|
+
)
|
152
|
+
exit 1
|
153
|
+
end
|
154
|
+
else
|
155
|
+
exit_cmd_not_recursive!(options)
|
156
|
+
end
|
157
|
+
solz = must_fetch_solutions!(options, args, biz)
|
158
|
+
solz.each do |sol|
|
159
|
+
nmorids += [[sol.sid, "‘#{sol.name}’ <#{sol.sid}>", sol]]
|
160
|
+
end
|
161
|
+
nmorids
|
162
|
+
end
|
163
|
+
|
164
|
+
def exit_cmd_not_recursive!(options)
|
165
|
+
return unless options.recursive
|
166
|
+
MrMurano::Verbose.error(
|
167
|
+
'The --recursive option does not apply when specifing solution IDs or names.'
|
168
|
+
)
|
169
|
+
exit 1
|
170
|
+
end
|
171
|
+
|
172
|
+
# The `murano solutions expunge -y` command simplifies what be done
|
173
|
+
# craftily other ways, e.g.,:
|
174
|
+
#
|
175
|
+
# $ for pid in $(murano product list --idonly) ; do murano product delete $pid ; done
|
176
|
+
command 'solutions expunge' do |c|
|
177
|
+
c.syntax = %(murano solution expunge)
|
178
|
+
c.summary = %(Delete all solutions)
|
179
|
+
c.description = %(
|
180
|
+
Delete all solutions in business.
|
181
|
+
).strip
|
182
|
+
c.project_not_required = true
|
183
|
+
|
184
|
+
c.option('--[no-]all', 'Delete all Solutions in Business, not just Project')
|
185
|
+
c.option('-y', '--[no-]yes', %(Answer "yes" to all prompts and run non-interactively))
|
186
|
+
|
187
|
+
c.action do |args, options|
|
188
|
+
c.verify_arg_count!(args)
|
189
|
+
name_or_id = '*'
|
190
|
+
n_deleted, n_faulted = solution_delete(name_or_id, yes: options.yes)
|
191
|
+
solution_delete_report(n_deleted, n_faulted)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def solution_delete(name_or_id, use_sol: nil, type: :all, yes: false)
|
196
|
+
biz = MrMurano::Business.new
|
197
|
+
biz.must_business_id!
|
198
|
+
|
199
|
+
if name_or_id == '*'
|
200
|
+
return unless biz.cmd_confirm_delete!(
|
201
|
+
'all solutions', yes, 'abort!'
|
202
|
+
) do |confirmed|
|
203
|
+
confirmed
|
204
|
+
end
|
205
|
+
name_or_id = ''
|
206
|
+
end
|
207
|
+
|
208
|
+
if !use_sol.nil?
|
209
|
+
solz = [use_sol]
|
210
|
+
else
|
211
|
+
MrMurano::Verbose.whirly_start('Looking for solutions...')
|
212
|
+
solz = biz.solutions(type: type)
|
213
|
+
# This used to use Hash.value? to see if the name exactly matches
|
214
|
+
# any key's value. But we should be able to stick to using name.
|
215
|
+
# (E.g., it used to call sol.meta.value?(name_or_id), but this
|
216
|
+
# would return true if, say, sol.meta[:any_key] equaled name_or_id.)
|
217
|
+
unless name_or_id.empty?
|
218
|
+
solz.select! do |sol|
|
219
|
+
sol.sid == name_or_id || sol.name == name_or_id || sol.domain =~ /#{Regexp.escape(name_or_id)}\./i
|
220
|
+
end
|
221
|
+
end
|
222
|
+
MrMurano::Verbose.whirly_stop
|
223
|
+
if $cfg['tool.debug']
|
224
|
+
say 'Matches found:'
|
225
|
+
biz.outf(solz)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
n_deleted = 0
|
230
|
+
n_faulted = 0
|
231
|
+
if solz.empty?
|
232
|
+
if !name_or_id.empty?
|
233
|
+
MrMurano::Verbose.error("No solution matching ‘#{name_or_id}’ found")
|
234
|
+
else
|
235
|
+
MrMurano::Verbose.error(MSG_SOLUTIONS_NONE_FOUND)
|
236
|
+
end
|
237
|
+
exit 1
|
238
|
+
else
|
239
|
+
# Solutions of different types can have the same name, so warning that
|
240
|
+
# more than one solution was found when searching by name is not valid.
|
241
|
+
#unless name_or_id.empty? or solz.length == 1
|
242
|
+
# MrMurano::Verbose.warning(
|
243
|
+
# "Unexpected number of solutions: found #{solz.length} for #{name_or_id} but expected 1"
|
244
|
+
# )
|
245
|
+
#end
|
246
|
+
MrMurano::Verbose.whirly_start('Deleting solutions...')
|
247
|
+
solz.each do |sol|
|
248
|
+
ret = biz.delete_solution(sol.sid)
|
249
|
+
if !ret.is_a?(Hash) && !ret.empty?
|
250
|
+
MrMurano::Verbose.error("Delete failed: #{ret}")
|
251
|
+
n_faulted += 1
|
252
|
+
else
|
253
|
+
n_deleted += 1
|
254
|
+
# Clear the ID from the config.
|
255
|
+
MrMurano::Config::CFG_SOLUTION_ID_KEYS.each do |keyn|
|
256
|
+
$cfg.set(keyn, nil) if $cfg[keyn] == sol.sid
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
MrMurano::Verbose.whirly_stop
|
261
|
+
end
|
262
|
+
|
263
|
+
[n_deleted, n_faulted]
|
264
|
+
end
|
265
|
+
|
266
|
+
def solution_delete_report(n_deleted, n_faulted)
|
267
|
+
unless n_deleted.nil? || n_deleted.zero?
|
268
|
+
# FIXME: Should this use 'say' or 'outf'?
|
269
|
+
inflection = MrMurano::Verbose.pluralize?('solution', n_deleted)
|
270
|
+
say "Deleted #{n_deleted} #{inflection}"
|
271
|
+
end
|
272
|
+
return if n_faulted.nil? || n_faulted.zero?
|
273
|
+
inflection = MrMurano::Verbose.pluralize?('solution', n_faulted)
|
274
|
+
MrMurano::Verbose.error("Failed to delete #{n_faulted} #{inflection}")
|
275
|
+
end
|
276
|
+
|
277
|
+
# *** List and Find solutions.
|
278
|
+
# ----------------------------
|
279
|
+
|
280
|
+
def cmd_solution_find_add_options(c)
|
281
|
+
c.option '--idonly', 'Only return the ids'
|
282
|
+
c.option '--[no-]brief', 'Show fewer fields: only Solution ID and domain'
|
283
|
+
c.option '--[no-]all', 'Find all Solutions in Business, not just Project'
|
284
|
+
c.option '-o', '--output FILE', %(Download to file instead of STDOUT)
|
285
|
+
end
|
286
|
+
|
287
|
+
command 'solution list' do |c|
|
288
|
+
c.syntax = %(murano solution list [--options])
|
289
|
+
c.summary = %(List solutions)
|
290
|
+
c.description = %(
|
291
|
+
List solutions in the current business.
|
292
|
+
).strip
|
293
|
+
c.project_not_required = true
|
294
|
+
|
295
|
+
cmd_solution_find_add_options(c)
|
296
|
+
|
297
|
+
# Add flag: --type [application|product|all].
|
298
|
+
cmd_add_solntype_pickers(c)
|
299
|
+
|
300
|
+
c.action do |args, options|
|
301
|
+
c.verify_arg_count!(args)
|
302
|
+
# Set all: true, so that must_fetch_solutions! finds 'em all.
|
303
|
+
options.default(all: true)
|
304
|
+
cmd_defaults_solntype_pickers(options)
|
305
|
+
cmd_solution_find_and_output(args, options)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
alias_command 'list application', 'solution list', '--type', 'application', '--brief'
|
309
|
+
alias_command 'list product', 'solution list', '--type', 'product', '--brief'
|
310
|
+
alias_command 'application list', 'solution list', '--type', 'application', '--brief'
|
311
|
+
alias_command 'product list', 'solution list', '--type', 'product', '--brief'
|
312
|
+
#
|
313
|
+
alias_command 'list solutions', 'solution list'
|
314
|
+
alias_command 'list applications', 'application list'
|
315
|
+
alias_command 'list products', 'product list'
|
316
|
+
alias_command 'solutions list', 'solution list'
|
317
|
+
alias_command 'applications list', 'application list'
|
318
|
+
alias_command 'products list', 'product list'
|
319
|
+
|
320
|
+
command 'solution find' do |c|
|
321
|
+
c.syntax = %(murano solution find [--options] [<name-or-ID,...>])
|
322
|
+
c.summary = %(Find solution by name or ID)
|
323
|
+
c.description = %(
|
324
|
+
Find solution by name or ID.
|
325
|
+
).strip
|
326
|
+
c.project_not_required = true
|
327
|
+
|
328
|
+
c.example %(
|
329
|
+
Find any solution named "mysolution"
|
330
|
+
).strip, 'murano solution find mysolution --name'
|
331
|
+
|
332
|
+
c.example %(
|
333
|
+
Find product with ID "abcdef123456"
|
334
|
+
).strip, 'murano product find abcdef123456 --id'
|
335
|
+
|
336
|
+
c.example %(
|
337
|
+
Find application with name or ID matching "1234"
|
338
|
+
).strip, 'murano application find 1234'
|
339
|
+
|
340
|
+
cmd_solution_find_add_options(c)
|
341
|
+
|
342
|
+
cmd_add_solntype_pickers(c)
|
343
|
+
|
344
|
+
# Add --id and --name options.
|
345
|
+
cmd_options_add_id_and_name(c)
|
346
|
+
|
347
|
+
# Add soln pickers: --application* and --product*
|
348
|
+
cmd_option_application_pickers(c)
|
349
|
+
cmd_option_product_pickers(c)
|
350
|
+
|
351
|
+
c.action do |args, options|
|
352
|
+
# SKIP: c.verify_arg_count!(args)
|
353
|
+
cmd_defaults_solntype_pickers(options)
|
354
|
+
cmd_defaults_id_and_name(options)
|
355
|
+
# Set all: true, so that must_fetch_solutions! finds 'em all.
|
356
|
+
options.default(all: true)
|
357
|
+
if args.none? && !any_solution_pickers!(options)
|
358
|
+
MrMurano::Verbose.error('What would you like to find?')
|
359
|
+
exit 1
|
360
|
+
end
|
361
|
+
cmd_solution_find_and_output(args, options)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
alias_command 'find application', 'solution find', '--type', 'application', '--brief'
|
365
|
+
alias_command 'find product', 'solution find', '--type', 'product', '--brief'
|
366
|
+
alias_command 'application find', 'solution find', '--type', 'application', '--brief'
|
367
|
+
alias_command 'product find', 'solution find', '--type', 'product', '--brief'
|
368
|
+
|
369
|
+
def cmd_solution_find_and_output(args, options)
|
370
|
+
cmd_verify_args_and_id_or_name!(args, options)
|
371
|
+
biz = MrMurano::Business.new
|
372
|
+
biz.must_business_id!
|
373
|
+
solz = cmd_solution_find_solutions(biz, args, options)
|
374
|
+
if solz.empty? && !options.idonly
|
375
|
+
MrMurano::Verbose.error(MSG_SOLUTIONS_NONE_FOUND)
|
376
|
+
exit 0
|
377
|
+
end
|
378
|
+
cmd_solution_output_solutions(biz, solz, options)
|
379
|
+
end
|
380
|
+
|
381
|
+
def cmd_solution_find_solutions(biz, args, options)
|
382
|
+
must_fetch_solutions!(options, args, biz)
|
383
|
+
end
|
384
|
+
|
385
|
+
def cmd_solution_output_solutions(biz, solz, options)
|
386
|
+
if options.idonly
|
387
|
+
headers = %i[apiId]
|
388
|
+
solz = solz.map { |row| [row.apiId] }
|
389
|
+
elsif options.brief
|
390
|
+
#headers = %i[apiId domain]
|
391
|
+
#solz = solz.map { |row| [row.apiId, row.domain] }
|
392
|
+
headers = %i[apiId domain name]
|
393
|
+
solz = solz.map { |row| [row.apiId, row.domain, row.name] }
|
394
|
+
else
|
395
|
+
headers = (solz.first && solz.first.meta || {}).keys
|
396
|
+
headers.delete(:sid) if headers.include?(:apiId) && headers.include?(:sid)
|
397
|
+
headers.sort_by! do |hdr|
|
398
|
+
case hdr
|
399
|
+
when :bizid
|
400
|
+
0
|
401
|
+
when :type
|
402
|
+
1
|
403
|
+
when :apiId
|
404
|
+
2
|
405
|
+
when :domain
|
406
|
+
3
|
407
|
+
when :name
|
408
|
+
4
|
409
|
+
else
|
410
|
+
5
|
411
|
+
end
|
412
|
+
end
|
413
|
+
solz = solz.map { |row| headers.map { |hdr| row.meta[hdr] } }
|
414
|
+
end
|
415
|
+
|
416
|
+
io = File.open(options.output, 'w') if options.output
|
417
|
+
biz.outf(solz, io) do |dd, ios|
|
418
|
+
if options.idonly
|
419
|
+
ios.puts(dd.join(' '))
|
420
|
+
else
|
421
|
+
biz.tabularize(
|
422
|
+
{
|
423
|
+
headers: headers.map(&:to_s),
|
424
|
+
rows: dd,
|
425
|
+
},
|
426
|
+
ios,
|
427
|
+
)
|
428
|
+
end
|
429
|
+
end
|
430
|
+
io.close unless io.nil?
|
431
|
+
end
|
432
|
+
|