AddEvent::getDockerComposeFilename()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 15
nc 4
nop 0
dl 0
loc 19
rs 9.7666
c 0
b 0
f 0
1
<?php
2
3
namespace TheAentMachine\AentDockerCompose\Event;
4
5
use Safe\Exceptions\FilesystemException;
6
use Safe\Exceptions\StringsException;
7
use Symfony\Component\Filesystem\Filesystem;
8
use TheAentMachine\Aent\Context\BaseOrchestratorContext;
9
use TheAentMachine\Aent\Context\Context;
10
use TheAentMachine\Aent\Context\ContextInterface;
11
use TheAentMachine\Aent\Event\Orchestrator\AbstractOrchestratorAddEvent;
12
use TheAentMachine\Aent\Payload\CI\DockerComposeDeployJobPayload;
13
use TheAentMachine\Aent\Payload\ReverseProxy\ReverseProxyAddPayload;
14
use TheAentMachine\Aent\Registry\ColonyRegistry;
15
use TheAentMachine\Aent\Registry\Exception\ColonyRegistryException;
16
use TheAentMachine\AentDockerCompose\Context\DockerComposeContext;
17
use TheAentMachine\AentDockerCompose\Helper\DockerComposeHelper;
18
use TheAentMachine\Aenthill\Aenthill;
19
use TheAentMachine\Exception\MissingEnvironmentVariableException;
20
use function Safe\sprintf;
21
use function Safe\chown;
22
use function Safe\chgrp;
23
use TheAentMachine\Service\Exception\ServiceException;
24
use TheAentMachine\Service\Service;
25
26
final class AddEvent extends AbstractOrchestratorAddEvent
27
{
28
    /** @var DockerComposeContext */
29
    private $context;
30
31
    /** @var ColonyRegistry */
32
    private $reverseProxyServiceRegistry;
33
34
    /**
35
     * @return ContextInterface
36
     * @throws ColonyRegistryException
37
     * @throws FilesystemException
38
     * @throws MissingEnvironmentVariableException
39
     * @throws ServiceException
40
     * @throws StringsException
41
     */
42
    protected function setup(): ContextInterface
43
    {
44
        $this->reverseProxyServiceRegistry = ColonyRegistry::reverseProxyServiceRegistry();
45
        $this->context = new DockerComposeContext(BaseOrchestratorContext::fromMetadata());
46
        $this->context->setDockerComposeFilename($this->getDockerComposeFilename());
47
        $this->createDockerComposeFile();
48
        $this->output->writeln(sprintf("\n👌 Alright, I've created the file <info>%s</info>!", $this->context->getDockerComposeFilename()));
49
        $this->prompt->printAltBlock("Docker Compose: adding reverse proxy...");
50
        $this->addReverseProxy();
51
        return $this->context;
52
    }
53
54
    /**
55
     * @param ContextInterface $context
56
     * @return ContextInterface
57
     */
58
    protected function addDeployJobInCI(ContextInterface $context): ContextInterface
59
    {
60
        $this->prompt->printAltBlock("Docker Compose: adding deploy job in CI/CD...");
61
        $payload = new DockerComposeDeployJobPayload($this->context->getDockerComposeFilename());
62
        Aenthill::runJson(DockerComposeContext::CI_DEPENDENCY_KEY, 'DOCKER_COMPOSE_DEPLOY_JOB', $payload->toArray());
63
        return $this->context;
64
    }
65
66
    /**
67
     * @return string
68
     */
69
    private function getDockerComposeFilename(): string
70
    {
71
        $environmentType = $this->context->getEnvironmentType();
72
        $environmentName = $this->context->getEnvironmentName();
73
        $projectDir = $this->context->getProjectDir();
74
        $items = [];
75
        if (!\file_exists("$projectDir/docker-compose.yml")) {
76
            $items[] = 'docker-compose.yml';
77
        }
78
        $i = 0;
79
        $tmpFileName = "docker-compose.$environmentName.yml";
80
        while (\file_exists("$projectDir/$tmpFileName")) {
81
            $i++;
82
            $tmpFileName = "docker-compose.$environmentName$i.yml";
83
        }
84
        $items[] = $tmpFileName;
85
        $text = "\nYour <info>Docker Compose</info> filename for your <info>$environmentType</info> environment <info>$environmentName</info>";
86
        $helpText = "By default, <info>Docker Compose</info> will look for a file named <info>docker-compose.yml</info> when you run <info>docker-compose up</info>. Otherwise, you should run <info>docker-compose -f filename up</info>.";
87
        return $this->prompt->select($text, $items, $helpText, $items[0], true) ?? '';
88
    }
89
90
    /**
91
     * @return void
92
     * @throws StringsException
93
     * @throws FilesystemException
94
     */
95
    private function createDockerComposeFile(): void
96
    {
97
        $fileSystem = new Filesystem();
98
        $dockerComposePath = $this->context->getDockerComposeFilePath();
99
        $fileSystem->dumpFile($dockerComposePath, sprintf("version: '%s'", DockerComposeHelper::VERSION));
100
        $dirInfo = new \SplFileInfo(\dirname($dockerComposePath));
101
        chown($dockerComposePath, $dirInfo->getOwner());
102
        chgrp($dockerComposePath, $dirInfo->getGroup());
103
    }
104
105
    /**
106
     * @return void
107
     * @throws ColonyRegistryException
108
     * @throws FilesystemException
109
     * @throws ServiceException
110
     * @throws StringsException
111
     */
112
    private function addReverseProxy(): void
113
    {
114
        $aent = $this->reverseProxyServiceRegistry->getAent(ColonyRegistry::TRAEFIK);
115
        $context = Context::fromMetadata();
116
        Aenthill::register($aent->getImage(), DockerComposeContext::REVERSE_PROXY_SERVICE_DEPENDENCY_KEY, $context->toArray());
117
        $payload = new ReverseProxyAddPayload($this->context->getBaseVirtualHost());
118
        $response = Aenthill::runJson(DockerComposeContext::REVERSE_PROXY_SERVICE_DEPENDENCY_KEY, 'ADD_REVERSE_PROXY', $payload->toArray());
119
        $assoc = \GuzzleHttp\json_decode($response[0], true);
120
        $service = Service::parsePayload($assoc);
121
        $serializedService = DockerComposeHelper::dockerComposeServiceSerialize($service);
122
        DockerComposeHelper::mergeContentInDockerComposeFile($serializedService, $this->context->getDockerComposeFilePath(), true);
123
    }
124
}
125