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