]> git.ipfire.org Git - people/ms/network.git/blob - src/functions/functions.zone
Remove port hooks as subhooks for zones.
[people/ms/network.git] / src / functions / functions.zone
1 #!/bin/bash
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2010 Michael Tremer & Christian Schmidt #
6 # #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
11 # #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
16 # #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 # #
20 ###############################################################################
21
22 function zone_dir() {
23 local zone=${1}
24
25 echo "${NETWORK_ZONE_DIR}/zones/${zone}"
26 }
27
28 function zone_exists() {
29 local zone=${1}
30 assert isset zone
31
32 [ -d "$(zone_dir ${zone})" ]
33 }
34
35 function zone_match() {
36 local match
37
38 local i
39 for i in ${VALID_ZONES}; do
40 match="${match}|${i}[0-9]{1,5}"
41 done
42
43 echo "${match:1:${#match}}"
44 }
45
46 function zone_name_is_valid() {
47 local zone=${1}
48
49 # Don't accept empty strings.
50 [ -z "${zone}" ] && return ${EXIT_FALSE}
51
52 [[ ${zone} =~ $(zone_match) ]]
53 }
54
55 function zone_is_local() {
56 local zone=${1}
57
58 [[ "${zone:0:${#ZONE_LOCAL}}" = "${ZONE_LOCAL}" ]]
59 }
60
61 function zone_is_nonlocal() {
62 local zone=${1}
63
64 [[ "${zone:0:${#ZONE_NONLOCAL}}" = "${ZONE_NONLOCAL}" ]]
65 }
66
67 function zone_get_hook() {
68 local zone=${1}
69 assert isset zone
70
71 config_get_hook $(zone_dir ${zone})/settings
72 }
73
74 function zone_start() {
75 # This function will bring up the zone
76 # 'asynchronously' with help of systemd.
77
78 local zone=${1}
79 assert zone_exists ${zone}
80
81 service_start "network@${zone}.service"
82 }
83
84 function zone_stop() {
85 # This function will bring down the zone
86 # 'asynchronously' with help of systemd.
87
88 local zone=${1}
89 assert zone_exists ${zone}
90
91 service_stop "network@${zone}.service"
92 }
93
94 function zone_enable() {
95 # This function will enable the zone
96 # with help of systemd.
97
98 local zone="${1}"
99 assert zone_exists "${zone}"
100
101 # Enable service for the zone
102 service_enable "network@${zone}.service"
103 local ret=$?
104
105 if [ ${ret} -eq ${EXIT_OK} ]; then
106 log INFO "Auto-start enabled for zone ${zone}"
107 return ${EXIT_OK}
108 fi
109
110 log ERROR "Could not enable zone ${zone}: ${ret}"
111 return ${ret}
112 }
113
114 function zone_disable() {
115 # This function will disable the zone
116 # with help of systemd.
117
118 local zone="${1}"
119 assert zone_exists "${zone}"
120
121 # Disable service for the zone
122 service_disable "network@${zone}.service"
123 local ret=$?
124
125 if [ ${ret} -eq ${EXIT_OK} ]; then
126 log INFO "Auto-start disabled for zone ${zone}"
127 return ${EXIT_OK}
128 fi
129
130 log ERROR "Could not disable zone ${zone}: ${ret}"
131 return ${ret}
132 }
133
134 function zone_is_enabled() {
135 local zone="${1}"
136 assert isset zone
137
138 # Ask systemd if the zone is enabled.
139 if service_is_enabled "network@${zone}.service"; then
140 return ${EXIT_TRUE}
141 fi
142
143 return ${EXIT_FALSE}
144 }
145
146 function zone_create() {
147 local zone=${1}
148 local hook=${2}
149 shift 2
150
151 if ! zone_name_is_valid ${zone}; then
152 error "Zone name '${zone}' is not valid."
153 return ${EXIT_ERROR}
154 fi
155
156 if zone_exists ${zone}; then
157 error "Zone '${zone}' does already exist."
158 return ${EXIT_ERROR}
159 fi
160
161 if ! hook_zone_exists ${hook}; then
162 error "Hook '${hook}' does not exist."
163 return ${EXIT_ERROR}
164 fi
165
166 mkdir -p $(zone_dir ${zone})
167
168 # Create directories for configs and ports
169 mkdir -p $(zone_dir ${zone})/{configs,ports}
170
171 hook_zone_exec ${hook} create ${zone} $@
172 local ret=$?
173
174 # Maybe the zone create hook did not exit correctly.
175 # If this is the case we remove the created zone immediately.
176 if [ "${ret}" = "${EXIT_ERROR}" ]; then
177 zone_remove_now ${zone}
178 return ${EXIT_ERROR}
179 fi
180
181 # Automatically enable zone.
182 zone_enable "${zone}"
183 }
184
185 function zone_edit() {
186 local zone=${1}
187 shift
188
189 if ! zone_exists ${zone}; then
190 error "Zone '${zone}' does not exist."
191 return ${EXIT_ERROR}
192 fi
193
194 # Check if the zone is tagged for removal.
195 if zone_has_remove_tag ${zone}; then
196 error "You cannot edit a zone that is tagged for removal."
197 return ${EXIT_ERROR}
198 fi
199
200 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
201
202 if [ -z "${hook}" ]; then
203 error "Config file did not provide any hook."
204 return ${EXIT_ERROR}
205 fi
206
207 if ! hook_zone_exists ${hook}; then
208 error "Hook '${hook}' does not exist."
209 return ${EXIT_ERROR}
210 fi
211
212 hook_zone_exec ${hook} edit ${zone} $@
213 }
214
215
216 function zone_remove() {
217 local zone=${1}
218 assert zone_exists ${zone}
219
220 # Make the zone for removal.
221 touch $(zone_dir ${zone})/.remove
222
223 log INFO "Zone '${zone}' has been tagged for removal."
224 }
225
226 function zone_has_remove_tag() {
227 local zone=${1}
228 assert zone_exists ${zone}
229
230 [ -e "$(zone_dir ${zone})/.remove" ]
231 }
232
233 # This function will remove the given zone
234 # RIGHT NOW. Use zone_remove to remove it
235 # at the next status change.
236 function zone_remove_now() {
237 local zone=${1}
238 assert zone_exists ${zone}
239
240 log INFO "Removing zone '${zone}' right now."
241
242 # Force the zone down.
243 zone_is_up ${zone} && zone_set_down ${zone}
244
245 # Disable zone.
246 zone_disable "${zone}"
247
248 rm -rf $(zone_dir ${zone})
249 }
250
251 function zone_up() {
252 local zone=${1}
253 shift
254
255 if ! zone_exists ${zone}; then
256 error "Zone '${zone}' does not exist."
257 return ${EXIT_ERROR}
258 fi
259
260 # Check if a zone has got the remove tag.
261 if zone_has_remove_tag ${zone}; then
262 error "Cannot bring up any zone which is to be removed."
263 return ${EXIT_ERROR}
264 fi
265
266 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
267
268 if [ -z "${hook}" ]; then
269 error "Config file did not provide any hook."
270 return ${EXIT_ERROR}
271 fi
272
273 if ! hook_zone_exists ${hook}; then
274 error "Hook '${hook}' does not exist."
275 return ${EXIT_ERROR}
276 fi
277
278 zone_db ${zone} starting
279
280 hook_zone_exec ${hook} up ${zone} $@
281
282 zone_db ${zone} started
283 }
284
285 function zone_down() {
286 local zone=${1}
287 shift
288
289 if ! zone_exists ${zone}; then
290 error "Zone '${zone}' does not exist."
291 return ${EXIT_ERROR}
292 fi
293
294 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
295
296 if [ -z "${hook}" ]; then
297 error "Config file did not provide any hook."
298 return ${EXIT_ERROR}
299 fi
300
301 if ! hook_zone_exists ${hook}; then
302 error "Hook '${hook}' does not exist."
303 return ${EXIT_ERROR}
304 fi
305
306 zone_db ${zone} stopping
307
308 hook_zone_exec ${hook} down ${zone} $@
309
310 zone_db ${zone} stopped
311
312 # Remove the zone, if it has got a remove tag.
313 if zone_has_remove_tag ${zone}; then
314 zone_remove_now ${zone}
315 fi
316 }
317
318 function zone_status() {
319 local zone=${1}
320 shift
321
322 if ! zone_exists ${zone}; then
323 error "Zone '${zone}' does not exist."
324 return ${EXIT_ERROR}
325 fi
326
327 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
328
329 if [ -z "${hook}" ]; then
330 error "Config file did not provide any hook."
331 return ${EXIT_ERROR}
332 fi
333
334 if ! hook_zone_exists ${hook}; then
335 error "Hook '${hook}' does not exist."
336 return ${EXIT_ERROR}
337 fi
338
339 hook_zone_exec ${hook} status ${zone} $@
340
341 # Show that the zone it to be removed soon.
342 if zone_has_remove_tag ${zone}; then
343 warning "This zone is tagged for removal."
344 fi
345 }
346
347 function zone_port() {
348 local zone=${1}
349 local action=${2}
350 shift 2
351
352 assert isset zone
353 assert isset action
354 assert zone_exists ${zone}
355
356 case "${action}" in
357 add|edit|remove)
358 zone_port_${action} ${zone} $@
359 ;;
360 *)
361 error "Unrecognized argument: ${action}"
362 cli_usage root-zone-port-subcommands
363 exit ${EXIT_ERROR}
364 ;;
365 esac
366 }
367
368 function zone_port_add() {
369 local zone="${1}"
370 assert isset zone
371
372 local port="${2}"
373 assert isset port
374
375 shift 2
376
377 # Check if the port actually exists.
378 if ! port_exists "${port}"; then
379 error "Cannot add port '${port}' which does not exist"
380 return ${EXIT_ERROR}
381 fi
382
383 # Check if the port is already connected to this or any other zone.
384 local z
385 for z in $(zones_get_all); do
386 if zone_has_port "${z}" "${port}"; then
387 error "Port '${port}' is already assigned to zone '${z}'"
388 return ${EXIT_ERROR}
389 fi
390 done
391
392 local hook=$(zone_get_hook "${zone}")
393 assert isset hook
394
395 hook_zone_exec "${hook}" "port_add" "${zone}" "${port}" "$@"
396 }
397
398 function zone_port_edit() {
399 local zone="${1}"
400 assert isset zone
401
402 local port="${2}"
403 assert isset port
404
405 shift 2
406
407 # Check if the port actually exists.
408 if ! port_exists "${port}"; then
409 error "Port '${port}' does not exist"
410 return ${EXIT_ERROR}
411 fi
412
413 # Check if the zone actually has this port.
414 if ! zone_has_port "${zone}" "${port}"; then
415 error "Port '${port}' is not attached to zone '${zone}'"
416 return ${EXIT_ERROR}
417 fi
418
419 local hook=$(zone_get_hook "${zone}")
420 assert isset hook
421
422 hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
423 }
424
425 function zone_port_remove() {
426 local zone="${1}"
427 assert isset zone
428
429 local port="${2}"
430 assert isset port
431
432 shift 2
433
434 # Check if the zone actually has this port.
435 if ! zone_has_port "${zone}" "${port}"; then
436 error "Port '${port}' is not attached to zone '${zone}'"
437 return ${EXIT_ERROR}
438 fi
439
440 local hook=$(zone_get_hook "${zone}")
441 assert isset hook
442
443 hook_zone_exec "${hook}" "port_remove" "${zone}" "${port}" "$@"
444 }
445
446 function zone_get_ports() {
447 local zone=${1}
448
449 assert isset zone
450
451 local port
452 for port in $(zone_dir ${zone})/ports/*; do
453 port=$(basename ${port})
454
455 if port_exists ${port}; then
456 echo "${port}"
457 fi
458 done
459 }
460
461 function zone_has_port() {
462 # Check, if the given port is configured
463 # in this zone.
464
465 local zone=${1}
466 local port=${2}
467 shift 2
468
469 assert isset zone
470 assert isset port
471
472 [ -e "$(zone_dir ${zone})/ports/${port}" ]
473 }
474
475 # XXX overwritten some lines below
476 function zone_config() {
477 local zone=${1}
478 shift
479
480 if ! zone_exists ${zone}; then
481 error "Zone '${zone}' does not exist."
482 return ${EXIT_ERROR}
483 fi
484
485 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
486
487 if [ -z "${hook}" ]; then
488 error "Config file did not provide any hook."
489 return ${EXIT_ERROR}
490 fi
491
492 if ! hook_zone_exists ${hook}; then
493 error "Hook '${hook}' does not exist."
494 return ${EXIT_ERROR}
495 fi
496
497 hook_zone_exec ${hook} config ${zone} $@
498 }
499
500 function zone_config() {
501 local zone=${1}
502 local action=${2}
503 shift 2
504
505 assert isset zone
506 assert isset action
507 assert zone_exists ${zone}
508
509 # Aliases
510 case "${action}" in
511 del|delete|remove)
512 action="rem"
513 ;;
514 esac
515
516 case "${action}" in
517 create|edit|rem)
518 zone_config_${action} ${zone} $@
519 ;;
520 *)
521 error "Unrecognized argument: ${action}"
522 cli_usage root-zone-config-subcommands
523 exit ${EXIT_ERROR}
524 ;;
525 esac
526 }
527
528 function zone_config_option() {
529 local zone=${1}
530 local option=${2}
531 local default=${3}
532 shift 2
533
534 assert isset zone
535 assert isset option
536
537 (
538 VALUE="${default}"
539 zone_config_read ${zone}
540
541 VALUE="${!option}"
542 echo "${VALUE}"
543 )
544 }
545
546 function zone_config_create() {
547 local zone=${1}
548 shift
549
550 assert isset zone
551
552 local hook=$(zone_get_hook ${zone})
553
554 assert isset hook
555
556 hook_zone_exec ${hook} config_create ${zone} $@
557 }
558
559 function zone_show() {
560 local zone=${1}
561
562 echo "${zone}"
563 echo " Type: $(zone_get_hook ${zone})"
564 echo
565 }
566
567 function zones_show() {
568 local zone
569
570 for zone in $(zones_get $@); do
571 zone_show ${zone}
572 done
573 }
574
575 function zones_get_all() {
576 local zone
577 for zone in $(zone_dir)/*; do
578 zone=$(basename ${zone})
579 zone_exists ${zone} || continue
580
581 echo "${zone}"
582 done
583 }
584
585 function zones_get_local() {
586 local zone
587 for zone in $(zones_get_all); do
588 zone_is_local ${zone} && echo "${zone}"
589 done
590 }
591
592 function zones_get_nonlocal() {
593 local zone
594 for zone in $(zones_get_all); do
595 zone_is_nonlocal ${zone} && echo "${zone}"
596 done
597 }
598
599 function zones_get() {
600 local local=1
601 local remote=1
602
603 local zones
604
605 while [ $# -gt 0 ]; do
606 case "${1}" in
607 --local-only)
608 local=1
609 remote=0
610 ;;
611 --remote-only)
612 local=0
613 remote=1
614 ;;
615 --all)
616 local=1
617 remote=1
618 ;;
619 *)
620 if zone_name_is_valid ${1}; then
621 zones="${zones} ${1}"
622 else
623 warning "Unrecognized argument '${1}'"
624 fi
625 ;;
626 esac
627 shift
628 done
629
630 if [ -n "${zones}" ]; then
631 local zone
632 for zone in ${zones}; do
633 zone_exists ${zone} && echo "${zone}"
634 done
635 exit ${EXIT_OK}
636 fi
637
638 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
639 zones_get_all
640 elif [ ${local} -eq 1 ]; then
641 zones_get_local
642 elif [ ${remote} -eq 1 ]; then
643 zones_get_nonlocal
644 fi
645 }
646
647 function zone_ports_list() {
648 local zone=${1}
649
650 local port
651 for port in $(zone_dir ${zone})/ports/*; do
652 [ -e "${port}" ] || continue
653
654 echo $(basename ${port})
655 done
656 }
657
658 function zone_ports_cmd() {
659 local cmd=${1}
660 local zone=${2}
661 shift 2
662
663 assert isset cmd
664 assert isset zone
665
666 assert zone_exists ${zone}
667
668 local hook=$(zone_get_hook ${zone})
669
670 local port
671 for port in $(zone_get_ports ${zone}); do
672 hook_zone_exec ${hook} ${cmd} ${zone} ${port} $@
673 done
674 }
675
676 function zone_ports_up() {
677 zone_ports_cmd port_up $@
678 }
679
680 function zone_ports_down() {
681 zone_ports_cmd port_down $@
682 }
683
684 function zone_ports_status() {
685 zone_ports_cmd port_status $@
686 }
687
688 function zone_configs_list() {
689 local zone=${1}
690
691 local config
692 for config in $(zone_dir ${zone})/configs/*; do
693 [ -e "${config}" ] || continue
694
695 basename ${config}
696 done
697 }
698
699 function zone_configs_cmd() {
700 local cmd=${1}
701 local zone=${2}
702 shift 2
703
704 local hook_zone=$(config_get_hook $(zone_dir ${zone})/settings)
705
706 local hook_config
707 local config
708 for config in $(zone_configs_list ${zone}); do
709 hook_config=$(config_get_hook $(zone_dir ${zone})/configs/${config})
710
711 hook_zone_config_exec ${hook_zone} ${hook_config} ${cmd} ${zone} ${config} $@
712 done
713 }
714
715 function zone_configs_up() {
716 zone_configs_cmd up $@
717 }
718
719 function zone_configs_down() {
720 zone_configs_cmd down $@
721 }
722
723 function zone_configs_status() {
724 zone_configs_cmd config_status $@
725 }
726
727 function zone_has_ip() {
728 device_has_ip $@
729 }
730
731 function zone_db() {
732 local zone=${1}
733 local action=${2}
734 shift 2
735
736 case "${action}" in
737 starting|started|stopping|stopped)
738 db_connection_update ${zone} ${action}
739 ;;
740 esac
741 }
742
743 function zone_is_up() {
744 local zone=${1}
745
746 device_is_up ${zone}
747 }
748
749 function zone_is_down() {
750 ! zone_is_up $@
751 }
752
753 function zone_get_supported_port_hooks() {
754 local zone=${1}
755
756 local hook=$(zone_get_hook ${zone})
757
758 hook_zone_ports_get_all ${hook}
759 }
760
761 function zone_get_supported_config_hooks() {
762 local zone=${1}
763
764 local hook=$(zone_get_hook ${zone})
765
766 hook_zone_configs_get_all ${hook}
767 }
768
769 function zone_file() {
770 local zone=${1}
771
772 assert isset zone
773
774 echo "$(zone_dir ${zone})/settings"
775 }
776
777 function zone_config_read() {
778 local zone=${1}
779
780 assert isset zone
781
782 # Save the HOOK variable.
783 local hook="${HOOK}"
784
785 config_read $(zone_file ${zone})
786
787 # Restore hook.
788 HOOK="${hook}"
789 }
790
791 function zone_config_write() {
792 local zone=${1}
793
794 assert isset zone
795
796 config_write $(zone_file ${zone}) ${HOOK_SETTINGS}
797 }
798
799 function zone_config_set() {
800 local zone=${1}
801 shift
802 local args="$@"
803
804 assert isset zone
805
806 (
807 zone_config_read ${zone}
808
809 for arg in ${args}; do
810 eval "${arg}"
811 done
812
813 zone_config_write ${zone}
814 )
815 }
816
817 function zone_config_get() {
818 local zone=${1}
819 local key=${2}
820
821 assert isset zone
822 assert isset key
823
824 (
825 zone_config_read ${zone}
826
827 echo "${!key}"
828 )
829 }