diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -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
diff --git a/.idea/deployment.xml b/.idea/deployment.xml
new file mode 100644
index 0000000..8e2db99
--- /dev/null
+++ b/.idea/deployment.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..15f749d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+ Error handlingJava
+
+
+ Java
+
+
+ Probable bugsJava
+
+
+ RESTful Web Service (JAX-RS)
+
+
+ Spring
+
+
+ Spring BootSpring
+
+
+
+
+ User defined
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..b89a405
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/php.xml b/.idea/php.xml
new file mode 100644
index 0000000..4bf4979
--- /dev/null
+++ b/.idea/php.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/protected-resources-list.iml b/.idea/protected-resources-list.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/protected-resources-list.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/sshConfigs.xml b/.idea/sshConfigs.xml
new file mode 100644
index 0000000..c76ae96
--- /dev/null
+++ b/.idea/sshConfigs.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/webServers.xml b/.idea/webServers.xml
new file mode 100644
index 0000000..0ccc552
--- /dev/null
+++ b/.idea/webServers.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 2ba54e9..7e567ab 100644
--- a/README.md
+++ b/README.md
@@ -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/
diff --git a/bin/sync-networks b/bin/sync-networks
new file mode 100755
index 0000000..16b4f50
--- /dev/null
+++ b/bin/sync-networks
@@ -0,0 +1,27 @@
+#!/usr/bin/php
+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);
\ No newline at end of file
diff --git a/bin/webui-server b/bin/webui-server
index 13d8d14..97ea029 100755
--- a/bin/webui-server
+++ b/bin/webui-server
@@ -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
\ No newline at end of file
diff --git a/classes/IPluggable.php b/classes/IPluggable.php
index 149322f..c8c4349 100644
--- a/classes/IPluggable.php
+++ b/classes/IPluggable.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();
}
\ No newline at end of file
diff --git a/classes/Plugin.php b/classes/Plugin.php
new file mode 100644
index 0000000..f9e123c
--- /dev/null
+++ b/classes/Plugin.php
@@ -0,0 +1,42 @@
+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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/classes/PluginContext.php b/classes/PluginContext.php
index e863662..d8ccfec 100644
--- a/classes/PluginContext.php
+++ b/classes/PluginContext.php
@@ -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;
diff --git a/classes/RPC.php b/classes/RPC.php
index 1a0be96..a5f707b 100644
--- a/classes/RPC.php
+++ b/classes/RPC.php
@@ -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);
diff --git a/loader.php b/loader.php
index a943e90..4880f31 100644
--- a/loader.php
+++ b/loader.php
@@ -3,4 +3,13 @@
require_once __DIR__ . "/common.inc.php";
spl_autoload_register(function ($classname) {
require_once __DIR__ . "/classes/" . $classname . ".php";
-});
\ No newline at end of file
+});
+if (isset($argv) and in_array("--init", $argv)) {
+ $rpc = new StaticRPC();
+ foreach ($rpc->getPlugins() as $plugin => $instance) {
+ /**
+ * @var IPluggable $instance
+ */
+ $instance->onServerStarted();
+ }
+}
\ No newline at end of file
diff --git a/networks/habr.json b/networks/habr.json
index b63b805..3adf98a 100644
--- a/networks/habr.json
+++ b/networks/habr.json
@@ -1,7 +1,7 @@
{
"description": "habrahabr",
"domains": [
-"habr.com"
+ "habr.com"
],
"networks": [
"178.248.237.68/32"
diff --git a/plugins/api/API.php b/plugins/api/API.php
new file mode 100644
index 0000000..aeaa10a
--- /dev/null
+++ b/plugins/api/API.php
@@ -0,0 +1,20 @@
+config["key"])) {
+ $this->config["key"] = sha1(rand() . uniqid());
+ $this->context->getConfig()->save();
+ }
+ }
+
+ public function getKey(): string
+ {
+ return $this->config["key"];
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/api/metadata.json b/plugins/api/metadata.json
new file mode 100644
index 0000000..8e2b88c
--- /dev/null
+++ b/plugins/api/metadata.json
@@ -0,0 +1,5 @@
+{
+ "class": "API",
+ "config": {
+ }
+}
\ No newline at end of file
diff --git a/plugins/api/plugin.js b/plugins/api/plugin.js
new file mode 100644
index 0000000..746ee31
--- /dev/null
+++ b/plugins/api/plugin.js
@@ -0,0 +1,7 @@
+import {App} from "/assets/App.js";
+
+(async function () {
+ let key = await App.RPC.__invoke("api::getKey");
+
+ $("body").append("API Key: " + key + "")
+})();
\ No newline at end of file
diff --git a/plugins/named/BindPlugin.php b/plugins/named/BindPlugin.php
new file mode 100644
index 0000000..8f4723b
--- /dev/null
+++ b/plugins/named/BindPlugin.php
@@ -0,0 +1,57 @@
+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 <<restart();
+ }
+
+ public function onSync()
+ {
+ $this->restart();
+ }
+}
\ No newline at end of file
diff --git a/plugins/named/metadata.json b/plugins/named/metadata.json
new file mode 100644
index 0000000..ade9a90
--- /dev/null
+++ b/plugins/named/metadata.json
@@ -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"]
+ }
+}
\ No newline at end of file
diff --git a/plugins/named/plugin.js b/plugins/named/plugin.js
new file mode 100644
index 0000000..3768e35
--- /dev/null
+++ b/plugins/named/plugin.js
@@ -0,0 +1,21 @@
+import {App} from "/assets/App.js";
+
+(async function () {
+ $("#buttons").append(``);
+ $("#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);
+ }
+
+ })();
+
+ });
+})();
\ No newline at end of file
diff --git a/plugins/netsync/Netsync.php b/plugins/netsync/Netsync.php
new file mode 100644
index 0000000..95bfa6d
--- /dev/null
+++ b/plugins/netsync/Netsync.php
@@ -0,0 +1,38 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/plugins/netsync/metadata.json b/plugins/netsync/metadata.json
new file mode 100644
index 0000000..534dff2
--- /dev/null
+++ b/plugins/netsync/metadata.json
@@ -0,0 +1,7 @@
+{
+ "class": "Netsync",
+ "config": {
+ "master": "127.0.0.1:8001",
+ "key": ""
+ }
+}
\ No newline at end of file
diff --git a/plugins/netsync/plugin.js b/plugins/netsync/plugin.js
new file mode 100644
index 0000000..adceea8
--- /dev/null
+++ b/plugins/netsync/plugin.js
@@ -0,0 +1,21 @@
+import {App} from "/assets/App.js";
+
+(async function () {
+ $("#buttons").append(``);
+ $("#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);
+ }
+
+ })();
+
+ });
+})();
\ No newline at end of file
diff --git a/plugins/openvpn/Openvpn.php b/plugins/openvpn/Openvpn.php
index 8e8b349..a042b47 100755
--- a/plugins/openvpn/Openvpn.php
+++ b/plugins/openvpn/Openvpn.php
@@ -1,29 +1,15 @@
#!/usr/bin/php
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();
+ }
}
diff --git a/plugins/quagga/QuaggaPlugin.php b/plugins/quagga/QuaggaPlugin.php
index f76a613..4b504bb 100644
--- a/plugins/quagga/QuaggaPlugin.php
+++ b/plugins/quagga/QuaggaPlugin.php
@@ -1,14 +1,14 @@
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();
}
}
\ No newline at end of file
diff --git a/plugins/updates/Updates.php b/plugins/updates/Updates.php
index 6edc71e..12e54aa 100644
--- a/plugins/updates/Updates.php
+++ b/plugins/updates/Updates.php
@@ -1,6 +1,6 @@
&1");
}
- public function init(PluginContext $context)
- {
- }
}
\ No newline at end of file
diff --git a/sort.php b/sort.php
new file mode 100644
index 0000000..b71950b
--- /dev/null
+++ b/sort.php
@@ -0,0 +1,12 @@
+