aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2020-03-06 19:24:21 +0100
committerIsmaël Bouya <ismael.bouya@normalesup.org>2020-03-06 19:24:21 +0100
commitd2c58adb0dfa47a4be23686e231d1a2ebc620b81 (patch)
tree343c82e494537d0d3c5e76205bb24a0251292f66
parentc5465178352d4bce4a4ea01bf03fbc6d6b7e59e8 (diff)
parent8093d467c2f81afe4d321d0547e2cfc2c4067f57 (diff)
downloadPuppet-d2c58adb0dfa47a4be23686e231d1a2ebc620b81.tar.gz
Puppet-d2c58adb0dfa47a4be23686e231d1a2ebc620b81.tar.zst
Puppet-d2c58adb0dfa47a4be23686e231d1a2ebc620b81.zip
Merge branch 'dev'
-rwxr-xr-xbin/install_script.sh10
-rw-r--r--modules/profile/manifests/mail.pp5
-rw-r--r--modules/profile/templates/mail/ssmtp.conf.erb7
-rw-r--r--python/get_initial_configuration_hetzner_server.py21
-rw-r--r--python/hetzner_helper.py59
-rw-r--r--python/list_servers.py6
-rw-r--r--python/reboot_hetzner_server.py18
-rwxr-xr-xscripts/hetzner_server/arch_chroot_script.sh18
-rwxr-xr-xscripts/hetzner_server/arch_host_puppet_configuration_script.sh13
-rwxr-xr-xscripts/hetzner_server/arch_host_script.sh49
10 files changed, 204 insertions, 2 deletions
diff --git a/bin/install_script.sh b/bin/install_script.sh
index 36cc594..322a1ed 100755
--- a/bin/install_script.sh
+++ b/bin/install_script.sh
@@ -11,6 +11,7 @@ $(basename $0) [options]
11 One of the following options is necessary: 11 One of the following options is necessary:
12 --instance-id id Id of the cloud instance 12 --instance-id id Id of the cloud instance
13 --vps-id id Id of the vps 13 --vps-id id Id of the vps
14 --hetzner-id id Id of the Hetzner server
14 15
15 Optional arguments: 16 Optional arguments:
16 --password password Password of the host (only useful in case of no reboot and vps) 17 --password password Password of the host (only useful in case of no reboot and vps)
@@ -53,6 +54,15 @@ while [ -n "$1" ]; do
53 T="ovh_vps_ssd" 54 T="ovh_vps_ssd"
54 shift 55 shift
55 ;; 56 ;;
57 --hetzner-id)
58 host_id="$2"
59 if [ -z "$host_user" ]; then
60 host_user="root"
61 fi
62 [ -n "$T" ] && usage && exit 1
63 T="hetzner_server"
64 shift
65 ;;
56 --password) 66 --password)
57 password="$2" 67 password="$2"
58 shift 68 shift
diff --git a/modules/profile/manifests/mail.pp b/modules/profile/manifests/mail.pp
index 0b4a7a5..ee295dd 100644
--- a/modules/profile/manifests/mail.pp
+++ b/modules/profile/manifests/mail.pp
@@ -5,7 +5,10 @@ class profile::mail (
5) { 5) {
6 ensure_packages(["s-nail", "ssmtp"]) 6 ensure_packages(["s-nail", "ssmtp"])
7 7
8 $hostname = lookup("base_installation::real_hostname") 8 $mail_host = "mail.immae.eu"
9 $password_seed = lookup("base_installation::puppet_pass_seed")
10 $ldap_password = generate_password(24, $password_seed, "ldap")
11 $ldap_cn = lookup("base_installation::ldap_cn")
9 12
10 file { "/etc/ssmtp/ssmtp.conf": 13 file { "/etc/ssmtp/ssmtp.conf":
11 ensure => "present", 14 ensure => "present",
diff --git a/modules/profile/templates/mail/ssmtp.conf.erb b/modules/profile/templates/mail/ssmtp.conf.erb
index 1766140..ea5bc99 100644
--- a/modules/profile/templates/mail/ssmtp.conf.erb
+++ b/modules/profile/templates/mail/ssmtp.conf.erb
@@ -11,4 +11,9 @@ mailhub=<%= @mailhub %>:<%= @mailhub_port %>
11# Where will the mail seem to come from? 11# Where will the mail seem to come from?
12#rewriteDomain=y 12#rewriteDomain=y
13# The full hostname 13# The full hostname
14hostname=<%= @hostname %> 14hostname=<%= @mail_host %>
15TLS_CA_FILE=/etc/ssl/certs/ca-certificates.crt
16UseTLS=Yes
17UseSTARTTLS=Yes
18AuthUser=<%= @ldap_cn %>
19AuthPass=<%= @ldap_password %>
diff --git a/python/get_initial_configuration_hetzner_server.py b/python/get_initial_configuration_hetzner_server.py
new file mode 100644
index 0000000..71583ff
--- /dev/null
+++ b/python/get_initial_configuration_hetzner_server.py
@@ -0,0 +1,21 @@
1import sys
2import json
3import hetzner_helper
4
5instance = sys.argv[-1]
6instance = hetzner_helper.get("servers/{}".format(instance))[1]["server"]
7
8infos = {}
9infos["ips"] = {
10 "v4": {
11 "ipAddress": instance["public_net"]["ipv4"]["ip"],
12 "gateway": "172.31.1.1",
13 },
14 "v6": {
15 "ipAddress": instance["public_net"]["ipv6"]["ip"].split("/")[0],
16 "gateway": "fe80::1",
17 "mask": instance["public_net"]["ipv6"]["ip"].split("/")[1],
18 }
19 }
20
21print(json.dumps(infos))
diff --git a/python/hetzner_helper.py b/python/hetzner_helper.py
new file mode 100644
index 0000000..496e14d
--- /dev/null
+++ b/python/hetzner_helper.py
@@ -0,0 +1,59 @@
1import json
2import requests
3import os
4
5from configparser import RawConfigParser, NoSectionError, NoOptionError
6
7class AuthenticationException(Exception):
8 pass
9
10class RateLimitExceeded(Exception):
11 pass
12
13class InternalServer(Exception):
14 pass
15
16class HetznerConfig:
17 def __init__(self):
18 config = RawConfigParser()
19 config.read([os.path.expanduser('~/.hetzner.conf')])
20
21 self.api_key = config.get("default", "api_key")
22
23config = HetznerConfig()
24
25def call(endpoint, url_params=None, body=None, method="GET"):
26 api = "https://api.hetzner.cloud/v1/{}".format(endpoint)
27 headers = {"Authorization": "Bearer {}".format(config.api_key)}
28 data = json.dumps(body) if body is not None else None
29
30 if method == "GET":
31 request = requests.get(api, headers=headers, params=url_params)
32 elif method == "POST" or (method == "GET" and body is not None):
33 request = requests.post(api, data=data, headers=headers, params=url_params)
34 elif method == "DELETE":
35 request = requests.delete(api, headers=headers)
36 elif method == "PUT":
37 request = requests.put(api, headers=headers, data=data)
38
39 if request.status_code == 401 or request.status_code == 403:
40 raise AuthenticationException()
41
42 if request.status_code == 429:
43 raise RateLimitExceeded()
44
45 if request.status_code == 500:
46 raise InternalServer(request.text)
47
48 if not request.text:
49 return request.status_code, ""
50
51 js = request.json()
52
53 return request.status_code, js
54
55def get(*args, **kwargs):
56 return call(*args, method="GET", **kwargs)
57
58def post(*args, **kwargs):
59 return call(*args, method="POST", **kwargs)
diff --git a/python/list_servers.py b/python/list_servers.py
index e7bd2af..6d22a56 100644
--- a/python/list_servers.py
+++ b/python/list_servers.py
@@ -21,3 +21,9 @@ print("OVH VPS SSD servers:")
21for vps in vps_list: 21for vps in vps_list:
22 print("\t{}".format(vps)) 22 print("\t{}".format(vps))
23 23
24import hetzner_helper
25
26print("Hetzner VPS servers:")
27return_code, json = hetzner_helper.call("servers")
28for server in json["servers"]:
29 print("\t{}: {}".format(server["name"], server["id"]))
diff --git a/python/reboot_hetzner_server.py b/python/reboot_hetzner_server.py
new file mode 100644
index 0000000..7452afe
--- /dev/null
+++ b/python/reboot_hetzner_server.py
@@ -0,0 +1,18 @@
1import sys
2import hetzner_helper
3
4instance = sys.argv[-1]
5actions = []
6if "--rescue" in sys.argv:
7 actions.append("enable_rescue")
8elif "--local" in sys.argv:
9 actions.append("disable_rescue")
10
11if "--hard" in sys.argv:
12 actions.append("reset")
13else:
14 actions.append("reboot")
15
16for action in actions:
17 result = hetzner_helper.post("servers/{}/actions/{}".format(instance, action))
18 print(result)
diff --git a/scripts/hetzner_server/arch_chroot_script.sh b/scripts/hetzner_server/arch_chroot_script.sh
new file mode 100755
index 0000000..afc78e2
--- /dev/null
+++ b/scripts/hetzner_server/arch_chroot_script.sh
@@ -0,0 +1,18 @@
1#!/bin/bash
2
3pacman-key --init
4pacman-key --populate archlinux
5
6UUID=$(cat /device_uuid)
7PART="/dev/disk/by-uuid/$UUID"
8DEVICE=$(realpath "$PART")
9
10mkfs.ext4 -F -U "$UUID" "$DEVICE"
11mount "$DEVICE" /mnt
12
13pacstrap -G /mnt base git puppet
14
15echo "$PART / auto defaults 0 1" > /mnt/etc/fstab
16
17umount /mnt
18
diff --git a/scripts/hetzner_server/arch_host_puppet_configuration_script.sh b/scripts/hetzner_server/arch_host_puppet_configuration_script.sh
new file mode 100755
index 0000000..3ca2b51
--- /dev/null
+++ b/scripts/hetzner_server/arch_host_puppet_configuration_script.sh
@@ -0,0 +1,13 @@
1#!/bin/bash
2
3git_branch="$1"
4environment="$2"
5
6DEVICE="/dev/sda1"
7MOUNTPOINT="/mnt"
8
9cp /tmp/arch_puppet_configuration_script.sh "$MOUNTPOINT/root/"
10
11/tmp/root.x86_64/bin/arch-chroot "$MOUNTPOINT" /root/arch_puppet_configuration_script.sh "$git_branch" "$environment"
12
13umount "$MOUNTPOINT"
diff --git a/scripts/hetzner_server/arch_host_script.sh b/scripts/hetzner_server/arch_host_script.sh
new file mode 100755
index 0000000..23fbc32
--- /dev/null
+++ b/scripts/hetzner_server/arch_host_script.sh
@@ -0,0 +1,49 @@
1#!/bin/bash
2
3set -e
4
5git_branch="$1"
6environment="$2"
7
8# Randomizer
9haveged &
10# /Randomizer
11
12# Prepare an arch chroot
13cd /tmp
14
15LATEST=$(curl -L https://mirrors.kernel.org/archlinux/iso/latest/sha1sums.txt | grep "bootstrap" | head -n1)
16SHA1=$(echo "$LATEST" | cut -d' ' -f1)
17NAME=$(echo "$LATEST" | cut -d' ' -f3)
18
19curl -L -O "https://mirrors.kernel.org/archlinux/iso/latest/$NAME"
20
21tar -xzf "$NAME"
22
23echo 'Server = http://archlinux.mirrors.ovh.net/archlinux/$repo/os/$arch' > /tmp/root.x86_64/etc/pacman.d/mirrorlist
24# /Prepare an arch chroot
25
26# Prepare device information (not available in chroot)
27DEVICE="/dev/sda1"
28MOUNTPOINT="/mnt"
29
30UUID=$(lsblk -rno UUID "$DEVICE")
31
32echo "$UUID" > /tmp/root.x86_64/device_uuid
33# /Prepare device information
34
35# Install very basic system via chroot (base git puppet)
36cp /tmp/arch_chroot_script.sh /tmp/root.x86_64/
37
38/tmp/root.x86_64/bin/arch-chroot /tmp/root.x86_64/ /arch_chroot_script.sh
39# /Install very basic system via chroot
40
41# Mount and install rest of system (via puppet)
42mount "$DEVICE" "$MOUNTPOINT"
43
44cp /tmp/arch_install_script.sh "$MOUNTPOINT/root/"
45cp /tmp/puppet_variables.json "$MOUNTPOINT/root/"
46
47/tmp/root.x86_64/bin/arch-chroot "$MOUNTPOINT" /root/arch_install_script.sh "$git_branch" "$environment"
48# /Mount and install rest of system
49