Do some work on form processing, and add a form for creating a new VPS

feature/node-rewrite
Sven Slootweg 12 years ago
parent b3b99f494a
commit abf4c53701

@ -580,7 +580,7 @@ form.dark label, form .filler
width: 45.8%; width: 45.8%;
} }
form.dark input form.dark input, form.dark select
{ {
display: block; display: block;
float: left; float: left;
@ -588,6 +588,7 @@ form.dark input
border: 0px; border: 0px;
margin: 3px 0.4%; margin: 3px 0.4%;
padding: 4px 2%; padding: 4px 2%;
box-sizing: content-box;
} }
form.dark input[type="checkbox"] form.dark input[type="checkbox"]

@ -20,6 +20,7 @@ require("include.config.php");
require("include.exceptions.php"); require("include.exceptions.php");
require("include.constants.php"); require("include.constants.php");
require("include.parsing.php"); require("include.parsing.php");
require("include.misc.php");
require("classes/class.user.php"); require("classes/class.user.php");
require("classes/class.controller.php"); require("classes/class.controller.php");
require("classes/class.container.php"); require("classes/class.container.php");

@ -0,0 +1,98 @@
<?php
/*
* CVM is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_CVM)) { die("Unauthorized."); }
function check_fields($source, $fields, &$errors)
{
/* This function runs through a GET/POST value array, checks if all values are filled in,
* and adds error messages to the specified array if this is not the case. */
foreach($fields as $field_name => $field_error)
{
if(empty($source[$field_name]))
{
$errors[] = $field_error;
}
}
return $errors;
}
function array_add(&$array, $value)
{
/* Why use a separate function to add an item to an array if the $name[] construct exists?
* We only want to add an element to an array if the element isn't in the array yet, hence
* the need for a custom function.
* NOTE: This function works in-place. */
if(in_array($value, $array) === false)
{
$array[] = $value;
}
}
function validate_hostname($hostname)
{
if(preg_match("/^[a-z\d](-*[a-z\d])*(\.[a-z\d](-*[a-z\d])*)*$/", $hostname))
{
return true;
}
else
{
return false;
}
}
function first_unused_ctid()
{
/* [OpenVZ only] This function finds the first valid unused CTID and returns it. */
global $database;
$id_list = array();
$highest = 101;
/* Collect all known CTIDs and keep track of the highest CTID. */
$result = $database->CachedQuery("SELECT `InternalId` FROM containers WHERE `VirtualizationType` = 1", array(), 0);
foreach($result->data as $row)
{
$id = filter_var($row['InternalId'] ,FILTER_VALIDATE_INT);
if($id !== false)
{
$id_list[] = $id;
if($id > $highest)
{
$highest = $id;
}
}
}
/* Generate a list of all possible CTIDs between 101 and the highest CTID, and find
* all possible CTIDs that do not exist in the known CTID list. We use array_merge
* because otherwise the array indexes may not start from 0. */
$all_ids = range(101, $highest, 1);
$missing = array_merge(array_diff($all_ids, $id_list));
if(count($missing) > 0)
{
/* Return the first unused CTID. */
return $missing[0];
}
else
{
/* All CTIDs up to the highest CTID have been used. We'll just return the CTID
* that is one above the highest known CTID. */
return $highest + 1;
}
}

@ -32,6 +32,7 @@ title-admin-userlist; User overview
title-admin-containerlist; VPS overview title-admin-containerlist; VPS overview
title-admin-nodelist; Node overview title-admin-nodelist; Node overview
title-admin-addnode; Add node title-admin-addnode; Add node
title-admin-addcontainer; Create VPS
title-admin-userinfo; User lookup title-admin-userinfo; User lookup
title-admin-nodeinfo; Node lookup title-admin-nodeinfo; Node lookup
title-admin-overview; Administrative overview title-admin-overview; Administrative overview
@ -244,9 +245,29 @@ error-admin-nodes-add-publickey; You did not upload a valid public key.
error-admin-nodes-add-privatekey; You did not upload a valid private key. error-admin-nodes-add-privatekey; You did not upload a valid private key.
error-admin-nodes-add-upload; Something went wrong while processing the uploaded keys. Ensure that the keys directory is writable. error-admin-nodes-add-upload; Something went wrong while processing the uploaded keys. Ensure that the keys directory is writable.
error-form; One or more problems occurred. error-form; One or more problems occurred.
error-admin-vpses-add-node; You did not select a valid node.
error-admin-vpses-add-user; You did not select a valid user.
error-admin-vpses-add-template; You did not select a valid template.
error-admin-vpses-add-disk; You did not enter a valid disk space specification.
error-admin-vpses-add-guaranteed; You did not enter a valid guaranteed RAM specification.
error-admin-vpses-add-burstable; You did not enter a valid burstable RAM specification.
error-admin-vpses-add-cpucount; You did not enter a valid amount of CPUs.
error-admin-vpses-add-traffic; You did not enter a valid traffic allocation specification.
error-admin-vpses-add-hostname; You entered an invalid hostname.
toolbar-addnode; Add node toolbar-addnode; Add node
toolbar-createvps; Create VPS toolbar-createvps; Create VPS
toolbar-editnode; Edit node details toolbar-editnode; Edit node details
toolbar-createuser; Create user toolbar-createuser; Create user
toolbar-edituser; Edit user details toolbar-edituser; Edit user details
addcontainer-node; Node
addcontainer-user; User
addcontainer-diskspace; Disk space
addcontainer-guaranteed; Guaranteed RAM
addcontainer-burstable; Burstable RAM
addcontainer-cpucount; CPUs
addcontainer-traffic; Traffic allocation
addcontainer-hostname; Hostname (optional)
addcontainer-template; Template
button-admin-addcontainer; Create VPS

@ -0,0 +1,197 @@
<?php
/*
* CVM is more free software. It is licensed under the WTFPL, which
* allows you to do pretty much anything with it, without having to
* ask permission. Commercial use is allowed, and no attribution is
* required. We do politely request that you share your modifications
* to benefit other developers, but you are under no enforced
* obligation to do so :)
*
* Please read the accompanying LICENSE document for the full WTFPL
* licensing text.
*/
if(!isset($_CVM)) { die("Unauthorized."); }
$sErrors = array();
if(isset($_POST['submit']))
{
check_fields($_POST, array(
'node' => $locale->strings['error-admin-vpses-add-node'],
'user' => $locale->strings['error-admin-vpses-add-user'],
'diskspace' => $locale->strings['error-admin-vpses-add-disk'],
'guaranteed' => $locale->strings['error-admin-vpses-add-guaranteed'],
'burstable' => $locale->strings['error-admin-vpses-add-burstable'],
'cpucount' => $locale->strings['error-admin-vpses-add-cpucount'],
'traffic' => $locale->strings['error-admin-vpses-add-traffic'],
'template' => $locale->strings['error-admin-vpses-add-template']
), $sErrors);
try
{
$disk_space = parse_size($_POST['diskspace']);
}
catch(ParsingException $e)
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-disk']);
}
try
{
$guaranteed_ram = parse_size($_POST['guaranteed']);
}
catch(ParsingException $e)
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-guaranteed']);
}
try
{
$burstable_ram = parse_size($_POST['burstable']);
}
catch(ParsingException $e)
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-burstable']);
}
try
{
$traffic = parse_size($_POST['traffic']);
}
catch(ParsingException $e)
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-traffic']);
}
if(is_numeric($_POST['cpucount']))
{
$cpu_count = (int) $_POST['cpucount'];
}
else
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-cpucount']);
}
try
{
$node = new Node($_POST['node']);
}
catch(NotFoundException $e)
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-node']);
}
try
{
$user = new User($_POST['user']);
}
catch(NotFoundException $e)
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-user']);
}
try
{
$template = new Template($_POST['template']);
}
catch(NotFoundException $e)
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-template']);
}
if(!empty($_POST['hostname']))
{
if(validate_hostname($_POST['hostname']))
{
$hostname = $_POST['hostname'];
}
else
{
array_add($sErrors, $locale->strings['error-admin-vpses-add-hostname']);
}
}
else
{
$hostname = random_string(12);
}
if(empty($sErrors))
{
$sContainer = new Container(0);
$sContainer->uHostname = $hostname;
$sContainer->uInternalId = first_unused_ctid();
$sContainer->uNodeId = $node->sId;
$sContainer->uTemplateId = $template->sId;
$sContainer->uUserId = $user->sId;
$sContainer->uVirtualizationType = CVM_VIRTUALIZATION_OPENVZ;
$sContainer->uGuaranteedRam = ($guaranteed_ram / 1024 / 1024); /* MB */
$sContainer->uBurstableRam = ($burstable_ram / 1024 / 1024); /* MB */
$sContainer->uDiskSpace = ($disk_space / 1024 / 1024); /* MB */
$sContainer->uCpuCount = $cpu_count;
$sContainer->uStatus = CVM_STATUS_BLANK;
$sContainer->uIncomingTrafficLimit = $traffic;
$sContainer->uOutgoingTrafficLimit = $traffic;
$sContainer->uTotalTrafficLimit = $traffic;
$sContainer->InsertIntoDatabase();
$sContainer->Deploy();
redirect("/admin/node/{$node->sId}/");
}
}
if(!empty($router->uVariables['prefilled_node']))
{
$_POST['node'] = $router->uParameters[1];
}
$result = $database->CachedQuery("SELECT * FROM nodes");
$sNodes = array();
foreach($result->data as $row)
{
$sNode = new Node($row);
$sNodes[] = array(
'id' => $sNode->sId,
'name' => $sNode->sName,
'location' => $sNode->sPhysicalLocation
);
}
$result = $database->CachedQuery("SELECT * FROM templates WHERE `Available` = 1");
$sTemplates = array();
foreach($result->data as $row)
{
$sTemplate = new Template($row);
$sTemplates[] = array(
'id' => $sTemplate->sId,
'name' => $sTemplate->sName
);
}
$result = $database->CachedQuery("SELECT * FROM users WHERE `AccessLevel` > 0");
$sUsers = array();
foreach($result->data as $row)
{
$sUserOption = new User($row);
$sUsers[] = array(
'id' => $sUserOption->sId,
'username' => $sUserOption->sUsername,
'selected' => (!empty($router->uVariables['prefilled_user']) && $sUserOption->sId == $router->uParameters[1])
);
}
$sPageContents = Templater::AdvancedParse("admin.containers.add", $locale->strings, array(
'errors' => $sErrors,
'nodes' => $sNodes,
'users' => $sUsers,
'templates' => $sTemplates
));

@ -60,9 +60,12 @@ $sContainer->InsertIntoDatabase();
$sContainer->Deploy(); $sContainer->Deploy();
*/ */
/*
var_dump( var_dump(
parse_size("15m"), parse_size("24 KB"), parse_size("51"), parse_size("15m"), parse_size("24 KB"), parse_size("51"),
parse_size("2 TiB"), parse_size("4.9GiB"), parse_size("0.75GB"), parse_size("2 TiB"), parse_size("4.9GiB"), parse_size("0.75GB"),
parse_size("20gb", 1000), parse_size("14.6 TiB", 1000), parse_size("84YB") parse_size("20gb", 1000), parse_size("14.6 TiB", 1000), parse_size("84YB")
); );
*/
var_dump(first_unused_ctid());

@ -134,6 +134,13 @@ try
'auth_error' => "error.access.php", 'auth_error' => "error.access.php",
'_menu' => "admin" '_menu' => "admin"
), ),
/* Admin - Nodes - Create VPS */
'^/admin/containers/add/?$' => array(
'target' => "module.admin.containers.create.php",
'authenticator' => "authenticator.admin.php",
'auth_error' => "error.access.php",
'_menu' => "admin"
),
/* Admin - Containers - Suspend */ /* Admin - Containers - Suspend */
'^/admin/container/([0-9]+)/suspend/?$' => array( '^/admin/container/([0-9]+)/suspend/?$' => array(
'target' => "module.admin.container.suspend.php", 'target' => "module.admin.container.suspend.php",
@ -176,6 +183,14 @@ try
'auth_error' => "error.access.php", 'auth_error' => "error.access.php",
'_menu' => "admin" '_menu' => "admin"
), ),
/* Admin - Nodes - Create VPS */
'^/admin/node/([0-9]+)/add/?$' => array(
'target' => "module.admin.containers.create.php",
'authenticator' => "authenticator.admin.php",
'auth_error' => "error.access.php",
'_menu' => "admin",
'_prefilled_node' => true
),
'^/test/?$' => "module.test.php" '^/test/?$' => "module.test.php"
) )
); );

@ -0,0 +1,88 @@
<h2>{%!title-admin-addcontainer}</h2>
{%if isempty|errors == false}
<div class="errorhandler error-error">
<div class="error-title">{%!error-form}</div>
<div class="error-message">
<ul>
{%foreach error in errors}
<li>{%?error}</li>
{%/foreach}
</ul>
</div>
</div>
{%/if}
<form method="post" action="/admin/containers/add/" class="add dark">
<div class="field">
<label for="form_addcontainer_node">{%!addcontainer-node}</label>
{%select group="addcontainer" name="node"}
{%foreach node in nodes}
{%option value="(?node[id])" text="(?node[name]) ((?node[location]))"}
{%/foreach}
{%/select}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addcontainer_template">{%!addcontainer-template}</label>
{%select group="addcontainer" name="template"}
{%foreach template in templates}
{%option value="(?template[id])" text="(?template[name])"}
{%/foreach}
{%/select}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addcontainer_user">{%!addcontainer-user}</label>
{%select group="addcontainer" name="user"}
{%foreach user in users}
{%option value="(?user[id])" text="(?user[username]) (#(?user[id]))"}
{%/foreach}
{%/select}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addnode_diskspace">{%!addcontainer-diskspace}</label>
{%input type="text" group="addcontainer" name="diskspace"}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addnode_guaranteed">{%!addcontainer-guaranteed}</label>
{%input type="text" group="addcontainer" name="guaranteed"}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addnode_burstable">{%!addcontainer-burstable}</label>
{%input type="text" group="addcontainer" name="burstable"}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addnode_cpucount">{%!addcontainer-cpucount}</label>
{%input type="text" group="addcontainer" name="cpucount"}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addnode_traffic">{%!addcontainer-traffic}</label>
{%input type="text" group="addcontainer" name="traffic"}
<div class="clear"></div>
</div>
<div class="field">
<label for="form_addnode_hostname">{%!addcontainer-hostname}</label>
{%input type="text" group="addcontainer" name="hostname"}
<div class="clear"></div>
</div>
<div class="field">
<div class="filler"></div>
<button type="submit" name="submit">{%!button-admin-addcontainer}</button>
<div class="clear"></div>
</div>
</form>
Loading…
Cancel
Save