Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'edit' action to Custom DNS endpoint #2379

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@

break;

case 'edit':
$data = editCustomDNSEntry();

break;

case 'delete':
$data = deleteCustomDNSEntry();

Expand Down
3 changes: 3 additions & 0 deletions scripts/pi-hole/php/customdns.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
case 'add': echo json_encode(addCustomDNSEntry());
break;

case 'edit': echo json_encode(editCustomDNSEntry());
break;

case 'delete': echo json_encode(deleteCustomDNSEntry());
break;

Expand Down
46 changes: 46 additions & 0 deletions scripts/pi-hole/php/func.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,52 @@ function addCustomDNSEntry($ip = '', $domain = '', $reload = '', $json = true)
}
}

function editCustomDNSEntry($ip = '', $domain = '', $reload = '', $json = true)
{
try {
$ip = !empty($_REQUEST['ip']) ? trim($_REQUEST['ip']) : $ip;
$domain = !empty($_REQUEST['domain']) ? trim($_REQUEST['domain']) : $domain;
$reload = !empty($_REQUEST['reload']) ? trim($_REQUEST['reload']) : $reload;

if (empty($ip)) {
return returnError('IP must be set', $json);
}

$ipType = get_ip_type($ip);

if (!$ipType) {
return returnError('IP must be valid', $json);
}

if (empty($domain)) {
return returnError('Domain must be set', $json);
}

if (!validDomain($domain)) {
return returnError('Domain must be valid', $json);
}

$existingEntries = getCustomDNSEntries();

foreach ($existingEntries as $entry) {
if ($entry->domain == $domain) {
$old_ip = $entry->ip;
break;
}
}

if (isset($old_ip)) {
pihole_execute('-a removecustomdns '.$old_ip.' '.$domain);
}

pihole_execute('-a addcustomdns '.$ip.' '.$domain.' '.$reload);

return returnSuccess('', $json);
} catch (\Exception $ex) {
return returnError($ex->getMessage(), $json);
}
}

Comment on lines +260 to +305
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is all logic that should be in what ever client that would be calling this endpoint.

The client should be doing the lifting of deciding if the record needs to be updated/modified by checking the existing records existence and then checking if the record needs updating. It would also be up to the client to decide if any existing records should be deleted since DNS itself has no requirement for an A record value to be unique.

I guess a simple wrapper update endpoint that is basically syntactic sugar for delete and then add could work but I like the idea of API endpoints doing one specific job and being extremely unambiguous with it's function.

Solely my views of course.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically:

// Pseudo-code. Not an actual code:
function editCustomDNSEntry($ip = '', $domain = '', $reload = '', $json = true) {
    deleteCustomDNSEntry($ip, $domain); // this function currently can't receive parameters
    addCustomDNSEntry($ip, $domain, $reload, $json);
}

The only thing needed is to allow deleteCustomDNSEntry() to receive parameters (ip and domain from the entry to be deleted).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you even need the IP address? Just the record should be enough.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rdwebdesign pretty much, except the current delete endpoint needs you to pass in the current IP address of the entry. As @dschaper points out, the IP is not actually needed, as you can only have one entry per hostname, so the hostname alone should be enough.

I can submit a separate PR to refactor the delete endpoint and remove the need for the IP to be sent. I think that's a good change regardless of the rest. What do you think?

Even if I make that change, it's still two API calls to "edit" a record. Ideally we would want one endpoint per CRUD operation, no? The only reason this is a discussion at the API level is because the underlying pihole CLI doesn't support edits. Maybe I should focus my efforts in adding the edit option there and keep the API a one-to-one mapping to the CLI.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this API was created mostly to be used by the web interface.
In my opinion, the introduced change is not being used by the web interface at all. No pages are using use the new feature.

Ideally we would want one endpoint per CRUD operation, no?

I understand your idea, but this doesn't matter. These API calls use pihole to delete/save the values.

Your new code calls pihole 2 times:
pihole_execute('-a removecustomdns '.$old_ip.' '.$domain) and
pihole_execute('-a addcustomdns '.$ip.' '.$domain.' '.$reload)

This is exactly like calling the functions we already have (deleteCustomDNSEntry() followed by addCustomDNSEntry()).

This new function just uses a slightly different "path", but it calls the same code from pihole.

In the end pihole code needs 2 calls because it has only 2 functions to handle Custom DNS entries.
There is no "edit" or "update" function there. It will just remove the record and write the new one.

function deleteCustomDNSEntry()
{
try {
Expand Down