@@ -546,12 +546,19 @@ Safe to rerun.
546546```bash
547547nebius-vpngw create-from-peer-config my-vpn.config.yaml \
548548 --peer-config-file gcp-peer.txt \
549- --peer-config-file aws-peer.xml
549+ --peer-config-file branch-office.csv
550550```
551551
552552If the generated output already matches the existing file, rerunning the command
553553is a no-op and exits successfully.
554554
555+ Supported peer input formats:
556+
557+ - `.txt`: free-form text, exported vendor configs, and config snippets
558+ - `.csv`: one row per tunnel; rows with the same `connection_name` + `vendor` are grouped
559+ - `.json`
560+ - `.yaml` / `.yml`
561+
555562### Deployment
556563
557564**Deploy or update:**
@@ -954,26 +961,61 @@ nebius-vpngw list-routes-remote --local-config-file <file>
954961
955962## Peer Integration
956963
957- ### Supported Vendors
964+ ### Supported Peer Inputs
958965
959- - **GCP HA VPN:** Cloud Router config exports
960- - **AWS Site-to-Site VPN:** Downloadable config files
961- - **Azure VPN Gateway:** Exported configurations
962- - **Cisco IOS:** IOS config snippets
966+ - **Text (`.txt`)**: vendor exports, router snippets, and key/value documents
967+ - **CSV (`.csv`)**: one row per tunnel; rows with the same `connection_name` + `vendor` are grouped
968+ - **JSON**
969+ - **YAML (`.yaml` / `.yml`)**
970+
971+ Vendor detection is best-effort and currently recognizes **GCP**, **AWS**, **Azure**, and **Cisco**. If nothing matches, the importer falls back to `vendor: generic`.
963972
964973### Import Workflow
965974
966975```bash
967976nebius-vpngw create-from-peer-config nebius-vpn.config.yaml \
968- --peer-config-file gcp-peer.txt \
969- --peer-config-file aws-peer.xml
977+ --peer-config-file gcp-peer.txt
970978```
971979
972- **Merge behavior:**
980+ `create-from-peer-config` now builds `connections:` from parsed peer specs instead of reusing the template' s fixed sample topology. The generated file is validated against the schema before it is written.
981+
982+ # ## Keyword Matching
983+
984+ The importer normalizes input keys and matches them against a keyword list. These aliases work across CSV headers, JSON/YAML keys, and ` key: value` / ` key = value` text.
985+
986+ | Target field | Accepted keywords |
987+ | --- | --- |
988+ | ` connection.name` | ` connection_name` , ` vpn_name` , ` peer_name` , ` gateway_name` , ` router_name` , ` name` |
989+ | ` connection.vendor` | ` vendor` , ` provider` , ` cloud` , ` platform` |
990+ | ` connection.routing_mode` | ` routing_mode` , ` route_mode` , ` routing_protocol` , ` mode` , ` protocol` |
991+ | ` connection.bgp.remote_asn` | ` remote_asn` , ` peer_asn` , ` bgp_asn` , ` neighbor_asn` , ` cloud_router_asn` , ` vgw_asn` , ` asn` |
992+ | ` connection.remote_prefixes` | ` remote_prefixes` , ` remote_networks` , ` destination_prefixes` , ` destination_cidrs` , ` routes` , ` networks` , ` subnets` |
993+ | ` tunnel.name` | ` tunnel_name` , ` vpn_tunnel_name` , ` interface_name` , ` interface` , ` name` |
994+ | ` tunnel.remote_public_ip` | ` remote_public_ip` , ` peer_public_ip` , ` remote_gateway_ip` , ` vpn_gateway_ip` , ` peer_ip` , ` endpoint_ip` , ` remote_ip` , ` outside_ip` |
995+ | ` tunnel.psk` | ` psk` , ` pre_shared_key` , ` shared_secret` , ` shared_key` , ` ipsec_shared_secret` , ` secret` |
996+ | ` tunnel.inner_cidr` | ` inner_cidr` , ` inside_cidr` , ` tunnel_cidr` , ` link_cidr` , ` vti_cidr` , ` apipa_cidr` , ` inside_ip_addresses` |
997+ | ` tunnel.inner_local_ip` | ` inner_local_ip` , ` local_inside_ip` , ` customer_inside_ip` , ` customer_gateway_inside_address` , ` peer_ip_address` , ` apipa_local` |
998+ | ` tunnel.inner_remote_ip` | ` inner_remote_ip` , ` remote_inside_ip` , ` vpn_gateway_inside_address` , ` cloud_inside_ip` , ` bgp_peer_ip` , ` ip_address` , ` apipa_remote` |
999+ | ` tunnel.gateway_instance_index` | ` gateway_instance_index` , ` instance_index` , ` vm_index` |
1000+ | ` tunnel.local_public_ip_index` | ` local_public_ip_index` , ` public_ip_index` , ` nic_index` , ` interface_index` |
1001+ | ` tunnel.ha_role` | ` ha_role` , ` role` , ` state` , ` active_standby_role` |
9731002
974- - Peer values overwrite template defaults when present
975- - Topology is taken from the generated config and should be reviewed
976- - Validate before deployment
1003+ # ## Defaulting Rules
1004+
1005+ If a field cannot be matched, the importer keeps going and fills schema-safe defaults:
1006+
1007+ - ` vendor` : ` generic`
1008+ - ` routing_mode` : ` static` when remote prefixes exist, ` bgp` when a remote ASN exists, otherwise ` static` for ` cisco/generic` and ` bgp` for cloud vendors
1009+ - BGP ` remote_asn` : ` 65014` when BGP is selected but no ASN is found
1010+ - Static ` remote_prefixes` : ` 192.0.2.0/24`
1011+ - Tunnel defaults:
1012+ - ` gateway_instance_index: 0`
1013+ - ` local_public_ip_index: 0`
1014+ - first tunnel ` ha_role: active` , later tunnels ` ha_role: passive`
1015+ - generated APIPA ` /30` ranges when inner addresses are missing
1016+ - generated PSK placeholders such as ` ${GCP_HA_VPN_TUNNEL_1_PSK} `
1017+
1018+ Review the generated YAML before deployment, especially placeholder PSKs, remote prefixes, public IPs, and any inferred routing mode.
9771019
9781020# ## Example: GCP HA VPN
9791021
@@ -992,7 +1034,7 @@ nebius-vpngw create-from-peer-config gcp-ha-vpn.config.yaml \
9921034 --peer-config-file gcp-peer.txt
9931035` ` `
9941036
995- **3. Review and fill in required values (tenant/project/region/PSKs/local prefixes ):**
1037+ ** 3. Generated BGP target shape (review and adjust values before deploy ):**
9961038
9971039` ` ` yaml
9981040connections:
@@ -1004,30 +1046,61 @@ connections:
10041046 remote_asn: 65014
10051047 advertise_local_prefixes: true
10061048 tunnels:
1007- - name: tunnel-1
1049+ - name: nebius-204-12-170-147- tunnel-1
10081050 gateway_instance_index: 0
1009- remote_public_ip: "203.0.113.1"
1010- psk: ${GCP_TUNNEL_1_PSK}
1051+ local_public_ip_index: 0
1052+ ha_role: active
1053+ remote_public_ip: " 34.157.15.187"
1054+ psk: " ${GCP_HA_VPN_TUNNEL_1_PSK} "
10111055 inner_cidr: " 169.254.10.0/30"
10121056 inner_local_ip: " 169.254.10.1"
10131057 inner_remote_ip: " 169.254.10.2"
1014- - name: tunnel-2
1058+ - name: nebius-204-12-170-147- tunnel-2
10151059 gateway_instance_index: 0
1016- remote_public_ip: "203.0.113.2"
1017- psk: ${GCP_TUNNEL_2_PSK}
1060+ local_public_ip_index: 0
1061+ ha_role: passive
1062+ remote_public_ip: " 34.157.140.153"
1063+ psk: " ${GCP_HA_VPN_TUNNEL_2_PSK} "
10181064 inner_cidr: " 169.254.11.0/30"
10191065 inner_local_ip: " 169.254.11.1"
10201066 inner_remote_ip: " 169.254.11.2"
10211067` ` `
10221068
1069+ # ## Example: Static Routing Import
1070+
1071+ If the input contains remote prefixes but no BGP ASN, the generator emits a static connection:
1072+
1073+ ` ` ` yaml
1074+ connections:
1075+ - name: onprem-static
1076+ vendor: cisco
1077+ routing_mode: static
1078+ remote_prefixes:
1079+ - " 192.168.0.0/16"
1080+ bgp:
1081+ enabled: false
1082+ remote_asn: null
1083+ advertise_local_prefixes: false
1084+ tunnels:
1085+ - name: onprem-static-tunnel-1
1086+ gateway_instance_index: 0
1087+ local_public_ip_index: 0
1088+ ha_role: active
1089+ remote_public_ip: " 203.0.113.5"
1090+ psk: " ${ONPREM_STATIC_TUNNEL_1_PSK} "
1091+ inner_cidr: " 169.254.30.0/30"
1092+ inner_local_ip: " 169.254.30.1"
1093+ inner_remote_ip: " 169.254.30.2"
1094+ ` ` `
1095+
10231096** 4. Validate and deploy:**
10241097
10251098` ` ` bash
10261099nebius-vpngw validate-config gcp-ha-vpn.config.yaml
10271100nebius-vpngw apply --local-config-file gcp-ha-vpn.config.yaml
10281101` ` `
10291102
1030- Peer import only fills what it can from the vendor file; PSKs and public IPs may still need to be set manually .
1103+ Peer import only fills what it can from the input. Any placeholder or inferred value should be treated as a review item, not as final deployment intent .
10311104
10321105# # VM Management
10331106
@@ -1660,12 +1733,10 @@ Notes:
16601733│ │ ├── vm_diff.py # VM change detection
16611734│ │ ├── route_manager.py # VPC route management
16621735│ │ └── ssh_push.py # SSH deployment
1663- │ ├── peer_parsers/ # Vendor config parsers
1736+ │ ├── peer_parsers/ # Keyword-based peer config importer
16641737│ │ ├── __init__.py
1665- │ │ ├── gcp.py
1666- │ │ ├── aws.py
1667- │ │ ├── azure.py
1668- │ │ └── cisco.py
1738+ │ │ ├── common.py
1739+ │ │ └── importer.py
16691740│ └── systemd/ # Systemd units/scripts
16701741│ ├── nebius-vpngw-agent.service # Agent service unit
16711742│ ├── nebius-vpngw-health-monitor.service # Tunnel health monitor service unit
@@ -1707,7 +1778,8 @@ Notes:
17071778
17081779** Peer Parsers:**
17091780
1710- - ` gcp.py ` , ` aws.py ` , ` azure.py ` , ` cisco.py ` : Vendor-specific config normalization
1781+ - ` importer.py` : Keyword-based peer config import for ` .txt` , ` .csv` , ` .json` , ` .yaml` , ` .yml`
1782+ - ` common.py` : Shared key normalization, vendor inference, and importer helpers
17111783
17121784---
17131785
0 commit comments