Добавил named и функцию синхронизации конфига
This commit is contained in:
parent
7f7106386a
commit
d43ad8168e
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PublishConfigData" autoUpload="Always" serverName="1" remoteFilesAllowedToDisappearOnAutoupload="false" confirmBeforeUploading="false">
|
||||
<option name="confirmBeforeUploading" value="false" />
|
||||
<serverData>
|
||||
<paths name="1">
|
||||
<serverdata>
|
||||
<mappings>
|
||||
<mapping deploy="/" local="$PROJECT_DIR$" web="/" />
|
||||
</mappings>
|
||||
</serverdata>
|
||||
</paths>
|
||||
</serverData>
|
||||
<option name="myAutoUpload" value="ALWAYS" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State>
|
||||
<id>Error handlingJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Probable bugsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>RESTful Web Service (JAX-RS)</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Spring</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Spring BootSpring</id>
|
||||
</State>
|
||||
</expanded-state>
|
||||
<selected-state>
|
||||
<State>
|
||||
<id>User defined</id>
|
||||
</State>
|
||||
</selected-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/protected-resources-list.iml" filepath="$PROJECT_DIR$/.idea/protected-resources-list.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.0" />
|
||||
</project>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SshConfigs">
|
||||
<configs>
|
||||
<sshConfig authType="PASSWORD" host="172.16.100.40" id="1f4a1f9f-da20-402f-aacd-0cb94b211004" port="22" nameFormat="DESCRIPTIVE" username="root" useOpenSSHConfig="false" />
|
||||
</configs>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="WebServers">
|
||||
<option name="servers">
|
||||
<webServer id="a4ede633-44cd-40df-a8db-a1d5f363083d" name="1">
|
||||
<fileTransfer rootFolder="/opt/protected-resources-list" accessType="SFTP" host="172.16.100.40" port="22" sshConfigId="1f4a1f9f-da20-402f-aacd-0cb94b211004" sshConfig="root@172.16.100.40:22 password">
|
||||
<advancedOptions>
|
||||
<advancedOptions dataProtectionLevel="Private" keepAliveTimeout="0" passiveMode="true" shareSSLContext="true" />
|
||||
</advancedOptions>
|
||||
</fileTransfer>
|
||||
</webServer>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -4,12 +4,9 @@
|
|||
## networks
|
||||
Каталог с файлами сервисов и их подсетей
|
||||
|
||||
## utils
|
||||
Различные скрипты и утилиты
|
||||
|
||||
### Установка
|
||||
```shell
|
||||
apk add php php-session jq git
|
||||
apk add php php-session php-curl jq git
|
||||
cd /opt
|
||||
git clone https://git.kirillius.ru/kirillius/protected-resources-list.git
|
||||
cd /opt/protected-resources-list/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
require_once dirname(__DIR__) . "/loader.php";
|
||||
require_once dirname(__DIR__) . "/plugins/netsync/Netsync.php";
|
||||
|
||||
try {
|
||||
|
||||
|
||||
|
||||
$rpc = new StaticRPC();
|
||||
$instance = $rpc->getPlugins()["netsync"] ?? null;
|
||||
if ($instance === null) {
|
||||
throw new RuntimeException("Plugin is not enabled");
|
||||
}
|
||||
/**
|
||||
* @var Netsync $instance
|
||||
*/
|
||||
|
||||
$config = $instance->getRoutingConfig();
|
||||
$outfile = $argv[1];
|
||||
file_put_contents($outfile, implode("\n", $config));
|
||||
} catch (Exception $e) {
|
||||
echo "\nError:" . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
|
@ -13,4 +13,5 @@ PORT=`jq -r .web.port $CFGFILE`
|
|||
#TODO FIXME !!!!
|
||||
killall php
|
||||
cd $ROOT
|
||||
php $ROOT/loader.php --init
|
||||
php -S $HOST:$PORT $ROOT/server.php
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
interface IPluggable
|
||||
{
|
||||
const PROTECTED_NAMES = ["enable", "disable", "render", "init"];
|
||||
|
||||
public function init(PluginContext $context);
|
||||
public function onServerStarted();
|
||||
public function onInit(PluginContext $context);
|
||||
public function onSync();
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
abstract class Plugin implements IPluggable
|
||||
{
|
||||
protected PluginContext $context;
|
||||
protected array $config;
|
||||
|
||||
public function onServerStarted()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function onSync()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function onInit(PluginContext $context): void
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->checkConfig();
|
||||
$this->config = $this->context->getConfig()[$context->getName()];
|
||||
}
|
||||
|
||||
protected function checkConfig(): void
|
||||
{
|
||||
$config = $this->context->getConfig();
|
||||
$defaults = $this->context->getMetadata()["config"];
|
||||
$name = $this->context->getName();
|
||||
|
||||
if (!isset($config[$name])) {
|
||||
$config[$name] = $defaults;
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($defaults as $key => $value) {
|
||||
if (!isset($config[$name][$key])) {
|
||||
$config[$name][$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,14 +5,22 @@ class PluginContext
|
|||
private RPC $RPC;
|
||||
private Config $config;
|
||||
private array $metadata;
|
||||
private string $name;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RPC $RPC
|
||||
* @param Config $config
|
||||
* @param array $metadata
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(RPC $RPC, Config $config, array $metadata)
|
||||
public function __construct(RPC $RPC, Config $config, array $metadata, string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->RPC = $RPC;
|
||||
$this->config = $config;
|
||||
$this->metadata = $metadata;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class RPC
|
|||
try {
|
||||
$meta = $this->getPluginMetadata($plugin);
|
||||
$inst = $this->loadPlugin($plugin, $meta["class"]);
|
||||
$inst->init(new PluginContext($this, $this->config, $meta));
|
||||
$inst->onInit(new PluginContext($this, $this->config, $meta, $plugin));
|
||||
} catch (Error $e) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -117,6 +117,12 @@ class RPC
|
|||
return md5(sha1($what) . md5($what));
|
||||
}
|
||||
|
||||
private function isInternalMethod($name)
|
||||
{
|
||||
$cls = new ReflectionClass(IPluggable::class);
|
||||
return $cls->hasMethod($name);
|
||||
}
|
||||
|
||||
public function __invoke($method, $args)
|
||||
{
|
||||
$parts = explode("::", $method);
|
||||
|
|
@ -126,7 +132,7 @@ class RPC
|
|||
$this->checkAuth();
|
||||
$plugin = $this->plugins[$parts[0]];
|
||||
$methodname = $parts[1];
|
||||
if (in_array($methodname, IPluggable::PROTECTED_NAMES)) {
|
||||
if ($this->isInternalMethod($methodname)) {
|
||||
throw new RuntimeException("Unable to invoke internal methods");
|
||||
}
|
||||
return call_user_func([$plugin, $methodname], $args);
|
||||
|
|
|
|||
11
loader.php
11
loader.php
|
|
@ -3,4 +3,13 @@
|
|||
require_once __DIR__ . "/common.inc.php";
|
||||
spl_autoload_register(function ($classname) {
|
||||
require_once __DIR__ . "/classes/" . $classname . ".php";
|
||||
});
|
||||
});
|
||||
if (isset($argv) and in_array("--init", $argv)) {
|
||||
$rpc = new StaticRPC();
|
||||
foreach ($rpc->getPlugins() as $plugin => $instance) {
|
||||
/**
|
||||
* @var IPluggable $instance
|
||||
*/
|
||||
$instance->onServerStarted();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"description": "habrahabr",
|
||||
"domains": [
|
||||
"habr.com"
|
||||
"habr.com"
|
||||
],
|
||||
"networks": [
|
||||
"178.248.237.68/32"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
|
||||
class API extends Plugin
|
||||
{
|
||||
public function onInit(PluginContext $context): void
|
||||
{
|
||||
parent::onInit($context);
|
||||
if (!isset($this->config["key"])) {
|
||||
$this->config["key"] = sha1(rand() . uniqid());
|
||||
$this->context->getConfig()->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return $this->config["key"];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"class": "API",
|
||||
"config": {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import {App} from "/assets/App.js";
|
||||
|
||||
(async function () {
|
||||
let key = await App.RPC.__invoke("api::getKey");
|
||||
|
||||
$("body").append("<span>API Key: " + key + "</span>")
|
||||
})();
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
class BindPlugin extends Plugin
|
||||
{
|
||||
public function restart(): string|bool|null
|
||||
{
|
||||
$selectedDomains = [];
|
||||
|
||||
$networks = (new NetworkConfigReader())->getConfigs();
|
||||
|
||||
//add new routes
|
||||
foreach ($this->context->getConfig()["networks"] as $key) {
|
||||
|
||||
if (isset($networks[$key])) {
|
||||
foreach ($networks[$key]["domains"] as $domain) {
|
||||
$selectedDomains[] = $domain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$selectedDomains = array_unique($selectedDomains);
|
||||
|
||||
$data = [];
|
||||
|
||||
foreach ($selectedDomains as $domain) {
|
||||
$data[] = $this->createForwardRecord($domain);
|
||||
}
|
||||
|
||||
file_put_contents($this->config["file"], implode("\n", $data));
|
||||
|
||||
|
||||
return shell_exec($this->config["restart_cmd"]);
|
||||
}
|
||||
|
||||
private function createForwardRecord($domain)
|
||||
{
|
||||
$fwd = implode(";", $this->config["forwarders"]) . ";";
|
||||
return <<<TXT
|
||||
zone "{$domain}" IN {
|
||||
type forward;
|
||||
forward only;
|
||||
forwarders{{$fwd}};
|
||||
};
|
||||
TXT;
|
||||
|
||||
}
|
||||
|
||||
public function onServerStarted()
|
||||
{
|
||||
$this->restart();
|
||||
}
|
||||
|
||||
public function onSync()
|
||||
{
|
||||
$this->restart();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"class": "BindPlugin",
|
||||
"config": {
|
||||
"restart_cmd": "/etc/init.d/named restart",
|
||||
"file": "/var/bind/forward.dns",
|
||||
"forwarders": ["8.8.8.8", "1.1.1.1"]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import {App} from "/assets/App.js";
|
||||
|
||||
(async function () {
|
||||
$("#buttons").append(`<button id="restart-bind">Restart named</button>`);
|
||||
$("#restart-bind").click(function () {
|
||||
|
||||
const self = $(this);
|
||||
self.prop("disabled", true);
|
||||
(async function () {
|
||||
try {
|
||||
alert(await App.RPC.__invoke("named::restart"));
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
self.prop("disabled", false);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
});
|
||||
})();
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
class Netsync extends Plugin
|
||||
{
|
||||
public function sync()
|
||||
{
|
||||
$host = $this->config["master"];
|
||||
$key = $this->config["key"];
|
||||
|
||||
if (empty($key)) {
|
||||
throw new RuntimeException("API key is empty");
|
||||
}
|
||||
|
||||
$ch = curl_init($host);
|
||||
|
||||
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
||||
"jsonrpc" => "2.0",
|
||||
"id" => "1",
|
||||
"method" => "getNetworks",
|
||||
"params" => []
|
||||
]));
|
||||
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"X-Auth: " . md5($key),
|
||||
"Content-type: application/json"
|
||||
]);
|
||||
|
||||
$output = curl_exec($ch);
|
||||
if (curl_error($ch)) {
|
||||
return curl_error($ch);
|
||||
}
|
||||
curl_close($ch);
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"class": "Netsync",
|
||||
"config": {
|
||||
"master": "127.0.0.1:8001",
|
||||
"key": ""
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import {App} from "/assets/App.js";
|
||||
|
||||
(async function () {
|
||||
$("#buttons").append(`<button id="sync">Force sync</button>`);
|
||||
$("#sync").click(function () {
|
||||
|
||||
const self = $(this);
|
||||
self.prop("disabled", true);
|
||||
(async function () {
|
||||
try {
|
||||
alert(await App.RPC.__invoke("netsync::sync"));
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
});
|
||||
})();
|
||||
|
|
@ -1,29 +1,15 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
class Openvpn implements IPluggable
|
||||
class Openvpn extends Plugin
|
||||
{
|
||||
private PluginContext $context;
|
||||
|
||||
public function restart()
|
||||
{
|
||||
//restart ovpn
|
||||
return shell_exec($this->context->getConfig()["ovpn"]["restart_cmd"]);
|
||||
return shell_exec($this->config["restart_cmd"]);
|
||||
}
|
||||
|
||||
public function init(PluginContext $context): void
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->checkConfig();
|
||||
}
|
||||
|
||||
private function checkConfig(): void
|
||||
{
|
||||
$config = $this->context->getConfig();
|
||||
if (!isset($config["ovpn"])) {
|
||||
$config["ovpn"] = $this->context->getMetadata()["config"];
|
||||
}
|
||||
}
|
||||
|
||||
public function getRoutingConfig(): array
|
||||
{
|
||||
|
|
@ -44,5 +30,15 @@ class Openvpn implements IPluggable
|
|||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function onServerStarted()
|
||||
{
|
||||
$this->restart();
|
||||
}
|
||||
|
||||
public function onSync()
|
||||
{
|
||||
$this->restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
|
||||
|
||||
class QuaggaPlugin implements IPluggable
|
||||
class QuaggaPlugin extends Plugin
|
||||
{
|
||||
private PluginContext $context;
|
||||
|
||||
const REM_PREFIX = "! routes from file ";
|
||||
|
||||
public function restart(): string
|
||||
{
|
||||
$configfile = $this->context->getConfig()["quagga"]["file"];
|
||||
$configfile = $this->config["file"];
|
||||
|
||||
if (!file_exists($configfile)) {
|
||||
throw new RuntimeException("Quagga config file not found");
|
||||
|
|
@ -67,23 +67,16 @@ class QuaggaPlugin implements IPluggable
|
|||
file_put_contents($configfile, implode("\n", $lines));
|
||||
|
||||
//restart zebra
|
||||
return shell_exec($this->context->getConfig()["quagga"]["restart_cmd"]);
|
||||
|
||||
|
||||
return shell_exec($this->config["restart_cmd"]);
|
||||
}
|
||||
|
||||
|
||||
public function init(PluginContext $context): void
|
||||
public function onServerStarted()
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->checkConfig();
|
||||
$this->restart();
|
||||
}
|
||||
|
||||
private function checkConfig(): void
|
||||
public function onSync()
|
||||
{
|
||||
$config = $this->context->getConfig();
|
||||
if (!isset($config["quagga"])) {
|
||||
$config["quagga"] = $this->context->getMetadata()["config"];
|
||||
}
|
||||
$this->restart();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
class Updates implements IPluggable
|
||||
class Updates extends Plugin
|
||||
{
|
||||
|
||||
|
||||
|
|
@ -20,8 +20,5 @@ class Updates implements IPluggable
|
|||
return @shell_exec("git --no-pager pull --verbose 2>&1");
|
||||
}
|
||||
|
||||
public function init(PluginContext $context)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
const FILE = "test.txt";
|
||||
|
||||
|
||||
$data = file_get_contents(FILE);
|
||||
|
||||
$data = explode("\n", $data);
|
||||
|
||||
sort($data);
|
||||
|
||||
file_put_contents(FILE, implode("\n", $data));
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
"108.138.0.0/15",
|
||||
"108.156.0.0/14",
|
||||
"111.13.0.0/8",
|
||||
|
||||
"116.129.226.0/24",
|
||||
|
||||
"118.193.97.0/24",
|
||||
|
||||
"119.147.182.0/24",
|
||||
|
||||
"120.232.0.0/16",
|
||||
|
||||
"120.52.0.0/16",
|
||||
|
||||
"13.0.0.0/8",
|
||||
|
||||
"130.176.0.0/16",
|
||||
|
||||
"143.204.0.0/16",
|
||||
"144.220.0.0/16",
|
||||
|
||||
"15.128.0.0/9",
|
||||
|
||||
"18.0.0.0/8",
|
||||
|
||||
"180.163.57.0/24",
|
||||
|
||||
"204.246.0.0/16",
|
||||
|
||||
|
||||
"205.251.0.0/16",
|
||||
|
||||
"216.137.32.0/19",
|
||||
|
||||
"3.0.0.0/8",
|
||||
|
||||
"34.128.0.0/9",
|
||||
"35.0.0.0/8",
|
||||
|
||||
|
||||
|
||||
|
||||
"36.103.232.0/24",
|
||||
|
||||
"43.218.56.0/24",
|
||||
|
||||
"44.0.0.0/8",
|
||||
|
||||
|
||||
|
||||
"47.129.0.0/16",
|
||||
|
||||
|
||||
"52.0.0.0/8",
|
||||
|
||||
|
||||
"54.0.0.0/8",
|
||||
|
||||
"58.254.138.0/24",
|
||||
|
||||
"64.252.0.0/16",
|
||||
|
||||
"65.8.0.0/16",
|
||||
"65.9.0.0/16",
|
||||
|
||||
"70.132.0.0/18",
|
||||
"71.152.0.0/17",
|
||||
|
||||
"99.0.0.0/8",
|
||||
Loading…
Reference in New Issue