Completed
Push — master ( 73295c...349be7 )
by David
02:23
created

NewServiceEventCommand::executeJsonEvent()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 50
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 27
dl 0
loc 50
rs 8.5546
c 0
b 0
f 0
cc 7
nc 13
nop 1
1
<?php
2
3
namespace TheAentMachine\AentDockerCompose\Command;
4
5
use TheAentMachine\AentDockerCompose\DockerCompose\DockerComposeService;
6
use TheAentMachine\AentDockerCompose\DockerCompose\EnvFile;
7
use TheAentMachine\Aenthill\Aenthill;
8
use TheAentMachine\Aenthill\CommonDependencies;
9
use TheAentMachine\Aenthill\CommonEvents;
10
use TheAentMachine\Aenthill\CommonMetadata;
11
use TheAentMachine\Aenthill\Manifest;
12
use TheAentMachine\Aenthill\Pheromone;
13
use TheAentMachine\Command\AbstractJsonEventCommand;
14
use TheAentMachine\Exception\CommonAentsException;
15
use TheAentMachine\Exception\ManifestException;
16
use TheAentMachine\Exception\MissingEnvironmentVariableException;
17
use TheAentMachine\Service\Exception\ServiceException;
18
use TheAentMachine\Service\Service;
19
20
class NewServiceEventCommand extends AbstractJsonEventCommand
21
{
22
    protected function getEventName(): string
23
    {
24
        return CommonEvents::NEW_SERVICE_EVENT;
25
    }
26
27
    /**
28
     * @param array $payload
29
     * @return array|null
30
     * @throws ManifestException
31
     * @throws MissingEnvironmentVariableException
32
     * @throws ServiceException
33
     * @throws CommonAentsException
34
     */
35
    protected function executeJsonEvent(array $payload): ?array
36
    {
37
        $service = Service::parsePayload($payload);
38
        if (!$service->isForMyEnvType()) {
39
            return null;
40
        }
41
42
        $fileName = Manifest::mustGetMetadata(CommonMetadata::DOCKER_COMPOSE_FILENAME_KEY);
43
        $dockerComposePath = Pheromone::getContainerProjectDirectory() . '/' . $fileName;
44
45
        $this->getAentHelper()->title($fileName);
46
47
        // Virtual Host
48
        if ($service->getNeedVirtualHost()) {
49
            if (null === Manifest::getDependency(CommonDependencies::REVERSE_PROXY_KEY)) {
50
                $this->getAentHelper()->getCommonQuestions()->askForReverseProxy();
51
                $this->runAddReverseProxy($dockerComposePath);
52
            }
53
            $service = $this->newVirtualHost($service);
54
        }
55
56
        if ($service->getNeedBuild()) {
57
            $service = $this->newImageToBuild($service);
58
        }
59
60
        $serviceName = $service->getServiceName();
61
62
        // .env-xxx file
63
        $envMapDotEnvFile = DockerComposeService::getEnvironmentVariablesForDotEnv($service);
64
        $envFilePath = null;
65
        if ($envMapDotEnvFile) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $envMapDotEnvFile of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
66
            // TODO: name of file is certainly impacted by name of docker-compose file.
67
            $envFilePath = '.env-' .$service->getServiceName();
68
            $dotEnvFile = new EnvFile(Pheromone::getContainerProjectDirectory() . '/' . $envFilePath);
69
            foreach ($envMapDotEnvFile as $key => $env) {
70
                $dotEnvFile->set($key, $env->getValue(), $env->getComment());
71
            }
72
        }
73
74
75
        // docker-compose
76
        $formattedPayload = DockerComposeService::dockerComposeServiceSerialize($service, $envFilePath);
77
        $this->log->debug(\GuzzleHttp\json_encode($formattedPayload, JSON_PRETTY_PRINT));
78
79
        $dockerComposePath = Pheromone::getContainerProjectDirectory() . '/' . $fileName;
80
        DockerComposeService::mergeContentInDockerComposeFile($formattedPayload, $dockerComposePath, true);
81
82
        $this->output->writeln("Service <info>$serviceName</info> has been successfully added in <info>$fileName</info>!");
83
84
        return null;
85
    }
