diff options
71 files changed, 1379 insertions, 964 deletions
diff --git a/.gitmodules b/.gitmodules index fa5163a..735ca8c 100644 --- a/.gitmodules +++ b/.gitmodules | |||
@@ -46,6 +46,9 @@ | |||
46 | [submodule "python/ovh"] | 46 | [submodule "python/ovh"] |
47 | path = python/ovh | 47 | path = python/ovh |
48 | url = git://git.immae.eu/github/ovh/python-ovh | 48 | url = git://git.immae.eu/github/ovh/python-ovh |
49 | [submodule "modules/ssh_keygen"] | ||
50 | path = modules/ssh_keygen | ||
51 | url = git://git.immae.eu/github/voxpupuli/puppet-ssh_keygen | ||
49 | [submodule "modules/ssl"] | 52 | [submodule "modules/ssl"] |
50 | path = modules/ssl | 53 | path = modules/ssl |
51 | url = git://git.immae.eu/github/fnerdwq/puppet-ssl | 54 | url = git://git.immae.eu/github/fnerdwq/puppet-ssl |
diff --git a/bin/install_script.sh b/bin/install_script.sh new file mode 100755 index 0000000..bd7f38b --- /dev/null +++ b/bin/install_script.sh | |||
@@ -0,0 +1,155 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | usage() { | ||
4 | cat <<EOF | ||
5 | $(basename $0) [options] | ||
6 | --help,-h This help | ||
7 | |||
8 | One of the following options is necessary: | ||
9 | --instance-id id Id of the cloud instance | ||
10 | --vps-id id Id of the vps | ||
11 | |||
12 | Optional arguments: | ||
13 | --password password Password of the host (only useful in case of no reboot and vps) | ||
14 | --reinstall-first Start with reinstalling the vps | ||
15 | --host-user user Use another user than the default one | ||
16 | --no-reboot Don't reboot | ||
17 | --no-reboot-start Don't reboot to rescue at the beginning | ||
18 | --no-reboot-end Don't reboot to normal at the end | ||
19 | --git-branch branch Use another puppet branch (default: master) | ||
20 | --environment env Environment to use for the install (default: production) | ||
21 | EOF | ||
22 | } | ||
23 | |||
24 | set -e | ||
25 | |||
26 | git_branch=master | ||
27 | environment=production | ||
28 | host_user="" | ||
29 | password="" | ||
30 | T="" | ||
31 | |||
32 | while [ -n "$1" ]; do | ||
33 | case "$1" in | ||
34 | --instance-id) | ||
35 | host_id="$2" | ||
36 | if [ -z "$host_user" ]; then | ||
37 | host_user="arch" | ||
38 | fi | ||
39 | if [ -z "$password" ]; then | ||
40 | password="x" | ||
41 | fi | ||
42 | [ -n "$T" ] && usage && exit 1 | ||
43 | T="ovh_cloud_instance" | ||
44 | shift | ||
45 | ;; | ||
46 | --vps-id) | ||
47 | host_id="$2" | ||
48 | if [ -z "$host_user" ]; then | ||
49 | host_user="root" | ||
50 | fi | ||
51 | [ -n "$T" ] && usage && exit 1 | ||
52 | T="ovh_vps_ssd" | ||
53 | shift | ||
54 | ;; | ||
55 | --password) | ||
56 | password="$2" | ||
57 | shift | ||
58 | ;; | ||
59 | --reinstall-first) | ||
60 | reinstall_first=1 | ||
61 | ;; | ||
62 | --host-user) | ||
63 | host_user="$2" | ||
64 | shift | ||
65 | ;; | ||
66 | --no-reboot) | ||
67 | no_reboot=1 | ||
68 | ;; | ||
69 | --no-reboot-start) | ||
70 | no_reboot_start=1 | ||
71 | ;; | ||
72 | --no-reboot-end) | ||
73 | no_reboot_end=1 | ||
74 | ;; | ||
75 | --git-branch) | ||
76 | git_branch="$2" | ||
77 | shift | ||
78 | ;; | ||
79 | --environment) | ||
80 | environment="$2" | ||
81 | shift | ||
82 | ;; | ||
83 | --help|-h) | ||
84 | usage | ||
85 | exit 0 | ||
86 | ;; | ||
87 | esac | ||
88 | |||
89 | shift | ||
90 | done | ||
91 | |||
92 | if [ -z "$T" -o -z "$host_id" ]; then | ||
93 | usage | ||
94 | exit 1 | ||
95 | fi | ||
96 | |||
97 | DIRECTORY=$(cd `dirname $0` && pwd) | ||
98 | PYTHON_DIRECTORY="$DIRECTORY/../python" | ||
99 | SCRIPTS="$DIRECTORY/../scripts" | ||
100 | |||
101 | if [ -n "$reinstall_first" ]; then | ||
102 | echo "Réinstallation du système" | ||
103 | python $PYTHON_DIRECTORY/reinstall_$T.py --use-current "$host_id" | ||
104 | |||
105 | read -p "Appuyer sur une touche quand le serveur est prêt" ready | ||
106 | fi | ||
107 | |||
108 | if [ -z "$no_reboot" -a -z "$no_reboot_start" ]; then | ||
109 | echo "Patienter le temps du reboot" | ||
110 | python $PYTHON_DIRECTORY/reboot_$T.py --rescue "$host_id" | ||
111 | |||
112 | read -p "Appuyer sur une touche quand l'instance a redémarré" ready | ||
113 | fi | ||
114 | |||
115 | if [ -z "$password" ]; then | ||
116 | stty -echo | ||
117 | read -p "Mot de passe reçu par e-mail : " password; echo | ||
118 | stty echo | ||
119 | fi | ||
120 | |||
121 | ARCH_DIR=`mktemp -d` | ||
122 | ARCH_HOST_SCRIPT="$SCRIPTS/$T/arch_host_script.sh" | ||
123 | if [ -f "$SCRIPTS/$T/arch_chroot_script.sh" ]; then | ||
124 | ARCH_CHROOT_SCRIPT="$SCRIPTS/$T/arch_chroot_script.sh" | ||
125 | else | ||
126 | ARCH_CHROOT_SCRIPT="" | ||
127 | fi | ||
128 | ARCH_INSTALL_SCRIPT="$SCRIPTS/arch_install_script.sh" | ||
129 | ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT="$SCRIPTS/$T/arch_host_puppet_configuration_script.sh" | ||
130 | ARCH_PUPPET_CONFIGURATION_SCRIPT="$SCRIPTS/arch_puppet_configuration_script.sh" | ||
131 | ARCH_PUPPET_INITIAL_CONFIGURATION="$ARCH_DIR/puppet_variables.json" | ||
132 | |||
133 | trap "rm -rf $ARCH_DIR" EXIT | ||
134 | |||
135 | #### Base installation stage | ||
136 | python $PYTHON_DIRECTORY/get_initial_configuration_$T.py $host_id > $ARCH_PUPPET_INITIAL_CONFIGURATION | ||
137 | host_address=$(python $PYTHON_DIRECTORY/get_initial_configuration_$T.py $host_id | jq -r '.ips.v4.ipAddress') | ||
138 | |||
139 | dest="$host_user@$host_address" | ||
140 | files="$ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_PUPPET_INITIAL_CONFIGURATION $ARCH_INSTALL_SCRIPT" | ||
141 | |||
142 | $SCRIPTS/send_and_run.tcl "$dest" "$password" "$git_branch" "$environment" $files | ||
143 | |||
144 | ### Role specific stage | ||
145 | read -p "Press key when LDAP is configured" i | ||
146 | |||
147 | files="$ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT $ARCH_PUPPET_CONFIGURATION_SCRIPT" | ||
148 | |||
149 | $SCRIPTS/send_and_run.tcl "$dest" "$password" "$git_branch" "$environment" $files | ||
150 | |||
151 | ### Installation finished | ||
152 | if [ -z "$no_reboot" -a -z "$no_reboot_end" ]; then | ||
153 | echo "Rebooting" | ||
154 | python $PYTHON_DIRECTORY/reboot_$T.py --local "$host_id" | ||
155 | fi | ||
diff --git a/bin/install_script_ovh_cloud_instance.sh b/bin/install_script_ovh_cloud_instance.sh deleted file mode 100755 index 26e410e..0000000 --- a/bin/install_script_ovh_cloud_instance.sh +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | usage() { | ||
4 | cat <<EOF | ||
5 | $0 [options] | ||
6 | --help,-h This help | ||
7 | --instance-id id Id of the instance | ||
8 | --reinstall-first Start with reinstalling the vps | ||
9 | --host-user user Use another user (default: arch) | ||
10 | --no-reboot Don't reboot | ||
11 | --no-reboot-start Don't reboot to rescue at the beginning | ||
12 | --no-reboot-end Don't reboot to normal at the end | ||
13 | --git-branch Use another puppet branch (default: master) | ||
14 | --environment Environment to use for the installl (default: production) | ||
15 | EOF | ||
16 | } | ||
17 | |||
18 | set -e | ||
19 | |||
20 | host_user=arch | ||
21 | git_branch=master | ||
22 | environment=production | ||
23 | |||
24 | while [ -n "$1" ]; do | ||
25 | case "$1" in | ||
26 | --instance-id) | ||
27 | instance_id="$2" | ||
28 | shift | ||
29 | ;; | ||
30 | --reinstall-first) | ||
31 | reinstall_first=1 | ||
32 | ;; | ||
33 | --host-user) | ||
34 | host_user="$2" | ||
35 | shift | ||
36 | ;; | ||
37 | --no-reboot) | ||
38 | no_reboot=1 | ||
39 | ;; | ||
40 | --no-reboot-start) | ||
41 | no_reboot_start=1 | ||
42 | ;; | ||
43 | --no-reboot-end) | ||
44 | no_reboot_end=1 | ||
45 | ;; | ||
46 | --git-branch) | ||
47 | git_branch="$2" | ||
48 | shift | ||
49 | ;; | ||
50 | --environment) | ||
51 | environment="$2" | ||
52 | shift | ||
53 | ;; | ||
54 | --help|-h) | ||
55 | usage | ||
56 | exit 0 | ||
57 | ;; | ||
58 | esac | ||
59 | |||
60 | shift | ||
61 | done | ||
62 | |||
63 | DIRECTORY=$(cd `dirname $0` && pwd) | ||
64 | PYTHON_DIRECTORY="$DIRECTORY/../python" | ||
65 | |||
66 | if [ -z "$instance_id" ]; then | ||
67 | read -p "Id de l'instance : " instance_id | ||
68 | fi | ||
69 | |||
70 | if [ -n "$reinstall_first" ]; then | ||
71 | echo "Réinstallation du système" | ||
72 | python $PYTHON_DIRECTORY/reinstall_cloud_instance.py --use-current "$instance_id" | ||
73 | |||
74 | read -p "Appuyer sur une touche quand le serveur est prêt" ready | ||
75 | fi | ||
76 | |||
77 | if [ -z "$no_reboot" -a -z "$no_reboot_start" ]; then | ||
78 | echo "Patienter le temps du reboot" | ||
79 | python $PYTHON_DIRECTORY/reboot_cloud_instance.py --rescue "$instance_id" | ||
80 | |||
81 | read -p "Appuyer sur une touche quand l'instance a redémarré" ready | ||
82 | fi | ||
83 | |||
84 | ARCH_DIR=`mktemp -d` | ||
85 | ARCH_HOST_SCRIPT="$ARCH_DIR/arch_host_script.sh" | ||
86 | ARCH_INSTALL_SCRIPT="$ARCH_DIR/arch_install_script.sh" | ||
87 | ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_host_puppet_configuration_script.sh" | ||
88 | ARCH_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_puppet_configuration_script.sh" | ||
89 | ARCH_PUPPET_INITIAL_CONFIGURATION="$ARCH_DIR/puppet_variables.json" | ||
90 | |||
91 | trap "rm -rf $ARCH_DIR" EXIT | ||
92 | |||
93 | #### Base installation stage | ||
94 | python $PYTHON_DIRECTORY/get_initial_configuration_cloud_instance.py $instance_id > $ARCH_PUPPET_INITIAL_CONFIGURATION | ||
95 | host_address=$(python $PYTHON_DIRECTORY/get_initial_configuration_cloud_instance.py $instance_id | jq -r '.ips.v4.ipAddress') | ||
96 | |||
97 | cat > $ARCH_HOST_SCRIPT <<EOF | ||
98 | #!/bin/bash | ||
99 | |||
100 | sudo haveged & | ||
101 | sudo pacman -Sy --noconfirm arch-install-scripts | ||
102 | |||
103 | DEVICE=/dev/vdb1 | ||
104 | MOUNTPOINT=/mnt | ||
105 | |||
106 | UUID=\$(lsblk -rno UUID "\$DEVICE") | ||
107 | PART="/dev/disk/by-uuid/\$UUID" | ||
108 | |||
109 | # mkfs.ext4 -F -U "\$UUID" "\$DEVICE" | ||
110 | sudo mount "\$DEVICE" /mnt | ||
111 | |||
112 | ##### FIXME: mkfs.ext4 would be better #### | ||
113 | for i in /mnt/*; do | ||
114 | if [ "\$i" = "/mnt/boot" ]; then | ||
115 | # keep /boot/grub | ||
116 | sudo rm -f \$i/* | ||
117 | else | ||
118 | sudo rm -rf \$i | ||
119 | fi | ||
120 | done | ||
121 | ##### /FIXME #### | ||
122 | |||
123 | sudo pacstrap /mnt base git puppet | ||
124 | |||
125 | echo "\$PART / auto defaults 0 1" | sudo tee /mnt/etc/fstab | ||
126 | |||
127 | sudo cp /tmp/arch_install_script.sh "\$MOUNTPOINT/root/" | ||
128 | sudo cp /tmp/puppet_variables.json "\$MOUNTPOINT/root/" | ||
129 | |||
130 | sudo arch-chroot "\$MOUNTPOINT" /root/arch_install_script.sh | ||
131 | EOF | ||
132 | |||
133 | cat > $ARCH_INSTALL_SCRIPT <<EOF | ||
134 | CODE_PATH="/etc/puppetlabs/code" | ||
135 | rm -rf \$CODE_PATH | ||
136 | git clone -b $git_branch --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git \$CODE_PATH | ||
137 | puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp | ||
138 | # The password seed requires puppet to be run twice | ||
139 | puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp | ||
140 | EOF | ||
141 | |||
142 | chmod a+x $ARCH_HOST_SCRIPT $ARCH_INSTALL_SCRIPT | ||
143 | |||
144 | expect -f - <<EOF | ||
145 | set timeout -1 | ||
146 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_PUPPET_INITIAL_CONFIGURATION $ARCH_HOST_SCRIPT $ARCH_INSTALL_SCRIPT $host_user@$host_address:/tmp | ||
147 | expect eof | ||
148 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $host_user@$host_address /tmp/arch_host_script.sh | ||
149 | expect eof | ||
150 | EOF | ||
151 | |||
152 | ### Role specific stage | ||
153 | read -p "Press key when LDAP is configured" i | ||
154 | |||
155 | cat > $ARCH_PUPPET_CONFIGURATION_SCRIPT <<EOF | ||
156 | CODE_PATH="/etc/puppetlabs/code" | ||
157 | puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp | ||
158 | EOF | ||
159 | |||
160 | cat > $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT <<EOF | ||
161 | MOUNTPOINT=/mnt | ||
162 | |||
163 | sudo cp /tmp/arch_puppet_configuration_script.sh "\$MOUNTPOINT/root/" | ||
164 | |||
165 | sudo arch-chroot "\$MOUNTPOINT" /root/arch_puppet_configuration_script.sh | ||
166 | EOF | ||
167 | |||
168 | chmod a+x $ARCH_PUPPET_CONFIGURATION_SCRIPT $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT | ||
169 | |||
170 | expect -f - <<EOF | ||
171 | set timeout -1 | ||
172 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_PUPPET_CONFIGURATION_SCRIPT $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT $host_user@$host_address:/tmp | ||
173 | expect eof | ||
174 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $host_user@$host_address /tmp/arch_host_puppet_configuration_script.sh | ||
175 | expect eof | ||
176 | EOF | ||
177 | |||
178 | ### Installation finished | ||
179 | if [ -z "$no_reboot" -a -z "$no_reboot_end" ]; then | ||
180 | echo "Rebooting" | ||
181 | python $PYTHON_DIRECTORY/reboot_cloud_instance.py --local "$instance_id" | ||
182 | fi | ||
diff --git a/bin/install_script_ovh_vps_ssd.sh b/bin/install_script_ovh_vps_ssd.sh deleted file mode 100755 index 6b1aa39..0000000 --- a/bin/install_script_ovh_vps_ssd.sh +++ /dev/null | |||
@@ -1,237 +0,0 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | usage() { | ||
4 | cat <<EOF | ||
5 | $0 [options] | ||
6 | --help,-h This help | ||
7 | --vps vps_name Name of the vps | ||
8 | --password password Password of the vps (only useful in case of no reboot) | ||
9 | --reinstall-first Start with reinstalling the vps | ||
10 | --host-user user Use another user (default: root) | ||
11 | --no-reboot Don't reboot | ||
12 | --no-reboot-start Don't reboot to rescue at the beginning | ||
13 | --no-reboot-end Don't reboot to normal at the end | ||
14 | --git-branch Use another puppet branch (default: master) | ||
15 | --environment Environment to use for the installl (default: production) | ||
16 | EOF | ||
17 | } | ||
18 | |||
19 | set -e | ||
20 | |||
21 | host_user=root | ||
22 | git_branch=master | ||
23 | environment=production | ||
24 | |||
25 | while [ -n "$1" ]; do | ||
26 | case "$1" in | ||
27 | --vps) | ||
28 | vps_name="$2" | ||
29 | shift | ||
30 | ;; | ||
31 | --reinstall-first) | ||
32 | reinstall_first=1 | ||
33 | ;; | ||
34 | --password) | ||
35 | password="$2" | ||
36 | shift | ||
37 | ;; | ||
38 | --host-user) | ||
39 | host_user="$2" | ||
40 | shift | ||
41 | ;; | ||
42 | --no-reboot) | ||
43 | no_reboot=1 | ||
44 | ;; | ||
45 | --no-reboot-start) | ||
46 | no_reboot_start=1 | ||
47 | ;; | ||
48 | --no-reboot-end) | ||
49 | no_reboot_end=1 | ||
50 | ;; | ||
51 | --git-branch) | ||
52 | git_branch="$2" | ||
53 | shift | ||
54 | ;; | ||
55 | --environment) | ||
56 | environment="$2" | ||
57 | shift | ||
58 | ;; | ||
59 | --help|-h) | ||
60 | usage | ||
61 | exit 0 | ||
62 | ;; | ||
63 | esac | ||
64 | |||
65 | shift | ||
66 | done | ||
67 | |||
68 | DIRECTORY=$(cd `dirname $0` && pwd) | ||
69 | PYTHON_DIRECTORY="$DIRECTORY/../python" | ||
70 | |||
71 | if [ -z "$vps_name" ]; then | ||
72 | read -p "Nom du vps : " vps_name | ||
73 | fi | ||
74 | |||
75 | if [ -n "$reinstall_first" ]; then | ||
76 | echo "Réinstallation du système" | ||
77 | python $PYTHON_DIRECTORY/reinstall_vps_server.py --use-current "$vps_name" | ||
78 | |||
79 | read -p "Appuyer sur une touche quand le serveur est prêt" ready | ||
80 | fi | ||
81 | |||
82 | if [ -z "$no_reboot" -a -z "$no_reboot_start" ]; then | ||
83 | echo "Patienter le temps du reboot" | ||
84 | python $PYTHON_DIRECTORY/reboot_vps_server.py --rescue "$vps_name" | ||
85 | fi | ||
86 | |||
87 | if [ -z "$password" ]; then | ||
88 | stty -echo | ||
89 | read -p "Mot de passe reçu par e-mail : " password; echo | ||
90 | stty echo | ||
91 | fi | ||
92 | |||
93 | ARCH_DIR=`mktemp -d` | ||
94 | ARCH_HOST_SCRIPT="$ARCH_DIR/arch_host_script.sh" | ||
95 | ARCH_CHROOT_SCRIPT="$ARCH_DIR/arch_chroot_script.sh" | ||
96 | ARCH_INSTALL_SCRIPT="$ARCH_DIR/arch_install_script.sh" | ||
97 | ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_host_puppet_configuration_script.sh" | ||
98 | ARCH_PUPPET_CONFIGURATION_SCRIPT="$ARCH_DIR/arch_puppet_configuration_script.sh" | ||
99 | ARCH_PUPPET_INITIAL_CONFIGURATION="$ARCH_DIR/puppet_variables.json" | ||
100 | |||
101 | trap "rm -rf $ARCH_DIR" EXIT | ||
102 | |||
103 | #### Base installation stage | ||
104 | python $PYTHON_DIRECTORY/get_initial_configuration.py $vps_name > $ARCH_PUPPET_INITIAL_CONFIGURATION | ||
105 | |||
106 | cat > $ARCH_HOST_SCRIPT <<EOF | ||
107 | #!/bin/bash | ||
108 | |||
109 | apt-get update | ||
110 | apt-get install -y haveged | ||
111 | haveged & | ||
112 | |||
113 | cd /tmp | ||
114 | |||
115 | LATEST=\$(curl https://mirrors.kernel.org/archlinux/iso/latest/sha1sums.txt | grep "bootstrap" | head -n1) | ||
116 | SHA1=\$(echo "\$LATEST" | cut -d' ' -f1) | ||
117 | NAME=\$(echo "\$LATEST" | cut -d' ' -f3) | ||
118 | |||
119 | curl -O "https://mirrors.kernel.org/archlinux/iso/latest/\$NAME" | ||
120 | |||
121 | tar -xzf "\$NAME" | ||
122 | |||
123 | echo 'Server = http://archlinux.mirrors.ovh.net/archlinux/\$repo/os/\$arch' > /tmp/root.x86_64/etc/pacman.d/mirrorlist | ||
124 | |||
125 | DEVICE_STR=\$(cat /proc/mounts | grep "/dev/[sv]d.. /mnt/") | ||
126 | DEVICE=\$(echo "\$DEVICE_STR" | cut -d' ' -f1) | ||
127 | MOUNTPOINT=\$(echo "\$DEVICE_STR" | cut -d' ' -f2) | ||
128 | |||
129 | umount "\$DEVICE" | ||
130 | UUID=\$(lsblk -rno UUID "\$DEVICE") | ||
131 | |||
132 | echo "\$UUID" > /tmp/root.x86_64/device_uuid | ||
133 | |||
134 | cp /tmp/arch_chroot_script.sh /tmp/root.x86_64/ | ||
135 | |||
136 | /tmp/root.x86_64/bin/arch-chroot /tmp/root.x86_64/ /arch_chroot_script.sh | ||
137 | |||
138 | mount "\$DEVICE" | ||
139 | |||
140 | cp /tmp/arch_install_script.sh "\$MOUNTPOINT/root/" | ||
141 | cp /tmp/puppet_variables.json "\$MOUNTPOINT/root/" | ||
142 | |||
143 | /tmp/root.x86_64/bin/arch-chroot "\$MOUNTPOINT" /root/arch_install_script.sh | ||
144 | EOF | ||
145 | |||
146 | |||
147 | cat > $ARCH_CHROOT_SCRIPT <<EOF | ||
148 | #!/bin/bash | ||
149 | |||
150 | pacman-key --init | ||
151 | pacman-key --populate archlinux | ||
152 | |||
153 | UUID=\$(cat /device_uuid) | ||
154 | PART="/dev/disk/by-uuid/\$UUID" | ||
155 | DEVICE=\$(realpath "\$PART") | ||
156 | |||
157 | # mkfs.ext4 -F -U "\$UUID" "\$DEVICE" | ||
158 | mount "\$DEVICE" /mnt | ||
159 | |||
160 | ##### FIXME: mkfs.ext4 would be better #### | ||
161 | for i in /mnt/*; do | ||
162 | if [ "\$i" = "/mnt/boot" ]; then | ||
163 | # keep /boot/grub | ||
164 | rm -f \$i/* | ||
165 | else | ||
166 | rm -rf \$i | ||
167 | fi | ||
168 | done | ||
169 | ##### /FIXME #### | ||
170 | |||
171 | pacstrap /mnt base git puppet | ||
172 | |||
173 | echo "\$PART / auto defaults 0 1" > /mnt/etc/fstab | ||
174 | |||
175 | umount /mnt | ||
176 | EOF | ||
177 | |||
178 | cat > $ARCH_INSTALL_SCRIPT <<EOF | ||
179 | CODE_PATH="/etc/puppetlabs/code" | ||
180 | rm -rf \$CODE_PATH | ||
181 | git clone -b $git_branch --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git \$CODE_PATH | ||
182 | puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp | ||
183 | # The password seed requires puppet to be run twice | ||
184 | puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp | ||
185 | EOF | ||
186 | |||
187 | chmod a+x $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT | ||
188 | |||
189 | expect -f - <<EOF | ||
190 | set timeout -1 | ||
191 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_PUPPET_INITIAL_CONFIGURATION $ARCH_HOST_SCRIPT $ARCH_CHROOT_SCRIPT $ARCH_INSTALL_SCRIPT $host_user@$vps_name:/tmp | ||
192 | expect "assword:" | ||
193 | send "$password\n" | ||
194 | expect eof | ||
195 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $host_user@$vps_name /tmp/arch_host_script.sh | ||
196 | expect "assword:" | ||
197 | send "$password\r" | ||
198 | expect eof | ||
199 | EOF | ||
200 | |||
201 | ### Role specific stage | ||
202 | read -p "Press key when LDAP is configured" i | ||
203 | |||
204 | cat > $ARCH_PUPPET_CONFIGURATION_SCRIPT <<EOF | ||
205 | CODE_PATH="/etc/puppetlabs/code" | ||
206 | puppet apply --environment $environment --tags base_installation --test \$CODE_PATH/manifests/site.pp | ||
207 | EOF | ||
208 | |||
209 | cat > $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT <<EOF | ||
210 | DEVICE_STR=\$(cat /proc/mounts | grep "/dev/[sv]d.. /mnt/") | ||
211 | DEVICE=\$(echo "\$DEVICE_STR" | cut -d' ' -f1) | ||
212 | MOUNTPOINT=\$(echo "\$DEVICE_STR" | cut -d' ' -f2) | ||
213 | |||
214 | cp /tmp/arch_puppet_configuration_script.sh "\$MOUNTPOINT/root/" | ||
215 | |||
216 | /tmp/root.x86_64/bin/arch-chroot "\$MOUNTPOINT" /root/arch_puppet_configuration_script.sh | ||
217 | EOF | ||
218 | |||
219 | chmod a+x $ARCH_PUPPET_CONFIGURATION_SCRIPT $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT | ||
220 | |||
221 | expect -f - <<EOF | ||
222 | set timeout -1 | ||
223 | spawn scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $ARCH_PUPPET_CONFIGURATION_SCRIPT $ARCH_HOST_PUPPET_CONFIGURATION_SCRIPT $host_user@$vps_name:/tmp | ||
224 | expect "assword:" | ||
225 | send "$password\n" | ||
226 | expect eof | ||
227 | spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no $host_user@$vps_name /tmp/arch_host_puppet_configuration_script.sh | ||
228 | expect "assword:" | ||
229 | send "$password\r" | ||
230 | expect eof | ||
231 | EOF | ||
232 | |||
233 | ### Installation finished | ||
234 | if [ -z "$no_reboot" -a -z "$no_reboot_end" ]; then | ||
235 | echo "Rebooting" | ||
236 | python $PYTHON_DIRECTORY/reboot_vps_server.py --local "$vps_name" | ||
237 | fi | ||
diff --git a/environments/global/common.yaml b/environments/global/common.yaml index 5b21dca..094e0ff 100644 --- a/environments/global/common.yaml +++ b/environments/global/common.yaml | |||
@@ -1,11 +1,17 @@ | |||
1 | --- | 1 | --- |
2 | lookup_options: | 2 | lookup_options: |
3 | base_installation::mounts: | 3 | profile::fstab::mounts: |
4 | merge: unique | 4 | merge: unique |
5 | classes: | 5 | classes: |
6 | merge: deep | 6 | merge: deep |
7 | base_installation::system_users: | 7 | base_installation::system_users: |
8 | merge: unique | 8 | merge: unique |
9 | letsencrypt::hosts: | ||
10 | merge: unique | ||
11 | role::backup::backups: | ||
12 | merge: unique | ||
13 | profile::known_hosts::hosts: | ||
14 | merge: unique | ||
9 | 15 | ||
10 | classes: | 16 | classes: |
11 | stdlib: ~ | 17 | stdlib: ~ |
@@ -16,22 +22,21 @@ base_installation::ldap_cn: "%{facts.ec2_metadata.hostname}" | |||
16 | base_installation::ldap_server: "ldap.immae.eu" | 22 | base_installation::ldap_server: "ldap.immae.eu" |
17 | base_installation::ldap_uri: "ldaps://ldap.immae.eu" | 23 | base_installation::ldap_uri: "ldaps://ldap.immae.eu" |
18 | # FIXME: get all mounts without needing that hack? | 24 | # FIXME: get all mounts without needing that hack? |
19 | base_installation::mounts: | ||
20 | - "%{facts.ldapvar.self.vars.mounts.0}" | ||
21 | - "%{facts.ldapvar.self.vars.mounts.1}" | ||
22 | base_installation::puppet_conf_path: "/etc/puppetlabs/puppet" | 25 | base_installation::puppet_conf_path: "/etc/puppetlabs/puppet" |
23 | base_installation::puppet_code_path: "/etc/puppetlabs/code" | 26 | base_installation::puppet_code_path: "/etc/puppetlabs/code" |
24 | base_installation::puppet_pass_seed: "/etc/puppetlabs/puppet/password_seed" | 27 | base_installation::puppet_pass_seed: "/etc/puppetlabs/puppet/password_seed" |
25 | base_installation::puppet_ssl_path: "/etc/puppetlabs/ssl" | 28 | base_installation::puppet_ssl_path: "/etc/puppetlabs/ssl" |
26 | base_installation::system_locales: ["fr_FR.UTF-8", "en_US.UTF-8"] | 29 | base_installation::system_locales: ["fr_FR.UTF-8", "en_US.UTF-8"] |
27 | base_installation::system_timezone: "Europe/Paris" | 30 | base_installation::system_timezone: "Europe/Paris" |
28 | base_installation::system_users: | 31 | base_installation::system_users: [] # Fetched via ldap |
29 | - userid: 1000 | 32 | profile::fstab::mounts: |
30 | username: "immae" | 33 | - "%{facts.ldapvar.self.vars.mounts.0}" |
31 | groups: ["wheel"] | 34 | - "%{facts.ldapvar.self.vars.mounts.1}" |
32 | keys: | 35 | profile::xmr_stak::mining_pool: "" # Fetched via ldap |
33 | - host: "immae.eu" | 36 | profile::xmr_stak::wallet: "" # Fetched via ldap |
34 | key: "AAAAB3NzaC1yc2EAAAADAQABAAABAQDi5PgLBwMRyRwzJPnSgUyRAuB9AAxMijsw1pR/t/wmxQne1O5fIPOleHx+D8dyZbwm+XkzlcJpgT0Qy3qC9J8BPhshJvO/tA/8CI/oS/FE0uWsyACH1DMO2dk4gRRZGSE9IuzDMRPlnfZ3n0tdsPzzv3GH4It/oPIgsvkTowKztGLQ7Xmjr5BxzAhXcIQymqA0U3XWHSdWvnSRDaOFG0PDoVMS85IdwlviVKLnV5Sstb4NC/P28LFfgvW8DO/XrOqujgDomqTmR41dK/AyrGGOb2cQUMO4l8Oa+74aOyKaB61rr/rJkr+wCbEttkTvgFa6zZygSk3edfiWE2rgn4+v" | 37 | profile::mail::mailhub: "" # Fetched via ldap |
35 | key_type: "ssh-rsa" | 38 | role::backup::mailto: "" # Fetched via ldap |
36 | xmr_stak::mining_pool: "pool.minexmr.com:7777" | 39 | role::backup::backups: [] # Fetched via ldap |
37 | xmr_stak::wallet: "44CA8TxTFYbQqN2kLyk8AnB6Ghz4mcbGpYC2EyXW7A8H9QspvWnTjDn39XUZDPrFwPa5JNwt4TmAxcooPWv4SaJqL87Bcdo" | 40 | profile::known_hosts::hosts: [] # Fetched via ldap |
41 | letsencrypt::email: ~ # Fetched via ldap | ||
42 | letsencrypt::try_for_real_hostname: true | ||
diff --git a/environments/global/roles/backup.yaml b/environments/global/roles/backup.yaml new file mode 100644 index 0000000..cdd5f09 --- /dev/null +++ b/environments/global/roles/backup.yaml | |||
@@ -0,0 +1,11 @@ | |||
1 | --- | ||
2 | classes: | ||
3 | role::backup: ~ | ||
4 | role::backup::user: "backup" | ||
5 | role::backup::group: "backup" | ||
6 | base_installation::system_users: | ||
7 | - username: "%{lookup('role::backup::user')}" | ||
8 | userid: 2000 | ||
9 | system: true | ||
10 | password: "!!" | ||
11 | |||
diff --git a/environments/global/roles/cryptoportfolio.yaml b/environments/global/roles/cryptoportfolio.yaml index 3d36e71..f875c1b 100644 --- a/environments/global/roles/cryptoportfolio.yaml +++ b/environments/global/roles/cryptoportfolio.yaml | |||
@@ -1,4 +1,19 @@ | |||
1 | --- | 1 | --- |
2 | classes: | 2 | classes: |
3 | role::cryptoportfolio: ~ | 3 | role::cryptoportfolio: ~ |
4 | cryptoportfolio::slack_webhook: "%{ldapvar.self.vars.cf_slack_webhook.0}" | 4 | letsencrypt::hosts: "%{lookup('base_installation::system_hostname')}" |
5 | role::cryptoportfolio::user: "cryptoportfolio" | ||
6 | role::cryptoportfolio::group: "cryptoportfolio" | ||
7 | role::cryptoportfolio::home: "/home/cryptoportfolio" | ||
8 | role::cryptoportfolio::env: "prod" | ||
9 | role::cryptoportfolio::webhook_url: "%{ldapvar.self.vars.cf_slack_webhook.0}" | ||
10 | role::cryptoportfolio::pg_db: "cryptoportfolio" | ||
11 | role::cryptoportfolio::pg_user: "cryptoportfolio" | ||
12 | role::cryptoportfolio::pg_user_replication: "cryptoportfolio_replication" | ||
13 | role::cryptoportfolio::web_host: "%{lookup('base_installation::system_hostname')}" | ||
14 | role::cryptoportfolio::web_port: "" | ||
15 | role::cryptoportfolio::web_ssl: true | ||
16 | base_installation::system_users: | ||
17 | - username: "%{lookup('role::cryptoportfolio::user')}" | ||
18 | system: true | ||
19 | password: "!!" | ||
diff --git a/environments/global/types/s1-2.yaml b/environments/global/types/s1-2.yaml index 496b741..5bfdf9a 100644 --- a/environments/global/types/s1-2.yaml +++ b/environments/global/types/s1-2.yaml | |||
@@ -6,4 +6,5 @@ classes: | |||
6 | base_installation::system_hostname: "%{ldapvar.self.vars.host.0}" | 6 | base_installation::system_hostname: "%{ldapvar.self.vars.host.0}" |
7 | base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.v.immae.eu" | 7 | base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.v.immae.eu" |
8 | base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt" | 8 | base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt" |
9 | ssl::try_letsencrypt_for_real_hostname: true | 9 | letsencrypt::try_for_real_hostname: true |
10 | profile::xmr_stak::cpulimit: "30" | ||
diff --git a/environments/global/types/vps-ovhssd-1.yaml b/environments/global/types/vps-ovhssd-1.yaml index 73f7a45..8dd512c 100644 --- a/environments/global/types/vps-ovhssd-1.yaml +++ b/environments/global/types/vps-ovhssd-1.yaml | |||
@@ -7,4 +7,5 @@ base_installation::system_hostname: "%{ldapvar.self.vars.host.0}" | |||
7 | base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.ovh.net" | 7 | base_installation::real_hostname: "%{facts.ec2_metadata.hostname}.ovh.net" |
8 | base_installation::grub_device: "/dev/sdb" | 8 | base_installation::grub_device: "/dev/sdb" |
9 | base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt" | 9 | base_installation::ldap_cert_path: "/etc/ssl/certs/ca-certificates.crt" |
10 | ssl::try_letsencrypt_for_real_hostname: false | 10 | letsencrypt::try_for_real_hostname: false |
11 | profile::xmr_stak::cpulimit: "90" | ||
diff --git a/environments/hiera.yaml b/environments/hiera.yaml index 5a9a6d6..61d40d8 100644 --- a/environments/hiera.yaml +++ b/environments/hiera.yaml | |||
@@ -8,6 +8,10 @@ defaults: | |||
8 | hierarchy: | 8 | hierarchy: |
9 | - name: "Initialization variables" | 9 | - name: "Initialization variables" |
10 | path: "/root/puppet_variables.json" | 10 | path: "/root/puppet_variables.json" |
11 | data_hash: json_data | ||
12 | |||
13 | - name: "Puppet ldap variables" | ||
14 | data_hash: ldap_data | ||
11 | 15 | ||
12 | - name: "Per-role environment data" | 16 | - name: "Per-role environment data" |
13 | mapped_paths: [ldapvar.self.vars.roles, role, "roles/%{role}.yaml"] | 17 | mapped_paths: [ldapvar.self.vars.roles, role, "roles/%{role}.yaml"] |
diff --git a/environments/integration/roles/cryptoportfolio.yaml b/environments/integration/roles/cryptoportfolio.yaml index 9825bce..6b8eb92 100644 --- a/environments/integration/roles/cryptoportfolio.yaml +++ b/environments/integration/roles/cryptoportfolio.yaml | |||
@@ -1,5 +1,3 @@ | |||
1 | --- | 1 | --- |
2 | cryptoportfolio::front_version: v0.0.2-3-g6200f9a | 2 | role::cryptoportfolio::front_version: v0.0.2-3-g6200f9a |
3 | cryptoportfolio::front_sha256: 69d31251ecd4fcea46d93dfee0184b1171019a765b6744b84f6eec6b10e5818f | 3 | role::cryptoportfolio::front_sha256: 69d31251ecd4fcea46d93dfee0184b1171019a765b6744b84f6eec6b10e5818f |
4 | cryptoportfolio::bot_version: v0.5-8-g34eb08f | ||
5 | cryptoportfolio::bot_sha256: f5b99c4a1cc4db0228f757705a5a909aa301e42787bc5842f8ba442fec0d3fd1 | ||
diff --git a/environments/production/roles/cryptoportfolio.yaml b/environments/production/roles/cryptoportfolio.yaml index c9328e1..566c7f2 100644 --- a/environments/production/roles/cryptoportfolio.yaml +++ b/environments/production/roles/cryptoportfolio.yaml | |||
@@ -1,5 +1,5 @@ | |||
1 | --- | 1 | --- |
2 | cryptoportfolio::front_version: v0.0.2-3-g6200f9a | 2 | role::cryptoportfolio::front_version: v0.0.2-3-g6200f9a |
3 | cryptoportfolio::front_sha256: 69d31251ecd4fcea46d93dfee0184b1171019a765b6744b84f6eec6b10e5818f | 3 | role::cryptoportfolio::front_sha256: 69d31251ecd4fcea46d93dfee0184b1171019a765b6744b84f6eec6b10e5818f |
4 | cryptoportfolio::bot_version: v0.5.1 | 4 | role::cryptoportfolio::bot_version: v0.5.1 |
5 | cryptoportfolio::bot_sha256: 733789711365b2397bd996689af616a6789207d26c71a31ad1af68620b267d54 | 5 | role::cryptoportfolio::bot_sha256: 733789711365b2397bd996689af616a6789207d26c71a31ad1af68620b267d54 |
diff --git a/manifests/site.pp b/manifests/site.pp index f922d2b..3d40ad2 100644 --- a/manifests/site.pp +++ b/manifests/site.pp | |||
@@ -1,5 +1,5 @@ | |||
1 | node default { | 1 | node default { |
2 | lookup('classes', Hash, 'deep').each |$class_name, $class_hash| { | 2 | lookup('classes').each |$class_name, $class_hash| { |
3 | if empty($class_hash) { | 3 | if empty($class_hash) { |
4 | include $class_name | 4 | include $class_name |
5 | } else { | 5 | } else { |
diff --git a/modules/base_installation/files/cronie/puppet-post-merge b/modules/base_installation/files/cronie/puppet-post-merge index ac5e3ff..f5c21a7 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 |
3 | git submodule update --init | 3 | git submodule update --init |
4 | /usr/bin/puppet apply `pwd`/manifests/site.pp | 4 | /usr/local/sbin/puppet_apply `pwd`/manifests/site.pp |
5 | 5 | ||
6 | ## Log status of the Puppet run | 6 | ## Log status of the Puppet run |
7 | if [ $? -eq 0 ] | 7 | if [ $? -eq 0 ] |
diff --git a/modules/base_installation/files/scripts/puppet_apply b/modules/base_installation/files/scripts/puppet_apply new file mode 100644 index 0000000..69673cc --- /dev/null +++ b/modules/base_installation/files/scripts/puppet_apply | |||
@@ -0,0 +1,23 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | lockfile=/var/run/puppet-apply.lock | ||
4 | path=`dirname $0` | ||
5 | path=`cd $path/..; pwd` | ||
6 | |||
7 | if [ $(id -u) -gt 0 ]; then | ||
8 | echo "You must be root to run this script." >&2 | ||
9 | exit 2 | ||
10 | fi | ||
11 | |||
12 | if (set -o noclobber; echo "$$" > "$lockfile") 2> /dev/null; then | ||
13 | trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT | ||
14 | |||
15 | puppet apply "$@" | ||
16 | |||
17 | rm -f "$lockfile" | ||
18 | trap - INT TERM EXIT | ||
19 | else | ||
20 | echo "Failed to acquire lockfile: $lockfile." >&2 | ||
21 | echo "Held by $(cat $lockfile 2>/dev/null)" >&2 | ||
22 | exit 1 | ||
23 | fi | ||
diff --git a/modules/base_installation/files/scripts/puppet_reset_and_apply b/modules/base_installation/files/scripts/puppet_reset_and_apply index 6743044..0350e6e 100644 --- a/modules/base_installation/files/scripts/puppet_reset_and_apply +++ b/modules/base_installation/files/scripts/puppet_reset_and_apply | |||
@@ -11,4 +11,4 @@ fi | |||
11 | git reset --hard origin/$branch | 11 | git reset --hard origin/$branch |
12 | 12 | ||
13 | git submodule update --init | 13 | git submodule update --init |
14 | puppet apply --test manifests/site.pp | 14 | puppet_apply --test manifests/site.pp |
diff --git a/modules/base_installation/lib/facter/ldapvar.rb b/modules/base_installation/lib/facter/ldapvar.rb index 3ee6623..08d58e4 100644 --- a/modules/base_installation/lib/facter/ldapvar.rb +++ b/modules/base_installation/lib/facter/ldapvar.rb | |||
@@ -27,16 +27,18 @@ begin | |||
27 | 27 | ||
28 | connection.search(base, scope, filter) do |entry| | 28 | connection.search(base, scope, filter) do |entry| |
29 | data_ = entry.to_hash | 29 | data_ = entry.to_hash |
30 | data_['vars'] = (data_[Puppet[:ldapstackedattrs]] || []) | 30 | if data_["objectClass"].any? { |class_| class_ == "puppetClient" } |
31 | .map { |var| var.split("=", 2) } | 31 | data_['vars'] = (data_[Puppet[:ldapstackedattrs]] || []) |
32 | .group_by { |(key, value)| key } | 32 | .map { |var| var.split("=", 2) } |
33 | .map { |key, value| [key, value.map(&:last)] } | 33 | .group_by { |(key, value)| key } |
34 | .to_h | 34 | .map { |key, value| [key, value.map(&:last)] } |
35 | .to_h | ||
35 | 36 | ||
36 | data[:other] << data_ | 37 | data[:other] << data_ |
37 | 38 | ||
38 | if data_["cn"].any? { |cn| cn == host } | 39 | if data_["cn"].any? { |cn| cn == host } |
39 | data[:self] = data_ | 40 | data[:self] = data_ |
41 | end | ||
40 | end | 42 | end |
41 | end | 43 | end |
42 | 44 | ||
diff --git a/modules/base_installation/lib/puppet/functions/ldap_data.rb b/modules/base_installation/lib/puppet/functions/ldap_data.rb new file mode 100644 index 0000000..0c92d89 --- /dev/null +++ b/modules/base_installation/lib/puppet/functions/ldap_data.rb | |||
@@ -0,0 +1,46 @@ | |||
1 | require 'json' | ||
2 | |||
3 | Puppet::Functions.create_function(:ldap_data) do | ||
4 | dispatch :ldap_data do | ||
5 | param 'Hash', :options | ||
6 | param 'Puppet::LookupContext', :context | ||
7 | end | ||
8 | |||
9 | def ldap_data(options, context) | ||
10 | begin | ||
11 | require 'ldap' | ||
12 | require 'puppet/util/ldap/connection' | ||
13 | rescue LoadError | ||
14 | context.not_found | ||
15 | return | ||
16 | end | ||
17 | |||
18 | if !context.cache_has_key("ldap_lookup") | ||
19 | begin | ||
20 | conn = Puppet::Util::Ldap::Connection.instance | ||
21 | conn.start | ||
22 | connection = conn.connection | ||
23 | rescue ::LDAP::ResultError => e | ||
24 | raise Puppet::ParseError, ("ldapquery(): LDAP ResultError - #{e.message}") | ||
25 | end | ||
26 | |||
27 | host = Facter.value('ec2_metadata')["hostname"] | ||
28 | base = Puppet[:ldapbase] | ||
29 | scope = ::LDAP::LDAP_SCOPE_SUBTREE | ||
30 | filter = "(objectclass=*)" | ||
31 | |||
32 | data = {} | ||
33 | connection.search(base, scope, filter) do |entry| | ||
34 | data_ = entry.to_hash | ||
35 | jsons = data_["immaePuppetJson"] || [] | ||
36 | jsons.each do |json| | ||
37 | data.merge!(JSON.parse(json)) | ||
38 | end | ||
39 | end | ||
40 | |||
41 | context.cache("ldap_lookup", data) | ||
42 | end | ||
43 | |||
44 | context.cached_value("ldap_lookup") | ||
45 | end | ||
46 | end | ||
diff --git a/modules/base_installation/manifests/cronie.pp b/modules/base_installation/manifests/cronie.pp index 72f2d8f..2235470 100644 --- a/modules/base_installation/manifests/cronie.pp +++ b/modules/base_installation/manifests/cronie.pp | |||
@@ -19,15 +19,22 @@ 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 $base_installation::puppet_code_path/manifests/site.pp", | 22 | command => "cd $base_installation::puppet_code_path ; /usr/local/sbin/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 $base_installation::puppet_code_path/manifests/site.pp", | 28 | command => "cd $base_installation::puppet_code_path ; /usr/local/sbin/puppet_apply $base_installation::puppet_code_path/manifests/site.pp", |
29 | user => root, | 29 | user => root, |
30 | special => "reboot" | 30 | special => "reboot" |
31 | } | 31 | } |
32 | cron { 'pacman_keys': | ||
33 | ensure => present, | ||
34 | command => "pacman-key --populate archlinux", | ||
35 | user => root, | ||
36 | minute => "0", | ||
37 | hour => "1", | ||
38 | } | ||
32 | } | 39 | } |
33 | } | 40 | } |
diff --git a/modules/base_installation/manifests/init.pp b/modules/base_installation/manifests/init.pp index cb1cdda..998f8ff 100644 --- a/modules/base_installation/manifests/init.pp +++ b/modules/base_installation/manifests/init.pp | |||
@@ -6,7 +6,6 @@ class base_installation ( | |||
6 | Optional[String] $ldap_dn = $base_installation::params::ldap_dn, | 6 | Optional[String] $ldap_dn = $base_installation::params::ldap_dn, |
7 | Optional[String] $ldap_server = $base_installation::params::ldap_server, | 7 | Optional[String] $ldap_server = $base_installation::params::ldap_server, |
8 | Optional[String] $ldap_uri = $base_installation::params::ldap_uri, | 8 | Optional[String] $ldap_uri = $base_installation::params::ldap_uri, |
9 | Optional[Array[String]] $mounts = $base_installation::params::mounts, | ||
10 | Optional[String] $puppet_code_path = $base_installation::params::puppet_code_path, | 9 | Optional[String] $puppet_code_path = $base_installation::params::puppet_code_path, |
11 | Optional[String] $puppet_conf_path = $base_installation::params::puppet_conf_path, | 10 | Optional[String] $puppet_conf_path = $base_installation::params::puppet_conf_path, |
12 | Optional[String] $puppet_pass_seed = $base_installation::params::puppet_pass_seed, | 11 | Optional[String] $puppet_pass_seed = $base_installation::params::puppet_pass_seed, |
@@ -31,5 +30,4 @@ class base_installation ( | |||
31 | contain ::base_installation::users | 30 | contain ::base_installation::users |
32 | contain ::base_installation::package_managers | 31 | contain ::base_installation::package_managers |
33 | contain ::base_installation::puppet | 32 | contain ::base_installation::puppet |
34 | contain ::base_installation::fstab | ||
35 | } | 33 | } |
diff --git a/modules/base_installation/manifests/params.pp b/modules/base_installation/manifests/params.pp index 2a9fe6a..5ade838 100644 --- a/modules/base_installation/manifests/params.pp +++ b/modules/base_installation/manifests/params.pp | |||
@@ -10,7 +10,6 @@ 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 | $mounts = [] | ||
14 | $real_hostname = "example.com" | 13 | $real_hostname = "example.com" |
15 | $system_hostname = "example.com" | 14 | $system_hostname = "example.com" |
16 | $system_locales = ["en_US.UTF-8"] | 15 | $system_locales = ["en_US.UTF-8"] |
diff --git a/modules/base_installation/manifests/puppet.pp b/modules/base_installation/manifests/puppet.pp index b3ce492..0cb43bc 100644 --- a/modules/base_installation/manifests/puppet.pp +++ b/modules/base_installation/manifests/puppet.pp | |||
@@ -39,6 +39,12 @@ class base_installation::puppet ( | |||
39 | source => "puppet:///modules/base_installation/scripts/report_print.rb" | 39 | source => "puppet:///modules/base_installation/scripts/report_print.rb" |
40 | } | 40 | } |
41 | 41 | ||
42 | file { '/usr/local/sbin/puppet_apply': | ||
43 | mode => "0755", | ||
44 | ensure => present, | ||
45 | source => "puppet:///modules/base_installation/scripts/puppet_apply", | ||
46 | } | ||
47 | |||
42 | unless empty(find_file($password_seed)) { | 48 | unless empty(find_file($password_seed)) { |
43 | $ldap_password = generate_password(24, $password_seed, "ldap") | 49 | $ldap_password = generate_password(24, $password_seed, "ldap") |
44 | $ssha_ldap_seed = generate_password(5, $password_seed, "ldap_seed") | 50 | $ssha_ldap_seed = generate_password(5, $password_seed, "ldap_seed") |
@@ -67,7 +73,7 @@ class base_installation::puppet ( | |||
67 | require => File[$base_installation::puppet_conf_path], | 73 | require => File[$base_installation::puppet_conf_path], |
68 | } | 74 | } |
69 | 75 | ||
70 | $ips = lookup("ips") |$key| { {} } | 76 | $ips = lookup("ips", { 'default_value' => undef }) |
71 | file { "$base_installation::puppet_conf_path/host_ldap.info": | 77 | file { "$base_installation::puppet_conf_path/host_ldap.info": |
72 | content => template("base_installation/puppet/host_ldap.info.erb"), | 78 | content => template("base_installation/puppet/host_ldap.info.erb"), |
73 | require => File[$base_installation::puppet_conf_path], | 79 | require => File[$base_installation::puppet_conf_path], |
diff --git a/modules/base_installation/manifests/services.pp b/modules/base_installation/manifests/services.pp index c641f4b..d7b4d61 100644 --- a/modules/base_installation/manifests/services.pp +++ b/modules/base_installation/manifests/services.pp | |||
@@ -38,7 +38,7 @@ class base_installation::services inherits base_installation { | |||
38 | group => "root" | 38 | group => "root" |
39 | } | 39 | } |
40 | 40 | ||
41 | $ip6 = lookup("ips.v6") |$key| { {} } | 41 | $ip6 = lookup("ips.v6", { 'default_value' => undef }) |
42 | file { '/etc/systemd/network/en-dhcp.network': | 42 | file { '/etc/systemd/network/en-dhcp.network': |
43 | ensure => "present", | 43 | ensure => "present", |
44 | path => "/etc/systemd/network/en-dhcp.network", | 44 | path => "/etc/systemd/network/en-dhcp.network", |
diff --git a/modules/base_installation/manifests/users.pp b/modules/base_installation/manifests/users.pp index 766c0f0..f893c51 100644 --- a/modules/base_installation/manifests/users.pp +++ b/modules/base_installation/manifests/users.pp | |||
@@ -26,22 +26,26 @@ class base_installation::users ( | |||
26 | ensure => "present", | 26 | ensure => "present", |
27 | groups => $user[groups], | 27 | groups => $user[groups], |
28 | managehome => true, | 28 | managehome => true, |
29 | system => !!$user[system], | ||
29 | home => "/home/${user[username]}", | 30 | home => "/home/${user[username]}", |
30 | notify => Exec["remove_password"], | 31 | notify => Exec["remove_password:${user[username]}:${user[userid]}"], |
31 | purge_ssh_keys => true | 32 | purge_ssh_keys => true |
32 | } | 33 | } |
33 | 34 | ||
34 | exec { "remove_password": | 35 | exec { "remove_password:${user[username]}:${user[userid]}": |
35 | command => "/usr/bin/chage -d 0 ${user[username]} && /usr/bin/passwd -d ${user[username]}", | 36 | command => "/usr/bin/chage -d 0 ${user[username]} && /usr/bin/passwd -d ${user[username]}", |
37 | onlyif => "/usr/bin/test -z '${user[password]}'", | ||
36 | refreshonly => true | 38 | refreshonly => true |
37 | } | 39 | } |
38 | 40 | ||
39 | $user[keys].each |$key| { | 41 | if has_key($user, "keys") { |
40 | ssh_authorized_key { "${user[username]}@${key[host]}": | 42 | $user[keys].each |$key| { |
41 | name => "${user[username]}@${key[host]}", | 43 | ssh_authorized_key { "${user[username]}@${key[host]}": |
42 | user => $user[username], | 44 | name => "${user[username]}@${key[host]}", |
43 | type => $key[key_type], | 45 | user => $user[username], |
44 | key => $key[key], | 46 | type => $key[key_type], |
47 | key => $key[key], | ||
48 | } | ||
45 | } | 49 | } |
46 | } | 50 | } |
47 | } | 51 | } |
diff --git a/modules/base_installation/templates/puppet/host_ldap.info.erb b/modules/base_installation/templates/puppet/host_ldap.info.erb index a71c6f3..9c79d3c 100644 --- a/modules/base_installation/templates/puppet/host_ldap.info.erb +++ b/modules/base_installation/templates/puppet/host_ldap.info.erb | |||
@@ -1,4 +1,4 @@ | |||
1 | #### Please add this node to LDAP: | 1 | [0;35m#### Please add this node to LDAP:[0m |
2 | ldapadd -D "cn=root,<%= @ldap_base %>" -W << 'EOF' | 2 | ldapadd -D "cn=root,<%= @ldap_base %>" -W << 'EOF' |
3 | dn: <%= @ldap_dn %> | 3 | dn: <%= @ldap_dn %> |
4 | cn: <%= @ldap_cn %> | 4 | cn: <%= @ldap_cn %> |
@@ -14,12 +14,13 @@ objectclass: ipHost | |||
14 | environment: <%= @environment %> | 14 | environment: <%= @environment %> |
15 | userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %> | 15 | userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %> |
16 | EOF | 16 | EOF |
17 | #### Or modify an existing entry: | 17 | [0;35m#### Or modify an existing entry:[0m |
18 | ldapmodify -D "cn=root,<%= @ldap_base %>" -W << 'EOF' | 18 | ldapmodify -D "cn=root,<%= @ldap_base %>" -W << 'EOF' |
19 | dn: <%= @ldap_dn %> | 19 | dn: <%= @ldap_dn %> |
20 | changetype: modify | 20 | changetype: modify |
21 | replace: userPassword | 21 | replace: userPassword |
22 | userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %> | 22 | userpassword: {SSHA}<%= Base64.encode64(Digest::SHA1.digest(@ldap_password+@ssha_ldap_seed)+@ssha_ldap_seed).chomp! %> |
23 | - | ||
23 | replace: environment | 24 | replace: environment |
24 | environment: <%= @environment %> | 25 | environment: <%= @environment %> |
25 | <%- unless @ips.empty? -%> | 26 | <%- unless @ips.empty? -%> |
diff --git a/modules/pacman b/modules/pacman | |||
Subproject 8db3b97081230d5d89f8f1467eec05bf19b03f3 | Subproject 5668cfa6dff56d5965ab2143fd0aeb322518d9c | ||
diff --git a/modules/profile/manifests/apache.pp b/modules/profile/manifests/apache.pp index 8db58da..382633b 100644 --- a/modules/profile/manifests/apache.pp +++ b/modules/profile/manifests/apache.pp | |||
@@ -67,13 +67,12 @@ class profile::apache { | |||
67 | install_method => "package", | 67 | install_method => "package", |
68 | package_name => "certbot", | 68 | package_name => "certbot", |
69 | package_command => "certbot", | 69 | package_command => "certbot", |
70 | # FIXME | 70 | email => lookup('letsencrypt::email'), |
71 | email => 'sites+letsencrypt@mail.immae.eu', | ||
72 | } | 71 | } |
73 | 72 | ||
74 | $real_hostname = lookup("base_installation::real_hostname") |$key| { {} } | 73 | $real_hostname = lookup("base_installation::real_hostname", { "default_value" => undef }) |
75 | unless empty($real_hostname) { | 74 | unless empty($real_hostname) { |
76 | if (lookup("ssl::try_letsencrypt_for_real_hostname") |$key| { true }) { | 75 | if (lookup("letsencrypt::try_for_real_hostname", { "default_value" => true })) { |
77 | letsencrypt::certonly { $real_hostname: | 76 | letsencrypt::certonly { $real_hostname: |
78 | before => Apache::Vhost["default_ssl"]; | 77 | before => Apache::Vhost["default_ssl"]; |
79 | default: * => $::profile::apache::letsencrypt_certonly_default; | 78 | default: * => $::profile::apache::letsencrypt_certonly_default; |
@@ -110,6 +109,14 @@ class profile::apache { | |||
110 | } | 109 | } |
111 | } | 110 | } |
112 | 111 | ||
112 | lookup("letsencrypt::hosts", { "default_value" => [] }).each |$host| { | ||
113 | if ($host != $real_hostname) { # Done above already | ||
114 | letsencrypt::certonly { $host: ; | ||
115 | default: * => $letsencrypt_certonly_default; | ||
116 | } | ||
117 | } | ||
118 | } | ||
119 | |||
113 | apache::vhost { "redirect_no_ssl": | 120 | apache::vhost { "redirect_no_ssl": |
114 | port => '80', | 121 | port => '80', |
115 | error_log => false, | 122 | error_log => false, |
diff --git a/modules/base_installation/manifests/fstab.pp b/modules/profile/manifests/fstab.pp index f012e76..5f2e58e 100644 --- a/modules/base_installation/manifests/fstab.pp +++ b/modules/profile/manifests/fstab.pp | |||
@@ -1,6 +1,6 @@ | |||
1 | class base_installation::fstab ( | 1 | class profile::fstab ( |
2 | $mounts = $base_installation::mounts | 2 | Optional[Array] $mounts = [] |
3 | ) inherits base_installation { | 3 | ) { |
4 | $mounts.each |$mount| { | 4 | $mounts.each |$mount| { |
5 | unless empty($mount) { | 5 | unless empty($mount) { |
6 | $infos = split($mount, ';') | 6 | $infos = split($mount, ';') |
diff --git a/modules/profile/manifests/known_hosts.pp b/modules/profile/manifests/known_hosts.pp new file mode 100644 index 0000000..ed9ec8e --- /dev/null +++ b/modules/profile/manifests/known_hosts.pp | |||
@@ -0,0 +1,11 @@ | |||
1 | class profile::known_hosts ( | ||
2 | Optional[Array] $hosts = [] | ||
3 | ) { | ||
4 | $hosts.each |$host| { | ||
5 | sshkey { $host["name"]: | ||
6 | ensure => "present", | ||
7 | key => $host["key"], | ||
8 | type => $host["type"], | ||
9 | } | ||
10 | } | ||
11 | } | ||
diff --git a/modules/profile/manifests/mail.pp b/modules/profile/manifests/mail.pp new file mode 100644 index 0000000..cc47b77 --- /dev/null +++ b/modules/profile/manifests/mail.pp | |||
@@ -0,0 +1,14 @@ | |||
1 | class profile::mail ( | ||
2 | String $mailhub, | ||
3 | Optional[Integer] $mailhub_port = 25, | ||
4 | ) { | ||
5 | ensure_packages(["s-nail", "ssmtp"]) | ||
6 | |||
7 | $hostname = lookup("base_installation::real_hostname") | ||
8 | |||
9 | file { "/etc/ssmtp/ssmtp.conf": | ||
10 | ensure => "present", | ||
11 | content => template("profile/mail/ssmtp.conf.erb"), | ||
12 | } | ||
13 | } | ||
14 | |||
diff --git a/modules/profile/manifests/postgresql.pp b/modules/profile/manifests/postgresql.pp index 1024c66..2cd1bcc 100644 --- a/modules/profile/manifests/postgresql.pp +++ b/modules/profile/manifests/postgresql.pp | |||
@@ -1,5 +1,5 @@ | |||
1 | class profile::postgresql { | 1 | class profile::postgresql { |
2 | $password_seed = lookup("base_installation::puppet_pass_seed") |$key| { {} } | 2 | $password_seed = lookup("base_installation::puppet_pass_seed") |
3 | 3 | ||
4 | class { '::postgresql::globals': | 4 | class { '::postgresql::globals': |
5 | encoding => 'UTF-8', | 5 | encoding => 'UTF-8', |
@@ -32,7 +32,7 @@ class profile::postgresql { | |||
32 | database => 'all', | 32 | database => 'all', |
33 | user => $pg_user, | 33 | user => $pg_user, |
34 | auth_method => 'ident', | 34 | auth_method => 'ident', |
35 | order => "a1", | 35 | order => "00-01", |
36 | } | 36 | } |
37 | postgresql::server::pg_hba_rule { 'localhost access as postgres user': | 37 | postgresql::server::pg_hba_rule { 'localhost access as postgres user': |
38 | description => 'Allow localhost access to postgres user', | 38 | description => 'Allow localhost access to postgres user', |
@@ -41,7 +41,7 @@ class profile::postgresql { | |||
41 | user => $pg_user, | 41 | user => $pg_user, |
42 | address => "127.0.0.1/32", | 42 | address => "127.0.0.1/32", |
43 | auth_method => 'md5', | 43 | auth_method => 'md5', |
44 | order => "a2", | 44 | order => "00-02", |
45 | } | 45 | } |
46 | postgresql::server::pg_hba_rule { 'localhost ip6 access as postgres user': | 46 | postgresql::server::pg_hba_rule { 'localhost ip6 access as postgres user': |
47 | description => 'Allow localhost access to postgres user', | 47 | description => 'Allow localhost access to postgres user', |
@@ -50,7 +50,7 @@ class profile::postgresql { | |||
50 | user => $pg_user, | 50 | user => $pg_user, |
51 | address => "::1/128", | 51 | address => "::1/128", |
52 | auth_method => 'md5', | 52 | auth_method => 'md5', |
53 | order => "a3", | 53 | order => "00-03", |
54 | } | 54 | } |
55 | postgresql::server::pg_hba_rule { 'deny access to postgresql user': | 55 | postgresql::server::pg_hba_rule { 'deny access to postgresql user': |
56 | description => 'Deny remote access to postgres user', | 56 | description => 'Deny remote access to postgres user', |
@@ -59,7 +59,7 @@ class profile::postgresql { | |||
59 | user => $pg_user, | 59 | user => $pg_user, |
60 | address => "0.0.0.0/0", | 60 | address => "0.0.0.0/0", |
61 | auth_method => 'reject', | 61 | auth_method => 'reject', |
62 | order => "a4", | 62 | order => "00-04", |
63 | } | 63 | } |
64 | 64 | ||
65 | postgresql::server::pg_hba_rule { 'local access': | 65 | postgresql::server::pg_hba_rule { 'local access': |
@@ -68,7 +68,7 @@ class profile::postgresql { | |||
68 | database => 'all', | 68 | database => 'all', |
69 | user => 'all', | 69 | user => 'all', |
70 | auth_method => 'md5', | 70 | auth_method => 'md5', |
71 | order => "b1", | 71 | order => "10-01", |
72 | } | 72 | } |
73 | 73 | ||
74 | postgresql::server::pg_hba_rule { 'local access with same name': | 74 | postgresql::server::pg_hba_rule { 'local access with same name': |
@@ -77,7 +77,7 @@ class profile::postgresql { | |||
77 | database => 'all', | 77 | database => 'all', |
78 | user => 'all', | 78 | user => 'all', |
79 | auth_method => 'ident', | 79 | auth_method => 'ident', |
80 | order => "b2", | 80 | order => "10-02", |
81 | } | 81 | } |
82 | 82 | ||
83 | } | 83 | } |
diff --git a/modules/profile/manifests/xmr_stak.pp b/modules/profile/manifests/xmr_stak.pp index e5582eb..ccb6baa 100644 --- a/modules/profile/manifests/xmr_stak.pp +++ b/modules/profile/manifests/xmr_stak.pp | |||
@@ -1,4 +1,9 @@ | |||
1 | class profile::xmr_stak { | 1 | class profile::xmr_stak ( |
2 | String $mining_pool, | ||
3 | String $wallet, | ||
4 | Optional[String] $cpulimit = "50", | ||
5 | Optional[String] $password = "x", | ||
6 | ) { | ||
2 | ensure_resource('exec', 'systemctl daemon-reload', { | 7 | ensure_resource('exec', 'systemctl daemon-reload', { |
3 | command => '/usr/bin/systemctl daemon-reload', | 8 | command => '/usr/bin/systemctl daemon-reload', |
4 | refreshonly => true | 9 | refreshonly => true |
@@ -21,15 +26,12 @@ class profile::xmr_stak { | |||
21 | mode => "0644", | 26 | mode => "0644", |
22 | owner => "root", | 27 | owner => "root", |
23 | group => "root", | 28 | group => "root", |
24 | source => "puppet:///modules/profile/xmr_stak/xmr-stak.service", | 29 | content => template("profile/xmr_stak/xmr-stak.service.erb"), |
25 | require => User["xmr_stak"], | 30 | require => User["xmr_stak"], |
26 | notify => Exec["systemctl daemon-reload"] | 31 | notify => Exec["systemctl daemon-reload"] |
27 | } | 32 | } |
28 | 33 | ||
29 | $mining_pool = lookup("xmr_stak::mining_pool") |$key| { {} } | 34 | $instance = regsubst(lookup("base_installation::ldap_cn"), '\.', "_", "G") |
30 | $wallet = lookup("xmr_stak::wallet") |$key| { {} } | ||
31 | $password = lookup("xmr_stak::password") |$key| { "x" } | ||
32 | $instance = regsubst($facts["ec2_metadata"]["hostname"], '\.', "_", "G") | ||
33 | 35 | ||
34 | file { "/var/lib/xmr_stak/xmr-stak.conf": | 36 | file { "/var/lib/xmr_stak/xmr-stak.conf": |
35 | mode => "0644", | 37 | mode => "0644", |
diff --git a/modules/profile/templates/mail/ssmtp.conf.erb b/modules/profile/templates/mail/ssmtp.conf.erb new file mode 100644 index 0000000..e7a0410 --- /dev/null +++ b/modules/profile/templates/mail/ssmtp.conf.erb | |||
@@ -0,0 +1,14 @@ | |||
1 | # | ||
2 | # /etc/ssmtp.conf -- a config file for sSMTP sendmail. | ||
3 | # | ||
4 | # The person who gets all mail for userids < 1000 | ||
5 | # Make this empty to disable rewriting. | ||
6 | root=postmaster | ||
7 | # The place where the mail goes. The actual machine name is required | ||
8 | # no MX records are consulted. Commonly mailhosts are named mail.domain.com | ||
9 | # The example will fit if you are in domain.com and you mailhub is so named. | ||
10 | mailhub=<%= @mailhub %>:<%= @mailhub_port %> | ||
11 | # Where will the mail seem to come from? | ||
12 | #rewriteDomain=y | ||
13 | # The full hostname | ||
14 | hostname=<%= @hostname %> | ||
diff --git a/modules/profile/files/xmr_stak/xmr-stak.service b/modules/profile/templates/xmr_stak/xmr-stak.service.erb index 93ee383..d63103b 100644 --- a/modules/profile/files/xmr_stak/xmr-stak.service +++ b/modules/profile/templates/xmr_stak/xmr-stak.service.erb | |||
@@ -8,8 +8,9 @@ WorkingDirectory=/var/lib/xmr_stak | |||
8 | Type=simple | 8 | Type=simple |
9 | User=xmr_stak | 9 | User=xmr_stak |
10 | Group=xmr_stak | 10 | Group=xmr_stak |
11 | ExecStart=/usr/bin/cpulimit --limit 90 /usr/bin/xmr-stak -c /var/lib/xmr_stak/xmr-stak.conf | 11 | ExecStart=/usr/bin/cpulimit --limit <%= @cpulimit %> /usr/bin/xmr-stak -c /var/lib/xmr_stak/xmr-stak.conf |
12 | Nice=19 | 12 | Nice=19 |
13 | 13 | ||
14 | [Install] | 14 | [Install] |
15 | WantedBy=multi-user.target | 15 | WantedBy=multi-user.target |
16 | |||
diff --git a/modules/role/manifests/backup.pp b/modules/role/manifests/backup.pp new file mode 100644 index 0000000..7a0c275 --- /dev/null +++ b/modules/role/manifests/backup.pp | |||
@@ -0,0 +1,125 @@ | |||
1 | class role::backup ( | ||
2 | String $user, | ||
3 | String $group, | ||
4 | String $mailto, | ||
5 | Optional[Array] $backups = [], | ||
6 | Optional[String] $mountpoint = "/backup1", | ||
7 | Optional[String] $backup_script = "/usr/local/bin/backup.sh", | ||
8 | ) { | ||
9 | include "base_installation" | ||
10 | |||
11 | include "profile::fstab" | ||
12 | include "profile::mail" | ||
13 | include "profile::tools" | ||
14 | include "profile::xmr_stak" | ||
15 | include "profile::known_hosts" | ||
16 | |||
17 | ensure_packages(["rsync"]) | ||
18 | |||
19 | ssh_keygen { $user: | ||
20 | notify => Notify_refresh["notify-backup-sshkey-change"] | ||
21 | } | ||
22 | |||
23 | $hosts = $backups.map |$backup| { $backup["host"] } | ||
24 | |||
25 | notify_refresh { "notify-backup-sshkey-change": | ||
26 | message => template("role/backup/ssh_key_changed.info.erb"), | ||
27 | refreshonly => true | ||
28 | } | ||
29 | |||
30 | $hosts.each |$host| { | ||
31 | notify_refresh { "notify-backup-sshhost-$host-changed": | ||
32 | message => template("role/backup/ssh_host_changed.info.erb"), | ||
33 | refreshonly => true, | ||
34 | subscribe => Sshkey[$host], | ||
35 | } | ||
36 | } | ||
37 | |||
38 | concat { $backup_script: | ||
39 | ensure => "present", | ||
40 | ensure_newline => true, | ||
41 | mode => "0755", | ||
42 | } | ||
43 | |||
44 | cron { "backup": | ||
45 | ensure => present, | ||
46 | command => $backup_script, | ||
47 | user => $user, | ||
48 | minute => 25, | ||
49 | hour => 3, | ||
50 | require => Concat[$backup_script], | ||
51 | } | ||
52 | |||
53 | concat::fragment { "backup_head": | ||
54 | target => $backup_script, | ||
55 | content => template("role/backup/backup_head.sh.erb"), | ||
56 | order => "01-50", | ||
57 | } | ||
58 | |||
59 | concat::fragment { "backup_tail": | ||
60 | target => $backup_script, | ||
61 | content => template("role/backup/backup_tail.sh.erb"), | ||
62 | order => "99-50", | ||
63 | } | ||
64 | |||
65 | $backups.each |$infos| { | ||
66 | $dirname = $infos["name"] | ||
67 | $login = $infos["login"] | ||
68 | $host = $infos["host"] | ||
69 | $dest = "$login@$host" | ||
70 | $base = "$mountpoint/$dirname" | ||
71 | $nbr = $infos["nbr"] | ||
72 | $order_dirname = $infos["order"] | ||
73 | |||
74 | file { $base: | ||
75 | ensure => "directory", | ||
76 | owner => $user, | ||
77 | group => $group, | ||
78 | require => Mount[$mountpoint], | ||
79 | } -> | ||
80 | file { "$base/older": | ||
81 | ensure => "directory", | ||
82 | owner => $user, | ||
83 | group => $group, | ||
84 | } -> | ||
85 | file { "$base/rsync_output": | ||
86 | ensure => "directory", | ||
87 | owner => $user, | ||
88 | group => $group, | ||
89 | } | ||
90 | |||
91 | concat::fragment { "backup_${dirname}_head": | ||
92 | target => $backup_script, | ||
93 | content => template("role/backup/backup_dirname_head.sh.erb"), | ||
94 | order => "$order_dirname-01", | ||
95 | } | ||
96 | |||
97 | concat::fragment { "backup_${dirname}_tail": | ||
98 | target => $backup_script, | ||
99 | content => template("role/backup/backup_dirname_tail.sh.erb"), | ||
100 | order => "$order_dirname-99", | ||
101 | } | ||
102 | |||
103 | $infos["parts"].each |$part| { | ||
104 | $local_folder = $part["local_folder"] | ||
105 | $remote_folder = $part["remote_folder"] | ||
106 | $exclude_from = $part["exclude_from"] | ||
107 | $files_from = $part["files_from"] | ||
108 | $args = $part["args"] | ||
109 | $order_part = $part["order"] | ||
110 | |||
111 | file { "$base/$local_folder": | ||
112 | ensure => "directory", | ||
113 | owner => $user, | ||
114 | group => $group, | ||
115 | require => File[$base], | ||
116 | } | ||
117 | |||
118 | concat::fragment { "backup_${dirname}_${local_folder}": | ||
119 | target => $backup_script, | ||
120 | content => template("role/backup/backup_dirname_part.sh.erb"), | ||
121 | order => "$order_dirname-$order_part", | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | } | ||
diff --git a/modules/role/manifests/cryptoportfolio.pp b/modules/role/manifests/cryptoportfolio.pp index bec247e..799e297 100644 --- a/modules/role/manifests/cryptoportfolio.pp +++ b/modules/role/manifests/cryptoportfolio.pp | |||
@@ -1,9 +1,22 @@ | |||
1 | class role::cryptoportfolio { | 1 | class role::cryptoportfolio ( |
2 | ensure_resource('exec', 'systemctl daemon-reload', { | 2 | String $user, |
3 | command => '/usr/bin/systemctl daemon-reload', | 3 | String $group, |
4 | refreshonly => true | 4 | String $home, |
5 | }) | 5 | Optional[String] $env = "prod", |
6 | 6 | Optional[String] $webhook_url = undef, | |
7 | String $pg_user, | ||
8 | String $pg_user_replication, | ||
9 | String $pg_db, | ||
10 | Optional[String] $pg_hostname = "localhost", | ||
11 | Optional[String] $pg_port = "5432", | ||
12 | Optional[String] $web_host = undef, | ||
13 | Optional[String] $web_port = "", | ||
14 | Optional[Boolean] $web_ssl = true, | ||
15 | Optional[String] $front_version = undef, | ||
16 | Optional[String] $front_sha256 = undef, | ||
17 | Optional[String] $bot_version = undef, | ||
18 | Optional[String] $bot_sha256 = undef, | ||
19 | ) { | ||
7 | include "base_installation" | 20 | include "base_installation" |
8 | 21 | ||
9 | include "profile::tools" | 22 | include "profile::tools" |
@@ -11,420 +24,17 @@ class role::cryptoportfolio { | |||
11 | include "profile::apache" | 24 | include "profile::apache" |
12 | include "profile::xmr_stak" | 25 | include "profile::xmr_stak" |
13 | 26 | ||
14 | $password_seed = lookup("base_installation::puppet_pass_seed") |$key| { {} } | 27 | contain "role::cryptoportfolio::postgresql" |
15 | 28 | contain "role::cryptoportfolio::apache" | |
16 | $cf_pg_user = "cryptoportfolio" | ||
17 | $cf_pg_user_replication = "cryptoportfolio_replication" | ||
18 | $cf_pg_db = "cryptoportfolio" | ||
19 | $cf_pg_password = generate_password(24, $password_seed, "postgres_cryptoportfolio") | ||
20 | $cf_pg_replication_password = generate_password(24, $password_seed, "postgres_cryptoportfolio_replication") | ||
21 | $cf_pg_hostname = "localhost" | ||
22 | $cf_pg_port = "5432" | ||
23 | $cf_pg_host = "${cf_pg_hostname}:${cf_pg_port}" | ||
24 | |||
25 | $cf_user = "cryptoportfolio" | ||
26 | $cf_group = "cryptoportfolio" | ||
27 | $cf_home = "/opt/cryptoportfolio" | ||
28 | $cf_env = "prod" | ||
29 | $cf_front_app_host = lookup("base_installation::system_hostname") |$key| { "example.com" } | ||
30 | $cf_front_app_port = "" | ||
31 | $cf_front_app_ssl = "true" | ||
32 | $cf_front_app = "${cf_home}/go/src/immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front" | ||
33 | $cf_front_app_api_workdir = "${cf_front_app}/cmd/app" | ||
34 | $cf_front_app_api_bin = "${cf_front_app_api_workdir}/cryptoportfolio-app" | ||
35 | $cf_front_app_api_conf = "${cf_home}/conf.toml" | ||
36 | $cf_front_app_api_secret = generate_password(24, $password_seed, "cryptoportfolio_api_secret") | ||
37 | |||
38 | $cf_front_app_static_conf = "${cf_front_app}/cmd/web/env/prod.env" | ||
39 | |||
40 | $cf_bot_app = "${cf_home}/bot" | ||
41 | $cf_bot_app_conf = "${cf_home}/bot_config.ini" | ||
42 | $cf_bot_app_reports = "${cf_home}/bot_reports" | ||
43 | |||
44 | $cf_webhook_url = lookup("cryptoportfolio::slack_webhook") |$key| { "" } | ||
45 | |||
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 | 29 | ||
54 | file { "/var/lib/postgres/data/certs/cert.pem": | 30 | contain "role::cryptoportfolio::notify" |
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 | |||
91 | postgresql::server::db { $cf_pg_db: | ||
92 | user => $cf_pg_user, | ||
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", | ||
127 | } | ||
128 | |||
129 | postgresql::server::pg_hba_rule { 'allow localhost TCP access to cryptoportfolio user': | ||
130 | type => 'host', | ||
131 | database => $cf_pg_db, | ||
132 | user => $cf_pg_user, | ||
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', | ||
139 | database => $cf_pg_db, | ||
140 | user => $cf_pg_user, | ||
141 | address => '::1/128', | ||
142 | auth_method => 'md5', | ||
143 | order => "b0", | ||
144 | } | ||
145 | |||
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 | |||
155 | letsencrypt::certonly { $cf_front_app_host: ; | ||
156 | default: * => $::profile::apache::letsencrypt_certonly_default; | ||
157 | } | ||
158 | |||
159 | class { 'apache::mod::headers': } | ||
160 | apache::vhost { $cf_front_app_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/$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; | ||
173 | } | ||
174 | |||
175 | user { $cf_user: | ||
176 | name => $cf_user, | ||
177 | ensure => "present", | ||
178 | managehome => true, | ||
179 | home => $cf_home, | ||
180 | system => true, | ||
181 | password => '!!', | ||
182 | } | ||
183 | |||
184 | file { "/usr/local/bin/slack-notify": | ||
185 | mode => "0755", | ||
186 | source => "puppet:///modules/role/cryptoportfolio/slack-notify.py", | ||
187 | } | ||
188 | |||
189 | $front_version = lookup("cryptoportfolio::front_version") |$key| { {} } | ||
190 | $front_sha256 = lookup("cryptoportfolio::front_sha256") |$key| { {} } | ||
191 | |||
192 | $bot_version = lookup("cryptoportfolio::bot_version") |$key| { {} } | ||
193 | $bot_sha256 = lookup("cryptoportfolio::bot_sha256") |$key| { {} } | ||
194 | 31 | ||
195 | unless empty($bot_version) { | 32 | unless empty($bot_version) { |
196 | ensure_packages(["python", "python-pip"]) | 33 | contain "role::cryptoportfolio::bot" |
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 | |||
206 | archive { "${cf_home}/trader_${bot_version}.tar.gz": | ||
207 | path => "${cf_home}/trader_${bot_version}.tar.gz", | ||
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, | ||
213 | user => $cf_user, | ||
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, | ||
226 | before => [ | ||
227 | File[$cf_bot_app_conf], | ||
228 | Cron["py-cryptoportfolio-before"], | ||
229 | Cron["py-cryptoportfolio-after"], | ||
230 | ] | ||
231 | } | ||
232 | |||
233 | file { $cf_bot_app_conf: | ||
234 | owner => $cf_user, | ||
235 | group => $cf_group, | ||
236 | mode => "0600", | ||
237 | content => template("role/cryptoportfolio/bot_config.ini.erb"), | ||
238 | require => [ | ||
239 | User[$cf_user], | ||
240 | Archive["${cf_home}/trader_${bot_version}.tar.gz"], | ||
241 | ], | ||
242 | } | ||
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], | ||
254 | Archive["${cf_home}/trader_${bot_version}.tar.gz"] | ||
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, | ||
264 | minute => 0, | ||
265 | environment => ["HOME=${cf_home}","PATH=/usr/bin/"], | ||
266 | require => [ | ||
267 | File[$cf_bot_app_conf], | ||
268 | Archive["${cf_home}/trader_${bot_version}.tar.gz"] | ||
269 | ], | ||
270 | } | ||
271 | |||
272 | unless empty($cf_webhook_url) { | ||
273 | exec { "bot-slack-notify": | ||
274 | refreshonly => true, | ||
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", | ||
283 | require => File["/usr/local/bin/slack-notify"], | ||
284 | subscribe => Exec["py-cryptoportfolio-dependencies"], | ||
285 | } | ||
286 | } | ||
287 | } | 34 | } |
288 | 35 | ||
289 | # FIXME: restore backup | 36 | # FIXME: restore backup |
290 | unless empty($front_version) { | 37 | unless empty($front_version) { |
291 | ensure_packages(["go", "npm", "nodejs", "yarn"]) | 38 | contain "role::cryptoportfolio::front" |
292 | |||
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", | ||
303 | mode => "0700", | ||
304 | owner => $cf_user, | ||
305 | group => $cf_group, | ||
306 | require => User[$cf_user], | ||
307 | } | ||
308 | |||
309 | file { "${cf_home}/front": | ||
310 | ensure => "link", | ||
311 | target => $cf_front_app, | ||
312 | before => File[$cf_front_app], | ||
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"), | ||
320 | notify => Exec["systemctl daemon-reload"], | ||
321 | } | ||
322 | |||
323 | service { 'cryptoportfolio-app': | ||
324 | enable => true, | ||
325 | ensure => "running", | ||
326 | subscribe => [Exec["go-cryptoportfolio-app"], Exec["web-cryptoportfolio-build"]], | ||
327 | require => [ | ||
328 | File["/etc/systemd/system/cryptoportfolio-app.service"], | ||
329 | Postgresql::Server::Db[$cf_pg_db] | ||
330 | ], | ||
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", | ||
337 | } | ||
338 | |||
339 | archive { "${cf_home}/front_${front_version}.tar.gz": | ||
340 | path => "${cf_home}/front_${front_version}.tar.gz", | ||
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 | ||
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"), | ||
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, | ||
386 | } | ||
387 | |||
388 | # Static pages | ||
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"), | ||
394 | before => Exec["web-cryptoportfolio-build"], | ||
395 | } | ||
396 | |||
397 | exec { "web-cryptoportfolio-dependencies": | ||
398 | cwd => "${cf_front_app}/cmd/web", | ||
399 | user => $cf_user, | ||
400 | environment => ["HOME=${cf_home}"], | ||
401 | command => "/usr/bin/make install", | ||
402 | refreshonly => true, | ||
403 | require => [Package["npm"], Package["nodejs"], Package["yarn"]] | ||
404 | } ~> | ||
405 | exec { "web-cryptoportfolio-build": | ||
406 | cwd => "${cf_front_app}/cmd/web", | ||
407 | user => $cf_user, | ||
408 | environment => ["HOME=${cf_home}"], | ||
409 | path => ["${cf_front_app}/cmd/web/node_modules/.bin/", "/usr/bin"], | ||
410 | command => "/usr/bin/make static ENV=${cf_env}", | ||
411 | refreshonly => true, | ||
412 | } | ||
413 | |||
414 | unless empty($cf_webhook_url) { | ||
415 | exec { "front-slack-notify": | ||
416 | refreshonly => true, | ||
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", | ||
425 | require => File["/usr/local/bin/slack-notify"], | ||
426 | subscribe => [Exec["go-cryptoportfolio-app"], Exec["web-cryptoportfolio-build"]], | ||
427 | } | ||
428 | } | ||
429 | } | 39 | } |
430 | } | 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 | } | ||
diff --git a/modules/role/templates/backup/backup_dirname_head.sh.erb b/modules/role/templates/backup/backup_dirname_head.sh.erb new file mode 100644 index 0000000..e20cfd3 --- /dev/null +++ b/modules/role/templates/backup/backup_dirname_head.sh.erb | |||
@@ -0,0 +1,27 @@ | |||
1 | ##### <%= @dirname %> ##### | ||
2 | DEST="<%= @dest %>" | ||
3 | BASE="<%= @base %>" | ||
4 | OLD_BAK_BASE=$BASE/older/j | ||
5 | BAK_BASE=${OLD_BAK_BASE}0 | ||
6 | RSYNC_OUTPUT=$BASE/rsync_output | ||
7 | NBR=<%= @nbr %> | ||
8 | |||
9 | if ! ssh \ | ||
10 | -o PreferredAuthentications=publickey \ | ||
11 | -o StrictHostKeyChecking=yes \ | ||
12 | -o ClearAllForwardings=yes \ | ||
13 | $DEST backup; then | ||
14 | echo "Fichier de verrouillage backup sur $DEST ou impossible de se connecter" >&2 | ||
15 | skip=$DEST | ||
16 | fi | ||
17 | |||
18 | rm -rf ${OLD_BAK_BASE}${NBR} | ||
19 | for j in `seq -w $(($NBR-1)) -1 0`; do | ||
20 | [ ! -d ${OLD_BAK_BASE}$j ] && continue | ||
21 | mv ${OLD_BAK_BASE}$j ${OLD_BAK_BASE}$(($j+1)) | ||
22 | done | ||
23 | mkdir $BAK_BASE | ||
24 | mv $RSYNC_OUTPUT $BAK_BASE | ||
25 | mkdir $RSYNC_OUTPUT | ||
26 | |||
27 | if [ "$skip" != "$DEST" ]; then | ||
diff --git a/modules/role/templates/backup/backup_dirname_part.sh.erb b/modules/role/templates/backup/backup_dirname_part.sh.erb new file mode 100644 index 0000000..ec662c4 --- /dev/null +++ b/modules/role/templates/backup/backup_dirname_part.sh.erb | |||
@@ -0,0 +1,26 @@ | |||
1 | ### <%= @dirname %> <%= @local_folder %> ### | ||
2 | LOCAL="<%= @local_folder %>" | ||
3 | REMOTE="<%= @remote_folder %>" | ||
4 | |||
5 | cd $BASE/$LOCAL | ||
6 | cat > $EXCL_FROM <<EOF | ||
7 | <%= @exclude_from.join("\n") %> | ||
8 | EOF | ||
9 | cat > $FILES_FROM <<EOF | ||
10 | <%= @files_from.join("\n") %> | ||
11 | EOF | ||
12 | |||
13 | OUT=$RSYNC_OUTPUT/$LOCAL | ||
14 | rsync -XAavbrz --fake-super -e ssh --numeric-ids --delete \ | ||
15 | --backup-dir=$BAK_BASE/$LOCAL \ | ||
16 | <%- unless @args.empty? -%> | ||
17 | <%= @args %>\ | ||
18 | <% end -%> | ||
19 | <%- unless @exclude_from.empty? -%> | ||
20 | --exclude-from=$EXCL_FROM \ | ||
21 | <% end -%> | ||
22 | <%- unless @files_from.empty? -%> | ||
23 | --files-from=$FILES_FROM \ | ||
24 | <% end -%> | ||
25 | $DEST:$REMOTE . > $OUT || true | ||
26 | ### End <%= @dirname %> <%= @local_folder %> ### | ||
diff --git a/modules/role/templates/backup/backup_dirname_tail.sh.erb b/modules/role/templates/backup/backup_dirname_tail.sh.erb new file mode 100644 index 0000000..6b16c9d --- /dev/null +++ b/modules/role/templates/backup/backup_dirname_tail.sh.erb | |||
@@ -0,0 +1,4 @@ | |||
1 | |||
2 | ssh $DEST sh -c "date > .last_backup" | ||
3 | fi # [ "$skip" != "$DEST" ] | ||
4 | ##### End <%= @dirname %> ##### | ||
diff --git a/modules/role/templates/backup/backup_head.sh.erb b/modules/role/templates/backup/backup_head.sh.erb new file mode 100644 index 0000000..be9f5bf --- /dev/null +++ b/modules/role/templates/backup/backup_head.sh.erb | |||
@@ -0,0 +1,20 @@ | |||
1 | #!/bin/bash | ||
2 | MAILTO="<%= @mailto %>" | ||
3 | |||
4 | EXCL_FROM=`mktemp` | ||
5 | FILES_FROM=`mktemp` | ||
6 | TMP_STDERR=`mktemp` | ||
7 | |||
8 | on_exit() { | ||
9 | if [ -s "$TMP_STDERR" ]; then | ||
10 | cat "$TMP_STDERR" | mail -Ssendwait -s "save_distant rsync error" "$MAILTO" | ||
11 | fi | ||
12 | rm -f $TMP_STDERR $EXCL_FROM $FILES_FROM | ||
13 | } | ||
14 | |||
15 | trap "on_exit" EXIT | ||
16 | |||
17 | exec 2> "$TMP_STDERR" | ||
18 | exec < /dev/null | ||
19 | |||
20 | set -e | ||
diff --git a/modules/role/templates/backup/backup_immae_eu.sh.erb b/modules/role/templates/backup/backup_immae_eu.sh.erb new file mode 100644 index 0000000..4fab30e --- /dev/null +++ b/modules/role/templates/backup/backup_immae_eu.sh.erb | |||
@@ -0,0 +1,79 @@ | |||
1 | #!/bin/bash | ||
2 | DEST="<%= @dest %>" | ||
3 | MAILTO="<%= @mailto %>" | ||
4 | BASE="<%= @base %>" | ||
5 | OLD_BAK_BASE=$BASE/older/j | ||
6 | BAK_BASE=${OLD_BAK_BASE}0 | ||
7 | RSYNC_OUTPUT=$BASE/rsync_output | ||
8 | NBR=7 | ||
9 | |||
10 | TMP=`mktemp` | ||
11 | TMP_STDERR=`mktemp` | ||
12 | |||
13 | trap "rm -f $TMP $TMP_STDERR" EXIT | ||
14 | |||
15 | exec 2> "$TMP_STDERR" | ||
16 | |||
17 | set -e | ||
18 | if ! `ssh -o ClearAllForwardings=yes $DEST backup`; then | ||
19 | echo "Fichier de verrouillage backup sur $DEST" | ||
20 | exit 1 | ||
21 | fi | ||
22 | |||
23 | rm -rf ${OLD_BAK_BASE}${NBR} | ||
24 | for j in `seq -w $(($NBR-1)) -1 0`; do | ||
25 | [ ! -d ${OLD_BAK_BASE}$j ] && continue | ||
26 | mv ${OLD_BAK_BASE}$j ${OLD_BAK_BASE}$(($j+1)) | ||
27 | done | ||
28 | mkdir $BAK_BASE | ||
29 | mv $RSYNC_OUTPUT $BAK_BASE | ||
30 | mkdir $RSYNC_OUTPUT | ||
31 | |||
32 | ############## | ||
33 | NAME="home" | ||
34 | FOLDER="/home/immae" | ||
35 | |||
36 | cd $BASE/$NAME | ||
37 | cat > $TMP <<EOF | ||
38 | /.no_backup/ | ||
39 | /hosts/florian/nobackup/ | ||
40 | /hosts/connexionswing.com/ | ||
41 | /hosts/connexionswing.immae.eu/ | ||
42 | /hosts/ludivine.immae.eu/ | ||
43 | /hosts/ludivinecassal.com/ | ||
44 | /hosts/piedsjaloux.fr/ | ||
45 | /hosts/piedsjaloux.immae.eu/ | ||
46 | /hosts/spip/sites/*/ | ||
47 | /hosts/spip/spip* | ||
48 | EOF | ||
49 | OUT=$RSYNC_OUTPUT/$NAME | ||
50 | rsync -XAavbrz --fake-super -e ssh --numeric-ids --delete \ | ||
51 | --backup-dir=$BAK_BASE/$NAME --exclude-from=$TMP \ | ||
52 | $DEST:$FOLDER . > $OUT || true | ||
53 | |||
54 | ############## | ||
55 | NAME="system" | ||
56 | FOLDER="/" | ||
57 | |||
58 | cd $BASE/$NAME | ||
59 | cat > $TMP <<EOF | ||
60 | /etc/ | ||
61 | /srv/ | ||
62 | /var/lib/ | ||
63 | /var/spool/ | ||
64 | /var/named/ | ||
65 | /usr/local/ | ||
66 | EOF | ||
67 | OUT=$RSYNC_OUTPUT/$NAME | ||
68 | rsync -XAavbrz -R --fake-super -e ssh --numeric-ids --delete \ | ||
69 | --rsync-path='sudo rsync' \ | ||
70 | --backup-dir=$BAK_BASE/$NAME \ | ||
71 | --files-from=$TMP \ | ||
72 | $DEST:$FOLDER . > $OUT || true | ||
73 | |||
74 | ############## | ||
75 | ssh $DEST sh -c "date > .last_backup" | ||
76 | |||
77 | if [ -s "$TMP_STDERR" ]; then | ||
78 | cat "$TMP_STDERR" | mail -Ssendwait -s "save_distant rsync error" "$MAILTO" | ||
79 | fi | ||
diff --git a/modules/role/templates/backup/backup_tail.sh.erb b/modules/role/templates/backup/backup_tail.sh.erb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/modules/role/templates/backup/backup_tail.sh.erb | |||
diff --git a/modules/role/templates/backup/ssh_host_changed.info.erb b/modules/role/templates/backup/ssh_host_changed.info.erb new file mode 100644 index 0000000..ebf202e --- /dev/null +++ b/modules/role/templates/backup/ssh_host_changed.info.erb | |||
@@ -0,0 +1,4 @@ | |||
1 | Host <%= @host %> added, please send <%= @user %> key if necessary. | ||
2 | <%- if File.exist?("/home/#{@user}/.ssh/id_rsa.pub") %> | ||
3 | <%= File.read("/home/#{@user}/.ssh/id_rsa.pub") %> | ||
4 | <% end -%> | ||
diff --git a/modules/role/templates/backup/ssh_key_changed.info.erb b/modules/role/templates/backup/ssh_key_changed.info.erb new file mode 100644 index 0000000..43fd2ec --- /dev/null +++ b/modules/role/templates/backup/ssh_key_changed.info.erb | |||
@@ -0,0 +1,5 @@ | |||
1 | ssh key of <%= @user %> changed, | ||
2 | please update hosts: | ||
3 | <%- @hosts.each do |host| %> | ||
4 | - <%= host %> | ||
5 | <% end -%> | ||
diff --git a/modules/role/templates/cryptoportfolio/api_conf.toml.erb b/modules/role/templates/cryptoportfolio/api_conf.toml.erb index 13550c9..7a4b66d 100644 --- a/modules/role/templates/cryptoportfolio/api_conf.toml.erb +++ b/modules/role/templates/cryptoportfolio/api_conf.toml.erb | |||
@@ -1,15 +1,15 @@ | |||
1 | log_level="info" | 1 | log_level="info" |
2 | mode="<%= @cf_env %>" | 2 | mode="<%= @env %>" |
3 | log_out="stdout" | 3 | log_out="stdout" |
4 | 4 | ||
5 | [db] | 5 | [db] |
6 | user="<%= @cf_pg_user %>" | 6 | user="<%= @pg_user %>" |
7 | password="<%= @cf_pg_password %>" | 7 | password="<%= @pg_password %>" |
8 | database="<%= @cf_pg_db %>" | 8 | database="<%= @pg_db %>" |
9 | address="<%= @cf_pg_host %>" | 9 | address="<%= @pg_host %>" |
10 | 10 | ||
11 | [api] | 11 | [api] |
12 | domain="<%= @cf_front_app_host %>" | 12 | domain="<%= @web_host %>" |
13 | jwt_secret="<%= @cf_front_app_api_secret %>" | 13 | jwt_secret="<%= @cf_front_app_api_secret %>" |
14 | 14 | ||
15 | [app] | 15 | [app] |
diff --git a/modules/role/templates/cryptoportfolio/bot_config.ini.erb b/modules/role/templates/cryptoportfolio/bot_config.ini.erb index 30298eb..b0211a6 100644 --- a/modules/role/templates/cryptoportfolio/bot_config.ini.erb +++ b/modules/role/templates/cryptoportfolio/bot_config.ini.erb | |||
@@ -1,9 +1,9 @@ | |||
1 | [postgresql] | 1 | [postgresql] |
2 | host = <%= @cf_pg_hostname %> | 2 | host = <%= @pg_hostname %> |
3 | port = <%= @cf_pg_port %> | 3 | port = <%= @pg_port %> |
4 | user = <%= @cf_pg_user %> | 4 | user = <%= @pg_user %> |
5 | password = <%= @cf_pg_password %> | 5 | password = <%= @pg_password %> |
6 | database = <%= @cf_pg_db %> | 6 | database = <%= @pg_db %> |
7 | 7 | ||
8 | [app] | 8 | [app] |
9 | report_path = <%= @cf_bot_app_reports %> | 9 | report_path = <%= @cf_bot_app_reports %> |
diff --git a/modules/role/templates/cryptoportfolio/cryptoportfolio-app.service.erb b/modules/role/templates/cryptoportfolio/cryptoportfolio-app.service.erb index a521c0e..ed2b908 100644 --- a/modules/role/templates/cryptoportfolio/cryptoportfolio-app.service.erb +++ b/modules/role/templates/cryptoportfolio/cryptoportfolio-app.service.erb | |||
@@ -5,8 +5,8 @@ Description=Cryptoportfolio app | |||
5 | Type=simple | 5 | Type=simple |
6 | 6 | ||
7 | WorkingDirectory=<%= @cf_front_app_api_workdir %> | 7 | WorkingDirectory=<%= @cf_front_app_api_workdir %> |
8 | User=<%= @cf_user %> | 8 | User=<%= @user %> |
9 | Group=<%= @cf_group %> | 9 | Group=<%= @group %> |
10 | UMask=007 | 10 | UMask=007 |
11 | 11 | ||
12 | ExecStart=<%= @cf_front_app_api_bin %> -conf <%= @cf_front_app_api_conf %> | 12 | ExecStart=<%= @cf_front_app_api_bin %> -conf <%= @cf_front_app_api_conf %> |
diff --git a/modules/role/templates/cryptoportfolio/static_conf.env.erb b/modules/role/templates/cryptoportfolio/static_conf.env.erb index db9759d..314ee14 100644 --- a/modules/role/templates/cryptoportfolio/static_conf.env.erb +++ b/modules/role/templates/cryptoportfolio/static_conf.env.erb | |||
@@ -1,4 +1,4 @@ | |||
1 | API_HOST="<%= @cf_front_app_host %>" | 1 | API_HOST="<%= @web_host %>" |
2 | API_PORT="<%= @cf_front_app_port %>" | 2 | API_PORT="<%= @web_port %>" |
3 | API_HTTPS="<%= @cf_front_app_ssl %>" | 3 | API_HTTPS="<%= @web_ssl %>" |
4 | 4 | ||
diff --git a/modules/ssh_keygen b/modules/ssh_keygen new file mode 160000 | |||
Subproject ca53363249b58af96f90cb810c7c51dda8ba803 | |||
diff --git a/python/buy_vps_server.py b/python/buy_ovh_vps_ssd.py index 44ae786..44ae786 100644 --- a/python/buy_vps_server.py +++ b/python/buy_ovh_vps_ssd.py | |||
diff --git a/python/get_initial_configuration_cloud_instance.py b/python/get_initial_configuration_ovh_cloud_instance.py index 4157716..844373c 100644 --- a/python/get_initial_configuration_cloud_instance.py +++ b/python/get_initial_configuration_ovh_cloud_instance.py | |||
@@ -6,6 +6,7 @@ except ImportError: | |||
6 | # In case it's installed globally | 6 | # In case it's installed globally |
7 | import ovh | 7 | import ovh |
8 | import sys | 8 | import sys |
9 | from ovh_helper import find_cloud_instance | ||
9 | 10 | ||
10 | infos = {} | 11 | infos = {} |
11 | 12 | ||
@@ -13,19 +14,7 @@ infos = {} | |||
13 | # See ovh/README.rst | 14 | # See ovh/README.rst |
14 | client = ovh.Client() | 15 | client = ovh.Client() |
15 | 16 | ||
16 | projects_list = client.get('/cloud/project/') | 17 | _, instance = find_cloud_instance(client, sys.argv[-1]) |
17 | if len(projects_list) > 1: | ||
18 | print("More than one project is not supported, taking the first one") | ||
19 | project = projects_list[0] | ||
20 | instances_list = client.get('/cloud/project/{}/instance'.format(project)) | ||
21 | instances = dict(map(lambda x: (x["id"], x), instances_list)) | ||
22 | if sys.argv[-1] in instances: | ||
23 | instance = instances[sys.argv[-1]] | ||
24 | else: | ||
25 | print("Instance not in list:") | ||
26 | for instance in instances_list: | ||
27 | print("{}: {}".format(instance["name"], instance["id"])) | ||
28 | sys.exit(1) | ||
29 | 18 | ||
30 | infos["ips"] = {} | 19 | infos["ips"] = {} |
31 | for ip_infos in instance["ipAddresses"]: | 20 | for ip_infos in instance["ipAddresses"]: |
diff --git a/python/get_initial_configuration.py b/python/get_initial_configuration_ovh_vps_ssd.py index 0c6f698..0c6f698 100644 --- a/python/get_initial_configuration.py +++ b/python/get_initial_configuration_ovh_vps_ssd.py | |||
diff --git a/python/list_servers.py b/python/list_servers.py index 9b8bc64..e7bd2af 100644 --- a/python/list_servers.py +++ b/python/list_servers.py | |||
@@ -6,7 +6,18 @@ except ImportError: | |||
6 | 6 | ||
7 | client = ovh.Client() | 7 | client = ovh.Client() |
8 | 8 | ||
9 | print("OVH cloud instances:") | ||
10 | projects_list = client.get('/cloud/project/') | ||
11 | for project_id in projects_list: | ||
12 | project = client.get('/cloud/project/{}'.format(project_id)) | ||
13 | print("\t{}:".format(project["description"])) | ||
14 | instances_list = client.get('/cloud/project/{}/instance'.format(project_id)) | ||
15 | for instance in instances_list: | ||
16 | print("\t\t{}: {}".format(instance["name"], instance["id"])) | ||
17 | |||
9 | vps_list = client.get('/vps/') | 18 | vps_list = client.get('/vps/') |
10 | 19 | ||
20 | print("OVH VPS SSD servers:") | ||
11 | for vps in vps_list: | 21 | for vps in vps_list: |
12 | print(vps) | 22 | print("\t{}".format(vps)) |
23 | |||
diff --git a/python/ovh_helper.py b/python/ovh_helper.py index a49a245..19834ae 100644 --- a/python/ovh_helper.py +++ b/python/ovh_helper.py | |||
@@ -1,4 +1,5 @@ | |||
1 | import time | 1 | import time |
2 | import sys | ||
2 | 3 | ||
3 | def show_progress(client, vps, task_type): | 4 | def show_progress(client, vps, task_type): |
4 | running_task_id = client.get("/vps/{}/tasks?type={}".format(vps, task_type))[0] | 5 | running_task_id = client.get("/vps/{}/tasks?type={}".format(vps, task_type))[0] |
@@ -17,3 +18,19 @@ def show_progress(client, vps, task_type): | |||
17 | time.sleep(3) | 18 | time.sleep(3) |
18 | 19 | ||
19 | print("\rFinished") | 20 | print("\rFinished") |
21 | |||
22 | def find_cloud_instance(client, instance_id): | ||
23 | projects_list = client.get('/cloud/project/') | ||
24 | instances_list = [] | ||
25 | for project in projects_list: | ||
26 | instances_list += list(map(lambda x: [project, x], | ||
27 | client.get('/cloud/project/{}/instance'.format(project)))) | ||
28 | instances = dict(map(lambda x: (x[1]["id"], x), instances_list)) | ||
29 | if instance_id in instances: | ||
30 | project_instance = instances[instance_id] | ||
31 | else: | ||
32 | print("Instance not in list:") | ||
33 | for instance in instances_list: | ||
34 | print("{}: {}".format(instance[1]["name"], instance[1]["id"])) | ||
35 | sys.exit(1) | ||
36 | return project_instance | ||
diff --git a/python/reboot_cloud_instance.py b/python/reboot_ovh_cloud_instance.py index b90f488..de20c07 100644 --- a/python/reboot_cloud_instance.py +++ b/python/reboot_ovh_cloud_instance.py | |||
@@ -6,24 +6,13 @@ except ImportError: | |||
6 | # In case it's installed globally | 6 | # In case it's installed globally |
7 | import ovh | 7 | import ovh |
8 | import sys | 8 | import sys |
9 | from ovh_helper import find_cloud_instance | ||
9 | 10 | ||
10 | # Credentials are stored in ~/.ovh.conf | 11 | # Credentials are stored in ~/.ovh.conf |
11 | # See ovh/README.rst | 12 | # See ovh/README.rst |
12 | client = ovh.Client() | 13 | client = ovh.Client() |
13 | 14 | ||
14 | projects_list = client.get('/cloud/project/') | 15 | project, instance = find_cloud_instance(client, sys.argv[-1]) |
15 | if len(projects_list) > 1: | ||
16 | print("More than one project is not supported, taking the first one") | ||
17 | project = projects_list[0] | ||
18 | instances_list = client.get('/cloud/project/{}/instance'.format(project)) | ||
19 | instances = dict(map(lambda x: (x["id"], x), instances_list)) | ||
20 | if sys.argv[-1] in instances: | ||
21 | instance = instances[sys.argv[-1]] | ||
22 | else: | ||
23 | print("Instance not in list:") | ||
24 | for instance in instances_list: | ||
25 | print("{}: {}".format(instance["name"], instance["id"])) | ||
26 | sys.exit(1) | ||
27 | 16 | ||
28 | if "--rescue" in sys.argv: | 17 | if "--rescue" in sys.argv: |
29 | netboot_mode="rescue" | 18 | netboot_mode="rescue" |
diff --git a/python/reboot_vps_server.py b/python/reboot_ovh_vps_ssd.py index 71c5227..71c5227 100644 --- a/python/reboot_vps_server.py +++ b/python/reboot_ovh_vps_ssd.py | |||
diff --git a/python/reinstall_cloud_instance.py b/python/reinstall_ovh_cloud_instance.py index c488fda..c0d2617 100644 --- a/python/reinstall_cloud_instance.py +++ b/python/reinstall_ovh_cloud_instance.py | |||
@@ -6,24 +6,13 @@ except ImportError: | |||
6 | # In case it's installed globally | 6 | # In case it's installed globally |
7 | import ovh | 7 | import ovh |
8 | import sys | 8 | import sys |
9 | from ovh_helper import find_cloud_instance | ||
9 | 10 | ||
10 | # Credentials are stored in ~/.ovh.conf | 11 | # Credentials are stored in ~/.ovh.conf |
11 | # See ovh/README.rst | 12 | # See ovh/README.rst |
12 | client = ovh.Client() | 13 | client = ovh.Client() |
13 | 14 | ||
14 | projects_list = client.get('/cloud/project/') | 15 | project, instance = find_cloud_instance(client, sys.argv[-1]) |
15 | if len(projects_list) > 1: | ||
16 | print("More than one project is not supported, taking the first one") | ||
17 | project = projects_list[0] | ||
18 | instances_list = client.get('/cloud/project/{}/instance'.format(project)) | ||
19 | instances = dict(map(lambda x: (x["id"], x), instances_list)) | ||
20 | if sys.argv[-1] in instances: | ||
21 | instance = instances[sys.argv[-1]] | ||
22 | else: | ||
23 | print("Instance not in list:") | ||
24 | for instance in instances_list: | ||
25 | print("{}: {}".format(instance["name"], instance["id"])) | ||
26 | sys.exit(1) | ||
27 | 16 | ||
28 | current_image = instance["imageId"] | 17 | current_image = instance["imageId"] |
29 | available_images = client.get('/cloud/project/{}/image'.format(project), | 18 | available_images = client.get('/cloud/project/{}/image'.format(project), |
diff --git a/python/reinstall_vps_server.py b/python/reinstall_ovh_vps_ssd.py index 9f535cc..9f535cc 100644 --- a/python/reinstall_vps_server.py +++ b/python/reinstall_ovh_vps_ssd.py | |||
diff --git a/scripts/arch_install_script.sh b/scripts/arch_install_script.sh new file mode 100755 index 0000000..d2c6107 --- /dev/null +++ b/scripts/arch_install_script.sh | |||
@@ -0,0 +1,16 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | git_branch="$1" | ||
4 | environment="$2" | ||
5 | CODE_PATH="/etc/puppetlabs/code" | ||
6 | |||
7 | rm -rf $CODE_PATH | ||
8 | |||
9 | pacman-key --init | ||
10 | pacman-key --populate archlinux | ||
11 | |||
12 | git clone -b $git_branch --recursive https://git.immae.eu/perso/Immae/Projets/Puppet.git $CODE_PATH | ||
13 | puppet apply --environment $environment --tags base_installation --test $CODE_PATH/manifests/site.pp | ||
14 | # The password seed requires puppet to be run twice | ||
15 | puppet apply --environment $environment --tags base_installation --test $CODE_PATH/manifests/site.pp | ||
16 | |||
diff --git a/scripts/arch_puppet_configuration_script.sh b/scripts/arch_puppet_configuration_script.sh new file mode 100755 index 0000000..caf8987 --- /dev/null +++ b/scripts/arch_puppet_configuration_script.sh | |||
@@ -0,0 +1,8 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | git_branch="$1" | ||
4 | environment="$2" | ||
5 | CODE_PATH="/etc/puppetlabs/code" | ||
6 | |||
7 | puppet apply --environment $environment --tags base_installation --test $CODE_PATH/manifests/site.pp | ||
8 | |||
diff --git a/scripts/ovh_cloud_instance/arch_host_puppet_configuration_script.sh b/scripts/ovh_cloud_instance/arch_host_puppet_configuration_script.sh new file mode 100755 index 0000000..6aae8a7 --- /dev/null +++ b/scripts/ovh_cloud_instance/arch_host_puppet_configuration_script.sh | |||
@@ -0,0 +1,12 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | git_branch="$1" | ||
4 | environment="$2" | ||
5 | |||
6 | MOUNTPOINT=/mnt | ||
7 | |||
8 | sudo cp /tmp/arch_puppet_configuration_script.sh "$MOUNTPOINT/root/" | ||
9 | |||
10 | sudo arch-chroot "$MOUNTPOINT" /root/arch_puppet_configuration_script.sh "$git_branch" "$environment" | ||
11 | |||
12 | sudo umount "$MOUNTPOINT" | ||
diff --git a/scripts/ovh_cloud_instance/arch_host_script.sh b/scripts/ovh_cloud_instance/arch_host_script.sh new file mode 100755 index 0000000..42dcc4a --- /dev/null +++ b/scripts/ovh_cloud_instance/arch_host_script.sh | |||
@@ -0,0 +1,50 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | set -e | ||
4 | |||
5 | git_branch="$1" | ||
6 | environment="$2" | ||
7 | |||
8 | # Randomizer | ||
9 | sudo haveged & | ||
10 | # /Randomizer | ||
11 | |||
12 | # Prepare an arch chroot | ||
13 | sudo pacman -Sy --noconfirm arch-install-scripts | ||
14 | # /Prepare an arch chroot | ||
15 | |||
16 | # Prepare device information | ||
17 | DEVICE=/dev/vdb1 | ||
18 | MOUNTPOINT=/mnt | ||
19 | |||
20 | UUID=$(lsblk -rno UUID "$DEVICE") | ||
21 | PART="/dev/disk/by-uuid/$UUID" | ||
22 | # /Prepare device information | ||
23 | |||
24 | # Install very basic system (base git puppet) | ||
25 | # mkfs.ext4 -F -U "$UUID" "$DEVICE" | ||
26 | sudo mount "$DEVICE" /mnt | ||
27 | |||
28 | ##### FIXME: mkfs.ext4 would be better #### | ||
29 | for i in /mnt/*; do | ||
30 | if [ "$i" = "/mnt/boot" ]; then | ||
31 | # keep /boot/grub | ||
32 | sudo rm -f $i/* || true | ||
33 | else | ||
34 | sudo rm -rf $i | ||
35 | fi | ||
36 | done | ||
37 | ##### /FIXME #### | ||
38 | |||
39 | sudo pacstrap -G /mnt base git puppet | ||
40 | |||
41 | echo "$PART / auto defaults 0 1" | sudo tee /mnt/etc/fstab | ||
42 | # /Install very basic system | ||
43 | |||
44 | # Install rest of system (via puppet) | ||
45 | sudo cp /tmp/arch_install_script.sh "$MOUNTPOINT/root/" | ||
46 | sudo cp /tmp/puppet_variables.json "$MOUNTPOINT/root/" | ||
47 | |||
48 | sudo arch-chroot "$MOUNTPOINT" /root/arch_install_script.sh "$git_branch" "$environment" | ||
49 | # /Install rest of system | ||
50 | |||
diff --git a/scripts/ovh_vps_ssd/arch_chroot_script.sh b/scripts/ovh_vps_ssd/arch_chroot_script.sh new file mode 100755 index 0000000..7b7887f --- /dev/null +++ b/scripts/ovh_vps_ssd/arch_chroot_script.sh | |||
@@ -0,0 +1,29 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | pacman-key --init | ||
4 | pacman-key --populate archlinux | ||
5 | |||
6 | UUID=$(cat /device_uuid) | ||
7 | PART="/dev/disk/by-uuid/$UUID" | ||
8 | DEVICE=$(realpath "$PART") | ||
9 | |||
10 | # mkfs.ext4 -F -U "$UUID" "$DEVICE" | ||
11 | mount "$DEVICE" /mnt | ||
12 | |||
13 | ##### FIXME: mkfs.ext4 would be better #### | ||
14 | for i in /mnt/*; do | ||
15 | if [ "$i" = "/mnt/boot" ]; then | ||
16 | # keep /boot/grub | ||
17 | rm -f $i/* | ||
18 | else | ||
19 | rm -rf $i | ||
20 | fi | ||
21 | done | ||
22 | ##### /FIXME #### | ||
23 | |||
24 | pacstrap -G /mnt base git puppet | ||
25 | |||
26 | echo "$PART / auto defaults 0 1" > /mnt/etc/fstab | ||
27 | |||
28 | umount /mnt | ||
29 | |||
diff --git a/scripts/ovh_vps_ssd/arch_host_puppet_configuration_script.sh b/scripts/ovh_vps_ssd/arch_host_puppet_configuration_script.sh new file mode 100755 index 0000000..35f46fd --- /dev/null +++ b/scripts/ovh_vps_ssd/arch_host_puppet_configuration_script.sh | |||
@@ -0,0 +1,14 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | git_branch="$1" | ||
4 | environment="$2" | ||
5 | |||
6 | DEVICE_STR=$(cat /proc/mounts | grep "/dev/[sv]d.. /mnt/") | ||
7 | DEVICE=$(echo "$DEVICE_STR" | cut -d' ' -f1) | ||
8 | MOUNTPOINT=$(echo "$DEVICE_STR" | cut -d' ' -f2) | ||
9 | |||
10 | cp /tmp/arch_puppet_configuration_script.sh "$MOUNTPOINT/root/" | ||
11 | |||
12 | /tmp/root.x86_64/bin/arch-chroot "$MOUNTPOINT" /root/arch_puppet_configuration_script.sh "$git_branch" "$environment" | ||
13 | |||
14 | umount "$MOUNTPOINT" | ||
diff --git a/scripts/ovh_vps_ssd/arch_host_script.sh b/scripts/ovh_vps_ssd/arch_host_script.sh new file mode 100755 index 0000000..8eecae4 --- /dev/null +++ b/scripts/ovh_vps_ssd/arch_host_script.sh | |||
@@ -0,0 +1,53 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | set -e | ||
4 | |||
5 | git_branch="$1" | ||
6 | environment="$2" | ||
7 | |||
8 | # Randomizer | ||
9 | apt-get update | ||
10 | apt-get install -y haveged | ||
11 | haveged & | ||
12 | # /Randomizer | ||
13 | |||
14 | # Prepare an arch chroot | ||
15 | cd /tmp | ||
16 | |||
17 | LATEST=$(curl -L https://mirrors.kernel.org/archlinux/iso/latest/sha1sums.txt | grep "bootstrap" | head -n1) | ||
18 | SHA1=$(echo "$LATEST" | cut -d' ' -f1) | ||
19 | NAME=$(echo "$LATEST" | cut -d' ' -f3) | ||
20 | |||
21 | curl -L -O "https://mirrors.kernel.org/archlinux/iso/latest/$NAME" | ||
22 | |||
23 | tar -xzf "$NAME" | ||
24 | |||
25 | echo 'Server = http://archlinux.mirrors.ovh.net/archlinux/$repo/os/$arch' > /tmp/root.x86_64/etc/pacman.d/mirrorlist | ||
26 | # /Prepare an arch chroot | ||
27 | |||
28 | # Prepare device information (not available in chroot) | ||
29 | DEVICE_STR=$(cat /proc/mounts | grep "/dev/[sv]d.. /mnt/") | ||
30 | DEVICE=$(echo "$DEVICE_STR" | cut -d' ' -f1) | ||
31 | MOUNTPOINT=$(echo "$DEVICE_STR" | cut -d' ' -f2) | ||
32 | |||
33 | umount "$DEVICE" | ||
34 | UUID=$(lsblk -rno UUID "$DEVICE") | ||
35 | |||
36 | echo "$UUID" > /tmp/root.x86_64/device_uuid | ||
37 | # /Prepare device information | ||
38 | |||
39 | # Install very basic system via chroot (base git puppet) | ||
40 | cp /tmp/arch_chroot_script.sh /tmp/root.x86_64/ | ||
41 | |||
42 | /tmp/root.x86_64/bin/arch-chroot /tmp/root.x86_64/ /arch_chroot_script.sh | ||
43 | # /Install very basic system via chroot | ||
44 | |||
45 | # Mount and install rest of system (via puppet) | ||
46 | mount "$DEVICE" | ||
47 | |||
48 | cp /tmp/arch_install_script.sh "$MOUNTPOINT/root/" | ||
49 | cp /tmp/puppet_variables.json "$MOUNTPOINT/root/" | ||
50 | |||
51 | /tmp/root.x86_64/bin/arch-chroot "$MOUNTPOINT" /root/arch_install_script.sh "$git_branch" "$environment" | ||
52 | # /Mount and install rest of system | ||
53 | |||
diff --git a/scripts/send_and_run.tcl b/scripts/send_and_run.tcl new file mode 100755 index 0000000..42fae62 --- /dev/null +++ b/scripts/send_and_run.tcl | |||
@@ -0,0 +1,31 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | set dest [lindex $argv 0] | ||
3 | set password [lindex $argv 1] | ||
4 | set git_branch [lindex $argv 2] | ||
5 | set environment [lindex $argv 3] | ||
6 | set script [lindex $argv 4] | ||
7 | set files [lrange $argv 4 end] | ||
8 | |||
9 | if {$password == "x"} { | ||
10 | set ask_password 0 | ||
11 | } else { | ||
12 | set ask_password 1 | ||
13 | } | ||
14 | |||
15 | set scriptname [file tail $script] | ||
16 | |||
17 | set sshopts [split "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no"] | ||
18 | |||
19 | set timeout -1 | ||
20 | spawn scp {*}$sshopts {*}$files $dest:/tmp | ||
21 | if {$ask_password} { | ||
22 | expect "assword:" | ||
23 | send "$password\n" | ||
24 | } | ||
25 | expect eof | ||
26 | spawn ssh {*}$sshopts $dest /tmp/$scriptname $git_branch $environment | ||
27 | if {$ask_password} { | ||
28 | expect "assword:" | ||
29 | send "$password\n" | ||
30 | } | ||
31 | expect eof | ||