Skip to content

Commit 88394ed

Browse files
authored
Merge pull request #10 from roaldnefs/add-domain-services
2 parents f11cdcd + b709c1a commit 88394ed

3 files changed

Lines changed: 200 additions & 17 deletions

File tree

docs/user/quickstart.rst

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,29 @@ We could also cancel a single
9191

9292
>>> client.domains.delete('transipdemonstratie.nl')
9393

94+
DNS
95+
***
96+
97+
We could also list the DNS entries as
98+
:class:`DnsEntry <transip.v6.services.domain.DnsEntry>` objects of a
99+
single :class:`Domain <transip.v6.services.domain.Domain>` object by its name::
100+
101+
>>> domain = client.domains.get('transipdemonstratie.nl')
102+
>>> entries = domain.dns.list()
103+
>>> for entry in entries:
104+
... print(entry)
105+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': '@', 'expire': 300, 'type': 'A', 'content': '37.97.254.27'}
106+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': '@', 'expire': 300, 'type': 'AAAA', 'content': '2a01:7c8:3:1337::27'}
107+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': '@', 'expire': 86400, 'type': 'MX', 'content': '10 @'}
108+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': '@', 'expire': 300, 'type': 'TXT', 'content': 'v=spf1 ~all'}
109+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': 'ftp', 'expire': 86400, 'type': 'CNAME', 'content': '@'}
110+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': 'mail', 'expire': 86400, 'type': 'CNAME', 'content': '@'}
111+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': 'transip-A._domainkey', 'expire': 3600, 'type': 'CNAME', 'content': '_dkim-A.transip.email.'}
112+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': 'transip-B._domainkey', 'expire': 3600, 'type': 'CNAME', 'content': '_dkim-B.transip.email.'}
113+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': 'transip-C._domainkey', 'expire': 3600, 'type': 'CNAME', 'content': '_dkim-C.transip.email.'}
114+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': 'www', 'expire': 86400, 'type': 'CNAME', 'content': '@'}
115+
<class 'transip.v6.services.domain.DnsEntry'> => {'name': '_dmarc', 'expire': 86400, 'type': 'TXT', 'content': 'v=DMARC1; p=none;'}
116+
94117
Domain Contacts
95118
***************
96119

@@ -99,13 +122,28 @@ We could also list the contacts as
99122
single :class:`Domain <transip.v6.services.domain.Domain>` object by its name::
100123

101124
>>> domain = client.domains.get('transipdemonstratie.nl')
102-
>>> contacts = domain.contacts()
125+
>>> contacts = domain.contacts.list()
103126
>>> for contact in contacts:
104127
... print(contact)
105128
<class 'transip.v6.services.domain.WhoisContact'> => {'type': 'registrant', 'firstName': 'TransIP', 'lastName': 'Demo', 'companyName': '', 'companyKvk': '', 'companyType': '', 'street': 'Schipholweg', 'number': '11e', 'postalCode': '2316 XB', 'city': 'LEIDEN', 'phoneNumber': '+31 715241919', 'faxNumber': '', 'email': 'feedback@transip.nl', 'country': 'nl'}
106129
<class 'transip.v6.services.domain.WhoisContact'> => {'type': 'administrative', 'firstName': 'TransIP', 'lastName': 'Demo', 'companyName': '', 'companyKvk': '', 'companyType': '', 'street': 'Schipholweg', 'number': '11e', 'postalCode': '2316 XB', 'city': 'LEIDEN', 'phoneNumber': '+31 715241919', 'faxNumber': '', 'email': 'feedback@transip.nl', 'country': 'nl'}
107130
<class 'transip.v6.services.domain.WhoisContact'> => {'type': 'technical', 'firstName': 'TransIP', 'lastName': 'Demo', 'companyName': '', 'companyKvk': '', 'companyType': '', 'street': 'Schipholweg', 'number': '11e', 'postalCode': '2316 XB', 'city': 'LEIDEN', 'phoneNumber': '+31 715241919', 'faxNumber': '', 'email': 'feedback@transip.nl', 'country': 'nl'}
108131

