diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Command/RunCommand.php | 46 | ||||
| -rw-r--r-- | src/IAC.php | 25 | ||||
| -rw-r--r-- | src/Module/AptModule.php | 48 | ||||
| -rw-r--r-- | src/Module/ModuleInterface.php | 10 | ||||
| -rw-r--r-- | src/Module/State.php | 9 | ||||
| -rw-r--r-- | src/Task.php | 27 | 
6 files changed, 165 insertions, 0 deletions
diff --git a/src/Command/RunCommand.php b/src/Command/RunCommand.php new file mode 100644 index 0000000..048e94c --- /dev/null +++ b/src/Command/RunCommand.php @@ -0,0 +1,46 @@ +<?php + +namespace PHPIAC\Command; + +use PHPIAC\Task; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Net\SSH2; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class RunCommand extends Command +{ +    protected static $defaultName = 'run'; + +    protected function configure() +    {} + +    protected function execute(InputInterface $input, OutputInterface $output) +    { +        $cwd = getcwd(); +        $config = include $cwd . '/config.php'; + +        global $ssh; +        $ssh = new SSH2($config['host']); +        if (! $ssh->login($config['user'], PublicKeyLoader::load(file_get_contents($config['private_key_file'])))) { +            throw new \Exception('Login failed'); +        } + +        $commands = []; +        foreach ($config['tasks'] as $task) { +            /**@var Task $task*/ +            if (! $task->module->checkState()) { +                $output->writeln('Adding commands from ' . get_class($task->module)); +                array_push($commands, ...$task->module->getCommands()); +            } +            else { +                $output->writeln('Skipping commands from ' . get_class($task->module)); +            } +        } + +        $ssh->exec(implode(PHP_EOL, $commands)); + +        return Command::SUCCESS; +    } +} diff --git a/src/IAC.php b/src/IAC.php new file mode 100644 index 0000000..c4e476d --- /dev/null +++ b/src/IAC.php @@ -0,0 +1,25 @@ +<?php + +namespace PHPIAC; + +use PetrKnap\Php\Singleton\SingletonTrait; +use PHPIAC\Command\RunCommand; +use Symfony\Component\Console\Application; + +class IAC +{ +    use SingletonTrait; + +    public function __construct() +    { +        $application = new Application(); + +        $defaultCommand = new RunCommand(); +        $application->add($defaultCommand); +        $application->setDefaultCommand($defaultCommand->getName()); + +        # ... other commands here + +        $application->run(); +    } +} diff --git a/src/Module/AptModule.php b/src/Module/AptModule.php new file mode 100644 index 0000000..ff4cb95 --- /dev/null +++ b/src/Module/AptModule.php @@ -0,0 +1,48 @@ +<?php + +namespace PHPIAC\Module; + +use phpseclib3\Net\SSH2; + +class AptModule implements ModuleInterface +{ +    public function __construct( +        private string $package, +        private string $state = State::PRESENT +    ) {} + +    public function checkState(): bool +    { +        global $ssh; +        /**@var SSH2 $ssh*/ +        $ssh->enablePTY(); +        $ssh->exec("which $this->package"); + +        if ($this->state === State::PRESENT) { +            $state = ! empty($ssh->read()); +        } +        else if ($this->state === State::ABSENT) { +            $state = empty($ssh->read()); +        } + +        $ssh->disablePTY(); + +        return $state; +    } + +    public function getCommands(): array +    { +        if ($this->state === State::PRESENT) { +            return [ +                "sudo apt install -y $this->package", +            ]; +        } +        else if ($this->state === State::ABSENT) { +            return [ +                "sudo apt remove -y $this->package", +            ]; +        } + +        return []; +    } +} diff --git a/src/Module/ModuleInterface.php b/src/Module/ModuleInterface.php new file mode 100644 index 0000000..2963b5f --- /dev/null +++ b/src/Module/ModuleInterface.php @@ -0,0 +1,10 @@ +<?php + +namespace PHPIAC\Module; + +interface ModuleInterface +{ +    public function checkState(): bool; + +    public function getCommands(): array; +} diff --git a/src/Module/State.php b/src/Module/State.php new file mode 100644 index 0000000..c7f7af9 --- /dev/null +++ b/src/Module/State.php @@ -0,0 +1,9 @@ +<?php + +namespace PHPIAC\Module; + +class State +{ +    public const PRESENT = 'present'; +    public const ABSENT = 'absent'; +} diff --git a/src/Task.php b/src/Task.php new file mode 100644 index 0000000..598f55c --- /dev/null +++ b/src/Task.php @@ -0,0 +1,27 @@ +<?php + +namespace PHPIAC; + +use PHPIAC\Module\ModuleInterface; + +class Task +{ +    public function __construct( +        public ModuleInterface $module, +        public array $vars, +    ) {} + +    public function setModule(ModuleInterface $module): self +    { +        $this->module = $module; + +        return $this; +    } + +    public function setVars(array $vars): self +    { +        $this->vars = $vars; + +        return $this; +    } +}  | 
