Merge ~dmzoneill/+git/vpn-host:dev/crontabs into ~dmzoneill/+git/vpn-host:master
- Git
- lp:~dmzoneill/+git/vpn-host
- dev/crontabs
- Merge into master
Proposed by
David O Neill
Status: | Needs review |
---|---|
Proposed branch: | ~dmzoneill/+git/vpn-host:dev/crontabs |
Merge into: | ~dmzoneill/+git/vpn-host:master |
Diff against target: |
306 lines (+156/-2) (has conflicts) 5 files modified
Makefile (+33/-1) config.yaml (+11/-0) requirements.txt (+5/-0) src/charm.py (+72/-0) tox.ini (+35/-1) Conflict in Makefile Conflict in config.yaml Conflict in src/charm.py Conflict in tox.ini |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David O Neill | Pending | ||
Review via email: mp+397662@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Unmerged commits
- d18de48... by David O Neill
-
Implement the feature to create crontab in /etc/cron.d/xxxx that runs iptables-dave > /x/y/z/$(date)
on given interval. - 02ba69a... by David O Neill
-
Just some basic code for relation test
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/Makefile b/Makefile | |||
2 | index a3bbf95..6ee8f98 100644 | |||
3 | --- a/Makefile | |||
4 | +++ b/Makefile | |||
5 | @@ -26,7 +26,11 @@ help: | |||
6 | 26 | 26 | ||
7 | 27 | clean: | 27 | clean: |
8 | 28 | @echo "Cleaning files" | 28 | @echo "Cleaning files" |
9 | 29 | <<<<<<< Makefile | ||
10 | 29 | @git clean -ffXd -e '!.idea' | 30 | @git clean -ffXd -e '!.idea' |
11 | 31 | ======= | ||
12 | 32 | @git clean -ffXd -e '!.idea' -e '!lib/vpncommon' | ||
13 | 33 | >>>>>>> Makefile | ||
14 | 30 | @echo "Cleaning existing build" | 34 | @echo "Cleaning existing build" |
15 | 31 | @rm -rf ${CHARM_BUILD_DIR}/${CHARM_NAME} | 35 | @rm -rf ${CHARM_BUILD_DIR}/${CHARM_NAME} |
16 | 32 | 36 | ||
17 | @@ -43,6 +47,7 @@ build: | |||
18 | 43 | @-git rev-parse --abbrev-ref HEAD > ./repo-info | 47 | @-git rev-parse --abbrev-ref HEAD > ./repo-info |
19 | 44 | @-git describe --always > ./version | 48 | @-git describe --always > ./version |
20 | 45 | @mkdir -p ${CHARM_BUILD_DIR}/${CHARM_NAME} | 49 | @mkdir -p ${CHARM_BUILD_DIR}/${CHARM_NAME} |
21 | 50 | <<<<<<< Makefile | ||
22 | 46 | @cp -a ./* ${CHARM_BUILD_DIR}/${CHARM_NAME} | 51 | @cp -a ./* ${CHARM_BUILD_DIR}/${CHARM_NAME} |
23 | 47 | @echo "Installing/updating env if requirements.txt exists" | 52 | @echo "Installing/updating env if requirements.txt exists" |
24 | 48 | @mkdir -p ${CHARM_BUILD_DIR}/${CHARM_NAME}/env/ | 53 | @mkdir -p ${CHARM_BUILD_DIR}/${CHARM_NAME}/env/ |
25 | @@ -51,6 +56,19 @@ build: | |||
26 | 51 | release: clean build | 56 | release: clean build |
27 | 52 | @echo "Charm is built at ${CHARM_BUILD_DIR}/${CHARM_NAME}" | 57 | @echo "Charm is built at ${CHARM_BUILD_DIR}/${CHARM_NAME}" |
28 | 53 | 58 | ||
29 | 59 | ======= | ||
30 | 60 | @tox -e build | ||
31 | 61 | @mv ${CHARM_NAME}.charm ${CHARM_BUILD_DIR}/. | ||
32 | 62 | |||
33 | 63 | release: clean build unpack | ||
34 | 64 | @echo "Charm is built at ${CHARM_BUILD_DIR}/${CHARM_NAME}" | ||
35 | 65 | |||
36 | 66 | unpack: build | ||
37 | 67 | @mkdir -p ${CHARM_BUILD_DIR}/${CHARM_NAME} | ||
38 | 68 | @echo "Unpacking built .charm into ${CHARM_BUILD_DIR}/${CHARM_NAME}" | ||
39 | 69 | @cd ${CHARM_BUILD_DIR}/${CHARM_NAME} && unzip -q ${CHARM_BUILD_DIR}/${CHARM_NAME}.charm | ||
40 | 70 | |||
41 | 71 | >>>>>>> Makefile | ||
42 | 54 | lint: | 72 | lint: |
43 | 55 | @echo "Running lint checks" | 73 | @echo "Running lint checks" |
44 | 56 | @tox -e lint | 74 | @tox -e lint |
45 | @@ -59,6 +77,7 @@ black: | |||
46 | 59 | @echo "Reformat files with black" | 77 | @echo "Reformat files with black" |
47 | 60 | @tox -e black | 78 | @tox -e black |
48 | 61 | 79 | ||
49 | 80 | <<<<<<< Makefile | ||
50 | 62 | proof: | 81 | proof: |
51 | 63 | @echo "Running charm proof" | 82 | @echo "Running charm proof" |
52 | 64 | @-charm proof | 83 | @-charm proof |
53 | @@ -66,6 +85,15 @@ proof: | |||
54 | 66 | unittests: | 85 | unittests: |
55 | 67 | @echo "Running unit tests" | 86 | @echo "Running unit tests" |
56 | 68 | @-tox -e unit | 87 | @-tox -e unit |
57 | 88 | ======= | ||
58 | 89 | proof: unpack | ||
59 | 90 | @echo "Running charm proof" | ||
60 | 91 | @cd ${CHARM_BUILD_DIR}/${CHARM_NAME} && charm proof | ||
61 | 92 | |||
62 | 93 | unittests: | ||
63 | 94 | @echo "Running unit tests" | ||
64 | 95 | @tox -e unit | ||
65 | 96 | >>>>>>> Makefile | ||
66 | 69 | 97 | ||
67 | 70 | functional: build | 98 | functional: build |
68 | 71 | @echo "Executing functional tests in ${CHARM_BUILD_DIR}" | 99 | @echo "Executing functional tests in ${CHARM_BUILD_DIR}" |
69 | @@ -75,4 +103,8 @@ test: lint proof unittests functional | |||
70 | 75 | @echo "Tests completed for charm ${CHARM_NAME}." | 103 | @echo "Tests completed for charm ${CHARM_NAME}." |
71 | 76 | 104 | ||
72 | 77 | # The targets below don't depend on a file | 105 | # The targets below don't depend on a file |
73 | 78 | .PHONY: help submodules submodules-update clean build release lint black proof unittests functional test | ||
74 | 79 | \ No newline at end of file | 106 | \ No newline at end of file |
75 | 107 | <<<<<<< Makefile | ||
76 | 108 | .PHONY: help submodules submodules-update clean build release lint black proof unittests functional test | ||
77 | 109 | ======= | ||
78 | 110 | .PHONY: help submodules submodules-update clean build release lint black proof unittests functional test | ||
79 | 111 | >>>>>>> Makefile | ||
80 | diff --git a/config.yaml b/config.yaml | |||
81 | index 25f8225..695b8d8 100644 | |||
82 | --- a/config.yaml | |||
83 | +++ b/config.yaml | |||
84 | @@ -1,4 +1,5 @@ | |||
85 | 1 | options: | 1 | options: |
86 | 2 | <<<<<<< config.yaml | ||
87 | 2 | example_string_config: | 3 | example_string_config: |
88 | 3 | type: string | 4 | type: string |
89 | 4 | description: 'An example string configuration item' | 5 | description: 'An example string configuration item' |
90 | @@ -11,3 +12,13 @@ options: | |||
91 | 11 | type: boolean | 12 | type: boolean |
92 | 12 | description: 'An example boolean configuration item' | 13 | description: 'An example boolean configuration item' |
93 | 13 | default: false | 14 | default: false |
94 | 15 | ======= | ||
95 | 16 | cron_iptables_save_interval: | ||
96 | 17 | type: string | ||
97 | 18 | description: '01 01 * * *\nhttps://help.ubuntu.com/community/CronHowto' | ||
98 | 19 | default: '01 01 * * *' | ||
99 | 20 | cron_iptables_save_retention: | ||
100 | 21 | type: int | ||
101 | 22 | description: 'Number of days to retain backups' | ||
102 | 23 | default: 21 | ||
103 | 24 | >>>>>>> config.yaml | ||
104 | diff --git a/requirements.txt b/requirements.txt | |||
105 | 14 | new file mode 100644 | 25 | new file mode 100644 |
106 | index 0000000..1655283 | |||
107 | --- /dev/null | |||
108 | +++ b/requirements.txt | |||
109 | @@ -0,0 +1,5 @@ | |||
110 | 1 | charmhelpers | ||
111 | 2 | jinja2 | ||
112 | 3 | ops | ||
113 | 4 | distro | ||
114 | 5 | numpy | ||
115 | 0 | \ No newline at end of file | 6 | \ No newline at end of file |
116 | diff --git a/src/charm.py b/src/charm.py | |||
117 | index 80c2c12..6dfa4a7 100755 | |||
118 | --- a/src/charm.py | |||
119 | +++ b/src/charm.py | |||
120 | @@ -5,6 +5,7 @@ | |||
121 | 5 | 5 | ||
122 | 6 | """Operator Charm main library.""" | 6 | """Operator Charm main library.""" |
123 | 7 | # Load modules from lib directory | 7 | # Load modules from lib directory |
124 | 8 | <<<<<<< src/charm.py | ||
125 | 8 | import hashlib | 9 | import hashlib |
126 | 9 | import json | 10 | import json |
127 | 10 | import logging | 11 | import logging |
128 | @@ -20,12 +21,29 @@ sys.path.append("lib") | |||
129 | 20 | import iptc # noqa:E402 | 21 | import iptc # noqa:E402 |
130 | 21 | 22 | ||
131 | 22 | import setuppath # noqa:F401 | 23 | import setuppath # noqa:F401 |
132 | 24 | ======= | ||
133 | 25 | import logging | ||
134 | 26 | import netifaces | ||
135 | 27 | import os | ||
136 | 28 | |||
137 | 29 | >>>>>>> src/charm.py | ||
138 | 23 | from ops.charm import CharmBase | 30 | from ops.charm import CharmBase |
139 | 24 | from ops.framework import StoredState | 31 | from ops.framework import StoredState |
140 | 25 | from ops.main import main | 32 | from ops.main import main |
141 | 26 | from ops.model import ActiveStatus, MaintenanceStatus | 33 | from ops.model import ActiveStatus, MaintenanceStatus |
142 | 27 | from ops.framework import Object | 34 | from ops.framework import Object |
143 | 28 | 35 | ||
144 | 36 | <<<<<<< src/charm.py | ||
145 | 37 | ======= | ||
146 | 38 | from charmhelpers.fetch import apt_install | ||
147 | 39 | from charmhelpers.fetch.python.packages import pip_install | ||
148 | 40 | |||
149 | 41 | try: | ||
150 | 42 | import iptc # noqa:E402 | ||
151 | 43 | except (ImportError, AttributeError): | ||
152 | 44 | apt_install(["python3-distutils"]) | ||
153 | 45 | pip_install(["python-iptables"]) | ||
154 | 46 | >>>>>>> src/charm.py | ||
155 | 29 | 47 | ||
156 | 30 | class VPNRequires(Object): | 48 | class VPNRequires(Object): |
157 | 31 | def __init__(self, charm, relation_name): | 49 | def __init__(self, charm, relation_name): |
158 | @@ -101,8 +119,46 @@ class VpnHostCharm(CharmBase): | |||
159 | 101 | logging.info("Stopping for configuration, event handle: {}".format(event.handle)) | 119 | logging.info("Stopping for configuration, event handle: {}".format(event.handle)) |
160 | 102 | # Configure the software | 120 | # Configure the software |
161 | 103 | logging.info("Configuring") | 121 | logging.info("Configuring") |
162 | 122 | <<<<<<< src/charm.py | ||
163 | 123 | self.state.configured = True | ||
164 | 124 | |||
165 | 125 | ======= | ||
166 | 126 | self.configure_crontabs() | ||
167 | 104 | self.state.configured = True | 127 | self.state.configured = True |
168 | 105 | 128 | ||
169 | 129 | def configure_crontabs(self): | ||
170 | 130 | save_folder = "/etc/vpnhost-backup/iptables" | ||
171 | 131 | |||
172 | 132 | if os.path.isdir(save_folder) is False: | ||
173 | 133 | logging.info(save_folder + " does not exist, attempting to create") | ||
174 | 134 | try: | ||
175 | 135 | os.makedirs(save_folder, exist_ok=True) | ||
176 | 136 | except OSError: | ||
177 | 137 | logging.info("Creation of the directory %s failed" % save_folder) | ||
178 | 138 | else: | ||
179 | 139 | logging.info("Successfully created the directory %s " % save_folder) | ||
180 | 140 | |||
181 | 141 | save_cronfile = open("/etc/cron.d/vpn-host-iptables-save", "w") | ||
182 | 142 | cron_iptables_save_interval = self.model.config["cron_iptables_save_interval"] | ||
183 | 143 | cronline = cron_iptables_save_interval | ||
184 | 144 | cronline += " root /sbin/iptables-save > " | ||
185 | 145 | cronline += save_folder | ||
186 | 146 | cronline += r"/`date +\%Y\%m\%d\%H\%M\%S`-cron.save" | ||
187 | 147 | save_cronfile.write(cronline) | ||
188 | 148 | save_cronfile.close() | ||
189 | 149 | |||
190 | 150 | cleanup_cronfile = open("/etc/cron.d/vpn-host-iptables-cleanup", "w") | ||
191 | 151 | cron_iptables_save_retention = self.model.config["cron_iptables_save_retention"] | ||
192 | 152 | cronline = "0 0 * * *" | ||
193 | 153 | cronline += " root /usr/bin/find " | ||
194 | 154 | cronline += save_folder | ||
195 | 155 | cronline += r" -type f -name \*.save -mtime +" | ||
196 | 156 | cronline += str(cron_iptables_save_retention) | ||
197 | 157 | cronline += r" -exec rm {} \;" | ||
198 | 158 | cleanup_cronfile.write(cronline) | ||
199 | 159 | cleanup_cronfile.close() | ||
200 | 160 | |||
201 | 161 | >>>>>>> src/charm.py | ||
202 | 106 | def _on_relation_changed(self, event): | 162 | def _on_relation_changed(self, event): |
203 | 107 | ip = event.relation.data[event.unit].get('ip', None) | 163 | ip = event.relation.data[event.unit].get('ip', None) |
204 | 108 | ports = event.relation.data[event.unit].get('ports', None) | 164 | ports = event.relation.data[event.unit].get('ports', None) |
205 | @@ -161,12 +217,28 @@ class VpnHostCharm(CharmBase): | |||
206 | 161 | start_port += 1 | 217 | start_port += 1 |
207 | 162 | 218 | ||
208 | 163 | # find rules to delete | 219 | # find rules to delete |
209 | 220 | <<<<<<< src/charm.py | ||
210 | 164 | delete_these = np.setdiff1d(current_rules, new_rules) | 221 | delete_these = np.setdiff1d(current_rules, new_rules) |
211 | 222 | ======= | ||
212 | 223 | delete_these = set(current_rules) | ||
213 | 224 | for item in new_rules: | ||
214 | 225 | if item in delete_these: | ||
215 | 226 | delete_these.remove(item) | ||
216 | 227 | # remaining is due for deletion | ||
217 | 228 | >>>>>>> src/charm.py | ||
218 | 165 | logging.info("delete these:") | 229 | logging.info("delete these:") |
219 | 166 | logging.info(delete_these) | 230 | logging.info(delete_these) |
220 | 167 | 231 | ||
221 | 168 | # find rules to add | 232 | # find rules to add |
222 | 233 | <<<<<<< src/charm.py | ||
223 | 169 | add_these = np.setdiff1d(new_rules, current_rules) | 234 | add_these = np.setdiff1d(new_rules, current_rules) |
224 | 235 | ======= | ||
225 | 236 | add_these = set(new_rules) | ||
226 | 237 | for item in current_rules: | ||
227 | 238 | if item in add_these: | ||
228 | 239 | add_these.remove(item) | ||
229 | 240 | # remaning new_rules to be added | ||
230 | 241 | >>>>>>> src/charm.py | ||
231 | 170 | logging.info("add these:") | 242 | logging.info("add these:") |
232 | 171 | logging.info(add_these) | 243 | logging.info(add_these) |
233 | 172 | 244 | ||
234 | diff --git a/tox.ini b/tox.ini | |||
235 | index 49c6e23..13a79b4 100644 | |||
236 | --- a/tox.ini | |||
237 | +++ b/tox.ini | |||
238 | @@ -22,6 +22,13 @@ passenv = | |||
239 | 22 | SNAP_HTTP_PROXY | 22 | SNAP_HTTP_PROXY |
240 | 23 | SNAP_HTTPS_PROXY | 23 | SNAP_HTTPS_PROXY |
241 | 24 | 24 | ||
242 | 25 | <<<<<<< tox.ini | ||
243 | 26 | ======= | ||
244 | 27 | [testenv:build] | ||
245 | 28 | deps = charmcraft | ||
246 | 29 | commands = charmcraft build | ||
247 | 30 | |||
248 | 31 | >>>>>>> tox.ini | ||
249 | 25 | [testenv:lint] | 32 | [testenv:lint] |
250 | 26 | commands = | 33 | commands = |
251 | 27 | flake8 | 34 | flake8 |
252 | @@ -41,6 +48,10 @@ exclude = | |||
253 | 41 | .tox, | 48 | .tox, |
254 | 42 | charmhelpers, | 49 | charmhelpers, |
255 | 43 | mod, | 50 | mod, |
256 | 51 | <<<<<<< tox.ini | ||
257 | 52 | ======= | ||
258 | 53 | build, | ||
259 | 54 | >>>>>>> tox.ini | ||
260 | 44 | .build | 55 | .build |
261 | 45 | 56 | ||
262 | 46 | max-line-length = 88 | 57 | max-line-length = 88 |
263 | @@ -48,18 +59,41 @@ max-complexity = 10 | |||
264 | 48 | 59 | ||
265 | 49 | [testenv:black] | 60 | [testenv:black] |
266 | 50 | commands = | 61 | commands = |
267 | 62 | <<<<<<< tox.ini | ||
268 | 51 | black --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod)/" . | 63 | black --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod)/" . |
269 | 64 | ======= | ||
270 | 65 | black --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod|vpncommon)/" . | ||
271 | 66 | >>>>>>> tox.ini | ||
272 | 52 | deps = | 67 | deps = |
273 | 53 | black | 68 | black |
274 | 54 | 69 | ||
275 | 55 | [testenv:unit] | 70 | [testenv:unit] |
276 | 56 | commands = | 71 | commands = |
277 | 57 | coverage run -m unittest discover -s {toxinidir}/tests/unit -v | 72 | coverage run -m unittest discover -s {toxinidir}/tests/unit -v |
278 | 73 | <<<<<<< tox.ini | ||
279 | 58 | coverage report --omit tests/*,mod/*,.tox/* | 74 | coverage report --omit tests/*,mod/*,.tox/* |
280 | 59 | coverage html --omit tests/*,mod/*,.tox/* | 75 | coverage html --omit tests/*,mod/*,.tox/* |
281 | 60 | deps = -r{toxinidir}/tests/unit/requirements.txt | 76 | deps = -r{toxinidir}/tests/unit/requirements.txt |
282 | 77 | ======= | ||
283 | 78 | coverage report --omit tests/*,mod/*,.tox/*,lib/vpncommon/* | ||
284 | 79 | coverage html --omit tests/*,mod/*,.tox/*,lib/vpncommon/* | ||
285 | 80 | deps = -r{toxinidir}/tests/unit/requirements.txt | ||
286 | 81 | -r{toxinidir}/requirements.txt | ||
287 | 82 | >>>>>>> tox.ini | ||
288 | 61 | 83 | ||
289 | 62 | [testenv:func] | 84 | [testenv:func] |
290 | 63 | changedir = {toxinidir}/tests/functional | 85 | changedir = {toxinidir}/tests/functional |
291 | 64 | commands = functest-run-suite {posargs} | 86 | commands = functest-run-suite {posargs} |
292 | 65 | deps = -r{toxinidir}/tests/functional/requirements.txt | ||
293 | 66 | \ No newline at end of file | 87 | \ No newline at end of file |
294 | 88 | <<<<<<< tox.ini | ||
295 | 89 | deps = -r{toxinidir}/tests/functional/requirements.txt | ||
296 | 90 | ======= | ||
297 | 91 | deps = -r{toxinidir}/tests/functional/requirements.txt | ||
298 | 92 | |||
299 | 93 | [testenv:func-noop] | ||
300 | 94 | basepython = python3 | ||
301 | 95 | commands = | ||
302 | 96 | functest-run-suite --help | ||
303 | 97 | deps = -r{toxinidir}/tests/functional/requirements.txt | ||
304 | 98 | -r{toxinidir}/requirements.txt | ||
305 | 99 | -r{toxinidir}/tests/unit/requirements.txt | ||
306 | 100 | >>>>>>> tox.ini |