mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-11-08 14:40: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'
|
||||
|
||||
### DATABASE - MySQL
|
||||
## Don't forget to uncomment the import in the top
|
||||
#SQLALCHEMY_DATABASE_URI = 'mysql://{}:{}@{}/{}'.format(
|
||||
# urllib.parse.quote_plus(SQLA_DB_USER),
|
||||
# urllib.parse.quote_plus(SQLA_DB_PASSWORD),
|
||||
@ -34,6 +35,15 @@ SESSION_TYPE = 'sqlalchemy'
|
||||
# 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
|
||||
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'pdns.db')
|
||||
|
||||
|
@ -11,6 +11,7 @@ RUN apt-get update -y \
|
||||
libffi-dev \
|
||||
libldap2-dev \
|
||||
libmariadb-dev-compat \
|
||||
libpq-dev \
|
||||
libsasl2-dev \
|
||||
libssl-dev \
|
||||
libxml2-dev \
|
||||
|
@ -2,6 +2,7 @@ FROM alpine:3.17 AS builder
|
||||
|
||||
ARG BUILD_DEPENDENCIES="build-base \
|
||||
libffi-dev \
|
||||
libpq-dev \
|
||||
libxml2-dev \
|
||||
mariadb-connector-c-dev \
|
||||
openldap-dev \
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
## Using PowerDNS-Admin
|
||||
|
||||
- Setting up a domain
|
||||
- Setting up a zone
|
||||
- Adding a record
|
||||
- <whatever else>
|
||||
|
||||
|
@ -11,7 +11,7 @@ Active Directory Setup - Tested with Windows Server 2012
|
||||
5) Fill in the required info -
|
||||
|
||||
* 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
|
||||
* Basic filter - (objectCategory=person)
|
||||
* 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
|
||||
$ createuser powerdnsadmin
|
||||
$ createdb powerdnsadmindb
|
||||
$ createdb -E UTF8 -l en_US.UTF-8 -O powerdnsadmin -T template0 powerdnsadmindb 'The database for PowerDNS-Admin'
|
||||
$ psql
|
||||
postgres=# alter user powerdnsadmin with encrypted password 'powerdnsadmin';
|
||||
postgres=# grant all privileges on database powerdnsadmindb to powerdnsadmin;
|
||||
postgres=# ALTER ROLE powerdnsadmin WITH PASSWORD 'powerdnsadmin_password';
|
||||
```
|
||||
|
||||
Note:
|
||||
@ -51,18 +50,14 @@ On debian based systems these files are located in:
|
||||
|
||||
## Install required packages:
|
||||
### Red-hat based systems:
|
||||
TODO: confirm this is correct
|
||||
```
|
||||
sudo yum install postgresql-libs
|
||||
```
|
||||
|
||||
### Debian based systems:
|
||||
```
|
||||
apt install libpq-dev python-dev
|
||||
```
|
||||
|
||||
### Install python packages:
|
||||
```
|
||||
pip3 install psycopg2
|
||||
apt install python3-psycopg2
|
||||
```
|
||||
|
||||
## Known Issues:
|
||||
|
@ -7,19 +7,30 @@ First setup your database accordingly:
|
||||
|
||||
### Install required packages for building python libraries from requirements.txt file
|
||||
|
||||
For Debian 11 (bullseye) and above:
|
||||
```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
|
||||
|
||||
```bash
|
||||
curl -sL https://deb.nodesource.com/setup_14.x | bash -
|
||||
apt install -y nodejs
|
||||
curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
|
||||
sudo apt install -y nodejs
|
||||
```
|
||||
|
||||
### 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
|
||||
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
|
||||
|
@ -270,7 +270,7 @@ def api_can_create_domain(f):
|
||||
if current_user.role.name not in [
|
||||
'Administrator', 'Operator'
|
||||
] 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))
|
||||
raise NotEnoughPrivileges()
|
||||
|
||||
@ -299,7 +299,7 @@ def apikey_can_create_domain(f):
|
||||
if g.apikey.role.name not in [
|
||||
'Administrator', 'Operator'
|
||||
] 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))
|
||||
raise NotEnoughPrivileges()
|
||||
|
||||
@ -329,7 +329,7 @@ def apikey_can_remove_domain(http_methods=[]):
|
||||
g.apikey.role.name not in ['Administrator', 'Operator'] and
|
||||
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))
|
||||
raise NotEnoughPrivileges()
|
||||
return f(*args, **kwargs)
|
||||
@ -344,7 +344,7 @@ def apikey_is_admin(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
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))
|
||||
raise NotEnoughPrivileges()
|
||||
return f(*args, **kwargs)
|
||||
|
@ -21,7 +21,7 @@ class StructuredException(Exception):
|
||||
class DomainNotExists(StructuredException):
|
||||
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)
|
||||
self.message = message
|
||||
self.name = name
|
||||
@ -30,7 +30,7 @@ class DomainNotExists(StructuredException):
|
||||
class DomainAlreadyExists(StructuredException):
|
||||
status_code = 409
|
||||
|
||||
def __init__(self, name=None, message="Domain already exists"):
|
||||
def __init__(self, name=None, message="Zone already exists"):
|
||||
StructuredException.__init__(self)
|
||||
self.message = message
|
||||
self.name = name
|
||||
@ -39,7 +39,7 @@ class DomainAlreadyExists(StructuredException):
|
||||
class DomainAccessForbidden(StructuredException):
|
||||
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)
|
||||
self.message = message
|
||||
self.name = name
|
||||
@ -47,7 +47,7 @@ class DomainAccessForbidden(StructuredException):
|
||||
class DomainOverrideForbidden(StructuredException):
|
||||
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)
|
||||
self.message = message
|
||||
self.name = name
|
||||
@ -67,7 +67,7 @@ class ApiKeyNotUsable(StructuredException):
|
||||
def __init__(
|
||||
self,
|
||||
name=None,
|
||||
message=("Api key must have domains or accounts"
|
||||
message=("Api key must have zones or accounts"
|
||||
" or an administrative role")):
|
||||
StructuredException.__init__(self)
|
||||
self.message = message
|
||||
|
@ -229,7 +229,7 @@ def ensure_list(l):
|
||||
|
||||
def pretty_domain_name(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
|
||||
if domain_name.endswith('.xn--'):
|
||||
@ -238,9 +238,9 @@ def pretty_domain_name(domain_name):
|
||||
domain_name = idna.decode(domain_name)
|
||||
except Exception as e:
|
||||
# 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
|
||||
|
||||
|
||||
|
@ -68,13 +68,13 @@ class Domain(db.Model):
|
||||
return True
|
||||
except Exception as e:
|
||||
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))
|
||||
return False
|
||||
|
||||
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}
|
||||
jdata = utils.fetch_json(urljoin(
|
||||
@ -88,7 +88,7 @@ class Domain(db.Model):
|
||||
|
||||
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}
|
||||
jdata = utils.fetch_json(
|
||||
@ -108,17 +108,17 @@ class Domain(db.Model):
|
||||
return domain.id
|
||||
except Exception as e:
|
||||
current_app.logger.error(
|
||||
'Domain does not exist. ERROR: {0}'.format(e))
|
||||
'Zone does not exist. ERROR: {0}'.format(e))
|
||||
return None
|
||||
|
||||
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--')
|
||||
|
||||
# Search for domain names that match the IDN pattern
|
||||
# Search for zone names that match the IDN pattern
|
||||
idn_domains = [
|
||||
domain for domain in self.get_domains() if idn_pattern.match(domain)
|
||||
]
|
||||
@ -129,12 +129,12 @@ class Domain(db.Model):
|
||||
|
||||
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()
|
||||
list_db_domain = [d.name for d 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)))
|
||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||
try:
|
||||
@ -149,17 +149,17 @@ class Domain(db.Model):
|
||||
"Found {} zones in PowerDNS server".format(len(list_jdomain)))
|
||||
|
||||
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(
|
||||
set(list_db_domain).difference(list_jdomain))
|
||||
for domain_name in should_removed_db_domain:
|
||||
self.delete_domain_from_pdnsadmin(domain_name, do_commit=False)
|
||||
except Exception as e:
|
||||
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())
|
||||
|
||||
# update/add new domain
|
||||
# update/add new zone
|
||||
account_cache = {}
|
||||
for data in jdata:
|
||||
if 'account' in data:
|
||||
@ -187,16 +187,16 @@ class Domain(db.Model):
|
||||
self.add_domain_to_powerdns_admin(domain=data, do_commit=False)
|
||||
|
||||
db.session.commit()
|
||||
current_app.logger.info('Update domain finished')
|
||||
current_app.logger.info('Update zone finished')
|
||||
return {
|
||||
'status': 'ok',
|
||||
'msg': 'Domain table has been updated successfully'
|
||||
'msg': 'Zone table has been updated successfully'
|
||||
}
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
current_app.logger.error(
|
||||
'Cannot update domain table. Error: {0}'.format(e))
|
||||
return {'status': 'error', 'msg': 'Cannot update domain table'}
|
||||
'Cannot update zone table. Error: {0}'.format(e))
|
||||
return {'status': 'error', 'msg': 'Cannot update zone table'}
|
||||
|
||||
def update_pdns_admin_domain(self, domain, account_id, data, do_commit=True):
|
||||
# existing domain, only update if something actually has changed
|
||||
@ -218,11 +218,11 @@ class Domain(db.Model):
|
||||
try:
|
||||
if do_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))
|
||||
except Exception as e:
|
||||
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))
|
||||
raise
|
||||
|
||||
@ -234,7 +234,7 @@ class Domain(db.Model):
|
||||
domain_master_ips=[],
|
||||
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'}
|
||||
@ -269,23 +269,23 @@ class Domain(db.Model):
|
||||
if 'error' in jdata.keys():
|
||||
current_app.logger.error(jdata['error'])
|
||||
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']}
|
||||
else:
|
||||
current_app.logger.info(
|
||||
'Added domain successfully to PowerDNS: {0}'.format(
|
||||
'Added zone successfully to PowerDNS: {0}'.format(
|
||||
domain_name))
|
||||
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:
|
||||
current_app.logger.error('Cannot add domain {0} {1}'.format(
|
||||
current_app.logger.error('Cannot add zone {0} {1}'.format(
|
||||
domain_name, e))
|
||||
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):
|
||||
"""
|
||||
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}
|
||||
if not domain:
|
||||
@ -299,7 +299,7 @@ class Domain(db.Model):
|
||||
timeout=int(Setting().get('pdns_api_timeout')),
|
||||
verify=Setting().get('verify_ssl_connections'))
|
||||
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.debug(traceback.format_exc())
|
||||
|
||||
@ -325,20 +325,20 @@ class Domain(db.Model):
|
||||
if do_commit:
|
||||
db.session.commit()
|
||||
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 {
|
||||
'status': 'ok',
|
||||
'msg': 'Added Domain successfully to PowerDNS-Admin'
|
||||
'msg': 'Added zone successfully to PowerDNS-Admin'
|
||||
}
|
||||
except Exception as e:
|
||||
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
|
||||
|
||||
def update_soa_setting(self, domain_name, soa_edit_api):
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
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'}
|
||||
|
||||
@ -365,7 +365,7 @@ class Domain(db.Model):
|
||||
return {'status': 'error', 'msg': jdata['error']}
|
||||
else:
|
||||
current_app.logger.info(
|
||||
'soa-edit-api changed for domain {0} successfully'.format(
|
||||
'soa-edit-api changed for zone {0} successfully'.format(
|
||||
domain_name))
|
||||
return {
|
||||
'status': 'ok',
|
||||
@ -375,11 +375,11 @@ class Domain(db.Model):
|
||||
current_app.logger.debug(e)
|
||||
current_app.logger.debug(traceback.format_exc())
|
||||
current_app.logger.error(
|
||||
'Cannot change soa-edit-api for domain {0}'.format(
|
||||
'Cannot change soa-edit-api for zone {0}'.format(
|
||||
domain_name))
|
||||
return {
|
||||
'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=[]):
|
||||
@ -388,7 +388,7 @@ class Domain(db.Model):
|
||||
"""
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
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'}
|
||||
|
||||
@ -409,26 +409,26 @@ class Domain(db.Model):
|
||||
return {'status': 'error', 'msg': jdata['error']}
|
||||
else:
|
||||
current_app.logger.info(
|
||||
'Update domain kind for {0} successfully'.format(
|
||||
'Update zone kind for {0} successfully'.format(
|
||||
domain_name))
|
||||
return {
|
||||
'status': 'ok',
|
||||
'msg': 'Domain kind changed successfully'
|
||||
'msg': 'Zone kind changed successfully'
|
||||
}
|
||||
except Exception as e:
|
||||
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))
|
||||
current_app.logger.debug(traceback.format_exc())
|
||||
|
||||
return {
|
||||
'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):
|
||||
"""
|
||||
Check the existing reverse lookup domain,
|
||||
Check the existing reverse lookup zone,
|
||||
if not exists create a new one automatically
|
||||
"""
|
||||
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', [], [])
|
||||
self.update()
|
||||
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),
|
||||
detail=json.dumps({
|
||||
'domain_type': 'Master',
|
||||
@ -459,7 +459,7 @@ class Domain(db.Model):
|
||||
else:
|
||||
return {
|
||||
'status': 'error',
|
||||
'msg': 'Adding reverse lookup domain failed'
|
||||
'msg': 'Adding reverse lookup zone failed'
|
||||
}
|
||||
domain_user_ids = self.get_user()
|
||||
if len(domain_user_ids) > 0:
|
||||
@ -469,13 +469,13 @@ class Domain(db.Model):
|
||||
'status':
|
||||
'ok',
|
||||
'msg':
|
||||
'New reverse lookup domain created with granted privileges'
|
||||
'New reverse lookup zone created with granted privileges'
|
||||
}
|
||||
return {
|
||||
'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):
|
||||
c = 1
|
||||
@ -504,22 +504,22 @@ class Domain(db.Model):
|
||||
|
||||
def delete(self, domain_name):
|
||||
"""
|
||||
Delete a single domain name from powerdns
|
||||
Delete a single zone name from powerdns
|
||||
"""
|
||||
try:
|
||||
self.delete_domain_from_powerdns(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:
|
||||
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.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):
|
||||
"""
|
||||
Delete a single domain name from powerdns
|
||||
Delete a single zone name from powerdns
|
||||
"""
|
||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||
|
||||
@ -531,12 +531,12 @@ class Domain(db.Model):
|
||||
method='DELETE',
|
||||
verify=Setting().get('verify_ssl_connections'))
|
||||
current_app.logger.info(
|
||||
'Deleted domain successfully from PowerDNS: {0}'.format(
|
||||
'Deleted zone successfully from PowerDNS: {0}'.format(
|
||||
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):
|
||||
# Revoke permission before deleting domain
|
||||
# Revoke permission before deleting zone
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
domain_user = DomainUser.query.filter(
|
||||
DomainUser.domain_id == domain.id)
|
||||
@ -548,7 +548,7 @@ class Domain(db.Model):
|
||||
domain_setting.delete()
|
||||
domain.apikeys[:] = []
|
||||
|
||||
# Remove history for domain
|
||||
# Remove history for zone
|
||||
if not Setting().get('preserve_history'):
|
||||
domain_history = History.query.filter(
|
||||
History.domain_id == domain.id
|
||||
@ -556,17 +556,17 @@ class Domain(db.Model):
|
||||
if domain_history:
|
||||
domain_history.delete()
|
||||
|
||||
# then remove domain
|
||||
# then remove zone
|
||||
Domain.query.filter(Domain.name == domain_name).delete()
|
||||
if do_commit:
|
||||
db.session.commit()
|
||||
current_app.logger.info(
|
||||
"Deleted domain successfully from pdnsADMIN: {}".format(
|
||||
"Deleted zone successfully from pdnsADMIN: {}".format(
|
||||
domain_name))
|
||||
|
||||
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 = []
|
||||
query = db.session.query(
|
||||
@ -596,7 +596,7 @@ class Domain(db.Model):
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
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))
|
||||
current_app.logger.debug(print(traceback.format_exc()))
|
||||
|
||||
@ -608,7 +608,7 @@ class Domain(db.Model):
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
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))
|
||||
current_app.logger.debug(print(traceback.format_exc()))
|
||||
|
||||
@ -625,7 +625,7 @@ class Domain(db.Model):
|
||||
|
||||
def add_user(self, user):
|
||||
"""
|
||||
Add a single user to Domain by User
|
||||
Add a single user to zone by User
|
||||
"""
|
||||
try:
|
||||
du = DomainUser(self.id, user.id)
|
||||
@ -635,7 +635,7 @@ class Domain(db.Model):
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
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))
|
||||
return False
|
||||
|
||||
@ -667,11 +667,11 @@ class Domain(db.Model):
|
||||
'There was something wrong, please contact administrator'
|
||||
}
|
||||
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):
|
||||
"""
|
||||
Get domain DNSSEC information
|
||||
Get zone DNSSEC information
|
||||
"""
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
if domain:
|
||||
@ -689,13 +689,13 @@ class Domain(db.Model):
|
||||
if 'error' in jdata:
|
||||
return {
|
||||
'status': 'error',
|
||||
'msg': 'DNSSEC is not enabled for this domain'
|
||||
'msg': 'DNSSEC is not enabled for this zone'
|
||||
}
|
||||
else:
|
||||
return {'status': 'ok', 'dnssec': jdata}
|
||||
except Exception as e:
|
||||
current_app.logger.error(
|
||||
'Cannot get domain dnssec. DETAIL: {0}'.format(e))
|
||||
'Cannot get zone dnssec. DETAIL: {0}'.format(e))
|
||||
return {
|
||||
'status':
|
||||
'error',
|
||||
@ -703,11 +703,11 @@ class Domain(db.Model):
|
||||
'There was something wrong, please contact administrator'
|
||||
}
|
||||
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):
|
||||
"""
|
||||
Enable domain DNSSEC
|
||||
Enable zone DNSSEC
|
||||
"""
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
if domain:
|
||||
@ -728,7 +728,7 @@ class Domain(db.Model):
|
||||
return {
|
||||
'status': 'error',
|
||||
'msg':
|
||||
'API-RECTIFY could not be enabled for this domain',
|
||||
'API-RECTIFY could not be enabled for this zone',
|
||||
'jdata': jdata
|
||||
}
|
||||
|
||||
@ -749,7 +749,7 @@ class Domain(db.Model):
|
||||
'status':
|
||||
'error',
|
||||
'msg':
|
||||
'Cannot enable DNSSEC for this domain. Error: {0}'.
|
||||
'Cannot enable DNSSEC for this zone. Error: {0}'.
|
||||
format(jdata['error']),
|
||||
'jdata':
|
||||
jdata
|
||||
@ -769,7 +769,7 @@ class Domain(db.Model):
|
||||
}
|
||||
|
||||
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):
|
||||
"""
|
||||
@ -794,13 +794,13 @@ class Domain(db.Model):
|
||||
'status':
|
||||
'error',
|
||||
'msg':
|
||||
'Cannot disable DNSSEC for this domain. Error: {0}'.
|
||||
'Cannot disable DNSSEC for this zone. Error: {0}'.
|
||||
format(jdata['error']),
|
||||
'jdata':
|
||||
jdata
|
||||
}
|
||||
|
||||
# Disable API-RECTIFY for domain, AFTER deactivating DNSSEC
|
||||
# Disable API-RECTIFY for zone, AFTER deactivating DNSSEC
|
||||
post_data = {"api_rectify": False}
|
||||
jdata = utils.fetch_json(
|
||||
urljoin(
|
||||
@ -815,7 +815,7 @@ class Domain(db.Model):
|
||||
return {
|
||||
'status': 'error',
|
||||
'msg':
|
||||
'API-RECTIFY could not be disabled for this domain',
|
||||
'API-RECTIFY could not be disabled for this zone',
|
||||
'jdata': jdata
|
||||
}
|
||||
|
||||
@ -834,22 +834,22 @@ class Domain(db.Model):
|
||||
}
|
||||
|
||||
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):
|
||||
"""
|
||||
Associate domain with a domain, specified by account id
|
||||
Associate account with a zone, specified by account id
|
||||
"""
|
||||
domain_name = self.name
|
||||
|
||||
# Sanity check - 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
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
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'}
|
||||
|
||||
@ -875,9 +875,9 @@ class Domain(db.Model):
|
||||
else:
|
||||
if 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))
|
||||
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({
|
||||
'assoc_account': 'None' if account_name == '' else account_name,
|
||||
'dissoc_account': 'None' if account_name_old == '' else account_name_old
|
||||
@ -889,16 +889,16 @@ class Domain(db.Model):
|
||||
except Exception as e:
|
||||
current_app.logger.debug(e)
|
||||
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))
|
||||
return {
|
||||
'status': 'error',
|
||||
'msg': 'Cannot change account for this domain.'
|
||||
'msg': 'Cannot change account for this zone.'
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
@ -907,7 +907,7 @@ class Domain(db.Model):
|
||||
def is_valid_access(self, user_id):
|
||||
"""
|
||||
Check if the user is allowed to access this
|
||||
domain name
|
||||
zone name
|
||||
"""
|
||||
return db.session.query(Domain) \
|
||||
.outerjoin(DomainUser, Domain.id == DomainUser.domain_id) \
|
||||
@ -919,8 +919,8 @@ class Domain(db.Model):
|
||||
AccountUser.user_id == user_id
|
||||
)).filter(Domain.id == self.id).first()
|
||||
|
||||
# Return None if this domain does not exist as record,
|
||||
# Return the parent domain that hold the record if exist
|
||||
# Return None if this zone does not exist as record,
|
||||
# Return the parent zone that hold the record if exist
|
||||
def is_overriding(self, domain_name):
|
||||
upper_domain_name = '.'.join(domain_name.split('.')[1:])
|
||||
while upper_domain_name != '':
|
||||
@ -929,7 +929,7 @@ class Domain(db.Model):
|
||||
if 'rrsets' in upper_domain:
|
||||
for r in upper_domain['rrsets']:
|
||||
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
|
||||
upper_domain_name = '.'.join(upper_domain_name.split('.')[1:])
|
||||
return None
|
||||
|
@ -45,11 +45,11 @@ class DomainTemplate(db.Model):
|
||||
return {'status': 'ok', 'msg': 'Template has been created'}
|
||||
except Exception as e:
|
||||
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()
|
||||
return {
|
||||
'status': 'error',
|
||||
'msg': 'Can not update domain template table'
|
||||
'msg': 'Can not update zone template table'
|
||||
}
|
||||
|
||||
def delete_template(self):
|
||||
@ -60,6 +60,6 @@ class DomainTemplate(db.Model):
|
||||
return {'status': 'ok', 'msg': 'Template has been deleted'}
|
||||
except Exception as e:
|
||||
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()
|
||||
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()
|
||||
except Exception as e:
|
||||
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()
|
||||
return {
|
||||
'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):
|
||||
"""
|
||||
Query domain's rrsets via PDNS API
|
||||
Query zone's rrsets via PDNS API
|
||||
"""
|
||||
headers = {'X-API-Key': self.PDNS_API_KEY}
|
||||
try:
|
||||
@ -59,7 +59,7 @@ class Record(object):
|
||||
verify=Setting().get('verify_ssl_connections'))
|
||||
except Exception as e:
|
||||
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))
|
||||
return []
|
||||
|
||||
@ -77,7 +77,7 @@ class Record(object):
|
||||
|
||||
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:
|
||||
domain_name(str): The zone name
|
||||
@ -115,7 +115,7 @@ class Record(object):
|
||||
return {'status': 'ok', 'msg': 'Record was added successfully'}
|
||||
except Exception as e:
|
||||
current_app.logger.error(
|
||||
"Cannot add record to domain {}. Error: {}".format(
|
||||
"Cannot add record to zone {}. Error: {}".format(
|
||||
domain_name, e))
|
||||
current_app.logger.debug("Submitted record rrset: \n{}".format(
|
||||
utils.pretty_json(rrset)))
|
||||
@ -172,7 +172,7 @@ class Record(object):
|
||||
record['record_name'] = utils.to_idna(record["record_name"], "encode")
|
||||
#TODO: error handling
|
||||
# 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':
|
||||
record['record_data'] = utils.to_idna(record['record_data'], 'encode')
|
||||
#TODO: error handling
|
||||
@ -343,7 +343,7 @@ class Record(object):
|
||||
|
||||
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
|
||||
REPLACE records (rrsets)
|
||||
"""
|
||||
@ -377,7 +377,7 @@ class Record(object):
|
||||
return {'status': 'ok', 'msg': 'Record was applied successfully', 'data': (new_rrsets, del_rrsets)}
|
||||
except Exception as e:
|
||||
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))
|
||||
current_app.logger.debug(traceback.format_exc())
|
||||
return {
|
||||
@ -480,7 +480,7 @@ class Record(object):
|
||||
}
|
||||
except Exception as e:
|
||||
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))
|
||||
current_app.logger.debug(traceback.format_exc())
|
||||
return {
|
||||
@ -492,7 +492,7 @@ class Record(object):
|
||||
|
||||
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'}
|
||||
data = {
|
||||
@ -517,7 +517,7 @@ class Record(object):
|
||||
return {'status': 'ok', 'msg': 'Record was removed successfully'}
|
||||
except Exception as e:
|
||||
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))
|
||||
return {
|
||||
'status': 'error',
|
||||
@ -540,7 +540,7 @@ class Record(object):
|
||||
|
||||
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)
|
||||
for r in rrsets:
|
||||
@ -588,7 +588,7 @@ class Record(object):
|
||||
return {'status': 'ok', 'msg': 'Record was updated successfully'}
|
||||
except Exception as e:
|
||||
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))
|
||||
return {
|
||||
'status': 'error',
|
||||
@ -614,11 +614,11 @@ class Record(object):
|
||||
db.session.commit()
|
||||
return {
|
||||
'status': True,
|
||||
'msg': 'Synced local serial for domain name {0}'.format(domain)
|
||||
'msg': 'Synced local serial for zone name {0}'.format(domain)
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'status': False,
|
||||
'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):
|
||||
"""
|
||||
Get list of domains which the user is granted to have
|
||||
Get list of zones which the user is granted to have
|
||||
access.
|
||||
|
||||
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):
|
||||
"""
|
||||
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
|
||||
user = db.session.query(User).filter(User.username == self.username).first()
|
||||
|
@ -838,10 +838,10 @@ class DetailedHistory():
|
||||
|
||||
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("""
|
||||
<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>
|
||||
</table>
|
||||
""",
|
||||
@ -881,7 +881,7 @@ class DetailedHistory():
|
||||
authenticator=detail_dict['authenticator'],
|
||||
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 = []
|
||||
self.detailed_msg = ""
|
||||
# extract_changelogs_from_a_history_entry(changes_set, history, 0)
|
||||
@ -897,11 +897,11 @@ class DetailedHistory():
|
||||
description=DetailedHistory.get_key_val(detail_dict,
|
||||
"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")
|
||||
self.detailed_msg = render_template_string("""
|
||||
<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>
|
||||
</table>
|
||||
""",
|
||||
@ -913,7 +913,7 @@ class DetailedHistory():
|
||||
<tr><td>Key: </td><td>{{ keyname }}</td></tr>
|
||||
<tr><td>Role:</td><td>{{ rolename }}</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>
|
||||
</table>
|
||||
""",
|
||||
@ -932,7 +932,7 @@ class DetailedHistory():
|
||||
<tr><td>Key: </td><td>{{ keyname }}</td></tr>
|
||||
<tr><td>Role:</td><td>{{ rolename }}</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>
|
||||
""",
|
||||
keyname=DetailedHistory.get_key_val(detail_dict, "key"),
|
||||
@ -942,11 +942,11 @@ class DetailedHistory():
|
||||
linked_domains=DetailedHistory.get_key_val(detail_dict,
|
||||
"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("""
|
||||
<table class="table table-bordered table-striped">
|
||||
<tr><td>Domain: </td><td>{{ domain }}</td></tr>
|
||||
<tr><td>Domain type:</td><td>{{ domain_type }}</td></tr>
|
||||
<tr><td>Zone: </td><td>{{ domain }}</td></tr>
|
||||
<tr><td>Zone type:</td><td>{{ domain_type }}</td></tr>
|
||||
<tr><td>Masters:</td><td>{{ masters }}</td></tr>
|
||||
</table>
|
||||
""",
|
||||
@ -957,8 +957,8 @@ class DetailedHistory():
|
||||
elif 'reverse' in history.msg:
|
||||
self.detailed_msg = render_template_string("""
|
||||
<table class="table table-bordered table-striped">
|
||||
<tr><td>Domain Type: </td><td>{{ domain_type }}</td></tr>
|
||||
<tr><td>Domain Master IPs:</td><td>{{ domain_master_ips }}</td></tr>
|
||||
<tr><td>Zone Type: </td><td>{{ domain_type }}</td></tr>
|
||||
<tr><td>Zone Master IPs:</td><td>{{ domain_master_ips }}</td></tr>
|
||||
</table>
|
||||
""",
|
||||
domain_type=DetailedHistory.get_key_val(detail_dict,
|
||||
@ -977,7 +977,7 @@ class DetailedHistory():
|
||||
'status'),
|
||||
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('''
|
||||
<table class="table table-bordered table-striped">
|
||||
<tr><td>Associate: </td><td>{{ history_assoc_account }}</td></tr>
|
||||
@ -1164,7 +1164,7 @@ def history_table(): # ajax call data
|
||||
else:
|
||||
# if the user isn't an administrator or operator,
|
||||
# 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) \
|
||||
.join(Domain, History.domain_id == Domain.id) \
|
||||
.outerjoin(DomainUser, Domain.id == DomainUser.domain_id) \
|
||||
@ -1231,11 +1231,14 @@ def history_table(): # ajax call data
|
||||
.filter(
|
||||
db.and_(
|
||||
db.or_(
|
||||
History.msg.like("%domain " + domain_name) if domain_name != "*" else History.msg.like(
|
||||
"%domain%"),
|
||||
History.msg.like("%domain " + domain_name) if domain_name != "*" else History.msg.like("%domain%"),
|
||||
History.msg.like("%zone " + domain_name) if domain_name != "*" else History.msg.like("%zone%"),
|
||||
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 >= min_date if min_date != None else True,
|
||||
@ -1247,8 +1250,12 @@ def history_table(): # ajax call data
|
||||
histories = base_query \
|
||||
.filter(
|
||||
db.and_(
|
||||
History.msg.like("Apply record changes to domain " + domain_name) if domain_name != "*" \
|
||||
else History.msg.like("Apply record changes to domain%"),
|
||||
db.or_(
|
||||
History.msg.like("Apply record changes to domain " + domain_name) if domain_name != "*" \
|
||||
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 >= min_date if min_date != 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)
|
||||
result = t.create()
|
||||
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({
|
||||
'name': name,
|
||||
'description': description
|
||||
@ -1871,7 +1878,7 @@ def create_template():
|
||||
return redirect(url_for('admin.create_template'))
|
||||
except Exception as e:
|
||||
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())
|
||||
abort(500)
|
||||
|
||||
@ -1905,7 +1912,7 @@ def create_template_from_zone():
|
||||
t = DomainTemplate(name=name, description=description)
|
||||
result = t.create()
|
||||
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({
|
||||
'name': name,
|
||||
'description': description
|
||||
@ -1913,7 +1920,7 @@ def create_template_from_zone():
|
||||
created_by=current_user.username)
|
||||
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.
|
||||
records = []
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
@ -1942,7 +1949,7 @@ def create_template_from_zone():
|
||||
'msg': result['msg']
|
||||
}), 200)
|
||||
else:
|
||||
# Revert the domain template (remove it)
|
||||
# Revert the zone template (remove it)
|
||||
# ff we cannot add records.
|
||||
t.delete_template()
|
||||
return make_response(
|
||||
@ -1999,7 +2006,7 @@ def edit_template(template):
|
||||
ttl_options=ttl_options)
|
||||
except Exception as e:
|
||||
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())
|
||||
abort(500)
|
||||
return redirect(url_for('admin.templates'))
|
||||
@ -2037,7 +2044,7 @@ def apply_records(template):
|
||||
jdata.pop('_csrf_token',
|
||||
None) # don't store csrf token in the 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),
|
||||
detail=json.dumps(jdata),
|
||||
created_by=current_user.username)
|
||||
@ -2068,7 +2075,7 @@ def delete_template(template):
|
||||
result = t.delete_template()
|
||||
if result['status'] == 'ok':
|
||||
history = History(
|
||||
msg='Deleted domain template {0}'.format(template),
|
||||
msg='Deleted zone template {0}'.format(template),
|
||||
detail=json.dumps({'name': template}),
|
||||
created_by=current_user.username)
|
||||
history.add()
|
||||
|
@ -211,7 +211,7 @@ def api_login_create_zone():
|
||||
accept='application/json; q=1',
|
||||
verify=Setting().get('verify_ssl_connections'))
|
||||
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)
|
||||
|
||||
if resp.status_code == 201:
|
||||
@ -222,7 +222,7 @@ def api_login_create_zone():
|
||||
domain.update()
|
||||
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('.')),
|
||||
detail=json.dumps(data),
|
||||
created_by=current_user.username,
|
||||
@ -230,7 +230,7 @@ def api_login_create_zone():
|
||||
history.add()
|
||||
|
||||
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.update()
|
||||
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.update()
|
||||
|
||||
history = History(msg='Delete domain {0}'.format(
|
||||
history = History(msg='Delete zone {0}'.format(
|
||||
utils.pretty_domain_name(domain_name)),
|
||||
detail='',
|
||||
created_by=current_user.username,
|
||||
@ -347,13 +347,13 @@ def api_generate_apikey():
|
||||
abort(400)
|
||||
|
||||
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()
|
||||
|
||||
if role_name == 'User' and len(domains) > 0:
|
||||
domain_obj_list = Domain.query.filter(Domain.name.in_(domains)).all()
|
||||
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)
|
||||
raise DomainNotExists(message=msg)
|
||||
|
||||
@ -383,13 +383,13 @@ def api_generate_apikey():
|
||||
domain_list = [item.name for item in 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("User domain list: {0}".format(user_domain_list))
|
||||
current_app.logger.debug("Input zone list: {0}".format(domain_list))
|
||||
current_app.logger.debug("User zone list: {0}".format(user_domain_list))
|
||||
|
||||
inter = set(domain_list).intersection(set(user_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)
|
||||
raise DomainAccessForbidden(message=msg)
|
||||
|
||||
@ -417,7 +417,7 @@ def api_get_apikeys(domain_name):
|
||||
|
||||
if current_user.role.name not in ['Administrator', 'Operator']:
|
||||
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)
|
||||
current_app.logger.debug(msg)
|
||||
apikeys = get_user_apikeys(domain_name)
|
||||
@ -427,7 +427,7 @@ def api_get_apikeys(domain_name):
|
||||
|
||||
current_app.logger.debug(apikey_schema.dump(apikeys))
|
||||
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)
|
||||
current_app.logger.debug(msg)
|
||||
|
||||
@ -438,7 +438,7 @@ def api_get_apikeys(domain_name):
|
||||
current_app.logger.error('Error: {0}'.format(e))
|
||||
abort(500)
|
||||
else:
|
||||
current_app.logger.debug("Getting all domains for administrative user")
|
||||
current_app.logger.debug("Getting all zones for administrative user")
|
||||
try:
|
||||
apikeys = ApiKey.query.all()
|
||||
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))
|
||||
|
||||
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)
|
||||
raise DomainAccessForbidden(message=msg)
|
||||
|
||||
@ -558,7 +558,7 @@ def api_update_apikey(apikey_id):
|
||||
if domains is not None:
|
||||
domain_obj_list = Domain.query.filter(Domain.name.in_(domains)).all()
|
||||
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)
|
||||
raise DomainNotExists(message=msg)
|
||||
|
||||
@ -578,12 +578,12 @@ def api_update_apikey(apikey_id):
|
||||
target_accounts = current_accounts
|
||||
|
||||
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()
|
||||
|
||||
if domains is not None and set(domains) == set(current_domains):
|
||||
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
|
||||
|
||||
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]
|
||||
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))
|
||||
"User zone list: {0}".format(user_domain_list))
|
||||
|
||||
inter = set(domain_list).intersection(set(user_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)
|
||||
raise DomainAccessForbidden(message=msg)
|
||||
|
||||
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)
|
||||
raise DomainAccessForbidden()
|
||||
|
||||
@ -966,9 +966,9 @@ def api_delete_account(account_id):
|
||||
# Remove account association from domains first
|
||||
if len(account.domains) > 0:
|
||||
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)
|
||||
current_app.logger.info("Syncing all domains")
|
||||
current_app.logger.info("Syncing all zones")
|
||||
Domain().update()
|
||||
|
||||
current_app.logger.debug(
|
||||
@ -1117,7 +1117,7 @@ def api_zone_forward(server_id, zone_id):
|
||||
if request.method in ['POST', 'PATCH']:
|
||||
data = request.get_json(force=True)
|
||||
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({
|
||||
'domain': zone_id.rstrip('.'),
|
||||
'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']:
|
||||
current_app.logger.debug(
|
||||
"Apikey is user key, assigning created domain")
|
||||
"Apikey is user key, assigning created zone")
|
||||
domain = Domain(name=data['name'].rstrip('.'))
|
||||
g.apikey.domains.append(domain)
|
||||
|
||||
domain = Domain()
|
||||
domain.update()
|
||||
|
||||
history = History(msg='Add domain {0}'.format(
|
||||
history = History(msg='Add zone {0}'.format(
|
||||
data['name'].rstrip('.')),
|
||||
detail=json.dumps(data),
|
||||
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]
|
||||
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)
|
||||
if i['name'].rstrip('.') in allowed_domains])
|
||||
return content, resp.status_code, resp.headers.items()
|
||||
@ -1236,14 +1236,14 @@ def health():
|
||||
domain_to_query = domain.query.first()
|
||||
|
||||
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)
|
||||
|
||||
try:
|
||||
domain.get_domain_info(domain_to_query.name)
|
||||
except Exception as e:
|
||||
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("Up", 200)
|
||||
|
@ -60,15 +60,31 @@ def login_via_authorization_header_or_remote_user(request):
|
||||
# Try to login using Basic Authentication
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if auth_header:
|
||||
|
||||
if auth_header[:6] != "Basic ":
|
||||
return None
|
||||
|
||||
auth_method = request.args.get('auth_method', '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:
|
||||
auth_header = str(base64.b64decode(auth_header), 'utf-8')
|
||||
username, password = auth_header.split(":")
|
||||
except TypeError as e:
|
||||
except (UnicodeDecodeError, TypeError) as e:
|
||||
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,
|
||||
password=password,
|
||||
plain_text_password=password)
|
||||
|
@ -176,10 +176,10 @@ def dashboard():
|
||||
|
||||
BG_DOMAIN_UPDATE = Setting().get('bg_domain_updates')
|
||||
if not BG_DOMAIN_UPDATE:
|
||||
current_app.logger.info('Updating domains in foreground...')
|
||||
current_app.logger.info('Updating zones in foreground...')
|
||||
Domain().update()
|
||||
else:
|
||||
current_app.logger.info('Updating domains in background...')
|
||||
current_app.logger.info('Updating zones in background...')
|
||||
|
||||
show_bg_domain_button = BG_DOMAIN_UPDATE
|
||||
if BG_DOMAIN_UPDATE and current_user.role.name not in ['Administrator', 'Operator']:
|
||||
@ -196,7 +196,7 @@ def dashboard():
|
||||
@login_required
|
||||
@operator_role_required
|
||||
def domains_updater():
|
||||
current_app.logger.debug('Update domains in background')
|
||||
current_app.logger.debug('Update zones in background')
|
||||
d = Domain().update()
|
||||
|
||||
response_data = {
|
||||
|
@ -178,7 +178,7 @@ def remove():
|
||||
if result['status'] == 'error':
|
||||
abort(500)
|
||||
|
||||
history = History(msg='Delete domain {0}'.format(
|
||||
history = History(msg='Delete zone {0}'.format(
|
||||
pretty_domain_name(domain_name)),
|
||||
created_by=current_user.username)
|
||||
history.add()
|
||||
@ -362,7 +362,7 @@ def add():
|
||||
if ' ' in domain_name or not domain_name or not domain_type:
|
||||
return render_template(
|
||||
'errors/400.html',
|
||||
msg="Please enter a valid domain name"), 400
|
||||
msg="Please enter a valid zone name"), 400
|
||||
|
||||
if domain_name.endswith('.'):
|
||||
domain_name = domain_name[:-1]
|
||||
@ -385,11 +385,11 @@ def add():
|
||||
try:
|
||||
domain_name = to_idna(domain_name, 'encode')
|
||||
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())
|
||||
return render_template(
|
||||
'errors/400.html',
|
||||
msg="Please enter a valid domain name"), 400
|
||||
msg="Please enter a valid zone name"), 400
|
||||
|
||||
if domain_type == 'slave':
|
||||
if request.form.getlist('domain_master_address'):
|
||||
@ -429,7 +429,7 @@ def add():
|
||||
else:
|
||||
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',
|
||||
domain_override_message=msg,
|
||||
@ -443,7 +443,7 @@ def add():
|
||||
account_name=account_name)
|
||||
if result['status'] == 'ok':
|
||||
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)),
|
||||
detail = json.dumps({
|
||||
'domain_type': domain_type,
|
||||
@ -507,7 +507,7 @@ def add():
|
||||
return render_template('errors/400.html',
|
||||
msg=result['msg']), 400
|
||||
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())
|
||||
abort(500)
|
||||
|
||||
@ -537,7 +537,7 @@ def delete(domain_name):
|
||||
if result['status'] == 'error':
|
||||
abort(500)
|
||||
|
||||
history = History(msg='Delete domain {0}'.format(
|
||||
history = History(msg='Delete zone {0}'.format(
|
||||
pretty_domain_name(domain_name)),
|
||||
created_by=current_user.username)
|
||||
history.add()
|
||||
@ -581,7 +581,7 @@ def setting(domain_name):
|
||||
d.grant_privileges(new_user_ids)
|
||||
|
||||
history = History(
|
||||
msg='Change domain {0} access control'.format(
|
||||
msg='Change zone {0} access control'.format(
|
||||
pretty_domain_name(domain_name)),
|
||||
detail=json.dumps({'user_has_access': new_user_list}),
|
||||
created_by=current_user.username,
|
||||
@ -619,7 +619,7 @@ def change_type(domain_name):
|
||||
kind=domain_type,
|
||||
masters=domain_master_ips)
|
||||
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)),
|
||||
detail=json.dumps({
|
||||
"domain": domain_name,
|
||||
@ -653,7 +653,7 @@ def change_soa_edit_api(domain_name):
|
||||
soa_edit_api=new_setting)
|
||||
if status['status'] == 'ok':
|
||||
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)),
|
||||
detail = json.dumps({
|
||||
'domain': domain_name,
|
||||
@ -697,7 +697,7 @@ def record_apply(domain_name):
|
||||
domain = Domain.query.filter(Domain.name == domain_name).first()
|
||||
|
||||
if domain:
|
||||
current_app.logger.debug('Current domain serial: {0}'.format(
|
||||
current_app.logger.debug('Current zone serial: {0}'.format(
|
||||
domain.serial))
|
||||
|
||||
if int(submitted_serial) != domain.serial:
|
||||
@ -714,14 +714,14 @@ def record_apply(domain_name):
|
||||
'status':
|
||||
'error',
|
||||
'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)
|
||||
|
||||
r = Record()
|
||||
result = r.apply(domain_name, submitted_record)
|
||||
if result['status'] == 'ok':
|
||||
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({
|
||||
'domain': domain_name,
|
||||
'add_rrsets': result['data'][0]['rrsets'],
|
||||
@ -733,7 +733,7 @@ def record_apply(domain_name):
|
||||
return make_response(jsonify(result), 200)
|
||||
else:
|
||||
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)),
|
||||
detail = json.dumps({
|
||||
'domain': domain_name,
|
||||
@ -760,7 +760,7 @@ def record_apply(domain_name):
|
||||
@can_access_domain
|
||||
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
|
||||
"""
|
||||
try:
|
||||
@ -818,7 +818,7 @@ def dnssec_enable(domain_name):
|
||||
dnssec = domain.enable_domain_dnssec(domain_name)
|
||||
domain_object = Domain.query.filter(domain_name == Domain.name).first()
|
||||
history = History(
|
||||
msg='DNSSEC was enabled for domain ' + domain_name ,
|
||||
msg='DNSSEC was enabled for zone ' + domain_name ,
|
||||
created_by=current_user.username,
|
||||
domain_id=domain_object.id)
|
||||
history.add()
|
||||
@ -837,7 +837,7 @@ def dnssec_disable(domain_name):
|
||||
domain.delete_dnssec_key(domain_name, key['id'])
|
||||
domain_object = Domain.query.filter(domain_name == Domain.name).first()
|
||||
history = History(
|
||||
msg='DNSSEC was disabled for domain ' + domain_name ,
|
||||
msg='DNSSEC was disabled for zone ' + domain_name ,
|
||||
created_by=current_user.username,
|
||||
domain_id=domain_object.id)
|
||||
history.add()
|
||||
@ -914,7 +914,7 @@ def admin_setdomainsetting(domain_name):
|
||||
}), 400)
|
||||
except Exception as e:
|
||||
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())
|
||||
return make_response(
|
||||
jsonify({
|
||||
|
@ -96,7 +96,7 @@
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<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.
|
||||
</p>
|
||||
<p>Click on users to move between columns.</p>
|
||||
@ -113,12 +113,12 @@
|
||||
</div>
|
||||
<!-- /.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.
|
||||
Moving already associated domains to this account will overwrite the previous
|
||||
Moving already associated zones to this account will overwrite the previous
|
||||
associated account.
|
||||
</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>
|
||||
<div class="form-group col-2">
|
||||
<select multiple="multiple" class="form-control" id="account_domains"
|
||||
@ -168,12 +168,12 @@
|
||||
<!-- /.card-header -->
|
||||
<div class="card-body">
|
||||
<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
|
||||
department.
|
||||
</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
|
||||
page.
|
||||
</p>
|
||||
@ -242,6 +242,6 @@
|
||||
}
|
||||
|
||||
addMultiSelect("#account_multi_user", "Username")
|
||||
addMultiSelect("#account_domains", "Domain")
|
||||
addMultiSelect("#account_domains", "Zone")
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -72,7 +72,7 @@
|
||||
<!-- /.card-header -->
|
||||
<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>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>
|
||||
<div class="form-group col-2">
|
||||
<select multiple="multiple" class="form-control" id="key_multi_account"
|
||||
@ -87,12 +87,12 @@
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
<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>
|
||||
<!-- /.card-header -->
|
||||
<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>Click on domains to move between the columns.</p>
|
||||
<p>This key will have access to the zones on the right.</p>
|
||||
<p>Click on zones to move between the columns.</p>
|
||||
<div class="form-group col-2">
|
||||
<select multiple="multiple" class="form-control" id="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><strong>Role</strong> The role of the key.</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>
|
||||
<!-- /.card-body -->
|
||||
</div>
|
||||
@ -154,13 +154,13 @@
|
||||
var warn_modal = $("#modal_warning");
|
||||
|
||||
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);
|
||||
warn_modal.modal('show');
|
||||
}
|
||||
|
||||
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);
|
||||
warn_modal.modal('show');
|
||||
}
|
||||
@ -203,8 +203,8 @@
|
||||
}
|
||||
});
|
||||
$("#key_multi_domain").multiSelect({
|
||||
selectableHeader: "<input type='text' class='search-input' autocomplete='off' placeholder='Domain Name'>",
|
||||
selectionHeader: "<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='Zone Name'>",
|
||||
afterInit: function (ms) {
|
||||
var that = this,
|
||||
$selectableSearch = that.$selectableUl.prev(),
|
||||
|
@ -135,9 +135,9 @@
|
||||
<div class="card-body">
|
||||
<p>Fill in all the fields to the in the form to the left.</p>
|
||||
{% 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
|
||||
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.
|
||||
</p>
|
||||
{% else %}
|
||||
|
@ -38,7 +38,7 @@
|
||||
<!-- /.card-header -->
|
||||
<div class="card-body">
|
||||
<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>
|
||||
</div>
|
||||
<!-- /.callout -->
|
||||
|
@ -49,7 +49,7 @@
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#tabs-domain" data-toggle="pill" role="tab">
|
||||
Search By Domain
|
||||
Search By Zone
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
@ -71,13 +71,13 @@
|
||||
</div>
|
||||
<div class="tab-pane" id="tabs-domain">
|
||||
<td>
|
||||
<label>Domain Name</label>
|
||||
<label>Zone Name</label>
|
||||
</td>
|
||||
<td>
|
||||
<div class="autocomplete" style="width:250px;">
|
||||
<input type="text" class="form-control" id="domain_name_filter"
|
||||
name="domain_name_filter"
|
||||
placeholder="Enter * to search for any domain" value="">
|
||||
placeholder="Enter * to search for any zone" value="">
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@ -447,7 +447,7 @@
|
||||
$('#auth_name_filter').val('');
|
||||
$('#user_name_filter').removeAttr('disabled');
|
||||
canSearch = false;
|
||||
main_field = "Domain Name"
|
||||
main_field = "Zone Name"
|
||||
});
|
||||
|
||||
$('#account_tab').click(function () {
|
||||
|
@ -48,7 +48,7 @@
|
||||
<th>Contact</th>
|
||||
<th>Mail</th>
|
||||
<th>Member</th>
|
||||
<th>Domain</th>
|
||||
<th>Zone(s)</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -43,7 +43,7 @@
|
||||
<th>Id</th>
|
||||
<th>Role</th>
|
||||
<th>Description</th>
|
||||
<th>Domains</th>
|
||||
<th>Zones</th>
|
||||
<th>Accounts</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
|
@ -143,7 +143,7 @@
|
||||
var modal = $("#modal_revoke");
|
||||
var username = $(this).prop('id');
|
||||
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('#button_revoke_confirm').click(function () {
|
||||
var postdata = {
|
||||
|
@ -671,7 +671,7 @@
|
||||
have no valid "powerdns-admin" records to their
|
||||
autoprovisioning field, will lose all their
|
||||
associations
|
||||
with any domain or account, also reverting to a
|
||||
with any zone or account, also reverting to a
|
||||
User in
|
||||
the process, despite their current role in the
|
||||
local db.<br>
|
||||
@ -1692,7 +1692,7 @@
|
||||
document.getElementById('purge_on').checked = false;
|
||||
document.getElementById('purge_off').checked = true;
|
||||
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('#button_confirm').click(function () {
|
||||
document.getElementById('purge_on').checked = true;
|
||||
|
@ -269,7 +269,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<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">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
@ -162,7 +162,7 @@
|
||||
<dt>Account</dt>
|
||||
<dd>Specifies the PowerDNS account value to use for the zone.</dd>
|
||||
<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>
|
||||
<li>
|
||||
<strong>Native</strong> - The server will not perform any Primary or Secondary
|
||||
@ -186,7 +186,7 @@
|
||||
<dt>SOA-EDIT-API</dt>
|
||||
<dd>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a
|
||||
change is
|
||||
made to the domain.
|
||||
made to the zone.
|
||||
<ul>
|
||||
<li>
|
||||
<strong>DEFAULT</strong> - Generate a soa serial of YYYYMMDD01. If the current serial
|
||||
@ -273,4 +273,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
@ -15,7 +15,7 @@
|
||||
{% if record_name and record_type %}
|
||||
Record changelog: <b>{{ record_name}}   {{ record_type }}</b>
|
||||
{% else %}
|
||||
Domain changelog: <b>{{ domain.name | pretty_domain_name }}</b>
|
||||
Zone changelog: <b>{{ domain.name | pretty_domain_name }}</b>
|
||||
{% endif %}
|
||||
</h1>
|
||||
</div>
|
||||
@ -41,7 +41,7 @@
|
||||
<div class="card-body">
|
||||
<button type="button" class="btn btn-primary float-left button_show_records" id="{{ domain.name }}">
|
||||
<i class="fa-solid fa-arrow-left"></i>
|
||||
Manage Domain {{ domain.name }}
|
||||
Manage Zone {{ domain.name }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@ -125,4 +125,4 @@
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
@ -37,7 +37,7 @@
|
||||
<div class="form-group">
|
||||
<label for="domainid">Zone</label>
|
||||
<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 %}
|
||||
<option value="{{ domain.id }}">{{ domain.name }}</option>
|
||||
{% endfor %}
|
||||
@ -83,7 +83,7 @@
|
||||
$(document.body).on("click", ".button_delete", function (e) {
|
||||
e.stopPropagation();
|
||||
if ($("#domainid").val() == 0) {
|
||||
showErrorModal("Please select domain to remove.");
|
||||
showErrorModal("Please select zone to remove.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -148,11 +148,11 @@
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<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>
|
||||
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>
|
||||
</div>
|
||||
</div>
|
||||
@ -197,7 +197,7 @@
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<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>
|
||||
<li>
|
||||
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.
|
||||
</li>
|
||||
</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) }}">
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
|
||||
<select name="domain_type" class="form-control" style="width:15em;">
|
||||
@ -251,7 +251,7 @@
|
||||
<div class="card-body">
|
||||
<p>The SOA-EDIT-API setting defines how the SOA serial number will be updated after a change
|
||||
is made
|
||||
to the domain.</p>
|
||||
to the zone.</p>
|
||||
<ul>
|
||||
<li>
|
||||
DEFAULT - Generate a soa serial of YYYYMMDD01. If the current serial is lower than
|
||||
@ -303,9 +303,9 @@
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<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
|
||||
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>
|
||||
<button type="button" title="Delete Zone" class="btn btn-danger float-left delete_domain"
|
||||
id="{{ domain.name }}">
|
||||
@ -402,7 +402,7 @@
|
||||
applyChanges(postdata, $SCRIPT_ROOT + '/domain/' + domain + '/manage-setting', true);
|
||||
});
|
||||
|
||||
// handle deletion of domain
|
||||
// handle deletion of zone
|
||||
$(document.body).on('click', '.delete_domain', function () {
|
||||
var modal = $("#modal_delete_domain");
|
||||
var domain = $(this).prop('id');
|
||||
@ -419,7 +419,7 @@
|
||||
modal.modal('show');
|
||||
});
|
||||
|
||||
// domain primary address input handeling
|
||||
// zone primary address input handeling
|
||||
$("select[name=domain_type]").change(function () {
|
||||
var type = $(this).val();
|
||||
if (type == "secondary") {
|
||||
|
@ -43,4 +43,5 @@ webcolors==1.12
|
||||
werkzeug==2.1.2
|
||||
zipp==3.11.0
|
||||
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)
|
||||
|
||||
### Start the update process
|
||||
app.logger.info('Update domains from nameserver API')
|
||||
app.logger.info('Update zones from nameserver API')
|
||||
|
||||
Domain().update()
|
||||
|
Loading…
Reference in New Issue
Block a user