Skip to content

Commit 7dc6dd6

Browse files
authored
feat: allow DNS entry to be deleted (#37)
Fixes #34
1 parent 9ccad0e commit 7dc6dd6

File tree

5 files changed

+291
-11
lines changed

5 files changed

+291
-11
lines changed

README.md

Lines changed: 157 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,16 @@
3838
- [Add a new SSH key](#add-a-new-ssh-key)
3939
- [Update an SSH key](#update-an-ssh-key)
4040
- [Delete an SSH key](#delete-an-ssh-key)
41-
- [Domains](#domains)
41+
- [Domain](#domain)
42+
- [Domains](#domains)
43+
- [The **Domain** class](#the-domain-class)
44+
- [List all domains](#list-all-domains)
45+
- [Retrieve an existing domain](#retrieve-an-existing-domain)
46+
- [DNS](#dns)
47+
- [The **DnsEntry** class](#the-dnsentry-class)
48+
- [List all DNS entries for a domain](#list-all-dns-entries-for-a-domain)
49+
- [Add a new single DNS entry to a domain](#add-a-new-single-dns-entry-to-a-domain)
50+
- [Remove a DNS entry from a domain](#remove-a-dns-entry-from-a-domain)
4251
- [VPS](#vps)
4352
- [HA-IP](#ha-ip)
4453
- [Colocation](#colocation)
@@ -102,7 +111,7 @@ The [general TransIP API](https://api.transip.nl/rest/docs.html#general) resourc
102111
### Products
103112
Manage available TransIP products and product specifications.
104113

105-
### The **Product** class
114+
#### The **Product** class
106115
When listing all products available on TransIP, a list of **transip.v6.objects.Product** objects is returned.
107116

108117
**_class_ Product**
@@ -115,7 +124,7 @@ The **Product** class makes the following attributes available:
115124
- **recurringPrice**: The recurring price for the product in cents.
116125
- **elements**: The service to list detailed information on the product elements.
117126

118-
### The **ProductElement** class
127+
#### The **ProductElement** class
119128
When listing all product elements of a **transip.v6.objects.Product** object, a list of **transip.v6.objects.ProductElement** objects is returned.
120129

121130
**_class_ ProductElement**
@@ -165,7 +174,7 @@ for product in client.products.list():
165174
### Availability Zones
166175
Manage TransIP availability zones.
167176

168-
### The **AvailabilityZone** class
177+
#### The **AvailabilityZone** class
169178
When listing all the available availability zones on TransIP, a list of **transip.v6.objects.AvailabilityZone** objects is returned.
170179

171180
**_class_ AvailabilityZone**
@@ -212,7 +221,7 @@ The [account TransIP API](https://api.transip.nl/rest/docs.html#account) resourc
212221
### Invoices
213222
Manage invoices attached to your TransIP account.
214223

215-
### The **Invoice** class
224+
#### The **Invoice** class
216225
When listing all invoices attached to your TransIP account, a list of **transip.v6.objects.Invoice** objects is returned.
217226

218227
**_class_ Invoice**
@@ -230,7 +239,7 @@ The **Invoice** class makes the following attributes available:
230239
- **items**: The service to list detailed information on the individual invoice items.
231240

232241

233-
### The **InvoiceItem** class
242+
#### The **InvoiceItem** class
234243
When listing all invoices items attached to a **transip.v6.objects.Invoice** object, a list of **transip.v6.objects.InvoiceItem** objects is returned.
235244

236245
**_class_ InvoiceItem**
@@ -437,8 +446,148 @@ The **transip.v6.objects.SshKey** class also provides a **delete()** method to d
437446

438447
**Note:** when using the demo access token, the API currently doesn't list any SSH keys.
439448

440-
## Domains
441-
The documentation for managing **domains** and related resources has not yet been documented. Feel free to file an [issue](https://github.com/roaldnefs/python-transip/issues/new/choose) for adding the missing section(s) in the documentation.
449+
## Domain
450+
The [domains TransIP API](https://api.transip.nl/rest/docs.html#general) resources allow you to manage domains, branding, contacts, DNS, DNSSEC, nameservers, actions, SSL, WHOIS, availability and call the tlds resource.
451+
452+
The documentation for managing **domains** and related resources has not yet completely been documented. Feel free to file an [issue](https://github.com/roaldnefs/python-transip/issues/new/choose) for adding the missing section(s) in the documentation.
453+
454+
### Domains
455+
Manage domains.
456+
457+
#### The **Domain** class
458+
When listing all domains in your TransIP account, a list of **transip.v6.objects.Domain** objects is returned.
459+
460+
**_class_ Domain**
461+
462+
The **Domain** class makes the following attributes available:
463+
464+
- **name**: The name, including the tld of this domain.
465+
- **authCode**: The authcode for this domain as generated by the registry.
466+
- **isTransferLocked**: If this domain supports transfer locking, this flag is True when the domains ability to transfer is locked at the registry.
467+
- **registrationDate**: The registration date of the domain, in YYYY-mm-dd format.
468+
- **renewalDate**: The next renewal date of the domain, in YYYY-mm-dd format.
469+
- **isWhitelabel**: If this domain is added to your whitelabel.
470+
- **cancellationDate**: Cancellation data, in YYYY-mm-dd h:i:s format, None if the domain is active.
471+
- **cancellationStatus**: Cancellation status, None if the domain is active, ‘cancelled’ when the domain is cancelled.
472+
- **isDnsOnly**: Whether this domain is DNS only.
473+
- **tags**: The custom tags added to this domain.
474+
- **contacts**: The service to manage the domain contacts.
475+
- **dns**: The service to manage the DNS-records of the domain.
476+
- **nameservers**: The service to manage the nameservers of the domain.
477+
478+
#### List all domains
479+
Retrieve all domains registered in your TransIP account by calling **transip.TransIP.domains.list()**. This will return a list of **transip.v6.objects.Domain** objects.
480+
481+
For example:
482+
```python
483+
import transip
484+
# Initialize a client using the TransIP demo token.
485+
client = transip.TransIP(access_token=transip.v6.DEMO_TOKEN)
486+
487+
# List all domains.
488+
domains = client.domains.list()
489+
# Show domain information on the screen.
490+
for domain in domains:
491+
print(f"Domain {domain.name} was registered at {domain.registrationDate}")
492+
```
493+
494+
#### Retrieve an existing domain
495+
Retrieve a single domain registered ion your TransIP account by its ID by calling **transip.TransIP.domains.get(_name_)**. This will return a **transip.v6.objects.Domain** object.
496+
497+
For example:
498+
```python
499+
import transip
500+
# Initialize a client using the TransIP demo token.
501+
client = transip.TransIP(access_token=transip.v6.DEMO_TOKEN)
502+
503+
# Retrieve a domain by its name
504+
domain = client.domains.get('transipdemonstratie.nl')
505+
# Show domain information on the screen.
506+
print(f"Domain {domain.name} was registered at {domain.registrationDate}")
507+
```
508+
509+
### DNS
510+
Manage DNS records of a domain. Any changes made here will be pushed to the TransIP nameservers.
511+
#### The **DnsEntry** class
512+
513+
When listing all DNS-records of a **transip.v6.objects.Domain** object, a list of **transip.v6.objects.DnsEntry** objects is returned.
514+
515+
**_class_ DnsEntry**
516+
517+
The **DnsEntry** class makes the following attributes available:
518+
519+
- **name**: The name of the dns entry, for example ‘@’ or ‘www’
520+
- **expire**: The expiration period of the dns entry, in seconds. For example 86400 for a day of expiration.
521+
- **type**: The type of dns entry. Possbible types are ‘A’, ‘AAAA’, ‘CNAME’, ‘MX’, ‘NS’, ‘TXT’, ‘SRV’, ‘SSHFP’ and ‘TLSA’.
522+
- **content**: The content of of the dns entry, for example ‘10 mail’, ‘127.0.0.1’ or ‘www’.
523+
524+
The class has the following methods:
525+
526+
- **delete()** will delete the DNS-record from the domain.
527+
528+
#### List all DNS entries for a domain
529+
Retrieve the DNS records of a single domain registered in your TransIP account by calling **dns.list()** on a **transip.v6.objects.Domain** object. This will return a list of **transip.v6.objects.DnsEntry** objects.
530+
531+
For example:
532+
```python
533+
import transip
534+
# Initialize a client using the TransIP demo token.
535+
client = transip.TransIP(access_token=transip.v6.DEMO_TOKEN)
536+
537+
# Retrieve a domain by its name.
538+
domain = client.domains.get('transipdemonstratie.nl')
539+
# Retrieve the DNS records of a single domain.
540+
records = domain.dns.list()
541+
# Show the DNS record information on the screen.
542+
for record in records:
543+
print(f"DNS: {record.name} {record.expire} {record.type} {record.content}")
544+
```
545+
546+
#### Add a new single DNS entry to a domain
547+
Add an new DNS record to a domain by calling **dns.create(_data_)** on a **transip.v6.objects.Domain** object. The **data** keyword argument a dictionary containing the **name**, **expire**, **type** and **content** attributes.
548+
549+
For example:
550+
```python
551+
import transip
552+
# Initialize a client using the TransIP demo token.
553+
client = transip.TransIP(access_token=transip.v6.DEMO_TOKEN)
554+
555+
# Retrieve a domain by its name.
556+
domain = client.domains.get('transipdemonstratie.nl')
557+
# Dictionary containing the information for a single DNS record.
558+
dns_entry_data = {
559+
"name": "www",
560+
"expire": 86400,
561+
"type": "A",
562+
"content": "127.0.0.1"
563+
}
564+
# Add the DNS record to the domain.
565+
domain.delete(dns_entry_data)
566+
```
567+
568+
#### Remove a DNS entry from a domain
569+
Delete an existing DNS record from a domain by calling **dns.delete(_data_)** on a **transip.v6.objects.Domain** object. The **data** keyword argument a dictionary containing the **name**, **expire**, **type** and **content** attributes.
570+
571+
For example:
572+
```python
573+
import transip
574+
# Initialize a client using the TransIP demo token.
575+
client = transip.TransIP(access_token=transip.v6.DEMO_TOKEN)
576+
577+
# Retrieve a domain by its name.
578+
domain = client.domains.get('transipdemonstratie.nl')
579+
# Dictionary containing the information for a single DNS record.
580+
dns_entry_data = {
581+
"name": "www",
582+
"expire": 86400,
583+
"type": "A",
584+
"content": "127.0.0.1"
585+
}
586+
# Delete the DNS record from the domain.
587+
domain.delete(dns_entry_data)
588+
```
589+
590+
The **transip.v6.objects.DnsEntry** class also provides a **delete()** method to delete a **DnsEntry** object from an instance.
442591

443592
## VPS
444593
The documentation for managing **VPSs** and related resources has not yet been documented. Feel free to file an [issue](https://github.com/roaldnefs/python-transip/issues/new/choose) for adding the missing section(s) in the documentation.

tests/fixtures/domains.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,20 @@
266266
"status": 200,
267267
"content_type": "application/json"
268268
},
269+
{
270+
"method": "DELETE",
271+
"url": "https://api.transip.nl/v6/domains/example.com/dns",
272+
"status": 204,
273+
"content_type": "application/json",
274+
"match_json_params": {
275+
"dnsEntry": {
276+
"name": "www",
277+
"expire": 86400,
278+
"type": "A",
279+
"content": "127.0.0.1"
280+
}
281+
}
282+
},
269283
{
270284
"method": "POST",
271285
"url": "https://api.transip.nl/v6/domains/example.com/dns",

tests/services/test_domains.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,47 @@ def test_dns_create(self) -> None:
8686
domain.dns.create(dns_entry_data) # type: ignore
8787

8888
assert len(responses.calls) == 2
89+
90+
@responses.activate
91+
def test_dns_delete(self) -> None:
92+
"""Check if a single DNS entry can be deleted."""
93+
dns_entry_data: Dict[str, Union[str, int]] = {
94+
"name": "www",
95+
"expire": 86400,
96+
"type": "A",
97+
"content": "127.0.0.1"
98+
}
99+
domain: Domain = self.client.domains.get("example.com") # type: ignore
100+
101+
try:
102+
domain.dns.delete(dns_entry_data) # type: ignore
103+
except Exception as exc:
104+
assert False, (
105+
"'transip.v6.objects.Domain.dns.delete' raised an exception "
106+
f"{exc}"
107+
)
108+
# Ensure only two calls are being made: the retrieval of the domain and
109+
# the deletion of the DNS entry
110+
self.assertEqual(len(responses.calls), 2)
111+
112+
@responses.activate
113+
def test_dns_delete_object(self) -> None:
114+
"""Check if a DNS entry can be deleted from the object itself."""
115+
domain: Domain = self.client.domains.get("example.com") # type: ignore
116+
entries = domain.dns.list()
117+
118+
self.assertEqual(len(entries), 1)
119+
120+
entry: DnsEntry = entries[0] # type: ignore
121+
try:
122+
# Delete the first DNS entry
123+
entry.delete()
124+
except Exception as exc:
125+
assert False, (
126+
"'transip.v6.objects.DnsEntry.delete' raised an exception "
127+
f"{exc}"
128+
)
129+
# Ensure only three calls are being made; the retrieval of the domain,
130+
# the listing of the DNS entries and the deletion of a single DNS
131+
# entry.
132+
self.assertEqual(len(responses.calls), 3)

transip/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,12 +426,16 @@ def patch(
426426
def delete(
427427
self,
428428
path: str,
429+
data: Optional[Any] = None,
430+
json: Optional[Any] = None,
429431
params: Optional[Dict[str, Any]] = None
430432
) -> Any:
431433
"""Make a GET request to the TransIP API.
432434
433435
Args:
434436
path (str): The path to append to the API URL
437+
data (dict): The body to attach to the request
438+
json (dict): The json body to attach to the request
435439
params (dict): URL parameters to append to the URL
436440
437441
Returns:
@@ -441,5 +445,5 @@ def delete(
441445
TransIPHTTPError: When the return code of the request is not 2xx
442446
"""
443447
return self.request(
444-
"DELETE", path, params=params
448+
"DELETE", path, data=data, json=json, params=params
445449
)

0 commit comments

Comments
 (0)