MuranoCLI 3.2.0.beta.9 → 3.2.1.pre.beta.3
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/.rubocop.yml +3 -0
- data/Rakefile +5 -0
- data/dockers/README.rst +7 -0
- data/dockers/RELEASE.rst +6 -3
- data/dockers/docker-test.sh +45 -17
- data/docs/completions/murano_completion-bash +211 -86
- data/lib/MrMurano/Account.rb +72 -4
- data/lib/MrMurano/Business.rb +163 -2
- data/lib/MrMurano/Commander-Entry.rb +1 -2
- data/lib/MrMurano/Config.rb +19 -18
- data/lib/MrMurano/Content.rb +26 -19
- data/lib/MrMurano/Gateway.rb +51 -10
- data/lib/MrMurano/ReCommander.rb +1 -1
- data/lib/MrMurano/Solution-Services.rb +80 -35
- data/lib/MrMurano/Solution-Users.rb +1 -0
- data/lib/MrMurano/SyncRoot.rb +10 -3
- data/lib/MrMurano/SyncUpDown-Core.rb +47 -36
- data/lib/MrMurano/SyncUpDown-Item.rb +46 -14
- data/lib/MrMurano/SyncUpDown.rb +22 -20
- data/lib/MrMurano/Webservice-Endpoint.rb +20 -18
- data/lib/MrMurano/Webservice-File.rb +63 -20
- data/lib/MrMurano/commands/business.rb +14 -1
- data/lib/MrMurano/commands/child.rb +148 -0
- data/lib/MrMurano/commands/devices.rb +298 -149
- data/lib/MrMurano/commands/element.rb +2 -1
- data/lib/MrMurano/commands/globals.rb +3 -0
- data/lib/MrMurano/commands/network.rb +152 -33
- data/lib/MrMurano/commands/sync.rb +2 -2
- data/lib/MrMurano/commands.rb +1 -0
- data/lib/MrMurano/verbosing.rb +13 -2
- data/lib/MrMurano/version.rb +1 -1
- data/spec/Account_spec.rb +43 -11
- data/spec/Content_spec.rb +5 -3
- data/spec/GatewayBase_spec.rb +1 -1
- data/spec/GatewayDevice_spec.rb +47 -8
- data/spec/GatewayResource_spec.rb +1 -1
- data/spec/GatewaySettings_spec.rb +1 -1
- data/spec/HttpAuthed_spec.rb +17 -3
- data/spec/ProjectFile_spec.rb +59 -23
- data/spec/Setting_spec.rb +2 -1
- data/spec/Solution-ServiceConfig_spec.rb +1 -1
- data/spec/Solution-ServiceEventHandler_spec.rb +27 -20
- data/spec/Solution-ServiceModules_spec.rb +7 -5
- data/spec/Solution-UsersRoles_spec.rb +7 -1
- data/spec/Solution_spec.rb +9 -1
- data/spec/SyncRoot_spec.rb +5 -5
- data/spec/SyncUpDown_spec.rb +262 -211
- data/spec/Verbosing_spec.rb +49 -8
- data/spec/Webservice-Cors_spec.rb +10 -1
- data/spec/Webservice-Endpoint_spec.rb +84 -65
- data/spec/Webservice-File_spec.rb +16 -11
- data/spec/Webservice-Setting_spec.rb +7 -1
- data/spec/_workspace.rb +9 -0
- data/spec/cmd_business_spec.rb +5 -10
- data/spec/cmd_common.rb +67 -32
- data/spec/cmd_config_spec.rb +9 -14
- data/spec/cmd_content_spec.rb +15 -26
- data/spec/cmd_cors_spec.rb +9 -12
- data/spec/cmd_device_spec.rb +31 -45
- data/spec/cmd_domain_spec.rb +12 -10
- data/spec/cmd_element_spec.rb +18 -17
- data/spec/cmd_exchange_spec.rb +1 -4
- data/spec/cmd_init_spec.rb +56 -72
- data/spec/cmd_keystore_spec.rb +17 -26
- data/spec/cmd_link_spec.rb +13 -17
- data/spec/cmd_password_spec.rb +9 -10
- data/spec/cmd_setting_application_spec.rb +95 -68
- data/spec/cmd_setting_product_spec.rb +59 -37
- data/spec/cmd_status_spec.rb +46 -84
- data/spec/cmd_syncdown_application_spec.rb +28 -50
- data/spec/cmd_syncdown_both_spec.rb +44 -93
- data/spec/cmd_syncdown_unit_spec.rb +858 -0
- data/spec/cmd_syncup_spec.rb +21 -56
- data/spec/cmd_token_spec.rb +0 -3
- data/spec/cmd_usage_spec.rb +15 -10
- data/spec/dry_run_formatter.rb +1 -0
- data/spec/fixtures/dumped_config +4 -4
- data/spec/spec_helper.rb +3 -0
- metadata +4 -2
|
@@ -9,35 +9,37 @@ require 'time'
|
|
|
9
9
|
require 'MrMurano/Gateway'
|
|
10
10
|
require 'MrMurano/ReCommander'
|
|
11
11
|
|
|
12
|
-
command :device do |
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Interact with a device.
|
|
12
|
+
command :device do |cmd|
|
|
13
|
+
cmd.syntax = %(murano device)
|
|
14
|
+
cmd.summary = %(Interact with a device)
|
|
15
|
+
cmd.description = %(
|
|
16
|
+
Interact with a device.
|
|
17
17
|
).strip
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
cmd.project_not_required = true
|
|
19
|
+
cmd.subcmdgrouphelp = true
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
cmd.action do |_args, _options|
|
|
22
22
|
::Commander::UI.enable_paging unless $cfg['tool.no-page']
|
|
23
|
-
say MrMurano::SubCmdGroupHelp.new(
|
|
23
|
+
say MrMurano::SubCmdGroupHelp.new(cmd).get_help
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
List identifiers for a product
|
|
27
|
+
# ***
|
|
28
|
+
|
|
29
|
+
command 'device list' do |cmd|
|
|
30
|
+
cmd.syntax = %(murano device list [--options])
|
|
31
|
+
cmd.summary = %(List identifiers for a product)
|
|
32
|
+
cmd.description = %(
|
|
33
|
+
List identifiers for a product.
|
|
32
34
|
).strip
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
cmd.option '--limit NUMBER', Integer, %(How many devices to return)
|
|
37
|
+
cmd.option '--before TIMESTAMP', Integer, %(Show devices before timestamp)
|
|
38
|
+
cmd.option '-l', '--long', %(show everything)
|
|
39
|
+
cmd.option '-o', '--output FILE', %(Download to file instead of STDOUT)
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
cmd.action do |args, options|
|
|
42
|
+
cmd.verify_arg_count!(args)
|
|
41
43
|
#options.default limit: 1000
|
|
42
44
|
|
|
43
45
|
prd = MrMurano::Gateway::Device.new
|
|
@@ -91,19 +93,21 @@ List identifiers for a product.
|
|
|
91
93
|
end
|
|
92
94
|
alias_command 'devices list', 'device list'
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
# ***
|
|
97
|
+
|
|
98
|
+
command 'device read' do |cmd|
|
|
99
|
+
cmd.syntax = %(murano device read <identifier> [<alias>...] [--options])
|
|
100
|
+
cmd.summary = %(Read state of a device)
|
|
101
|
+
cmd.description = %(
|
|
98
102
|
Read state of a device.
|
|
99
103
|
|
|
100
104
|
This reads the latest state values for the resources in a device.
|
|
101
105
|
).strip
|
|
102
106
|
|
|
103
|
-
|
|
107
|
+
cmd.option '-o', '--output FILE', %(Download to file instead of STDOUT)
|
|
104
108
|
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
cmd.action do |args, options|
|
|
110
|
+
cmd.verify_arg_count!(args, nil, ['Missing device identifier'])
|
|
107
111
|
|
|
108
112
|
prd = MrMurano::Gateway::Device.new
|
|
109
113
|
|
|
@@ -134,17 +138,19 @@ This reads the latest state values for the resources in a device.
|
|
|
134
138
|
end
|
|
135
139
|
end
|
|
136
140
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
# ***
|
|
142
|
+
|
|
143
|
+
command 'device write' do |cmd|
|
|
144
|
+
cmd.syntax = %(murano device write <identifier> <Alias=Value> [<Alias=Value>...])
|
|
145
|
+
cmd.summary = %(Write to 'set' of aliases on devices)
|
|
146
|
+
cmd.description = %(
|
|
141
147
|
Write to 'set' of aliases on devices.
|
|
142
148
|
|
|
143
149
|
If an alias is not settable, this will fail.
|
|
144
150
|
).strip
|
|
145
151
|
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
cmd.action do |args, _options|
|
|
153
|
+
cmd.verify_arg_count!(args, nil, ['Missing device identifier'])
|
|
148
154
|
|
|
149
155
|
resources = (MrMurano::Gateway::GweBase.new.info || {})[:resources]
|
|
150
156
|
|
|
@@ -175,117 +181,248 @@ If an alias is not settable, this will fail.
|
|
|
175
181
|
end
|
|
176
182
|
end
|
|
177
183
|
|
|
178
|
-
|
|
179
|
-
c.syntax = %(murano device enable (<identifier>|--file <path>) [--options])
|
|
180
|
-
c.summary = %(Enable Identifiers in Murano for real world devices)
|
|
181
|
-
c.description = %(
|
|
182
|
-
Enables Identifiers, creating devices, or digital shadows, in Murano.
|
|
183
|
-
).strip
|
|
184
|
+
# ***
|
|
184
185
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
c.option '--key FILE', %(Path to file containing public TLS key for this device)
|
|
188
|
-
allowed_types = MrMurano::Gateway::Device::DEVICE_AUTH_TYPES.map(&:to_s).sort
|
|
189
|
-
c.option '--auth TYPE', %(Type of credential used to authenticate [#{allowed_types.join('|')}])
|
|
190
|
-
c.option '--cred KEY', %(The credential used to authenticate, e.g., token, password, etc.)
|
|
186
|
+
class DeviceEnableCmd
|
|
187
|
+
include MrMurano::Verbose
|
|
191
188
|
|
|
192
|
-
|
|
193
|
-
|
|
189
|
+
def command_init(cmd)
|
|
190
|
+
configure_command_meta(cmd)
|
|
191
|
+
configure_command_options(cmd)
|
|
192
|
+
configure_command_action(cmd)
|
|
193
|
+
end
|
|
194
194
|
|
|
195
|
-
|
|
195
|
+
def configure_command_meta(cmd)
|
|
196
|
+
cmd.syntax = %(murano device enable (<identifier>|--file <path>) [--options])
|
|
197
|
+
cmd.summary = %(Enable Identifiers in Murano for real world devices)
|
|
198
|
+
cmd.description = %(
|
|
199
|
+
Enable one or more Identities to create Devices, a/k/a digital twins, in Murano.
|
|
200
|
+
).strip
|
|
201
|
+
cmd.example %(
|
|
202
|
+
Use a certificate request to enable a new device identity
|
|
203
|
+
# and obtain a TLS Client Certificate for the device to use
|
|
204
|
+
# to communicate with Murano.
|
|
205
|
+
#
|
|
206
|
+
# SETUP: Use the web UI to configure your Product's Public Key
|
|
207
|
+
# Infrastructure.
|
|
208
|
+
#
|
|
209
|
+
# Navigate to the Product Settings page, e.g.,
|
|
210
|
+
#
|
|
211
|
+
# http://localhost:4000/business/<business.id>/connectivity/<product.id>/settings
|
|
212
|
+
#
|
|
213
|
+
# Select "Enable PKI", and fill in the fields.†
|
|
214
|
+
#
|
|
215
|
+
# [†: The process of signing up with a certificate provider,
|
|
216
|
+
# obtaining an API key, and gererating a Client CA certificate
|
|
217
|
+
# is beyond the scope of this help documentation.]
|
|
218
|
+
#
|
|
219
|
+
# USAGE: You may now enable a device identify and receive a certificate.
|
|
220
|
+
#
|
|
221
|
+
# First, generate a certificate request.
|
|
222
|
+
#
|
|
223
|
+
# The following is an example of how one might use openssl to make a CSR:
|
|
224
|
+
#
|
|
225
|
+
# openssl genrsa -out rootCA.key 2048
|
|
226
|
+
#
|
|
227
|
+
# openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem
|
|
228
|
+
# # 1. Be sure to set the Organization Name as the same name used to the
|
|
229
|
+
# # Client CA Certificate.
|
|
230
|
+
# # 2. Set the Common Name to the name of the device identity you want to enable.
|
|
231
|
+
#
|
|
232
|
+
# openssl req -x509 -nodes -days 365 -sha256 \\
|
|
233
|
+
# -subj /C=/ST=/L=/O=<ORGANIZATION_NAME>/CN=<COMMON_NAME> \\
|
|
234
|
+
# -newkey rsa:2048 -keyout deviceIdent-key.pem
|
|
235
|
+
# # Be sure to set ORGANIZATION_NAME and COMMON_NAME appropriately.
|
|
236
|
+
#
|
|
237
|
+
# openssl req -new -key deviceIdent-key.pem -out deviceIdent.csr \\
|
|
238
|
+
# -subj "/C=/ST=/L=/O=<ORGANIZATION_NAME>/CN=<COMMON_NAME>"
|
|
239
|
+
# # Be sure to set ORGANIZATION_NAME and COMMON_NAME appropriately.
|
|
240
|
+
#
|
|
241
|
+
# Next, enable the device and copy the certificate.
|
|
242
|
+
).lstrip, 'device_cert=$(murano device enable 12345 --expire 1 --auth csr --csr path/to/deviceIdent.csr)'
|
|
243
|
+
end
|
|
196
244
|
|
|
245
|
+
def configure_command_options(cmd)
|
|
246
|
+
cmd.option '-e', '--expire HOURS', %(
|
|
247
|
+
Devices that do not activate within HOURS hours will be deleted for security purposes
|
|
248
|
+
).strip
|
|
249
|
+
cmd.option '-f', '--file FILE', %(A file of serial numbers, one per line)
|
|
250
|
+
allowed_types = MrMurano::Gateway::Device::DEVICE_AUTH_TYPES.map(&:to_s).sort
|
|
251
|
+
cmd.option '--auth TYPE', %(
|
|
252
|
+
Type of credential used to authenticate [#{allowed_types.join('|')}]
|
|
253
|
+
).strip
|
|
254
|
+
cmd.option '--cred KEY', %(
|
|
255
|
+
The credential used to authenticate, e.g., token, password, etc.
|
|
256
|
+
).strip
|
|
257
|
+
cmd.option '--key FILE', %(Path to file containing public TLS key for this device)
|
|
258
|
+
# (lb): --csr is identical to --key, but it's included because semantics.
|
|
259
|
+
cmd.option '--csr FILE', %(Path to CSR file containing certificate request)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def configure_command_action(cmd)
|
|
263
|
+
cmd.action do |args, options|
|
|
264
|
+
cmd.verify_arg_count!(args, 1)
|
|
265
|
+
must_specify_device_id_or_file!(args, options)
|
|
266
|
+
must_specify_auth_or_cred_maybe!(options)
|
|
267
|
+
must_specify_sane_expire!(options)
|
|
268
|
+
must_specify_valid_auth!(options)
|
|
269
|
+
enable_device(args, options)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def must_specify_device_id_or_file!(args, options)
|
|
197
274
|
if args.count.zero? && options.file.to_s.empty?
|
|
198
|
-
|
|
275
|
+
error 'Missing device identifier or --file'
|
|
199
276
|
exit 1
|
|
200
277
|
elsif !args.count.zero? && !options.file.to_s.empty?
|
|
201
|
-
|
|
278
|
+
error 'Please specify an identifier or --file but not both'
|
|
202
279
|
exit 1
|
|
203
280
|
end
|
|
281
|
+
end
|
|
204
282
|
|
|
205
|
-
|
|
206
|
-
|
|
283
|
+
def must_specify_auth_or_cred_maybe!(options)
|
|
284
|
+
if (
|
|
285
|
+
!options.file.nil? &&
|
|
286
|
+
(!options.key.nil? || !options.auth.nil? || !options.cred.nil?)
|
|
287
|
+
)
|
|
288
|
+
error %(Cannot use --file with any of: --key, --auth, or --cred)
|
|
207
289
|
exit 1
|
|
208
290
|
end
|
|
209
|
-
|
|
210
|
-
|
|
291
|
+
credish_opts = [options.cred, options.key, options.csr]
|
|
292
|
+
n_credish_opts = credish_opts.count { |opt| !opt.nil? }
|
|
293
|
+
if n_credish_opts > 1
|
|
294
|
+
error %(Please use only one of: --cred, --key, or --csr)
|
|
211
295
|
exit 1
|
|
212
296
|
end
|
|
213
|
-
if options.auth
|
|
214
|
-
|
|
297
|
+
if options.auth && n_credish_opts.zero?
|
|
298
|
+
error %(When using --auth, please specify one of: --cred, -key, or --csr)
|
|
215
299
|
exit 1
|
|
216
300
|
end
|
|
217
301
|
options.auth = options.auth.to_sym unless options.auth.nil?
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
else
|
|
222
|
-
options.auth = :certificate
|
|
223
|
-
end
|
|
302
|
+
return if options.key.nil?
|
|
303
|
+
if !options.auth.nil? && !%i[certificate csr].include?(options.auth)
|
|
304
|
+
warning %(You probably mean to use "--auth certificate" with --key)
|
|
224
305
|
end
|
|
306
|
+
return if options.csr.nil? || options.auth == :csr
|
|
307
|
+
warning %(The --csr option is only relevant when used with "--auth csr")
|
|
308
|
+
end
|
|
225
309
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
# or hours * 60 * 60 * 1000 * 1000
|
|
235
|
-
micros_since_epoch = (Time.now.to_f * 1_000_000).to_i
|
|
236
|
-
mircos_until_purge = options.expire.to_i * 60 * 60 * 1000 * 1000
|
|
237
|
-
options.expire = micros_since_epoch + mircos_until_purge
|
|
310
|
+
def must_specify_sane_expire!(options)
|
|
311
|
+
return if options.expire.nil?
|
|
312
|
+
unless options.expire =~ /^[0-9]+$/
|
|
313
|
+
fancy_expire = fancy_ticks(options.expire)
|
|
314
|
+
error %(
|
|
315
|
+
The --expire value is not a number of hours: #{fancy_expire}
|
|
316
|
+
).strip
|
|
317
|
+
exit 1
|
|
238
318
|
end
|
|
319
|
+
# The platform expects the expiration time to be an integer
|
|
320
|
+
# representing microseconds since the epoch, e.g.,
|
|
321
|
+
# hours * mins/hour * secs/min * msec/sec * μsec/msec
|
|
322
|
+
# or hours * 60 * 60 * 1000 * 1000
|
|
323
|
+
micros_since_epoch = (Time.now.to_f * 1_000_000).to_i
|
|
324
|
+
mircos_until_purge = options.expire.to_i * 60 * 60 * 1000 * 1000
|
|
325
|
+
options.expire = micros_since_epoch + mircos_until_purge
|
|
326
|
+
end
|
|
239
327
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
328
|
+
def must_specify_valid_auth!(options)
|
|
329
|
+
return if options.auth.nil?
|
|
330
|
+
options.auth = options.auth.to_sym
|
|
331
|
+
return if MrMurano::Gateway::Device::DEVICE_AUTH_TYPES.include?(options.auth)
|
|
332
|
+
MrMurano::Verbose.error("unrecognized --auth: #{options.auth}")
|
|
333
|
+
exit 1
|
|
334
|
+
end
|
|
247
335
|
|
|
336
|
+
def enable_device(args, options)
|
|
337
|
+
prd = MrMurano::Gateway::Device.new
|
|
248
338
|
if !options.file.to_s.empty?
|
|
249
|
-
|
|
250
|
-
begin
|
|
251
|
-
header = File.new(options.file).gets
|
|
252
|
-
rescue Errno::ENOENT => err
|
|
253
|
-
prd.error %(Unable to open file #{prd.fancy_ticks(options.file)}: #{err.message})
|
|
254
|
-
exit 2
|
|
255
|
-
end
|
|
256
|
-
if header.nil?
|
|
257
|
-
prd.error 'Nothing in file!'
|
|
258
|
-
exit 1
|
|
259
|
-
end
|
|
260
|
-
unless header =~ /\s*ID\s*(,SSL Client Certificate\s*)?/
|
|
261
|
-
prd.error %(Missing column headers in file "#{options.file}")
|
|
262
|
-
prd.error %(First line in file should be either "ID" or "ID, SSL Client Certificate")
|
|
263
|
-
exit 2
|
|
264
|
-
end
|
|
265
|
-
prd.enable_batch(options.file, options.expire)
|
|
339
|
+
enable_device_batch(prd, options)
|
|
266
340
|
elsif args.count > 0
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
opts[:type] = options.auth unless options.auth.nil?
|
|
270
|
-
if options.key
|
|
271
|
-
File.open(options.key, 'rb') do |io|
|
|
272
|
-
prd.enable(args[0], **opts, key: io)
|
|
273
|
-
end
|
|
274
|
-
else
|
|
275
|
-
opts[:key] = options.cred unless options.cred.nil?
|
|
276
|
-
prd.enable(args[0], **opts)
|
|
277
|
-
end
|
|
341
|
+
result = enable_device_single(prd, args[0], options)
|
|
342
|
+
process_enable_single_result(result, options)
|
|
278
343
|
else
|
|
279
344
|
# Impossible path: neither args nor --file; would've exited by now.
|
|
280
345
|
raise 'Impossible'
|
|
281
346
|
end
|
|
282
347
|
end
|
|
348
|
+
|
|
349
|
+
def enable_device_batch(prd, options)
|
|
350
|
+
header = header_from_file!(options)
|
|
351
|
+
must_validate_header!(header, options)
|
|
352
|
+
prd.enable_batch(options.file, options.expire)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def header_from_file!(options)
|
|
356
|
+
# Check file for headers.
|
|
357
|
+
File.new(options.file).gets
|
|
358
|
+
rescue Errno::ENOENT => err
|
|
359
|
+
fancy_file = fancy_ticks(options.file)
|
|
360
|
+
error %(Unable to open file #{fancy_file}: #{err.message})
|
|
361
|
+
exit 2
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def must_validate_header!(header, options)
|
|
365
|
+
if header.nil?
|
|
366
|
+
error 'Nothing in file!'
|
|
367
|
+
exit 1
|
|
368
|
+
end
|
|
369
|
+
return if header =~ /\s*ID\s*(,SSL Client Certificate\s*)?/
|
|
370
|
+
error %(Missing column headers in file "#{options.file}")
|
|
371
|
+
error %(
|
|
372
|
+
First line in file should be either "ID" or "ID, SSL Client Certificate"
|
|
373
|
+
).strip
|
|
374
|
+
exit 2
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def enable_device_single(prd, device_id, options)
|
|
378
|
+
enable_opts = {}
|
|
379
|
+
enable_opts[:expire] = options.expire unless options.expire.nil?
|
|
380
|
+
enable_opts[:type] = options.auth unless options.auth.nil?
|
|
381
|
+
enable_device_slurp_key(options, enable_opts)
|
|
382
|
+
prd.enable(device_id, **enable_opts)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def enable_device_slurp_key(options, enable_opts)
|
|
386
|
+
if options.key
|
|
387
|
+
enable_device_slurp_key_read_file(options.key, enable_opts)
|
|
388
|
+
elsif options.csr
|
|
389
|
+
enable_device_slurp_key_read_file(options.csr, enable_opts)
|
|
390
|
+
elsif !options.cred.nil?
|
|
391
|
+
enable_opts[:key] = options.cred
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
def enable_device_slurp_key_read_file(key_file_path, enable_opts)
|
|
396
|
+
File.open(key_file_path, 'rb') do |io|
|
|
397
|
+
enable_opts[:key] = io.read
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def process_enable_single_result(result, options)
|
|
402
|
+
return unless options.auth == :csr
|
|
403
|
+
if result.to_s.empty?
|
|
404
|
+
warning %(Unexpected: Response missing new device identity certificate)
|
|
405
|
+
elsif !result.is_a?(Hash) || !result.key?(:certificate)
|
|
406
|
+
warning %(Unexpected: Unrecognized result format: #{result})
|
|
407
|
+
else
|
|
408
|
+
puts result[:certificate]
|
|
409
|
+
end
|
|
410
|
+
end
|
|
283
411
|
end
|
|
284
412
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
413
|
+
def wire_cmd_device_enable
|
|
414
|
+
device_enable_cmd = DeviceEnableCmd.new
|
|
415
|
+
command('device enable') { |cmd| device_enable_cmd.command_init(cmd) }
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
wire_cmd_device_enable
|
|
419
|
+
|
|
420
|
+
# ***
|
|
421
|
+
|
|
422
|
+
command 'device activate' do |cmd|
|
|
423
|
+
cmd.syntax = %(murano device activate <identifier>)
|
|
424
|
+
cmd.summary = %(Activate a serial number, retrieving its CIK)
|
|
425
|
+
cmd.description = %(
|
|
289
426
|
Activate an Identifier.
|
|
290
427
|
|
|
291
428
|
Generally you should not use this.
|
|
@@ -300,22 +437,24 @@ Note that you can only activate a device once. After that
|
|
|
300
437
|
you cannot retrive the CIK again.
|
|
301
438
|
).strip
|
|
302
439
|
|
|
303
|
-
|
|
304
|
-
|
|
440
|
+
cmd.action do |args, _options|
|
|
441
|
+
cmd.verify_arg_count!(args, nil, ['Missing device identifier'])
|
|
305
442
|
prd = MrMurano::Gateway::Device.new
|
|
306
443
|
prd.outf prd.activate(args.first)
|
|
307
444
|
end
|
|
308
445
|
end
|
|
309
446
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
Delete a device
|
|
447
|
+
# ***
|
|
448
|
+
|
|
449
|
+
command 'device delete' do |cmd|
|
|
450
|
+
cmd.syntax = %(murano device delete <identifier>)
|
|
451
|
+
cmd.summary = %(Delete a device)
|
|
452
|
+
cmd.description = %(
|
|
453
|
+
Delete a device.
|
|
315
454
|
).strip
|
|
316
455
|
|
|
317
|
-
|
|
318
|
-
|
|
456
|
+
cmd.action do |args, _options|
|
|
457
|
+
cmd.verify_arg_count!(args, nil, ['Missing device identifier'])
|
|
319
458
|
prd = MrMurano::Gateway::Device.new
|
|
320
459
|
snid = args.shift
|
|
321
460
|
ret = prd.remove(snid)
|
|
@@ -323,60 +462,68 @@ Delete a device.
|
|
|
323
462
|
end
|
|
324
463
|
end
|
|
325
464
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
Get the URL for the HTTP-Data-API for this Project
|
|
465
|
+
# ***
|
|
466
|
+
|
|
467
|
+
command 'device httpurl' do |cmd|
|
|
468
|
+
cmd.syntax = %(murano device httpurl)
|
|
469
|
+
cmd.summary = %(Get the URL for the HTTP-Data-API for this Project)
|
|
470
|
+
cmd.description = %(
|
|
471
|
+
Get the URL for the HTTP-Data-API for this Project.
|
|
331
472
|
).strip
|
|
332
473
|
|
|
333
|
-
|
|
334
|
-
|
|
474
|
+
cmd.action do |args, _options|
|
|
475
|
+
cmd.verify_arg_count!(args)
|
|
335
476
|
prd = MrMurano::Gateway::GweBase.new
|
|
336
477
|
ret = prd.info
|
|
337
478
|
say "https://#{ret[:fqdn]}/onep:v1/stack/alias"
|
|
338
479
|
end
|
|
339
480
|
end
|
|
340
481
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
Lock a device, not allowing connections to it until unlocked
|
|
482
|
+
# ***
|
|
483
|
+
|
|
484
|
+
command 'device lock' do |cmd|
|
|
485
|
+
cmd.syntax = %(murano device lock <identifier>)
|
|
486
|
+
cmd.summary = %(Lock a device, not allowing connections to it until unlocked)
|
|
487
|
+
cmd.description = %(
|
|
488
|
+
Lock a device, not allowing connections to it until unlocked.
|
|
346
489
|
).strip
|
|
347
490
|
|
|
348
|
-
|
|
349
|
-
|
|
491
|
+
cmd.action do |args, _options|
|
|
492
|
+
cmd.verify_arg_count!(args, 1, ['Missing device identifier'])
|
|
350
493
|
prd = MrMurano::Gateway::Device.new
|
|
351
494
|
prd.lock(args[0])
|
|
352
495
|
end
|
|
353
496
|
end
|
|
354
497
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
Unlock a device, allowing connections to it again
|
|
498
|
+
# ***
|
|
499
|
+
|
|
500
|
+
command 'device unlock' do |cmd|
|
|
501
|
+
cmd.syntax = %(murano device unlock <identifier>)
|
|
502
|
+
cmd.summary = %(Unlock a device, allowing connections to it again)
|
|
503
|
+
cmd.description = %(
|
|
504
|
+
Unlock a device, allowing connections to it again.
|
|
360
505
|
).strip
|
|
361
506
|
|
|
362
|
-
|
|
363
|
-
|
|
507
|
+
cmd.action do |args, _options|
|
|
508
|
+
cmd.verify_arg_count!(args, 1, ['Missing device identifier'])
|
|
364
509
|
prd = MrMurano::Gateway::Device.new
|
|
365
510
|
prd.unlock(args[0])
|
|
366
511
|
end
|
|
367
512
|
end
|
|
368
513
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
514
|
+
# ***
|
|
515
|
+
|
|
516
|
+
command 'device revoke' do |cmd|
|
|
517
|
+
cmd.syntax = %(murano device revoke <identifier>)
|
|
518
|
+
cmd.summary = %(Force device to reprovision)
|
|
519
|
+
cmd.description = %(
|
|
373
520
|
Force device to reprovision.
|
|
374
521
|
|
|
375
522
|
This will revoke the device's keys and cause it to temporarily disconnect. The will then reconnect and be provisioned with new keys.
|
|
376
523
|
).strip
|
|
377
524
|
|
|
378
|
-
|
|
379
|
-
|
|
525
|
+
cmd.action do |args, _options|
|
|
526
|
+
cmd.verify_arg_count!(args, 1, ['Missing device identifier'])
|
|
380
527
|
prd = MrMurano::Gateway::Device.new
|
|
381
528
|
# MAYBE/2017-08-23: This command doesn't return an error if the device
|
|
382
529
|
# ID was not found, or if the keys were already revoked. Do we care?
|
|
@@ -385,6 +532,8 @@ This will revoke the device's keys and cause it to temporarily disconnect. The w
|
|
|
385
532
|
end
|
|
386
533
|
end
|
|
387
534
|
|
|
535
|
+
# ***
|
|
536
|
+
|
|
388
537
|
alias_command 'product device', 'device'
|
|
389
538
|
alias_command 'product device list', 'device list'
|
|
390
539
|
alias_command 'product devices list', 'device list'
|