Class: BeakerAnswers::Answers

Inherits:
Object
  • Object
show all
Defined in:
lib/beaker-answers/answers.rb

Overview

This class provides methods for generating PE answer file information.

Direct Known Subclasses

Upgrade, Version20, Version28, Version30

Constant Summary collapse

DEFAULT_FORMAT =

This is a temporary default for deciding which configuration file format to fall back to in 2016.2.0. Once we have cutover to MEEP, it should be removed.

:bash
DEFAULT_ANSWERS =
StringifyHash.new.merge({
  :q_install                                     => 'y',
  :q_puppet_enterpriseconsole_auth_user_email    => '[email protected]',
  :q_puppet_enterpriseconsole_auth_password      => '~!@#$%^*-/ aZ',
  :q_puppet_enterpriseconsole_smtp_port          => 25,
  :q_puppet_enterpriseconsole_smtp_use_tls       => 'n',
  :q_verify_packages                             => 'y',
  :q_puppetdb_database_password                  => '~!@#$%^*-/ aZ',
  :q_puppetmaster_enterpriseconsole_port         => 443,
  :q_puppet_enterpriseconsole_auth_database_name => 'console_auth',
  :q_puppet_enterpriseconsole_auth_database_user => 'mYu7hu3r',
  :q_puppet_enterpriseconsole_database_name      => 'console',
  :q_puppet_enterpriseconsole_database_user      => 'mYc0nS03u3r',
  :q_database_root_password                      => '=ZYdjiP3jCwV5eo9s1MBd',
  :q_database_root_user                          => 'pe-postgres',
  :q_database_export_dir                         => '/tmp',
  :q_orchestrator_database_name                  => 'pe-orchestrator',
  :q_orchestrator_database_user                  => 'Orc3Str8R',
  :q_orchestrator_database_password              => '~!@#$%^*-/ aZ',
  :q_puppetdb_database_name                      => 'pe-puppetdb',
  :q_puppetdb_database_user                      => 'mYpdBu3r',
  :q_database_port                               => 5432,
  :q_puppetdb_port                               => 8081,
  :q_classifier_database_name                    => 'pe-classifier',
  :q_classifier_database_user                    => 'DFGhjlkj',
  :q_classifier_database_password                => '~!@#$%^*-/ aZ',
  :q_activity_database_user                      => 'adsfglkj',
  :q_activity_database_name                      => 'pe-activity',
  :q_activity_database_password                  => '~!@#$%^*-/ aZ',
  :q_rbac_database_user                          => 'RbhNBklm',
  :q_rbac_database_name                          => 'pe-rbac',
  :q_rbac_database_password                      => '~!@#$%^*-/ aZ',
  :q_install_update_server                       => 'y',
  :q_exit_for_nc_migrate                         => 'n',
  :q_enable_future_parser                        => 'n',
  :q_pe_check_for_updates                        => 'n',
})
DEFAULT_HIERA_ANSWERS =
StringifyHash.new.merge(flatten_keys_to_joined_string({
  'console_admin_password' => DEFAULT_ANSWERS[:q_puppet_enterpriseconsole_auth_password],
  'puppet_enterprise' => {
    'puppetdb_database_name'         => DEFAULT_ANSWERS[:q_puppetdb_database_name],
    'puppetdb_database_user'         => DEFAULT_ANSWERS[:q_puppetdb_database_user],
    'puppetdb_database_password'     => DEFAULT_ANSWERS[:q_puppetdb_database_password],
    'classifier_database_name'       => DEFAULT_ANSWERS[:q_classifier_database_name],
    'classifier_database_user'       => DEFAULT_ANSWERS[:q_classifier_database_user],
    'classifier_database_password'   => DEFAULT_ANSWERS[:q_classifier_database_password],
    'activity_database_name'         => DEFAULT_ANSWERS[:q_activity_database_name],
    'activity_database_user'         => DEFAULT_ANSWERS[:q_activity_database_user],
    'activity_database_password'     => DEFAULT_ANSWERS[:q_activity_database_password],
    'rbac_database_name'             => DEFAULT_ANSWERS[:q_rbac_database_name],
    'rbac_database_user'             => DEFAULT_ANSWERS[:q_rbac_database_user],
    'rbac_database_password'         => DEFAULT_ANSWERS[:q_rbac_database_password],
    'orchestrator_database_name'     => DEFAULT_ANSWERS[:q_orchestrator_database_name],
    'orchestrator_database_user'     => DEFAULT_ANSWERS[:q_orchestrator_database_user],
    'orchestrator_database_password' => DEFAULT_ANSWERS[:q_orchestrator_database_password],
    'use_application_services'       => true,
  }
}))

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(version, hosts, options) ⇒ Hash

