#!/usr/bin/env bash # ============================================ # Lifecycle # ============================================ function cmd::rename::on_load() { flag::register --name flag::register --type flag::register --new-name flag::register --new-type } # ============================================ # Help # ============================================ function cmd::rename::help() { cat < --new-name Rename an existing WireGuard client. The client IP and keys are preserved, only the name changes. Options: --name Current client name (e.g. phone-phone-nuno) --new-name New client name (e.g. phone-nuno) Examples: wgctl rename --name phone-phone-nuno --new-name phone-nuno wgctl mv --name laptop-old --new-name laptop-nuno EOF } # ============================================ # Run # ============================================ function cmd::rename::run() { local name="" local type="" local new_name="" local new_type="" while [[ $# -gt 0 ]]; do case "$1" in --name) name="$2"; shift 2 ;; --type) type="$2"; shift 2 ;; --new-name) new_name="$2"; shift 2 ;; --new-type) new_type="$2"; shift 2 ;; --help) cmd::rename::help; return ;; *) log::error "Unknown flag: $1" cmd::rename::help return 1 ;; esac done if [[ -z "$name" ]]; then log::error "Missing required flag: --name" cmd::rename::help return 1 fi if [[ -z "$new_name" ]]; then log::error "Missing required flag: --new-name" cmd::rename::help return 1 fi name=$(peers::resolve_and_require "$name" "$type") || return 1 # Resolve new name if provided if [[ -n "$new_name" || -n "$new_type" ]]; then # If only new_type provided, keep same base name if [[ -z "$new_name" ]]; then new_name=$(echo "$name" | cut -d'-' -f2-) fi new_name=$(peers::resolve_name "$new_name" "$new_type") || return 1 fi local dir dir="$(ctx::clients)" if [[ ! -f "${dir}/${name}.conf" ]]; then log::error "Client not found: ${name}" return 1 fi if [[ -f "${dir}/${new_name}.conf" ]]; then log::error "Client already exists: ${new_name}" return 1 fi log::section "Renaming client: ${name} → ${new_name}" # Rename client files mv "${dir}/${name}.conf" "${dir}/${new_name}.conf" mv "${dir}/${name}_private.key" "${dir}/${new_name}_private.key" mv "${dir}/${name}_public.key" "${dir}/${new_name}_public.key" log::fs_write "Renamed client files" # Update comment in wg0.conf sed -i "s/^# ${name}$/# ${new_name}/" "$(config::config_file)" log::fs_write "Updated server config" # Update block file if exists local block_file block_file="$(ctx::block::path "${name}.block")" if [[ -f "$block_file" ]]; then mv "$block_file" "$(ctx::block::path "${new_name}.block")" log::fs_write "Renamed block file" fi local old_meta new_meta old_meta=$(peers::meta_path "$name") new_meta=$(peers::meta_path "$new_name") [[ -f "$old_meta" ]] && mv "$old_meta" "$new_meta" # Reload WireGuard peers::reload log::wg_success "Client renamed: ${name} → ${new_name}" }