AddEvent::getMySQLUser()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TheAentMachine\AentMysql\Event;
4
5
use Safe\Exceptions\ArrayException;
6
use Safe\Exceptions\FilesystemException;
7
use Safe\Exceptions\StringsException;
8
use TheAentMachine\Aent\Event\Service\AbstractServiceAddEvent;
9
use TheAentMachine\Aent\Event\Service\Model\Environments;
10
use TheAentMachine\Aent\Event\Service\Model\ServiceState;
11
use TheAentMachine\Prompt\Helper\ValidatorHelper;
12
use TheAentMachine\Service\Service;
13
14
final class AddEvent extends AbstractServiceAddEvent
15
{
16
    private const MYSQL_IMAGE = 'mysql';
17
    private const PHPMYADMIN_IMAGE = 'phpmyadmin/phpmyadmin';
18
19
    /**
20
     * @param Environments $environments
21
     * @return ServiceState[]
22
     * @throws ArrayException
23
     * @throws FilesystemException
24
     * @throws StringsException
25
     */
26
    protected function createServices(Environments $environments): array
27
    {
28
        $mysqlService = $this->createMySQLService();
29
        if ($environments->hasDevelopmentEnvironments() || $environments->hasTestEnvironments()) {
30
            $text = "\nDo you want a <info>phpMyAdmin</info> service?";
31
            $helpText = "<info>phpMyAdmin</info> will help you manage your database from your web browser.";
32
            $addPhpMyAdmin = $this->prompt->confirm($text, $helpText, null, true);
33
            if ($addPhpMyAdmin) {
34
                $this->output->writeln("\nšŸ‘Œ Alright, let's configure <info>phpMyAdmin</info>!");
35
                $phpMyAdminService = $this->createPhpMyAdminService($mysqlService);
36
                $mysqlServiceState = new ServiceState($mysqlService, $mysqlService, $mysqlService);
37
                $phpMyAdminServiceState = new ServiceState($phpMyAdminService, $phpMyAdminService, $phpMyAdminService);
38
                return [ $mysqlServiceState, $phpMyAdminServiceState ];
39
            }
40
            $this->output->writeln("\nšŸ‘Œ Alright, I'm not going to configure <info>phpMyAdmin</info>!");
41
            $serviceState = new ServiceState($mysqlService, $mysqlService, $mysqlService);
42
            return [ $serviceState ];
43
        }
44
        $this->output->writeln("\nAs you don't have <info>development</info> and <info>test</info> environments, I'm skipping <info>phpMyAdmin</info>!");
45
        $serviceState = new ServiceState($mysqlService, $mysqlService, $mysqlService);
46
        return [ $serviceState ];
47
    }
48
49
    /**
50
     * @return Service
51
     * @throws ArrayException
52
     * @throws FilesystemException
53
     * @throws StringsException
54
     */
55
    private function createMySQLService(): Service
56
    {
57
        $service = new Service();
58
        $service->setNeedBuild(false);
59
        $service->setServiceName($this->prompt->getPromptHelper()->getServiceName());
60
        $version = $this->prompt->getPromptHelper()->getVersion(self::MYSQL_IMAGE);
61
        $image = self::MYSQL_IMAGE . ':' . $version;
62
        $service->setImage($image);
63
        $service->addInternalPort(3306);
64
        // Argument necessary on Kubernetes clusters (the volume has a lost+found dir at the root)
65
        $service->addCommand('--ignore-db-dir=lost+found');
66
        $service->addCommand('--max_allowed_packet=512M');
67
        $rootPassword = $this->getMySQLPassword('Root password', 'The MySQL root password will be stored in the <info>MYSQL_ROOT_PASSWORD</info> environment variable.');
68
        $service->addSharedSecret('MYSQL_ROOT_PASSWORD', $rootPassword, 'The password for the root user of MySQL', $service->getServiceName());
69
        $databaseName = $this->getDatabaseName();
70
        $service->addSharedEnvVariable('MYSQL_DATABASE', trim($databaseName), 'A default database, created on MySQL first startup', $service->getServiceName());
71
        $databaseUser = $this->getMySQLUser();
72
        $service->addSharedEnvVariable('MYSQL_USER', $databaseUser, 'A default user, created on MySQL first startup', $service->getServiceName());
73
        $databaseUserPassword = $this->getMySQLPassword('Database user password', 'The MySQL user password will be stored in the <info>MYSQL_PASSWORD</info> environment variable.');
74
        $service->addSharedSecret('MYSQL_PASSWORD', $databaseUserPassword, 'The password of the default user, created on MySQL first startup', $service->getServiceName());
75
        $this->output->writeln("\nšŸ‘Œ Alright, we're almost done! Let's configure a named volume where your MySQL data will be stored!");
76
        $volumeName = $this->getMySQLNamedVolumeName();
77
        $service->addNamedVolume($volumeName, '/var/lib/mysql', false, 'This volume contains the whole MySQL data.');
78
        return $service;
79
    }
80
81
    /**
82
     * @return string
83
     */
84
    public function getDatabaseName(): string
85
    {
86
        $text = "\nDatabase name";
87
        $helpText = 'The database name will be stored in the <info>MYSQL_DATABASE</info> environment variable.';
88
        return $this->prompt->input($text, $helpText, null, true, ValidatorHelper::getAlphaWithAdditionalCharactersValidator(['-', '_'])) ?? '';
89
    }
90
91
    /**
92
     * @param string $text
93
     * @param string $helpText
94
     * @return string
95
     */
96
    private function getMySQLPassword(string $text, string $helpText): string
97
    {
98
        return $this->prompt->input($text, $helpText, null, true, ValidatorHelper::getAlphaWithAdditionalCharactersValidator(['-', '_'])) ?? '';
99
    }
100
101
    /**
102
     * @return string
103
     */
104
    private function getMySQLUser(): string
105
    {
106
        $text = "\nDatabase user";
107
        $helpText = 'The database user name will be stored in the <info>MYSQL_USER</info> environment variable.';
108
        return $this->prompt->input($text, $helpText, null, true, ValidatorHelper::getAlphaWithAdditionalCharactersValidator(['-', '_'])) ?? '';
109
    }
110
111
    /**
112
     * @return string
113
     */
114
    private function getMySQLNamedVolumeName(): string
115
    {
116
        $text = "\nMySQL named volume name";
117
        $helpText = 'The database files (located in the container in the <info>/var/lib/mysql</info> folder) will be stored in an external Docker volume.';
118
        return $this->prompt->input($text, $helpText, 'mysql-data', true, ValidatorHelper::getAlphaWithAdditionalCharactersValidator(['-', '_'])) ?? '';
119
    }
120
121
    /**
122
     * @param Service $mysqlService
123
     * @return Service
124
     * @throws ArrayException
125
     * @throws FilesystemException
126
     * @throws StringsException
127
     */
128
    private function createPhpMyAdminService(Service $mysqlService): Service
129
    {
130
        $service = new Service();
131
        $service->setNeedBuild(false);
132
        $service->setServiceName($this->prompt->getPromptHelper()->getServiceName());
133
        $version = $this->prompt->getPromptHelper()->getVersion(self::PHPMYADMIN_IMAGE);
134
        $image = self::PHPMYADMIN_IMAGE . ':' . $version;
135
        $service->setImage($image);
136
        $service->addInternalPort(80);
137
        $service->addContainerEnvVariable('PMA_HOST', $mysqlService->getServiceName());
138
        $service->addVirtualHost(80);
139
        return $service;
140
    }
141
}
142