mvc: add a mutable service controller for easy reuse

This commit is contained in:
Franco Fichtner 2017-12-24 15:56:49 +01:00
parent a46afb51a0
commit b83282f267
3 changed files with 208 additions and 0 deletions

View File

@ -34,6 +34,7 @@ Copyright (c) 2015 Manuel Faux <mfaux@conf.at>
Copyright (c) 2003-2007 Manuel Kasper <mk@neon1.net>
Copyright (c) 2012 Marcello Coutinho
Copyright (c) 2010-2015 Michael Bostock
Copyright (c) 2017 Michael Muenz
Copyright (c) 2005-2006 Paul Taylor <paultaylor@winn-dixie.com>
Copyright (c) 2005-2006 Peter Allgeyer <allgeyer@web.de>
Copyright (c) 2004 Peter Curran <peter@closeconsultants.com>

1
plist
View File

@ -329,6 +329,7 @@
/usr/local/opnsense/mvc/app/config/services_api.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/Base/ApiControllerBase.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/Base/ApiMutableModelControllerBase.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/Base/ApiMutableServiceControllerBase.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/Base/ControllerBase.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/Base/ControllerRoot.php
/usr/local/opnsense/mvc/app/controllers/OPNsense/Base/IndexController.php

View File

@ -0,0 +1,206 @@
<?php
/*
* Copyright (C) 2017 Franco Fichtner <franco@opnsense.org>
* Copyright (C) 2017 Michael Muenz
* Copyright (C) 2016 IT-assistans Sverige AB
* Copyright (C) 2016 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;
/**
* Class ApiMutableServiceControllerBase, inherit this class to implement
* an API that exposes a service controller with start, stop, restart,
* reconfigure and status actions.
* @package OPNsense\Base
*/
abstract class ApiMutableServiceControllerBase extends ApiControllerBase
{
/**
* @var string this implementations internal model name to use
*/
static protected $internalModelName = null;
/**
* @var string model class name to use
*/
static protected $internalModelClass = null;
/**
* @var string model template name to use
*/
static protected $internalModelTemplate = null;
/**
* @var string model enabled xpath to use
*/
static protected $internalModelEnabled = null;
/**
* @var null|BaseModel model object to work on
*/
private $modelHandle = null;
/**
* validate on initialization
* @throws Exception
*/
public function initialize()
{
parent::initialize();
if (empty(static::$internalModelClass)) {
throw new \Exception('cannot instantiate without internalModelClass defined.');
}
if (empty(static::$internalModelName)) {
throw new \Exception('cannot instantiate without internalModelName defined.');
}
if (empty(static::$internalModelTemplate)) {
throw new \Exception('cannot instantiate without internalModelTemplate defined.');
}
if (empty(static::$internalModelEnabled)) {
throw new \Exception('cannot instantiate without internalModelEnabled defined.');
}
}
/**
* @return null|BaseModel
*/
protected function getModel()
{
if ($this->modelHandle == null) {
$this->modelHandle = (new \ReflectionClass(static::$internalModelClass))->newInstance();
}
return $this->modelHandle;
}
/**
* start service
* @return array
*/
public function startAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$backend = new Backend();
$response = $backend->configdRun(escapeshellarg($internalModelName) . ' start');
return array('response' => $response);
} else {
return array('response' => array());
}
}
/**
* stop service
* @return array
*/
public function stopAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$backend = new Backend();
$response = $backend->configdRun(escapeshellarg($internalModelName) . ' stop');
return array('response' => $response);
} else {
return array('response' => array());
}
}
/**
* restart service
* @return array
*/
public function restartAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$backend = new Backend();
$response = $backend->configdRun(escapeshellarg($internalModelName) . ' restart');
return array('response' => $response);
} else {
return array('response' => array());
}
}
/**
* reconfigure, generate config and reload
*/
public function reconfigureAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$model = $this->getModel();
$backend = new Backend();
$this->stopAction();
// generate template
$backend->configdRun('template reload ' . escapeshellarg($internalModelTemplate));
// (re)start daemon
if ((string)$model->xpath($internalModelEnabled) == '1') {
$this->startAction();
}
return array('status' => 'ok');
} else {
return array('status' => 'failed');
}
}
/**
* retrieve status of service
* @return array
* @throws \Exception
*/
public function statusAction()
{
$backend = new Backend();
$model = $this->getModel();
$response = $backend->configdRun(escapeshellarg($internalModelName) . ' status');
if (strpos($response, 'not running') > 0) {
if ((string)$model->xpath($internalModelEnabled) == 1) {
$status = 'stopped';
} else {
$status = 'disabled';
}
} elseif (strpos($response, 'is running') > 0) {
$status = 'running';
} elseif ((string)$model->xpath($internalModelEnabled) == 0) {
$status = 'disabled';
} else {
$status = 'unknown';
}
return array('status' => $status);
}
}