Class: ChefLicensing::LicenseKeyFetcher::File

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

Overview

Represents a fethced license ID recorded on disk

Constant Summary collapse

LICENSE_KEY_FILE =
"licenses.yaml".freeze
LICENSE_FILE_FORMAT_VERSION =
"4.0.0".freeze
LICENSE_TYPES =

License types list

{
  free: :free,
  trial: :trial,
  commercial: :commercial,
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ File

Returns a new instance of File.



31
32
33
34
35
36
37
38
39
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 31

def initialize(opts)
  @opts = opts
  @logger = ChefLicensing::Config.logger
  @contents_ivar = nil
  @location = nil

  @opts[:dir] ||= LicenseKeyFetcher::File.default_file_location
  @local_dir = @opts[:dir]
end

Instance Attribute Details

#contentsObject (readonly)

Returns the value of attribute contents.



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

def contents
  @contents
end

#local_dirObject

Optional local path to use to seek



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

def local_dir
  @local_dir
end

#locationObject (readonly)

Returns the value of attribute location.



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

def location
  @location
end

#loggerObject (readonly)

Returns the value of attribute logger.



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

def logger
  @logger
end

Class Method Details

.default_file_locationObject



168
169
170
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 168

def self.default_file_location
  ChefConfig::PathHelper.home(".chef")
end

.fetch_license_keys_based_on_type(license_type, opts = {}) ⇒ Object



172
173
174
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 172

def self.fetch_license_keys_based_on_type(license_type, opts = {})
  new(opts).fetch_license_keys_based_on_type(license_type)
end

.fetch_or_persist_url(license_server_url_from_config, license_server_url_from_system = nil, opts = {}) ⇒ Object



180
181
182
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 180

def self.fetch_or_persist_url(license_server_url_from_config, license_server_url_from_system = nil, opts = {})
  new(opts).fetch_or_persist_url(license_server_url_from_config, license_server_url_from_system)
end

.user_has_active_trial_license?(opts = {}) ⇒ Boolean

Returns:

  • (Boolean)


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

def self.user_has_active_trial_license?(opts = {})
  new(opts).user_has_active_trial_license?
end

Instance Method Details

#fetchObject



41
42
43
44
45
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 41

def fetch
  read_license_key_file
  # Check if contents is valid and not an error before accessing license data
  (contents && !contents.is_a?(StandardError) && contents.key?(:licenses)) ? fetch_license_keys(contents[:licenses]) : []
end

#fetch_allowed_license_types_for_additionObject



83
84
85
86
87
88
89
90
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 83

def fetch_allowed_license_types_for_addition
  license_types = %i{free trial commercial}
  existing_license_types = fetch_license_types

  license_types -= [:trial] if existing_license_types.include? :trial
  license_types -= [:free] if existing_license_types.include?(:free) || user_has_active_trial_license?
  license_types.uniq
end

#fetch_license_keys(licenses) ⇒ Object



47
48
49
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 47

def fetch_license_keys(licenses)
  licenses.collect { |x| x[:license_key] }
end

#fetch_license_keys_based_on_type(license_type) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 92

def fetch_license_keys_based_on_type(license_type)
  read_license_key_file
  # Return empty array if contents failed to load or is nil
  if contents.is_a?(StandardError) || contents.nil?
    []
  else
    contents[:licenses].collect do |x|
      x[:license_key] if x[:license_type] == license_type
    end.compact
  end
end

#fetch_license_typesObject



51
52
53
54
55
56
57
58
59
60
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 51

def fetch_license_types
  read_license_key_file

  # Return empty array if contents failed to load, is nil, or has no licenses
  if contents.is_a?(StandardError) || contents.nil? || contents[:licenses].nil?
    []
  else
    contents[:licenses].collect { |x| x[:license_type] }
  end
end

#fetch_or_persist_url(license_server_url_from_config, license_server_url_from_system = nil) ⇒ Object



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
165
166
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 132

def fetch_or_persist_url(license_server_url_from_config, license_server_url_from_system = nil)
  dir = @opts[:dir]
  license_key_file_path = "#{dir}/#{LICENSE_KEY_FILE}"
  create_license_directory_if_not_exist(dir, license_key_file_path)

  @contents = load_license_file(license_key_file_path)

  # Three possible cases:
  # 1. If contents is nil or an error occurred while loading, load basic license data with the latest structure.
  # 2. If contents is not nil and valid, but the license server URL in contents is different from the system's,
  #    update the license server URL in contents and licenses.yaml file.
  # 3. If contents is valid and no update is needed, return the existing license server URL.
  # Handle error cases first - when file loading failed or contents is nil
  if @contents.is_a?(StandardError) || @contents.nil?
    url = license_server_url_from_system || license_server_url_from_config
    load_basic_license_data_to_contents(url, [])
  elsif @contents && license_server_url_from_system && license_server_url_from_system != @contents[:license_server_url]
    @contents[:license_server_url] = license_server_url_from_system
  else
    # Nothing to change in the file
    @license_server_url = @contents[:license_server_url]
    return @license_server_url
  end

  # Ensure the license server URL is returned to the caller in all cases
  # (even if it's not persisted to the licenses.yaml file on the disk)
  begin
    write_license_file(license_key_file_path)
  rescue StandardError => e
    handle_error(e)
  ensure
    @license_server_url = @contents[:license_server_url]
  end
  @license_server_url
end

#persist(license_key, license_type = nil) ⇒ Object

Writes a license_id file to disk in the location specified, with the content given.

Returns:

  • Array of Errors

Raises:



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 107

def persist(license_key, license_type = nil)
  raise LicenseKeyNotPersistedError.new("License type #{license_type} is not a valid license type.") unless LICENSE_TYPES[license_type.to_sym]

  license_data = {
    license_key: license_key,
    license_type: LICENSE_TYPES[license_type.to_sym],
    update_time: DateTime.now.to_s,
  }

  dir = @opts[:dir]
  license_key_file_path = "#{dir}/#{LICENSE_KEY_FILE}"
  create_license_directory_if_not_exist(dir, license_key_file_path)

  @contents = load_license_file(license_key_file_path)

  load_license_data_to_contents(license_data)
  write_license_file(license_key_file_path)
  []
end

#persisted?Boolean

Returns true if a license_key file exists.

Returns:

  • (Boolean)


128
129
130
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 128

def persisted?
  !!seek
end

#user_has_active_trial_license?Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
69
70
71
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 62

def user_has_active_trial_license?
  @active_trial_status = false
  read_license_key_file

  # Only proceed if contents loaded successfully and contains license data
  if contents && !contents.is_a?(StandardError) && contents.key?(:licenses)
    @active_trial_status = contents[:licenses].any? { |license| license[:license_type] == :trial && ChefLicensing.client(license_keys: [license[:license_key]]).active? }
  end
  @active_trial_status
end

#user_has_active_trial_or_free_license?Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
80
81
# File 'lib/chef-licensing/license_key_fetcher/file.rb', line 73

def user_has_active_trial_or_free_license?
  read_license_key_file
  # Early return if contents failed to load or doesn't contain license data
  return false unless contents && !contents.is_a?(StandardError) && contents.key?(:licenses)

  all_license_keys = contents[:licenses].collect { |license| license[:license_key] }
  license_obj = ChefLicensing.client(license_keys: all_license_keys)
  (%w{trial free}.include? license_obj.license_type&.downcase) && license_obj.active?
end