MVC - core: add VirtualIPField including unit tests for https://github.com/opnsense/plugins/issues/2091

This commit is contained in:
Ad Schellevis 2020-11-06 14:23:06 +01:00
parent 8282910e5b
commit 668d916834
3 changed files with 252 additions and 0 deletions

View File

@ -0,0 +1,91 @@
<?php
/*
* Copyright (C) 2015-2019 Deciso B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\Base\FieldTypes;
use OPNsense\Core\Config;
/**
* Class VirtualIPField field type to select virtual ip's (such as carp)
* @package OPNsense\Base\FieldTypes
*/
class VirtualIPField extends BaseListField
{
/**
* @var string virtual ip type
*/
private $vipType = "*";
/**
* @var array cached collected certs
*/
private static $internalStaticOptionList = array();
/**
* set virtual ip type (carp, proxyarp, ..)
* @param $value string vip type
*/
public function setType($value)
{
$this->vipType = $value;
}
/**
* generate validation data (list of virtual ips)
*/
protected function actionPostLoadingEvent()
{
if (!isset(self::$internalStaticOptionList[$this->vipType])) {
self::$internalStaticOptionList[$this->vipType] = array();
$configObj = Config::getInstance()->object();
if (!empty($configObj->virtualip) && !empty($configObj->virtualip->vip)) {
$filter_types = explode(',', $this->vipType);
foreach ($configObj->virtualip->vip as $vip) {
if ($this->vipType == '*' || in_array($vip->mode, $filter_types)) {
if (isset($configObj->{$vip->interface}->descr)) {
$intf_name = $configObj->{$vip->interface}->descr;
} else {
$intf_name = $vip->interface;
}
if (!empty($vip->vhid)) {
$caption = sprintf(
gettext("[%s] %s on %s (vhid %s)"), $vip->subnet, $vip->descr, $intf_name, $vip->vhid
);
} else {
$caption = sprintf(gettext("[%s] %s on %s"), $vip->subnet, $vip->descr, $intf_name);
}
self::$internalStaticOptionList[$this->vipType][(string)$vip->subnet] = $caption;
}
}
natcasesort(self::$internalStaticOptionList[$this->vipType]);
}
}
$this->internalOptionList = self::$internalStaticOptionList[$this->vipType];
}
}

View File

@ -0,0 +1,103 @@
<?php
/**
* Copyright (C) 2020 Deciso B.V.
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace tests\OPNsense\Base\FieldTypes;
// @CodingStandardsIgnoreStart
require_once 'Field_Framework_TestCase.php';
// @CodingStandardsIgnoreEnd
use OPNsense\Base\FieldTypes\VirtualIPField;
use Phalcon\DI\FactoryDefault;
use OPNsense\Core\Config;
class VirtualIPFieldTest extends Field_Framework_TestCase
{
/**
* test construct
*/
public function testCanBeCreated()
{
$this->assertInstanceOf('\OPNsense\Base\FieldTypes\VirtualIPField', new VirtualIPField());
// switch config to test set for this type
FactoryDefault::getDefault()->get('config')->globals->config_path = __DIR__ . '/VirtualIPFieldTest/';
Config::getInstance()->forceReload();
}
/**
* @depends testCanBeCreated
*/
public function testCarp()
{
// init field
$field = new VirtualIPField();
$field->setType("carp");
$field->eventPostLoading();
$this->assertContains('10.100.0.10', array_keys($field->getNodeData()));
$this->assertNotContains('172.11.1.0', array_keys($field->getNodeData()));
}
/**
* @depends testCanBeCreated
*/
public function testIPAlias()
{
// init field
$field = new VirtualIPField();
$field->setType("ipalias");
$field->eventPostLoading();
$this->assertContains('172.11.1.0', array_keys($field->getNodeData()));
$this->assertNotContains('10.207.0.1', array_keys($field->getNodeData()));
}
/**
* @depends testCanBeCreated
*/
public function testOther()
{
// init field
$field = new VirtualIPField();
$field->setType("other");
$field->eventPostLoading();
$this->assertNotContains('172.11.1.0', array_keys($field->getNodeData()));
$this->assertContains('10.207.0.1', array_keys($field->getNodeData()));
}
/**
* type is not a container
*/
public function testIsContainer()
{
$field = new VirtualIPField();
$this->assertFalse($field->isContainer());
}
}

View File

@ -0,0 +1,58 @@
<?xml version="1.0"?>
<opnsense>
<interfaces>
<wan>
<if>if001</if>
<descr>WAN</descr>
<enable>1</enable>
<ipaddr>dhcp</ipaddr>
</wan>
<lan>
<if>if002</if>
<descr>LAN</descr>
<enable>1</enable>
</lan>
</interfaces>
<virtualip>
<vip>
<type>network</type>
<subnet_bits>24</subnet_bits>
<mode>ipalias</mode>
<interface>lan</interface>
<descr>test_vip_1</descr>
<subnet>172.11.1.0</subnet>
</vip>
<vip>
<type>network</type>
<subnet_bits>24</subnet_bits>
<mode>other</mode>
<interface>wan</interface>
<descr>test_vip_2</descr>
<subnet>10.207.0.1</subnet>
</vip>
<vip>
<type>single</type>
<subnet_bits>24</subnet_bits>
<mode>carp</mode>
<interface>lan</interface>
<descr>test_vip_3</descr>
<subnet>10.100.0.10</subnet>
<vhid>9</vhid>
<advskew>0</advskew>
<advbase>1</advbase>
<password>opnsense</password>
</vip>
<vip>
<type>single</type>
<subnet_bits>24</subnet_bits>
<mode>carp</mode>
<interface>wan</interface>
<descr>test_vip_4</descr>
<subnet>10.100.0.11</subnet>
<vhid>9</vhid>
<advskew>0</advskew>
<advbase>1</advbase>
<password>opnsense</password>
</vip>
</virtualip>
</opnsense>