core/homeassistant/components/route53/__init__.py

119 lines
3.4 KiB
Python

"""Update the IP addresses of your Route53 DNS records."""
from datetime import timedelta
import logging
from typing import List
import boto3
import requests
import voluptuous as vol
from homeassistant.const import CONF_DOMAIN, CONF_TTL, CONF_ZONE, HTTP_OK
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.event import track_time_interval
_LOGGER = logging.getLogger(__name__)
CONF_ACCESS_KEY_ID = "aws_access_key_id"
CONF_SECRET_ACCESS_KEY = "aws_secret_access_key"
CONF_RECORDS = "records"
DOMAIN = "route53"
INTERVAL = timedelta(minutes=60)
DEFAULT_TTL = 300
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_ACCESS_KEY_ID): cv.string,
vol.Required(CONF_DOMAIN): cv.string,
vol.Required(CONF_RECORDS): vol.All(cv.ensure_list, [cv.string]),
vol.Required(CONF_SECRET_ACCESS_KEY): cv.string,
vol.Required(CONF_ZONE): cv.string,
vol.Optional(CONF_TTL, default=DEFAULT_TTL): cv.positive_int,
}
)
},
extra=vol.ALLOW_EXTRA,
)
def setup(hass, config):
"""Set up the Route53 component."""
domain = config[DOMAIN][CONF_DOMAIN]
records = config[DOMAIN][CONF_RECORDS]
zone = config[DOMAIN][CONF_ZONE]
aws_access_key_id = config[DOMAIN][CONF_ACCESS_KEY_ID]
aws_secret_access_key = config[DOMAIN][CONF_SECRET_ACCESS_KEY]
ttl = config[DOMAIN][CONF_TTL]
def update_records_interval(now):
"""Set up recurring update."""
_update_route53(
aws_access_key_id, aws_secret_access_key, zone, domain, records, ttl
)
def update_records_service(now):
"""Set up service for manual trigger."""
_update_route53(
aws_access_key_id, aws_secret_access_key, zone, domain, records, ttl
)
track_time_interval(hass, update_records_interval, INTERVAL)
hass.services.register(DOMAIN, "update_records", update_records_service)
return True
def _update_route53(
aws_access_key_id: str,
aws_secret_access_key: str,
zone: str,
domain: str,
records: List[str],
ttl: int,
):
_LOGGER.debug("Starting update for zone %s", zone)
client = boto3.client(
DOMAIN,
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
)
# Get the IP Address and build an array of changes
try:
ipaddress = requests.get("https://api.ipify.org/", timeout=5).text
except requests.RequestException:
_LOGGER.warning("Unable to reach the ipify service")
return
changes = []
for record in records:
_LOGGER.debug("Processing record: %s", record)
changes.append(
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": f"{record}.{domain}",
"Type": "A",
"TTL": ttl,
"ResourceRecords": [{"Value": ipaddress}],
},
}
)
_LOGGER.debug("Submitting the following changes to Route53")
_LOGGER.debug(changes)
response = client.change_resource_record_sets(
HostedZoneId=zone, ChangeBatch={"Changes": changes}
)
_LOGGER.debug("Response is %s", response)
if response["ResponseMetadata"]["HTTPStatusCode"] != HTTP_OK:
_LOGGER.warning(response)