Browse Source

added logger

tags/v2.0.0
Robin Thoni 8 years ago
parent
commit
61e6edde2f
2 changed files with 145 additions and 23 deletions
  1. 18
    0
      fake-letsencrypt.sh
  2. 127
    23
      sitegen.py

+ 18
- 0
fake-letsencrypt.sh View File

1
+#! /usr/bin/env sh
2
+
3
+dir="$(dirname $(readlink -f "${0}"))"
4
+host="${1}"
5
+
6
+if [ "${host}" = "error.com" ]
7
+then
8
+    echo "Failed to get certificate" >&2
9
+    exit 1
10
+fi
11
+
12
+leDir="${dir}/tests/etc/letsencypt/live/${host}"
13
+
14
+sleep 1
15
+
16
+mkdir -p "${leDir}"
17
+touch "${leDir}/cert.pem" "${leDir}/privkey.pem" "${leDir}/chain.pem"
18
+echo "Generation successful"

+ 127
- 23
sitegen.py View File

3
 import json
3
 import json
4
 import argparse
4
 import argparse
5
 import os
5
 import os
6
+import subprocess
6
 
7
 
7
 from os import path
8
 from os import path
8
 
9
 
25
     templatesDir = ""
26
     templatesDir = ""
26
     certRenewTime = ""
27
     certRenewTime = ""
27
     letsencryptCommand = ""
28
     letsencryptCommand = ""
29
+    letsencryptDir = ""
28
     certDir = ""
30
     certDir = ""
29
 
31
 
30
     def __init__(self, config):
32
     def __init__(self, config):
36
         self.templatesDir = path.join(self.confDir, "templates")
38
         self.templatesDir = path.join(self.confDir, "templates")
37
         self.certRenewTime = config["certRenewTime"]
39
         self.certRenewTime = config["certRenewTime"]
38
         self.letsencryptCommand = config["letsencryptCommand"]
40
         self.letsencryptCommand = config["letsencryptCommand"]
41
+        self.letsencryptDir = config["letsencryptDir"]
39
         self.certDir = config["certDir"]
42
         self.certDir = config["certDir"]
40
 
43
 
44
+    def make_dirs(self):
45
+        if not path.isdir(self.certDir):
46
+            os.makedirs(self.certDir)
47
+
41
     def get_hook_dir(self, hook_type, is_enabled):
48
     def get_hook_dir(self, hook_type, is_enabled):
42
         return path.join(self.hooksEnabledDir if is_enabled else self.hooksAvailableDir, hook_type)
49
         return path.join(self.hooksEnabledDir if is_enabled else self.hooksAvailableDir, hook_type)
43
 
50
 
56
     def is_hook_enabled(self, hook_type, hook_name):
63
     def is_hook_enabled(self, hook_type, hook_name):
57
         return self.is_hook_present(hook_type, hook_name, True)
64
         return self.is_hook_present(hook_type, hook_name, True)
58
 
65
 
59
-    def cert_request(self, domain):
60
-        pass
61
-
62
-    def cert_check(self, domain):
63
-        pass
64
-
65
-    def cert_renew(self, domain):
66
-        pass
67
-
68
-    def site_create(self, domain):
66
+    def get_letsencrypt_dir(self, domain):
67
+        return path.join(self.letsencryptDir, domain)
68
+
69
+    def symlink_letsencrypt_file(self, domain, file, outfile):
70
+        letsencrypt_cert_file = path.abspath(self.get_letsencrypt_dir(domain))
71
+        my_cert_file = path.join(self.certDir, outfile)
72
+        if path.lexists(my_cert_file):
73
+            os.remove(my_cert_file)
74
+        os.symlink(path.join(letsencrypt_cert_file, file), my_cert_file)
75
+
76
+    def get_cert_files(self, domain):
77
+        return [path.abspath(path.join(self.certDir, domain + ".crt")),
78
+                path.abspath(path.join(self.certDir, domain + ".key")),
79
+                path.abspath(path.join(self.certDir, domain + "-chain.crt"))]
80
+
81
+    def execute(self, exe, args, get_output):
82
+        args.insert(0, exe)
83
+        proc = subprocess.Popen(args, stdout=(subprocess.PIPE if get_output else None))
84
+        out = proc.communicate()
85
+        return proc.returncode, out[0]
86
+
87
+    def execute_hooks(self, hook_type, args):
88
+        for hook_name in self.get_hook_files(hook_type, True):
89
+            self.execute(self.get_hook_file(hook_type, hook_name, True), args, False)
90
+
91
+    def is_cert_present(self, domain):
92
+        cert_files = self.get_cert_files(domain)
93
+        for cert_file in cert_files:
94
+            if not path.isfile(cert_file):
95
+                return False
96
+        return True
97
+
98
+    def get_cert_end_date(self, domain):
99
+        cert_files = self.get_cert_files(domain)
100
+        res, out = self.execute("openssl", ["x509", "-noout", "-in", cert_files[0], "-enddate"], True)
101
+        if res == 0:
102
+            return out.decode("UTF-8").split("=")[1][:-1]
103
+        return None
104
+
105
+    def is_cert_gonna_expire(self, domain, checkend):
106
+        cert_files = self.get_cert_files(domain)
107
+        res, out = self.execute("openssl", ["x509", "-noout", "-in", cert_files[0], "-checkend", str(checkend)], True)
108
+        return res == 1
109
+
110
+    def get_all_domains(self):
111
+        files = os.listdir(self.certDir)
112
+        files.sort()
113
+        domains = []
114
+        for file in files:
115
+            if file.endswith(".crt") and self.is_cert_present(file[:-4]):
116
+                domains.append(file[:-4])
117
+        return domains
118
+
119
+    def cert_request(self, domain, logger):
120
+        logger("Requesting: %s" % domain)
121
+
122
+        res, out = self.execute(self.letsencryptCommand, [domain], False)
123
+        if res != 0:
124
+            raise SiteGenException("Certificate request failed with code %i" % res, res)
125
+
126
+        self.symlink_letsencrypt_file(domain, "cert.pem", domain + ".crt")
127
+        self.symlink_letsencrypt_file(domain, "privkey.pem", domain + ".key")
128
+        self.symlink_letsencrypt_file(domain, "chain.pem", domain + "-chain.crt")
129
+
130
+        cert_files = self.get_cert_files(domain)
131
+        cert_files.insert(0, domain)
132
+        self.execute_hooks("cert", cert_files)
133
+
134
+    def certs_request(self, domains, logger):
135
+        for domain in domains:
136
+            self.cert_request(domain, logger)
137
+
138
+    def cert_check(self, domain, logger):
139
+        if not self.is_cert_present(domain):
140
+            raise SiteGenException("Certificate not present: %s" % domain, 1)
141
+        if self.is_cert_gonna_expire(domain, self.certRenewTime):
142
+            logger("%s: %s" % (domain, self.get_cert_end_date(domain)))
143
+            return True
144
+        return False
145
+
146
+    def certs_check(self, domains, logger):
147
+        for domain in domains:
148
+            self.cert_check(domain, logger)
149
+
150
+    def cert_renew(self, domain, logger):
151
+        if self.cert_check(domain, logger):
152
+            self.cert_request(domain, logger)
153
+
154
+    def certs_renew(self, domains, logger):
155
+        for domain in domains:
156
+            self.cert_renew(domain, logger)
157
+
158
+    def site_create(self, domain, logger):
69
         pass
159
         pass
70
 
160
 
71
-    def site_remove(self, domain):
161
+    def site_remove(self, domain, logger):
72
         pass
162
         pass
73
 
163
 
74
-    def hook_enable(self, hook_type, hook_name):
164
+    def hook_enable(self, hook_type, hook_name, logger):
75
         if not self.is_hook_present(hook_type, hook_name, False):
165
         if not self.is_hook_present(hook_type, hook_name, False):
76
             raise SiteGenException("Hook is not present", 1)
166
             raise SiteGenException("Hook is not present", 1)
77
         if self.is_hook_enabled(hook_type, hook_name):
167
         if self.is_hook_enabled(hook_type, hook_name):
78
             raise SiteGenException("Hook is already enabled", 0)
168
             raise SiteGenException("Hook is already enabled", 0)
169
+        logger("Enabling %s %s" % (hook_type, hook_name))
79
         hook_dir = self.get_hook_dir(hook_type, hook_name)
170
         hook_dir = self.get_hook_dir(hook_type, hook_name)
80
         if not path.isdir(hook_dir):
