Passed
Push — develop ( 6e8c98...2d3c3b )
by Nikolay
04:46
created

AWSCloud::getMetaDataAWS()   A

Complexity

Conditions 5
Paths 10

Size

Total Lines 26
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 20
dl 0
loc 26
rs 9.2888
c 1
b 0
f 1
cc 5
nc 10
nop 1
1
<?php
2
/*
3
 * MikoPBX - free phone system for small business
4
 * Copyright © 2017-2024 Alexey Portnov and Nikolay Beketov
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with this program.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
namespace MikoPBX\Core\System\CloudProvisioning;
21
22
use GuzzleHttp\Exception\GuzzleException;
23
use GuzzleHttp;
24
25
class AWSCloud extends CloudProvider
26
{
27
    public const CloudID = 'AWSCloud';
28
    /**
29
     * Performs the Amazon Web Services cloud provisioning.
30
     *
31
     * @return bool True if the provisioning was successful, false otherwise.
32
     */
33
    public function provision(): bool
34
    {
35
        // Cloud check
36
        $checkValue = $this->getMetaDataAWS('services/partition');
37
        if ($checkValue!=='aws'){
38
            return false;
39
        }
40
41
        // Get host name
42
        $hostname = $this->getMetaDataAWS('hostname');
43
        if (empty($hostname)) {
44
            return false;
45
        }
46
47
        // Update machine name
48
        $this->updateHostName($hostname);
49
50
        // Update LAN settings with the external IP address
51
        $extIp = $this->getMetaDataAWS('public-ipv4');
52
        $this->updateLanSettings($extIp);
53
54
        // Update SSH keys, if available
55
        $sshKey = '';
56
        $sshKeys = $this->getMetaDataAWS('public-keys');
57
        $sshId = explode('=', $sshKeys)[0] ?? '';
58
        if ($sshId !== '') {
59
            $sshKey = $this->getMetaDataAWS("public-keys/$sshId/openssh-key");
60
        }
61
        $this->updateSSHKeys($sshKey);
62
63
        // Update SSH and WEB passwords using some unique identifier from the metadata
64
        $vmId = $this->getMetaDataAWS('instance-id')??'';
65
        $this->updateSSHPassword($vmId);
66
        $this->updateWebPassword($vmId);
67
68
        return true;
69
    }
70
71
    /**
72
     * Retrieves metadata from the MCS endpoint.
73
     *
74
     * @param string $url The URL of the metadata endpoint.
75
     * @return string The response body.
76
     */
77
    private function getMetaDataAWS(string $url): string
78
    {
79
        $baseUrl = 'http://169.254.169.254/latest/meta-data/';
80
        $client = new GuzzleHttp\Client();
81
        $headers = [];
82
        $params = [];
83
        $options = [
84
            'timeout' => self::HTTP_TIMEOUT,
85
            'http_errors' => false,
86
            'headers' => $headers
87
        ];
88
89
        $url = "$baseUrl/$url?" . http_build_query($params);
90
        try {
91
            $res = $client->request('GET', $url, $options);
92
            $code = $res->getStatusCode();
93
        } catch (GuzzleHttp\Exception\ConnectException $e) {
94
            $code = 0;
95
        } catch (GuzzleException $e) {
96
            $code = 0;
97
        }
98
        $body = '';
99
        if ($code === 200 && isset($res)) {
100
            $body = $res->getBody()->getContents();
101
        }
102
        return $body;
103
    }
104
}