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
53
# 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
  logger.debug "License Key fetcher - fetching license keys depending upon the context (either API or file)"
  # 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



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

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

.fetch(opts = {}) ⇒ Object



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

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

.fetch_and_persist(opts = {}) ⇒ Object



182
183
184
# File 'lib/chef-licensing/license_key_fetcher.rb', line 182

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

Instance Method Details

#add_licenseObject



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/chef-licensing/license_key_fetcher.rb', line 157

def add_license
  logger.debug "License Key fetcher - add license flow, starting..."
  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



176
177
178
179
180
# File 'lib/chef-licensing/license_key_fetcher.rb', line 176

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.



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

def fetch_and_persist
  if ChefLicensing::Context.local_licensing_service?
    perform_on_prem_operations
  else
    perform_global_operations
  end
end

#perform_global_operationsObject



99
100
101
102
103
104
105
106
107
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
# File 'lib/chef-licensing/license_key_fetcher.rb', line 99

def perform_global_operations
  logger.debug "License Key fetcher examining CLI arg checks"
  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)
    # 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

  logger.debug "License Key fetcher examining ENV checks"
  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)
    # 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
    logger.debug "License Key fetcher - detected TTY, prompting..."
    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)
      persist_and_concat(new_keys, prompt_fetcher.license_type)
      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.
  logger.debug "License Key fetcher - no license Key able to be fetched."
  raise LicenseKeyNotFetchedError.new("Unable to obtain a License Key.")
end

#perform_on_prem_operationsObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/chef-licensing/license_key_fetcher.rb', line 66

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.
  logger.debug "License Key fetcher - no license Key able to be fetched."
  raise LicenseKeyNotFetchedError.new("Unable to obtain a License Key.")
end