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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: daba1b4af5298de677c11ea6bdfa10fe560e94f3dc26ba60e68f887be5d3d187
4
- data.tar.gz: c45e92d1bba749e0aff95328df2b35bcba959022584cc07ad2e475f8a89be945
3
+ metadata.gz: 1bc6490da547bbded96f9eae129f488d1be7178feae66dc02dad8acba71fff0b
4
+ data.tar.gz: 16f191bd6102f08be159bb73c88f1e992657e829248b54ecdd0c5743982f65d2
5
5
  SHA512:
6
- metadata.gz: c0ff4a1cf85a1155badc2f18f1e31be42745c8952c495b87ab9af8067d13a3b2568e009c6a9bb0b1abf7812317994cf38d388c0220673e0a2027b590dbab26a8
7
- data.tar.gz: bf7296fdb8806695442b1b19d9968853984def094d126134e03774ec9bfed481cf8a66306848743a8b2c970f35b05dc6708583fe01a8222907435ce96da96ec2
6
+ metadata.gz: 873ad985ccfc6cf42478d5e0deceb001d85f6ed74d6b62b0bb9355db66da9ad7f707f5a3d1f2aa2cece612f688321757d8c406c331c8e8ab543d1c12fbe4b794
7
+ data.tar.gz: 155632f6ced920a84a6700c58bad75534e34c85fbf10b4f262b5cea030fecb291de9e429e41b4108b17e97e6f3ba744bc8cefbb1b15729a43bf89e75a0e8656f
@@ -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 = "LicenseRef-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
- spec.add_dependency "activesupport", "~> 7.0", ">= 7.0.4.2"
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
@@ -0,0 +1,10 @@
1
+ require_relative "error"
2
+
3
+ module ChefLicensing
4
+ class InvalidFileFormatVersion < Error
5
+ def message
6
+ super || "Invalid File Format Version"
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,9 @@
1
+ require_relative "error"
2
+
3
+ module ChefLicensing
4
+ class LicenseFileCorrupted < Error
5
+ def message
6
+ super || "License file contents are corrupted"
7
+ end
8
+ end
9
+ 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("supportlink.chef.io")%> portal.
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: [free_license_disclaimer, commercial_license_selection, exit]
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": free_license_disclaimer
267
- "1. Free License\n Validity: Unlimited\n No. of units: 10 targets\n": free_license_disclaimer
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: [trial_license_selection, commercial_license_selection, exit]
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": trial_license_selection
282
- "1. Trial License\n Validity: 30 Days\n No. of units: Unlimited targets\n": trial_license_selection
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: [free_license_disclaimer, commercial_license_selection, trial_license_selection, exit]
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": free_license_disclaimer
298
- "1. Free License\n Validity: Unlimited\n No. of units: 10 targets\n": free_license_disclaimer
299
- "2. Trial License\n Validity: 30 Days\n No. of units: Unlimited nodes\n": trial_license_selection
300
- "2. Trial License\n Validity: 30 Days\n No. of units: Unlimited targets\n": trial_license_selection
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
- free_license_disclaimer:
305
- messages: '<%= input[:pastel].bold("A Free License can be used for personal, non-commercial use only.\n")%>'
306
- prompt_type: "warn"
307
- paths: [free_license_selection]
308
-
309
- free_license_selection:
310
- messages: "Type: Free License\n Validity: Unlimited\n No. of units: 10 <%= input[:unit_measure] %>\n"
311
- prompt_type: "silent"
312
- paths: [check_if_user_details_are_present]
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
- trial_license_selection:
315
- messages: "Type: Trial License\n Validity: 30 days\n No. of units: Unlimited <%= input[:unit_measure] %>\n"
316
- prompt_type: "silent"
317
- paths: [check_if_user_details_are_present]
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
- @contents = {
123
- file_format_version: LICENSE_FILE_FORMAT_VERSION,
124
- license_server_url: license_server_url_from_system || license_server_url_from_config,
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 LicenseKeyNotFetchedError.new("License File version #{@contents[:file_format_version]} not supported.")
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
- @contents = {
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
- if licenses_active?
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 free license
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 free license, and user has active trial license, we fetch the trial license key
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 : #{license.license_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
- # Sets the validity text for a free license as "Unlimited" and displays the number of days for others.
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 : #{license.license_type.capitalize}
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
- handle_get_connection do |connection|
79
- connection.get(endpoint, params).body
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
- handle_post_connection do |connection|
86
- response = connection.post(endpoint) do |request|
87
- request.body = payload.to_json
88
- request.headers = headers
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
- raise RestfulClientError, format_error_from(response) unless response.success?
91
-
92
- response.body
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: ChefLicensing::Config.license_server_url) do |config|
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: ChefLicensing::Config.license_server_url) do |config|
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
- ChefLicensing::Config.logger.debug("Connection failed to #{ChefLicensing::Config.license_server_url} with error: #{e.message}")
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
@@ -6,8 +6,6 @@ module ChefLicensing
6
6
  class V1 < Base
7
7
  END_POINTS = END_POINTS.merge({
8
8
  VALIDATE: "v1/validate",
9
- GENERATE_TRIAL_LICENSE: "v1/trial",
10
- GENERATE_FREE_LICENSE: "v1/free",
11
9
  CLIENT: "v1/client",
12
10
  DESCRIBE: "v1/desc",
13
11
  LIST_LICENSES: "v1/listLicenses",
@@ -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 free license, and user has active trial license, we fetch the trial license key
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
@@ -1,3 +1,3 @@
1
1
  module ChefLicensing
2
- VERSION = "0.4.44".freeze
2
+ VERSION = "0.7.5".freeze
3
3
  end
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.44
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-07-11 00:00:00.000000000 Z
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.0.4.2
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.0.4.2
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/license_generation_failed.rb
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
- - LicenseRef-LICENSE
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,9 +0,0 @@
1
- require_relative "error"
2
-
3
- module ChefLicensing
4
- class LicenseGenerationFailed < Error
5
- def message
6
- super || "License Generation Failed"
7
- end
8
- end
9
- end
@@ -1,7 +0,0 @@
1
- module ChefLicensing
2
- class LicenseGenerationRejected < Error
3
- def message
4
- super || "License Generation Rejected"
5
- end
6
- end
7
- end
@@ -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