chef-licensing 0.4.44 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|