]> git.ipfire.org Git - people/ms/network.git/blob - src/functions/functions.zone
hook: Rename HOOK_CONFIG_SETTINGS to HOOK_SETTINGS
[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 zone_exists() {
23 local zone=${1}
24 assert isset zone
25
26 [ -d "${NETWORK_ZONES_DIR}/${zone}" ]
27 }
28
29 zone_match() {
30 local match
31
32 local i
33 for i in ${VALID_ZONES}; do
34 match="${match}|${i}[0-9]{1,5}"
35 done
36
37 echo "${match:1:${#match}}"
38 }
39
40 zone_name_is_valid() {
41 local zone=${1}
42
43 # Don't accept empty strings.
44 [ -z "${zone}" ] && return ${EXIT_FALSE}
45
46 [[ ${zone} =~ $(zone_match) ]]
47 }
48
49 zone_is_local() {
50 local zone=${1}
51
52 [[ "${zone:0:${#ZONE_LOCAL}}" = "${ZONE_LOCAL}" ]]
53 }
54
55 zone_is_nonlocal() {
56 local zone=${1}
57
58 [[ "${zone:0:${#ZONE_NONLOCAL}}" = "${ZONE_NONLOCAL}" ]]
59 }
60
61 zone_get_hook() {
62 local zone=${1}
63 assert isset zone
64
65 config_get_hook "${NETWORK_ZONES_DIR}/${zone}/settings"
66 }
67
68 zone_start() {
69 # This function will bring up the zone
70 # 'asynchronously' with help of systemd.
71
72 local zone=${1}
73 assert zone_exists ${zone}
74
75 service_start "network@${zone}.service"
76 }
77
78 zone_start_auto() {
79 local zone="${1}"
80 assert zone_exists "${zone}"
81
82 # If the zone has already been started, we
83 # will reload it so the current configuration
84 # is re-applied.
85 if zone_is_active "${zone}"; then
86 zone_reload "${zone}"
87 return ${?}
88
89 # If the zone is still down, but in auto-start mode,
90 # we will start it.
91 elif zone_is_enabled "${zone}"; then
92 zone_start "${zone}"
93 return ${?}
94 fi
95
96 # Otherwise, nothing will be done.
97 return ${EXIT_OK}
98 }
99
100 zone_stop() {
101 # This function will bring down the zone
102 # 'asynchronously' with help of systemd.
103
104 local zone=${1}
105 assert zone_exists ${zone}
106
107 service_stop "network@${zone}.service"
108 }
109
110 zone_reload() {
111 local zone="${1}"
112 assert zone_exists "${zone}"
113
114 service_reload "network@${zone}.service"
115 }
116
117 zone_hotplug_event() {
118 local zone="${1}"
119 assert isset zone
120
121 hotplug_assert_in_hotplug_event
122
123 zone_cmd "hotplug" "${zone}"
124 }
125
126 zone_enable() {
127 # This function will enable the zone
128 # with help of systemd.
129
130 local zone="${1}"
131 assert zone_exists "${zone}"
132
133 # Enable service for the zone
134 service_enable "network@${zone}.service"
135 local ret=$?
136
137 if [ ${ret} -eq ${EXIT_OK} ]; then
138 log INFO "Auto-start enabled for zone ${zone}"
139 return ${EXIT_OK}
140 fi
141
142 log ERROR "Could not enable zone ${zone}: ${ret}"
143 return ${ret}
144 }
145
146 zone_disable() {
147 # This function will disable the zone
148 # with help of systemd.
149
150 local zone="${1}"
151 assert zone_exists "${zone}"
152
153 # Disable service for the zone
154 service_disable "network@${zone}.service"
155 local ret=$?
156
157 if [ ${ret} -eq ${EXIT_OK} ]; then
158 log INFO "Auto-start disabled for zone ${zone}"
159 return ${EXIT_OK}
160 fi
161
162 log ERROR "Could not disable zone ${zone}: ${ret}"
163 return ${ret}
164 }
165
166 zone_is_enabled() {
167 local zone="${1}"
168 assert isset zone
169
170 # Ask systemd if the zone is enabled.
171 if service_is_enabled "network@${zone}.service"; then
172 return ${EXIT_TRUE}
173 fi
174
175 return ${EXIT_FALSE}
176 }
177
178 zone_is_active() {
179 local zone="${1}"
180 assert isset zone
181
182 if service_is_active "network@${zone}.service"; then
183 return ${EXIT_TRUE}
184 fi
185
186 return ${EXIT_FALSE}
187 }
188
189 zone_is_enabled_or_active() {
190 local zone="${1}"
191 assert isset zone
192
193 zone_is_enabled "${zone}" || zone_is_active "${zone}"
194 }
195
196 zone_cmd() {
197 local cmd="${1}"
198 local port="${2}"
199 shift 2
200
201 assert isset cmd
202 assert isset zone
203
204 local hook="$(zone_get_hook ${zone})"
205 assert isset hook
206
207 hook_exec zone "${hook}" "${cmd}" "${zone}" "$@"
208 }
209
210 zone_new() {
211 local zone=${1}
212 local hook=${2}
213 shift 2
214
215 if ! zone_name_is_valid ${zone}; then
216 error "Zone name '${zone}' is not valid."
217 return ${EXIT_ERROR}
218 fi
219
220 if zone_exists ${zone}; then
221 error "Zone '${zone}' does already exist."
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 # Create directories for configs and ports
231 local what
232 for what in configs ports; do
233 make_directory "${NETWORK_ZONES_DIR}/${zone}/${what}"
234 done
235
236 hook_zone_exec "${hook}" "new" "${zone}" "$@"
237 local ret=$?
238
239 # Maybe the zone new hook did not exit correctly.
240 # If this is the case we remove the created zone immediately.
241 if [ "${ret}" != "${EXIT_OK}" ]; then
242 zone_destroy "${zone}"
243 return ${EXIT_ERROR}
244 fi
245
246 # Automatically enable zone.
247 zone_enable "${zone}"
248
249 # Bring up the zone immediately after
250 zone_start "${zone}"
251 }
252
253 zone_edit() {
254 local zone=${1}
255 shift
256
257 if ! zone_exists ${zone}; then
258 error "Zone '${zone}' does not exist."
259 return ${EXIT_ERROR}
260 fi
261
262 local hook="$(zone_get_hook "${zone}")"
263 if [ -z "${hook}" ]; then
264 error "Config file did not provide any hook."
265 return ${EXIT_ERROR}
266 fi
267
268 if ! hook_zone_exists ${hook}; then
269 error "Hook '${hook}' does not exist."
270 return ${EXIT_ERROR}
271 fi
272
273 hook_zone_exec ${hook} edit ${zone} "$@"
274 }
275
276 zone_rename() {
277 assert [ $# -eq 2 ]
278
279 local zone="${1}"
280 local name="${2}"
281
282 assert zone_exists "${zone}"
283 assert not zone_exists "${name}"
284
285 # The zone must be shut down before, is then renamed and
286 # potentially brought up again
287
288 # Save if the zone is running right now
289 zone_is_active "${zone}"
290 local zone_was_active="${?}"
291
292 # Save if the zone is enabled (i.e. auto-start)
293 zone_is_enabled "${zone}"
294 local zone_was_enabled="${?}"
295
296 # Stop the zone
297 zone_stop "${zone}"
298
299 # Disable the zone
300 zone_disable "${zone}"
301
302 # Rename the configuration files
303 mv -f "${NETWORK_ZONES_DIR}/${zone}" "${NETWORK_ZONES_DIR}/${name}"
304
305 # Enable the zone if it was enabled before
306 [ ${zone_was_enabled} -eq ${EXIT_TRUE} ] && zone_enable "${name}"
307
308 # Start the zone if it was up before
309 [ ${zone_was_active} -eq ${EXIT_TRUE} ] && zone_start "${name}"
310
311 log INFO "Zone ${zone} was renamed to ${name}"
312 return ${EXIT_OK}
313 }
314
315
316 zone_destroy() {
317 local zone="${1}"
318
319 # Cannot delete a zone that does not exist
320 if ! zone_exists "${zone}"; then
321 log ERROR "Zone ${zone} does not exist"
322 return ${EXIT_ERROR}
323 fi
324
325 # Force the zone down.
326 zone_is_active "${zone}" && zone_stop "${zone}"
327
328 # Disable zone auto-start
329 zone_disable "${zone}"
330
331 if ! rm -rf "${NETWORK_ZONES_DIR}/${zone}"; then
332 log ERROR "Could not destroy zone ${zone}"
333 return ${EXIT_ERROR}
334 fi
335
336 log INFO "Destroyed zone ${zone}"
337 return ${EXIT_OK}
338 }
339
340 zone_up() {
341 local zone=${1}
342 shift
343
344 if ! zone_exists ${zone}; then
345 error "Zone '${zone}' does not exist."
346 return ${EXIT_ERROR}
347 fi
348
349 local hook="$(zone_get_hook "${zone}")"
350 if [ -z "${hook}" ]; then
351 error "Config file did not provide any hook."
352 return ${EXIT_ERROR}
353 fi
354
355 if ! hook_zone_exists ${hook}; then
356 error "Hook '${hook}' does not exist."
357 return ${EXIT_ERROR}
358 fi
359
360 zone_db ${zone} starting
361
362 hook_zone_exec ${hook} up ${zone} "$@"
363
364 zone_db ${zone} started
365
366 # Execute all triggers after the zone got up
367 triggers_execute_all "up" ZONE="${zone}"
368 }
369
370 zone_down() {
371 local zone=${1}
372 shift
373
374 if ! zone_exists ${zone}; then
375 error "Zone '${zone}' does not exist."
376 return ${EXIT_ERROR}
377 fi
378
379 local hook="$(zone_get_hook "${zone}")"
380 if [ -z "${hook}" ]; then
381 error "Config file did not provide any hook."
382 return ${EXIT_ERROR}
383 fi
384
385 if ! hook_zone_exists ${hook}; then
386 error "Hook '${hook}' does not exist."
387 return ${EXIT_ERROR}
388 fi
389
390 zone_db ${zone} stopping
391
392 hook_zone_exec ${hook} down ${zone} "$@"
393
394 zone_db ${zone} stopped
395
396 # Execute all triggers after the zone went down
397 triggers_execute_all "down" ZONE="${zone}"
398 }
399
400 zone_status() {
401 local zone="${1}"
402 assert isset zone
403 shift
404
405 if ! zone_exists "${zone}"; then
406 error "Zone '${zone}' does not exist."
407 return ${EXIT_ERROR}
408 fi
409
410 local hook="$(zone_get_hook "${zone}")"
411 if [ -z "${hook}" ]; then
412 error "Config file did not provide any hook."
413 return ${EXIT_ERROR}
414 fi
415
416 if ! hook_zone_exists "${hook}"; then
417 error "Hook '${hook}' does not exist."
418 return ${EXIT_ERROR}
419 fi
420
421 hook_zone_exec "${hook}" "status" "${zone}" "$@"
422 }
423
424 zone_identify() {
425 assert [ $# -ge 1 ]
426
427 local zone="${1}"
428 shift
429
430 assert zone_exists "${zone}"
431
432 log INFO "Identifying zone ${zone}"
433 local pids
434
435 local pid
436 local port
437 for port in $(zone_get_ports "${zone}"); do
438 # Identify all the ports
439 port_identify "${port}" --background "$@"
440
441 # Save the PIDs of the subprocesses
442 list_append pids "$(cmd_background_get_pid)"
443 done
444
445 # Wait until all port_identfy processes have finished
446 for pid in ${pids}; do
447 cmd_background_result "${pid}"
448 done
449
450 return ${EXIT_OK}
451 }
452
453 zone_get_ports() {
454 local zone=${1}
455
456 assert isset zone
457
458 local port
459 for port in $(list_directory "${NETWORK_ZONES_DIR}/${zone}/ports"); do
460 if port_exists "${port}"; then
461 echo "${port}"
462 fi
463 done
464 }
465
466 zone_get_ports_num() {
467 local zone="${1}"
468 assert isset zone
469
470 local counter=0
471 local port
472 for port in $(list_directory "${NETWORK_ZONES_DIR}/${zone}/ports"); do
473 if port_exists "${port}"; then
474 counter=$(( ${counter} + 1 ))
475 fi
476 done
477
478 echo "${counter}"
479 return ${EXIT_OK}
480 }
481
482 zone_has_port() {
483 # Check, if the given port is configured
484 # in this zone.
485
486 local zone=${1}
487 local port=${2}
488 shift 2
489
490 assert isset zone
491 assert isset port
492
493 [ -e "${NETWORK_ZONES_DIR}/${zone}/ports/${port}" ]
494 }
495
496 zone_config() {
497 local zone="${1}"
498 local cmd="${2}"
499 shift 2
500
501 assert isset zone
502 assert isset cmd
503 assert zone_exists "${zone}"
504
505 case "${cmd}" in
506 new)
507 zone_config_new "${zone}" "$@"
508 ;;
509 destroy)
510 # usually ${1} is a valid hid
511 local hid=${1}
512 shift 1
513
514 # We convert the hid into an id
515 local id=$(zone_config_convert_hid_to_id ${zone} ${hid})
516
517 # If id isset the hid is valid and we can go on with the id
518 if isset id; then
519 zone_config_destroy "${zone}" "${id}" "$@"
520
521 # If we can't get a valid hid we check if we got a valid id
522 else
523 if zone_config_id_is_valid ${zone} ${hid}; then
524 zone_config_destroy "${zone}" ${hid} "$@"
525 else
526 log ERROR "${id} is not a valid id or hid"
527 fi
528 fi
529 ;;
530 list)
531 zone_config_list "${zone}" "$@"
532 ;;
533 *)
534 # usually ${1} is a valid hid
535 local hid=${cmd}
536 local cmd=${1}
537 shift 1
538
539 local id=$(zone_config_convert_hid_to_id ${zone} ${hid})
540
541 # If id isset the hid is valid and we can go on with the id
542 if isset id && [[ ${cmd} == "edit" ]]; then
543 zone_config_edit "${zone}" "${id}" "$@"
544
545 # If we didn't get a valid hid we check if we got a valid id
546 else
547 if zone_config_id_is_valid ${zone} ${id} && [[ ${cmd} == "edit" ]]; then
548 shift 1
549 zone_config_edit "${zone}" "${id}" "$@"
550 else
551 # in ${hid} is saved the command after network zone ${zone} config
552 error "Unrecognized argument: ${hid}"
553 cli_usage root-zone-config-subcommands
554 exit ${EXIT_ERROR}
555 fi
556 fi
557 ;;
558 esac
559 }
560
561 zone_config_cmd() {
562 assert [ $# -gt 2 ]
563
564 local cmd="${1}"
565 local zone="${2}"
566 shift 2
567
568 local hook="$(zone_get_hook "${zone}")"
569 assert isset hook
570
571 hook_zone_exec "${hook}" "config_${cmd}" "${zone}" "$@"
572 }
573
574 zone_config_new() {
575 local zone="${1}"
576 shift
577
578 # Create a new configuration, but exit when that was
579 # not successful.
580 zone_config_cmd "new" "${zone}" "$@" || return ${?}
581
582 # If the config could be created, we will try to bring
583 # it up if the zone is up, too.
584 if zone_is_up "${zone}"; then
585 zone_configs_up "${zone}"
586 fi
587 }
588
589 zone_config_destroy() {
590 zone_config_cmd "destroy" "$@"
591 }
592
593 zone_config_edit() {
594 zone_config_cmd "edit" "$@"
595 }
596
597 zone_config_list() {
598 # This function list in an nice way all configs of a zone
599 local zone=${1}
600 assert isset zone
601
602 # Print a nice header
603 local format="%-3s %-20s %-20s"
604 print "${format}" "ID" "HOOK" "HID"
605
606 local config
607 local hook
608 local id
609 local hid
610
611 # Print for all config:
612 # id and hook
613 for config in $(zone_configs_list "${zone}"); do
614 id=${config##*.}
615 hook=$(zone_config_get_hook "${zone}" "${config}")
616 hid=$(zone_config_get_hid "${zone}" "${config}")
617 assert isset hook
618 print "${format}" "${id}" "${hook}" "${hid}"
619 done
620 }
621
622 # Returns a list of all used ids for a zone
623 zone_config_list_ids() {
624 assert [ $# -eq 1 ]
625
626 local zone=${1}
627 local config
628 local ids
629
630 for config in $(zone_configs_list ${zone}); do
631 list_append ids "$(config_get_id_from_config ${config})"
632 done
633
634 echo ${ids}
635 }
636
637 # List all hids of a zone
638 zone_config_list_hids() {
639 assert [ $# -eq 1 ]
640
641 local zone=${1}
642
643 local config
644 for config in $(zone_configs_list ${zone}); do
645 zone_config_get_hid "${zone}" "${config}"
646 done
647 }
648
649 # get the hid from a given config
650 zone_config_get_hid() {
651 assert [ $# -eq 2 ]
652
653 local zone=${1}
654 local config=${2}
655
656 local hook="$(zone_config_get_hook "${zone}" "${config}")"
657
658 hook_exec "config" "${hook}" "hid" "${zone}" "${config}"
659 }
660
661 # Checks if a hid is valid for a given zone
662 zone_config_hid_is_valid() {
663 assert [ $# -eq 2]
664
665 local zone=${1}
666 local hid=${2}
667
668 local _hid
669 for _hid in $(zone_config_list_hids "${zone}"); do
670 if [[ ${_hid} = ${hid} ]]; then
671 return ${EXIT_TRUE}
672 fi
673 done
674
675 return ${EXIT_FALSE}
676 }
677
678 # This function converts a hid to a id
679 zone_config_convert_hid_to_id() {
680 assert [ $# -eq 2 ]
681
682 local zone=${1}
683 local hid=${2}
684
685 local config
686 for config in $(zone_configs_list ${zone}); do
687 # Get hook from config
688 local hook="$(zone_config_get_hook "${zone}" "${config}")"
689
690 if [[ "$(hook_exec "config" "${hook}" "hid" "${zone}" "${config}")" == "${hid}" ]]; then
691 config_get_id_from_config "${config}"
692 return ${EXIT_TRUE}
693 fi
694 done
695
696 return ${EXIT_FALSE}
697 }
698
699 zones_get_all() {
700 local zone
701 for zone in $(list_directory "${NETWORK_ZONES_DIR}"); do
702 if zone_exists ${zone}; then
703 echo "${zone}"
704 fi
705 done
706 }
707
708 zones_get_next_free() {
709 # This function return the next free zones.
710 # Example net0 upl0 upl1 are configured so the next free zones are:
711 # net1 upl2
712 local i
713 local zone_name
714 for zone_name in ${VALID_ZONES}; do
715 i=0
716
717 while true; do
718 local zone="${zone_name}${i}"
719 if ! zone_exists ${zone}; then
720 echo "${zone}"
721 break
722 fi
723 i=$(( i + 1 ))
724 done
725 done
726 }
727
728 zones_get_local() {
729 local zone
730 for zone in $(zones_get_all); do
731 zone_is_local ${zone} && echo "${zone}"
732 done
733 }
734
735 zones_get_nonlocal() {
736 local zone
737 for zone in $(zones_get_all); do
738 zone_is_nonlocal ${zone} && echo "${zone}"
739 done
740 }
741
742 zones_get() {
743 local local=1
744 local remote=1
745
746 local zones
747
748 while [ $# -gt 0 ]; do
749 case "${1}" in
750 --local-only)
751 local=1
752 remote=0
753 ;;
754 --remote-only)
755 local=0
756 remote=1
757 ;;
758 --all)
759 local=1
760 remote=1
761 ;;
762 *)
763 if zone_name_is_valid ${1}; then
764 zones="${zones} ${1}"
765 else
766 warning "Unrecognized argument '${1}'"
767 fi
768 ;;
769 esac
770 shift
771 done
772
773 if [ -n "${zones}" ]; then
774 local zone
775 for zone in ${zones}; do
776 zone_exists ${zone} && echo "${zone}"
777 done
778 exit ${EXIT_OK}
779 fi
780
781 if [ ${local} -eq 1 ] && [ ${remote} -eq 1 ]; then
782 zones_get_all
783 elif [ ${local} -eq 1 ]; then
784 zones_get_local
785 elif [ ${remote} -eq 1 ]; then
786 zones_get_nonlocal
787 fi
788 }
789
790 zone_ports_list() {
791 local zone=${1}
792
793 list_directory "${NETWORK_ZONES_DIR}/${zone}/ports"
794 }
795
796 zone_port_attach() {
797 local zone="${1}"
798 assert isset zone
799
800 local port="${2}"
801 assert isset port
802
803 shift 2
804
805 # Check if the port actually exists.
806 if ! port_exists "${port}"; then
807 error "Cannot attach port '${port}' which does not exist"
808 return ${EXIT_ERROR}
809 fi
810
811 # Check if the port is already connected to this or any other zone.
812 local z
813 for z in $(zones_get_all); do
814 if zone_has_port "${z}" "${port}"; then
815 error "Port '${port}' is already attached to zone '${z}'"
816 return ${EXIT_ERROR}
817 fi
818 done
819
820 local hook="$(zone_get_hook "${zone}")"
821 assert isset hook
822
823 # Make the port briefly flash if supported
824 if device_exists ${port}; then
825 port_identify "${port}" --background
826 fi
827
828 hook_zone_exec "${hook}" "port_attach" "${zone}" "${port}" "$@"
829 local ret="${?}"
830
831 case "${ret}" in
832 ${EXIT_OK})
833 log INFO "${port} has been attached to ${zone}"
834
835 # Automatically connect the port
836 zone_port_start "${zone}" "${port}"
837 ;;
838 *)
839 log CRITICAL "${port} could not be attached to ${zone}"
840 ;;
841 esac
842
843 return ${ret}
844 }
845
846 zone_port_edit() {
847 local zone="${1}"
848 assert isset zone
849
850 local port="${2}"
851 assert isset port
852
853 shift 2
854
855 # Check if the port actually exists.
856 if ! port_exists "${port}"; then
857 error "Port '${port}' does not exist"
858 return ${EXIT_ERROR}
859 fi
860
861 # Check if the zone actually has this port.
862 if ! zone_has_port "${zone}" "${port}"; then
863 error "Port '${port}' is not attached to zone '${zone}'"
864 return ${EXIT_ERROR}
865 fi
866
867 local hook=$(zone_get_hook "${zone}")
868 assert isset hook
869
870 hook_zone_exec "${hook}" "port_edit" "${zone}" "${port}" "$@"
871 }
872
873 zone_port_detach() {
874 local zone="${1}"
875 assert isset zone
876
877 local port="${2}"
878 assert isset port
879
880 shift 2
881
882 # Check if the zone actually has this port.
883 if ! zone_has_port "${zone}" "${port}"; then
884 error "Port '${port}' is not attached to zone '${zone}'"
885 return ${EXIT_ERROR}
886 fi
887
888 local hook=$(zone_get_hook "${zone}")
889 assert isset hook
890
891 # Make the port briefly flash if supported
892 port_identify "${port}" --background
893
894 hook_zone_exec "${hook}" "port_detach" "${zone}" "${port}" "$@"
895 local ret="${?}"
896
897 case "${ret}" in
898 ${EXIT_OK})
899 log INFO "${port} has been detached from ${zone}"
900
901 # Bring down the port if needed
902 zone_port_stop "${zone}" "${port}"
903 ;;
904 *)
905 log CRITICAL "${port} could not be detached from ${zone}"
906 ;;
907 esac
908
909 return ${ret}
910 }
911
912 zone_port_cmd() {
913 local cmd="${1}"
914 assert isset cmd
915
916 local zone="${2}"
917 assert isset zone
918
919 local port="${3}"
920 assert isset port
921
922 shift 3
923
924 local hook="$(zone_get_hook "${zone}")"
925 assert isset hook
926
927 # Dispatch command to hook
928 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" "$@"
929 }
930
931 zone_port_create() {
932 zone_port_cmd "port_create" "$@"
933 }
934
935 zone_port_remove() {
936 zone_port_cmd "port_remove" "$@"
937 }
938
939 zone_port_up() {
940 zone_port_cmd "port_up" "$@"
941 }
942
943 zone_port_down() {
944 zone_port_cmd "port_down" "$@"
945 }
946
947 # The next two functions automagically bring up and down
948 # port that are attached to a bridge or similar.
949 # The problem that is tried to overcome here is that there
950 # are ports which exist all the time (like ethernet ports)
951 # and therefore do not dispatch a hotplug event when
952 # port_create is called.
953
954 zone_port_start() {
955 local zone="${1}"
956 local port="${2}"
957
958 if zone_is_active "${zone}"; then
959 if device_exists "${port}"; then
960 zone_port_up "${zone}" "${port}"
961 return ${?}
962 else
963 zone_port_create "${zone}" "${port}"
964 return ${?}
965 fi
966 fi
967
968 return ${EXIT_OK}
969 }
970
971 zone_port_stop() {
972 local zone="${1}"
973 local port="${2}"
974
975 # Shut down the port if necessary
976 if zone_is_active "${zone}" && port_is_up "${port}"; then
977 zone_port_down "${zone}" "${port}"
978 fi
979
980 # Remove the port
981 zone_port_remove "${zone}" "${port}"
982 }
983
984 zone_port_status() {
985 zone_port_cmd "port_status" "$@"
986 }
987
988 zone_ports_cmd() {
989 local cmd="${1}"
990 assert isset cmd
991
992 local zone="${2}"
993 assert isset zone
994
995 shift 2
996
997 local hook="$(zone_get_hook "${zone}")"
998
999 local port
1000 for port in $(zone_get_ports ${zone}); do
1001 hook_zone_exec "${hook}" "${cmd}" "${zone}" "${port}" "$@"
1002 done
1003 }
1004
1005 zone_ports_create() {
1006 zone_ports_cmd "port_create" "$@"
1007 }
1008
1009 zone_ports_remove() {
1010 zone_ports_cmd "port_remove" "$@"
1011 }
1012
1013 zone_ports_up() {
1014 zone_ports_cmd "port_up" "$@"
1015 }
1016
1017 zone_ports_down() {
1018 zone_ports_cmd "port_down" "$@"
1019 }
1020
1021 zone_ports_status() {
1022 zone_ports_cmd "port_status" "$@"
1023 }
1024
1025 zone_configs_cmd() {
1026 assert [ $# -ge 2 ]
1027
1028 local cmd="${1}"
1029 local zone="${2}"
1030 shift 2
1031
1032 assert zone_exists "${zone}"
1033
1034 local config
1035 for config in $(zone_configs_list "${zone}"); do
1036 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1037 assert isset config_hook
1038
1039 hook_config_exec "${config_hook}" "${cmd}" "${zone}" "${config}" "$@"
1040 done
1041 }
1042
1043 zone_configs_up() {
1044 zone_configs_cmd "up" "$@"
1045 }
1046
1047 zone_configs_down() {
1048 zone_configs_cmd "down" "$@"
1049 }
1050
1051 zone_configs_status() {
1052 zone_configs_cmd "status" "$@"
1053 }
1054
1055 zone_configs_list() {
1056 local zone=${1}
1057
1058 list_directory "${NETWORK_ZONES_DIR}/${zone}/configs"
1059 }
1060
1061 zone_config_get_new_id() {
1062 # This functions returns the next free id for a zone
1063
1064 assert [ $# -eq 1 ]
1065 local zone=${1}
1066
1067 local zone_path="${NETWORK_ZONES_DIR}/${zone}"
1068 local i=0
1069
1070 while true; do
1071 if [ ! -f ${zone_path}/configs/*.${i} ]; then
1072 echo "${i}"
1073 return ${EXIT_OK}
1074 fi
1075 (( i++ ))
1076 done
1077 }
1078
1079 zone_config_check_same_setting() {
1080 # This functions checks if a config hook
1081 # with the same setting is already configured for this zone.
1082 # Returns True when yes and False when no.
1083
1084 assert [ $# -eq 5 ]
1085
1086 local zone=${1}
1087 local hook=${2}
1088 local id=${3}
1089 local key=${4}
1090 local value=${5}
1091
1092 # The key should be local for this function
1093 local ${key}
1094 local config
1095
1096 for config in $(zone_configs_list ${zone}); do
1097 # Check if the config is eqal with the config we want to edit, when continue
1098 if [[ "${config}" = "${hook}.${id}" ]]; then
1099 continue
1100 fi
1101
1102 # Check if the config is from the given hook, when not continue
1103 if [[ $(zone_config_get_hook "${zone}" "${config}") != ${hook} ]]; then
1104 continue
1105 fi
1106
1107 # Get the value of the key for a given function
1108 zone_config_settings_read "${zone}" "${config}" \
1109 --ignore-superfluous-settings "${key}"
1110 # Check if the value of the config and the passed value are eqal
1111 if [[ "${value}" == "${!key}" ]]; then
1112 return ${EXIT_TRUE}
1113 fi
1114 done
1115
1116 return ${EXIT_FALSE}
1117 }
1118
1119 zone_config_get_hook() {
1120 assert [ $# -eq 2 ]
1121
1122 local zone="${1}"
1123 assert isset zone
1124
1125 local config="${2}"
1126 assert isset config
1127
1128 local HOOK
1129 zone_config_settings_read "${zone}" "${config}" \
1130 --ignore-superfluous-settings HOOK
1131
1132 print "${HOOK}"
1133 }
1134
1135 zone_config_hook_is_configured() {
1136 # Checks if a zone has already at least one config with the given hook.
1137 # Returns True when yes and False when no
1138
1139 assert [ $# -eq 2 ]
1140 local zone=${1}
1141 local hook=${2}
1142
1143 local config
1144 for config in $(zone_configs_list "${zone}"); do
1145 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1146 assert isset config_hook
1147 if [[ ${hook} == ${config_hook} ]]; then
1148 return ${EXIT_TRUE}
1149 fi
1150
1151 done
1152
1153 # If we get here the zone has no config with the given hook
1154 return ${EXIT_FALSE}
1155 }
1156
1157 zone_config_id_is_valid() {
1158 # This function checks if a given id is valid for a zone
1159 # Return True when yes and false when no
1160
1161 assert [ $# -eq 2 ]
1162 local zone=${1}
1163 local id=${2}
1164
1165 local zone_path="${NETWORK_ZONES_DIR}/${zone}"
1166
1167 [ -f ${zone_path}/configs/*.${id} ];
1168 }
1169
1170 # This function checks if a given hid is valid for a zone
1171 # Return True when yes and false when no
1172 zone_config_hid_is_valid() {
1173 assert [ $# -eq 2 ]
1174 local zone=${1}
1175 local hid=${2}
1176
1177 local _hid
1178 for _hid in $(zone_config_list_hids ${zone}); do
1179 if [[ ${_hid} == ${hid} ]]; then
1180 return ${EXIT_TRUE}
1181 fi
1182 done
1183
1184 return ${EXIT_FALSE}
1185 }
1186
1187 zone_config_get_hook_from_id() {
1188 # Returns the hook for a given id
1189 assert [ $# -eq 2 ]
1190 local zone=${1}
1191 local id=${2}
1192
1193 local config
1194 for config in $(zone_configs_list "${zone}"); do
1195 if [[ ${config} == *.${id} ]]; then
1196 local config_hook="$(zone_config_get_hook "${zone}" "${config}")"
1197 assert isset config_hook
1198 print "${config_hook}"
1199 return "${EXIT_OK}"
1200 fi
1201 done
1202
1203 # If we get here the zone has no config with the given id
1204 return ${EXIT_ERROR}
1205 }
1206
1207 zone_has_ip() {
1208 device_has_ip "$@"
1209 }
1210
1211 zone_db() {
1212 local zone=${1}
1213 local action=${2}
1214 shift 2
1215
1216 case "${action}" in
1217 starting|started|stopping|stopped)
1218 db_connection_update ${zone} ${action}
1219 ;;
1220 esac
1221 }
1222
1223 zone_is_up() {
1224 local zone=${1}
1225
1226 device_is_up ${zone}
1227 }
1228
1229 zone_is_down() {
1230 ! zone_is_up "$@"
1231 }
1232
1233 zone_get_supported_port_hooks() {
1234 local zone=${1}
1235
1236 local hook=$(zone_get_hook ${zone})
1237
1238 hook_zone_ports_get_all ${hook}
1239 }
1240
1241 zone_get_supported_config_hooks() {
1242 hook_config_get_all
1243 }
1244
1245 zone_settings_read() {
1246 local zone=${1}
1247 assert isset zone
1248 shift
1249
1250 local args
1251 if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS[*]}" ]; then
1252 list_append args ${HOOK_SETTINGS[*]}
1253 else
1254 list_append args "$@"
1255 fi
1256
1257 # Save the HOOK variable.
1258 local hook="${HOOK}"
1259
1260 settings_read "${NETWORK_ZONES_DIR}/${zone}/settings" ${args}
1261
1262 # Restore hook.
1263 HOOK="${hook}"
1264 }
1265
1266 zone_settings_write() {
1267 local zone="${1}"
1268 assert isset zone
1269
1270 settings_write "${NETWORK_ZONES_DIR}/${zone}/settings" \
1271 --check="hook_check_settings" HOOK ${HOOK_SETTINGS[*]}
1272 }
1273
1274 zone_settings_set() {
1275 local zone=${1}
1276 shift
1277 local args="$@"
1278
1279 assert isset zone
1280
1281 (
1282 zone_settings_read ${zone}
1283
1284 for arg in ${args}; do
1285 eval "${arg}"
1286 done
1287
1288 zone_settings_write ${zone}
1289 )
1290 }
1291
1292 zone_settings_get() {
1293 local zone=${1}
1294 local key=${2}
1295
1296 assert isset zone
1297 assert isset key
1298
1299 (
1300 zone_settings_read "${zone}" "${key}" \
1301 --ignore-superfluous-settings
1302
1303 echo "${!key}"
1304 )
1305 }
1306
1307 zone_config_settings_read() {
1308 assert [ $# -ge 2 ]
1309
1310 local zone="${1}"
1311 local config="${2}"
1312 shift 2
1313
1314 local args
1315 if [ $# -eq 0 ] && [ -n "${HOOK_SETTINGS[*]}" ]; then
1316 list_append args ${HOOK_SETTINGS[*]}
1317 else
1318 list_append args "$@"
1319 fi
1320
1321 local path="${NETWORK_ZONES_DIR}/${zone}/configs/${config}"
1322 settings_read "${path}" ${args}
1323 }
1324
1325 zone_config_settings_write() {
1326 assert [ $# -eq 3 ]
1327
1328 local zone="${1}"
1329 local hook="${2}"
1330 local id=${3}
1331
1332 assert isset id
1333
1334 local path="${NETWORK_ZONES_DIR}/${zone}/configs/${hook}.${id}"
1335 settings_write "${path}" \
1336 --check="hook_check_config_settings" HOOK ${HOOK_SETTINGS[*]}
1337 }
1338
1339 zone_config_settings_destroy() {
1340 # This function deletes the config file for a given zone and config
1341 assert [ $# -ge 2 ]
1342 local zone="${1}"
1343 local config="${2}"
1344
1345 local path="${NETWORK_ZONES_DIR}/${zone}/configs/${config}"
1346
1347 # Check if path is valid
1348 if [ ! -f ${path} ]; then
1349 log ERROR "Path: '${path}' is not valid"
1350 return ${EXIT_ERROR}
1351 fi
1352
1353 log DEBUG "Deleting config file ${path}"
1354 rm -f "${path}"
1355
1356 }
1357
1358 zone_config_find_by_hook() {
1359 local zone="${1}"
1360 assert isset zone
1361
1362 local hook="${2}"
1363 assert isset hook
1364
1365 local config
1366 for config in $(zone_configs_list "${zone}"); do
1367 local h="$(zone_config_get_hook "${zone}" "${config}")"
1368
1369 [[ "${hook}" = "${h}" ]] && echo "${config}"
1370 done
1371
1372 return ${EXIT_OK}
1373 }
1374
1375 zone_config_settings_read_by_hook() {
1376 local zone="${1}"
1377 assert isset zone
1378
1379 local hook="${2}"
1380 assert isset hook
1381
1382 local config
1383 for config in $(zone_config_find_by_hook "${zone}" "${hook}"); do
1384 zone_config_settings_read "${zone}" "${config}"
1385 done
1386
1387 return ${EXIT_OK}
1388 }
1389
1390 zone_port_settings_read() {
1391 assert [ $# -ge 2 ]
1392
1393 local zone="${1}"
1394 local port="${2}"
1395 shift 2
1396
1397 local args
1398 if [ $# -eq 0 ] && [ -n "${HOOK_PORT_SETTINGS}" ]; then
1399 list_append args ${HOOK_PORT_SETTINGS}
1400 else
1401 list_append args "$@"
1402 fi
1403
1404 local path="${NETWORK_ZONES_DIR}/${zone}/ports/${port}"
1405 settings_read "${path}" ${args}
1406 }
1407
1408 zone_port_settings_write() {
1409 assert [ $# -eq 2 ]
1410
1411 local zone="${1}"
1412 local port="${2}"
1413
1414 local path="${NETWORK_ZONES_DIR}/${zone}/ports/${port}"
1415 settings_write "${path}" \
1416 --check="hook_check_port_settings" ${HOOK_PORT_SETTINGS[*]}
1417 }
1418
1419 zone_port_settings_remove() {
1420 assert [ $# -eq 2 ]
1421
1422 local zone="${1}"
1423 local port="${2}"
1424
1425 local path="${NETWORK_ZONES_DIR}/${zone}/ports/${port}"
1426 settings_remove "${path}"
1427 }
1428
1429 zone_get_color() {
1430 # This function return the color of a zone
1431 assert [ $# -eq 1 ]
1432
1433 local name=${1}
1434 color_read "zone" ${name}
1435 }
1436
1437 zone_get_description_title() {
1438 assert [ $# -eq 1 ]
1439
1440 local name=${1}
1441 description_title_read $(description_format_filename "zone" "${name}")
1442 }