chef-licensing 0.4.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +1 -0
  3. data/chef-licensing.gemspec +35 -0
  4. data/lib/chef-licensing/api/client.rb +39 -0
  5. data/lib/chef-licensing/api/describe.rb +62 -0
  6. data/lib/chef-licensing/api/license_feature_entitlement.rb +55 -0
  7. data/lib/chef-licensing/api/license_software_entitlement.rb +53 -0
  8. data/lib/chef-licensing/api/list_licenses.rb +30 -0
  9. data/lib/chef-licensing/api/parser/client.rb +100 -0
  10. data/lib/chef-licensing/api/parser/describe.rb +118 -0
  11. data/lib/chef-licensing/cli_flags/mixlib_cli.rb +28 -0
  12. data/lib/chef-licensing/cli_flags/thor.rb +21 -0
  13. data/lib/chef-licensing/config.rb +44 -0
  14. data/lib/chef-licensing/config_fetcher/arg_fetcher.rb +38 -0
  15. data/lib/chef-licensing/config_fetcher/env_fetcher.rb +21 -0
  16. data/lib/chef-licensing/context.rb +98 -0
  17. data/lib/chef-licensing/exceptions/client_error.rb +9 -0
  18. data/lib/chef-licensing/exceptions/describe_error.rb +9 -0
  19. data/lib/chef-licensing/exceptions/error.rb +4 -0
  20. data/lib/chef-licensing/exceptions/feature_not_entitled.rb +9 -0
  21. data/lib/chef-licensing/exceptions/invalid_license.rb +10 -0
  22. data/lib/chef-licensing/exceptions/license_generation_failed.rb +9 -0
  23. data/lib/chef-licensing/exceptions/license_generation_rejected.rb +7 -0
  24. data/lib/chef-licensing/exceptions/list_licenses_error.rb +12 -0
  25. data/lib/chef-licensing/exceptions/missing_api_credentials_error.rb +7 -0
  26. data/lib/chef-licensing/exceptions/restful_client_connection_error.rb +9 -0
  27. data/lib/chef-licensing/exceptions/restful_client_error.rb +9 -0
  28. data/lib/chef-licensing/exceptions/software_not_entitled.rb +9 -0
  29. data/lib/chef-licensing/license.rb +151 -0
  30. data/lib/chef-licensing/license_key_fetcher/base.rb +28 -0
  31. data/lib/chef-licensing/license_key_fetcher/chef_licensing_interactions.yaml +534 -0
  32. data/lib/chef-licensing/license_key_fetcher/file.rb +275 -0
  33. data/lib/chef-licensing/license_key_fetcher/prompt.rb +43 -0
  34. data/lib/chef-licensing/license_key_fetcher.rb +314 -0
  35. data/lib/chef-licensing/license_key_generator.rb +47 -0
  36. data/lib/chef-licensing/license_key_validator.rb +24 -0
  37. data/lib/chef-licensing/licensing_service/local.rb +29 -0
  38. data/lib/chef-licensing/list_license_keys.rb +142 -0
  39. data/lib/chef-licensing/restful_client/base.rb +139 -0
  40. data/lib/chef-licensing/restful_client/middleware/exceptions_handler.rb +16 -0
  41. data/lib/chef-licensing/restful_client/v1.rb +17 -0
  42. data/lib/chef-licensing/tui_engine/tui_actions.rb +238 -0
  43. data/lib/chef-licensing/tui_engine/tui_engine.rb +174 -0
  44. data/lib/chef-licensing/tui_engine/tui_engine_state.rb +62 -0
  45. data/lib/chef-licensing/tui_engine/tui_exceptions.rb +17 -0
  46. data/lib/chef-licensing/tui_engine/tui_interaction.rb +17 -0
  47. data/lib/chef-licensing/tui_engine/tui_prompt.rb +117 -0
  48. data/lib/chef-licensing/tui_engine.rb +2 -0
  49. data/lib/chef-licensing/version.rb +3 -0
  50. data/lib/chef-licensing.rb +70 -0
  51. metadata +191 -0
