ref_arch_setup 0.0.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,119 @@
1
+ #----------------------------------------------------------------------------
2
+ # Puppet Enterprise installer configuration file
3
+ # https://docs.puppet.com/pe/latest/install_pe_conf_param.html
4
+ #
5
+ # Format: Hocon
6
+ # https://docs.puppet.com/pe/latest/config_hocon.html
7
+ #----------------------------------------------------------------------------
8
+ {
9
+ #--------------------------------------------------------------------------
10
+ # ⚠️ REQUIRED FOR INSTALLATION ⚠️
11
+ #
12
+ # The password to log into the Puppet Enterprise console.
13
+ #
14
+ # After installation, you may set the console_admin_password to an empty
15
+ # string to avoid storing a password in plain text.
16
+ #--------------------------------------------------------------------------
17
+ "console_admin_password": "puppetlabs"
18
+
19
+
20
+ #--------------------------------------------------------------------------
21
+ # PE Component assignments.
22
+ #
23
+ # If you're performing a monolithic install (recommended), there is no need
24
+ # to change the default settings, and you do not need to set the
25
+ # puppetdb_host and console_host parameters.
26
+ #
27
+ # When performing a split install, do not use the %{::trusted.certname} fact.
28
+ # Instead set the FQDN for all three PE component nodes.
29
+ # For more information, refer to:
30
+ # https://docs.puppet.com/pe/latest/install_text_mode_split.html
31
+ #
32
+ # Overview of PE Components:
33
+ # https://docs.puppet.com/pe/latest/pe_architecture_overview.html
34
+ #-------------------------------------------------------------------------
35
+
36
+ # Puppet Enterprise Master
37
+ "puppet_enterprise::puppet_master_host": "%{::trusted.certname}"
38
+
39
+ # Puppet Enterprise Console
40
+ #"puppet_enterprise::console_host": ""
41
+
42
+ # PuppetDB
43
+ #"puppet_enterprise::puppetdb_host": ""
44
+
45
+ # Hostname of database node if pe-postgres is being run on its own node
46
+ #"puppet_enterprise::database_host": ""
47
+
48
+ #--------------------------------------------------------------------------
49
+ # DATABASE CONFIGURATION
50
+ #
51
+ # Puppet Enterprise uses PostgreSQL as a database backend.
52
+ # PE can install and manage a new one (recommended), or you can use an
53
+ # existing instance.
54
+ #
55
+ # For details on using an existing PostgreSQL database, visit:
56
+ # https://docs.puppet.com/pe/latest/install_system_requirements.html
57
+ #
58
+ # UPGRADE NOTE:
59
+ # If you’re upgrading and have previously used non-default database names and
60
+ # users, you must uncomment and change these parameters to match what you
61
+ # have used.
62
+ #--------------------------------------------------------------------------
63
+
64
+ #"puppet_enterprise::activity_database_name": "pe-activity"
65
+ #"puppet_enterprise::activity_service_migration_db_user": "pe-activity"
66
+ #"puppet_enterprise::activity_service_regular_db_user": "pe-activity"
67
+ #"puppet_enterprise::classifier_database_name": "pe-classifier"
68
+ #"puppet_enterprise::classifier_service_migration_db_user": "pe-classifier"
69
+ #"puppet_enterprise::classifier_service_regular_db_user": "pe-classifier"
70
+ #"puppet_enterprise::orchestrator_database_name": "pe-orchestrator"
71
+ #"puppet_enterprise::orchestrator_service_migration_db_user": "pe-orchestrator"
72
+ #"puppet_enterprise::orchestrator_service_regular_db_user": "pe-orchestrator"
73
+ #"puppet_enterprise::rbac_database_name": "pe-rbac"
74
+ #"puppet_enterprise::rbac_service_migration_db_user": "pe-rbac"
75
+ #"puppet_enterprise::rbac_service_regular_db_user": "pe-rbac"
76
+ #"puppet_enterprise::puppetdb_database_name": "pe-puppetdb"
77
+ #"puppet_enterprise::puppetdb_database_user": "pe-puppetdb"
78
+
79
+
80
+ # EXTERNAL POSTGRES OPTIONS ONLY
81
+ # If you're using an existing PostgreSQL instance that was not set up by
82
+ # Puppet Enterprise, set the following parameters:
83
+
84
+ #"puppet_enterprise::database_ssl": false
85
+ #"puppet_enterprise::database_cert_auth": false
86
+ #"puppet_enterprise::activity_database_password": "PASSWORD"
87
+ #"puppet_enterprise::classifier_database_password": "PASSWORD"
88
+ #"puppet_enterprise::orchestrator_database_password": "PASSWORD"
89
+ #"puppet_enterprise::rbac_database_password": "PASSWORD"
90
+ #"puppet_enterprise::puppetdb_database_password": "PASSWORD"
91
+
92
+
93
+ #--------------------------------------------------------------------------
94
+ # ADVANCED AND CUSTOM PARAMETERS
95
+ #
96
+ # You can use the following parameters as needed, or add your own parameters
97
+ # to this section.
98
+ #
99
+ # For a complete list of parameters and what they do, visit:
100
+ # https://docs.puppet.com/pe/latest/install_pe_conf_param.html
101
+ #--------------------------------------------------------------------------
102
+
103
+ # DNS altnames to be added to the SSL certificate generated for the Puppet
104
+ # master node. Only used at install time.
105
+ #"pe_install::puppet_master_dnsaltnames": ["puppet"]
106
+
107
+ #Enabling this configures code manager, all three below values should be enabled and populated at the same time.
108
+ #"puppet_enterprise::profile::master::code_manager_auto_configure": true
109
+
110
+ #The ssh url to your existing control repo.
111
+ #"puppet_enterprise::profile::master::r10k_remote": "git@your.git.server.com:puppet/control.git"
112
+
113
+ #The private key to your puppetmaster for establishing key-based ssh authentication to your vcs.
114
+ #"puppet_enterprise::profile::master::r10k_private_key": "/etc/puppetlabs/puppetserver/ssh/id-control_repo.rsa"
115
+
116
+ #test key that does nothing
117
+ "ref_arch::name": "basic"
118
+ }
119
+
@@ -1,8 +1,14 @@
1
1
  # General namespace for RAS
2
2
  module RefArchSetup
3
- %w[cli version install].each do |lib|
3
+ %w[cli bolt_helper download_helper version install].each do |lib|
4
4
  require "ref_arch_setup/#{lib}"
5
5
  end
6
+ # the location of ref_arch_setup
7
+ RAS_PATH = File.dirname(__FILE__) + "/..".freeze
6
8
  # location of modules shipped with RAS (Ref Arch Setup)
7
- RAS_MODULE_PATH = File.dirname(__FILE__) + "/../modules"
9
+ RAS_MODULE_PATH = "#{RAS_PATH}/modules".freeze
10
+ # location of fixtures shipped with RAS (Ref Arch Setup)
11
+ RAS_FIXTURES_PATH = "#{RAS_PATH}/fixtures".freeze
12
+ # location of modules downloaded from the Puppet Forge
13
+ FORGE_MODULE_PATH = "#{RAS_PATH}/Boltdir/modules".freeze
8
14
  end
@@ -0,0 +1,263 @@
1
+ # General namespace for RAS
2
+ module RefArchSetup
3
+ # Bolt helper methods
4
+ class BoltHelper
5
+ # the user RAS will provide to the bolt --run-as option
6
+ BOLT_RUN_AS_USER = "root".freeze
7
+
8
+ # the default options to specify when running bolt commands
9
+ BOLT_DEFAULT_OPTIONS = { "run-as" => BOLT_RUN_AS_USER }.freeze
10
+
11
+ @bolt_options = BOLT_DEFAULT_OPTIONS
12
+
13
+ # custom exception class for bolt command errors
14
+ class BoltCommandError < StandardError
15
+ attr_reader :output
16
+ def initialize(message, output)
17
+ @output = output
18
+ super(message)
19
+ end
20
+ end
21
+
22
+ # Initializes the bolt options to the default
23
+ #
24
+ # @author Bill Claytor
25
+ #
26
+ def self.init
27
+ @bolt_options = BOLT_DEFAULT_OPTIONS
28
+ end
29
+
30
+ # Merges the specified bolt options with the default options
31
+ # or optionally overwriting the default options
32
+ #
33
+ # @author Bill Claytor
34
+ #
35
+ # @param [hash] options_hash The user-specified bolt options hash
36
+ # @param [boolean] overwrite The flag indicating whether the default options
37
+ # should be overwritten
38
+ #
39
+ def self.bolt_options(options_hash, overwrite = false)
40
+ @bolt_options = if overwrite
41
+ options_hash
42
+ else
43
+ @bolt_options.merge(options_hash)
44
+ end
45
+ end
46
+
47
+ # Merges the default bolt options with the specified options
48
+ #
49
+ # @author Bill Claytor
50
+ #
51
+ # @param [hash] options_hash The user-specified bolt options hash
52
+ #
53
+ def self.bolt_options=(options_hash)
54
+ bolt_options(options_hash)
55
+ end
56
+
57
+ # Gets the bolt options as a string
58
+ #
59
+ # @author Sam Woods
60
+ # @return [string] the string value for bolt options
61
+ def self.bolt_options_string
62
+ bolt_options_string = ""
63
+ @bolt_options.each do |key, value|
64
+ bolt_options_string << " --#{key} #{value}"
65
+ end
66
+ bolt_options_string
67
+ end
68
+
69
+ # Creates a dir on the target_host
70
+ # Doesn't fail if dir is already there
71
+ # Uses -p to create parent dirs if needed
72
+ #
73
+ # @author Randell Pelak
74
+ #
75
+ # @param [string] dir Directory to create
76
+ # @param [string] nodes Hosts to make dir on
77
+ #
78
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
79
+ #
80
+ # @return [true,false] Based on the output returned from the bolt command
81
+ def self.make_dir(dir, nodes)
82
+ error_message = "ERROR: Failed to make dir #{dir} on all nodes"
83
+ cmd = "mkdir -p #{dir}"
84
+ output = run_cmd_with_bolt(cmd, nodes, error_message)
85
+ success = output.nil? ? false : true
86
+ return success
87
+ end
88
+
89
+ # Run the specified command
90
+ #
91
+ # @author Bill Claytor
92
+ #
93
+ # @param command [string] The command to run
94
+ # @param error_message [string] The error to raise if the command is not successful
95
+ #
96
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
97
+ #
98
+ # @return [string] The output returned from the command
99
+ def self.run_command(command, error_message = "ERROR: command failed!")
100
+ puts "Running: #{command}"
101
+ output = `#{command}`
102
+ puts "Output was: #{output}"
103
+
104
+ success = $?.success? # rubocop:disable Style/SpecialGlobalVars
105
+ puts "Exit status was: #{$?.exitstatus}" # rubocop:disable Style/SpecialGlobalVars
106
+ puts
107
+
108
+ # raise error_message unless success
109
+ raise BoltCommandError.new(error_message, output) if output.nil?
110
+ raise BoltCommandError.new(error_message, output) unless success
111
+
112
+ return output
113
+ end
114
+
115
+ # Run a command with bolt on given nodes
116
+ #
117
+ # @author Randell Pelak
118
+ #
119
+ # @param [string] cmd Command to run on the specified nodes
120
+ # @param [string] nodes Nodes on which the command should be run
121
+ # @param [string] error_message The message that should be used if an error is raised
122
+ #
123
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
124
+ #
125
+ # @return [string] The output returned from the bolt command
126
+ def self.run_cmd_with_bolt(cmd, nodes, error_message = "ERROR: bolt command failed!")
127
+ command = "bolt command run '#{cmd}'"
128
+ command << " --nodes #{nodes}"
129
+ command << bolt_options_string
130
+
131
+ output = run_command(command, error_message)
132
+ return output
133
+ end
134
+
135
+ # Run a task with bolt on given nodes
136
+ #
137
+ # @author Sam Woods
138
+ #
139
+ # @param task [string] Task to run on nodes
140
+ # @param params [hash] task parameters to send to bolt
141
+ # @param nodes [string] Host or space delimited hosts to run task on
142
+ # @param modulepath [string] The modulepath to use when running bolt
143
+ #
144
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
145
+ #
146
+ # @return [string] The output returned from the bolt command
147
+ def self.run_task_with_bolt(task, params, nodes, modulepath = RAS_MODULE_PATH)
148
+ params_str = ""
149
+ params_str = params_to_string(params) unless params.nil?
150
+ command = "bolt task run #{task} #{params_str}"
151
+ command << " --modulepath #{modulepath} --nodes #{nodes}"
152
+ command << bolt_options_string
153
+
154
+ output = run_command(command, "ERROR: bolt task failed!")
155
+ return output
156
+ end
157
+
158
+ # Run a plan with bolt on given nodes
159
+ #
160
+ # @author Sam Woods
161
+ #
162
+ # @param plan [string] Plan to run on nodes
163
+ # @param params [hash] Plan parameters to send to bolt
164
+ # @param nodes [string] Host or space delimited hosts to run plan on
165
+ # @param modulepath [string] The modulepath to use when running bolt
166
+ #
167
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
168
+ #
169
+ # @return [string] The output returned from the bolt command
170
+ def self.run_plan_with_bolt(plan, params, nodes, modulepath = RAS_MODULE_PATH)
171
+ params_str = ""
172
+ params_str = params_to_string(params) unless params.nil?
173
+ command = "bolt plan run #{plan} #{params_str}"
174
+ command << " --modulepath #{modulepath} --nodes #{nodes}"
175
+ command << bolt_options_string
176
+
177
+ output = run_command(command, "ERROR: bolt plan failed!")
178
+ return output
179
+ end
180
+
181
+ # Run a task from the forge with bolt on given nodes
182
+ #
183
+ # @author Bill Claytor
184
+ #
185
+ # @param task [string] Task to run on nodes
186
+ # @param params [hash] Task parameters to send to bolt
187
+ # @param nodes [string] Host or space delimited hosts to run task on
188
+ #
189
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
190
+ #
191
+ # @return [string] The output returned from the bolt command
192
+ def self.run_forge_task_with_bolt(task, params, nodes)
193
+ install_forge_modules
194
+ output = run_task_with_bolt(task, params, nodes, FORGE_MODULE_PATH)
195
+ return output
196
+ end
197
+
198
+ # Run a plan from the forge with bolt on given nodes
199
+ #
200
+ # @author Bill Claytor
201
+ #
202
+ # @param plan [string] Plan to run on nodes
203
+ # @param params [hash] Plan parameters to send to bolt
204
+ # @param nodes [string] Host or space delimited hosts to run plan on
205
+ #
206
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
207
+ #
208
+ # @return [string] The output returned from the bolt command
209
+ def self.run_forge_plan_with_bolt(plan, params, nodes)
210
+ install_forge_modules
211
+ output = run_plan_with_bolt(plan, params, nodes, FORGE_MODULE_PATH)
212
+ return output
213
+ end
214
+
215
+ # Convert params to string for bolt
216
+ # format is space separated list of name=value
217
+ #
218
+ # @author Randell Pelak
219
+ #
220
+ # @param params [Array] params to convert
221
+ #
222
+ # @return [String] stringified params
223
+ def self.params_to_string(params)
224
+ str = params.map { |k, v| "#{k}=#{v}" }.join(" ")
225
+ return str
226
+ end
227
+
228
+ # Upload a file to given nodes
229
+ #
230
+ # @author Randell Pelak
231
+ #
232
+ # @param [string] source File to upload
233
+ # @param [string] destination Path to upload to
234
+ # @param [string] nodes Host to put files on
235
+ #
236
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
237
+ #
238
+ # @return [output] The output returned from the bolt command
239
+ def self.upload_file(source, destination, nodes)
240
+ command = "bolt file upload #{source} #{destination}"
241
+ command << " --nodes #{nodes}"
242
+ command << bolt_options_string
243
+
244
+ error_message = "ERROR: failed to upload file #{source} to #{destination} on #{nodes}"
245
+ output = run_command(command, error_message)
246
+ return output
247
+ end
248
+
249
+ # Install modules from the forge via Puppetfile
250
+ # The modules are defined in Boltdir/Puppetfile
251
+ #
252
+ # @author Bill Claytor
253
+ #
254
+ # @raise [BoltCommandError] If the bolt command is not successful or the output is nil
255
+ #
256
+ # @return [string] The output returned from the bolt command
257
+ def self.install_forge_modules
258
+ command = "cd #{RAS_PATH} && bolt puppetfile install --modulepath #{FORGE_MODULE_PATH}"
259
+ output = run_command(command, "ERROR: bolt puppetfile install failed!")
260
+ return output
261
+ end
262
+ end
263
+ end
@@ -14,8 +14,9 @@ module RefArchSetup
14
14
  # @option options [String] something not yet defined
15
15
  #
16
16
  # @return [void]
17
- def initialize(options)
17
+ def initialize(options, bolt_options)
18
18
  @options = options
19
+ @bolt_options = bolt_options
19
20
  end
20
21
 
21
22
  # Check values of options to see if they are really an option
@@ -57,20 +58,88 @@ module RefArchSetup
57
58
  "option --#{option} is required for the #{subcommand} subcommand"
58
59
  end
59
60
 
61
+ # Wrapper around commands
62
+ #
63
+ # @author Randell Pelak
64
+ #
65
+ # @param [string] command the name of the command to run
66
+ # @param [string] subcommand the name of the subcommand to run
67
+ #
68
+ # @return [boolean] success of install
69
+ def run(command, subcommand = nil)
70
+ check_for_missing_value
71
+ BoltHelper.bolt_options = @bolt_options
72
+
73
+ comm = command
74
+ unless subcommand.nil?
75
+ str = subcommand.tr("-", "_")
76
+ comm += "_" + str
77
+ end
78
+ success = send(comm)
79
+ return success
80
+ end
81
+
60
82
  # Installs a bootstrap version of mono on the target host using the provided tarball and pe.conf
61
83
  #
62
84
  # @author Randell Pelak
63
85
  #
64
86
  # @return [boolean] success of install
