]>
Commit | Line | Data |
---|---|---|
1 | class role::cryptoportfolio { | |
2 | ensure_resource('exec', 'systemctl daemon-reload', { | |
3 | command => '/usr/bin/systemctl daemon-reload', | |
4 | refreshonly => true | |
5 | }) | |
6 | ||
7 | include "base_installation" | |
8 | ||
9 | include "profile::tools" | |
10 | include "profile::postgresql" | |
11 | include "profile::apache" | |
12 | include "profile::xmr_stak" | |
13 | ||
14 | $password_seed = lookup("base_installation::puppet_pass_seed") |$key| { {} } | |
15 | ||
16 | $cf_pg_user = "cryptoportfolio" | |
17 | $cf_pg_user_replication = "cryptoportfolio_replication" | |
18 | $cf_pg_db = "cryptoportfolio" | |
19 | $cf_pg_password = generate_password(24, $password_seed, "postgres_cryptoportfolio") | |
20 | $cf_pg_replication_password = generate_password(24, $password_seed, "postgres_cryptoportfolio_replication") | |
21 | $cf_pg_hostname = "localhost" | |
22 | $cf_pg_port = "5432" | |
23 | $cf_pg_host = "${cf_pg_hostname}:${cf_pg_port}" | |
24 | ||
25 | $cf_user = "cryptoportfolio" | |
26 | $cf_group = "cryptoportfolio" | |
27 | $cf_home = "/opt/cryptoportfolio" | |
28 | $cf_env = "prod" | |
29 | $cf_front_app_host = lookup("base_installation::system_hostname") |$key| { "example.com" } | |
30 | $cf_front_app_port = "" | |
31 | $cf_front_app_ssl = "true" | |
32 | $cf_front_app = "${cf_home}/go/src/immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front" | |
33 | $cf_front_app_api_workdir = "${cf_front_app}/cmd/app" | |
34 | $cf_front_app_api_bin = "${cf_front_app_api_workdir}/cryptoportfolio-app" | |
35 | $cf_front_app_api_conf = "${cf_home}/conf.toml" | |
36 | $cf_front_app_api_secret = generate_password(24, $password_seed, "cryptoportfolio_api_secret") | |
37 | ||
38 | $cf_front_app_static_conf = "${cf_front_app}/cmd/web/env/prod.env" | |
39 | ||
40 | $cf_bot_app = "${cf_home}/bot" | |
41 | $cf_bot_app_conf = "${cf_home}/bot_config.ini" | |
42 | $cf_bot_app_reports = "${cf_home}/bot_reports" | |
43 | ||
44 | file { "/var/lib/postgres/data/certs": | |
45 | ensure => directory, | |
46 | mode => "0700", | |
47 | owner => $::profile::postgresql::pg_user, | |
48 | group => $::profile::postgresql::pg_user, | |
49 | require => File["/var/lib/postgres"], | |
50 | } | |
51 | ||
52 | file { "/var/lib/postgres/data/certs/cert.pem": | |
53 | source => "file:///etc/letsencrypt/live/$cf_front_app_host/cert.pem", | |
54 | mode => "0600", | |
55 | links => "follow", | |
56 | owner => $::profile::postgresql::pg_user, | |
57 | group => $::profile::postgresql::pg_user, | |
58 | require => [Letsencrypt::Certonly[$cf_front_app_host], File["/var/lib/postgres/data/certs"]] | |
59 | } | |
60 | ||
61 | file { "/var/lib/postgres/data/certs/privkey.pem": | |
62 | source => "file:///etc/letsencrypt/live/$cf_front_app_host/privkey.pem", | |
63 | mode => "0600", | |
64 | links => "follow", | |
65 | owner => $::profile::postgresql::pg_user, | |
66 | group => $::profile::postgresql::pg_user, | |
67 | require => [Letsencrypt::Certonly[$cf_front_app_host], File["/var/lib/postgres/data/certs"]] | |
68 | } | |
69 | ||
70 | postgresql::server::config_entry { "wal_level": | |
71 | value => "logical", | |
72 | } | |
73 | ||
74 | postgresql::server::config_entry { "ssl": | |
75 | value => "on", | |
76 | require => Letsencrypt::Certonly[$cf_front_app_host], | |
77 | } | |
78 | ||
79 | postgresql::server::config_entry { "ssl_cert_file": | |
80 | value => "/var/lib/postgres/data/certs/cert.pem", | |
81 | require => Letsencrypt::Certonly[$cf_front_app_host], | |
82 | } | |
83 | ||
84 | postgresql::server::config_entry { "ssl_key_file": | |
85 | value => "/var/lib/postgres/data/certs/privkey.pem", | |
86 | require => Letsencrypt::Certonly[$cf_front_app_host], | |
87 | } | |
88 | ||
89 | postgresql::server::db { $cf_pg_db: | |
90 | user => $cf_pg_user, | |
91 | password => postgresql_password($cf_pg_user, $cf_pg_password), | |
92 | } | |
93 | -> | |
94 | postgresql_psql { "CREATE PUBLICATION ${cf_pg_db}_publication FOR ALL TABLES": | |
95 | db => $cf_pg_db, | |
96 | unless => "SELECT 1 FROM pg_catalog.pg_publication WHERE pubname = '${cf_pg_db}_publication'", | |
97 | } | |
98 | -> | |
99 | postgresql::server::role { $cf_pg_user_replication: | |
100 | db => $cf_pg_db, | |
101 | replication => true, | |
102 | password_hash => postgresql_password($cf_pg_user_replication, $cf_pg_replication_password), | |
103 | } | |
104 | -> | |
105 | postgresql::server::database_grant { $cf_pg_user_replication: | |
106 | db => $cf_pg_db, | |
107 | privilege => "CONNECT", | |
108 | role => $cf_pg_user_replication, | |
109 | } | |
110 | -> | |
111 | postgresql::server::grant { "all tables in schema:public:$cf_pg_user_replication": | |
112 | db => $cf_pg_db, | |
113 | role => $cf_pg_user_replication, | |
114 | privilege => "SELECT", | |
115 | object_type => "ALL TABLES IN SCHEMA", | |
116 | object_name => "public", | |
117 | } | |
118 | -> | |
119 | postgresql::server::grant { "all sequences in schema:public:$cf_pg_user_replication": | |
120 | db => $cf_pg_db, | |
121 | role => $cf_pg_user_replication, | |
122 | privilege => "SELECT", | |
123 | object_type => "ALL SEQUENCES IN SCHEMA", | |
124 | object_name => "public", | |
125 | } | |
126 | ||
127 | postgresql::server::pg_hba_rule { 'allow localhost TCP access to cryptoportfolio user': | |
128 | type => 'host', | |
129 | database => $cf_pg_db, | |
130 | user => $cf_pg_user, | |
131 | address => '127.0.0.1/32', | |
132 | auth_method => 'md5', | |
133 | order => "b0", | |
134 | } | |
135 | postgresql::server::pg_hba_rule { 'allow localhost ip6 TCP access to cryptoportfolio user': | |
136 | type => 'host', | |
137 | database => $cf_pg_db, | |
138 | user => $cf_pg_user, | |
139 | address => '::1/128', | |
140 | auth_method => 'md5', | |
141 | order => "b0", | |
142 | } | |
143 | ||
144 | postgresql::server::pg_hba_rule { 'allow TCP access to replication user from immae.eu': | |
145 | type => 'hostssl', | |
146 | database => $cf_pg_db, | |
147 | user => $cf_pg_user_replication, | |
148 | address => 'immae.eu', | |
149 | auth_method => 'md5', | |
150 | order => "b0", | |
151 | } | |
152 | ||
153 | letsencrypt::certonly { $cf_front_app_host: ; | |
154 | default: * => $::profile::apache::letsencrypt_certonly_default; | |
155 | } | |
156 | ||
157 | class { 'apache::mod::headers': } | |
158 | apache::vhost { $cf_front_app_host: | |
159 | port => '443', | |
160 | docroot => false, | |
161 | manage_docroot => false, | |
162 | proxy_dest => "http://localhost:8000", | |
163 | request_headers => 'set X-Forwarded-Proto "https"', | |
164 | ssl => true, | |
165 | ssl_cert => "/etc/letsencrypt/live/$cf_front_app_host/cert.pem", | |
166 | ssl_key => "/etc/letsencrypt/live/$cf_front_app_host/privkey.pem", | |
167 | ssl_chain => "/etc/letsencrypt/live/$cf_front_app_host/chain.pem", | |
168 | require => Letsencrypt::Certonly[$cf_front_app_host], | |
169 | proxy_preserve_host => true; | |
170 | default: * => $::profile::apache::apache_vhost_default; | |
171 | } | |
172 | ||
173 | user { $cf_user: | |
174 | name => $cf_user, | |
175 | ensure => "present", | |
176 | managehome => true, | |
177 | home => $cf_home, | |
178 | system => true, | |
179 | password => '!!', | |
180 | } | |
181 | ||
182 | $front_version = lookup("cryptoportfolio::front_version") |$key| { {} } | |
183 | $front_sha256 = lookup("cryptoportfolio::front_sha256") |$key| { {} } | |
184 | ||
185 | $bot_version = lookup("cryptoportfolio::bot_version") |$key| { {} } | |
186 | $bot_sha256 = lookup("cryptoportfolio::bot_sha256") |$key| { {} } | |
187 | ||
188 | unless empty($bot_version) { | |
189 | ensure_packages(["python", "python-pip"]) | |
190 | ||
191 | file { $cf_bot_app: | |
192 | ensure => "directory", | |
193 | mode => "0700", | |
194 | owner => $cf_user, | |
195 | group => $cf_group, | |
196 | require => User[$cf_user], | |
197 | } | |
198 | ||
199 | archive { "${cf_home}/${bot_version}.tar.gz": | |
200 | path => "${cf_home}/${bot_version}.tar.gz", | |
201 | source => "https://git.immae.eu/releases/cryptoportfolio/trader/trader_${bot_version}.tar.gz", | |
202 | checksum_type => "sha256", | |
203 | checksum => $bot_sha256, | |
204 | cleanup => false, | |
205 | extract => true, | |
206 | user => "cryptoportfolio", | |
207 | username => $facts["ec2_metadata"]["hostname"], | |
208 | password => generate_password(24, $password_seed, "ldap"), | |
209 | extract_path => $cf_bot_app, | |
210 | require => [User[$cf_user], File[$cf_bot_app]], | |
211 | } ~> | |
212 | exec { "py-cryptoportfolio-dependencies": | |
213 | cwd => $cf_bot_app, | |
214 | user => $cf_user, | |
215 | environment => ["HOME=${cf_home}"], | |
216 | command => "/usr/bin/make install", | |
217 | require => User[$cf_user], | |
218 | refreshonly => true, | |
219 | before => [ | |
220 | File[$cf_bot_app_conf], | |
221 | Cron["py-cryptoportfolio-before"], | |
222 | Cron["py-cryptoportfolio-after"], | |
223 | ] | |
224 | } | |
225 | ||
226 | file { $cf_bot_app_conf: | |
227 | owner => $cf_user, | |
228 | group => $cf_group, | |
229 | mode => "0600", | |
230 | content => template("role/cryptoportfolio/bot_config.ini.erb"), | |
231 | require => [ | |
232 | User[$cf_user], | |
233 | Archive["${cf_home}/${bot_version}.tar.gz"], | |
234 | ], | |
235 | } | |
236 | ||
237 | cron { "py-cryptoportfolio-before": | |
238 | ensure => present, | |
239 | command => "cd $cf_bot_app ; python main.py --config $cf_bot_app_conf --before", | |
240 | user => "cryptoportfolio", | |
241 | weekday => 7, # Sunday | |
242 | hour => 22, | |
243 | minute => 30, | |
244 | environment => ["HOME=${cf_home}","PATH=/usr/bin/"], | |
245 | require => [ | |
246 | File[$cf_bot_app_conf], | |
247 | Archive["${cf_home}/${bot_version}.tar.gz"] | |
248 | ], | |
249 | } | |
250 | ||
251 | cron { "py-cryptoportfolio-after": | |
252 | ensure => present, | |
253 | command => "cd $cf_bot_app ; python main.py --config $cf_bot_app_conf --after", | |
254 | user => "cryptoportfolio", | |
255 | weekday => 1, # Monday | |
256 | hour => 1, | |
257 | minute => 0, | |
258 | environment => ["HOME=${cf_home}","PATH=/usr/bin/"], | |
259 | require => [ | |
260 | File[$cf_bot_app_conf], | |
261 | Archive["${cf_home}/${bot_version}.tar.gz"] | |
262 | ], | |
263 | } | |
264 | } | |
265 | ||
266 | # FIXME: incorrect build for go app | |
267 | # FIXME: restore backup | |
268 | unless empty($front_version) { | |
269 | ensure_packages(["go", "npm", "nodejs", "yarn"]) | |
270 | ||
271 | file { [ | |
272 | "${cf_home}/go/", | |
273 | "${cf_home}/go/src", | |
274 | "${cf_home}/go/src/immae.eu", | |
275 | "${cf_home}/go/src/immae.eu/Immae", | |
276 | "${cf_home}/go/src/immae.eu/Immae/Projets", | |
277 | "${cf_home}/go/src/immae.eu/Immae/Projets/Cryptomonnaies", | |
278 | "${cf_home}/go/src/immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio", | |
279 | $cf_front_app]: | |
280 | ensure => "directory", | |
281 | mode => "0700", | |
282 | owner => $cf_user, | |
283 | group => $cf_group, | |
284 | require => User[$cf_user], | |
285 | } | |
286 | ||
287 | archive { "${cf_home}/${front_version}.tar.gz": | |
288 | path => "${cf_home}/${front_version}.tar.gz", | |
289 | source => "https://git.immae.eu/releases/cryptoportfolio/front/front_${front_version}.tar.gz", | |
290 | checksum_type => "sha256", | |
291 | checksum => $front_sha256, | |
292 | cleanup => false, | |
293 | extract => true, | |
294 | user => $cf_user, | |
295 | username => $facts["ec2_metadata"]["hostname"], | |
296 | password => generate_password(24, $password_seed, "ldap"), | |
297 | extract_path => $cf_front_app, | |
298 | require => [User[$cf_user], File[$cf_front_app]], | |
299 | } | |
300 | ||
301 | file { "${cf_home}/front": | |
302 | ensure => "link", | |
303 | target => $cf_front_app, | |
304 | before => File[$cf_front_app], | |
305 | } ~> | |
306 | exec { "remove old ${cf_front_app} directory": | |
307 | refreshonly => true, | |
308 | user => $cf_user, | |
309 | command => "/usr/bin/rm -rf ${cf_front_app}", | |
310 | before => File[$cf_front_app], | |
311 | } | |
312 | ||
313 | exec { "go-get-dep": | |
314 | user => $cf_user, | |
315 | environment => ["HOME=${cf_home}"], | |
316 | creates => "${cf_home}/go/bin/dep", | |
317 | command => "/usr/bin/go get -u github.com/golang/dep/cmd/dep", | |
318 | require => User[$cf_user], | |
319 | } | |
320 | ||
321 | exec { "go-cryptoportfolio-dependencies": | |
322 | cwd => $cf_front_app, | |
323 | user => $cf_user, | |
324 | environment => ["HOME=${cf_home}"], | |
325 | creates => "${cf_front_app}/vendor", | |
326 | command => "${cf_home}/go/bin/dep ensure", | |
327 | require => [Exec["go-get-dep"], Archive["${cf_home}/${front_version}.tar.gz"]], | |
328 | } | |
329 | ||
330 | exec { "go-cryptoportfolio-app": | |
331 | cwd => $cf_front_app_api_workdir, | |
332 | user => $cf_user, | |
333 | environment => ["HOME=${cf_home}"], | |
334 | creates => $cf_front_app_api_bin, | |
335 | command => "/usr/bin/make build", | |
336 | require => Exec["go-cryptoportfolio-dependencies"], | |
337 | } | |
338 | ||
339 | file { "/etc/systemd/system/cryptoportfolio-app.service": | |
340 | mode => "0644", | |
341 | owner => "root", | |
342 | group => "root", | |
343 | content => template("role/cryptoportfolio/cryptoportfolio-app.service.erb"), | |
344 | notify => Exec["systemctl daemon-reload"], | |
345 | } | |
346 | ||
347 | service { 'cryptoportfolio-app': | |
348 | enable => true, | |
349 | ensure => "running", | |
350 | subscribe => [Exec["go-cryptoportfolio-app"], Exec["web-cryptoportfolio-build"]], | |
351 | require => [ | |
352 | File["/etc/systemd/system/cryptoportfolio-app.service"], | |
353 | Postgresql::Server::Db[$cf_pg_db] | |
354 | ], | |
355 | } ~> | |
356 | exec { "dump $cf_pg_db structure": | |
357 | refreshonly => true, | |
358 | user => $::profile::postgresql::pg_user, | |
359 | group => $::profile::postgresql::pg_user, | |
360 | command => "/usr/bin/pg_dump --schema-only --clean --no-publications $cf_pg_db > /var/lib/postgres/${cf_pg_db}.schema", | |
361 | } | |
362 | ||
363 | file { $cf_front_app_api_conf: | |
364 | owner => $cf_user, | |
365 | group => $cf_group, | |
366 | mode => "0600", | |
367 | content => template("role/cryptoportfolio/api_conf.toml.erb"), | |
368 | } | |
369 | ||
370 | file { $cf_front_app_static_conf: | |
371 | owner => $cf_user, | |
372 | group => $cf_group, | |
373 | mode => "0600", | |
374 | content => template("role/cryptoportfolio/static_conf.env.erb"), | |
375 | notify => Exec["remove build ${cf_front_app}/cmd/web/build/"], | |
376 | } | |
377 | ||
378 | exec { "web-cryptoportfolio-dependencies": | |
379 | cwd => "${cf_front_app}/cmd/web", | |
380 | environment => ["HOME=${cf_home}"], | |
381 | command => "/usr/bin/make install", | |
382 | creates => "${cf_front_app}/cmd/web/node_modules", | |
383 | notify => Exec["remove build ${cf_front_app}/cmd/web/build/"], | |
384 | require => [Package["npm"], Package["nodejs"], Package["yarn"]] | |
385 | } | |
386 | ||
387 | exec { "remove build ${cf_front_app}/cmd/web/build/": | |
388 | command => "/usr/bin/rm -rf '${cf_front_app}/cmd/web/build/'", | |
389 | refreshonly => true, | |
390 | before => Exec["web-cryptoportfolio-build"] | |
391 | } | |
392 | ||
393 | exec { "web-cryptoportfolio-build": | |
394 | cwd => "${cf_front_app}/cmd/web", | |
395 | environment => ["HOME=${cf_home}"], | |
396 | path => ["${cf_front_app}/cmd/web/node_modules/.bin/", "/usr/bin"], | |
397 | command => "/usr/bin/make static ENV=${cf_env}", | |
398 | creates => "${cf_front_app}/cmd/web/build/static", | |
399 | require => [File[$cf_front_app_static_conf], Exec["web-cryptoportfolio-dependencies"]] | |
400 | } | |
401 | } | |
402 | } |