132+
Nameservers
133+
***********
134+
135+
We could also list the nameserver as
136+
:class:`Nameserver <transip.v6.services.domain.Nameserver>` objects of a
137+
single :class:`Domain <transip.v6.services.domain.Domain>` object by its name::
138+
139+
>>> domain = client.domains.get('transipdemonstratie.nl')
140+
>>> nameservers = domain.nameservers.list()
141+
>>> for nameserver in nameservers:
142+
... print(nameserver)
143+
<class 'transip.v6.services.domain.Nameserver'> => {'hostname': 'ns0.transip.net', 'ipv4': '', 'ipv6': ''}
144+
<class 'transip.v6.services.domain.Nameserver'> => {'hostname': 'ns1.transip.nl', 'ipv4': '', 'ipv6': ''}
145+
<class 'transip.v6.services.domain.Nameserver'> => {'hostname': 'ns2.transip.eu', 'ipv4': '', 'ipv6': ''}
146+
109147
Invoices
110148
--------
111149

tests/services/test_domains.py

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import responses # type: ignore
2222

2323
from transip import TransIP
24-
from transip.v6.services.domain import Domain, WhoisContact
24+
from transip.v6.services.domain import (
25+
Domain, WhoisContact, Nameserver, DnsEntry
26+
)
2527

2628

2729
@responses.activate
@@ -103,7 +105,100 @@ def test_domains_contacts_list(transip_minimal_client: Type[TransIP]) -> None:
103105
)
104106

105107
domain: Type[Domain] = transip_minimal_client.domains.get("example.com")
106-
contacts: List[Type[Domain]] = domain.contacts() # type: ignore
108+
contacts: List[Type[Domain]] = domain.contacts.list() # type: ignore
107109
contact: Type[Domain] = contacts[0]
108110
assert len(contacts) == 1
109111
assert contact.companyName == "Example B.V." # type: ignore
112+
113+
114+
@responses.activate
115+
def test_domains_nameservers_list(transip_minimal_client: Type[TransIP]) -> None:
116+
responses.add(
117+
responses.GET,
118+
"https://api.transip.nl/v6/domains/example.com",
119+
json={
120+
"domain": {
121+
"name": "example.com",
122+
"authCode": "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud4nfpzw8qBsfR2JqAj7Ce12SxKcGD09v+yXd6lrm",
123+
"isTransferLocked": False,
124+
"registrationDate": "2016-01-01",
125+
"renewalDate": "2020-01-01",
126+
"isWhitelabel": False,
127+
"cancellationDate": "2020-01-01 12:00:00",
128+
"cancellationStatus": "signed",
129+
"isDnsOnly": False,
130+
"tags": [
131+
"customTag",
132+
"anotherTag"
133+
]
134+
}
135+
},
136+
status=200,
137+
)
138+
responses.add(
139+
responses.GET,
140+
"https://api.transip.nl/v6/domains/example.com/nameservers",
141+
json={
142+
"nameservers": [
143+
{
144+
"hostname": "ns0.transip.nl",
145+
"ipv4": "",
146+
"ipv6": ""
147+
}
148+
]
149+
},
150+
status=200,
151+
)
152+
153+
domain: Type[Domain] = transip_minimal_client.domains.get("example.com")
154+
nameservers: List[Type[Nameserver]] = domain.nameservers.list() # type: ignore
155+
nameserver: Type[Nameserver] = nameservers[0]
156+
assert len(nameservers) == 1
157+
assert nameserver.get_id() == "ns0.transip.nl" # type: ignore
158+
159+
160+
@responses.activate
161+
def test_domains_dns_list(transip_minimal_client: Type[TransIP]) -> None:
162+
responses.add(
163+
responses.GET,
164+
"https://api.transip.nl/v6/domains/example.com",
165+
json={
166+
"domain": {
167+
"name": "example.com",
168+
"authCode": "kJqfuOXNOYQKqh/jO4bYSn54YDqgAt1ksCe+ZG4Ud4nfpzw8qBsfR2JqAj7Ce12SxKcGD09v+yXd6lrm",
169+
"isTransferLocked": False,
170+
"registrationDate": "2016-01-01",
171+
"renewalDate": "2020-01-01",
172+
"isWhitelabel": False,
173+
"cancellationDate": "2020-01-01 12:00:00",
174+
"cancellationStatus": "signed",
175+
"isDnsOnly": False,
176+
"tags": [
177+
"customTag",
178+
"anotherTag"
179+
]
180+
}
181+
},
182+
status=200,
183+
)
184+
responses.add(
185+
responses.GET,
186+
"https://api.transip.nl/v6/domains/example.com/dns",
187+
json={
188+
"dnsEntries": [
189+
{
190+
"name": "www",
191+
"expire": 86400,
192+
"type": "A",
193+
"content": "127.0.0.1"
194+
}
195+
]
196+
},
197+
status=200,
198+
)
199+
200+
domain: Type[Domain] = transip_minimal_client.domains.get("example.com")
201+
entries: List[Type[DnsEntry]] = domain.dns.list() # type: ignore
202+
entry: Type[DnsEntry] = entries[0]
203+
assert len(entries) == 1
204+
assert entry.name == "www" # type: ignore

