function domain_server_del($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.02'; printmsg("DEBUG => domain_server_del({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is yes) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Return the usage summary if we need to if ($options['help'] or !($options['domain'] and $options['server'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM domain_server_del-v{$version} Removes a domain record from a DNS server Synopsis: domain_server_del [KEY=VALUE] ... Required: domain=NAME or ID domain name or ID server=NAME[.DOMAIN] or ID server name or ID Optional: commit=[Y|N] commit db transaction (no) EOM ); } if (is_numeric($options['domain'])) { $domainsearch['id'] = $options['domain']; } else { $domainsearch['name'] = strtoupper($options['domain']); } // Determine the entry itself exists list($status, $rows, $domain) = ona_get_domain_record($domainsearch); // Test to see that we were able to find the specified record if (!$domain['id']) { printmsg("DEBUG => Unable to find the domain record using {$options['domain']}!", 3); $self['error'] = "ERROR => Unable to find the domain record using {$options['domain']}!"; return array(4, $self['error'] . "\n"); } printmsg("DEBUG => domain_server_del(): Found domain, {$domain['name']}", 3); if ($options['server']) { // Determine the server is valid list($status, $rows, $host) = ona_find_host($options['server']); if (!$host['id']) { printmsg("DEBUG => The server ({$options['server']}) does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['server']}, does not exist!"; return array(2, $self['error'] . "\n"); } } // Test that this domain is even assigned to the server list($status, $rows, $domainserver) = ona_get_dns_server_domain_record(array('host_id' => $host['id'], 'domain_id' => $domain['id'])); if (!$rows) { printmsg("DEBUG => Unable to find {$domain['name']} on server {$host['fqdn']}", 3); $self['error'] = "ERROR => Unable to find {$domain['name']} on server {$host['fqdn']}"; return array(11, $self['error'] . "\n"); } // Test that there are no NS records for this pair // ASSUMPTION: MP this will always be just one record?? // depending on how the user has their NS records set up, we may not find anything. list($status, $dnsrows, $dnsrec) = db_get_record($onadb, 'dns', "domain_id = {$domain['id']} AND type = 'NS' AND interface_id in (select id from interfaces where host_id = {$host['id']})"); // If "commit" is yes, delete the record if ($options['commit'] == 'Y') { // Check permissions if (!auth('advanced') or !authlvl($host['LVL']) or !authlvl($domain['LVL'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // delete record from domain_server_domains list($status, $rows) = db_delete_records($onadb, 'dns_server_domains', array('id' => $domainserver['id'])); if ($status) { $self['error'] = "ERROR => domain_server_del() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } // Run the module to delete the associated NS record.. Only if we found a dns record for NS if ($dnsrec['id']) { list($status, $output) = run_module('dns_record_del', array('name' => $dnsrec['id'], 'type' => 'NS', 'commit' => 'Y')); if ($status) { $self['error'] = "ERROR => domain_server_del() NS record delete failed:" . $output; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } else { // add the output to self error for display $add_to_error = $output; } } // Return the success notice $self['error'] = "INFO => DNS Domain/Server Pair DELETED: {$domain['name']}/{$host['fqdn']} "; printmsg($self['error'], 0); return array(0, $add_to_error . $self['error'] . "\n"); } // Otherwise display the record that would have been deleted $text = <<<EOL Record(s) NOT DELETED (see "commit" option) Displaying record(s) that would have been removed: {$domain['name']} from: {$host['fqdn']} EOL; if ($dnsrows) { $text .= " Removing related NS record, if any. Please double check your NS records for this domain.\n"; } return array(6, $text); }
function dns_record_del($options = "") { global $conf, $self, $onadb; printmsg("DEBUG => dns_record_del({$options}) called", 3); // Version - UPDATE on every edit! $version = '1.03'; // 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['name']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dns_record_del-v{$version} Deletes a DNS record from the database Synopsis: dns_record_del [KEY=VALUE] ... Required: name=NAME[.DOMAIN] or ID hostname or ID of the record to delete type=TYPE record type (A,CNAME,PTR...) Optional: ip=ADDRESS ip address (numeric or dotted) commit=[yes|no] commit db transaction (no) EOM ); } /* thoughts on the flow of things: A records: remove any CNAMES using this A record remove any PTR records using this A record test that it is not a primary_dns_id, if it is, it must be reassigned should make a find_dns_record(s) function. a find by host option would be good. need to do a better delete of DNS records when deleting a host.. currently its a problem. MP: TODO: this delete will not handle DNS views unless you use the ID of the record to delete. add a view option at some point. */ // If the name we were passed has a leading . in it then remove the dot. $options['name'] = preg_replace("/^\\./", '', $options['name']); // FIXME: MP Fix this to use a find_dns_record function ID only for now // Find the DNS record from $options['name'] list($status, $rows, $dns) = ona_find_dns_record($options['name'], $options['type']); printmsg("DEBUG => dns_record_del() DNS record: {$options['name']}", 3); if (!$dns['id']) { printmsg("DEBUG => Unknown DNS record: {$options['name']} ({$options['type']})", 3); $self['error'] = "ERROR => Unknown DNS record: {$options['name']} ({$options['type']})"; 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 = ""; // SUMMARY: // Display any associated PTR records for an A record // Display any associated CNAMEs for an A record // Test if it is used as a primary_dns_id unless it is the host_del module calling if (!isset($options['delete_by_module'])) { list($status, $rows, $srecord) = db_get_record($onadb, 'hosts', array('primary_dns_id' => $dns['id'])); if ($rows) { $self['error'] = "ERROR => dns_record_del() The DNS record, {$dns['name']}.{$dns['domain_fqdn']}[{$dns['id']}], is a primary A record for a host! You can not delete it until you associate a new primary record, or delete the host."; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } } // Delete related Points to records // get list for logging list($status, $rows, $records) = db_get_records($onadb, 'dns', array('dns_id' => $dns['id'])); // do the delete list($status, $rows) = db_delete_records($onadb, 'dns', array('dns_id' => $dns['id'])); if ($status) { $self['error'] = "ERROR => dns_record_del() Child record delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } if ($rows) { // log deletions // FIXME: do better logging here printmsg("INFO => {$rows} child DNS record(s) DELETED from {$dns['fqdn']}", 0); $add_to_error .= "INFO => {$rows} child record(s) DELETED from {$dns['fqdn']}\n"; } // TRIGGER: flag the domains for rebuild foreach ($records as $record) { list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $record['domain_id']), array('rebuild_flag' => 1)); if ($status) { $self['error'] = "ERROR => dns_record_del() Unable to update rebuild flags for domain.: {$self['error']}"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } } // Delete the DNS record list($status, $rows) = db_delete_records($onadb, 'dns', array('id' => $dns['id'])); if ($status) { $self['error'] = "ERROR => dns_record_del() DNS record delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $add_to_error . $self['error'] . "\n"); } // TRIGGER: flag the current dnsrecords domain for rebuild list($status, $rows) = db_update_record($onadb, 'dns_server_domains', array('domain_id' => $dns['domain_id']), array('rebuild_flag' => 1)); if ($status) { $self['error'] = "ERROR => dns_record_del() Unable to update rebuild flags for domain.: {$self['error']}"; printmsg($self['error'], 0); return array(7, $self['error'] . "\n"); } // FIXME: if it is a NS or something display a proper FQDN message here // Display proper PTR information if ($dns['type'] == 'PTR') { list($status, $rows, $pointsto) = ona_get_dns_record(array('id' => $dns['dns_id']), ''); list($status, $rows, $ptrint) = ona_get_interface_record(array('id' => $dns['interface_id']), ''); $ipflip = ip_mangle($ptrint['ip_addr'], 'flip'); $octets = explode(".", $ipflip); if (count($octets) > 4) { $arpa = '.ip6.arpa'; $octcount = 31; } else { $arpa = '.in-addr.arpa'; $octcount = 3; } $dns['fqdn'] = "{$ipflip}{$arpa} -> {$pointsto['fqdn']}"; } // Return the success notice $self['error'] = "INFO => DNS {$dns['type']} record DELETED: {$dns['fqdn']}"; printmsg($self['error'], 0); return array(0, $add_to_error . $self['error'] . "\n"); } // // We are just displaying records that would have been deleted // // SUMMARY: // Display any associated PTR records for an A record // Display any associated CNAMEs for an A record // 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"; // Test if it is used as a primary_dns_id list($status, $rows, $srecord) = db_get_record($onadb, 'hosts', array('primary_dns_id' => $dns['id'])); if ($rows) { $text .= "\nWARNING! This DNS record is a primary A record for a host\n"; } // Display the complete dns record list($status, $tmp) = dns_record_display("name={$dns['id']}&verbose=N"); $text .= "\n" . $tmp; // Display associated Child records list($status, $rows, $records) = db_get_records($onadb, 'dns', array('dns_id' => $dns['id'])); if ($rows) { $text .= "\nASSOCIATED POINTS-TO RECORDS ({$rows}):\n"; } foreach ($records as $record) { if ($record['type'] == 'NS') { $record['name'] = ''; } // FIXME:I could fix this but I'm lazy if ($record['type'] == 'PTR') { $record['name'] = '??'; } list($status, $rows, $domain) = ona_get_domain_record(array('id' => $record['domain_id']), ''); $text .= " {$record['type']}: {$record['name']}.{$domain['fqdn']} -> {$dns['fqdn']}\n"; } return array(7, $text); }
function ws_delete_configs($window_name, $form = '') { global $conf, $self, $onadb; global $images, $color, $style; // If the user supplied an array in a string, build the array and store it in $form $form = parse_options_string($form); // Load the host record list($status, $rows, $host) = ona_find_host($form['host_id']); if (!$host['id']) { array_pop($_SESSION['ona']['work_space']['history']); $html .= "<br><center><font color=\"red\"><b>Host doesn't exist!</b></font></center>"; $response = new xajaxResponse(); $response->addAssign("work_space_content", "innerHTML", $html); return $response->getXML(); } // Check permissions if (!(auth('host_config_admin') and authlvl($host['lvl']))) { $response = new xajaxResponse(); $response->addScript("alert('Permission denied!');"); return $response->getXML(); } // Load the config type list($status, $rows, $type) = ona_get_config_type_record(array('id' => $form['type_id'])); if ($status or !$rows) { $response = new xajaxResponse(); $response->addScript("alert('ERROR => Invalid config type!');"); return $response->getXML(); } // Delete the config text records that match // FIXME, this should probably use a module, but there isn't one! list($status, $rows) = db_delete_records($onadb, 'configurations', array('host_id' => $host['id'], 'configuration_type_id' => $type['id'])); if ($status or !$rows) { $response = new xajaxResponse(); $response->addScript("alert('Delete failed!');"); return $response->getXML(); } // Insert the new html into the window // Instantiate the xajaxResponse object $response = new xajaxResponse(); if ($form['js']) { $response->addScript($form['js']); } return $response->getXML(); }
function dhcp_server_del($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg("DEBUG => dhcp_server_del({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Sanitize options[commit] (default is yes) $options['commit'] = sanitize_YN($options['commit'], 'N'); // Return the usage summary if we need to if ($options['help'] or !($options['subnet'] and $options['server'])) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_server_del-v{$version} Removes a subnet record from a DHCP server Synopsis: dhcp_server_del [KEY=VALUE] ... Required: subnet=NAME or ID subnet name or ID server=NAME[.DOMAIN] or ID server name or ID Optional: commit=[Y|N] commit db transaction (no) Notes: DOMAIN will default to {$conf['dns_defaultdomain']} if not specified EOM ); } // Determine the entry itself exists list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); // Test to see that we were able to find the specified record if (!$subnet['id']) { printmsg("DEBUG => Unable to find the subnet record using {$options['subnet']}!", 3); $self['error'] = "ERROR => Unable to find the subnet record using {$options['subnet']}!"; return array(4, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_server_del(): Found subnet, {$subnet['name']}", 3); if ($options['server']) { // Determine the server is valid list($status, $rows, $host) = ona_find_host($options['server']); if (!$host['id']) { printmsg("DEBUG => The server ({$options['server']}) does not exist!", 3); $self['error'] = "ERROR => The server specified, {$options['server']}, does not exist!"; return array(2, $self['error'] . "\n"); } } //printmsg("DEBUG => dhcp_server_del(): Found server, {$host['FQDN']}", 3); // Test that this subnet is even assigned to the server list($status, $rows, $dhcpserver) = ona_get_dhcp_server_subnet_record(array('host_id' => $host['id'], 'subnet_id' => $subnet['id'])); if (!$rows) { printmsg("DEBUG => Unable to find {$subnet['name']} on server {$host['fqdn']}", 3); $self['error'] = "ERROR => Unable to find {$subnet['name']} on server {$host['fqdn']}"; return array(11, $self['error'] . "\n"); } // If "commit" is yes, delete the record if ($options['commit'] == 'Y') { // Check permissions if (!auth('advanced') or !authlvl($host['LVL']) or !authlvl($subnet['LVL'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // check if allowed to remove subnet from server // check for pool assigned to the server itself list($status, $rows, $pools) = db_get_records($onadb, 'dhcp_pools', array('subnet_id' => $subnet['id'])); foreach ($pools as $pool) { if ($pool['dhcp_failover_group_id']) { $foundfg = 0; list($status, $rows, $primary) = ona_get_dhcp_failover_group_record(array('id' => $pool['dhcp_failover_group_id'], 'primary_server_id' => $host['id'])); if ($rows) { $foundfg++; } list($status, $rows, $secondary) = ona_get_dhcp_failover_group_record(array('id' => $pool['dhcp_failover_group_id'], 'secondary_server_id' => $host['id'])); if ($rows) { $foundfg++; } // if a subnet/server pair is found in dhcp pools, don't allow removal if ($foundfg > 0) { printmsg("DEBUG => Subnet ({$subnet['name']}) has a pool assigned to this Server ({$host['fqdn']}), which is part of a failover group. The server must be removed from the failover group first.", 3); $self['error'] = "ERROR => Subnet ({$subnet['name']}) has a pool assigned to this Server ({$host['fqdn']}), which is part of a failover group. The server must be removed from the failover group first."; return array(12, $self['error'] . "\n"); } } } // MP: remove this after testing. dhcp options should not stop us from dis-associating a subnet from a server // Not really sure why I have this.. probably left over cruft from old thoughts // // check if there are any DHCP parameters assigned to the subnet // list($status, $rows, $tmp) = ona_get_dhcp_option_entry_record(array('subnet_id' => $subnet['id'])); // // // if so, check that this is not the last DHCP server that services this subnet // if ($rows > 0) { // list($status, $rows, $tmp) = ona_get_dhcp_server_subnet_record(array('subnet_id' => $subnet['id'])); // // // If this is the last DHCP server that services this subnet, don't allow removal until DHCP parameters are removed // if($rows <= 1){ // printmsg("DEBUG => Subnet ({$subnet['name']}) has DHCP parameters assigned which need to be removed first",3); // $self['error'] = "ERROR => Subnet ({$subnet['name']}) has DHCP parameters assigned which need to be removed first"; // return(array(12, $self['error'] . "\n")); // } // } // delete record from dhcp_server_subnets list($status, $rows) = db_delete_records($onadb, 'dhcp_server_subnets', array('id' => $dhcpserver['id'])); if ($status) { $self['error'] = "ERROR => dhcp_server_del() SQL Query failed:" . $self['error']; printmsg($self['error'], 0); return array(9, $self['error'] . "\n"); } // Return the success notice $self['error'] = "INFO => DHCP Subnet/Server Pair DELETED: {$subnet['name']}/{$host['fqdn']} "; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); } // Otherwise display the record that would have been deleted $text = <<<EOL Record(s) NOT DELETED (see "commit" option) Displaying record(s) that would have been removed: {$subnet['name']} from: {$host['fqdn']} EOL; return array(6, $text); }
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); }
function dhcp_pool_modify($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.03'; printmsg("DEBUG => dhcp_pool_modify({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['pool'] and ($options['set_failover_group'] or $options['set_start'] or $options['set_end'] or $options['set_llength'] or $options['set_lgrace'] or $options['set_lrenewal'] or $options['set_lrebind']))) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_pool_modify-v{$version} Updates a dhcp pool in the database pointing to the specified identifier Synopsis: dhcp_pool_modify [KEY=VALUE] ... Where: pool=ID Table ID for the pool Optional: set_failover_group=ID group identifier set_server=NAME[.DOMAIN] or ID server identifier set_start=IP Start ip address of pool set_end=IP End IP of pool set_llength=NUMBER Lease Time. Default ({$conf['dhcp_pool']['llength']}) set_lgrace=NUMBER Lease Grace Period. Default ({$conf['dhcp_pool']['lgrace']}) set_lrenewal=NUMBER Lease Renewal. Default ({$conf['dhcp_pool']['lrenewal']}) set_lrebind=NUMBER Lease Rebind. Default ({$conf['dhcp_pool']['lrebind']}) EOM ); } // get the existing pool to edit list($status, $rows, $pool) = db_get_record($onadb, 'dhcp_pools', array('id' => $options['pool'])); if (!$rows) { printmsg("DEBUG => Unable to find the DHCP pool record using id: {$options['id']}!", 3); $self['error'] = "ERROR => Unable to find a pool using id: {$options['pool']}"; return array(1, $self['error'] . "\n"); } // set the pool id in the set variable $SET['id'] = $pool['id']; // NOTE: currently modify pool does not allow you to change subnets // Get subnet info.. list($status, $rows, $subnet) = ona_find_subnet($pool['subnet_id']); $SET['subnet_id'] = $subnet['id']; // make sure that the start address is actually part of an existing subnet if ($options['set_start']) { list($status, $rows, $subnetstart) = ona_find_subnet(ip_mangle($options['set_start'], 'dotted')); if (!$rows) { printmsg("DEBUG => Unable to find a subnet related to starting address ({$options['set_start']})!", 3); $self['error'] = "ERROR => Unable to find a subnet related to your starting address of {$options['set_start']}."; return array(1, $self['error'] . "\n"); } if ($subnetstart['id'] != $pool['subnet_id']) { printmsg("DEBUG => The starting address ({$options['set_start']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!", 3); $self['error'] = "ERROR => The starting address ({$options['set_start']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!"; return array(1, $self['error'] . "\n"); } } // make sure that the end address is actually part of an existing subnet if ($options['set_end']) { list($status, $rows, $subnetend) = ona_find_subnet(ip_mangle($options['set_end'], 'dotted')); if (!$rows) { printmsg("DEBUG => Unable to find a subnet related to ending address ({$options['set_end']})!", 3); $self['error'] = "ERROR => Unable to find a subnet related to your ending address of {$options['set_end']}."; return array(1, $self['error'] . "\n"); } if ($subnetend['id'] != $pool['subnet_id']) { printmsg("DEBUG => The ending address ({$options['set_end']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!", 3); $self['error'] = "ERROR => The ending address ({$options['set_end']}) is not on the same subnet of the pool ({$pool['id']}) you are editing!"; return array(1, $self['error'] . "\n"); } } // Assign which failover group to use if ($options['set_failover_group'] == 0) { $desc = 'Not using a failover group'; $SET['dhcp_failover_group_id'] = 0; } else { list($status, $rows, $fg) = ona_get_dhcp_failover_group_record(array('id' => $options['set_failover_group'])); if (!$fg['id']) { printmsg("DEBUG => The failover_group specified ({$options['set_failover_group']}) does not exist", 3); $self['error'] = "ERROR => The failover_group specified ({$options['set_failover_group']}) does not exist!"; return array(4, $self['error'] . "\n"); } // get the server names for the two servers list($fail_host1, $fail_zone1) = ona_find_host($fg['primary_server_id']); list($fail_host2, $fail_zone2) = ona_find_host($fg['secondary_server_id']); $desc = $fail_host1['fqdn'] . '/' . $fail_host2['fqdn']; $SET['dhcp_failover_group_id'] = $fg['id']; } // check that start and end are not the same //if ($options['set_start'] and $options['set_end'] and $options['set_start'] == $options['set_end']) { // printmsg("DEBUG => The start and end IP addresses (" . ip_mangle($options['set_start'],'dotted') . ") cannot be the same!",3); // $self['error'] = "ERROR => The start and end IP addresses (" . ip_mangle($options['set_start'],'dotted') . ") cannot be the same!"; // return(array(2, $self['error'] . "\n")); //} if ($options['set_start']) { $start_dec = ip_mangle($options['set_start'], 'numeric'); } else { $start_dec = $pool['ip_addr_start']; } if ($options['set_end']) { $end_dec = ip_mangle($options['set_end'], 'numeric'); } else { $end_dec = $pool['ip_addr_end']; } $net_end = 4294967295 - $subnet['ip_mask'] + $subnet['ip_addr']; // Validate that the IP address supplied isn't the base or broadcast of the subnet if ($start_dec == $subnet['ip_addr'] or $end_dec == $subnet['ip_addr']) { printmsg("DEBUG => IP address can't be a subnet's base address (" . ip_mangle($subnet['ip_addr'], 'dotted') . ")!", 3); $self['error'] = "ERROR => IP address can't be a subnet's base address (" . ip_mangle($subnet['ip_addr'], 'dotted') . ")!"; return array(7, $self['error'] . "\n"); } if ($start_dec == $net_end or $end_dec == $net_end) { printmsg("DEBUG => IP address can't be a subnet's broadcast address (" . ip_mangle($net_end, 'dotted') . ")!", 3); $self['error'] = "ERROR => IP address can't be the subnet broadcast address(" . ip_mangle($net_end, 'dotted') . ")!"; return array(8, $self['error'] . "\n"); } // check that start is not after the end if ($start_dec > $end_dec) { printmsg("DEBUG => The start IP addresses (" . ip_mangle($start_dec, 'dotted') . ") falls after the end IP address (" . ip_mangle($end_dec, 'dotted') . ")!", 3); $self['error'] = "ERROR => The start IP addresses (" . ip_mangle($start_dec, 'dotted') . ") falls after the end IP address(" . ip_mangle($end_dec, 'dotted') . ")!"; return array(2, $self['error'] . "\n"); } // check for existing hosts inside the pool range list($status, $rows, $interface) = db_get_records($onadb, 'interfaces', 'subnet_id = ' . $subnet['id'] . ' AND ip_addr BETWEEN ' . $start_dec . ' AND ' . $end_dec, '', 0); if ($rows) { printmsg("DEBUG => IP conflict: Specified range (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") encompasses {$rows} host(s)!", 3); $self['error'] = "ERROR => IP conflict: Specified range (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") encompasses {$rows} host(s)"; return array(4, $self['error'] . "\n"); } // *** Check to see if the new pool overlaps any existing pools *** // // Look for overlaps like this (where new pool address starts inside an existing pool): // [ -- new pool -- ] // [ -- old pool --] list($status, $rows, $tmp) = db_get_record($onadb, 'dhcp_pools', 'id != ' . $SET['id'] . ' AND ' . $start_dec . ' BETWEEN ip_addr_start AND ip_addr_end'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict: New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") starts inside an existing pool!", 3); $self['error'] = "ERROR => Pool address conflict! New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") starts inside an existing pool."; return array(5, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$tmp['id']}\n"); } // Look for overlaps like this (where the new pool ends inside an existing pool): // [ -- new pool -- ] // [ -- old pool --] list($status, $rows, $tmp) = db_get_record($onadb, 'dhcp_pools', 'id != ' . $SET['id'] . ' AND ' . $end_dec . ' BETWEEN ip_addr_start AND ip_addr_end'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict: New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") ends inside an existing pool!", 3); $self['error'] = "ERROR => Pool address conflict! New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") ends inside an existing pool."; return array(6, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$tmp['id']}\n"); } // Look for overlaps like this (where the new pool entirely overlaps an existing pool): // [ -------- new pool --------- ] // [ -- old pool --] list($status, $rows, $tmp) = db_get_record($onadb, 'dhcp_pools', 'id != ' . $SET['id'] . ' AND (ip_addr_start BETWEEN ' . $start_dec . ' AND ' . $end_dec . ' OR ip_addr_end BETWEEN ' . $start_dec . ' AND ' . $end_dec . ')'); if ($rows != 0) { printmsg("DEBUG => Pool address conflict: New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") would encompass an existing pool!", 3); $self['error'] = "ERROR => Pool address conflict! New pool (" . ip_mangle($start_dec, 'dotted') . "-" . ip_mangle($end_dec, 'dotted') . ") would encompass an existing pool."; return array(7, $self['error'] . "\n" . "INFO => Conflicting pool record ID: {$tmp['id']}\n"); } // Check permissions if (!auth('advanced') or !authlvl($subnet['lvl'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(8, $self['error'] . "\n"); } // define the remaining entries if (array_key_exists('set_lgrace', $options)) { $SET['lease_grace_period'] = $options['set_lgrace']; } if (array_key_exists('set_llength', $options)) { $SET['lease_length'] = $options['set_llength']; } if (array_key_exists('set_lrenewal', $options)) { $SET['lease_renewal_time'] = $options['set_lrenewal']; } if (array_key_exists('set_lrebind', $options)) { $SET['lease_rebind_time'] = $options['set_lrebind']; } // Set the IPs if you got this far $SET['ip_addr_start'] = $start_dec; $SET['ip_addr_end'] = $end_dec; // Get the DHCP pool record before updating (logging) list($status, $rows, $original_pool) = ona_get_dhcp_pool_record(array('id' => $SET['id'])); // Update the record list($status, $rows) = db_update_record($onadb, 'dhcp_pools', array('id' => $SET['id']), $SET); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_pool_modify() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $add_to_error . $self['error'] . "\n"); } $success_start = ip_mangle($SET['ip_addr_start'], 'dotted'); $success_end = ip_mangle($SET['ip_addr_end'], 'dotted'); // Get the DHCP pool record after updating (logging) list($status, $rows, $new_pool) = ona_get_dhcp_pool_record(array('id' => $SET['id'])); // Return the success notice $self['error'] = "INFO => DHCP pool UPDATED:{$original_pool['id']}: {$success_start}-{$success_end} on {$subnet['name']}."; $log_msg = "INFO => DHCP pool UPDATED:{$original_pool['id']}: "; $more = ""; foreach (array_keys($original_pool) as $key) { if ($original_pool[$key] != $new_pool[$key]) { $log_msg .= $more . $key . "[" . $original_pool[$key] . "=>" . $new_pool[$key] . "]"; $more = ";"; } } // only print to logfile if a change has been made to the record if ($more != '') { printmsg($self['error'], 0); printmsg($log_msg, 0); } return array(0, $add_to_error . $self['error'] . "\n"); }
function subnet_del($options = "") { global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.06'; printmsg('DEBUG => subnet_del(' . $options . ') called', 3); // 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['subnet']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM subnet_del-v{$version} Deletes a subnet (subnet) from the database Synopsis: subnet_del [KEY=VALUE] ... Required: subnet=IP or ID select subnet by search string Optional: commit=[yes|no] commit db transaction (no) EOM ); } // Find the subnet record we're deleting list($status, $rows, $subnet) = ona_find_subnet($options['subnet']); if ($status or !$rows) { $self['error'] = "ERROR => Subnet not found"; return array(2, $self['error'] . "\n"); } // Check permissions if (!auth('subnet_del') or !authlvl($subnet['lvl'])) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(3, $self['error'] . "\n"); } // If "commit" is yes, delete the subnet if ($options['commit'] == 'Y') { $text = ""; // FIXME: (add all this) ... // SUMMARY: // Delete assignments to any DHCP servers // Delete any DHCP pools on the current subnet // Delete any DHCP options associated with this subnet // Delete any interfaces belonging to hosts with more than one interface // Delete any hosts (and all their associated info) that have only one interface // Delete subnet Record // Delete custom attributes // // FIXME: display a warning if there are no more subnets that a dhcp server is serving dhcp for? // Delete DHCP server assignments list($status, $rows) = db_delete_records($onadb, 'dhcp_server_subnets', array('subnet_id' => $subnet['id'])); if ($status) { $self['error'] = "ERROR => DHCP server assignment delete failed: {$self['error']}"; return array(5, $self['error'] . "\n"); } // Delete DHCP pools list($status, $rows) = db_delete_records($onadb, 'dhcp_pools', array('subnet_id' => $subnet['id'])); if ($status) { $self['error'] = "ERROR => DHCP pool delete failed: {$self['error']}"; return array(5, $self['error'] . "\n"); } // Delete DHCP options list($status, $rows) = db_delete_records($onadb, 'dhcp_option_entries', array('subnet_id' => $subnet['id'])); if ($status) { $self['error'] = "ERROR => DHCP parameter delete failed: {$self['error']}"; return array(5, $self['error'] . "\n"); } // Delete tag entries list($status, $rows, $records) = db_get_records($onadb, 'tags', array('type' => 'subnet', 'reference' => $subnet['id'])); $log = array(); $i = 0; foreach ($records as $record) { $log[$i] = "INFO => Tag DELETED: {$record['name']} from {$subnet['name']}"; $i++; } //do the delete list($status, $rows) = db_delete_records($onadb, 'tags', array('type' => 'subnet', 'reference' => $subnet['id'])); if ($status) { $self['error'] = "ERROR => subnet_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' => 'subnets', 'table_id_ref' => $subnet['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 {$subnet['name']}"; $i++; } //do the delete list($status, $rows) = db_delete_records($onadb, 'custom_attributes', array('table_name_ref' => 'subnets', 'table_id_ref' => $subnet['id'])); if ($status) { $self['error'] = "ERROR => subnet_del() Custom attribute delete SQL Query failed: {$self['error']}"; printmsg($self['error'], 0); return array(5, $self['error'] . "\n"); } //log deletions foreach ($log as $log_msg) { printmsg($log_msg, 0); //$add_to_error .= $log_msg . "\n"; } // Delete associated host / interface records that need to be deleted // BUSINESS RULE: We delete hosts that have only one interface (and it's on this subnet) // BUSINESS RULE: We delete interfaces from hosts that have multiple interfaces list($status, $rows, $interfaces) = db_get_records($onadb, 'interfaces', array('subnet_id' => $subnet['id'])); $hosts_to_delete = array(); $interfaces_to_delete = array(); foreach ($interfaces as $interface) { // Select all interfaces for the associated host where the subnet ID is not our subnet ID $where = "host_id = {$interface['host_id']} AND subnet_id != {$subnet['id']}"; list($status, $rows, $tmp) = db_get_records($onadb, 'interfaces', $where, '', 0); // We'll delete hosts that have only one interface (i.e. no interfaces on any other subnets) if ($rows == 0) { array_push($hosts_to_delete, $interface['host_id']); } else { array_push($interfaces_to_delete, $interface['id']); } } unset($interfaces); // make sure we only have one reference for each host and interface $interfaces_to_delete = array_unique($interfaces_to_delete); $hosts_to_delete = array_unique($hosts_to_delete); // Delete interfaces we have selected foreach ($interfaces_to_delete as $interface_id) { list($status, $output) = run_module('interface_del', array('interface' => $interface_id, 'commit' => 'Y')); if ($status) { return array(5, $output); } } // Delete hosts we have selected foreach ($hosts_to_delete as $host_id) { list($status, $output) = run_module('host_del', array('host' => $host_id, 'commit' => 'Y')); if ($status) { return array(5, $output); } } // Delete the subnet list($status, $rows) = db_delete_records($onadb, 'subnets', array('id' => $subnet['id'])); if ($status or !$rows) { $self['error'] = "ERROR => Subnet delete failed: {$self['error']}"; return array(5, $self['error'] . "\n"); } // Return the success notice $ip = ip_mangle($subnet['ip_addr'], 'dotted'); $cidr = ip_mangle($subnet['ip_mask'], 'cidr'); $self['error'] = "INFO => Subnet DELETED: {$subnet['name']} IP: {$ip}/{$cidr}"; printmsg($self['error'], 0); return array(0, $self['error'] . "\n"); } // // We are just displaying records that would have been deleted // // SUMMARY: // Display assignments to any DHCP servers // Display any DHCP pools on the current subnet // Display any DHCP parameters associated with this subnet // Display subnet Record // Display Host records (and all their sub-records) // Display custom attributes // 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 the Subnet's complete record list($status, $tmp) = subnet_display("subnet={$subnet['id']}&verbose=N"); $text .= "\n" . $tmp; // Display assignments to any DHCP servers list($status, $rows, $records) = db_get_records($onadb, 'dhcp_server_subnets', array('subnet_id' => $subnet['id'])); if ($rows) { $text .= "\nASSOCIATED DHCP SERVER ASSIGNMENT RECORDS ({$rows}):\n"; } foreach ($records as $record) { $text .= format_array($record); } // Display any DHCP pools on the current subnet list($status, $rows, $records) = db_get_records($onadb, 'dhcp_pools', array('subnet_id' => $subnet['id'])); if ($rows) { $text .= "\nASSOCIATED DHCP POOL RECORDS ({$rows}):\n"; } foreach ($records as $record) { $text .= format_array($record); } // Display associated DHCP entries list($status, $rows, $records) = db_get_records($onadb, 'dhcp_option_entries', array('subnet_id' => $subnet['id'])); if ($rows) { $text .= "\nASSOCIATED DHCP ENTRY 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"; } // Display associated tags list($status, $rows, $records) = db_get_records($onadb, 'tags', array('type' => 'subnet', 'reference' => $subnet['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' => 'subnets', 'table_id_ref' => $subnet['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 host / interface records that would be deleted // BUSINESS RULE: We delete hosts that have only one interface (and it's on this subnet) // BUSINESS RULE: We delete interfaces from hosts that have multiple interfaces (including at least one on a different subnet) list($status, $rows, $interfaces) = db_get_records($onadb, 'interfaces', array('subnet_id' => $subnet['id'])); $hosts_to_delete = array(); $interfaces_to_delete = array(); foreach ($interfaces as $interface) { // Select all interfaces for the associated host where the subnet ID is not our subnet ID $where = "host_id = {$interface['host_id']} AND subnet_id != {$subnet['id']}"; list($status, $rows, $tmp) = db_get_records($onadb, 'interfaces', $where, '', 0); // We'll delete hosts that have only one interface (i.e. no interfaces on any other subnets) if ($rows == 0) { array_push($hosts_to_delete, $interface['host_id']); } else { array_push($interfaces_to_delete, $interface['id']); } } unset($interfaces); // make sure we only have one reference for each host and interface $interfaces_to_delete = array_unique($interfaces_to_delete); $hosts_to_delete = array_unique($hosts_to_delete); // Display interfaces we would have deleted $rows = count($interfaces_to_delete); if ($rows) { $text .= "\n----- ASSOCIATED HOST INTERFACE RECORDS ({$rows}) -----\n"; } foreach ($interfaces_to_delete as $interface_id) { list($status, $output) = run_module('interface_del', array('interface' => $interface_id), false); $output = preg_replace('/^(.*)?\\n(.*)?\\n/', '', $output); $text .= $output; } // Display hosts we would have deleted $rows = count($hosts_to_delete); if ($rows) { $text .= "\n-----ASSOCIATED HOSTS ({$rows}) -----\n"; } foreach ($hosts_to_delete as $host_id) { list($status, $output) = run_module('host_del', array('host' => $host_id), false); $output = preg_replace('/^(.*)?\\n(.*)?\\n/', '', $output); $text .= $output; } return array(7, $text); }
function dhcp_entry_modify($options = "") { // The important globals global $conf, $self, $onadb; // Version - UPDATE on every edit! $version = '1.04'; printmsg("DEBUG => dhcp_entry_modify({$options}) called", 3); // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !($options['id'] and ($options['set_option'] and array_key_exists('set_value', $options) or array_key_exists('set_value', $options)))) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM dhcp_entry_modify-v{$version} Modifies a DHCP entry in the database Synopsis: dhcp_entry_modify [KEY=VALUE] ... Where: id=ID DHCP entry ID Options: set_option=DHCP type DHCP parameter type set_value=STRING string value for the DHCP type Notes: If you specify a type, you must specify a value. EOM ); } // Determine the entry itself exists list($status, $rows, $entry) = ona_get_dhcp_option_entry_record(array('id' => $options['id'])); if ($status or !$rows) { printmsg("DEBUG => Invalid DHCP entry record ID ({$options['id']})!", 3); $self['error'] = "ERROR => Invalid DHCP entry record ID ({$options['id']})!"; return array(2, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_entry_modify(): Found entry, {$entry['display_name']} => {$entry['value']}", 3); $desc = ''; // Load associated host, subnet or server record $host = $subnet = $server = array(); if ($entry['host_id']) { list($status, $rows, $host) = ona_find_host($entry['host_id']); $desc = $host['fqdn']; } if ($entry['subnet_id']) { list($status, $rows, $subnet) = ona_find_subnet($entry['subnet_id']); $desc = "{$subnet['name']} (" . ip_mangle($subnet['ip_addr']) . ")"; } if ($entry['server_id']) { list($status, $rows, $server) = ona_find_host($entry['server_id']); $desc = $server['fqdn']; } // Check permissions on source identifier $lvl = 100; if ($host['id']) { $lvl = $host['lvl']; } if ($subnet['id']) { $lvl = $subnet['lvl']; } if (!auth('advanced') or !authlvl($lvl)) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(10, $self['error'] . "\n"); } // unset $host if $server is defined .. we don't need it anymore if ($server['id']) { $host = array(); } // This variable will contain the updated info we'll insert into the DB $SET = array(); if (array_key_exists('set_value', $options)) { // trim leading and trailing whitespace from 'value' $SET['value'] = trim($options['set_value']); // trim leading and trailing whitespace from 'value' and check that a value exists $SET['value'] = trim($options['set_value']); if (strlen($SET['value']) == 0) { printmsg("DEBUG => The DHCP value was blank", 3); $self['error'] = "ERROR => DHCP value was blank"; return array(2, $self['error'] . "\n"); } } if ($options['set_option']) { // Make sure they specified a value if (!array_key_exists('set_value', $options)) { printmsg("DEBUG => No value specified for given DHCP parameter type ({$options['set_option']})!", 3); $self['error'] = "ERROR => No value specified for given DHCP parameter type ({$options['set_option']})!"; return array(8, $self['error'] . "\n"); } // Determine the type is valid list($status, $rows, $type) = ona_find_dhcp_option(trim($options['set_option'])); if ($status or !$rows) { printmsg("DEBUG => Invalid DHCP parameter type specified ({$options['set_option']})!", 3); $self['error'] = "ERROR => Invalid DHCP parameter type specified ({$options['set_option']})!"; return array(8, $self['error'] . "\n"); } printmsg("DEBUG => dhcp_entry_modify(): Found parameter type {$type['display_name']}", 3); $SET['dhcp_option_id'] = $type['id']; // Make sure this isn't a duplicate // TODO: this code seems a bit suspect of being nasty.. possibly fix it up $search = array('dhcp_option_id' => $type['id'], 'host_id' => 0, 'subnet_id' => 0); if ($host['id']) { $search['host_id'] = $host['id']; } if ($subnet['id']) { $search['subnet_id'] = $subnet['id']; } if ($server['id']) { $search['server_id'] = $server['id']; } list($status, $rows, $record) = ona_get_dhcp_option_entry_record($search); if ($status or $rows > 1 or $rows == 1 and $record['id'] != $entry['id']) { printmsg("DEBUG => That DHCP parameter type is already defined ({$search})!", 3); $self['error'] = "ERROR => That DHCP parameter type is already defined ({$search})!"; return array(11, $self['error'] . "\n"); } } // Get the dhcp entry record before updating (logging) list($status, $rows, $original_entry) = ona_get_dhcp_option_entry_record(array('id' => $entry['id'])); // Update the record list($status, $rows) = db_update_record($onadb, 'dhcp_option_entries', array('id' => $entry['id']), $SET); if ($status or !$rows) { $self['error'] = "ERROR => dhcp_entry_modify() SQL Query failed: " . $self['error']; printmsg($self['error'], 0); return array(6, $self['error'] . "\n"); } // Get the entry again to display details list($status, $tmp_rows, $entry) = ona_get_dhcp_option_entry_record(array('id' => $entry['id'])); // Return the success notice $self['error'] = "INFO => DHCP entry UPDATED:{$entry['id']}: \"{$entry['display_name']}\"={$entry['value']} on {$desc} "; $log_msg = "INFO => DHCP entry UPDATED:{$entry['id']}: "; $more = ""; foreach (array_keys($original_entry) as $key) { if ($original_entry[$key] != $entry[$key]) { $log_msg .= $more . $key . "[" . $original_entry[$key] . "=>" . $entry[$key] . "]"; $more = ";"; } } // only print to logfile if a change has been made to the record if ($more != '') { printmsg($self['error'], 0); printmsg($log_msg, 0); } return array(0, $self['error'] . "\n"); }
function interface_move($options = "") { global $conf, $self, $onadb; printmsg("DEBUG => interface_move({$options}) called", 3); // Version - UPDATE on every edit! $version = '1.04'; // Parse incoming options string to an array $options = parse_options($options); // Return the usage summary if we need to if ($options['help'] or !$options['start'] or !$options['new_start']) { // NOTE: Help message lines should not exceed 80 characters for proper display on a console $self['error'] = 'ERROR => Insufficient parameters'; return array(1, <<<EOM interface_move-v{$version} Moves all interface addresses from one subnet to another. The initial range of IPs does not have to be consecutive. The new range of IPs will be used sequentially. Synopsis: interface_move [KEY=VALUE] ... IP block to move: (source) start=IP first IP to move [end=IP] last IP to move New IP block: (destination) new_start=IP first new IP address [new_end=IP] last new IP address Optional: commit=[yes|no] commit db transaction (no) EOM ); } // Set options[force] and options[create_a] to N if it's not set $options['commit'] = sanitize_YN($options['commit'], 'N'); // Find the "start" subnet record by IP address list($status, $rows, $old_subnet) = ona_find_subnet($options['start']); if (!$old_subnet or !$old_subnet['id']) { printmsg("DEBUG => Source start address ({$options['start']}) isn't valid!", 3); $self['error'] = "ERROR => Source (start) address specified isn't valid!"; return array(2, $self['error'] . "\n"); } // If they specified an "END" address, make sure it's valid and on the same subnet if ($options['end']) { // Find an interface record by something in that interface's record list($status, $rows, $old_subnet_end) = ona_find_subnet($options['end']); // If we didn't get a record then exit if (!$old_subnet_end or !$old_subnet_end['id']) { printmsg("DEBUG => Source end address ({$options['end']}) isn't valid!", 3); $self['error'] = "ERROR => Source (end) address specified isn't valid!"; return array(3, $self['error'] . "\n"); } if ($old_subnet_end['id'] != $old_subnet['id']) { printmsg("DEBUG => Both source addresses ({$options['start']} and {$options['end']}) must be on the same subnet!", 3); $self['error'] = "ERROR => Both the source addresses (start and end) must be on the same subnet!"; return array(4, $self['error'] . "\n"); } } else { printmsg("DEBUG => Only moving one host source={$options['start']}!", 3); $options['end'] = $options['start']; } // Find the "end" subnet record by IP address list($status, $rows, $new_subnet) = ona_find_subnet($options['new_start']); // If we didn't get a record then exit if (!$new_subnet or !$new_subnet['id']) { printmsg("DEBUG => Destination start address ({$options['new_start']}) isn't valid!", 3); $self['error'] = "ERROR => Destination (new_start) address specified isn't valid!"; return array(2, $self['error'] . "\n"); } // Make sure the "old" and "new" subnets are different subnets if ($old_subnet['id'] == $new_subnet['id']) { printmsg("DEBUG => Both the source IP range ({$options['start']}+) and the destination IP range ({$options['new_start']}+) are on the same subnet!", 3); $self['error'] = "ERROR => Both the source IP range and the destination IP range are on the same subnet!"; return array(2, $self['error'] . "\n"); } // If they specified a "new_end" address, make sure it's valid and on the same subnet as the new_start subnet if ($options['new_end']) { // Find an interface record by something in that interface's record list($status, $rows, $new_subnet_end) = ona_find_subnet($options['new_end']); // If we didn't get a record then exit if (!$new_subnet_end or !$new_subnet_end['id']) { printmsg("DEBUG => Destination end address ({$options['new_end']}) isn't valid!", 3); $self['error'] = "ERROR => Destination (new_end) address specified isn't valid!"; return array(3, $self['error'] . "\n"); } if ($new_subnet_end['id'] != $new_subnet['id']) { printmsg("DEBUG => Both destination addresses ({$options['new_start']} and {$options['new_end']}) must be on the same subnet!", 3); $self['error'] = "ERROR => Both the destination addresses (new_start and new_end) must be on the same subnet!"; return array(4, $self['error'] . "\n"); } } else { printmsg("DEBUG => Only moving one host destination={$options['new_start']}!", 3); $options['new_end'] = $options['new_start']; } // Check permissions at the subnet level if (!auth('interface_modify')) { $self['error'] = "Permission denied!"; printmsg($self['error'], 0); return array(13, $self['error'] . "\n"); } // An array for all the interface records we'll be moving $to_move = array(); // Message to display if we succeed $message = ""; // Load all the interface records we'll be moving $i = 0; do { // FIXME: this should do a more advanced query someday! (like checking that the ipaddress is >= start and <= end list($status, $rows, $interface) = ona_get_interface_record(array('subnet_id' => $old_subnet['id']), 'ip_addr'); if ($rows == 0) { break; } $i++; if ($interface['ip_addr'] >= ip_mangle($options['start'], 'numeric')) { if ($interface['ip_addr'] <= ip_mangle($options['end'], 'numeric')) { $to_move[$i] = $interface; } } } while ($i < $rows); $total_to_move = count($to_move); $total_assigned = 0; // If there's nothing to do, tell them if ($total_to_move == 0) { printmsg("DEBUG => There are no interfaces in the source address block!", 3); $self['error'] = "ERROR => There are no interfaces in the source address block!"; return array(6, $self['error'] . "\n"); } // Make sure we have a high enough "LVL" to modify the associated hosts foreach ($to_move as $interface) { // Load the associated host record list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); list($status, $rows, $dns) = ona_get_dns_record(array('id' => $host['primary_dns_id'], 'type' => 'A')); // Check permissions at the subnet level if (!authlvl($host['LVL'])) { $self['error'] = "Permission denied! Can't modify Host: {$host['id']} {$dns['fqdn']}"; printmsg($self['error'], 0); return array(14, $self['error'] . "\n"); } // Check to see if the host has any interfaces in the destination subnet // MP: this is now allowed // list($status, $rows, $interface) = ona_get_interface_record(array('host_id' => $interface['host_id'], 'subnet_id' => $new_subnet['id'])); // if ($status or $rows) { // printmsg("DEBUG => Source host {$ddns['fqdn']} already has an interface on the destination subnet!",3); // $self['error'] = "ERROR => Source host {$dns['fqdn']} (ID {$host['id']}) already has an interface on the destination subnet!"; // return(array(15, $self['error'] . "\n")); // } } // Get the numeric version of the start/end addresses we are moving interfaces to // .. and make sure that the $low_ip and $high_ip are not subnet or broadcast addresses! $low_ip = ip_mangle($options['new_start'], 'numeric'); $high_ip = ip_mangle($options['new_end'], 'numeric'); if ($low_ip == $new_subnet['ip_addr']) { $low_ip++; } $num_hosts = 0xffffffff - $new_subnet['ip_mask']; if ($high_ip == $new_subnet['ip_addr'] + $num_hosts) { $high_ip--; } printmsg("INFO => Asked to move {$total_to_move} interfaces to new range: " . ip_mangle($low_ip, 'dotted') . ' - ' . ip_mangle($high_ip, 'dotted'), 0); // Loop through each interface we need to move, and find an available address for it. $pool_interfering = 0; foreach (array_keys($to_move) as $i) { while ($low_ip <= $high_ip) { list($status, $rows, $interface) = ona_get_interface_record(array('ip_addr' => $low_ip)); if ($rows == 0 and $status == 0) { // Since the IP seems available, let's double check and make sure it's not in a DHCP address pool list($status, $rows, $pool) = ona_get_dhcp_pool_record("ip_addr_start < '{$low_ip}' AND ip_addr_end > '{$low_ip}'"); if ($rows == 0 and $status == 0) { // The IP is available, lets use it! $to_move[$i]['new_ip_address'] = $low_ip; $total_assigned++; $low_ip++; break; } $pool_interfering = 1; printmsg("DEBUG => Couldn't use the DHCP POOL address: " . ip_mangle($low_ip, 'dotted'), 3); } $low_ip++; } } // If total_assigned != total_to_move, error - not enough free IP addresses in destination subnet! if ($total_assigned != $total_to_move) { printmsg("DEBUG => The destination IP range doesn't have enough free IP addresses!", 3); $self['error'] = "ERROR => The destination IP range doesn't have enough free IP addresses!\n"; if ($pool_interfering) { $self['error'] .= "INFO => Some IPs in the destination range were part of a DHCP pool range.\n"; } return array(6, $self['error']); } // Display what we would have done if "commit" isn't "yes" if ($options['commit'] != "Y") { $self['error'] = "Interface(s) NOT MOVED (see \"commit\" option)"; $text = $self['error'] . "\n" . "Displaying {$total_to_move} interface(s) that would have been moved:\n\n"; foreach ($to_move as $interface) { // Get display the hostname we would have moved, as well as it's IP address. list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); list($status, $rows, $dns) = ona_get_dns_record(array('id' => $host['primary_dns_id'], 'type' => 'A')); $hostname = strtolower("{$dns['fqdn']}"); $text .= " " . ip_mangle($interface['ip_addr'], 'dotted') . " -> " . ip_mangle($interface['new_ip_address'], 'dotted') . "\t({$hostname})\n"; } $text .= "\n"; return array(7, $text); } // Loop through and update each interface's IP_ADDRESS and SUBNET_ID $text = "SUCCESS => {$total_to_move} interface(s) moved\n"; $text .= "Interface(s) moved:\n\n"; foreach ($to_move as $interface) { list($status, $rows) = ona_update_record("interfaces", array('id' => $interface['id']), array('ip_addr' => $interface['new_ip_address'], 'subnet_id' => $new_subnet['id'])); if ($status != 0 or $rows != 1) { $self['error'] = "ERROR => Database update failed! {$self['error']}"; return array(8, $self['error'] . "\n"); } // Get display the hostname we would have moved, as well as its IP address. list($status, $rows, $host) = ona_get_host_record(array('id' => $interface['host_id'])); list($status, $rows, $dns) = ona_get_dns_record(array('id' => $host['primary_dns_id'], 'type' => 'A')); $hostname = strtolower("{$dns['fqdn']}"); $text .= " " . ip_mangle($interface['ip_addr'], 'dotted') . " -> " . ip_mangle($interface['new_ip_address'], 'dotted') . "\t({$hostname})\n"; } // Return the success notice return array(0, $text); }