Re: dnsEditor [was: DLZ Web Management Interface]
"Michael J. Ayers" <[email protected]>
| Newsgroups | gmane.network.dns.bind9.dlz |
|---|---|
| Message-ID | <[email protected]> |
Lokkju Brennr wrote: > Micheal, that would be much appreciated, especially if you were to do > it in the form of a patch to the svn check out - but even just files > would be accepted! > > Thanks > > Lokkju > > On Tue, Apr 8, 2008 at 2:09 PM, Michael J. Ayers <[email protected]> wrote: > >> I have made some modifications to your interface to support reverse zones >> and custom per entry TTL's. I can forward all this stuff to you if you >> would like. >> >> Michael >> >> >> >> On Thu, Feb 14, 2008 at 10:33 AM, Lokkju Brennr <[email protected]> wrote: >> >> >>> >>> Well, I know it has a long way to go - we manage about 900 domains >>> with it on a daily basis, and it was written specifically to fill a >>> need in our infrastructure. >>> My plan is to eventually rebuild it in django, but there a few things >>> I really want to have solved: >>> - I need some sort of user defined queries/views for CRUD to the >>> database, so the end user can use their own database format - one >>> option is to just require that some stored procedures exist, and use >>> those (obviously, this includes the ability to connect to multiple >>> backends). >>> - subdomains as separate records needs to be supported >>> - per domain/per records access control and authentication needs to be >>> implemented >>> - more/custom record types. the main records types are supported, >>> including TXT, but some people need more, and sometimes need custom or >>> unique record types >>> >>> and then, as you pointed out, an ajax search/paging or zones would be >>> necessary for any large amount of zones. >>> >>> I am interested in developing it further, but just don't have much >>> incentive to right now, as it *works*, and it is at the point that it >>> covers all of our DNS management needs. Not to mention, I always have >>> way to many projects going, so... >>> >>> Lokkju >>> >>> >>> >>> >>> >>> >>> >>> On Thu, Feb 14, 2008 at 12:44 AM, Jan-Piet Mens <[email protected]> wrote: >>> >>>> Lokkju, >>>> >>>> On Thu Feb 14 2008 at 08:43:53 CET, Lokkju Brennr wrote: >>>> >>>> > https://svn.lokkju.com/svn/dnsEditor/trunk >>>> >>>> It is very good looking and quite functional, but there are some things >>>> wrong with it: >>>> >>>> 1. You load all the zones into a table in the browser; that works well >>>> enough for a handful of zones, but try pointing the program at a >>>> database with 100k zones in it ;-) >>>> >>>> 2. Unless I've overlooked something, there is no way to get additional >>>> types into the database (SRV, etc.) >>>> >>>> 3. If the database contains other DNS record types, they are not >>>> displayed. >>>> >>>> 4. There is something wrong with $cfg_primary_ns; PHP complains that >>>> $primary_ns is undefined... >>>> >>>> 5. The button `update server' should be unnecessary; the provided shell >>>> script dumps records and inserts them into other databases. People >>>> will typically use MySQL replication for that... >>>> >>>> Apart from that, you've done a great job, and it would be very valuable >>>> if you could continue on it. >>>> >>>> -JP >>>> >>>> >>> ------------------------------------------------------------------------- >>> This SF.net email is sponsored by: Microsoft >>> Defy all challenges. Microsoft(R) Visual Studio 2008. >>> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ >>> _______________________________________________ >>> Bind-dlz-testers mailing list >>> [email protected] >>> https://lists.sourceforge.net/lists/listinfo/bind-dlz-testers >>> >>> >> >> -- >> Michael J. Ayers >> Senior Systems Engineer >> ------------------------------------------------------------------------- >> This SF.net email is sponsored by the 2008 JavaOne(SM) Conference >> Register now and save $200. Hurry, offer ends at 11:59 p.m., >> Monday, April 7! Use priority code J8TLD2. >> >> http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone >> _______________________________________________ >> Bind-dlz-testers mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/bind-dlz-testers >> >> >> > > ------------------------------------------------------------------------- > This SF.net email is sponsored by the 2008 JavaOne(SM) Conference > Don't miss this year's exciting event. There's still time to save $100. > Use priority code J8TL2D2. > http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone > _______________________________________________ > Bind-dlz-testers mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/bind-dlz-testers > > I have my web team here looking into REALLY fleshing this thing out. Might take a few weeks to get that done, but it is going to be extremely functional and really nice. The intent is to take the menu list on the left side and provide drilldowns for both forward and reverse zones, so you only need to expand what you are working on. Then they are going to make the entire frame dynamic so that it expands properly with large zones and looks correct. They will also be adding entry fields to non required fields with no popup warnings for lack of data...not every field NEEDS data. Here is what I have hacked into it so far. Michael ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ Bind-dlz-testers mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/bind-dlz-testers
dnsEditor.php
(application/x-php, 30.8 KB)
<?php
include 'config.php';
ini_set('log_errors', $cfg_log_errors);
$primary_ns = $cfg_primary_ns;
// Begin session
session_start();
// DB connection
mysql_select_db($cfg_db_name, mysql_connect($cfg_db_host, $cfg_db_user, $cfg_db_pass)) or die (mysql_error());
// This calls a shell script. Eventually we may want to have it perform some other forms of updating
function updateServers() {
$err = 0;
$r = exec("./dns_update.forbidden",$r_array,$r_code);
// create string to return to the page
$errText = "";
if ($r_code != 0) {
$errText = "Error: " . mysql_error();
}
$r_text = implode("\r\n",$r_array);
$newText = "Servers Updated:\r\n" . $r_text . '~~|~~' . $errText;
return $newText;
}
function ToDBString($string, $isNumber=false) {
if($isNumber) {
if(preg_match("/^\d*[\.\,\']\d+|\d+[\.\,\']|\d+$/A", $string))
return preg_replace( array("/^(\d+)[\.\,\']$/","/^(\d*)[\.\,\'](\d+)$/"),array("\1.","\1.\2"), $string);
else
die("~~|~~~~|~~String validation error: Not a number: \"".$string ."\"");
} else {
return "'".mysql_real_escape_string(trim(strtolower($string)))."'";
}
}
// Main function to update table information
function updateSerial($rid) {
$m_sql = "select zone from records where rid = " . ToDBString($rid,true) . ";";
$sql = @mysql_query($m_sql);
$err = mysql_errno();
if ($err != 0) {
$errText .= "MySQL Error: " . mysql_error() . "\r\n" . $m_sql;
return $errText;
}
$row = mysql_fetch_row($sql);
$zone = $row[0];
if ($zone) {
$m_sql = "UPDATE records SET serial = " . date("U") . " WHERE zone='$zone' AND type='SOA';";
$sql = @mysql_query($m_sql);
$err = mysql_errno();
if ($err != 0) {
$errText .= "MySQL Error: " . mysql_error() . "\r\n" . $m_sql;
return $errText;
}
} else {
$errText .= "MySQL Error: " . mysql_error() . "\r\n" . $m_sql;
return $errText;
}
}
function changeText($sValue) {
// decode submitted data
$errText = "";
$sValue_array = explode("~~|~~", $sValue);
$sCell = explode("__", $sValue_array[1]);
// strip bad stuff
$parsedInput = htmlspecialchars($sValue_array[0], ENT_QUOTES);
//update DB
if ($sCell[0]) {
$sql = @mysql_query("UPDATE records SET $sCell[1]= '$parsedInput' WHERE rid = ".ToDBString($sCell[0],true));
$err = mysql_errno();
$errText .= updateSerial($sCell[0]);
}
// create string to return to the page
if ($err != 0) {
$errText .= "MySQL Error: " . mysql_error();
}
$newText = '<div onclick="editCell(\''.$sValue_array[1].'\', this);">'.$parsedInput.'</div>~~|~~'.$sValue_array[1] . '~~|~~' . $errText;
return $newText;
}
function changeZone($sValue) {
// decode submitted data
$sValue_array = explode("~~|~~", $sValue);
$sZone = $sValue_array[0];
// strip bad stuff
// create string to return to the page
$errText = "";
if ($err != 0) {
$errText = "MySQL Error: " . mysql_error();
}
$newText = getZone($sZone) . "~~|~~" . $zone . '~~|~~' . $errText;
return $newText;
}
function addRecord($sValue) {
$errText = "";
$sValue_array = explode("~~|~~", $sValue);
$zone = $sValue_array[0];
$rtype = $sValue_array[1];
$rtype = strtoupper($rtype);
if (isValidType($rtype)) {
switch ($rtype) {
case "A":
$sql_string = "INSERT INTO records (zone,type) VALUES (".ToDBString($zone) . ",UCASE(" . ToDBString($rtype) . "));";
if (zoneExists($zone)) {
$sql = @mysql_query($sql_string);
$err = mysql_errno();
} else {
$errText .= "Zone does not exist. (zone: " . $zone . ")\r\n";
}
break;
case "SOA":
$sql_string = "INSERT INTO records (zone,host,type,data,ttl,refresh,retry,expire,minimum,serial,resp_person) VALUES (".ToDBString($zone) . ",'@',UCASE(" . ToDBString($rtype) . "),'".$primary_ns."',86400,7200,3600,604800,3600,".date("YmdU").",'hostmaster');";
if (!zoneExists($zone)) {
$sql = @mysql_query($sql_string);
$err = mysql_errno();
} else {
$errText .= "Zone already exists. (zone: " . $zone . ")\r\n";
}
break;
default:
$sql_string = "INSERT INTO records (zone,type) VALUES (".ToDBString($zone) . ",UCASE(" . ToDBString($rtype) . "));";
if (zoneExists($zone)) {
$sql = @mysql_query($sql_string);
$err = mysql_errno();
} else {
$errText .= "Zone does not exist. (zone: " . $zone . ")\r\n";
}
break;
}
} else {
$errText .= "Invalid record type specified. (type: " . $rtype . ")\r\n";
}
// create string to return to the page
if ($err != 0) {
$errText .= "MySQL Error: " . mysql_error() . "\r\n";
}
$typehtml = "";
switch ($rtype) {
case "SOA":
$typehtml = getSOARecord($zone);
break;
case "NS":
$typehtml = getNSRecords($zone);
break;
case "MX":
$typehtml = getMXRecords($zone);
break;
case "A":
$typehtml = getARecords($zone);
break;
case "PTR":
$typehtml = getPTRRecords($zone);
break;
case 'CNAME':
$typehtml = getCNAMERecords($zone);
break;
case 'TXT':
$typehtml = getTXTRecords($zone);
break;
}
$newtext = $rtype . '~~|~~' . $typehtml . '~~|~~' . $errText;
return $newtext;
}
function delZone($sValue) {
$errText = "";
$sValue_array = explode("~~|~~", $sValue);
$zone = $sValue_array[0];
if (zoneExists($zone)) {
$sql = @mysql_query("delete from records where zone=".ToDBString($zone).";");
$err = mysql_errno();
} else {
$errText .= "Cannot delete zone: Zone does not exist. (zone: ".$zone.")\r\n";
}
// create string to return to the page
if ($err != 0) {
$errText .= "MySQL Error: " . mysql_error() . "\r\n";
}
$typehtml = "";
$newtext = '~~|~~~~|~~' . $errText;
return $newtext;
}
function delRecord($sValue) {
$errText = "";
$sValue_array = explode("~~|~~", $sValue);
$zone = $sValue_array[0];
$rtype = $sValue_array[1];
$rtype = strtoupper($rtype);
$rid = $sValue_array[2];
if (ridExists($rid)) {
$sql = @mysql_query("delete from records where rid=".ToDBString($rid,true).";");
$err = mysql_errno();
} else {
$errText .= "Record id does not exist. (rid: ".$rid.")\r\n";
}
// create string to return to the page
if ($err != 0) {
$errText .= "MySQL Error: " . mysql_error() . "\r\n";
}
$typehtml = "";
switch ($rtype) {
case "SOA":
$typehtml = getSOARecord($zone);
break;
case "NS":
$typehtml = getNSRecords($zone);
break;
case "MX":
$typehtml = getMXRecords($zone);
break;
case "A":
$typehtml = getARecords($zone);
break;
case "PTR":
$typehtml = getPTRRecords($zone);
break;
case 'CNAME':
$typehtml = getCNAMERecords($zone);
break;
case 'TXT':
$typehtml = getTXTRecords($zone);
break;
}
$newtext = $rtype . '~~|~~' . $typehtml . '~~|~~' . $errText;
return $newtext;
}
function zoneExists($zone) {
$sql = @mysql_query("select rid from records where type='SOA' and zone=".ToDBString($zone).";");
$err = mysql_errno();
$rec = mysql_num_rows($sql);
return $rec > 0;
}
function isValidType($rtype) {
switch ($rtype) {
case "SOA":
case "NS":
case "MX":
case "A":
case "TXT":
case "PTR":
case 'CNAME':
return 1;
break;
default:
return 0;
break;
}
}
function ridExists($rid) {
$sql = @mysql_query("select rid from records where rid=".ToDBString($rid,true).";");
$err = mysql_errno();
$rec = mysql_num_rows($sql);
return $rec > 0;
}
function getZone($zone) {
if (zoneExists($zone)) {
$html .= "<table class=\"editable_table\" border=\"0\">\n";
$html .= "<tr class=\"yellow\"><th>Edit Zone [". $zone . "]</th></tr>\n";
$html .= "</table>\n";
$html .= "<div id=\"div_soa_records\">" . getSOARecord($zone) . "</div>";
$html .= "<div id=\"div_ns_records\">" . getNSRecords($zone) . "</div>";
$html .= "<div id=\"div_mx_records\">" . getMXRecords($zone) . "</div>";
$html .= "<div id=\"div_a_records\">" . getARecords($zone) . "</div>";
$html .= "<div id=\"div_ptr_records\">" . getPTRRecords($zone) . "</div>";
$html .= '<div id="div_cname_records">' . getCNAMERecords($zone) . '</div>';
$html .= '<div id="div_txt_records">' . getTXTRecords($zone) . '</div>';
} else {
$html .= "<h2>Zone [$zone] does not exist.</h2>";
}
if (mysql_error()) {
$html .= "<div id=\"mysql_error\">MySql Error:<br>" . mysql_error() . "</div>";
}
return $html;
}
// functions for each record type
function getSOARecord($zone) {
// the TR string
$table = "";
// query DB
$sql = @mysql_query("SELECT rid,host,data,resp_person,refresh,retry,expire,minimum FROM records WHERE type='SOA' AND zone=".ToDBString($zone)."");
// build table
$table .= "<table id=\"tbl_soa_records\" class=\"editable_table\">";
$table .= "<tr class=\"yellow\"><td class=\"row_head\"><strong>SOA</strong></td><td>MNAME</td><td>RNAME</td><td>Refresh</td><td>Retry</td><td>Expire</td><td>Minimum</td></tr>\n";
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr><td class=\"row_head\" align=\"right\"><!-- <span class=\"del\" onclick=\"delRecord('$zone', 'SOA', $rid);\">-</span>//--></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__data\" onmouseover=\"bgSwitch('on', this, 'Modify Zone Primary Master Server' );\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= " <div onclick=\"editCell('".$rid."__data', this);\">".$data."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__resp_person\" onmouseover=\"bgSwitch('on', this, 'Modify Zone Responsible Person');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= " <div onclick=\"editCell('".$rid."__resp_person', this);\">".$resp_person."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__refresh\" onmouseover=\"bgSwitch('on', this, 'Refresh determines the number of seconds between a successful check on the serial number on the zone of the primary, and the next attempt. Usually around 2-24 hours. Not used by a primary server.');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= " <div onclick=\"editCell('".$rid."__refresh', this);\">".$refresh."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__retry\" onmouseover=\"bgSwitch('on', this, 'If a refresh attempt fails, a server will retry after this many seconds. Not used by a primary server.');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= " <div onclick=\"editCell('".$rid."__retry', this);\">".$retry."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__expire\" onmouseover=\"bgSwitch('on', this, 'Measured in seconds. If the refresh and retry attempts fail after that many seconds the server will stop serving the zone. Typical value is 1 week. Not used by a primary server.');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= " <div onclick=\"editCell('".$rid."__expire', this);\">".$expire."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__minimum\" onmouseover=\"bgSwitch('on', this, 'The default TTL for every record in the zone. Can be overridden for any particular record. Typical values range from eight hours to four days. When changes are being made to a zone, often set at ten minutes or less.');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= " <div onclick=\"editCell('".$rid."__minimum', this);\">".$minimum."</div>\n";
$table .= "</td>\n";
$table .= "</tr>\n";
}
$table .= "</table>\n";
return $table;
}
function getARecords($zone) {
// the TR string
$table = "";
// query DB
$sql = @mysql_query("SELECT rid,host,data,ttl FROM records WHERE type='A' AND zone=".ToDBString($zone)." ORDER BY host");
// build table
$table .= "<table id=\"tbl_a_records\" class=\"editable_table\">";
$table .= "<tr class=\"yellow\">\n";
$table .= "<td class=\"row_head\"><strong><span class=\"add\" onclick=\"addRecord('$zone', 'A');\" onmouseover=\"bgSwitch('on', this, 'Add A Record');\" onmouseout=\"bgSwitch('off', this, '');\"\"><img src=\"add.png\" border=0 alt=\"Add Record\" /></span> A</strong></td>\n";
$table .= "<td>Name</td>\n";
$table .= "<td>IP Address</td>\n";
$table .= "<td>TTL</td>\n";
$table .= "</tr>\n";
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr>\n<td class=\"row_head\" align=\"right\"><span class=\"del\" onclick=\"delRecord('$zone', 'A', $rid);\"><img src=\"delete.png\" border=0 alt=\"Delete Record\" /></span></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__host\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record Host');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__host', this);\">".$host."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__data\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record IP');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__data', this);\">".$data."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__ttl\" onmouseover=\"bgSwitch('on', this, 'Modify Address TTL');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__ttl', this);\">".$ttl."</div>\n";
$table .= "</td>\n</tr>\n";
}
$table .= "</table>\n";
return $table;
}
function getPTRRecords($zone) {
// the TR string
$table = "";
// query DB
$sql = @mysql_query("SELECT rid,host,data,ttl FROM records WHERE type='PTR' AND zone=".ToDBString($zone)." ORDER BY host");
// build table
$table .= "<table id=\"tbl_ptr_records\" class=\"editable_table\">";
$table .= "<tr class=\"yellow\">\n";
$table .= "<td class=\"row_head\"><strong><span class=\"add\" onclick=\"addRecord('$zone', 'PTR');\" onmouseover=\"bgSwitch('on', this, 'Add PTR Record');\" onmouseout=\"bgSwitch('off', this, '');\"\"><img src=\"add.png\" border=0 alt=\"Add Record\" /></span> PTR</strong></td>\n";
$table .= "<td>IP Address</td>\n";
$table .= "<td>Name</td>\n";
$table .= "<td>TTL</td>\n";
$table .= "</tr>\n";
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr>\n<td class=\"row_head\" align=\"right\"><span class=\"del\" onclick=\"delRecord('$zone', 'PTR', $rid);\"><img src=\"delete.png\" border=0 alt=\"Delete Record\" /></span></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__host\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record Host');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__host', this);\">".$host."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__data\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record IP');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__data', this);\">".$data."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__ttl\" onmouseover=\"bgSwitch('on', this, 'Modify Address TTL');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__ttl', this);\">".$ttl."</div>\n";
$table .= "</td>\n</tr>\n";
}
$table .= "</table>\n";
return $table;
}
function getCNAMERecords($zone) {
// the TR string
$table = "";
// query DB
$sql = @mysql_query("SELECT rid,host,data FROM records WHERE type='CNAME' AND zone=".ToDBString($zone)." ORDER BY host");
// build table
$table .= "<table id=\"tbl_cname_records\" class=\"editable_table\">";
$table .= "<tr class=\"yellow\">\n";
$table .= "<td class=\"row_head\"><strong><span class=\"add\" onclick=\"addRecord('$zone', 'CNAME');\" onmouseover=\"bgSwitch('on', this, 'Add CNAME Record');\" onmouseout=\"bgSwitch('off', this, '');\"\"><img src=\"add.png\" border=0 alt=\"Add Record\" /></span> CNAME</strong></td>\n";
$table .= "<td>Name</td>\n";
$table .= "<td>Canonical Name</td>\n";
$table .= "</tr>\n";
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr>\n<td class=\"row_head\" align=\"right\"><span class=\"del\" onclick=\"delRecord('$zone', 'CNAME', $rid);\"><img src=\"delete.png\" border=0 alt=\"Delete Record\" /></span></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__host\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record Host');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__host', this);\">".$host."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__data\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record IP');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__data', this);\">".$data."</div>\n";
$table .= "</td>\n</tr>\n";
}
$table .= "</table>\n";
return $table;
}
function getTXTRecords($zone) {
// the TR string
$table = "";
// query DB
$sql = @mysql_query("SELECT rid,host,data FROM records WHERE type='TXT' AND zone=".ToDBString($zone)." ORDER BY host");
// build table
$table .= "<table id=\"tbl_txt_records\" class=\"editable_table\">";
$table .= "<tr class=\"yellow\">\n";
$table .= "<td class=\"row_head\"><strong><span class=\"add\" onclick=\"addRecord('$zone', 'TXT');\" onmouseover=\"bgSwitch('on', this, 'Add TXT Record');\" onmouseout=\"bgSwitch('off', this, '');\"\"><img src=\"add.png\" border=0 alt=\"Add Record\" /></span> TXT</strong></td>\n";
$table .= "<td>Name</td>\n";
$table .= "<td>Text</td>\n";
$table .= "</tr>\n";
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr>\n<td class=\"row_head\" align=\"right\"><span class=\"del\" onclick=\"delRecord('$zone', 'TXT', $rid);\"><img src=\"delete.png\" border=0 alt=\"Delete Record\" /></span></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__host\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record Host');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__host', this);\">".$host."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__data\" onmouseover=\"bgSwitch('on', this, 'Modify Address Record IP');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__data', this);\">".$data."</div>\n";
$table .= "</td>\n</tr>\n";
}
$table .= "</table>\n";
return $table;
}
function getMXRecords($zone) {
// the TR string
$table = "";
// query DB
$sql = @mysql_query("SELECT rid,mx_priority,data FROM records WHERE type='MX' AND zone=".ToDBString($zone)." ORDER BY mx_priority");
// build table
$table .= "<table id=\"tbl_mx_records\" class=\"editable_table\">";
$table .= "<tr class=\"yellow\">\n";
$table .= "<td class=\"row_head\"><strong><span class=\"add\" onclick=\"addRecord('$zone', 'MX');\" onmouseover=\"bgSwitch('on', this, 'Add MX Record');\" onmouseout=\"bgSwitch('off', this, '');\"\"><img src=\"add.png\" border=0 alt=\"Add Record\" /></span> MX</strong></td>\n";
$table .= "<td>Name</td>\n";
$table .= "<td>Priority</td>\n";
$table .= "</tr>\n";
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr>\n<td class=\"row_head\" align=\"right\"><span class=\"del\" onclick=\"delRecord('$zone', 'MX', $rid);\"><img src=\"delete.png\" border=0 alt=\"Delete Record\" /></span></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__data\" onmouseover=\"bgSwitch('on', this, 'Modify Mail Exchange Name');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__data', this);\">".$data."</div>\n";
$table .= "</td>\n";
$table .= "<td class=\"point_small\" id=\"".$rid."__mx_priority\" onmouseover=\"bgSwitch('on', this, 'Modify Mail Exchange Priority');\" onmouseout=\"bgSwitch('off', this);\">\n";
$table .= "<div onclick=\"editCell('".$rid."__mx_priority', this);\">".$mx_priority."</div>\n";
$table .= "</td>\n</tr>\n";
}
$table .= "</table>\n";
return $table;
}
function getNSRecords($zone) {
// the TR string
$table = "";
// query DB
$sql = @mysql_query("SELECT rid,data FROM records WHERE type='NS' AND zone=".ToDBString($zone)." order by DATA");
// build table
$table .= "<table id=\"tbl_nsrecords\" class=\"editable_table\">";
$table .= "<tr class=\"yellow\">\n";
$table .= "<td class=\"row_head\"><strong><span class=\"add\" onclick=\"addRecord('$zone', 'NS');\" onmouseover=\"bgSwitch('on', this, 'Add Nameserver Record');\" onmouseout=\"bgSwitch('off', this, '');\"><img src=\"add.png\" border=0 alt=\"Add Record\" /></span> NS</strong></td>\n";
$table .= "<td>Nameserver</td>\n";
$table .= "</tr>\n";
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr>\n<td class=\"row_head\" align=\"right\"><span class=\"del\" onclick=\"delRecord('$zone', 'NS', $rid);\" onmouseover=\"bgSwitch('on', this, 'Delete Nameserver Record');\" onmouseout=\"bgSwitch('off', this, '');\"><img src=\"delete.png\" border=0 alt=\"Delete Record\" /></span></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__data\" onmouseover=\"bgSwitch('on', this, 'Modify Nameserver Record');\" onmouseout=\"bgSwitch('off', this, '');\">\n";
$table .= "<div onclick=\"editCell('".$rid."__data', this);\">".$data."</div>\n";
$table .= "</td>\n</tr>\n";
}
$table .= "</table>\n";
return $table;
}
function getZoneList() {
// the TR string
$table = "";
// query DB
$sql = mysql_query("SELECT DISTINCT zone,rid FROM records WHERE type='SOA' order by zone asc");
if(!$sql)
echo mysql_error();
// build table
while($row = mysql_fetch_array($sql)){
stripslashes(extract($row));
$table .= "<tr><td class=\"point_del\"><span class=\"del\" onclick=\"javascript:delZone('".$zone."');\" onmouseover=\"bgSwitch('on', this, 'Delete Zone: ".$zone."');\" onmouseout=\"bgSwitch('off', this);\"><img src=\"delete.png\" border=\"0\" alt=\"Delete Zone\" /></span></td>\n";
$table .= "<td class=\"point\" id=\"".$rid."__zone\" onmouseover=\"bgSwitch('on', this, 'Edit Zone: ".$zone."');\" onmouseout=\"bgSwitch('off', this, '');\">\n";
$table .= "<div onclick=\"editZone('".$zone."');\">".$zone."</div>\n";
$table .= "</td>\n</tr>\n";
}
return $table;
}
// sajax
require("sajax.php");
$sajax_request_type = "POST";
sajax_init();
//$sajax_debug_mode = 1;
sajax_export("changeText");
sajax_export("changeZone");
sajax_export("addRecord");
sajax_export("delRecord");
sajax_export("updateServers");
sajax_export("getZoneList");
sajax_export("delZone");
sajax_handle_client_request();
?>
<html>
<head>
<title>dnsEditor: Ajaxified</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en-us" />
<meta name="ROBOTS" content="ALL" />
<meta http-equiv="imagetoolbar" content="no" />
<meta name="MSSmartTagsPreventParsing" content="true" />
<meta name="Copyright" content="(c) 2005 Copyright content & design: Lokkju, Inc" />
<meta name="Keywords" content="dns ajax edit bind" />
<meta name="Description" content="Ajax based edit in place DNS Record configuration system" />
<!-- (c) Copyright 2005 by Lokkju, Inc All Rights Reserved. -->
<link href="dnsEditor.css" rel="stylesheet" type="text/css" media="all" />
<!-- KLUDGE:: Win IE 5 -->
<!-- corrects the unsightly Flash of Unstyled Content. See http://www.bluerobot.com/web/css/fouc.asp for more info -->
<script type="text/javascript"></script>
<!-- END KLUDGE:: -->
<script src="filtertable.js" type="text/javascript" language="javascript" charset="utf-8"></script>
<script type="text/javascript">
<?
sajax_show_javascript();
?>
function trim(str) {
str = " " + str + " ";
return str.replace(/^\s+/g, '').replace(/\s+$/g, '');
}
function textChanger_cb(result) {
var result_array=result.split("~~|~~");
if (result_array[2]) {
alert(result_array[2]);
}
document.getElementById(result_array[1]).innerHTML = result_array[0];
Fat.fade_element(result_array[1], 30, 1500, "#EEFCC5", "#FFFFFF")
}
function zoneChanger_cb(result) {
var result_array=result.split("~~|~~");
if (result_array[2]) {
alert(result_array[2]);
}
document.getElementById('zoneinfo').innerHTML = result_array[0];
}
function getZoneList_cb(result) {
var result_array=result.split("~~|~~");
if (result_array[2]) {
alert(result_array[2]);
}
document.getElementById('zonemenu_filterable').innerHTML = result_array[0];
}
function addRecord_cb(result) {
var result_array=result.split("~~|~~");
if (result_array[2]) {
alert(result_array[2]);
}
switch(result_array[0]) {
case "NS":
document.getElementById('div_ns_records').innerHTML = result_array[1];
break;
case "MX":
document.getElementById('div_mx_records').innerHTML = result_array[1];
break;
case "A":
document.getElementById('div_a_records').innerHTML = result_array[1];
break;
case "PTR":
document.getElementById('div_ptr_records').innerHTML = result_array[1];
break;
case 'CNAME':
document.getElementById('div_cname_records').innerHTML = result_array[1];
break;
case 'TXT':
document.getElementById('div_txt_records').innerHTML = result_array[1];
break;
case 'SOA':
refreshZones();
break;
}
}
function delZone_cb(result) {
var result_array=result.split("~~|~~");
if (result_array[2]) {
alert(result_array[2]);
}
refreshZones();
}
function delRecord_cb(result) {
var result_array=result.split("~~|~~");
if (result_array[2]) {
alert(result_array[2]);
}
switch(result_array[0]) {
case "NS":
document.getElementById('div_ns_records').innerHTML = result_array[1];
break;
case "MX":
document.getElementById('div_mx_records').innerHTML = result_array[1];
break;
case "A":
document.getElementById('div_a_records').innerHTML = result_array[1];
break;
case "PTR":
document.getElementById('div_ptr_records').innerHTML = result_array[1];
break;
case 'CNAME':
document.getElementById('div_cname_records').innerHTML = result_array[1];
break;
case 'TXT':
document.getElementById('div_txt_records').innerHTML = result_array[1];
break;
case "SOA":
refreshZones();
break;
}
}
function updateServers_cb(result) {
var result_array=result.split("~~|~~");
if (result_array[1]) {
alert(result_array[1]);
}
alert(result_array[0]);
document.getElementById('btn_updateServers').value='Update Servers';
}
function parseForm(cellID, inputID) {
var temp = trim(document.getElementById(inputID).value);
var obj = /^(\s*)([\W\w]*)(\b\s*$)/;
if (obj.test(temp)) { temp = temp.replace(obj, '$2'); }
var obj = / /g;
while (temp.match(obj)) { temp = temp.replace(obj, " "); }
if (temp == " ") { temp = ""; }
if (! temp) {alert("This field must contain at least one non-whitespace character.");return;}
var st = trim(document.getElementById(inputID).value) + '~~|~~' + cellID;
document.getElementById(cellID).innerHTML = "<div class=\"update\">Updating...</div>";
x_changeText(st, textChanger_cb);
document.getElementById(cellID).style.border = 'none';
}
function editCell(id, cellSpan) {
var inputWidth = (document.getElementById(id).offsetWidth / 7);
var oldCellSpan = trim(cellSpan.innerHTML);
document.getElementById(id).innerHTML = "<div id=\"" + id + "span\"><form name=\"activeForm\" onsubmit=\"parseForm('"+id+"', '"+id+"input');return false;\" style=\"margin:0;\" action=\"\"><input type=\"text\" class=\"dynaInput\" id=\""+id+"input\" size=\""+ inputWidth + "\" onblur=\"parseForm('"+id+"', '"+id+"input');return false;\"><br /><noscript><input value=\"OK\" type=\"submit\"></noscript></form></div>";
document.getElementById(id+"input").value = oldCellSpan;
document.getElementById(id).style.background = '#ffc';
document.getElementById(id+"span").style.border = '1px solid #fc0';
document.getElementById(id+"input").focus(); // for some reason, two focus calls are needed - no idea why? perhaps one to render, and the other to focus?
document.getElementById(id+"input").focus();
}
function editZone(zone) {
x_changeZone(trim(zone), zoneChanger_cb);
document.getElementById('zoneinfo').innerHTML = "<div id='zone_edit_msg'><strong>Retrieving Zone [" + zone + "]...</strong></div>";
}
function addRecord(zone,rtype) {
var st = trim(zone) + "~~|~~" + trim(rtype);
x_addRecord(st,addRecord_cb);
}
function addZone() {
var zone = prompt("Please enter the domain name to add:","");
if ((zone==null)||(zone.length==0)) {
alert("Invalid Zone");
return false;
}
addRecord(zone,"SOA");
}
function delZone(zone) {
var answer = confirm ("You are about to delete all records for " + zone + "\r\nAre your sure you want to delete ALL entries for this zone?")
if (answer) {
var st = trim(zone);
x_delZone(st,delZone_cb);
}
}
function refreshZones() {
document.getElementById('zonemenu_filterable').innerHTML = "<tr><td>Updating...</td></tr>";
document.getElementById('zoneinfo').innerHTML = "<div id='zone_edit_msg'><strong>Select a zone.</strong></div>";
x_getZoneList("",getZoneList_cb);
}
function delRecord(zone,rtype,rid) {
var answer = confirm ("Are your sure you want to delete this record?")
if (answer) {
var st = trim(zone) + "~~|~~" + trim(rtype) + '~~|~~' + trim(rid);
x_delRecord(st,delRecord_cb);
}
}
function bgSwitch(ac, td, st) {
if (ac == 'on'){
if (td.tagName == "TD") td.style.background = '#ffc';
if (st) mys(st);
} else if (ac == 'off'){
if (td.tagName == "TD") td.style.background = '#ffffff';
mys('');
}
}
function mys(s) {
if (s==null || s==''){
document.getElementById("status_div_over").innerHTML = "";
} else {
document.getElementById("status_div_over").innerHTML = s;
}
}
</script>
<script type="text/javascript" src="fat.js"></script>
<style type="text/css">
</style>
<!-- <base href="" /> Breaks in IE -->
</head>
<body id="thebody" onload="">
<div id="zonelist">
<div id="zonelist_top">
<table class="" border="0" width="100%">
<tr>
<th colspan="1" align="left">Zone List <a href="javascript:refreshZones();"><img src="refresh.png" border=0 alt="refresh" onmouseover="bgSwitch('on', this, 'Refresh Zone List');" onmouseout="bgSwitch('off', this, '');"/></a></th>
<td align="right"><input type="button" class="cmdBtn" value="Add Zone" onClick="javascript:addZone();" onmouseover="bgSwitch('on', this, 'Add a new Zone');" onmouseout="bgSwitch('off', this, '');"/><br><input class="cmdBtn" type="button" value="Update Servers" name="btn_updateServers" id="btn_updateServers" onclick="javascript:this.value='Updating...';x_updateServers('',updateServers_cb);" onmouseover="bgSwitch('on', this, 'Syncronize all DNS Servers');" onmouseout="bgSwitch('off', this, '');" /></td>
</tr>
</table>
</div>
<div id="zonelist_filter_div" onmouseover="bgSwitch('on', this, 'Filter zones based on text string');" onmouseout="bgSwitch('off', this, '');">
Filter: <input name="zonemenu_filterable_filter" id="zonemenu_filterable_filter" type="text" value="" size="10" maxlength="10"/>
</div>
<div id="zonelist_menu">
<table class="zonemenu_filterable" id="zonemenu_filterable" border="0">
<?php echo getZoneList(); ?>
</table>
</div>
<div id="status_div">
<div id="status_div_over">
</div>
<div id="status_div_ajax">
</div>
</div>
</div>
<div id="zoneinfo">
<div id="zone_edit_msg"><strong>Select a zone.</strong></div>
</div>
</body>
</html>