- flag::define: variadic constraint args (key:value) instead of bracket string - flag::_parse_constraints_from_args: replaces flag::_parse_and_cache - flag::set_constraint: Option B syntax for post-definition constraints - choices separator: comma (choices:split,full) — no quoting needed - guard against empty _CURRENT_COMMAND in exclusive groups lookup - migrate all commands to new constraint syntax - add helpful error for unknown constraint args
169 lines
No EOL
5.2 KiB
Bash
169 lines
No EOL
5.2 KiB
Bash
#!/usr/bin/env bash
|
|
# commands/config/helpers.sh
|
|
|
|
function cmd::config::_migrate_impl() {
|
|
local force="$1" dry_run="$2"
|
|
|
|
local wgctl_dir; wgctl_dir="$(ctx::wgctl)"
|
|
local config_dir="${wgctl_dir}/config"
|
|
local data_dir="${wgctl_dir}/data"
|
|
local legacy_conf="${wgctl_dir}/wgctl.conf"
|
|
local json_conf="${config_dir}/wgctl.json"
|
|
|
|
if [[ -f "$json_conf" && ! -f "$legacy_conf" ]]; then
|
|
log::wg_warning "Already migrated to new config structure"
|
|
return 0
|
|
fi
|
|
|
|
log::section "wgctl Config Migration"
|
|
printf "\n"
|
|
printf " This will:\n"
|
|
printf " 1. Create %s/config/ and %s/data/\n" "$wgctl_dir" "$wgctl_dir"
|
|
printf " 2. Convert wgctl.conf → wgctl.json\n"
|
|
printf " 3. Move data files to data/\n\n"
|
|
|
|
if [[ "$force" != "true" && "$dry_run" != "true" ]]; then
|
|
read -r -p " Proceed? [y/N] " confirm
|
|
case "$confirm" in [yY]*) ;; *) log::info "Aborted"; return 0 ;; esac
|
|
fi
|
|
|
|
$dry_run || mkdir -p "$config_dir" "$data_dir"
|
|
$dry_run && printf " Would create: %s/config/\n" "$wgctl_dir"
|
|
$dry_run && printf " Would create: %s/data/\n" "$wgctl_dir"
|
|
|
|
if [[ -f "$legacy_conf" ]]; then
|
|
$dry_run || config::_convert_to_json "$legacy_conf" "$json_conf"
|
|
printf " %s wgctl.conf → config/wgctl.json\n" \
|
|
"$($dry_run && echo '[dry-run]' || echo '✓')"
|
|
else
|
|
log::wg_warning "No wgctl.conf found — creating default wgctl.json"
|
|
$dry_run || config::_write_default_json "$json_conf"
|
|
fi
|
|
|
|
local -a data_files=(hosts.json services.json subnets.json policies.json)
|
|
local -a data_dirs=(rules identities groups blocks meta peer-history)
|
|
|
|
for f in "${data_files[@]}"; do
|
|
if [[ -f "${wgctl_dir}/${f}" ]]; then
|
|
$dry_run || mv "${wgctl_dir}/${f}" "${data_dir}/${f}"
|
|
printf " %s %s → data/%s\n" \
|
|
"$($dry_run && echo '[dry-run]' || echo '✓')" "$f" "$f"
|
|
fi
|
|
done
|
|
|
|
for d in "${data_dirs[@]}"; do
|
|
if [[ -d "${wgctl_dir}/${d}" ]]; then
|
|
$dry_run || mv "${wgctl_dir}/${d}" "${data_dir}/${d}"
|
|
printf " %s %s/ → data/%s/\n" \
|
|
"$($dry_run && echo '[dry-run]' || echo '✓')" "$d" "$d"
|
|
fi
|
|
done
|
|
|
|
if [[ "$dry_run" != "true" && -f "$legacy_conf" ]]; then
|
|
mv "$legacy_conf" "${legacy_conf}.bak"
|
|
printf " ✓ wgctl.conf → wgctl.conf.bak (backup)\n"
|
|
fi
|
|
|
|
printf "\n"
|
|
[[ "$dry_run" == "true" ]] \
|
|
&& log::wg_warning "Dry run — no changes made" \
|
|
|| log::wg_success "Migration complete"
|
|
}
|
|
|
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
|
|
|
function config::_convert_to_json() {
|
|
local legacy_file="$1" output_file="$2"
|
|
|
|
# Read legacy conf into variables
|
|
local wg_interface="wg0" wg_endpoint="" wg_dns="10.0.0.103"
|
|
local wg_dns_fallback="" wg_port="51820" wg_subnet="10.1.0.0/16"
|
|
local wg_lan="10.0.0.0/24" wg_hs_check="300" date_format="eu"
|
|
|
|
while IFS='=' read -r key value || [[ -n "$key" ]]; do
|
|
[[ "$key" =~ ^[[:space:]]*# ]] && continue
|
|
[[ -z "${key// }" ]] && continue
|
|
key="${key// /}"
|
|
value="${value// /}"
|
|
case "$key" in
|
|
WG_INTERFACE) wg_interface="$value" ;;
|
|
WG_ENDPOINT) wg_endpoint="$value" ;;
|
|
WG_DNS) wg_dns="$value" ;;
|
|
WG_DNS_FALLBACK) wg_dns_fallback="$value" ;;
|
|
WG_PORT) wg_port="$value" ;;
|
|
WG_SUBNET) wg_subnet="$value" ;;
|
|
WG_LAN) wg_lan="$value" ;;
|
|
WG_HANDSHAKE_CHECK_TIME_SEC) wg_hs_check="$value" ;;
|
|
DATE_FORMAT) date_format="$value" ;;
|
|
esac
|
|
done < "$legacy_file"
|
|
|
|
# Build fallback DNS array
|
|
local dns_fallback_json="[]"
|
|
if [[ -n "$wg_dns_fallback" ]]; then
|
|
local fallback_array
|
|
fallback_array=$(echo "$wg_dns_fallback" | tr ',' '\n' | \
|
|
while IFS= read -r s; do
|
|
s="${s// /}"
|
|
[[ -n "$s" ]] && printf '"%s",' "$s"
|
|
done | sed 's/,$//')
|
|
dns_fallback_json="[${fallback_array}]"
|
|
fi
|
|
|
|
mkdir -p "$(dirname "$output_file")"
|
|
cat > "$output_file" << JSON
|
|
{
|
|
"wireguard": {
|
|
"interface": "${wg_interface}",
|
|
"endpoint": "${wg_endpoint}",
|
|
"port": ${wg_port},
|
|
"subnet": "${wg_subnet}",
|
|
"lan": "${wg_lan}"
|
|
},
|
|
"dns": {
|
|
"primary": "${wg_dns}",
|
|
"fallback": ${dns_fallback_json}
|
|
},
|
|
"handshake": {
|
|
"check_interval_sec": ${wg_hs_check}
|
|
},
|
|
"activity": {
|
|
"total": {"low": 1000000, "medium": 10000000, "high": 100000000},
|
|
"current": {"low": 1000000, "medium": 10000000, "high": 100000000}
|
|
},
|
|
"display": {
|
|
"date_format": "${date_format}"
|
|
}
|
|
}
|
|
JSON
|
|
}
|
|
|
|
function config::_write_default_json() {
|
|
local output_file="$1"
|
|
mkdir -p "$(dirname "$output_file")"
|
|
cat > "$output_file" << 'JSON'
|
|
{
|
|
"wireguard": {
|
|
"interface": "wg0",
|
|
"endpoint": "",
|
|
"port": 51820,
|
|
"subnet": "10.1.0.0/16",
|
|
"lan": "10.0.0.0/24"
|
|
},
|
|
"dns": {
|
|
"primary": "10.0.0.103",
|
|
"fallback": []
|
|
},
|
|
"handshake": {
|
|
"check_interval_sec": 300
|
|
},
|
|
"activity": {
|
|
"total": {"low": 1000000, "medium": 10000000, "high": 100000000},
|
|
"current": {"low": 1000000, "medium": 10000000, "high": 100000000}
|
|
},
|
|
"display": {
|
|
"date_format": "eu"
|
|
}
|
|
}
|
|
JSON
|
|
} |