86
87
    /**
88
     * @param string $dockerComposePath
89
     * @throws ManifestException
90
     * @throws ServiceException
91
     */
92
    private function runAddReverseProxy(string $dockerComposePath): void
93
    {
94
        $reverseProxyKey = Manifest::mustGetDependency(CommonDependencies::REVERSE_PROXY_KEY);
95
        $repliedPayloads = Aenthill::runJson($reverseProxyKey, CommonEvents::ADD_EVENT, []);
96
        $payload = \GuzzleHttp\json_decode($repliedPayloads[0], true);
97
        $service = Service::parsePayload($payload);
98
        $formattedPayload = DockerComposeService::dockerComposeServiceSerialize($service);
99
        DockerComposeService::mergeContentInDockerComposeFile($formattedPayload, $dockerComposePath, true);
100
101
        $serviceName = $service->getServiceName();
102
        $fileName = Manifest::mustGetMetadata(CommonMetadata::DOCKER_COMPOSE_FILENAME_KEY);
103
        $this->output->writeln("Reverse proxy <info>$serviceName</info> has been successfully added in <info>$fileName</info>!");
104
    }
105
106
107
    /**
108
     * @param Service $service
109
     * @return Service
110
     * @throws ManifestException
111
     * @throws ServiceException
112
     */
113
    private function newVirtualHost(Service $service): Service
114
    {
115
        $reverseProxyKey = Manifest::mustGetDependency(CommonDependencies::REVERSE_PROXY_KEY);
116
        $repliedPayloads = Aenthill::runJson($reverseProxyKey, CommonEvents::NEW_VIRTUAL_HOST_EVENT, $service->jsonSerialize());
117
        $payload = \GuzzleHttp\json_decode($repliedPayloads[0], true);
118
        $service = Service::parsePayload($payload);
119
120
        $serviceName = $service->getServiceName();
121
        $this->output->writeln("A new virtual host has been successfully added for <info>$serviceName</info>!");
122
        $this->getAentHelper()->spacer();
123
124
        return $service;
125
    }
126
127
    /**
128
     * @param Service $service
129
     * @return Service
130
     */
131
    private function newImageToBuild(Service $service): Service
132
    {
133
        $imageBuilderAentID = Manifest::getDependency(CommonDependencies::IMAGE_BUILDER_KEY);
134
        if (null === $imageBuilderAentID) {
135
            return $service;
136
        }
137
138
        $repliedPayloads = Aenthill::runJson($imageBuilderAentID, CommonEvents::NEW_IMAGE_EVENT, $service->imageJsonSerialize());
139
        $payload = \GuzzleHttp\json_decode($repliedPayloads[0], true);
140
        $dockerfileName = $payload['dockerfileName'];
141
        $this->getAentHelper()->spacer();
142
143
        $CIAentID = Manifest::getDependency(CommonDependencies::CI_KEY);
144
        if (null === $CIAentID) {
145
            return $service;
146
        }
147
148
        $serviceName = $service->getServiceName();
149
150
        $repliedPayloads = Aenthill::runJson($CIAentID, CommonEvents::NEW_BUILD_IMAGE_JOB_EVENT, [
151
            'serviceName' => $serviceName,
152
            'dockerfileName' => $dockerfileName,
153
        ]);
154
        $payload = \GuzzleHttp\json_decode($repliedPayloads[0], true);
155
156
        $dockerImageName = $payload['dockerImageName'];
157
        $service->setImage($dockerImageName);
158
        $service->removeAllBindVolumes();
159
160
        $this->getAentHelper()->spacer();
161
        $this->output->writeln("Service <info>$serviceName</info> is now using image <info>$dockerImageName</info>!");
162
        $this->getAentHelper()->spacer();
163
164
        return $service;
165
    }
166
}
167