65
87
  def install
66
- check_for_missing_value
67
- check_option("target_host", "install")
68
- check_option("pe_tarball_path", "install")
69
- check_option("pe_conf_path", "install")
70
- install_obj = RefArchSetup::Install.new(@options["target_host"])
71
- success = install_obj.bootstrap_mono(@options["pe_conf_path"], @options["pe_tarball_path"])
88
+ puts "Running install command"
89
+ success = true
90
+ success = install_generate_pe_conf unless @options.key?("pe_conf")
91
+ # TODO: Pass pe.conf object along so we don't have to read/validate it in each subcommand
92
+ success = install_bootstrap if success
93
+ success = install_pe_infra_agent_install if success
94
+ success = install_configure if success
95
+ return success
96
+ end
97
+
98
+ # Generates a pe.conf for use doing the install
99
+ #
100
+ # @author Randell Pelak
101
+ #
102
+ # @return [boolean] success of generating the pe.conf file
103
+ def install_generate_pe_conf
104
+ puts "Running generate-pe-conf subcommand of install command"
105
+ # check_option("console_password", "install") # password hardcoded in base file for now
106
+ return true
107
+ end
108
+
109
+ # Installs a bootstrap version of PE on the target host using the provided tarball and pe.conf
110
+ #
111
+ # @author Randell Pelak
112
+ #
113
+ # @return [boolean] success of install
114
+ def install_bootstrap
115
+ puts "Running bootstrap subcommand of install command"
116
+ # none of these will be required in the future... but are for now
117
+ check_option("primary_master", "install")
118
+ install_obj = RefArchSetup::Install.new(@options["primary_master"])
119
+ success = install_obj.bootstrap(@options["pe_conf"], @options["pe_tarball"],
120
+ @options["pe_version"])
72
121
  return success
73
122
  end
123
+
124
+ # Installs an agent on infrastructure nodes
125
+ #
126
+ # @author Randell Pelak
127
+ #
128
+ # @return [boolean] success of agent install
129
+ def install_pe_infra_agent_install
130
+ puts "Running pe-infra-agent-install subcommand of install command"
131
+ return true
132
+ end
133
+
134
+ # Configures infrastructure nodes and do initial perf tuning
135
+ #
136
+ # @author Randell Pelak
137
+ #
138
+ # @return [boolean] success of all the things
139
+ def install_configure
140
+ puts "Running configure subcommand of install command"
141
+ return true
142
+ end
74
143
  end
75
144
  end
76
145