function pool_display($pool) { if (xvp_db_user_rights(null, $pool) == "none") { return; } $hidehosts = xvp_db_user_host_rights($pool) == "none"; $displayname = htmlspecialchars($pool->poolname, ENT_QUOTES); if ($pool->domainname) { $displayname .= " in domain " . htmlspecialchars(substr($pool->domainname, 1), ENT_QUOTES); } foreach ($pool->vms as $vm) { if (xvp_db_user_rights($vm, $pool) == "none") { continue; } echo <<<EOF <iframe class="hidden" id="actions-{$vm->fullname}" name="actions-{$vm->fullname}" src="blank.html"></iframe> <iframe class="hidden" id="console-{$vm->fullname}" name="console-{$vm->fullname}" src="blank.html"></iframe> <ul id="vmmenu-{$vm->fullname}" class="contextMenu"> <li class="console"> <a href="#console">Console</a> </li> <li class="boot separator"> <a href="#boot">Boot</a> </li> <li class="booton"> <a href="#booton">Boot on ...</a> </li> <li class="bootrecovery"> <a href="#bootrecovery">Boot Recovery</a> </li> <li class="shutdown separator"> <a href="#shutdown">Shutdown</a> </li> <li class="poweroff"> <a href="#poweroff">Force Shutdown</a> </li> <li class="reboot separator"> <a href="#reboot">Reboot</a> </li> <li class="reset"> <a href="#reset">Force Reboot</a> </li> <li class="suspend separator"> <a href="#suspend">Suspend</a> </li> <li class="resume"> <a href="#resume">Resume</a> </li> <li class="resumeon"> <a href="#resumeon">Resume on ...</a> </li> <li class="migrate separator"> <a href="#migrate">Migrate to ...</a> </li> <li class="snapshot separator"> <a href="#snapshot">Snapshots</a> </li> <li class="properties separator"> <a href="#properties">Properties</a> </li> </ul> EOF; } $poolid = xvp_make_fullname($pool->poolname, null); $jspoolid = addslashes($poolid); echo "\n<div class=\"pool\" id=\"pool-{$poolid}\">\n\n"; if ($hidehosts) { echo <<<EOF <h2 class="center"><img class="toggle" id="toggle-{$poolid}" alt="" title="" src="images/minus.png" onclick="poolToggle('{$jspoolid}');" />Pool {$displayname}</h2> <div class="vmscenter"> EOF; } else { echo <<<EOF <h2><img class="toggle" id="toggle-{$poolid}" alt="" title="" src="images/minus.png" onclick="poolToggle('{$jspoolid}');" />Pool {$displayname}</h2> <div class="hosts"> <h3 class="hosts">Server Hosts</h3> <table class="hosts"> <tr> <td class="group"> <img class="toggle" id="toggle-{$poolid}-hosts" alt="" title="" src="images/minus.png" onclick="hostsToggle('{$jspoolid}');" /> </td> </tr> EOF; foreach ($pool->hosts as $host) { host_display($host); } echo <<<EOF </table> </div> <div class="vmsright"> EOF; } echo <<<EOF <h3>Virtual Machines</h3> <table class="vms"> EOF; $groupname = "--"; foreach ($pool->vms as $vm) { if (!xvp_config_host_by_name($pool, $vm->vmname)) { vm_display($vm, $groupname); } } echo <<<EOF </table> </div> </div> EOF; }
function host_del($options = "") { global $conf, $self, $onadb; printmsg("DEBUG => host_del({$options}) called", 3); // Version - UPDATE on every edit! $version = '1.19'; // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is no) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Return the usage summary if we need to if ($options['help'] or !$options['host']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM host_del-v{$version} Deletes a host, and all related records from the database Synopsis: host_del [KEY=VALUE] ... Required: host=NAME[.DOMAIN] or ID Hostname or ID of the host to delete Optional: commit=[yes|no] Commit db transaction (no) Notes: * A host won't be deleted if it has config text records * A host won't be deleted if it's configured as a dns or dhcp server EOM ); } // Find the host (and domain) record from $options['host'] list($status, $rows, $host) = ona_find_host($options['host']); printmsg("DEBUG => host_del() Host: {$host['fqdn']} ({$host['id']})", 3); if (!$host['id']) { printmsg("DEBUG => Unknown host: {$host['fqdn']}", 3); $self['error'] = "ERROR => Unknown host: {$host['fqdn']}"; return array(2, $self['error'] . "\n"); } // Check permissions if (!auth('host_del') or !authlvl($host['LVL'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // If "commit" is yes, delete the host if ($options['commit'] == 'Y') { $text = ""; $add_to_error = ""; $add_to_status = 0; // SUMMARY: // Don't allow a delete if it is performing server duties // Don't allow a delete if config text entries exist // Delete Interfaces // Delete interface cluster entries // Delete dns records // Delete custom attributes // Delete DHCP entries // Delete device record if it is the last host associated with it. // // IDEA: If it's the last host in a domain (maybe do the same for or a networks & vlans in the interface delete) // It could just print a notice or something. // Check that it is the host is not performing server duties // FIXME: MP mostly fixed..needs testing $serverrow = 0; // check ALL the places server_id is used and remove the entry from server_b if it is not used list($status, $rows, $srecord) = db_get_record($onadb, 'dhcp_server_subnets', array('host_id' => $host['id'])); if ($rows) { $serverrow++; } list($status, $rows, $srecord) = db_get_record($onadb, 'dhcp_failover_groups', array('primary_server_id' => $host['id'])); if ($rows) { $serverrow++; } list($status, $rows, $srecord) = db_get_record($onadb, 'dhcp_failover_groups', array('secondary_server_id' => $host['id'])); if ($rows) { $serverrow++; } if ($serverrow > 0) { printmsg("DEBUG => Host ({$host['fqdn']}) cannot be deleted, it is performing duties as a DHCP server!", 3); $self['error'] = "ERROR => Host ({$host['fqdn']}) cannot be deleted, it is performing duties as a DHCP server!"; return array(5, $self['error'] . "\n"); } // Check if host is a dns server $serverrow = 0; list($status, $rows, $srecord) = db_get_record($onadb, 'dns_server_domains', array('host_id' => $host['id'])); if ($rows) { $serverrow++; } if ($serverrow > 0) { printmsg("DEBUG => Host ({$host['fqdn']}) cannot be deleted, it is performing duties as a DNS server!", 3); $self['error'] = "ERROR => Host ({$host['fqdn']}) cannot be deleted, it is performing duties as a DNS server!"; return array(5, $self['error'] . "\n"); } // Display an error if it has any entries in configurations list($status, $rows, $server) = db_get_record($onadb, 'configurations', array('host_id' => $host['id'])); if ($rows) { printmsg("DEBUG => Host ({$host['fqdn']}) cannot be deleted, it has config archives!", 3); $self['error'] = "ERROR => Host ({$host['fqdn']}) cannot be deleted, it has config archives!"; return array(5, $self['error'] . "\n"); } // Delete interface(s) // get list for logging $clustcount = 0; $dnscount = 0; list($status, $rows, $interfaces) = db_get_records($onadb, 'interfaces', array('host_id' => $host['id'])); // Cant delete if one of the interfaces is primary for a cluster foreach ($interfaces as $int) { list($status, $rows, $records) = db_get_records($onadb, 'interface_clusters', array('interface_id' => $int['id'])); $clustcount = $clustcount + $rows; } if ($clustcount) { $self['error'] = "ERROR => host_del() An interface on this host is primary for some interface shares, delete the share or move the interface first."; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } // do the interface_cluster delete. This just removes this host from the cluster, not the whole cluster itself // It will error out as well if this interface is the primary in the cluster list($status, $rows) = db_delete_records($onadb, 'interface_clusters', array('host_id' => $host['id'])); if ($status) { $self['error'] = "ERROR => host_del() interface_cluster delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } // log deletions printmsg("INFO => {$rows} Shared interface(s) DELETED from {$host['fqdn']}", 0); $add_to_error .= "INFO => {$rows} Shared interface(s) DELETED from {$host['fqdn']}\n"; // Delete each DNS record associated with this hosts interfaces. // foreach ($interfaces as $int) { // // Loop through each dns record associated with this interface. // list($status, $rows, $records) = db_get_records($onadb, 'dns', array('interface_id' => $int['id'])); // if ($rows) { // foreach($records as $record) { // // Run the module // list($status, $output) = run_module('dns_record_del', array('name' => $record['id'], 'type' => $record['type'], 'commit' => 'Y', 'delete_by_module' => 'Y')); // $add_to_error .= $output; // $add_to_status = $add_to_status + $status; // } // } // } // Delete messages // get list for logging list($status, $rows, $records) = db_get_records($onadb, 'messages', array('table_name_ref' => 'hosts', 'table_id_ref' => $host['id'])); // do the delete list($status, $rows) = db_delete_records($onadb, 'messages', array('table_name_ref' => 'hosts', 'table_id_ref' => $host['id'])); if ($status) { $self['error'] = "ERROR => host_del() message delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } // log deletions printmsg("INFO => {$rows} Message(s) DELETED from {$host['fqdn']}", 0); $add_to_error .= "INFO => {$rows} Message(s) DELETED from {$host['fqdn']}\n"; // Delete the interfaces.. this should delete dns names and other things associated with interfaces.. foreach ($interfaces as $record) { // Run the module list($status, $output) = run_module('interface_del', array('interface' => $record['id'], 'commit' => 'on', 'delete_by_module' => 'Y')); $add_to_error .= $output; $add_to_status = $add_to_status + $status; } // Delete device record // Count how many hosts use this same device list($status, $rows, $records) = db_get_records($onadb, 'hosts', array('device_id' => $host['device_id'])); // if device count is just 1 do the delete if ($rows == 1) { list($status, $rows) = db_delete_records($onadb, 'devices', array('id' => $host['device_id'])); if ($status) { $self['error'] = "ERROR => host_del() device delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $add_to_error . $self['error'] . "\n"); } // log deletions printmsg("INFO => Device record DELETED: [{$record['id']}] no remaining hosts using this device", 0); } else { printmsg("INFO => Device record NOT DELETED: [{$record['id']}] there are other hosts using this device.", 1); } // Delete tag entries list($status, $rows, $records) = db_get_records($onadb, 'tags', array('type' => 'host', 'reference' => $host['id'])); $log = array(); $i = 0; foreach ($records as $record) { $log[$i] = "INFO => Tag DELETED: {$record['name']} from {$host['fqdn']}"; $i++; } //do the delete list($status, $rows) = db_delete_records($onadb, 'tags', array('type' => 'host', 'reference' => $host['id'])); if ($status) { $self['error'] = "ERROR => host_del() Tag delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $add_to_error . $self['error'] . "\n"); } //log deletions foreach ($log as $log_msg) { printmsg($log_msg, 0); $add_to_error .= $log_msg . "\n"; } // Delete custom attribute entries // get list for logging list($status, $rows, $records) = db_get_records($onadb, 'custom_attributes', array('table_name_ref' => 'hosts', 'table_id_ref' => $host['id'])); $log = array(); $i = 0; foreach ($records as $record) { list($status, $rows, $ca) = ona_get_custom_attribute_record(array('id' => $record['id'])); $log[$i] = "INFO => Custom Attribute DELETED: {$ca['name']} ({$ca['value']}) from {$host['fqdn']}"; $i++; } //do the delete list($status, $rows) = db_delete_records($onadb, 'custom_attributes', array('table_name_ref' => 'hosts', 'table_id_ref' => $host['id'])); if ($status) { $self['error'] = "ERROR => host_del() Custom attribute delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $add_to_error . $self['error'] . "\n"); } //log deletions foreach ($log as $log_msg) { printmsg($log_msg, 0); $add_to_error .= $log_msg . "\n"; } // Delete DHCP options // get list for logging list($status, $rows, $records) = db_get_records($onadb, 'dhcp_option_entries', array('host_id' => $host['id'])); $log = array(); $i = 0; foreach ($records as $record) { list($status, $rows, $dhcp) = ona_get_dhcp_option_entry_record(array('id' => $record['id'])); $log[$i] = "INFO => DHCP entry DELETED: {$dhcp['display_name']}={$dhcp['value']} from {$host['fqdn']}"; $i++; } // do the delete list($status, $rows) = db_delete_records($onadb, 'dhcp_option_entries', array('host_id' => $host['id'])); if ($status) { $self['error'] = "ERROR => host_del() DHCP option entry delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $add_to_error . $self['error'] . "\n"); } // log deletions foreach ($log as $log_msg) { printmsg($log_msg, 0); $add_to_error .= $log_msg . "\n"; } // Delete the host list($status, $rows) = db_delete_records($onadb, 'hosts', array('id' => $host['id'])); if ($status) { $self['error'] = "ERROR => host_del() host delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $add_to_error . $self['error'] . "\n"); } // Return the success notice if ($add_to_status == 0) { $self['error'] = "INFO => Host DELETED: {$host['fqdn']}"; } printmsg($self['error'], 0); return array($add_to_status, $add_to_error . $self['error'] . "\n"); } // // We are just displaying records that would have been deleted // // SUMMARY: // Display a warning if it is a server // Display a warning if it has config text entries // Display Interfaces // Display dns records // Display custom attributes // Display DHCP entries // Otherwise just display the host record for the host we would have deleted $text = "Record(s) NOT DELETED (see \"commit\" option)\n" . "Displaying record(s) that would have been deleted:\n"; // Display a warning if host is performing server duties list($status, $rows, $srecord) = db_get_record($onadb, 'dhcp_server_subnets', array('host_id' => $host['id'])); if ($rows) { $text .= "\nWARNING! This host is a DHCP server for {$rows} subnet(s)\n"; } list($status, $rows, $srecord) = db_get_record($onadb, 'dns_server_domains', array('host_id' => $host['id'])); if ($rows) { $text .= "\nWARNING! This host is a DNS server for one or more domains!\n"; } list($status, $rows, $srecord) = db_get_record($onadb, 'dhcp_failover_groups', array('primary_server_id' => $host['id'])); if ($rows) { $text .= "\nWARNING! This host is a server that is primary in a DHCP failover group\n"; } list($status, $rows, $srecord) = db_get_record($onadb, 'dhcp_failover_groups', array('secondary_server_id' => $host['id'])); if ($rows) { $text .= "\nWARNING! This host is a server that is secondary in a DHCP failover group\n"; } // Display a warning if it has any configurations list($status, $rows, $server) = db_get_record($onadb, 'configurations', array('host_id' => $host['id'])); if ($rows) { $text .= "\nWARNING! Host can not be deleted, it has config archives!\n"; } if ($rows) { $text .= "\nWARNING! Host will NOT be deleted, due to previous warnings!\n"; } // Display the Host's complete record list($status, $tmp) = host_display("host={$host['id']}&verbose=N"); $text .= "\n" . $tmp; // Display count of messages list($status, $rows, $records) = db_get_records($onadb, 'messages', array('table_name_ref' => 'hosts', 'table_id_ref' => $host['id'])); if ($rows) { $text .= "\nASSOCIATED MESSAGE RECORDS ({$rows}):\n"; } // Display associated interface(s) list($status, $int_rows, $interfaces) = db_get_records($onadb, 'interfaces', array('host_id' => $host['id'])); // show the dns records associated foreach ($interfaces as $record) { list($status, $rows, $dnsrec) = db_get_records($onadb, 'dns', array('interface_id' => $record['id'])); if ($rows) { $text .= "\nASSOCIATED DNS RECORDS ({$rows}) ON INTERFACE (" . ip_mangle($record['ip_addr'], 'dotted') . "):\n"; foreach ($dnsrec as $rec) { // show AAAA or A type as needed if ($record['ip_addr'] > 4294967295 and $rec['type'] == 'A') { $rec['type'] = 'AAAA'; } $text .= " TYPE: [ID:{$rec['id']}] {$rec['type']}, {$rec['name']} -> " . ip_mangle($record['ip_addr'], 'dotted') . "\n"; } } } if ($int_rows) { $text .= "\nASSOCIATED INTERFACE RECORDS ({$int_rows}):\n"; } foreach ($interfaces as $record) { $text .= " [ID:{$record['id']}] " . ip_mangle($record['ip_addr'], 'dotted') . "\n"; } // Display associated interface_clusters(s) list($status, $clust_rows, $interfaceclusters) = db_get_records($onadb, 'interface_clusters', array('host_id' => $host['id'])); if ($clust_rows) { $text .= "\nASSOCIATED SHARED INTERFACE RECORDS ({$clust_rows}):\n"; } foreach ($interfaceclusters as $record) { list($status, $rows, $int) = ona_get_interface_record(array('id' => $record['interface_id'])); $text .= " [ID:{$int['id']}] {$int['ip_addr_text']}\n"; } // Display associated tags list($status, $rows, $records) = db_get_records($onadb, 'tags', array('type' => 'host', 'reference' => $host['id'])); if ($rows) { $text .= "\nASSOCIATED TAG RECORDS ({$rows}):\n"; } foreach ($records as $record) { $text .= " {$record['name']}\n"; } // Display associated custom attributes list($status, $rows, $records) = db_get_records($onadb, 'custom_attributes', array('table_name_ref' => 'hosts', 'table_id_ref' => $host['id'])); if ($rows) { $text .= "\nASSOCIATED CUSTOM ATTRIBUTE RECORDS ({$rows}):\n"; } foreach ($records as $record) { list($status, $rows, $ca) = ona_get_custom_attribute_record(array('id' => $record['id'])); $text .= " {$ca['name']} => {$ca['value']}\n"; } // Display associated DHCP entries list($status, $rows, $records) = db_get_records($onadb, 'dhcp_option_entries', array('host_id' => $host['id'])); if ($rows) { $text .= "\nASSOCIATED DHCP OPTION RECORDS ({$rows}):\n"; } foreach ($records as $record) { list($status, $rows, $dhcp) = ona_get_dhcp_option_entry_record(array('id' => $record['id'])); $text .= " {$dhcp['display_name']} => {$dhcp['value']}\n"; } return array(7, $text); }