@@ -0,0 +1,24 @@
1
+ require_relative "restful_client/v1"
2
+ require_relative "exceptions/invalid_license"
3
+
4
+ module ChefLicensing
5
+ class LicenseKeyValidator
6
+ attr_reader :license
7
+
8
+ class << self
9
+ def validate!(license)
10
+ new(license).validate!
11
+ end
12
+ end
13
+
14
+ def initialize(license, restful_client: ChefLicensing::RestfulClient::V1)
15
+ @license = license || raise(ArgumentError, "Missing Params: `license`")
16
+ @restful_client = restful_client.new
17
+ end
18
+
19
+ def validate!
20
+ response = @restful_client.validate(license)
21
+ response.data || raise(ChefLicensing::InvalidLicense, response.message)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "../config"
2
+ require_relative "../api/list_licenses"
3
+ require_relative "../exceptions/list_licenses_error"
4
+
5
+ module ChefLicensing
6
+ class LicensingService
7
+ class Local
8
+ attr_reader :logger
9
+
10
+ class << self
11
+ def detected?
12
+ new.detected?
13
+ end
14
+ end
15
+
16
+ def detected?
17
+ return ChefLicensing::Config.is_local_license_service if ChefLicensing::Config.is_local_license_service
18
+
19
+ ChefLicensing::Api::ListLicenses.info
20
+ true
21
+ rescue ChefLicensing::ListLicensesError => e
22
+ # If API call returns 404, it is a global licensing service
23
+ return false if e.status_code == 404
24
+
25
+ raise(ChefLicensing::ListLicensesError.new("Error occured while fetching licenses #{e.message}", e.status_code))
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,142 @@
1
+ require_relative "license_key_fetcher"
2
+ require_relative "api/describe"
3
+ require_relative "exceptions/describe_error"
4
+ require "pastel" unless defined?(Pastel)
5
+ require_relative "config"
6
+
7
+ module ChefLicensing
8
+ class ListLicenseKeys
9
+ def self.display(opts = {})
10
+ new(opts).display
11
+ end
12
+
13
+ def self.display_overview(opts = {})
14
+ new(opts).display_overview
15
+ end
16
+
17
+ def initialize(opts = {})
18
+ @logger = ChefLicensing::Config.logger
19
+ @output = ChefLicensing::Config.output
20
+ @pastel = Pastel.new
21
+ @license_keys = fetch_license_keys(opts)
22
+ @licenses_metadata = fetch_licenses_metadata
23
+ end
24
+
25
+ def display
26
+ output.puts "+------------ License Information ------------+"
27
+ output.puts "Total Licenses found: #{licenses_metadata.length}\n\n"
28
+
29
+ licenses_metadata.each do |license|
30
+ puts_bold "License Key : #{license.id}"
31
+ output.puts <<~LICENSE
32
+ Type : #{license.license_type}
33
+ Status : #{license.status}
34
+ Expiration Date : #{license.expiration_date}
35
+
36
+ LICENSE
37
+
38
+ iterate_attributes(license.software_entitlements, "Software Entitlements")
39
+ iterate_attributes(license.asset_entitlements, "Asset Entitlements")
40
+ iterate_attributes(license.feature_entitlements, "Feature Entitlements")
41
+
42
+ puts_bold "License Limits"
43
+ license.limits.each do |limit|
44
+ usage_limit = limit.usage_limit == -1 ? "Unlimited" : limit.usage_limit
45
+ output.puts <<~LIMIT
46
+ Usage Status : #{limit.usage_status}
47
+ Usage Limit : #{usage_limit}
48
+ Usage Measure : #{limit.usage_measure}
49
+ Used : #{limit.used}
50
+ Software : #{limit.software}
51
+ LIMIT
52
+ end
53
+ output.puts "+----------------------------------------------+"
54
+ end
55
+ end
56
+
57
+ def display_overview
58
+ output.puts "------------------------------------------------------------"
59
+ licenses_metadata.each do |license|
60
+ # Sets the validity text for a free license as "Unlimited" and displays the number of days for others.
61
+ validity = if license.license_type == "free"
62
+ "Unlimited"
63
+ else
64
+ # find the number of days left for the license to expire
65
+ days = (Date.parse(license.expiration_date) - Date.today).to_i
66
+ "#{days > 0 ? days : 0} #{"Day".pluralize(days)}"
67
+ end
68
+ num_of_units = license.limits&.first&.usage_limit || 0
69
+ num_of_units = num_of_units == -1 ? "Unlimited" : num_of_units
70
+ unit_measure = license.limits&.first&.usage_measure || "unit"
71
+ output.puts <<~LICENSE
72
+ #{pastel.bold("License Details")}
73
+ Asset Name : #{license.limits.first.software}
74
+ License ID : #{license.id}
75
+ Type : #{license.license_type.capitalize}
76
+ Status : #{license.status.capitalize}
77
+ Validity : #{validity}
78
+ No. Of Units : #{num_of_units} #{unit_measure.capitalize.pluralize(num_of_units)}
79
+ ------------------------------------------------------------
80
+ LICENSE
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ attr_reader :pastel, :output, :logger, :license_keys, :licenses_metadata
87
+
88
+ def display_info(component)
89
+ output.puts <<~INFO
90
+ ID : #{component.id}
91
+ Name : #{component.name}
92
+ Status : #{component.status}
93
+ Entitled : #{component.entitled}
94
+ INFO
95
+ output.puts "\n"
96
+ end
97
+
98
+ def iterate_attributes(component, header)
99
+ puts_bold header
100
+ puts "No #{header.downcase} found.\n\n" if component.empty?
101
+ component.each do |attribute|
102
+ display_info(attribute)
103
+ end
104
+ end
105
+
106
+ def puts_bold(title)
107
+ output.puts pastel.bold(title)
108
+ end
109
+
110
+ def fetch_license_keys(opts = {})
111
+ license_keys = opts[:license_keys] || ChefLicensing::LicenseKeyFetcher.fetch({ dir: opts[:dir] })
112
+
113
+ if license_keys.empty?
114
+ logger.debug "No license keys found on disk."
115
+ output.puts "No license keys found on disk."
116
+ exit
117
+ end
118
+ logger.debug "License keys fetched from disk: #{license_keys}"
119
+
120
+ license_keys
121
+ rescue ChefLicensing::LicenseKeyFetcher::LicenseKeyNotFetchedError => e
122
+ logger.debug "Error occured while fetching license keys from disk: #{e.message}"
123
+ output.puts "Error occured while fetching license keys from disk: #{e.message}"
124
+ # TODO: Exit with a non-zero status code
125
+ exit
126
+ end
127
+
128
+ def fetch_licenses_metadata
129
+ licenses_metadata = ChefLicensing::Api::Describe.list({
130
+ license_keys: license_keys,
131
+ })
132
+ logger.debug "License metadata fetched from server: #{licenses_metadata}"
133
+
134
+ licenses_metadata
135
+ rescue ChefLicensing::DescribeError => e
136
+ logger.debug "Error occured while fetching license information: #{e.message}"
137
+ output.puts "Error occured while fetching license information: #{e.message}"
138
+ # TODO: Exit with a non-zero status code
139
+ exit
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,139 @@
1
+ require "faraday" unless defined?(Faraday)
2
+ require "faraday/http_cache"
3
+ require "active_support"
4
+ require "tmpdir" unless defined?(Dir.mktmpdir)
5
+ require_relative "../exceptions/restful_client_error"
6
+ require_relative "../exceptions/restful_client_connection_error"
7
+ require_relative "../exceptions/missing_api_credentials_error"
8
+ require_relative "../config"
9
+ require_relative "middleware/exceptions_handler"
10
+
11
+ module ChefLicensing
12
+ module RestfulClient
13
+
14
+ # Base class to handle all License Server endpoints
15
+ class Base
16
+
17
+ END_POINTS = {
18
+ FEATURE_BY_NAME: "license-service/featurebyname",
19
+ FEATURE_BY_ID: "license-service/featurebyid",
20
+ ENTITLEMENT_BY_NAME: "license-service/entitlementbyname",
21
+ ENTITLEMENT_BY_ID: "license-service/entitlementbyid",
22
+ }.freeze
23
+
24
+ CURRENT_ENDPOINT_VERSION = 2
25
+
26
+ def initialize
27
+ 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?
28
+
29
+ @logger = ChefLicensing::Config.logger
30
+ end
31
+
32
+ def validate(license)
33
+ invoke_get_api(self.class::END_POINTS[:VALIDATE], { licenseId: license, version: CURRENT_ENDPOINT_VERSION })
34
+ end
35
+
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
+ def feature_by_name(payload)
45
+ invoke_post_api(self.class::END_POINTS[:FEATURE_BY_NAME], payload)
46
+ end
47
+
48
+ def feature_by_id(payload)
49
+ invoke_post_api(self.class::END_POINTS[:FEATURE_BY_ID], payload)
50
+ end
51
+
52
+ def entitlement_by_name(payload)
53
+ invoke_post_api(self.class::END_POINTS[:ENTITLEMENT_BY_NAME], payload)
54
+ end
55
+
56
+ def entitlement_by_id(payload)
57
+ invoke_post_api(self.class::END_POINTS[:ENTITLEMENT_BY_ID], payload)
58
+ end
59
+
60
+ def client(params = {})
61
+ invoke_get_api(self.class::END_POINTS[:CLIENT], { licenseId: params[:license_keys], entitlementId: params[:entitlement_id] })
62
+ end
63
+
64
+ def describe(params = {})
65
+ invoke_get_api(self.class::END_POINTS[:DESCRIBE], { licenseId: params[:license_keys], entitlementId: params[:entitlement_id] })
66
+ end
67
+
68
+ def list_licenses(params = {})
69
+ invoke_get_api(self.class::END_POINTS[:LIST_LICENSES])
70
+ end
71
+
72
+ private
73
+
74
+ attr_reader :logger
75
+
76
+ # a common method to handle the get API calls
77
+ def invoke_get_api(endpoint, params = {})
78
+ handle_get_connection do |connection|
79
+ connection.get(endpoint, params).body
80
+ end
81
+ end
82
+
83
+ # a common method to handle the post API calls
84
+ 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
89
+ end
90
+ raise RestfulClientError, format_error_from(response) unless response.success?
91
+
92
+ response.body
93
+ end
94
+ end
95
+
96
+ def handle_get_connection
97
+ # handle faraday errors
98
+ yield get_connection
99
+ rescue Faraday::ClientError => e
100
+ logger.debug "Restful Client Error #{e.message}"
101
+ raise RestfulClientError, e.message
102
+ end
103
+
104
+ def handle_post_connection
105
+ # handle faraday errors
106
+ yield post_connection
107
+ rescue Faraday::ClientError => e
108
+ logger.debug "Restful Client Error #{e.message}"
109
+ raise RestfulClientError, e.message
110
+ end
111
+
112
+ def get_connection
113
+ store = ::ActiveSupport::Cache.lookup_store(:file_store, Dir.tmpdir)
114
+ Faraday.new(url: ChefLicensing::Config.license_server_url) do |config|
115
+ config.request :json
116
+ config.response :json, parser_options: { object_class: OpenStruct }
117
+ config.use Faraday::HttpCache, shared_cache: false, logger: logger, store: store
118
+ config.use Middleware::ExceptionsHandler
119
+ config.adapter Faraday.default_adapter
120
+ end
121
+ end
122
+
123
+ def post_connection
124
+ Faraday.new(url: ChefLicensing::Config.license_server_url) do |config|
125
+ config.request :json
126
+ config.response :json, parser_options: { object_class: OpenStruct }
127
+ config.use Middleware::ExceptionsHandler
128
+ end
129
+ end
130
+
131
+ def format_error_from(response)
132
+ error_details = response.body&.data&.error
133
+ return response.reason_phrase unless error_details
134
+
135
+ error_details
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,16 @@
1
+ require "faraday" unless defined?(Faraday)
2
+ require "faraday/middleware"
3
+ require_relative "../../../chef-licensing/exceptions/restful_client_connection_error"
4
+
5
+ module Middleware
6
+ # Middleware that handles the exception handler for chef licensing
7
+ class ExceptionsHandler < Faraday::Middleware
8
+ def call(env)
9
+ @app.call(env)
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
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "base"
2
+
3
+ module ChefLicensing
4
+ module RestfulClient
5
+ # Client that handles all License Server V1 endpoints
6
+ class V1 < Base
7
+ END_POINTS = END_POINTS.merge({
8
+ VALIDATE: "v1/validate",
9
+ GENERATE_TRIAL_LICENSE: "v1/trial",
10
+ GENERATE_FREE_LICENSE: "v1/free",
11
+ CLIENT: "v1/client",
12
+ DESCRIBE: "v1/desc",
13
+ LIST_LICENSES: "v1/listLicenses",
14
+ }).freeze
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,238 @@
1
+ require_relative "../license_key_validator"
2
+ require_relative "../license_key_generator"
3
+ require_relative "../exceptions/invalid_license"
4
+ require_relative "../exceptions/license_generation_failed"
5
+ require_relative "../exceptions/license_generation_rejected"
6
+ require_relative "../license_key_fetcher/base"
7
+ require_relative "../config"
8
+ require_relative "../context"
9
+ require_relative "../list_license_keys"
10
+ require "tty-spinner"
11
+
12
+ module ChefLicensing
13
+ class TUIEngine
14
+ class TUIActions
15
+ attr_accessor :logger, :output, :license_id, :error_msg, :rejection_msg, :invalid_license_msg, :license_type, :license
16
+ def initialize(opts = {})
17
+ @opts = opts
18
+ @logger = ChefLicensing::Config.logger
19
+ @output = ChefLicensing::Config.output
20
+ end
21
+
22
+ def is_license_with_valid_pattern?(input)
23
+ license_id = input[:ask_for_license_id]
24
+ input[:ask_for_license_id] = ChefLicensing::LicenseKeyFetcher::Base.verify_and_extract_license(license_id)
25
+ true
26
+ rescue ChefLicensing::LicenseKeyFetcher::Base::InvalidLicenseKeyFormat => e
27
+ output.puts e.message
28
+ logger.debug e.message
29
+ false
30
+ end
31
+
32
+ def is_license_valid_on_server?(input)
33
+ license_id = input[:ask_for_license_id]
34
+ spinner = TTY::Spinner.new(":spinner [Running] License validation in progress...", format: :dots, clear: true, output: output)
35
+ spinner.auto_spin # Start the spinner
36
+ is_valid = ChefLicensing::LicenseKeyValidator.validate!(license_id)
37
+ spinner.success # Stop the spinner
38
+ self.license_id = license_id
39
+ is_valid
40
+ rescue ChefLicensing::InvalidLicense => e
41
+ spinner.error # Stop the spinner
42
+ self.invalid_license_msg = e.message || "Something went wrong while validating the license"
43
+ false
44
+ end
45
+
46
+ def is_license_allowed?(input)
47
+ client_api_call(license_id)
48
+ self.license_type = get_license_type
49
+ if license_restricted?(license_type)
50
+ # 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
52
+ if license_type == :free && LicenseKeyFetcher::File.user_has_active_trial_license?(@opts)
53
+ existing_license_keys_in_file = LicenseKeyFetcher::File.fetch_license_keys_based_on_type(:trial, @opts)
54
+ else
55
+ existing_license_keys_in_file = LicenseKeyFetcher::File.fetch_license_keys_based_on_type(license_type, @opts)
56
+ end
57
+ self.license_id = existing_license_keys_in_file.last
58
+ false
59
+ else
60
+ true
61
+ end
62
+ end
63
+
64
+ def license_expiration_status?(input)
65
+ get_license(license_id)
66
+ if license.expired? || license.have_grace?
67
+ ChefLicensing::Context.local_licensing_service? ? "expired_in_local_mode" : "expired"
68
+ elsif license.about_to_expire?
69
+ input[:license_expiration_date] = Date.parse(license.expiration_date).strftime("%a, %d %b %Y")
70
+ input[:number_of_days_in_expiration] = license.number_of_days_in_expiration
71
+ "about_to_expire"
72
+ else
73
+ "active"
74
+ end
75
+ end
76
+
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
+ def fetch_license_id(input)
105
+ license_id
106
+ end
107
+
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
+ def fetch_invalid_license_msg(input)
134
+ invalid_license_msg
135
+ end
136
+
137
+ def display_license_info(inputs)
138
+ ChefLicensing::ListLicenseKeys.display_overview({ license_keys: [license_id] })
139
+ end
140
+
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
+ def set_license_info(input)
156
+ self.license_id = input[:license_id]
157
+ self.license_type = input[:license_type]
158
+ end
159
+
160
+ def determine_restriction_type(input)
161
+ if license_type == :free && LicenseKeyFetcher::File.user_has_active_trial_license?(@opts)
162
+ "active_trial_restriction"
163
+ else
164
+ "#{license_type}_restriction"
165
+ end
166
+ end
167
+
168
+ def fetch_license_type_restricted(inputs)
169
+ if license_restricted?(:trial) && license_restricted?(:free)
170
+ "trial_and_free"
171
+ elsif license_restricted?(:trial)
172
+ "trial"
173
+ else
174
+ "free"
175
+ end
176
+ end
177
+
178
+ def filter_license_type_options(inputs)
179
+ if (license_restricted?(:trial) && license_restricted?(:free)) || LicenseKeyFetcher::File.user_has_active_trial_license?(@opts)
180
+ "ask_for_commercial_only"
181
+ elsif license_restricted?(:trial)
182
+ "ask_for_license_except_trial"
183
+ elsif license_restricted?(:free)
184
+ "ask_for_license_except_free"
185
+ else
186
+ "ask_for_all_license_type"
187
+ end
188
+ end
189
+
190
+ private
191
+
192
+ attr_accessor :opts
193
+
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
+ def get_license(license_key)
217
+ spinner = TTY::Spinner.new(":spinner [Running] License validation in progress...", format: :dots, clear: true, output: output)
218
+ spinner.auto_spin # Start the spinner
219
+ client_api_call(license_key)
220
+ spinner.success # Stop the spinner
221
+ end
222
+
223
+ def client_api_call(license_key)
224
+ self.license ||= ChefLicensing.client(license_keys: [license_key])
225
+ end
226
+
227
+ def get_license_type
228
+ license.license_type.downcase.to_sym
229
+ end
230
+
231
+ def license_restricted?(license_type)
232
+ file_fetcher = LicenseKeyFetcher::File.new(@opts)
233
+ allowed_license_types = file_fetcher.fetch_allowed_license_types_for_addition
234
+ !(allowed_license_types.include? license_type)
235
+ end
236
+ end
237
+ end
238
+ end