aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/install_script.sh12
-rw-r--r--environments/integration/data/common.yaml25
-rw-r--r--environments/integration/data/roles/cryptoportfolio.yaml7
-rw-r--r--environments/integration/data/types/vps-ovhssd-1.yaml10
-rw-r--r--environments/integration/hiera.yaml19
-rw-r--r--environments/production/data/nodes/vps464408.novalocal.yaml1
-rw-r--r--environments/production/data/nodes/vps494082.yaml5
-rw-r--r--environments/production/data/roles/cryptoportfolio.yaml4
-rw-r--r--environments/production/data/types/vps-ovhssd-1.yaml1
-rw-r--r--environments/production/hiera.yaml9
-rw-r--r--modules/base_installation/files/cronie/puppet-post-merge2
-rw-r--r--modules/base_installation/files/scripts/puppet_reset_and_apply14
-rw-r--r--modules/base_installation/files/scripts/report_print.rb396
-rw-r--r--modules/base_installation/manifests/cronie.pp4
-rw-r--r--modules/base_installation/manifests/init.pp1
-rw-r--r--modules/base_installation/manifests/params.pp1
-rw-r--r--modules/base_installation/manifests/puppet.pp12
-rw-r--r--modules/base_installation/manifests/system_config.pp34
-rw-r--r--modules/base_installation/templates/puppet/host_ldap.info.erb4
-rw-r--r--modules/base_installation/templates/puppet/puppet.conf.erb4
-rw-r--r--modules/profile/manifests/apache.pp8
-rw-r--r--modules/role/manifests/cryptoportfolio.pp123
-rw-r--r--python/list_servers.py12
23 files changed, 602 insertions, 106 deletions
diff --git a/bin/install_script.sh b/bin/install_script.sh
index 49a737f..6b1aa39 100755
--- a/bin/install_script.sh
+++ b/bin/install_script.sh
@@ -12,6 +12,7 @@ cat <<EOF
12 --no-reboot-start Don't reboot to rescue at the beginning 12 --no-reboot-start Don't reboot to rescue at the beginning
13 --no-reboot-end Don't reboot to normal at the end 13 --no-reboot-end Don't reboot to normal at the end
14 --git-branch Use another puppet branch (default: master) 14 --git-branch Use another puppet branch (default: master)
15 --environment Environment to use for the installl (default: production)
15EOF 16EOF
16} 17}
17 18
@@ -19,6 +20,7 @@ set -e
19 20
20host_user=root 21host_user=root
21git_branch=master 22git_branch=master
23environment=production
22 24
23while [ -n "$1" ]; do 25while [ -n "$1" ]; do
24 case "$1" in 26 case "$1" in
@@ -50,6 +52,10 @@ while [ -n "$1" ]; do
50 git_branch="$2" 52 git_branch="$2"
51 shift 53 shift
52 ;; 54 ;;
55 --environment)
56 environment="$2"
57 shift
58 ;;
53 --help|-h) 59 --help|-h)
54 usage 60 usage
55 exit 0 61 exit 0
@@ -173,9 +179,9 @@ cat > $ARCH_INSTALL_SCRIPT <<EOF
173CODE_PATH="/etc/puppetlabs/code" 179CODE_PATH="/etc/puppetlabs/code"
174rm -rf \$CODE_PATH 180rm -rf \$CODE_PATH
175git clone -b $git_branch --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git \$CODE_PATH 181git clone -b $git_branch --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git \$CODE_PATH
176puppet apply --tags base_installation --test \$CODE_PATH/manifests/site.pp 182puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp
177# The password seed requires puppet to be run twice 183# The password seed requires puppet to be run twice
178puppet apply --tags base_installation --test \$CODE_PATH/manifests/site.pp 184puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp
179EOF 185EOF
180 186
181chmod a+x $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT 187chmod a+x $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT
@@ -197,7 +203,7 @@ read -p "Press key when LDAP is configured" i
197 203
198cat > $ARCH_PUPPET_CONFIGURATION_SCRIPT <<EOF 204cat > $ARCH_PUPPET_CONFIGURATION_SCRIPT <<EOF
199CODE_PATH="/etc/puppetlabs/code" 205CODE_PATH="/etc/puppetlabs/code"
200puppet apply --tags base_installation --test \$CODE_PATH/manifests/site.pp 206puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp
201EOF 207EOF
202 208
203cat > $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT <<EOF 209cat > $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT <<EOF
diff --git a/environments/integration/data/common.yaml b/environments/integration/data/common.yaml
new file mode 100644
index 0000000..78cce6b
--- /dev/null
+++ b/environments/integration/data/common.yaml
@@ -0,0 +1,25 @@
1---
2classes:
3 stdlib: ~
4
5base_installation::ldap_base: "dc=immae,dc=eu"
6base_installation::ldap_dn: "cn=%{facts.ec2_metadata.hostname},ou=hosts,dc=immae,dc=eu"
7base_installation::ldap_cn: "%{facts.ec2_metadata.hostname}"
8base_installation::ldap_server: "ldap.immae.eu"
9base_installation::ldap_uri: "ldaps://ldap.immae.eu"
10base_installation::puppet_conf_path: "/etc/puppetlabs/puppet"
11base_installation::puppet_code_path: "/etc/puppetlabs/code"
12base_installation::puppet_pass_seed: "/etc/puppetlabs/puppet/password_seed"
13base_installation::puppet_ssl_path: "/etc/puppetlabs/ssl"
14base_installation::system_locales: ["fr_FR.UTF-8", "en_US.UTF-8"]
15base_installation::system_timezone: "Europe/Paris"
16base_installation::system_users:
17 - userid: 1000
18 username: "immae"
19 groups: ["wheel"]
20 keys:
21 - host: "immae.eu"
22 key: "AAAAB3NzaC1yc2EAAAADAQABAAABAQDi5PgLBwMRyRwzJPnSgUyRAuB9AAxMijsw1pR/t/wmxQne1O5fIPOleHx+D8dyZbwm+XkzlcJpgT0Qy3qC9J8BPhshJvO/tA/8CI/oS/FE0uWsyACH1DMO2dk4gRRZGSE9IuzDMRPlnfZ3n0tdsPzzv3GH4It/oPIgsvkTowKztGLQ7Xmjr5BxzAhXcIQymqA0U3XWHSdWvnSRDaOFG0PDoVMS85IdwlviVKLnV5Sstb4NC/P28LFfgvW8DO/XrOqujgDomqTmR41dK/AyrGGOb2cQUMO4l8Oa+74aOyKaB61rr/rJkr+wCbEttkTvgFa6zZygSk3edfiWE2rgn4+v"
23 key_type: "ssh-rsa"
24xmr_stak::mining_pool: "pool.minexmr.com:7777"
25xmr_stak::wallet: "44CA8TxTFYbQqN2kLyk8AnB6Ghz4mcbGpYC2EyXW7A8H9QspvWnTjDn39XUZDPrFwPa5JNwt4TmAxcooPWv4SaJqL87Bcdo"
diff --git a/environments/integration/data/roles/cryptoportfolio.yaml b/environments/integration/data/roles/cryptoportfolio.yaml
new file mode 100644
index 0000000..e55d15b
--- /dev/null
+++ b/environments/integration/data/roles/cryptoportfolio.yaml
@@ -0,0 +1,7 @@
1---
2classes:
3 role::cryptoportfolio: ~
4cryptoportfolio::front_version: v0.0.2-3-g6200f9a
5cryptoportfolio::front_sha256: 69d31251ecd4fcea46d93dfee0184b1171019a765b6744b84f6eec6b10e5818f
6cryptoportfolio::bot_version: v0.4-2-g123411c
7cryptoportfolio::bot_sha256: c344653c6523ed4902e4e4270740c434b45c87876d827d2a695c6732a99cd59b
diff --git a/environments/integration/data/types/vps-ovhssd-1.yaml b/environments/integration/data/types/vps-ovhssd-1.yaml
new file mode 100644
index 0000000..73f7a45
--- /dev/null
+++ b/environments/integration/data/types/vps-ovhssd-1.yaml
@@ -0,0 +1,10 @@
1---
2classes:
3 base_installation:
4 stage: "setup"
5
6base_installation::system_hostname: "%{ldapvar.self.vars.host.0}"
7base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.ovh.net"
8base_installation::grub_device: "/dev/sdb"
9base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt"
10ssl::try_letsencrypt_for_real_hostname: false
diff --git a/environments/integration/hiera.yaml b/environments/integration/hiera.yaml
new file mode 100644
index 0000000..a63fc92
--- /dev/null
+++ b/environments/integration/hiera.yaml
@@ -0,0 +1,19 @@
1---
2version: 5
3
4defaults:
5 datadir: data
6 data_hash: yaml_data
7
8hierarchy:
9 - name: "Initialization variables"
10 path: "/root/puppet_variables.json"
11
12 - name: "Per-role data"
13 mapped_paths: [ldapvar.self.vars.roles, role, "roles/%{role}.yaml"]
14
15 - name: "Per-type data"
16 path: "types/%{facts.ec2_metadata.instance-type}.yaml"
17
18 - name: "Common data"
19 path: "common.yaml"
diff --git a/environments/production/data/nodes/vps464408.novalocal.yaml b/environments/production/data/nodes/vps464408.novalocal.yaml
deleted file mode 100644
index ad3a440..0000000
--- a/environments/production/data/nodes/vps464408.novalocal.yaml
+++ /dev/null
@@ -1 +0,0 @@
1base_installation::system_hostname: ns2.immae.eu
diff --git a/environments/production/data/nodes/vps494082.yaml b/environments/production/data/nodes/vps494082.yaml
deleted file mode 100644
index c7d1c85..0000000
--- a/environments/production/data/nodes/vps494082.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
1base_installation::system_hostname: cryptoportfolio.immae.eu
2cryptoportfolio::front_version: v0.0.2
3cryptoportfolio::front_sha256: 2ace0197a34f9f130523eecf8a43aa4f411cdca09de33838e074f25a7e1d6c5e
4cryptoportfolio::bot_version: v0.2-4-gf70bb85
5cryptoportfolio::bot_sha256: e9850a667e0672cdd0363bb93124b59610c4d67e3ed9908b004a9d15c2276340
diff --git a/environments/production/data/roles/cryptoportfolio.yaml b/environments/production/data/roles/cryptoportfolio.yaml
index da46382..e55d15b 100644
--- a/environments/production/data/roles/cryptoportfolio.yaml
+++ b/environments/production/data/roles/cryptoportfolio.yaml
@@ -1,3 +1,7 @@
1--- 1---
2classes: 2classes:
3 role::cryptoportfolio: ~ 3 role::cryptoportfolio: ~
4cryptoportfolio::front_version: v0.0.2-3-g6200f9a
5cryptoportfolio::front_sha256: 69d31251ecd4fcea46d93dfee0184b1171019a765b6744b84f6eec6b10e5818f
6cryptoportfolio::bot_version: v0.4-2-g123411c
7cryptoportfolio::bot_sha256: c344653c6523ed4902e4e4270740c434b45c87876d827d2a695c6732a99cd59b
diff --git a/environments/production/data/types/vps-ovhssd-1.yaml b/environments/production/data/types/vps-ovhssd-1.yaml
index 9130ad1..73f7a45 100644
--- a/environments/production/data/types/vps-ovhssd-1.yaml
+++ b/environments/production/data/types/vps-ovhssd-1.yaml
@@ -3,6 +3,7 @@ classes:
3 base_installation: 3 base_installation:
4 stage: "setup" 4 stage: "setup"
5 5
6base_installation::system_hostname: "%{ldapvar.self.vars.host.0}"
6base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.ovh.net" 7base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.ovh.net"
7base_installation::grub_device: "/dev/sdb" 8base_installation::grub_device: "/dev/sdb"
8base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt" 9base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt"
diff --git a/environments/production/hiera.yaml b/environments/production/hiera.yaml
index 9cedf47..a63fc92 100644
--- a/environments/production/hiera.yaml
+++ b/environments/production/hiera.yaml
@@ -6,15 +6,6 @@ defaults:
6 data_hash: yaml_data 6 data_hash: yaml_data
7 7
8hierarchy: 8hierarchy:
9# FIXME: those informations should be taken in LDAP, but bootstrap
10# problem for the hostname
11 - name: "Per-named-node data"
12 mapped_paths: [ldapvar.self.cn, hostname, "named_nodes/%{hostname}.yaml"]
13
14 - name: "Per-node data"
15 path: "nodes/%{facts.ec2_metadata.hostname}.yaml"
16### /FIXME
17
18 - name: "Initialization variables" 9 - name: "Initialization variables"
19 path: "/root/puppet_variables.json" 10 path: "/root/puppet_variables.json"
20 11
diff --git a/modules/base_installation/files/cronie/puppet-post-merge b/modules/base_installation/files/cronie/puppet-post-merge
index 35fa2d7..ac5e3ff 100644
--- a/modules/base_installation/files/cronie/puppet-post-merge
+++ b/modules/base_installation/files/cronie/puppet-post-merge
@@ -1,7 +1,7 @@
1#!/bin/bash 1#!/bin/bash
2## Run Puppet locally using puppet apply 2## Run Puppet locally using puppet apply
3git submodule update --init 3git submodule update --init
4/usr/bin/puppet apply --test `pwd`/manifests/site.pp 4/usr/bin/puppet apply `pwd`/manifests/site.pp
5 5
6## Log status of the Puppet run 6## Log status of the Puppet run
7if [ $? -eq 0 ] 7if [ $? -eq 0 ]
diff --git a/modules/base_installation/files/scripts/puppet_reset_and_apply b/modules/base_installation/files/scripts/puppet_reset_and_apply
new file mode 100644
index 0000000..ff71aa8
--- /dev/null
+++ b/modules/base_installation/files/scripts/puppet_reset_and_apply
@@ -0,0 +1,14 @@
1#!/bin/bash
2
3cd /etc/puppetlabs/code
4git fetch origin
5
6branch="master"
7if [ -n "$1" ]; then
8 branch="$1"
9fi
10
11git reset --hard origin/$1
12
13git submodule update --init
14puppet apply --test manifests/site.pp
diff --git a/modules/base_installation/files/scripts/report_print.rb b/modules/base_installation/files/scripts/report_print.rb
new file mode 100644
index 0000000..632374c
--- /dev/null
+++ b/modules/base_installation/files/scripts/report_print.rb
@@ -0,0 +1,396 @@
1#!/usr/bin/env ruby
2# This file was modified from its original version at
3# https://github.com/ripienaar/puppet-reportprint/
4#
5# Copyright 2013-2016 R.I.Pienaar and contributors
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18
19require 'puppet'
20require 'pp'
21require 'optparse'
22
23def get_server_reports_dir
24 Puppet.settings[:reportdir]
25end
26
27class ::Numeric
28 def bytes_to_human
29 # Prevent nonsense values being returned for fractions
30 if self >= 1
31 units = ['B', 'KB', 'MB' ,'GB' ,'TB']
32 e = (Math.log(self)/Math.log(1024)).floor
33 # Cap at TB
34 e = 4 if e > 4
35 s = "%.2f " % (to_f / 1024**e)
36 s.sub(/\.?0*$/, units[e])
37 else
38 "0 B"
39 end
40 end
41end
42
43def load_report(path)
44 YAML.load_file(path)
45end
46
47def report_resources(report)
48 report.resource_statuses
49end
50
51def resource_with_evaluation_time(report)
52 report_resources(report).select{|r_name, r| !r.evaluation_time.nil? }
53end
54
55def resource_by_eval_time(report)
56 report_resources(report).reject{|r_name, r| r.evaluation_time.nil? }.sort_by{|r_name, r| r.evaluation_time rescue 0}
57end
58
59def resources_of_type(report, type)
60 report_resources(report).select{|r_name, r| r.resource_type == type}
61end
62
63def color(code, msg, reset=false)
64 colors = {
65 :red => "",
66 :green => "",
67 :yellow => "",
68 :cyan => "",
69 :bold => "",
70 :underline => "",
71 :reset => "",
72 }
73
74 colors.merge!(
75 :changed => colors[:yellow],
76 :unchanged => colors[:green],
77 :failed => colors[:red]
78 )
79
80 return "%s%s%s%s" % [colors.fetch(code, ""), msg, colors[:reset], reset ? colors.fetch(reset, "") : ""] if @options[:color]
81
82 msg
83end
84
85def print_report_summary(report)
86 puts color(:bold, "Report for %s in environment %s at %s" % [color(:underline, report.host, :bold), color(:underline, report.environment, :bold), color(:underline, report.time, :bold)])
87 puts
88 puts " Report File: %s" % @options[:report]
89 puts " Report Status: %s" % report.status
90 puts " Puppet Version: %s" % report.puppet_version
91 puts " Report Format: %s" % report.report_format
92 puts " Configuration Version: %s" % report.configuration_version
93 puts " UUID: %s" % report.transaction_uuid rescue nil
94 puts " Log Lines: %s %s" % [report.logs.size, @options[:logs] ? "" : "(show with --log)"]
95
96 puts
97end
98
99def print_report_motd(report, motd_path)
100 motd = []
101 header = "# #{report.host} #"
102 headline = "#" * header.size
103 motd << headline << header << headline << ''
104
105 motd << "Last puppet run happened at %s in environment %s." % [report.time, report.environment]
106
107 motd << "The result of this puppet run was %s." % color(report.status.to_sym, report.status)
108
109 if report.metrics.empty? or report.metrics["events"].nil?
110 motd << 'No Report Metrics.'
111 else
112 motd << 'Events:'
113 report.metrics["events"].values.each do |metric|
114 i, m, v = metric
115 motd.last << ' ' << [m, v].join(': ') << '.'
116 end
117 end
118
119 motd << '' << ''
120
121 File.write(motd_path, motd.join("\n"))
122end
123
124def print_report_metrics(report)
125 if report.metrics.empty?
126 puts color(:bold, "No Report Metrics")
127 puts
128 return
129 end
130
131 puts color(:bold, "Report Metrics:")
132 puts
133
134 padding = report.metrics.map{|i, m| m.values}.flatten(1).map{|i, m, v| m.size}.sort[-1] + 6
135
136 report.metrics.sort_by{|i, m| m.label}.each do |i, metric|
137 puts " %s:" % metric.label
138
139 metric.values.sort_by{|j, m, v| v}.reverse.each do |j, m, v|
140 puts "%#{padding}s: %s" % [m, v]
141 end
142
143 puts
144 end
145
146 puts
147end
148
149def print_summary_by_type(report)
150 summary = {}
151
152 report_resources(report).each do |resource|
153 if resource[0] =~ /^(.+?)\[/
154 name = $1
155
156 summary[name] ||= 0
157 summary[name] += 1
158 else
159 STDERR.puts "ERROR: Cannot parse type %s" % resource[0]
160 end
161 end
162
163 puts color(:bold, "Resources by resource type:")
164 puts
165
166 summary.sort_by{|k, v| v}.reverse.each do |type, count|
167 puts " %4d %s" % [count, type]
168 end
169
170 puts
171end
172
173def print_slow_resources(report, number=20)
174 if report.report_format < 4
175 puts color(:red, " Cannot print slow resources for report versions %d" % report.report_format)
176 puts
177 return
178 end
179
180 resources = resource_by_eval_time(report)
181
182 number = resources.size if resources.size < number
183
184 puts color(:bold, "Slowest %d resources by evaluation time:" % number)
185 puts
186
187 resources[(0-number)..-1].reverse.each do |r_name, r|
188 puts " %7.2f %s" % [r.evaluation_time, r_name]
189 end
190
191 puts
192end
193
194def print_logs(report)
195 puts color(:bold, "%d Log lines:" % report.logs.size)
196 puts
197
198 report.logs.each do |log|
199 puts " %s" % log.to_report
200 end
201
202 puts
203end
204
205def print_summary_by_containment_path(report, number=20)
206 resources = resource_with_evaluation_time(report)
207
208 containment = Hash.new(0)
209
210 resources.each do |r_name, r|
211 r.containment_path.each do |containment_path|
212 #if containment_path !~ /\[/
213 containment[containment_path] += r.evaluation_time
214 #end
215 end
216 end
217
218 number = containment.size if containment.size < number
219
220 puts color(:bold, "%d most time consuming containment" % number)
221 puts
222
223 containment.sort_by{|c, s| s}[(0-number)..-1].reverse.each do |c_name, evaluation_time|
224 puts " %7.2f %s" % [evaluation_time, c_name]
225 end
226
227 puts
228end
229
230def print_files(report, number=20)
231 resources = resources_of_type(report, "File")
232
233 files = {}
234
235 resources.each do |r_name, r|
236 if r_name =~ /^File\[(.+)\]$/
237 file = $1
238
239 if File.exist?(file) && File.readable?(file) && File.file?(file) && !File.symlink?(file)
240 files[file] = File.size?(file) || 0
241 end
242 end
243 end
244
245 number = files.size if files.size < number
246
247 puts color(:bold, "%d largest managed files" % number) + " (only those with full path as resource name that are readable)"
248 puts
249
250 files.sort_by{|f, s| s}[(0-number)..-1].reverse.each do |f_name, size|
251 puts " %9s %s" % [size.bytes_to_human, f_name]
252 end
253
254 puts
255end
256
257def get_reports_for_node(nodename)
258 Dir.glob("%s/%s/*.yaml" % [get_server_reports_dir, nodename]).sort_by{|p|File.basename(p, ".*")}
259end
260
261def load_report_for_node(nodename, report)
262 report_path = "%s/%s/%s.yaml" % [get_server_reports_dir, nodename, report]
263 puts report_path
264 load_report(report_path) unless report_path.nil?
265end
266
267def load_report_by_id(report)
268 report_glob = "%s/*/%s.yaml" % [get_server_reports_dir, report]
269 Dir.glob(report_glob).map do |report_path|
270 puts report_path
271 load_report(report_path) unless report_path.nil?
272 end.first
273end
274
275def load_last_report_for_node(nodename)
276 report_path = get_reports_for_node(nodename).last
277 load_report(report_path) unless report_path.nil?
278end
279
280def print_reports_for_node(nodename)
281 puts color(:bold, "Reports for %s" % nodename)
282 get_reports_for_node(nodename).each do |report_path|
283 prefix = File.basename(report_path, ".*")
284 report = load_report(report_path)
285 print_report_oneliner(report, prefix)
286 end
287end
288
289def print_report_oneliner(report, prefix)
290 puts "%s: %s" % [prefix, color(report.status.to_sym, report.status)]
291end
292
293def print_node_oneliner(nodename)
294 report = load_last_report_for_node(nodename)
295 print_report_oneliner(report, report.name) unless report.nil?
296end
297
298def print_server_nodes_status
299 puts color(:bold, 'Nodes list')
300 dir = get_server_reports_dir
301 puts color(:bold, 'No nodes found!') unless Puppet::FileSystem.exist?(dir)
302 Dir.glob("%s/*/" % dir).each do |node_path|
303 print_node_oneliner(File.basename(node_path))
304 end
305end
306
307def initialize_puppet
308 require 'puppet/util/run_mode'
309 Puppet.settings.preferred_run_mode = :agent
310 Puppet.settings.initialize_global_settings([])
311 Puppet.settings.initialize_app_defaults(Puppet::Settings.app_defaults_for_run_mode(Puppet.run_mode))
312end
313
314initialize_puppet
315
316opt = OptionParser.new
317
318@options = {
319 :logs => false,
320 :history => false,
321 :server => false,
322 :node => nil,
323 :motd => false,
324 :motd_path => '/etc/motd',
325 :count => 20,
326 :report => Puppet[:lastrunreport],
327 :reportid => nil,
328 :color => STDOUT.tty?}
329
330opt.on("--logs", "Show logs") do |val|
331 @options[:logs] = val
332end
333
334opt.on("--nodelist", "(Puppet Server) List Puppet nodes and the status of their last report") do |val|
335 @options[:server] = val
336end
337
338opt.on("--node [NODE]", "(Puppet Server) Use last report of a node") do |val|
339 @options[:node] = val
340end
341
342opt.on("--history", "(with --node) Print the reports history for a node") do |val|
343 @options[:history] = val
344end
345
346opt.on("--motd", "Produce an output suitable for MOTD") do |val|
347 @options[:motd] = val
348end
349
350opt.on("--motd-path [PATH]", "Path to the MOTD file to overwrite with the --motd option") do |val|
351 @options[:motd_path] = val
352end
353
354opt.on("--count [RESOURCES]", Integer, "Number of resources to show evaluation times for") do |val|
355 @options[:count] = val
356end
357
358opt.on("--report [REPORT]", "Path to the Puppet last run report") do |val|
359 abort("Could not find report %s" % val) unless File.readable?(val)
360 @options[:report] = val
361end
362
363opt.on("--report-id [REPORTID]", "(with --node) ID of the report to load") do |val|
364 @options[:reportid] = val
365end
366
367opt.on("--[no-]color", "Colorize the report") do |val|
368 @options[:color] = val
369end
370
371opt.parse!
372
373report = load_report(@options[:report]) unless @options[:server] or @options[:node]
374if @options[:node] and not @options[:history] and not @options[:reportid]
375 report = load_last_report_for_node(@options[:node])
376elsif @options[:node] and @options[:reportid]
377 report = load_report_for_node(@options[:node], @options[:reportid])
378elsif @options[:reportid]
379 report = load_report_by_id(@options[:reportid])
380end
381
382if @options[:server]
383 print_server_nodes_status
384elsif @options[:node] and @options[:history]
385 print_reports_for_node(@options[:node])
386elsif @options[:motd]
387 print_report_motd(report, @options[:motd_path])
388else
389 print_report_summary(report)
390 print_report_metrics(report)
391 print_summary_by_type(report)
392 print_slow_resources(report, @options[:count])
393 print_files(report, @options[:count])
394 print_summary_by_containment_path(report, @options[:count])
395 print_logs(report) if @options[:logs]
396end
diff --git a/modules/base_installation/manifests/cronie.pp b/modules/base_installation/manifests/cronie.pp
index 4df0e37..72f2d8f 100644
--- a/modules/base_installation/manifests/cronie.pp
+++ b/modules/base_installation/manifests/cronie.pp
@@ -19,13 +19,13 @@ class base_installation::cronie inherits base_installation {
19 } 19 }
20 cron { 'puppet-apply': 20 cron { 'puppet-apply':
21 ensure => present, 21 ensure => present,
22 command => "cd $base_installation::puppet_code_path ; puppet apply --test $base_installation::puppet_code_path/manifests/site.pp", 22 command => "cd $base_installation::puppet_code_path ; puppet apply $base_installation::puppet_code_path/manifests/site.pp",
23 user => root, 23 user => root,
24 minute => '*/20' 24 minute => '*/20'
25 } 25 }
26 cron { 'puppet-apply-reboot': 26 cron { 'puppet-apply-reboot':
27 ensure => present, 27 ensure => present,
28 command => "cd $base_installation::puppet_code_path ; puppet apply --test $base_installation::puppet_code_path/manifests/site.pp", 28 command => "cd $base_installation::puppet_code_path ; puppet apply $base_installation::puppet_code_path/manifests/site.pp",
29 user => root, 29 user => root,
30 special => "reboot" 30 special => "reboot"
31 } 31 }
diff --git a/modules/base_installation/manifests/init.pp b/modules/base_installation/manifests/init.pp
index f9fdcd4..998f8ff 100644
--- a/modules/base_installation/manifests/init.pp
+++ b/modules/base_installation/manifests/init.pp
@@ -10,6 +10,7 @@ class base_installation (
10 Optional[String] $puppet_conf_path = $base_installation::params::puppet_conf_path, 10 Optional[String] $puppet_conf_path = $base_installation::params::puppet_conf_path,
11 Optional[String] $puppet_pass_seed = $base_installation::params::puppet_pass_seed, 11 Optional[String] $puppet_pass_seed = $base_installation::params::puppet_pass_seed,
12 Optional[String] $puppet_ssl_path = $base_installation::params::puppet_ssl_path, 12 Optional[String] $puppet_ssl_path = $base_installation::params::puppet_ssl_path,
13 Optional[String] $real_hostname = $base_installation::params::real_hostname,
13 Optional[String] $system_hostname = $base_installation::params::system_hostname, 14 Optional[String] $system_hostname = $base_installation::params::system_hostname,
14 Optional[Array[String]] $system_locales = $base_installation::params::system_locales, 15 Optional[Array[String]] $system_locales = $base_installation::params::system_locales,
15 Optional[String] $system_timezone = $base_installation::params::system_timezone, 16 Optional[String] $system_timezone = $base_installation::params::system_timezone,
diff --git a/modules/base_installation/manifests/params.pp b/modules/base_installation/manifests/params.pp
index c03eb1e..5ade838 100644
--- a/modules/base_installation/manifests/params.pp
+++ b/modules/base_installation/manifests/params.pp
@@ -10,6 +10,7 @@ class base_installation::params {
10 $ldap_cert_path = "/etc/ssl/certs/ca-certificates.crt" 10 $ldap_cert_path = "/etc/ssl/certs/ca-certificates.crt"
11 $ldap_uri = "ldaps://ldap.example.com" 11 $ldap_uri = "ldaps://ldap.example.com"
12 $ldap_server = "ldap.example.com" 12 $ldap_server = "ldap.example.com"
13 $real_hostname = "example.com"
13 $system_hostname = "example.com" 14 $system_hostname = "example.com"
14 $system_locales = ["en_US.UTF-8"] 15 $system_locales = ["en_US.UTF-8"]
15 $system_timezone = "UTC" 16 $system_timezone = "UTC"
diff --git a/modules/base_installation/manifests/puppet.pp b/modules/base_installation/manifests/puppet.pp
index a8dc641..b3ce492 100644
--- a/modules/base_installation/manifests/puppet.pp
+++ b/modules/base_installation/manifests/puppet.pp
@@ -27,6 +27,18 @@ class base_installation::puppet (
27 } 27 }
28 ### 28 ###
29 29
30 file { '/usr/local/sbin/i_puppet_reset_and_apply':
31 mode => "0755",
32 ensure => present,
33 source => "puppet:///modules/base_installation/scripts/puppet_reset_and_apply"
34 }
35
36 file { '/usr/local/sbin/i_puppet_report_print':
37 mode => "0755",
38 ensure => present,
39 source => "puppet:///modules/base_installation/scripts/report_print.rb"
40 }
41
30 unless empty(find_file($password_seed)) { 42 unless empty(find_file($password_seed)) {
31 $ldap_password = generate_password(24, $password_seed, "ldap") 43 $ldap_password = generate_password(24, $password_seed, "ldap")
32 $ssha_ldap_seed = generate_password(5, $password_seed, "ldap_seed") 44 $ssha_ldap_seed = generate_password(5, $password_seed, "ldap_seed")
diff --git a/modules/base_installation/manifests/system_config.pp b/modules/base_installation/manifests/system_config.pp
index 25bfe0f..ccc5dcc 100644
--- a/modules/base_installation/manifests/system_config.pp
+++ b/modules/base_installation/manifests/system_config.pp
@@ -6,23 +6,27 @@ class base_installation::system_config inherits base_installation {
6 } 6 }
7 } 7 }
8 8
9 unless empty($base_installation::system_hostname) { 9 if empty($base_installation::system_hostname) {
10 file { '/etc/hostname': 10 $hostname = $base_installation::real_hostname
11 content => "$base_installation::system_hostname\n", 11 } else {
12 } 12 $hostname = $base_installation::system_hostname
13 }
13 14
14 exec { "set_hostname": 15 file { '/etc/hostname':
15 command => "/usr/bin/hostnamectl set-hostname $base_installation::system_hostname", 16 content => "$base_installation::system_hostname\n",
16 refreshonly => true, 17 }
17 subscribe => File["/etc/hostname"],
18 returns => [0, 1],
19 }
20 18
21 # TODO: find a way to ensure that /etc/hostname doesn't change 19 exec { "set_hostname":
22 # exec { "set_hostname_firstboot": 20 command => "/usr/bin/hostnamectl set-hostname $base_installation::system_hostname",
23 # command => "/usr/bin/systemd-firstboot --hostname=$base_installation::system_hostname", 21 refreshonly => true,
24 # creates => "/etc/hostname", 22 subscribe => File["/etc/hostname"],
25 # } 23 returns => [0, 1],
26 } 24 }
27 25
26 # TODO: find a way to ensure that /etc/hostname doesn't change
27 # exec { "set_hostname_firstboot":
28 # command => "/usr/bin/systemd-firstboot --hostname=$base_installation::system_hostname",
29 # creates => "/etc/hostname",
30 # }
31
28} 32}
diff --git a/modules/base_installation/templates/puppet/host_ldap.info.erb b/modules/base_installation/templates/puppet/host_ldap.info.erb
index 525739b..a71c6f3 100644
--- a/modules/base_installation/templates/puppet/host_ldap.info.erb
+++ b/modules/base_installation/templates/puppet/host_ldap.info.erb
@@ -2,7 +2,6 @@
2ldapadd -D "cn=root,<%= @ldap_base %>" -W << 'EOF' 2ldapadd -D "cn=root,<%= @ldap_base %>" -W << 'EOF'
3dn: <%= @ldap_dn %> 3dn: <%= @ldap_dn %>
4cn: <%= @ldap_cn %> 4cn: <%= @ldap_cn %>
5cn: <%= @system_hostname %>
6objectclass: device 5objectclass: device
7objectclass: top 6objectclass: top
8objectclass: simpleSecurityObject 7objectclass: simpleSecurityObject
@@ -12,6 +11,7 @@ objectclass: ipHost
12<% unless @ips["v4"].nil? -%>ipHostNumber: <%= @ips["v4"]["ipAddress"] %><%- end %> 11<% unless @ips["v4"].nil? -%>ipHostNumber: <%= @ips["v4"]["ipAddress"] %><%- end %>
13<% unless @ips["v6"].nil? -%>ipHostNumber: <%= @ips["v6"]["ipAddress"] %>/<%= @ips["v6"]["mask"] %><%- end %> 12<% unless @ips["v6"].nil? -%>ipHostNumber: <%= @ips["v6"]["ipAddress"] %>/<%= @ips["v6"]["mask"] %><%- end %>
14<%- end -%> 13<%- end -%>
14environment: <%= @environment %>
15userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %> 15userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %>
16EOF 16EOF
17#### Or modify an existing entry: 17#### Or modify an existing entry:
@@ -20,6 +20,8 @@ dn: <%= @ldap_dn %>
20changetype: modify 20changetype: modify
21replace: userPassword 21replace: userPassword
22userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %> 22userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %>
23replace: environment
24environment: <%= @environment %>
23<%- unless @ips.empty? -%> 25<%- unless @ips.empty? -%>
24- 26-
25delete: ipHostNumber 27delete: ipHostNumber
diff --git a/modules/base_installation/templates/puppet/puppet.conf.erb b/modules/base_installation/templates/puppet/puppet.conf.erb
index 3748039..24e67c8 100644
--- a/modules/base_installation/templates/puppet/puppet.conf.erb
+++ b/modules/base_installation/templates/puppet/puppet.conf.erb
@@ -1,8 +1,10 @@
1[main] 1[main]
2ssldir = <%= @puppet_ssl_path %> 2ssldir = <%= @puppet_ssl_path %>
3 3
4environment = <%= @environment %>
5
4node_terminus = ldap 6node_terminus = ldap
5certname = <%= @system_hostname %> 7certname = <%= @real_hostname %>
6ldapserver = <%= @ldap_server %> 8ldapserver = <%= @ldap_server %>
7ldaptls = true 9ldaptls = true
8ldapbase = <%= @ldap_base %> 10ldapbase = <%= @ldap_base %>
diff --git a/modules/profile/manifests/apache.pp b/modules/profile/manifests/apache.pp
index 605b701..8db58da 100644
--- a/modules/profile/manifests/apache.pp
+++ b/modules/profile/manifests/apache.pp
@@ -49,11 +49,17 @@ class profile::apache {
49 ] 49 ]
50 } 50 }
51 51
52 exec { 'Start-apache':
53 command => "/usr/bin/systemctl start httpd",
54 before => Class["::letsencrypt"],
55 unless => "/usr/bin/systemctl is-active httpd",
56 }
57
52 $letsencrypt_certonly_default = { 58 $letsencrypt_certonly_default = {
53 plugin => "webroot", 59 plugin => "webroot",
54 webroot_paths => ["/srv/http/"], 60 webroot_paths => ["/srv/http/"],
55 notify => Class['Apache::Service'], 61 notify => Class['Apache::Service'],
56 require => [Apache::Vhost["redirect_no_ssl"],Apache::Custom_config["letsencrypt.conf"]], 62 require => [Exec['Start-apache'],Apache::Vhost["redirect_no_ssl"],Apache::Custom_config["letsencrypt.conf"]],
57 manage_cron => true, 63 manage_cron => true,
58 } 64 }
59 65
diff --git a/modules/role/manifests/cryptoportfolio.pp b/modules/role/manifests/cryptoportfolio.pp
index 32b6ac7..6c760b5 100644
--- a/modules/role/manifests/cryptoportfolio.pp
+++ b/modules/role/manifests/cryptoportfolio.pp
@@ -26,7 +26,7 @@ class role::cryptoportfolio {
26 $cf_group = "cryptoportfolio" 26 $cf_group = "cryptoportfolio"
27 $cf_home = "/opt/cryptoportfolio" 27 $cf_home = "/opt/cryptoportfolio"
28 $cf_env = "prod" 28 $cf_env = "prod"
29 $cf_front_app_host = "cryptoportfolio.immae.eu" 29 $cf_front_app_host = lookup("base_installation::system_hostname") |$key| { "example.com" }
30 $cf_front_app_port = "" 30 $cf_front_app_port = ""
31 $cf_front_app_ssl = "true" 31 $cf_front_app_ssl = "true"
32 $cf_front_app = "${cf_home}/go/src/immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front" 32 $cf_front_app = "${cf_home}/go/src/immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front"
@@ -196,14 +196,14 @@ class role::cryptoportfolio {
196 require => User[$cf_user], 196 require => User[$cf_user],
197 } 197 }
198 198
199 archive { "${cf_home}/${bot_version}.tar.gz": 199 archive { "${cf_home}/trader_${bot_version}.tar.gz":
200 path => "${cf_home}/${bot_version}.tar.gz", 200 path => "${cf_home}/trader_${bot_version}.tar.gz",
201 source => "https://git.immae.eu/releases/cryptoportfolio/trader/trader_${bot_version}.tar.gz", 201 source => "https://git.immae.eu/releases/cryptoportfolio/trader/trader_${bot_version}.tar.gz",
202 checksum_type => "sha256", 202 checksum_type => "sha256",
203 checksum => $bot_sha256, 203 checksum => $bot_sha256,
204 cleanup => false, 204 cleanup => false,
205 extract => true, 205 extract => true,
206 user => "cryptoportfolio", 206 user => $cf_user,
207 username => $facts["ec2_metadata"]["hostname"], 207 username => $facts["ec2_metadata"]["hostname"],
208 password => generate_password(24, $password_seed, "ldap"), 208 password => generate_password(24, $password_seed, "ldap"),
209 extract_path => $cf_bot_app, 209 extract_path => $cf_bot_app,
@@ -230,7 +230,7 @@ class role::cryptoportfolio {
230 content => template("role/cryptoportfolio/bot_config.ini.erb"), 230 content => template("role/cryptoportfolio/bot_config.ini.erb"),
231 require => [ 231 require => [
232 User[$cf_user], 232 User[$cf_user],
233 Archive["${cf_home}/${bot_version}.tar.gz"], 233 Archive["${cf_home}/trader_${bot_version}.tar.gz"],
234 ], 234 ],
235 } 235 }
236 236
@@ -244,7 +244,7 @@ class role::cryptoportfolio {
244 environment => ["HOME=${cf_home}","PATH=/usr/bin/"], 244 environment => ["HOME=${cf_home}","PATH=/usr/bin/"],
245 require => [ 245 require => [
246 File[$cf_bot_app_conf], 246 File[$cf_bot_app_conf],
247 Archive["${cf_home}/${bot_version}.tar.gz"] 247 Archive["${cf_home}/trader_${bot_version}.tar.gz"]
248 ], 248 ],
249 } 249 }
250 250
@@ -258,12 +258,11 @@ class role::cryptoportfolio {
258 environment => ["HOME=${cf_home}","PATH=/usr/bin/"], 258 environment => ["HOME=${cf_home}","PATH=/usr/bin/"],
259 require => [ 259 require => [
260 File[$cf_bot_app_conf], 260 File[$cf_bot_app_conf],
261 Archive["${cf_home}/${bot_version}.tar.gz"] 261 Archive["${cf_home}/trader_${bot_version}.tar.gz"]
262 ], 262 ],
263 } 263 }
264 } 264 }
265 265
266 # FIXME: incorrect build for go app
267 # FIXME: restore backup 266 # FIXME: restore backup
268 unless empty($front_version) { 267 unless empty($front_version) {
269 ensure_packages(["go", "npm", "nodejs", "yarn"]) 268 ensure_packages(["go", "npm", "nodejs", "yarn"])
@@ -284,56 +283,10 @@ class role::cryptoportfolio {
284 require => User[$cf_user], 283 require => User[$cf_user],
285 } 284 }
286 285
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": 286 file { "${cf_home}/front":
302 ensure => "link", 287 ensure => "link",
303 target => $cf_front_app, 288 target => $cf_front_app,
304 before => File[$cf_front_app], 289 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 } 290 }
338 291
339 file { "/etc/systemd/system/cryptoportfolio-app.service": 292 file { "/etc/systemd/system/cryptoportfolio-app.service":
@@ -360,43 +313,79 @@ class role::cryptoportfolio {
360 command => "/usr/bin/pg_dump --schema-only --clean --no-publications $cf_pg_db > /var/lib/postgres/${cf_pg_db}.schema", 313 command => "/usr/bin/pg_dump --schema-only --clean --no-publications $cf_pg_db > /var/lib/postgres/${cf_pg_db}.schema",
361 } 314 }
362 315
316 archive { "${cf_home}/front_${front_version}.tar.gz":
317 path => "${cf_home}/front_${front_version}.tar.gz",
318 source => "https://git.immae.eu/releases/cryptoportfolio/front/front_${front_version}.tar.gz",
319 checksum_type => "sha256",
320 checksum => $front_sha256,
321 cleanup => false,
322 extract => true,
323 user => $cf_user,
324 username => $facts["ec2_metadata"]["hostname"],
325 password => generate_password(24, $password_seed, "ldap"),
326 extract_path => $cf_front_app,
327 require => [User[$cf_user], File[$cf_front_app]],
328 notify => [
329 Exec["web-cryptoportfolio-dependencies"],
330 Exec["go-get-dep"],
331 ]
332 }
333
334 # Api
363 file { $cf_front_app_api_conf: 335 file { $cf_front_app_api_conf:
364 owner => $cf_user, 336 owner => $cf_user,
365 group => $cf_group, 337 group => $cf_group,
366 mode => "0600", 338 mode => "0600",
367 content => template("role/cryptoportfolio/api_conf.toml.erb"), 339 content => template("role/cryptoportfolio/api_conf.toml.erb"),
340 before => Exec["go-cryptoportfolio-app"],
368 } 341 }
369 342
343 exec { "go-get-dep":
344 user => $cf_user,
345 environment => ["HOME=${cf_home}"],
346 creates => "${cf_home}/go/bin/dep",
347 command => "/usr/bin/go get -u github.com/golang/dep/cmd/dep",
348 refreshonly => true,
349 } ~>
350 exec { "go-cryptoportfolio-dependencies":
351 cwd => $cf_front_app,
352 user => $cf_user,
353 environment => ["HOME=${cf_home}"],
354 command => "${cf_home}/go/bin/dep ensure",
355 refreshonly => true,
356 } ~>
357 exec { "go-cryptoportfolio-app":
358 cwd => $cf_front_app_api_workdir,
359 user => $cf_user,
360 environment => ["HOME=${cf_home}"],
361 command => "/usr/bin/make build",
362 refreshonly => true,
363 }
364
365 # Static pages
370 file { $cf_front_app_static_conf: 366 file { $cf_front_app_static_conf:
371 owner => $cf_user, 367 owner => $cf_user,
372 group => $cf_group, 368 group => $cf_group,
373 mode => "0600", 369 mode => "0600",
374 content => template("role/cryptoportfolio/static_conf.env.erb"), 370 content => template("role/cryptoportfolio/static_conf.env.erb"),
375 notify => Exec["remove build ${cf_front_app}/cmd/web/build/"], 371 before => Exec["web-cryptoportfolio-build"],
376 } 372 }
377 373
378 exec { "web-cryptoportfolio-dependencies": 374 exec { "web-cryptoportfolio-dependencies":
379 cwd => "${cf_front_app}/cmd/web", 375 cwd => "${cf_front_app}/cmd/web",
376 user => $cf_user,
380 environment => ["HOME=${cf_home}"], 377 environment => ["HOME=${cf_home}"],
381 command => "/usr/bin/make install", 378 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, 379 refreshonly => true,
390 before => Exec["web-cryptoportfolio-build"] 380 require => [Package["npm"], Package["nodejs"], Package["yarn"]]
391 } 381 } ~>
392
393 exec { "web-cryptoportfolio-build": 382 exec { "web-cryptoportfolio-build":
394 cwd => "${cf_front_app}/cmd/web", 383 cwd => "${cf_front_app}/cmd/web",
384 user => $cf_user,
395 environment => ["HOME=${cf_home}"], 385 environment => ["HOME=${cf_home}"],
396 path => ["${cf_front_app}/cmd/web/node_modules/.bin/", "/usr/bin"], 386 path => ["${cf_front_app}/cmd/web/node_modules/.bin/", "/usr/bin"],
397 command => "/usr/bin/make static ENV=${cf_env}", 387 command => "/usr/bin/make static ENV=${cf_env}",
398 creates => "${cf_front_app}/cmd/web/build/static", 388 refreshonly => true,
399 require => [File[$cf_front_app_static_conf], Exec["web-cryptoportfolio-dependencies"]]
400 } 389 }
401 } 390 }
402} 391}
diff --git a/python/list_servers.py b/python/list_servers.py
new file mode 100644
index 0000000..9b8bc64
--- /dev/null
+++ b/python/list_servers.py
@@ -0,0 +1,12 @@
1try:
2 from ovh import ovh
3except ImportError:
4 # In case it's installed globally
5 import ovh
6
7client = ovh.Client()
8
9vps_list = client.get('/vps/')
10
11for vps in vps_list:
12 print(vps)