NatCreateCommand::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Devgiants\Command;
4
5
use Buzz\Message\Request;
6
use Devgiants\Model\ApplicationCommand;
7
use Devgiants\Model\NatRule;
8
use Devgiants\Configuration\ConfigurationManager;
9
use Devgiants\Configuration\ApplicationConfiguration as AppConf;
10
use Pimple\Container;
11
use Symfony\Component\Console\Exception\InvalidOptionException;
12
use Symfony\Component\Console\Input\InputArgument;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Input\InputOption;
15
use Symfony\Component\Console\Output\OutputInterface;
16
17
class NatCreateCommand extends ApplicationCommand
18
{
19
20
    const OPTION_ID = 'id';
21
    const OPTION_PORT_INTERNAL = 'internal';
22
    const OPTION_PORT_EXTERNAL = 'external';
23
    const OPTION_IP = 'ip';
24
    const OPTION_PROTOCOL = 'protocol';
25
    const OPTION_WHITELIST = 'whitelist';
26
27
    /**
28
     * Wan command constructor.
29
     *
30
     * @param null|string $name
31
     * @param Container $container
32
     */
33
    public function __construct($name, Container $container)
34
    {
35
        parent::__construct($name, $container);
36
    }
37
38
    /**
39
     * @inheritdoc
40
     */
41
    protected function configure()
42
    {
43
        $this
44
            ->setName('nat:create')
45
            ->setDescription('Create NAT entry')
46
            ->addOption(static::OPTION_ID, static::OPTION_ID, InputOption::VALUE_REQUIRED, 'Id/Name of the NAT rule')
47
            ->addOption(static::OPTION_IP, static::OPTION_IP, InputOption::VALUE_REQUIRED, 'IP of the NAT rule')
48
            ->addOption(static::OPTION_PORT_EXTERNAL, static::OPTION_PORT_EXTERNAL, InputOption::VALUE_REQUIRED, 'External port of the NAT rule')
49
            ->addOption(static::OPTION_PORT_INTERNAL, static::OPTION_PORT_INTERNAL, InputOption::VALUE_REQUIRED, 'Internal port of the NAT rule')
50
            ->addOption(static::OPTION_PROTOCOL, static::OPTION_PROTOCOL, InputOption::VALUE_OPTIONAL, 'Protocol of the NAT rule: tcp, udp, both', 'tcp')
51
            ->addOption(static::OPTION_WHITELIST, static::OPTION_WHITELIST, InputOption::VALUE_OPTIONAL, 'IP authorized for access')
52
            ->setHelp("This command allows you to add livebox NAT entry to open port");
53
54
        parent::configure();
55
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60
    protected function execute(InputInterface $input, OutputInterface $output)
61
    {
62
63
        $ymlFile = $this->getConfigurationFile($input);
64
65
        if ($ymlFile !== NULL && is_file($ymlFile)) {
66
67
            // Structures check and configuration loading
68
            $configurationManager = new ConfigurationManager($ymlFile);
69
            $configuration = $configurationManager->load();
70
71
            // Authentication
72
            $this->tools->authenticate(
73
                $configuration[AppConf::HOST[AppConf::NODE_NAME]],
74
                $configuration[AppConf::USER[AppConf::NODE_NAME]],
75
                $configuration[AppConf::PASSWORD]
76
            );
77
78
            $ruleId = $input->getOption(static::OPTION_ID);
79
            $natRule = new NatRule();
80
            $natRule->setId($ruleId);
81
            $natRule->setDescription($ruleId);
82
            $natRule->setDestinationIPAddress($input->getOption(static::OPTION_IP));
83
            $natRule->setExternalPort($input->getOption(static::OPTION_PORT_EXTERNAL));
84
            $natRule->setInternalPort($input->getOption(static::OPTION_PORT_INTERNAL));
85
86
            $protocolMapping = [
87
                'tcp' => NatRule::PROTOCOL_TCP,
88
                'udp' => NatRule::PROTOCOL_UDP,
89
                'both' => NatRule::PROTOCOL_BOTH_INTERNAL
90
            ];
91
92
            if ($input->hasOption(static::OPTION_PROTOCOL)) {
93
                $protocol = $input->getOption(static::OPTION_PROTOCOL);
94
                if (!in_array($protocol, array_keys($protocolMapping))) {
95
                    $stringProtocol = implode(' or ', array_map(function ($protocol) {
96
                        return '"' . $protocol . '"';
97
                    }, $protocolMapping));
98
                    throw new InvalidOptionException("Protocol argument get only " . $stringProtocol . " value.");
99
                }
100
                $natRule->setProtocol($protocolMapping[$protocol]);
101
            }
102
103
            if ($input->hasOption(static::OPTION_WHITELIST)) {
104
                $natRule->setSourcePrefix($input->getOption(static::OPTION_WHITELIST));
105
            }
106
107
            // Execute request
108
            $response = $this->tools->createRequest(
109
                Request::METHOD_POST,
110
                "{$configuration[ AppConf::HOST[ AppConf::NODE_NAME ] ]}/ws",
111
                [
112
                    "service" => "Firewall",
113
                    "method" => "setPortForwarding",
114
                    "parameters" => $natRule->getOutput()
115
                ]
116
            );
117
            $output->write($response->getContent());
118
119
            // Handle post command stuff
120
            parent::execute($input, $output);
121
        }
122
    }
123
}