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

How to add new NS with different TTL without remove existing NS #65

Closed
arislanhaikal opened this issue Mar 19, 2021 · 10 comments
Closed
Assignees

Comments

@arislanhaikal
Copy link

Detailed description

I have created a new zone with the default NS. How do I add a new NS with a different TTL without deleting the existing NS.

$domain = 'dns-new-zone-test.nl';
$nameServers = ['ns1.example.com.', 'ns2.example.com.'];
$dnsRecords = [
    ['name' => '@', 'type' => RecordType::A, 'content' => '127.0.0.1', 'ttl' => 60],
    ['name' => 'www', 'type' => RecordType::A, 'content' => '127.0.0.1', 'ttl' => 60],
    ['name' => 'mail01', 'type' => RecordType::A, 'content' => '127.0.0.1'],
    ['name' => 'mail02', 'type' => RecordType::A, 'content' => '127.0.0.2']
];

$powerdns = new Powerdns('127.0.0.1', 'very_secret_secret');

$powerdns->createZone($domain, $nameServers)->create($dnsRecords);

with this i have two NS

Name Type Status TTL Data
@ NS Active 3600 ns1.example.com.
@ NS Active 3600 ns2.example.com.

Then can I add one NS with a different TTL without deleting the existing NS?
I did with this, but the existing NS is gone

$zone->create('@', RecordType::NS, 'ns3.example.com.', 86400);

My assumption is that there is no need to send all existing records to add new records, just enough records have just been added.

Expectation

Name Type Status TTL Data
@ NS Active 3600 ns1.example.com.
@ NS Active 3600 ns2.example.com.
@ NS Active 86400 ns3.example.com.

Can anyone provide a more detailed sample regarding adding records without deleting the existing ones. This applies not only to NS but all records.

Thank you for the help

@trizz trizz self-assigned this Mar 19, 2021
@trizz
Copy link
Member

trizz commented Mar 19, 2021

Hi @arislanhaikal,

Unfortunately, it is not possible to add an NS record without sending the existing ones also. The reason for this is that the NS records in fact is just one 'record' ('resource set') with multiple values as content and not three (or two) separate records.

For more information you can look at #44 and #37. Please let me know if you still have questions about this, and I'll look if I can give you some examples.

@arislanhaikal
Copy link
Author

Ahh i see. I understand now, if the NS records in fact is just one record.

How about delete one record? like the sample above, suppose I want to delete ns3.example.com.
I have to send 2 ns (ns1, ns2) to save only, or can I use unset record?

I saw the post on #43 . But but I still don't understand how to delete unwanted arrays. Can you provide an example of how to delete it?

Sorry my question is too stupid, i am a newbie :)

Thank for your answer @trizz

@trizz
Copy link
Member

trizz commented Mar 19, 2021

Sorry my question is too stupid, i am a newbie :)

No worries, we've all been there.

How about delete one record? like the sample above, suppose I want to delete ns3.example.com.
I have to send 2 ns (ns1, ns2) to save only, or can I use unset record?

Yes, you need to update with ns1/ns2 as value. Below you'll find three examples: first create a new zone with ns1/ns2, next add another value for ns3 and after that remove ns2. As you can see it is a matter of updating an array with the data you want.

If things are still unclear, just let me know!

use Exonet\Powerdns\Powerdns;
use Exonet\Powerdns\RecordType;
use Exonet\Powerdns\Resources\Record;
use Exonet\Powerdns\Resources\ResourceRecord;
use Exonet\Powerdns\Resources\ResourceSet;

$domain = 'ns-example.id';

// Update the key to the real PowerDNS API Key.
$powerdns = new Powerdns('127.0.0.1', 'very_secret_secret');

// Uncomment this line if you want to run this example multiple times.
// $powerdns->deleteZone($domain);

/***************************************************************
 * Create a new zone with the defined records and name servers.
 */
$zone = $powerdns->createZone($domain, ['ns1.example.com.', 'ns2.example.eu.']);
displayNsContents($zone->get(RecordType::NS));

/***************************************
 * Add an extra item to the NS records.
 */
$resourceSets = $zone->get(RecordType::NS);

