commit
aea056f04b
@ -2,4 +2,4 @@
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y vim inetutils-ping
|
||||
sudo apt-get install -y vim iputils-ping rsync wireguard-tools
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
---
|
||||
# Default VXLAN settings for site nodes
|
||||
vxlan_dev_if: wg0
|
||||
vxlan_vni: 100
|
||||
vxlan_cidr_suffix: 16
|
||||
overlay_config_path: config/sit/vpn-overlay.yaml
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
# 安全增强版 VXLAN Overlay 脚本(支持 wg0 作为通道设备 + 可选公网 DNAT 映射)
|
||||
# 用法: ./setup_sit_vxlan.sh <dev_if> <local_ip> <remote_ip> <br0_ip> [cidr_suffix] [vxlan_id] [mtu] [expose_port]
|
||||
|
||||
set -e
|
||||
|
||||
DEV_IF="$1"
|
||||
LOCAL_IP="$2"
|
||||
REMOTE_IP="$3"
|
||||
BRIDGE_IP="$4"
|
||||
CIDR_SUFFIX="${5:-16}"
|
||||
VNI="${6:-100}"
|
||||
MTU="${7:-1400}"
|
||||
EXPOSE_PORT="${8:-443}"
|
||||
|
||||
if [[ -z "$DEV_IF" || -z "$LOCAL_IP" || -z "$REMOTE_IP" || -z "$BRIDGE_IP" ]]; then
|
||||
echo "Usage: $0 <dev_if> <local_ip> <remote_ip> <br0_ip> [cidr_suffix] [vxlan_id] [mtu] [expose_port]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VXLAN_IF="vxlan${VNI}"
|
||||
BR_IF="br0"
|
||||
BRIDGE_CIDR="${BRIDGE_IP}/${CIDR_SUFFIX}"
|
||||
SUBNET="$(echo "$BRIDGE_IP" | cut -d. -f1-2).0.0/${CIDR_SUFFIX}"
|
||||
|
||||
# 自动判断 dev 是否能用于 VXLAN(需支持广播)
|
||||
function is_vxlan_dev_usable() {
|
||||
[[ -d "/sys/class/net/$1" ]] && grep -q "broadcast" "/sys/class/net/$1/flags"
|
||||
}
|
||||
|
||||
echo "🔍 检查 $DEV_IF 是否可用于 VXLAN..."
|
||||
USE_DEV_PARAM=true
|
||||
if ! is_vxlan_dev_usable "$DEV_IF"; then
|
||||
echo "⚠️ $DEV_IF 不支持广播,将省略 dev 参数(通过路由走隧道)"
|
||||
USE_DEV_PARAM=false
|
||||
fi
|
||||
|
||||
# 清理旧接口
|
||||
for iface in "$VXLAN_IF" "$BR_IF"; do
|
||||
ip link show "$iface" &>/dev/null && ip link set "$iface" down && ip link del "$iface"
|
||||
done
|
||||
|
||||
# 创建 VXLAN 接口
|
||||
echo "🛠️ 创建 VXLAN 接口 $VXLAN_IF ..."
|
||||
if $USE_DEV_PARAM; then
|
||||
ip link add "$VXLAN_IF" type vxlan id "$VNI" dstport 4789 local "$LOCAL_IP" remote "$REMOTE_IP" dev "$DEV_IF"
|
||||
else
|
||||
ip link add "$VXLAN_IF" type vxlan id "$VNI" dstport 4789 local "$LOCAL_IP" remote "$REMOTE_IP"
|
||||
fi
|
||||
ip link set "$VXLAN_IF" mtu "$MTU"
|
||||
ip link set "$VXLAN_IF" up
|
||||
|
||||
# 创建 br0 桥
|
||||
ip link add "$BR_IF" type bridge
|
||||
ip link set "$BR_IF" mtu "$MTU"
|
||||
ip link set "$VXLAN_IF" master "$BR_IF"
|
||||
ip link set "$BR_IF" up
|
||||
|
||||
# 配置 IP
|
||||
ip addr add "$BRIDGE_CIDR" dev "$BR_IF"
|
||||
|
||||
# 启用转发 + SNAT(仅主机出网时)
|
||||
sysctl -w net.ipv4.ip_forward=1
|
||||
iptables -t nat -C POSTROUTING -s "$SUBNET" -o "$DEV_IF" -j MASQUERADE 2>/dev/null || \
|
||||
iptables -t nat -A POSTROUTING -s "$SUBNET" -o "$DEV_IF" -j MASQUERADE
|
||||
|
||||
# ⚠️ 可选:仅在 EXPOSE_PORT 被定义时启用 DNAT 公网端口映射
|
||||
if [[ -n "$EXPOSE_PORT" ]]; then
|
||||
echo "🌐 添加 DNAT 映射规则:公网:$EXPOSE_PORT → ${BRIDGE_IP}:443"
|
||||
|
||||
iptables -t nat -C PREROUTING -p tcp -m tcp --dport "$EXPOSE_PORT" -j DNAT --to-destination "${BRIDGE_IP}:443" 2>/dev/null || \
|
||||
iptables -t nat -A PREROUTING -p tcp -m tcp --dport "$EXPOSE_PORT" -j DNAT --to-destination "${BRIDGE_IP}:443"
|
||||
fi
|
||||
|
||||
# 展示结果
|
||||
echo ""
|
||||
echo "✅ VXLAN Overlay 已建立"
|
||||
echo " - bridge: $BR_IF ($BRIDGE_CIDR)"
|
||||
echo " - vxlan: $VXLAN_IF ($LOCAL_IP ⇄ $REMOTE_IP, id=$VNI, mtu=$MTU)"
|
||||
echo " - SNAT: $SUBNET → $DEV_IF"
|
||||
if [[ -n "$EXPOSE_PORT" ]]; then
|
||||
echo " - DNAT: 公网:$EXPOSE_PORT → ${BRIDGE_IP}:443"
|
||||
fi
|
||||
@ -0,0 +1,54 @@
|
||||
---
|
||||
- name: Load site overlay config
|
||||
set_fact:
|
||||
overlay_data: "{{ lookup('file', overlay_config_path) | from_yaml }}"
|
||||
|
||||
- name: Select current site from config
|
||||
set_fact:
|
||||
current_site: "{{ overlay_data.sites | selectattr('name', 'equalto', inventory_hostname) | list | first }}"
|
||||
|
||||
- name: Fail if no matching site found
|
||||
fail:
|
||||
msg: "当前主机 {{ inventory_hostname }} 未在 config 中定义"
|
||||
when: current_site is not defined
|
||||
|
||||
- name: Select first hub as default
|
||||
set_fact:
|
||||
selected_hub: "{{ overlay_data.hubs[0] }}"
|
||||
|
||||
- name: Set VXLAN parameters
|
||||
set_fact:
|
||||
vxlan_dev_if: "{{ current_site.interface}}"
|
||||
vxlan_local_ip: "{{ current_site.local_ip }}"
|
||||
vxlan_remote_ip: "{{ current_site.remote_ip }}"
|
||||
vxlan_br_ip: "{{ current_site.br_ip }}"
|
||||
vxlan_cidr_suffix: "{{ overlay_data.vxlan_cidr_suffix | default(16) }}"
|
||||
vxlan_vni: "{{ overlay_data.vxlan_id | default(100) }}"
|
||||
|
||||
- name: 使用 rsync 分发 VXLAN 脚本
|
||||
synchronize:
|
||||
src: "files/setup_sit_vxlan.sh"
|
||||
dest: /tmp/setup_sit_vxlan.sh
|
||||
mode: push
|
||||
|
||||
- name: 移动脚本并赋权到 /usr/local/bin
|
||||
shell: |
|
||||
mv /tmp/setup_sit_vxlan.sh /usr/local/bin/setup_sit_vxlan.sh
|
||||
chmod +x /usr/local/bin/setup_sit_vxlan.sh
|
||||
become: true
|
||||
|
||||
- name: Render systemd unit for VXLAN
|
||||
template:
|
||||
src: vxlan-setup.service.j2
|
||||
dest: /etc/systemd/system/vxlan-setup.service
|
||||
mode: '0644'
|
||||
|
||||
- name: Reload systemd daemon
|
||||
systemd:
|
||||
daemon_reload: true
|
||||
|
||||
- name: Enable and start VXLAN overlay setup
|
||||
systemd:
|
||||
name: vxlan-setup
|
||||
enabled: true
|
||||
state: started
|
||||
@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=VXLAN Overlay Setup for {{ inventory_hostname }}
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/setup_sit_vxlan.sh {{ vxlan_dev_if }} {{ vxlan_local_ip }} {{ vxlan_remote_ip }} {{ vxlan_br_ip }} {{ vxlan_cidr_suffix }} {{ vxlan_vni }}
|
||||
RemainAfterExit=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@ -0,0 +1,8 @@
|
||||
wg_interface: "wg0"
|
||||
|
||||
# 默认配置文件路径,可在 playbook 中覆盖
|
||||
overlay_config_path: "{{ playbook_dir }}/../../config/sit/vpn-overlay.yaml"
|
||||
overlay_keys_path: "{{ playbook_dir }}/../../config/sit/vpn-keys.yaml"
|
||||
|
||||
# WireGuard 默认端口(若 overlay_data.hub_port 未定义)
|
||||
wg_port: "51820"
|
||||
@ -0,0 +1,58 @@
|
||||
---
|
||||
- name: 加载 overlay 配置(标准 YAML)
|
||||
set_fact:
|
||||
overlay_data: "{{ lookup('file', overlay_config_path) | from_yaml }}"
|
||||
|
||||
- name: 加载密钥配置(支持 !vault)
|
||||
include_vars:
|
||||
file: "{{ overlay_keys_path }}"
|
||||
name: overlay_keys
|
||||
|
||||
- name: 提取当前节点信息(作为 current)
|
||||
set_fact:
|
||||
current_node: >-
|
||||
{{ (overlay_data.sites + overlay_data.hubs)
|
||||
| selectattr('name', 'equalto', inventory_hostname)
|
||||
| list | first }}
|
||||
current_key: >-
|
||||
{{ overlay_keys['keys']
|
||||
| selectattr('name', 'equalto', inventory_hostname)
|
||||
| list | first }}
|
||||
|
||||
- name: 提取对端 peer 节点列表
|
||||
set_fact:
|
||||
peer_node_list: "{{ (overlay_data.sites + overlay_data.hubs) | selectattr('name', 'equalto', current_node.wireguard_peer) | list }}"
|
||||
peer_key_list: "{{ overlay_keys['keys'] | selectattr('name', 'equalto', current_node.wireguard_peer) | list }}"
|
||||
|
||||
- name: 校验 wireguard_peer 是否匹配成功
|
||||
fail:
|
||||
msg: "未找到对端节点 '{{ current_node.wireguard_peer }}' 或其密钥"
|
||||
when: peer_node_list | length == 0 or peer_key_list | length == 0
|
||||
|
||||
- name: 设置对端节点与密钥
|
||||
set_fact:
|
||||
peer_nodes: "{{ peer_node_list }}"
|
||||
peer_keys: "{{ peer_key_list }}"
|
||||
|
||||
- name: 提取最终配置变量(私钥、公钥、端口等)
|
||||
set_fact:
|
||||
wg_port: "{{ wg_port }}"
|
||||
current_wg_ip: "{{ current_node.wg_ip }}"
|
||||
current_private_key: "{{ current_key.private_key }}"
|
||||
current_allowed_ips: "{{ current_node.allowed_ips }}"
|
||||
peer_public_key: "{{ peer_keys[0].public_key }}"
|
||||
peer_endpoint: "{{ peer_nodes[0].public_ip }}:{{ overlay_data.hub_port | default(wg_port) }}"
|
||||
|
||||
- name: 渲染 wg0.conf
|
||||
template:
|
||||
src: wg0.conf.j2
|
||||
dest: /etc/wireguard/wg0.conf
|
||||
mode: '0600'
|
||||
become: true
|
||||
|
||||
- name: 启用并启动 wg-quick@wg0
|
||||
systemd:
|
||||
name: wg-quick@wg0
|
||||
enabled: true
|
||||
state: started
|
||||
become: true
|
||||
@ -0,0 +1,12 @@
|
||||
[Interface]
|
||||
PrivateKey = {{ current_private_key }}
|
||||
Address = {{ current_wg_ip }}/32
|
||||
ListenPort = {{ wg_port }}
|
||||
DNS = 8.8.8.8
|
||||
MTU = 1400
|
||||
|
||||
[Peer]
|
||||
PublicKey = {{ peer_public_key }}
|
||||
AllowedIPs = {{ current_allowed_ips }}
|
||||
Endpoint = {{ peer_endpoint }}
|
||||
PersistentKeepalive = 25
|
||||
8
ansible/playbooks/vpn-overlay.yaml
Normal file
8
ansible/playbooks/vpn-overlay.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
- name: Run infrastructure setup
|
||||
hosts: all
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
vars:
|
||||
overlay_config_path: "{{ playbook_dir }}/../../config/sit/vpn-overlay.yaml"
|
||||
roles:
|
||||
- vhosts/vpn-overlay/vxlan/site
|
||||
8
ansible/playbooks/vpn-wireguard-site.yaml
Normal file
8
ansible/playbooks/vpn-wireguard-site.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
- name: Setup WireGuard for site
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
overlay_config_path: "{{ playbook_dir }}/../../config/sit/vpn-overlay.yaml"
|
||||
overlay_keys_path: "{{ playbook_dir }}/../../config/sit/vpn-keys.yaml"
|
||||
roles:
|
||||
- vhosts/vpn-overlay/wireguard/site
|
||||
17
config/sit/vpn-keys.md
Normal file
17
config/sit/vpn-keys.md
Normal file
@ -0,0 +1,17 @@
|
||||
只加密 private_key 字段
|
||||
1. 原始 vpn-keys.yaml
|
||||
yaml
|
||||
keys:
|
||||
- name: master-1
|
||||
private_key: <master_private_key>
|
||||
public_key: <master_public_key>
|
||||
2. 使用 ansible-vault encrypt_string 加密 private_key
|
||||
bash
|
||||
ansible-vault encrypt_string 'my-secret-private-key' --name 'private_key'
|
||||
示例输出(加密后是 YAML 结构):
|
||||
|
||||
yaml
|
||||
private_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
62326432376162336462343864333933356363373235623262306463326432363737623732613763
|
||||
3962613662616565393463343030653733623066626137610a313465323462623261303031323337
|
||||
48
config/sit/vpn-keys.yaml
Normal file
48
config/sit/vpn-keys.yaml
Normal file
@ -0,0 +1,48 @@
|
||||
keys:
|
||||
- name: master-1
|
||||
private_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
35363663306235633966383634393535366462633039383137316163653166643832376264653965
|
||||
3163363463663535363734343135643061653834353134610a393465636431346635643231613632
|
||||
66393139656238333637353132663937633632396230313438656135353066383234353139343666
|
||||
6230626332326437310a626639363063613062616239623734333131633865393063343030353133
|
||||
32323465393434343634646238636531646230356365343264656364333132316636353338353133
|
||||
6261663131646237316635306438613938396639383439653665
|
||||
public_key: <master_public_key>
|
||||
|
||||
- name: slave-1
|
||||
private_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
64393432666564616632613366663264326338643931653966653961643362306562643537663636
|
||||
6434343630366165623261623363376333306339333164360a353037383261616335623561386538
|
||||
64633762323939656633313433306330333533373434323664393965373038623431653539633561
|
||||
3461626530613863640a353931346639653961303136303763303432653532636438636532613936
|
||||
64313264643465303663646135383537623930626137656264323433373536326530613131363134
|
||||
6334613964626261323838616534623639616133303564653063
|
||||
public_key: <slave_public_key>
|
||||
|
||||
- name: site_c
|
||||
private_key: <site_c_private_key>
|
||||
public_key: <site_c_public_key>
|
||||
|
||||
- name: hub-1
|
||||
private_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
33643635306332303761356562383035353333373234393132313162613834323963313635326562
|
||||
3932356235303234356561623762393862666438386565310a376235306238343139386532336162
|
||||
65623164666665353435653432396530303634666438656566656466643866366139613961363631
|
||||
6363306631393038320a613163313338313237383837303966356333303737643331616433396430
|
||||
33316331333766613438356462313130326433363961316162313761616561616466363939613033
|
||||
3837623938376434656434386135333739613939653133373733
|
||||
public_key: !vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
38336537383061383333643431643261343739323864316235303366623930633366336139386636
|
||||
6162336232336533636134353863386233303631626363360a376533336664636661373933623230
|
||||
34333765346661383335663034393561646436333135613838373438396336633061396533613061
|
||||
3031326364353036630a373862396266653961346334663139626633313362656131663163383563
|
||||
34376231306239636536313830333962323934343035333263643234363363396164626366353061
|
||||
3833613132373666303563623863373735396566666239316536
|
||||
|
||||
- name: hub2
|
||||
private_key: <hub2_private_key>
|
||||
public_key: <hub2_public_key>
|
||||
66
config/sit/vpn-overlay.yaml
Normal file
66
config/sit/vpn-overlay.yaml
Normal file
@ -0,0 +1,66 @@
|
||||
# 基础网络参数
|
||||
wg_network: 172.16.0.0/24
|
||||
bridge_network: 10.253.0.0/16
|
||||
vxlan_id: 100
|
||||
hub_port: 51820
|
||||
|
||||
# 全局功能开关
|
||||
features:
|
||||
enable_vxlan_between_sits: true # 是否开启 vxlan 桥接(站点接入 Hub)
|
||||
enable_vxlan_between_hubs: true # 是否开启 Hub 之间的 VXLAN Mesh
|
||||
enable_vless: true # 是否通过 VLESS 中转 WG 流量
|
||||
enable_multi_hub: true # 是否支持多 Hub 架构(false 则为单 Hub star 架构)
|
||||
only_wireguard: false # 若为 true,仅使用 WireGuard 点对点,忽略 gretap/vxlan
|
||||
|
||||
# WireGuard Hub 节点配置
|
||||
hubs:
|
||||
- name: hub-1
|
||||
wg_ip: 10.255.0.1
|
||||
br_ip: 172.16.0.1
|
||||
public_ip: global-proxy.onwalk.net
|
||||
|
||||
- name: hub2
|
||||
wg_ip: 10.100.1.1
|
||||
br_ip: 172.16.1.1
|
||||
public_ip: hub2.example.com
|
||||
|
||||
# 各个站点定义
|
||||
sites:
|
||||
- name: master-1
|
||||
interface: ens5
|
||||
allowed_ips: "10.255.0.0/16,10.253.0.0/16"
|
||||
wireguard_peer: hub-1
|
||||
wg_ip: 10.255.0.200
|
||||
br_ip: 172.16.0.2
|
||||
local_ip: 10.255.0.200
|
||||
remote_ip: 10.255.0.100
|
||||
vless:
|
||||
enabled: false
|
||||
uuid: "11111111-1111-1111-1111-111111111111"
|
||||
transport: ws
|
||||
tls: true
|
||||
path: /wg
|
||||
|
||||
- name: slave-1
|
||||
interface: ens5
|
||||
wireguard_peer: hub-1
|
||||
allowed_ips: "10.255.0.0/16,10.253.0.0/16"
|
||||
br_ip: 172.16.0.2
|
||||
wg_ip: 10.255.0.100
|
||||
local_ip: 10.255.0.100
|
||||
remote_ip: 10.255.0.200
|
||||
vless:
|
||||
enabled: false # 此节点不通过 VLESS,直接访问 Hub
|
||||
|
||||
- name: site_c
|
||||
wg_ip: 10.100.1.2
|
||||
br_ip: 172.16.1.2
|
||||
hub: hub2
|
||||
public_ip: c.example.com
|
||||
vless:
|
||||
enabled: true
|
||||
endpoint: vless-c.example.com
|
||||
uuid: "33333333-3333-3333-3333-333333333333"
|
||||
transport: ws
|
||||
tls: true
|
||||
path: /xray
|
||||
@ -1,61 +0,0 @@
|
||||
# 基础网络参数
|
||||
wg_network: 10.100.0.0/24
|
||||
bridge_network: 172.16.0.0/16
|
||||
vxlan_id: 100
|
||||
hub_port: 51820
|
||||
|
||||
# 全局功能开关
|
||||
features:
|
||||
enable_gretap: true # 是否开启 gretap 桥接(站点接入 Hub)
|
||||
enable_vxlan_between_hubs: true # 是否开启 Hub 之间的 VXLAN Mesh
|
||||
enable_vless: true # 是否通过 VLESS 中转 WG 流量
|
||||
enable_multi_hub: true # 是否支持多 Hub 架构(false 则为单 Hub star 架构)
|
||||
only_wireguard: false # 若为 true,仅使用 WireGuard 点对点,忽略 gretap/vxlan
|
||||
|
||||
# WireGuard Hub 节点配置
|
||||
hubs:
|
||||
- name: hub1
|
||||
wg_ip: 10.100.0.1
|
||||
br_ip: 172.16.0.1
|
||||
public_ip: hub1.example.com
|
||||
|
||||
- name: hub2
|
||||
wg_ip: 10.100.1.1
|
||||
br_ip: 172.16.1.1
|
||||
public_ip: hub2.example.com
|
||||
|
||||
# 各个站点定义
|
||||
sites:
|
||||
- name: site_a
|
||||
wg_ip: 10.100.0.2
|
||||
br_ip: 172.16.0.2
|
||||
hub: hub1
|
||||
public_ip: a.example.com
|
||||
vless:
|
||||
enabled: true
|
||||
endpoint: vless-a.example.com
|
||||
uuid: "11111111-1111-1111-1111-111111111111"
|
||||
transport: ws
|
||||
tls: true
|
||||
path: /wg
|
||||
|
||||
- name: site_b
|
||||
wg_ip: 10.100.0.3
|
||||
br_ip: 172.16.0.3
|
||||
hub: hub1
|
||||
public_ip: b.example.com
|
||||
vless:
|
||||
enabled: false # 此节点不通过 VLESS,直接访问 Hub
|
||||
|
||||
- name: site_c
|
||||
wg_ip: 10.100.1.2
|
||||
br_ip: 172.16.1.2
|
||||
hub: hub2
|
||||
public_ip: c.example.com
|
||||
vless:
|
||||
enabled: true
|
||||
endpoint: vless-c.example.com
|
||||
uuid: "33333333-3333-3333-3333-333333333333"
|
||||
transport: ws
|
||||
tls: true
|
||||
path: /xray
|
||||
@ -14,22 +14,29 @@ def deep_merge(dict1, dict2):
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
def load_merged_config(config_dir=None):
|
||||
def load_merged_config(config_dir=None, ignore_files=None):
|
||||
config_dir = config_dir or os.environ.get("CONFIG_PATH", "config")
|
||||
ignore_files = set(ignore_files or ['vpn-keys.yaml']) # 默认忽略敏感 key 文件
|
||||
|
||||
if not os.path.isdir(config_dir):
|
||||
raise FileNotFoundError(f"❌ 配置目录不存在: {config_dir}")
|
||||
|
||||
merged = {}
|
||||
files = sorted(glob.glob(os.path.join(config_dir, "*.yaml")) + glob.glob(os.path.join(config_dir, "*.yml")))
|
||||
files = sorted(
|
||||
glob.glob(os.path.join(config_dir, "*.yaml")) + glob.glob(os.path.join(config_dir, "*.yml"))
|
||||
)
|
||||
|
||||
if not files:
|
||||
raise FileNotFoundError(f"⚠️ 未找到任何 YAML 配置文件于: {config_dir}")
|
||||
|
||||
for file in files:
|
||||
filename = os.path.basename(file)
|
||||
if filename in ignore_files:
|
||||
continue
|
||||
|
||||
with open(file) as f:
|
||||
part = yaml.safe_load(f) or {}
|
||||
merged = deep_merge(merged, part)
|
||||
|
||||
merged["__config_path__"] = config_dir # 可选调试字段
|
||||
merged["__config_path__"] = config_dir
|
||||
return merged
|
||||
|
||||
@ -262,12 +262,14 @@ pulumi_run() {
|
||||
|
||||
# ========== 执行 Ansible ==========
|
||||
run_ansible() {
|
||||
if [ ! -f scripts/inventory.py ]; then
|
||||
echo "❌ 未找到 scripts/inventory.py"
|
||||
if [ ! -f scripts/dynamic_inventory.py ]; then
|
||||
echo "❌ 未找到 scripts/dynamic_inventory.py"
|
||||
exit 1
|
||||
fi
|
||||
echo "🧪 执行 Ansible Playbook"
|
||||
ansible-playbook -i scripts/inventory.py "$ANSIBLE_DIR/playbooks/setup.yml"
|
||||
ansible-playbook -i scripts/dynamic_inventory.py ansible/playbooks/common_setup.yml -D
|
||||
ansible-playbook -i scripts/dynamic_inventory.py ansible/playbooks/vpn-wireguard-site.yaml -D -l slave-1,master-1
|
||||
ansible-playbook -i scripts/dynamic_inventory.py ansible/playbooks/vpn-overlay.yaml -D -l slave-1,master-1
|
||||
}
|
||||
|
||||
# ========== 分发 ==========
|
||||
|
||||
Loading…
Reference in New Issue
Block a user