Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Update the IP addresses of your Route53 DNS records."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 from http import HTTPStatus
7 import logging
8 
9 import boto3
10 import requests
11 import voluptuous as vol
12 
13 from homeassistant.const import CONF_DOMAIN, CONF_TTL, CONF_ZONE
14 from homeassistant.core import HomeAssistant, ServiceCall
16 from homeassistant.helpers.event import track_time_interval
17 from homeassistant.helpers.typing import ConfigType
18 
19 _LOGGER = logging.getLogger(__name__)
20 
21 CONF_ACCESS_KEY_ID = "aws_access_key_id"
22 CONF_SECRET_ACCESS_KEY = "aws_secret_access_key"
23 CONF_RECORDS = "records"
24 
25 DOMAIN = "route53"
26 
27 INTERVAL = timedelta(minutes=60)
28 DEFAULT_TTL = 300
29 
30 CONFIG_SCHEMA = vol.Schema(
31  {
32  DOMAIN: vol.Schema(
33  {
34  vol.Required(CONF_ACCESS_KEY_ID): cv.string,
35  vol.Required(CONF_DOMAIN): cv.string,
36  vol.Required(CONF_RECORDS): vol.All(cv.ensure_list, [cv.string]),
37  vol.Required(CONF_SECRET_ACCESS_KEY): cv.string,
38  vol.Required(CONF_ZONE): cv.string,
39  vol.Optional(CONF_TTL, default=DEFAULT_TTL): cv.positive_int,
40  }
41  )
42  },
43  extra=vol.ALLOW_EXTRA,
44 )
45 
46 
47 def setup(hass: HomeAssistant, config: ConfigType) -> bool:
48  """Set up the Route53 component."""
49  domain = config[DOMAIN][CONF_DOMAIN]
50  records = config[DOMAIN][CONF_RECORDS]
51  zone = config[DOMAIN][CONF_ZONE]
52  aws_access_key_id = config[DOMAIN][CONF_ACCESS_KEY_ID]
53  aws_secret_access_key = config[DOMAIN][CONF_SECRET_ACCESS_KEY]
54  ttl = config[DOMAIN][CONF_TTL]
55 
56  def update_records_interval(now):
57  """Set up recurring update."""
59  aws_access_key_id, aws_secret_access_key, zone, domain, records, ttl
60  )
61 
62  def update_records_service(call: ServiceCall) -> None:
63  """Set up service for manual trigger."""
65  aws_access_key_id, aws_secret_access_key, zone, domain, records, ttl
66  )
67 
68  track_time_interval(hass, update_records_interval, INTERVAL)
69 
70  hass.services.register(DOMAIN, "update_records", update_records_service)
71  return True
72 
73 
74 def _get_fqdn(record, domain):
75  if record == ".":
76  return domain
77  return f"{record}.{domain}"
78 
79 
81  aws_access_key_id: str,
82  aws_secret_access_key: str,
83  zone: str,
84  domain: str,
85  records: list[str],
86  ttl: int,
87 ):
88  _LOGGER.debug("Starting update for zone %s", zone)
89 
90  client = boto3.client(
91  DOMAIN,
92  aws_access_key_id=aws_access_key_id,
93  aws_secret_access_key=aws_secret_access_key,
94  )
95 
96  # Get the IP Address and build an array of changes
97  try:
98  ipaddress = requests.get("https://api.ipify.org/", timeout=5).text
99 
100  except requests.RequestException:
101  _LOGGER.warning("Unable to reach the ipify service")
102  return
103 
104  changes = []
105  for record in records:
106  _LOGGER.debug("Processing record: %s", record)
107 
108  changes.append(
109  {
110  "Action": "UPSERT",
111  "ResourceRecordSet": {
112  "Name": _get_fqdn(record, domain),
113  "Type": "A",
114  "TTL": ttl,
115  "ResourceRecords": [{"Value": ipaddress}],
116  },
117  }
118  )
119 
120  _LOGGER.debug("Submitting the following changes to Route53")
121  _LOGGER.debug(changes)
122 
123  response = client.change_resource_record_sets(
124  HostedZoneId=zone, ChangeBatch={"Changes": changes}
125  )
126  _LOGGER.debug("Response is %s", response)
127 
128  if response["ResponseMetadata"]["HTTPStatusCode"] != HTTPStatus.OK:
129  _LOGGER.warning(response)
def _update_route53(str aws_access_key_id, str aws_secret_access_key, str zone, str domain, list[str] records, int ttl)
Definition: __init__.py:87
bool setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:47
def _get_fqdn(record, domain)
Definition: __init__.py:74