Failed Conditions
Pull Request — master (#68)
by Keoghan
06:18 queued 02:53
created

Open::checkItWillResolveProperly()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
dl 0
loc 16
ccs 0
cts 9
cp 0
rs 9.9666
c 1
b 0
f 0
cc 3
nc 5
nop 0
crap 12
1
<?php
2
3
namespace App\Commands\Ngrok;
4
5
use App\Commands\BaseCommand;
6
use App\Models\Site;
7
use App\Porter;
8
use App\Support\Mechanics\Exceptions\UnableToRetrieveIP;
9
use App\Support\Mechanics\Mechanic;
10
11
class Open extends BaseCommand
12
{
13
    /**
14
     * The signature of the command.
15
     *
16
     * @var string
17
     */
18
    protected $signature = 'ngrok {site?} {--region=eu} {--no-inspection}';
19
20
    /**
21
     * The description of the command.
22
     *
23
     * @var string
24
     */
25
    protected $description = 'Open ngrok connection to forward your dev environment to an external url';
26
27
    /**
28
     * Execute the console command.
29
     *
30
     * @return void
31
     */
32
    public function handle(): void
33
    {
34
        $site = Site::resolveFromPathOrCurrentWorkingDirectory($this->argument('site'));
0 ignored issues
show
Bug introduced by
It seems like $this->argument('site') can also be of type array; however, parameter $path of App\Models\Site::resolve...rrentWorkingDirectory() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

34
        $site = Site::resolveFromPathOrCurrentWorkingDirectory(/** @scrutinizer ignore-type */ $this->argument('site'));
Loading history...
35
        $wasSecure = false;
36
37
        if (!$site) {
38
            $this->error('No site at this location, and no site path provided.');
39
40
            return;
41
        }
42
43
        if (!$this->checkItWillResolveProperly()) {
44
            return;
45
        }
46
47
        if ($site->secure) {
48
            $this->info('Removing SSL for site (required for free ngrok version)');
49
            $site->unsecure();
50
            $wasSecure = true;
51
        }
52
53
        app(Porter::class)->stop('ngrok');
54
55
        $tls = ' -bind-tls='.($wasSecure ? 'true' : 'false');
56
        $region = ' -region='.$this->option('region');
57
        $inspect = ' -inspect='.($this->option('no-inspection') ? 'false' : 'true');
58
59
        $this->dockerCompose
60
            ->runContainer('ngrok')
61
            ->append("ngrok http -host-header=rewrite{$region}{$tls}{$inspect} {$site->url}:80")
62
            ->interactive()
63
            ->perform();
64
65
        if ($wasSecure) {
66
            $this->info('Restoring SSL for site');
67
            $site->secure();
68
        }
69
70
        app(Porter::class)->stop('ngrok');
71
    }
72
73
    /**
74
     * Checking that Porter is using the dns:set-host IP. If we don't ngrok
75
     * requests will only resolve to 127.0.0.1 which is internal to the
76
     * ngrok container, and results in a useless 502 error.
77
     *
78
     * @return bool
79
     */
80
    public function checkItWillResolveProperly()
81
    {
82
        try {
83
            if (app(Mechanic::class)->isUsingDefaultHostAddress()) {
84
                $this->info('You need to use an alternative loopback address.');
85
                $this->info('Please run porter dns:set-host and review the documentation here: https://github.com/konsulting/porter#dns');
86
87
                return false;
88
            }
89
        } catch (UnableToRetrieveIP $e) {
90
            $this->info('Please run porter dns:flush and try again. You may need to give it a little while.');
91
92
            return false;
93
        }
94
95
        return true;
96
    }
97
}
98