Class: ChefLicensing::LicenseKeyFetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/chef-licensing/license_key_fetcher.rb,
lib/chef-licensing/license_key_fetcher/base.rb,
lib/chef-licensing/license_key_fetcher/file.rb,
lib/chef-licensing/license_key_fetcher/prompt.rb

Defined Under Namespace

Classes: Base, File, LicenseKeyAddNotAllowed, LicenseKeyNotFetchedError, LicenseKeyNotPersistedError, Prompt

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ LicenseKeyFetcher

Returns a new instance of LicenseKeyFetcher.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/chef-licensing/license_key_fetcher.rb', line 32

def initialize(opts = {})
  @config = opts
  @logger = ChefLicensing::Config.logger
  @config[:output] = ChefLicensing::Config.output
  config[:logger] = logger
  config[:dir] = opts[:dir]

  # While using on-prem licensing service, @license_keys are fetched from API
  # While using global licensing service, @license_keys are fetched from file
  @license_keys = ChefLicensing::Context.license_keys(opts) || []

  argv = opts[:argv] || ARGV
  env = opts[:env] || ENV

  # The various things that have a say in fetching the license Key.
  @arg_fetcher = ChefLicensing::ArgFetcher.new(argv)
  @env_fetcher = ChefLicensing::EnvFetcher.new(env)
  @file_fetcher = LicenseKeyFetcher::File.new(config)
  @prompt_fetcher = LicenseKeyFetcher::Prompt.new(config)
  @license = nil
end

Instance Attribute Details

#arg_fetcherObject (readonly)

Returns the value of attribute arg_fetcher.



29
30
31
# File 'lib/chef-licensing/license_key_fetcher.rb', line 29

def arg_fetcher
  @arg_fetcher
end

#client_api_call_errorObject

Returns the value of attribute client_api_call_error.



30
31
32
# File 'lib/chef-licensing/license_key_fetcher.rb', line 30

def client_api_call_error
  @client_api_call_error
end

#configObject (readonly)

Returns the value of attribute config.



29
30
31
# File 'lib/chef-licensing/license_key_fetcher.rb', line 29

def config
  @config
end

#env_fetcherObject (readonly)

Returns the value of attribute env_fetcher.



29
30
31
# File 'lib/chef-licensing/license_key_fetcher.rb', line 29

def env_fetcher
  @env_fetcher
end

#file_fetcherObject (readonly)

Returns the value of attribute file_fetcher.



29
30
31
# File 'lib/chef-licensing/license_key_fetcher.rb', line 29

def file_fetcher
  @file_fetcher
end

#license_keysObject (readonly)

Returns the value of attribute license_keys.



29
30
31
# File 'lib/chef-licensing/license_key_fetcher.rb', line 29

def license_keys
  @license_keys
end

#loggerObject (readonly)

Returns the value of attribute logger.



29
30
31
# File 'lib/chef-licensing/license_key_fetcher.rb', line 29

def logger
  @logger
end

#prompt_fetcherObject (readonly)

Returns the value of attribute prompt_fetcher.



29
30
31
# File 'lib/chef-licensing/license_key_fetcher.rb', line 29

def prompt_fetcher
  @prompt_fetcher
end

Class Method Details

.add_license(opts = {}) ⇒ Object



202
203
204
# File 'lib/chef-licensing/license_key_fetcher.rb', line 202

def self.add_license(opts = {})
  new(opts).add_license
end

.fetch(opts = {}) ⇒ Object



198
199
200
# File 'lib/chef-licensing/license_key_fetcher.rb', line 198

def self.fetch(opts = {})
  new(opts).fetch
end

.fetch_and_persist(opts = {}) ⇒ Object



190
191
192
# File 'lib/chef-licensing/license_key_fetcher.rb', line 190

def self.fetch_and_persist(opts = {})
  new(opts).fetch_and_persist
end

.fetch_and_validate(opts = {}) ⇒ Object



194
195
196
# File 'lib/chef-licensing/license_key_fetcher.rb', line 194

def self.fetch_and_validate(opts = {})
  new(opts).fetch_and_validate
end

Instance Method Details

#add_licenseObject



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/chef-licensing/license_key_fetcher.rb', line 166

def add_license
  if ChefLicensing::Context.local_licensing_service?
    raise LicenseKeyAddNotAllowed.new("'inspec license add' command is not supported with airgapped environment. You cannot generate license from airgapped environment.")
  else
    config = {}
    config[:start_interaction] = :add_license_all
    prompt_fetcher.config = config
    append_extra_info_to_tui_engine
    new_keys = prompt_fetcher.fetch
    unless new_keys.empty?
      prompt_fetcher.license_type ||= get_license_type(new_keys.first)
      persist_and_concat(new_keys, prompt_fetcher.license_type)
      license_keys
    end
  end
end

#fetchObject

Note: Fetching from arg and env as well, to be able to fetch license when disk is non-writable



184
185
186
187
188
# File 'lib/chef-licensing/license_key_fetcher.rb', line 184

def fetch
  # While using on-prem licensing service, @license_keys have been fetched from API
  # While using global licensing service, @license_keys have been fetched from file
  (fetch_license_key_from_arg << fetch_license_key_from_env << @license_keys).flatten.uniq
end

#fetch_and_persistObject

Methods for obtaining consent from the user.



57
58
59
60
61
62
63
64
# File 'lib/chef-licensing/license_key_fetcher.rb', line 57

def fetch_and_persist
  ChefLicensing::Config.persist_license_data = true
  if ChefLicensing::Context.local_licensing_service?
    perform_on_prem_operations
  else
    perform_global_operations
  end
end

#fetch_and_validateObject

Method for validating license key without writing to disk



67
68
69
70
71
72
73
74
# File 'lib/chef-licensing/license_key_fetcher.rb', line 67

def fetch_and_validate
  ChefLicensing::Config.persist_license_data = false
  if ChefLicensing::Context.local_licensing_service?
    perform_on_prem_operations
  else
    perform_global_operations(false)
  end
end

#perform_global_operations(persist = true) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/chef-licensing/license_key_fetcher.rb', line 108

def perform_global_operations(persist = true)
  new_keys = fetch_license_key_from_arg
  license_type = validate_and_fetch_license_type(new_keys)
  if license_type && !unrestricted_license_added?(new_keys, license_type, persist)
    # break the flow after the prompt if there is a restriction in adding license
    # and return the license keys persisted in the file or @license_keys if any
    return license_keys
  end

  new_keys = fetch_license_key_from_env
  license_type = validate_and_fetch_license_type(new_keys)
  if license_type && !unrestricted_license_added?(new_keys, license_type, persist)
    # break the flow after the prompt if there is a restriction in adding license
    # and return the license keys persisted in the file or @license_keys if any
    return license_keys
  end

  # Return keys if license keys are active and not expired or expiring
  # Return keys if there is any error in /client API call, and do not block the flow.
  # Client API possible errors will be handled in software entitlement check call (made after this)
  # client_api_call_error is set to true when there is an error in licenses_active? call
  return @license_keys if (!@license_keys.empty? && licenses_active? && ChefLicensing::Context.license.license_type.downcase == "commercial") || client_api_call_error

  # Lowest priority is to interactively prompt if we have a TTY
  if config[:output].isatty
    append_extra_info_to_tui_engine # will add extra dynamic values in tui flows
    new_keys = prompt_fetcher.fetch

    unless new_keys.empty?
      # If license type is not selected using TUI, assign it using API call to fetch type.
      prompt_fetcher.license_type ||= get_license_type(new_keys.first)
      if persist
        persist_and_concat(new_keys, prompt_fetcher.license_type)
      else
        validate_and_concat(new_keys, prompt_fetcher.license_type)
      end
      license ||= ChefLicensing::Context.license
      # Expired trial licenses and exhausted free licenses will be blocked
      # Not blocking commercial licenses
      if (!license&.expired? && !license&.exhausted?) || (license&.license_type&.downcase == "commercial")
        return license_keys
      end
    end
  else
    new_keys = []
  end

  # Expired trial licenses and exhausted free licenses will be blocked
  # Not blocking commercial licenses
  license ||= ChefLicensing::Context.license
  if new_keys.empty? && license && ((!license.expired? && !license.exhausted?) || (license.license_type.downcase == "commercial"))
    return @license_keys
  end

  # Otherwise nothing was able to fetch a license. Throw an exception.
  raise LicenseKeyNotFetchedError.new("Unable to obtain a License Key.")
end

#perform_on_prem_operationsObject



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/chef-licensing/license_key_fetcher.rb', line 76

def perform_on_prem_operations
  # While using on-prem licensing service no option to add/generate license is enabled

  new_keys = fetch_license_key_from_arg
  raise LicenseKeyAddNotAllowed.new("'--chef-license-key <value>' option is not supported with airgapped environment. You cannot add license from airgapped environment.") unless new_keys.empty?

  unless @license_keys.empty?
    # Licenses expiration check
    # Client API possible errors will be handled in software entitlement check call (made after this)
    # client_api_call_error is set to true when there is an error in licenses_active? call
    if licenses_active? || client_api_call_error
      return @license_keys
    else
      # Prompts if the keys are expired or expiring
      if config[:output].isatty
        append_extra_info_to_tui_engine # will add extra dynamic values in tui flows
        logger.debug "License Key fetcher - detected TTY, prompting..."
        prompt_fetcher.fetch
      end
    end
  end

  # Expired trial licenses and exhausted free licenses will be blocked
  # Not blocking commercial licenses
  if license && ((!license.expired? && !license.exhausted?) || (license.license_type.downcase == "commercial"))
    return @license_keys
  end

  # Otherwise nothing was able to fetch a license. Throw an exception.
  raise LicenseKeyNotFetchedError.new("Unable to obtain a License Key.")
end