refactor vscale output provider
reuse client with headers, base_url enable http2
This commit is contained in:
parent
952d043fc9
commit
cb57ed07de
@ -11,111 +11,85 @@ class VscaleDomains(BaseOutputProvider):
|
||||
self.__token = self.get_api_token()
|
||||
if not self.__token:
|
||||
raise KeyError("no api token, use env VSCALE_API_TOKEN")
|
||||
target = self.config["target"]
|
||||
self.domain = self.config["domain"]
|
||||
self.target = f"{target}.{self.domain}"
|
||||
self.ttl = self.config.get("ttl", 300)
|
||||
|
||||
def get_api_token(self) -> str:
|
||||
token_env = self.config.get("api_token_env", "VSCALE_API_TOKEN")
|
||||
return os.environ[token_env]
|
||||
|
||||
async def find_domain_id(self, transport) -> Optional[int]:
|
||||
domain = self.config["domain"]
|
||||
headers = {"X-Token": self.__token}
|
||||
async with httpx.AsyncClient(transport=transport) as client:
|
||||
response = await client.get(
|
||||
"https://api.vscale.io/v1/domains/", headers=headers
|
||||
)
|
||||
if httpx.codes.is_success(response.status_code):
|
||||
data = response.json()
|
||||
if isinstance(data, list):
|
||||
for entry in data:
|
||||
if entry["name"] == domain:
|
||||
return entry["id"]
|
||||
else:
|
||||
raise TypeError(
|
||||
"failed to find domain id, unexpected response type"
|
||||
)
|
||||
async def find_domain_id(self, client) -> Optional[int]:
|
||||
response = await client.get("/domains/")
|
||||
if httpx.codes.is_success(response.status_code):
|
||||
data = response.json()
|
||||
if isinstance(data, list):
|
||||
for entry in data:
|
||||
if entry["name"] == self.domain:
|
||||
return entry["id"]
|
||||
else:
|
||||
raise ValueError(
|
||||
f"failed to find domain id, code: {response.status_code}"
|
||||
)
|
||||
raise TypeError("failed to find domain id, unexpected response type")
|
||||
else:
|
||||
raise ValueError(f"failed to find domain id, code: {response.status_code}")
|
||||
|
||||
async def find_record(self, transport, domain_id, record_type) -> Optional[int]:
|
||||
target = self.config["target"]
|
||||
domain = self.config["domain"]
|
||||
target = f"{target}.{domain}"
|
||||
headers = {"X-Token": self.__token}
|
||||
async with httpx.AsyncClient(transport=transport) as client:
|
||||
response = await client.get(
|
||||
f"https://api.vscale.io/v1/domains/{domain_id}/records/",
|
||||
headers=headers,
|
||||
async def find_record(self, client, domain_id, record_type) -> Optional[int]:
|
||||
response = await client.get(
|
||||
f"/domains/{domain_id}/records/",
|
||||
)
|
||||
if httpx.codes.is_success(response.status_code):
|
||||
data = response.json()
|
||||
if isinstance(data, list):
|
||||
for entry in data:
|
||||
if entry["name"] == self.target and entry["type"] == record_type:
|
||||
return entry["id"]
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f"error list records {domain_id=}: ", response.status_code
|
||||
)
|
||||
if httpx.codes.is_success(response.status_code):
|
||||
data = response.json()
|
||||
if isinstance(data, list):
|
||||
for entry in data:
|
||||
if entry["name"] == target and entry["type"] == record_type:
|
||||
return entry["id"]
|
||||
else:
|
||||
raise RuntimeError(
|
||||
f"error list records {domain_id=}: ", response.status_code
|
||||
)
|
||||
|
||||
async def get_record_value(self, transport, domain_id, record_id) -> str:
|
||||
headers = {"X-Token": self.__token}
|
||||
async with httpx.AsyncClient(transport=transport) as client:
|
||||
response = await client.get(
|
||||
f"https://api.vscale.io/v1/domains/{domain_id}/records/{record_id}",
|
||||
headers=headers,
|
||||
)
|
||||
if httpx.codes.is_success(response.status_code):
|
||||
data = response.json()
|
||||
if isinstance(data, dict):
|
||||
return data["content"]
|
||||
async def get_record_value(self, client, domain_id, record_id) -> str:
|
||||
response = await client.get(f"/domains/{domain_id}/records/{record_id}")
|
||||
if httpx.codes.is_success(response.status_code):
|
||||
data = response.json()
|
||||
if isinstance(data, dict):
|
||||
return data["content"]
|
||||
|
||||
async def change_record(self, transport, domain_id, record_id, record_type, value):
|
||||
target = self.config["target"]
|
||||
domain = self.config["domain"]
|
||||
target = f"{target}.{domain}"
|
||||
ttl = self.config.get("ttl", 300)
|
||||
headers = {"X-Token": self.__token, "Content-Type": "application/json"}
|
||||
async def change_record(self, client, domain_id, record_id, record_type, value):
|
||||
data = {
|
||||
"content": value,
|
||||
"name": target,
|
||||
"ttl": ttl,
|
||||
"name": self.target,
|
||||
"ttl": self.ttl,
|
||||
"type": record_type,
|
||||
"id": record_id,
|
||||
}
|
||||
async with httpx.AsyncClient(transport=transport) as client:
|
||||
response = await client.put(
|
||||
f"https://api.vscale.io/v1/domains/{domain_id}/records/{record_id}",
|
||||
headers=headers,
|
||||
json=data,
|
||||
)
|
||||
if not httpx.codes.is_success(response.status_code):
|
||||
raise RuntimeError(
|
||||
f"failed to change record: {target=},{domain_id=}, {record_id=}, {record_type=}, {value=}"
|
||||
)
|
||||
|
||||
async def create_record(self, transport, domain_id, record_type, value):
|
||||
target = self.config["target"]
|
||||
domain = self.config["domain"]
|
||||
target = f"{target}.{domain}"
|
||||
ttl = self.config.get("ttl", 300)
|
||||
headers = {"X-Token": self.__token, "Content-Type": "application/json"}
|
||||
data = {"content": value, "name": target, "ttl": ttl, "type": record_type}
|
||||
async with httpx.AsyncClient(transport=transport) as client:
|
||||
response = await client.post(
|
||||
f"https://api.vscale.io/v1/domains/{domain_id}/records/",
|
||||
headers=headers,
|
||||
json=data,
|
||||
response = await client.put(
|
||||
f"/domains/{domain_id}/records/{record_id}",
|
||||
json=data,
|
||||
)
|
||||
if not httpx.codes.is_success(response.status_code):
|
||||
raise RuntimeError(
|
||||
f"failed to change record: {self.target=},{domain_id=}, {record_id=}, {record_type=}, {value=}"
|
||||
)
|
||||
|
||||
async def create_record(self, client, domain_id, record_type, value):
|
||||
data = {
|
||||
"content": value,
|
||||
"name": self.target,
|
||||
"ttl": self.ttl,
|
||||
"type": record_type,
|
||||
}
|
||||
response = await client.post(
|
||||
f"/domains/{domain_id}/records/",
|
||||
json=data,
|
||||
)
|
||||
if not httpx.codes.is_success(response.status_code):
|
||||
raise RuntimeError(
|
||||
f"failed to create record: {self.target=},{domain_id=}, {record_type=}, {value=}, {response.status_code=}"
|
||||
)
|
||||
if not httpx.codes.is_success(response.status_code):
|
||||
raise RuntimeError(
|
||||
f"failed to create record: {target=},{domain_id=}, {record_type=}, {value=}, {response.status_code=}"
|
||||
)
|
||||
|
||||
async def set_addrs_imp(self, source_provider, addr_v4, addr_v6):
|
||||
transport = self.best_transport(addr_v4, addr_v6)
|
||||
domain_id = await self.find_domain_id(transport)
|
||||
save_ipv4 = self.config.get("ipv4", False)
|
||||
save_ipv6 = self.config.get("ipv6", False)
|
||||
if "ipv4" not in self.config and "ipv6" not in self.config:
|
||||
@ -128,15 +102,26 @@ class VscaleDomains(BaseOutputProvider):
|
||||
if addr_v6 and save_ipv6:
|
||||
save_addrs.append(("AAAA", addr_v6))
|
||||
|
||||
for record_type, value in save_addrs:
|
||||
record_id = await self.find_record(transport, domain_id, record_type)
|
||||
if record_id:
|
||||
old_value = await self.get_record_value(transport, domain_id, record_id)
|
||||
if old_value != value:
|
||||
await self.change_record(
|
||||
transport, domain_id, record_id, record_type, value
|
||||
transport = self.best_transport(addr_v4, addr_v6)
|
||||
api_base = self.config.get("api_base", "https://api.vscale.io/v1/")
|
||||
headers = {"X-Token": self.__token}
|
||||
async with httpx.AsyncClient(
|
||||
transport=transport, base_url=api_base, headers=headers, http2=True
|
||||
) as client:
|
||||
domain_id = await self.find_domain_id(client)
|
||||
for record_type, value in save_addrs:
|
||||
record_id = await self.find_record(client, domain_id, record_type)
|
||||
if record_id:
|
||||
old_value = await self.get_record_value(
|
||||
client, domain_id, record_id
|
||||
)
|
||||
if old_value != value:
|
||||
await self.change_record(
|
||||
client, domain_id, record_id, record_type, value
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f"vscale: skip record change ({record_type=}), value equal"
|
||||
)
|
||||
else:
|
||||
print(f"vscale: skip record change ({record_type=}), value equal")
|
||||
else:
|
||||
await self.create_record(transport, domain_id, record_type, value)
|
||||
await self.create_record(client, domain_id, record_type, value)
|
||||
|
Loading…
Reference in New Issue
Block a user