chef-licensing 0.4.44 → 0.7.5
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/chef-licensing.gemspec +5 -2
- data/lib/chef-licensing/exceptions/invalid_file_format_version.rb +10 -0
- data/lib/chef-licensing/exceptions/license_file_corrupted.rb +9 -0
- data/lib/chef-licensing/license_key_fetcher/chef_licensing_interactions.yaml +39 -235
- data/lib/chef-licensing/license_key_fetcher/file.rb +62 -14
- data/lib/chef-licensing/license_key_fetcher/license_file/base.rb +63 -0
- data/lib/chef-licensing/license_key_fetcher/license_file/v3.rb +12 -0
- data/lib/chef-licensing/license_key_fetcher/license_file/v4.rb +27 -0
- data/lib/chef-licensing/license_key_fetcher.rb +7 -4
- data/lib/chef-licensing/list_license_keys.rb +9 -3
- data/lib/chef-licensing/restful_client/base.rb +60 -26
- data/lib/chef-licensing/restful_client/middleware/exceptions_handler.rb +1 -3
- data/lib/chef-licensing/restful_client/v1.rb +0 -2
- data/lib/chef-licensing/tui_engine/tui_actions.rb +1 -92
- data/lib/chef-licensing/version.rb +1 -1
- metadata +12 -11
- data/LICENSE +0 -1
- data/lib/chef-licensing/exceptions/license_generation_failed.rb +0 -9
- data/lib/chef-licensing/exceptions/license_generation_rejected.rb +0 -7
- data/lib/chef-licensing/license_key_generator.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bc6490da547bbded96f9eae129f488d1be7178feae66dc02dad8acba71fff0b
|
4
|
+
data.tar.gz: 16f191bd6102f08be159bb73c88f1e992657e829248b54ecdd0c5743982f65d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 873ad985ccfc6cf42478d5e0deceb001d85f6ed74d6b62b0bb9355db66da9ad7f707f5a3d1f2aa2cece612f688321757d8c406c331c8e8ab543d1c12fbe4b794
|
7
|
+
data.tar.gz: 155632f6ced920a84a6700c58bad75534e34c85fbf10b4f262b5cea030fecb291de9e429e41b4108b17e97e6f3ba744bc8cefbb1b15729a43bf89e75a0e8656f
|
data/chef-licensing.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.version = ChefLicensing::VERSION
|
8
8
|
spec.authors = ["Inspec Team"]
|
9
9
|
spec.email = ["inspec@progress.com"]
|
10
|
-
spec.license = "
|
10
|
+
spec.license = "Apache-2.0"
|
11
11
|
|
12
12
|
spec.summary = %q{Chef License storage, generation, and entitlement}
|
13
13
|
spec.description = %q{Ruby library to support CLI tools that use Progress Chef license storage, generation, and entitlement.}
|
@@ -30,6 +30,9 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_dependency "tty-prompt", "~> 0.23"
|
31
31
|
spec.add_dependency "faraday", ">= 1", "< 3"
|
32
32
|
spec.add_dependency "faraday-http-cache"
|
33
|
-
|
33
|
+
# Note: 7.1.0 does not defaults its cache_format_version to 7.1 but 6.1 instead which gives deprecation warnings
|
34
|
+
# Remove the version constraint when we can upgrade to 7.1.1 post stable release of Activesupport 7.1
|
35
|
+
# Similar issue with 7.0 existed: https://github.com/rails/rails/pull/45293
|
36
|
+
spec.add_dependency "activesupport", "~> 7.0", "< 7.1"
|
34
37
|
spec.add_dependency "tty-spinner", "~> 0.9.3"
|
35
38
|
end
|
@@ -7,13 +7,13 @@ interactions:
|
|
7
7
|
License ID Validation
|
8
8
|
|
9
9
|
To continue using Chef <%= input[:chef_product_name] %>, a license ID is required.
|
10
|
-
(Free, Trial, or Commercial)
|
10
|
+
(Free Tier, Trial, or Commercial)
|
11
11
|
|
12
12
|
If you generated a license previously, you might
|
13
13
|
have received it in an email.
|
14
14
|
|
15
15
|
If you are a commercial user, you can also find it in the
|
16
|
-
<%= input[:pastel].underline.green("
|
16
|
+
<%= input[:pastel].underline.green("https://community.progress.com/s/products/chef")%> portal.
|
17
17
|
------------------------------------------------------------
|
18
18
|
prompt_type: "say"
|
19
19
|
paths: [ask_if_user_has_license_id]
|
@@ -46,7 +46,7 @@ interactions:
|
|
46
46
|
paths: [add_license_info_in_restriction_flow]
|
47
47
|
|
48
48
|
free_license_already_exist_message:
|
49
|
-
messages: "A Free License already exists with following details: \n"
|
49
|
+
messages: "A Free Tier License already exists with following details: \n"
|
50
50
|
prompt_type: "say"
|
51
51
|
paths: [add_license_info_in_restriction_flow]
|
52
52
|
|
@@ -70,7 +70,7 @@ interactions:
|
|
70
70
|
trial_restriction_message:
|
71
71
|
prompt_type: "say"
|
72
72
|
messages:
|
73
|
-
Please generate a Free or Commercial License by running <%= input[:pastel].bold("#{ChefLicensing::Config.chef_executable_name} license add")%>.
|
73
|
+
Please generate a Free Tier or Commercial License by running <%= input[:pastel].bold("#{ChefLicensing::Config.chef_executable_name} license add")%>.
|
74
74
|
paths: [exit_with_message]
|
75
75
|
|
76
76
|
free_restriction_message:
|
@@ -92,7 +92,7 @@ interactions:
|
|
92
92
|
|
93
93
|
Get a Commercial License to receive bug fixes, updates
|
94
94
|
and new features.
|
95
|
-
Get a Free License to scan limited <%= input[:unit_measure] %>.
|
95
|
+
Get a Free Tier License to scan limited <%= input[:unit_measure] %>.
|
96
96
|
|
97
97
|
To get a new license, run <%= input[:pastel].bold("#{ChefLicensing::Config.chef_executable_name} license add")%>
|
98
98
|
and select a license type.
|
@@ -107,7 +107,7 @@ interactions:
|
|
107
107
|
|
108
108
|
Get a Commercial License to receive bug fixes, updates
|
109
109
|
and new features.
|
110
|
-
Get a Free License to scan limited <%= input[:unit_measure] %>.
|
110
|
+
Get a Free Tier License to scan limited <%= input[:unit_measure] %>.
|
111
111
|
------------------------------------------------------------
|
112
112
|
prompt_type: "say"
|
113
113
|
paths: [fetch_license_id]
|
@@ -257,14 +257,14 @@ interactions:
|
|
257
257
|
prompt_type: "select"
|
258
258
|
messages: ["Select the type of license below and then enter user details\n" ,
|
259
259
|
[
|
260
|
-
"1. Free License\n Validity: Unlimited\n No. of units: 10 <%= input[:unit_measure] %>\n",
|
260
|
+
"1. Free Tier License\n Validity: Unlimited\n No. of units: 10 <%= input[:unit_measure] %>\n",
|
261
261
|
"2. Commercial License\n",
|
262
262
|
"3. Quit license generation"
|
263
263
|
]]
|
264
|
-
paths: [
|
264
|
+
paths: [free_trial_license_selection, commercial_license_selection, exit]
|
265
265
|
response_path_map:
|
266
|
-
"1. Free License\n Validity: Unlimited\n No. of units: 10 nodes\n":
|
267
|
-
"1. Free License\n Validity: Unlimited\n No. of units: 10 targets\n":
|
266
|
+
"1. Free Tier License\n Validity: Unlimited\n No. of units: 10 nodes\n": free_trial_license_selection
|
267
|
+
"1. Free Tier License\n Validity: Unlimited\n No. of units: 10 targets\n": free_trial_license_selection
|
268
268
|
"2. Commercial License\n": commercial_license_selection
|
269
269
|
"3. Quit license generation": exit
|
270
270
|
|
@@ -276,10 +276,10 @@ interactions:
|
|
276
276
|
"2. Commercial License\n",
|
277
277
|
"3. Quit license generation"
|
278
278
|
]]
|
279
|
-
paths: [
|
279
|
+
paths: [free_trial_license_selection, commercial_license_selection, exit]
|
280
280
|
response_path_map:
|
281
|
-
"1. Trial License\n Validity: 30 Days\n No. of units: Unlimited nodes\n":
|
282
|
-
"1. Trial License\n Validity: 30 Days\n No. of units: Unlimited targets\n":
|
281
|
+
"1. Trial License\n Validity: 30 Days\n No. of units: Unlimited nodes\n": free_trial_license_selection
|
282
|
+
"1. Trial License\n Validity: 30 Days\n No. of units: Unlimited targets\n": free_trial_license_selection
|
283
283
|
"2. Commercial License\n": commercial_license_selection
|
284
284
|
"3. Quit license generation": exit
|
285
285
|
|
@@ -287,34 +287,41 @@ interactions:
|
|
287
287
|
prompt_type: "select"
|
288
288
|
messages: ["Select the type of license below and then enter user details\n" ,
|
289
289
|
[
|
290
|
-
"1. Free License\n Validity: Unlimited\n No. of units: 10 <%= input[:unit_measure] %>\n",
|
290
|
+
"1. Free Tier License\n Validity: Unlimited\n No. of units: 10 <%= input[:unit_measure] %>\n",
|
291
291
|
"2. Trial License\n Validity: 30 Days\n No. of units: Unlimited <%= input[:unit_measure] %>\n",
|
292
292
|
"3. Commercial License\n",
|
293
293
|
"4. Quit license generation"
|
294
294
|
]]
|
295
|
-
paths: [
|
295
|
+
paths: [free_trial_license_selection, commercial_license_selection, exit]
|
296
296
|
response_path_map:
|
297
|
-
"1. Free License\n Validity: Unlimited\n No. of units: 10 nodes\n":
|
298
|
-
"1. Free License\n Validity: Unlimited\n No. of units: 10 targets\n":
|
299
|
-
"2. Trial License\n Validity: 30 Days\n No. of units: Unlimited nodes\n":
|
300
|
-
"2. Trial License\n Validity: 30 Days\n No. of units: Unlimited targets\n":
|
297
|
+
"1. Free Tier License\n Validity: Unlimited\n No. of units: 10 nodes\n": free_trial_license_selection
|
298
|
+
"1. Free Tier License\n Validity: Unlimited\n No. of units: 10 targets\n": free_trial_license_selection
|
299
|
+
"2. Trial License\n Validity: 30 Days\n No. of units: Unlimited nodes\n": free_trial_license_selection
|
300
|
+
"2. Trial License\n Validity: 30 Days\n No. of units: Unlimited targets\n": free_trial_license_selection
|
301
301
|
"3. Commercial License\n": commercial_license_selection
|
302
302
|
"4. Quit license generation": exit
|
303
303
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
304
|
+
# Note: The below link is specific to InSpec; as per PO there will be different link for other products.
|
305
|
+
# We need to update the link for other products once we have the link or update to a common link.
|
306
|
+
free_trial_license_selection:
|
307
|
+
messages: ["<%= input[:pastel].yellow(\"!\") %> Kindly complete the user registration at <%= input[:pastel].blue.underline.blue(\"https://www.chef.io/license-generation-free-trial\") %>\nOnce you submit the details, you will receive the license ID on the email id you provided.\n\nSelect an option",
|
308
|
+
[
|
309
|
+
Validate license now,
|
310
|
+
Quit and validate license later
|
311
|
+
]
|
312
|
+
]
|
313
|
+
prompt_type: "select"
|
314
|
+
paths: [validate_license_later_message, ask_for_license_id]
|
315
|
+
response_path_map:
|
316
|
+
"Validate license now": ask_for_license_id
|
317
|
+
"Quit and validate license later": validate_license_later_message
|
313
318
|
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
319
|
+
# TODO: Update the link for other ways to validate the license document.
|
320
|
+
validate_license_later_message:
|
321
|
+
messages: |
|
322
|
+
You can enter the license later on by selecting <%= input[:pastel].bold("'I already have a license ID'") %> when prompted for license.
|
323
|
+
To learn about more ways to enter the license, kindly visit <%= input[:pastel].blue.underline.blue("www.docs.chef.io") %>.
|
324
|
+
paths: [exit]
|
318
325
|
|
319
326
|
commercial_license_selection:
|
320
327
|
messages: ["Get in touch with the Sales Team by filling out the form available at <%= input[:pastel].blue.underline.blue(\"https://www.chef.io/contact-us\") %>\n",
|
@@ -323,213 +330,10 @@ interactions:
|
|
323
330
|
prompt_type: "select"
|
324
331
|
paths: [exit_with_message]
|
325
332
|
|
326
|
-
check_if_user_details_are_present:
|
327
|
-
action: are_user_details_present?
|
328
|
-
paths: [ask_for_user_details, print_to_review_details]
|
329
|
-
response_path_map:
|
330
|
-
"true": "print_to_review_details"
|
331
|
-
"false": "ask_for_user_details"
|
332
|
-
|
333
|
-
ask_for_user_details:
|
334
|
-
messages: |
|
335
|
-
Please enter the following details:
|
336
|
-
First Name, Last Name, Email, Company, Phone
|
337
|
-
|
338
|
-
paths: [gather_user_first_name_for_license_generation]
|
339
|
-
|
340
|
-
gather_user_first_name_for_license_generation:
|
341
|
-
messages: "Enter First Name: "
|
342
|
-
prompt_type: "ask"
|
343
|
-
paths: [validate_user_first_name_for_license_generation]
|
344
|
-
|
345
|
-
validate_user_first_name_for_license_generation:
|
346
|
-
action: is_user_name_valid?
|
347
|
-
paths: [gather_user_last_name_for_license_generation, user_first_name_validation_failure]
|
348
|
-
response_path_map:
|
349
|
-
"true": gather_user_last_name_for_license_generation
|
350
|
-
"false": user_first_name_validation_failure
|
351
|
-
|
352
|
-
user_first_name_validation_failure:
|
353
|
-
messages: "Invalid name. It should contain only A-Z/a-z alphabets."
|
354
|
-
prompt_type: "error"
|
355
|
-
paths: [gather_user_first_name_for_license_generation]
|
356
|
-
|
357
|
-
gather_user_last_name_for_license_generation:
|
358
|
-
messages: "Enter Last Name: "
|
359
|
-
prompt_type: "ask"
|
360
|
-
paths: [validate_user_last_name_for_license_generation]
|
361
|
-
|
362
|
-
validate_user_last_name_for_license_generation:
|
363
|
-
action: is_user_name_valid?
|
364
|
-
paths: [gather_user_email_for_license_generation, user_last_name_validation_failure]
|
365
|
-
response_path_map:
|
366
|
-
"true": gather_user_email_for_license_generation
|
367
|
-
"false": user_last_name_validation_failure
|
368
|
-
|
369
|
-
user_last_name_validation_failure:
|
370
|
-
messages: "Invalid name. It should contain only A-Z/a-z alphabets."
|
371
|
-
prompt_type: "error"
|
372
|
-
paths: [gather_user_last_name_for_license_generation]
|
373
|
-
|
374
|
-
gather_user_email_for_license_generation:
|
375
|
-
messages: "Enter Email Address: "
|
376
|
-
prompt_type: "ask"
|
377
|
-
paths: [validate_user_email_for_license_generation]
|
378
|
-
|
379
|
-
validate_user_email_for_license_generation:
|
380
|
-
action: is_email_valid?
|
381
|
-
paths: [gather_user_company_for_license_generation, user_email_validation_failure]
|
382
|
-
response_path_map:
|
383
|
-
"true": gather_user_company_for_license_generation
|
384
|
-
"false": user_email_validation_failure
|
385
|
-
|
386
|
-
user_email_validation_failure:
|
387
|
-
messages: "Invalid email address."
|
388
|
-
prompt_type: "error"
|
389
|
-
paths: [gather_user_email_for_license_generation]
|
390
|
-
|
391
|
-
gather_user_company_for_license_generation:
|
392
|
-
messages: "Enter Company Name: "
|
393
|
-
prompt_type: "ask"
|
394
|
-
paths: [validate_user_company_name_for_license_generation]
|
395
|
-
|
396
|
-
validate_user_company_name_for_license_generation:
|
397
|
-
action: is_company_name_valid?
|
398
|
-
paths: [gather_user_phone_no_for_license_generation, user_company_name_validation_failure]
|
399
|
-
response_path_map:
|
400
|
-
"true": gather_user_phone_no_for_license_generation
|
401
|
-
"false": user_company_name_validation_failure
|
402
|
-
|
403
|
-
user_company_name_validation_failure:
|
404
|
-
messages: "Invalid company name. It should contain only A-Z/a-z alphabets, numbers or special characters."
|
405
|
-
prompt_type: "error"
|
406
|
-
paths: [gather_user_company_for_license_generation]
|
407
|
-
|
408
|
-
gather_user_phone_no_for_license_generation:
|
409
|
-
messages: "Enter phone number: "
|
410
|
-
prompt_type: "ask"
|
411
|
-
paths: [validate_user_phone_no]
|
412
|
-
|
413
|
-
validate_user_phone_no:
|
414
|
-
action: is_phone_no_valid?
|
415
|
-
paths: [print_to_review_details, user_phone_no_validation_failure]
|
416
|
-
response_path_map:
|
417
|
-
"true": print_to_review_details
|
418
|
-
"false": user_phone_no_validation_failure
|
419
|
-
|
420
|
-
user_phone_no_validation_failure:
|
421
|
-
messages: "Please enter a valid phone number."
|
422
|
-
prompt_type: "error"
|
423
|
-
paths: [gather_user_phone_no_for_license_generation]
|
424
|
-
|
425
|
-
print_to_review_details:
|
426
|
-
messages: |
|
427
|
-
------------------------------------------------------------
|
428
|
-
Review the details below and confirm to proceed.
|
429
|
-
------------------------------------------------------------
|
430
|
-
License Details
|
431
|
-
|
432
|
-
<%= input[:free_license_selection] || input[:trial_license_selection] %>
|
433
|
-
User Details
|
434
|
-
|
435
|
-
First Name: <%= input[:gather_user_first_name_for_license_generation] %>
|
436
|
-
Last Name: <%= input[:gather_user_last_name_for_license_generation] %>
|
437
|
-
Email: <%= input[:gather_user_email_for_license_generation] %>
|
438
|
-
Company: <%= input[:gather_user_company_for_license_generation] %>
|
439
|
-
Phone number: <%= input[:gather_user_phone_no_for_license_generation] %>
|
440
|
-
------------------------------------------------------------
|
441
|
-
prompt_type: "say"
|
442
|
-
paths: [ask_for_review_confirmation]
|
443
|
-
|
444
|
-
ask_for_review_confirmation:
|
445
|
-
prompt_type: "select"
|
446
|
-
messages: ["Please select", ["Confirm the details and proceed", "Reselect the license type", "Edit user details", "Quit the license generation process"]]
|
447
|
-
paths: [pre_license_generation, clear_current_license_type_selection, ask_for_user_details, exit]
|
448
|
-
response_path_map:
|
449
|
-
"Confirm the details and proceed": pre_license_generation
|
450
|
-
"Reselect the license type": clear_current_license_type_selection
|
451
|
-
"Edit user details": ask_for_user_details
|
452
|
-
"Quit the license generation process": exit
|
453
|
-
|
454
|
-
clear_current_license_type_selection:
|
455
|
-
action: clear_license_type_selection
|
456
|
-
paths: [info_of_license_types]
|
457
|
-
|
458
|
-
pre_license_generation:
|
459
|
-
action: select_license_generation_based_on_type
|
460
|
-
paths: [generate_free_license, generate_trial_license]
|
461
|
-
response_path_map:
|
462
|
-
"free": generate_free_license
|
463
|
-
"trial": generate_trial_license
|
464
|
-
|
465
|
-
generate_free_license:
|
466
|
-
action: generate_free_license
|
467
|
-
paths: [free_license_generation_success, license_generation_failure]
|
468
|
-
response_path_map:
|
469
|
-
"true": free_license_generation_success
|
470
|
-
"false": license_generation_failure
|
471
|
-
|
472
|
-
generate_trial_license:
|
473
|
-
action: generate_trial_license
|
474
|
-
paths: [trial_license_generation_success, license_generation_failure]
|
475
|
-
response_path_map:
|
476
|
-
"true": trial_license_generation_success
|
477
|
-
"false": license_generation_failure
|
478
|
-
|
479
|
-
free_license_generation_success:
|
480
|
-
messages: |
|
481
|
-
<%= input[:pastel].green("✔ [Success] License generated successfully") %>
|
482
|
-
|
483
|
-
The license ID has been sent to <%= input[:gather_user_email_for_license_generation] %>.
|
484
|
-
paths: [ask_for_license_id]
|
485
|
-
|
486
|
-
trial_license_generation_success:
|
487
|
-
messages: |
|
488
|
-
<%= input[:pastel].green("✔ [Success] License generated successfully") %>
|
489
|
-
|
490
|
-
The license ID has been sent to <%= input[:gather_user_email_for_license_generation] %>.
|
491
|
-
paths: [ask_for_license_id]
|
492
|
-
|
493
333
|
fetch_license_id:
|
494
334
|
action: fetch_license_id
|
495
335
|
paths: [exit]
|
496
336
|
|
497
|
-
license_generation_failure:
|
498
|
-
messages: "✖ [Error] License generation failed."
|
499
|
-
prompt_type: "error"
|
500
|
-
paths: [check_failure_reason]
|
501
|
-
|
502
|
-
check_failure_reason:
|
503
|
-
action: license_generation_rejected?
|
504
|
-
paths: [fetch_license_failure_error_msg, fetch_license_failure_rejection_msg]
|
505
|
-
response_path_map:
|
506
|
-
"true": fetch_license_failure_rejection_msg
|
507
|
-
"false": fetch_license_failure_error_msg
|
508
|
-
|
509
|
-
fetch_license_failure_error_msg:
|
510
|
-
action: fetch_license_failure_error_msg
|
511
|
-
paths: [license_generation_with_errors]
|
512
|
-
|
513
|
-
fetch_license_failure_rejection_msg:
|
514
|
-
action: fetch_license_failure_rejection_msg
|
515
|
-
paths: [license_generation_rejected]
|
516
|
-
|
517
|
-
license_generation_rejected:
|
518
|
-
messages: ["Your request for a license was denied for the following reason: <%= input[:fetch_license_failure_rejection_msg] %>. Please select one of the following options:", ["Try again", "Skip"]]
|
519
|
-
prompt_type: "select"
|
520
|
-
paths: [pre_license_generation, skip_message]
|
521
|
-
response_path_map:
|
522
|
-
"Try again": pre_license_generation
|
523
|
-
"Skip": skip_message
|
524
|
-
|
525
|
-
license_generation_with_errors:
|
526
|
-
messages: ["\nAn error occurred while generating your license.\nError message: <%= input[:fetch_license_failure_error_msg] %>\n", ["Try again", "Skip"]]
|
527
|
-
prompt_type: "select"
|
528
|
-
paths: [pre_license_generation, skip_message]
|
529
|
-
response_path_map:
|
530
|
-
"Try again": pre_license_generation
|
531
|
-
"Skip": skip_message
|
532
|
-
|
533
337
|
exit:
|
534
338
|
messages: ""
|
535
339
|
|
@@ -5,6 +5,10 @@ require "date"
|
|
5
5
|
require "fileutils" unless defined?(FileUtils)
|
6
6
|
require_relative "../license_key_fetcher"
|
7
7
|
require_relative "../config"
|
8
|
+
require_relative "../exceptions/license_file_corrupted"
|
9
|
+
require_relative "license_file/v4"
|
10
|
+
require_relative "license_file/v3"
|
11
|
+
require_relative "../exceptions/invalid_file_format_version"
|
8
12
|
|
9
13
|
module ChefLicensing
|
10
14
|
class LicenseKeyFetcher
|
@@ -118,15 +122,15 @@ module ChefLicensing
|
|
118
122
|
|
119
123
|
@contents = load_license_file(license_key_file_path)
|
120
124
|
|
125
|
+
# Two possible cases:
|
126
|
+
# 1. If contents is nil, load basic license data with the latest structure.
|
127
|
+
# 2. If contents is not nil, but the license server URL in contents is different from the system's,
|
128
|
+
# update the license server URL in contents and licenses.yaml file.
|
121
129
|
if @contents.nil?
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
else
|
127
|
-
if license_server_url_from_system && license_server_url_from_system != @contents[:license_server_url]
|
128
|
-
@contents[:license_server_url] = license_server_url_from_system
|
129
|
-
end
|
130
|
+
url = license_server_url_from_system || license_server_url_from_config
|
131
|
+
load_basic_license_data_to_contents(url, [])
|
132
|
+
elsif @contents && license_server_url_from_system && license_server_url_from_system != @contents[:license_server_url]
|
133
|
+
@contents[:license_server_url] = license_server_url_from_system
|
130
134
|
end
|
131
135
|
|
132
136
|
# Ensure the license server URL is returned to the caller in all cases
|
@@ -207,11 +211,27 @@ module ChefLicensing
|
|
207
211
|
|
208
212
|
# only checking for major version for file format for breaking changes
|
209
213
|
@contents ||= YAML.load(::File.read(path))
|
214
|
+
|
215
|
+
# raise error if the file_format_version key is missing
|
216
|
+
raise LicenseFileCorrupted.new("Unrecognized license file; :file_format_version missing.") unless @contents.key?(:file_format_version)
|
217
|
+
|
218
|
+
# Three possible cases after loading the license file contents:
|
219
|
+
# 1. If the file format version is the same as the current version (latest), verify the structure and return the contents.
|
220
|
+
# 2. If the file format version is different but supported, migrate the contents to the current version and return them.
|
221
|
+
# 3. If the file format version is different and not supported, raise an error.
|
210
222
|
if major_version(@contents[:file_format_version]) == major_version(LICENSE_FILE_FORMAT_VERSION)
|
223
|
+
current_version_class_name = get_license_file_class(LICENSE_FILE_FORMAT_VERSION)
|
224
|
+
# we ignore any additional keys in the license file during verification
|
225
|
+
raise LicenseFileCorrupted.new("Invalid data found in the license file.") unless current_version_class_name.send(:verify_structure, @contents)
|
226
|
+
|
227
|
+
@contents
|
228
|
+
elsif license_file_class_exists?(@contents[:file_format_version])
|
229
|
+
@contents = migrate_license_file_content_to_current_version(@contents)
|
230
|
+
write_license_file(path) # update the license file contents to the latest version
|
211
231
|
@contents
|
212
232
|
else
|
213
233
|
logger.debug "License File version #{@contents[:file_format_version]} not supported."
|
214
|
-
raise
|
234
|
+
raise ChefLicensing::InvalidFileFormatVersion.new("Unable to read licenses. License File version #{@contents[:file_format_version]} not supported.")
|
215
235
|
end
|
216
236
|
end
|
217
237
|
|
@@ -244,11 +264,7 @@ module ChefLicensing
|
|
244
264
|
|
245
265
|
logger.debug "Loading license data to contents"
|
246
266
|
if @contents.nil? || @contents.empty? # this case is likely to happen only during testing
|
247
|
-
@
|
248
|
-
file_format_version: LICENSE_FILE_FORMAT_VERSION,
|
249
|
-
license_server_url: @license_server_url,
|
250
|
-
licenses: [license_data],
|
251
|
-
}
|
267
|
+
load_basic_license_data_to_contents(@license_server_url, [license_data])
|
252
268
|
elsif @contents[:licenses].nil?
|
253
269
|
@contents[:licenses] = [license_data]
|
254
270
|
elsif fetch_license_keys(@contents[:licenses])&.include?(license_data[:license_key])
|
@@ -270,6 +286,38 @@ module ChefLicensing
|
|
270
286
|
logger.debug "#{e.backtrace.join("\n\t")}"
|
271
287
|
e
|
272
288
|
end
|
289
|
+
|
290
|
+
# Returns the license file class for the given version.
|
291
|
+
def get_license_file_class(version)
|
292
|
+
Object.const_get("ChefLicensing::LicenseFile::V#{major_version(version)}")
|
293
|
+
end
|
294
|
+
|
295
|
+
# Returns true if the license file class for the given version exists.
|
296
|
+
def license_file_class_exists?(version)
|
297
|
+
Object.const_defined?("ChefLicensing::LicenseFile::V#{major_version(version)}")
|
298
|
+
end
|
299
|
+
|
300
|
+
# Loads the basic license data to contents in the current version's structure.
|
301
|
+
def load_basic_license_data_to_contents(url, license_data = [])
|
302
|
+
current_version_class_name = get_license_file_class(LICENSE_FILE_FORMAT_VERSION)
|
303
|
+
@contents = current_version_class_name.send(:load_primary_structure)
|
304
|
+
@contents[:file_format_version] = LICENSE_FILE_FORMAT_VERSION
|
305
|
+
@contents[:license_server_url] = url || ""
|
306
|
+
@contents[:licenses] = license_data
|
307
|
+
end
|
308
|
+
|
309
|
+
# Migrates the license file content to the current version and returns the migrated contents.
|
310
|
+
def migrate_license_file_content_to_current_version(contents)
|
311
|
+
logger.warn "License File version #{contents[:file_format_version]} is deprecated."
|
312
|
+
logger.warn "Automatically migrating license file to version #{LICENSE_FILE_FORMAT_VERSION}."
|
313
|
+
given_version_class_name = get_license_file_class(contents[:file_format_version])
|
314
|
+
# we ignore any additional keys in the license file during verification
|
315
|
+
raise LicenseFileCorrupted.new("Invalid data found in the license file.") unless given_version_class_name.send(:verify_structure, contents)
|
316
|
+
|
317
|
+
current_version_class_name = get_license_file_class(LICENSE_FILE_FORMAT_VERSION)
|
318
|
+
contents = current_version_class_name.send(:migrate_structure, contents, major_version(contents[:file_format_version]))
|
319
|
+
contents
|
320
|
+
end
|
273
321
|
end
|
274
322
|
end
|
275
323
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module ChefLicensing
|
2
|
+
module LicenseFile
|
3
|
+
class Base
|
4
|
+
EXPECTED_STRUCTURE = {
|
5
|
+
file_format_version: "0.0.0",
|
6
|
+
licenses: [
|
7
|
+
{
|
8
|
+
license_key: String,
|
9
|
+
license_type: Symbol,
|
10
|
+
update_time: String,
|
11
|
+
},
|
12
|
+
],
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
# @param [Hash] data: The data to verify
|
16
|
+
# @param [Hash] expected_structure: The structure to verify against
|
17
|
+
# @return [Boolean] true if the data matches the expected structure, false otherwise
|
18
|
+
# @note This method ignores extra keys in the data that are not in the expected structure
|
19
|
+
def self.verify_structure(data, expected_structure = self::EXPECTED_STRUCTURE)
|
20
|
+
return false unless data.is_a?(Hash)
|
21
|
+
|
22
|
+
expected_structure.each do |key, value|
|
23
|
+
return false unless data.key?(key)
|
24
|
+
|
25
|
+
if value.is_a?(Hash)
|
26
|
+
return false unless verify_structure(data[key], value)
|
27
|
+
elsif value.is_a?(Array)
|
28
|
+
return false unless data[key].is_a?(Array)
|
29
|
+
|
30
|
+
data[key].each do |item|
|
31
|
+
return false unless verify_structure(item, value[0])
|
32
|
+
end
|
33
|
+
elsif value.is_a?(Class)
|
34
|
+
return false unless data[key].is_a?(value)
|
35
|
+
else
|
36
|
+
return false unless data[key] == value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Hash] The primary structure of the license file, without nested structures
|
44
|
+
def self.load_primary_structure
|
45
|
+
expected_structure_dup = self::EXPECTED_STRUCTURE.dup
|
46
|
+
expected_structure_dup[:licenses] = []
|
47
|
+
expected_structure_dup
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Hash] The complete structure of the license file, including nested structures
|
51
|
+
def self.load_structure
|
52
|
+
self::EXPECTED_STRUCTURE
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param [Hash] contents: The contents of the license file
|
56
|
+
# @param [Integer] version: The version of the license file
|
57
|
+
# @return [Hash] The contents of the license file after migration
|
58
|
+
def self.migrate_structure(contents, version)
|
59
|
+
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
module ChefLicensing
|
4
|
+
module LicenseFile
|
5
|
+
class V3 < Base
|
6
|
+
LICENSE_FILE_FORMAT_VERSION = "3.0.0".freeze
|
7
|
+
EXPECTED_STRUCTURE = EXPECTED_STRUCTURE.merge({
|
8
|
+
file_format_version: V3::LICENSE_FILE_FORMAT_VERSION,
|
9
|
+
}).freeze
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
require_relative "../../config"
|
3
|
+
|
4
|
+
module ChefLicensing
|
5
|
+
module LicenseFile
|
6
|
+
class V4 < Base
|
7
|
+
LICENSE_FILE_FORMAT_VERSION = "4.0.0".freeze
|
8
|
+
|
9
|
+
EXPECTED_STRUCTURE = EXPECTED_STRUCTURE.merge({
|
10
|
+
file_format_version: V4::LICENSE_FILE_FORMAT_VERSION,
|
11
|
+
license_server_url: String,
|
12
|
+
}).freeze
|
13
|
+
|
14
|
+
# @param [Hash] contents: The contents of the license file
|
15
|
+
# @param [Integer] version: The version of the license file
|
16
|
+
# @return [Hash] The contents of the license file after migration
|
17
|
+
def self.migrate_structure(contents, version)
|
18
|
+
# Backwards compatibility for version 3 license files
|
19
|
+
if version == 3
|
20
|
+
contents[:license_server_url] = ChefLicensing::Config.license_server_url || ""
|
21
|
+
contents[:file_format_version] = V4::LICENSE_FILE_FORMAT_VERSION
|
22
|
+
end
|
23
|
+
contents
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -71,7 +71,9 @@ module ChefLicensing
|
|
71
71
|
|
72
72
|
unless @license_keys.empty?
|
73
73
|
# Licenses expiration check
|
74
|
-
|
74
|
+
# Client API possible errors will be handled in software entitlement check call (made after this)
|
75
|
+
# client_api_call_error is set to true when there is an error in licenses_active? call
|
76
|
+
if licenses_active? || client_api_call_error
|
75
77
|
return @license_keys
|
76
78
|
else
|
77
79
|
# Prompts if the keys are expired or expiring
|
@@ -116,6 +118,7 @@ module ChefLicensing
|
|
116
118
|
# Return keys if license keys are active and not expired or expiring
|
117
119
|
# Return keys if there is any error in /client API call, and do not block the flow.
|
118
120
|
# Client API possible errors will be handled in software entitlement check call (made after this)
|
121
|
+
# client_api_call_error is set to true when there is an error in licenses_active? call
|
119
122
|
return @license_keys if (!@license_keys.empty? && licenses_active?) || client_api_call_error
|
120
123
|
|
121
124
|
# Lowest priority is to interactively prompt if we have a TTY
|
@@ -283,7 +286,7 @@ module ChefLicensing
|
|
283
286
|
def prompt_license_addition_restricted(license_type, existing_license_keys_in_file)
|
284
287
|
logger.debug "License Key fetcher - prompting license addition restriction"
|
285
288
|
# For trial license
|
286
|
-
# TODO for
|
289
|
+
# TODO for Free Tier License
|
287
290
|
config[:start_interaction] = :prompt_license_addition_restriction
|
288
291
|
prompt_fetcher.config = config
|
289
292
|
# Existing license keys are needed to show details of existing license of license type which is restricted.
|
@@ -294,7 +297,7 @@ module ChefLicensing
|
|
294
297
|
def unrestricted_license_added?(new_keys, license_type)
|
295
298
|
if license_restricted?(license_type)
|
296
299
|
# Existing license keys of same license type are fetched to compare if old license key or a new one is added.
|
297
|
-
# However, if user is trying to add
|
300
|
+
# However, if user is trying to add Free Tier License, and user has active trial license, we fetch the trial license key
|
298
301
|
if license_type == :free && file_fetcher.user_has_active_trial_license?
|
299
302
|
existing_license_keys_in_file = file_fetcher.fetch_license_keys_based_on_type(:trial)
|
300
303
|
else
|
@@ -313,4 +316,4 @@ module ChefLicensing
|
|
313
316
|
end
|
314
317
|
end
|
315
318
|
end
|
316
|
-
end
|
319
|
+
end
|
@@ -28,8 +28,11 @@ module ChefLicensing
|
|
28
28
|
|
29
29
|
licenses_metadata.each do |license|
|
30
30
|
puts_bold "License Key : #{license.id}"
|
31
|
+
# Note: The license type is returned as "free" for Free Tier Licenses from the server.
|
32
|
+
# This is capitalized to "Free Tier" for display purposes as recommended by the product team.
|
33
|
+
license_type = license.license_type == "free" ? "Free Tier" : license.license_type.capitalize
|
31
34
|
output.puts <<~LICENSE
|
32
|
-
Type : #{
|
35
|
+
Type : #{license_type}
|
33
36
|
Status : #{license.status}
|
34
37
|
Expiration Date : #{license.expiration_date}
|
35
38
|
|
@@ -57,7 +60,10 @@ module ChefLicensing
|
|
57
60
|
def display_overview
|
58
61
|
output.puts "------------------------------------------------------------"
|
59
62
|
licenses_metadata.each do |license|
|
60
|
-
#
|
63
|
+
# Note: The license type is returned as "free" for Free Tier Licenses from the server.
|
64
|
+
# This is capitalized to "Free Tier" for display purposes as recommended by the product team.
|
65
|
+
license_type = license.license_type == "free" ? "Free Tier" : license.license_type.capitalize
|
66
|
+
# Sets the validity text for a Free Tier License as "Unlimited" and displays the number of days for others.
|
61
67
|
validity = if license.license_type == "free"
|
62
68
|
"Unlimited"
|
63
69
|
else
|
@@ -72,7 +78,7 @@ module ChefLicensing
|
|
72
78
|
#{pastel.bold("License Details")}
|
73
79
|
Asset Name : #{license.limits.first.software}
|
74
80
|
License ID : #{license.id}
|
75
|
-
Type : #{
|
81
|
+
Type : #{license_type}
|
76
82
|
Status : #{license.status.capitalize}
|
77
83
|
Validity : #{validity}
|
78
84
|
No. Of Units : #{num_of_units} #{unit_measure.capitalize.pluralize(num_of_units)}
|
@@ -22,6 +22,7 @@ module ChefLicensing
|
|
22
22
|
}.freeze
|
23
23
|
|
24
24
|
CURRENT_ENDPOINT_VERSION = 2
|
25
|
+
REQUEST_LIMIT = 5
|
25
26
|
|
26
27
|
def initialize
|
27
28
|
raise MissingAPICredentialsError, "Missing credential in config: Set in block chef_license_server or use environment variable CHEF_LICENSE_SERVER or pass through argument --chef-license-server" if ChefLicensing::Config.license_server_url.nil?
|
@@ -33,14 +34,6 @@ module ChefLicensing
|
|
33
34
|
invoke_get_api(self.class::END_POINTS[:VALIDATE], { licenseId: license, version: CURRENT_ENDPOINT_VERSION })
|
34
35
|
end
|
35
36
|
|
36
|
-
def generate_trial_license(payload)
|
37
|
-
invoke_post_api(self.class::END_POINTS[:GENERATE_TRIAL_LICENSE], payload)
|
38
|
-
end
|
39
|
-
|
40
|
-
def generate_free_license(payload)
|
41
|
-
invoke_post_api(self.class::END_POINTS[:GENERATE_FREE_LICENSE], payload)
|
42
|
-
end
|
43
|
-
|
44
37
|
def feature_by_name(payload)
|
45
38
|
invoke_post_api(self.class::END_POINTS[:FEATURE_BY_NAME], payload)
|
46
39
|
end
|
@@ -75,43 +68,71 @@ module ChefLicensing
|
|
75
68
|
|
76
69
|
# a common method to handle the get API calls
|
77
70
|
def invoke_get_api(endpoint, params = {})
|
78
|
-
|
79
|
-
|
80
|
-
end
|
71
|
+
response = invoke_api(ChefLicensing::Config.license_server_url.split(","), endpoint, :get, nil, params)
|
72
|
+
response.body
|
81
73
|
end
|
82
74
|
|
83
75
|
# a common method to handle the post API calls
|
84
76
|
def invoke_post_api(endpoint, payload, headers = {})
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
77
|
+
response = invoke_api(ChefLicensing::Config.license_server_url.split(","), endpoint, :post, payload, nil, headers)
|
78
|
+
raise RestfulClientError, format_error_from(response) unless response.success?
|
79
|
+
|
80
|
+
response.body
|
81
|
+
end
|
82
|
+
|
83
|
+
def invoke_api(urls, endpoint, http_method, payload = nil, params = {}, headers = {})
|
84
|
+
handle_connection = http_method == :get ? method(:handle_get_connection) : method(:handle_post_connection)
|
85
|
+
response = nil
|
86
|
+
attempted_urls = []
|
87
|
+
|
88
|
+
logger.warn "Only the first #{REQUEST_LIMIT} urls will be tried." if urls.size > REQUEST_LIMIT
|
89
|
+
urls.each_with_index do |url, i|
|
90
|
+
url = url.strip
|
91
|
+
attempted_urls << url
|
92
|
+
break if i == REQUEST_LIMIT - 1
|
93
|
+
|
94
|
+
logger.debug "Trying to connect to #{url}"
|
95
|
+
handle_connection.call(url) do |connection|
|
96
|
+
response = connection.send(http_method, endpoint) do |request|
|
97
|
+
request.body = payload.to_json if payload
|
98
|
+
request.params = params if params
|
99
|
+
request.headers = headers if headers
|
100
|
+
end
|
89
101
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
102
|
+
# At this point, we have a successful connection
|
103
|
+
# Update the value of license server url in config
|
104
|
+
ChefLicensing::Config.license_server_url = url
|
105
|
+
logger.debug "Connection succeeded to #{url}"
|
106
|
+
break response
|
107
|
+
rescue RestfulClientConnectionError
|
108
|
+
logger.warn "Connection failed to #{url}"
|
109
|
+
rescue URI::InvalidURIError
|
110
|
+
logger.warn "Invalid URI #{url}"
|
93
111
|
end
|
112
|
+
|
113
|
+
raise_restful_client_conn_error(attempted_urls) if response.nil?
|
114
|
+
response
|
94
115
|
end
|
95
116
|
|
96
|
-
def handle_get_connection
|
117
|
+
def handle_get_connection(url = nil)
|
97
118
|
# handle faraday errors
|
98
|
-
yield get_connection
|
119
|
+
yield get_connection(url)
|
99
120
|
rescue Faraday::ClientError => e
|
100
121
|
logger.debug "Restful Client Error #{e.message}"
|
101
122
|
raise RestfulClientError, e.message
|
102
123
|
end
|
103
124
|
|
104
|
-
def handle_post_connection
|
125
|
+
def handle_post_connection(url = nil)
|
105
126
|
# handle faraday errors
|
106
|
-
yield post_connection
|
127
|
+
yield post_connection(url)
|
107
128
|
rescue Faraday::ClientError => e
|
108
129
|
logger.debug "Restful Client Error #{e.message}"
|
109
130
|
raise RestfulClientError, e.message
|
110
131
|
end
|
111
132
|
|
112
|
-
def get_connection
|
133
|
+
def get_connection(url = nil)
|
113
134
|
store = ::ActiveSupport::Cache.lookup_store(:file_store, Dir.tmpdir)
|
114
|
-
Faraday.new(url:
|
135
|
+
Faraday.new(url: url) do |config|
|
115
136
|
config.request :json
|
116
137
|
config.response :json, parser_options: { object_class: OpenStruct }
|
117
138
|
config.use Faraday::HttpCache, shared_cache: false, logger: logger, store: store
|
@@ -120,8 +141,8 @@ module ChefLicensing
|
|
120
141
|
end
|
121
142
|
end
|
122
143
|
|
123
|
-
def post_connection
|
124
|
-
Faraday.new(url:
|
144
|
+
def post_connection(url = nil)
|
145
|
+
Faraday.new(url: url) do |config|
|
125
146
|
config.request :json
|
126
147
|
config.response :json, parser_options: { object_class: OpenStruct }
|
127
148
|
config.use Middleware::ExceptionsHandler
|
@@ -134,6 +155,19 @@ module ChefLicensing
|
|
134
155
|
|
135
156
|
error_details
|
136
157
|
end
|
158
|
+
|
159
|
+
def raise_restful_client_conn_error(urls)
|
160
|
+
error_message = <<~EOM
|
161
|
+
Unable to connect to the licensing server. #{ChefLicensing::Config.chef_product_name} requires server communication to operate.
|
162
|
+
The following URL(s) were tried:\n#{
|
163
|
+
urls.each_with_index.map do |url, index|
|
164
|
+
"#{index + 1}. #{url}"
|
165
|
+
end.join("\n")
|
166
|
+
}
|
167
|
+
EOM
|
168
|
+
|
169
|
+
raise RestfulClientConnectionError, error_message
|
170
|
+
end
|
137
171
|
end
|
138
172
|
end
|
139
173
|
end
|
@@ -8,9 +8,7 @@ module Middleware
|
|
8
8
|
def call(env)
|
9
9
|
@app.call(env)
|
10
10
|
rescue Faraday::ConnectionFailed => e
|
11
|
-
|
12
|
-
error_message = "Unable to connect to the licensing server at #{ChefLicensing::Config.license_server_url}.\nPlease check if the server is reachable and try again. #{ChefLicensing::Config.chef_product_name} requires server communication to operate."
|
13
|
-
raise ChefLicensing::RestfulClientConnectionError, error_message
|
11
|
+
raise ChefLicensing::RestfulClientConnectionError, e.message
|
14
12
|
end
|
15
13
|
end
|
16
14
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
require_relative "../license_key_validator"
|
2
|
-
require_relative "../license_key_generator"
|
3
2
|
require_relative "../exceptions/invalid_license"
|
4
|
-
require_relative "../exceptions/license_generation_failed"
|
5
|
-
require_relative "../exceptions/license_generation_rejected"
|
6
3
|
require_relative "../license_key_fetcher/base"
|
7
4
|
require_relative "../config"
|
8
5
|
require_relative "../context"
|
@@ -48,7 +45,7 @@ module ChefLicensing
|
|
48
45
|
self.license_type = get_license_type
|
49
46
|
if license_restricted?(license_type)
|
50
47
|
# Existing license keys needs to be fetcher to show details of existing license of license type which is restricted.
|
51
|
-
# However, if user is trying to add
|
48
|
+
# However, if user is trying to add Free Tier License, and user has active trial license, we fetch the trial license key
|
52
49
|
if license_type == :free && LicenseKeyFetcher::File.user_has_active_trial_license?(@opts)
|
53
50
|
existing_license_keys_in_file = LicenseKeyFetcher::File.fetch_license_keys_based_on_type(:trial, @opts)
|
54
51
|
else
|
@@ -74,62 +71,10 @@ module ChefLicensing
|
|
74
71
|
end
|
75
72
|
end
|
76
73
|
|
77
|
-
def is_user_name_valid?(input)
|
78
|
-
user_name = input[:gather_user_last_name_for_license_generation] || input[:gather_user_first_name_for_license_generation]
|
79
|
-
(user_name =~ /\A[a-zA-Z]{1,16}\Z/) == 0
|
80
|
-
end
|
81
|
-
|
82
|
-
def is_email_valid?(input)
|
83
|
-
(input[:gather_user_email_for_license_generation] =~ URI::MailTo::EMAIL_REGEXP) == 0
|
84
|
-
end
|
85
|
-
|
86
|
-
def is_company_name_valid?(input)
|
87
|
-
(input[:gather_user_company_for_license_generation] =~ /\A[a-zA-Z0-9][a-zA-Z0-9\W_]{2,15}\z/) == 0
|
88
|
-
end
|
89
|
-
|
90
|
-
def is_phone_no_valid?(input)
|
91
|
-
# No validation
|
92
|
-
# Optional field
|
93
|
-
true
|
94
|
-
end
|
95
|
-
|
96
|
-
def generate_trial_license(input)
|
97
|
-
generate_license(input, :trial)
|
98
|
-
end
|
99
|
-
|
100
|
-
def generate_free_license(input)
|
101
|
-
generate_license(input, :free)
|
102
|
-
end
|
103
|
-
|
104
74
|
def fetch_license_id(input)
|
105
75
|
license_id
|
106
76
|
end
|
107
77
|
|
108
|
-
def fetch_license_failure_error_msg(input)
|
109
|
-
error_msg
|
110
|
-
end
|
111
|
-
|
112
|
-
def fetch_license_failure_rejection_msg(input)
|
113
|
-
rejection_msg
|
114
|
-
end
|
115
|
-
|
116
|
-
def select_license_generation_based_on_type(inputs)
|
117
|
-
if inputs.key? :free_license_selection
|
118
|
-
inputs[:license_type] = :free
|
119
|
-
"free"
|
120
|
-
elsif inputs.key? :trial_license_selection
|
121
|
-
inputs[:license_type] = :trial
|
122
|
-
"trial"
|
123
|
-
else
|
124
|
-
inputs[:license_type] = :commercial
|
125
|
-
"commercial"
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def license_generation_rejected?(inputs)
|
130
|
-
!!rejection_msg
|
131
|
-
end
|
132
|
-
|
133
78
|
def fetch_invalid_license_msg(input)
|
134
79
|
invalid_license_msg
|
135
80
|
end
|
@@ -138,20 +83,6 @@ module ChefLicensing
|
|
138
83
|
ChefLicensing::ListLicenseKeys.display_overview({ license_keys: [license_id] })
|
139
84
|
end
|
140
85
|
|
141
|
-
def clear_license_type_selection(inputs)
|
142
|
-
inputs.delete(:free_license_selection)
|
143
|
-
inputs.delete(:trial_license_selection)
|
144
|
-
inputs.delete(:commercial_license_selection)
|
145
|
-
end
|
146
|
-
|
147
|
-
def are_user_details_present?(inputs)
|
148
|
-
inputs.key?(:gather_user_first_name_for_license_generation) &&
|
149
|
-
inputs.key?(:gather_user_last_name_for_license_generation) &&
|
150
|
-
inputs.key?(:gather_user_email_for_license_generation) &&
|
151
|
-
inputs.key?(:gather_user_company_for_license_generation) &&
|
152
|
-
inputs.key?(:gather_user_phone_no_for_license_generation)
|
153
|
-
end
|
154
|
-
|
155
86
|
def set_license_info(input)
|
156
87
|
self.license_id = input[:license_id]
|
157
88
|
self.license_type = input[:license_type]
|
@@ -191,28 +122,6 @@ module ChefLicensing
|
|
191
122
|
|
192
123
|
attr_accessor :opts
|
193
124
|
|
194
|
-
def generate_license(inputs, license_type)
|
195
|
-
spinner = TTY::Spinner.new(":spinner [Running] License generation in progress...", format: :dots, clear: true, output: output)
|
196
|
-
spinner.auto_spin # Start the spinner
|
197
|
-
self.license_id = ChefLicensing::LicenseKeyGenerator.send("generate_#{license_type}_license!",
|
198
|
-
first_name: inputs[:gather_user_first_name_for_license_generation],
|
199
|
-
last_name: inputs[:gather_user_last_name_for_license_generation],
|
200
|
-
email_id: inputs[:gather_user_email_for_license_generation],
|
201
|
-
product: ChefLicensing::Config.chef_product_name&.capitalize,
|
202
|
-
company: inputs[:gather_user_company_for_license_generation],
|
203
|
-
phone: inputs[:gather_user_phone_no_for_license_generation])
|
204
|
-
spinner.success # Stop the spinner
|
205
|
-
true
|
206
|
-
rescue ChefLicensing::LicenseGenerationFailed => e
|
207
|
-
spinner.error # Stop the spinner
|
208
|
-
self.error_msg = e.message
|
209
|
-
false
|
210
|
-
rescue ChefLicensing::LicenseGenerationRejected => e
|
211
|
-
spinner.error # Stop the spinner
|
212
|
-
self.rejection_msg = e.message
|
213
|
-
false
|
214
|
-
end
|
215
|
-
|
216
125
|
def get_license(license_key)
|
217
126
|
spinner = TTY::Spinner.new(":spinner [Running] License validation in progress...", format: :dots, clear: true, output: output)
|
218
127
|
spinner.auto_spin # Start the spinner
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-licensing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Inspec Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-config
|
@@ -79,9 +79,9 @@ dependencies:
|
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '7.0'
|
82
|
-
- - "
|
82
|
+
- - "<"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: 7.
|
84
|
+
version: '7.1'
|
85
85
|
type: :runtime
|
86
86
|
prerelease: false
|
87
87
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -89,9 +89,9 @@ dependencies:
|
|
89
89
|
- - "~>"
|
90
90
|
- !ruby/object:Gem::Version
|
91
91
|
version: '7.0'
|
92
|
-
- - "
|
92
|
+
- - "<"
|
93
93
|
- !ruby/object:Gem::Version
|
94
|
-
version: 7.
|
94
|
+
version: '7.1'
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
96
|
name: tty-spinner
|
97
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +114,6 @@ executables: []
|
|
114
114
|
extensions: []
|
115
115
|
extra_rdoc_files: []
|
116
116
|
files:
|
117
|
-
- LICENSE
|
118
117
|
- chef-licensing.gemspec
|
119
118
|
- lib/chef-licensing.rb
|
120
119
|
- lib/chef-licensing/api/client.rb
|
@@ -134,9 +133,9 @@ files:
|
|
134
133
|
- lib/chef-licensing/exceptions/describe_error.rb
|
135
134
|
- lib/chef-licensing/exceptions/error.rb
|
136
135
|
- lib/chef-licensing/exceptions/feature_not_entitled.rb
|
136
|
+
- lib/chef-licensing/exceptions/invalid_file_format_version.rb
|
137
137
|
- lib/chef-licensing/exceptions/invalid_license.rb
|
138
|
-
- lib/chef-licensing/exceptions/
|
139
|
-
- lib/chef-licensing/exceptions/license_generation_rejected.rb
|
138
|
+
- lib/chef-licensing/exceptions/license_file_corrupted.rb
|
140
139
|
- lib/chef-licensing/exceptions/list_licenses_error.rb
|
141
140
|
- lib/chef-licensing/exceptions/missing_api_credentials_error.rb
|
142
141
|
- lib/chef-licensing/exceptions/restful_client_connection_error.rb
|
@@ -147,8 +146,10 @@ files:
|
|
147
146
|
- lib/chef-licensing/license_key_fetcher/base.rb
|
148
147
|
- lib/chef-licensing/license_key_fetcher/chef_licensing_interactions.yaml
|
149
148
|
- lib/chef-licensing/license_key_fetcher/file.rb
|
149
|
+
- lib/chef-licensing/license_key_fetcher/license_file/base.rb
|
150
|
+
- lib/chef-licensing/license_key_fetcher/license_file/v3.rb
|
151
|
+
- lib/chef-licensing/license_key_fetcher/license_file/v4.rb
|
150
152
|
- lib/chef-licensing/license_key_fetcher/prompt.rb
|
151
|
-
- lib/chef-licensing/license_key_generator.rb
|
152
153
|
- lib/chef-licensing/license_key_validator.rb
|
153
154
|
- lib/chef-licensing/licensing_service/local.rb
|
154
155
|
- lib/chef-licensing/list_license_keys.rb
|
@@ -165,7 +166,7 @@ files:
|
|
165
166
|
- lib/chef-licensing/version.rb
|
166
167
|
homepage: https://github.com/chef/chef-licensing
|
167
168
|
licenses:
|
168
|
-
-
|
169
|
+
- Apache-2.0
|
169
170
|
metadata:
|
170
171
|
homepage_uri: https://github.com/chef/chef-licensing
|
171
172
|
source_code_uri: https://github.com/chef/chef-licensing
|
data/LICENSE
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Proprietary code. All rights reserved.
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require_relative "restful_client/v1"
|
2
|
-
require_relative "exceptions/license_generation_failed"
|
3
|
-
|
4
|
-
module ChefLicensing
|
5
|
-
class LicenseKeyGenerator
|
6
|
-
attr_reader :payload
|
7
|
-
|
8
|
-
class << self
|
9
|
-
# @param [Hash] KWARGS keys accepted are [first_name, last_name, email_id, product, company, phone]
|
10
|
-
def generate_trial_license!(kwargs)
|
11
|
-
new(kwargs).generate_trial_license!
|
12
|
-
end
|
13
|
-
|
14
|
-
def generate_free_license!(kwargs)
|
15
|
-
new(kwargs).generate_free_license!
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(kwargs, restful_client: ChefLicensing::RestfulClient::V1)
|
20
|
-
# TODO: validate kwargs
|
21
|
-
@payload = build_payload_from(kwargs)
|
22
|
-
@restful_client = restful_client.new
|
23
|
-
end
|
24
|
-
|
25
|
-
def generate_trial_license!
|
26
|
-
response = @restful_client.generate_trial_license(payload)
|
27
|
-
# need some logic around delivery
|
28
|
-
# how the delivery is decided?
|
29
|
-
response.licenseId
|
30
|
-
rescue RestfulClientError => e
|
31
|
-
raise ChefLicensing::LicenseGenerationFailed, e.message
|
32
|
-
end
|
33
|
-
|
34
|
-
def generate_free_license!
|
35
|
-
response = @restful_client.generate_free_license(payload)
|
36
|
-
response.licenseId
|
37
|
-
rescue RestfulClientError => e
|
38
|
-
raise ChefLicensing::LicenseGenerationFailed, e.message
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def build_payload_from(kwargs)
|
44
|
-
kwargs.slice(:first_name, :last_name, :email_id, :product, :company, :phone)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|