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