zboxapi 0.0.4__tar.gz → 0.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.5"
|
|
@@ -3,8 +3,6 @@ import fcntl
|
|
|
3
3
|
import os
|
|
4
4
|
import re
|
|
5
5
|
import socket
|
|
6
|
-
|
|
7
|
-
# import ssl
|
|
8
6
|
import subprocess
|
|
9
7
|
import time
|
|
10
8
|
from ipaddress import IPv4Address
|
|
@@ -18,6 +16,8 @@ from fastapi.security.api_key import APIKey, APIKeyHeader
|
|
|
18
16
|
from pydantic import AfterValidator, BaseModel
|
|
19
17
|
from pydantic_core import PydanticCustomError
|
|
20
18
|
|
|
19
|
+
from zboxapi import __version__
|
|
20
|
+
|
|
21
21
|
api_key_header = APIKeyHeader(name="access_token", auto_error=False)
|
|
22
22
|
|
|
23
23
|
|
|
@@ -120,29 +120,17 @@ def simplify_operation_ids(api: FastAPI) -> None:
|
|
|
120
120
|
route.operation_id = f"{tag}_{route.name}"
|
|
121
121
|
|
|
122
122
|
|
|
123
|
-
def
|
|
124
|
-
return obj if isinstance(obj, list) else [obj]
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def ip_fqdn_str(obj, ip_key="ip", fqdn_key="fqdn"):
|
|
128
|
-
return f"ip={getattr(obj, ip_key)}, fqdn={getattr(obj, fqdn_key)}"
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def ip_fqdn_dict(obj, ip_key="ip", fqdn_key="fqdn"):
|
|
132
|
-
return {"ip": getattr(obj, ip_key), "fqdn": getattr(obj, fqdn_key)}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def RecordNotFound(obj, ip_key="ip", fqdn_key="fqdn"):
|
|
123
|
+
def RecordNotFound(ip, fqdn):
|
|
136
124
|
return HTTPException(
|
|
137
|
-
status_code=status.
|
|
138
|
-
detail=f"
|
|
125
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
126
|
+
detail=f"DNS record not found: ip={ip}, fqdn={fqdn}",
|
|
139
127
|
)
|
|
140
128
|
|
|
141
129
|
|
|
142
|
-
def RecordAlreadyPresent(
|
|
130
|
+
def RecordAlreadyPresent(ip, fqdn):
|
|
143
131
|
return HTTPException(
|
|
144
132
|
status_code=status.HTTP_406_NOT_ACCEPTABLE,
|
|
145
|
-
detail=f"
|
|
133
|
+
detail=f"DNS record already present: ip={ip}, fqdn={fqdn}",
|
|
146
134
|
)
|
|
147
135
|
|
|
148
136
|
|
|
@@ -176,79 +164,92 @@ def validate_fqdn(value: str):
|
|
|
176
164
|
FQDN = Annotated[str, AfterValidator(validate_fqdn)]
|
|
177
165
|
|
|
178
166
|
|
|
179
|
-
class
|
|
167
|
+
class DnsCreate(BaseModel):
|
|
180
168
|
ip: IPv4Address
|
|
181
169
|
fqdn: FQDN
|
|
182
170
|
|
|
183
171
|
|
|
184
|
-
class
|
|
172
|
+
class DnsDelete(BaseModel):
|
|
185
173
|
ip: IPv4Address
|
|
186
174
|
fqdn: FQDN
|
|
187
175
|
|
|
188
176
|
|
|
189
|
-
class
|
|
177
|
+
class DnsUpdate(BaseModel):
|
|
190
178
|
ip: IPv4Address
|
|
191
179
|
fqdn: FQDN
|
|
192
|
-
new_ip: IPv4Address
|
|
193
|
-
new_fqdn: FQDN
|
|
194
180
|
|
|
195
181
|
|
|
196
|
-
class
|
|
182
|
+
class DnsView(BaseModel):
|
|
197
183
|
ip: IPv4Address
|
|
198
184
|
fqdn: str
|
|
199
185
|
|
|
200
186
|
|
|
201
|
-
|
|
187
|
+
dns_router = APIRouter(prefix="/dns", tags=["dns"])
|
|
202
188
|
|
|
203
189
|
|
|
204
|
-
@
|
|
205
|
-
def
|
|
206
|
-
ip: IPv4Address | None = None,
|
|
207
|
-
fqdn: str | None = None,
|
|
208
|
-
) -> list[HostsView]:
|
|
190
|
+
@dns_router.get("")
|
|
191
|
+
def dns_get_all() -> list[DnsView]:
|
|
209
192
|
with get_hosts_file_object() as hosts_fo:
|
|
210
193
|
hosts_lines = get_hosts_lines(hosts_fo)
|
|
211
|
-
hosts_lines = filter_hosts_file(hosts_lines, ip, fqdn)
|
|
212
194
|
return hosts_lines
|
|
213
195
|
|
|
214
196
|
|
|
215
|
-
@
|
|
216
|
-
def
|
|
197
|
+
@dns_router.get("/{ip}/{fqdn}")
|
|
198
|
+
def dns_get(
|
|
199
|
+
ip: IPv4Address,
|
|
200
|
+
fqdn: FQDN,
|
|
201
|
+
) -> DnsView:
|
|
202
|
+
with get_hosts_file_object() as hosts_fo:
|
|
203
|
+
hosts_lines = get_hosts_lines(hosts_fo)
|
|
204
|
+
hosts_lines = filter_hosts_file(hosts_lines, ip, fqdn)
|
|
205
|
+
if not hosts_lines:
|
|
206
|
+
raise RecordNotFound(ip, fqdn)
|
|
207
|
+
return hosts_lines[0]
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
@dns_router.post("")
|
|
211
|
+
def dns_add(
|
|
212
|
+
dns_in: DnsCreate,
|
|
213
|
+
) -> list[DnsView]:
|
|
217
214
|
with get_hosts_file_object() as hosts_fo:
|
|
218
215
|
hosts_lines = get_hosts_lines(hosts_fo)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
hosts_lines.append(ip_fqdn_dict(line))
|
|
216
|
+
if filter_hosts_file(hosts_lines, dns_in.ip, dns_in.fqdn):
|
|
217
|
+
raise RecordAlreadyPresent(dns_in.ip, dns_in.fqdn)
|
|
218
|
+
hosts_lines.append({"ip": dns_in.ip, "fqdn": dns_in.fqdn})
|
|
223
219
|
write_hosts_file(hosts_fo, hosts_lines)
|
|
224
220
|
dnsmasq_sighup()
|
|
225
221
|
return hosts_lines
|
|
226
222
|
|
|
227
223
|
|
|
228
|
-
@
|
|
229
|
-
def
|
|
224
|
+
@dns_router.put("/{ip}/{fqdn}")
|
|
225
|
+
def dns_update(
|
|
226
|
+
ip: IPv4Address,
|
|
227
|
+
fqdn: FQDN,
|
|
228
|
+
dns_in: DnsUpdate,
|
|
229
|
+
) -> list[DnsView]:
|
|
230
230
|
with get_hosts_file_object() as hosts_fo:
|
|
231
231
|
hosts_lines = get_hosts_lines(hosts_fo)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
hosts_lines[ix] = ip_fqdn_dict(line, "new_ip", "new_fqdn")
|
|
232
|
+
key = {"ip": ip, "fqdn": fqdn}
|
|
233
|
+
if key not in hosts_lines:
|
|
234
|
+
raise RecordNotFound(ip, fqdn)
|
|
235
|
+
ix = hosts_lines.index(key)
|
|
236
|
+
hosts_lines[ix] = {"ip": dns_in.ip, "fqdn": dns_in.fqdn}
|
|
238
237
|
write_hosts_file(hosts_fo, hosts_lines)
|
|
239
238
|
dnsmasq_sighup()
|
|
240
239
|
return hosts_lines
|
|
241
240
|
|
|
242
241
|
|
|
243
|
-
@
|
|
244
|
-
def
|
|
242
|
+
@dns_router.delete("/{ip}/{fqdn}")
|
|
243
|
+
def dns_delete(
|
|
244
|
+
ip: IPv4Address,
|
|
245
|
+
fqdn: FQDN,
|
|
246
|
+
) -> list[DnsView]:
|
|
245
247
|
with get_hosts_file_object() as hosts_fo:
|
|
246
248
|
hosts_lines = get_hosts_lines(hosts_fo)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
hosts_lines.remove(key)
|
|
249
|
+
key = {"ip": ip, "fqdn": fqdn}
|
|
250
|
+
if key not in hosts_lines:
|
|
251
|
+
raise RecordNotFound(ip, fqdn)
|
|
252
|
+
hosts_lines.remove(key)
|
|
252
253
|
write_hosts_file(hosts_fo, hosts_lines)
|
|
253
254
|
dnsmasq_sighup()
|
|
254
255
|
return hosts_lines
|
|
@@ -260,8 +261,9 @@ app = FastAPI(
|
|
|
260
261
|
title="zBox API",
|
|
261
262
|
root_path=zboxapi_root_path,
|
|
262
263
|
dependencies=[Depends(validate_api_key)],
|
|
264
|
+
version=__version__,
|
|
263
265
|
)
|
|
264
|
-
app.include_router(
|
|
266
|
+
app.include_router(dns_router)
|
|
265
267
|
simplify_operation_ids(app)
|
|
266
268
|
|
|
267
269
|
ZPOD_PASSWORD = get_zpod_password()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.4"
|
|
File without changes
|