GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( 0e985d...08b4ed )
by Stuart
05:49
created

FromHost::getStorySetting()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 28
rs 8.8571
cc 3
eloc 13
nc 3
nop 1
1
<?php
2
3
/**
4
 * Copyright (c) 2011-present Mediasift Ltd
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 *   * Redistributions of source code must retain the above copyright
12
 *     notice, this list of conditions and the following disclaimer.
13
 *
14
 *   * Redistributions in binary form must reproduce the above copyright
15
 *     notice, this list of conditions and the following disclaimer in
16
 *     the documentation and/or other materials provided with the
17
 *     distribution.
18
 *
19
 *   * Neither the names of the copyright holders nor the names of his
20
 *     contributors may be used to endorse or promote products derived
21
 *     from this software without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 *
36
 * @category  Libraries
37
 * @package   Storyplayer/Modules/Host
38
 * @author    Stuart Herbert <[email protected]>
39
 * @copyright 2011-present Mediasift Ltd www.datasift.com
40
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
41
 * @link      http://datasift.github.io/storyplayer
42
 */
43
44
namespace Storyplayer\SPv2\Modules\Host;
45
46
use DataSift\Storyplayer\HostLib;
47
use DataSift\Storyplayer\OsLib;
48
49
use DataSift\Stone\DataLib\DataPrinter;
50
use DataSift\Stone\ObjectLib\BaseObject;
51
52
use GanbaroDigital\TextTools\Filters\FilterColumns;
53
use GanbaroDigital\TextTools\Filters\FilterForMatchingRegex;
54
use GanbaroDigital\TextTools\Filters\FilterForMatchingString;
55
56
use Storyplayer\SPv2\Modules\Exceptions;
57
58
/**
59
 * get information about a given host
60
 *
61
 * @category  Libraries
62
 * @package   Storyplayer/Modules/Host
63
 * @author    Stuart Herbert <[email protected]>
64
 * @copyright 2011-present Mediasift Ltd www.datasift.com
65
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
66
 * @link      http://datasift.github.io/storyplayer
67
 */
68
class FromHost extends HostBase
69
{
70
    /**
71
     * @return object
72
     */
73 View Code Duplication
    public function getDetails()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
74
    {
75
        // what are we doing?
76
        $log = usingLog()->startAction("retrieve details for host '{$this->args[0]}'");
77
78
        // get the host details
79
        $hostDetails = $this->getHostDetails();
80
81
        // we already have details - are they valid?
82
        if (isset($hostDetails->invalidHost) && $hostDetails->invalidHost) {
83
            $msg = "there are no details about host '{$hostDetails->hostId}'";
84
            $log->endAction($msg);
85
            throw Exceptions::newActionFailedException(__METHOD__, $msg);
86
        }
87
88
        // return the details
89
        $log->endAction();
90
        return $hostDetails;
91
    }
92
93
    /**
94
     * is a host up and running?
95
     *
96
     * @return boolean
97
     */
98
    public function getHostIsRunning()
99
    {
100
        // what are we doing?
101
        $log = usingLog()->startAction("is host '{$this->args[0]}' running?");
102
103
        // make sure we have valid host details
104
        $hostDetails = $this->getHostDetails();
105
106
        // get an object to talk to this host
107
        $host = HostLib::getHostAdapter($this->st, $hostDetails->type);
108
109
        // if the box is running, it should have a status of 'running'
110
        $result = $host->isRunning($hostDetails);
111
112
        if (!$result) {
113
            $log->endAction("host is not running");
114
            return false;
115
        }
116
117
        // all done
118
        $log->endAction("host is running");
119
        return true;
120
    }
121
122
    /**
123
     * get the hostname for a host
124
     *
125
     * the returned hostname is suitable for use in HTTP/HTTPS URLs
126
     *
127
     * if we have been unable to determine the hostname for the host,
128
     * this will return the host's IP address instead
129
     *
130
     * @return string
131
     */
132
    public function getHostname()
133
    {
134
        // what are we doing?
135
        $log = usingLog()->startAction("get the hostname of host ID '{$this->args[0]}'");
136
137
        // make sure we have valid host details
138
        $hostDetails = $this->getHostDetails();
139
140
        // do we have a hostname?
141
        if (!isset($hostDetails->hostname)) {
142
            throw Exceptions::newActionFailedException(__METHOD__, "no hostname found for host ID '{$this->args[0]}'");
143
        }
144
145
        // all done
146
        $log->endAction("hostname is '{$hostDetails->hostname}'");
147
        return $hostDetails->hostname;
148
    }
149
150
    /**
151
     * get the IP address for a host
152
     *
153
     * @return string
154
     */
155 View Code Duplication
    public function getIpAddress()
156
    {
157
        // what are we doing?
158
        $log = usingLog()->startAction("get IP address of host '{$this->args[0]}'");
159
160
        // make sure we have valid host details
161
        $hostDetails = $this->getHostDetails();
162
163
        // all done
164
        $log->endAction("IP address is '{$hostDetails->ipAddress}'");
165
        return $hostDetails->ipAddress;
166
    }
167
168
    /**
169
     * @param  string $packageName
170
     * @return object
171
     */
172 View Code Duplication
    public function getInstalledPackageDetails($packageName)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
173
    {
174
        // what are we doing?
175
        $log = usingLog()->startAction("get details for package '{$packageName}' installed on host '{$this->args[0]}'");
176
177
        // make sure we have valid host details
178
        $hostDetails = $this->getHostDetails();
179
180
        // get an object to talk to this host
181
        $host = OsLib::getHostAdapter($this->st, $hostDetails->osName);
182
183
        // get the information
184
        $return = $host->getInstalledPackageDetails($hostDetails, $packageName);
185
186
        // all done
187
        $log->endAction();
188
        return $return;
189
    }
190
191
    /**
192
     * @param  int $pid
193
     * @return bool
194
     */
195 View Code Duplication
    public function getPidIsRunning($pid)
196
    {
197
        // what are we doing?
198
        $log = usingLog()->startAction("is process PID '{$pid}' running on host '{$this->args[0]}'?");
199
200
        // make sure we have valid host details
201
        $hostDetails = $this->getHostDetails();
202
203
        // get an object to talk to this host
204
        $host = OsLib::getHostAdapter($this->st, $hostDetails->osName);
205
206
        // get the information
207
        $return = $host->getPidIsRunning($hostDetails, $pid);
208
209
        // did it work?
210
        if ($return) {
211
            $log->endAction("'{$pid}' is running");
212
            return true;
213
        }
214
215
        $log->endAction("'{$pid}' is not running");
216
        return false;
217
    }
218
219
    /**
220
     * @param  string $processName
221
     * @return bool
222
     */
223 View Code Duplication
    public function getProcessIsRunning($processName)
224
    {
225
        // what are we doing?
226
        $log = usingLog()->startAction("is process '{$processName}' running on host '{$this->args[0]}'?");
227
228
        // make sure we have valid host details
229
        $hostDetails = $this->getHostDetails();
230
231
        // get an object to talk to this host
232
        $host = OsLib::getHostAdapter($this->st, $hostDetails->osName);
233
234
        // get the information
235
        $return = $host->getProcessIsRunning($hostDetails, $processName);
236
237
        // did it work?
238
        if ($return) {
239
            $log->endAction("'{$processName}' is running");
240
            return true;
241
        }
242
243
        $log->endAction("'{$processName}' is not running");
244
        return false;
245
    }
246
247
    /**
248
     * @param  string $processName
249
     * @return int
250
     */
251 View Code Duplication
    public function getPid($processName)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
252
    {
253
        // log some info to the user
254
        $log = usingLog()->startAction("get id of process '{$processName}' running on VM '{$this->args[0]}'");
255
256
        // make sure we have valid host details
257
        $hostDetails = $this->getHostDetails();
258
259
        // get an object to talk to this host
260
        $host = OsLib::getHostAdapter($this->st, $hostDetails->osName);
261
262
        // get the information
263
        $return = $host->getPid($hostDetails, $processName);
264
265
        // success
266
        $log->endAction("pid is '{$return}'");
267
        return $return;
268
    }
269
270
    /**
271
     * @return string
272
     */
273 View Code Duplication
    public function getSshUsername()
274
    {
275
        // what are we doing?
276
        $log = usingLog()->startAction("get username to use with SSH to host '{$this->args[0]}'");
277
278
        // make sure we have valid host details
279
        $hostDetails = $this->getHostDetails();
280
281
        // get the information
282
        $return = $hostDetails->sshUsername;
283
284
        // all done
285
        $log->endAction("username is '{$return}'");
286
        return $return;
287
    }
288
289
    /**
290
     * @return string
291
     */
292 View Code Duplication
    public function getSshKeyFile()
293
    {
294
        // what are we doing?
295
        $log = usingLog()->startAction("get key file to use with SSH to host '{$this->args[0]}'");
296
297
        // make sure we have valid host details
298
        $hostDetails = $this->getHostDetails();
299
300
        // get the information
301
        $return = $hostDetails->sshKeyFile;
302
303
        // all done
304
        $log->endAction("key file is '{$return}'");
305
        return $return;
306
    }
307
308
    /**
309
     * @param  string $sessionName
310
     * @return bool
311
     */
312
    public function getIsScreenRunning($sessionName)
313
    {
314
        return $this->getScreenIsRunning($sessionName);
315
    }
316
317
    /**
318
     * @param  string $sessionName
319
     * @return bool
320
     */
321
    public function getScreenIsRunning($sessionName)
322
    {
323
        // what are we doing?
324
        $log = usingLog()->startAction("check if screen session '{$sessionName}' is still running");
325
326
        // get the details
327
        $sessionData = fromHost($this->args[0])->getScreenSessionDetails($sessionName);
328
329
        // all done
330
        if ($sessionData) {
331
            $log->endAction("still running");
332
            return true;
333
        }
334
        else {
335
            $log->endAction("not running");
336
            return false;
337
        }
338
    }
339
340
    /**
341
     * @param  string $sessionName
342
     * @return BaseObject|null
343
     */
344
    public function getScreenSessionDetails($sessionName)
345
    {
346
        // what are we doing?
347
        $log = usingLog()->startAction("get details about screen session '{$sessionName}' on host '{$this->args[0]}' from Storyplayer");
348
349
        // are there any details?
350
        $cmd = "screen -ls";
351
        $result = usingHost($this->args[0])->runCommandAndIgnoreErrors($cmd);
352
353
        // NOTE:
354
        //
355
        // screen is not a well-behaved UNIX program, and its exit code
356
        // can be non-zero when everything is good
357
        if (empty($result->output)) {
358
            $msg = "unable to get list of screen sessions";
0 ignored issues
show
Unused Code introduced by
$msg is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
359
            return null;
360
        }
361
362
        // do we have the session we are looking for?
363
        $lines = explode("\n", $result->output);
364
        $lines = FilterForMatchingRegex::against($lines, "/[0-9]+\\.{$sessionName}\t/");
365
        $lines = FilterColumns::from($lines, "0", '.');
366
367
        if (empty($lines)) {
368
            $msg = "screen session '{$sessionName}' is not running";
369
            $log->endAction($msg);
370
            return null;
371
        }
372
373
        // there might be
374
        $processDetails = new BaseObject;
375
        $processDetails->hostId = $this->args[0];
376
        $processDetails->name = $sessionName;
377
        $processDetails->type = 'screen';
378
        $processDetails->pid = trim(rtrim($lines[0]));
379
380
        // all done
381
        $log->endAction("session is running as PID '{$processDetails->pid}'");
382
        return $processDetails;
383
    }
384
385
    /**
386
     * @return array<object>
387
     */
388
    public function getAllScreenSessions()
389
    {
390
        // what are we doing?
391
        $log = usingLog()->startAction("get details about all screen sessions on host '{$this->args[0]}'");
392
393
        // are there any details?
394
        $cmd = "screen -ls";
395
        $result = usingHost($this->args[0])->runCommandAndIgnoreErrors($cmd);
396
397
        // NOTE:
398
        //
399
        // screen is not a well-behaved UNIX program, and its exit code
400
        // can be non-zero when everything is good
401
        if (empty($result->output)) {
402
            $msg = "unable to get list of screen sessions";
403
            $log->endAction($msg);
404
            return [];
405
        }
406
407
        // reduce the output down to a list of sessions
408
        $lines = explode("\n", $result->output);
409
        $lines = FilterForMatchingRegex::against($lines, "/[0-9]+.+\t/");
410
411
        if (empty($lines)) {
412
            $msg = "no screen processes running";
413
            $log->endAction($msg);
414
            return [];
415
        }
416
417
        $retval = [];
418
        foreach ($lines as $line) {
419
            $parts = explode('.', $line);
420
421
            $processDetails = new BaseObject;
422
            $processDetails->hostId = $this->args[0];
423
            $processDetails->type = 'screen';
424
            $processDetails->pid  = trim($parts[0]);
425
            $processDetails->name = rtrim($parts[1]);
426
427
            $retval[] = $processDetails;
428
        }
429
430
        // all done
431
        $log->endAction("found " . count($retval) . " screen process(es)");
432
433
        // all done
434
        return $retval;
435
    }
436
437
    /**
438
     * @param  string $appName
439
     * @return mixed
440
     */
441
    public function getAppSettings($appName)
442
    {
443
        // what are we doing?
444
        $log = usingLog()->startAction("get settings for '{$appName}' from host '{$this->args[0]}'");
445
446
        // make sure we have valid host details
447
        $hostDetails = $this->getHostDetails();
448
449
        // do we have any app settings?
450
        if (!isset($hostDetails->appSettings, $hostDetails->appSettings->$appName)) {
451
            $log->endAction("setting does not exist :(");
452
            throw Exceptions::newActionFailedException(__METHOD__);
453
        }
454
455
        // yes we do
456
        $value = $hostDetails->appSettings->$appName;
457
458
        // log the settings
459
        $printer  = new DataPrinter();
460
        $logValue = $printer->convertToString($value);
461
        $log->endAction("settings for '{$appName}' are '{$logValue}'");
462
463
        // all done
464
        return $value;
465
    }
466
467
    /**
468
     * @param  string $path
469
     * @param  string|null $settingName
470
     * @return mixed
471
     */
472
    public function getAppSetting($path, $settingName = null)
473
    {
474
        // are we operating in legacy mode (for DataSift), or are we using
475
        // the new dot.notation.support that we want everywhere in v2?
476
        $parts = explode(".", $path);
477
        if (count($parts) === 1 && $settingName !== null) {
478
            return $this->getLegacyAppSetting($path, $settingName);
479
        }
480
481
        // if we get here, then we are using the new dot.notation.support
482
483
        // what are we doing?
484
        $log = usingLog()->startAction("get appSetting '{$path}' from host '{$this->args[0]}'");
485
486
        // make sure we have valid host details
487
        $hostDetails = $this->getHostDetails();
488
489
        // do we have any app settings?
490
        if (!isset($hostDetails->appSettings)) {
491
            $msg = "host has no appSettings at all";
492
            $log->endAction($msg);
493
            throw Exceptions::newActionFailedException(__METHOD__, $msg);
494
        }
495
496
        // do we have the setting that we want?
497
        if (!$hostDetails->appSettings->hasData($path)) {
498
            $msg = "host does not have appSetting '{$path}'";
499
            throw Exceptions::newActionFailedException(__METHOD__, $msg);
500
        }
501
502
        // success
503
        $data = $hostDetails->appSettings->getData($path);
504
505
        // all done
506
        $log->endAction([ "setting is", $data ]);
507
        return $data;
508
    }
509
510
    /**
511
     * @param  string $appName
512
     * @param  string $settingName
513
     * @return mixed
514
     */
515
    protected function getLegacyAppSetting($appName, $settingName)
516
    {
517
        // what are we doing?
518
        $log = usingLog()->startAction("get $settingName for '{$appName}' from host '{$this->args[0]}'");
519
520
        // make sure we have valid host details
521
        $hostDetails = $this->getHostDetails();
522
523
        // do we have any app settings?
524
        if (!isset($hostDetails->appSettings)) {
525
            $log->endAction("host has no appSettings at all");
526
            throw Exceptions::newActionFailedException(__METHOD__);
527
        }
528
        if (!isset($hostDetails->appSettings->$appName)) {
529
            $log->endAction("host has no appSettings for {$appName}");
530
            throw Exceptions::newActionFailedException(__METHOD__);
531
        }
532
        if (!isset($hostDetails->appSettings->$appName->$settingName)) {
533
            $log->endAction("host has no appSetting '{$settingName}' for {$appName}");
534
            throw Exceptions::newActionFailedException(__METHOD__);
535
        }
536
537
        // yes we do
538
        $value = $hostDetails->appSettings->$appName->$settingName;
539
540
        // log the settings
541
        $printer  = new DataPrinter();
542
        $logValue = $printer->convertToString($value);
543
        $log->endAction("setting for '{$appName}' is '{$logValue}'");
544
545
        // all done
546
        return $value;
547
    }
548
549
    /**
550
     * @param  string $path
551
     * @return mixed
552
     */
553
    public function getStorySetting($path)
554
    {
555
        // what are we doing?
556
        $log = usingLog()->startAction("get storySetting '{$path}' from host '{$this->args[0]}'");
557
558
        // make sure we have valid host details
559
        $hostDetails = $this->getHostDetails();
560
561
        // do we have any app settings?
562
        if (!isset($hostDetails->storySettings)) {
563
            $msg = "host has no storySettings at all";
564
            $log->endAction($msg);
565
            throw Exceptions::newActionFailedException(__METHOD__, $msg);
566
        }
567
568
        // do we have the setting that we want?
569
        if (!$hostDetails->storySettings->hasData($path)) {
570
            $msg = "host does not have storySetting '{$path}'";
571
            throw Exceptions::newActionFailedException(__METHOD__, $msg);
572
        }
573
574
        // success
575
        $data = $hostDetails->storySettings->getData($path);
576
577
        // all done
578
        $log->endAction([ "setting is", $data ]);
579
        return $data;
580
    }
581
582
    /**
583
     * @param  string $sourceFilename
584
     * @param  string $destFilename
585
     * @return \DataSift\Storyplayer\CommandLib\CommandResult
586
     */
587 View Code Duplication
    public function downloadFile($sourceFilename, $destFilename)
588
    {
589
        // what are we doing?
590
        $log = usingLog()->startAction("download file '{$this->args[0]}':'{$sourceFilename}' to '{$destFilename}'");
591
592
        // make sure we have valid host details
593
        $hostDetails = $this->getHostDetails();
594
595
        // get an object to talk to this host
596
        $host = OsLib::getHostAdapter($this->st, $hostDetails->osName);
597
598
        // upload the file
599
        $result = $host->downloadFile($hostDetails, $sourceFilename, $destFilename);
600
601
        // did the command used to upload succeed?
602
        if ($result->didCommandFail()) {
603
            $msg = "download failed with return code '{$result->returnCode}' and output '{$result->output}'";
604
            $log->endAction($msg);
605
            throw Exceptions::newActionFailedException(__METHOD__, $msg);
606
        }
607
608
        // all done
609
        $log->endAction();
610
        return $result;
611
    }
612
613
    /**
614
     * @param  string $filename
615
     * @return object
616
     */
617 View Code Duplication
    public function getFileDetails($filename)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
618
    {
619
        // what are we doing?
620
        $log = usingLog()->startAction("get details for '{$filename}' on host '{$this->args[0]}'");
621
622
        // make sure we have valid host details
623
        $hostDetails = $this->getHostDetails();
624
625
        // get an object to talk to this host
626
        $host = OsLib::getHostAdapter($this->st, $hostDetails->osName);
627
628
        // get the details
629
        $details = $host->getFileDetails($hostDetails, $filename);
630
631
        // all done
632
        $log->endAction();
633
        return $details;
634
    }
635
636
    /**
637
     * which local folder do we need to be in when working with this host?
638
     *
639
     * @return string
640
     */
641 View Code Duplication
    public function getLocalFolder()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
642
    {
643
        // what are we doing?
644
        $log = usingLog()->startAction("get local folder for host '{$this->args[0]}'");
645
646
        // make sure we have valid host details
647
        $hostDetails = $this->getHostDetails();
648
649
        // does it have a folder defined?
650
        if (isset($hostDetails->dir)) {
651
            $retval = $hostDetails->dir;
652
        }
653
        else {
654
            $retval = getcwd();
655
        }
656
657
        // all done
658
        $log->endAction($retval);
659
        return $retval;
660
    }
661
}
662