Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 11 |
CRAP | |
0.00% |
0 / 113 |
Diffusion | |
0.00% |
0 / 1 |
|
0.00% |
0 / 11 |
1056 | |
0.00% |
0 / 113 |
__construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
run | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 18 |
|||
getSiteDetail | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
copyFilesToCdnMirror | |
0.00% |
0 / 1 |
30 | |
0.00% |
0 / 19 |
|||
createZone | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
createAlias | |
0.00% |
0 / 1 |
30 | |
0.00% |
0 / 17 |
|||
getDomain | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
getSubDomain | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
createDnsEntry | |
0.00% |
0 / 1 |
42 | |
0.00% |
0 / 18 |
|||
getTrackerConfig | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
copyFilesToTrackers | |
0.00% |
0 / 1 |
42 | |
0.00% |
0 / 25 |
1 | <?php |
2 | |
3 | |
4 | namespace Qmp\Laravel\SiteGeneratorDiffusion\Services; |
5 | |
6 | use Illuminate\Support\Facades\{Log, Redis, Storage}; |
7 | use Illuminate\Http\File as HttpFile; |
8 | use Qmp\Laravel\CDNApi\Cdn\InterfaceProvider; |
9 | use Qmp\Laravel\MicroService\Client\Tools\Request as ClientRequest; |
10 | use Qmp\Laravel\MicroService\Client\Client; |
11 | use Qmp\Laravel\ToolsLaravel\FilesManager\FilesManager; |
12 | use \Illuminate\Filesystem\FilesystemManager; |
13 | |
14 | class Diffusion |
15 | { |
16 | private $cdn; |
17 | |
18 | private $filesManager; |
19 | |
20 | private $serviceSiteDetail = 'service_site_generator_detail'; |
21 | |
22 | private $serviceTracker = 'service_tracker'; |
23 | |
24 | private $serviceOvh = 'service_ovh'; |
25 | |
26 | private $siteDetail; |
27 | |
28 | private $assetsFilesLocationDisk = 'site_generator'; |
29 | |
30 | private $originFilesLocationDisk = 'site_generator_sg_tpl'; |
31 | |
32 | private $cdnFilesLocationDisk = 'cdn_mirror_public'; |
33 | |
34 | private $trackersFilesLocationDisks = ['ssh_tracker1']; |
35 | |
36 | private $pathCdnMirror = 'assets'; |
37 | |
38 | private $pathTracker = 'siteGenerator'; |
39 | |
40 | public function __construct() |
41 | { |
42 | $this->cdn = resolve(InterfaceProvider::class); |
43 | |
44 | $this->filesManager = resolve(FilesManager::class); |
45 | } |
46 | |
47 | public function run($siteId) |
48 | { |
49 | // Get site detail config |
50 | $this->siteDetail = $this->getSiteDetail($siteId); |
51 | $domainName = 'cdn.' . ($this->siteDetail->config->domain->text ?? ''); |
52 | |
53 | // Copy to project public cdn mirror url |
54 | $filesToPurge = $this->copyFilesToCdnMirror($siteId); |
55 | if (empty($filesToPurge)) { |
56 | Redis::publish('site-generator-creator', json_encode(['action' => 'upload-sites', 'siteId' => $siteId, 'message' => 'No files copies to CDN'])); |
57 | return false; |
58 | } else { |
59 | // Upload assets to CDN |
60 | $zone = $this->cdn->getZoneByAliasName($domainName); |
61 | $urls = array_map(function($file) use ($domainName) { |
62 | return $domainName . '/' . $file; |
63 | }, $filesToPurge); |
64 | |
65 | // Purge CDN files |
66 | if (!$this->cdn->purgeFilesByUrls($zone['id'], $urls)) { |
67 | Log::debug('Unable to purge files for ' . $siteId); |
68 | } |
69 | |
70 | // upload html file to Tracker |
71 | $filesUploaded = $this->copyFilesToTrackers($siteId); |
72 | |
73 | // Send pub/sub to finish diffusion of site |
74 | if (empty($filesUploaded)) { |
75 | Redis::publish('site-generator-creator', json_encode(['action' => 'upload-sites', 'siteId' => $siteId, 'message' => 'No files copies to Trackers'])); |
76 | return false; |
77 | } else { |
78 | Redis::publish('site-generator-creator', json_encode(['action' => 'upload-sites', 'siteId' => $siteId, 'message' => 'files copied to CDN and Trackers'])); |
79 | return true; |
80 | } |
81 | } |
82 | } |
83 | |
84 | protected function getSiteDetail($siteId) |
85 | { |
86 | $request = ClientRequest::createObject($this->serviceSiteDetail, 'site'); |
87 | $response = Client::systemSend('get', $request, $siteId); |
88 | |
89 | return json_decode($response->body)->site_detail; |
90 | } |
91 | |
92 | protected function copyFilesToCdnMirror($siteId) |
93 | { |
94 | $pathToSite = $this->pathCdnMirror . '/' . $this->siteDetail->config->url . '/' . $this->siteDetail->config->urlHash; |
95 | $this->filesManager->to(Storage::disk($this->cdnFilesLocationDisk)); |
96 | |
97 | // Save file to good folder |
98 | $this->filesManager->from(Storage::disk($this->originFilesLocationDisk)) |
99 | ->directory($siteId, $pathToSite, true); |
100 | |
101 | $this->filesManager->from(Storage::disk($this->assetsFilesLocationDisk)); |
102 | |
103 | // Copy uploaded images to cdn |
104 | foreach ($this->siteDetail->template->images->affectation as $item) { |
105 | if ($item->value) { |
106 | $this->filesManager->file( |
107 | $item->value, |
108 | $pathToSite . '/images/' . $item->value |
109 | ); |
110 | } |
111 | } |
112 | |
113 | // Copy uploaded regulation file to cdn |
114 | if (!empty($this->siteDetail->template->regulationFile->name)) { |
115 | $this->filesManager->file( |
116 | $this->siteDetail->template->regulationFile->name, |
117 | $pathToSite . '/' . $this->siteDetail->template->regulationFile->name |
118 | ); |
119 | } |
120 | |
121 | // Copy uploaded terms file to cdn |
122 | if (!empty($this->siteDetail->template->termsFile->name)) { |
123 | $this->filesManager->file( |
124 | $this->siteDetail->template->termsFile->name, |
125 | $pathToSite . '/' . $this->siteDetail->template->termsFile->name |
126 | ); |
127 | } |
128 | |
129 | return $this->filesManager->allDestinationFiles($pathToSite); |
130 | } |
131 | |
132 | public function createZone($zoneName) |
133 | { |
134 | return $this->cdn->createZone([ |
135 | 'name' => $zoneName, |
136 | 'originurl' => Storage::disk($this->cdnFilesLocationDisk)->url('') |
137 | ]); |
138 | } |
139 | |
140 | public function createAlias($zoneId, $url) |
141 | { |
142 | // Create CDN Alias |
143 | $zone = $this->cdn->zone($zoneId); |
144 | $aliases = array_filter($zone['aliases'], function ($item) use ($zoneId, $url) { |
145 | return $item['zone_id'] === $zoneId || $item['name'] === $url; |
146 | }); |
147 | |
148 | if (!empty($aliases)) { |
149 | foreach ($aliases as $alias) { |
150 | $this->cdn->deleteAlias($alias['id']); |
151 | } |
152 | } |
153 | |
154 | $aliasAction = $this->cdn->createAlias($zoneId, $url); |
155 | |
156 | if ($aliasAction) { |
157 | // Create DNS for CDN |
158 | $domain = $this->getDomain($url); |
159 | $subdomain = $this->getSubDomain($url); |
160 | return $this->createDnsEntry($domain, [ |
161 | 'fieldType' => "CNAME", |
162 | 'subDomain' => $subdomain, |
163 | 'target' => $zone['zoneurl'], |
164 | 'ttl' => 86400 |
165 | ]); |
166 | } |
167 | |
168 | return false; |
169 | } |
170 | |
171 | protected function getDomain($url) |
172 | { |
173 | $explodedUrl = explode('.', $url); |
174 | return implode('.', array_slice($explodedUrl, -2, 2)); |
175 | } |
176 | |
177 | protected function getSubDomain($url) |
178 | { |
179 | $domain = $this->getDomain($url); |
180 | return sustr(str_replace($domain, '', $url), 0, -1); |
181 | } |
182 | |
183 | protected function createDnsEntry(string $domainName, array $data) |
184 | { |
185 | $subDomainsRequest = ClientRequest::createObject($this->serviceOvh, 'records'); |
186 | $subDomainsResponse = Client::systemSend('get', $subDomainsRequest); |
187 | $subDomains = json_decode($subDomainsResponse->body); |
188 | |
189 | $subDomains = array_filter($subDomains, function ($item) use ($data) { |
190 | return $item['subDomain'] === $data['subDomain'] && $item['fieldType'] === $data['fieldType']; |
191 | }); |
192 | |
193 | if (!empty($subDomains)) { |
194 | $request = ClientRequest::createObject($this->serviceOvh, $domainName . '/records/' . $subDomains['id']); |
195 | $response = Client::systemSend('put', $request, $data); |
196 | } else { |
197 | $request = ClientRequest::createObject($this->serviceOvh, $domainName . '/records'); |
198 | $response = Client::systemSend('post', $request, $data); |
199 | } |
200 | |
201 | try { |
202 | $response = json_decode($response->body); |
203 | if (!$response->status || $response->status !== 'ok') { |
204 | throw new \Exception('cannot create DNS on OVH : ' . $domainName); |
205 | } |
206 | |
207 | return true; |
208 | } catch (\Exception $e) { |
209 | Log::debug($e->getMessage()); |
210 | |
211 | return false; |
212 | } |
213 | } |
214 | |
215 | protected function getTrackerConfig() |
216 | { |
217 | $request = ClientRequest::createObject($this->serviceTracker, 'config'); |
218 | $response = Client::systemSend('get', $request); |
219 | |
220 | return json_decode($response->body); |
221 | } |
222 | |
223 | protected function copyFilesToTrackers($siteId) |
224 | { |
225 | $files = []; |
226 | |
227 | $config = $this->getTrackerConfig(); |
228 | $fsMg = new FilesystemManager(app()); |
229 | $this->filesManager->from(Storage::disk($this->originFilesLocationDisk)); |
230 | foreach ($config as $trackerConfig) { |
231 | if ($trackerConfig->active && $trackerConfig->ssh && $trackerConfig->ssh->active) { |
232 | $pathToSite = $this->pathTracker . '/' . $this->siteDetail->config->url . '/' . $this->siteDetail->config->urlHash; |
233 | |
234 | $sshConfig = [ |
235 | 'driver' => 'sftp', |
236 | 'host' => $trackerConfig->ip, |
237 | 'port' => $trackerConfig->ssh->port, |
238 | 'username' => $trackerConfig->ssh->user, |
239 | 'password' => $trackerConfig->ssh->password, |
240 | 'root' => $trackerConfig->ssh->root, |
241 | 'timeout' => 30, |
242 | ]; |
243 | $tracker = $fsMg->createSftpDriver($sshConfig); |
244 | |
245 | // Save file to good folder |
246 | $this->filesManager->to($tracker)->put( |
247 | $pathToSite, |
248 | new HttpFile(Storage::disk($this->originFilesLocationDisk)->path($siteId . '/index.html')), |
249 | 'index.html', |
250 | true |
251 | ); |
252 | |
253 | $filesTracker = $this->filesManager->allDestinationFiles($pathToSite); |
254 | if (empty($filesTracker)) { |
255 | Log::debug('No files copies to ' . $tracker->name . ' for id ' . $siteId); |
256 | } else { |
257 | $files = array_merge([], $files, $filesTracker); |
258 | } |
259 | } |
260 | } |
261 | |
262 | return $files; |
263 | } |
264 | } |