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,174 @@
1
+ require_relative "tui_exceptions"
2
+ require_relative "tui_interaction"
3
+ require_relative "tui_engine_state"
4
+ require_relative "tui_prompt"
5
+ require_relative "tui_actions"
6
+ require_relative "../config"
7
+
8
+ module ChefLicensing
9
+ class TUIEngine
10
+
11
+ INTERACTION_FILE_FORMAT_VERSION = "1.0.0".freeze
12
+
13
+ attr_accessor :interaction_data, :tui_interactions, :opts, :logger, :prompt_methods, :action_methods, :interaction_attributes, :traversed_interaction
14
+
15
+ def initialize(opts = {})
16
+ @opts = opts
17
+ @logger = ChefLicensing::Config.logger
18
+ @tui_interactions = {}
19
+ @traversed_interaction = []
20
+ initialization_of_engine(opts[:interaction_file])
21
+ @state = ChefLicensing::TUIEngine::TUIEngineState.new(@opts)
22
+ end
23
+
24
+ def run_interaction(start_interaction_id = nil)
25
+ start_interaction_id ||= @tui_interactions.keys.first
26
+ current_interaction = @tui_interactions[start_interaction_id]
27
+
28
+ previous_interaction = nil
29
+
30
+ until current_interaction.nil? || current_interaction.id == :exit
31
+ @traversed_interaction << current_interaction.id
32
+ state.default_action(current_interaction)
33
+ previous_interaction = current_interaction
34
+ current_interaction = state.next_interaction_id.nil? ? nil : current_interaction.paths[state.next_interaction_id.to_sym]
35
+ end
36
+
37
+ # If the last interaction is not the exit interaction. Something went wrong in the flow.
38
+ # raise the message where the flow broke.
39
+ raise ChefLicensing::TUIEngine::IncompleteFlowException, "Something went wrong in the flow. The last interaction was #{previous_interaction&.id}." unless current_interaction&.id == :exit
40
+
41
+ state.default_action(current_interaction)
42
+ # remove the pastel key we used in tui engine state for styling and return the remaining parsed input
43
+ state.input.delete(:pastel)
44
+ state.input
45
+ end
46
+
47
+ def append_info_to_input(extra_info_hash)
48
+ state.append_info_to_input(extra_info_hash)
49
+ end
50
+
51
+ private
52
+
53
+ attr_accessor :state
54
+
55
+ def initialization_of_engine(interaction_file)
56
+ raise ChefLicensing::TUIEngine::MissingInteractionFile, "No interaction file found. Please provide a valid file path to continue." unless interaction_file
57
+
58
+ @interaction_data = inflate_interaction_data(interaction_file)
59
+ verify_interaction_data
60
+ store_interaction_objects
61
+ build_interaction_path
62
+ logger.debug "TUI Engine initialized."
63
+ end
64
+
65
+ def inflate_interaction_data(interaction_file)
66
+ require "yaml" unless defined?(YAML)
67
+ YAML.load_file(interaction_file)
68
+ rescue => e
69
+ raise ChefLicensing::TUIEngine::BadInteractionFile, "Unable to load interaction file: #{interaction_file}.\n#{e.message}"
70
+ end
71
+
72
+ def store_interaction_objects
73
+ unless major_version(@interaction_data[:file_format_version]) == major_version(INTERACTION_FILE_FORMAT_VERSION)
74
+ raise ChefLicensing::TUIEngine::UnsupportedInteractionFileFormat, "Unsupported interaction file format version.\nExpected #{INTERACTION_FILE_FORMAT_VERSION} but found #{@interaction_data[:file_format_version]}."
75
+ end
76
+
77
+ @interaction_data["interactions"].each do |k, opts|
78
+ opts.transform_keys!(&:to_sym)
79
+ opts.store(:id, k.to_sym)
80
+ @tui_interactions.store(k.to_sym, ChefLicensing::TUIEngine::TUIInteraction.new(opts))
81
+ end
82
+ end
83
+
84
+ def build_interaction_path
85
+ @interaction_data["interactions"].each do |k, opts|
86
+ current_interaction = @tui_interactions[k.to_sym]
87
+ opts.transform_keys!(&:to_sym)
88
+ paths = opts[:paths] || []
89
+ paths.each do |path|
90
+ current_interaction.paths.store(path.to_sym, @tui_interactions[path.to_sym])
91
+ end
92
+ end
93
+ end
94
+
95
+ def verify_interaction_data
96
+ raise ChefLicensing::TUIEngine::BadInteractionFile, "The interaction file has no data." unless @interaction_data
97
+
98
+ raise ChefLicensing::TUIEngine::BadInteractionFile, "`file_format_version` key not found in yaml file." unless @interaction_data[:file_format_version]
99
+
100
+ raise ChefLicensing::TUIEngine::BadInteractionFile, "`interactions` key not found in yaml file." unless @interaction_data["interactions"]
101
+
102
+ @interaction_data["interactions"].each do |i_id, opts|
103
+ opts.transform_keys!(&:to_sym)
104
+ verify_interaction_purpose(i_id, opts)
105
+ opts.each do |k, val|
106
+ validate_interaction_attribute(i_id, k, val)
107
+ end
108
+ end
109
+ end
110
+
111
+ def verify_interaction_purpose(i_id, opts)
112
+ # An interaction must be either action or a prompt to display messages.
113
+ unless opts[:action] || opts[:messages]
114
+ raise ChefLicensing::TUIEngine::BadInteractionFile, "No action or messages found for interaction #{i_id}.\nAdd either action or messages to the interaction."
115
+ end
116
+
117
+ # Supporting both could lead ambiguous flow in response_path_map
118
+ if opts[:action] && opts[:messages]
119
+ warning_message = "Both `action` and `messages` keys found in yaml file for interaction #{i_id}.\n`response_path_map` keys would be considered response from messages and not action.\nYour yaml file may not work as expected."
120
+ warn warning_message
121
+ end
122
+ end
123
+
124
+ def validate_interaction_attribute(i_id, k, val)
125
+ if is_valid_interaction_attribute?(k)
126
+ if k == :prompt_type && !is_valid_prompt_method?(val)
127
+ raise ChefLicensing::TUIEngine::BadInteractionFile, "Invalid value `#{val}` for `prompt_type` key in yaml file for interaction #{i_id}."
128
+ elsif k == :action && !is_valid_action_method?(val)
129
+ raise ChefLicensing::TUIEngine::BadInteractionFile, "Invalid value `#{val}` for `action` key in yaml file for interaction #{i_id}."
130
+ end
131
+ else
132
+ warning_message = "Invalid key `#{k}` found in yaml file for interaction #{i_id}.\nValid keys are #{@interaction_attributes.join(", ")}.\n#{k} will be ignored.\nYour yaml file may not work as expected."
133
+ warn warning_message
134
+ end
135
+ end
136
+
137
+ def is_valid_prompt_method?(val)
138
+ @prompt_methods ||= begin
139
+ # Find the getter methods of TUIPrompt class
140
+ prompt_getter = ChefLicensing::TUIEngine::TUIPrompt.new.instance_variables.map { |var| var.to_s.delete("@").to_sym }
141
+
142
+ # Find the setter methods of TUIPrompt class
143
+ prompt_setter = prompt_getter.map { |attr| "#{attr}=".to_sym }
144
+
145
+ # Subtract the getter and setter of TUIPrompt class from the instance methods of TUIPrompt class
146
+ ChefLicensing::TUIEngine::TUIPrompt.instance_methods(false) - prompt_getter - prompt_setter
147
+ end
148
+ @prompt_methods.include?(val.to_sym)
149
+ end
150
+
151
+ def is_valid_action_method?(val)
152
+ @action_methods ||= begin
153
+ # Find the getter methods of TUIActions class
154
+ action_getter = ChefLicensing::TUIEngine::TUIActions.new.instance_variables.map { |var| var.to_s.delete("@").to_sym }
155
+
156
+ # Find the setter methods of TUIActions class
157
+ action_setter = action_getter.map { |attr| "#{attr}=".to_sym }
158
+
159
+ # Subtract the getter and setter of TUIActions class from the instance methods of TUIActions class
160
+ ChefLicensing::TUIEngine::TUIActions.instance_methods(false) - action_getter - action_setter
161
+ end
162
+ @action_methods.include?(val.to_sym)
163
+ end
164
+
165
+ def is_valid_interaction_attribute?(val)
166
+ @interaction_attributes ||= ChefLicensing::TUIEngine::TUIInteraction.new.instance_variables.map { |var| var.to_s.delete("@").to_sym }
167
+ @interaction_attributes.include?(val.to_sym)
168
+ end
169
+
170
+ def major_version(version)
171
+ Gem::Version.new(version).segments[0]
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,62 @@
1
+ require_relative "tui_prompt"
2
+ require_relative "tui_actions"
3
+ require "erb" unless defined?(Erb)
4
+ require_relative "../config"
5
+ require "pastel" unless defined?(Pastel)
6
+
7
+ module ChefLicensing
8
+ class TUIEngine
9
+ class TUIEngineState < Hash
10
+ attr_accessor :next_interaction_id, :input, :logger, :prompt, :tui_actions
11
+
12
+ def initialize(opts = {})
13
+ @input = {}
14
+ # store the pastel key for enabling styled messages in the yaml file
15
+ @input[:pastel] = Pastel.new
16
+ @logger = ChefLicensing::Config.logger
17
+ @prompt = ChefLicensing::TUIEngine::TUIPrompt.new(opts)
18
+ @tui_actions = ChefLicensing::TUIEngine::TUIActions.new(opts)
19
+ end
20
+
21
+ def default_action(interaction)
22
+ logger.debug "Default action called for interaction id: #{interaction.id}"
23
+
24
+ response = if interaction.messages
25
+ messages = render_messages(interaction.messages)
26
+ @prompt.send(interaction.prompt_type, messages, interaction.prompt_attributes)
27
+ elsif interaction.action
28
+ @tui_actions.send(interaction.action, @input)
29
+ end
30
+
31
+ @input.store(interaction.id, response)
32
+ logger.debug "Response for interaction #{interaction.id} is #{@input[interaction.id]}"
33
+
34
+ @next_interaction_id = if interaction.paths.size > 1
35
+ interaction.response_path_map[response.to_s]
36
+ elsif interaction.paths.size == 1
37
+ interaction.paths.keys.first
38
+ end
39
+ end
40
+
41
+ def append_info_to_input(extra_info_hash)
42
+ @input.merge!(extra_info_hash)
43
+ end
44
+
45
+ private
46
+
47
+ def erb_result(message)
48
+ ERB.new(message).result_with_hash(input: input)
49
+ end
50
+
51
+ def render_messages(messages)
52
+ if messages.is_a?(String)
53
+ erb_result(messages)
54
+ elsif messages.is_a?(Array)
55
+ messages.map do |message|
56
+ render_messages(message)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,17 @@
1
+ require "timeout" unless defined?(Timeout)
2
+
3
+ module ChefLicensing
4
+ class TUIEngine
5
+ class BadInteractionFile < StandardError; end
6
+
7
+ class PromptTimeout < Timeout::Error; end
8
+
9
+ class IncompleteFlowException < StandardError; end
10
+
11
+ class UnsupportedInteractionFileFormat < StandardError; end
12
+
13
+ class MissingInteractionFile < StandardError; end
14
+
15
+ class BadPromptInput < StandardError; end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module ChefLicensing
2
+ class TUIEngine
3
+ class TUIInteraction
4
+ attr_accessor :id, :messages, :action, :paths, :prompt_type, :response_path_map, :prompt_attributes, :description
5
+ def initialize(opts = {})
6
+ @id = opts[:id]
7
+ @messages = opts[:messages]
8
+ @action = opts[:action]
9
+ @prompt_type = opts[:prompt_type] || "say"
10
+ @prompt_attributes = opts[:prompt_attributes] || {}
11
+ @response_path_map = opts[:response_path_map]
12
+ @paths = {}
13
+ @description = opts[:description] || ""
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,117 @@
1
+ require "timeout" unless defined?(Timeout)
2
+ require "tty-prompt"
3
+ require_relative "tui_exceptions"
4
+ require "erb" unless defined?(Erb)
5
+ require_relative "../config"
6
+
7
+ module ChefLicensing
8
+ class TUIEngine
9
+ class TUIPrompt
10
+ attr_accessor :output, :input, :logger, :tty_prompt
11
+
12
+ def initialize(opts = {})
13
+ @output = ChefLicensing::Config.output
14
+ @input = opts[:input] || STDIN
15
+ @logger = ChefLicensing::Config.logger
16
+ @tty_prompt = opts[:prompt] || TTY::Prompt.new(track_history: false, active_color: :bold, interrupt: :exit, output: output, input: input)
17
+ end
18
+
19
+ # yes prompts the user with a yes/no question and returns true if the user
20
+ # answers yes and false if the user answers no.
21
+ # prompt_attributes is added to extend the prompt in future.
22
+ def yes(messages, prompt_attributes)
23
+ message = Array(messages).first
24
+ @tty_prompt.yes?(message)
25
+ end
26
+
27
+ # say prints the given message to the output stream.
28
+ # default prompt_type of an interaction is say.
29
+ # prompt_attributes is added to extend the prompt in future.
30
+ def say(messages, prompt_attributes)
31
+ message = Array(messages).first
32
+ @tty_prompt.say(message)
33
+ end
34
+
35
+ # ok prints the given message to the output stream in green color.
36
+ # prompt_attributes is added to extend the prompt in future.
37
+ def ok(messages, prompt_attributes)
38
+ message = Array(messages).first
39
+ @tty_prompt.ok(message)
40
+ end
41
+
42
+ # warn prints the given message to the output stream in yellow color.
43
+ # prompt_attributes is added to extend the prompt in future.
44
+ def warn(messages, prompt_attributes)
45
+ message = Array(messages).first
46
+ @tty_prompt.warn(message)
47
+ end
48
+
49
+ # error prints the given message to the output stream in red color.
50
+ # prompt_attributes is added to extend the prompt in future.
51
+ def error(messages, prompt_attributes)
52
+ message = Array(messages).first
53
+ @tty_prompt.error(message)
54
+ end
55
+
56
+ # select prompts the user to select an option from a list of options.
57
+ # prompt_attributes is added to extend the prompt in future.
58
+ def select(messages, prompt_attributes)
59
+ header, choices_list = fetch_header_and_choices(messages, :select)
60
+ @tty_prompt.select(header, choices_list)
61
+ end
62
+
63
+ # enum_select prompts the user to select an option from a list of options.
64
+ # prompt_attributes is added to extend the prompt in future.
65
+ def enum_select(messages, prompt_attributes)
66
+ header, choices_list = fetch_header_and_choices(messages, :enum_select)
67
+ @tty_prompt.enum_select(header, choices_list)
68
+ end
69
+
70
+ # ask prompts the user to enter a value.
71
+ # prompt_attributes is added to extend the prompt in future.
72
+ def ask(messages, prompt_attributes)
73
+ message = Array(messages).first
74
+ @tty_prompt.ask(message)
75
+ end
76
+
77
+ # timeout_yes prompt wraps yes prompt with timeout.
78
+ # prompt_attributes is added to extend the prompt in future.
79
+ def timeout_yes(messages, prompt_attributes)
80
+ timeout_helper(messages, method(:yes), prompt_attributes)
81
+ end
82
+
83
+ def timeout_select(messages, prompt_attributes)
84
+ timeout_helper(messages, method(:select), prompt_attributes)
85
+ end
86
+
87
+ def silent(messages, prompt_attributes)
88
+ Array(messages).first
89
+ end
90
+
91
+ private
92
+
93
+ def fetch_header_and_choices(messages, prompt_type)
94
+ unless messages.is_a?(Array) && messages.size > 1
95
+ raise ChefLicensing::TUIEngine::BadPromptInput, "messages for #{prompt_type} must be an array of size greater than 1"
96
+ end
97
+
98
+ header, *choices_list = messages
99
+ [header, choices_list]
100
+ end
101
+
102
+ def timeout_helper(messages, prompt_method, prompt_attributes)
103
+ prompt_attributes.transform_keys!(&:to_sym)
104
+ timeout_duration = prompt_attributes[:timeout_duration] || 60
105
+ Timeout.timeout(timeout_duration, PromptTimeout) do
106
+ prompt_method.call(messages, prompt_attributes)
107
+ rescue PromptTimeout
108
+ error(prompt_attributes[:timeout_message] || "Prompt Timeout", prompt_attributes)
109
+ @tty_prompt.unsubscribe(@tty_prompt.reader)
110
+ # TODO: Exit with a meaningful error code.
111
+ output.puts "Timed out!"
112
+ exit
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,2 @@
1
+ # This is simply a loader file.
2
+ require_relative "tui_engine/tui_engine"
@@ -0,0 +1,3 @@
1
+ module ChefLicensing
2
+ VERSION = "0.4.43".freeze
3
+ end
@@ -0,0 +1,70 @@
1
+ require "chef-licensing/version"
2
+ require "chef-licensing/license_key_fetcher"
3
+ require "chef-licensing/config"
4
+ require "chef-licensing/api/describe"
5
+ require "chef-licensing/list_license_keys"
6
+ require "chef-licensing/exceptions/feature_not_entitled"
7
+ require "chef-licensing/exceptions/software_not_entitled"
8
+ require "chef-licensing/exceptions/client_error"
9
+ require "chef-licensing/api/client"
10
+ require "chef-licensing/license_key_fetcher/prompt"
11
+
12
+ module ChefLicensing
13
+ class << self
14
+
15
+ # @example
16
+ # ChefLicensing.configure do |config|
17
+ # config.licensing_server_url = 'LICENSE_SERVER'
18
+ # config.logger = Logger.new($stdout)
19
+ # end
20
+ def configure(&block)
21
+ yield(ChefLicensing::Config)
22
+ end
23
+
24
+ def check_feature_entitlement!(feature_name: nil, feature_id: nil)
25
+ # Checking for feature presence in license feature entitlements
26
+ license = client(license_keys: license_keys)
27
+ feature_entitlements = license.feature_entitlements.select { |feature| feature.id == feature_id || feature.name == feature_name }
28
+ if feature_entitlements.empty?
29
+ raise(ChefLicensing::FeatureNotEntitled)
30
+ else
31
+ true
32
+ end
33
+ end
34
+
35
+ def check_software_entitlement!
36
+ # If API call is not breaking that means license is entitled.
37
+ client(license_keys: license_keys)
38
+ true
39
+ rescue ChefLicensing::ClientError => e
40
+ # Checking specific text phrase for entitlement error
41
+ if e.message.match?(/not entitled/)
42
+ raise(ChefLicensing::SoftwareNotEntitled)
43
+ else
44
+ raise
45
+ end
46
+ end
47
+
48
+ # @note no in-memory caching of the licenses so that it fetches updated licenses always
49
+ def license_keys
50
+ ChefLicensing::LicenseKeyFetcher.fetch
51
+ end
52
+
53
+ # @note fetch_and_persist is invoked by chef-products to fetch and persist the license keys
54
+ def fetch_and_persist
55
+ ChefLicensing::LicenseKeyFetcher.fetch_and_persist
56
+ end
57
+
58
+ def list_license_keys_info(opts = {})
59
+ ChefLicensing::ListLicenseKeys.display(opts)
60
+ end
61
+
62
+ def client(opts = {})
63
+ ChefLicensing::Api::Client.info(opts)
64
+ end
65
+
66
+ def add_license
67
+ ChefLicensing::LicenseKeyFetcher.add_license
68
+ end
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chef-licensing
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.43
5
+ platform: ruby
6
+ authors:
7
+ - Inspec Team
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-07-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chef-config
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '15'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: tty-prompt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.23'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.23'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '1'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '3'
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '1'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '3'
61
+ - !ruby/object:Gem::Dependency
62
+ name: faraday-http-cache
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: activesupport
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '7.0'
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 7.0.4.2
85
+ type: :runtime
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '7.0'
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 7.0.4.2
95
+ - !ruby/object:Gem::Dependency
96
+ name: tty-spinner
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: 0.9.3
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: 0.9.3
109
+ description: Ruby library to support CLI tools that use Progress Chef license storage,
110
+ generation, and entitlement.
111
+ email:
112
+ - inspec@progress.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - LICENSE
118
+ - chef-licensing.gemspec
119
+ - lib/chef-licensing.rb
120
+ - lib/chef-licensing/api/client.rb
121
+ - lib/chef-licensing/api/describe.rb
122
+ - lib/chef-licensing/api/license_feature_entitlement.rb
123
+ - lib/chef-licensing/api/license_software_entitlement.rb
124
+ - lib/chef-licensing/api/list_licenses.rb
125
+ - lib/chef-licensing/api/parser/client.rb
126
+ - lib/chef-licensing/api/parser/describe.rb
127
+ - lib/chef-licensing/cli_flags/mixlib_cli.rb
128
+ - lib/chef-licensing/cli_flags/thor.rb
129
+ - lib/chef-licensing/config.rb
130
+ - lib/chef-licensing/config_fetcher/arg_fetcher.rb
131
+ - lib/chef-licensing/config_fetcher/env_fetcher.rb
132
+ - lib/chef-licensing/context.rb
133
+ - lib/chef-licensing/exceptions/client_error.rb
134
+ - lib/chef-licensing/exceptions/describe_error.rb
135
+ - lib/chef-licensing/exceptions/error.rb
136
+ - lib/chef-licensing/exceptions/feature_not_entitled.rb
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
140
+ - lib/chef-licensing/exceptions/list_licenses_error.rb
141
+ - lib/chef-licensing/exceptions/missing_api_credentials_error.rb
142
+ - lib/chef-licensing/exceptions/restful_client_connection_error.rb
143
+ - lib/chef-licensing/exceptions/restful_client_error.rb
144
+ - lib/chef-licensing/exceptions/software_not_entitled.rb
145
+ - lib/chef-licensing/license.rb
146
+ - lib/chef-licensing/license_key_fetcher.rb
147
+ - lib/chef-licensing/license_key_fetcher/base.rb
148
+ - lib/chef-licensing/license_key_fetcher/chef_licensing_interactions.yaml
149
+ - lib/chef-licensing/license_key_fetcher/file.rb
150
+ - lib/chef-licensing/license_key_fetcher/prompt.rb
151
+ - lib/chef-licensing/license_key_generator.rb
152
+ - lib/chef-licensing/license_key_validator.rb
153
+ - lib/chef-licensing/licensing_service/local.rb
154
+ - lib/chef-licensing/list_license_keys.rb
155
+ - lib/chef-licensing/restful_client/base.rb
156
+ - lib/chef-licensing/restful_client/middleware/exceptions_handler.rb
157
+ - lib/chef-licensing/restful_client/v1.rb
158
+ - lib/chef-licensing/tui_engine.rb
159
+ - lib/chef-licensing/tui_engine/tui_actions.rb
160
+ - lib/chef-licensing/tui_engine/tui_engine.rb
161
+ - lib/chef-licensing/tui_engine/tui_engine_state.rb
162
+ - lib/chef-licensing/tui_engine/tui_exceptions.rb
163
+ - lib/chef-licensing/tui_engine/tui_interaction.rb
164
+ - lib/chef-licensing/tui_engine/tui_prompt.rb
165
+ - lib/chef-licensing/version.rb
166
+ homepage: https://github.com/chef/chef-licensing
167
+ licenses:
168
+ - LicenseRef-LICENSE
169
+ metadata:
170
+ homepage_uri: https://github.com/chef/chef-licensing
171
+ source_code_uri: https://github.com/chef/chef-licensing
172
+ post_install_message:
173
+ rdoc_options: []
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 2.3.0
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ requirements: []
187
+ rubygems_version: 3.3.7
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: Chef License storage, generation, and entitlement
191
+ test_files: []