]> git.ipfire.org Git - people/stevee/network.git/blob - src/functions/functions.zone
c6c9f38874d9f0c28ab0532b24cdf57a9da802db
[people/stevee/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_reload() {
95 local zone="${1}"
96 assert zone_exists "${zone}"
97
98 service_reload "network@${zone}.service"
99 }
100
101 function zone_enable() {
102 # This function will enable the zone
103 # with help of systemd.
104
105 local zone="${1}"
106 assert zone_exists "${zone}"
107
108 # Enable service for the zone
109 service_enable "network@${zone}.service"
110 local ret=$?
111
112 if [ ${ret} -eq ${EXIT_OK} ]; then
113 log INFO "Auto-start enabled for zone ${zone}"
114 return ${EXIT_OK}
115 fi
116
117 log ERROR "Could not enable zone ${zone}: ${ret}"
118 return ${ret}
119 }
120
121 function zone_disable() {
122 # This function will disable the zone
123 # with help of systemd.
124
125 local zone="${1}"
126 assert zone_exists "${zone}"
127
128 # Disable service for the zone
129 service_disable "network@${zone}.service"
130 local ret=$?
131
132 if [ ${ret} -eq ${EXIT_OK} ]; then
133 log INFO "Auto-start disabled for zone ${zone}"
134 return ${EXIT_OK}
135 fi
136
137 log ERROR "Could not disable zone ${zone}: ${ret}"
138 return ${ret}
139 }
140
141 function zone_is_enabled() {
142 local zone="${1}"
143 assert isset zone
144
145 # Ask systemd if the zone is enabled.
146 if service_is_enabled "network@${zone}.service"; then
147 return ${EXIT_TRUE}
148 fi
149
150 return ${EXIT_FALSE}
151 }
152
153 function zone_is_active() {
154 local zone="${1}"
155 assert isset zone
156
157 if service_is_active "network@${zone}.service"; then
158 return ${EXIT_TRUE}
159 fi
160
161 return ${EXIT_FALSE}
162 }
163
164 function zone_create() {
165 local zone=${1}
166 local hook=${2}
167 shift 2
168
169 if ! zone_name_is_valid ${zone}; then
170 error "Zone name '${zone}' is not valid."
171 return ${EXIT_ERROR}
172 fi
173
174 if zone_exists ${zone}; then
175 error "Zone '${zone}' does already exist."
176 return ${EXIT_ERROR}
177 fi
178
179 if ! hook_zone_exists ${hook}; then
180 error "Hook '${hook}' does not exist."
181 return ${EXIT_ERROR}
182 fi
183
184 mkdir -p $(zone_dir ${zone})
185
186 # Create directories for configs and ports
187 mkdir -p $(zone_dir ${zone})/{configs,ports}
188
189 hook_zone_exec ${hook} create ${zone} $@
190 local ret=$?
191
192 # Maybe the zone create hook did not exit correctly.
193 # If this is the case we remove the created zone immediately.
194 if [ "${ret}" = "${EXIT_ERROR}" ]; then
195 zone_remove_now ${zone}
196 return ${EXIT_ERROR}
197 fi
198
199 # Automatically enable zone.
200 zone_enable "${zone}"
201 }
202
203 function zone_edit() {
204 local zone=${1}
205 shift
206
207 if ! zone_exists ${zone}; then
208 error "Zone '${zone}' does not exist."
209 return ${EXIT_ERROR}
210 fi
211
212 # Check if the zone is tagged for removal.
213 if zone_has_remove_tag ${zone}; then
214 error "You cannot edit a zone that is tagged for removal."
215 return ${EXIT_ERROR}
216 fi
217
218 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
219
220 if [ -z "${hook}" ]; then
221 error "Config file did not provide any hook."
222 return ${EXIT_ERROR}
223 fi
224
225 if ! hook_zone_exists ${hook}; then
226 error "Hook '${hook}' does not exist."
227 return ${EXIT_ERROR}
228 fi
229
230 hook_zone_exec ${hook} edit ${zone} $@
231 }
232
233
234 function zone_remove() {
235 local zone=${1}
236 assert zone_exists ${zone}
237
238 # Make the zone for removal.
239 touch $(zone_dir ${zone})/.remove
240
241 log INFO "Zone '${zone}' has been tagged for removal."
242 }
243
244 function zone_has_remove_tag() {
245 local zone=${1}
246 assert zone_exists ${zone}
247
248 [ -e "$(zone_dir ${zone})/.remove" ]
249 }
250
251 # This function will remove the given zone
252 # RIGHT NOW. Use zone_remove to remove it
253 # at the next status change.
254 function zone_remove_now() {
255 local zone=${1}
256 assert zone_exists ${zone}
257
258 log INFO "Removing zone '${zone}' right now."
259
260 # Force the zone down.
261 zone_is_up ${zone} && zone_set_down ${zone}
262
263 # Disable zone.
264 zone_disable "${zone}"
265
266 rm -rf $(zone_dir ${zone})
267 }
268
269 function zone_up() {
270 local zone=${1}
271 shift
272
273 if ! zone_exists ${zone}; then
274 error "Zone '${zone}' does not exist."
275 return ${EXIT_ERROR}
276 fi
277
278 # Check if a zone has got the remove tag.
279 if zone_has_remove_tag ${zone}; then
280 error "Cannot bring up any zone which is to be removed."
281 return ${EXIT_ERROR}
282 fi
283
284 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
285
286 if [ -z "${hook}" ]; then
287 error "Config file did not provide any hook."
288 return ${EXIT_ERROR}
289 fi
290
291 if ! hook_zone_exists ${hook}; then
292 error "Hook '${hook}' does not exist."
293 return ${EXIT_ERROR}
294 fi
295
296 zone_db ${zone} starting
297
298 hook_zone_exec ${hook} up ${zone} $@
299
300 zone_db ${zone} started
301 }
302
303 function zone_down() {
304 local zone=${1}
305 shift
306
307 if ! zone_exists ${zone}; then
308 error "Zone '${zone}' does not exist."
309 return ${EXIT_ERROR}
310 fi
311
312 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
313
314 if [ -z "${hook}" ]; then
315 error "Config file did not provide any hook."
316 return ${EXIT_ERROR}
317 fi
318
319 if ! hook_zone_exists ${hook}; then
320 error "Hook '${hook}' does not exist."
321 return ${EXIT_ERROR}
322 fi
323
324 zone_db ${zone} stopping
325
326 hook_zone_exec ${hook} down ${zone} $@
327
328 zone_db ${zone} stopped
329
330 # Remove the zone, if it has got a remove tag.
331 if zone_has_remove_tag ${zone}; then
332 zone_remove_now ${zone}
333 fi
334 }
335
336 function zone_status() {
337 local zone=${1}
338 shift
339
340 if ! zone_exists ${zone}; then
341 error "Zone '${zone}' does not exist."
342 return ${EXIT_ERROR}
343 fi
344
345 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
346
347 if [ -z "${hook}" ]; then
348 error "Config file did not provide any hook."
349 return ${EXIT_ERROR}
350 fi
351
352 if ! hook_zone_exists ${hook}; then
353 error "Hook '${hook}' does not exist."
354 return ${EXIT_ERROR}
355 fi
356
357 hook_zone_exec ${hook} status ${zone} $@
358
359 # Show that the zone it to be removed soon.
360 if zone_has_remove_tag ${zone}; then
361 warning "This zone is tagged for removal."
362 fi
363 }
364
365 function zone_port() {
366 local zone=${1}
367 local action=${2}
368 shift 2
369
370 assert isset zone
371 assert isset action
372 assert zone_exists ${zone}
373
374 case "${action}" in
375 add|edit|remove)
376 zone_port_${action} ${zone} $@
377 ;;
378 *)
379 error "Unrecognized argument: ${action}"
380 cli_usage root-zone-port-subcommands
381 exit ${EXIT_ERROR}
382 ;;
383 esac
384 }
385
386 function zone_port_add() {
387 local zone="${1}"
388 assert isset zone
389
390 local port="${2}"
391 assert isset port
392
393 shift 2
394
395 # Check if the port actually exists.
396 if ! port_exists "${port}"; then
397 error "Cannot add port '${port}' which does not exist"
398 return ${EXIT_ERROR}
399 fi
400
401 # Check if the port is already connected to this or any other zone.
402 local z
403 for z in $(zones_get_all); do
404 if zone_has_port "${z}" "${port}"; then
405 error "Port '${port}' is already assigned to zone '${z}'"
406 return ${EXIT_ERROR}
407 fi
408 done
409
410 local hook=$(zone_get_hook "${zone}")
411 assert isset hook
412
413 hook_zone_exec "${hook}" "port_add" "${zone}" "${port}" "$@"
414 }
415
416 function zone_port_edit() {
417 local zone="${1}"
418 assert isset zone
419
420 local port="${2}"
421 assert isset port
422
423 shift 2
424
425 # Check if the port actually exists.
426 if ! port_exists "${port}"; then
427 error "Port '${port}' does not exist"
428 return ${EXIT_ERROR}
429 fi
430
431 # Check if the zone actually has this port.
432 if ! zone_has_port "${zone}" "${port}"; then
433 error "Port '${port}' is not attached to zone '${zone}'"
434 return ${EXIT_ERROR}
435 fi
436
437 local hook=$(zone_get_hook "${zone}")
438 assert isset hook
439
440 hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
441 }
442
443 function zone_port_remove() {
444 local zone="${1}"
445 assert isset zone
446
447 local port="${2}"
448 assert isset port
449
450 shift 2
451
452 # Check if the zone actually has this port.
453 if ! zone_has_port "${zone}" "${port}"; then
454 error "Port '${port}' is not attached to zone '${zone}'"
455 return ${EXIT_ERROR}
456 fi
457
458 local hook=$(zone_get_hook "${zone}")
459 assert isset hook
460
461 hook_zone_exec "${hook}" "port_remove" "${zone}" "${port}" "$@"
462 }
463
464 function zone_get_ports() {
465 local zone=${1}
466
467 assert isset zone
468
469 local port
470 for port in $(zone_dir ${zone})/ports/*; do
471 port=$(basename ${port})
472
473 if port_exists ${port}; then
474 echo "${port}"
475 fi
476 done
477 }
478
479 function zone_get_ports_num() {
480 local zone="${1}"
481 assert isset zone
482
483 local counter=0
484 local port
485 for port in $(zone_dir "${zone}")/ports/*; do
486 port="$(basename "${port}")"
487
488 if port_exists "${port}"; then
489 counter=$(( ${counter} + 1 ))
490 fi
491 done
492
493 echo "${counter}"
494 return ${EXIT_OK}
495 }
496
497 function zone_has_port() {
498 # Check, if the given port is configured
499 # in this zone.
500
501 local zone=${1}
502 local port=${2}
503 shift 2
504
505 assert isset zone
506 assert isset port
507
508 [ -e "$(zone_dir ${zone})/ports/${port}" ]
509 }
510
511 # XXX overwritten some lines below
512 function zone_config() {
513 local zone=${1}
514 shift
515
516 if ! zone_exists ${zone}; then
517 error "Zone '${zone}' does not exist."
518 return ${EXIT_ERROR}
519 fi
520
521 local hook=$(config_get_hook $(zone_dir ${zone})/settings)
522
523 if [ -z "${hook}" ]; then
524 error "Config file did not provide any hook."
525 return ${EXIT_ERROR}
526 fi
527
528 if ! hook_zone_exists ${hook}; then
529 error "Hook '${hook}' does not exist."
530 return ${EXIT_ERROR}
531 fi
532
533 hook_zone_exec ${hook} config ${zone} $@
534 }
535
536 function zone_config() {
537 local zone=${1}
538 local action=${2}
539 shift 2
540
541 assert isset zone
542 assert isset action
543 assert zone_exists ${zone}
544
545 # Aliases
546 case "${action}" in
547 del|delete|remove)
548 action="rem"
549 ;;
550 esac
551
552 case "${action}" in
553 create|edit|rem)
554 zone_config_${action} ${zone} $@
555 ;;
556 *)
557 error "Unrecognized argument: ${action}"
558 cli_usage root-zone-config-subcommands
559 exit ${EXIT_ERROR}
560 ;;
561 esac
562 }
563
564 function zone_config_create() {
565 local zone="${1}"
566 assert isset zone
567 shift
568
569 local hook=$(zone_get_hook "${zone}")
570 assert isset hook
571
572 hook_zone_exec "${hook}" "config_create" "${zone}" "$@"
573 }
574
575 function zone_show() {
576 local zone=${1}
577
578 echo "${zone}"
579 echo " Type: $(zone_get_hook ${zone})"
580 echo
581 }
582
583 function zones_show() {
584 local zone
585
586 for zone in $(zones_get $@); do
587 zone_show ${zone}
588 done
589 }
590
591 function zones_get_all() {
592 local zone
593 for zone in $(zone_dir)/*; do
594 zone=$(basename ${zone})
595 zone_exists ${zone} || continue
596
597 echo "${zone}"
598 done
599 }
600
601 function zones_get_local() {
602 local zone
603 for zone in $(zones_get_all); do
604 zone_is_local ${zone} && echo "${zone}"
605 done
606 }
607
608 function zones_get_nonlocal() {
609 local zone
610 for zone in $(zones_get_all); do
611 zone_is_nonlocal ${zone} && echo "${zone}"
612 done
613 }
614
615 function zones_get() {
616 local local=1
617 local remote=1
618
619 local zones
620
621 while [ $# -gt 0 ]; do
622 case "${1}" in
623 --local-only)
624 local=1
625 remote=0
626 ;;
627 --remote-only)
628 local=0
629 remote=1
630 ;;
631 --all)
632 local=1
633 remote=1
634 ;;
635 *)
636 if zone_name_is_valid ${1}; then
637 zones="${zones} ${1}"
638 else
639 warning "Unrecognized argument '${1}'"
640 fi
641 ;;
642 esac
643 shift
644 done
645
646 if [ -n "${zones}" ]; then
647 local zone
648 for zone in ${zones}; do
649 zone_exists ${zone} && echo "${zone}"
650 done
651 exit ${EXIT_OK}
652 fi
653
654 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
655 zones_get_all
656 elif [ ${local} -eq 1 ]; then
657 zones_get_local
658 elif [ ${remote} -eq 1 ]; then
659 zones_get_nonlocal
660 fi
661 }
662
663 function zone_ports_list() {
664 local zone=${1}
665
666 local port
667 for port in $(zone_dir ${zone})/ports/*; do
668 [ -e "${port}" ] || continue
669
670 echo $(basename ${port})
671 done
672 }
673
674 function zone_ports_cmd() {
675 local cmd=${1}
676 local zone=${2}
677 shift 2
678
679 assert isset cmd
680 assert isset zone
681
682 assert zone_exists ${zone}
683
684 local hook=$(zone_get_hook ${zone})
685
686 local port
687 for port in $(zone_get_ports ${zone}); do
688 hook_zone_exec ${hook} ${cmd} ${zone} ${port} $@
689 done
690 }
691
692 function zone_ports_up() {
693 zone_ports_cmd port_up $@
694 }
695
696 function zone_ports_down() {
697 zone_ports_cmd port_down $@
698 }
699
700 function zone_ports_status() {
701 zone_ports_cmd port_status $@
702 }
703
704 function zone_configs_list() {
705 local zone=${1}
706
707 local config
708 for config in $(zone_dir ${zone})/configs/*; do
709 [ -e "${config}" ] || continue
710
711 basename ${config}
712 done
713 }
714
715 function zone_configs_cmd() {
716 local cmd=${1}
717 local zone=${2}
718 shift 2
719
720 local hook_zone=$(config_get_hook $(zone_dir ${zone})/settings)
721
722 local hook_config
723 local config
724 for config in $(zone_configs_list ${zone}); do
725 hook_config=$(config_get_hook $(zone_dir ${zone})/configs/${config})
726
727 hook_zone_config_exec ${hook_zone} ${hook_config} ${cmd} ${zone} ${config} $@
728 done
729 }
730
731 function zone_configs_up() {
732 zone_configs_cmd up $@
733 }
734
735 function zone_configs_down() {
736 zone_configs_cmd down $@
737 }
738
739 function zone_configs_status() {
740 zone_configs_cmd config_status $@
741 }
742
743 function zone_has_ip() {
744 device_has_ip $@
745 }
746
747 function zone_db() {
748 local zone=${1}
749 local action=${2}
750 shift 2
751
752 case "${action}" in
753 starting|started|stopping|stopped)
754 db_connection_update ${zone} ${action}
755 ;;
756 esac
757 }
758
759 function zone_is_up() {
760 local zone=${1}
761
762 device_is_up ${zone}
763 }
764
765 function zone_is_down() {
766 ! zone_is_up $@
767 }
768
769 function zone_get_supported_port_hooks() {
770 local zone=${1}
771
772 local hook=$(zone_get_hook ${zone})
773
774 hook_zone_ports_get_all ${hook}
775 }
776
777 function zone_get_supported_config_hooks() {
778 local zone=${1}
779
780 local hook=$(zone_get_hook ${zone})
781
782 hook_zone_configs_get_all ${hook}
783 }
784
785 function zone_file() {
786 local zone=${1}
787
788 assert isset zone
789
790 echo "$(zone_dir ${zone})/settings"
791 }
792
793 function zone_settings_read() {
794 local zone=${1}
795
796 assert isset zone
797
798 # Save the HOOK variable.
799 local hook="${HOOK}"
800
801 settings_read $(zone_file ${zone})
802
803 # Restore hook.
804 HOOK="${hook}"
805 }
806
807 function zone_settings_write() {
808 local zone=${1}
809
810 assert isset zone
811
812 settings_write $(zone_file ${zone}) ${HOOK_SETTINGS}
813 }
814
815 function zone_settings_set() {
816 local zone=${1}
817 shift
818 local args="$@"
819
820 assert isset zone
821
822 (
823 zone_settings_read ${zone}
824
825 for arg in ${args}; do
826 eval "${arg}"
827 done
828
829 zone_settings_write ${zone}
830 )
831 }
832
833 function zone_settings_get() {
834 local zone=${1}
835 local key=${2}
836
837 assert isset zone
838 assert isset key
839
840 (
841 zone_settings_read ${zone}
842
843 echo "${!key}"
844 )
845 }
846
847 function zone_config_settings_read() {
848 assert [ $# -gt 2 ]
849
850 local zone="${1}"
851 local config="${2}"
852 shift 2
853
854 local path="$(zone_dir "${zone}")/configs/${config}"
855 settings_read "${path}" "$@"
856 }
857
858 function zone_config_settings_write() {
859 assert [ $# -gt 2 ]
860
861 local zone="${1}"
862 local config="${2}"
863 shift 2
864
865 local path="$(zone_dir "${zone}")/configs/${config}"
866 settings_write "${path}" "$@"
867 }
868
869 function zone_port_settings_read() {
870 assert [ $# -gt 2 ]
871
872 local zone="${1}"
873 local port="${2}"
874 shift 2
875
876 local path="$(zone_dir "${zone}")/ports/${port}"
877 settings_read "${path}" "$@"
878 }
879
880 function zone_port_settings_write() {
881 assert [ $# -gt 2 ]
882
883 local zone="${1}"
884 local port="${2}"
885 shift 2
886
887 local path="$(zone_dir "${zone}")/ports/${port}"
888 settings_write "${path}" "$@"
889 }
890
891 function zone_port_settings_remove() {
892 assert [ $# -eq 2 ]
893
894 local zone="${1}"
895 local port="${2}"
896
897 local path="$(zone_dir "${zone}")/ports/${port}"
898 settings_remove "${path}"
899 }