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