gistfile1.txt
· 3.5 KiB · Text
Исходник
function cmd::add::run() {
local name=""
local type=""
local subtype=""
local rule=""
local ip=""
local tunnel=""
local guest=false
local presets=()
local show_config=false
local show_qr=false
# Parse flags
while [[ $# -gt 0 ]]; do
case "$1" in
--name) name="$2"; shift 2 ;;
--type) type="$2"; shift 2 ;;
--subtype) subtype="$2"; shift 2 ;;
--rule) rule="$2"; shift 2 ;;
--ip) ip="$2"; shift 2 ;;
--preset) presets+=("$2"); shift 2 ;;
--guest) guest=true; shift ;;
--tunnel) tunnel="$2"; shift 2 ;;
--show-config) show_config=true; shift ;;
--show-qr) show_qr=true; shift ;;
--help) cmd::add::help; return ;;
*)
log::error "Unknown flag: $1"
cmd::add::help
return 1
;;
esac
done
# --guest shorthand
if $guest; then
type="guest"
fi
# Resolve guest subtype
local effective_type="$type"
if [[ "$type" == "guest" && -n "$subtype" ]]; then
# Validate subtype
local valid_subtypes="desktop laptop phone tablet"
if ! echo "$valid_subtypes" | grep -qw "$subtype"; then
log::error "Invalid subtype: ${subtype} (valid: desktop, laptop, phone, tablet)"
return 1
fi
effective_type="guest-${subtype}"
fi
# Build full client name
local full_name="${type}-${name}"
# Validate
cmd::add::validate "$name" "$type" "$ip" "$tunnel" || return 1
# Resolve tunnel mode — flag > device default
if [[ -z "$tunnel" ]]; then
tunnel=$(config::default_tunnel_for "$type")
fi
# Determine rule — explicit flag > type default
if [[ -z "$rule" ]]; then
if config::is_guest_type "$type"; then
rule="guest"
else
rule="user"
fi
fi
# Validate rule if specified
if ! rule::exists "$rule"; then
log::error "Rule not found: ${rule}"
return 1
fi
local allowed_ips
allowed_ips=$(config::allowed_ips_for "$effective_type" "$tunnel") || return 1
log::section "Adding client: ${full_name}"
# Auto-assign IP if not provided
if [[ -z "$ip" ]]; then
ip=$(ip::next_for_type "$effective_type") || return 1
fi
log::wg_add "Name: ${full_name}"
log::wg_add "Type: ${type}"
log::wg_add "IP: ${ip}"
log::wg_add "Tunnel: ${tunnel} (${allowed_ips})"
# Generate keys
keys::generate_pair "$full_name" || return 1
# Create client config
peers::create_client_config "$full_name" "$effective_type" "$ip" "$allowed_ips" || return 1
# Store subtype in meta
if [[ -n "$subtype" ]]; then
peers::set_meta "$full_name" "subtype" "$subtype"
fi
# Add peer to server config
local public_key
public_key=$(keys::public "$full_name") || return 1
peers::add_to_server "$full_name" "$public_key" "$ip" || return 1
log::wg_add "Rule: ${rule:-none}"
# Apply presets
for preset in "${presets[@]}"; do
fw::apply_preset "$preset" "${ip}" || return 1
done
# Apply rule
if [[ -n "$rule" ]]; then
rule::apply "$rule" "$ip" || return 1
fi
# Reload WireGuard
peers::reload || return 1
log::wg_success "Client added successfully: ${full_name} (${ip}) [${tunnel} tunnel]"
# Show QR for mobile by default, config for desktop/laptop
local display_type="${subtype:-$type}"
if cmd::add::is_mobile "$display_type"; then
keys::qr "$full_name"
else
log::section "Client Config"
cat "$(ctx::clients)/${full_name}.conf"
fi
}
| 1 | function cmd::add::run() { |
| 2 | local name="" |
| 3 | local type="" |
| 4 | local subtype="" |
| 5 | local rule="" |
| 6 | local ip="" |
| 7 | local tunnel="" |
| 8 | local guest=false |
| 9 | local presets=() |
| 10 | local show_config=false |
| 11 | local show_qr=false |
| 12 | |
| 13 | # Parse flags |
| 14 | while [[ $# -gt 0 ]]; do |
| 15 | case "$1" in |
| 16 | --name) name="$2"; shift 2 ;; |
| 17 | --type) type="$2"; shift 2 ;; |
| 18 | --subtype) subtype="$2"; shift 2 ;; |
| 19 | --rule) rule="$2"; shift 2 ;; |
| 20 | --ip) ip="$2"; shift 2 ;; |
| 21 | --preset) presets+=("$2"); shift 2 ;; |
| 22 | --guest) guest=true; shift ;; |
| 23 | --tunnel) tunnel="$2"; shift 2 ;; |
| 24 | --show-config) show_config=true; shift ;; |
| 25 | --show-qr) show_qr=true; shift ;; |
| 26 | --help) cmd::add::help; return ;; |
| 27 | *) |
| 28 | log::error "Unknown flag: $1" |
| 29 | cmd::add::help |
| 30 | return 1 |
| 31 | ;; |
| 32 | esac |
| 33 | done |
| 34 | |
| 35 | # --guest shorthand |
| 36 | if $guest; then |
| 37 | type="guest" |
| 38 | fi |
| 39 | |
| 40 | # Resolve guest subtype |
| 41 | local effective_type="$type" |
| 42 | if [[ "$type" == "guest" && -n "$subtype" ]]; then |
| 43 | # Validate subtype |
| 44 | local valid_subtypes="desktop laptop phone tablet" |
| 45 | if ! echo "$valid_subtypes" | grep -qw "$subtype"; then |
| 46 | log::error "Invalid subtype: ${subtype} (valid: desktop, laptop, phone, tablet)" |
| 47 | return 1 |
| 48 | fi |
| 49 | effective_type="guest-${subtype}" |
| 50 | fi |
| 51 | |
| 52 | # Build full client name |
| 53 | local full_name="${type}-${name}" |
| 54 | |
| 55 | # Validate |
| 56 | cmd::add::validate "$name" "$type" "$ip" "$tunnel" || return 1 |
| 57 | |
| 58 | # Resolve tunnel mode — flag > device default |
| 59 | if [[ -z "$tunnel" ]]; then |
| 60 | tunnel=$(config::default_tunnel_for "$type") |
| 61 | fi |
| 62 | |
| 63 | # Determine rule — explicit flag > type default |
| 64 | if [[ -z "$rule" ]]; then |
| 65 | if config::is_guest_type "$type"; then |
| 66 | rule="guest" |
| 67 | else |
| 68 | rule="user" |
| 69 | fi |
| 70 | fi |
| 71 | |
| 72 | # Validate rule if specified |
| 73 | if ! rule::exists "$rule"; then |
| 74 | log::error "Rule not found: ${rule}" |
| 75 | return 1 |
| 76 | fi |
| 77 | |
| 78 | local allowed_ips |
| 79 | allowed_ips=$(config::allowed_ips_for "$effective_type" "$tunnel") || return 1 |
| 80 | |
| 81 | log::section "Adding client: ${full_name}" |
| 82 | |
| 83 | # Auto-assign IP if not provided |
| 84 | if [[ -z "$ip" ]]; then |
| 85 | ip=$(ip::next_for_type "$effective_type") || return 1 |
| 86 | fi |
| 87 | |
| 88 | log::wg_add "Name: ${full_name}" |
| 89 | log::wg_add "Type: ${type}" |
| 90 | log::wg_add "IP: ${ip}" |
| 91 | log::wg_add "Tunnel: ${tunnel} (${allowed_ips})" |
| 92 | |
| 93 | # Generate keys |
| 94 | keys::generate_pair "$full_name" || return 1 |
| 95 | |
| 96 | # Create client config |
| 97 | peers::create_client_config "$full_name" "$effective_type" "$ip" "$allowed_ips" || return 1 |
| 98 | |
| 99 | # Store subtype in meta |
| 100 | if [[ -n "$subtype" ]]; then |
| 101 | peers::set_meta "$full_name" "subtype" "$subtype" |
| 102 | fi |
| 103 | |
| 104 | # Add peer to server config |
| 105 | local public_key |
| 106 | public_key=$(keys::public "$full_name") || return 1 |
| 107 | peers::add_to_server "$full_name" "$public_key" "$ip" || return 1 |
| 108 | |
| 109 | log::wg_add "Rule: ${rule:-none}" |
| 110 | |
| 111 | # Apply presets |
| 112 | for preset in "${presets[@]}"; do |
| 113 | fw::apply_preset "$preset" "${ip}" || return 1 |
| 114 | done |
| 115 | |
| 116 | # Apply rule |
| 117 | if [[ -n "$rule" ]]; then |
| 118 | rule::apply "$rule" "$ip" || return 1 |
| 119 | fi |
| 120 | |
| 121 | # Reload WireGuard |
| 122 | peers::reload || return 1 |
| 123 | |
| 124 | log::wg_success "Client added successfully: ${full_name} (${ip}) [${tunnel} tunnel]" |
| 125 | |
| 126 | # Show QR for mobile by default, config for desktop/laptop |
| 127 | local display_type="${subtype:-$type}" |
| 128 | |
| 129 | if cmd::add::is_mobile "$display_type"; then |
| 130 | keys::qr "$full_name" |
| 131 | else |
| 132 | log::section "Client Config" |
| 133 | cat "$(ctx::clients)/${full_name}.conf" |
| 134 | fi |
| 135 | } |