Class: LicenseAcceptance::Acceptor

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Logger
Defined in:
lib/license_acceptance/acceptor.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logger

initialize, logger, #logger

Constructor Details

#initialize(opts = {}) ⇒ Acceptor

Returns a new instance of Acceptor.



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/license_acceptance/acceptor.rb', line 24

def initialize(opts = {})
  @config = Config.new(opts)
  Logger.initialize(config.logger)
  @product_reader = ProductReader.new
  product_reader.read
  @env_strategy = Strategy::Environment.new(ENV)
  @file_strategy = Strategy::File.new(config)
  @arg_strategy = Strategy::Argument.new(ARGV)
  @prompt_strategy = Strategy::Prompt.new(config)
  @provided_strategy = Strategy::ProvidedValue.new(opts.fetch(:provided, nil))
  @acceptance_value = nil
end

Instance Attribute Details

#arg_strategyObject (readonly)

Returns the value of attribute arg_strategy.



22
23
24
# File 'lib/license_acceptance/acceptor.rb', line 22

def arg_strategy
  @arg_strategy
end

#configObject (readonly)

Returns the value of attribute config.



22
23
24
# File 'lib/license_acceptance/acceptor.rb', line 22

def config
  @config
end

#env_strategyObject (readonly)

Returns the value of attribute env_strategy.



22
23
24
# File 'lib/license_acceptance/acceptor.rb', line 22

def env_strategy
  @env_strategy
end

#file_strategyObject (readonly)

Returns the value of attribute file_strategy.



22
23
24
# File 'lib/license_acceptance/acceptor.rb', line 22

def file_strategy
  @file_strategy
end

#product_readerObject (readonly)

Returns the value of attribute product_reader.



22
23
24
# File 'lib/license_acceptance/acceptor.rb', line 22

def product_reader
  @product_reader
end

#prompt_strategyObject (readonly)

Returns the value of attribute prompt_strategy.



22
23
24
# File 'lib/license_acceptance/acceptor.rb', line 22

def prompt_strategy
  @prompt_strategy
end

#provided_strategyObject (readonly)

Returns the value of attribute provided_strategy.



22
23
24
# File 'lib/license_acceptance/acceptor.rb', line 22

def provided_strategy
  @provided_strategy
end

Class Method Details

.check_and_persist(product_id, version, opts = {}) ⇒ Object



95
96
97
# File 'lib/license_acceptance/acceptor.rb', line 95

def self.check_and_persist(product_id, version, opts = {})
  new(opts).check_and_persist(product_id, version)
end

.check_and_persist!(product_id, version, opts = {}) ⇒ Object



91
92
93
# File 'lib/license_acceptance/acceptor.rb', line 91

def self.check_and_persist!(product_id, version, opts = {})
  new(opts).check_and_persist!(product_id, version)
end

Instance Method Details

#acceptance_valueObject

Return the value that was matched (“accept”, “accept-no-persist”, etc.). Used by callers so they do not have to know the precedence order between provided/environment/argument. Can just get back the value that was used. Value is only guaranteed to be set after calling check_and_persist.



135
136
137
# File 'lib/license_acceptance/acceptor.rb', line 135

def acceptance_value
  @acceptance_value
end

#acceptance_value_provided?Boolean

Returns:

  • (Boolean)


153
154
155
# File 'lib/license_acceptance/acceptor.rb', line 153

def acceptance_value_provided?
  provided_strategy.value? || env_strategy.value? || arg_strategy.value?
end

#accepted?Boolean

Returns:

  • (Boolean)


139
140
141
# File 'lib/license_acceptance/acceptor.rb', line 139

def accepted?
  provided_strategy.accepted? || env_strategy.accepted? || arg_strategy.accepted?
end

#accepted_license_prompt?(product_relationship, missing_licenses) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/license_acceptance/acceptor.rb', line 99

def accepted_license_prompt?(product_relationship, missing_licenses)
  prompt_strategy.request(missing_licenses) do
    # We have to infer the acceptance value if they use the prompt to accept
    if config.persist
      @acceptance_value = ACCEPT
      file_strategy.persist(product_relationship, missing_licenses)
    else
      @acceptance_value = ACCEPT_NO_PERSIST
      []
    end
  end
end

#accepted_no_persist?Boolean

no-persist is silent too

Returns:

  • (Boolean)


144
145
146
# File 'lib/license_acceptance/acceptor.rb', line 144

def accepted_no_persist?
  provided_strategy.no_persist? || env_strategy.no_persist? || arg_strategy.no_persist?
end

#accepted_silent?Boolean

persist but be silent like no-persist

Returns:

  • (Boolean)


149
150
151
# File 'lib/license_acceptance/acceptor.rb', line 149

def accepted_silent?
  provided_strategy.silent? || env_strategy.silent? || arg_strategy.silent?
end

#check_and_persist(product_id, version) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/license_acceptance/acceptor.rb', line 49

def check_and_persist(product_id, version)
  if accepted_no_persist?
    logger.debug("Chef License accepted with no persistence")
    @acceptance_value = ACCEPT_NO_PERSIST
    return true
  end

  product_relationship = product_reader.lookup(product_id, version)

  missing_licenses = file_strategy.accepted?(product_relationship)

  # They have already accepted all licenses and stored their acceptance in the persistent files
  if missing_licenses.empty?
    logger.debug("All licenses present")
    @acceptance_value = ACCEPT
    return true
  end

  if accepted? || accepted_silent?
    if config.persist
      errs = file_strategy.persist(product_relationship, missing_licenses)
      if errs.empty?
        output_num_persisted(missing_licenses.size) unless accepted_silent?
      else
        output_persist_failed(errs)
      end
    end
    @acceptance_value = accepted_silent? ? ACCEPT_SILENT : ACCEPT
    return true
  end

  if acceptance_value_provided?
    value = provided_strategy.value || env_strategy.value || arg_strategy.value
    output.puts("Unrecognized license acceptance value '#{value}', expected one of: '#{ACCEPT}', '#{ACCEPT_SILENT}', '#{ACCEPT_NO_PERSIST}'")
    raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
  end

  return true if output.isatty && accepted_license_prompt?(product_relationship, missing_licenses)

  raise LicenseNotAcceptedError.new(product_relationship.parent, missing_licenses)
end

#check_and_persist!(product_id, version) ⇒ Object

For applications that just need simple logic to handle a failed license acceptance flow we include this small wrapper. Apps with more complex logic (like logging to a logging engine) should call the non-bang version and handle the exception.



42
43
44
45
46
47
# File 'lib/license_acceptance/acceptor.rb', line 42

def check_and_persist!(product_id, version)
  check_and_persist(product_id, version)
rescue LicenseNotAcceptedError => e
  output.puts "#{e.product.pretty_name} cannot execute without accepting the license"
  exit 172
end

#id_from_mixlib(mixlib_name) ⇒ Object

Some callers only know about mixlib names so we need a way for them to get the product id as this library knows it.



125
126
127
128
129
130
# File 'lib/license_acceptance/acceptor.rb', line 125

def id_from_mixlib(mixlib_name)
  product = product_reader.lookup_by_mixlib(mixlib_name)
  return nil if product.nil?

  product.id
end

#license_required?(mixlib_name, version) ⇒ Boolean

Check whether the specified product requires license acceptance for the given version.

Returns:

  • (Boolean)


113
114
115
116
117
118
119
120
121
# File 'lib/license_acceptance/acceptor.rb', line 113

def license_required?(mixlib_name, version)
  product = product_reader.lookup_by_mixlib(mixlib_name)
  return false if product.nil?
  # If they don't pass a version we assume they want latest
  # All versions in all channels require license acceptance
  return true if %w{latest unstable current stable}.include?(version.to_s) || version.nil?

  Gem::Version.new(version) >= Gem::Version.new(product.license_required_version)
end

#output_num_persisted(count) ⇒ Object

In the case where users accept with a command line argument or environment variable we still want to output the fact that the filesystem was changed.



159
160
161
162
163
164
165
166
# File 'lib/license_acceptance/acceptor.rb', line 159

def output_num_persisted(count)
  s = count > 1 ? "s" : ""
  output.puts <<~EOM
    #{Strategy::Prompt::BORDER}
    #{Strategy::Prompt::CHECK} #{count} product license#{s} accepted.
    #{Strategy::Prompt::BORDER}
  EOM
end

#output_persist_failed(errs) ⇒ Object



168
169
170
171
172
173
174
175
# File 'lib/license_acceptance/acceptor.rb', line 168

def output_persist_failed(errs)
  output.puts <<~EOM
    #{Strategy::Prompt::BORDER}
    #{Strategy::Prompt::CHECK} Product license accepted.
    Could not persist acceptance:\n\t* #{errs.map(&:message).join("\n\t* ")}
    #{Strategy::Prompt::BORDER}
  EOM
end