foreach ($resourceSets as $resourceSet) {
    $records = $resourceSet->getRecords();

    // $records is a plain array consisting of Record classes for each record.
    // You can do with this array whatever you want. Add items, remove items, update items, etc.
    $records[] = (new Record())->setContent('ns3.example.io.');

    // After you've changed the array to your liking, you need to replace the existing ones:
    $resourceSet->setRecords($records);

    // And save the resource set:
    $resourceSet->save();
}
displayNsContents($zone->get(RecordType::NS));

/**************
 * Remove ns2
 */
$resourceSets = $zone->get(RecordType::NS);

foreach ($resourceSets as $resourceSet) {
    $records = $resourceSet->getRecords();

    foreach ($records as $index => $record) {
        if ($record->getContent() === 'ns2.example.eu.') {
            unset($records[$index]);
        }
    }

    $resourceSet->setRecords($records);
    $resourceSet->save();
}
displayNsContents($zone->get(RecordType::NS));


/**
 * Little helper function to display the data.
 */
function displayNsContents(ResourceSet $nsResourceSet)
{
    /** @var ResourceRecord $nsResource */
    foreach ($nsResourceSet as $nsResource) {
        echo "\n".$nsResource->getName();
        foreach ($nsResource->getRecords() as $record) {
            echo "\n  ".$record->getContent();
        }
    }

    echo "\n\n";
}

The expected output of this script:

ns-example.id.
  ns1.example.com.
  ns2.example.eu.


ns-example.id.
  ns1.example.com.
  ns2.example.eu.
  ns3.example.io.


ns-example.id.
  ns1.example.com.
  ns3.example.io.

@arislanhaikal
Copy link
Author

Yeah, this is the sample that I want. I understand now.

Thank you for creating this amazing package 💯

@trizz trizz closed this as completed Mar 19, 2021
@arislanhaikal
Copy link
Author

arislanhaikal commented Mar 19, 2021

Hi @trizz
May I ask again?

How do I remove a different name, while the type and content are the same.
Ex.

Name Type Status TTL Data
ftp CNAME Active 3600 example.com.
www CNAME Active 3600 example.com.
mail CNAME Active 3600 example.com.

I want remove mail. Can i use unset as you demonstrated?
And how to add an extra item to the CNAME records, with some content but different name?
Its make me confused.

Sorry I ask many questions.

@trizz
Copy link
Member

trizz commented Mar 19, 2021

No, in this case it works differently. An important thing to remember is that, for PowerDNS, the "unique" is the combination of name and type. In case of the NS records, the name and type are the same, so the content is in a single resource set. In the case of this CNAMEs, the combination mail and CNAME is unique, so you can remove it like this:

$zone->find('mail', RecordType::CNAME)->delete();

Creating a new CNAME with the same content, but another name is the same as adding a new record, because the name/type combination does not exist yet:

$zone->create('some-record', RecordType::CNAME, 'example.com.', 3600);
$zone->create('another-record', RecordType::CNAME, 'example.com.', 3600);

@arislanhaikal
Copy link
Author

Oh i sorry about that, so other than NS what is in the content is in a single resource set? MX?
What it all depends on the conditions. And I have to manually check with find whether it already exists or not, if it already exists, it means using single resource set, if there does not exist, with create method. Its that true?

@trizz
Copy link
Member

trizz commented Mar 19, 2021

so other than NS what is in the content is in a single resource set? MX?

In theory, it can be for every record, for example an A record with two different IPs. But that isn't used much, so usually NS and MX records.

What it all depends on the conditions. And I have to manually check with find whether it already exists or not, if it already exists, it means using single resource set, if there does not exist, with create method. Its that true?

I'm not sure that I understand what you mean. But yes, it depends on the conditions. You need to check if the name/type combination is unique, otherwise you'll overwrite existing data.

@arislanhaikal
Copy link
Author

arislanhaikal commented Mar 19, 2021

Thank you very much for your explanation. I'm actually learning about the DNS system.

One more thing, can you give a sample how to create an SRV record type, where there are content, priority, port and weight?

Hopefully in the future I can learn a lot from you. Don't get bored if I often ask LOL.

Thanks again 🙏🏻

@trizz
Copy link
Member

trizz commented Mar 19, 2021

where there are content, priority, port and weight?

You can pass them as content, separated with a space in the same way as with MX records:

$zone->create('some-record', RecordType::SRV, '100 1 443 example.com.', 3600);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants