ref_arch_setup 0.0.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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