Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CoreDNS as DNS backend #1195

Merged
merged 44 commits into from Aug 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ee55137
Add CoreDNS / DNS configuration
pvizeli Aug 9, 2019
139c26d
Support get version
pvizeli Aug 9, 2019
fdec7f2
add version
pvizeli Aug 9, 2019
67b1443
add coresys
pvizeli Aug 9, 2019
055ec21
Add more logic
pvizeli Aug 9, 2019
371c890
move forwareder into dns
pvizeli Aug 9, 2019
2cd043f
Setup docker inside
pvizeli Aug 10, 2019
86f2c6a
add docker to env
pvizeli Aug 10, 2019
2aa8e36
Add more function
pvizeli Aug 10, 2019
0ad711d
more interface
pvizeli Aug 10, 2019
9c23e5d
Update hosts template
pvizeli Aug 10, 2019
7ef7072
Add DNS folder
pvizeli Aug 10, 2019
a04e07e
Fix issues
pvizeli Aug 10, 2019
698aa14
Add more logic
pvizeli Aug 10, 2019
21fdc2c
Add handling for hosts
pvizeli Aug 10, 2019
f458ead
Fix setting
pvizeli Aug 11, 2019
5bc9be4
fix lint
pvizeli Aug 11, 2019
294f92a
Fix some issues
pvizeli Aug 11, 2019
37593a5
Fix issue
pvizeli Aug 11, 2019
a39b787
Run with no cache
pvizeli Aug 11, 2019
940e482
Fix issue on validate
pvizeli Aug 11, 2019
4fa0102
Fix bug
pvizeli Aug 12, 2019
2c66d69
Merge remote-tracking branch 'origin/dev' into dns-v2
pvizeli Aug 12, 2019
75c3978
Allow to jump into dev mode
pvizeli Aug 12, 2019
e3de668
Fix permission
pvizeli Aug 12, 2019
adc63d1
Fix issue
pvizeli Aug 12, 2019
3277f95
Add dns search
pvizeli Aug 12, 2019
4369944
Add watchdog
pvizeli Aug 12, 2019
6f0a4c3
Fix set issues
pvizeli Aug 12, 2019
2cf4c04
add API description
pvizeli Aug 12, 2019
6494a47
Add API endpoint
pvizeli Aug 12, 2019
5345894
Add CLI support
pvizeli Aug 13, 2019
c56d666
Fix logs + add hostname
pvizeli Aug 13, 2019
30a36aa
Add/remove DNS entry
pvizeli Aug 13, 2019
303f769
Fix attribute
pvizeli Aug 13, 2019
b3eb5f2
Fix style
pvizeli Aug 13, 2019
6489036
Better shutdown
pvizeli Aug 13, 2019
28e36da
Remove ha from network mapping
pvizeli Aug 13, 2019
e2ec9e1
Add more options
pvizeli Aug 13, 2019
226b963
Fix env shutdown
pvizeli Aug 13, 2019
3cf7c26
Add support for new repair function
pvizeli Aug 13, 2019
42cf80e
Start coreDNS faster after restart
pvizeli Aug 13, 2019
7960ac7
remove options
pvizeli Aug 13, 2019
7cc1387
Fix ha fix
pvizeli Aug 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 19 additions & 3 deletions .devcontainer/Dockerfile
@@ -1,8 +1,8 @@
FROM python:3.7

WORKDIR /workspace
WORKDIR /workspaces

# install Node/Yarn for Frontent
# Install Node/Yarn for Frontent
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
Expand All @@ -17,8 +17,24 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
ENV NVM_DIR /root/.nvm

# Install docker
# https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/
RUN apt-get update && apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
curl \
software-properties-common \
gpg-agent \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \
&& add-apt-repository "deb https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
&& apt-get update && apt-get install -y --no-install-recommends \
docker-ce \
docker-ce-cli \
containerd.io \
&& rm -rf /var/lib/apt/lists/*

# Install Python dependencies from requirements.txt if it exists
COPY requirements.txt requirements_tests.txt /workspace/
COPY requirements.txt requirements_tests.txt /workspaces/
RUN pip install -r requirements.txt \
&& pip3 install -r requirements_tests.txt \
&& pip install black tox
Expand Down
6 changes: 4 additions & 2 deletions .devcontainer/devcontainer.json
Expand Up @@ -3,9 +3,11 @@
"name": "Hass.io dev",
"context": "..",
"dockerFile": "Dockerfile",
"appPort": "9123:8123",
"runArgs": [
"-e",
"GIT_EDTIOR='code --wait'"
"GIT_EDITOR='code --wait'",
"--privileged"
],
"extensions": [
"ms-python.python"
Expand All @@ -24,4 +26,4 @@
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true
}
}
}
3 changes: 3 additions & 0 deletions .dockerignore
Expand Up @@ -18,3 +18,6 @@ venv/
home-assistant-polymer/*
misc/*
script/*

# Test ENV
data/
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -95,3 +95,6 @@ ENV/
.vscode/*
!.vscode/cSpell.json
!.vscode/tasks.json

# Test Env
test_data/
73 changes: 73 additions & 0 deletions .vscode/tasks.json
@@ -1,6 +1,34 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Testenv",
"type": "shell",
"command": "./script/test_env.sh",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Run Testenv CLI",
"type": "shell",
"command": "docker run --rm -ti -v /etc/machine-id:/etc/machine-id --network=hassio --add-host hassio:172.30.32.2 homeassistant/amd64-hassio-cli:dev",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Update UI",
"type": "shell",
Expand All @@ -14,6 +42,51 @@
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Pytest",
"type": "shell",
"command": "pytest --timeout=10 tests",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Flake8",
"type": "shell",
"command": "flake8 homeassistant tests",
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
},
{
"label": "Pylint",
"type": "shell",
"command": "pylint homeassistant",
"dependsOn": [
"Install all Requirements"
],
"group": {
"kind": "test",
"isDefault": true,
},
"presentation": {
"reveal": "always",
"panel": "new"
},
"problemMatcher": []
}
]
}
42 changes: 42 additions & 0 deletions API.md
Expand Up @@ -473,6 +473,7 @@ Get all available addons.
{
"name": "xy bla",
"slug": "xdssd_xybla",
"hostname": "xdssd-xybla",
"description": "description",
"long_description": "null|markdown",
"auto_update": "bool",
Expand Down Expand Up @@ -739,6 +740,47 @@ return:
}
```

### DNS

- GET `/dns/info`
```json
{
"host": "ip-address",
"version": "1",
"latest_version": "2",
"servers": ["dns://8.8.8.8"]
}
```

- POST `/dns/options`
```json
{
"servers": ["dns://8.8.8.8"]
}
```

- POST `/dns/update`
```json
{
"version": "VERSION"
}
```

- GET `/dns/logs`

- GET `/dns/stats`
```json
{
"cpu_percent": 0.0,
"memory_usage": 283123,
"memory_limit": 329392,
"network_tx": 0,
"network_rx": 0,
"blk_read": 0,
"blk_write": 0
}
```

### Auth / SSO API

You can use the user system on homeassistant. We handle this auth system on
Expand Down
5 changes: 5 additions & 0 deletions hassio/addons/model.py
Expand Up @@ -109,6 +109,11 @@ def name(self) -> str:
"""Return name of add-on."""
return self.data[ATTR_NAME]

@property
def hostname(self) -> str:
"""Return slug/id of add-on."""
return self.slug.replace("_", "-")

@property
def timeout(self) -> int:
"""Return timeout of addon for docker stop."""
Expand Down
17 changes: 17 additions & 0 deletions hassio/api/__init__.py
Expand Up @@ -9,6 +9,7 @@
from .addons import APIAddons
from .auth import APIAuth
from .discovery import APIDiscovery
from .dns import APICoreDNS
from .hardware import APIHardware
from .hassos import APIHassOS
from .homeassistant import APIHomeAssistant
Expand Down Expand Up @@ -55,6 +56,7 @@ async def load(self) -> None:
self._register_services()
self._register_info()
self._register_auth()
self._register_dns()

def _register_host(self) -> None:
"""Register hostcontrol functions."""
Expand Down Expand Up @@ -264,6 +266,21 @@ def _register_discovery(self) -> None:
]
)

def _register_dns(self) -> None:
"""Register DNS functions."""
api_dns = APICoreDNS()
api_dns.coresys = self.coresys

self.webapp.add_routes(
[
web.get("/dns/info", api_dns.info),
web.get("/dns/stats", api_dns.stats),
web.get("/dns/logs", api_dns.logs),
web.post("/dns/update", api_dns.update),
web.post("/dns/options", api_dns.options),
]
)

def _register_panel(self) -> None:
"""Register panel for Home Assistant."""
panel_dir = Path(__file__).parent.joinpath("panel")
Expand Down
2 changes: 2 additions & 0 deletions hassio/api/addons.py
Expand Up @@ -41,6 +41,7 @@
ATTR_HOST_IPC,
ATTR_HOST_NETWORK,
ATTR_HOST_PID,
ATTR_HOSTNAME,
ATTR_ICON,
ATTR_INGRESS,
ATTR_INGRESS_ENTRY,
Expand Down Expand Up @@ -180,6 +181,7 @@ async def info(self, request: web.Request) -> Dict[str, Any]:
data = {
ATTR_NAME: addon.name,
ATTR_SLUG: addon.slug,
ATTR_HOSTNAME: addon.hostname,
ATTR_DESCRIPTON: addon.description,
ATTR_LONG_DESCRIPTION: addon.long_description,
ATTR_AUTO_UPDATE: None,
Expand Down
87 changes: 87 additions & 0 deletions hassio/api/dns.py
@@ -0,0 +1,87 @@
"""Init file for Hass.io DNS RESTful API."""
import asyncio
import logging
from typing import Any, Awaitable, Dict

from aiohttp import web
import voluptuous as vol

from ..const import (
ATTR_BLK_READ,
ATTR_BLK_WRITE,
ATTR_CPU_PERCENT,
ATTR_HOST,
ATTR_LATEST_VERSION,
ATTR_MEMORY_LIMIT,
ATTR_MEMORY_USAGE,
ATTR_NETWORK_RX,
ATTR_NETWORK_TX,
ATTR_SERVERS,
ATTR_VERSION,
CONTENT_TYPE_BINARY,
)
from ..coresys import CoreSysAttributes
from ..exceptions import APIError
from ..validate import DNS_SERVER_LIST
from .utils import api_process, api_process_raw, api_validate

_LOGGER = logging.getLogger(__name__)

# pylint: disable=no-value-for-parameter
SCHEMA_OPTIONS = vol.Schema({vol.Optional(ATTR_SERVERS): DNS_SERVER_LIST})

SCHEMA_VERSION = vol.Schema({vol.Optional(ATTR_VERSION): vol.Coerce(str)})


class APICoreDNS(CoreSysAttributes):
"""Handle RESTful API for DNS functions."""

@api_process
async def info(self, request: web.Request) -> Dict[str, Any]:
"""Return DNS information."""
return {
ATTR_VERSION: self.sys_dns.version,
ATTR_LATEST_VERSION: self.sys_dns.latest_version,
ATTR_HOST: str(self.sys_docker.network.dns),
ATTR_SERVERS: self.sys_dns.servers,
}

@api_process
async def options(self, request: web.Request) -> None:
"""Set DNS options."""
body = await api_validate(SCHEMA_OPTIONS, request)

if ATTR_SERVERS in body:
self.sys_dns.servers = body[ATTR_SERVERS]

self.sys_dns.save_data()

@api_process
async def stats(self, request: web.Request) -> Dict[str, Any]:
"""Return resource information."""
stats = await self.sys_dns.stats()

return {
ATTR_CPU_PERCENT: stats.cpu_percent,
ATTR_MEMORY_USAGE: stats.memory_usage,
ATTR_MEMORY_LIMIT: stats.memory_limit,
ATTR_NETWORK_RX: stats.network_rx,
ATTR_NETWORK_TX: stats.network_tx,
ATTR_BLK_READ: stats.blk_read,
ATTR_BLK_WRITE: stats.blk_write,
}

@api_process
async def update(self, request: web.Request) -> None:
"""Update DNS plugin."""
body = await api_validate(SCHEMA_VERSION, request)
version = body.get(ATTR_VERSION, self.sys_dns.latest_version)

if version == self.sys_dns.version:
raise APIError("Version {} is already in use".format(version))
await asyncio.shield(self.sys_dns.update(version))

@api_process_raw(CONTENT_TYPE_BINARY)
def logs(self, request: web.Request) -> Awaitable[bytes]:
"""Return DNS Docker logs."""
return self.sys_dns.logs()
4 changes: 3 additions & 1 deletion hassio/arch.py
Expand Up @@ -10,6 +10,8 @@

_LOGGER = logging.getLogger(__name__)

ARCH_JSON: Path = Path(__file__).parent.joinpath("data/arch.json")

MAP_CPU = {
"armv7": "armv7",
"armv6": "armhf",
Expand Down Expand Up @@ -47,7 +49,7 @@ def supported(self) -> List[str]:
async def load(self) -> None:
"""Load data and initialize default arch."""
try:
arch_data = read_json_file(Path(__file__).parent.joinpath("arch.json"))
arch_data = read_json_file(ARCH_JSON)
except JsonFileError:
_LOGGER.warning("Can't read arch json")
return
Expand Down