enfcli 4.0.0 → 5.0.0.pre.alpha
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/.circleci/Dockerfile +2 -2
- data/.circleci/config.yml +5 -0
- data/Gemfile.lock +38 -26
- data/Makefile +7 -0
- data/README.md +52 -7
- data/enfcli.gemspec +28 -26
- data/format.sh +9 -0
- data/lib/enfapi.rb +184 -237
- data/lib/enfapi/dns.rb +95 -0
- data/lib/enfapi/firewall.rb +37 -0
- data/lib/enfapi/user.rb +75 -0
- data/lib/enfcli.rb +211 -111
- data/lib/enfcli/commands/captive.rb +518 -157
- data/lib/enfcli/commands/user.rb +208 -160
- data/lib/enfcli/commands/xcr.rb +151 -119
- data/lib/enfcli/commands/xdns.rb +65 -55
- data/lib/enfcli/commands/xfw.rb +37 -37
- data/lib/enfcli/commands/xiam.rb +87 -80
- data/lib/enfcli/version.rb +2 -2
- data/lib/enfthor.rb +38 -14
- metadata +65 -5
data/lib/enfcli/commands/xiam.rb
CHANGED
@@ -13,18 +13,17 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
|
-
require
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
16
|
+
require "enfthor"
|
17
|
+
require "enfapi"
|
18
|
+
require "digest"
|
19
|
+
require "openssl"
|
20
|
+
require "ipaddr"
|
21
21
|
|
22
22
|
module EnfCli
|
23
23
|
module Cmd
|
24
|
-
|
25
24
|
class Xiam < EnfThor
|
26
25
|
no_commands {
|
27
|
-
def write_pem_file
|
26
|
+
def write_pem_file(keyfile, data)
|
28
27
|
# check if keyfile ends with .pem extension
|
29
28
|
keyfile = "#{keyfile}.pem" unless keyfile.end_with?(".pem")
|
30
29
|
|
@@ -34,17 +33,17 @@ module EnfCli
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
|
-
def write_to_file
|
36
|
+
def write_to_file(filename, data)
|
38
37
|
begin
|
39
38
|
# check if file exists
|
40
39
|
filename = EnfCli::expand_path(filename)
|
41
|
-
if File.exists?(
|
40
|
+
if File.exists?(filename)
|
42
41
|
proceed = ask("Overwrite #{filename}(type 'yes' to continue...)?")
|
43
|
-
return nil unless (proceed.downcase ==
|
42
|
+
return nil unless (proceed.downcase == "yes")
|
44
43
|
end
|
45
44
|
|
46
45
|
# write to file
|
47
|
-
open filename,
|
46
|
+
open filename, "w" do |io| io.write data end
|
48
47
|
|
49
48
|
# return success
|
50
49
|
return true
|
@@ -59,13 +58,13 @@ module EnfCli
|
|
59
58
|
|
60
59
|
def scan_group_qr_code()
|
61
60
|
# Initalize values
|
62
|
-
gpk_header =
|
63
|
-
gpk_info =
|
61
|
+
gpk_header = ""
|
62
|
+
gpk_info = ""
|
64
63
|
|
65
64
|
# Scan QR Code
|
66
|
-
gpk_header = EnfCli::ask_password(
|
65
|
+
gpk_header = EnfCli::ask_password("Scan DAA group information:")
|
67
66
|
if gpk_header.length < 16
|
68
|
-
gpk_info = EnfCli::ask_password(
|
67
|
+
gpk_info = EnfCli::ask_password("")
|
69
68
|
else
|
70
69
|
tmp_header = gpk_header[0..12]
|
71
70
|
gpk_info = gpk_header[13..gpk_header.length]
|
@@ -90,7 +89,7 @@ module EnfCli
|
|
90
89
|
def read_ec_key_file(keyfile)
|
91
90
|
# expand path
|
92
91
|
keyfile = EnfCli::expand_path(keyfile)
|
93
|
-
|
92
|
+
|
94
93
|
## return if keyfile not found
|
95
94
|
raise EnfCli::ERROR, "#{keyfile} not found!" unless File.exists?(keyfile)
|
96
95
|
|
@@ -98,16 +97,15 @@ module EnfCli
|
|
98
97
|
OpenSSL::PKey::EC.new(File.read(keyfile))
|
99
98
|
end
|
100
99
|
|
101
|
-
def display_groups
|
102
|
-
headings = [
|
103
|
-
rows = groups.map{ |hash|
|
104
|
-
[
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
]
|
100
|
+
def display_groups(groups)
|
101
|
+
headings = ["DAA Group", "Base Name", "Provisioned", "Onboarded", "Default Network", "Domain"]
|
102
|
+
rows = groups.map { |hash|
|
103
|
+
[hash[:gid],
|
104
|
+
hash[:basename],
|
105
|
+
hash[:provisioned_count],
|
106
|
+
hash[:onboarded_count],
|
107
|
+
hash[:default_network] ? hash[:default_network] : "<not set>",
|
108
|
+
hash[:domain]]
|
111
109
|
}
|
112
110
|
render_table(headings, rows)
|
113
111
|
end
|
@@ -119,23 +117,23 @@ module EnfCli
|
|
119
117
|
# create NEW_CREDENTIAL_ECDSA
|
120
118
|
new_credential = {
|
121
119
|
:type => "ecdsa_p256",
|
122
|
-
:key => pubkey
|
123
|
-
}
|
120
|
+
:key => pubkey,
|
121
|
+
}
|
124
122
|
|
125
123
|
# create NEW_ENDPOINT_AUTH
|
126
124
|
new_endpoint_auth = {
|
127
125
|
:ecdsa_credential => new_credential,
|
128
126
|
:address_request => {
|
129
|
-
:address => ipv6_address.to_s
|
130
|
-
}
|
127
|
+
:address => ipv6_address.to_s,
|
128
|
+
},
|
131
129
|
}
|
132
130
|
|
133
131
|
data = EnfApi::Iam.instance.provision_endpoint new_endpoint_auth
|
134
132
|
provisioned_ip = data[:address]
|
135
133
|
|
136
134
|
# Make sure provisioned ip is same as the requested ip
|
137
|
-
raise EnfCli::ERROR, "Provisioned IPv6 address not the same as requested" unless provisioned_ip.eql?(
|
138
|
-
|
135
|
+
raise EnfCli::ERROR, "Provisioned IPv6 address not the same as requested" unless provisioned_ip.eql?(ipv6_address.to_s)
|
136
|
+
|
139
137
|
say "Created new ipv6 endpoint #{provisioned_ip}", :green
|
140
138
|
end
|
141
139
|
|
@@ -146,7 +144,7 @@ module EnfCli
|
|
146
144
|
# create NEW_CREDENTIAL_ECDSA
|
147
145
|
new_credential = {
|
148
146
|
:type => "ecdsa_p256",
|
149
|
-
:key => pubkey
|
147
|
+
:key => pubkey,
|
150
148
|
}
|
151
149
|
|
152
150
|
EnfApi::Iam.instance.update_endpoint_key ipv6_address, new_credential
|
@@ -155,11 +153,12 @@ module EnfCli
|
|
155
153
|
end
|
156
154
|
}
|
157
155
|
|
158
|
-
option_gid = [:gid, {default: nil, type: :string, banner:
|
159
|
-
|
156
|
+
option_gid = [:gid, { default: nil, type: :string, banner: "GID",
|
157
|
+
desc: "The group to get. If not specified, scan the group QR code" }]
|
160
158
|
|
161
159
|
desc "get-group", "Get DAA Group Information"
|
162
160
|
method_option *option_gid
|
161
|
+
|
163
162
|
def get_group
|
164
163
|
try_with_rescue_in_session do
|
165
164
|
# scan if gid not in options
|
@@ -178,8 +177,9 @@ module EnfCli
|
|
178
177
|
end
|
179
178
|
|
180
179
|
desc "list-groups", "List DAA Groups Information"
|
181
|
-
method_option :'network', default: nil, type: :string, banner:
|
182
|
-
desc:
|
180
|
+
method_option :'network', default: nil, type: :string, banner: "NETWORK",
|
181
|
+
desc: "List only groups in this network"
|
182
|
+
|
183
183
|
def list_groups
|
184
184
|
try_with_rescue_in_session do
|
185
185
|
# The xiam API doesn't properly support the 'network' query
|
@@ -207,6 +207,7 @@ module EnfCli
|
|
207
207
|
desc "set-group-default-network", "Set /64 network as default for the DAA group"
|
208
208
|
method_option :'network', :type => :string, :required => true
|
209
209
|
method_option *option_gid
|
210
|
+
|
210
211
|
def set_group_default_network
|
211
212
|
try_with_rescue_in_session do
|
212
213
|
network = EnfCli::IPV6Cidr.new(options[:network]).to_s
|
@@ -221,7 +222,7 @@ module EnfCli
|
|
221
222
|
# create MODIFIED_GROUP
|
222
223
|
modified_group = {
|
223
224
|
:gid => gid,
|
224
|
-
:default_network => network
|
225
|
+
:default_network => network,
|
225
226
|
}
|
226
227
|
|
227
228
|
# Post to server
|
@@ -234,6 +235,7 @@ module EnfCli
|
|
234
235
|
desc "set-group-domain", "Set /48 domain for the DAA group"
|
235
236
|
method_option :'domain', :type => :string, :required => true
|
236
237
|
method_option *option_gid
|
238
|
+
|
237
239
|
def set_group_domain
|
238
240
|
try_with_rescue_in_session do
|
239
241
|
domain = EnfCli::IPV6Cidr.new(options[:domain]).to_s
|
@@ -248,7 +250,7 @@ module EnfCli
|
|
248
250
|
# create MODIFIED_GROUP
|
249
251
|
modified_group = {
|
250
252
|
:gid => gid,
|
251
|
-
:domain => domain
|
253
|
+
:domain => domain,
|
252
254
|
}
|
253
255
|
|
254
256
|
# Post to server
|
@@ -262,6 +264,7 @@ module EnfCli
|
|
262
264
|
method_option :'network', :type => :string, :required => true
|
263
265
|
method_option *option_gid
|
264
266
|
method_option :'set_as_default', :type => :boolean, default: false, desc: "Set the network as the default for this group"
|
267
|
+
|
265
268
|
def add_group_to_network
|
266
269
|
try_with_rescue_in_session do
|
267
270
|
network = EnfCli::IPV6Cidr.new(options[:network]).to_s
|
@@ -276,7 +279,7 @@ module EnfCli
|
|
276
279
|
if options[:set_as_default]
|
277
280
|
modified_group = {
|
278
281
|
:gid => gid,
|
279
|
-
:default_network => network
|
282
|
+
:default_network => network,
|
280
283
|
}
|
281
284
|
|
282
285
|
EnfApi::Iam.instance.update_group gid, modified_group
|
@@ -291,6 +294,7 @@ module EnfCli
|
|
291
294
|
desc "provision-group", "Provision a DAA Group"
|
292
295
|
method_option :'device-count', :type => :numeric, :required => true
|
293
296
|
method_option :'operator', :type => :array, :required => true, :banner => "OPERATOR"
|
297
|
+
|
294
298
|
def provision_group
|
295
299
|
try_with_rescue_in_session do
|
296
300
|
qr_code_info = scan_group_qr_code()
|
@@ -311,16 +315,16 @@ module EnfCli
|
|
311
315
|
new_provisioning = {
|
312
316
|
:group_id => gid,
|
313
317
|
:quantity => quantity,
|
314
|
-
:operator => operator
|
318
|
+
:operator => operator,
|
315
319
|
}
|
316
320
|
|
317
321
|
# create NEW_GROUP
|
318
322
|
new_group = {
|
319
323
|
:group_public_key => gpk,
|
320
324
|
:basename => basename,
|
321
|
-
:provisionings => [
|
325
|
+
:provisionings => [new_provisioning],
|
322
326
|
}
|
323
|
-
|
327
|
+
|
324
328
|
# Post to server
|
325
329
|
EnfApi::Iam.instance.provision_group new_group
|
326
330
|
|
@@ -330,16 +334,17 @@ module EnfCli
|
|
330
334
|
end
|
331
335
|
|
332
336
|
desc "create-endpoint-key", "Generate a pem encoded EC key pair"
|
333
|
-
method_option :'key-out-file', :type => :string, :required => true, :banner =>
|
334
|
-
method_option :'public-key-out-file', :type => :string, :required => true, :banner =>
|
337
|
+
method_option :'key-out-file', :type => :string, :required => true, :banner => "<file>"
|
338
|
+
method_option :'public-key-out-file', :type => :string, :required => true, :banner => "<file>"
|
339
|
+
|
335
340
|
def create_endpoint_key
|
336
341
|
try_with_rescue_in_session do
|
337
342
|
# get options
|
338
|
-
keyfile = options[
|
339
|
-
pubfile = options[
|
343
|
+
keyfile = options["key-out-file"]
|
344
|
+
pubfile = options["public-key-out-file"]
|
340
345
|
|
341
346
|
# Generate a key pair
|
342
|
-
key = OpenSSL::PKey::EC.new(
|
347
|
+
key = OpenSSL::PKey::EC.new("prime256v1")
|
343
348
|
key.generate_key
|
344
349
|
|
345
350
|
# write key pair to file
|
@@ -347,20 +352,21 @@ module EnfCli
|
|
347
352
|
|
348
353
|
# write public key to file
|
349
354
|
key.private_key = nil
|
350
|
-
write_pem_file pubfile, key.to_pem
|
355
|
+
write_pem_file pubfile, key.to_pem
|
351
356
|
end
|
352
357
|
end
|
353
358
|
|
354
359
|
desc "create-endpoint-cert", "Creates and signs a certificate for a particular identity using the provided private key"
|
355
|
-
method_option :'identity', :type => :string, :required => true, :banner =>
|
356
|
-
method_option :'key-in-file', :type => :string, :required => true, :banner =>
|
357
|
-
method_option :'cert-out-file', :type => :string, :required => true, :banner =>
|
360
|
+
method_option :'identity', :type => :string, :required => true, :banner => "<ipv6>"
|
361
|
+
method_option :'key-in-file', :type => :string, :required => true, :banner => "<file>"
|
362
|
+
method_option :'cert-out-file', :type => :string, :required => true, :banner => "<file>"
|
363
|
+
|
358
364
|
def create_endpoint_cert
|
359
365
|
try_with_rescue_in_session do
|
360
366
|
# get options
|
361
|
-
ipv6 = EnfCli::IPV6.new(options[
|
362
|
-
keyfile = EnfCli::expand_path(options[
|
363
|
-
certfile = EnfCli::expand_path(options[
|
367
|
+
ipv6 = EnfCli::IPV6.new(options["identity"]).to_s
|
368
|
+
keyfile = EnfCli::expand_path(options["key-in-file"])
|
369
|
+
certfile = EnfCli::expand_path(options["cert-out-file"])
|
364
370
|
|
365
371
|
# read the private key
|
366
372
|
key = read_ec_key_file keyfile
|
@@ -369,18 +375,19 @@ module EnfCli
|
|
369
375
|
cert = EnfCli::generate_ec_cert(key, ipv6)
|
370
376
|
|
371
377
|
# write to file
|
372
|
-
write_pem_file certfile, cert.to_pem
|
378
|
+
write_pem_file certfile, cert.to_pem
|
373
379
|
end
|
374
380
|
end
|
375
381
|
|
376
382
|
desc "create-endpoint-in-network", "Create an IPV6 endpoint in /64 network"
|
377
383
|
method_option :'network', :type => :string, :required => true, :banner => "<ipv6 network>"
|
378
384
|
method_option :'public-key-in-file', :type => :string, :required => true, :banner => "<file>"
|
385
|
+
|
379
386
|
def create_endpoint_in_network
|
380
387
|
try_with_rescue_in_session do
|
381
388
|
# Read options
|
382
389
|
network = EnfCli::IPV6Cidr.new(options[:network]).to_s
|
383
|
-
keyfile = EnfCli::expand_path(options[
|
390
|
+
keyfile = EnfCli::expand_path(options["public-key-in-file"])
|
384
391
|
|
385
392
|
# read keyfile
|
386
393
|
key = read_ec_key_file keyfile
|
@@ -392,49 +399,50 @@ module EnfCli
|
|
392
399
|
# create NEW_CREDENTIAL_ECDSA
|
393
400
|
new_credential = {
|
394
401
|
:type => "ecdsa_p256",
|
395
|
-
:key => pubkey
|
402
|
+
:key => pubkey,
|
396
403
|
}
|
397
|
-
|
404
|
+
|
398
405
|
# create NEW_ENDPOINT_AUTH
|
399
406
|
new_endpoint = {
|
400
407
|
:ecdsa_credential => new_credential,
|
401
408
|
:address_request => {
|
402
|
-
:network => network
|
403
|
-
}
|
409
|
+
:network => network,
|
410
|
+
},
|
404
411
|
}
|
405
412
|
|
406
413
|
data = EnfApi::Iam.instance.provision_endpoint new_endpoint
|
407
414
|
provisioned_ip = data[:address]
|
408
|
-
|
415
|
+
|
409
416
|
say "Created new ipv6 endpoint #{provisioned_ip}", :green
|
410
417
|
end
|
411
418
|
end
|
412
419
|
|
413
420
|
desc "create-endpoint-with-address", "Create an IPV6 endpoint in /64 network with user specified address"
|
414
421
|
method_option :'address', :type => :string, :required => true, :banner => "<ipv6 address>"
|
415
|
-
method_option :'public-key-in-file', :type => :string, :required => true, :banner => "<file>"
|
422
|
+
method_option :'public-key-in-file', :type => :string, :required => true, :banner => "<file>"
|
423
|
+
|
416
424
|
def create_endpoint_with_address
|
417
425
|
try_with_rescue_in_session do
|
418
426
|
# Read address
|
419
427
|
ipv6_address = EnfCli::IPV6.new options[:address]
|
420
428
|
|
421
429
|
# read key
|
422
|
-
keyfile = EnfCli::expand_path(options[
|
430
|
+
keyfile = EnfCli::expand_path(options["public-key-in-file"])
|
423
431
|
key = read_ec_key_file keyfile
|
424
432
|
pub = key.public_key
|
425
433
|
|
426
434
|
# create_endpoint
|
427
435
|
provision_endpoint ipv6_address, pub
|
428
|
-
|
429
436
|
end
|
430
437
|
end
|
431
438
|
|
432
439
|
desc "create-endpoint-from-cert", "Create an IPV6 endpoint in /64 network with address from cert"
|
433
|
-
method_option :'cert-in-file', :type => :string, :required => true, :banner => "<file>"
|
440
|
+
method_option :'cert-in-file', :type => :string, :required => true, :banner => "<file>"
|
441
|
+
|
434
442
|
def create_endpoint_from_cert
|
435
443
|
try_with_rescue_in_session do
|
436
444
|
# read options
|
437
|
-
certfile = EnfCli::expand_path(options[
|
445
|
+
certfile = EnfCli::expand_path(options["cert-in-file"])
|
438
446
|
raise EnfCli::ERROR, "#{certfile} does not exist!" unless File.exists?(certfile)
|
439
447
|
|
440
448
|
# read cert file
|
@@ -445,42 +453,43 @@ module EnfCli
|
|
445
453
|
subject = cert.subject.to_a
|
446
454
|
|
447
455
|
# get ipv6 CN record
|
448
|
-
cn = subject.select { |d| "CN".eql?(
|
449
|
-
ipv6_address =
|
456
|
+
cn = subject.select { |d| "CN".eql?(d[0].upcase) }
|
457
|
+
ipv6_address = EnfCli::IPV6.new cn[0][1]
|
450
458
|
|
451
459
|
# get the public key
|
452
460
|
pub = cert.public_key.public_key
|
453
461
|
|
454
462
|
# create_endpoint
|
455
463
|
provision_endpoint ipv6_address, pub
|
456
|
-
|
457
|
-
end
|
464
|
+
end
|
458
465
|
end
|
459
466
|
|
460
467
|
desc "update-endpoint-key", "Update an IPV6 endpoint's credentials"
|
461
468
|
method_option :'address', :type => :string, :required => true, :banner => "<ipv6 address>"
|
462
469
|
method_option :'public-key-in-file', :type => :string, :required => true, :banner => "<file>"
|
470
|
+
|
463
471
|
def update_endpoint_key
|
464
472
|
try_with_rescue_in_session do
|
465
473
|
# Read address
|
466
474
|
ipv6_address = EnfCli::IPV6.new options[:address]
|
467
475
|
|
468
476
|
# read key
|
469
|
-
keyfile = EnfCli::expand_path(options[
|
477
|
+
keyfile = EnfCli::expand_path(options["public-key-in-file"])
|
470
478
|
key = read_ec_key_file keyfile
|
471
479
|
pub = key.public_key
|
472
480
|
|
473
481
|
# update endpoint
|
474
482
|
update_endpoint_credentials ipv6_address, pub
|
475
|
-
end
|
483
|
+
end
|
476
484
|
end
|
477
485
|
|
478
486
|
desc "update-endpoint-cert", "Update an IPV6 endpoint's credentials"
|
479
|
-
method_option :'cert-in-file', :type => :string, :required => true, :banner => "<file>"
|
487
|
+
method_option :'cert-in-file', :type => :string, :required => true, :banner => "<file>"
|
488
|
+
|
480
489
|
def update_endpoint_cert
|
481
490
|
try_with_rescue_in_session do
|
482
491
|
# read options
|
483
|
-
certfile = EnfCli::expand_path(options[
|
492
|
+
certfile = EnfCli::expand_path(options["cert-in-file"])
|
484
493
|
raise EnfCli::ERROR, "#{certfile} does not exist!" unless File.exists?(certfile)
|
485
494
|
|
486
495
|
# read cert file
|
@@ -491,8 +500,8 @@ module EnfCli
|
|
491
500
|
subject = cert.subject.to_a
|
492
501
|
|
493
502
|
# get ipv6 CN record
|
494
|
-
cn = subject.select { |d| "CN".eql?(
|
495
|
-
ipv6_address =
|
503
|
+
cn = subject.select { |d| "CN".eql?(d[0].upcase) }
|
504
|
+
ipv6_address = EnfCli::IPV6.new cn[0][1]
|
496
505
|
|
497
506
|
# get the public key
|
498
507
|
pub = cert.public_key.public_key
|
@@ -501,8 +510,6 @@ module EnfCli
|
|
501
510
|
update_endpoint_credentials ipv6_address, pub
|
502
511
|
end
|
503
512
|
end
|
504
|
-
|
505
|
-
end
|
513
|
+
end
|
506
514
|
end
|
507
515
|
end
|
508
|
-
|
data/lib/enfcli/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright 2018 Xaptum,Inc
|
2
|
+
# Copyright 2018-2020 Xaptum,Inc
|
3
3
|
#
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
5
|
# you may not use this file except in compliance with the License.
|
@@ -14,5 +14,5 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
module EnfCli
|
17
|
-
VERSION =
|
17
|
+
VERSION = "5.0.0-alpha"
|
18
18
|
end
|