Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions connector_dns/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.. image:: https://img.shields.io/badge/licence-LGPL-3-blue.svg
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL

=============
DNS Connector
=============

Odoo modules related to the management of Domain Name Server services within network infrastructure.
2 changes: 2 additions & 0 deletions connector_dns/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import components
from . import models
16 changes: 16 additions & 0 deletions connector_dns/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{
'name': 'DNS Base',
'category': 'connector',
'version': '12.0.1.0.0',
'license': 'LGPL-3',
'author': 'Elico Corp, Odoo Community Association (OCA)',
'website': 'https://github.com/OCA/infrastructure-dns',
'depends': [
'connector',
],
'data': [
'views/dns_view.xml',
],
}
7 changes: 7 additions & 0 deletions connector_dns/components/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from . import core
from . import backend_adapter
from . import binder
from . import importer
from . import exporter
from . import deleter
from . import mapper
24 changes: 24 additions & 0 deletions connector_dns/components/backend_adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo.addons.component.core import AbstractComponent


class DNSAbstractAdapter(AbstractComponent):
_name = 'dns.abstract.adapter'
_inherit = ['base.backend.adapter', 'base.dns.connector']
_usage = 'backend.adapter'

def search_all(self, domain_id):
raise NotImplementedError

def search(self, external_id):
raise NotImplementedError

def create(self):
raise NotImplementedError

def write(self, external_id):
raise NotImplementedError

def delete(self, external_id):
raise NotImplementedError
9 changes: 9 additions & 0 deletions connector_dns/components/binder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo.addons.component.core import Component


class DNSBinder(Component):
_name = 'dns.binder'
_inherit = ['base.binder', 'base.dns.connector']
_apply_on = ['dns.domain']
12 changes: 12 additions & 0 deletions connector_dns/components/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo.addons.component.core import AbstractComponent


class BaseDNSConnectorComponent(AbstractComponent):
""" Base DNS Connector Component
All components of this connector should inherit from it.
"""
_name = 'base.dns.connector'
_inherit = 'base.connector'
_collection = 'dns.backend'
20 changes: 20 additions & 0 deletions connector_dns/components/deleter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo.addons.component.core import AbstractComponent


class DNSAbstractDeleter(AbstractComponent):
_name = 'dns.abstract.deleter'
_inherit = 'base.deleter'
_usage = 'dns.deleter'

def run(self, binding):
self._before_delete(binding)
self.backend_adapter.delete(binding)
self._after_delete()

def _before_delete(self, binding):
return

def _after_delete(self):
return
35 changes: 35 additions & 0 deletions connector_dns/components/exporter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo.addons.component.core import AbstractComponent


class DNSAbstractExporter(AbstractComponent):
_name = 'dns.abstract.exporter'
_inherit = ['base.exporter', 'base.dns.connector']
_usage = 'dns.exporter'

def __init__(self, work_context):
super(DNSAbstractExporter, self).__init__(work_context)
self.binding = None
self.external_id = None

def run(self, binding):
self.binding = binding
self.external_id = self.binder.to_external(self.binding)
self._before_export()
if self.external_id:
self.backend_adapter.write(self.binding)
else:
response = self.backend_adapter.create(self.binding)
self.external_id = self._get_external_id(response)
self.binder.bind(self.external_id, self.binding)
self._after_export()

def _before_export(self):
return

def _after_export(self):
return

def _get_external_id(self, response):
raise NotImplementedError
76 changes: 76 additions & 0 deletions connector_dns/components/importer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
import logging

from odoo.addons.component.core import AbstractComponent

_logger = logging.getLogger(__name__)


class DNSAbstractImporter(AbstractComponent):
_name = 'dns.abstract.importer'
_inherit = ['base.importer', 'base.dns.connector']
_usage = 'dns.importer'

def __init__(self, work_context):
super(DNSAbstractImporter, self).__init__(work_context)
self.domain_id = None
self.external_id = None
self.dns_record = None

def _before_import(self):
return

def _after_import(self):
return

def _get_records(self):
return self.backend_adapter.search(self.external_id)

def _validate_data(self, data):
return

def _map_data(self):
return self.mapper.map_record(self.dns_record)

def _get_binding(self):
return self.binder.to_internal(self.external_id)

def _create_data(self, map_record, **kwargs):
return map_record.values(for_create=True, **kwargs)

def _create(self, data):
""" Create the Odoo record """
# special check on data before import
self._validate_data(data)
model = self.model.with_context(connector_no_export=True)
binding = model.create(data)
return binding

def _update_data(self, map_record, **kwargs):
return map_record.values(**kwargs)

def _update(self, binding, data):
self._validate_data(data)
binding.with_context(no_connector_export=True).write(data)

def run(self, domain_id):
self.domain_id = domain_id
for _id in self.backend_adapter.search_all(domain_id):
self._run(_id)

def _run(self, external_id):
self.external_id = external_id
self.dns_record = self._get_records()

binding = self._get_binding()
self._before_import()
map_record = self._map_data()
if binding:
record = self._update_data(map_record)
self._update(binding, record)
else:
record = self._create_data(map_record)
binding = self._create(record)
self.binder.bind(self.external_id, binding)
self._after_import()
9 changes: 9 additions & 0 deletions connector_dns/components/mapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo.addons.component.core import AbstractComponent


class DNSAbstractImportMapper(AbstractComponent):
_name = 'dns.abstract.mapper'
_inherit = ['base.dns.connector', 'base.import.mapper']
_usage = 'import.mapper'
4 changes: 4 additions & 0 deletions connector_dns/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import dns_backend
from . import dns_binding
from . import dns_domain
from . import dns_record
16 changes: 16 additions & 0 deletions connector_dns/models/dns_backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import models, fields


class DNSBackend(models.Model):
_name = 'dns.backend'
_inherit = 'connector.backend'
_description = 'DNS Connector Backend'

name = fields.Char('Name', required=True)
company_id = fields.Many2one(
'res.company',
default=lambda self: self.env.user.company_id,
string='Company')
is_default = fields.Boolean('Is Default Backend')
47 changes: 47 additions & 0 deletions connector_dns/models/dns_binding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import api, fields, models
from odoo.addons.queue_job.job import job


class DNSBingingAbstract(models.AbstractModel):
_name = 'dns.binding'
_inherit = 'external.binding'
_description = 'DNS binding (abstract)'

# odoo_id = odoo-side id must be declared in concrete model
backend_id = fields.Many2one(
'dns.backend',
string='DNS Backend',
required=True,
ondelete='restrict')
external_id = fields.Char('ID on DNS Provider', readonly=True)
sync_date = fields.Datetime('Sync Date')

@job(default_channel='root')
@api.model
def import_dns_domains(self, backend_id, binding):
with backend_id.work_on(self._name) as work:
importer = work.component(usage='dns.importer')
return importer.run(binding)

@job(default_channel='root')
@api.model
def import_dns_records(self, backend_id, binding):
with backend_id.work_on(self._name) as work:
importer = work.component(usage='dns.importer')
return importer.run(binding)

@job(default_channel='root')
@api.model
def export_dns_records(self, backend_id, binding):
with backend_id.work_on(self._name) as work:
exporter = work.component(usage='dns.exporter')
return exporter.run(binding)

@job(default_channel='root')
@api.model
def delete_dns_records(self, backend_id, binding):
with backend_id.work_on(self._name) as work:
deleter = work.component(usage='dns.deleter')
return deleter.run(binding)
32 changes: 32 additions & 0 deletions connector_dns/models/dns_domain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import models, fields


class DNSDomain(models.Model):
_name = 'dns.domain'
_inherit = 'dns.binding'
_description = 'DNS Domain'

name = fields.Char(
string='Domain',
required=True,
help='Domain name without "www", such as "dnspod.cn"'
)
state = fields.Selection([
('draft', 'Draft'),
('done', 'Done'),
('exception', 'Exception')],
string='State',
default='draft',
help='Done when succeed otherwise Exception')
record_ids = fields.One2many(
comodel_name='dns.record',
inverse_name='domain_id',
string='Subdomains'
)

_sql_constraints = [
('dns_domain_uniq', 'unique(external_id)',
"An external_id already exists with the same record."),
]
34 changes: 34 additions & 0 deletions connector_dns/models/dns_record.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# © 2015-2019 Elico Corp (https://www.elico-corp.com).
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import models, fields


class DNSRecord(models.Model):
_name = 'dns.record'
_description = 'DNS records'

name = fields.Char(
'Subdomain',
help='Host record, such as "www"',
required=True)
domain_id = fields.Many2one(
comodel_name='dns.domain',
domain="[('state', '=', 'done')]",
string='Domain',
ondelete='cascade')
value = fields.Text(
string='Value',
help="such as IP:200.200.200.200",
required=True
)
mx_priority = fields.Integer(
string='MX priority',
help="scope: 1-20",
default=1
)
ttl = fields.Integer(
string='TTL',
default=600,
help="scope: 1-604800",
required=True
)
Loading