summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--composer.json3
-rw-r--r--composer.lock489
-rw-r--r--src/AptModule.php38
-rw-r--r--src/CopyModule.php50
-rw-r--r--src/FileModule.php43
-rw-r--r--src/GitModule.php45
-rw-r--r--src/Support/HasPermissions.php15
-rw-r--r--src/Support/Permissions.php28
-rw-r--r--src/TemplateModule.php42
-rw-r--r--src/UfwModule.php39
-rw-r--r--src/UserModule.php61
11 files changed, 606 insertions, 247 deletions
diff --git a/composer.json b/composer.json
index 326cfdf..5a62542 100644
--- a/composer.json
+++ b/composer.json
@@ -7,7 +7,8 @@
}
],
"require": {
- "php": "^8.0"
+ "php": "^8.0",
+ "twig/twig": "^3.0"
},
"require-dev": {
"php-iac/php-iac": "*"
diff --git a/composer.lock b/composer.lock
index 74e0af2..6fb3ab6 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,247 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "3d3602fe312c9cb5a40153c717023570",
- "packages": [],
+ "content-hash": "f7aa089ef09df7a3a5b28d5a0b5cc327",
+ "packages": [
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+ "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-02-19T12:13:01+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "298b87cbbe99cb2c9f88fb1d1de78833b64b483e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/298b87cbbe99cb2c9f88fb1d1de78833b64b483e",
+ "reference": "298b87cbbe99cb2c9f88fb1d1de78833b64b483e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ },
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/main"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-19T09:32:22+00:00"
+ },
+ {
+ "name": "twig/twig",
+ "version": "3.x-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "32d72de1885889452f3d8aa298a90b04d263651b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/32d72de1885889452f3d8aa298a90b04d263651b",
+ "reference": "32d72de1885889452f3d8aa298a90b04d263651b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9"
+ },
+ "default-branch": true,
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/3.x"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-04-15T10:09:30+00:00"
+ }
+ ],
"packages-dev": [
{
"name": "paragonie/constant_time_encoding",
@@ -175,16 +414,18 @@
"dist": {
"type": "path",
"url": "../php-iac-cli",
- "reference": "671e3f1540f3a683d548dafd64c068ad6a64ac2f"
+ "reference": "3983548e7c0f107fa7b7cc3c4c36aa009590b481"
},
"require": {
"petrknap/php-singleton": "^1.0",
"php": "^8.0",
+ "php-iac/modules": "*",
+ "php-iac/role": "*",
"phpseclib/phpseclib": "^3.0",
"symfony/console": "^5.2"
},
"bin": [
- "bin/iac"
+ "bin/phpiac"
],
"type": "library",
"autoload": {
@@ -211,6 +452,37 @@
}
},
{
+ "name": "php-iac/role",
+ "version": "dev-main",
+ "dist": {
+ "type": "path",
+ "url": "../role",
+ "reference": "a8ddac7859f7139ce13d244c7dd39fae6ed07db0"
+ },
+ "require": {
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "php-iac/modules": "*",
+ "php-iac/php-iac": "*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPIAC\\Role\\": "src"
+ }
+ },
+ "authors": [
+ {
+ "name": "Daniel Weipert",
+ "email": "code@drogueronin.de"
+ }
+ ],
+ "transport-options": {
+ "relative": true
+ }
+ },
+ {
"name": "phpseclib/phpseclib",
"version": "3.0.x-dev",
"source": {
@@ -537,97 +809,17 @@
"time": "2021-03-23T23:28:01+00:00"
},
{
- "name": "symfony/polyfill-ctype",
- "version": "dev-main",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
- "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "suggest": {
- "ext-ctype": "For best performance"
- },
- "default-branch": true,
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.22-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2021-01-07T16:49:33+00:00"
- },
- {
"name": "symfony/polyfill-intl-grapheme",
"version": "dev-main",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170"
+ "reference": "053f7184175d5417c933817341c5cc0053ddacd5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170",
- "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/053f7184175d5417c933817341c5cc0053ddacd5",
+ "reference": "053f7184175d5417c933817341c5cc0053ddacd5",
"shasum": ""
},
"require": {
@@ -640,7 +832,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.22-dev"
+ "dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -680,7 +872,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1"
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/main"
},
"funding": [
{
@@ -696,7 +888,7 @@
"type": "tidelift"
}
],
- "time": "2021-01-22T09:19:47+00:00"
+ "time": "2021-02-19T12:13:01+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
@@ -704,12 +896,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
+ "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
- "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
+ "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
"shasum": ""
},
"require": {
@@ -722,7 +914,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.22-dev"
+ "dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -765,88 +957,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2021-01-22T09:19:47+00:00"
- },
- {
- "name": "symfony/polyfill-mbstring",
- "version": "dev-main",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
- "reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "suggest": {
- "ext-mbstring": "For best performance"
- },
- "default-branch": true,
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.22-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/main"
},
"funding": [
{
@@ -862,7 +973,7 @@
"type": "tidelift"
}
],
- "time": "2021-01-22T09:19:47+00:00"
+ "time": "2021-02-19T12:13:01+00:00"
},
{
"name": "symfony/polyfill-php73",
@@ -870,12 +981,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2"
+ "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
- "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010",
+ "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010",
"shasum": ""
},
"require": {
@@ -885,7 +996,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.22-dev"
+ "dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -926,7 +1037,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1"
+ "source": "https://github.com/symfony/polyfill-php73/tree/main"
},
"funding": [
{
@@ -942,7 +1053,7 @@
"type": "tidelift"
}
],
- "time": "2021-01-07T16:49:33+00:00"
+ "time": "2021-02-19T12:13:01+00:00"
},
{
"name": "symfony/polyfill-php80",
@@ -950,12 +1061,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
+ "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
- "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0",
+ "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0",
"shasum": ""
},
"require": {
@@ -965,7 +1076,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "1.22-dev"
+ "dev-main": "1.23-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -1010,7 +1121,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
+ "source": "https://github.com/symfony/polyfill-php80/tree/main"
},
"funding": [
{
@@ -1026,7 +1137,7 @@
"type": "tidelift"
}
],
- "time": "2021-01-07T16:49:33+00:00"
+ "time": "2021-02-19T12:13:01+00:00"
},
{
"name": "symfony/service-contracts",
diff --git a/src/AptModule.php b/src/AptModule.php
index 9b882e8..c133521 100644
--- a/src/AptModule.php
+++ b/src/AptModule.php
@@ -2,41 +2,33 @@
namespace PHPIAC\Modules;
+use PHPIAC\Connection;
use PHPIAC\Module\Module;
use PHPIAC\Module\State;
-use phpseclib3\Net\SSH2;
class AptModule extends Module
{
- /**
- * AptModule constructor.
- *
- * @param string $package
- * @param string $state
- */
- public function __construct(
- private string $package,
- private string $state = State::PRESENT
- ) {}
+ protected string $package;
+
+ protected string $state = State::PRESENT;
+ protected bool $updateCache = false;
/**
* @inheritDoc
*/
public function checkState(): bool
{
- global $ssh;
- /**@var SSH2 $ssh*/
- $ssh->enablePTY();
+ Connection::enablePty();
- $ssh->exec("dpkg -l $this->package | grep 'ii'");
- $dpkg = $ssh->read();
+ Connection::exec("dpkg -l $this->package | grep 'ii'");
+ $dpkg = Connection::read();
$state = match ($this->state) {
State::PRESENT => str_starts_with($dpkg, 'ii'),
State::ABSENT => str_contains($dpkg, 'no packages found'),
};
- $ssh->disablePTY();
+ Connection::disablePty();
return $state;
}
@@ -46,9 +38,13 @@ class AptModule extends Module
*/
public function getCommands(): array
{
- return match ($this->state) {
- State::PRESENT => ["sudo apt install -y $this->package"],
- State::ABSENT => ["sudo apt remove -y $this->package"],
- };
+ if ($this->state === State::PRESENT) {
+ Connection::exec("sudo apt install -y $this->package");
+ }
+ else if ($this->state === State::ABSENT) {
+ Connection::exec("sudo apt remove -y $this->package");
+ }
+
+ return [];
}
}
diff --git a/src/CopyModule.php b/src/CopyModule.php
new file mode 100644
index 0000000..069f594
--- /dev/null
+++ b/src/CopyModule.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace PHPIAC\Modules;
+
+use PHPIAC\Connection;
+use PHPIAC\Module\Module;
+use PHPIAC\Modules\Support\HasPermissions;
+
+class CopyModule extends Module
+{
+ use HasPermissions;
+
+ protected string $src;
+ protected string $dest;
+
+ protected bool $remoteSrc = false;
+
+ /**
+ * @inheritDoc
+ */
+ public function __construct(array $config)
+ {
+ parent::__construct($config);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function checkState(): bool
+ {
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getCommands(): array
+ {
+ if ($this->remoteSrc) {
+ Connection::exec("sudo cp -r $this->src $this->dest");
+ }
+ else {
+ Connection::put($this->dest, $this->src);
+ }
+
+ Connection::exec($this->getPermissions($this->dest));
+
+ return [];
+ }
+}
diff --git a/src/FileModule.php b/src/FileModule.php
new file mode 100644
index 0000000..95ba771
--- /dev/null
+++ b/src/FileModule.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace PHPIAC\Modules;
+
+use PHPIAC\Connection;
+use PHPIAC\Module\Module;
+use PHPIAC\Module\State;
+use PHPIAC\Modules\Support\HasPermissions;
+
+class FileModule extends Module
+{
+ use HasPermissions;
+
+ protected string $path;
+
+ protected string $state = State::PRESENT;
+
+ /**
+ * @inheritDoc
+ */
+ public function checkState(): bool
+ {
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getCommands(): array
+ {
+ if ($this->state === State::PRESENT) {
+ Connection::exec(
+ "sudo touch $this->path" . PHP_EOL .
+ $this->getPermissions($this->path)
+ );
+ }
+ else {
+ Connection::exec("sudo rm -rf $this->path");
+ }
+
+ return [];
+ }
+}
diff --git a/src/GitModule.php b/src/GitModule.php
new file mode 100644
index 0000000..3927992
--- /dev/null
+++ b/src/GitModule.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace PHPIAC\Modules;
+
+use PHPIAC\Connection;
+use PHPIAC\Module\Module;
+use PHPIAC\Modules\Support\HasPermissions;
+
+class GitModule extends Module
+{
+ use HasPermissions;
+
+ protected string $repo;
+ protected string $dest;
+
+ /**
+ * @inheritDoc
+ */
+ public function checkState(): bool
+ {
+ Connection::enablePty();
+
+ Connection::exec("ls $this->dest");
+ $ls = Connection::read();
+
+ $state = ! str_contains($ls, 'No such file or directory');
+
+ Connection::disablePty();
+
+ return $state;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getCommands(): array
+ {
+ Connection::exec(
+ "sudo git clone $this->repo $this->dest" . PHP_EOL .
+ $this->getPermissions($this->dest)
+ );
+
+ return [];
+ }
+}
diff --git a/src/Support/HasPermissions.php b/src/Support/HasPermissions.php
new file mode 100644
index 0000000..c42d71d
--- /dev/null
+++ b/src/Support/HasPermissions.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace PHPIAC\Modules\Support;
+
+trait HasPermissions
+{
+ protected string $owner = '';
+ protected string $group = '';
+ protected int $mode = 0;
+
+ public function getPermissions($path): string
+ {
+ return new Permissions($path, $this->owner, $this->group, $this->mode);
+ }
+}
diff --git a/src/Support/Permissions.php b/src/Support/Permissions.php
new file mode 100644
index 0000000..daabf5a
--- /dev/null
+++ b/src/Support/Permissions.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace PHPIAC\Modules\Support;
+
+class Permissions
+{
+ public function __construct(
+ protected string $path,
+ protected string $owner = '',
+ protected string $group = '',
+ protected int $mode = 0,
+ ) {}
+
+ public function __toString(): string
+ {
+ $permissions = [];
+
+ if (! empty($this->owner) || ! empty($this->group)) {
+ $permissions[] = "sudo chown -R $this->owner:$this->group $this->path";
+ }
+
+ if (! empty($this->mode)) {
+ $permissions[] = "sudo chmod -R $this->mode $this->path";
+ }
+
+ return implode(PHP_EOL, $permissions);
+ }
+}
diff --git a/src/TemplateModule.php b/src/TemplateModule.php
new file mode 100644
index 0000000..515d891
--- /dev/null
+++ b/src/TemplateModule.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace PHPIAC\Modules;
+
+use PHPIAC\Connection;
+use PHPIAC\Module\Module;
+use PHPIAC\Modules\Support\HasPermissions;
+use Twig\Environment;
+use Twig\Loader\FilesystemLoader;
+
+class TemplateModule extends Module
+{
+ use HasPermissions;
+
+ protected string $src;
+ protected string $dest;
+ protected array $vars;
+
+ /**
+ * @inheritDoc
+ */
+ public function checkState(): bool
+ {
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getCommands(): array
+ {
+ $loader = new FilesystemLoader(dirname($this->src));
+ $twig = new Environment($loader);
+ $rendered = $twig->render(basename($this->src), $this->vars);
+
+ Connection::put($this->dest, $rendered);
+
+ Connection::exec($this->getPermissions($this->dest));
+
+ return [];
+ }
+}
diff --git a/src/UfwModule.php b/src/UfwModule.php
new file mode 100644
index 0000000..1ec4452
--- /dev/null
+++ b/src/UfwModule.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace PHPIAC\Modules;
+
+use PHPIAC\Connection;
+use PHPIAC\Module\Module;
+use PHPIAC\Module\State;
+
+class UfwModule extends Module
+{
+ protected string $rule;
+ protected string $name;
+
+ protected string $state = State::ENABLED;
+
+ /**
+ * @inheritDoc
+ */
+ public function checkState(): bool
+ {
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getCommands(): array
+ {
+ Connection::exec(implode(PHP_EOL, [
+ "sudo ufw $this->rule $this->name",
+ match ($this->state) {
+ State::ENABLED => "sudo ufw --force enable",
+ State::DISABLED => "sudo ufw disable",
+ },
+ ]));
+
+ return [];
+ }
+}
diff --git a/src/UserModule.php b/src/UserModule.php
index fcab5a8..c230976 100644
--- a/src/UserModule.php
+++ b/src/UserModule.php
@@ -2,50 +2,37 @@
namespace PHPIAC\Modules;
+use PHPIAC\Connection;
use PHPIAC\Module\Module;
use PHPIAC\Module\State;
-use phpseclib3\Net\SSH2;
class UserModule extends Module
{
- /**
- * UserModule constructor.
- *
- * @param string $username
- * @param array $options
- * @param string $state
- */
- public function __construct(
- private string $username,
- private array $options = [],
- private string $state = State::PRESENT
- ) {
- $this->options = array_replace([
- 'append' => false,
- 'create_home' => true,
- 'groups' => [],
- 'shell' => '/bin/bash',
- ], $options);
- }
+ protected string $username;
+ protected string $password;
+
+ protected bool $append = false;
+ protected bool $createHome = true;
+ protected array $groups = [];
+ protected string $shell = '/bin/bash';
+ protected string $state = State::PRESENT;
/**
* @inheritDoc
*/
public function checkState(): bool
{
- global $ssh;
- /**@var SSH2 $ssh*/
- $ssh->enablePTY();
+ Connection::enablePty();
- $ssh->exec("cat /etc/passwd | grep $this->username:");
- $hasUser = $ssh->read();
+ Connection::exec("cat /etc/passwd | grep $this->username:");
+ $hasUser = Connection::read();
$state = match ($this->state) {
State::PRESENT => str_starts_with($hasUser, "$this->username:"),
State::ABSENT => empty($hasUser),
};
- $ssh->disablePTY();
+ Connection::disablePty();
return $state;
}
@@ -55,16 +42,18 @@ class UserModule extends Module
*/
public function getCommands(): array
{
- return match ($this->state) {
- State::PRESENT => [
+ if ($this->state === State::PRESENT) {
+ Connection::exec(implode(PHP_EOL, [
"sudo adduser $this->username --quiet" .
- " --shell " . $this->options['shell'] .
- ($this->options['create_home'] ? '' : ' --no-create-home'),
- "sudo usermod -" . ($this->options['append'] ? 'a' : '') . "G " . implode(',', $this->options['groups']) . " $this->username"
- ],
- State::ABSENT => [
- "sudo userdel $this->username",
- ],
- };
+ " --shell " . $this->shell .
+ ($this->createHome ? '' : ' --no-create-home'),
+ "sudo usermod -" . ($this->append ? 'a' : '') . "G " . implode(',', $this->groups) . " $this->username"
+ ]));
+ }
+ else if ($this->state === State::ABSENT) {
+ Connection::exec("sudo userdel $this->username");
+ }
+
+ return [];
}
}