Commit a568393f authored by 神楽坂玲奈's avatar 神楽坂玲奈

.

parent d07f5a2a
---
- hosts: wg
tasks:
- name: work dir
file:
path: /tmp/nextgen
state: directory
- name: 'loop through list from a variable'
debug:
msg: 'An item: {{ item.metric }} {{item.protocol}} {{item.params}}'
include_tasks: '{{item.protocol}}.yaml'
vars:
name: '{{item.name}}'
metric: '{{item.metric}}'
mark: '{{item.mark}}'
inbound: '{{item.inbound}}'
params: '{{item.params}}'
with_items: '{{ connections }}'
[Interface]
Address = {{address}}/24
PrivateKey = {{key}}
{% if listen_port is defined %}
ListenPort = {{listen_port}}
{% endif %}
{% if listen_port is defined %}
ListenPort = {{listen_port}}
{% endif %}
{% if params.if is defined %}
FwMark = {{gateways[params.if].mark_gateway}}
{% endif %}
{% if inbound is not defined %}
Table = {{table}}
{% endif %}
- name: placeholder foo
template:
src: wg.conf.j2
dest: '/tmp/nextgen/{{name}}.conf'
- name: placeholder foo
debug:
msg: 'An item: {{params.key}}'
......@@ -3,44 +3,66 @@ import util from 'util';
import fs from 'fs';
import path from 'path';
import YAML from 'yaml';
import { intersection } from 'lodash';
import _ from 'lodash';
async function main() {
const data = await fs.promises.readFile(path.join('data', '内网互联计划 - nextgen links.csv'));
class InventoryBuilder {
hosts: { [key: string]: any };
gateways: any;
connections: string[];
async load(sheetName) {
const data = await fs.promises.readFile(path.join('data', `内网互联计划 - ${sheetName}.csv`));
// @ts-ignore
const records = (await util.promisify(parse)(data, { columns: true })).filter(h => h.id);
const _hosts = Object.fromEntries(records.map(h => [h.name, h]));
const connections = intersection(Object.keys(_hosts), Object.keys(records[0]));
const hosts = Object.fromEntries(records.map(h => [h.host, host_vars(h, _hosts, connections)]));
return (await util.promisify(parse)(data, { columns: true, cast: true })).filter(h => h.id);
}
async main() {
this.hosts = _.keyBy(await this.load('nextgen links'), 'name');
this.gateways = _.mapValues(_.groupBy(await this.load('gateways'), 'name'), g => _.keyBy(g, 'isp'));
this.connections = _.intersection(Object.keys(this.hosts), Object.keys(_.find(this.hosts)));
console.log(Object.values(this.hosts));
const hosts = Object.fromEntries(Object.values(this.hosts).map(h => [h.host, this.host_vars(h)]));
console.log(hosts);
const result = YAML.stringify({ wg: { hosts } });
return fs.promises.writeFile('result/inventory.yaml', result);
}
}
function host_vars(host, hosts, hostNames: string[]) {
host_vars(host) {
const connections = [];
for (const h of hostNames) {
for (const h of this.connections) {
if (h != host.name) {
const peer = host[h] || hosts[h][host.name];
if (peer) {
connections.push(parse_connection(h, peer));
const to = host[h];
const from = this.hosts[h][host.name];
if (from && to) {
// 非对称连接
connections.push(this.parse_connection(h, from, true));
connections.push(this.parse_connection(h, to));
} else if (from || to) {
// 对称连接
connections.push(this.parse_connection(h, from || to));
}
// 不连接
}
}
return {
ansible_ssh_user: host.user,
address: host.address,
key: host.wgPrivateKey,
gateways: _.mapValues(this.gateways[host.name], gw => _.pick(gw, ['mark_gateway'])),
connections
};
}
function connections() {}
}
function parse_connection(name: string, str: string) {
parse_connection(_name: string, str: string, inbound = false) {
const [_metric, protocol, _params] = str.split(',');
const metric = parseInt(_metric);
const params = _params ? _params.split(':') : [];
return { name, metric, protocol, params };
const params = Object.fromEntries(new URLSearchParams(_params).entries());
const mark = this.hosts[_name].mark;
const name = inbound ? `${_name}-in` : _name;
return { name, metric, protocol, params, mark, inbound };
}
}
main();
new InventoryBuilder().main();
#!/usr/bin/env bash
set -e
mkdir -p result
npm run inventory
cd ansible || exit
ansible-playbook -i ../result/inventory.yaml install.yaml
ansible-playbook -i ../result/inventory.yaml "$@" install.yaml
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment