View source
<?php
include_once "hosting_server.service.inc";
include_once "hosting.ip.inc";
function hosting_server_node_info() {
$types["server"] = array(
"type" => 'server',
"name" => 'Server',
"module" => 'hosting_server',
"has_title" => true,
"title_label" => t('Host name'),
"description" => hosting_node_help("server"),
"has_body" => 0,
"body_label" => '',
"min_word_count" => 0,
);
return $types;
}
function hosting_server_menu() {
$items = array();
$items['hosting/servers'] = array(
'title' => 'Servers',
'description' => 'List of servers',
'page callback' => 'hosting_server_listing',
'access arguments' => array(
'view server',
),
);
return $items;
}
function hosting_server_hosting_feature() {
$features['server'] = array(
'title' => t('Server administration'),
'description' => t('Manage multiple servers.'),
'status' => HOSTING_FEATURE_ENABLED,
'node' => 'server',
);
return $features;
}
function hosting_server_hosting_tasks() {
$tasks = array();
$tasks['server']['verify'] = array(
'title' => t('Verify'),
'description' => t('Verify that the server is correctly installed and working.'),
'weight' => 10,
'provision_save' => TRUE,
);
return $tasks;
}
function hosting_server_perm() {
return array(
'create server',
'view server',
'edit server',
'delete server',
);
}
function hosting_server_access($op, $node, $account) {
if (!hosting_feature('server')) {
return FALSE;
}
switch ($op) {
case 'create':
return user_access('create server', $account);
case 'view':
return user_access('view server', $account);
case 'update':
return user_access('edit server', $account);
case 'delete':
return user_access('delete server', $account);
}
}
function hosting_server_services() {
static $services;
if (!isset($services)) {
$services = module_invoke_all('hosting_service_type');
foreach (module_implements('hosting_service') as $module) {
foreach (module_invoke($module, 'hosting_service') as $service => $service_type) {
module_load_include('service.inc', $module);
$services[$service_type]['types'][$service] = 'hostingService_' . $service_type . '_' . $service;
}
}
}
return $services;
}
function hosting_services_new_object($name, $type, $node, $values = null) {
$services = hosting_server_services();
$class = $services[$name]['types'][$type];
if (!$class) {
return;
}
return new $class($node, $values);
}
function hosting_services_add(&$node, $name, $type, $values = array()) {
$values['available'] = isset($values['available']) ? $values['available'] : 1;
if ($service_object = hosting_services_new_object($name, $type, $node, $values)) {
$node->services[$name] = $service_object;
}
}
function hosting_server_init_services(&$node) {
$node->services = array();
$result = db_query("SELECT service, type FROM {hosting_service} WHERE vid=%d AND available=1", $node->vid);
while ($record = db_fetch_object($result)) {
$name = $record->service;
if ($service_object = hosting_services_new_object($name, $record->type, $node)) {
$node->services[$name] = $service_object;
}
}
return $node;
}
function hosting_server_services_from_post(&$node) {
if (isset($node->services) && is_array($node->services)) {
foreach (hosting_server_services() as $name => $data) {
if (isset($node->services[$name]) && is_array($node->services[$name])) {
if ($node->services[$name]['type'] !== 'null') {
if ($service_object = hosting_services_new_object($name, $node->services[$name]['type'], $node, $node->services[$name][$node->services[$name]['type']])) {
$node->services[$name] = hosting_services_new_object($name, $node->services[$name]['type'], $node, $node->services[$name][$node->services[$name]['type']]);
$node->services[$name]->available = TRUE;
}
}
else {
unset($node->services[$name]);
}
}
}
}
}
function hosting_server_invoke_services(&$node, $method, &$arg1 = null, &$arg2 = null, &$arg3 = null, &$arg4 = null) {
$return = array();
foreach ($node->services as $name => $service) {
$result = $service
->{$method}($arg1, $arg2, $arg3, $arg4);
if (isset($result) && is_array($result)) {
$return = array_merge_recursive($return, $result);
}
else {
if (isset($result)) {
$return[] = $result;
}
}
}
return $return;
}
function hosting_server_form(&$node) {
drupal_add_js(drupal_get_path('module', 'hosting_server') . '/hosting_server.js');
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Server hostname'),
'#required' => TRUE,
'#default_value' => $node->title,
'#description' => t('The host name of the server. This is the address that will be used by Hostmaster to connect to the server to issue commands. It is to resolve to the internal network, if you have such a separation.<br /><strong>Be careful when changing the node title, it is used to create the SQL users if the IP address, below, is not set.</strong>'),
'#weight' => -10,
);
$form['ip_addresses'] = array(
'#type' => 'textarea',
'#title' => t('Ip addresses'),
'#description' => t('A list of IP addresses this server is publicly available under, one per line. If none is specified, a DNS lookup will be performed based on the server hostname above. <br /><strong>This should point to the public network, if you have such a separation.</strong>'),
'#default_value' => implode("\n", _hosting_ip_list($node->ip_addresses)),
'#weight' => -9,
);
$form['services'] = array(
'#weight' => -5,
'#tree' => TRUE,
);
if (!$node->nid) {
$node->services = array();
}
foreach (hosting_server_services() as $name => $service) {
$form['services'][$name] = array(
'#type' => 'fieldset',
'#title' => $service['title'],
'#prefix' => '<div class="hosting-service-form">',
'#suffix' => '</div>',
'#weight' => isset($service['weight']) ? $service['weight'] : 0,
);
$form['services'][$name]['type'] = array(
'#type' => 'radios',
'#weight' => -99,
'#options' => array_merge(array(
'null' => 'None',
), drupal_map_assoc(array_keys($service['types']))),
'#default_value' => isset($node->services[$name]->available) && $node->services[$name]->available ? $node->services[$name]->type : 'null',
);
foreach ($service['types'] as $type => $class) {
$form['services'][$name][$type] = array(
'#prefix' => '<div id="provision-service-settings-' . $name . '-' . $type . '" class="provision-service-settings-' . $name . '">',
'#suffix' => '</div>',
);
if (isset($node->services[$name]) && $node->services[$name]->type === $type) {
$node->services[$name]
->form($form['services'][$name][$type]);
}
else {
$service_object = hosting_services_new_object($name, $type, $node);
$service_object
->form($form['services'][$name][$type]);
}
}
}
return $form;
}
function hosting_nodeapi_server_presave(&$node) {
if (empty($node->ip_addresses)) {
$ips = gethostbynamel($node->title);
if ($ips) {
drupal_set_message(t('Initialized the IP to %ip based on hostname %name. If an HTTP service is enabled, this will be used to create database grants so make sure it is the right address, as seen from the database server.', array(
'%ip' => join(',', $ips),
'%name' => $node->title,
)), 'message');
$node->ip_addresses = $ips;
}
else {
drupal_set_message(t("Could not resolve IP address of server %name, not automatically setting IP address. DNS may fail.", array(
'%name' => $node->title,
)));
}
}
hosting_server_services_from_post($node);
}
function hosting_server_validate(&$node, &$form) {
hosting_ip_validate($node);
if (!_hosting_valid_fqdn($node->title)) {
form_set_error('title', t('Invalid hostname. Use a proper hostname or an IP address.'));
}
if (!$node->nid && db_result(db_query("SELECT COUNT(nid) FROM {node} WHERE type='server' AND title='%s'", $node->title))) {
form_set_error('title', t("The hostname you have specified is already in use."));
}
hosting_server_services_from_post($node);
hosting_server_invoke_services($node, 'validate', $node, $form);
}
function hosting_server_update($node) {
if (!empty($node->revision)) {
hosting_server_insert($node);
}
else {
hosting_server_invoke_services($node, 'save', $node);
hosting_server_invoke_services($node, 'update', $node);
foreach (array_diff(array_keys(hosting_server_services()), array_keys($node->services)) as $name) {
db_query("DELETE FROM {hosting_service} WHERE service = '%s' AND nid = %d", $name, $node->nid);
}
}
hosting_ip_save($node, TRUE);
if (!$node->no_verify) {
hosting_add_task($node->nid, 'verify');
}
}
function hosting_server_insert($node) {
if (!$node->revision) {
$hosting_name = $node->hosting_name ? $node->hosting_name : 'server_' . preg_replace("/[!\\W\\.\\-]/", "", $node->title);
hosting_context_register($node->nid, $hosting_name);
}
db_query("INSERT INTO {hosting_server} (vid, nid) \n VALUES (%d, %d)", $node->vid, $node->nid);
hosting_ip_save($node, FALSE);
hosting_server_invoke_services($node, 'save', $node);
hosting_server_invoke_services($node, 'insert', $node);
if (!$node->no_verify) {
hosting_add_task($node->nid, 'verify');
}
}
function hosting_nodeapi_server_delete_revision(&$node) {
db_query('DELETE FROM {hosting_server} WHERE vid = %d', $node->vid);
hosting_ip_delete_revision($node);
hosting_server_invoke_services($node, 'delete_revision');
}
function hosting_server_delete($node) {
db_query('DELETE FROM {hosting_server} WHERE nid = %d', $node->nid);
hosting_ip_delete($node);
hosting_context_delete($node->nid);
hosting_server_invoke_services($node, 'delete_revision');
}
function hosting_server_load($node) {
hosting_server_init_services($node);
hosting_server_invoke_services($node, 'load');
$additions = new stdClass();
$additions->services = $node->services;
$additions->ip_addresses = hosting_ip_load($node);
return $additions;
}
function hosting_server_node_load($arg) {
if (!is_numeric($arg)) {
return FALSE;
}
if ($node = node_load($arg)) {
if ($node->type === 'server') {
return $node;
}
}
return FALSE;
}
function hosting_server_view(&$node, $teaser = FALSE, $page = FALSE) {
hosting_set_breadcrumb($node);
$node = node_prepare($node, $teaser);
$services = hosting_server_services();
$node->content['info'] = array(
'#prefix' => '<div id="hosting-server-info">',
'#suffix' => '</div>',
);
hosting_ip_view($node);
if (isset($node->content->info->ip_addresses['#weight'])) {
$node->content->info->ip_addresses['#weight'] = -30;
}
foreach ($node->services as $name => $service) {
$node->content['info'][$name] = array(
'#prefix' => '<div class="hosting-service-info hosting-service-' . $name . '-info">',
'#suffix' => '</div>',
);
if (isset($services[$name]['weight'])) {
$node->content['info'][$name]['#weight'] = $services[$name]['weight'];
}
$title = $services[$name]['title'] . ' : ' . $service->type;
$node->content['info'][$name]['title'] = array(
'#value' => '<h3>' . $title . '</h3>',
'#weight' => -20,
);
$service
->view($node->content['info'][$name]);
}
if ($page) {
if ($node->nid) {
$node->content['tasks_view'] = array(
'#type' => 'item',
'#value' => hosting_task_table($node),
'#prefix' => '<div id="hosting-task-list">',
'#suffix' => '</div>',
'#weight' => 10,
);
$settings['hostingTaskRefresh'] = array(
'nid' => $node->nid,
'changed' => $node->changed,
);
drupal_add_js($settings, 'setting');
drupal_add_js(drupal_get_path('module', 'hosting_task') . '/hosting_task.js');
}
}
return $node;
}
function hosting_server_listing() {
$services = hosting_server_services();
$header = array(
t('Server'),
);
foreach ($services as $service => $data) {
if ($service !== 'server') {
$header[] = $data['title'];
}
}
$result = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.type='server' AND n.status = 1 ORDER BY n.title"));
$rows = array();
while ($obj = db_fetch_object($result)) {
$row = array();
$server = node_load($obj->nid);
$row[] = l($server->title, 'node/' . $server->nid);
foreach ($services as $service => $data) {
if ($service !== 'server') {
if ($server->services[$service]->available) {
$row[] = array(
'class' => 'hosting-service-available',
'data' => $server->services[$service]->type,
);
}
else {
$row[] = array(
'class' => 'hosting-service-unavailable',
'data' => t('No'),
);
}
}
}
$rows[] = $row;
}
return theme('table', $header, $rows, array(
'class' => 'hosting-table',
));
}
function hosting_get_servers($service) {
$return = array();
$result = db_query("SELECT n.nid, n.title FROM {node} n INNER JOIN {hosting_service} s ON n.vid = s.vid AND s.available = 1 AND s.service = '%s'", $service);
while ($server = db_fetch_object($result)) {
$return[$server->nid] = $server->title;
}
drupal_alter('hosting_servers_titles', $return, $service);
return $return;
}