Commit 24153779 authored by anarcat's avatar anarcat

switch to cert/IP association instead of site/IP

note that the upgrade path is still broken here, as the incorrect
cert/IP associations get created. that huge SQL query need to be
refactored.

we completely remove the site/IP association, and the IP of a site
isn't displayed in the frontend anymore, as that IP is irrelevant most
of time.

we still need to handle properly multiple IP certs (for clusters), but
the database structure supports this at least.
parent 72f322cc
......@@ -88,42 +88,24 @@ function hosting_ip_delete($node) {
* IP Utility function for hook_delete_revision.
*/
function hosting_ip_delete_revision($node) {
db_query("DELETE FROM {hosting_ip_addresses} WHERE vid=%d", $node->vid);
}
/**
* Pick an IP for a site on a given server.
*
* XXX: this needs to be re-written to rely on the hosting_ssl_cert table
*
* @return the first available IP on the server, or FALSE if no IP is available
*/
function hosting_ip_pick($node) {
// basically, we do a double-left-join on the ip_address table but then
// restrict the left table to the server we're interested in and the
// right tables to only sites (using a subselect, because I couldn't
// figure out how to do it with a join).
//
// took me about 40 minutes to figure out that bastard.
return db_result(db_query("SELECT server.ip_address FROM {hosting_ip_addresses} AS server
LEFT JOIN {hosting_ip_addresses} AS site ON site.ip_address = server.ip_address
and site.nid IN (SELECT nid FROM {node} WHERE type = 'site')
WHERE server.vid=%d AND site.nid IS NULL", $node->vid));
db_query("DELETE FROM {hosting_ip_addresses} WHERE nid=%d", $node->nid);
}
/**
* Allocate an IP for a given site on a given server.
*/
function hosting_ip_allocate($node) {
db_query("LOCK TABLES {hosting_ip_addresses}"); // make sure the IP is
// not allocated after
// the pick
function hosting_ip_allocate($cert, $site) {
// make sure the IP is not allocated while we pick ours
db_query("LOCK TABLES {hosting_ssl_cert_ips} WRITE");
$platform = node_load($node->platform);
$server = node_load($platform->web_server);
$ip = hosting_ip_pick($server);
// guess the next available IP
$ip = db_result(db_query("SELECT server.ip_address FROM hosting_ip_addresses AS server
LEFT JOIN hosting_ssl_cert_ips AS certs ON server.id = certs.ip_address
WHERE certs.ip_address IS NULL AND nid = %d LIMIT 1;", $node->nid));
if ($ip) {
db_query("INSERT INTO {hosting_ip_addresses} (vid, nid, ip_address) VALUES (%d, %d, '%s')", $node->vid, $node->nid, $ip);
db_query("INSERT INTO {hosting_ssl_cert_ips} (cid, ip_address) VALUES (%d, %d)", $cert->nid, $ip);
}
db_query("UNLOCK TABLES {hosting_ip_addresses}");
db_query("UNLOCK TABLES {hosting_ssl_cert_ips}");
return $ip;
}
\ No newline at end of file
......@@ -226,3 +226,87 @@ function hosting_server_update_6200() {
db_add_primary_key($ret, 'hosting_ip_addresses', array('id'));
return $ret;
}
/**
* Create SSL cert to IP mapping table.
*
* We create the SSL cert to IP mapping table here instead of in the ssl
* module as we need to cleanup the ip_address table after and we can't sync
* across modules. Since this module is a dependency of hosting_site_ssl, this
* is not a problem.
*/
function hosting_server_update_6201() {
$ret = array();
$schema = array(
'fields' => array(
// cert id
'cid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
// reference to the hosting_ip_addresses table
'ip_address' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'indexes' => array(
'cid' => array('cid'),
'ip_address' => array('ip_address'),
));
db_create_table($ret, 'hosting_ssl_cert_ips', $schema);
return $ret;
}
/**
* Migrate site-specific IPs to server-specific IPs.
*
* This is the meat of the migration path.
*/
function hosting_server_update_6202() {
$ret = array();
/* now we need to insert a IP/ssl cert mapping in here
here's a request that gives a list of IP/site/key mapping:
SELECT n.nid,ip_address, site.status, title, ssl_enabled, cid, c.ssl_key
FROM hosting_ssl_site s
INNER JOIN hosting_ssl_cert c ON c.cid = s.ssl_key
INNER JOIN node n ON n.nid = s.nid
INNER JOIN hosting_ip_addresses ip ON ip.nid = n.nid
INNER JOIN hosting_site site ON site.nid = n.nid
WHERE site.status > 0
ORDER BY c.cid, n.nid;
SELECT ip_address, cid, c.ssl_key FROM hosting_ssl_site s INNER JOIN hosting_ssl_cert c ON c.cid = s.ssl_key INNER JOIN hosting_ip_addresses ip ON ip.nid = s.nid INNER JOIN hosting_site site ON site.nid = s.nid WHERE site.status > 0 GROUP BY cid ORDER BY c.cid, s.nid;
*/
// XXX: this is broken, as it inserts the site-specific IP instead of the
// server-level IP. that IP gets removed in the next update, so this fucks
// up.
$ret[] = update_sql("INSERT INTO {hosting_ssl_cert_ips} (cid, ip_address)
SELECT cid, ip.id FROM {hosting_ssl_site} s
INNER JOIN {hosting_ssl_cert c ON c.cid = s.ssl_key
INNER JOIN {hosting_ip_addresses}} ip ON ip.nid = s.nid
INNER JOIN {hosting_site site} ON site.nid = s.nid
INNER JOIN {hosting_platform} p ON p.nid = site.platform
WHERE ssl_enabled > %d AND site.status > %d
GROUP BY cid ORDER BY c.cid, s.nid",
HOSTING_SSL_DISABLED, HOSTING_SITE_DELETED);
return $ret;
}
/**
* Cleanup site-specific IP mappings.
*
* Those are now associated to certificates.
*/
function hosting_server_update_6202() {
$ret = array();
$ret[] = update_sql("DELETE {hosting_ip_addresses} FROM {hosting_ip_addresses} JOIN {node} ON hosting_ip_addresses.nid = node.nid WHERE node.type <> 'server';");
return $ret;
}
\ No newline at end of file
......@@ -405,8 +405,6 @@ function hosting_import_site($site_id, $data, $platform) {
$site->no_verify = TRUE;
$site->verified = time();
$site->client = $client->nid;
// XXX: check if the IP is allocated in the server??
$site->ip_addresses = array_values($data['site_ip_addresses']);
$site->cron_key = ($data['cron_key']) ? $data['cron_key'] : '';
$site->aliases = ($data['aliases']) ? $data['aliases'] : array();
......
......@@ -83,8 +83,6 @@ function hosting_site_view(&$node, $teaser = false) {
);
}
hosting_ip_view($node);
$node->content['info']['#suffix'] = '</div>';
if ($node->nid) {
......@@ -110,7 +108,6 @@ function hosting_site_view(&$node, $teaser = false) {
* Implementation of hook_nodeapi_delete_revision().
*/
function hosting_nodeapi_site_delete_revision(&$node) {
hosting_ip_delete_revision($node);
db_query('DELETE FROM {hosting_site} WHERE vid = %d', $node->vid);
}
......@@ -118,7 +115,6 @@ function hosting_nodeapi_site_delete_revision(&$node) {
* Implementation of hook_delete().
*/
function hosting_site_delete($node) {
hosting_ip_delete($node);
db_query('DELETE FROM {hosting_site} WHERE nid = %d', $node->nid);
db_query('DELETE FROM {hosting_package_instance} WHERE rid=%d', $node->nid);
hosting_context_delete($node->nid);
......@@ -174,7 +170,6 @@ function hosting_site_update(&$node) {
if ($node->site_status == HOSTING_SITE_DELETED) {
$node->no_verify = TRUE;
}
hosting_ip_save($node, TRUE);
db_query("UPDATE {hosting_site} SET client = %d, db_server = %d, platform = %d, last_cron = %d, cron_key = '%s', status = %d, profile = %d, language = '%s', verified = %d WHERE vid=%d",
$node->client, $node->db_server, $node->platform, $node->last_cron, $node->cron_key, $node->site_status, $node->profile, $node->site_language, $node->verified, $node->vid);
......@@ -192,6 +187,5 @@ function hosting_site_update(&$node) {
*/
function hosting_site_load($node) {
$additions = db_fetch_object(db_query('SELECT client, db_server, platform, profile, language as site_language, last_cron, cron_key, status AS site_status, verified FROM {hosting_site} WHERE vid = %d', $node->vid));
$additions->ip_addresses = hosting_ip_load($node);
return $additions;
}
......@@ -85,6 +85,28 @@ function hosting_ssl_schema() {
),
'primary key' => array('vid', 'nid'),
);
$schema['hosting_ssl_cert_ips'] = array(
'fields' => array(
// cert id
'cid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
// reference to the hosting_ip_addresses table
'ip_address' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'indexes' => array(
'cid' => array('cid'),
'ip_address' => array('ip_address'),
));
return $schema;
}
......
......@@ -193,7 +193,7 @@ function hosting_ssl_nodeapi_site_presave(&$node) {
if (($node->ssl_key == HOSTING_SSL_CUSTOM_KEY) && isset($node->ssl_key_new)) {
$node->ssl_key = hosting_ssl_filter_key($node->ssl_key_new);
}
// allocate the site's IP here
// this creates the SSL key for the site, if required
$node->ssl_key = hosting_ssl_save_key($node);
}
......@@ -251,8 +251,8 @@ function hosting_ssl_save_key($node) {
$obj->ssl_key = $node->key;
$obj->client = $node->client;
$obj->status = 0;
$obj->ip_address = hosting_ip_allocate($node);
drupal_write_record("hosting_ssl_cert", $obj);
hosting_ip_allocate($cert, $node);
}
return $obj->cid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment