Support adding HE DNS entries
continuous-integration/drone the build failed
Details
continuous-integration/drone the build failed
Details
This commit is contained in:
parent
6e16ac7ec6
commit
7360e0d614
|
@ -14,6 +14,7 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Scone. If not, see <https://www.gnu.org/licenses/>.
|
||||
import logging
|
||||
from asyncio import Lock
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
|
@ -25,14 +26,62 @@ from scone.head.kitchen import Kitchen, Preparation
|
|||
from scone.head.recipe import HeadRecipe, RecipeContext
|
||||
from scone.head.utils import check_type
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class DnsRecord:
|
||||
pass
|
||||
subdomain: str
|
||||
kind: str
|
||||
value: str
|
||||
ttl: Optional[str]
|
||||
priority: Optional[str]
|
||||
|
||||
|
||||
def parse_records(given: Union[Any, Dict[str, Any]]) -> List[DnsRecord]:
|
||||
pass
|
||||
def parse_records(given_raw: Union[Any, Dict[str, Dict[str, str]]]) -> List[DnsRecord]:
|
||||
given = check_type(given_raw, dict, "records")
|
||||
|
||||
the_list: List[DnsRecord] = []
|
||||
|
||||
for key, attributes in given.items():
|
||||
# keys: "xyz A"
|
||||
# values: dicts, with keys:
|
||||
# - v: 1.2.3.4
|
||||
# - ttl: 86400
|
||||
# - priority: 50 (for MXes)
|
||||
|
||||
pieces = key.split(" ")
|
||||
if len(pieces) > 2:
|
||||
raise ValueError(
|
||||
f"Key {key} should be space-separable with 2 or less pieces."
|
||||
)
|
||||
|
||||
if len(pieces) == 2:
|
||||
subdomain, kind = pieces
|
||||
else:
|
||||
assert len(pieces) == 1
|
||||
(kind,) = pieces
|
||||
subdomain = ""
|
||||
|
||||
ttl_raw = attributes.get("ttl")
|
||||
prio_raw = attributes.get("priority")
|
||||
|
||||
record_value = attributes.get("v", attributes.get("value", None))
|
||||
|
||||
if record_value is None:
|
||||
raise ValueError("No record value")
|
||||
|
||||
the_list.append(
|
||||
DnsRecord(
|
||||
subdomain=subdomain,
|
||||
kind=kind,
|
||||
value=record_value,
|
||||
ttl=None if ttl_raw is None else str(ttl_raw),
|
||||
priority=None if prio_raw is None else str(prio_raw),
|
||||
)
|
||||
)
|
||||
|
||||
return the_list
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
|
@ -117,10 +166,43 @@ class HurricaneElectricDns(HeadRecipe):
|
|||
return domain.records
|
||||
|
||||
async def cook(self, kitchen: Kitchen) -> None:
|
||||
# TODO(correctness): can't handle multiple DNS records
|
||||
# with same (type, subdomain)
|
||||
kitchen.get_dependency_tracker().ignore()
|
||||
cached = await self._get_client(kitchen.head)
|
||||
|
||||
records = await self._get_records(cached, cached.domains[self.domain])
|
||||
|
||||
records_cache: Dict[Tuple[str, str], HeRecord] = {}
|
||||
|
||||
for record in records:
|
||||
print(record)
|
||||
dotted_subdomain_suffix = f".{self.domain}"
|
||||
if record.host == self.domain:
|
||||
subdomain = ""
|
||||
elif record.host.endswith(dotted_subdomain_suffix):
|
||||
subdomain = record.host[: -len(dotted_subdomain_suffix)]
|
||||
else:
|
||||
raise ValueError(f"Can't figure out subdomain for {record.host}")
|
||||
|
||||
records_cache[(subdomain, record.type)] = record
|
||||
|
||||
logger.debug("Present records: %r", records_cache.keys())
|
||||
|
||||
for wanted_record in self.records:
|
||||
wr_key = (wanted_record.subdomain, wanted_record.kind)
|
||||
logger.debug("Want %r: %r", wr_key, wanted_record)
|
||||
existing_record = records_cache.get(wr_key)
|
||||
if existing_record is not None:
|
||||
# TODO(correctness): amend as needed
|
||||
logger.debug("Found existing %r", existing_record)
|
||||
else:
|
||||
logger.debug("Will need to create new one")
|
||||
async with cached.lock:
|
||||
cached.client.add_record(
|
||||
self.domain,
|
||||
wanted_record.subdomain,
|
||||
wanted_record.kind,
|
||||
wanted_record.value,
|
||||
wanted_record.priority or None,
|
||||
wanted_record.ttl or 86400,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue