Merge "The New Agent"

This commit is contained in:
Jenkins 2015-03-31 19:18:43 +00:00 committed by Gerrit Code Review
commit 8afd19fc20
1 changed files with 316 additions and 0 deletions

316
specs/kilo/new-agent.rst Normal file
View File

@ -0,0 +1,316 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported License.
http://creativecommons.org/licenses/by/3.0/legalcode
=============================
New Agent
=============================
This spec describes a proposed service for Designate, tentatively called the
"Agent," not to be confused with the current component with the same name.
Terminology
===========
+----------+---------------------------------------------+
| Term | Meaning |
+==========+=============================================+
| AXFR | A DNS zone transfer |
+----------+---------------------------------------------+
| NOTIFY | A DNS protocol to inform of a zone update |
+----------+---------------------------------------------+
| OPCODE | Part of a DNS message that informs action |
| | http://bit.ly/1pfG8Zp |
+----------+---------------------------------------------+
| Backend | Different code paths for various DNS servers|
+----------+---------------------------------------------+
| MiniDNS | Designate component in charge of sending |
| | NOTIFYs, and answering AXFRs. |
+----------+---------------------------------------------+
Problem description
===================
MiniDNS provides a very elegant solution for many DNS installations. Having a
Designate component as the DNS master enables Designate to have a great amount
of control over the DNS server, and makes certain processes much easier to
implement across backends.
However, some deployments may not be able to use MiniDNS as a true DNS Master,
and would rather keep the current style of backends in some form with the added
benefits of MiniDNS. They might need a more specialized type of interaction
between Designate and the DNS server, making Designate more flexible.
Additionally, there are potential problems with having MiniDNS and it's database
being a single point of failure for a DNS infrastructure.
Proposed change
===============
An agent deployed on the Master DNS server that interacts with MiniDNS solves
these problems. A plugable backend that enables users to use any backend with
MiniDNS, as well as the ability to isolate MiniDNS from being a master in
large deployments are much simpler with an Agent.
The Agent would be a standalone service that acts as a sort of mirror to
MiniDNS. It would receive AXFR/IXFR, NOTIFYs, and other notifications and
perform changes to the DNS server through a plugin-style backend.
Pool Manager Changes
--------------------
A new backend for the Pool Manager would be created for the Agent.
It should send fire-and-forget DNS messages with classes and RRTYPE intended for
private use, shown here: http://bit.ly/1soCZTffor on Creates/Deletes, and call
into MiniDNS as it would normally for updates.
Agent Changes
-------------
The agent service will need to be created (possibly supplanting the old "agent")
The structure will be very similar to MiniDNS. A service (TCP, rather than RPC)
will listen for TCP and UDP traffic. NOTIFYs and AXFRs will be handled, along
with regular DNS queries (via pass through to the real DNS server), and the
special DNS CLASSES and RRDTYPEs that are chosen to signify Creates and Deletes.
DNS traffic will result in calls into the configured backend. A special OPCODE,
14 will be used for all non-standard actions like Creating and Deleting zones.
Configuration
^^^^^^^^^^^^^
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
| **Parameter** | **Default** | **Required** | **Notes** |
+==========================+=============+==============+========================================================================================================+
| *backend_driver* | 'None' | Yes | The name of the backend driver to use with the Agent |
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
| *workers* | None | No | The number of worker processes to spawn |
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
| *masters* | [] | Yes | List of IP/Ports of Masters the Agent will query for AXFRs and SOA queries |
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
| *allow-notify* | [] | Yes | List of IP/Ports of Masters allowed to NOTIFY/AXFR with the Agent |
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
| *host* | '0.0.0.0' | Yes | Bind host for the Agent |
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
| *port* | 5354 | Yes | Port to bind to |
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
| *tcp_backlog* | 100 | Yes | TCP backlog for the Agent |
+--------------------------+-------------+--------------+--------------------------------------------------------------------------------------------------------+
There would also be sub-configuration sections for the different backends, using
the form [agent:backend_name]. These would be mostly ported from the current
backends.
Service
^^^^^^^
Initialization of the service, and basic handling of TCP/UDP traffic. Does some
validation on the traffic coming in, making sure it is valid before sending on
to the core application logic. This should be mostly taken from
designate/mdns/service.py
There could be some optimization, since the Agent will be talking only to mdns.
Middleware
^^^^^^^^^^
A thin middleware that sits between the TCP message receiving, and the handler.
Allows for contexts or other metadata to be attached to a request before it goes
to a handler.
Handler
^^^^^^^
The handler will take DNS requests in, and take the appropriate action. This
will be very similar to mdns/handler.py
_handle_update(request, op)
"""""""""""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *request* | Serialized request data from the DNS request | Yes |
+---------------+-----------------------------------------------+--------------+
| *op* | Whether an update or create is happening | Yes |
+---------------+-----------------------------------------------+--------------+
1. Get the name from the request
2. Make sure the requester is in the allowed list of notifiers
3. Call the backend's find_domain to see if the message is for a zone on the DNS
server. If not, throw the message away
4. Query the requesting mdns (SOA), per the RFC (????)
5. Call out to the Agent's AXFR module asynchronously which will perform the
AXFR, get the zone and call backend's create or update domain, based on the
action.
_handle_delete(request)
"""""""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *request* | Serialized request data from the DNS request | Yes |
+---------------+-----------------------------------------------+--------------+
1. Get the name from the request
2. Make sure the requester is in the allowed list of notifiers
3. Call out to the backend's delete_domain
_handle_record_query(request)
"""""""""""""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *request* | Serialized request data from the DNS request | Yes |
+---------------+-----------------------------------------------+--------------+
1. Repackage the request, send it along to the local DNS server
2. Return the results
This is a possible way for the Agent to answer DNS queries when MiniDNS is
polling for changes
AXFR
^^^^
The AXFR module will send the AXFR query to one of the masters specified in the
config for the zone name that was passed in. Based on the type of query that
called for the AXFR, a backend call will then be made with the information
gathered from the AXFR.
_do_axfr(zone_name, action)
"""""""""""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *zone_name* | The zone name to ask for the AXFR with | Yes |
+---------------+-----------------------------------------------+--------------+
| *new_domain* | Boolean value to inform AXFR if the zone is a | No |
| | new zone or not. Default is False | |
+---------------+-----------------------------------------------+--------------+
1. Pick a master from the config file
2. Send the AXFR query
3. Parse the response into a designate domain object
4. Call the backend for the specified action (Create, Update)
.. note:: Eventually this module could be renamed "Transfer" and do IXFRs.
Backend
^^^^^^^
The Backend module will house a base plugin, and a variety of plugins with a
similar interface to the Pool Manager. The intent is to take the zone changes
gleaned from an AXFR (or IXFR) and apply them to the DNS server. The manner of
accomplishing this will vary widely for each DNS server, you might be editing a
flat file, or making database calls, or some other method. The following methods
would compose the base plugin.
find_zone(zone_name)
""""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *zone_name* | The zone name to be searched for | Yes |
+---------------+-----------------------------------------------+--------------+
When a NOTIFY comes in for a zone, the Agent must first check to make sure that
the zone is valid for the DNS server. Otherwise, it might do an AXFR and try to
update a zone that doesn't exist on the server. It's possible that this check
could be incorporated in to the update_zone function, but it seems more
efficient to do it here.
create_zone(domain)
"""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *domain* | A Designate domain object to create on the | Yes |
| | backend server, including it's recordsets | |
+---------------+-----------------------------------------------+--------------+
Take the appropriate measure to create the zone on the DNS server. This object
will hold all the necessary information to serve the zone.
update_zone(domain)
"""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *domain* | A Designate domain object to update on the | Yes |
| | backend server, including it's recordsets | |
+---------------+-----------------------------------------------+--------------+
Take the appropriate measure to update the zone on the DNS server. This has the
potential to be very similar to the create_zone logic if there is no way to
discern the differences between this object, and the zone on the server.
delete_zone(zone_name)
""""""""""""""""""""""
+---------------+-----------------------------------------------+--------------+
| **Parameter** | **Description** | **Required** |
+===============+===============================================+==============+
| *zone_name* | The zone name identified for deletion | Yes |
+---------------+-----------------------------------------------+--------------+
Take the appropriate measure to delete the zone on the DNS server, and ideally
all of it's subresources.
Other Changes
-------------
This should fit into the Designate pattern well. To the Pool Manager and
MiniDNS, the Agent is the same as any other DNS server. It's possible that
something in MiniDNS could be supplemented to use with the Agent, but it
shouldn't be needed.
A lot of the code that MiniDNS uses for the actual DNS protocol stuff will
be reused in some form in the Agent. Development of the agent would be a good
time to port the commonalities into the dnsutils module of Designate.
Benefits
========
- Configurable backends that can do the work required for different DNS servers
(RNDC, Database addition) that dont connect directly to the database
- A deployment with the benefits of MiniDNS, while keeping a traditional
Master/Slave DNS setup is possible
- Less DNS servers must be managed by Designate
- Less chatter between MiniDNS and the database because SOA refreshes and
other queries can be handled by a master
- MiniDNS becomes less vital to a deployment, MiniDNS/Database issues are
isolated from the DNS infrastructure
- An agent with direct control of the DNS servers adds the benefit of doing
things outside of pure DNS protocol with a DNS server, periodic syncs, etc are
made easier
Implementation
==============
Assignee(s)
-----------
Primary assignee:
tim-simmons-t
Milestones
----------
Target Milestone for completion:
Kilo
Work Items
----------
- Create the Agent service
- Add support for receiving NOTIFYs
- Add support for receiving AXFRs
- Decide and implement receiving messages with non-standard CLASS/RRDATA
- Add a base class backend that is called for different operations
- Port some of the existing backends, or add some new ones