171
         if not path.isdir(hook_dir):
81
             os.makedirs(hook_dir)
172
             os.makedirs(hook_dir)
85
 
176
 
86
         os.symlink(hook_relative_file, hook_file_enabled)
177
         os.symlink(hook_relative_file, hook_file_enabled)
87
 
178
 
88
-    def hook_disable(self, hook_type, hook_name):
179
+    def hook_disable(self, hook_type, hook_name, logger):
89
         if not self.is_hook_present(hook_type, hook_name, False):
180
         if not self.is_hook_present(hook_type, hook_name, False):
90
             raise SiteGenException("Hook is not present", 1)
181
             raise SiteGenException("Hook is not present", 1)
91
         if not self.is_hook_enabled(hook_type, hook_name):
182
         if not self.is_hook_enabled(hook_type, hook_name):
92
             raise SiteGenException("Hook is not enabled", 0)
183
             raise SiteGenException("Hook is not enabled", 0)
184
+        logger("Disabling %s %s" % (hook_type, hook_name))
93
         os.remove(self.get_hook_file(hook_type, hook_name, True))
185
         os.remove(self.get_hook_file(hook_type, hook_name, True))
94
 
186
 
95
 
187
 
119
         config = json.load(f)
211
         config = json.load(f)
120
 
212
 
121
     site_gen = SiteGen(config)
213
     site_gen = SiteGen(config)
122
-    print(site_gen.get_hook_files("site", True))
214
+
215
+    site_gen.make_dirs()
216
+
217
+    logger = print
123
 
218
 
124
     try:
219
     try:
125
         if args.cert_request is not None:
220
         if args.cert_request is not None:
126
-            site_gen.cert_request(args.cert_request)
221
+            if args.cert_request == "":
222
+                site_gen.certs_request(site_gen.get_all_domains(), logger)
223
+            else:
224
+                site_gen.cert_request(args.cert_request, logger)
127
 
225
 
128
         elif args.cert_check is not None:
226
         elif args.cert_check is not None:
129
-            site_gen.cert_check(args.cert_check)
227
+            if args.cert_check == "":
228
+                site_gen.certs_check(site_gen.get_all_domains(), logger)
229
+            else:
230
+                site_gen.cert_check(args.cert_check, logger)
130
 
231
 
131
         elif args.cert_renew is not None:
232
         elif args.cert_renew is not None:
132
-            site_gen.cert_renew(args.cert_renew)
233
+            if args.cert_renew == "":
234
+                site_gen.certs_renew(site_gen.get_all_domains(), logger)
235
+            else:
236
+                site_gen.cert_renew(args.cert_renew, logger)
133
 
237
 
134
         elif args.site_create is not None:
238
         elif args.site_create is not None:
135
-            site_gen.site_create(args.site_create)
239
+            site_gen.site_create(args.site_create, logger)
136
 
240
 
137
         elif args.site_remove is not None:
241
         elif args.site_remove is not None:
138
-            site_gen.site_remove(args.site_remove)
242
+            site_gen.site_remove(args.site_remove, logger)
139
 
243
 
140
         elif args.site_hook_enable is not None:
244
         elif args.site_hook_enable is not None:
141
-            site_gen.hook_enable("site", args.site_hook_enable)
245
+            site_gen.hook_enable("site", args.site_hook_enable, logger)
142
 
246
 
143
         elif args.site_hook_disable is not None:
247
         elif args.site_hook_disable is not None:
144
-            site_gen.hook_disable("site", args.site_hook_disable)
248
+            site_gen.hook_disable("site", args.site_hook_disable, logger)
145
 
249
 
146
         elif args.hook_cert_enable is not None:
250
         elif args.hook_cert_enable is not None:
147
-            site_gen.hook_enable("cert", args.hook_cert_enable)
251
+            site_gen.hook_enable("cert", args.hook_cert_enable, logger)
148
 
252
 
149
         elif args.hook_cert_disable is not None:
253
         elif args.hook_cert_disable is not None:
150
-            site_gen.hook_disable("cert", args.hook_cert_disable)
254
+            site_gen.hook_disable("cert", args.hook_cert_disable, logger)
151
 
255
 
152
         else:
256
         else:
153
             parser.print_help()
257
             parser.print_help()

Loading…
Cancel
Save