diff options
-rw-r--r-- | composer.json | 3 | ||||
-rw-r--r-- | composer.lock | 489 | ||||
-rw-r--r-- | src/AptModule.php | 38 | ||||
-rw-r--r-- | src/CopyModule.php | 50 | ||||
-rw-r--r-- | src/FileModule.php | 43 | ||||
-rw-r--r-- | src/GitModule.php | 45 | ||||
-rw-r--r-- | src/Support/HasPermissions.php | 15 | ||||
-rw-r--r-- | src/Support/Permissions.php | 28 | ||||
-rw-r--r-- | src/TemplateModule.php | 42 | ||||
-rw-r--r-- | src/UfwModule.php | 39 | ||||
-rw-r--r-- | src/UserModule.php | 61 |
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 []; } } |