When given a Puppet Enterprise version, a list of hosts and other qualifying data this method will return a hash (keyed from the hosts) of default Puppet Enterprise answer file data hashes.

Parameters:

  • version (String)

    Puppet Enterprise version to generate answer data for

  • hosts (Array<Beaker::Host>)

    An array of host objects.

  • options (Hash)

    options for answer files

Options Hash (options):

  • :type (Symbol)

    Should be one of :upgrade or :install.

  • :format (Symbol)

    Should be one of :bash or :hiera. This is a temporary setting which only has an impact on version201620 answers. Setting :bash will result in the “classic” PE answer file being generated Setting :hiera will generate the new PE hiera config file format



171
172
173
174
175
176
# File 'lib/beaker-answers/answers.rb', line 171

def initialize(version, hosts, options)
  @version = version
  @hosts = hosts
  @options = options
  @format = (options[:format] || DEFAULT_FORMAT).to_sym
end

Class Method Details

.create(version, hosts, options) ⇒ Hash

When given a Puppet Enterprise version, a list of hosts and other qualifying data this method will return the appropriate object that can be used to generate answer file data.

Parameters:

  • version (String)

    Puppet Enterprise version to generate answer data for

  • hosts (Array<Beaker::Host>)

    An array of host objects.

  • options (Hash)

    options for answer files

Options Hash (options):

  • :type (Symbol)

    Should be one of :upgrade or :install.

Returns:

  • (Hash)

    A hash (keyed from hosts) containing hashes of answer file data.

Raises:

  • (NotImplementedError)


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/beaker-answers/answers.rb', line 92

def self.create version, hosts, options
  # if :upgrade is detected, then we return the simpler upgrade answers
  if options[:type] == :upgrade
    self.supported_upgrade_versions.each do |upgrade_version_class|
      if BeakerAnswers.const_get(upgrade_version_class).send(:upgrade_version_matcher) =~ version
        return BeakerAnswers.const_get(upgrade_version_class).send(:new, version, hosts, options)
      end
    end
    warn 'Only upgrades to version 3.8.x generate specific upgrade answers. Defaulting to full answers.'
  end

  # finds all potential version classes
  # discovers new version classes as they are added, no more crazy case statement
  version_classes = self.supported_versions
  version_classes.each do |vc|
    # check to see if the version matches the regex for this class of answers
    if BeakerAnswers.const_get(vc).send(:pe_version_matcher) =~ version
      return BeakerAnswers.const_get(vc).send(:new, version, hosts, options)
    end
  end
  raise NotImplementedError, "Don't know how to generate answers for #{version}"
end

.supported_upgrade_versionsArray<String>

Determine the list of supported upgrade PE versions, return as an array

Returns:

  • (Array<String>)

    An array of the supported versions



78
79
80
# File 'lib/beaker-answers/answers.rb', line 78

def self.supported_upgrade_versions
  BeakerAnswers.constants.select {|c| BeakerAnswers.const_get(c).is_a?(Class) && BeakerAnswers.const_get(c).respond_to?(:upgrade_version_matcher)}
end

.supported_versionsArray<String>

Determine the list of supported PE versions, return as an array

Returns:

  • (Array<String>)

    An array of the supported versions



72
73
74
# File 'lib/beaker-answers/answers.rb', line 72

def self.supported_versions
  BeakerAnswers.constants.select {|c| BeakerAnswers.const_get(c).is_a?(Class) && BeakerAnswers.const_get(c).respond_to?(:pe_version_matcher)}
end

Instance Method Details

#answer_for(options, q, default = nil) ⇒ String

The answer value for a provided question. Use the user answer when available, otherwise return the default.

Parameters:

  • options (Hash)

    options for answer file

  • default (String) (defaults to: nil)

    Should there be no user value for the provided question name return this default

Options Hash (options):

  • :answers (Symbol)

    Contains a hash of user provided question name and answer value pairs.

Returns:

  • (String)

    The answer value



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/beaker-answers/answers.rb', line 124

def answer_for(options, q, default = nil)
  case @format
  when :bash
    answer = DEFAULT_ANSWERS[q]
    answers = options[:answers]
  when :hiera
    answer = DEFAULT_HIERA_ANSWERS[q]
    answers = flatten_keys_to_joined_string(options[:answers]) if options[:answers]
  else
    raise NotImplementedError, "Don't know how to determine answers for #{@format}"
  end

  # check to see if there is a value for this in the provided options
  if answers && answers[q]
    answer = answers[q]
  end
  # use the default if we don't have anything
  if not answer
    answer = default
  end
  answer
end

#answer_hieraObject

Raises:

  • (NotImplementedError)


205
206
207
# File 'lib/beaker-answers/answers.rb', line 205

def answer_hiera
  raise(NotImplementedError, "Hiera configuration is not available in this version of PE (#{self.class})")
end

#answer_string(host) ⇒ String

This converts a data hash provided by answers, and returns a Puppet Enterprise compatible answer file ready for use.

end

Examples:

Generating an answer file for a series of hosts

hosts.each do |host|
  answers = Beaker::Answers.new("2.0", hosts, "master")
  create_remote_file host, "/mypath/answer", answers.answer_string(host, answers)

Parameters:

  • host (Beaker::Host)

    Host object in question to generate the answer file for.

Returns:

  • (String)

    a string of answers



201
202
203
# File 'lib/beaker-answers/answers.rb', line 201

def answer_string(host)
  answers[host.name].map { |k,v| "#{k}=#{v}" }.join("\n")
end

#answersHash

Access the answers hash for this version, host and option information. If the answers have not yet been calculated, generate them.

Returns:

  • (Hash)

    A hash of answers keyed by host.name



186
187
188
# File 'lib/beaker-answers/answers.rb', line 186

def answers
  @answers ||= generate_answers
end

#generate_answersObject

Generate the answers hash based upon version, host and option information



179
180
181
# File 'lib/beaker-answers/answers.rb', line 179

def generate_answers
  raise "This should be handled by subclasses!"
end

#get_defaults_or_answers(defaults_to_set) ⇒ Object



147
148
149
150
151
152
153
154
155
# File 'lib/beaker-answers/answers.rb', line 147

def get_defaults_or_answers(defaults_to_set)
  config = {}

  defaults_to_set.each do |key|
      config[key] = answer_for(@options, key)
  end

  return config
end

#installer_configuration_string(host) ⇒ Object



209
210
211
# File 'lib/beaker-answers/answers.rb', line 209

def installer_configuration_string(host)
  answer_string(host)
end

#only_host_with_role(hosts, role) ⇒ Host

Find a single host with the role provided. Raise an error if more than one host is found to have the provided role.

Parameters:

  • hosts (Array<Host>)

    The hosts to examine

  • role (String)

    The host returned will have this role in its role list

Returns:

  • (Host)

    The single host with the desired role in its roles list

Raises:

  • (ArgumentError)

    Raised if more than one host has the given role defined, or if no host has the role defined.



221
222
223
224
225
226
227
# File 'lib/beaker-answers/answers.rb', line 221

def only_host_with_role(hosts, role)
  found_hosts =  hosts.select{ |host| role.nil? or host['roles'].include?(role.to_s)}
  if found_hosts.length == 0 or found_hosts.length > 1
    raise ArgumentError, "There should be one host with #{role} defined, found #{found_hosts.length} matching hosts (#{found_hosts})"
  end
  found_hosts.first
end