mirror of
https://github.com/Telecominfraproject/olg-scratchpad.git
synced 2026-01-27 02:21:33 +00:00
Modified the earlier logic of applying uCentral Config to VYOS ie.(load(config.boot file) + merge)
To new logic ( retrieve(necessary configs) + load(necessary configs + Received Config from Ucentral) Due to this logic the data path will not get affected for configuration changes. Also Added the vyos_version.uc to prevent migration scripts from running.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"op": "merge",
|
||||
"host": "https://192.168.76.195",
|
||||
"key": "MY-HTTPS-API-PLAINTEXT-KEY"
|
||||
"host": "https://192.168.76.195",
|
||||
"key": "MY-HTTPS-API-PLAINTEXT-KEY"
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@ push(REQUIRE_SEARCH_PATH,
|
||||
let schemareader = require("schemareader");
|
||||
let fs = require("fs");
|
||||
let ubus = require("ubus").connect();
|
||||
|
||||
let vyos = require("vyos.config_prepare");
|
||||
|
||||
let vyos_api = require("vyos.https_server_api");
|
||||
let inputfile = fs.open(ARGV[0], "r");
|
||||
let inputjson = json(inputfile.read("all"));
|
||||
let custom_config = (split(ARGV[0], ".")[0] != "/etc/ucentral/ucentral");
|
||||
@@ -27,32 +26,26 @@ if (fs.stat(args_path)) {
|
||||
f.close();
|
||||
}
|
||||
|
||||
let op = (ARGV.length > 1 && ARGV[1] != "-") ? ARGV[1] : (args.op ?? null);
|
||||
let host = (ARGV.length > 2 && ARGV[2] != "-") ? ARGV[2] : (args.host ?? null);
|
||||
let key = (ARGV.length > 3 && ARGV[3] != "-") ? ARGV[3] : (args.key ?? null);
|
||||
|
||||
if (!op || !host || !key) {
|
||||
if (!host || !key) {
|
||||
print("Missing op/host/key. Provide them in /etc/ucentral/vyos-info.json or pass '-' placeholders and ensure file exists.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
for (let cmd in [ 'rm -rf /tmp/ucentral',
|
||||
'mkdir /tmp/ucentral',
|
||||
'rm /tmp/dnsmasq.conf',
|
||||
'/etc/init.d/spotfilter stop',
|
||||
'touch /tmp/dnsmasq.conf' ])
|
||||
system(cmd);
|
||||
|
||||
let state = schemareader.validate(inputjson, logs);
|
||||
let vyos_config_payload = vyos.vyos_render(state);
|
||||
let scope = {
|
||||
vyos_config_payload, op, host, key
|
||||
};
|
||||
let rc = include('vyos/https_server_api.uc', scope);
|
||||
/* TODO: Return Handling to be done yet */
|
||||
if(rc != 0){
|
||||
error = 0;
|
||||
let op_arg = { };
|
||||
vyos_config_payload = vyos.vyos_render(state);
|
||||
op_arg.string = vyos_config_payload;
|
||||
let op = "load";
|
||||
let rc = vyos_api.vyos_api_call(op_arg, op, host, key);
|
||||
if(rc != ''){
|
||||
rc = json(rc);
|
||||
}
|
||||
if(rc != '' && rc.success == false){
|
||||
error = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// This file is to generatre full VyOS style configuration from uCentral config
|
||||
|
||||
let fs = require("fs");
|
||||
|
||||
let vyos_api = require("vyos.https_server_api");
|
||||
function load_capabilities() {
|
||||
let capabfile = fs.open("/etc/ucentral/capabilities.json", "r");
|
||||
if (!capabfile)
|
||||
@@ -49,6 +49,23 @@ function convert_lease_time_to_seconds(s, def){
|
||||
if(u=="d") return n*86400;
|
||||
return def;
|
||||
}
|
||||
function vyos_retrieve_info(op_arg, op)
|
||||
{
|
||||
let args_path = "/etc/ucentral/vyos-info.json";
|
||||
let args = {};
|
||||
if (fs.stat(args_path)) {
|
||||
let f = fs.open(args_path, "r");
|
||||
args = json(f.read("all"));
|
||||
f.close();
|
||||
}
|
||||
|
||||
let host = args.host;
|
||||
let key = args.key;
|
||||
let resp = vyos_api.vyos_api_call(op_arg, op, host, key);
|
||||
//TODO:Check Return Value and handle response from here
|
||||
let jsn = json(resp);
|
||||
return jsn;
|
||||
}
|
||||
|
||||
return {
|
||||
vyos_render: function(config) {
|
||||
@@ -63,6 +80,12 @@ return {
|
||||
if (type(capab.network.lan) == "array" && length(capab.network.lan) > 0)
|
||||
lan_ifname = capab.network.lan[0];
|
||||
}
|
||||
let op_arg = { };
|
||||
let op = "showConfig";
|
||||
op_arg.path = ["pki"];
|
||||
|
||||
let rc = vyos_retrieve_info(op_arg, op);
|
||||
let pki = render('templates/pki.uc', {rc});
|
||||
|
||||
let interfaces = render('templates/interface.uc', {
|
||||
config,
|
||||
@@ -70,14 +93,21 @@ return {
|
||||
lan_ifname
|
||||
});
|
||||
|
||||
op_arg.path = ["system", "login"];
|
||||
let systeminfo = vyos_retrieve_info(op_arg, op);
|
||||
let system = render('templates/system.uc',{systeminfo});
|
||||
|
||||
let nat = render('templates/nat.uc', {
|
||||
config,
|
||||
wan_ifname,
|
||||
network_base
|
||||
});
|
||||
|
||||
op_arg.path = ["service", "https"];
|
||||
let https = vyos_retrieve_info(op_arg, op);
|
||||
let services = render('templates/service.uc', {
|
||||
config,
|
||||
https,
|
||||
split_ip_prefix,
|
||||
network_base,
|
||||
add_host,
|
||||
@@ -88,7 +118,9 @@ return {
|
||||
int_to_tuple,
|
||||
convert_lease_time_to_seconds
|
||||
});
|
||||
//TODO: Need to understand Firmware Upgrade and Migration Logic of VyOS then modify this
|
||||
let vyos_version = render('templates/version.uc');
|
||||
|
||||
return interfaces + "\n" + nat + "\n" + services + "\n";
|
||||
return interfaces + "\n" + nat + "\n" + services + "\n" + pki + "\n" + system + "\n" + vyos_version + "\n";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,37 +1,84 @@
|
||||
#!/usr/bin/ucode
|
||||
push(REQUIRE_SEARCH_PATH,
|
||||
"/usr/lib/ucode/*.so",
|
||||
"/usr/share/ucentral/*.uc");
|
||||
// This provides support to call VyOS Https Server API's as per operation mode
|
||||
|
||||
let fs = require("fs");
|
||||
|
||||
if (!key) { fprintf(stderr, "Missing API key\n"); exit(2); }
|
||||
/* TODO: pass as container environment variable for load */
|
||||
let loadapi_payload_obj = { op: "load", file: "/opt/vyatta/etc/config/config.boot" };
|
||||
let loadapi_payload_str = sprintf("%J", loadapi_payload_obj);
|
||||
let api_payload_obj = { op: op, string: vyos_config_payload };
|
||||
let api_payload_str = sprintf("%J", api_payload_obj);
|
||||
function quoteForShell(s) {
|
||||
if (s == null)
|
||||
return "''";
|
||||
|
||||
let parts = split(s, "'");
|
||||
return "'" + join("'\"'\"'", parts) + "'";
|
||||
}
|
||||
let url = host + "/config-file";
|
||||
printf("url is %s\n",url);
|
||||
let api_load_op_cmd = sprintf(
|
||||
"curl -skL --connect-timeout 3 -m 5 -X POST %s --form-string data=%s --form key=%s",
|
||||
quoteForShell(url), quoteForShell(loadapi_payload_str), quoteForShell(key)
|
||||
);
|
||||
|
||||
printf("api_load_op_cmd is %s\n\n", api_load_op_cmd);
|
||||
system(api_load_op_cmd);
|
||||
return{
|
||||
vyos_api_call: function(op_arg, op, host, key) {
|
||||
// Basic argument validation
|
||||
if (!key) {
|
||||
fprintf(stderr, "Missing API key\n");
|
||||
return null;
|
||||
}
|
||||
if (!host) {
|
||||
fprintf(stderr, "Missing host\n");
|
||||
return null;
|
||||
}
|
||||
if (!op) {
|
||||
fprintf(stderr, "Missing op\n");
|
||||
return null;
|
||||
}
|
||||
|
||||
let api_op_cmd = sprintf(
|
||||
"curl -skL --connect-timeout 3 -m 5 -X POST %s --form-string data=%s --form key=%s",
|
||||
quoteForShell(url), quoteForShell(api_payload_str), quoteForShell(key)
|
||||
);
|
||||
// Determine endpoint and payload based on op
|
||||
let endpoint;
|
||||
let payloadObj = { op: op };
|
||||
|
||||
printf("api_op_cmd is %s\n\n", api_op_cmd);
|
||||
let rc = system(api_op_cmd);
|
||||
return rc;
|
||||
if (op == "load" || op == "merge") {
|
||||
endpoint = "/config-file";
|
||||
|
||||
if (op_arg && op_arg.file) {
|
||||
payloadObj.file = op_arg.file;
|
||||
} else if (op_arg && op_arg.string) {
|
||||
payloadObj.string = op_arg.string;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported op_arg for op %s\n", op);
|
||||
return null;
|
||||
}
|
||||
|
||||
} else if (op == "showConfig") {
|
||||
endpoint = "/retrieve";
|
||||
|
||||
if (op_arg && op_arg.path) {
|
||||
payloadObj.path = op_arg.path;
|
||||
} else {
|
||||
// default: whole config
|
||||
payloadObj.path = [];
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported op: %s\n", op);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Convert payload to JSON string
|
||||
let payloadStr = sprintf("%J", payloadObj);
|
||||
let url = host + endpoint;
|
||||
|
||||
// Build the curl command
|
||||
let cmd = sprintf(
|
||||
"curl -skL --connect-timeout 3 -m 5 -X POST %s " +
|
||||
"--form-string data=%s --form key=%s",
|
||||
quoteForShell(url),
|
||||
quoteForShell(payloadStr),
|
||||
quoteForShell(key)
|
||||
);
|
||||
|
||||
// Run curl and capture output
|
||||
let proc = fs.popen(cmd, "r");
|
||||
if (!proc) {
|
||||
fprintf(stderr, "Failed to start curl\n");
|
||||
return null;
|
||||
}
|
||||
|
||||
let out = proc.read("all");
|
||||
proc.close();
|
||||
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{%
|
||||
|
||||
let data = (type(rc) == "object" && type(rc.data) == "object") ? rc.data : {};
|
||||
let ca_map = (type(data.ca) == "object") ? data.ca : {};
|
||||
let cert_map = (type(data.certificate) == "object") ? data.certificate : {};
|
||||
|
||||
let ca_names = keys(ca_map);
|
||||
let cert_names = keys(cert_map);
|
||||
%}
|
||||
pki {
|
||||
{%
|
||||
/* ---- CA blocks ---- */
|
||||
for (let i = 0; i < length(ca_names); i++) {
|
||||
let name = ca_names[i];
|
||||
let ca = ca_map[name] || {};
|
||||
%}
|
||||
ca {{name}} {
|
||||
certificate {{ca.certificate}}
|
||||
{%
|
||||
if (type(ca.private) == "object" && ca.private.key) {
|
||||
%}
|
||||
private {
|
||||
key {{ca.private.key}}
|
||||
}
|
||||
{%
|
||||
}
|
||||
%}
|
||||
}
|
||||
{%
|
||||
}
|
||||
|
||||
/* ---- certificate blocks ---- */
|
||||
for (let i = 0; i < length(cert_names); i++) {
|
||||
let name = cert_names[i];
|
||||
let cert = cert_map[name] || {};
|
||||
%}
|
||||
certificate {{name}} {
|
||||
certificate {{cert.certificate}}
|
||||
{%
|
||||
if (type(cert.private) == "object" && cert.private.key) {
|
||||
%}
|
||||
private {
|
||||
key {{cert.private.key}}
|
||||
}
|
||||
{%
|
||||
}
|
||||
%}
|
||||
}
|
||||
{%
|
||||
}
|
||||
%}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,10 +132,66 @@
|
||||
type(config.services.ssh) == "object" &&
|
||||
config.services.ssh.port)
|
||||
ssh_port = int(config.services.ssh.port);
|
||||
%}
|
||||
|
||||
let https_enabled = false;
|
||||
let https_allow_from = [];
|
||||
let https_keys = [];
|
||||
let https_ca_cert = null;
|
||||
let https_cert = null;
|
||||
let https_port = 443;
|
||||
|
||||
if (type(https) == "object" &&
|
||||
https.success === true &&
|
||||
type(https.data) == "object") {
|
||||
|
||||
let h = https.data;
|
||||
|
||||
// ----- allow-client -----
|
||||
if (type(h["allow-client"]) == "object") {
|
||||
let ac = h["allow-client"];
|
||||
|
||||
if (type(ac.address) == "string") {
|
||||
push(https_allow_from, ac.address);
|
||||
} else if (type(ac.address) == "array") {
|
||||
for (let addr in ac.address) {
|
||||
if (type(addr) == "string")
|
||||
push(https_allow_from, addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----- api keys -----
|
||||
if (type(h.api) == "object" &&
|
||||
type(h.api.keys) == "object" &&
|
||||
type(h.api.keys.id) == "object") {
|
||||
|
||||
for (let kid in keys(h.api.keys.id)) {
|
||||
let kobj = h.api.keys.id[kid];
|
||||
if (type(kobj) == "object" && kobj.key) {
|
||||
push(https_keys, { id: kid, key: kobj.key });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----- certificates -----
|
||||
if (type(h.certificates) == "object") {
|
||||
if (type(h.certificates["ca-certificate"]) == "string")
|
||||
https_ca_cert = h.certificates["ca-certificate"];
|
||||
|
||||
if (type(h.certificates.certificate) == "string")
|
||||
https_cert = h.certificates.certificate;
|
||||
}
|
||||
|
||||
// ----- port -----
|
||||
if (h.port)
|
||||
https_port = int(h.port);
|
||||
|
||||
https_enabled = true;
|
||||
}
|
||||
%}
|
||||
service {
|
||||
{% include('services/dhcp-server.uc', {lans}); %}
|
||||
{% include('services/dns-forwarding.uc', {lans}); %}
|
||||
{% include('services/ssh.uc', {ssh_port}); %}
|
||||
{% include('services/https.uc', {https_enabled, https_allow_from, https_keys, https_ca_cert, https_cert, https_port}); %}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
{% if (https_enabled): %}
|
||||
https {
|
||||
{% if (length(https_allow_from) > 0): %}
|
||||
allow-client {
|
||||
{% for (let a in https_allow_from): %}
|
||||
address {{ a }}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
{% if (length(https_keys) > 0): %}
|
||||
api {
|
||||
keys {
|
||||
{% for (let k in https_keys): %}
|
||||
id {{ k.id }} {
|
||||
key {{ k.key }}
|
||||
}
|
||||
{% endfor %}
|
||||
}
|
||||
rest {
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
certificates {
|
||||
{% if (https_ca_cert): %}
|
||||
ca-certificate {{ https_ca_cert }}
|
||||
{% endif %}
|
||||
{% if (https_cert): %}
|
||||
certificate {{ https_cert }}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
port {{ https_port }}
|
||||
}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,70 @@
|
||||
{%
|
||||
let data = (type(systeminfo) == "object" && type(systeminfo.data) == "object")
|
||||
? systeminfo.data : {};
|
||||
|
||||
let og_map = (type(data["operator-group"]) == "object") ? data["operator-group"] : {};
|
||||
let user_map = (type(data.user) == "object") ? data.user : {};
|
||||
|
||||
let og_names = keys(og_map);
|
||||
let user_names = keys(user_map);
|
||||
|
||||
%}
|
||||
system {
|
||||
login {
|
||||
{%
|
||||
for (let i = 0; i < length(og_names); i++) {
|
||||
let og_name = og_names[i];
|
||||
let og = og_map[og_name] || {};
|
||||
let cp = (type(og["command-policy"]) == "object") ? og["command-policy"] : {};
|
||||
let cp_allow = cp.allow || null;
|
||||
%}
|
||||
operator-group {{og_name}} {
|
||||
{%
|
||||
if (cp_allow) {
|
||||
%}
|
||||
command-policy {
|
||||
allow "{{cp_allow}}"
|
||||
}
|
||||
{%
|
||||
}
|
||||
%}
|
||||
}
|
||||
{%
|
||||
}
|
||||
|
||||
for (let i = 0; i < length(user_names); i++) {
|
||||
let user_name = user_names[i];
|
||||
let u = user_map[user_name] || {};
|
||||
let auth = (type(u.authentication) == "object") ? u.authentication : {};
|
||||
|
||||
let enc_pw = auth["encrypted-password"] || null;
|
||||
let plain_pw = auth["plaintext-password"] ? auth["plaintext-password"] : "";
|
||||
%}
|
||||
user {{user_name}} {
|
||||
{%
|
||||
if (type(auth) == "object") {
|
||||
%}
|
||||
authentication {
|
||||
{%
|
||||
if (enc_pw) {
|
||||
%}
|
||||
encrypted-password "{{enc_pw}}"
|
||||
{%
|
||||
}
|
||||
if (plain_pw) {
|
||||
%}
|
||||
plaintext-password "{{plain_pw}}"
|
||||
{%
|
||||
}
|
||||
%}
|
||||
}
|
||||
{%
|
||||
}
|
||||
%}
|
||||
}
|
||||
{%
|
||||
}
|
||||
%}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
// Warning: Do not remove the following line.
|
||||
// vyos-config-version: "bgp@6:broadcast-relay@1:cluster@2:config-management@1:conntrack@6:conntrack-sync@2:container@3:dhcp-relay@2:dhcp-server@11:dhcpv6-server@6:dns-dynamic@4:dns-forwarding@4:firewall@20:flow-accounting@2:https@7:ids@2:interfaces@33:ipoe-server@4:ipsec@13:isis@3:l2tp@9:lldp@3:mdns@1:monitoring@2:nat@8:nat66@3:nhrp@1:ntp@3:openconnect@3:openvpn@4:ospf@2:pim@1:policy@9:pppoe-server@11:pptp@5:qos@3:quagga@12:reverse-proxy@3:rip@1:rpki@2:salt@1:snmp@3:ssh@2:sstp@6:system@29:vpp@1:vrf@3:vrrp@4:vyos-accel-ppp@2:wanloadbalance@4:webproxy@2"
|
||||
// Release version: 2025.09.10-0018-rolling
|
||||
Reference in New Issue
Block a user