mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-09 23:20:27 +00:00
Merge branch 'dev' into nkupdates-password-policy
This commit is contained in:
commit
78f0332a2d
@ -27,6 +27,7 @@ CAPTCHA_SESSION_KEY = 'captcha_image'
|
|||||||
SESSION_TYPE = 'sqlalchemy'
|
SESSION_TYPE = 'sqlalchemy'
|
||||||
|
|
||||||
### DATABASE - MySQL
|
### DATABASE - MySQL
|
||||||
|
## Don't forget to uncomment the import in the top
|
||||||
#SQLALCHEMY_DATABASE_URI = 'mysql://{}:{}@{}/{}'.format(
|
#SQLALCHEMY_DATABASE_URI = 'mysql://{}:{}@{}/{}'.format(
|
||||||
# urllib.parse.quote_plus(SQLA_DB_USER),
|
# urllib.parse.quote_plus(SQLA_DB_USER),
|
||||||
# urllib.parse.quote_plus(SQLA_DB_PASSWORD),
|
# urllib.parse.quote_plus(SQLA_DB_PASSWORD),
|
||||||
@ -34,6 +35,15 @@ SESSION_TYPE = 'sqlalchemy'
|
|||||||
# SQLA_DB_NAME
|
# SQLA_DB_NAME
|
||||||
#)
|
#)
|
||||||
|
|
||||||
|
### DATABASE - PostgreSQL
|
||||||
|
## Don't forget to uncomment the import in the top
|
||||||
|
#SQLALCHEMY_DATABASE_URI = 'postgres://{}:{}@{}/{}'.format(
|
||||||
|
# urllib.parse.quote_plus(SQLA_DB_USER),
|
||||||
|
# urllib.parse.quote_plus(SQLA_DB_PASSWORD),
|
||||||
|
# SQLA_DB_HOST,
|
||||||
|
# SQLA_DB_NAME
|
||||||
|
#)
|
||||||
|
|
||||||
### DATABASE - SQLite
|
### DATABASE - SQLite
|
||||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'pdns.db')
|
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'pdns.db')
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ RUN apt-get update -y \
|
|||||||
libffi-dev \
|
libffi-dev \
|
||||||
libldap2-dev \
|
libldap2-dev \
|
||||||
libmariadb-dev-compat \
|
libmariadb-dev-compat \
|
||||||
|
libpq-dev \
|
||||||
libsasl2-dev \
|
libsasl2-dev \
|
||||||
libssl-dev \
|
libssl-dev \
|
||||||
libxml2-dev \
|
libxml2-dev \
|
||||||
|
@ -2,6 +2,7 @@ FROM alpine:3.17 AS builder
|
|||||||
|
|
||||||
ARG BUILD_DEPENDENCIES="build-base \
|
ARG BUILD_DEPENDENCIES="build-base \
|
||||||
libffi-dev \
|
libffi-dev \
|
||||||
|
libpq-dev \
|
||||||
libxml2-dev \
|
libxml2-dev \
|
||||||
mariadb-connector-c-dev \
|
mariadb-connector-c-dev \
|
||||||
openldap-dev \
|
openldap-dev \
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
## Using PowerDNS-Admin
|
## Using PowerDNS-Admin
|
||||||
|
|
||||||
- Setting up a domain
|
- Setting up a zone
|
||||||
- Adding a record
|
- Adding a record
|
||||||
- <whatever else>
|
- <whatever else>
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ Active Directory Setup - Tested with Windows Server 2012
|
|||||||
5) Fill in the required info -
|
5) Fill in the required info -
|
||||||
|
|
||||||
* LDAP URI - ldap://ip.of.your.domain.controller:389
|
* LDAP URI - ldap://ip.of.your.domain.controller:389
|
||||||
* LDAP Base DN - dc=youdomain,dc=com
|
* LDAP Base DN - dc=yourdomain,dc=com
|
||||||
* Active Directory domain - yourdomain.com
|
* Active Directory domain - yourdomain.com
|
||||||
* Basic filter - (objectCategory=person)
|
* Basic filter - (objectCategory=person)
|
||||||
* the brackets here are **very important**
|
* the brackets here are **very important**
|
||||||
|
@ -15,10 +15,9 @@ The below will create a database called powerdnsadmindb and a user of powerdnsad
|
|||||||
```
|
```
|
||||||
$ sudo su - postgres
|
$ sudo su - postgres
|
||||||
$ createuser powerdnsadmin
|
$ createuser powerdnsadmin
|
||||||
$ createdb powerdnsadmindb
|
$ createdb -E UTF8 -l en_US.UTF-8 -O powerdnsadmin -T template0 powerdnsadmindb 'The database for PowerDNS-Admin'
|
||||||
$ psql
|
$ psql
|
||||||
postgres=# alter user powerdnsadmin with encrypted password 'powerdnsadmin';
|
postgres=# ALTER ROLE powerdnsadmin WITH PASSWORD 'powerdnsadmin_password';
|
||||||
postgres=# grant all privileges on database powerdnsadmindb to powerdnsadmin;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
@ -51,18 +50,14 @@ On debian based systems these files are located in:
|
|||||||
|
|
||||||
## Install required packages:
|
## Install required packages:
|
||||||
### Red-hat based systems:
|
### Red-hat based systems:
|
||||||
|
TODO: confirm this is correct
|
||||||
```
|
```
|
||||||
sudo yum install postgresql-libs
|
sudo yum install postgresql-libs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debian based systems:
|
### Debian based systems:
|
||||||
```
|
```
|
||||||
apt install libpq-dev python-dev
|
apt install python3-psycopg2
|
||||||
```
|
|
||||||
|
|
||||||
### Install python packages:
|
|
||||||
```
|
|
||||||
pip3 install psycopg2
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Known Issues:
|
## Known Issues:
|
||||||
|
@ -7,19 +7,30 @@ First setup your database accordingly:
|
|||||||
|
|
||||||
### Install required packages for building python libraries from requirements.txt file
|
### Install required packages for building python libraries from requirements.txt file
|
||||||
|
|
||||||
|
For Debian 11 (bullseye) and above:
|
||||||
```bash
|
```bash
|
||||||
sudo apt install -y python3-dev git libsasl2-dev libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev libffi-dev pkg-config apt-transport-https virtualenv build-essential curl
|
sudo apt install -y python3-dev git libsasl2-dev libldap2-dev python3-venv libmariadb-dev pkg-config build-essential curl libpq-dev
|
||||||
|
```
|
||||||
|
Older systems might also need the following:
|
||||||
|
```bash
|
||||||
|
sudo apt install -y libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev libffi-dev apt-transport-https virtualenv
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install NodeJs
|
### Install NodeJs
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sL https://deb.nodesource.com/setup_14.x | bash -
|
curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
|
||||||
apt install -y nodejs
|
sudo apt install -y nodejs
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install yarn to build asset files
|
### Install yarn to build asset files
|
||||||
|
For Debian 11 (bullseye) and above:
|
||||||
|
```bash
|
||||||
|
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null
|
||||||
|
echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
|
||||||
|
sudo apt update && sudo apt install -y yarn
|
||||||
|
```
|
||||||
|
For older Debian systems:
|
||||||
```bash
|
```bash
|
||||||
sudo curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
sudo curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
|
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
|
||||||
|
@ -270,7 +270,7 @@ def api_can_create_domain(f):
|
|||||||
if current_user.role.name not in [
|
if current_user.role.name not in [
|
||||||
'Administrator', 'Operator'
|
'Administrator', 'Operator'
|
||||||
] and not Setting().get('allow_user_create_domain'):
|
] and not Setting().get('allow_user_create_domain'):
|
||||||
msg = "User {0} does not have enough privileges to create domain"
|
msg = "User {0} does not have enough privileges to create zone"
|
||||||
current_app.logger.error(msg.format(current_user.username))
|
current_app.logger.error(msg.format(current_user.username))
|
||||||
raise NotEnoughPrivileges()
|
raise NotEnoughPrivileges()
|
||||||
|
|
||||||
@ -299,7 +299,7 @@ def apikey_can_create_domain(f):
|
|||||||
if g.apikey.role.name not in [
|
if g.apikey.role.name not in [
|
||||||
'Administrator', 'Operator'
|
'Administrator', 'Operator'
|
||||||
] and not Setting().get('allow_user_create_domain'):
|
] and not Setting().get('allow_user_create_domain'):
|
||||||
msg = "ApiKey #{0} does not have enough privileges to create domain"
|
msg = "ApiKey #{0} does not have enough privileges to create zone"
|
||||||
current_app.logger.error(msg.format(g.apikey.id))
|
current_app.logger.error(msg.format(g.apikey.id))
|
||||||
raise NotEnoughPrivileges()
|
raise NotEnoughPrivileges()
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ def apikey_can_remove_domain(http_methods=[]):
|
|||||||
g.apikey.role.name not in ['Administrator', 'Operator'] and
|
g.apikey.role.name not in ['Administrator', 'Operator'] and
|
||||||
not Setting().get('allow_user_remove_domain')
|
not Setting().get('allow_user_remove_domain')
|
||||||
):
|
):
|
||||||
msg = "ApiKey #{0} does not have enough privileges to remove domain"
|
msg = "ApiKey #{0} does not have enough privileges to remove zone"
|
||||||
current_app.logger.error(msg.format(g.apikey.id))
|
current_app.logger.error(msg.format(g.apikey.id))
|
||||||
raise NotEnoughPrivileges()
|
raise NotEnoughPrivileges()
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
@ -344,7 +344,7 @@ def apikey_is_admin(f):
|
|||||||
@wraps(f)
|
@wraps(f)
|
||||||
def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
if g.apikey.role.name != 'Administrator':
|
if g.apikey.role.name != 'Administrator':
|
||||||
msg = "Apikey {0} does not have enough privileges to create domain"
|
msg = "Apikey {0} does not have enough privileges to create zone"
|
||||||
current_app.logger.error(msg.format(g.apikey.id))
|
current_app.logger.error(msg.format(g.apikey.id))
|
||||||
raise NotEnoughPrivileges()
|
raise NotEnoughPrivileges()
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
|
@ -21,7 +21,7 @@ class StructuredException(Exception):
|
|||||||
class DomainNotExists(StructuredException):
|
class DomainNotExists(StructuredException):
|
||||||
status_code = 404
|
status_code = 404
|
||||||
|
|
||||||
def __init__(self, name=None, message="Domain does not exist"):
|
def __init__(self, name=None, message="Zone does not exist"):
|
||||||
StructuredException.__init__(self)
|
StructuredException.__init__(self)
|
||||||
self.message = message
|
self.message = message
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -30,7 +30,7 @@ class DomainNotExists(StructuredException):
|
|||||||
class DomainAlreadyExists(StructuredException):
|
class DomainAlreadyExists(StructuredException):
|
||||||
status_code = 409
|
status_code = 409
|
||||||
|
|
||||||
def __init__(self, name=None, message="Domain already exists"):
|
def __init__(self, name=None, message="Zone already exists"):
|
||||||
StructuredException.__init__(self)
|
StructuredException.__init__(self)
|
||||||
self.message = message
|
self.message = message
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -39,7 +39,7 @@ class DomainAlreadyExists(StructuredException):
|
|||||||
class DomainAccessForbidden(StructuredException):
|
class DomainAccessForbidden(StructuredException):
|
||||||
status_code = 403
|
status_code = 403
|
||||||
|
|
||||||
def __init__(self, name=None, message="Domain access not allowed"):
|
def __init__(self, name=None, message="Zone access not allowed"):
|
||||||
StructuredException.__init__(self)
|
StructuredException.__init__(self)
|
||||||
self.message = message
|
self.message = message
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -47,7 +47,7 @@ class DomainAccessForbidden(StructuredException):
|
|||||||
class DomainOverrideForbidden(StructuredException):
|
class DomainOverrideForbidden(StructuredException):
|
||||||
status_code = 409
|
status_code = 409
|
||||||
|
|
||||||
def __init__(self, name=None, message="Domain override of record not allowed"):
|
def __init__(self, name=None, message="Zone override of record not allowed"):
|
||||||
StructuredException.__init__(self)
|
StructuredException.__init__(self)
|
||||||
self.message = message
|
self.message = message
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -67,7 +67,7 @@ class ApiKeyNotUsable(StructuredException):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
name=None,
|
name=None,
|
||||||
message=("Api key must have domains or accounts"
|
message=("Api key must have zones or accounts"
|
||||||
" or an administrative role")):
|
" or an administrative role")):
|
||||||
StructuredException.__init__(self)
|
StructuredException.__init__(self)
|
||||||
self.message = message
|
self.message = message
|
||||||
|
@ -229,7 +229,7 @@ def ensure_list(l):
|
|||||||
|
|
||||||
def pretty_domain_name(domain_name):
|
def pretty_domain_name(domain_name):
|
||||||
# Add a debugging statement to print out the domain name
|
# Add a debugging statement to print out the domain name
|
||||||
print("Received domain name:", domain_name)
|
print("Received zone name:", domain_name)
|
||||||
|
|
||||||
# Check if the domain name is encoded using Punycode
|
# Check if the domain name is encoded using Punycode
|
||||||
if domain_name.endswith('.xn--'):
|
if domain_name.endswith('.xn--'):
|
||||||
@ -238,9 +238,9 @@ def pretty_domain_name(domain_name):
|
|||||||
domain_name = idna.decode(domain_name)
|
domain_name = idna.decode(domain_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# If the decoding fails, raise an exception with more information
|
# If the decoding fails, raise an exception with more information
|
||||||
raise Exception('Cannot decode IDN domain: {}'.format(e))
|
raise Exception('Cannot decode IDN zone: {}'.format(e))
|
||||||
|
|
||||||
# Return the "pretty" version of the domain name
|
# Return the "pretty" version of the zone name
|
||||||
return domain_name
|
return domain_name
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,13 +68,13 @@ class Domain(db.Model):
|
|||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Can not create setting {0} for domain {1}. {2}'.format(
|
'Can not create setting {0} for zone {1}. {2}'.format(
|
||||||
setting, self.name, e))
|
setting, self.name, e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_domain_info(self, domain_name):
|
def get_domain_info(self, domain_name):
|
||||||
"""
|
"""
|
||||||
Get all domains which has in PowerDNS
|
Get all zones which has in PowerDNS
|
||||||
"""
|
"""
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||||
jdata = utils.fetch_json(urljoin(
|
jdata = utils.fetch_json(urljoin(
|
||||||
@ -88,7 +88,7 @@ class Domain(db.Model):
|
|||||||
|
|
||||||
def get_domains(self):
|
def get_domains(self):
|
||||||
"""
|
"""
|
||||||
Get all domains which has in PowerDNS
|
Get all zones which has in PowerDNS
|
||||||
"""
|
"""
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||||
jdata = utils.fetch_json(
|
jdata = utils.fetch_json(
|
||||||
@ -108,17 +108,17 @@ class Domain(db.Model):
|
|||||||
return domain.id
|
return domain.id
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Domain does not exist. ERROR: {0}'.format(e))
|
'Zone does not exist. ERROR: {0}'.format(e))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def search_idn_domains(self, search_string):
|
def search_idn_domains(self, search_string):
|
||||||
"""
|
"""
|
||||||
Search for IDN domains using the provided search string.
|
Search for IDN zones using the provided search string.
|
||||||
"""
|
"""
|
||||||
# Compile the regular expression pattern for matching IDN domain names
|
# Compile the regular expression pattern for matching IDN zone names
|
||||||
idn_pattern = re.compile(r'^xn--')
|
idn_pattern = re.compile(r'^xn--')
|
||||||
|
|
||||||
# Search for domain names that match the IDN pattern
|
# Search for zone names that match the IDN pattern
|
||||||
idn_domains = [
|
idn_domains = [
|
||||||
domain for domain in self.get_domains() if idn_pattern.match(domain)
|
domain for domain in self.get_domains() if idn_pattern.match(domain)
|
||||||
]
|
]
|
||||||
@ -129,12 +129,12 @@ class Domain(db.Model):
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""
|
"""
|
||||||
Fetch zones (domains) from PowerDNS and update into DB
|
Fetch zones (zones) from PowerDNS and update into DB
|
||||||
"""
|
"""
|
||||||
db_domain = Domain.query.all()
|
db_domain = Domain.query.all()
|
||||||
list_db_domain = [d.name for d in db_domain]
|
list_db_domain = [d.name for d in db_domain]
|
||||||
dict_db_domain = dict((x.name, x) for x in db_domain)
|
dict_db_domain = dict((x.name, x) for x in db_domain)
|
||||||
current_app.logger.info("Found {} domains in PowerDNS-Admin".format(
|
current_app.logger.info("Found {} zones in PowerDNS-Admin".format(
|
||||||
len(list_db_domain)))
|
len(list_db_domain)))
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||||
try:
|
try:
|
||||||
@ -149,17 +149,17 @@ class Domain(db.Model):
|
|||||||
"Found {} zones in PowerDNS server".format(len(list_jdomain)))
|
"Found {} zones in PowerDNS server".format(len(list_jdomain)))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# domains should remove from db since it doesn't exist in powerdns anymore
|
# zones should remove from db since it doesn't exist in powerdns anymore
|
||||||
should_removed_db_domain = list(
|
should_removed_db_domain = list(
|
||||||
set(list_db_domain).difference(list_jdomain))
|
set(list_db_domain).difference(list_jdomain))
|
||||||
for domain_name in should_removed_db_domain:
|
for domain_name in should_removed_db_domain:
|
||||||
self.delete_domain_from_pdnsadmin(domain_name, do_commit=False)
|
self.delete_domain_from_pdnsadmin(domain_name, do_commit=False)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Can not delete domain from DB. DETAIL: {0}'.format(e))
|
'Can not delete zone from DB. DETAIL: {0}'.format(e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
|
|
||||||
# update/add new domain
|
# update/add new zone
|
||||||
account_cache = {}
|
account_cache = {}
|
||||||
for data in jdata:
|
for data in jdata:
|
||||||
if 'account' in data:
|
if 'account' in data:
|
||||||
@ -187,16 +187,16 @@ class Domain(db.Model):
|
|||||||
self.add_domain_to_powerdns_admin(domain=data, do_commit=False)
|
self.add_domain_to_powerdns_admin(domain=data, do_commit=False)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
current_app.logger.info('Update domain finished')
|
current_app.logger.info('Update zone finished')
|
||||||
return {
|
return {
|
||||||
'status': 'ok',
|
'status': 'ok',
|
||||||
'msg': 'Domain table has been updated successfully'
|
'msg': 'Zone table has been updated successfully'
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot update domain table. Error: {0}'.format(e))
|
'Cannot update zone table. Error: {0}'.format(e))
|
||||||
return {'status': 'error', 'msg': 'Cannot update domain table'}
|
return {'status': 'error', 'msg': 'Cannot update zone table'}
|
||||||
|
|
||||||
def update_pdns_admin_domain(self, domain, account_id, data, do_commit=True):
|
def update_pdns_admin_domain(self, domain, account_id, data, do_commit=True):
|
||||||
# existing domain, only update if something actually has changed
|
# existing domain, only update if something actually has changed
|
||||||
@ -218,11 +218,11 @@ class Domain(db.Model):
|
|||||||
try:
|
try:
|
||||||
if do_commit:
|
if do_commit:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
current_app.logger.info("Updated PDNS-Admin domain {0}".format(
|
current_app.logger.info("Updated PDNS-Admin zone {0}".format(
|
||||||
domain.name))
|
domain.name))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.info("Rolled back Domain {0} {1}".format(
|
current_app.logger.info("Rolled back zone {0} {1}".format(
|
||||||
domain.name, e))
|
domain.name, e))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ class Domain(db.Model):
|
|||||||
domain_master_ips=[],
|
domain_master_ips=[],
|
||||||
account_name=None):
|
account_name=None):
|
||||||
"""
|
"""
|
||||||
Add a domain to power dns
|
Add a zone to power dns
|
||||||
"""
|
"""
|
||||||
|
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
||||||
@ -269,23 +269,23 @@ class Domain(db.Model):
|
|||||||
if 'error' in jdata.keys():
|
if 'error' in jdata.keys():
|
||||||
current_app.logger.error(jdata['error'])
|
current_app.logger.error(jdata['error'])
|
||||||
if jdata.get('http_code') == 409:
|
if jdata.get('http_code') == 409:
|
||||||
return {'status': 'error', 'msg': 'Domain already exists'}
|
return {'status': 'error', 'msg': 'Zone already exists'}
|
||||||
return {'status': 'error', 'msg': jdata['error']}
|
return {'status': 'error', 'msg': jdata['error']}
|
||||||
else:
|
else:
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
'Added domain successfully to PowerDNS: {0}'.format(
|
'Added zone successfully to PowerDNS: {0}'.format(
|
||||||
domain_name))
|
domain_name))
|
||||||
self.add_domain_to_powerdns_admin(domain_dict=post_data)
|
self.add_domain_to_powerdns_admin(domain_dict=post_data)
|
||||||
return {'status': 'ok', 'msg': 'Added domain successfully'}
|
return {'status': 'ok', 'msg': 'Added zone successfully'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error('Cannot add domain {0} {1}'.format(
|
current_app.logger.error('Cannot add zone {0} {1}'.format(
|
||||||
domain_name, e))
|
domain_name, e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
return {'status': 'error', 'msg': 'Cannot add this domain.'}
|
return {'status': 'error', 'msg': 'Cannot add this zone.'}
|
||||||
|
|
||||||
def add_domain_to_powerdns_admin(self, domain=None, domain_dict=None, do_commit=True):
|
def add_domain_to_powerdns_admin(self, domain=None, domain_dict=None, do_commit=True):
|
||||||
"""
|
"""
|
||||||
Read Domain from PowerDNS and add into PDNS-Admin
|
Read zone from PowerDNS and add into PDNS-Admin
|
||||||
"""
|
"""
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||||
if not domain:
|
if not domain:
|
||||||
@ -299,7 +299,7 @@ class Domain(db.Model):
|
|||||||
timeout=int(Setting().get('pdns_api_timeout')),
|
timeout=int(Setting().get('pdns_api_timeout')),
|
||||||
verify=Setting().get('verify_ssl_connections'))
|
verify=Setting().get('verify_ssl_connections'))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error('Can not read domain from PDNS')
|
current_app.logger.error('Can not read zone from PDNS')
|
||||||
current_app.logger.error(e)
|
current_app.logger.error(e)
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
|
|
||||||
@ -325,20 +325,20 @@ class Domain(db.Model):
|
|||||||
if do_commit:
|
if do_commit:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
"Synced PowerDNS Domain to PDNS-Admin: {0}".format(d.name))
|
"Synced PowerDNS zone to PDNS-Admin: {0}".format(d.name))
|
||||||
return {
|
return {
|
||||||
'status': 'ok',
|
'status': 'ok',
|
||||||
'msg': 'Added Domain successfully to PowerDNS-Admin'
|
'msg': 'Added zone successfully to PowerDNS-Admin'
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.info("Rolled back Domain {0}".format(d.name))
|
current_app.logger.info("Rolled back zone {0}".format(d.name))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def update_soa_setting(self, domain_name, soa_edit_api):
|
def update_soa_setting(self, domain_name, soa_edit_api):
|
||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
if not domain:
|
if not domain:
|
||||||
return {'status': 'error', 'msg': 'Domain does not exist.'}
|
return {'status': 'error', 'msg': 'Zone does not exist.'}
|
||||||
|
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ class Domain(db.Model):
|
|||||||
return {'status': 'error', 'msg': jdata['error']}
|
return {'status': 'error', 'msg': jdata['error']}
|
||||||
else:
|
else:
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
'soa-edit-api changed for domain {0} successfully'.format(
|
'soa-edit-api changed for zone {0} successfully'.format(
|
||||||
domain_name))
|
domain_name))
|
||||||
return {
|
return {
|
||||||
'status': 'ok',
|
'status': 'ok',
|
||||||
@ -375,11 +375,11 @@ class Domain(db.Model):
|
|||||||
current_app.logger.debug(e)
|
current_app.logger.debug(e)
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot change soa-edit-api for domain {0}'.format(
|
'Cannot change soa-edit-api for zone {0}'.format(
|
||||||
domain_name))
|
domain_name))
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg': 'Cannot change soa-edit-api for this domain.'
|
'msg': 'Cannot change soa-edit-api for this zone.'
|
||||||
}
|
}
|
||||||
|
|
||||||
def update_kind(self, domain_name, kind, masters=[]):
|
def update_kind(self, domain_name, kind, masters=[]):
|
||||||
@ -388,7 +388,7 @@ class Domain(db.Model):
|
|||||||
"""
|
"""
|
||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
if not domain:
|
if not domain:
|
||||||
return {'status': 'error', 'msg': 'Domain does not exist.'}
|
return {'status': 'error', 'msg': 'Znoe does not exist.'}
|
||||||
|
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
||||||
|
|
||||||
@ -409,26 +409,26 @@ class Domain(db.Model):
|
|||||||
return {'status': 'error', 'msg': jdata['error']}
|
return {'status': 'error', 'msg': jdata['error']}
|
||||||
else:
|
else:
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
'Update domain kind for {0} successfully'.format(
|
'Update zone kind for {0} successfully'.format(
|
||||||
domain_name))
|
domain_name))
|
||||||
return {
|
return {
|
||||||
'status': 'ok',
|
'status': 'ok',
|
||||||
'msg': 'Domain kind changed successfully'
|
'msg': 'Zone kind changed successfully'
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot update kind for domain {0}. Error: {1}'.format(
|
'Cannot update kind for zone {0}. Error: {1}'.format(
|
||||||
domain_name, e))
|
domain_name, e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg': 'Cannot update kind for this domain.'
|
'msg': 'Cannot update kind for this zone.'
|
||||||
}
|
}
|
||||||
|
|
||||||
def create_reverse_domain(self, domain_name, domain_reverse_name):
|
def create_reverse_domain(self, domain_name, domain_reverse_name):
|
||||||
"""
|
"""
|
||||||
Check the existing reverse lookup domain,
|
Check the existing reverse lookup zone,
|
||||||
if not exists create a new one automatically
|
if not exists create a new one automatically
|
||||||
"""
|
"""
|
||||||
domain_obj = Domain.query.filter(Domain.name == domain_name).first()
|
domain_obj = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
@ -448,7 +448,7 @@ class Domain(db.Model):
|
|||||||
result = self.add(domain_reverse_name, 'Master', 'DEFAULT', [], [])
|
result = self.add(domain_reverse_name, 'Master', 'DEFAULT', [], [])
|
||||||
self.update()
|
self.update()
|
||||||
if result['status'] == 'ok':
|
if result['status'] == 'ok':
|
||||||
history = History(msg='Add reverse lookup domain {0}'.format(
|
history = History(msg='Add reverse lookup zone {0}'.format(
|
||||||
domain_reverse_name),
|
domain_reverse_name),
|
||||||
detail=json.dumps({
|
detail=json.dumps({
|
||||||
'domain_type': 'Master',
|
'domain_type': 'Master',
|
||||||
@ -459,7 +459,7 @@ class Domain(db.Model):
|
|||||||
else:
|
else:
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg': 'Adding reverse lookup domain failed'
|
'msg': 'Adding reverse lookup zone failed'
|
||||||
}
|
}
|
||||||
domain_user_ids = self.get_user()
|
domain_user_ids = self.get_user()
|
||||||
if len(domain_user_ids) > 0:
|
if len(domain_user_ids) > 0:
|
||||||
@ -469,13 +469,13 @@ class Domain(db.Model):
|
|||||||
'status':
|
'status':
|
||||||
'ok',
|
'ok',
|
||||||
'msg':
|
'msg':
|
||||||
'New reverse lookup domain created with granted privileges'
|
'New reverse lookup zone created with granted privileges'
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
'status': 'ok',
|
'status': 'ok',
|
||||||
'msg': 'New reverse lookup domain created without users'
|
'msg': 'New reverse lookup zone created without users'
|
||||||
}
|
}
|
||||||
return {'status': 'ok', 'msg': 'Reverse lookup domain already exists'}
|
return {'status': 'ok', 'msg': 'Reverse lookup zone already exists'}
|
||||||
|
|
||||||
def get_reverse_domain_name(self, reverse_host_address):
|
def get_reverse_domain_name(self, reverse_host_address):
|
||||||
c = 1
|
c = 1
|
||||||
@ -504,22 +504,22 @@ class Domain(db.Model):
|
|||||||
|
|
||||||
def delete(self, domain_name):
|
def delete(self, domain_name):
|
||||||
"""
|
"""
|
||||||
Delete a single domain name from powerdns
|
Delete a single zone name from powerdns
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.delete_domain_from_powerdns(domain_name)
|
self.delete_domain_from_powerdns(domain_name)
|
||||||
self.delete_domain_from_pdnsadmin(domain_name)
|
self.delete_domain_from_pdnsadmin(domain_name)
|
||||||
return {'status': 'ok', 'msg': 'Delete domain successfully'}
|
return {'status': 'ok', 'msg': 'Delete zone successfully'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot delete domain {0}'.format(domain_name))
|
'Cannot delete zone {0}'.format(domain_name))
|
||||||
current_app.logger.error(e)
|
current_app.logger.error(e)
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
return {'status': 'error', 'msg': 'Cannot delete domain'}
|
return {'status': 'error', 'msg': 'Cannot delete zone'}
|
||||||
|
|
||||||
def delete_domain_from_powerdns(self, domain_name):
|
def delete_domain_from_powerdns(self, domain_name):
|
||||||
"""
|
"""
|
||||||
Delete a single domain name from powerdns
|
Delete a single zone name from powerdns
|
||||||
"""
|
"""
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||||
|
|
||||||
@ -531,12 +531,12 @@ class Domain(db.Model):
|
|||||||
method='DELETE',
|
method='DELETE',
|
||||||
verify=Setting().get('verify_ssl_connections'))
|
verify=Setting().get('verify_ssl_connections'))
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
'Deleted domain successfully from PowerDNS: {0}'.format(
|
'Deleted zone successfully from PowerDNS: {0}'.format(
|
||||||
domain_name))
|
domain_name))
|
||||||
return {'status': 'ok', 'msg': 'Delete domain successfully'}
|
return {'status': 'ok', 'msg': 'Delete zone successfully'}
|
||||||
|
|
||||||
def delete_domain_from_pdnsadmin(self, domain_name, do_commit=True):
|
def delete_domain_from_pdnsadmin(self, domain_name, do_commit=True):
|
||||||
# Revoke permission before deleting domain
|
# Revoke permission before deleting zone
|
||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
domain_user = DomainUser.query.filter(
|
domain_user = DomainUser.query.filter(
|
||||||
DomainUser.domain_id == domain.id)
|
DomainUser.domain_id == domain.id)
|
||||||
@ -548,7 +548,7 @@ class Domain(db.Model):
|
|||||||
domain_setting.delete()
|
domain_setting.delete()
|
||||||
domain.apikeys[:] = []
|
domain.apikeys[:] = []
|
||||||
|
|
||||||
# Remove history for domain
|
# Remove history for zone
|
||||||
if not Setting().get('preserve_history'):
|
if not Setting().get('preserve_history'):
|
||||||
domain_history = History.query.filter(
|
domain_history = History.query.filter(
|
||||||
History.domain_id == domain.id
|
History.domain_id == domain.id
|
||||||
@ -556,17 +556,17 @@ class Domain(db.Model):
|
|||||||
if domain_history:
|
if domain_history:
|
||||||
domain_history.delete()
|
domain_history.delete()
|
||||||
|
|
||||||
# then remove domain
|
# then remove zone
|
||||||
Domain.query.filter(Domain.name == domain_name).delete()
|
Domain.query.filter(Domain.name == domain_name).delete()
|
||||||
if do_commit:
|
if do_commit:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
current_app.logger.info(
|
current_app.logger.info(
|
||||||
"Deleted domain successfully from pdnsADMIN: {}".format(
|
"Deleted zone successfully from pdnsADMIN: {}".format(
|
||||||
domain_name))
|
domain_name))
|
||||||
|
|
||||||
def get_user(self):
|
def get_user(self):
|
||||||
"""
|
"""
|
||||||
Get users (id) who have access to this domain name
|
Get users (id) who have access to this zone name
|
||||||
"""
|
"""
|
||||||
user_ids = []
|
user_ids = []
|
||||||
query = db.session.query(
|
query = db.session.query(
|
||||||
@ -596,7 +596,7 @@ class Domain(db.Model):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot revoke user privileges on domain {0}. DETAIL: {1}'.
|
'Cannot revoke user privileges on zone {0}. DETAIL: {1}'.
|
||||||
format(self.name, e))
|
format(self.name, e))
|
||||||
current_app.logger.debug(print(traceback.format_exc()))
|
current_app.logger.debug(print(traceback.format_exc()))
|
||||||
|
|
||||||
@ -608,7 +608,7 @@ class Domain(db.Model):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot grant user privileges to domain {0}. DETAIL: {1}'.
|
'Cannot grant user privileges to zone {0}. DETAIL: {1}'.
|
||||||
format(self.name, e))
|
format(self.name, e))
|
||||||
current_app.logger.debug(print(traceback.format_exc()))
|
current_app.logger.debug(print(traceback.format_exc()))
|
||||||
|
|
||||||
@ -625,7 +625,7 @@ class Domain(db.Model):
|
|||||||
|
|
||||||
def add_user(self, user):
|
def add_user(self, user):
|
||||||
"""
|
"""
|
||||||
Add a single user to Domain by User
|
Add a single user to zone by User
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
du = DomainUser(self.id, user.id)
|
du = DomainUser(self.id, user.id)
|
||||||
@ -635,7 +635,7 @@ class Domain(db.Model):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot add user privileges on domain {0}. DETAIL: {1}'.
|
'Cannot add user privileges on zone {0}. DETAIL: {1}'.
|
||||||
format(self.name, e))
|
format(self.name, e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -667,11 +667,11 @@ class Domain(db.Model):
|
|||||||
'There was something wrong, please contact administrator'
|
'There was something wrong, please contact administrator'
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return {'status': 'error', 'msg': 'This domain does not exist'}
|
return {'status': 'error', 'msg': 'This zone does not exist'}
|
||||||
|
|
||||||
def get_domain_dnssec(self, domain_name):
|
def get_domain_dnssec(self, domain_name):
|
||||||
"""
|
"""
|
||||||
Get domain DNSSEC information
|
Get zone DNSSEC information
|
||||||
"""
|
"""
|
||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
if domain:
|
if domain:
|
||||||
@ -689,13 +689,13 @@ class Domain(db.Model):
|
|||||||
if 'error' in jdata:
|
if 'error' in jdata:
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg': 'DNSSEC is not enabled for this domain'
|
'msg': 'DNSSEC is not enabled for this zone'
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return {'status': 'ok', 'dnssec': jdata}
|
return {'status': 'ok', 'dnssec': jdata}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot get domain dnssec. DETAIL: {0}'.format(e))
|
'Cannot get zone dnssec. DETAIL: {0}'.format(e))
|
||||||
return {
|
return {
|
||||||
'status':
|
'status':
|
||||||
'error',
|
'error',
|
||||||
@ -703,11 +703,11 @@ class Domain(db.Model):
|
|||||||
'There was something wrong, please contact administrator'
|
'There was something wrong, please contact administrator'
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return {'status': 'error', 'msg': 'This domain does not exist'}
|
return {'status': 'error', 'msg': 'This zone does not exist'}
|
||||||
|
|
||||||
def enable_domain_dnssec(self, domain_name):
|
def enable_domain_dnssec(self, domain_name):
|
||||||
"""
|
"""
|
||||||
Enable domain DNSSEC
|
Enable zone DNSSEC
|
||||||
"""
|
"""
|
||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
if domain:
|
if domain:
|
||||||
@ -728,7 +728,7 @@ class Domain(db.Model):
|
|||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg':
|
'msg':
|
||||||
'API-RECTIFY could not be enabled for this domain',
|
'API-RECTIFY could not be enabled for this zone',
|
||||||
'jdata': jdata
|
'jdata': jdata
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,7 +749,7 @@ class Domain(db.Model):
|
|||||||
'status':
|
'status':
|
||||||
'error',
|
'error',
|
||||||
'msg':
|
'msg':
|
||||||
'Cannot enable DNSSEC for this domain. Error: {0}'.
|
'Cannot enable DNSSEC for this zone. Error: {0}'.
|
||||||
format(jdata['error']),
|
format(jdata['error']),
|
||||||
'jdata':
|
'jdata':
|
||||||
jdata
|
jdata
|
||||||
@ -769,7 +769,7 @@ class Domain(db.Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return {'status': 'error', 'msg': 'This domain does not exist'}
|
return {'status': 'error', 'msg': 'This zone does not exist'}
|
||||||
|
|
||||||
def delete_dnssec_key(self, domain_name, key_id):
|
def delete_dnssec_key(self, domain_name, key_id):
|
||||||
"""
|
"""
|
||||||
@ -794,13 +794,13 @@ class Domain(db.Model):
|
|||||||
'status':
|
'status':
|
||||||
'error',
|
'error',
|
||||||
'msg':
|
'msg':
|
||||||
'Cannot disable DNSSEC for this domain. Error: {0}'.
|
'Cannot disable DNSSEC for this zone. Error: {0}'.
|
||||||
format(jdata['error']),
|
format(jdata['error']),
|
||||||
'jdata':
|
'jdata':
|
||||||
jdata
|
jdata
|
||||||
}
|
}
|
||||||
|
|
||||||
# Disable API-RECTIFY for domain, AFTER deactivating DNSSEC
|
# Disable API-RECTIFY for zone, AFTER deactivating DNSSEC
|
||||||
post_data = {"api_rectify": False}
|
post_data = {"api_rectify": False}
|
||||||
jdata = utils.fetch_json(
|
jdata = utils.fetch_json(
|
||||||
urljoin(
|
urljoin(
|
||||||
@ -815,7 +815,7 @@ class Domain(db.Model):
|
|||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg':
|
'msg':
|
||||||
'API-RECTIFY could not be disabled for this domain',
|
'API-RECTIFY could not be disabled for this zone',
|
||||||
'jdata': jdata
|
'jdata': jdata
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -834,22 +834,22 @@ class Domain(db.Model):
|
|||||||
}
|
}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return {'status': 'error', 'msg': 'This domain does not exist'}
|
return {'status': 'error', 'msg': 'This zone does not exist'}
|
||||||
|
|
||||||
def assoc_account(self, account_id, update=True):
|
def assoc_account(self, account_id, update=True):
|
||||||
"""
|
"""
|
||||||
Associate domain with a domain, specified by account id
|
Associate account with a zone, specified by account id
|
||||||
"""
|
"""
|
||||||
domain_name = self.name
|
domain_name = self.name
|
||||||
|
|
||||||
# Sanity check - domain name
|
# Sanity check - domain name
|
||||||
if domain_name == "":
|
if domain_name == "":
|
||||||
return {'status': False, 'msg': 'No domain name specified'}
|
return {'status': False, 'msg': 'No zone name specified'}
|
||||||
|
|
||||||
# read domain and check that it exists
|
# read domain and check that it exists
|
||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
if not domain:
|
if not domain:
|
||||||
return {'status': False, 'msg': 'Domain does not exist'}
|
return {'status': False, 'msg': 'Zone does not exist'}
|
||||||
|
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
||||||
|
|
||||||
@ -875,9 +875,9 @@ class Domain(db.Model):
|
|||||||
else:
|
else:
|
||||||
if update:
|
if update:
|
||||||
self.update()
|
self.update()
|
||||||
msg_str = 'Account changed for domain {0} successfully'
|
msg_str = 'Account changed for zone {0} successfully'
|
||||||
current_app.logger.info(msg_str.format(domain_name))
|
current_app.logger.info(msg_str.format(domain_name))
|
||||||
history = History(msg='Update domain {0} associate account {1}'.format(domain.name, 'none' if account_name == '' else account_name),
|
history = History(msg='Update zone {0} associate account {1}'.format(domain.name, 'none' if account_name == '' else account_name),
|
||||||
detail = json.dumps({
|
detail = json.dumps({
|
||||||
'assoc_account': 'None' if account_name == '' else account_name,
|
'assoc_account': 'None' if account_name == '' else account_name,
|
||||||
'dissoc_account': 'None' if account_name_old == '' else account_name_old
|
'dissoc_account': 'None' if account_name_old == '' else account_name_old
|
||||||
@ -889,16 +889,16 @@ class Domain(db.Model):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.debug(e)
|
current_app.logger.debug(e)
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
msg_str = 'Cannot change account for domain {0}'
|
msg_str = 'Cannot change account for zone {0}'
|
||||||
current_app.logger.error(msg_str.format(domain_name))
|
current_app.logger.error(msg_str.format(domain_name))
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg': 'Cannot change account for this domain.'
|
'msg': 'Cannot change account for this zone.'
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_account(self):
|
def get_account(self):
|
||||||
"""
|
"""
|
||||||
Get current account associated with this domain
|
Get current account associated with this zone
|
||||||
"""
|
"""
|
||||||
domain = Domain.query.filter(Domain.name == self.name).first()
|
domain = Domain.query.filter(Domain.name == self.name).first()
|
||||||
|
|
||||||
@ -907,7 +907,7 @@ class Domain(db.Model):
|
|||||||
def is_valid_access(self, user_id):
|
def is_valid_access(self, user_id):
|
||||||
"""
|
"""
|
||||||
Check if the user is allowed to access this
|
Check if the user is allowed to access this
|
||||||
domain name
|
zone name
|
||||||
"""
|
"""
|
||||||
return db.session.query(Domain) \
|
return db.session.query(Domain) \
|
||||||
.outerjoin(DomainUser, Domain.id == DomainUser.domain_id) \
|
.outerjoin(DomainUser, Domain.id == DomainUser.domain_id) \
|
||||||
@ -919,8 +919,8 @@ class Domain(db.Model):
|
|||||||
AccountUser.user_id == user_id
|
AccountUser.user_id == user_id
|
||||||
)).filter(Domain.id == self.id).first()
|
)).filter(Domain.id == self.id).first()
|
||||||
|
|
||||||
# Return None if this domain does not exist as record,
|
# Return None if this zone does not exist as record,
|
||||||
# Return the parent domain that hold the record if exist
|
# Return the parent zone that hold the record if exist
|
||||||
def is_overriding(self, domain_name):
|
def is_overriding(self, domain_name):
|
||||||
upper_domain_name = '.'.join(domain_name.split('.')[1:])
|
upper_domain_name = '.'.join(domain_name.split('.')[1:])
|
||||||
while upper_domain_name != '':
|
while upper_domain_name != '':
|
||||||
@ -929,7 +929,7 @@ class Domain(db.Model):
|
|||||||
if 'rrsets' in upper_domain:
|
if 'rrsets' in upper_domain:
|
||||||
for r in upper_domain['rrsets']:
|
for r in upper_domain['rrsets']:
|
||||||
if domain_name.rstrip('.') in r['name'].rstrip('.'):
|
if domain_name.rstrip('.') in r['name'].rstrip('.'):
|
||||||
current_app.logger.error('Domain already exists as a record: {} under domain: {}'.format(r['name'].rstrip('.'), upper_domain_name))
|
current_app.logger.error('Zone already exists as a record: {} under zone: {}'.format(r['name'].rstrip('.'), upper_domain_name))
|
||||||
return upper_domain_name
|
return upper_domain_name
|
||||||
upper_domain_name = '.'.join(upper_domain_name.split('.')[1:])
|
upper_domain_name = '.'.join(upper_domain_name.split('.')[1:])
|
||||||
return None
|
return None
|
||||||
|
@ -45,11 +45,11 @@ class DomainTemplate(db.Model):
|
|||||||
return {'status': 'ok', 'msg': 'Template has been created'}
|
return {'status': 'ok', 'msg': 'Template has been created'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Can not update domain template table. Error: {0}'.format(e))
|
'Can not update zone template table. Error: {0}'.format(e))
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg': 'Can not update domain template table'
|
'msg': 'Can not update zone template table'
|
||||||
}
|
}
|
||||||
|
|
||||||
def delete_template(self):
|
def delete_template(self):
|
||||||
@ -60,6 +60,6 @@ class DomainTemplate(db.Model):
|
|||||||
return {'status': 'ok', 'msg': 'Template has been deleted'}
|
return {'status': 'ok', 'msg': 'Template has been deleted'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Can not delete domain template. Error: {0}'.format(e))
|
'Can not delete zone template. Error: {0}'.format(e))
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
return {'status': 'error', 'msg': 'Can not delete domain template'}
|
return {'status': 'error', 'msg': 'Can not delete zone template'}
|
||||||
|
@ -39,9 +39,9 @@ class DomainTemplateRecord(db.Model):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Can not update domain template table. Error: {0}'.format(e))
|
'Can not update zone template table. Error: {0}'.format(e))
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
'msg': 'Can not update domain template table'
|
'msg': 'Can not update zone template table'
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ class Record(object):
|
|||||||
|
|
||||||
def get_rrsets(self, domain):
|
def get_rrsets(self, domain):
|
||||||
"""
|
"""
|
||||||
Query domain's rrsets via PDNS API
|
Query zone's rrsets via PDNS API
|
||||||
"""
|
"""
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||||
try:
|
try:
|
||||||
@ -59,7 +59,7 @@ class Record(object):
|
|||||||
verify=Setting().get('verify_ssl_connections'))
|
verify=Setting().get('verify_ssl_connections'))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Cannot fetch domain's record data from remote powerdns api. DETAIL: {0}"
|
"Cannot fetch zone's record data from remote powerdns api. DETAIL: {0}"
|
||||||
.format(e))
|
.format(e))
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ class Record(object):
|
|||||||
|
|
||||||
def add(self, domain_name, rrset):
|
def add(self, domain_name, rrset):
|
||||||
"""
|
"""
|
||||||
Add a record to a domain (Used by auto_ptr and DynDNS)
|
Add a record to a zone (Used by auto_ptr and DynDNS)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
domain_name(str): The zone name
|
domain_name(str): The zone name
|
||||||
@ -115,7 +115,7 @@ class Record(object):
|
|||||||
return {'status': 'ok', 'msg': 'Record was added successfully'}
|
return {'status': 'ok', 'msg': 'Record was added successfully'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Cannot add record to domain {}. Error: {}".format(
|
"Cannot add record to zone {}. Error: {}".format(
|
||||||
domain_name, e))
|
domain_name, e))
|
||||||
current_app.logger.debug("Submitted record rrset: \n{}".format(
|
current_app.logger.debug("Submitted record rrset: \n{}".format(
|
||||||
utils.pretty_json(rrset)))
|
utils.pretty_json(rrset)))
|
||||||
@ -172,7 +172,7 @@ class Record(object):
|
|||||||
record['record_name'] = utils.to_idna(record["record_name"], "encode")
|
record['record_name'] = utils.to_idna(record["record_name"], "encode")
|
||||||
#TODO: error handling
|
#TODO: error handling
|
||||||
# If the record is an alias (CNAME), we will also make sure that
|
# If the record is an alias (CNAME), we will also make sure that
|
||||||
# the target domain is properly converted to punycode (IDN)
|
# the target zone is properly converted to punycode (IDN)
|
||||||
if record['record_type'] == 'CNAME' or record['record_type'] == 'SOA':
|
if record['record_type'] == 'CNAME' or record['record_type'] == 'SOA':
|
||||||
record['record_data'] = utils.to_idna(record['record_data'], 'encode')
|
record['record_data'] = utils.to_idna(record['record_data'], 'encode')
|
||||||
#TODO: error handling
|
#TODO: error handling
|
||||||
@ -343,7 +343,7 @@ class Record(object):
|
|||||||
|
|
||||||
def apply(self, domain_name, submitted_records):
|
def apply(self, domain_name, submitted_records):
|
||||||
"""
|
"""
|
||||||
Apply record changes to a domain. This function
|
Apply record changes to a zone. This function
|
||||||
will make 1 call to the PDNS API to DELETE and
|
will make 1 call to the PDNS API to DELETE and
|
||||||
REPLACE records (rrsets)
|
REPLACE records (rrsets)
|
||||||
"""
|
"""
|
||||||
@ -377,7 +377,7 @@ class Record(object):
|
|||||||
return {'status': 'ok', 'msg': 'Record was applied successfully', 'data': (new_rrsets, del_rrsets)}
|
return {'status': 'ok', 'msg': 'Record was applied successfully', 'data': (new_rrsets, del_rrsets)}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Cannot apply record changes to domain {0}. Error: {1}".format(
|
"Cannot apply record changes to zone {0}. Error: {1}".format(
|
||||||
domain_name, e))
|
domain_name, e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
return {
|
return {
|
||||||
@ -480,7 +480,7 @@ class Record(object):
|
|||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Cannot update auto-ptr record changes to domain {0}. Error: {1}"
|
"Cannot update auto-ptr record changes to zone {0}. Error: {1}"
|
||||||
.format(domain_name, e))
|
.format(domain_name, e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
return {
|
return {
|
||||||
@ -492,7 +492,7 @@ class Record(object):
|
|||||||
|
|
||||||
def delete(self, domain):
|
def delete(self, domain):
|
||||||
"""
|
"""
|
||||||
Delete a record from domain
|
Delete a record from zone
|
||||||
"""
|
"""
|
||||||
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
headers = {'X-API-Key': self.PDNS_API_KEY, 'Content-Type': 'application/json'}
|
||||||
data = {
|
data = {
|
||||||
@ -517,7 +517,7 @@ class Record(object):
|
|||||||
return {'status': 'ok', 'msg': 'Record was removed successfully'}
|
return {'status': 'ok', 'msg': 'Record was removed successfully'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Cannot remove record {0}/{1}/{2} from domain {3}. DETAIL: {4}"
|
"Cannot remove record {0}/{1}/{2} from zone {3}. DETAIL: {4}"
|
||||||
.format(self.name, self.type, self.data, domain, e))
|
.format(self.name, self.type, self.data, domain, e))
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
@ -540,7 +540,7 @@ class Record(object):
|
|||||||
|
|
||||||
def exists(self, domain):
|
def exists(self, domain):
|
||||||
"""
|
"""
|
||||||
Check if record is present within domain records, and if it's present set self to found record
|
Check if record is present within zone records, and if it's present set self to found record
|
||||||
"""
|
"""
|
||||||
rrsets = self.get_rrsets(domain)
|
rrsets = self.get_rrsets(domain)
|
||||||
for r in rrsets:
|
for r in rrsets:
|
||||||
@ -588,7 +588,7 @@ class Record(object):
|
|||||||
return {'status': 'ok', 'msg': 'Record was updated successfully'}
|
return {'status': 'ok', 'msg': 'Record was updated successfully'}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Cannot add record {0}/{1}/{2} to domain {3}. DETAIL: {4}".
|
"Cannot add record {0}/{1}/{2} to zone {3}. DETAIL: {4}".
|
||||||
format(self.name, self.type, self.data, domain, e))
|
format(self.name, self.type, self.data, domain, e))
|
||||||
return {
|
return {
|
||||||
'status': 'error',
|
'status': 'error',
|
||||||
@ -614,11 +614,11 @@ class Record(object):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
return {
|
return {
|
||||||
'status': True,
|
'status': True,
|
||||||
'msg': 'Synced local serial for domain name {0}'.format(domain)
|
'msg': 'Synced local serial for zone name {0}'.format(domain)
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
return {
|
return {
|
||||||
'status': False,
|
'status': False,
|
||||||
'msg':
|
'msg':
|
||||||
'Could not find domain name {0} in local db'.format(domain)
|
'Could not find zone name {0} in local db'.format(domain)
|
||||||
}
|
}
|
||||||
|
@ -527,7 +527,7 @@ class User(db.Model):
|
|||||||
|
|
||||||
def get_domains(self):
|
def get_domains(self):
|
||||||
"""
|
"""
|
||||||
Get list of domains which the user is granted to have
|
Get list of zones which the user is granted to have
|
||||||
access.
|
access.
|
||||||
|
|
||||||
Note: This doesn't include the permission granting from Account
|
Note: This doesn't include the permission granting from Account
|
||||||
@ -680,7 +680,7 @@ class User(db.Model):
|
|||||||
|
|
||||||
def addMissingDomain(self, autoprovision_domain, current_domains):
|
def addMissingDomain(self, autoprovision_domain, current_domains):
|
||||||
"""
|
"""
|
||||||
Add domain gathered by autoprovisioning to the current domains list of a user
|
Add domain gathered by autoprovisioning to the current zones list of a user
|
||||||
"""
|
"""
|
||||||
from ..models.domain import Domain
|
from ..models.domain import Domain
|
||||||
user = db.session.query(User).filter(User.username == self.username).first()
|
user = db.session.query(User).filter(User.username == self.username).first()
|
||||||
|
@ -838,10 +838,10 @@ class DetailedHistory():
|
|||||||
|
|
||||||
detail_dict = json.loads(history.detail)
|
detail_dict = json.loads(history.detail)
|
||||||
|
|
||||||
if 'domain_type' in detail_dict and 'account_id' in detail_dict: # this is a domain creation
|
if 'domain_type' in detail_dict and 'account_id' in detail_dict: # this is a zone creation
|
||||||
self.detailed_msg = render_template_string("""
|
self.detailed_msg = render_template_string("""
|
||||||
<table class="table table-bordered table-striped">
|
<table class="table table-bordered table-striped">
|
||||||
<tr><td>Domain Type:</td><td>{{ domaintype }}</td></tr>
|
<tr><td>Zone Type:</td><td>{{ domaintype }}</td></tr>
|
||||||
<tr><td>Account:</td><td>{{ account }}</td></tr>
|
<tr><td>Account:</td><td>{{ account }}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
""",
|
""",
|
||||||
@ -881,7 +881,7 @@ class DetailedHistory():
|
|||||||
authenticator=detail_dict['authenticator'],
|
authenticator=detail_dict['authenticator'],
|
||||||
ip_address=detail_dict['ip_address'])
|
ip_address=detail_dict['ip_address'])
|
||||||
|
|
||||||
elif 'add_rrsets' in detail_dict: # this is a domain record change
|
elif 'add_rrsets' in detail_dict: # this is a zone record change
|
||||||
# changes_set = []
|
# changes_set = []
|
||||||
self.detailed_msg = ""
|
self.detailed_msg = ""
|
||||||
# extract_changelogs_from_a_history_entry(changes_set, history, 0)
|
# extract_changelogs_from_a_history_entry(changes_set, history, 0)
|
||||||
@ -897,11 +897,11 @@ class DetailedHistory():
|
|||||||
description=DetailedHistory.get_key_val(detail_dict,
|
description=DetailedHistory.get_key_val(detail_dict,
|
||||||
"description"))
|
"description"))
|
||||||
|
|
||||||
elif 'Change domain' in history.msg and 'access control' in history.msg: # added or removed a user from a domain
|
elif any(msg in history.msg for msg in ['Change zone','Change domain']) and 'access control' in history.msg: # added or removed a user from a zone
|
||||||
users_with_access = DetailedHistory.get_key_val(detail_dict, "user_has_access")
|
users_with_access = DetailedHistory.get_key_val(detail_dict, "user_has_access")
|
||||||
self.detailed_msg = render_template_string("""
|
self.detailed_msg = render_template_string("""
|
||||||
<table class="table table-bordered table-striped">
|
<table class="table table-bordered table-striped">
|
||||||
<tr><td>Users with access to this domain</td><td>{{ users_with_access }}</td></tr>
|
<tr><td>Users with access to this zone</td><td>{{ users_with_access }}</td></tr>
|
||||||
<tr><td>Number of users:</td><td>{{ users_with_access | length }}</td><tr>
|
<tr><td>Number of users:</td><td>{{ users_with_access | length }}</td><tr>
|
||||||
</table>
|
</table>
|
||||||
""",
|
""",
|
||||||
@ -913,7 +913,7 @@ class DetailedHistory():
|
|||||||
<tr><td>Key: </td><td>{{ keyname }}</td></tr>
|
<tr><td>Key: </td><td>{{ keyname }}</td></tr>
|
||||||
<tr><td>Role:</td><td>{{ rolename }}</td></tr>
|
<tr><td>Role:</td><td>{{ rolename }}</td></tr>
|
||||||
<tr><td>Description:</td><td>{{ description }}</td></tr>
|
<tr><td>Description:</td><td>{{ description }}</td></tr>
|
||||||
<tr><td>Accessible domains with this API key:</td><td>{{ linked_domains }}</td></tr>
|
<tr><td>Accessible zones with this API key:</td><td>{{ linked_domains }}</td></tr>
|
||||||
<tr><td>Accessible accounts with this API key:</td><td>{{ linked_accounts }}</td></tr>
|
<tr><td>Accessible accounts with this API key:</td><td>{{ linked_accounts }}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
""",
|
""",
|
||||||
@ -932,7 +932,7 @@ class DetailedHistory():
|
|||||||
<tr><td>Key: </td><td>{{ keyname }}</td></tr>
|
<tr><td>Key: </td><td>{{ keyname }}</td></tr>
|
||||||
<tr><td>Role:</td><td>{{ rolename }}</td></tr>
|
<tr><td>Role:</td><td>{{ rolename }}</td></tr>
|
||||||
<tr><td>Description:</td><td>{{ description }}</td></tr>
|
<tr><td>Description:</td><td>{{ description }}</td></tr>
|
||||||
<tr><td>Accessible domains with this API key:</td><td>{{ linked_domains }}</td></tr>
|
<tr><td>Accessible zones with this API key:</td><td>{{ linked_domains }}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
""",
|
""",
|
||||||
keyname=DetailedHistory.get_key_val(detail_dict, "key"),
|
keyname=DetailedHistory.get_key_val(detail_dict, "key"),
|
||||||
@ -942,11 +942,11 @@ class DetailedHistory():
|
|||||||
linked_domains=DetailedHistory.get_key_val(detail_dict,
|
linked_domains=DetailedHistory.get_key_val(detail_dict,
|
||||||
"domains"))
|
"domains"))
|
||||||
|
|
||||||
elif 'Update type for domain' in history.msg:
|
elif any(msg in history.msg for msg in ['Update type for zone','Update type for domain']):
|
||||||
self.detailed_msg = render_template_string("""
|
self.detailed_msg = render_template_string("""
|
||||||
<table class="table table-bordered table-striped">
|
<table class="table table-bordered table-striped">
|
||||||
<tr><td>Domain: </td><td>{{ domain }}</td></tr>
|
<tr><td>Zone: </td><td>{{ domain }}</td></tr>
|
||||||
<tr><td>Domain type:</td><td>{{ domain_type }}</td></tr>
|
<tr><td>Zone type:</td><td>{{ domain_type }}</td></tr>
|
||||||
<tr><td>Masters:</td><td>{{ masters }}</td></tr>
|
<tr><td>Masters:</td><td>{{ masters }}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
""",
|
""",
|
||||||
@ -957,8 +957,8 @@ class DetailedHistory():
|
|||||||
elif 'reverse' in history.msg:
|
elif 'reverse' in history.msg:
|
||||||
self.detailed_msg = render_template_string("""
|
self.detailed_msg = render_template_string("""
|
||||||
<table class="table table-bordered table-striped">
|
<table class="table table-bordered table-striped">
|
||||||
<tr><td>Domain Type: </td><td>{{ domain_type }}</td></tr>
|
<tr><td>Zone Type: </td><td>{{ domain_type }}</td></tr>
|
||||||
<tr><td>Domain Master IPs:</td><td>{{ domain_master_ips }}</td></tr>
|
<tr><td>Zone Master IPs:</td><td>{{ domain_master_ips }}</td></tr>
|
||||||
</table>
|
</table>
|
||||||
""",
|
""",
|
||||||
domain_type=DetailedHistory.get_key_val(detail_dict,
|
domain_type=DetailedHistory.get_key_val(detail_dict,
|
||||||
@ -977,7 +977,7 @@ class DetailedHistory():
|
|||||||
'status'),
|
'status'),
|
||||||
history_msg=DetailedHistory.get_key_val(detail_dict, 'msg'))
|
history_msg=DetailedHistory.get_key_val(detail_dict, 'msg'))
|
||||||
|
|
||||||
elif 'Update domain' in history.msg and 'associate account' in history.msg: # When an account gets associated or dissociate with domains
|
elif any(msg in history.msg for msg in ['Update zone','Update domain']) and 'associate account' in history.msg: # When an account gets associated or dissociate with zones
|
||||||
self.detailed_msg = render_template_string('''
|
self.detailed_msg = render_template_string('''
|
||||||
<table class="table table-bordered table-striped">
|
<table class="table table-bordered table-striped">
|
||||||
<tr><td>Associate: </td><td>{{ history_assoc_account }}</td></tr>
|
<tr><td>Associate: </td><td>{{ history_assoc_account }}</td></tr>
|
||||||
@ -1164,7 +1164,7 @@ def history_table(): # ajax call data
|
|||||||
else:
|
else:
|
||||||
# if the user isn't an administrator or operator,
|
# if the user isn't an administrator or operator,
|
||||||
# allow_user_view_history must be enabled to get here,
|
# allow_user_view_history must be enabled to get here,
|
||||||
# so include history for the domains for the user
|
# so include history for the zones for the user
|
||||||
base_query = db.session.query(History) \
|
base_query = db.session.query(History) \
|
||||||
.join(Domain, History.domain_id == Domain.id) \
|
.join(Domain, History.domain_id == Domain.id) \
|
||||||
.outerjoin(DomainUser, Domain.id == DomainUser.domain_id) \
|
.outerjoin(DomainUser, Domain.id == DomainUser.domain_id) \
|
||||||
@ -1231,11 +1231,14 @@ def history_table(): # ajax call data
|
|||||||
.filter(
|
.filter(
|
||||||
db.and_(
|
db.and_(
|
||||||
db.or_(
|
db.or_(
|
||||||
History.msg.like("%domain " + domain_name) if domain_name != "*" else History.msg.like(
|
History.msg.like("%domain " + domain_name) if domain_name != "*" else History.msg.like("%domain%"),
|
||||||
"%domain%"),
|
History.msg.like("%zone " + domain_name) if domain_name != "*" else History.msg.like("%zone%"),
|
||||||
History.msg.like(
|
History.msg.like(
|
||||||
"%domain " + domain_name + " access control") if domain_name != "*" else History.msg.like(
|
"%domain " + domain_name + " access control") if domain_name != "*" else History.msg.like(
|
||||||
"%domain%access control")
|
"%domain%access control"),
|
||||||
|
History.msg.like(
|
||||||
|
"%zone " + domain_name + " access control") if domain_name != "*" else History.msg.like(
|
||||||
|
"%zone%access control")
|
||||||
),
|
),
|
||||||
History.created_on <= max_date if max_date != None else True,
|
History.created_on <= max_date if max_date != None else True,
|
||||||
History.created_on >= min_date if min_date != None else True,
|
History.created_on >= min_date if min_date != None else True,
|
||||||
@ -1247,8 +1250,12 @@ def history_table(): # ajax call data
|
|||||||
histories = base_query \
|
histories = base_query \
|
||||||
.filter(
|
.filter(
|
||||||
db.and_(
|
db.and_(
|
||||||
|
db.or_(
|
||||||
History.msg.like("Apply record changes to domain " + domain_name) if domain_name != "*" \
|
History.msg.like("Apply record changes to domain " + domain_name) if domain_name != "*" \
|
||||||
else History.msg.like("Apply record changes to domain%"),
|
else History.msg.like("Apply record changes to domain%"),
|
||||||
|
History.msg.like("Apply record changes to zone " + domain_name) if domain_name != "*" \
|
||||||
|
else History.msg.like("Apply record changes to zone%"),
|
||||||
|
),
|
||||||
History.created_on <= max_date if max_date != None else True,
|
History.created_on <= max_date if max_date != None else True,
|
||||||
History.created_on >= min_date if min_date != None else True,
|
History.created_on >= min_date if min_date != None else True,
|
||||||
History.created_by == changed_by if changed_by != None else True
|
History.created_by == changed_by if changed_by != None else True
|
||||||
@ -1858,7 +1865,7 @@ def create_template():
|
|||||||
t = DomainTemplate(name=name, description=description)
|
t = DomainTemplate(name=name, description=description)
|
||||||
result = t.create()
|
result = t.create()
|
||||||
if result['status'] == 'ok':
|
if result['status'] == 'ok':
|
||||||
history = History(msg='Add domain template {0}'.format(name),
|
history = History(msg='Add zone template {0}'.format(name),
|
||||||
detail=json.dumps({
|
detail=json.dumps({
|
||||||
'name': name,
|
'name': name,
|
||||||
'description': description
|
'description': description
|
||||||
@ -1871,7 +1878,7 @@ def create_template():
|
|||||||
return redirect(url_for('admin.create_template'))
|
return redirect(url_for('admin.create_template'))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot create domain template. Error: {0}'.format(e))
|
'Cannot create zone template. Error: {0}'.format(e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
@ -1905,7 +1912,7 @@ def create_template_from_zone():
|
|||||||
t = DomainTemplate(name=name, description=description)
|
t = DomainTemplate(name=name, description=description)
|
||||||
result = t.create()
|
result = t.create()
|
||||||
if result['status'] == 'ok':
|
if result['status'] == 'ok':
|
||||||
history = History(msg='Add domain template {0}'.format(name),
|
history = History(msg='Add zone template {0}'.format(name),
|
||||||
detail=json.dumps({
|
detail=json.dumps({
|
||||||
'name': name,
|
'name': name,
|
||||||
'description': description
|
'description': description
|
||||||
@ -1913,7 +1920,7 @@ def create_template_from_zone():
|
|||||||
created_by=current_user.username)
|
created_by=current_user.username)
|
||||||
history.add()
|
history.add()
|
||||||
|
|
||||||
# After creating the domain in Domain Template in the,
|
# After creating the zone in Zone Template in the,
|
||||||
# local DB. We add records into it Record Template.
|
# local DB. We add records into it Record Template.
|
||||||
records = []
|
records = []
|
||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
@ -1942,7 +1949,7 @@ def create_template_from_zone():
|
|||||||
'msg': result['msg']
|
'msg': result['msg']
|
||||||
}), 200)
|
}), 200)
|
||||||
else:
|
else:
|
||||||
# Revert the domain template (remove it)
|
# Revert the zone template (remove it)
|
||||||
# ff we cannot add records.
|
# ff we cannot add records.
|
||||||
t.delete_template()
|
t.delete_template()
|
||||||
return make_response(
|
return make_response(
|
||||||
@ -1999,7 +2006,7 @@ def edit_template(template):
|
|||||||
ttl_options=ttl_options)
|
ttl_options=ttl_options)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot open domain template page. DETAIL: {0}'.format(e))
|
'Cannot open zone template page. DETAIL: {0}'.format(e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
abort(500)
|
abort(500)
|
||||||
return redirect(url_for('admin.templates'))
|
return redirect(url_for('admin.templates'))
|
||||||
@ -2037,7 +2044,7 @@ def apply_records(template):
|
|||||||
jdata.pop('_csrf_token',
|
jdata.pop('_csrf_token',
|
||||||
None) # don't store csrf token in the history.
|
None) # don't store csrf token in the history.
|
||||||
history = History(
|
history = History(
|
||||||
msg='Apply domain template record changes to domain template {0}'
|
msg='Apply zone template record changes to zone template {0}'
|
||||||
.format(template),
|
.format(template),
|
||||||
detail=json.dumps(jdata),
|
detail=json.dumps(jdata),
|
||||||
created_by=current_user.username)
|
created_by=current_user.username)
|
||||||
@ -2068,7 +2075,7 @@ def delete_template(template):
|
|||||||
result = t.delete_template()
|
result = t.delete_template()
|
||||||
if result['status'] == 'ok':
|
if result['status'] == 'ok':
|
||||||
history = History(
|
history = History(
|
||||||
msg='Deleted domain template {0}'.format(template),
|
msg='Deleted zone template {0}'.format(template),
|
||||||
detail=json.dumps({'name': template}),
|
detail=json.dumps({'name': template}),
|
||||||
created_by=current_user.username)
|
created_by=current_user.username)
|
||||||
history.add()
|
history.add()
|
||||||
|
@ -211,7 +211,7 @@ def api_login_create_zone():
|
|||||||
accept='application/json; q=1',
|
accept='application/json; q=1',
|
||||||
verify=Setting().get('verify_ssl_connections'))
|
verify=Setting().get('verify_ssl_connections'))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error("Cannot create domain. Error: {}".format(e))
|
current_app.logger.error("Cannot create zone. Error: {}".format(e))
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
if resp.status_code == 201:
|
if resp.status_code == 201:
|
||||||
@ -222,7 +222,7 @@ def api_login_create_zone():
|
|||||||
domain.update()
|
domain.update()
|
||||||
domain_id = domain.get_id_by_name(data['name'].rstrip('.'))
|
domain_id = domain.get_id_by_name(data['name'].rstrip('.'))
|
||||||
|
|
||||||
history = History(msg='Add domain {0}'.format(
|
history = History(msg='Add zone {0}'.format(
|
||||||
data['name'].rstrip('.')),
|
data['name'].rstrip('.')),
|
||||||
detail=json.dumps(data),
|
detail=json.dumps(data),
|
||||||
created_by=current_user.username,
|
created_by=current_user.username,
|
||||||
@ -230,7 +230,7 @@ def api_login_create_zone():
|
|||||||
history.add()
|
history.add()
|
||||||
|
|
||||||
if current_user.role.name not in ['Administrator', 'Operator']:
|
if current_user.role.name not in ['Administrator', 'Operator']:
|
||||||
current_app.logger.debug("User is ordinary user, assigning created domain")
|
current_app.logger.debug("User is ordinary user, assigning created zone")
|
||||||
domain = Domain(name=data['name'].rstrip('.'))
|
domain = Domain(name=data['name'].rstrip('.'))
|
||||||
domain.update()
|
domain.update()
|
||||||
domain.grant_privileges([current_user.id])
|
domain.grant_privileges([current_user.id])
|
||||||
@ -296,7 +296,7 @@ def api_login_delete_zone(domain_name):
|
|||||||
domain_id = domain.get_id_by_name(domain_name)
|
domain_id = domain.get_id_by_name(domain_name)
|
||||||
domain.update()
|
domain.update()
|
||||||
|
|
||||||
history = History(msg='Delete domain {0}'.format(
|
history = History(msg='Delete zone {0}'.format(
|
||||||
utils.pretty_domain_name(domain_name)),
|
utils.pretty_domain_name(domain_name)),
|
||||||
detail='',
|
detail='',
|
||||||
created_by=current_user.username,
|
created_by=current_user.username,
|
||||||
@ -347,13 +347,13 @@ def api_generate_apikey():
|
|||||||
abort(400)
|
abort(400)
|
||||||
|
|
||||||
if role_name == 'User' and len(domains) == 0 and len(accounts) == 0:
|
if role_name == 'User' and len(domains) == 0 and len(accounts) == 0:
|
||||||
current_app.logger.error("Apikey with User role must have domains or accounts")
|
current_app.logger.error("Apikey with User role must have zones or accounts")
|
||||||
raise ApiKeyNotUsable()
|
raise ApiKeyNotUsable()
|
||||||
|
|
||||||
if role_name == 'User' and len(domains) > 0:
|
if role_name == 'User' and len(domains) > 0:
|
||||||
domain_obj_list = Domain.query.filter(Domain.name.in_(domains)).all()
|
domain_obj_list = Domain.query.filter(Domain.name.in_(domains)).all()
|
||||||
if len(domain_obj_list) == 0:
|
if len(domain_obj_list) == 0:
|
||||||
msg = "One of supplied domains does not exist"
|
msg = "One of supplied zones does not exist"
|
||||||
current_app.logger.error(msg)
|
current_app.logger.error(msg)
|
||||||
raise DomainNotExists(message=msg)
|
raise DomainNotExists(message=msg)
|
||||||
|
|
||||||
@ -383,13 +383,13 @@ def api_generate_apikey():
|
|||||||
domain_list = [item.name for item in domain_obj_list]
|
domain_list = [item.name for item in domain_obj_list]
|
||||||
user_domain_list = [item.name for item in user_domain_obj_list]
|
user_domain_list = [item.name for item in user_domain_obj_list]
|
||||||
|
|
||||||
current_app.logger.debug("Input domain list: {0}".format(domain_list))
|
current_app.logger.debug("Input zone list: {0}".format(domain_list))
|
||||||
current_app.logger.debug("User domain list: {0}".format(user_domain_list))
|
current_app.logger.debug("User zone list: {0}".format(user_domain_list))
|
||||||
|
|
||||||
inter = set(domain_list).intersection(set(user_domain_list))
|
inter = set(domain_list).intersection(set(user_domain_list))
|
||||||
|
|
||||||
if not (len(inter) == len(domain_list)):
|
if not (len(inter) == len(domain_list)):
|
||||||
msg = "You don't have access to one of domains"
|
msg = "You don't have access to one of zones"
|
||||||
current_app.logger.error(msg)
|
current_app.logger.error(msg)
|
||||||
raise DomainAccessForbidden(message=msg)
|
raise DomainAccessForbidden(message=msg)
|
||||||
|
|
||||||
@ -417,7 +417,7 @@ def api_get_apikeys(domain_name):
|
|||||||
|
|
||||||
if current_user.role.name not in ['Administrator', 'Operator']:
|
if current_user.role.name not in ['Administrator', 'Operator']:
|
||||||
if domain_name:
|
if domain_name:
|
||||||
msg = "Check if domain {0} exists and is allowed for user.".format(
|
msg = "Check if zone {0} exists and is allowed for user.".format(
|
||||||
domain_name)
|
domain_name)
|
||||||
current_app.logger.debug(msg)
|
current_app.logger.debug(msg)
|
||||||
apikeys = get_user_apikeys(domain_name)
|
apikeys = get_user_apikeys(domain_name)
|
||||||
@ -427,7 +427,7 @@ def api_get_apikeys(domain_name):
|
|||||||
|
|
||||||
current_app.logger.debug(apikey_schema.dump(apikeys))
|
current_app.logger.debug(apikey_schema.dump(apikeys))
|
||||||
else:
|
else:
|
||||||
msg_str = "Getting all allowed domains for user {0}"
|
msg_str = "Getting all allowed zones for user {0}"
|
||||||
msg = msg_str.format(current_user.username)
|
msg = msg_str.format(current_user.username)
|
||||||
current_app.logger.debug(msg)
|
current_app.logger.debug(msg)
|
||||||
|
|
||||||
@ -438,7 +438,7 @@ def api_get_apikeys(domain_name):
|
|||||||
current_app.logger.error('Error: {0}'.format(e))
|
current_app.logger.error('Error: {0}'.format(e))
|
||||||
abort(500)
|
abort(500)
|
||||||
else:
|
else:
|
||||||
current_app.logger.debug("Getting all domains for administrative user")
|
current_app.logger.debug("Getting all zones for administrative user")
|
||||||
try:
|
try:
|
||||||
apikeys = ApiKey.query.all()
|
apikeys = ApiKey.query.all()
|
||||||
current_app.logger.debug(apikey_schema.dump(apikeys))
|
current_app.logger.debug(apikey_schema.dump(apikeys))
|
||||||
@ -488,7 +488,7 @@ def api_delete_apikey(apikey_id):
|
|||||||
inter = set(apikey_domains_list).intersection(set(user_domains_list))
|
inter = set(apikey_domains_list).intersection(set(user_domains_list))
|
||||||
|
|
||||||
if not (len(inter) == len(apikey_domains_list)):
|
if not (len(inter) == len(apikey_domains_list)):
|
||||||
msg = "You don't have access to some domains apikey belongs to"
|
msg = "You don't have access to some zones apikey belongs to"
|
||||||
current_app.logger.error(msg)
|
current_app.logger.error(msg)
|
||||||
raise DomainAccessForbidden(message=msg)
|
raise DomainAccessForbidden(message=msg)
|
||||||
|
|
||||||
@ -558,7 +558,7 @@ def api_update_apikey(apikey_id):
|
|||||||
if domains is not None:
|
if domains is not None:
|
||||||
domain_obj_list = Domain.query.filter(Domain.name.in_(domains)).all()
|
domain_obj_list = Domain.query.filter(Domain.name.in_(domains)).all()
|
||||||
if len(domain_obj_list) != len(domains):
|
if len(domain_obj_list) != len(domains):
|
||||||
msg = "One of supplied domains does not exist"
|
msg = "One of supplied zones does not exist"
|
||||||
current_app.logger.error(msg)
|
current_app.logger.error(msg)
|
||||||
raise DomainNotExists(message=msg)
|
raise DomainNotExists(message=msg)
|
||||||
|
|
||||||
@ -578,12 +578,12 @@ def api_update_apikey(apikey_id):
|
|||||||
target_accounts = current_accounts
|
target_accounts = current_accounts
|
||||||
|
|
||||||
if len(target_domains) == 0 and len(target_accounts) == 0:
|
if len(target_domains) == 0 and len(target_accounts) == 0:
|
||||||
current_app.logger.error("Apikey with User role must have domains or accounts")
|
current_app.logger.error("Apikey with User role must have zones or accounts")
|
||||||
raise ApiKeyNotUsable()
|
raise ApiKeyNotUsable()
|
||||||
|
|
||||||
if domains is not None and set(domains) == set(current_domains):
|
if domains is not None and set(domains) == set(current_domains):
|
||||||
current_app.logger.debug(
|
current_app.logger.debug(
|
||||||
"Domains are the same, apikey domains won't be updated")
|
"Zones are the same, apikey zones won't be updated")
|
||||||
domains = None
|
domains = None
|
||||||
|
|
||||||
if accounts is not None and set(accounts) == set(current_accounts):
|
if accounts is not None and set(accounts) == set(current_accounts):
|
||||||
@ -610,19 +610,19 @@ def api_update_apikey(apikey_id):
|
|||||||
domain_list = [item.name for item in domain_obj_list]
|
domain_list = [item.name for item in domain_obj_list]
|
||||||
user_domain_list = [item.name for item in user_domain_obj_list]
|
user_domain_list = [item.name for item in user_domain_obj_list]
|
||||||
|
|
||||||
current_app.logger.debug("Input domain list: {0}".format(domain_list))
|
current_app.logger.debug("Input zone list: {0}".format(domain_list))
|
||||||
current_app.logger.debug(
|
current_app.logger.debug(
|
||||||
"User domain list: {0}".format(user_domain_list))
|
"User zone list: {0}".format(user_domain_list))
|
||||||
|
|
||||||
inter = set(domain_list).intersection(set(user_domain_list))
|
inter = set(domain_list).intersection(set(user_domain_list))
|
||||||
|
|
||||||
if not (len(inter) == len(domain_list)):
|
if not (len(inter) == len(domain_list)):
|
||||||
msg = "You don't have access to one of domains"
|
msg = "You don't have access to one of zones"
|
||||||
current_app.logger.error(msg)
|
current_app.logger.error(msg)
|
||||||
raise DomainAccessForbidden(message=msg)
|
raise DomainAccessForbidden(message=msg)
|
||||||
|
|
||||||
if apikey_id not in apikeys_ids:
|
if apikey_id not in apikeys_ids:
|
||||||
msg = 'Apikey does not belong to domain to which user has access'
|
msg = 'Apikey does not belong to zone to which user has access'
|
||||||
current_app.logger.error(msg)
|
current_app.logger.error(msg)
|
||||||
raise DomainAccessForbidden()
|
raise DomainAccessForbidden()
|
||||||
|
|
||||||
@ -966,9 +966,9 @@ def api_delete_account(account_id):
|
|||||||
# Remove account association from domains first
|
# Remove account association from domains first
|
||||||
if len(account.domains) > 0:
|
if len(account.domains) > 0:
|
||||||
for domain in account.domains:
|
for domain in account.domains:
|
||||||
current_app.logger.info(f"Disassociating domain {domain.name} with {account.name}")
|
current_app.logger.info(f"Disassociating zone {domain.name} with {account.name}")
|
||||||
Domain(name=domain.name).assoc_account(None, update=False)
|
Domain(name=domain.name).assoc_account(None, update=False)
|
||||||
current_app.logger.info("Syncing all domains")
|
current_app.logger.info("Syncing all zones")
|
||||||
Domain().update()
|
Domain().update()
|
||||||
|
|
||||||
current_app.logger.debug(
|
current_app.logger.debug(
|
||||||
@ -1117,7 +1117,7 @@ def api_zone_forward(server_id, zone_id):
|
|||||||
if request.method in ['POST', 'PATCH']:
|
if request.method in ['POST', 'PATCH']:
|
||||||
data = request.get_json(force=True)
|
data = request.get_json(force=True)
|
||||||
history = History(
|
history = History(
|
||||||
msg='Apply record changes to domain {0}'.format(zone_id.rstrip('.')),
|
msg='Apply record changes to zone {0}'.format(zone_id.rstrip('.')),
|
||||||
detail = json.dumps({
|
detail = json.dumps({
|
||||||
'domain': zone_id.rstrip('.'),
|
'domain': zone_id.rstrip('.'),
|
||||||
'add_rrsets': list(filter(lambda r: r['changetype'] == "REPLACE", data['rrsets'])),
|
'add_rrsets': list(filter(lambda r: r['changetype'] == "REPLACE", data['rrsets'])),
|
||||||
@ -1164,14 +1164,14 @@ def api_create_zone(server_id):
|
|||||||
|
|
||||||
if g.apikey.role.name not in ['Administrator', 'Operator']:
|
if g.apikey.role.name not in ['Administrator', 'Operator']:
|
||||||
current_app.logger.debug(
|
current_app.logger.debug(
|
||||||
"Apikey is user key, assigning created domain")
|
"Apikey is user key, assigning created zone")
|
||||||
domain = Domain(name=data['name'].rstrip('.'))
|
domain = Domain(name=data['name'].rstrip('.'))
|
||||||
g.apikey.domains.append(domain)
|
g.apikey.domains.append(domain)
|
||||||
|
|
||||||
domain = Domain()
|
domain = Domain()
|
||||||
domain.update()
|
domain.update()
|
||||||
|
|
||||||
history = History(msg='Add domain {0}'.format(
|
history = History(msg='Add zone {0}'.format(
|
||||||
data['name'].rstrip('.')),
|
data['name'].rstrip('.')),
|
||||||
detail=json.dumps(data),
|
detail=json.dumps(data),
|
||||||
created_by=created_by_value,
|
created_by=created_by_value,
|
||||||
@ -1198,7 +1198,7 @@ def api_get_zones(server_id):
|
|||||||
|
|
||||||
accounts_domains = [d.name for a in g.apikey.accounts for d in a.domains]
|
accounts_domains = [d.name for a in g.apikey.accounts for d in a.domains]
|
||||||
allowed_domains = set(domain_list + accounts_domains)
|
allowed_domains = set(domain_list + accounts_domains)
|
||||||
current_app.logger.debug("Account domains: {}".format('/'.join(accounts_domains)))
|
current_app.logger.debug("Account zones: {}".format('/'.join(accounts_domains)))
|
||||||
content = json.dumps([i for i in json.loads(resp.content)
|
content = json.dumps([i for i in json.loads(resp.content)
|
||||||
if i['name'].rstrip('.') in allowed_domains])
|
if i['name'].rstrip('.') in allowed_domains])
|
||||||
return content, resp.status_code, resp.headers.items()
|
return content, resp.status_code, resp.headers.items()
|
||||||
@ -1236,14 +1236,14 @@ def health():
|
|||||||
domain_to_query = domain.query.first()
|
domain_to_query = domain.query.first()
|
||||||
|
|
||||||
if not domain_to_query:
|
if not domain_to_query:
|
||||||
current_app.logger.error("No domain found to query a health check")
|
current_app.logger.error("No zone found to query a health check")
|
||||||
return make_response("Unknown", 503)
|
return make_response("Unknown", 503)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
domain.get_domain_info(domain_to_query.name)
|
domain.get_domain_info(domain_to_query.name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
"Health Check - Failed to query authoritative server for domain {}".format(domain_to_query.name))
|
"Health Check - Failed to query authoritative server for zone {}".format(domain_to_query.name))
|
||||||
return make_response("Down", 503)
|
return make_response("Down", 503)
|
||||||
|
|
||||||
return make_response("Up", 200)
|
return make_response("Up", 200)
|
||||||
|
@ -60,15 +60,31 @@ def login_via_authorization_header_or_remote_user(request):
|
|||||||
# Try to login using Basic Authentication
|
# Try to login using Basic Authentication
|
||||||
auth_header = request.headers.get('Authorization')
|
auth_header = request.headers.get('Authorization')
|
||||||
if auth_header:
|
if auth_header:
|
||||||
|
|
||||||
|
if auth_header[:6] != "Basic ":
|
||||||
|
return None
|
||||||
|
|
||||||
auth_method = request.args.get('auth_method', 'LOCAL')
|
auth_method = request.args.get('auth_method', 'LOCAL')
|
||||||
auth_method = 'LDAP' if auth_method != 'LOCAL' else 'LOCAL'
|
auth_method = 'LDAP' if auth_method != 'LOCAL' else 'LOCAL'
|
||||||
auth_header = auth_header.replace('Basic ', '', 1)
|
|
||||||
|
# Remove "Basic " from the header value
|
||||||
|
auth_header = auth_header[6:]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
auth_header = str(base64.b64decode(auth_header), 'utf-8')
|
auth_header = str(base64.b64decode(auth_header), 'utf-8')
|
||||||
username, password = auth_header.split(":")
|
except (UnicodeDecodeError, TypeError) as e:
|
||||||
except TypeError as e:
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# NK: We use auth_components here as we don't know if we'll have a :, we split it maximum 1 times to grab the
|
||||||
|
# username, the rest of the string would be the password.
|
||||||
|
auth_components = auth_header.split(':', maxsplit=1)
|
||||||
|
|
||||||
|
# If we don't have two auth components (username, password), we can return
|
||||||
|
if len(auth_components) != 2:
|
||||||
|
return None
|
||||||
|
|
||||||
|
(username, password) = auth_components
|
||||||
|
|
||||||
user = User(username=username,
|
user = User(username=username,
|
||||||
password=password,
|
password=password,
|
||||||
plain_text_password=password)
|
plain_text_password=password)
|
||||||
|
@ -176,10 +176,10 @@ def dashboard():
|
|||||||
|
|
||||||
BG_DOMAIN_UPDATE = Setting().get('bg_domain_updates')
|
BG_DOMAIN_UPDATE = Setting().get('bg_domain_updates')
|
||||||
if not BG_DOMAIN_UPDATE:
|
if not BG_DOMAIN_UPDATE:
|
||||||
current_app.logger.info('Updating domains in foreground...')
|
current_app.logger.info('Updating zones in foreground...')
|
||||||
Domain().update()
|
Domain().update()
|
||||||
else:
|
else:
|
||||||
current_app.logger.info('Updating domains in background...')
|
current_app.logger.info('Updating zones in background...')
|
||||||
|
|
||||||
show_bg_domain_button = BG_DOMAIN_UPDATE
|
show_bg_domain_button = BG_DOMAIN_UPDATE
|
||||||
if BG_DOMAIN_UPDATE and current_user.role.name not in ['Administrator', 'Operator']:
|
if BG_DOMAIN_UPDATE and current_user.role.name not in ['Administrator', 'Operator']:
|
||||||
@ -196,7 +196,7 @@ def dashboard():
|
|||||||
@login_required
|
@login_required
|
||||||
@operator_role_required
|
@operator_role_required
|
||||||
def domains_updater():
|
def domains_updater():
|
||||||
current_app.logger.debug('Update domains in background')
|
current_app.logger.debug('Update zones in background')
|
||||||
d = Domain().update()
|
d = Domain().update()
|
||||||
|
|
||||||
response_data = {
|
response_data = {
|
||||||
|
@ -178,7 +178,7 @@ def remove():
|
|||||||
if result['status'] == 'error':
|
if result['status'] == 'error':
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
history = History(msg='Delete domain {0}'.format(
|
history = History(msg='Delete zone {0}'.format(
|
||||||
pretty_domain_name(domain_name)),
|
pretty_domain_name(domain_name)),
|
||||||
created_by=current_user.username)
|
created_by=current_user.username)
|
||||||
history.add()
|
history.add()
|
||||||
@ -362,7 +362,7 @@ def add():
|
|||||||
if ' ' in domain_name or not domain_name or not domain_type:
|
if ' ' in domain_name or not domain_name or not domain_type:
|
||||||
return render_template(
|
return render_template(
|
||||||
'errors/400.html',
|
'errors/400.html',
|
||||||
msg="Please enter a valid domain name"), 400
|
msg="Please enter a valid zone name"), 400
|
||||||
|
|
||||||
if domain_name.endswith('.'):
|
if domain_name.endswith('.'):
|
||||||
domain_name = domain_name[:-1]
|
domain_name = domain_name[:-1]
|
||||||
@ -385,11 +385,11 @@ def add():
|
|||||||
try:
|
try:
|
||||||
domain_name = to_idna(domain_name, 'encode')
|
domain_name = to_idna(domain_name, 'encode')
|
||||||
except:
|
except:
|
||||||
current_app.logger.error("Cannot encode the domain name {}".format(domain_name))
|
current_app.logger.error("Cannot encode the zone name {}".format(domain_name))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
return render_template(
|
return render_template(
|
||||||
'errors/400.html',
|
'errors/400.html',
|
||||||
msg="Please enter a valid domain name"), 400
|
msg="Please enter a valid zone name"), 400
|
||||||
|
|
||||||
if domain_type == 'slave':
|
if domain_type == 'slave':
|
||||||
if request.form.getlist('domain_master_address'):
|
if request.form.getlist('domain_master_address'):
|
||||||
@ -429,7 +429,7 @@ def add():
|
|||||||
else:
|
else:
|
||||||
accounts = current_user.get_accounts()
|
accounts = current_user.get_accounts()
|
||||||
|
|
||||||
msg = 'Domain already exists as a record under domain: {}'.format(upper_domain)
|
msg = 'Zone already exists as a record under zone: {}'.format(upper_domain)
|
||||||
|
|
||||||
return render_template('domain_add.html',
|
return render_template('domain_add.html',
|
||||||
domain_override_message=msg,
|
domain_override_message=msg,
|
||||||
@ -443,7 +443,7 @@ def add():
|
|||||||
account_name=account_name)
|
account_name=account_name)
|
||||||
if result['status'] == 'ok':
|
if result['status'] == 'ok':
|
||||||
domain_id = Domain().get_id_by_name(domain_name)
|
domain_id = Domain().get_id_by_name(domain_name)
|
||||||
history = History(msg='Add domain {0}'.format(
|
history = History(msg='Add zone {0}'.format(
|
||||||
pretty_domain_name(domain_name)),
|
pretty_domain_name(domain_name)),
|
||||||
detail = json.dumps({
|
detail = json.dumps({
|
||||||
'domain_type': domain_type,
|
'domain_type': domain_type,
|
||||||
@ -507,7 +507,7 @@ def add():
|
|||||||
return render_template('errors/400.html',
|
return render_template('errors/400.html',
|
||||||
msg=result['msg']), 400
|
msg=result['msg']), 400
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error('Cannot add domain. Error: {0}'.format(e))
|
current_app.logger.error('Cannot add zone. Error: {0}'.format(e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
@ -537,7 +537,7 @@ def delete(domain_name):
|
|||||||
if result['status'] == 'error':
|
if result['status'] == 'error':
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
history = History(msg='Delete domain {0}'.format(
|
history = History(msg='Delete zone {0}'.format(
|
||||||
pretty_domain_name(domain_name)),
|
pretty_domain_name(domain_name)),
|
||||||
created_by=current_user.username)
|
created_by=current_user.username)
|
||||||
history.add()
|
history.add()
|
||||||
@ -581,7 +581,7 @@ def setting(domain_name):
|
|||||||
d.grant_privileges(new_user_ids)
|
d.grant_privileges(new_user_ids)
|
||||||
|
|
||||||
history = History(
|
history = History(
|
||||||
msg='Change domain {0} access control'.format(
|
msg='Change zone {0} access control'.format(
|
||||||
pretty_domain_name(domain_name)),
|
pretty_domain_name(domain_name)),
|
||||||
detail=json.dumps({'user_has_access': new_user_list}),
|
detail=json.dumps({'user_has_access': new_user_list}),
|
||||||
created_by=current_user.username,
|
created_by=current_user.username,
|
||||||
@ -619,7 +619,7 @@ def change_type(domain_name):
|
|||||||
kind=domain_type,
|
kind=domain_type,
|
||||||
masters=domain_master_ips)
|
masters=domain_master_ips)
|
||||||
if status['status'] == 'ok':
|
if status['status'] == 'ok':
|
||||||
history = History(msg='Update type for domain {0}'.format(
|
history = History(msg='Update type for zone {0}'.format(
|
||||||
pretty_domain_name(domain_name)),
|
pretty_domain_name(domain_name)),
|
||||||
detail=json.dumps({
|
detail=json.dumps({
|
||||||
"domain": domain_name,
|
"domain": domain_name,
|
||||||
@ -653,7 +653,7 @@ def change_soa_edit_api(domain_name):
|
|||||||
soa_edit_api=new_setting)
|
soa_edit_api=new_setting)
|
||||||
if status['status'] == 'ok':
|
if status['status'] == 'ok':
|
||||||
history = History(
|
history = History(
|
||||||
msg='Update soa_edit_api for domain {0}'.format(
|
msg='Update soa_edit_api for zone {0}'.format(
|
||||||
pretty_domain_name(domain_name)),
|
pretty_domain_name(domain_name)),
|
||||||
detail = json.dumps({
|
detail = json.dumps({
|
||||||
'domain': domain_name,
|
'domain': domain_name,
|
||||||
@ -697,7 +697,7 @@ def record_apply(domain_name):
|
|||||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||||
|
|
||||||
if domain:
|
if domain:
|
||||||
current_app.logger.debug('Current domain serial: {0}'.format(
|
current_app.logger.debug('Current zone serial: {0}'.format(
|
||||||
domain.serial))
|
domain.serial))
|
||||||
|
|
||||||
if int(submitted_serial) != domain.serial:
|
if int(submitted_serial) != domain.serial:
|
||||||
@ -714,14 +714,14 @@ def record_apply(domain_name):
|
|||||||
'status':
|
'status':
|
||||||
'error',
|
'error',
|
||||||
'msg':
|
'msg':
|
||||||
'Domain name {0} does not exist'.format(pretty_domain_name(domain_name))
|
'Zone name {0} does not exist'.format(pretty_domain_name(domain_name))
|
||||||
}), 404)
|
}), 404)
|
||||||
|
|
||||||
r = Record()
|
r = Record()
|
||||||
result = r.apply(domain_name, submitted_record)
|
result = r.apply(domain_name, submitted_record)
|
||||||
if result['status'] == 'ok':
|
if result['status'] == 'ok':
|
||||||
history = History(
|
history = History(
|
||||||
msg='Apply record changes to domain {0}'.format(pretty_domain_name(domain_name)),
|
msg='Apply record changes to zone {0}'.format(pretty_domain_name(domain_name)),
|
||||||
detail = json.dumps({
|
detail = json.dumps({
|
||||||
'domain': domain_name,
|
'domain': domain_name,
|
||||||
'add_rrsets': result['data'][0]['rrsets'],
|
'add_rrsets': result['data'][0]['rrsets'],
|
||||||
@ -733,7 +733,7 @@ def record_apply(domain_name):
|
|||||||
return make_response(jsonify(result), 200)
|
return make_response(jsonify(result), 200)
|
||||||
else:
|
else:
|
||||||
history = History(
|
history = History(
|
||||||
msg='Failed to apply record changes to domain {0}'.format(
|
msg='Failed to apply record changes to zone {0}'.format(
|
||||||
pretty_domain_name(domain_name)),
|
pretty_domain_name(domain_name)),
|
||||||
detail = json.dumps({
|
detail = json.dumps({
|
||||||
'domain': domain_name,
|
'domain': domain_name,
|
||||||
@ -760,7 +760,7 @@ def record_apply(domain_name):
|
|||||||
@can_access_domain
|
@can_access_domain
|
||||||
def record_update(domain_name):
|
def record_update(domain_name):
|
||||||
"""
|
"""
|
||||||
This route is used for domain work as Slave Zone only
|
This route is used for zone work as Slave Zone only
|
||||||
Pulling the records update from its Master
|
Pulling the records update from its Master
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@ -818,7 +818,7 @@ def dnssec_enable(domain_name):
|
|||||||
dnssec = domain.enable_domain_dnssec(domain_name)
|
dnssec = domain.enable_domain_dnssec(domain_name)
|
||||||
domain_object = Domain.query.filter(domain_name == Domain.name).first()
|
domain_object = Domain.query.filter(domain_name == Domain.name).first()
|
||||||
history = History(
|
history = History(
|
||||||
msg='DNSSEC was enabled for domain ' + domain_name ,
|
msg='DNSSEC was enabled for zone ' + domain_name ,
|
||||||
created_by=current_user.username,
|
created_by=current_user.username,
|
||||||
domain_id=domain_object.id)
|
domain_id=domain_object.id)
|
||||||
history.add()
|
history.add()
|
||||||
@ -837,7 +837,7 @@ def dnssec_disable(domain_name):
|
|||||||
domain.delete_dnssec_key(domain_name, key['id'])
|
domain.delete_dnssec_key(domain_name, key['id'])
|
||||||
domain_object = Domain.query.filter(domain_name == Domain.name).first()
|
domain_object = Domain.query.filter(domain_name == Domain.name).first()
|
||||||
history = History(
|
history = History(
|
||||||
msg='DNSSEC was disabled for domain ' + domain_name ,
|
msg='DNSSEC was disabled for zone ' + domain_name ,
|
||||||
created_by=current_user.username,
|
created_by=current_user.username,
|
||||||
domain_id=domain_object.id)
|
domain_id=domain_object.id)
|
||||||
history.add()
|
history.add()
|
||||||
@ -914,7 +914,7 @@ def admin_setdomainsetting(domain_name):
|
|||||||
}), 400)
|
}), 400)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.error(
|
current_app.logger.error(
|
||||||
'Cannot change domain setting. Error: {0}'.format(e))
|
'Cannot change zone setting. Error: {0}'.format(e))
|
||||||
current_app.logger.debug(traceback.format_exc())
|
current_app.logger.debug(traceback.format_exc())
|
||||||
return make_response(
|
return make_response(
|
||||||
jsonify({
|
jsonify({
|
||||||
|
@ -96,7 +96,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.card-header -->
|
<!-- /.card-header -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>Users on the right have access to manage records in all domains
|
<p>Users on the right have access to manage records in all zones
|
||||||
associated with the account.
|
associated with the account.
|
||||||
</p>
|
</p>
|
||||||
<p>Click on users to move between columns.</p>
|
<p>Click on users to move between columns.</p>
|
||||||
@ -113,12 +113,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.card-body -->
|
<!-- /.card-body -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>Domains on the right are associated with the account. Red marked domain names are
|
<p>Zones on the right are associated with the account. Red marked zone names are
|
||||||
already associated with other accounts.
|
already associated with other accounts.
|
||||||
Moving already associated domains to this account will overwrite the previous
|
Moving already associated zones to this account will overwrite the previous
|
||||||
associated account.
|
associated account.
|
||||||
</p>
|
</p>
|
||||||
<p>Hover over the red domain names to show the associated account. Click on domains to
|
<p>Hover over the red zone names to show the associated account. Click on zones to
|
||||||
move between columns.</p>
|
move between columns.</p>
|
||||||
<div class="form-group col-2">
|
<div class="form-group col-2">
|
||||||
<select multiple="multiple" class="form-control" id="account_domains"
|
<select multiple="multiple" class="form-control" id="account_domains"
|
||||||
@ -168,12 +168,12 @@
|
|||||||
<!-- /.card-header -->
|
<!-- /.card-header -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>
|
<p>
|
||||||
An account allows grouping of domains belonging to a particular entity, such as a
|
An account allows grouping of zones belonging to a particular entity, such as a
|
||||||
customer or
|
customer or
|
||||||
department.
|
department.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
A domain can be assigned to an account upon domain creation or through the domain
|
A zone can be assigned to an account upon zone creation or through the zone
|
||||||
administration
|
administration
|
||||||
page.
|
page.
|
||||||
</p>
|
</p>
|
||||||
@ -242,6 +242,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
addMultiSelect("#account_multi_user", "Username")
|
addMultiSelect("#account_multi_user", "Username")
|
||||||
addMultiSelect("#account_domains", "Domain")
|
addMultiSelect("#account_domains", "Zone")
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
<!-- /.card-header -->
|
<!-- /.card-header -->
|
||||||
<div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
|
<div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
|
||||||
<p>This key will be linked to the accounts on the right,</p>
|
<p>This key will be linked to the accounts on the right,</p>
|
||||||
<p>thus granting access to domains owned by the selected accounts.</p>
|
<p>thus granting access to zones owned by the selected accounts.</p>
|
||||||
<p>Click on accounts to move between the columns.</p>
|
<p>Click on accounts to move between the columns.</p>
|
||||||
<div class="form-group col-2">
|
<div class="form-group col-2">
|
||||||
<select multiple="multiple" class="form-control" id="key_multi_account"
|
<select multiple="multiple" class="form-control" id="key_multi_account"
|
||||||
@ -87,12 +87,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.card-body -->
|
<!-- /.card-body -->
|
||||||
<div class="card-header key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
|
<div class="card-header key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
|
||||||
<h3 class="card-title">Domain Access Control</h3>
|
<h3 class="card-title">Zone Access Control</h3>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.card-header -->
|
<!-- /.card-header -->
|
||||||
<div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
|
<div class="card-body key-opts"{% if hide_opts %} style="display: none;"{% endif %}>
|
||||||
<p>This key will have access to the domains on the right.</p>
|
<p>This key will have access to the zones on the right.</p>
|
||||||
<p>Click on domains to move between the columns.</p>
|
<p>Click on zones to move between the columns.</p>
|
||||||
<div class="form-group col-2">
|
<div class="form-group col-2">
|
||||||
<select multiple="multiple" class="form-control" id="key_multi_domain"
|
<select multiple="multiple" class="form-control" id="key_multi_domain"
|
||||||
name="key_multi_domain">
|
name="key_multi_domain">
|
||||||
@ -131,7 +131,7 @@
|
|||||||
<p>Fill in all the fields in the form to the left.</p>
|
<p>Fill in all the fields in the form to the left.</p>
|
||||||
<p><strong>Role</strong> The role of the key.</p>
|
<p><strong>Role</strong> The role of the key.</p>
|
||||||
<p><strong>Description</strong> The key description.</p>
|
<p><strong>Description</strong> The key description.</p>
|
||||||
<p><strong>Access Control</strong> The domains or accounts which the key has access to.</p>
|
<p><strong>Access Control</strong> The zones or accounts which the key has access to.</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.card-body -->
|
<!-- /.card-body -->
|
||||||
</div>
|
</div>
|
||||||
@ -154,13 +154,13 @@
|
|||||||
var warn_modal = $("#modal_warning");
|
var warn_modal = $("#modal_warning");
|
||||||
|
|
||||||
if (selectedRole != "User" && selectedDomains > 0 && selectedAccounts > 0) {
|
if (selectedRole != "User" && selectedDomains > 0 && selectedAccounts > 0) {
|
||||||
var warning = "Administrator and Operators have access to all domains. Your domain an account selection won't be saved.";
|
var warning = "Administrator and Operators have access to all zones. Your zone an account selection won't be saved.";
|
||||||
e.preventDefault(e);
|
e.preventDefault(e);
|
||||||
warn_modal.modal('show');
|
warn_modal.modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedRole == "User" && selectedDomains == 0 && selectedAccounts == 0) {
|
if (selectedRole == "User" && selectedDomains == 0 && selectedAccounts == 0) {
|
||||||
var warning = "User role must have at least one account or one domain bound. None selected.";
|
var warning = "User role must have at least one account or one zone bound. None selected.";
|
||||||
e.preventDefault(e);
|
e.preventDefault(e);
|
||||||
warn_modal.modal('show');
|
warn_modal.modal('show');
|
||||||
}
|
}
|
||||||
@ -203,8 +203,8 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
$("#key_multi_domain").multiSelect({
|
$("#key_multi_domain").multiSelect({
|
||||||
selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Domain Name'>",
|
selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Zone Name'>",
|
||||||
selectionHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Domain Name'>",
|
selectionHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Zone Name'>",
|
||||||
afterInit: function (ms) {
|
afterInit: function (ms) {
|
||||||
var that = this,
|
var that = this,
|
||||||
$selectableSearch = that.$selectableUl.prev(),
|
$selectableSearch = that.$selectableUl.prev(),
|
||||||
|
@ -135,9 +135,9 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>Fill in all the fields to the in the form to the left.</p>
|
<p>Fill in all the fields to the in the form to the left.</p>
|
||||||
{% if create %}
|
{% if create %}
|
||||||
<p><strong>Newly created users do not have access to any domains.</strong> You will need
|
<p><strong>Newly created users do not have access to any zones.</strong> You will need
|
||||||
to grant
|
to grant
|
||||||
access to the user once it is created via the domain management buttons on the
|
access to the user once it is created via the zone management buttons on the
|
||||||
dashboard.
|
dashboard.
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
<!-- /.card-header -->
|
<!-- /.card-header -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="callout callout-info">
|
<div class="callout callout-info">
|
||||||
<p>This tool can be used to search for domains, records, and comments via the PDNS
|
<p>This tool can be used to search for zones, records, and comments via the PDNS
|
||||||
API.</p>
|
API.</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.callout -->
|
<!-- /.callout -->
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#tabs-domain" data-toggle="pill" role="tab">
|
<a class="nav-link" href="#tabs-domain" data-toggle="pill" role="tab">
|
||||||
Search By Domain
|
Search By Zone
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
@ -71,13 +71,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" id="tabs-domain">
|
<div class="tab-pane" id="tabs-domain">
|
||||||
<td>
|
<td>
|
||||||
<label>Domain Name</label>
|
<label>Zone Name</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="autocomplete" style="width:250px;">
|
<div class="autocomplete" style="width:250px;">
|
||||||
<input type="text" class="form-control" id="domain_name_filter"
|
<input type="text" class="form-control" id="domain_name_filter"
|
||||||
name="domain_name_filter"
|
name="domain_name_filter"
|
||||||
placeholder="Enter * to search for any domain" value="">
|
placeholder="Enter * to search for any zone" value="">
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -447,7 +447,7 @@
|
|||||||
$('#auth_name_filter').val('');
|
$('#auth_name_filter').val('');
|
||||||
$('#user_name_filter').removeAttr('disabled');
|
$('#user_name_filter').removeAttr('disabled');
|
||||||
canSearch = false;
|
canSearch = false;
|
||||||
main_field = "Domain Name"
|
main_field = "Zone Name"
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#account_tab').click(function () {
|
$('#account_tab').click(function () {
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
<th>Contact</th>
|
<th>Contact</th>
|
||||||
<th>Mail</th>
|
<th>Mail</th>
|
||||||
<th>Member</th>
|
<th>Member</th>
|
||||||
<th>Domain</th>
|
<th>Zone(s)</th>
|
||||||
<th>Action</th>
|
<th>Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
<th>Role</th>
|
<th>Role</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th>Domains</th>
|
<th>Zones</th>
|
||||||
<th>Accounts</th>
|
<th>Accounts</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -143,7 +143,7 @@
|
|||||||
var modal = $("#modal_revoke");
|
var modal = $("#modal_revoke");
|
||||||
var username = $(this).prop('id');
|
var username = $(this).prop('id');
|
||||||
var info = "Are you sure you want to revoke all privileges for user " + username +
|
var info = "Are you sure you want to revoke all privileges for user " + username +
|
||||||
"? They will not able to access any domain.";
|
"? They will not able to access any zone.";
|
||||||
modal.find('.modal-body p').text(info);
|
modal.find('.modal-body p').text(info);
|
||||||
modal.find('#button_revoke_confirm').click(function () {
|
modal.find('#button_revoke_confirm').click(function () {
|
||||||
var postdata = {
|
var postdata = {
|
||||||
|
@ -671,7 +671,7 @@
|
|||||||
have no valid "powerdns-admin" records to their
|
have no valid "powerdns-admin" records to their
|
||||||
autoprovisioning field, will lose all their
|
autoprovisioning field, will lose all their
|
||||||
associations
|
associations
|
||||||
with any domain or account, also reverting to a
|
with any zone or account, also reverting to a
|
||||||
User in
|
User in
|
||||||
the process, despite their current role in the
|
the process, despite their current role in the
|
||||||
local db.<br>
|
local db.<br>
|
||||||
@ -1692,7 +1692,7 @@
|
|||||||
document.getElementById('purge_on').checked = false;
|
document.getElementById('purge_on').checked = false;
|
||||||
document.getElementById('purge_off').checked = true;
|
document.getElementById('purge_off').checked = true;
|
||||||
var modal = $("#modal_confirm");
|
var modal = $("#modal_confirm");
|
||||||
var info = "Are you sure you want to do this? Users will lose their associated domains unless they already have their autoprovisioning field prepopulated.";
|
var info = "Are you sure you want to do this? Users will lose their associated zones unless they already have their autoprovisioning field prepopulated.";
|
||||||
modal.find('.modal-body p').text(info);
|
modal.find('.modal-body p').text(info);
|
||||||
modal.find('#button_confirm').click(function () {
|
modal.find('#button_confirm').click(function () {
|
||||||
document.getElementById('purge_on').checked = true;
|
document.getElementById('purge_on').checked = true;
|
||||||
|
@ -269,7 +269,7 @@
|
|||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title">Sync Domains from backend</h4>
|
<h4 class="modal-title">Sync Zones from backend</h4>
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -162,7 +162,7 @@
|
|||||||
<dt>Account</dt>
|
<dt>Account</dt>
|
||||||
<dd>Specifies the PowerDNS account value to use for the zone.</dd>
|
<dd>Specifies the PowerDNS account value to use for the zone.</dd>
|
||||||
<dt>Zone Type</dt>
|
<dt>Zone Type</dt>
|
||||||
<dd>The type decides how the domain will be replicated across multiple DNS servers.
|
<dd>The type decides how the zone will be replicated across multiple DNS servers.
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<strong>Native</strong> - The server will not perform any Primary or Secondary
|
<strong>Native</strong> - The server will not perform any Primary or Secondary
|
||||||
@ -186,7 +186,7 @@
|
|||||||
<dt>SOA-EDIT-API</dt>
|
<dt>SOA-EDIT-API</dt>
|
||||||
<dd>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a
|
<dd>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a
|
||||||
change is
|
change is
|
||||||
made to the domain.
|
made to the zone.
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<strong>DEFAULT</strong> - Generate a soa serial of YYYYMMDD01. If the current serial
|
<strong>DEFAULT</strong> - Generate a soa serial of YYYYMMDD01. If the current serial
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
{% if record_name and record_type %}
|
{% if record_name and record_type %}
|
||||||
Record changelog: <b>{{ record_name}}   {{ record_type }}</b>
|
Record changelog: <b>{{ record_name}}   {{ record_type }}</b>
|
||||||
{% else %}
|
{% else %}
|
||||||
Domain changelog: <b>{{ domain.name | pretty_domain_name }}</b>
|
Zone changelog: <b>{{ domain.name | pretty_domain_name }}</b>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<button type="button" class="btn btn-primary float-left button_show_records" id="{{ domain.name }}">
|
<button type="button" class="btn btn-primary float-left button_show_records" id="{{ domain.name }}">
|
||||||
<i class="fa-solid fa-arrow-left"></i>
|
<i class="fa-solid fa-arrow-left"></i>
|
||||||
Manage Domain {{ domain.name }}
|
Manage Zone {{ domain.name }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="domainid">Zone</label>
|
<label for="domainid">Zone</label>
|
||||||
<select id=domainid class="form-control" style="width:15em;">
|
<select id=domainid class="form-control" style="width:15em;">
|
||||||
<option value="0">- Select Domain -</option>
|
<option value="0">- Select Zone -</option>
|
||||||
{% for domain in domainss %}
|
{% for domain in domainss %}
|
||||||
<option value="{{ domain.id }}">{{ domain.name }}</option>
|
<option value="{{ domain.id }}">{{ domain.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -83,7 +83,7 @@
|
|||||||
$(document.body).on("click", ".button_delete", function (e) {
|
$(document.body).on("click", ".button_delete", function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if ($("#domainid").val() == 0) {
|
if ($("#domainid").val() == 0) {
|
||||||
showErrorModal("Please select domain to remove.");
|
showErrorModal("Please select zone to remove.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,11 +148,11 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<p>Users on the right have access to manage the records in
|
<p>Users on the right have access to manage the records in
|
||||||
the {{ domain.name | pretty_domain_name }} domain.</p>
|
the {{ domain.name | pretty_domain_name }} zone.</p>
|
||||||
<p>Click on users to move from between columns.</p>
|
<p>Click on users to move from between columns.</p>
|
||||||
<p>
|
<p>
|
||||||
Users in <font style="color: red;">red</font> are Administrators
|
Users in <font style="color: red;">red</font> are Administrators
|
||||||
and already have access to <b>ALL</b> domains.
|
and already have access to <b>ALL</b> zones.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -197,7 +197,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.card-header -->
|
<!-- /.card-header -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>The type decides how the domain will be replicated across multiple DNS servers.</p>
|
<p>The type decides how the zone will be replicated across multiple DNS servers.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Native - PowerDNS will not perform any replication. Use this if you only have one
|
Native - PowerDNS will not perform any replication. Use this if you only have one
|
||||||
@ -214,7 +214,7 @@
|
|||||||
zone transfers (AXFRs) from other servers configured as primaries.
|
zone transfers (AXFRs) from other servers configured as primaries.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<b>New Domain Type Setting:</b>
|
<b>New Zone Type Setting:</b>
|
||||||
<form method="post" action="{{ url_for('domain.change_type', domain_name=domain.name) }}">
|
<form method="post" action="{{ url_for('domain.change_type', domain_name=domain.name) }}">
|
||||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
||||||
<select name="domain_type" class="form-control" style="width:15em;">
|
<select name="domain_type" class="form-control" style="width:15em;">
|
||||||
@ -251,7 +251,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a change
|
<p>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a change
|
||||||
is made
|
is made
|
||||||
to the domain.</p>
|
to the zone.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
DEFAULT - Generate a soa serial of YYYYMMDD01. If the current serial is lower than
|
DEFAULT - Generate a soa serial of YYYYMMDD01. If the current serial is lower than
|
||||||
@ -303,9 +303,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.card-header -->
|
<!-- /.card-header -->
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>This function is used to remove a domain from PowerDNS-Admin <b>AND</b> PowerDNS. All
|
<p>This function is used to remove a zone from PowerDNS-Admin <b>AND</b> PowerDNS. All
|
||||||
records and
|
records and
|
||||||
user privileges associated with this domain will also be removed. This change cannot be
|
user privileges associated with this zone will also be removed. This change cannot be
|
||||||
reverted.</p>
|
reverted.</p>
|
||||||
<button type="button" title="Delete Zone" class="btn btn-danger float-left delete_domain"
|
<button type="button" title="Delete Zone" class="btn btn-danger float-left delete_domain"
|
||||||
id="{{ domain.name }}">
|
id="{{ domain.name }}">
|
||||||
@ -402,7 +402,7 @@
|
|||||||
applyChanges(postdata, $SCRIPT_ROOT + '/domain/' + domain + '/manage-setting', true);
|
applyChanges(postdata, $SCRIPT_ROOT + '/domain/' + domain + '/manage-setting', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// handle deletion of domain
|
// handle deletion of zone
|
||||||
$(document.body).on('click', '.delete_domain', function () {
|
$(document.body).on('click', '.delete_domain', function () {
|
||||||
var modal = $("#modal_delete_domain");
|
var modal = $("#modal_delete_domain");
|
||||||
var domain = $(this).prop('id');
|
var domain = $(this).prop('id');
|
||||||
@ -419,7 +419,7 @@
|
|||||||
modal.modal('show');
|
modal.modal('show');
|
||||||
});
|
});
|
||||||
|
|
||||||
// domain primary address input handeling
|
// zone primary address input handeling
|
||||||
$("select[name=domain_type]").change(function () {
|
$("select[name=domain_type]").change(function () {
|
||||||
var type = $(this).val();
|
var type = $(this).val();
|
||||||
if (type == "secondary") {
|
if (type == "secondary") {
|
||||||
|
@ -44,3 +44,4 @@ werkzeug==2.1.2
|
|||||||
zipp==3.11.0
|
zipp==3.11.0
|
||||||
rcssmin==1.1.1
|
rcssmin==1.1.1
|
||||||
zxcvbn==4.4.28
|
zxcvbn==4.4.28
|
||||||
|
psycopg2==2.9.5
|
@ -29,6 +29,6 @@ with app.app_context():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
### Start the update process
|
### Start the update process
|
||||||
app.logger.info('Update domains from nameserver API')
|
app.logger.info('Update zones from nameserver API')
|
||||||
|
|
||||||
Domain().update()
|
Domain().update()
|
||||||
|
Loading…
Reference in New Issue
Block a user