transip/v6/services/domain.py

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,82 @@
2323
from transip.mixins import GetMixin, DeleteMixin, ListMixin
2424

2525

26-
class Domain(ApiObject):
26+
class WhoisContact(ApiObject):
27+
28+
_id_attr: Optional[str] = None
2729

28-
_id_attr: str = "name"
2930

30-
def contacts(self):
31-
service = WhoisContactService(self.service.client, parent=self)
32-
return service.list()
31+
class WhoisContactService(ListMixin, ApiService):
32+
"""Service to manage domain contacts of a domain."""
3333

34+
_path: str = "/domains/{parent_id}/contacts"
35+
_obj_cls: Optional[Type[ApiObject]] = WhoisContact
3436

35-
class WhoisContact(ApiObject):
37+
_resp_list_attr: str = "contacts"
38+
39+
40+
class DnsEntry(ApiObject):
3641

3742
_id_attr: Optional[str] = None
3843

3944

45+
class DnsEntryService(ListMixin, ApiService):
46+
"""Service to manage DNS entries of a domain."""
47+
48+
_path: str = "/domains/{parent_id}/dns"
49+
_obj_cls: Optional[Type[ApiObject]] = DnsEntry
50+
51+
_resp_list_attr: str = "dnsEntries"
52+
53+
54+
class Nameserver(ApiObject):
55+
56+
_id_attr: Optional[str] = "hostname"
57+
58+
59+
class NameserverService(ListMixin, ApiService):
60+
"""Service to nameservers of a domain."""
61+
62+
_path: str = "/domains/{parent_id}/nameservers"
63+
_obj_cls: Optional[Type[ApiObject]] = Nameserver
64+
65+
_resp_list_attr: str = "nameservers"
66+
67+
68+
class Domain(ApiObject):
69+
70+
_id_attr: str = "name"
71+
72+
@property
73+
def contacts(self) -> WhoisContactService:
74+
"""Return the service to manage the WHOIS contacts of the domain."""
75+
return WhoisContactService(
76+
self.service.client,
77+
parent=self # type: ignore
78+
)
79+
80+
@property
81+
def dns(self) -> DnsEntryService:
82+
"""Return the service to manage the DNS entries of the domain."""
83+
return DnsEntryService(
84+
self.service.client,
85+
parent=self # type: ignore
86+
)
87+
88+
@property
89+
def nameservers(self) -> NameserverService:
90+
"""Return the service to manage the nameservers of the domain."""
91+
return NameserverService(
92+
self.service.client,
93+
parent=self # type: ignore
94+
)
95+
96+
4097
class DomainService(GetMixin, DeleteMixin, ListMixin, ApiService):
98+
"""Service to manage domain."""
4199

42100
_path: str = "/domains"
43101
_obj_cls: Optional[Type[ApiObject]] = Domain
44102

45103
_resp_list_attr: str = "domains"
46104
_resp_get_attr: str = "domain"
47-
48-
49-
class WhoisContactService(ListMixin, ApiService):
50-
51-
_path: str = "/domains/{parent_id}/contacts"
52-
_obj_cls: Optional[Type[ApiObject]] = WhoisContact
53-
54-
_resp_list_attr: str = "contacts"

0 commit comments

Comments
 (0)